summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShinya Maeda <shinya@gitlab.com>2018-09-24 20:02:26 +0900
committerAlessio Caiazza <acaiazza@gitlab.com>2018-10-02 17:04:04 +0200
commit703a41f8862c7278559ff13f2aa4f39ffd660c4e (patch)
treef408d57fbb5caaac94ff41b7e942f07c22b6841c
parentf97ec4b8f44152036a8f8242bcf1584cfbd56cec (diff)
downloadgitlab-ce-703a41f8862c7278559ff13f2aa4f39ffd660c4e.tar.gz
Introduce enqueue_scheduled event
-rw-r--r--app/models/ci/build.rb23
-rw-r--r--app/models/ci/build_schedule.rb35
-rw-r--r--app/presenters/ci/build_presenter.rb4
-rw-r--r--app/services/ci/run_scheduled_build_service.rb13
-rw-r--r--app/views/projects/ci/builds/_build.html.haml4
-rw-r--r--app/workers/ci/build_schedule_worker.rb7
-rw-r--r--lib/gitlab/ci/status/build/scheduled.rb2
-rw-r--r--scheduled_job_fixture.rb12
8 files changed, 47 insertions, 53 deletions
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index cf5df2ca354..3f2630798f3 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -22,7 +22,6 @@ module Ci
}.freeze
has_one :last_deployment, -> { order('deployments.id DESC') }, as: :deployable, class_name: 'Deployment'
- has_one :build_schedule, class_name: 'Ci::BuildSchedule', foreign_key: :build_id
has_many :trace_sections, class_name: 'Ci::BuildTraceSection'
has_many :trace_chunks, class_name: 'Ci::BuildTraceChunk', foreign_key: :build_id
@@ -168,12 +167,26 @@ module Ci
transition scheduled: :manual
end
- before_transition created: :scheduled do |build|
- build.build_build_schedule(execute_at: build.execute_at)
+ event :enqueue_scheduled do
+ transition scheduled: :pending do
+ validate do |build|
+ build.scheduled_at && build.scheduled_at < Time.now
+ end
+ end
end
before_transition scheduled: any do |build|
- build.build_schedule.delete
+ build.scheduled_at = nil
+ end
+
+ before_transition created: :scheduled do |build|
+ build.scheduled_at = build.get_scheduled_at
+ end
+
+ after_transition created: :scheduled do |build|
+ build.run_after_commit do
+ Ci::BuildScheduleWorker.perform_at(build.scheduled_at, build.id)
+ end
end
after_transition any => [:pending] do |build|
@@ -250,7 +263,7 @@ module Ci
self.when == 'delayed' && options[:start_in].present?
end
- def execute_at
+ def get_scheduled_at
ChronicDuration.parse(options[:start_in])&.seconds&.from_now
end
diff --git a/app/models/ci/build_schedule.rb b/app/models/ci/build_schedule.rb
deleted file mode 100644
index 4128fade86c..00000000000
--- a/app/models/ci/build_schedule.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-# frozen_string_literal: true
-
-module Ci
- class BuildSchedule < ActiveRecord::Base
- extend Gitlab::Ci::Model
- include Importable
- include AfterCommitQueue
-
- belongs_to :build
-
- validate :schedule_at_future
-
- after_create :schedule, unless: :importing?
-
- scope :stale, -> { where("execute_at < ?", Time.now) }
-
- def execute_in
- [0, self.execute_at - Time.now].max
- end
-
- private
-
- def schedule_at_future
- if self.execute_at < Time.now
- errors.add(:execute_at, "Excute point must be somewhere in the future")
- end
- end
-
- def schedule
- run_after_commit do
- Ci::BuildScheduleWorker.perform_at(self.execute_at, self.build_id)
- end
- end
- end
-end
diff --git a/app/presenters/ci/build_presenter.rb b/app/presenters/ci/build_presenter.rb
index 5331cdf632b..4005840ce58 100644
--- a/app/presenters/ci/build_presenter.rb
+++ b/app/presenters/ci/build_presenter.rb
@@ -35,6 +35,10 @@ module Ci
"#{subject.name} - #{detailed_status.status_tooltip}"
end
+ def execute_in
+ [0, scheduled_at - Time.now].max
+ end
+
private
def tooltip_for_badge
diff --git a/app/services/ci/run_scheduled_build_service.rb b/app/services/ci/run_scheduled_build_service.rb
new file mode 100644
index 00000000000..8e4a628296f
--- /dev/null
+++ b/app/services/ci/run_scheduled_build_service.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Ci
+ class RunScheduledBuildService < ::BaseService
+ def execute(build)
+ unless can?(current_user, :update_build, build)
+ raise Gitlab::Access::AccessDeniedError
+ end
+
+ build.enqueue_scheduled!
+ end
+ end
+end
diff --git a/app/views/projects/ci/builds/_build.html.haml b/app/views/projects/ci/builds/_build.html.haml
index 1ba8b698fe2..c706703ae6f 100644
--- a/app/views/projects/ci/builds/_build.html.haml
+++ b/app/views/projects/ci/builds/_build.html.haml
@@ -104,9 +104,9 @@
- elsif job.scheduled?
.btn-group
.btn.btn-default.has-tooltip{ disabled: true,
- title: job.build_schedule.execute_at }
+ title: job.scheduled_at }
= sprite_icon('planning')
- = duration_in_numbers(job.build_schedule.execute_in)
+ = duration_in_numbers(job.execute_in)
.btn.btn-default.btn-build.has-tooltip{ title: s_('DelayedJobs|Start now') }
= sprite_icon('play')
.btn.btn-default.btn-build.has-tooltip{ title: s_('DelayedJobs|Unschedule') }
diff --git a/app/workers/ci/build_schedule_worker.rb b/app/workers/ci/build_schedule_worker.rb
index 0d17a960c00..2a2d2bff282 100644
--- a/app/workers/ci/build_schedule_worker.rb
+++ b/app/workers/ci/build_schedule_worker.rb
@@ -6,10 +6,9 @@ module Ci
include PipelineQueue
def perform(build_id)
- ::Ci::Build.find_by(id: build_id).try do |build|
- break unless build.scheduled?
-
- Ci::PlayBuildService.new(build.project, build.user).execute(build)
+ ::Ci::Build.find_by_id(build_id).try do |build|
+ Ci::RunScheduledBuildService
+ .new(build.project, build.user).execute(build)
end
end
end
diff --git a/lib/gitlab/ci/status/build/scheduled.rb b/lib/gitlab/ci/status/build/scheduled.rb
index 05a97b1de47..270a2706c87 100644
--- a/lib/gitlab/ci/status/build/scheduled.rb
+++ b/lib/gitlab/ci/status/build/scheduled.rb
@@ -23,7 +23,7 @@ module Gitlab
private
def execute_in
- Time.at(subject.build_schedule.execute_in).utc.strftime("%H:%M:%S")
+ Time.at(subject.scheduled_at).utc.strftime("%H:%M:%S")
end
end
end
diff --git a/scheduled_job_fixture.rb b/scheduled_job_fixture.rb
index 7389e63a0da..9ed59d337f7 100644
--- a/scheduled_job_fixture.rb
+++ b/scheduled_job_fixture.rb
@@ -64,15 +64,15 @@ cleanup:
#
# ### Reproduce the scenario ~ when all stages succeeded ~
#
-# 1. ScheduledJobFixture.new(29, 1).create_pipeline('master')
-# 1. ScheduledJobFixture.new(29, 1).finish_stage_until('test')
+# 1. ScheduledJobFixture.new(16, 1).create_pipeline('master')
+# 1. ScheduledJobFixture.new(16, 1).finish_stage_until('test')
# 1. Wait until rollout 10% job is triggered
-# 1. ScheduledJobFixture.new(29, 1).finish_stage_until('rollout 10%')
+# 1. ScheduledJobFixture.new(16, 1).finish_stage_until('rollout 10%')
# 1. Wait until rollout 50% job is triggered
-# 1. ScheduledJobFixture.new(29, 1).finish_stage_until('rollout 50%')
+# 1. ScheduledJobFixture.new(16, 1).finish_stage_until('rollout 50%')
# 1. Wait until rollout 100% job is triggered
-# 1. ScheduledJobFixture.new(29, 1).finish_stage_until('rollout 100%')
-# 1. ScheduledJobFixture.new(29, 1).finish_stage_until('cleanup')
+# 1. ScheduledJobFixture.new(16, 1).finish_stage_until('rollout 100%')
+# 1. ScheduledJobFixture.new(16, 1).finish_stage_until('cleanup')
#
# Expectation: Users see a succeccful pipeline
#