summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJames Lopez <james@jameslopez.es>2016-03-28 09:37:55 +0200
committerJames Lopez <james@jameslopez.es>2016-03-28 09:37:55 +0200
commitfcb85381cf025da5e8cfecdc1a4afc016b5cb6ae (patch)
treeb9b0fec56e7645ee55896c05bf9e84c9b3446a11 /lib
parentcc4d04f97f891479c4d033196c6868e19528c51c (diff)
parent30e4d3ce9a18340c689557cd0c7b5f69e48795d4 (diff)
downloadgitlab-ce-fcb85381cf025da5e8cfecdc1a4afc016b5cb6ae.tar.gz
Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce into fix/project-import_url
Diffstat (limited to 'lib')
-rw-r--r--lib/ci/gitlab_ci_yaml_processor.rb21
-rw-r--r--lib/gitlab/email/receiver.rb14
-rw-r--r--lib/gitlab/exclusive_lease.rb21
-rw-r--r--lib/tasks/gitlab/backup.rake34
-rw-r--r--lib/tasks/gitlab/db.rake35
5 files changed, 100 insertions, 25 deletions
diff --git a/lib/ci/gitlab_ci_yaml_processor.rb b/lib/ci/gitlab_ci_yaml_processor.rb
index c89e1b51019..b7209c14148 100644
--- a/lib/ci/gitlab_ci_yaml_processor.rb
+++ b/lib/ci/gitlab_ci_yaml_processor.rb
@@ -26,8 +26,8 @@ module Ci
validate!
end
- def builds_for_stage_and_ref(stage, ref, tag = false)
- builds.select{|build| build[:stage] == stage && process?(build[:only], build[:except], ref, tag)}
+ def builds_for_stage_and_ref(stage, ref, tag = false, trigger_request = nil)
+ builds.select{|build| build[:stage] == stage && process?(build[:only], build[:except], ref, tag, trigger_request)}
end
def builds
@@ -242,9 +242,9 @@ module Ci
stage_index = stages.index(job[:stage])
job[:dependencies].each do |dependency|
- raise ValidationError, "#{name} job: undefined dependency: #{dependency}" unless @jobs[dependency]
+ raise ValidationError, "#{name} job: undefined dependency: #{dependency}" unless @jobs[dependency.to_sym]
- unless stages.index(@jobs[dependency][:stage]) < stage_index
+ unless stages.index(@jobs[dependency.to_sym][:stage]) < stage_index
raise ValidationError, "#{name} job: dependency #{dependency} is not defined in prior stages"
end
end
@@ -266,29 +266,30 @@ module Ci
value.in?([true, false])
end
- def process?(only_params, except_params, ref, tag)
+ def process?(only_params, except_params, ref, tag, trigger_request)
if only_params.present?
- return false unless matching?(only_params, ref, tag)
+ return false unless matching?(only_params, ref, tag, trigger_request)
end
if except_params.present?
- return false if matching?(except_params, ref, tag)
+ return false if matching?(except_params, ref, tag, trigger_request)
end
true
end
- def matching?(patterns, ref, tag)
+ def matching?(patterns, ref, tag, trigger_request)
patterns.any? do |pattern|
- match_ref?(pattern, ref, tag)
+ match_ref?(pattern, ref, tag, trigger_request)
end
end
- def match_ref?(pattern, ref, tag)
+ def match_ref?(pattern, ref, tag, trigger_request)
pattern, path = pattern.split('@', 2)
return false if path && path != self.path
return true if tag && pattern == 'tags'
return true if !tag && pattern == 'branches'
+ return true if trigger_request.present? && pattern == 'triggers'
if pattern.first == "/" && pattern.last == "/"
Regexp.new(pattern[1...-1]) =~ ref
diff --git a/lib/gitlab/email/receiver.rb b/lib/gitlab/email/receiver.rb
index 2ca21af5bc8..d4b6f6d120d 100644
--- a/lib/gitlab/email/receiver.rb
+++ b/lib/gitlab/email/receiver.rb
@@ -45,12 +45,12 @@ module Gitlab
note = create_note(reply)
unless note.persisted?
- message = "The comment could not be created for the following reasons:"
+ msg = "The comment could not be created for the following reasons:"
note.errors.full_messages.each do |error|
- message << "\n\n- #{error}"
+ msg << "\n\n- #{error}"
end
- raise InvalidNoteError, message
+ raise InvalidNoteError, msg
end
end
@@ -63,13 +63,13 @@ module Gitlab
end
def reply_key
- reply_key = nil
+ key = nil
message.to.each do |address|
- reply_key = Gitlab::IncomingEmail.key_from_address(address)
- break if reply_key
+ key = Gitlab::IncomingEmail.key_from_address(address)
+ break if key
end
- reply_key
+ key
end
def sent_notification
diff --git a/lib/gitlab/exclusive_lease.rb b/lib/gitlab/exclusive_lease.rb
index 2ef50286b1d..c73eca832d7 100644
--- a/lib/gitlab/exclusive_lease.rb
+++ b/lib/gitlab/exclusive_lease.rb
@@ -15,6 +15,25 @@ module Gitlab
# seconds then two overlapping operations may hold a lease for the same
# key at the same time.
#
+ # This class has no 'cancel' method. I originally decided against adding
+ # it because it would add complexity and a false sense of security. The
+ # complexity: instead of setting '1' we would have to set a UUID, and to
+ # delete it we would have to execute Lua on the Redis server to only
+ # delete the key if the value was our own UUID. Otherwise there is a
+ # chance that when you intend to cancel your lease you actually delete
+ # someone else's. The false sense of security: you cannot design your
+ # system to rely too much on the lease being cancelled after use because
+ # the calling (Ruby) process may crash or be killed. You _cannot_ count
+ # on begin/ensure blocks to cancel a lease, because the 'ensure' does
+ # not always run. Think of 'kill -9' from the Unicorn master for
+ # instance.
+ #
+ # If you find that leases are getting in your way, ask yourself: would
+ # it be enough to lower the lease timeout? Another thing that might be
+ # appropriate is to only use a lease for bulk/automated operations, and
+ # to ignore the lease when you get a single 'manual' user request (a
+ # button click).
+ #
class ExclusiveLease
def initialize(key, timeout:)
@key, @timeout = key, timeout
@@ -27,6 +46,8 @@ module Gitlab
!!redis.set(redis_key, '1', nx: true, ex: @timeout)
end
+ # No #cancel method. See comments above!
+
private
def redis
diff --git a/lib/tasks/gitlab/backup.rake b/lib/tasks/gitlab/backup.rake
index cb4abe13799..402bb338f27 100644
--- a/lib/tasks/gitlab/backup.rake
+++ b/lib/tasks/gitlab/backup.rake
@@ -22,7 +22,7 @@ namespace :gitlab do
end
# Restore backup of GitLab system
- desc "GitLab | Restore a previously created backup"
+ desc 'GitLab | Restore a previously created backup'
task restore: :environment do
warn_user_is_not_gitlab
configure_cron_mode
@@ -30,13 +30,31 @@ namespace :gitlab do
backup = Backup::Manager.new
backup.unpack
- Rake::Task["gitlab:backup:db:restore"].invoke unless backup.skipped?("db")
- Rake::Task["gitlab:backup:repo:restore"].invoke unless backup.skipped?("repositories")
- Rake::Task["gitlab:backup:uploads:restore"].invoke unless backup.skipped?("uploads")
- Rake::Task["gitlab:backup:builds:restore"].invoke unless backup.skipped?("builds")
- Rake::Task["gitlab:backup:artifacts:restore"].invoke unless backup.skipped?("artifacts")
- Rake::Task["gitlab:backup:lfs:restore"].invoke unless backup.skipped?("lfs")
- Rake::Task["gitlab:shell:setup"].invoke
+ unless backup.skipped?('db')
+ unless ENV['force'] == 'yes'
+ warning = warning = <<-MSG.strip_heredoc
+ Before restoring the database we recommend removing all existing
+ tables to avoid future upgrade problems. Be aware that if you have
+ custom tables in the GitLab database these tables and all data will be
+ removed.
+ MSG
+ ask_to_continue
+ puts 'Removing all tables. Press `Ctrl-C` within 5 seconds to abort'.yellow
+ sleep(5)
+ end
+ # Drop all tables Load the schema to ensure we don't have any newer tables
+ # hanging out from a failed upgrade
+ $progress.puts 'Cleaning the database ... '.blue
+ Rake::Task['gitlab:db:drop_tables'].invoke
+ $progress.puts 'done'.green
+ Rake::Task['gitlab:backup:db:restore'].invoke
+ end
+ Rake::Task['gitlab:backup:repo:restore'].invoke unless backup.skipped?('repositories')
+ Rake::Task['gitlab:backup:uploads:restore'].invoke unless backup.skipped?('uploads')
+ Rake::Task['gitlab:backup:builds:restore'].invoke unless backup.skipped?('builds')
+ Rake::Task['gitlab:backup:artifacts:restore'].invoke unless backup.skipped?('artifacts')
+ Rake::Task['gitlab:backup:lfs:restore'].invoke unless backup.skipped?('lfs')
+ Rake::Task['gitlab:shell:setup'].invoke
backup.cleanup
end
diff --git a/lib/tasks/gitlab/db.rake b/lib/tasks/gitlab/db.rake
new file mode 100644
index 00000000000..4921c6e0bcf
--- /dev/null
+++ b/lib/tasks/gitlab/db.rake
@@ -0,0 +1,35 @@
+namespace :gitlab do
+ namespace :db do
+ desc 'GitLab | Manually insert schema migration version'
+ task :mark_migration_complete, [:version] => :environment do |_, args|
+ unless args[:version]
+ puts "Must specify a migration version as an argument".red
+ exit 1
+ end
+
+ version = args[:version].to_i
+ if version == 0
+ puts "Version '#{args[:version]}' must be a non-zero integer".red
+ exit 1
+ end
+
+ sql = "INSERT INTO schema_migrations (version) VALUES (#{version})"
+ begin
+ ActiveRecord::Base.connection.execute(sql)
+ puts "Successfully marked '#{version}' as complete".green
+ rescue ActiveRecord::RecordNotUnique
+ puts "Migration version '#{version}' is already marked complete".yellow
+ end
+ end
+
+ desc 'Drop all tables'
+ task :drop_tables => :environment do
+ connection = ActiveRecord::Base.connection
+ tables = connection.tables
+ tables.delete 'schema_migrations'
+ # Truncate schema_migrations to ensure migrations re-run
+ connection.execute('TRUNCATE schema_migrations')
+ tables.each { |t| connection.execute("DROP TABLE #{t}") }
+ end
+ end
+end