diff --git a/src/build/build.v b/src/build/build.v index c69a6132..756e8f6f 100644 --- a/src/build/build.v +++ b/src/build/build.v @@ -94,8 +94,8 @@ pub: } // build_target builds the given target. Internally it calls `build_config`. -pub fn build_target(address string, api_key string, base_image_id string, target &Target, force bool) !BuildResult { - config := target.as_build_config(base_image_id, force) +pub fn build_target(address string, api_key string, base_image_id string, target &Target, force bool, timeout int) !BuildResult { + config := target.as_build_config(base_image_id, force, timeout) return build_config(address, api_key, config) } diff --git a/src/build/queue.v b/src/build/queue.v index 73068ac4..bc4db9d7 100644 --- a/src/build/queue.v +++ b/src/build/queue.v @@ -33,6 +33,8 @@ pub struct BuildJobQueue { default_schedule &cron.Expression // Base image to use for targets without defined base image default_base_image string + // After how many minutes a build should be forcefully cancelled + default_build_timeout int mut: mutex shared util.Dummy // For each architecture, a priority queue is tracked @@ -44,10 +46,11 @@ mut: } // new_job_queue initializes a new job queue -pub fn new_job_queue(default_schedule &cron.Expression, default_base_image string) BuildJobQueue { +pub fn new_job_queue(default_schedule &cron.Expression, default_base_image string, default_build_timeout int) BuildJobQueue { return BuildJobQueue{ default_schedule: unsafe { default_schedule } default_base_image: default_base_image + default_build_timeout: default_build_timeout invalidated: map[int]time.Time{} } } @@ -80,7 +83,7 @@ pub fn (mut q BuildJobQueue) insert(input InsertConfig) ! { mut job := BuildJob{ created: time.now() single: input.single - config: input.target.as_build_config(q.default_base_image, input.force) + config: input.target.as_build_config(q.default_base_image, input.force, q.default_build_timeout) } if !input.now { diff --git a/src/console/targets/build.v b/src/console/targets/build.v index a59e6a10..93464af2 100644 --- a/src/console/targets/build.v +++ b/src/console/targets/build.v @@ -6,7 +6,7 @@ import os import build // build locally builds the target with the given id. -fn build_target(conf Config, target_id int, force bool) ! { +fn build_target(conf Config, target_id int, force bool, timeout int) ! { c := client.new(conf.address, conf.api_key) target := c.get_target(target_id)! @@ -16,7 +16,7 @@ fn build_target(conf Config, target_id int, force bool) ! { image_id := build.create_build_image(conf.base_image)! println('Running build...') - res := build.build_target(conf.address, conf.api_key, image_id, target, force)! + res := build.build_target(conf.address, conf.api_key, image_id, target, force, timeout)! println('Removing build image...') diff --git a/src/console/targets/targets.v b/src/console/targets/targets.v index 676fa0a3..80fc36b6 100644 --- a/src/console/targets/targets.v +++ b/src/console/targets/targets.v @@ -232,6 +232,12 @@ pub fn cmd() cli.Command { description: 'Architecture to schedule build for. Required when using -remote.' flag: cli.FlagType.string }, + cli.Flag{ + name: 'timeout' + description: 'After how many minutes to cancel the build. Only applies to local builds.' + flag: cli.FlagType.int + default_value: ['60'] + }, ] execute: fn (cmd cli.Command) ! { config_file := cmd.flags.get_string('config-file')! @@ -239,6 +245,7 @@ pub fn cmd() cli.Command { remote := cmd.flags.get_bool('remote')! force := cmd.flags.get_bool('force')! + timeout := cmd.flags.get_int('timeout')! target_id := cmd.args[0].int() if remote { @@ -251,7 +258,7 @@ pub fn cmd() cli.Command { c := client.new(conf_.address, conf_.api_key) c.queue_job(target_id, arch, force)! } else { - build_target(conf_, target_id, force)! + build_target(conf_, target_id, force, timeout)! } } }, diff --git a/src/models/builds.v b/src/models/builds.v index be2910ca..6923115b 100644 --- a/src/models/builds.v +++ b/src/models/builds.v @@ -10,9 +10,10 @@ pub: repo string base_image string force bool + timeout int } // str return a single-line string representation of a build log pub fn (c BuildConfig) str() string { - return '{ target: ${c.target_id}, kind: ${c.kind}, url: ${c.url}, branch: ${c.branch}, path: ${c.path}, repo: ${c.repo}, base_image: ${c.base_image}, force: ${c.force} }' + return '{ target: ${c.target_id}, kind: ${c.kind}, url: ${c.url}, branch: ${c.branch}, path: ${c.path}, repo: ${c.repo}, base_image: ${c.base_image}, force: ${c.force}, timeout: ${c.timeout} }' } diff --git a/src/models/targets.v b/src/models/targets.v index 3c0c9cf1..14cc8a62 100644 --- a/src/models/targets.v +++ b/src/models/targets.v @@ -54,7 +54,7 @@ pub fn (t &Target) str() string { // as_build_config converts a Target into a BuildConfig, given some extra // needed information. -pub fn (t &Target) as_build_config(base_image string, force bool) BuildConfig { +pub fn (t &Target) as_build_config(base_image string, force bool, timeout int) BuildConfig { return BuildConfig{ target_id: t.id kind: t.kind @@ -64,6 +64,7 @@ pub fn (t &Target) as_build_config(base_image string, force bool) BuildConfig { repo: t.repo base_image: base_image force: force + timeout: timeout } } diff --git a/src/server/cli.v b/src/server/cli.v index 08ad5f82..c24812d3 100644 --- a/src/server/cli.v +++ b/src/server/cli.v @@ -5,17 +5,18 @@ import conf as vconf struct Config { pub: - port int = 8000 - log_level string = 'WARN' - pkg_dir string - data_dir string - api_key string - default_arch string - global_schedule string = '0 3' - base_image string = 'archlinux:base-devel' - max_log_age int [empty_default] - log_removal_schedule string = '0 0' - collect_metrics bool [empty_default] + port int = 8000 + log_level string = 'WARN' + pkg_dir string + data_dir string + api_key string + default_arch string + global_schedule string = '0 3' + base_image string = 'archlinux:base-devel' + max_log_age int [empty_default] + log_removal_schedule string = '0 0' + collect_metrics bool [empty_default] + default_build_timeout int = 60 } // cmd returns the cli submodule that handles starting the server diff --git a/src/server/server.v b/src/server/server.v index 4cccb270..e1516fa8 100644 --- a/src/server/server.v +++ b/src/server/server.v @@ -108,7 +108,7 @@ pub fn server(conf Config) ! { repo: repo_ db: db collector: collector - job_queue: build.new_job_queue(global_ce, conf.base_image) + job_queue: build.new_job_queue(global_ce, conf.base_image, conf.default_build_timeout) } app.init_job_queue() or { util.exit_with_message(1, 'Failed to inialize job queue: ${err.msg()}')