forked from vieter-v/vieter
Compare commits
No commits in common. "f7ca005ad530fd0861f63d10636521ef0b434990" and "9e11237ff940f50cda467556b977d667576e1298" have entirely different histories.
f7ca005ad5
...
9e11237ff9
|
|
@ -1,25 +0,0 @@
|
||||||
module agent
|
|
||||||
|
|
||||||
import log
|
|
||||||
import os
|
|
||||||
|
|
||||||
const log_file_name = 'vieter.agent.log'
|
|
||||||
|
|
||||||
// agent start an agent service
|
|
||||||
pub fn agent(conf Config) ! {
|
|
||||||
// Configure logger
|
|
||||||
log_level := log.level_from_tag(conf.log_level) or {
|
|
||||||
return error('Invalid log level. The allowed values are FATAL, ERROR, WARN, INFO & DEBUG.')
|
|
||||||
}
|
|
||||||
|
|
||||||
mut logger := log.Log{
|
|
||||||
level: log_level
|
|
||||||
}
|
|
||||||
|
|
||||||
log_file := os.join_path_single(conf.data_dir, agent.log_file_name)
|
|
||||||
logger.set_full_logpath(log_file)
|
|
||||||
logger.log_to_console_too()
|
|
||||||
|
|
||||||
mut d := agent_init(logger, conf)
|
|
||||||
d.run()
|
|
||||||
}
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
module agent
|
|
||||||
|
|
||||||
import cli
|
|
||||||
import conf as vconf
|
|
||||||
|
|
||||||
struct Config {
|
|
||||||
pub:
|
|
||||||
log_level string = 'WARN'
|
|
||||||
api_key string
|
|
||||||
address string
|
|
||||||
data_dir string
|
|
||||||
max_concurrent_builds int = 1
|
|
||||||
polling_frequency int = 30
|
|
||||||
// Architecture of agent
|
|
||||||
// arch string
|
|
||||||
// image_rebuild_frequency int = 1440
|
|
||||||
}
|
|
||||||
|
|
||||||
// cmd returns the cli module that handles the cron daemon.
|
|
||||||
pub fn cmd() cli.Command {
|
|
||||||
return cli.Command{
|
|
||||||
name: 'agent'
|
|
||||||
description: 'Start an agent service & start polling for new builds.'
|
|
||||||
execute: fn (cmd cli.Command) ! {
|
|
||||||
config_file := cmd.flags.get_string('config-file')!
|
|
||||||
conf := vconf.load<Config>(prefix: 'VIETER_', default_path: config_file)!
|
|
||||||
|
|
||||||
agent(conf)!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
module agent
|
|
||||||
|
|
||||||
import log
|
|
||||||
import sync.stdatomic
|
|
||||||
import build { BuildConfig }
|
|
||||||
import client
|
|
||||||
|
|
||||||
const (
|
|
||||||
build_empty = 0
|
|
||||||
build_running = 1
|
|
||||||
build_done = 2
|
|
||||||
)
|
|
||||||
|
|
||||||
struct AgentDaemon {
|
|
||||||
logger shared log.Log
|
|
||||||
conf Config
|
|
||||||
// Which builds are currently running; length is same as
|
|
||||||
// conf.max_concurrent_builds
|
|
||||||
builds []BuildConfig
|
|
||||||
// Atomic variables used to detect when a build has finished; length is the
|
|
||||||
// same as conf.max_concurrent_builds
|
|
||||||
client client.Client
|
|
||||||
atomics []u64
|
|
||||||
}
|
|
||||||
|
|
||||||
fn agent_init(logger log.Log, conf Config) AgentDaemon {
|
|
||||||
mut d := AgentDaemon{
|
|
||||||
logger: logger
|
|
||||||
client: client.new(conf.address, conf.api_key)
|
|
||||||
conf: conf
|
|
||||||
builds: []BuildConfig{len: conf.max_concurrent_builds}
|
|
||||||
atomics: []u64{len: conf.max_concurrent_builds}
|
|
||||||
}
|
|
||||||
|
|
||||||
return d
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (mut d AgentDaemon) run() {
|
|
||||||
for {
|
|
||||||
free_builds := d.update_atomics()
|
|
||||||
|
|
||||||
if free_builds > 0 {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// clean_finished_builds checks for each build whether it's completed, and sets
|
|
||||||
// it to free again if so. The return value is how many fields are now set to
|
|
||||||
// free.
|
|
||||||
fn (mut d AgentDaemon) update_atomics() int {
|
|
||||||
mut count := 0
|
|
||||||
|
|
||||||
for i in 0 .. d.atomics.len {
|
|
||||||
if stdatomic.load_u64(&d.atomics[i]) == agent.build_done {
|
|
||||||
stdatomic.store_u64(&d.atomics[i], agent.build_empty)
|
|
||||||
count++
|
|
||||||
} else if stdatomic.load_u64(&d.atomics[i]) == agent.build_empty {
|
|
||||||
count++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return count
|
|
||||||
}
|
|
||||||
|
|
@ -16,16 +16,6 @@ const (
|
||||||
'/usr/local/bin', '/usr/bin/site_perl', '/usr/bin/vendor_perl', '/usr/bin/core_perl']
|
'/usr/local/bin', '/usr/bin/site_perl', '/usr/bin/vendor_perl', '/usr/bin/core_perl']
|
||||||
)
|
)
|
||||||
|
|
||||||
pub struct BuildConfig {
|
|
||||||
pub:
|
|
||||||
id int
|
|
||||||
kind string
|
|
||||||
url string
|
|
||||||
branch string
|
|
||||||
repo string
|
|
||||||
base_image string
|
|
||||||
}
|
|
||||||
|
|
||||||
// create_build_image creates a builder image given some base image which can
|
// create_build_image creates a builder image given some base image which can
|
||||||
// then be used to build & package Arch images. It mostly just updates the
|
// then be used to build & package Arch images. It mostly just updates the
|
||||||
// system, install some necessary packages & creates a non-root user to run
|
// system, install some necessary packages & creates a non-root user to run
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ import console.schedule
|
||||||
import console.man
|
import console.man
|
||||||
import console.aur
|
import console.aur
|
||||||
import cron
|
import cron
|
||||||
import agent
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
mut app := cli.Command{
|
mut app := cli.Command{
|
||||||
|
|
@ -41,7 +40,6 @@ fn main() {
|
||||||
schedule.cmd(),
|
schedule.cmd(),
|
||||||
man.cmd(),
|
man.cmd(),
|
||||||
aur.cmd(),
|
aur.cmd(),
|
||||||
agent.cmd(),
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
app.setup()
|
app.setup()
|
||||||
|
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
module server
|
|
||||||
|
|
||||||
import web
|
|
||||||
import web.response { new_response }
|
|
||||||
// import db
|
|
||||||
import time
|
|
||||||
// import os
|
|
||||||
// import util
|
|
||||||
// import models { BuildLog, BuildLogFilter }
|
|
||||||
|
|
||||||
['/api/v1/builds/poll'; auth; get]
|
|
||||||
fn (mut app App) v1_poll_build_queue() web.Result {
|
|
||||||
arch := app.query['arch'] or {
|
|
||||||
return app.json(.bad_request, new_response('Missing arch query arg.'))
|
|
||||||
}
|
|
||||||
|
|
||||||
max_str := app.query['max'] or {
|
|
||||||
return app.json(.bad_request, new_response('Missing max query arg.'))
|
|
||||||
}
|
|
||||||
max := max_str.int()
|
|
||||||
|
|
||||||
|
|
||||||
mut out := []
|
|
||||||
|
|
||||||
now := time.now()
|
|
||||||
lock app.build_queue {
|
|
||||||
for app.build_queue.len() > 0 && out.len() < max {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -6,9 +6,6 @@ import log
|
||||||
import repo
|
import repo
|
||||||
import util
|
import util
|
||||||
import db
|
import db
|
||||||
import datatypes { MinHeap }
|
|
||||||
import build { BuildConfig }
|
|
||||||
import time
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
log_file_name = 'vieter.log'
|
log_file_name = 'vieter.log'
|
||||||
|
|
@ -17,25 +14,12 @@ const (
|
||||||
logs_dir_name = 'logs'
|
logs_dir_name = 'logs'
|
||||||
)
|
)
|
||||||
|
|
||||||
struct ScheduledBuild {
|
|
||||||
pub:
|
|
||||||
timestamp time.Time
|
|
||||||
target_id int
|
|
||||||
build_config BuildConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
// Overloaded operator for comparing ScheduledBuild objects
|
|
||||||
fn (r1 ScheduledBuild) < (r2 ScheduledBuild) bool {
|
|
||||||
return r1.timestamp < r2.timestamp
|
|
||||||
}
|
|
||||||
|
|
||||||
struct App {
|
struct App {
|
||||||
web.Context
|
web.Context
|
||||||
pub:
|
pub:
|
||||||
conf Config [required; web_global]
|
conf Config [required; web_global]
|
||||||
pub mut:
|
pub mut:
|
||||||
repo repo.RepoGroupManager [required; web_global]
|
repo repo.RepoGroupManager [required; web_global]
|
||||||
build_queue shared MinHeap<ScheduledBuild>
|
|
||||||
db db.VieterDb
|
db db.VieterDb
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -93,6 +77,5 @@ pub fn server(conf Config) ! {
|
||||||
conf: conf
|
conf: conf
|
||||||
repo: repo
|
repo: repo
|
||||||
db: db
|
db: db
|
||||||
build_queue: MinHeap<ScheduledBuild>{}
|
|
||||||
}, conf.port)
|
}, conf.port)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue