Show timeout information on job's page
This commit is contained in:
parent
d633bc8134
commit
78a4189ece
|
@ -39,6 +39,15 @@
|
||||||
runnerId() {
|
runnerId() {
|
||||||
return `#${this.job.runner.id}`;
|
return `#${this.job.runner.id}`;
|
||||||
},
|
},
|
||||||
|
timeout() {
|
||||||
|
let t = `${this.job.timeout.value}`;
|
||||||
|
|
||||||
|
if (this.job.timeout.source != null) {
|
||||||
|
t += ` (from ${this.job.timeout.source})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return t;
|
||||||
|
},
|
||||||
renderBlock() {
|
renderBlock() {
|
||||||
return this.job.merge_request ||
|
return this.job.merge_request ||
|
||||||
this.job.duration ||
|
this.job.duration ||
|
||||||
|
@ -114,6 +123,12 @@
|
||||||
title="Queued"
|
title="Queued"
|
||||||
:value="queued"
|
:value="queued"
|
||||||
/>
|
/>
|
||||||
|
<detail-row
|
||||||
|
class="js-job-timeout"
|
||||||
|
v-if="job.timeout"
|
||||||
|
title="Timeout"
|
||||||
|
:value="timeout"
|
||||||
|
/>
|
||||||
<detail-row
|
<detail-row
|
||||||
class="js-job-runner"
|
class="js-job-runner"
|
||||||
v-if="job.runner"
|
v-if="job.runner"
|
||||||
|
|
|
@ -6,6 +6,7 @@ module Ci
|
||||||
include ObjectStorage::BackgroundMove
|
include ObjectStorage::BackgroundMove
|
||||||
include Presentable
|
include Presentable
|
||||||
include Importable
|
include Importable
|
||||||
|
include ChronicDurationAttribute
|
||||||
|
|
||||||
MissingDependenciesError = Class.new(StandardError)
|
MissingDependenciesError = Class.new(StandardError)
|
||||||
|
|
||||||
|
@ -90,6 +91,8 @@ module Ci
|
||||||
after_commit :update_project_statistics_after_save, on: [:create, :update]
|
after_commit :update_project_statistics_after_save, on: [:create, :update]
|
||||||
after_commit :update_project_statistics, on: :destroy
|
after_commit :update_project_statistics, on: :destroy
|
||||||
|
|
||||||
|
chronic_duration_attribute_reader :used_timeout_user_readable, :used_timeout
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
# This is needed for url_for to work,
|
# This is needed for url_for to work,
|
||||||
# as the controller is JobsController
|
# as the controller is JobsController
|
||||||
|
@ -120,6 +123,10 @@ module Ci
|
||||||
end
|
end
|
||||||
|
|
||||||
after_transition pending: :running do |build|
|
after_transition pending: :running do |build|
|
||||||
|
build.used_timeout = build.timeout
|
||||||
|
build.timeout_source = build.should_use_runner_timeout? ? 'Runner' : 'Project'
|
||||||
|
build.save!
|
||||||
|
|
||||||
build.run_after_commit do
|
build.run_after_commit do
|
||||||
BuildHooksWorker.perform_async(id)
|
BuildHooksWorker.perform_async(id)
|
||||||
end
|
end
|
||||||
|
@ -232,15 +239,14 @@ module Ci
|
||||||
end
|
end
|
||||||
|
|
||||||
def timeout
|
def timeout
|
||||||
return runner.maximum_job_timeout if should_use_runner_timeout
|
return runner.maximum_job_timeout if should_use_runner_timeout?
|
||||||
|
|
||||||
project.build_timeout
|
project.build_timeout
|
||||||
end
|
end
|
||||||
|
|
||||||
def should_use_runner_timeout
|
def should_use_runner_timeout?
|
||||||
!runner.nil? && runner.defines_maximum_job_timeout? && runner.maximum_job_timeout < project.build_timeout
|
!runner.nil? && runner.defines_maximum_job_timeout? && runner.maximum_job_timeout < project.build_timeout
|
||||||
end
|
end
|
||||||
private :should_use_runner_timeout
|
|
||||||
|
|
||||||
def triggered_by?(current_user)
|
def triggered_by?(current_user)
|
||||||
user == current_user
|
user == current_user
|
||||||
|
|
|
@ -5,6 +5,11 @@ class BuildDetailsEntity < JobEntity
|
||||||
expose :runner, using: RunnerEntity
|
expose :runner, using: RunnerEntity
|
||||||
expose :pipeline, using: PipelineEntity
|
expose :pipeline, using: PipelineEntity
|
||||||
|
|
||||||
|
expose :timeout, if: -> (*) { !build.used_timeout.nil? } do |build|
|
||||||
|
{ value: build.used_timeout_user_readable,
|
||||||
|
source: build.timeout_source }
|
||||||
|
end
|
||||||
|
|
||||||
expose :erased_by, if: -> (*) { build.erased? }, using: UserEntity
|
expose :erased_by, if: -> (*) { build.erased? }, using: UserEntity
|
||||||
expose :erase_path, if: -> (*) { build.erasable? && can?(current_user, :erase_build, build) } do |build|
|
expose :erase_path, if: -> (*) { build.erasable? && can?(current_user, :erase_build, build) } do |build|
|
||||||
erase_project_job_path(project, build)
|
erase_project_job_path(project, build)
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
class AddUsedTimeoutAndTimeoutSourceColumnsToCiBuilds < ActiveRecord::Migration
|
||||||
|
include Gitlab::Database::MigrationHelpers
|
||||||
|
|
||||||
|
DOWNTIME = false
|
||||||
|
|
||||||
|
def up
|
||||||
|
add_column :ci_builds, :used_timeout, :integer
|
||||||
|
add_column :ci_builds, :timeout_source, :string
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
remove_column :ci_builds, :used_timeout
|
||||||
|
remove_column :ci_builds, :timeout_source
|
||||||
|
end
|
||||||
|
end
|
|
@ -311,6 +311,8 @@ ActiveRecord::Schema.define(version: 20180327101207) do
|
||||||
t.integer "artifacts_metadata_store"
|
t.integer "artifacts_metadata_store"
|
||||||
t.boolean "protected"
|
t.boolean "protected"
|
||||||
t.integer "failure_reason"
|
t.integer "failure_reason"
|
||||||
|
t.integer "used_timeout"
|
||||||
|
t.string "timeout_source"
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "ci_builds", ["artifacts_expire_at"], name: "index_ci_builds_on_artifacts_expire_at", where: "(artifacts_file <> ''::text)", using: :btree
|
add_index "ci_builds", ["artifacts_expire_at"], name: "index_ci_builds_on_artifacts_expire_at", where: "(artifacts_file <> ''::text)", using: :btree
|
||||||
|
|
|
@ -283,6 +283,8 @@ CommitStatus:
|
||||||
- retried
|
- retried
|
||||||
- protected
|
- protected
|
||||||
- failure_reason
|
- failure_reason
|
||||||
|
- used_timeout
|
||||||
|
- timeout_source
|
||||||
Ci::Variable:
|
Ci::Variable:
|
||||||
- id
|
- id
|
||||||
- project_id
|
- project_id
|
||||||
|
|
|
@ -1,28 +1,46 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
shared_examples 'ChronicDurationAttribute' do
|
shared_examples 'ChronicDurationAttribute reader' do
|
||||||
describe 'dynamically defined methods' do
|
it 'contains dynamically created reader method' do
|
||||||
it { expect(subject.class).to be_public_method_defined(virtual_field) }
|
expect(subject.class).to be_public_method_defined(virtual_field)
|
||||||
it { expect(subject.class).to be_public_method_defined("#{virtual_field}=") }
|
end
|
||||||
|
|
||||||
it 'parses chronic duration input' do
|
it 'outputs chronic duration formated value' do
|
||||||
subject.send("#{virtual_field}=", "10m")
|
subject.send("#{source_field}=", 120)
|
||||||
|
|
||||||
expect(subject.send(source_field)).to eq(600)
|
expect(subject.send(virtual_field)).to eq('2m')
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
it 'outputs chronic duration formated value' do
|
shared_examples 'ChronicDurationAttribute writer' do
|
||||||
subject.send("#{source_field}=", 120)
|
it 'contains dynamically created writer method' do
|
||||||
|
expect(subject.class).to be_public_method_defined("#{virtual_field}=")
|
||||||
|
end
|
||||||
|
|
||||||
expect(subject.send(virtual_field)).to eq('2m')
|
it 'parses chronic duration input' do
|
||||||
end
|
subject.send("#{virtual_field}=", "10m")
|
||||||
|
|
||||||
|
expect(subject.send(source_field)).to eq(600)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'ChronicDurationAttribute' do
|
describe 'ChronicDurationAttribute' do
|
||||||
let(:source_field) { :maximum_job_timeout }
|
let(:source_field) {:maximum_job_timeout}
|
||||||
let(:virtual_field) { :maximum_job_timeout_user_readable }
|
let(:virtual_field) {:maximum_job_timeout_user_readable}
|
||||||
subject { Ci::Runner.new }
|
subject {Ci::Runner.new}
|
||||||
|
|
||||||
it_behaves_like 'ChronicDurationAttribute'
|
it_behaves_like 'ChronicDurationAttribute reader'
|
||||||
|
it_behaves_like 'ChronicDurationAttribute writer'
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'ChronicDurationAttribute - reader' do
|
||||||
|
let(:source_field) {:used_timeout}
|
||||||
|
let(:virtual_field) {:used_timeout_user_readable}
|
||||||
|
subject {Ci::Build.new}
|
||||||
|
|
||||||
|
it "doesn't contain dynamically created writer method" do
|
||||||
|
expect(subject.class).not_to be_public_method_defined("#{virtual_field}=")
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'ChronicDurationAttribute reader'
|
||||||
end
|
end
|
||||||
|
|
|
@ -29,7 +29,8 @@ describe Ci::RetryBuildService do
|
||||||
commit_id deployments erased_by_id last_deployment project_id
|
commit_id deployments erased_by_id last_deployment project_id
|
||||||
runner_id tag_taggings taggings tags trigger_request_id
|
runner_id tag_taggings taggings tags trigger_request_id
|
||||||
user_id auto_canceled_by_id retried failure_reason
|
user_id auto_canceled_by_id retried failure_reason
|
||||||
artifacts_file_store artifacts_metadata_store].freeze
|
artifacts_file_store artifacts_metadata_store
|
||||||
|
used_timeout timeout_source].freeze
|
||||||
|
|
||||||
shared_examples 'build duplication' do
|
shared_examples 'build duplication' do
|
||||||
let(:another_pipeline) { create(:ci_empty_pipeline, project: project) }
|
let(:another_pipeline) { create(:ci_empty_pipeline, project: project) }
|
||||||
|
|
Loading…
Reference in New Issue