Compare commits

...

2 Commits

Author SHA1 Message Date
Jef Roosens 26796f2228
feat(server): use cron schedule for log removal instead 2022-12-19 09:49:03 +01:00
Jef Roosens 09c61143b0
docs: updated the docs 2022-12-19 09:48:56 +01:00
10 changed files with 147 additions and 37 deletions

View File

@ -0,0 +1,51 @@
# Jobs
<aside class="notice">
All routes in this section require authentication.
</aside>
## Manually schedule a job
```shell
curl \
-H 'X-Api-Key: secret' \
https://example.com/api/v1/jobs/queue?target=10&force&arch=x86_64
```
Manually schedule a job on the server.
### HTTP Request
`POST /api/v1/jobs/queue`
### Query Parameters
Parameter | Description
--------- | -----------
target | Id of target to schedule build for
arch | Architecture to build on
force | Whether it's a forced build (true if present)
## Poll for new jobs
<aside class="warning">
This endpoint is used by the agents and should not be used manually. It's just
here for completeness.
</aside>
Poll the server for new builds.
### HTTP Request
`GET /api/v1/jobs/poll`
### Query Parameters
Parameter | Description
--------- | -----------
arch | For which architecture to receive jobs
max | How many jobs to receive at most

View File

@ -11,6 +11,7 @@ includes:
- repository - repository
- targets - targets
- logs - logs
- jobs
search: true search: true

View File

@ -32,11 +32,11 @@ configuration variable required for each command.
### `vieter server` ### `vieter server`
* `port`: HTTP port to run on
* Default: `8000`
* `log_level`: log verbosity level. Value should be one of `FATAL`, `ERROR`, * `log_level`: log verbosity level. Value should be one of `FATAL`, `ERROR`,
`WARN`, `INFO` or `DEBUG`. `WARN`, `INFO` or `DEBUG`.
* Default: `WARN` * Default: `WARN`
* `log_file`: log file to write logs to.
* Default: `vieter.log` (in the current directory)
* `pkg_dir`: where Vieter should store the actual package archives. * `pkg_dir`: where Vieter should store the actual package archives.
* `data_dir`: where Vieter stores the repositories, log file & database. * `data_dir`: where Vieter stores the repositories, log file & database.
* `api_key`: the API key to use when authenticating requests. * `api_key`: the API key to use when authenticating requests.
@ -44,14 +44,27 @@ configuration variable required for each command.
* Packages with architecture `any` are always added to this architecture. * Packages with architecture `any` are always added to this architecture.
This prevents the server from being confused when an `any` package is This prevents the server from being confused when an `any` package is
published as the very first package for a repository. published as the very first package for a repository.
* Git repositories added without an `arch` value use this value instead. * Targets added without an `arch` value use this value instead.
* `port`: HTTP port to run on * `global_schedule`: build schedule for any target that does not have a
* Default: `8000` schedule defined. For information about this syntax, see
[here](/usage/builds/schedule).
* Default: `0 3` (3AM every night)
* `base_image`: Docker image to use when building a package. Any Pacman-based
distro image should work, as long as `/etc/pacman.conf` is used &
`base-devel` exists in the repositories. Make sure that the image supports
the architecture of your cron daemon.
* Default: `archlinux:base-devel` (only works on `x86_64`). If you require
`aarch64` support, consider using
[`menci/archlinuxarm:base-devel`](https://hub.docker.com/r/menci/archlinuxarm)
([GitHub](https://github.com/Menci/docker-archlinuxarm)). This is the
image used for the Vieter CI builds.
* `max_log_age`: maximum age of logs (in days). Logs older than this will get * `max_log_age`: maximum age of logs (in days). Logs older than this will get
cleaned by the log removal daemon every 24 hours. If set to a negative value, cleaned by the log removal daemon . If set to a negative value, no logs are
no logs are ever removed. The age of logs is determined by the time the build ever removed. The age of logs is determined by the time the build was
was started. started.
* Default: `-1` * Default: `-1`
* `log_removal_schedule`: cron schedule defining when to clean old logs.
* Default: `0 0` (every day at midnight)
### `vieter cron` ### `vieter cron`

View File

@ -23,15 +23,15 @@ 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 and the agent. 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 a minimal compose file to set up both the repository server & a build
cron daemon: agent:
```yaml ```yaml
version: '3' version: '3'
services: services:
server: server:
image: 'chewingbever/vieter:dev' image: 'chewingbever/vieter:0.5.0-rc.1'
restart: 'always' restart: 'always'
environment: environment:
@ -41,18 +41,19 @@ services:
- 'data:/data' - 'data:/data'
cron: cron:
image: 'chewingbever/vieter:dev' image: 'chewingbever/vieter:0.5.0-rc.1'
restart: 'always' restart: 'always'
# Required to connect to the Docker daemon
user: root user: root
command: 'vieter cron' command: 'vieter agent'
environment: environment:
- 'VIETER_API_KEY=secret' - 'VIETER_API_KEY=secret'
# MUST be public URL of Vieter repository # MUST be public URL of Vieter repository
- 'VIETER_ADDRESS=https://example.com' - 'VIETER_ADDRESS=https://example.com'
- 'VIETER_DEFAULT_ARCH=x86_64' # Architecture for which the agent builds
- 'VIETER_ARCH=x86_64'
- 'VIETER_MAX_CONCURRENT_BUILDS=2' - 'VIETER_MAX_CONCURRENT_BUILDS=2'
- 'VIETER_GLOBAL_SCHEDULE=0 3'
volumes: volumes:
- '/var/run/docker.sock:/var/run/docker.sock' - '/var/run/docker.sock:/var/run/docker.sock'
@ -63,14 +64,17 @@ volumes:
If you do not require the build system, the repository server can be used If you do not require the build system, the repository server can be used
independently as well. independently as well.
Of course, Vieter allows a lot more configuration than this. This compose file
is meant as a starting point for setting up your installation.
{{< hint info >}} {{< hint info >}}
**Note** **Note**
Builds are executed on the cron daemon's system using the host's Docker daemon. Builds are executed on the agent's system using the host's Docker daemon. An
A cron daemon on a specific architecture will only build packages for that agent for a specific `arch` will only build packages for that specific
specific architecture. Therefore, if you wish to build packages for both architecture. Therefore, if you wish to build packages for both `x86_64` &
`x86_64` & `aarch64`, you'll have to deploy two cron daemons, one on each `aarch64`, you'll have to deploy two agents, one on each architecture.
architecture. Afterwards, any Git repositories enabled for those two Afterwards, any Git repositories enabled for those two architectures will build
architectures will build on both. on both.
{{< /hint >}} {{< /hint >}}
## Binary ## Binary
@ -99,9 +103,9 @@ latest official release or `vieter-git` for the latest development release.
### AUR ### AUR
If you prefer building the packages locally (or on your own Vieter instance), If you prefer building the packages locally (or on your own Vieter instance),
there's the `[vieter](https://aur.archlinux.org/packages/vieter)` & there's the [`vieter`](https://aur.archlinux.org/packages/vieter) &
`[vieter-git](https://aur.archlinux.org/packages/vieter-git)` packages on the [`vieter-git`](https://aur.archlinux.org/packages/vieter-git) packages on the
AUR. These packages build using the `vlang-git` compiler package, so I can't AUR. These packages build using the `vlang` compiler package, so I can't
guarantee that a compiler update won't temporarily break them. guarantee that a compiler update won't temporarily break them.
## Building from source ## Building from source

View File

@ -0,0 +1,24 @@
---
weight: 20
---
# Cleanup
Vieter stores the logs of every single package build. While this is great for
debugging why builds fails, it also causes an active or long-running Vieter
instance to accumulate thousands of logs.
To combat this, a log removal daemon can be enabled that periodically removes
old build logs. By starting your server with the `max_log_age` variable (see
[Configuration](/configuration#vieter-server) for more info), a daemon will
get enabled that periodically removes logs older than this setting. By default,
this will happen every day at midnight, but this behavior can be changed using
the `log_removal_schedule` variable.
{{< hint info >}}
**Note**
The daemon will always run a removal of logs on startup. Therefore, it's
possible the daemon will be *very* active when first enabling this setting.
After the initial surge of logs to remove, it'll calm down again.
{{< /hint >}}

View File

@ -1,3 +1,7 @@
---
weight: 10
---
# Cron schedule syntax # Cron schedule syntax
The Vieter cron daemon uses a subset of the cron expression syntax to schedule The Vieter cron daemon uses a subset of the cron expression syntax to schedule

View File

@ -5,15 +5,16 @@ import conf as vconf
struct Config { struct Config {
pub: pub:
port int = 8000
log_level string = 'WARN' log_level string = 'WARN'
pkg_dir string pkg_dir string
data_dir string data_dir string
api_key string api_key string
default_arch string default_arch string
global_schedule string = '0 3' global_schedule string = '0 3'
port int = 8000
base_image string = 'archlinux:base-devel' base_image string = 'archlinux:base-devel'
max_log_age int = -1 max_log_age int = -1
log_removal_schedule string = '0 0'
} }
// cmd returns the cli submodule that handles starting the server // cmd returns the cli submodule that handles starting the server

View File

@ -3,11 +3,12 @@ module server
import time import time
import models { BuildLog } import models { BuildLog }
import os import os
import cron.expression { CronExpression }
const log_removal_frequency = 24 * time.hour const fallback_log_removal_frequency = 24 * time.hour
// log_removal_daemon removes old build logs every `log_removal_frequency`. // log_removal_daemon removes old build logs every `log_removal_frequency`.
fn (mut app App) log_removal_daemon() { fn (mut app App) log_removal_daemon(schedule CronExpression) {
mut start_time := time.Time{} mut start_time := time.Time{}
for { for {
@ -51,6 +52,12 @@ fn (mut app App) log_removal_daemon() {
app.linfo('Cleaned $counter logs ($failed failed)') app.linfo('Cleaned $counter logs ($failed failed)')
// Sleep until the next cycle // Sleep until the next cycle
time.sleep(start_time.add_days(1) - time.now()) next_time := schedule.next_from_now() or {
app.lerror("Log removal daemon couldn't calculate next time: $err.msg(); fallback to $server.fallback_log_removal_frequency")
start_time.add(server.fallback_log_removal_frequency)
}
time.sleep(next_time - time.now())
} }
} }

View File

@ -55,6 +55,10 @@ pub fn server(conf Config) ! {
util.exit_with_message(1, 'Invalid global cron expression: $err.msg()') util.exit_with_message(1, 'Invalid global cron expression: $err.msg()')
} }
log_removal_ce := expression.parse_expression(conf.log_removal_schedule) or {
util.exit_with_message(1, 'Invalid log removal cron expression: $err.msg()')
}
// Configure logger // Configure logger
log_level := log.level_from_tag(conf.log_level) or { log_level := log.level_from_tag(conf.log_level) or {
util.exit_with_message(1, 'Invalid log level. The allowed values are FATAL, ERROR, WARN, INFO & DEBUG.') util.exit_with_message(1, 'Invalid log level. The allowed values are FATAL, ERROR, WARN, INFO & DEBUG.')
@ -109,7 +113,7 @@ pub fn server(conf Config) ! {
} }
if conf.max_log_age > 0 { if conf.max_log_age > 0 {
go app.log_removal_daemon() go app.log_removal_daemon(log_removal_ce)
} }
web.run(app, conf.port) web.run(app, conf.port)

View File

@ -13,3 +13,4 @@ api_update_frequency = 2
image_rebuild_frequency = 1 image_rebuild_frequency = 1
max_concurrent_builds = 3 max_concurrent_builds = 3
max_log_age = 64 max_log_age = 64
log_removal_schedule = '*/2 *'