This commit is contained in:
2025-08-16 17:45:04 +02:00
parent de60c5f78e
commit 5825640c2c
98 changed files with 3115 additions and 2120 deletions

View File

@@ -4,12 +4,18 @@ import freeflowuniverse.herolib.core.generator.generic as generator
import freeflowuniverse.herolib.core.pathlib
mut args := generator.GeneratorArgs{
path: '~/code/github/freeflowuniverse/herolib/lib/clients'
path: '~/code/github/freeflowuniverse/herolib/lib/installers'
force: true
}
// mut args2 := generator.GeneratorArgs{
// path: '~/code/github/freeflowuniverse/herolib/lib/installers/lang/rust'
// force: true
// }
// generator.scan(args2)!
// mut args := generator.GeneratorArgs{
// path: '~/code/github/freeflowuniverse/herolib/lib'
// path: '~/code/github/freeflowuniverse/herolib/lib/installers'
// force: true
// }

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env -S v -n -w -gc none -cc tcc -d use_openssl -enable-globals run
#!/usr/bin/env -S v -n -w -cg -gc none -cc tcc -d use_openssl -enable-globals run
import freeflowuniverse.herolib.installers.infra.zinit_installer

View File

@@ -3,12 +3,18 @@
import freeflowuniverse.herolib.installers.net.mycelium_installer
import freeflowuniverse.herolib.clients.mycelium
mut installer := mycelium_installer.get()!
mut installer := mycelium_installer.get(create:true)!
println(installer)
installer.start()!
$dbg;
mut r := mycelium.inspect()!
println(r)
$dbg;
mut client := mycelium.get()!
// Send a message to a node by public key

View File

@@ -7,7 +7,7 @@ import freeflowuniverse.herolib.core.pathlib
@if args.startupmanager
import freeflowuniverse.herolib.osal.systemd
import freeflowuniverse.herolib.osal.zinit
import freeflowuniverse.herolib.osal.startupmanager
@end
import freeflowuniverse.herolib.installers.ulist
@@ -20,11 +20,11 @@ import freeflowuniverse.herolib.installers.lang.python
import os
@if args.startupmanager
fn startupcmd () ![]zinit.ZProcessNewArgs{
fn startupcmd () ![]startupmanager.ZProcessNewArgs{
mut installer := get()!
mut res := []zinit.ZProcessNewArgs{}
mut res := []startupmanager.ZProcessNewArgs{}
//THIS IS EXAMPLE CODEAND NEEDS TO BE CHANGED
// res << zinit.ZProcessNewArgs{
// res << startupmanager.ZProcessNewArgs{
// name: '${args.name}'
// cmd: '${args.name} server'
// env: {

View File

@@ -9,19 +9,21 @@ import json
@if args.cat == .installer
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
@if args.startupmanager
import time
@end
@end
@if ! args.singleton
__global (
${args.name}_global map[string]&${args.classname}
${args.name}_default string
)
@end
/////////FACTORY
@if args.hasconfig
@@[params]
pub struct ArgsGet {
pub mut:
@@ -29,6 +31,13 @@ pub mut:
fromdb bool //will load from filesystem
create bool //default will not create if not exist
}
@else
@@[params]
pub struct ArgsGet {
pub mut:
name string = "default"
}
@end
@if args.hasconfig
pub fn new(args ArgsGet) !&${args.classname} {
@@ -47,7 +56,7 @@ pub fn get(args ArgsGet) !&${args.classname} {
if r.hexists('context:${args.name}', args.name)! {
data := r.hget('context:${args.name}', args.name)!
if data.len == 0 {
return error('${args.name} with name: ${args.name} does not exist, prob bug.')
return error('${args.classname} with name: ${args.name} does not exist, prob bug.')
}
mut obj := json.decode(${args.classname},data)!
set_in_mem(obj)!
@@ -127,19 +136,21 @@ fn set_in_mem(o ${args.classname}) ! {
${args.name}_default = o.name
}
// switch instance to be used for ${args.name}
pub fn switch(name string) {
${args.name}_default = name
}
@else
pub fn new(args ArgsGet) !&${args.classname} {
return &${args.classname}{}
}
pub fn get(args ArgsGet) !&${args.classname} {
return new(args)!
}
@end
pub fn play(mut plbook PlayBook) ! {
if ! plbook.exists(filter: '${args.name}.'){
return
}
mut install_actions := plbook.find(filter: '${args.name}.configure')!
if install_actions.len > 0 {
@if args.hasconfig
@@ -149,7 +160,7 @@ pub fn play(mut plbook PlayBook) ! {
set(obj2)!
}
@else
panic("can't configure ??{${args.name}_obj}, because no config in this class.")
return error("can't configure ${args.name}, because no configuration allowed for this installer.")
@end
}
@if args.cat == .installer
@@ -200,23 +211,27 @@ pub fn play(mut plbook PlayBook) ! {
////////////////////////////////////////////////////////////////////////////////////////////////////
@if args.startupmanager
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
fn startupmanager_get(cat startupmanager.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
// systemd
match cat{
.screen {
console.print_debug("startupmanager: zinit")
return startupmanager.get(.screen)!
}
.zinit{
console.print_debug("startupmanager: zinit")
return startupmanager.get(cat:.zinit)!
return startupmanager.get(.zinit)!
}
.systemd{
console.print_debug("startupmanager: systemd")
return startupmanager.get(cat:.systemd)!
return startupmanager.get(.systemd)!
}else{
console.print_debug("startupmanager: auto")
return startupmanager.get()!
return startupmanager.get(.auto)!
}
}
}
@@ -225,14 +240,18 @@ fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManag
@if args.hasconfig
//load from disk and make sure is properly intialized
pub fn (mut self ${args.classname}) reload() ! {
@if ! args.singleton
switch(self.name)
@end
self=obj_init(self)!
}
@end
@if args.startupmanager
pub fn (mut self ${args.classname}) start() ! {
@if ! args.singleton
switch(self.name)
@end
if self.running()!{
return
}
@@ -296,10 +315,12 @@ pub fn (mut self ${args.classname}) running() !bool {
//walk over the generic processes, if not running return
for zprocess in startupcmd()!{
mut sm:=startupmanager_get(zprocess.startuptype)!
r:=sm.running(zprocess.name)!
if r==false{
return false
if zprocess.startuptype != .screen{
mut sm:=startupmanager_get(zprocess.startuptype)!
r:=sm.running(zprocess.name)!
if r==false{
return false
}
}
}
return running()!
@@ -337,3 +358,9 @@ pub fn (mut self ${args.classname}) destroy() ! {
@end
// switch instance to be used for ${args.name}
pub fn switch(name string) {
@if ! args.singleton
${args.name}_default = name
@end
}

View File

@@ -56,7 +56,10 @@ pub fn get_dir(args_ GetArgs) !Path {
p2.absolute()
if p2.exist == .no {
if args.create {
os.mkdir_all(p2.absolute()) or { return error('cannot create path ${p2}, ${err}') } // Make sure that all the needed paths created
os.mkdir_all(p2.absolute()) or {
print_backtrace()
return error('cannot create path ${p2}, ${err}')
} // Make sure that all the needed paths created
p2.check()
}
return p2
@@ -97,7 +100,10 @@ pub fn get_file(args_ GetArgs) !Path {
mut parent_ := p2.parent()!
parent_.check()
if parent_.exist == .no {
os.mkdir_all(parent_.path) or { return error('cannot create path:${args.path}') }
os.mkdir_all(parent_.path) or {
print_backtrace()
return error('cannot create path:${args.path}')
}
}
if p2.exist == .no || args.empty {
os.write_file(args.path, '') or {

View File

@@ -90,7 +90,7 @@ pub fn start(args RedisInstallArgs) ! {
// osal.exec(cmd:"redis-server ${configfilepath()} --daemonize yes")!
// }
} else {
mut sm := startupmanager.get()!
mut sm := startupmanager.get(.auto)!
sm.new(name: 'redis', cmd: 'redis-server ${configfilepath()}', start: true)!
}

View File

@@ -5,18 +5,18 @@ import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.core.texttools
import freeflowuniverse.herolib.core.pathlib
import freeflowuniverse.herolib.osal.systemd
import freeflowuniverse.herolib.osal.zinit
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.installers.ulist
import freeflowuniverse.herolib.installers.lang.golang
import freeflowuniverse.herolib.installers.lang.rust
import freeflowuniverse.herolib.installers.lang.python
import os
fn startupcmd() ![]zinit.ZProcessNewArgs {
fn startupcmd() ![]startupmanager.ZProcessNewArgs {
mut installer := get()!
mut res := []zinit.ZProcessNewArgs{}
mut res := []startupmanager.ZProcessNewArgs{}
// THIS IS EXAMPLE CODEAND NEEDS TO BE CHANGED
// res << zinit.ZProcessNewArgs{
// res << startupmanager.ZProcessNewArgs{
// name: 'cometbft'
// cmd: 'cometbft server'
// env: {

View File

@@ -3,8 +3,8 @@ module cometbft
import freeflowuniverse.herolib.core.base
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time
__global (
@@ -17,61 +17,97 @@ __global (
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
fromdb bool // will load from filesystem
create bool // default will not create if not exist
}
fn args_get(args_ ArgsGet) ArgsGet {
mut args := args_
if args.name == '' {
args.name = 'default'
}
return args
}
pub fn get(args_ ArgsGet) !&CometBFT {
mut context := base.context()!
mut args := args_get(args_)
pub fn new(args ArgsGet) !&CometBFT {
mut obj := CometBFT{
name: args.name
}
if args.name !in cometbft_global {
if !exists(args)! {
set(obj)!
set(obj)!
return &obj
}
pub fn get(args ArgsGet) !&CometBFT {
mut context := base.context()!
cometbft_default = args.name
if args.fromdb || args.name !in cometbft_global {
mut r := context.redis()!
if r.hexists('context:cometbft', args.name)! {
data := r.hget('context:cometbft', args.name)!
if data.len == 0 {
return error('CometBFT with name: cometbft does not exist, prob bug.')
}
mut obj := json.decode(CometBFT, data)!
set_in_mem(obj)!
} else {
heroscript := context.hero_config_get('cometbft', args.name)!
mut obj_ := heroscript_loads(heroscript)!
set_in_mem(obj_)!
if args.create {
new(args)!
} else {
return error("CometBFT with name 'cometbft' does not exist")
}
}
return get(name: args.name)! // no longer from db nor create
}
return cometbft_global[args.name] or {
println(cometbft_global)
// bug if we get here because should be in globals
panic('could not get config for cometbft with name, is bug:${args.name}')
return error('could not get config for cometbft with name:cometbft')
}
}
// register the config for the future
pub fn set(o CometBFT) ! {
set_in_mem(o)!
cometbft_default = o.name
mut context := base.context()!
heroscript := heroscript_dumps(o)!
context.hero_config_set('cometbft', o.name, heroscript)!
mut r := context.redis()!
r.hset('context:cometbft', o.name, json.encode(o))!
}
// does the config exists?
pub fn exists(args_ ArgsGet) !bool {
pub fn exists(args ArgsGet) !bool {
mut context := base.context()!
mut args := args_get(args_)
return context.hero_config_exists('cometbft', args.name)
mut r := context.redis()!
return r.hexists('context:cometbft', args.name)!
}
pub fn delete(args_ ArgsGet) ! {
mut args := args_get(args_)
pub fn delete(args ArgsGet) ! {
mut context := base.context()!
context.hero_config_delete('cometbft', args.name)!
if args.name in cometbft_global {
// del cometbft_global[args.name]
mut r := context.redis()!
r.hdel('context:cometbft', args.name)!
}
@[params]
pub struct ArgsList {
pub mut:
fromdb bool // will load from filesystem
}
// if fromdb set: load from filesystem, and not from mem, will also reset what is in mem
pub fn list(args ArgsList) ![]&CometBFT {
mut res := []&CometBFT{}
mut context := base.context()!
if args.fromdb {
// reset what is in mem
cometbft_global = map[string]&CometBFT{}
cometbft_default = ''
}
if args.fromdb {
mut r := context.redis()!
mut l := r.hkeys('context:cometbft')!
for name in l {
res << get(name: name, fromdb: true)!
}
return res
} else {
// load from memory
for _, client in cometbft_global {
res << client
}
}
return res
}
// only sets in mem, does not set as config
@@ -82,6 +118,9 @@ fn set_in_mem(o CometBFT) ! {
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'cometbft.') {
return
}
mut install_actions := plbook.find(filter: 'cometbft.configure')!
if install_actions.len > 0 {
for install_action in install_actions {
@@ -90,7 +129,6 @@ pub fn play(mut plbook PlayBook) ! {
set(obj2)!
}
}
mut other_actions := plbook.find(filter: 'cometbft.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -131,24 +169,28 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
fn startupmanager_get(cat startupmanager.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.screen {
console.print_debug('startupmanager: zinit')
return startupmanager.get(.screen)!
}
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
return startupmanager.get(.zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
return startupmanager.get(.systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
return startupmanager.get(.auto)!
}
}
}
@@ -223,10 +265,12 @@ pub fn (mut self CometBFT) running() !bool {
// walk over the generic processes, if not running return
for zprocess in startupcmd()! {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
if zprocess.startuptype != .screen {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
}
}
}
return running()!
@@ -260,10 +304,3 @@ pub fn (mut self CometBFT) destroy() ! {
pub fn switch(name string) {
cometbft_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -2,7 +2,7 @@ module meilisearch_installer
import freeflowuniverse.herolib.osal.core as osal
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.osal.zinit
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.installers.ulist
import freeflowuniverse.herolib.core.httpconnection
import freeflowuniverse.herolib.core.texttools
@@ -22,14 +22,15 @@ fn generate_master_key(length int) !string {
return key.string()
}
fn startupcmd() ![]zinit.ZProcessNewArgs {
mut res := []zinit.ZProcessNewArgs{}
fn startupcmd() ![]startupmanager.ZProcessNewArgs {
mut res := []startupmanager.ZProcessNewArgs{}
mut installer := get()!
mut env := 'development'
if installer.production {
env = 'production'
}
res << zinit.ZProcessNewArgs{
res << startupmanager.ZProcessNewArgs
{
name: 'meilisearch'
cmd: 'meilisearch --no-analytics --http-addr ${installer.host}:${installer.port} --env ${env} --db-path ${installer.path} --master-key ${installer.masterkey}'
startuptype: .zinit

View File

@@ -3,8 +3,8 @@ module meilisearch_installer
import freeflowuniverse.herolib.core.base
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time
__global (
@@ -17,61 +17,97 @@ __global (
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
fromdb bool // will load from filesystem
create bool // default will not create if not exist
}
fn args_get(args_ ArgsGet) ArgsGet {
mut args := args_
if args.name == '' {
args.name = 'default'
}
return args
}
pub fn get(args_ ArgsGet) !&MeilisearchInstaller {
mut context := base.context()!
mut args := args_get(args_)
pub fn new(args ArgsGet) !&MeilisearchInstaller {
mut obj := MeilisearchInstaller{
name: args.name
}
if args.name !in meilisearch_installer_global {
if !exists(args)! {
set(obj)!
set(obj)!
return &obj
}
pub fn get(args ArgsGet) !&MeilisearchInstaller {
mut context := base.context()!
meilisearch_installer_default = args.name
if args.fromdb || args.name !in meilisearch_installer_global {
mut r := context.redis()!
if r.hexists('context:meilisearch_installer', args.name)! {
data := r.hget('context:meilisearch_installer', args.name)!
if data.len == 0 {
return error('MeilisearchInstaller with name: meilisearch_installer does not exist, prob bug.')
}
mut obj := json.decode(MeilisearchInstaller, data)!
set_in_mem(obj)!
} else {
heroscript := context.hero_config_get('meilisearch_installer', args.name)!
mut obj_ := heroscript_loads(heroscript)!
set_in_mem(obj_)!
if args.create {
new(args)!
} else {
return error("MeilisearchInstaller with name 'meilisearch_installer' does not exist")
}
}
return get(name: args.name)! // no longer from db nor create
}
return meilisearch_installer_global[args.name] or {
println(meilisearch_installer_global)
// bug if we get here because should be in globals
panic('could not get config for meilisearch_installer with name, is bug:${args.name}')
return error('could not get config for meilisearch_installer with name:meilisearch_installer')
}
}
// register the config for the future
pub fn set(o MeilisearchInstaller) ! {
set_in_mem(o)!
meilisearch_installer_default = o.name
mut context := base.context()!
heroscript := heroscript_dumps(o)!
context.hero_config_set('meilisearch_installer', o.name, heroscript)!
mut r := context.redis()!
r.hset('context:meilisearch_installer', o.name, json.encode(o))!
}
// does the config exists?
pub fn exists(args_ ArgsGet) !bool {
pub fn exists(args ArgsGet) !bool {
mut context := base.context()!
mut args := args_get(args_)
return context.hero_config_exists('meilisearch_installer', args.name)
mut r := context.redis()!
return r.hexists('context:meilisearch_installer', args.name)!
}
pub fn delete(args_ ArgsGet) ! {
mut args := args_get(args_)
pub fn delete(args ArgsGet) ! {
mut context := base.context()!
context.hero_config_delete('meilisearch_installer', args.name)!
if args.name in meilisearch_installer_global {
// del meilisearch_installer_global[args.name]
mut r := context.redis()!
r.hdel('context:meilisearch_installer', args.name)!
}
@[params]
pub struct ArgsList {
pub mut:
fromdb bool // will load from filesystem
}
// if fromdb set: load from filesystem, and not from mem, will also reset what is in mem
pub fn list(args ArgsList) ![]&MeilisearchInstaller {
mut res := []&MeilisearchInstaller{}
mut context := base.context()!
if args.fromdb {
// reset what is in mem
meilisearch_installer_global = map[string]&MeilisearchInstaller{}
meilisearch_installer_default = ''
}
if args.fromdb {
mut r := context.redis()!
mut l := r.hkeys('context:meilisearch_installer')!
for name in l {
res << get(name: name, fromdb: true)!
}
return res
} else {
// load from memory
for _, client in meilisearch_installer_global {
res << client
}
}
return res
}
// only sets in mem, does not set as config
@@ -82,6 +118,9 @@ fn set_in_mem(o MeilisearchInstaller) ! {
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'meilisearch_installer.') {
return
}
mut install_actions := plbook.find(filter: 'meilisearch_installer.configure')!
if install_actions.len > 0 {
for install_action in install_actions {
@@ -90,7 +129,6 @@ pub fn play(mut plbook PlayBook) ! {
set(obj2)!
}
}
mut other_actions := plbook.find(filter: 'meilisearch_installer.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -131,24 +169,28 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
fn startupmanager_get(cat startupmanager.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.screen {
console.print_debug('startupmanager: zinit')
return startupmanager.get(.screen)!
}
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
return startupmanager.get(.zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
return startupmanager.get(.systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
return startupmanager.get(.auto)!
}
}
}
@@ -223,10 +265,12 @@ pub fn (mut self MeilisearchInstaller) running() !bool {
// walk over the generic processes, if not running return
for zprocess in startupcmd()! {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
if zprocess.startuptype != .screen {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
}
}
}
return running()!
@@ -260,10 +304,3 @@ pub fn (mut self MeilisearchInstaller) destroy() ! {
pub fn switch(name string) {
meilisearch_installer_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -3,23 +3,25 @@ module postgresql
import freeflowuniverse.herolib.osal.core as osal
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.installers.virt.podman as podman_installer
import freeflowuniverse.herolib.osal.zinit
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.installers.ulist
import os
fn startupcmd() ![]zinit.ZProcessNewArgs {
fn startupcmd() ![]startupmanager.ZProcessNewArgs {
mut cfg := get()!
mut res := []zinit.ZProcessNewArgs{}
mut res := []startupmanager.ZProcessNewArgs{}
cmd := "
mkdir -p ${cfg.volume_path}
podman run --name ${cfg.container_name} -e POSTGRES_USER=${cfg.user} -e POSTGRES_PASSWORD=\"${cfg.password}\" -v ${cfg.volume_path}:/var/lib/postgresql/data -p ${cfg.port}:5432 --health-cmd=\"pg_isready -U ${cfg.user}\" postgres:latest
"
res << zinit.ZProcessNewArgs{
res << startupmanager.ZProcessNewArgs
{
name: 'postgresql'
cmd: cmd
startuptype: .zinit
}
return res
}

View File

@@ -3,75 +3,106 @@ module postgresql
import freeflowuniverse.herolib.core.base
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time
__global (
postgresql_global map[string]&Postgresql
postgresql_default string
)
/////////FACTORY
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
fromdb bool // will load from filesystem
create bool // default will not create if not exist
}
fn args_get(args_ ArgsGet) ArgsGet {
mut args := args_
if args.name == '' {
args.name = 'default'
}
return args
}
pub fn get(args_ ArgsGet) !&Postgresql {
mut context := base.context()!
mut args := args_get(args_)
pub fn new(args ArgsGet) !&Postgresql {
mut obj := Postgresql{
name: args.name
}
if args.name !in postgresql_global {
if !exists(args)! {
set(obj)!
set(obj)!
return &obj
}
pub fn get(args ArgsGet) !&Postgresql {
mut context := base.context()!
postgresql_default = args.name
if args.fromdb || args.name !in postgresql_global {
mut r := context.redis()!
if r.hexists('context:postgresql', args.name)! {
data := r.hget('context:postgresql', args.name)!
if data.len == 0 {
return error('Postgresql with name: postgresql does not exist, prob bug.')
}
mut obj := json.decode(Postgresql, data)!
set_in_mem(obj)!
} else {
heroscript := context.hero_config_get('postgresql', args.name)!
mut obj_ := heroscript_loads(heroscript)!
set_in_mem(obj_)!
if args.create {
new(args)!
} else {
return error("Postgresql with name 'postgresql' does not exist")
}
}
return get(name: args.name)! // no longer from db nor create
}
return postgresql_global[args.name] or {
println(postgresql_global)
// bug if we get here because should be in globals
panic('could not get config for postgresql with name, is bug:${args.name}')
return error('could not get config for postgresql with name:postgresql')
}
}
// register the config for the future
pub fn set(o Postgresql) ! {
set_in_mem(o)!
postgresql_default = o.name
mut context := base.context()!
heroscript := heroscript_dumps(o)!
context.hero_config_set('postgresql', o.name, heroscript)!
mut r := context.redis()!
r.hset('context:postgresql', o.name, json.encode(o))!
}
// does the config exists?
pub fn exists(args_ ArgsGet) !bool {
pub fn exists(args ArgsGet) !bool {
mut context := base.context()!
mut args := args_get(args_)
return context.hero_config_exists('postgresql', args.name)
mut r := context.redis()!
return r.hexists('context:postgresql', args.name)!
}
pub fn delete(args_ ArgsGet) ! {
mut args := args_get(args_)
pub fn delete(args ArgsGet) ! {
mut context := base.context()!
context.hero_config_delete('postgresql', args.name)!
if args.name in postgresql_global {
// del postgresql_global[args.name]
mut r := context.redis()!
r.hdel('context:postgresql', args.name)!
}
@[params]
pub struct ArgsList {
pub mut:
fromdb bool // will load from filesystem
}
// if fromdb set: load from filesystem, and not from mem, will also reset what is in mem
pub fn list(args ArgsList) ![]&Postgresql {
mut res := []&Postgresql{}
mut context := base.context()!
if args.fromdb {
// reset what is in mem
postgresql_global = map[string]&Postgresql{}
postgresql_default = ''
}
if args.fromdb {
mut r := context.redis()!
mut l := r.hkeys('context:postgresql')!
for name in l {
res << get(name: name, fromdb: true)!
}
return res
} else {
// load from memory
for _, client in postgresql_global {
res << client
}
}
return res
}
// only sets in mem, does not set as config
@@ -82,6 +113,9 @@ fn set_in_mem(o Postgresql) ! {
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'postgresql.') {
return
}
mut install_actions := plbook.find(filter: 'postgresql.configure')!
if install_actions.len > 0 {
for install_action in install_actions {
@@ -90,7 +124,6 @@ pub fn play(mut plbook PlayBook) ! {
set(obj2)!
}
}
mut other_actions := plbook.find(filter: 'postgresql.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -131,36 +164,38 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
fn startupmanager_get(cat startupmanager.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.screen {
console.print_debug('startupmanager: zinit')
return startupmanager.get(.screen)!
}
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
return startupmanager.get(.zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
return startupmanager.get(.systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
return startupmanager.get(.auto)!
}
}
}
// load from disk and make sure is properly intialized
pub fn (mut self Postgresql) reload() ! {
switch(self.name)
self = obj_init(self)!
}
pub fn (mut self Postgresql) start() ! {
switch(self.name)
if self.running()! {
return
}
@@ -223,10 +258,12 @@ pub fn (mut self Postgresql) running() !bool {
// walk over the generic processes, if not running return
for zprocess in startupcmd()! {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
if zprocess.startuptype != .screen {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
}
}
}
return running()!
@@ -253,12 +290,4 @@ pub fn (mut self Postgresql) destroy() ! {
// switch instance to be used for postgresql
pub fn switch(name string) {
postgresql_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -1,17 +1,19 @@
module qdrant_installer
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.osal.zinit
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.installers.ulist
import os
fn startupcmd() ![]zinit.ZProcessNewArgs {
mut res := []zinit.ZProcessNewArgs{}
res << zinit.ZProcessNewArgs{
fn startupcmd() ![]startupmanager.ZProcessNewArgs {
mut res := []startupmanager.ZProcessNewArgs{}
res << startupmanager.ZProcessNewArgs
{
name: 'qdrant'
cmd: 'sleep 5 && qdrant --config-path ${os.home_dir()}/hero/var/qdrant/config.yaml'
startuptype: .zinit
}
return res
}

View File

@@ -3,8 +3,8 @@ module qdrant_installer
import freeflowuniverse.herolib.core.base
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time
__global (
@@ -17,61 +17,97 @@ __global (
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
fromdb bool // will load from filesystem
create bool // default will not create if not exist
}
fn args_get(args_ ArgsGet) ArgsGet {
mut args := args_
if args.name == '' {
args.name = 'default'
}
return args
}
pub fn get(args_ ArgsGet) !&QDrant {
mut context := base.context()!
mut args := args_get(args_)
pub fn new(args ArgsGet) !&QDrant {
mut obj := QDrant{
name: args.name
}
if args.name !in qdrant_installer_global {
if !exists(args)! {
set(obj)!
set(obj)!
return &obj
}
pub fn get(args ArgsGet) !&QDrant {
mut context := base.context()!
qdrant_installer_default = args.name
if args.fromdb || args.name !in qdrant_installer_global {
mut r := context.redis()!
if r.hexists('context:qdrant_installer', args.name)! {
data := r.hget('context:qdrant_installer', args.name)!
if data.len == 0 {
return error('QDrant with name: qdrant_installer does not exist, prob bug.')
}
mut obj := json.decode(QDrant, data)!
set_in_mem(obj)!
} else {
heroscript := context.hero_config_get('qdrant_installer', args.name)!
mut obj_ := heroscript_loads(heroscript)!
set_in_mem(obj_)!
if args.create {
new(args)!
} else {
return error("QDrant with name 'qdrant_installer' does not exist")
}
}
return get(name: args.name)! // no longer from db nor create
}
return qdrant_installer_global[args.name] or {
println(qdrant_installer_global)
// bug if we get here because should be in globals
panic('could not get config for qdrant_installer with name, is bug:${args.name}')
return error('could not get config for qdrant_installer with name:qdrant_installer')
}
}
// register the config for the future
pub fn set(o QDrant) ! {
set_in_mem(o)!
qdrant_installer_default = o.name
mut context := base.context()!
heroscript := heroscript_dumps(o)!
context.hero_config_set('qdrant_installer', o.name, heroscript)!
mut r := context.redis()!
r.hset('context:qdrant_installer', o.name, json.encode(o))!
}
// does the config exists?
pub fn exists(args_ ArgsGet) !bool {
pub fn exists(args ArgsGet) !bool {
mut context := base.context()!
mut args := args_get(args_)
return context.hero_config_exists('qdrant_installer', args.name)
mut r := context.redis()!
return r.hexists('context:qdrant_installer', args.name)!
}
pub fn delete(args_ ArgsGet) ! {
mut args := args_get(args_)
pub fn delete(args ArgsGet) ! {
mut context := base.context()!
context.hero_config_delete('qdrant_installer', args.name)!
if args.name in qdrant_installer_global {
// del qdrant_installer_global[args.name]
mut r := context.redis()!
r.hdel('context:qdrant_installer', args.name)!
}
@[params]
pub struct ArgsList {
pub mut:
fromdb bool // will load from filesystem
}
// if fromdb set: load from filesystem, and not from mem, will also reset what is in mem
pub fn list(args ArgsList) ![]&QDrant {
mut res := []&QDrant{}
mut context := base.context()!
if args.fromdb {
// reset what is in mem
qdrant_installer_global = map[string]&QDrant{}
qdrant_installer_default = ''
}
if args.fromdb {
mut r := context.redis()!
mut l := r.hkeys('context:qdrant_installer')!
for name in l {
res << get(name: name, fromdb: true)!
}
return res
} else {
// load from memory
for _, client in qdrant_installer_global {
res << client
}
}
return res
}
// only sets in mem, does not set as config
@@ -82,6 +118,9 @@ fn set_in_mem(o QDrant) ! {
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'qdrant_installer.') {
return
}
mut install_actions := plbook.find(filter: 'qdrant_installer.configure')!
if install_actions.len > 0 {
for install_action in install_actions {
@@ -90,7 +129,6 @@ pub fn play(mut plbook PlayBook) ! {
set(obj2)!
}
}
mut other_actions := plbook.find(filter: 'qdrant_installer.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -131,24 +169,28 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
fn startupmanager_get(cat startupmanager.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.screen {
console.print_debug('startupmanager: zinit')
return startupmanager.get(.screen)!
}
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
return startupmanager.get(.zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
return startupmanager.get(.systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
return startupmanager.get(.auto)!
}
}
}
@@ -223,10 +265,12 @@ pub fn (mut self QDrant) running() !bool {
// walk over the generic processes, if not running return
for zprocess in startupcmd()! {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
if zprocess.startuptype != .screen {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
}
}
}
return running()!
@@ -260,10 +304,3 @@ pub fn (mut self QDrant) destroy() ! {
pub fn switch(name string) {
qdrant_installer_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -3,7 +3,7 @@ module zerodb
import freeflowuniverse.herolib.osal.core as osal
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.core
import freeflowuniverse.herolib.osal.zinit
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.installers.ulist
import freeflowuniverse.herolib.develop.gittools
import freeflowuniverse.herolib.installers.base
@@ -14,19 +14,21 @@ import rand
import os
import time
fn startupcmd() ![]zinit.ZProcessNewArgs {
fn startupcmd() ![]startupmanager.ZProcessNewArgs {
mut cfg := get()!
mut cmd := 'zdb --socket ${os.home_dir()}/var/zdb.sock --port ${cfg.port} --admin ${cfg.secret} --data ${cfg.datadir} --index ${cfg.indexdir} --dualnet --protect --rotate ${cfg.rotateperiod}'
if cfg.sequential {
cmd += ' --mode seq'
}
mut res := []zinit.ZProcessNewArgs{}
res << zinit.ZProcessNewArgs{
mut res := []startupmanager.ZProcessNewArgs{}
res << startupmanager.ZProcessNewArgs
{
name: 'zdb'
cmd: cmd
startuptype: .zinit
}
return res
}

View File

@@ -3,75 +3,106 @@ module zerodb
import freeflowuniverse.herolib.core.base
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time
__global (
zerodb_global map[string]&ZeroDB
zerodb_default string
)
/////////FACTORY
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
fromdb bool // will load from filesystem
create bool // default will not create if not exist
}
fn args_get(args_ ArgsGet) ArgsGet {
mut args := args_
if args.name == '' {
args.name = 'default'
}
return args
}
pub fn get(args_ ArgsGet) !&ZeroDB {
mut context := base.context()!
mut args := args_get(args_)
pub fn new(args ArgsGet) !&ZeroDB {
mut obj := ZeroDB{
name: args.name
}
if args.name !in zerodb_global {
if !exists(args)! {
set(obj)!
set(obj)!
return &obj
}
pub fn get(args ArgsGet) !&ZeroDB {
mut context := base.context()!
zerodb_default = args.name
if args.fromdb || args.name !in zerodb_global {
mut r := context.redis()!
if r.hexists('context:zerodb', args.name)! {
data := r.hget('context:zerodb', args.name)!
if data.len == 0 {
return error('ZeroDB with name: zerodb does not exist, prob bug.')
}
mut obj := json.decode(ZeroDB, data)!
set_in_mem(obj)!
} else {
heroscript := context.hero_config_get('zerodb', args.name)!
mut obj_ := heroscript_loads(heroscript)!
set_in_mem(obj_)!
if args.create {
new(args)!
} else {
return error("ZeroDB with name 'zerodb' does not exist")
}
}
return get(name: args.name)! // no longer from db nor create
}
return zerodb_global[args.name] or {
println(zerodb_global)
// bug if we get here because should be in globals
panic('could not get config for zerodb with name, is bug:${args.name}')
return error('could not get config for zerodb with name:zerodb')
}
}
// register the config for the future
pub fn set(o ZeroDB) ! {
set_in_mem(o)!
zerodb_default = o.name
mut context := base.context()!
heroscript := heroscript_dumps(o)!
context.hero_config_set('zerodb', o.name, heroscript)!
mut r := context.redis()!
r.hset('context:zerodb', o.name, json.encode(o))!
}
// does the config exists?
pub fn exists(args_ ArgsGet) !bool {
pub fn exists(args ArgsGet) !bool {
mut context := base.context()!
mut args := args_get(args_)
return context.hero_config_exists('zerodb', args.name)
mut r := context.redis()!
return r.hexists('context:zerodb', args.name)!
}
pub fn delete(args_ ArgsGet) ! {
mut args := args_get(args_)
pub fn delete(args ArgsGet) ! {
mut context := base.context()!
context.hero_config_delete('zerodb', args.name)!
if args.name in zerodb_global {
// del zerodb_global[args.name]
mut r := context.redis()!
r.hdel('context:zerodb', args.name)!
}
@[params]
pub struct ArgsList {
pub mut:
fromdb bool // will load from filesystem
}
// if fromdb set: load from filesystem, and not from mem, will also reset what is in mem
pub fn list(args ArgsList) ![]&ZeroDB {
mut res := []&ZeroDB{}
mut context := base.context()!
if args.fromdb {
// reset what is in mem
zerodb_global = map[string]&ZeroDB{}
zerodb_default = ''
}
if args.fromdb {
mut r := context.redis()!
mut l := r.hkeys('context:zerodb')!
for name in l {
res << get(name: name, fromdb: true)!
}
return res
} else {
// load from memory
for _, client in zerodb_global {
res << client
}
}
return res
}
// only sets in mem, does not set as config
@@ -82,6 +113,9 @@ fn set_in_mem(o ZeroDB) ! {
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'zerodb.') {
return
}
mut install_actions := plbook.find(filter: 'zerodb.configure')!
if install_actions.len > 0 {
for install_action in install_actions {
@@ -90,7 +124,6 @@ pub fn play(mut plbook PlayBook) ! {
set(obj2)!
}
}
mut other_actions := plbook.find(filter: 'zerodb.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -131,36 +164,38 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
fn startupmanager_get(cat startupmanager.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.screen {
console.print_debug('startupmanager: zinit')
return startupmanager.get(.screen)!
}
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
return startupmanager.get(.zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
return startupmanager.get(.systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
return startupmanager.get(.auto)!
}
}
}
// load from disk and make sure is properly intialized
pub fn (mut self ZeroDB) reload() ! {
switch(self.name)
self = obj_init(self)!
}
pub fn (mut self ZeroDB) start() ! {
switch(self.name)
if self.running()! {
return
}
@@ -223,10 +258,12 @@ pub fn (mut self ZeroDB) running() !bool {
// walk over the generic processes, if not running return
for zprocess in startupcmd()! {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
if zprocess.startuptype != .screen {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
}
}
}
return running()!
@@ -258,12 +295,4 @@ pub fn (mut self ZeroDB) destroy() ! {
// switch instance to be used for zerodb
pub fn switch(name string) {
zerodb_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -5,18 +5,18 @@ import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.core.texttools
import freeflowuniverse.herolib.core.pathlib
import freeflowuniverse.herolib.osal.systemd
import freeflowuniverse.herolib.osal.zinit
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.installers.ulist
import freeflowuniverse.herolib.installers.lang.golang
import freeflowuniverse.herolib.installers.lang.rust
import freeflowuniverse.herolib.installers.lang.python
import os
fn startupcmd() ![]zinit.ZProcessNewArgs {
fn startupcmd() ![]startupmanager.ZProcessNewArgs {
mut installer := get()!
mut res := []zinit.ZProcessNewArgs{}
mut res := []startupmanager.ZProcessNewArgs{}
// THIS IS EXAMPLE CODEAND NEEDS TO BE CHANGED
// res << zinit.ZProcessNewArgs{
// res << startupmanager.ZProcessNewArgs{
// name: 'zerofs'
// cmd: 'zerofs server'
// env: {

View File

@@ -2,28 +2,34 @@ module zerofs
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time
__global (
zerofs_global map[string]&ZeroFS
zerofs_default string
)
/////////FACTORY
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
}
pub fn get(args_ ArgsGet) !&ZeroFS {
pub fn new(args ArgsGet) !&ZeroFS {
return &ZeroFS{}
}
pub fn get(args ArgsGet) !&ZeroFS {
return new(args)!
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'zerofs.') {
return
}
mut install_actions := plbook.find(filter: 'zerofs.configure')!
if install_actions.len > 0 {
return error("can't configure zerofs, because no configuration allowed for this installer.")
}
mut other_actions := plbook.find(filter: 'zerofs.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -64,30 +70,33 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
fn startupmanager_get(cat startupmanager.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.screen {
console.print_debug('startupmanager: zinit')
return startupmanager.get(.screen)!
}
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
return startupmanager.get(.zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
return startupmanager.get(.systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
return startupmanager.get(.auto)!
}
}
}
pub fn (mut self ZeroFS) start() ! {
switch(self.name)
if self.running()! {
return
}
@@ -150,10 +159,12 @@ pub fn (mut self ZeroFS) running() !bool {
// walk over the generic processes, if not running return
for zprocess in startupcmd()! {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
if zprocess.startuptype != .screen {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
}
}
}
return running()!
@@ -185,12 +196,4 @@ pub fn (mut self ZeroFS) destroy() ! {
// switch instance to be used for zerofs
pub fn switch(name string) {
zerofs_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -6,20 +6,22 @@ import freeflowuniverse.herolib.core.texttools
import freeflowuniverse.herolib.core.pathlib
import freeflowuniverse.herolib.core
import freeflowuniverse.herolib.develop.gittools
import freeflowuniverse.herolib.osal.zinit
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.installers.ulist
import freeflowuniverse.herolib.core.httpconnection
import freeflowuniverse.herolib.installers.lang.golang
import os
fn startupcmd() ![]zinit.ZProcessNewArgs {
fn startupcmd() ![]startupmanager.ZProcessNewArgs {
mut args := get()!
mut res := []zinit.ZProcessNewArgs{}
mut res := []startupmanager.ZProcessNewArgs{}
cmd := "coredns -conf '${args.config_path}'"
res << zinit.ZProcessNewArgs{
res << startupmanager.ZProcessNewArgs
{
name: 'coredns'
cmd: cmd
}
return res
}

View File

@@ -3,75 +3,106 @@ module coredns
import freeflowuniverse.herolib.core.base
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time
__global (
coredns_global map[string]&CoreDNS
coredns_default string
)
/////////FACTORY
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
fromdb bool // will load from filesystem
create bool // default will not create if not exist
}
fn args_get(args_ ArgsGet) ArgsGet {
mut args := args_
if args.name == '' {
args.name = 'default'
}
return args
}
pub fn get(args_ ArgsGet) !&CoreDNS {
mut context := base.context()!
mut args := args_get(args_)
pub fn new(args ArgsGet) !&CoreDNS {
mut obj := CoreDNS{
name: args.name
}
if args.name !in coredns_global {
if !exists(args)! {
set(obj)!
set(obj)!
return &obj
}
pub fn get(args ArgsGet) !&CoreDNS {
mut context := base.context()!
coredns_default = args.name
if args.fromdb || args.name !in coredns_global {
mut r := context.redis()!
if r.hexists('context:coredns', args.name)! {
data := r.hget('context:coredns', args.name)!
if data.len == 0 {
return error('CoreDNS with name: coredns does not exist, prob bug.')
}
mut obj := json.decode(CoreDNS, data)!
set_in_mem(obj)!
} else {
heroscript := context.hero_config_get('coredns', args.name)!
mut obj_ := heroscript_loads(heroscript)!
set_in_mem(obj_)!
if args.create {
new(args)!
} else {
return error("CoreDNS with name 'coredns' does not exist")
}
}
return get(name: args.name)! // no longer from db nor create
}
return coredns_global[args.name] or {
println(coredns_global)
// bug if we get here because should be in globals
panic('could not get config for coredns with name, is bug:${args.name}')
return error('could not get config for coredns with name:coredns')
}
}
// register the config for the future
pub fn set(o CoreDNS) ! {
set_in_mem(o)!
coredns_default = o.name
mut context := base.context()!
heroscript := heroscript_dumps(o)!
context.hero_config_set('coredns', o.name, heroscript)!
mut r := context.redis()!
r.hset('context:coredns', o.name, json.encode(o))!
}
// does the config exists?
pub fn exists(args_ ArgsGet) !bool {
pub fn exists(args ArgsGet) !bool {
mut context := base.context()!
mut args := args_get(args_)
return context.hero_config_exists('coredns', args.name)
mut r := context.redis()!
return r.hexists('context:coredns', args.name)!
}
pub fn delete(args_ ArgsGet) ! {
mut args := args_get(args_)
pub fn delete(args ArgsGet) ! {
mut context := base.context()!
context.hero_config_delete('coredns', args.name)!
if args.name in coredns_global {
// del coredns_global[args.name]
mut r := context.redis()!
r.hdel('context:coredns', args.name)!
}
@[params]
pub struct ArgsList {
pub mut:
fromdb bool // will load from filesystem
}
// if fromdb set: load from filesystem, and not from mem, will also reset what is in mem
pub fn list(args ArgsList) ![]&CoreDNS {
mut res := []&CoreDNS{}
mut context := base.context()!
if args.fromdb {
// reset what is in mem
coredns_global = map[string]&CoreDNS{}
coredns_default = ''
}
if args.fromdb {
mut r := context.redis()!
mut l := r.hkeys('context:coredns')!
for name in l {
res << get(name: name, fromdb: true)!
}
return res
} else {
// load from memory
for _, client in coredns_global {
res << client
}
}
return res
}
// only sets in mem, does not set as config
@@ -82,6 +113,9 @@ fn set_in_mem(o CoreDNS) ! {
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'coredns.') {
return
}
mut install_actions := plbook.find(filter: 'coredns.configure')!
if install_actions.len > 0 {
for install_action in install_actions {
@@ -90,7 +124,6 @@ pub fn play(mut plbook PlayBook) ! {
set(obj2)!
}
}
mut other_actions := plbook.find(filter: 'coredns.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -131,36 +164,38 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
fn startupmanager_get(cat startupmanager.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.screen {
console.print_debug('startupmanager: zinit')
return startupmanager.get(.screen)!
}
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
return startupmanager.get(.zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
return startupmanager.get(.systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
return startupmanager.get(.auto)!
}
}
}
// load from disk and make sure is properly intialized
pub fn (mut self CoreDNS) reload() ! {
switch(self.name)
self = obj_init(self)!
}
pub fn (mut self CoreDNS) start() ! {
switch(self.name)
if self.running()! {
return
}
@@ -223,10 +258,12 @@ pub fn (mut self CoreDNS) running() !bool {
// walk over the generic processes, if not running return
for zprocess in startupcmd()! {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
if zprocess.startuptype != .screen {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
}
}
}
return running()!
@@ -258,12 +295,4 @@ pub fn (mut self CoreDNS) destroy() ! {
// switch instance to be used for coredns
pub fn switch(name string) {
coredns_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -5,7 +5,7 @@ import freeflowuniverse.herolib.core
import freeflowuniverse.herolib.core.texttools
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.installers.ulist
import freeflowuniverse.herolib.osal.zinit
import freeflowuniverse.herolib.osal.startupmanager
import os
fn installed() !bool {
@@ -30,16 +30,12 @@ fn install() ! {
mut url := ''
if core.is_linux_arm()! {
// https://github.com/go-gitea/gitea/releases/download/v1.23.2/gitea-1.23.2-linux-arm64.xz
url = '${baseurl}-linux-arm64.xz'
} else if core.is_linux_intel()! {
// https://github.com/go-gitea/gitea/releases/download/v1.23.2/gitea-1.23.2-linux-amd64.xz
url = '${baseurl}-linux-amd64.xz'
} else if core.is_osx_arm()! {
// https://github.com/go-gitea/gitea/releases/download/v1.23.2/gitea-1.23.2-darwin-10.12-arm64.xz
url = '${baseurl}-darwin-10.12-arm64.xz'
} else if core.is_osx_intel()! {
// https://github.com/go-gitea/gitea/releases/download/v1.23.2/gitea-1.23.2-darwin-10.12-amd64.xz
url = '${baseurl}-darwin-10.12-amd64.xz'
} else {
return error('unsported platform')
@@ -90,10 +86,11 @@ fn ulist_get() !ulist.UList {
// uploads to S3 server if configured
fn upload() ! {}
fn startupcmd() ![]zinit.ZProcessNewArgs {
fn startupcmd() ![]startupmanager.ZProcessNewArgs {
mut cfg := get()!
mut res := []zinit.ZProcessNewArgs{}
res << zinit.ZProcessNewArgs{
mut res := []startupmanager.ZProcessNewArgs{}
res << startupmanager.ZProcessNewArgs
{
name: 'gitea'
cmd: 'gitea server'
env: {
@@ -101,11 +98,12 @@ fn startupcmd() ![]zinit.ZProcessNewArgs {
'GITEA_CONFIG': cfg.config_path()
}
}
return res
// mut res := []zinit.ZProcessNewArgs{}
// mut res := []startupmanager.ZProcessNewArgs{}
// cfg := get()!
// res << zinit.ZProcessNewArgs{
// res << startupmanager.ZProcessNewArgs{
// name: 'gitea'
// // cmd: 'GITEA_WORK_DIR=${cfg.path} sudo -u git /var/lib/git/gitea web -c /etc/gitea_app.ini'
// cmd: '
@@ -151,7 +149,7 @@ fn startupcmd() ![]zinit.ZProcessNewArgs {
// '
// workdir: cfg.path
// }
// res << zinit.ZProcessNewArgs{
// res << startupmanager.ZProcessNewArgs{
// name: 'restart_gitea'
// cmd: 'sleep 30 && zinit restart gitea && exit 1'
// after: ['gitea']

View File

@@ -3,75 +3,106 @@ module gitea
import freeflowuniverse.herolib.core.base
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time
__global (
gitea_global map[string]&GiteaServer
gitea_default string
)
/////////FACTORY
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
fromdb bool // will load from filesystem
create bool // default will not create if not exist
}
fn args_get(args_ ArgsGet) ArgsGet {
mut args := args_
if args.name == '' {
args.name = 'default'
}
return args
}
pub fn get(args_ ArgsGet) !&GiteaServer {
mut context := base.context()!
mut args := args_get(args_)
pub fn new(args ArgsGet) !&GiteaServer {
mut obj := GiteaServer{
name: args.name
}
if args.name !in gitea_global {
if !exists(args)! {
set(obj)!
set(obj)!
return &obj
}
pub fn get(args ArgsGet) !&GiteaServer {
mut context := base.context()!
gitea_default = args.name
if args.fromdb || args.name !in gitea_global {
mut r := context.redis()!
if r.hexists('context:gitea', args.name)! {
data := r.hget('context:gitea', args.name)!
if data.len == 0 {
return error('GiteaServer with name: gitea does not exist, prob bug.')
}
mut obj := json.decode(GiteaServer, data)!
set_in_mem(obj)!
} else {
heroscript := context.hero_config_get('gitea', args.name)!
mut obj_ := heroscript_loads(heroscript)!
set_in_mem(obj_)!
if args.create {
new(args)!
} else {
return error("GiteaServer with name 'gitea' does not exist")
}
}
return get(name: args.name)! // no longer from db nor create
}
return gitea_global[args.name] or {
println(gitea_global)
// bug if we get here because should be in globals
panic('could not get config for gitea with name, is bug:${args.name}')
return error('could not get config for gitea with name:gitea')
}
}
// register the config for the future
pub fn set(o GiteaServer) ! {
set_in_mem(o)!
gitea_default = o.name
mut context := base.context()!
heroscript := heroscript_dumps(o)!
context.hero_config_set('gitea', o.name, heroscript)!
mut r := context.redis()!
r.hset('context:gitea', o.name, json.encode(o))!
}
// does the config exists?
pub fn exists(args_ ArgsGet) !bool {
pub fn exists(args ArgsGet) !bool {
mut context := base.context()!
mut args := args_get(args_)
return context.hero_config_exists('gitea', args.name)
mut r := context.redis()!
return r.hexists('context:gitea', args.name)!
}
pub fn delete(args_ ArgsGet) ! {
mut args := args_get(args_)
pub fn delete(args ArgsGet) ! {
mut context := base.context()!
context.hero_config_delete('gitea', args.name)!
if args.name in gitea_global {
// del gitea_global[args.name]
mut r := context.redis()!
r.hdel('context:gitea', args.name)!
}
@[params]
pub struct ArgsList {
pub mut:
fromdb bool // will load from filesystem
}
// if fromdb set: load from filesystem, and not from mem, will also reset what is in mem
pub fn list(args ArgsList) ![]&GiteaServer {
mut res := []&GiteaServer{}
mut context := base.context()!
if args.fromdb {
// reset what is in mem
gitea_global = map[string]&GiteaServer{}
gitea_default = ''
}
if args.fromdb {
mut r := context.redis()!
mut l := r.hkeys('context:gitea')!
for name in l {
res << get(name: name, fromdb: true)!
}
return res
} else {
// load from memory
for _, client in gitea_global {
res << client
}
}
return res
}
// only sets in mem, does not set as config
@@ -82,6 +113,9 @@ fn set_in_mem(o GiteaServer) ! {
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'gitea.') {
return
}
mut install_actions := plbook.find(filter: 'gitea.configure')!
if install_actions.len > 0 {
for install_action in install_actions {
@@ -90,7 +124,6 @@ pub fn play(mut plbook PlayBook) ! {
set(obj2)!
}
}
mut other_actions := plbook.find(filter: 'gitea.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -131,36 +164,38 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
fn startupmanager_get(cat startupmanager.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.screen {
console.print_debug('startupmanager: zinit')
return startupmanager.get(.screen)!
}
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
return startupmanager.get(.zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
return startupmanager.get(.systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
return startupmanager.get(.auto)!
}
}
}
// load from disk and make sure is properly intialized
pub fn (mut self GiteaServer) reload() ! {
switch(self.name)
self = obj_init(self)!
}
pub fn (mut self GiteaServer) start() ! {
switch(self.name)
if self.running()! {
return
}
@@ -223,10 +258,12 @@ pub fn (mut self GiteaServer) running() !bool {
// walk over the generic processes, if not running return
for zprocess in startupcmd()! {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
if zprocess.startuptype != .screen {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
}
}
}
return running()!
@@ -258,12 +295,4 @@ pub fn (mut self GiteaServer) destroy() ! {
// switch instance to be used for gitea
pub fn switch(name string) {
gitea_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -10,7 +10,7 @@ import freeflowuniverse.herolib.clients.mailclient
import freeflowuniverse.herolib.clients.postgresql_client
import rand
pub const version = '1.23.3'
pub const version = '1.24.5'
const singleton = true
const default = false

View File

@@ -1,7 +1,7 @@
module livekit
import freeflowuniverse.herolib.osal.core as osal
import freeflowuniverse.herolib.osal.zinit
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.core.texttools
import freeflowuniverse.herolib.installers.ulist
@@ -45,10 +45,11 @@ fn generate_keys() ! {
obj.apisecret = api_secret
}
fn startupcmd() ![]zinit.ZProcessNewArgs {
mut res := []zinit.ZProcessNewArgs{}
fn startupcmd() ![]startupmanager.ZProcessNewArgs {
mut res := []startupmanager.ZProcessNewArgs{}
mut installer := get()!
res << zinit.ZProcessNewArgs{
res << startupmanager.ZProcessNewArgs
{
name: 'livekit'
cmd: 'livekit-server --config ${installer.configpath} --bind 0.0.0.0'
startuptype: .zinit

View File

@@ -3,8 +3,8 @@ module livekit
import freeflowuniverse.herolib.core.base
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time
__global (
@@ -17,61 +17,97 @@ __global (
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
fromdb bool // will load from filesystem
create bool // default will not create if not exist
}
fn args_get(args_ ArgsGet) ArgsGet {
mut args := args_
if args.name == '' {
args.name = 'default'
}
return args
}
pub fn get(args_ ArgsGet) !&LivekitServer {
mut context := base.context()!
mut args := args_get(args_)
pub fn new(args ArgsGet) !&LivekitServer {
mut obj := LivekitServer{
name: args.name
}
if args.name !in livekit_global {
if !exists(args)! {
set(obj)!
set(obj)!
return &obj
}
pub fn get(args ArgsGet) !&LivekitServer {
mut context := base.context()!
livekit_default = args.name
if args.fromdb || args.name !in livekit_global {
mut r := context.redis()!
if r.hexists('context:livekit', args.name)! {
data := r.hget('context:livekit', args.name)!
if data.len == 0 {
return error('LivekitServer with name: livekit does not exist, prob bug.')
}
mut obj := json.decode(LivekitServer, data)!
set_in_mem(obj)!
} else {
heroscript := context.hero_config_get('livekit', args.name)!
mut obj_ := heroscript_loads(heroscript)!
set_in_mem(obj_)!
if args.create {
new(args)!
} else {
return error("LivekitServer with name 'livekit' does not exist")
}
}
return get(name: args.name)! // no longer from db nor create
}
return livekit_global[args.name] or {
println(livekit_global)
// bug if we get here because should be in globals
panic('could not get config for livekit with name, is bug:${args.name}')
return error('could not get config for livekit with name:livekit')
}
}
// register the config for the future
pub fn set(o LivekitServer) ! {
set_in_mem(o)!
livekit_default = o.name
mut context := base.context()!
heroscript := heroscript_dumps(o)!
context.hero_config_set('livekit', o.name, heroscript)!
mut r := context.redis()!
r.hset('context:livekit', o.name, json.encode(o))!
}
// does the config exists?
pub fn exists(args_ ArgsGet) !bool {
pub fn exists(args ArgsGet) !bool {
mut context := base.context()!
mut args := args_get(args_)
return context.hero_config_exists('livekit', args.name)
mut r := context.redis()!
return r.hexists('context:livekit', args.name)!
}
pub fn delete(args_ ArgsGet) ! {
mut args := args_get(args_)
pub fn delete(args ArgsGet) ! {
mut context := base.context()!
context.hero_config_delete('livekit', args.name)!
if args.name in livekit_global {
// del livekit_global[args.name]
mut r := context.redis()!
r.hdel('context:livekit', args.name)!
}
@[params]
pub struct ArgsList {
pub mut:
fromdb bool // will load from filesystem
}
// if fromdb set: load from filesystem, and not from mem, will also reset what is in mem
pub fn list(args ArgsList) ![]&LivekitServer {
mut res := []&LivekitServer{}
mut context := base.context()!
if args.fromdb {
// reset what is in mem
livekit_global = map[string]&LivekitServer{}
livekit_default = ''
}
if args.fromdb {
mut r := context.redis()!
mut l := r.hkeys('context:livekit')!
for name in l {
res << get(name: name, fromdb: true)!
}
return res
} else {
// load from memory
for _, client in livekit_global {
res << client
}
}
return res
}
// only sets in mem, does not set as config
@@ -82,6 +118,9 @@ fn set_in_mem(o LivekitServer) ! {
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'livekit.') {
return
}
mut install_actions := plbook.find(filter: 'livekit.configure')!
if install_actions.len > 0 {
for install_action in install_actions {
@@ -90,7 +129,6 @@ pub fn play(mut plbook PlayBook) ! {
set(obj2)!
}
}
mut other_actions := plbook.find(filter: 'livekit.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -131,24 +169,28 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
fn startupmanager_get(cat startupmanager.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.screen {
console.print_debug('startupmanager: zinit')
return startupmanager.get(.screen)!
}
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
return startupmanager.get(.zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
return startupmanager.get(.systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
return startupmanager.get(.auto)!
}
}
}
@@ -223,10 +265,12 @@ pub fn (mut self LivekitServer) running() !bool {
// walk over the generic processes, if not running return
for zprocess in startupcmd()! {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
if zprocess.startuptype != .screen {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
}
}
}
return running()!
@@ -255,10 +299,3 @@ pub fn (mut self LivekitServer) destroy() ! {
pub fn switch(name string) {
livekit_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -2,8 +2,8 @@ module screen
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (
screen_global map[string]&Screen
@@ -15,14 +15,25 @@ __global (
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
}
pub fn get(args_ ArgsGet) !&Screen {
pub fn new(args ArgsGet) !&Screen {
return &Screen{}
}
pub fn get(args ArgsGet) !&Screen {
return new(args)!
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'screen.') {
return
}
mut install_actions := plbook.find(filter: 'screen.configure')!
if install_actions.len > 0 {
return error("can't configure screen, because no configuration allowed for this installer.")
}
mut other_actions := plbook.find(filter: 'screen.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -44,28 +55,6 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
}
}
}
@[params]
pub struct InstallArgs {
pub mut:
@@ -88,10 +77,3 @@ pub fn (mut self Screen) destroy() ! {
pub fn switch(name string) {
screen_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -6,18 +6,28 @@ import freeflowuniverse.herolib.core.texttools
import freeflowuniverse.herolib.develop.gittools
import freeflowuniverse.herolib.core
import freeflowuniverse.herolib.osal.systemd
import freeflowuniverse.herolib.osal.zinit as zinit_module
import freeflowuniverse.herolib.installers.ulist
import freeflowuniverse.herolib.installers.lang.rust
import freeflowuniverse.herolib.osal.startupmanager
import os
fn startupcmd() ![]zinit_module.ZProcessNewArgs {
mut res := []zinit_module.ZProcessNewArgs{}
res << zinit_module.ZProcessNewArgs{
name: 'zinit'
cmd: '/usr/local/bin/zinit init'
startuptype: .systemd
start: true
restart: true
fn startupcmd() ![]startupmanager.ZProcessNewArgs {
mut res := []startupmanager.ZProcessNewArgs{}
if core.is_linux()! {
res << startupmanager.ZProcessNewArgs{
name: 'zinit'
cmd: '/usr/local/bin/zinit init'
startuptype: .systemd
start: true
restart: true
}
} else {
res << startupmanager.ZProcessNewArgs{
name: 'zinit'
cmd: '~/hero/bin/zinit init --config ~/hero/cfg/zinit'
startuptype: .screen
start: true
}
}
return res
}
@@ -70,25 +80,29 @@ fn upload() ! {}
fn install() ! {
console.print_header('install zinit')
if !core.is_linux()! {
return error('only support linux for now')
baseurl := 'https://github.com/threefoldtech/zinit/releases/download/v${version}/zinit-'
mut url := ''
if core.is_linux_intel()! {
url = '${baseurl}linux-x86_64'
} else if core.is_osx_arm()! {
url = '${baseurl}macos-aarch64'
} else if core.is_osx_intel()! {
url = '${baseurl}macos-x86_64'
} else {
return error('unsupported platform to install zinit')
}
release_url := 'https://github.com/threefoldtech/zinit/releases/download/v0.2.25/zinit'
mut dest := osal.download(
url: release_url
minsize_kb: 2000
reset: true
url: url
minsize_kb: 4000
)!
osal.cmd_add(
cmdname: 'zinit'
source: dest.path
)!
osal.dir_ensure('/etc/zinit')!
console.print_header('install zinit done')
}
fn build() ! {
@@ -96,7 +110,8 @@ fn build() ! {
return error('only support linux for now')
}
// rust.install()
mut i := rust.new()!
i.install()!
// install zinit if it was already done will return true
console.print_header('build zinit')
@@ -125,8 +140,12 @@ fn build() ! {
}
fn destroy() ! {
mut systemdfactory := systemd.new()!
systemdfactory.destroy('zinit') or { return error('Could not destroy zinit due to: ${err}') }
if core.is_linux()! {
mut systemdfactory := systemd.new()!
systemdfactory.destroy('zinit') or {
return error('Could not destroy zinit due to: ${err}')
}
}
osal.process_kill_recursive(name: 'zinit') or {
return error('Could not kill zinit due to: ${err}')

View File

@@ -2,28 +2,34 @@ module zinit_installer
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time
__global (
zinit_installer_global map[string]&ZinitInstaller
zinit_installer_default string
)
/////////FACTORY
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
}
pub fn get(args_ ArgsGet) !&ZinitInstaller {
pub fn new(args ArgsGet) !&ZinitInstaller {
return &ZinitInstaller{}
}
pub fn get(args ArgsGet) !&ZinitInstaller {
return new(args)!
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'zinit_installer.') {
return
}
mut install_actions := plbook.find(filter: 'zinit_installer.configure')!
if install_actions.len > 0 {
return error("can't configure zinit_installer, because no configuration allowed for this installer.")
}
mut other_actions := plbook.find(filter: 'zinit_installer.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -64,30 +70,33 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
fn startupmanager_get(cat startupmanager.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.screen {
console.print_debug('startupmanager: zinit')
return startupmanager.get(.screen)!
}
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
return startupmanager.get(.zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
return startupmanager.get(.systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
return startupmanager.get(.auto)!
}
}
}
pub fn (mut self ZinitInstaller) start() ! {
switch(self.name)
if self.running()! {
return
}
@@ -150,10 +159,12 @@ pub fn (mut self ZinitInstaller) running() !bool {
// walk over the generic processes, if not running return
for zprocess in startupcmd()! {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
if zprocess.startuptype != .screen {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
}
}
}
return running()!
@@ -185,12 +196,4 @@ pub fn (mut self ZinitInstaller) destroy() ! {
// switch instance to be used for zinit_installer
pub fn switch(name string) {
zinit_installer_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -2,7 +2,7 @@ module zinit_installer
import freeflowuniverse.herolib.data.encoderhero
pub const version = '0.0.0'
pub const version = '0.2.25'
const singleton = true
const default = true
@@ -23,14 +23,3 @@ fn obj_init(mycfg_ ZinitInstaller) !ZinitInstaller {
fn configure() ! {
// mut installer := get()!
}
/////////////NORMALLY NO NEED TO TOUCH
pub fn heroscript_dumps(obj ZinitInstaller) !string {
return encoderhero.encode[ZinitInstaller](obj)!
}
pub fn heroscript_loads(heroscript string) !ZinitInstaller {
mut obj := encoderhero.decode[ZinitInstaller](heroscript)!
return obj
}

View File

@@ -2,27 +2,33 @@ module golang
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (
golang_global map[string]&GolangInstaller
golang_default string
)
/////////FACTORY
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
}
pub fn get(args_ ArgsGet) !&GolangInstaller {
pub fn new(args ArgsGet) !&GolangInstaller {
return &GolangInstaller{}
}
pub fn get(args ArgsGet) !&GolangInstaller {
return new(args)!
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'golang.') {
return
}
mut install_actions := plbook.find(filter: 'golang.configure')!
if install_actions.len > 0 {
return error("can't configure golang, because no configuration allowed for this installer.")
}
mut other_actions := plbook.find(filter: 'golang.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -44,28 +50,6 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
}
}
}
@[params]
pub struct InstallArgs {
pub mut:
@@ -91,12 +75,4 @@ pub fn (mut self GolangInstaller) destroy() ! {
// switch instance to be used for golang
pub fn switch(name string) {
golang_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -2,27 +2,33 @@ module nodejs
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (
nodejs_global map[string]&NodeJS
nodejs_default string
)
/////////FACTORY
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
}
pub fn get(args_ ArgsGet) !&NodeJS {
pub fn new(args ArgsGet) !&NodeJS {
return &NodeJS{}
}
pub fn get(args ArgsGet) !&NodeJS {
return new(args)!
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'nodejs.') {
return
}
mut install_actions := plbook.find(filter: 'nodejs.configure')!
if install_actions.len > 0 {
return error("can't configure nodejs, because no configuration allowed for this installer.")
}
mut other_actions := plbook.find(filter: 'nodejs.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -44,28 +50,6 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
}
}
}
@[params]
pub struct InstallArgs {
pub mut:
@@ -86,12 +70,4 @@ pub fn (mut self NodeJS) destroy() ! {
// switch instance to be used for nodejs
pub fn switch(name string) {
nodejs_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -2,27 +2,33 @@ module python
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (
python_global map[string]&PythonInstaller
python_default string
)
/////////FACTORY
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
}
pub fn get(args_ ArgsGet) !&PythonInstaller {
pub fn new(args ArgsGet) !&PythonInstaller {
return &PythonInstaller{}
}
pub fn get(args ArgsGet) !&PythonInstaller {
return new(args)!
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'python.') {
return
}
mut install_actions := plbook.find(filter: 'python.configure')!
if install_actions.len > 0 {
return error("can't configure python, because no configuration allowed for this installer.")
}
mut other_actions := plbook.find(filter: 'python.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -44,28 +50,6 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
}
}
}
@[params]
pub struct InstallArgs {
pub mut:
@@ -86,12 +70,4 @@ pub fn (mut self PythonInstaller) destroy() ! {
// switch instance to be used for python
pub fn switch(name string) {
python_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -2,27 +2,33 @@ module rust
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (
rust_global map[string]&RustInstaller
rust_default string
)
/////////FACTORY
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
}
pub fn get(args_ ArgsGet) !&RustInstaller {
pub fn new(args ArgsGet) !&RustInstaller {
return &RustInstaller{}
}
pub fn get(args ArgsGet) !&RustInstaller {
return new(args)!
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'rust.') {
return
}
mut install_actions := plbook.find(filter: 'rust.configure')!
if install_actions.len > 0 {
return error("can't configure rust, because no configuration allowed for this installer.")
}
mut other_actions := plbook.find(filter: 'rust.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -44,28 +50,6 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
}
}
}
@[params]
pub struct InstallArgs {
pub mut:
@@ -86,12 +70,4 @@ pub fn (mut self RustInstaller) destroy() ! {
// switch instance to be used for rust
pub fn switch(name string) {
rust_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -8,26 +8,26 @@ import freeflowuniverse.herolib.core.pathlib
import freeflowuniverse.herolib.installers.infra.zinit_installer
import freeflowuniverse.herolib.clients.mycelium
import freeflowuniverse.herolib.develop.gittools
import freeflowuniverse.herolib.osal.zinit
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.installers.ulist
import freeflowuniverse.herolib.installers.lang.rust
import os
fn startupcmd() ![]zinit.ZProcessNewArgs {
fn startupcmd() ![]startupmanager.ZProcessNewArgs {
mut installer := get()!
mut res := []zinit.ZProcessNewArgs{}
mut res := []startupmanager.ZProcessNewArgs{}
mut peers_str := installer.peers.join(' ')
mut tun_name := 'tun${installer.tun_nr}'
res << zinit.ZProcessNewArgs{
res << startupmanager.ZProcessNewArgs
{
name: 'mycelium'
startuptype: .zinit
cmd: 'mycelium --key-file ${osal.hero_path()!}/cfg/priv_key.bin --peers ${peers_str} --tun-name ${tun_name}'
env: {
'HOME': '/root'
env: {
'HOME': os.home_dir()
}
}
return res
}

View File

@@ -3,8 +3,8 @@ module mycelium_installer
import freeflowuniverse.herolib.core.base
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time
__global (
@@ -17,61 +17,97 @@ __global (
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
fromdb bool // will load from filesystem
create bool // default will not create if not exist
}
fn args_get(args_ ArgsGet) ArgsGet {
mut args := args_
if args.name == '' {
args.name = 'default'
}
return args
}
pub fn get(args_ ArgsGet) !&MyceliumInstaller {
mut context := base.context()!
mut args := args_get(args_)
pub fn new(args ArgsGet) !&MyceliumInstaller {
mut obj := MyceliumInstaller{
name: args.name
}
if args.name !in mycelium_installer_global {
if !exists(args)! {
set(obj)!
set(obj)!
return &obj
}
pub fn get(args ArgsGet) !&MyceliumInstaller {
mut context := base.context()!
mycelium_installer_default = args.name
if args.fromdb || args.name !in mycelium_installer_global {
mut r := context.redis()!
if r.hexists('context:mycelium_installer', args.name)! {
data := r.hget('context:mycelium_installer', args.name)!
if data.len == 0 {
return error('MyceliumInstaller with name: mycelium_installer does not exist, prob bug.')
}
mut obj := json.decode(MyceliumInstaller, data)!
set_in_mem(obj)!
} else {
heroscript := context.hero_config_get('mycelium_installer', args.name)!
mut obj_ := heroscript_loads(heroscript)!
set_in_mem(obj_)!
if args.create {
new(args)!
} else {
return error("MyceliumInstaller with name 'mycelium_installer' does not exist")
}
}
return get(name: args.name)! // no longer from db nor create
}
return mycelium_installer_global[args.name] or {
println(mycelium_installer_global)
// bug if we get here because should be in globals
panic('could not get config for mycelium_installer with name, is bug:${args.name}')
return error('could not get config for mycelium_installer with name:mycelium_installer')
}
}
// register the config for the future
pub fn set(o MyceliumInstaller) ! {
set_in_mem(o)!
mycelium_installer_default = o.name
mut context := base.context()!
heroscript := heroscript_dumps(o)!
context.hero_config_set('mycelium_installer', o.name, heroscript)!
mut r := context.redis()!
r.hset('context:mycelium_installer', o.name, json.encode(o))!
}
// does the config exists?
pub fn exists(args_ ArgsGet) !bool {
pub fn exists(args ArgsGet) !bool {
mut context := base.context()!
mut args := args_get(args_)
return context.hero_config_exists('mycelium_installer', args.name)
mut r := context.redis()!
return r.hexists('context:mycelium_installer', args.name)!
}
pub fn delete(args_ ArgsGet) ! {
mut args := args_get(args_)
pub fn delete(args ArgsGet) ! {
mut context := base.context()!
context.hero_config_delete('mycelium_installer', args.name)!
if args.name in mycelium_installer_global {
// del mycelium_installer_global[args.name]
mut r := context.redis()!
r.hdel('context:mycelium_installer', args.name)!
}
@[params]
pub struct ArgsList {
pub mut:
fromdb bool // will load from filesystem
}
// if fromdb set: load from filesystem, and not from mem, will also reset what is in mem
pub fn list(args ArgsList) ![]&MyceliumInstaller {
mut res := []&MyceliumInstaller{}
mut context := base.context()!
if args.fromdb {
// reset what is in mem
mycelium_installer_global = map[string]&MyceliumInstaller{}
mycelium_installer_default = ''
}
if args.fromdb {
mut r := context.redis()!
mut l := r.hkeys('context:mycelium_installer')!
for name in l {
res << get(name: name, fromdb: true)!
}
return res
} else {
// load from memory
for _, client in mycelium_installer_global {
res << client
}
}
return res
}
// only sets in mem, does not set as config
@@ -82,6 +118,9 @@ fn set_in_mem(o MyceliumInstaller) ! {
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'mycelium_installer.') {
return
}
mut install_actions := plbook.find(filter: 'mycelium_installer.configure')!
if install_actions.len > 0 {
for install_action in install_actions {
@@ -90,7 +129,6 @@ pub fn play(mut plbook PlayBook) ! {
set(obj2)!
}
}
mut other_actions := plbook.find(filter: 'mycelium_installer.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -131,24 +169,28 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
fn startupmanager_get(cat startupmanager.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.screen {
console.print_debug('startupmanager: zinit')
return startupmanager.get(.screen)!
}
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
return startupmanager.get(.zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
return startupmanager.get(.systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
return startupmanager.get(.auto)!
}
}
}
@@ -223,10 +265,12 @@ pub fn (mut self MyceliumInstaller) running() !bool {
// walk over the generic processes, if not running return
for zprocess in startupcmd()! {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
if zprocess.startuptype != .screen {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
}
}
}
return running()!
@@ -260,10 +304,3 @@ pub fn (mut self MyceliumInstaller) destroy() ! {
pub fn switch(name string) {
mycelium_installer_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -2,8 +2,8 @@ module wireguard_installer
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (
wireguard_installer_global map[string]&WireGuard
@@ -15,14 +15,25 @@ __global (
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
}
pub fn get(args_ ArgsGet) !&WireGuard {
pub fn new(args ArgsGet) !&WireGuard {
return &WireGuard{}
}
pub fn get(args ArgsGet) !&WireGuard {
return new(args)!
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'wireguard_installer.') {
return
}
mut install_actions := plbook.find(filter: 'wireguard_installer.configure')!
if install_actions.len > 0 {
return error("can't configure wireguard_installer, because no configuration allowed for this installer.")
}
mut other_actions := plbook.find(filter: 'wireguard_installer.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -44,28 +55,6 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
}
}
}
@[params]
pub struct InstallArgs {
pub mut:
@@ -88,10 +77,3 @@ pub fn (mut self WireGuard) destroy() ! {
pub fn switch(name string) {
wireguard_installer_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -5,18 +5,18 @@ import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.core.texttools
import freeflowuniverse.herolib.core.pathlib
import freeflowuniverse.herolib.osal.systemd
import freeflowuniverse.herolib.osal.zinit
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.installers.ulist
import freeflowuniverse.herolib.installers.lang.golang
import freeflowuniverse.herolib.installers.lang.rust
import freeflowuniverse.herolib.installers.lang.python
import os
fn startupcmd() ![]zinit.ZProcessNewArgs {
fn startupcmd() ![]startupmanager.ZProcessNewArgs {
mut installer := get()!
mut res := []zinit.ZProcessNewArgs{}
mut res := []startupmanager.ZProcessNewArgs{}
// THIS IS EXAMPLE CODEAND NEEDS TO BE CHANGED
// res << zinit.ZProcessNewArgs{
// res << startupmanager.ZProcessNewArgs{
// name: 'yggdrasil'
// cmd: 'yggdrasil server'
// env: {

View File

@@ -2,28 +2,34 @@ module yggdrasil
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time
__global (
yggdrasil_global map[string]&YggdrasilInstaller
yggdrasil_default string
)
/////////FACTORY
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
}
pub fn get(args_ ArgsGet) !&YggdrasilInstaller {
pub fn new(args ArgsGet) !&YggdrasilInstaller {
return &YggdrasilInstaller{}
}
pub fn get(args ArgsGet) !&YggdrasilInstaller {
return new(args)!
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'yggdrasil.') {
return
}
mut install_actions := plbook.find(filter: 'yggdrasil.configure')!
if install_actions.len > 0 {
return error("can't configure yggdrasil, because no configuration allowed for this installer.")
}
mut other_actions := plbook.find(filter: 'yggdrasil.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -64,30 +70,33 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
fn startupmanager_get(cat startupmanager.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.screen {
console.print_debug('startupmanager: zinit')
return startupmanager.get(.screen)!
}
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
return startupmanager.get(.zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
return startupmanager.get(.systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
return startupmanager.get(.auto)!
}
}
}
pub fn (mut self YggdrasilInstaller) start() ! {
switch(self.name)
if self.running()! {
return
}
@@ -150,10 +159,12 @@ pub fn (mut self YggdrasilInstaller) running() !bool {
// walk over the generic processes, if not running return
for zprocess in startupcmd()! {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
if zprocess.startuptype != .screen {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
}
}
}
return running()!
@@ -185,12 +196,4 @@ pub fn (mut self YggdrasilInstaller) destroy() ! {
// switch instance to be used for yggdrasil
pub fn switch(name string) {
yggdrasil_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -2,15 +2,16 @@ module actrunner
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.core.texttools
import freeflowuniverse.herolib.osal.zinit
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.installers.ulist
import freeflowuniverse.herolib.osal.core as osal
import freeflowuniverse.herolib.core
import os
fn startupcmd() ![]zinit.ZProcessNewArgs {
mut res := []zinit.ZProcessNewArgs{}
res << zinit.ZProcessNewArgs{
fn startupcmd() ![]startupmanager.ZProcessNewArgs {
mut res := []startupmanager.ZProcessNewArgs{}
res << startupmanager.ZProcessNewArgs
{
name: 'actrunner'
cmd: 'actrunner daemon'
startuptype: .zinit

View File

@@ -2,28 +2,34 @@ module actrunner
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time
__global (
actrunner_global map[string]&ActRunner
actrunner_default string
)
/////////FACTORY
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
}
pub fn get(args_ ArgsGet) !&ActRunner {
pub fn new(args ArgsGet) !&ActRunner {
return &ActRunner{}
}
pub fn get(args ArgsGet) !&ActRunner {
return new(args)!
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'actrunner.') {
return
}
mut install_actions := plbook.find(filter: 'actrunner.configure')!
if install_actions.len > 0 {
return error("can't configure actrunner, because no configuration allowed for this installer.")
}
mut other_actions := plbook.find(filter: 'actrunner.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -64,30 +70,33 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
fn startupmanager_get(cat startupmanager.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.screen {
console.print_debug('startupmanager: zinit')
return startupmanager.get(.screen)!
}
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
return startupmanager.get(.zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
return startupmanager.get(.systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
return startupmanager.get(.auto)!
}
}
}
pub fn (mut self ActRunner) start() ! {
switch(self.name)
if self.running()! {
return
}
@@ -150,10 +159,12 @@ pub fn (mut self ActRunner) running() !bool {
// walk over the generic processes, if not running return
for zprocess in startupcmd()! {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
if zprocess.startuptype != .screen {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
}
}
}
return running()!
@@ -185,12 +196,4 @@ pub fn (mut self ActRunner) destroy() ! {
// switch instance to be used for actrunner
pub fn switch(name string) {
actrunner_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -2,27 +2,33 @@ module b2
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (
b2_global map[string]&BackBase
b2_default string
)
/////////FACTORY
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
}
pub fn get(args_ ArgsGet) !&BackBase {
pub fn new(args ArgsGet) !&BackBase {
return &BackBase{}
}
pub fn get(args ArgsGet) !&BackBase {
return new(args)!
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'b2.') {
return
}
mut install_actions := plbook.find(filter: 'b2.configure')!
if install_actions.len > 0 {
return error("can't configure b2, because no configuration allowed for this installer.")
}
mut other_actions := plbook.find(filter: 'b2.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -44,28 +50,6 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
}
}
}
@[params]
pub struct InstallArgs {
pub mut:
@@ -86,12 +70,4 @@ pub fn (mut self BackBase) destroy() ! {
// switch instance to be used for b2
pub fn switch(name string) {
b2_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -7,14 +7,15 @@ import freeflowuniverse.herolib.core
import freeflowuniverse.herolib.core.httpconnection
import freeflowuniverse.herolib.installers.ulist
// import freeflowuniverse.herolib.develop.gittools
import freeflowuniverse.herolib.osal.zinit
import freeflowuniverse.herolib.osal.startupmanager
import os
fn startupcmd() ![]zinit.ZProcessNewArgs {
mut res := []zinit.ZProcessNewArgs{}
fn startupcmd() ![]startupmanager.ZProcessNewArgs {
mut res := []startupmanager.ZProcessNewArgs{}
mut cfg := get()!
res << zinit.ZProcessNewArgs{
res << startupmanager.ZProcessNewArgs
{
name: 'dagu'
cmd: 'dagu server'
env: {
@@ -23,7 +24,8 @@ fn startupcmd() ![]zinit.ZProcessNewArgs {
}
}
res << zinit.ZProcessNewArgs{
res << startupmanager.ZProcessNewArgs
{
name: 'dagu_scheduler'
cmd: 'dagu scheduler'
env: {

View File

@@ -3,75 +3,106 @@ module daguserver
import freeflowuniverse.herolib.core.base
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time
__global (
daguserver_global map[string]&DaguInstaller
daguserver_default string
)
/////////FACTORY
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
fromdb bool // will load from filesystem
create bool // default will not create if not exist
}
fn args_get(args_ ArgsGet) ArgsGet {
mut args := args_
if args.name == '' {
args.name = 'default'
}
return args
}
pub fn get(args_ ArgsGet) !&DaguInstaller {
mut context := base.context()!
mut args := args_get(args_)
pub fn new(args ArgsGet) !&DaguInstaller {
mut obj := DaguInstaller{
name: args.name
}
if args.name !in daguserver_global {
if !exists(args)! {
set(obj)!
set(obj)!
return &obj
}
pub fn get(args ArgsGet) !&DaguInstaller {
mut context := base.context()!
daguserver_default = args.name
if args.fromdb || args.name !in daguserver_global {
mut r := context.redis()!
if r.hexists('context:daguserver', args.name)! {
data := r.hget('context:daguserver', args.name)!
if data.len == 0 {
return error('DaguInstaller with name: daguserver does not exist, prob bug.')
}
mut obj := json.decode(DaguInstaller, data)!
set_in_mem(obj)!
} else {
heroscript := context.hero_config_get('daguserver', args.name)!
mut obj_ := heroscript_loads(heroscript)!
set_in_mem(obj_)!
if args.create {
new(args)!
} else {
return error("DaguInstaller with name 'daguserver' does not exist")
}
}
return get(name: args.name)! // no longer from db nor create
}
return daguserver_global[args.name] or {
println(daguserver_global)
// bug if we get here because should be in globals
panic('could not get config for daguserver with name, is bug:${args.name}')
return error('could not get config for daguserver with name:daguserver')
}
}
// register the config for the future
pub fn set(o DaguInstaller) ! {
set_in_mem(o)!
daguserver_default = o.name
mut context := base.context()!
heroscript := heroscript_dumps(o)!
context.hero_config_set('daguserver', o.name, heroscript)!
mut r := context.redis()!
r.hset('context:daguserver', o.name, json.encode(o))!
}
// does the config exists?
pub fn exists(args_ ArgsGet) !bool {
pub fn exists(args ArgsGet) !bool {
mut context := base.context()!
mut args := args_get(args_)
return context.hero_config_exists('daguserver', args.name)
mut r := context.redis()!
return r.hexists('context:daguserver', args.name)!
}
pub fn delete(args_ ArgsGet) ! {
mut args := args_get(args_)
pub fn delete(args ArgsGet) ! {
mut context := base.context()!
context.hero_config_delete('daguserver', args.name)!
if args.name in daguserver_global {
// del daguserver_global[args.name]
mut r := context.redis()!
r.hdel('context:daguserver', args.name)!
}
@[params]
pub struct ArgsList {
pub mut:
fromdb bool // will load from filesystem
}
// if fromdb set: load from filesystem, and not from mem, will also reset what is in mem
pub fn list(args ArgsList) ![]&DaguInstaller {
mut res := []&DaguInstaller{}
mut context := base.context()!
if args.fromdb {
// reset what is in mem
daguserver_global = map[string]&DaguInstaller{}
daguserver_default = ''
}
if args.fromdb {
mut r := context.redis()!
mut l := r.hkeys('context:daguserver')!
for name in l {
res << get(name: name, fromdb: true)!
}
return res
} else {
// load from memory
for _, client in daguserver_global {
res << client
}
}
return res
}
// only sets in mem, does not set as config
@@ -82,6 +113,9 @@ fn set_in_mem(o DaguInstaller) ! {
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'daguserver.') {
return
}
mut install_actions := plbook.find(filter: 'daguserver.configure')!
if install_actions.len > 0 {
for install_action in install_actions {
@@ -90,7 +124,6 @@ pub fn play(mut plbook PlayBook) ! {
set(obj2)!
}
}
mut other_actions := plbook.find(filter: 'daguserver.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -131,36 +164,38 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
fn startupmanager_get(cat startupmanager.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.screen {
console.print_debug('startupmanager: zinit')
return startupmanager.get(.screen)!
}
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
return startupmanager.get(.zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
return startupmanager.get(.systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
return startupmanager.get(.auto)!
}
}
}
// load from disk and make sure is properly intialized
pub fn (mut self DaguInstaller) reload() ! {
switch(self.name)
self = obj_init(self)!
}
pub fn (mut self DaguInstaller) start() ! {
switch(self.name)
if self.running()! {
return
}
@@ -223,10 +258,12 @@ pub fn (mut self DaguInstaller) running() !bool {
// walk over the generic processes, if not running return
for zprocess in startupcmd()! {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
if zprocess.startuptype != .screen {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
}
}
}
return running()!
@@ -253,12 +290,4 @@ pub fn (mut self DaguInstaller) destroy() ! {
// switch instance to be used for daguserver
pub fn switch(name string) {
daguserver_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -5,18 +5,18 @@ import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.core.texttools
import freeflowuniverse.herolib.core.pathlib
import freeflowuniverse.herolib.osal.systemd
import freeflowuniverse.herolib.osal.zinit
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.installers.ulist
import freeflowuniverse.herolib.installers.lang.golang
import freeflowuniverse.herolib.installers.lang.rust
import freeflowuniverse.herolib.installers.lang.python
import os
fn startupcmd() ![]zinit.ZProcessNewArgs {
fn startupcmd() ![]startupmanager.ZProcessNewArgs {
mut installer := get()!
mut res := []zinit.ZProcessNewArgs{}
mut res := []startupmanager.ZProcessNewArgs{}
// THIS IS EXAMPLE CODEAND NEEDS TO BE CHANGED
// res << zinit.ZProcessNewArgs{
// res << startupmanager.ZProcessNewArgs{
// name: 'fungistor'
// cmd: 'fungistor server'
// env: {

View File

@@ -2,28 +2,34 @@ module fungistor
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time
__global (
fungistor_global map[string]&FungiStor
fungistor_default string
)
/////////FACTORY
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
}
pub fn get(args_ ArgsGet) !&FungiStor {
pub fn new(args ArgsGet) !&FungiStor {
return &FungiStor{}
}
pub fn get(args ArgsGet) !&FungiStor {
return new(args)!
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'fungistor.') {
return
}
mut install_actions := plbook.find(filter: 'fungistor.configure')!
if install_actions.len > 0 {
return error("can't configure fungistor, because no configuration allowed for this installer.")
}
mut other_actions := plbook.find(filter: 'fungistor.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -64,30 +70,33 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
fn startupmanager_get(cat startupmanager.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.screen {
console.print_debug('startupmanager: zinit')
return startupmanager.get(.screen)!
}
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
return startupmanager.get(.zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
return startupmanager.get(.systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
return startupmanager.get(.auto)!
}
}
}
pub fn (mut self FungiStor) start() ! {
switch(self.name)
if self.running()! {
return
}
@@ -150,10 +159,12 @@ pub fn (mut self FungiStor) running() !bool {
// walk over the generic processes, if not running return
for zprocess in startupcmd()! {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
if zprocess.startuptype != .screen {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
}
}
}
return running()!
@@ -185,12 +196,4 @@ pub fn (mut self FungiStor) destroy() ! {
// switch instance to be used for fungistor
pub fn switch(name string) {
fungistor_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -4,15 +4,16 @@ import freeflowuniverse.herolib.osal.core as osal
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.core.texttools
import freeflowuniverse.herolib.core
import freeflowuniverse.herolib.osal.zinit
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.installers.ulist
import freeflowuniverse.herolib.core.httpconnection
import os
import json
fn startupcmd() ![]zinit.ZProcessNewArgs {
mut res := []zinit.ZProcessNewArgs{}
res << zinit.ZProcessNewArgs{
fn startupcmd() ![]startupmanager.ZProcessNewArgs {
mut res := []startupmanager.ZProcessNewArgs{}
res << startupmanager.ZProcessNewArgs
{
name: 'garage_s3'
cmd: 'garage_s3 -c /var/garage/config.toml server'
startuptype: .zinit

View File

@@ -3,8 +3,8 @@ module garage_s3
import freeflowuniverse.herolib.core.base
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time
__global (
@@ -17,61 +17,97 @@ __global (
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
fromdb bool // will load from filesystem
create bool // default will not create if not exist
}
fn args_get(args_ ArgsGet) ArgsGet {
mut args := args_
if args.name == '' {
args.name = 'default'
}
return args
}
pub fn get(args_ ArgsGet) !&GarageS3 {
mut context := base.context()!
mut args := args_get(args_)
pub fn new(args ArgsGet) !&GarageS3 {
mut obj := GarageS3{
name: args.name
}
if args.name !in garage_s3_global {
if !exists(args)! {
set(obj)!
set(obj)!
return &obj
}
pub fn get(args ArgsGet) !&GarageS3 {
mut context := base.context()!
garage_s3_default = args.name
if args.fromdb || args.name !in garage_s3_global {
mut r := context.redis()!
if r.hexists('context:garage_s3', args.name)! {
data := r.hget('context:garage_s3', args.name)!
if data.len == 0 {
return error('GarageS3 with name: garage_s3 does not exist, prob bug.')
}
mut obj := json.decode(GarageS3, data)!
set_in_mem(obj)!
} else {
heroscript := context.hero_config_get('garage_s3', args.name)!
mut obj_ := heroscript_loads(heroscript)!
set_in_mem(obj_)!
if args.create {
new(args)!
} else {
return error("GarageS3 with name 'garage_s3' does not exist")
}
}
return get(name: args.name)! // no longer from db nor create
}
return garage_s3_global[args.name] or {
println(garage_s3_global)
// bug if we get here because should be in globals
panic('could not get config for garage_s3 with name, is bug:${args.name}')
return error('could not get config for garage_s3 with name:garage_s3')
}
}
// register the config for the future
pub fn set(o GarageS3) ! {
set_in_mem(o)!
garage_s3_default = o.name
mut context := base.context()!
heroscript := heroscript_dumps(o)!
context.hero_config_set('garage_s3', o.name, heroscript)!
mut r := context.redis()!
r.hset('context:garage_s3', o.name, json.encode(o))!
}
// does the config exists?
pub fn exists(args_ ArgsGet) !bool {
pub fn exists(args ArgsGet) !bool {
mut context := base.context()!
mut args := args_get(args_)
return context.hero_config_exists('garage_s3', args.name)
mut r := context.redis()!
return r.hexists('context:garage_s3', args.name)!
}
pub fn delete(args_ ArgsGet) ! {
mut args := args_get(args_)
pub fn delete(args ArgsGet) ! {
mut context := base.context()!
context.hero_config_delete('garage_s3', args.name)!
if args.name in garage_s3_global {
// del garage_s3_global[args.name]
mut r := context.redis()!
r.hdel('context:garage_s3', args.name)!
}
@[params]
pub struct ArgsList {
pub mut:
fromdb bool // will load from filesystem
}
// if fromdb set: load from filesystem, and not from mem, will also reset what is in mem
pub fn list(args ArgsList) ![]&GarageS3 {
mut res := []&GarageS3{}
mut context := base.context()!
if args.fromdb {
// reset what is in mem
garage_s3_global = map[string]&GarageS3{}
garage_s3_default = ''
}
if args.fromdb {
mut r := context.redis()!
mut l := r.hkeys('context:garage_s3')!
for name in l {
res << get(name: name, fromdb: true)!
}
return res
} else {
// load from memory
for _, client in garage_s3_global {
res << client
}
}
return res
}
// only sets in mem, does not set as config
@@ -82,6 +118,9 @@ fn set_in_mem(o GarageS3) ! {
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'garage_s3.') {
return
}
mut install_actions := plbook.find(filter: 'garage_s3.configure')!
if install_actions.len > 0 {
for install_action in install_actions {
@@ -90,7 +129,6 @@ pub fn play(mut plbook PlayBook) ! {
set(obj2)!
}
}
mut other_actions := plbook.find(filter: 'garage_s3.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -131,24 +169,28 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
fn startupmanager_get(cat startupmanager.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.screen {
console.print_debug('startupmanager: zinit')
return startupmanager.get(.screen)!
}
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
return startupmanager.get(.zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
return startupmanager.get(.systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
return startupmanager.get(.auto)!
}
}
}
@@ -223,10 +265,12 @@ pub fn (mut self GarageS3) running() !bool {
// walk over the generic processes, if not running return
for zprocess in startupcmd()! {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
if zprocess.startuptype != .screen {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
}
}
}
return running()!
@@ -255,10 +299,3 @@ pub fn (mut self GarageS3) destroy() ! {
pub fn switch(name string) {
garage_s3_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -5,18 +5,18 @@ import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.core.texttools
import freeflowuniverse.herolib.core.pathlib
import freeflowuniverse.herolib.osal.systemd
import freeflowuniverse.herolib.osal.zinit
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.installers.ulist
import freeflowuniverse.herolib.installers.lang.golang
import freeflowuniverse.herolib.installers.lang.rust
import freeflowuniverse.herolib.installers.lang.python
import os
fn startupcmd() ![]zinit.ZProcessNewArgs {
fn startupcmd() ![]startupmanager.ZProcessNewArgs {
mut installer := get()!
mut res := []zinit.ZProcessNewArgs{}
mut res := []startupmanager.ZProcessNewArgs{}
// THIS IS EXAMPLE CODEAND NEEDS TO BE CHANGED
// res << zinit.ZProcessNewArgs{
// res << startupmanager.ZProcessNewArgs{
// name: 'grafana'
// cmd: 'grafana server'
// env: {

View File

@@ -2,28 +2,34 @@ module grafana
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time
__global (
grafana_global map[string]&Grafana
grafana_default string
)
/////////FACTORY
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
}
pub fn get(args_ ArgsGet) !&Grafana {
pub fn new(args ArgsGet) !&Grafana {
return &Grafana{}
}
pub fn get(args ArgsGet) !&Grafana {
return new(args)!
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'grafana.') {
return
}
mut install_actions := plbook.find(filter: 'grafana.configure')!
if install_actions.len > 0 {
return error("can't configure grafana, because no configuration allowed for this installer.")
}
mut other_actions := plbook.find(filter: 'grafana.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -64,30 +70,33 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
fn startupmanager_get(cat startupmanager.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.screen {
console.print_debug('startupmanager: zinit')
return startupmanager.get(.screen)!
}
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
return startupmanager.get(.zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
return startupmanager.get(.systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
return startupmanager.get(.auto)!
}
}
}
pub fn (mut self Grafana) start() ! {
switch(self.name)
if self.running()! {
return
}
@@ -150,10 +159,12 @@ pub fn (mut self Grafana) running() !bool {
// walk over the generic processes, if not running return
for zprocess in startupcmd()! {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
if zprocess.startuptype != .screen {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
}
}
}
return running()!
@@ -185,12 +196,4 @@ pub fn (mut self Grafana) destroy() ! {
// switch instance to be used for grafana
pub fn switch(name string) {
grafana_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -5,18 +5,18 @@ import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.core.texttools
import freeflowuniverse.herolib.core.pathlib
import freeflowuniverse.herolib.osal.systemd
import freeflowuniverse.herolib.osal.zinit
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.installers.ulist
import freeflowuniverse.herolib.installers.lang.golang
import freeflowuniverse.herolib.installers.lang.rust
import freeflowuniverse.herolib.installers.lang.python
import os
fn startupcmd() ![]zinit.ZProcessNewArgs {
fn startupcmd() ![]startupmanager.ZProcessNewArgs {
mut installer := get()!
mut res := []zinit.ZProcessNewArgs{}
mut res := []startupmanager.ZProcessNewArgs{}
// THIS IS EXAMPLE CODEAND NEEDS TO BE CHANGED
// res << zinit.ZProcessNewArgs{
// res << startupmanager.ZProcessNewArgs{
// name: 'prometheus'
// cmd: 'prometheus server'
// env: {

View File

@@ -2,28 +2,34 @@ module prometheus
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time
__global (
prometheus_global map[string]&Prometheus
prometheus_default string
)
/////////FACTORY
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
}
pub fn get(args_ ArgsGet) !&Prometheus {
pub fn new(args ArgsGet) !&Prometheus {
return &Prometheus{}
}
pub fn get(args ArgsGet) !&Prometheus {
return new(args)!
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'prometheus.') {
return
}
mut install_actions := plbook.find(filter: 'prometheus.configure')!
if install_actions.len > 0 {
return error("can't configure prometheus, because no configuration allowed for this installer.")
}
mut other_actions := plbook.find(filter: 'prometheus.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -64,30 +70,33 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
fn startupmanager_get(cat startupmanager.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.screen {
console.print_debug('startupmanager: zinit')
return startupmanager.get(.screen)!
}
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
return startupmanager.get(.zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
return startupmanager.get(.systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
return startupmanager.get(.auto)!
}
}
}
pub fn (mut self Prometheus) start() ! {
switch(self.name)
if self.running()! {
return
}
@@ -150,10 +159,12 @@ pub fn (mut self Prometheus) running() !bool {
// walk over the generic processes, if not running return
for zprocess in startupcmd()! {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
if zprocess.startuptype != .screen {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
}
}
}
return running()!
@@ -185,12 +196,4 @@ pub fn (mut self Prometheus) destroy() ! {
// switch instance to be used for prometheus
pub fn switch(name string) {
prometheus_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -3,8 +3,8 @@ module rclone
import freeflowuniverse.herolib.core.base
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (
rclone_global map[string]&RClone
@@ -16,61 +16,97 @@ __global (
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
fromdb bool // will load from filesystem
create bool // default will not create if not exist
}
fn args_get(args_ ArgsGet) ArgsGet {
mut args := args_
if args.name == '' {
args.name = 'default'
}
return args
}
pub fn get(args_ ArgsGet) !&RClone {
mut context := base.context()!
mut args := args_get(args_)
pub fn new(args ArgsGet) !&RClone {
mut obj := RClone{
name: args.name
}
if args.name !in rclone_global {
if !exists(args)! {
set(obj)!
set(obj)!
return &obj
}
pub fn get(args ArgsGet) !&RClone {
mut context := base.context()!
rclone_default = args.name
if args.fromdb || args.name !in rclone_global {
mut r := context.redis()!
if r.hexists('context:rclone', args.name)! {
data := r.hget('context:rclone', args.name)!
if data.len == 0 {
return error('RClone with name: rclone does not exist, prob bug.')
}
mut obj := json.decode(RClone, data)!
set_in_mem(obj)!
} else {
heroscript := context.hero_config_get('rclone', args.name)!
mut obj_ := heroscript_loads(heroscript)!
set_in_mem(obj_)!
if args.create {
new(args)!
} else {
return error("RClone with name 'rclone' does not exist")
}
}
return get(name: args.name)! // no longer from db nor create
}
return rclone_global[args.name] or {
println(rclone_global)
// bug if we get here because should be in globals
panic('could not get config for rclone with name, is bug:${args.name}')
return error('could not get config for rclone with name:rclone')
}
}
// register the config for the future
pub fn set(o RClone) ! {
set_in_mem(o)!
rclone_default = o.name
mut context := base.context()!
heroscript := heroscript_dumps(o)!
context.hero_config_set('rclone', o.name, heroscript)!
mut r := context.redis()!
r.hset('context:rclone', o.name, json.encode(o))!
}
// does the config exists?
pub fn exists(args_ ArgsGet) !bool {
pub fn exists(args ArgsGet) !bool {
mut context := base.context()!
mut args := args_get(args_)
return context.hero_config_exists('rclone', args.name)
mut r := context.redis()!
return r.hexists('context:rclone', args.name)!
}
pub fn delete(args_ ArgsGet) ! {
mut args := args_get(args_)
pub fn delete(args ArgsGet) ! {
mut context := base.context()!
context.hero_config_delete('rclone', args.name)!
if args.name in rclone_global {
// del rclone_global[args.name]
mut r := context.redis()!
r.hdel('context:rclone', args.name)!
}
@[params]
pub struct ArgsList {
pub mut:
fromdb bool // will load from filesystem
}
// if fromdb set: load from filesystem, and not from mem, will also reset what is in mem
pub fn list(args ArgsList) ![]&RClone {
mut res := []&RClone{}
mut context := base.context()!
if args.fromdb {
// reset what is in mem
rclone_global = map[string]&RClone{}
rclone_default = ''
}
if args.fromdb {
mut r := context.redis()!
mut l := r.hkeys('context:rclone')!
for name in l {
res << get(name: name, fromdb: true)!
}
return res
} else {
// load from memory
for _, client in rclone_global {
res << client
}
}
return res
}
// only sets in mem, does not set as config
@@ -81,6 +117,9 @@ fn set_in_mem(o RClone) ! {
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'rclone.') {
return
}
mut install_actions := plbook.find(filter: 'rclone.configure')!
if install_actions.len > 0 {
for install_action in install_actions {
@@ -89,7 +128,6 @@ pub fn play(mut plbook PlayBook) ! {
set(obj2)!
}
}
mut other_actions := plbook.find(filter: 'rclone.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -111,28 +149,6 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
}
}
}
// load from disk and make sure is properly intialized
pub fn (mut self RClone) reload() ! {
switch(self.name)
@@ -161,10 +177,3 @@ pub fn (mut self RClone) destroy() ! {
pub fn switch(name string) {
rclone_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -5,18 +5,18 @@ import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.core.texttools
import freeflowuniverse.herolib.core.pathlib
import freeflowuniverse.herolib.osal.systemd
import freeflowuniverse.herolib.osal.zinit
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.installers.ulist
import freeflowuniverse.herolib.installers.lang.golang
import freeflowuniverse.herolib.installers.lang.rust
import freeflowuniverse.herolib.installers.lang.python
import os
fn startupcmd() ![]zinit.ZProcessNewArgs {
fn startupcmd() ![]startupmanager.ZProcessNewArgs {
mut installer := get()!
mut res := []zinit.ZProcessNewArgs{}
mut res := []startupmanager.ZProcessNewArgs{}
// THIS IS EXAMPLE CODEAND NEEDS TO BE CHANGED
// res << zinit.ZProcessNewArgs{
// res << startupmanager.ZProcessNewArgs{
// name: 'restic'
// cmd: 'restic server'
// env: {

View File

@@ -2,28 +2,34 @@ module restic
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time
__global (
restic_global map[string]&Restic
restic_default string
)
/////////FACTORY
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
}
pub fn get(args_ ArgsGet) !&Restic {
pub fn new(args ArgsGet) !&Restic {
return &Restic{}
}
pub fn get(args ArgsGet) !&Restic {
return new(args)!
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'restic.') {
return
}
mut install_actions := plbook.find(filter: 'restic.configure')!
if install_actions.len > 0 {
return error("can't configure restic, because no configuration allowed for this installer.")
}
mut other_actions := plbook.find(filter: 'restic.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -64,30 +70,33 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
fn startupmanager_get(cat startupmanager.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.screen {
console.print_debug('startupmanager: zinit')
return startupmanager.get(.screen)!
}
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
return startupmanager.get(.zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
return startupmanager.get(.systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
return startupmanager.get(.auto)!
}
}
}
pub fn (mut self Restic) start() ! {
switch(self.name)
if self.running()! {
return
}
@@ -150,10 +159,12 @@ pub fn (mut self Restic) running() !bool {
// walk over the generic processes, if not running return
for zprocess in startupcmd()! {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
if zprocess.startuptype != .screen {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
}
}
}
return running()!
@@ -185,12 +196,4 @@ pub fn (mut self Restic) destroy() ! {
// switch instance to be used for restic
pub fn switch(name string) {
restic_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -5,18 +5,18 @@ import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.core.texttools
import freeflowuniverse.herolib.core.pathlib
import freeflowuniverse.herolib.osal.systemd
import freeflowuniverse.herolib.osal.zinit
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.installers.ulist
import freeflowuniverse.herolib.installers.lang.golang
import freeflowuniverse.herolib.installers.lang.rust
import freeflowuniverse.herolib.installers.lang.python
import os
fn startupcmd() ![]zinit.ZProcessNewArgs {
fn startupcmd() ![]startupmanager.ZProcessNewArgs {
mut installer := get()!
mut res := []zinit.ZProcessNewArgs{}
mut res := []startupmanager.ZProcessNewArgs{}
// THIS IS EXAMPLE CODEAND NEEDS TO BE CHANGED
// res << zinit.ZProcessNewArgs{
// res << startupmanager.ZProcessNewArgs{
// name: 's3'
// cmd: 's3 server'
// env: {

View File

@@ -2,28 +2,34 @@ module s3
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time
__global (
s3_global map[string]&S3Installer
s3_default string
)
/////////FACTORY
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
}
pub fn get(args_ ArgsGet) !&S3Installer {
pub fn new(args ArgsGet) !&S3Installer {
return &S3Installer{}
}
pub fn get(args ArgsGet) !&S3Installer {
return new(args)!
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 's3.') {
return
}
mut install_actions := plbook.find(filter: 's3.configure')!
if install_actions.len > 0 {
return error("can't configure s3, because no configuration allowed for this installer.")
}
mut other_actions := plbook.find(filter: 's3.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -64,30 +70,33 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
fn startupmanager_get(cat startupmanager.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.screen {
console.print_debug('startupmanager: zinit')
return startupmanager.get(.screen)!
}
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
return startupmanager.get(.zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
return startupmanager.get(.systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
return startupmanager.get(.auto)!
}
}
}
pub fn (mut self S3Installer) start() ! {
switch(self.name)
if self.running()! {
return
}
@@ -150,10 +159,12 @@ pub fn (mut self S3Installer) running() !bool {
// walk over the generic processes, if not running return
for zprocess in startupcmd()! {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
if zprocess.startuptype != .screen {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
}
}
}
return running()!
@@ -185,12 +196,4 @@ pub fn (mut self S3Installer) destroy() ! {
// switch instance to be used for s3
pub fn switch(name string) {
s3_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -1,7 +1,7 @@
module s3
import freeflowuniverse.herolib.osal.core as osal
import freeflowuniverse.herolib.osal.zinit
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.data.dbfs
import freeflowuniverse.herolib.core.texttools
import json

View File

@@ -2,27 +2,33 @@ module griddriver
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (
griddriver_global map[string]&GridDriverInstaller
griddriver_default string
)
/////////FACTORY
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
}
pub fn get(args_ ArgsGet) !&GridDriverInstaller {
pub fn new(args ArgsGet) !&GridDriverInstaller {
return &GridDriverInstaller{}
}
pub fn get(args ArgsGet) !&GridDriverInstaller {
return new(args)!
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'griddriver.') {
return
}
mut install_actions := plbook.find(filter: 'griddriver.configure')!
if install_actions.len > 0 {
return error("can't configure griddriver, because no configuration allowed for this installer.")
}
mut other_actions := plbook.find(filter: 'griddriver.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -44,28 +50,6 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
}
}
}
@[params]
pub struct InstallArgs {
pub mut:
@@ -91,12 +75,4 @@ pub fn (mut self GridDriverInstaller) destroy() ! {
// switch instance to be used for griddriver
pub fn switch(name string) {
griddriver_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -2,27 +2,33 @@ module cloudhypervisor
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (
cloudhypervisor_global map[string]&CloudHypervisor
cloudhypervisor_default string
)
/////////FACTORY
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
}
pub fn get(args_ ArgsGet) !&CloudHypervisor {
pub fn new(args ArgsGet) !&CloudHypervisor {
return &CloudHypervisor{}
}
pub fn get(args ArgsGet) !&CloudHypervisor {
return new(args)!
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'cloudhypervisor.') {
return
}
mut install_actions := plbook.find(filter: 'cloudhypervisor.configure')!
if install_actions.len > 0 {
return error("can't configure cloudhypervisor, because no configuration allowed for this installer.")
}
mut other_actions := plbook.find(filter: 'cloudhypervisor.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -44,28 +50,6 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
}
}
}
@[params]
pub struct InstallArgs {
pub mut:
@@ -91,12 +75,4 @@ pub fn (mut self CloudHypervisor) destroy() ! {
// switch instance to be used for cloudhypervisor
pub fn switch(name string) {
cloudhypervisor_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -3,12 +3,13 @@ module docker
import freeflowuniverse.herolib.core
import freeflowuniverse.herolib.osal.core as osal
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.osal.zinit
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.installers.ulist
fn startupcmd() ![]zinit.ZProcessNewArgs {
mut res := []zinit.ZProcessNewArgs{}
res << zinit.ZProcessNewArgs{
fn startupcmd() ![]startupmanager.ZProcessNewArgs {
mut res := []startupmanager.ZProcessNewArgs{}
res << startupmanager.ZProcessNewArgs
{
name: 'docker'
cmd: 'dockerd'
}

View File

@@ -2,8 +2,8 @@ module docker
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time
__global (
@@ -16,14 +16,25 @@ __global (
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
}
pub fn get(args_ ArgsGet) !&DockerInstaller {
pub fn new(args ArgsGet) !&DockerInstaller {
return &DockerInstaller{}
}
pub fn get(args ArgsGet) !&DockerInstaller {
return new(args)!
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'docker.') {
return
}
mut install_actions := plbook.find(filter: 'docker.configure')!
if install_actions.len > 0 {
return error("can't configure docker, because no configuration allowed for this installer.")
}
mut other_actions := plbook.find(filter: 'docker.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -64,24 +75,28 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
fn startupmanager_get(cat startupmanager.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.screen {
console.print_debug('startupmanager: zinit')
return startupmanager.get(.screen)!
}
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
return startupmanager.get(.zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
return startupmanager.get(.systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
return startupmanager.get(.auto)!
}
}
}
@@ -150,10 +165,12 @@ pub fn (mut self DockerInstaller) running() !bool {
// walk over the generic processes, if not running return
for zprocess in startupcmd()! {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
if zprocess.startuptype != .screen {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
}
}
}
return running()!
@@ -182,10 +199,3 @@ pub fn (mut self DockerInstaller) destroy() ! {
pub fn switch(name string) {
docker_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -2,27 +2,33 @@ module pacman
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (
pacman_global map[string]&PacmanInstaller
pacman_default string
)
/////////FACTORY
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
}
pub fn get(args_ ArgsGet) !&PacmanInstaller {
pub fn new(args ArgsGet) !&PacmanInstaller {
return &PacmanInstaller{}
}
pub fn get(args ArgsGet) !&PacmanInstaller {
return new(args)!
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'pacman.') {
return
}
mut install_actions := plbook.find(filter: 'pacman.configure')!
if install_actions.len > 0 {
return error("can't configure pacman, because no configuration allowed for this installer.")
}
mut other_actions := plbook.find(filter: 'pacman.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -44,28 +50,6 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
}
}
}
@[params]
pub struct InstallArgs {
pub mut:
@@ -86,12 +70,4 @@ pub fn (mut self PacmanInstaller) destroy() ! {
// switch instance to be used for pacman
pub fn switch(name string) {
pacman_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -2,27 +2,33 @@ module podman
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (
podman_global map[string]&PodmanInstaller
podman_default string
)
/////////FACTORY
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
}
pub fn get(args_ ArgsGet) !&PodmanInstaller {
pub fn new(args ArgsGet) !&PodmanInstaller {
return &PodmanInstaller{}
}
pub fn get(args ArgsGet) !&PodmanInstaller {
return new(args)!
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'podman.') {
return
}
mut install_actions := plbook.find(filter: 'podman.configure')!
if install_actions.len > 0 {
return error("can't configure podman, because no configuration allowed for this installer.")
}
mut other_actions := plbook.find(filter: 'podman.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -44,28 +50,6 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
}
}
}
@[params]
pub struct InstallArgs {
pub mut:
@@ -86,12 +70,4 @@ pub fn (mut self PodmanInstaller) destroy() ! {
// switch instance to be used for podman
pub fn switch(name string) {
podman_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -2,27 +2,33 @@ module youki
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (
youki_global map[string]&YoukiInstaller
youki_default string
)
/////////FACTORY
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
}
pub fn get(args_ ArgsGet) !&YoukiInstaller {
pub fn new(args ArgsGet) !&YoukiInstaller {
return &YoukiInstaller{}
}
pub fn get(args ArgsGet) !&YoukiInstaller {
return new(args)!
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'youki.') {
return
}
mut install_actions := plbook.find(filter: 'youki.configure')!
if install_actions.len > 0 {
return error("can't configure youki, because no configuration allowed for this installer.")
}
mut other_actions := plbook.find(filter: 'youki.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -44,28 +50,6 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
}
}
}
@[params]
pub struct InstallArgs {
pub mut:
@@ -91,12 +75,4 @@ pub fn (mut self YoukiInstaller) destroy() ! {
// switch instance to be used for youki
pub fn switch(name string) {
youki_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -2,27 +2,33 @@ module bun
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (
bun_global map[string]&Bun
bun_default string
)
/////////FACTORY
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
}
pub fn get(args_ ArgsGet) !&Bun {
pub fn new(args ArgsGet) !&Bun {
return &Bun{}
}
pub fn get(args ArgsGet) !&Bun {
return new(args)!
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'bun.') {
return
}
mut install_actions := plbook.find(filter: 'bun.configure')!
if install_actions.len > 0 {
return error("can't configure bun, because no configuration allowed for this installer.")
}
mut other_actions := plbook.find(filter: 'bun.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -44,28 +50,6 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
}
}
}
@[params]
pub struct InstallArgs {
pub mut:
@@ -86,12 +70,4 @@ pub fn (mut self Bun) destroy() ! {
// switch instance to be used for bun
pub fn switch(name string) {
bun_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -5,18 +5,18 @@ import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.core.texttools
import freeflowuniverse.herolib.core.pathlib
import freeflowuniverse.herolib.osal.systemd
import freeflowuniverse.herolib.osal.zinit
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.installers.ulist
import freeflowuniverse.herolib.installers.lang.golang
import freeflowuniverse.herolib.installers.lang.rust
import freeflowuniverse.herolib.installers.lang.python
import os
fn startupcmd() ![]zinit.ZProcessNewArgs {
fn startupcmd() ![]startupmanager.ZProcessNewArgs {
mut installer := get()!
mut res := []zinit.ZProcessNewArgs{}
mut res := []startupmanager.ZProcessNewArgs{}
// THIS IS EXAMPLE CODEAND NEEDS TO BE CHANGED
// res << zinit.ZProcessNewArgs{
// res << startupmanager.ZProcessNewArgs{
// name: 'imagemagick'
// cmd: 'imagemagick server'
// env: {

View File

@@ -2,28 +2,34 @@ module imagemagick
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time
__global (
imagemagick_global map[string]&ImageMagick
imagemagick_default string
)
/////////FACTORY
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
}
pub fn get(args_ ArgsGet) !&ImageMagick {
pub fn new(args ArgsGet) !&ImageMagick {
return &ImageMagick{}
}
pub fn get(args ArgsGet) !&ImageMagick {
return new(args)!
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'imagemagick.') {
return
}
mut install_actions := plbook.find(filter: 'imagemagick.configure')!
if install_actions.len > 0 {
return error("can't configure imagemagick, because no configuration allowed for this installer.")
}
mut other_actions := plbook.find(filter: 'imagemagick.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -64,30 +70,33 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
fn startupmanager_get(cat startupmanager.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.screen {
console.print_debug('startupmanager: zinit')
return startupmanager.get(.screen)!
}
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
return startupmanager.get(.zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
return startupmanager.get(.systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
return startupmanager.get(.auto)!
}
}
}
pub fn (mut self ImageMagick) start() ! {
switch(self.name)
if self.running()! {
return
}
@@ -150,10 +159,12 @@ pub fn (mut self ImageMagick) running() !bool {
// walk over the generic processes, if not running return
for zprocess in startupcmd()! {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
if zprocess.startuptype != .screen {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
}
}
}
return running()!
@@ -185,12 +196,4 @@ pub fn (mut self ImageMagick) destroy() ! {
// switch instance to be used for imagemagick
pub fn switch(name string) {
imagemagick_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -5,7 +5,7 @@ import freeflowuniverse.herolib.osal.core as osal
import freeflowuniverse.herolib.core.pathlib
import freeflowuniverse.herolib.core.texttools
import freeflowuniverse.herolib.installers.infra.zinit
import freeflowuniverse.herolib.osal.zinit as zinitmgmt
import freeflowuniverse.herolib.osal.startupmanager as zinitmgmt
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.osal.screen
import os

View File

@@ -5,18 +5,18 @@ import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.core.texttools
import freeflowuniverse.herolib.core.pathlib
import freeflowuniverse.herolib.osal.systemd
import freeflowuniverse.herolib.osal.zinit
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.installers.ulist
import freeflowuniverse.herolib.installers.lang.golang
import freeflowuniverse.herolib.installers.lang.rust
import freeflowuniverse.herolib.installers.lang.python
import os
fn startupcmd() ![]zinit.ZProcessNewArgs {
fn startupcmd() ![]startupmanager.ZProcessNewArgs {
mut installer := get()!
mut res := []zinit.ZProcessNewArgs{}
mut res := []startupmanager.ZProcessNewArgs{}
// THIS IS EXAMPLE CODEAND NEEDS TO BE CHANGED
// res << zinit.ZProcessNewArgs{
// res << startupmanager.ZProcessNewArgs{
// name: 'lighttpd'
// cmd: 'lighttpd server'
// env: {

View File

@@ -2,28 +2,34 @@ module lighttpd
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time
__global (
lighttpd_global map[string]&LightHttpdInstaller
lighttpd_default string
)
/////////FACTORY
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
}
pub fn get(args_ ArgsGet) !&LightHttpdInstaller {
pub fn new(args ArgsGet) !&LightHttpdInstaller {
return &LightHttpdInstaller{}
}
pub fn get(args ArgsGet) !&LightHttpdInstaller {
return new(args)!
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'lighttpd.') {
return
}
mut install_actions := plbook.find(filter: 'lighttpd.configure')!
if install_actions.len > 0 {
return error("can't configure lighttpd, because no configuration allowed for this installer.")
}
mut other_actions := plbook.find(filter: 'lighttpd.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -64,30 +70,33 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
fn startupmanager_get(cat startupmanager.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.screen {
console.print_debug('startupmanager: zinit')
return startupmanager.get(.screen)!
}
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
return startupmanager.get(.zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
return startupmanager.get(.systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
return startupmanager.get(.auto)!
}
}
}
pub fn (mut self LightHttpdInstaller) start() ! {
switch(self.name)
if self.running()! {
return
}
@@ -150,10 +159,12 @@ pub fn (mut self LightHttpdInstaller) running() !bool {
// walk over the generic processes, if not running return
for zprocess in startupcmd()! {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
if zprocess.startuptype != .screen {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
}
}
}
return running()!
@@ -185,12 +196,4 @@ pub fn (mut self LightHttpdInstaller) destroy() ! {
// switch instance to be used for lighttpd
pub fn switch(name string) {
lighttpd_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -2,8 +2,8 @@ module tailwind
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (
tailwind_global map[string]&Tailwind
@@ -15,14 +15,25 @@ __global (
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
}
pub fn get(args_ ArgsGet) !&Tailwind {
pub fn new(args ArgsGet) !&Tailwind {
return &Tailwind{}
}
pub fn get(args ArgsGet) !&Tailwind {
return new(args)!
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'tailwind.') {
return
}
mut install_actions := plbook.find(filter: 'tailwind.configure')!
if install_actions.len > 0 {
return error("can't configure tailwind, because no configuration allowed for this installer.")
}
mut other_actions := plbook.find(filter: 'tailwind.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -44,28 +55,6 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
}
}
}
@[params]
pub struct InstallArgs {
pub mut:
@@ -88,10 +77,3 @@ pub fn (mut self Tailwind) destroy() ! {
pub fn switch(name string) {
tailwind_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -2,8 +2,8 @@ module tailwind4
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (
tailwind4_global map[string]&Tailwind
@@ -15,14 +15,25 @@ __global (
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
}
pub fn get(args_ ArgsGet) !&Tailwind {
pub fn new(args ArgsGet) !&Tailwind {
return &Tailwind{}
}
pub fn get(args ArgsGet) !&Tailwind {
return new(args)!
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'tailwind4.') {
return
}
mut install_actions := plbook.find(filter: 'tailwind4.configure')!
if install_actions.len > 0 {
return error("can't configure tailwind4, because no configuration allowed for this installer.")
}
mut other_actions := plbook.find(filter: 'tailwind4.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -44,28 +55,6 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
}
}
}
@[params]
pub struct InstallArgs {
pub mut:
@@ -88,10 +77,3 @@ pub fn (mut self Tailwind) destroy() ! {
pub fn switch(name string) {
tailwind4_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -4,14 +4,15 @@ import freeflowuniverse.herolib.osal.core as osal
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.core.texttools
import freeflowuniverse.herolib.core
import freeflowuniverse.herolib.osal.zinit
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.installers.ulist
import os
fn startupcmd() ![]zinit.ZProcessNewArgs {
fn startupcmd() ![]startupmanager.ZProcessNewArgs {
mut installer := get()!
mut res := []zinit.ZProcessNewArgs{}
res << zinit.ZProcessNewArgs{
mut res := []startupmanager.ZProcessNewArgs{}
res << startupmanager.ZProcessNewArgs
{
name: 'traefik'
cmd: 'traefik'
}

View File

@@ -3,75 +3,106 @@ module traefik
import freeflowuniverse.herolib.core.base
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time
__global (
traefik_global map[string]&TraefikServer
traefik_default string
)
/////////FACTORY
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
fromdb bool // will load from filesystem
create bool // default will not create if not exist
}
fn args_get(args_ ArgsGet) ArgsGet {
mut args := args_
if args.name == '' {
args.name = 'default'
}
return args
}
pub fn get(args_ ArgsGet) !&TraefikServer {
mut context := base.context()!
mut args := args_get(args_)
pub fn new(args ArgsGet) !&TraefikServer {
mut obj := TraefikServer{
name: args.name
}
if args.name !in traefik_global {
if !exists(args)! {
set(obj)!
set(obj)!
return &obj
}
pub fn get(args ArgsGet) !&TraefikServer {
mut context := base.context()!
traefik_default = args.name
if args.fromdb || args.name !in traefik_global {
mut r := context.redis()!
if r.hexists('context:traefik', args.name)! {
data := r.hget('context:traefik', args.name)!
if data.len == 0 {
return error('TraefikServer with name: traefik does not exist, prob bug.')
}
mut obj := json.decode(TraefikServer, data)!
set_in_mem(obj)!
} else {
heroscript := context.hero_config_get('traefik', args.name)!
mut obj_ := heroscript_loads(heroscript)!
set_in_mem(obj_)!
if args.create {
new(args)!
} else {
return error("TraefikServer with name 'traefik' does not exist")
}
}
return get(name: args.name)! // no longer from db nor create
}
return traefik_global[args.name] or {
println(traefik_global)
// bug if we get here because should be in globals
panic('could not get config for traefik with name, is bug:${args.name}')
return error('could not get config for traefik with name:traefik')
}
}
// register the config for the future
pub fn set(o TraefikServer) ! {
set_in_mem(o)!
traefik_default = o.name
mut context := base.context()!
heroscript := heroscript_dumps(o)!
context.hero_config_set('traefik', o.name, heroscript)!
mut r := context.redis()!
r.hset('context:traefik', o.name, json.encode(o))!
}
// does the config exists?
pub fn exists(args_ ArgsGet) !bool {
pub fn exists(args ArgsGet) !bool {
mut context := base.context()!
mut args := args_get(args_)
return context.hero_config_exists('traefik', args.name)
mut r := context.redis()!
return r.hexists('context:traefik', args.name)!
}
pub fn delete(args_ ArgsGet) ! {
mut args := args_get(args_)
pub fn delete(args ArgsGet) ! {
mut context := base.context()!
context.hero_config_delete('traefik', args.name)!
if args.name in traefik_global {
// del traefik_global[args.name]
mut r := context.redis()!
r.hdel('context:traefik', args.name)!
}
@[params]
pub struct ArgsList {
pub mut:
fromdb bool // will load from filesystem
}
// if fromdb set: load from filesystem, and not from mem, will also reset what is in mem
pub fn list(args ArgsList) ![]&TraefikServer {
mut res := []&TraefikServer{}
mut context := base.context()!
if args.fromdb {
// reset what is in mem
traefik_global = map[string]&TraefikServer{}
traefik_default = ''
}
if args.fromdb {
mut r := context.redis()!
mut l := r.hkeys('context:traefik')!
for name in l {
res << get(name: name, fromdb: true)!
}
return res
} else {
// load from memory
for _, client in traefik_global {
res << client
}
}
return res
}
// only sets in mem, does not set as config
@@ -82,6 +113,9 @@ fn set_in_mem(o TraefikServer) ! {
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'traefik.') {
return
}
mut install_actions := plbook.find(filter: 'traefik.configure')!
if install_actions.len > 0 {
for install_action in install_actions {
@@ -90,7 +124,6 @@ pub fn play(mut plbook PlayBook) ! {
set(obj2)!
}
}
mut other_actions := plbook.find(filter: 'traefik.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -131,36 +164,38 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
fn startupmanager_get(cat startupmanager.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.screen {
console.print_debug('startupmanager: zinit')
return startupmanager.get(.screen)!
}
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
return startupmanager.get(.zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
return startupmanager.get(.systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
return startupmanager.get(.auto)!
}
}
}
// load from disk and make sure is properly intialized
pub fn (mut self TraefikServer) reload() ! {
switch(self.name)
self = obj_init(self)!
}
pub fn (mut self TraefikServer) start() ! {
switch(self.name)
if self.running()! {
return
}
@@ -223,10 +258,12 @@ pub fn (mut self TraefikServer) running() !bool {
// walk over the generic processes, if not running return
for zprocess in startupcmd()! {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
if zprocess.startuptype != .screen {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
}
}
}
return running()!
@@ -253,12 +290,4 @@ pub fn (mut self TraefikServer) destroy() ! {
// switch instance to be used for traefik
pub fn switch(name string) {
traefik_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -2,8 +2,8 @@ module zola
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (
zola_global map[string]&ZolaInstaller
@@ -15,14 +15,25 @@ __global (
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
}
pub fn get(args_ ArgsGet) !&ZolaInstaller {
pub fn new(args ArgsGet) !&ZolaInstaller {
return &ZolaInstaller{}
}
pub fn get(args ArgsGet) !&ZolaInstaller {
return new(args)!
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'zola.') {
return
}
mut install_actions := plbook.find(filter: 'zola.configure')!
if install_actions.len > 0 {
return error("can't configure zola, because no configuration allowed for this installer.")
}
mut other_actions := plbook.find(filter: 'zola.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -44,28 +55,6 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
}
}
}
@[params]
pub struct InstallArgs {
pub mut:
@@ -93,10 +82,3 @@ pub fn (mut self ZolaInstaller) destroy() ! {
pub fn switch(name string) {
zola_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -0,0 +1,18 @@
module model
// a actor is a participant in the new internet, the one who can ask for work
// user can have more than one actor operating for them, an actor always operates in a context which is hosted by the hero of the user
// stored in the context db at actor:<id> (actor is hset)
@[heap]
pub struct Actor {
pub mut:
id u32
pubkey string
address []Address // address (is to reach the actor back), normally mycelium but doesn't have to be
created_at u32 // epoch
updated_at u32 // epoch
}
pub fn (self Actor) redis_key() string {
return 'actor:${self.id}'
}

View File

@@ -0,0 +1,20 @@
module model
// each job is run in a context, this corresponds to a DB in redis and has specific rights to actors
// context is a redis db and also a locaction on a filesystem which can be used for e.g. logs, temporary files, etc.
// actors create contexts for others to work in
// stored in the context db at context:<id> (context is hset)
@[heap]
pub struct Context {
pub mut:
id u32 // corresponds with the redis db (in our ourdb or other redis)
admins []u32 // actors which have admin rights on this context (means can do everything)
readers []u32 // actors which can read the context info
executors []u32 // actors which can execute jobs in this context
created_at u32 // epoch
updated_at u32 // epoch
}
pub fn (self Context) redis_key() string {
return 'context:${self.id}'
}

41
lib/mycojobs/model/flow.v Normal file
View File

@@ -0,0 +1,41 @@
module model
// what get's executed by an actor and needs to be tracked as a whole, can be represented as a DAG graph
// this is the high level representation of a workflow to execute on work, its fully decentralized and distributed
// only the actor who created the flow can modify it and holds it in DB
// stored in the context db at flow:<id> (flow is hset)
@[heap]
pub struct Flow {
pub mut:
id u32 // this job id is given by the actor who called for it
caller_id u32 // is the actor which called for this job
context_id u32 // each job is executed in a context
jobs []u32 // links to all jobs which make up this flow, this can be dynamically modified
env_vars map[string]string // they are copied to every job done
result map[string]string // the result of the flow
created_at u32 // epoch
updated_at u32 // epoch
status FlowStatus
}
pub fn (self Flow) redis_key() string {
return 'flow:${self.id}'
}
// FlowStatus represents the status of a flow
pub enum FlowStatus {
dispatched
started
error
finished
}
// str returns the string representation of FlowStatus
pub fn (self FlowStatus) str() string {
return match self {
.dispatched { 'dispatched' }
.started { 'started' }
.error { 'error' }
.finished { 'finished' }
}
}

View File

@@ -0,0 +1,68 @@
module model
// Messages is what goes over mycelium (which is our messaging system), they can have a job inside
// stored in the context db at msg:<callerid>:<id> (msg is hset)
// there are 2 queues in the context db: queue: msg_out and msg_in these are generic queues which get all messages from mycelium (in) and the ones who need to be sent (out) are in the outqueue
@[heap]
pub struct Message {
pub mut:
id u32 // is unique id for the message, has been given by the caller
caller_id u32 // is the actor whos send this message
context_id u32 // each message is for a specific context
message string
message_type ScriptType
message_format_type MessageFormatType
timeout u32 // in sec, to arrive destination
timeout_ack u32 // in sec, to acknowledge receipt
timeout_result u32 // in sec, to process result and have it back
job []Job
logs []Log // e.g. for streaming logs back to originator
created_at u32 // epoch
updated_at u32 // epoch
status MessageStatus
}
// MessageType represents the type of message
pub enum MessageType {
job
chat
mail
}
// MessageFormatType represents the format of a message
pub enum MessageFormatType {
html
text
md
}
pub fn (self Message) redis_key() string {
return 'message:${self.caller_id}:${self.id}'
}
// queue_suffix returns the queue suffix for the message type
pub fn (mt MessageType) queue_suffix() string {
return match mt {
.job { 'job' }
.chat { 'chat' }
.mail { 'mail' }
}
}
// MessageStatus represents the status of a message
pub enum MessageStatus {
dispatched
acknowledged
error
processed // e.g. can be something which comes back
}
// str returns the string representation of MessageStatus
pub fn (ms MessageStatus) str() string {
return match ms {
.dispatched { 'dispatched' }
.acknowledged { 'acknowledged' }
.error { 'error' }
.processed { 'processed' }
}
}

View File

@@ -0,0 +1,27 @@
module model
// a runner executes a job, this can be in VM, in a container or just some processes running somewhere
// the messages always come in over a topic
// stored in the context db at runner:<id> (runner is hset)
@[heap]
pub struct Runner {
pub mut:
id u32
pubkey string // from mycelium
address string // mycelium address
topic string // needs to be set by the runner but often runner<runnerid> e.g. runner20
local bool // if local then goes on redis using the id
created_at u32 // epoch
updated_at u32 // epoch
}
pub enum RunnerType {
v
python
osis
rust
}
pub fn (self Runner) redis_key() string {
return 'runner:${self.id}'
}

View File

@@ -0,0 +1,64 @@
module model
// Job represents a job, a job is only usable in the context of a runner (which is part of a hero)
// stored in the context db at job:<callerid>:<id> (job is hset)
@[heap]
pub struct RunnerJob {
pub mut:
id u32 // this job id is given by the actor who called for it
caller_id u32 // is the actor which called for this job
context_id u32 // each job is executed in a context
script string
script_type ScriptType
timeout u32 // in sec
retries u8
env_vars map[string]string
result map[string]string
prerequisites []string
dependends []u32
created_at u32 // epoch
updated_at u32 // epoch
status JobStatus
}
// ScriptType represents the type of script
pub enum ScriptType {
osis
sal
v
python
}
pub fn (self RunnerJob) redis_key() string {
return 'job:${self.caller_id}:${self.id}'
}
// queue_suffix returns the queue suffix for the script type
pub fn (st ScriptType) queue_suffix() string {
return match st {
.osis { 'osis' }
.sal { 'sal' }
.v { 'v' }
.python { 'python' }
}
}
// JobStatus represents the status of a job
pub enum JobStatus {
dispatched
waiting_for_prerequisites
started
error
finished
}
// str returns the string representation of JobStatus
pub fn (js JobStatus) str() string {
return match js {
.dispatched { 'dispatched' }
.waiting_for_prerequisites { 'waiting_for_prerequisites' }
.started { 'started' }
.error { 'error' }
.finished { 'finished' }
}
}

View File

@@ -0,0 +1,314 @@
# Models Specification
*Freeflow Universe mycojobs*
This document gathers **all datamodels** that exist in the `lib/mycojobs/model/` package, together with a concise purpose description, field semantics, Redis storage layout and the role each model plays in the overall *decentralised workflow* architecture.
## Table of Contents
1. [Actor](#actor)
2. [Context](#context)
3. [Flow](#flow)
4. [Message](#message)
5. [Runner](#runner)
6. [RunnerJob](#runnerjob)
7. [Enums & Shared Types](#enums-shared-types)
8. [Keygeneration helpers](#key-generation-helpers)
---
## <a name="actor"></a>1`Actor` Identity & entrypoint
| Field | Type | Description |
|------|------|-------------|
| `id` | `u32` | Sequential identifier **unique per tenant**. Used as part of the Redis key `actor:<id>`. |
| `pubkey` | `string` | Public key (Myceliumcompatible) that authenticates the actor when it sends/receives messages. |
| `address` | `[]Address` | One or more reachable addresses (normally Mycelium topics) that other participants can use to contact the actor. |
| `created_at` | `u32` | Unixepoch time when the record was created. |
| `updated_at` | `u32` | Unixepoch time of the last mutation. |
### Purpose
* An **Actor** is the *humanorservice* that **requests work**, receives results and can be an administrator of a **Context**.
* It is the *security principal* every operation in a context is authorised against the actors ID and its public key signature.
### Redis representation
| Key | Example | Storage type | Fields |
|-----|---------|--------------|--------|
| `actor:${id}` | `actor:12` | **hash** (`HSET`) | `id`, `pubkey`, `address` (list), `created_at`, `updated_at` |
---
## <a name="context"></a>2`Context` Tenant & permission container
| Field | Type | Description |
|------|------|-------------|
| `id` | `u32` | Identifier that also selects the underlying **Redis DB** for this tenant. |
| `admins` | `[]u32` | Actor IDs that have **full control** (create/delete any object, manage permissions). |
| `readers` | `[]u32` | Actor IDs that may **read** any object in the context but cannot modify. |
| `executors` | `[]u32` | Actor IDs allowed to **run** `RunnerJob`s and update their status. |
| `created_at` | `u32` | Unixepoch of creation. |
| `updated_at` | `u32` | Unixepoch of last modification. |
### Purpose
* A **Context** isolates a *tenant* each tenant gets its own Redis database and a dedicated filesystem area (for logs, temporary files, …).
* It stores **permission lists** that the system consults before any operation (e.g., creating a `Flow`, enqueuing a `RunnerJob`).
### Redis representation
| Key | Example | Storage type | Fields |
|-----|---------|--------------|--------|
| `context:${id}` | `context:7` | **hash** | `id`, `admins`, `readers`, `executors`, `created_at`, `updated_at` |
---
## <a name="flow"></a>3`Flow` Highlevel workflow (DAG)
| Field | Type | Description |
|------|------|-------------|
| `id` | `u32` | Flow identifier *unique inside the creators actor space*. |
| `caller_id` | `u32` | Actor that **created** the flow (owner). |
| `context_id` | `u32` | Context in which the flow lives. |
| `jobs` | `[]u32` | List of **RunnerJob** IDs that belong to this flow (the DAG edges are stored in each jobs `dependends`). |
| `env_vars` | `map[string]string` | Global environment variables injected into **every** job of the flow. |
| `result` | `map[string]string` | Aggregated output produced by the flow (filled by the orchestrator when the flow finishes). |
| `created_at` | `u32` | Creation timestamp. |
| `updated_at` | `u32` | Last update timestamp. |
| `status` | `FlowStatus` | Current lifecycle stage (`dispatched`, `started`, `error`, `finished`). |
### Purpose
* A **Flow** is the *publicfacing* representation of a **workflow**.
* It groups many `RunnerJob`s, supplies common envvars, tracks overall status and collects the final result.
* Only the *creator* (the `caller_id`) may mutate the flow definition.
### Redis representation
| Key | Example | Storage type | Fields |
|-----|---------|--------------|--------|
| `flow:${id}` | `flow:33` | **hash** | `id`, `caller_id`, `context_id`, `jobs`, `env_vars`, `result`, `created_at`, `updated_at`, `status` |
### `FlowStatus` enum
| Value | Meaning |
|-------|---------|
| `dispatched` | Flow has been stored but not yet started. |
| `started` | At least one job is running. |
| `error` | One or more jobs failed; flow aborted. |
| `finished` | All jobs succeeded, `result` is final. |
---
## <a name="message"></a>4`Message` Transport unit (Mycelium)
| Field | Type | Description |
|------|------|-------------|
| `id` |u32 `_type` | `ScriptType` | *Kind* of the message currently reused for job payloads (`osis`, `sal`, `v`, `python`). |
| `message_format_type` | `MessageFormatType` | Formatting of `message` (`html`, `text`, `md`). |
| `timeout` | `u32` | Seconds before the message is considered *lost* if not delivered. |
| `timeout_ack` | `u32` | Seconds allowed for the receiver to acknowledge. |
| `timeout_result` | `u32` | Seconds allowed for the receiver to send back a result. |
| `job` | `[]Job` | Embedded **RunnerJob** objects (normally a single job). |
| `logs` | `[]Log` | Optional streaming logs attached to the message. |
| `created_at` | `u32` | Timestamp of creation. |
| `updated_at` | `u32` | Timestamp of latest update. |
| `status` | `MessageStatus` | Current lifecycle (`dispatched`, `acknowledged`, `error`, `processed`). |
### Purpose
* `Message` is the **payload carrier** that travels over **Mycelium** (the pub/sub system).
* It can be a **job request**, a **chat line**, an **email**, or any generic data that needs to be routed between actors, runners, or services.
* Every message is persisted as a Redis hash; the system also maintains two *generic* queues:
* `msg_out` outbound messages waiting to be handed to Mycelium.
* `msg_in` inbound messages that have already arrived and are awaiting local processing.
### Redis representation
| Key | Example | Storage type | Fields |
|-----|---------|--------------|--------|
| `message:${caller_id}:${id}` | `message:12:101` | **hash** | All fields above (`id`, `caller_id`, `context_id`, …, `status`). |
### `MessageType` enum (legacy not used in current code but documented)
| Value | Meaning |
|-------|---------|
| `job` | Payload carries a `RunnerJob`. |
| `chat` | Humantohuman communication. |
| `mail` | Emaillike message. |
### `MessageFormatType` enum
| Value | Meaning |
|-------|---------|
| `html` | HTML formatted body. |
| `text` | Plaintext. |
| `md` | Markdown. |
### `MessageStatus` enum
| Value | Meaning |
|-------|---------|
| `dispatched` | Stored, not yet processed. |
| `acknowledged` | Receiver has confirmed receipt. |
| `error` | Delivery or processing failed. |
|` | Message handled (e.g., job result returned). |
---
## <a name="runner"></a>5`Runner` Worker that executes jobs
| Field | Type | Description |
|------|------|-------------|
| `id` | `u32` | Unique runner identifier. |
| `pubkey` | `string` | Public key of the runner (used by Mycelium for auth). |
| `address` | `string` | Mycelium address (e.g., `mycelium://…`). |
| `topic` | `string` | Pub/Sub topic the runner subscribes to; defaults to `runner${id}`. |
| `local` | `bool` | If `true`, the runner also consumes jobs directly from **Redis queues** (e.g., `queue:v`). |
| `created_at` | `u32` | Creation timestamp. |
| `updated_at` | `u32` | Last modification timestamp. |
### Purpose
* A **Runner** is the *execution engine* it could be a VM, a container, or a process that knows how to run a specific script type (`v`, `python`, `osis`, `rust`).
* It **subscribes** to a Mycelium topic to receive jobrelated messages, and, when `local==true`, it also **polls** a Redis list named after the scripttype (`queue:<suffix>`).
### Redis representation
| Key | Example | Storage type |
|-----|---------|--------------|
| `runner:${id}` | `runner:20` | **hash** *(all fields above)* |
### `RunnerType` enum
| Value | Intended runtime |
|-------|------------------|
| `v` | V language VM |
| `python` | CPython / PyPy |
| `osis` | OSISspecific runtime |
| `rust` | Native Rust binary |
---
## <a name="runnerjob"></a>6`RunnerJob` Executable unit
| Field | Type | Description |
|------|------|-------------|
| `id` | `u32` | Job identifier **provided by the caller**. |
| `caller_id` | `u32` | Actor that created the job. |
| `context_id` | `u32` | Context in which the job will run. |
| `script` | `string` | Source code / command to be executed. |
| `script_type` | `ScriptType` | Language or runtime of the script (`osis`, `sal`, `v`, `python`). |
| `timeout` | `u32` | Maximum execution time (seconds). |
| `retries` | `u8` | Number of automatic retries on failure. |
| `env_vars` | `map[string]string` | Jobspecific environment variables (merged with `Flow.env_vars`). |
| `result` | `map[string]string` | Keyvalue map that the job writes back upon completion. |
| `prerequisites` | `[]string` | Humanreadable IDs of **external** prerequisites (e.g., files, other services). |
| `dependends` | `[]u32` | IDs of **other RunnerJob** objects that must finish before this job can start. |
| `created_at` | `u32` | Creation timestamp. |
| `updated_at` | `u32` | Last update timestamp. |
| `status` | `JobStatus` | Lifecycle status (`dispatched`, `waiting_for_prerequisites`, `started`, `error`, `finished`). |
### Purpose
* A **RunnerJob** is the *atomic piece of work* that a `Runner` executes.
* It lives inside a **Context**, is queued according to its `script_type`, and moves through a welldefined **state machine**.
* The `dependends` field enables the *DAG* behaviour that the `Flow` model represents at a higher level.
### Redis representation
| Key | Example | Storage type |
|-----|---------|--------------|
| `job:${caller_id}:${id}` | `job:12:2001` | **hash** *(all fields above)* |
### `ScriptType` enum
| Value | Runtime |
|-------|---------|
| `osis` | OSIS interpreter |
| `sal` | SAL DSL (custom) |
| `v` | V language |
| `python`| CPython / PyPy |
*The enum provides a **`queue_suffix()`** helper that maps a script type to the name of the Redis list used for local job dispatch (`queue:python`, `queue:v`, …).*
### `JobStatus` enum
| Value | Meaning |
|-------|---------|
| `dispatched` | Stored, waiting to be examined for prerequisites. |
| `waiting_for_prerequisites` | Has `dependends` that are not yet finished. |
| `started` | Currently executing on a runner. |
| `error` | Execution failed (or exceeded retries). |
| `finished` | Successfully completed, `result` populated. |
---
## <a name="enums-shared-types"></a>7Other Enums & Shared Types
| Enum | Location | Values | Note |
|------|----------|--------|------|
| `MessageType` | `message.v` | `job`, `chat`, `mail` | Determines how a `Message` is interpreted. |
| `MessageFormatType` | `message.v` | `html`, `text`, `md` | UIlayer rendering hint. |
| `MessageStatus` | `message.v` | `dispatched`, `acknowledged`, `error`, `processed` | Lifecycle of a `Message`. |
| `FlowStatus` | `flow.v` | `dispatched`, `started`, `error`, `finished` | Highlevel flow progress. |
| `RunnerType` | `runner.v` | `v`, `python`, `osis`, `rust` | Not currently stored; used by the orchestration layer to pick a runner implementation. |
| `ScriptType` | `runnerjob.v` | `osis`, `sal`, `v`, `python` | Determines queue suffix & runtime. |
| `JobStatus` | `runnerjob.v` | `dispatched`, `waiting_for_prerequisites`, `started`, `error`, `finished` | Perjob state machine. |
---
## <a name="key-generation-helpers"></a>8Keygeneration helpers (methods)
| Model | Method | Returns | Example |
|-------|--------|---------|---------|
| `Actor` | `redis_key()` | `"actor:${self.id}"` | `actor:12` |
| `Context` | `redis_key()` | `"context:${self.id}"` | `context:7` |
| `Flow` | `redis_key()` | `"flow:${self.id}"` | `flow:33` |
| `Message` | `redis_key()` | `"message:${self.caller_id}:${self.id}"` | `message:12:101` |
| `Runner` | `redis_key()` | `"runner:${self.id}"` | `runner:20` |
| `RunnerJob` | `redis_key()` | `"job:${self.caller_id}:${self.id}"` | `job:12:2001` |
| `MessageType` | `queue_suffix()` | `"job"` / `"chat"` / `"mail"` | `MessageType.job.queue_suffix() → "job"` |
| `ScriptType` | `queue_suffix()` | `"osis"` / `"sal"` / `"v"` / `"python"` | `ScriptType.python.queue_suffix() → "python"` |
These helpers guarantee **canonical key naming** throughout the code base and simplify Redis interactions.
---
## 📌Summary Diagram (quick reference)
```mermaid
%%{init: {"theme":"dark"}}%%
graph TD
%% Actors and what they can create
A[Actor] -->|creates| Ctx[Context]
A -->|creates| Fl[Flow]
A -->|creates| Msg[Message]
A -->|creates| Rnr[Runner]
A -->|creates| Job[RunnerJob]
%% All objects live inside one Redis DB that belongs to a Context
subgraph "Redis DB (per Context)"
Ctx
A
Fl
Msg
Rnr
Job
end
%% Messaging queues (global, outside the Context DB)
Msg -->|pushes key onto| OutQ[msg_out]
OutQ -->|transport via Mycelium| InQ[msg_in]
InQ -->|pulled by| Rnr
%% Local runner queues (only when runner.local == true)
Rnr -->|BRPOP from| QueueV["queue:v"]
Rnr -->|BRPOP from| QueuePy["queue:python"]
Rnr -->|BRPOP from| QueueOSIS["queue:osis"]
```
## context based
* Inside a Context, an **Actor** can create a **Flow** that references many **RunnerJob** IDs (the DAG).
* To *initiate* execution, the Actor packages a **RunnerJob** (or a full Flow) inside a **Message**, pushes it onto `msg_out`, and the system routes it via **Mycelium** to the target Context.
* The remote **Runner** receives the Message, materialises the **RunnerJob**, queues it on a scripttype list, executes it, writes back `result` and status, and optionally sends a *result Message* back to the originator.
All state is persisted as **Redis hashes**, guaranteeing durability and enabling *idempotent* retries. The uniform naming conventions (`actor:<id>`, `job:<caller_id>:<id>`, …) make it trivial to locate any object given its identifiers.

263
lib/mycojobs/specs/specs.md Normal file
View File

@@ -0,0 +1,263 @@
## Objects Used
| Component | What it **stores** | Where it lives (Redis key) | Main responsibilities |
|------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Actor** | Public key, reachable addresses, timestamps | `actor:<id>` (hash) | An identity that can request work, receive results and act as an administrator of a *Context*. |
| **Context**| Permission lists (`admins`, `readers`, `executors`), timestamps | `context:<id>` (hash) | An isolated “tenant” a separate Redis DB and filesystem area. All objects (flows, messages, jobs, runners) belonging to a given workflow are stored under this context. The permission lists control who may read, execute or administer the context. |
| **Flow** | DAG of job IDs, envvars, result map, status, timestamps | `flow:<id>` (hash) | A highlevel workflow created by a single **Actor**. It groups many **RunnerJob** objects, records their execution order, supplies common environment variables and aggregates the final result. |
| **Message**| Payload, type (`job\|chat\|mail`), format (`html\|text\|md`), timeouts, embedded **Job** objects, log stream, status, timestamps | `message:<caller_id>:<id>` (hash) | The transport unit that travels over **Mycelium** (the pub/sub/message bus). A message can contain a **RunnerJob** (or a list of jobs) and is queued in two generic Redis lists: `msg_out` (to be sent) and `msg_in` (already received). |
| **Runner** | Public key, Mycelium address, topic name, type (`v\|python\|osis\|rust`), local flag, timestamps | `runner:<id>` (hash) | The *worker* that actually executes **RunnerJob** scripts. It subscribes to a Mycelium topic (normally `runner<id>`). If `local == true` the runner also consumes jobs directly from a Redis queue that is named after the scripttype suffix (`v`, `python`, …). |
| **RunnerJob**| Script source, type (`osis\|sal\|v\|python`), envvars, prerequisites, dependencies, status, timestamps, result map | `job:<caller_id>:<id>` (hash) | A single executable unit. It lives inside a **Context**, belongs to a **Runner**, and is queued according to its `script_type` (e.g. `queue:python`). Its status moves through the lifecycle `dispatched → waiting_for_prerequisites → started → finished|error`. |
> **Key idea:** All objects are persisted as *hashes* in a **Redis** database that is dedicated to a *Context*. The system is completely **decentralised** each actor owns its own context and can spin up as many runners as needed. Communication between actors, runners and the rest of the system happens over **Mycelium**, a messagebus that uses Redis lists as queues.
---
## Interaction diagram (who talks to who)
### Sequence diagram “Submit a flow and run it”
```mermaid
%%{init: {"theme":"dark"}}%%
sequenceDiagram
participant A as Actor
participant L as LocalContext (Redis)
participant M as Mycelium (msg_out / msg_in)
participant R as RemoteContext (Redis)
participant W as Runner (worker)
%% 1. Actor creates everything locally
A->>L: create Flow + RunnerJob (J)
A->>L: LPUSH msg_out Message{type=job, payload=J, target=Remote}
%% 2. Mycelium transports the message
M->>R: LPUSH msg_in (Message key)
%% 3. Remote context materialises the job
R->>R: HSET Message hash
R->>R: HSET RunnerJob (J') // copy of payload
R->>R: LPUSH queue:v (job key)
%% 4. Runner consumes and executes
W->>R: BRPOP queue:v (job key)
W->>R: HSET job status = started
W->>W: execute script
W->>R: HSET job result + status = finished
%% 5. Result is sent back
W->>M: LPUSH msg_out Message{type=result, payload=result, target=Local}
M->>L: LPUSH msg_in (result Message key)
%% 6. Actor receives the result
A->>L: RPOP msg_in → read result
```
### 2.2Component diagram “Static view of objects & links”
```mermaid
%%{init: {"theme":"dark"}}%%
graph LR
subgraph Redis["Redis (per Context)"]
A[Actor] -->|stores| Ctx[Context]
Ctx -->|stores| Fl[Flow]
Ctx -->|stores| Msg[Message]
Ctx -->|stores| Rnr[Runner]
Ctx -->|stores| Job[RunnerJob]
end
subgraph Mycelium["Mycelium (Pub/Sub)"]
MsgOut["queue:msg_out"] -->|outgoing| Mcel[Mycelium Bus]
Mcel -->|incoming| MsgIn["queue:msg_in"]
RnrTopic["topic:runnerX"] -->|subscribed by| Rnr
queueV["queue:v"] -->|local jobs| Rnr
queuePython["queue:python"] -->|local jobs| Rnr
end
A -->|creates / reads| Fl
A -->|creates / reads| Msg
A -->|creates / reads| Rnr
A -->|creates / reads| Job
Fl -->|references| Job
Msg -->|may embed| Job
Rnr -->|executes| Job
Job -->|updates| Fl
Msg -->|carries result back to| A
```
### 2.3Flowstatus lifecycle (state diagram)
```mermaid
%%{init: {"theme":"dark"}}%%
stateDiagram-v2
[*] --> dispatched
dispatched --> waiting_for_prerequisites : has prereqs
waiting_for_prerequisites --> started : prereqs met
dispatched --> started : no prereqs
started --> finished : success
started --> error : failure
waiting_for_prerequisites --> error : timeout / impossible
error --> [*]
finished --> [*]
```
---
## 3Redis objects concrete key & data layout
All objects are stored as **hashes** (`HSET`). Below is a concise catalog that can be copied into a design doc.
| Key pattern | Example | Fields (type) | Comments |
|-------------|---------|---------------|----------|
| `actor:${id}` | `actor:12` | `id`u32, `pubkey`str, `address`list\<Address\>, `created_at`u32, `updated_at`u32 | One hash per actor. |
| `context:${id}` | `context:7` | `id`u32, `admins`list\<u32\>, `readers`list\<u32\>, `executors`list\<u32\>, `created_at`u32, `updated_at`u32 | Holds permission lists for a tenant. |
| `flow:${id}` | `flow:33` | `id`u32, `caller_id`u32, `context_id`u32, `jobs`list\<u32\>, `env_vars`map\<str,str\>, `result`map\<str,str\>, `created_at`u32, `updated_at`u32, `status`str (`dispatched|started|error|finished`) |
| `message:${caller_id}:${id}` | `message:12:101` | `id`u32, `caller_id`u32, `context_id`u32, `message`str, `message_type`str (`job|chat|mail`), `message_format_type`str (`html|text|md`), `timeout`u32, `timeout_ack`u32, `timeout_result`u32, `job`list\<RunnerJob\> (serialized), `logs`list\<Log\>, `created_at`u32, `updated_at`u32, `status`str (`dispatched|acknowledged|error|processed`) |
| `runner:${id}` | `runner:20` | `id`u32, `pubkey`str, `address`str, `topic`str, `local`bool, `created_at`u32, `updated_at`u32 |
| `job:${caller_id}:${id}` | `job:12:2001` | `id`u32, `caller_id`u32, `context_id`u32, `script`str, `script_type`str (`osis|sal|v|python`), `timeout`u32, `retries`u8, `env_vars`map\<str,str\>, `result`map\<str,str\>, `prerequisites`list\<str\>, `dependends`list\<u32\>, `created_at`u32, `updated_at`u32, `status`str (`dispatched|waiting_for_prerequisites|started|error|finished`) |
#### Queue objects (lists)
| Queue name | Purpose |
|------------|---------|
| `msg_out` | **Outbound** generic queue every `Message` that an actor wants to send is pushed here. |
| `msg_in` | **Inbound** generic queue every message received from Mycelium is placed here for the local consumer to process. |
| `queue:${suffix}` (e.g. `queue:v`, `queue:python`) | Local job queues used by a **Runner** when `local == true`. The suffix comes from `ScriptType.queue_suffix()`. |
---
## 4System specification (as a concise “specs” section)
### 4.1Naming conventions
* All Redis **hashes** are prefixed with the object name (`actor:`, `context:`, …).
* All **queues** are simple Redis lists (`LPUSH` / `RPOP`).
* **Message** keys embed both the *caller* and a locally unique *message id* this guarantees global uniqueness across contexts.
### 4.2Permissions & security
* Only IDs present in `Context.admins` may **create** or **delete** any object inside that context.
* `Context.readers` can **GET** any hash but not modify it.
* `Context.executors` are allowed to **update** `RunnerJob.status`, `result` and to **pop** from local job queues.
* Every `Actor` must present a `pubkey` that can be verified by the receiving side (Mycelium uses asymmetric crypto).
### 4.3Message flow (publish / consume)
Below is a **rewritten “Message flow (publish/consume)”** that reflects the real runtime components:
* **Supervisordaemon** runs on the node that owns the **Flow** (the *actors* side).
It is the only process that ever **RPOP**s from the global `msg_out` queue, adds the proper routing information and hands the message to **Mycelium**.
* **Mycelium** the pure pub/sub/messagebus. It never touches Redis directly; it only receives a *payload key* from the coordinator and delivers that key to the remote tenants `msg_in` list.
* **Remoteside runner / service** consumes from its own `msg_in`, materialises the job and executes it.
The table now uses the exact component names and adds a short note about the permission check that the coordinator performs before it releases a message.
| # | Action (what the system does) | Component that performs it | Redis interaction (exact commands) |
|---|-------------------------------|----------------------------|------------------------------------|
| **1Publish** | Actor creates a `Message` hash and **LPUSH**es its key onto the *outbound* queue. | **Actor** (client code) | `HSET message:12:101 …` <br/> `LPUSH msg_out message:12:101` |
| **2Coordinate & route** | The **Supervisor daemon** (running at source) **RPOP**s the key, checks the actors permissions, adds the *targetcontext* and *topic* fields, then forwards the key to Mycelium. | **Supervisor daemon** (peractor) | `RPOP msg_out` → (inprocess) → `LPUSH msg_out_coordinator <key>` (internal buffer) |
| **3Transport** | Mycelium receives the key, looks at `Message.message_type` (or the explicit `topic`) and pushes the key onto the *inbound* queue of the **remote** tenant. | **Mycelium bus** (network layer) | `LPUSH msg_in:<remotectx> <key>` |
| **4Consume** | The **Remote side** (runner or service) **RPOP**s from its `msg_in`, loads the full hash, verifies the actors signature and decides what to do based on `message_type`. | **Remote consumer** (runner/service | `RPOP msg_in:<remotectx>``HGETALL message:<key>` |
| **5Job materialisation** | If `message_type == "job"` the consumer creates a **RunnerJob** entry inside the **remote** context, adds the job **key** to the proper *scripttype* queue (`queue:v`, `queue:python`, …). | **Remote consumer** | `HSET job:<caller_id>:<job_id> …` <br/> `LPUSH queue:<script_type> job:<caller_id>:<job_id>` |
| **6Runner execution loop** | A **Runner** attached to that remote context **BRPOP**s from its scripttype queue, sets `status = started`, runs the script, writes `result` and final `status`. | **Runner** | `BRPOP queue:<script_type>``HSET job:<…> status started` → … → `HSET job:<…> result … status finished` |
| **7Result notification** | The runner builds a new `Message` (type `chat`, `result`, …) and pushes it onto **msg_out** again. The **Supervisor daemon** on the *originating* side will later pick it up and route it back to the original actor. | **Runner****Supervisor (remote side)****Mycelium****Supervisor (origin side)****Actor** | `HSET message:<res_key> …` <br/> `LPUSH msg_out message:<res_key>` (steps 23 repeat in reverse direction) |
---
## Tiny endtoend sequence (still simple enough to render)
```mermaid
%%{init: {"theme":"dark"}}%%
sequenceDiagram
participant A as Actor
participant L as LocalRedis (Flow ctx)
participant C as Supervisor daemon (local)
participant M as Mycelium bus
participant R as RemoteRedis (target ctx)
participant W as Runner (remote)
%% 1⃣ publish
A->>L: HSET message:12:101 …
A->>L: LPUSH msg_out message:12:101
%% 2⃣ coordinate
C->>L: RPOP msg_out
C->>C: check permissions / add routing info
C->>M: push key to Mycelium (msg_out_coordinator)
%% 3⃣ transport
M->>R: LPUSH msg_in message:12:101
%% 4⃣ consume
R->>W: RPOP msg_in
R->>R: HGETALL message:12:101
R->>R: verify signature
alt message_type == job
R->>R: HSET job:12:2001 …
R->>R: LPUSH queue:v job:12:2001
end
%% 5⃣ runner loop
W->>R: BRPOP queue:v (job:12:2001)
W->>R: HSET job:12:2001 status started
W->>W: execute script
W->>R: HSET job:12:2001 result … status finished
%% 6⃣ result back
W->>R: HSET message:12:900 result …
W->>R: LPUSH msg_out message:12:900
C->>M: (coordinator on remote side) routes back
M->>L: LPUSH msg_in message:12:900
A->>L: RPOP msg_in → read result
```
## 5What the **system** is trying to achieve
| Goal | How it is realized |
|------|--------------------|
| **Decentralised execution** | Every *actor* owns a **Context**; any number of **Runners** can be attached to that context, possibly on different machines, and they all talk over the same Mycelium/Redis backend. |
| **Finegrained permissions** | `Context.admins/readers/executors` enforce who can create, view or run jobs. |
| **Loose coupling via messages** | All actions (job submission, result propagation, chat, mail …) use the generic `Message` object; the same transport pipeline handles all of them. |
| **Workflow orchestration** | The **Flow** object models a DAG of jobs, tracks collective status and aggregates results, without needing a central scheduler. |
| **Pluggable runtimes** | `ScriptType` and `RunnerType` let a runner choose the proper execution environment (V, Python, OSIS, Rust, …) adding a new language only means adding a new `ScriptType` and a corresponding worker. |
| **Observability** | `Log` arrays attached to a `Message` and the timestamps on every hash give a complete audit trail. |
| **Resilience** | Jobs are idempotent hash entries; queues are persisted in Redis, and status changes are atomic (`HSET`). Retries and timeouts guarantee eventual consistency. |
---
## 6Diagram summary (quick visual cheatsheet)
```mermaid
%%{init: {"theme":"dark"}}%%
graph TD
A[Actor] -->|creates| Ctx[Context]
A -->|creates| Flow
A -->|creates| Msg
A -->|creates| Rnr[Runner]
A -->|creates| Job[RunnerJob]
subgraph Redis["Redis (per Context)"]
Ctx --> A
Ctx --> Flow
Ctx --> Msg
Ctx --> Rnr
Ctx --> Job
end
Msg -->|push to| OutQ[msg_out]
OutQ --> Myc[Mycelium Bus]
Myc -->|deliver| InQ[msg_in]
InQ --> Rnr
Rnr -->|pop from| Qv["queue:v"]
Rnr -->|pop from| Qpy["queue:python"]
Rnr -->|updates| Job
Job -->|updates| Flow
Flow -->|result Message| Msg
```

View File

@@ -5,7 +5,8 @@ import freeflowuniverse.herolib.core.texttools
// import freeflowuniverse.herolib.screen
import os
import time
import freeflowuniverse.herolib.ui.console
// import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.osal.core as osal
@[heap]
pub struct ScreensFactory {
@@ -54,11 +55,12 @@ pub fn (mut self ScreensFactory) scan() ! {
return
}
// there is stuff to parses
// println(res.output)
res1 := texttools.remove_empty_lines(res.output)
.split_into_lines()
.filter(it.starts_with(' ') || it.starts_with('\t'))
.join_lines()
// println(res1)
mut res2 := texttools.to_list_map('pre,state', res1, '').map(init_screen_object(it))
for mut item in res2 {
if self.exists(item.name) {
@@ -105,7 +107,6 @@ pub fn (mut self ScreensFactory) add(args_ ScreenAddArgs) !Screen {
mut myscreen := self.get(args.name) or {
return error('couldnt start screen with name ${args.name}, was not found afterwards.\ncmd:${args.cmd}\nScreens found.\n${self.str()}')
}
if args.attach {
myscreen.attach()!
}
@@ -133,19 +134,23 @@ pub fn (mut self ScreensFactory) get(name string) !Screen {
}
pub fn (mut self ScreensFactory) start(name string) ! {
mut s := self.get(name) or {
return error("can't start screen with name:${name}, couldn't find.\nScreens found.\n${self.str()}")
}
s.start_()!
osal.sleep(1)
for {
self.scan()!
mut s2 := self.get(name) or {
return error('couldnt start screen with name ${name}, was not found in screen scan.\ncmd:\n${s.cmd}\nScreens found.\n${self.str()}')
}
if s2.pid > 0 {
return
}
console.print_debug(s2.str())
time.sleep(100000)
}
}

View File

@@ -0,0 +1,39 @@
module startupmanager
pub enum StartupManagerType {
unknown
screen
zinit
tmux
systemd
auto
}
@[params]
pub struct ZProcessNewArgs {
pub mut:
name string @[required]
cmd string @[required]
cmd_stop string // command to stop (optional)
cmd_test string // command line to test service is running
workdir string // where to execute the commands
after []string // list of service we depend on
env map[string]string
oneshot bool
start bool = true
restart bool = true // whether the process should be restarted on failure
description string // not used in zinit
startuptype StartupManagerType
}
fn startup_manager_type_get(c string) StartupManagerType {
match c {
"unknown" { return .unknown }
"screen" { return .screen }
"zinit" { return .zinit }
"tmux" { return .tmux }
"systemd" { return .systemd }
"auto" { return .auto }
else { return .unknown }
}
}

View File

@@ -1,16 +1,232 @@
# startup manager
# Startup Manager
```go
The `startupmanager` module provides a unified interface for managing processes across different underlying startup systems like `screen`, `systemd`, and `zinit`. It abstracts away the complexities of each system, allowing you to start, stop, restart, delete, and query the status of processes using a consistent API.
## How it Works
The `StartupManager` struct acts as a facade, delegating calls to the appropriate underlying startup system based on the `StartupManagerType` configured or automatically detected.
When you create a new `StartupManager` instance using `startupmanager.get()`, it attempts to detect if `zinit` is available on the system. If `zinit` is found, it will be used as the default startup manager. Otherwise, it falls back to `screen`. You can also explicitly specify the desired `StartupManagerType` during initialization.
The `ZProcessNewArgs` struct defines the parameters for creating and managing a new process.
## Usage
### Initializing the Startup Manager
You can initialize the `StartupManager` in a few ways:
1. **Automatic Detection (Recommended):**
The manager will automatically detect if `zinit` is available and use it, otherwise it defaults to `screen`.
```v
import freeflowuniverse.herolib.osal.startupmanager
fn main() {
mut sm := startupmanager.get(cat:.screen)!
// sm.cat will be .zinit or .screen
println("Using startup manager: ${sm.cat}")
}
```
2. **Explicitly Specify Type:**
You can force the manager to use a specific type.
```v
import freeflowuniverse.herolib.osal.startupmanager
fn main() {
mut sm_zinit := startupmanager.get(cat: .zinit)!
println("Using startup manager: ${sm_zinit.cat}")
mut sm_screen := startupmanager.get(cat: .screen)!
println("Using startup manager: ${sm_screen.cat}")
mut sm_systemd := startupmanager.get(cat: .systemd)!
println("Using startup manager: ${sm_systemd.cat}")
}
```
### Managing Processes
The following examples demonstrate how to use the `StartupManager` to interact with processes. The `new` method takes a `ZProcessNewArgs` struct to define the process.
#### `new(args ZProcessNewArgs)`: Launch a new process
This method creates and optionally starts a new process.
```v
import freeflowuniverse.herolib.osal.startupmanager
mut sm:=startupmanager.get()!
fn main() {
mut sm := startupmanager.get()!
sm.start(
name: 'myscreen'
cmd: 'htop'
description: '...'
)!
// Example: Starting a simple web server with zinit
sm.new(
name: "my_web_server"
cmd: "python3 -m http.server 8000"
start: true
restart: true
description: "A simple Python HTTP server"
startuptype: .zinit // Explicitly use zinit for this process
)!
println("Web server 'my_web_server' started with ${sm.cat}")
// Example: Starting a long-running script with screen
sm.new(
name: "my_background_script"
cmd: "bash -c 'while true; do echo Hello from script; sleep 5; done'"
start: true
restart: true
startuptype: .screen // Explicitly use screen for this process
)!
println("Background script 'my_background_script' started with ${sm.cat}")
// Example: Starting a systemd service (requires root privileges and proper systemd setup)
// This assumes you have a systemd unit file configured for 'my_systemd_service'
// For example, a file like /etc/systemd/system/my_systemd_service.service
// [Unit]
// Description=My Systemd Service
// After=network.target
//
// [Service]
// ExecStart=/usr/bin/python3 -m http.server 8080
// Restart=always
//
// [Install]
// WantedBy=multi-user.target
sm.new(
name: "my_systemd_service"
cmd: "python3 -m http.server 8080" // This command is used to generate the unit file if it doesn't exist
start: true
restart: true
startuptype: .systemd
)!
println("Systemd service 'my_systemd_service' created/started with ${sm.cat}")
}
```
#### `start(name string)`: Start a process
Starts an existing process.
```v
import freeflowuniverse.herolib.osal.startupmanager
fn main() {
mut sm := startupmanager.get()!
sm.start("my_web_server")!
println("Process 'my_web_server' started.")
}
```
#### `stop(name string)`: Stop a process
Stops a running process.
```v
import freeflowuniverse.herolib.osal.startupmanager
fn main() {
mut sm := startupmanager.get()!
sm.stop("my_web_server")!
println("Process 'my_web_server' stopped.")
}
```
#### `restart(name string)`: Restart a process
Restarts a process.
```v
import freeflowuniverse.herolib.osal.startupmanager
fn main() {
mut sm := startupmanager.get()!
sm.restart("my_web_server")!
println("Process 'my_web_server' restarted.")
}
```
#### `delete(name string)`: Delete a process
Removes a process from the startup manager.
```v
import freeflowuniverse.herolib.osal.startupmanager
fn main() {
mut sm := startupmanager.get()!
sm.delete("my_web_server")!
println("Process 'my_web_server' deleted.")
}
```
#### `status(name string) !ProcessStatus`: Get process status
Returns the current status of a process.
```v
import freeflowuniverse.herolib.osal.startupmanager
fn main() {
mut sm := startupmanager.get()!
status := sm.status("my_web_server")!
println("Status of 'my_web_server': ${status}")
}
```
#### `running(name string) !bool`: Check if process is running
Returns `true` if the process is active, `false` otherwise.
```v
import freeflowuniverse.herolib.osal.startupmanager
fn main() {
mut sm := startupmanager.get()!
is_running := sm.running("my_web_server")!
println("Is 'my_web_server' running? ${is_running}")
}
```
#### `output(name string) !string`: Get process output
Retrieves the output (logs) of a process. Currently supported for `systemd`.
```v
import freeflowuniverse.herolib.osal.startupmanager
fn main() {
mut sm := startupmanager.get(startupmanager.StartupManagerArgs{cat: .systemd})!
output := sm.output("my_systemd_service")!
println("Output of 'my_systemd_service':\n${output}")
}
```
#### `exists(name string) !bool`: Check if process exists
Returns `true` if the process is known to the startup manager, `false` otherwise.
```v
import freeflowuniverse.herolib.osal.startupmanager
fn main() {
mut sm := startupmanager.get()!
does_exist := sm.exists("my_web_server")!
println("Does 'my_web_server' exist? ${does_exist}")
}
```
#### `list() ![]string`: List all managed services
Returns a list of names of all services managed by the startup manager.
```v
import freeflowuniverse.herolib.osal.startupmanager
fn main() {
mut sm := startupmanager.get()!
services := sm.list()!
println("Managed services: ${services}")
}

View File

@@ -7,7 +7,7 @@ import freeflowuniverse.herolib.osal.zinit
// // TODO: check if using this interface would simplify things
// pub interface StartupManagerI {
// new(args zinit.ZProcessNewArgs)!
// new(args startupmanager.ZProcessNewArgs)!
// start(name string)!
// stop(name string)!
// restart(name string)!
@@ -19,35 +19,32 @@ import freeflowuniverse.herolib.osal.zinit
// list_services() ![]string
// }
pub enum StartupManagerType {
unknown
screen
zinit
tmux
systemd
}
pub struct StartupManager {
pub mut:
cat StartupManagerType
}
@[params]
pub struct StartupManagerArgs {
pub mut:
cat StartupManagerType
}
// @[params]
// pub struct StartupManagerArgs {
// pub mut:
// cat StartupManagerType
// }
pub fn get(args StartupManagerArgs) !StartupManager {
pub fn get(cat StartupManagerType) !StartupManager {
console.print_debug('startupmanager get ${cat}')
mut sm := StartupManager{
cat: args.cat
cat: cat
}
if args.cat == .unknown {
if sm.cat == .auto {
if zinit.check() {
sm.cat = .zinit
} else {
sm.cat = .screen
}
}
if sm.cat == .unknown {
print_backtrace()
return error("can't determine startup manager type, need to be a known one.")
}
return sm
}
@@ -67,12 +64,9 @@ pub fn get(args StartupManagerArgs) !StartupManager {
// restart bool = true // whether the process should be restarted on failure
// description string //not used in zinit
//```
pub fn (mut sm StartupManager) new(args zinit.ZProcessNewArgs) ! {
pub fn (mut sm StartupManager) new(args ZProcessNewArgs) ! {
console.print_debug("startupmanager start:${args.name} cmd:'${args.cmd}' restart:${args.restart}")
mut mycat := sm.cat
if args.startuptype == .systemd {
mycat = .systemd
}
match mycat {
.screen {
mut scr := screen.new(reset: false)!
@@ -83,40 +77,33 @@ pub fn (mut sm StartupManager) new(args zinit.ZProcessNewArgs) ! {
// console.print_debug('systemd start ${args.name}')
mut systemdfactory := systemd.new()!
systemdfactory.new(
cmd: args.cmd
name: args.name
description: args.description
start: args.start
restart: args.restart
env: args.env
cmd: args.cmd
name: args.name
start: args.start
restart: args.restart
env: args.env
)!
}
.zinit {
console.print_debug('zinit start ${args.name}')
mut zinitfactory := zinit.new()!
// pub struct ZProcessNewArgs {
// name string @[required]
// cmd string @[required]
// cmd_stop string
// cmd_test string
// cmd_file bool // if we wanna force to run it as a file which is given to bash -c (not just a cmd in zinit)
// test string
// test_file bool
// after []string
// env map[string]string
// oneshot bool
// }
zinitfactory.new(args)!
zinitfactory.new(
name: args.name
cmd: args.cmd
cmd_stop: args.cmd_stop
cmd_test: args.cmd_test
workdir: args.workdir
after: args.after
env: args.env
oneshot: args.oneshot
start: args.start
restart: args.restart
)!
}
else {
panic('to implement, startup manager only support screen & systemd for now: ${mycat}')
}
}
// if args.start {
// sm.start(args.name)!
// } else if args.restart {
// sm.restart(args.name)!
// }
}
pub fn (mut sm StartupManager) start(name string) ! {
@@ -309,7 +296,7 @@ pub fn (mut sm StartupManager) output(name string) !string {
}
pub fn (mut sm StartupManager) exists(name string) !bool {
println(sm.cat)
if sm.cat == .unknown {
if zinit.check() {
sm.cat = .zinit
@@ -359,30 +346,3 @@ pub fn (mut sm StartupManager) list() ![]string {
}
}
}
// THIS IS PROBABLY PART OF OTHER MODULE NOW
// pub struct SecretArgs {
// pub mut:
// name string @[required]
// cat SecretType
// }
// pub enum SecretType {
// normal
// }
// // creates a secret if it doesn exist yet
// pub fn (mut sm StartupManager) secret(args SecretArgs) !string {
// if !(sm.exists(args.name)) {
// return error("can't find screen with name ${args.name}, for secret")
// }
// key := 'secrets:startup:${args.name}'
// mut redis := redisclient.core_get()!
// mut secret := redis.get(key)!
// if secret.len == 0 {
// secret = rand.hex(16)
// redis.set(key, secret)!
// }
// return secret
// }

View File

@@ -1,224 +0,0 @@
# Implementation Plan: Zinit OpenRPC Client Refactoring
## Current State Analysis
- Multiple implementations (zinit.v, zinit_stateless.v, rpc.v, zprocess.v)
- Inconsistent use of OpenRPC vs. direct filesystem operations
- Duplication of functionality across multiple files
- Lack of a unified approach
## Implementation Plan
### Phase 1: Create a New Unified OpenRPC Client
1. Create a new file `zinit_client.v` with a unified `ZinitClient` struct
2. Implement all methods using the OpenRPC protocol exclusively
3. Ensure the client handles all error cases properly
4. Add comprehensive documentation for all methods
```mermaid
graph TD
A[Create New OpenRPC Client] --> B[Implement Core Client Methods]
B --> C[Implement Service Management Methods]
C --> D[Implement Configuration Management Methods]
D --> E[Implement System Operations Methods]
E --> F[Implement Logging Methods]
```
### Phase 2: Refactor Existing Implementations
1. Refactor `ZinitStateless` to use the new client for all operations
2. Refactor `Zinit` to use the new client for all operations
3. Refactor `ZProcess` to use the new client for all operations
4. Update factory methods to use the new client
5. Ensure backward compatibility by maintaining the same API/interface
```mermaid
graph TD
A[Refactor ZinitStateless] --> B[Refactor Zinit]
B --> C[Refactor ZProcess]
C --> D[Update Factory Methods]
D --> E[Ensure Backward Compatibility]
```
### Phase 3: Update Tests and Examples
1. Update existing tests to use the new client
2. Add new tests to cover all OpenRPC methods
3. Update examples to demonstrate the new client
4. Create new examples to showcase best practices
```mermaid
graph TD
A[Update Unit Tests] --> B[Update Integration Tests]
B --> C[Update Examples]
C --> D[Create New Examples]
```
### Phase 4: Documentation and Cleanup
1. Update the README with comprehensive documentation
2. Add detailed API documentation for all methods
3. Add usage examples for common scenarios
4. Mark old implementations as deprecated (with a migration guide)
```mermaid
graph TD
A[Update README] --> B[Add API Documentation]
B --> C[Add Usage Examples]
C --> D[Mark Deprecated Code]
```
## Detailed Implementation Steps
### 1. Create New OpenRPC Client (zinit_client.v)
```v
module zinit
import freeflowuniverse.herolib.schemas.jsonrpc
import json
// ZinitClient is a unified client for interacting with Zinit using OpenRPC
pub struct ZinitClient {
pub mut:
rpc_client &jsonrpc.Client
}
// new_client creates a new Zinit OpenRPC client
pub fn new_client(socket_path string) ZinitClient {
mut cl := jsonrpc.new_unix_socket_client(socket_path)
return ZinitClient{
rpc_client: cl
}
}
// Implement all OpenRPC methods...
```
### 2. Refactor ZinitStateless (zinit_stateless.v)
```v
module zinit
import freeflowuniverse.herolib.core.pathlib
@[params]
pub struct ZinitConfig {
path string = '/etc/zinit'
pathcmds string = '/etc/zinit/cmds'
socket_path string = default_socket_path
}
pub struct ZinitStateless {
pub mut:
client ZinitClient
path pathlib.Path
pathcmds pathlib.Path
}
pub fn new_stateless(z ZinitConfig) !ZinitStateless {
return ZinitStateless{
client: new_client(z.socket_path)
path: pathlib.get_dir(path: z.path, create: true)!
pathcmds: pathlib.get_dir(path: z.pathcmds, create: true)!
}
}
// Refactor methods to use the OpenRPC client...
```
### 3. Refactor Zinit (zinit.v)
```v
module zinit
import freeflowuniverse.herolib.core.pathlib
@[heap]
pub struct Zinit {
pub mut:
processes map[string]ZProcess
path pathlib.Path
pathcmds pathlib.Path
client ZinitClient
}
// Refactor methods to use the OpenRPC client...
```
### 4. Refactor ZProcess (zprocess.v)
```v
module zinit
pub struct ZProcess {
pub:
name string = 'default'
pub mut:
cmd string
cmd_stop string
cmd_test string
workdir string
status ZProcessStatus
pid int
after []string
env map[string]string
oneshot bool
start bool = true
restart bool = true
description string
client &ZinitClient
}
// Refactor methods to use the OpenRPC client...
```
## Key Changes Required
1. **Replace Direct Filesystem Operations**:
- Replace file creation/modification with `service_create` OpenRPC calls
- Replace file deletion with `service_delete` OpenRPC calls
- Replace file reading with `service_get` OpenRPC calls
2. **Replace Shell Commands**:
- Replace `zinit list` shell commands with `service_list` OpenRPC calls
- Replace `zinit status` shell commands with `service_status` OpenRPC calls
- Replace `zinit log` shell commands with `stream_currentLogs` OpenRPC calls
3. **Unify Error Handling**:
- Implement consistent error handling across all methods
- Properly propagate OpenRPC error responses to the caller
4. **Maintain Backward Compatibility**:
- Keep the same method signatures for public methods
- Ensure the same behavior for all methods
- Add deprecation notices for methods that will be removed in the future
## Testing Strategy
1. **Unit Tests**:
- Test each OpenRPC method individually
- Test error handling for each method
- Test with mock responses for predictable testing
2. **Integration Tests**:
- Test with a real Zinit instance
- Test the full lifecycle of services (create, start, status, stop, delete)
- Test edge cases and error conditions
3. **Backward Compatibility Tests**:
- Test existing code that uses the old implementations
- Ensure no regressions in functionality
## Documentation Updates
1. **README.md**:
- Update with comprehensive documentation
- Add examples for common use cases
- Add migration guide for users of the old implementations
2. **API Documentation**:
- Document all public methods
- Document all structs and their fields
- Document error conditions and how to handle them
3. **Examples**:
- Update existing examples
- Add new examples for common use cases
- Add examples for error handling

View File

@@ -22,7 +22,7 @@ Zinit is a process manager that allows you to manage services on a system. This
### Basic Usage
```v
import freeflowuniverse.herolib.osal.zinit
import freeflowuniverse.herolib.osal.startupmanager
fn main() {
// Create a new Zinit client with the default socket path
@@ -47,7 +47,7 @@ fn main() {
### Creating a New Service
```v
import freeflowuniverse.herolib.osal.zinit
import freeflowuniverse.herolib.osal.startupmanager
fn main() {
mut zinit_client := zinit.new_stateless()!
@@ -77,7 +77,7 @@ fn main() {
### Getting Service Statistics
```v
import freeflowuniverse.herolib.osal.zinit
import freeflowuniverse.herolib.osal.startupmanager
fn main() {
mut zinit_client := zinit.new_stateless()!
@@ -98,7 +98,7 @@ fn main() {
### Retrieving Logs
```v
import freeflowuniverse.herolib.osal.zinit
import freeflowuniverse.herolib.osal.startupmanager
fn main() {
mut zinit_client := zinit.new_stateless()!

View File

@@ -15,6 +15,21 @@ pub mut:
pathcmds pathlib.Path
}
@[params]
pub struct ZProcessNewArgs {
pub mut:
name string @[required]
cmd string @[required]
cmd_stop string // command to stop (optional)
cmd_test string // command line to test service is running
workdir string // where to execute the commands
after []string // list of service we depend on
env map[string]string
oneshot bool
start bool = true
restart bool = true // whether the process should be restarted on failure
}
// will delete the process if it exists while starting
pub fn (mut zinit Zinit) new(args_ ZProcessNewArgs) !ZProcess {
console.print_header(' zinit process new')

View File

@@ -34,30 +34,6 @@ pub enum ZProcessStatus {
spawned
}
pub enum StartupManagerType {
unknown
zinit
systemd
screen
}
@[params]
pub struct ZProcessNewArgs {
pub mut:
name string @[required]
cmd string @[required]
cmd_stop string // command to stop (optional)
cmd_test string // command line to test service is running
workdir string // where to execute the commands
after []string // list of service we depend on
env map[string]string
oneshot bool
start bool = true
restart bool = true // whether the process should be restarted on failure
description string // not used in zinit
startuptype StartupManagerType
}
pub fn (zp ZProcess) cmd() !string {
mut zinitobj := new()!
mut path := zinitobj.pathcmds.file_get_new('${zp.name}_start.sh')!

View File

@@ -5,7 +5,7 @@ import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.core.texttools
import freeflowuniverse.herolib.core.pathlib
import freeflowuniverse.herolib.osal.systemd
import freeflowuniverse.herolib.osal.zinit
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.installers.ulist
import freeflowuniverse.herolib.installers.lang.golang
import freeflowuniverse.herolib.installers.lang.rust
@@ -17,7 +17,8 @@ fn startupcmd() ![]zinit.ZProcessNewArgs {
mut installer := get()!
mut res := []zinit.ZProcessNewArgs{}
mut cfg := get()!
res << zinit.ZProcessNewArgs{
res << zinit.ZProcessNewArgs
{
name: 'docker'
cmd: 'dockerd'
startuptype: .systemd
@@ -31,11 +32,13 @@ fn startupcmd() ![]zinit.ZProcessNewArgs {
cd ${cfg.path}/docker/
docker compose --env-file ${cfg.path}/docker/.env up
"
res << zinit.ZProcessNewArgs{
res << zinit.ZProcessNewArgs
{
name: 'dify'
cmd: cmd
startuptype: .systemd
}
return res
}

View File

@@ -3,75 +3,106 @@ module dify
import freeflowuniverse.herolib.core.base
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import json
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time
__global (
dify_global map[string]&DifyInstaller
dify_default string
)
/////////FACTORY
@[params]
pub struct ArgsGet {
pub mut:
name string
name string = 'default'
fromdb bool // will load from filesystem
create bool // default will not create if not exist
}
fn args_get(args_ ArgsGet) ArgsGet {
mut args := args_
if args.name == '' {
args.name = 'default'
}
return args
}
pub fn get(args_ ArgsGet) !&DifyInstaller {
mut context := base.context()!
mut args := args_get(args_)
pub fn new(args ArgsGet) !&DifyInstaller {
mut obj := DifyInstaller{
name: args.name
}
if args.name !in dify_global {
if !exists(args)! {
set(obj)!
set(obj)!
return &obj
}
pub fn get(args ArgsGet) !&DifyInstaller {
mut context := base.context()!
dify_default = args.name
if args.fromdb || args.name !in dify_global {
mut r := context.redis()!
if r.hexists('context:dify', args.name)! {
data := r.hget('context:dify', args.name)!
if data.len == 0 {
return error('DifyInstaller with name: dify does not exist, prob bug.')
}
mut obj := json.decode(DifyInstaller, data)!
set_in_mem(obj)!
} else {
heroscript := context.hero_config_get('dify', args.name)!
mut obj_ := heroscript_loads(heroscript)!
set_in_mem(obj_)!
if args.create {
new(args)!
} else {
return error("DifyInstaller with name 'dify' does not exist")
}
}
return get(name: args.name)! // no longer from db nor create
}
return dify_global[args.name] or {
println(dify_global)
// bug if we get here because should be in globals
panic('could not get config for dify with name, is bug:${args.name}')
return error('could not get config for dify with name:dify')
}
}
// register the config for the future
pub fn set(o DifyInstaller) ! {
set_in_mem(o)!
dify_default = o.name
mut context := base.context()!
heroscript := heroscript_dumps(o)!
context.hero_config_set('dify', o.name, heroscript)!
mut r := context.redis()!
r.hset('context:dify', o.name, json.encode(o))!
}
// does the config exists?
pub fn exists(args_ ArgsGet) !bool {
pub fn exists(args ArgsGet) !bool {
mut context := base.context()!
mut args := args_get(args_)
return context.hero_config_exists('dify', args.name)
mut r := context.redis()!
return r.hexists('context:dify', args.name)!
}
pub fn delete(args_ ArgsGet) ! {
mut args := args_get(args_)
pub fn delete(args ArgsGet) ! {
mut context := base.context()!
context.hero_config_delete('dify', args.name)!
if args.name in dify_global {
// del dify_global[args.name]
mut r := context.redis()!
r.hdel('context:dify', args.name)!
}
@[params]
pub struct ArgsList {
pub mut:
fromdb bool // will load from filesystem
}
// if fromdb set: load from filesystem, and not from mem, will also reset what is in mem
pub fn list(args ArgsList) ![]&DifyInstaller {
mut res := []&DifyInstaller{}
mut context := base.context()!
if args.fromdb {
// reset what is in mem
dify_global = map[string]&DifyInstaller{}
dify_default = ''
}
if args.fromdb {
mut r := context.redis()!
mut l := r.hkeys('context:dify')!
for name in l {
res << get(name: name, fromdb: true)!
}
return res
} else {
// load from memory
for _, client in dify_global {
res << client
}
}
return res
}
// only sets in mem, does not set as config
@@ -82,6 +113,9 @@ fn set_in_mem(o DifyInstaller) ! {
}
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'dify.') {
return
}
mut install_actions := plbook.find(filter: 'dify.configure')!
if install_actions.len > 0 {
for install_action in install_actions {
@@ -90,7 +124,6 @@ pub fn play(mut plbook PlayBook) ! {
set(obj2)!
}
}
mut other_actions := plbook.find(filter: 'dify.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
@@ -131,36 +164,38 @@ pub fn play(mut plbook PlayBook) ! {
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
fn startupmanager_get(cat startupmanager.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.screen {
console.print_debug('startupmanager: zinit')
return startupmanager.get(.screen)!
}
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
return startupmanager.get(.zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
return startupmanager.get(.systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
return startupmanager.get(.auto)!
}
}
}
// load from disk and make sure is properly intialized
pub fn (mut self DifyInstaller) reload() ! {
switch(self.name)
self = obj_init(self)!
}
pub fn (mut self DifyInstaller) start() ! {
switch(self.name)
if self.running()! {
return
}
@@ -223,10 +258,12 @@ pub fn (mut self DifyInstaller) running() !bool {
// walk over the generic processes, if not running return
for zprocess in startupcmd()! {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
if zprocess.startuptype != .screen {
mut sm := startupmanager_get(zprocess.startuptype)!
r := sm.running(zprocess.name)!
if r == false {
return false
}
}
}
return running()!
@@ -258,12 +295,4 @@ pub fn (mut self DifyInstaller) destroy() ! {
// switch instance to be used for dify
pub fn switch(name string) {
dify_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}