Files
herolib/lib/virt/docker/docker_recipe_zinit.v
2024-12-25 20:13:02 +01:00

131 lines
3.5 KiB
V

module docker
import freeflowuniverse.herolib.core.pathlib
import freeflowuniverse.herolib.core.texttools
pub struct ZinitItem {
pub mut:
name string
exec string // e.g. redis-server --port 7777
test string // e.g. redis-cli -p 7777 PING
after []string // e.g. copy,tmuxp these are the names of the ones we are depending on
log ZinitLogType
signal string // could be 'SIGKILL' as well, if not specified then 'SIGTERM'
oneshot bool // is the command supposed to stop and only be used one, so not as daemon
}
enum ZinitLogType {
ring
stdout
null
}
@[params]
pub struct ZinitAddArgs {
pub mut:
// more info see https://github.com/threefoldtech/zinit/tree/master/docs
name string
exec string // e.g. redis-server --port 7777
test string // e.g. redis-cli -p 7777 PING
after string // e.g. 'copy,tmuxp' these are the names of the ones we are depending on, is comma separated
log ZinitLogType
signal string // could be 'SIGKILL' as well, if not specified then 'SIGTERM'
oneshot bool // is the command supposed to stop and only be used one, so not as daemon
}
// add a zinit to the docker container
// each init will launch a process in the container
// the init files are rendered as yaml files in the build directory and added to the docker at the end
// how to use zinit see: https://github.com/threefoldtech/zinit/tree/master/docs
pub fn (mut b DockerBuilderRecipe) add_zinit_cmd(args ZinitAddArgs) ! {
if args.name.len < 3 {
return error('min length of name is 3')
}
if args.exec.len < 3 {
return error('min length of val is 3')
}
// TODO: make sure after is lowercase and trimmed
mut item := ZinitItem{
name: args.name
exec: args.exec
test: args.test
log: args.log
signal: args.signal
oneshot: args.oneshot
}
mut afterargs := []string{}
if args.after.len > 0 {
for afteritem in args.after.split(',') {
afterargs << afteritem.to_lower().trim_space()
}
item.after = afterargs
}
b.items << item
mut zinitfilecontent := ''
if args.exec.contains('\n') {
// we now suppose this file is a bash file
mut content := texttools.dedent(args.exec)
if !content.trim_space().starts_with('set ') {
content = 'set -ex\n\n${content}'
}
b.write_file(
dest: '/cmds/${args.name}.sh'
content: content
make_executable: true
name: args.name + '.sh'
)!
zinitfilecontent += 'exec: /bin/bash /cmds/${args.name}.sh\n'
} else {
zinitfilecontent += 'exec: ${args.exec}\n'
}
if args.test.len > 0 {
zinitfilecontent += 'test: ${args.test}\n'
}
if args.after.len > 0 {
zinitfilecontent += 'after:\n'
for a in afterargs {
zinitfilecontent += ' - ${a}\n'
}
}
if args.signal.len > 0 {
zinitfilecontent += 'signal:\n'
zinitfilecontent += ' stop: ${args.signal.to_upper()} \n'
}
if args.log == .stdout {
zinitfilecontent += 'log: stdout\n'
} else if args.log == .ring {
zinitfilecontent += 'log: ring\n'
} else if args.log == .null {
zinitfilecontent += 'log: null\n'
} else {
panic('other log')
}
if args.oneshot {
zinitfilecontent += 'oneshot: true\n'
}
mut ff := pathlib.get_file(path: b.path() + '/zinit/${args.name}.yaml', create: true)!
ff.write(zinitfilecontent)!
}
pub fn (mut i ZinitItem) check() ! {
// nothing much we can do here I guess
}
pub fn (mut i ZinitItem) render() !string {
// nothing to render only in final step
return ''
}
// example file format
// exec: redis-server --port 7777
// test: redis-cli -p 7777 PING
// after:
// - copy
// - tmuxp