Compare commits

...

2 Commits

7 changed files with 72 additions and 59 deletions

View File

@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Migrated codebase to V 0.3.2 * Migrated codebase to V 0.3.2
* Cron expression parser now uses bitfields instead of bool arrays * Cron expression parser now uses bitfields instead of bool arrays
* Added option to deploy using agent-server architecture instead of cron daemon
### Fixed ### Fixed
@ -19,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* CLI no longer exits with non-zero status code when removing/patching * CLI no longer exits with non-zero status code when removing/patching
target target
* Allow NULL values for branch in database * Allow NULL values for branch in database
* Endpoint for adding targets now returns the correct id
## [0.4.0](https://git.rustybever.be/vieter-v/vieter/src/tag/0.4.0) ## [0.4.0](https://git.rustybever.be/vieter-v/vieter/src/tag/0.4.0)

View File

@ -21,7 +21,8 @@ quicker.
I chose [V](https://vlang.io/) as I've been very intrigued by this language for I chose [V](https://vlang.io/) as I've been very intrigued by this language for
a while now. I wanted a fast language that I could code while relaxing, without a while now. I wanted a fast language that I could code while relaxing, without
having to exert too much mental effort & V seemed like the right choice for having to exert too much mental effort & V seemed like the right choice for
that. that. Sadly, this didn't quite turn out the way I expected, but I'm sticking
with it anyways ;p
## Features ## Features
@ -49,7 +50,7 @@ update`.
I used to maintain a mirror that tracked the latest master, but nowadays, I I used to maintain a mirror that tracked the latest master, but nowadays, I
maintain a Docker image containing the specific compiler version that Vieter maintain a Docker image containing the specific compiler version that Vieter
builds with. Currently, this is V 0.3. builds with. Currently, this is V 0.3.2.
## Contributing ## Contributing

View File

@ -97,3 +97,25 @@ configuration variable required for each command.
build`. build`.
* Default: `archlinux:base-devel` * Default: `archlinux:base-devel`
### `vieter agent`
* `log_level`: log verbosity level. Value should be one of `FATAL`, `ERROR`,
`WARN`, `INFO` or `DEBUG`.
* Default: `WARN`
* `address`: *public* URL of the Vieter repository server to build for. From
this server jobs are retrieved. All built packages are published to this
server.
* `api_key`: API key of the above server.
* `data_dir`: directory to store log file in.
* `max_concurrent_builds`: how many builds to run at the same time.
* Default: `1`
* `polling_frequency`: how often (in seconds) to poll the server for new
builds. Note that the agent might poll more frequently when it's actively
processing builds.
* `image_rebuild_frequency`: Vieter periodically builds images that are then
used as a basis for running build containers. This is to prevent each build
from downloading an entire repository worth of dependencies. This setting
defines how frequently (in minutes) to rebuild these images.
* Default: `1440` (every 24 hours)
* `arch`: architecture for which this agent should pull down builds (e.g.
`x86_64`)

View File

@ -21,7 +21,7 @@ branch. This branch will be the most up to date, but does not give any
guarantees about stability, so beware! guarantees about stability, so beware!
Thanks to the single-binary design of Vieter, this image can be used both for Thanks to the single-binary design of Vieter, this image can be used both for
the repository server & the cron daemon. the repository server, the cron daemon and the agent.
Below is an example compose file to set up both the repository server & the Below is an example compose file to set up both the repository server & the
cron daemon: cron daemon:
@ -76,7 +76,7 @@ architectures will build on both.
## Binary ## Binary
On the On the
[releases](https://git.rustybever.be/vieter/vieter/releases) [releases](https://git.rustybever.be/vieter-v/vieter/releases)
page, you can find statically compiled binaries for all page, you can find statically compiled binaries for all
released versions. This is the same binary as used inside released versions. This is the same binary as used inside
the Docker images. the Docker images.
@ -106,5 +106,5 @@ guarantee that a compiler update won't temporarily break them.
## Building from source ## Building from source
The project [README](https://git.rustybever.be/vieter/vieter#building) contains The project [README](https://git.rustybever.be/vieter-v/vieter#building)
instructions for building Vieter from source. contains instructions for building Vieter from source.

View File

@ -37,6 +37,6 @@ Each section can consist of as many of these parts as necessary.
## CLI tool ## CLI tool
The Vieter binary contains a command that shows you the next matching times for The Vieter binary contains a command that shows you the next matching times for
a given expression. This can be useful to understand the syntax. For more a given expression. This can be useful for understanding the syntax. For more
information, see information, see
[vieter-schedule(1)](https://rustybever.be/man/vieter/vieter-schedule.1.html). [vieter-schedule(1)](https://rustybever.be/man/vieter/vieter-schedule.1.html).

View File

@ -32,7 +32,7 @@ fn agent_init(logger log.Log, conf Config) AgentDaemon {
logger: logger logger: logger
client: client.new(conf.address, conf.api_key) client: client.new(conf.address, conf.api_key)
conf: conf conf: conf
images: new_image_manager(conf.image_rebuild_frequency) images: new_image_manager(conf.image_rebuild_frequency * 60)
builds: []BuildConfig{len: conf.max_concurrent_builds} builds: []BuildConfig{len: conf.max_concurrent_builds}
atomics: []u64{len: conf.max_concurrent_builds} atomics: []u64{len: conf.max_concurrent_builds}
} }

View File

@ -110,6 +110,21 @@ fn (mut q BuildJobQueue) reschedule(job BuildJob, arch string) ! {
q.queues[arch].insert(new_job) q.queues[arch].insert(new_job)
} }
// pop_invalid pops all invalid jobs.
fn (mut q BuildJobQueue) pop_invalid(arch string) {
for {
job := q.queues[arch].peek() or { return }
if job.config.target_id in q.invalidated
&& job.created < q.invalidated[job.config.target_id] {
// This pop *should* never fail according to the source code
q.queues[arch].pop() or {}
} else {
break
}
}
}
// peek shows the first job for the given architecture that's ready to be // peek shows the first job for the given architecture that's ready to be
// executed, if present. // executed, if present.
pub fn (mut q BuildJobQueue) peek(arch string) ?BuildJob { pub fn (mut q BuildJobQueue) peek(arch string) ?BuildJob {
@ -118,20 +133,11 @@ pub fn (mut q BuildJobQueue) peek(arch string) ?BuildJob {
return none return none
} }
for { q.pop_invalid(arch)
job := q.queues[arch].peek() or { return none } job := q.queues[arch].peek()?
// Skip any invalidated jobs if job.timestamp < time.now() {
if job.config.target_id in q.invalidated return job
&& job.created < q.invalidated[job.config.target_id] {
// This pop *should* never fail according to the source code
q.queues[arch].pop() or { return none }
continue
}
if job.timestamp < time.now() {
return job
}
} }
} }
@ -146,27 +152,18 @@ pub fn (mut q BuildJobQueue) pop(arch string) ?BuildJob {
return none return none
} }
for { q.pop_invalid(arch)
mut job := q.queues[arch].peek() or { return none } mut job := q.queues[arch].peek()?
// Skip any invalidated jobs if job.timestamp < time.now() {
if job.config.target_id in q.invalidated job = q.queues[arch].pop()?
&& job.created < q.invalidated[job.config.target_id] {
// This pop *should* never fail according to the source code
q.queues[arch].pop() or { return none }
continue
}
if job.timestamp < time.now() { // TODO how do we handle this properly? Is it even possible for a
job = q.queues[arch].pop()? // cron expression to not return a next time if it's already been
// used before?
q.reschedule(job, arch) or {}
// TODO how do we handle this properly? Is it even possible for a return job
// cron expression to not return a next time if it's already been
// used before?
q.reschedule(job, arch) or {}
return job
}
} }
} }
@ -182,28 +179,19 @@ pub fn (mut q BuildJobQueue) pop_n(arch string, n int) []BuildJob {
mut out := []BuildJob{} mut out := []BuildJob{}
outer: for out.len < n { for out.len < n {
for { q.pop_invalid(arch)
mut job := q.queues[arch].peek() or { break outer } mut job := q.queues[arch].peek() or { break }
// Skip any invalidated jobs if job.timestamp < time.now() {
if job.config.target_id in q.invalidated job = q.queues[arch].pop() or { break }
&& job.created < q.invalidated[job.config.target_id] {
// This pop *should* never fail according to the source code
q.queues[arch].pop() or { break outer }
continue
}
if job.timestamp < time.now() { // TODO idem
job = q.queues[arch].pop() or { break outer } q.reschedule(job, arch) or {}
// TODO idem out << job
q.reschedule(job, arch) or {} } else {
break
out << job
} else {
break outer
}
} }
} }