feat(agent): initial working version

Jef Roosens 2022-12-12 22:58:43 +01:00 committed by Chewing_Bever
parent 6f23d690a7
commit 3611123f45
Signed by untrusted user: Jef Roosens
GPG Key ID: B75D4F293C7052DB
7 changed files with 47 additions and 24 deletions

View File

@ -5,9 +5,9 @@ import conf as vconf
struct Config {
pub:
log_level string = 'WARN'
log_level string = 'WARN'
// Architecture that the agent represents
arch string
arch string
api_key string
address string
data_dir string

View File

@ -41,6 +41,10 @@ fn agent_init(logger log.Log, conf Config) AgentDaemon {
}
pub fn (mut d AgentDaemon) run() {
// This is just so that the very first time the loop is ran, the jobs are
// always polled
mut last_poll_time := time.now().add_seconds(-d.conf.polling_frequency)
for {
free_builds := d.update_atomics()
@ -54,16 +58,37 @@ pub fn (mut d AgentDaemon) run() {
d.images.clean_old_images()
// Poll for new jobs
new_configs := d.client.poll_jobs(free_builds) or {
d.lerror('Failed to poll jobs: $err.msg()')
if time.now() >= last_poll_time.add_seconds(d.conf.polling_frequency) {
new_configs := d.client.poll_jobs(d.conf.arch, free_builds) or {
d.lerror('Failed to poll jobs: $err.msg()')
time.sleep(5 * time.second)
continue
}
last_poll_time = time.now()
// Schedule new jobs
for config in new_configs {
// TODO handle this better than to just skip the config
// Make sure a recent build base image is available for building the config
d.images.refresh_image(config.base_image) or {
d.lerror(err.msg())
continue
}
d.start_build(config)
}
time.sleep(1 * time.second)
continue
}
// Schedule new jobs
for config in new_configs {
d.start_build(config)
// Builds are running, so check again after one second
else if free_builds < d.conf.max_concurrent_builds {
time.sleep(1 * time.second)
}
// The agent is not doing anything, so we just wait until the next poll
// time
else {
time_until_next_poll := time.now() - last_poll_time
time.sleep(time_until_next_poll)
}
}
}

View File

@ -104,16 +104,16 @@ pub:
}
pub fn build_target(address string, api_key string, base_image_id string, target &Target) !BuildResult {
config := BuildConfig{
target_id: target.id
kind: target.kind
url: target.url
branch: target.branch
repo: target.repo
base_image: base_image_id
}
config := BuildConfig{
target_id: target.id
kind: target.kind
url: target.url
branch: target.branch
repo: target.repo
base_image: base_image_id
}
return build_config(address, api_key, config)
return build_config(address, api_key, config)
}
// build_target builds, packages & publishes a given Arch package based on the

View File

@ -76,7 +76,6 @@ pub fn (mut q BuildJobQueue) insert(target Target, arch string) ! {
}
}
dump(job)
q.queues[arch].insert(job)
}
}

View File

@ -1,7 +1,5 @@
module build
import models { Target }
// escape_shell_string escapes any characters that could be interpreted
// incorrectly by a shell. The resulting value should be safe to use inside an
// echo statement.

View File

@ -2,9 +2,10 @@ module client
import build { BuildConfig }
pub fn (c &Client) poll_jobs(max int) ![]BuildConfig {
pub fn (c &Client) poll_jobs(arch string, max int) ![]BuildConfig {
data := c.send_request<[]BuildConfig>(.get, '/api/v1/jobs/poll', {
'max': max.str()
'arch': arch
'max': max.str()
})!
return data.data

View File

@ -4,6 +4,7 @@ data_dir = "data"
pkg_dir = "data/pkgs"
log_level = "DEBUG"
default_arch = "x86_64"
arch = "x86_64"
address = "http://localhost:8000"
@ -11,4 +12,3 @@ global_schedule = '* *'
api_update_frequency = 2
image_rebuild_frequency = 1
max_concurrent_builds = 3