summaryrefslogtreecommitdiff
path: root/lib/ci
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ci')
-rw-r--r--lib/ci/gitlab_ci_yaml_processor.rb43
-rw-r--r--lib/ci/migrate/builds.rb29
-rw-r--r--lib/ci/migrate/database.rb67
-rw-r--r--lib/ci/migrate/manager.rb72
-rw-r--r--lib/ci/migrate/tags.rb42
-rw-r--r--lib/ci/status.rb21
6 files changed, 49 insertions, 225 deletions
diff --git a/lib/ci/gitlab_ci_yaml_processor.rb b/lib/ci/gitlab_ci_yaml_processor.rb
index c47951bc5d1..efcd2faffc7 100644
--- a/lib/ci/gitlab_ci_yaml_processor.rb
+++ b/lib/ci/gitlab_ci_yaml_processor.rb
@@ -5,7 +5,7 @@ module Ci
DEFAULT_STAGES = %w(build test deploy)
DEFAULT_STAGE = 'test'
ALLOWED_YAML_KEYS = [:before_script, :image, :services, :types, :stages, :variables]
- ALLOWED_JOB_KEYS = [:tags, :script, :only, :except, :type, :image, :services, :allow_failure, :type, :stage]
+ ALLOWED_JOB_KEYS = [:tags, :script, :only, :except, :type, :image, :services, :allow_failure, :type, :stage, :when]
attr_reader :before_script, :image, :services, :variables
@@ -93,6 +93,7 @@ module Ci
only: job[:only],
except: job[:except],
allow_failure: job[:allow_failure] || false,
+ when: job[:when] || 'on_success',
options: {
image: job[:image] || @image,
services: job[:services] || @services
@@ -138,62 +139,74 @@ module Ci
end
@jobs.each do |name, job|
- validate_job!("#{name} job", job)
+ validate_job!(name, job)
end
true
end
def validate_job!(name, job)
+ if name.blank? || !validate_string(name)
+ raise ValidationError, "job name should be non-empty string"
+ end
+
job.keys.each do |key|
unless ALLOWED_JOB_KEYS.include? key
- raise ValidationError, "#{name}: unknown parameter #{key}"
+ raise ValidationError, "#{name} job: unknown parameter #{key}"
end
end
- if !job[:script].is_a?(String) && !validate_array_of_strings(job[:script])
- raise ValidationError, "#{name}: script should be a string or an array of a strings"
+ if !validate_string(job[:script]) && !validate_array_of_strings(job[:script])
+ raise ValidationError, "#{name} job: script should be a string or an array of a strings"
end
if job[:stage]
unless job[:stage].is_a?(String) && job[:stage].in?(stages)
- raise ValidationError, "#{name}: stage parameter should be #{stages.join(", ")}"
+ raise ValidationError, "#{name} job: stage parameter should be #{stages.join(", ")}"
end
end
- if job[:image] && !job[:image].is_a?(String)
- raise ValidationError, "#{name}: image should be a string"
+ if job[:image] && !validate_string(job[:image])
+ raise ValidationError, "#{name} job: image should be a string"
end
if job[:services] && !validate_array_of_strings(job[:services])
- raise ValidationError, "#{name}: services should be an array of strings"
+ raise ValidationError, "#{name} job: services should be an array of strings"
end
if job[:tags] && !validate_array_of_strings(job[:tags])
- raise ValidationError, "#{name}: tags parameter should be an array of strings"
+ raise ValidationError, "#{name} job: tags parameter should be an array of strings"
end
if job[:only] && !validate_array_of_strings(job[:only])
- raise ValidationError, "#{name}: only parameter should be an array of strings"
+ raise ValidationError, "#{name} job: only parameter should be an array of strings"
end
if job[:except] && !validate_array_of_strings(job[:except])
- raise ValidationError, "#{name}: except parameter should be an array of strings"
+ raise ValidationError, "#{name} job: except parameter should be an array of strings"
end
if job[:allow_failure] && !job[:allow_failure].in?([true, false])
- raise ValidationError, "#{name}: allow_failure parameter should be an boolean"
+ raise ValidationError, "#{name} job: allow_failure parameter should be an boolean"
+ end
+
+ if job[:when] && !job[:when].in?(%w(on_success on_failure always))
+ raise ValidationError, "#{name} job: when parameter should be on_success, on_failure or always"
end
end
private
def validate_array_of_strings(values)
- values.is_a?(Array) && values.all? {|tag| tag.is_a?(String)}
+ values.is_a?(Array) && values.all? { |value| validate_string(value) }
end
def validate_variables(variables)
- variables.is_a?(Hash) && variables.all? {|key, value| key.is_a?(Symbol) && value.is_a?(String)}
+ variables.is_a?(Hash) && variables.all? { |key, value| validate_string(key) && validate_string(value) }
+ end
+
+ def validate_string(value)
+ value.is_a?(String) || value.is_a?(Symbol)
end
end
end
diff --git a/lib/ci/migrate/builds.rb b/lib/ci/migrate/builds.rb
deleted file mode 100644
index c4f62e55295..00000000000
--- a/lib/ci/migrate/builds.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-module Ci
- module Migrate
- class Builds
- attr_reader :app_builds_dir, :backup_builds_tarball, :backup_dir
-
- def initialize
- @app_builds_dir = Settings.gitlab_ci.builds_path
- @backup_dir = Gitlab.config.backup.path
- @backup_builds_tarball = File.join(backup_dir, 'builds/builds.tar.gz')
- end
-
- def restore
- backup_existing_builds_dir
-
- FileUtils.mkdir_p(app_builds_dir, mode: 0700)
- unless system('tar', '-C', app_builds_dir, '-zxf', backup_builds_tarball)
- abort 'Restore failed'.red
- end
- end
-
- def backup_existing_builds_dir
- timestamped_builds_path = File.join(app_builds_dir, '..', "builds.#{Time.now.to_i}")
- if File.exists?(app_builds_dir)
- FileUtils.mv(app_builds_dir, File.expand_path(timestamped_builds_path))
- end
- end
- end
- end
-end
diff --git a/lib/ci/migrate/database.rb b/lib/ci/migrate/database.rb
deleted file mode 100644
index bf9b80f1f62..00000000000
--- a/lib/ci/migrate/database.rb
+++ /dev/null
@@ -1,67 +0,0 @@
-require 'yaml'
-
-module Ci
- module Migrate
- class Database
- attr_reader :config
-
- def initialize
- @config = YAML.load_file(File.join(Rails.root, 'config', 'database.yml'))[Rails.env]
- end
-
- def restore
- decompress_rd, decompress_wr = IO.pipe
- decompress_pid = spawn(*%W(gzip -cd), out: decompress_wr, in: db_file_name)
- decompress_wr.close
-
- restore_pid = case config["adapter"]
- when /^mysql/ then
- $progress.print "Restoring MySQL database #{config['database']} ... "
- # Workaround warnings from MySQL 5.6 about passwords on cmd line
- ENV['MYSQL_PWD'] = config["password"].to_s if config["password"]
- spawn('mysql', *mysql_args, config['database'], in: decompress_rd)
- when "postgresql" then
- $progress.print "Restoring PostgreSQL database #{config['database']} ... "
- pg_env
- spawn('psql', config['database'], in: decompress_rd)
- end
- decompress_rd.close
-
- success = [decompress_pid, restore_pid].all? { |pid| Process.waitpid(pid); $?.success? }
- abort 'Restore failed' unless success
- end
-
- protected
-
- def db_file_name
- File.join(Gitlab.config.backup.path, 'db', 'database.sql.gz')
- end
-
- def mysql_args
- args = {
- 'host' => '--host',
- 'port' => '--port',
- 'socket' => '--socket',
- 'username' => '--user',
- 'encoding' => '--default-character-set'
- }
- args.map { |opt, arg| "#{arg}=#{config[opt]}" if config[opt] }.compact
- end
-
- def pg_env
- ENV['PGUSER'] = config["username"] if config["username"]
- ENV['PGHOST'] = config["host"] if config["host"]
- ENV['PGPORT'] = config["port"].to_s if config["port"]
- ENV['PGPASSWORD'] = config["password"].to_s if config["password"]
- end
-
- def report_success(success)
- if success
- puts '[DONE]'.green
- else
- puts '[FAILED]'.red
- end
- end
- end
- end
-end
diff --git a/lib/ci/migrate/manager.rb b/lib/ci/migrate/manager.rb
deleted file mode 100644
index e5e4fb784eb..00000000000
--- a/lib/ci/migrate/manager.rb
+++ /dev/null
@@ -1,72 +0,0 @@
-module Ci
- module Migrate
- class Manager
- CI_IMPORT_PREFIX = '8.0' # Only allow imports from CI 8.0.x
-
- def cleanup
- $progress.print "Deleting tmp directories ... "
-
- backup_contents.each do |dir|
- next unless File.exist?(File.join(Gitlab.config.backup.path, dir))
-
- if FileUtils.rm_rf(File.join(Gitlab.config.backup.path, dir))
- $progress.puts "done".green
- else
- puts "deleting tmp directory '#{dir}' failed".red
- abort 'Backup failed'
- end
- end
- end
-
- def unpack
- Dir.chdir(Gitlab.config.backup.path)
-
- # check for existing backups in the backup dir
- file_list = Dir.glob("*_gitlab_ci_backup.tar").each.map { |f| f.split(/_/).first.to_i }
- puts "no backups found" if file_list.count == 0
-
- if file_list.count > 1 && ENV["BACKUP"].nil?
- puts "Found more than one backup, please specify which one you want to restore:"
- puts "rake gitlab:backup:restore BACKUP=timestamp_of_backup"
- exit 1
- end
-
- tar_file = ENV["BACKUP"].nil? ? File.join("#{file_list.first}_gitlab_ci_backup.tar") : File.join(ENV["BACKUP"] + "_gitlab_ci_backup.tar")
-
- unless File.exists?(tar_file)
- puts "The specified CI backup doesn't exist!"
- exit 1
- end
-
- $progress.print "Unpacking backup ... "
-
- unless Kernel.system(*%W(tar -xf #{tar_file}))
- puts "unpacking backup failed".red
- exit 1
- else
- $progress.puts "done".green
- end
-
- ENV["VERSION"] = "#{settings[:db_version]}" if settings[:db_version].to_i > 0
-
- # restoring mismatching backups can lead to unexpected problems
- if !settings[:gitlab_version].start_with?(CI_IMPORT_PREFIX)
- puts "GitLab CI version mismatch:".red
- puts " Your current GitLab CI version (#{GitlabCi::VERSION}) differs from the GitLab CI (#{settings[:gitlab_version]}) version in the backup!".red
- exit 1
- end
- end
-
- private
-
- def backup_contents
- ["db", "builds", "backup_information.yml"]
- end
-
- def settings
- @settings ||= YAML.load_file("backup_information.yml")
- end
- end
- end
-end
-
diff --git a/lib/ci/migrate/tags.rb b/lib/ci/migrate/tags.rb
deleted file mode 100644
index 97e043ece27..00000000000
--- a/lib/ci/migrate/tags.rb
+++ /dev/null
@@ -1,42 +0,0 @@
-require 'yaml'
-
-module Ci
- module Migrate
- class Tags
- def restore
- puts 'Inserting tags...'
- connection.select_all('SELECT ci_tags.name FROM ci_tags').each do |tag|
- begin
- connection.execute("INSERT INTO tags (name) VALUES(#{ActiveRecord::Base::sanitize(tag['name'])})")
- rescue ActiveRecord::RecordNotUnique
- end
- end
-
- ActiveRecord::Base.transaction do
- puts 'Deleting old taggings...'
- connection.execute "DELETE FROM taggings WHERE context = 'tags' AND taggable_type LIKE 'Ci::%'"
-
- puts 'Inserting taggings...'
- connection.execute(
- 'INSERT INTO taggings (taggable_type, taggable_id, tag_id, context) ' +
- "SELECT CONCAT('Ci::', ci_taggings.taggable_type), ci_taggings.taggable_id, tags.id, 'tags' FROM ci_taggings " +
- 'JOIN ci_tags ON ci_tags.id = ci_taggings.tag_id ' +
- 'JOIN tags ON tags.name = ci_tags.name '
- )
-
- puts 'Resetting counters... '
- connection.execute(
- 'UPDATE tags SET ' +
- 'taggings_count = (SELECT COUNT(*) FROM taggings WHERE tags.id = taggings.tag_id)'
- )
- end
- end
-
- protected
-
- def connection
- ActiveRecord::Base.connection
- end
- end
- end
-end
diff --git a/lib/ci/status.rb b/lib/ci/status.rb
new file mode 100644
index 00000000000..c02b3b8f3e4
--- /dev/null
+++ b/lib/ci/status.rb
@@ -0,0 +1,21 @@
+module Ci
+ class Status
+ def self.get_status(statuses)
+ statuses.reject! { |status| status.try(&:allow_failure?) }
+
+ if statuses.none?
+ 'skipped'
+ elsif statuses.all?(&:success?)
+ 'success'
+ elsif statuses.all?(&:pending?)
+ 'pending'
+ elsif statuses.any?(&:running?) || statuses.any?(&:pending?)
+ 'running'
+ elsif statuses.all?(&:canceled?)
+ 'canceled'
+ else
+ 'failed'
+ end
+ end
+ end
+end