...
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#!/usr/bin/env -S v -n -w -gc none -cc tcc -d use_openssl -enable-globals run
|
||||
|
||||
import freeflowuniverse.herolib.clients.zinit_rpc
|
||||
import freeflowuniverse.herolib.clients.zinit
|
||||
import freeflowuniverse.herolib.installers.infra.zinit_installer
|
||||
import os
|
||||
import time
|
||||
|
||||
@@ -9,34 +10,33 @@ import time
|
||||
|
||||
println('=== Zinit RPC Client Example ===\n')
|
||||
|
||||
// Start Zinit in the background
|
||||
println('Starting Zinit in background...')
|
||||
mut zinit_process := os.new_process('/usr/local/bin/zinit')
|
||||
zinit_process.set_args(['init'])
|
||||
zinit_process.set_redirect_stdio()
|
||||
zinit_process.run()
|
||||
// // Start Zinit in the background
|
||||
// println('Starting Zinit in background...')
|
||||
// mut zinit_process := os.new_process('/usr/local/bin/zinit')
|
||||
// zinit_process.set_args(['init'])
|
||||
// zinit_process.set_redirect_stdio()
|
||||
// zinit_process.run()
|
||||
|
||||
// Wait a moment for Zinit to start up
|
||||
time.sleep(2000 * time.millisecond)
|
||||
println('✓ Zinit started')
|
||||
// time.sleep(2000 * time.millisecond)
|
||||
// println('✓ Zinit started')
|
||||
|
||||
// Ensure we clean up Zinit when done
|
||||
defer {
|
||||
println('\nCleaning up...')
|
||||
zinit_process.signal_kill()
|
||||
zinit_process.wait()
|
||||
println('✓ Zinit stopped')
|
||||
}
|
||||
// defer {
|
||||
// println('\nCleaning up...')
|
||||
// zinit_process.signal_kill()
|
||||
// zinit_process.wait()
|
||||
// println('✓ Zinit stopped')
|
||||
// }
|
||||
|
||||
// mut installer := zinit_installer.get()!
|
||||
// installer.install()!
|
||||
// installer.start()!
|
||||
|
||||
// Create a new client
|
||||
mut client := zinit_rpc.new_client(
|
||||
name: 'example_client'
|
||||
socket_path: '/tmp/zinit.sock'
|
||||
) or {
|
||||
println('Failed to create client: ${err}')
|
||||
println('Make sure Zinit is running and the socket exists at /tmp/zinit.sock')
|
||||
exit(1)
|
||||
}
|
||||
mut client := zinit.new()!
|
||||
|
||||
println(client)
|
||||
|
||||
println('✓ Created Zinit RPC client')
|
||||
|
||||
@@ -66,7 +66,7 @@ for service_name, state in services {
|
||||
// 3. Create a test service configuration
|
||||
println('\n3. Creating a test service...')
|
||||
test_service_name := 'test_echo_service'
|
||||
config := zinit_rpc.ServiceConfig{
|
||||
config := zinit.ServiceConfig{
|
||||
exec: '/bin/echo "Hello from test service"'
|
||||
oneshot: true
|
||||
log: 'stdout'
|
||||
@@ -147,7 +147,7 @@ println('\n8. Getting service statistics...')
|
||||
stats := client.service_stats(test_service_name) or {
|
||||
println('Failed to get service stats (service might not be running): ${err}')
|
||||
// Continue anyway
|
||||
zinit_rpc.ServiceStats{}
|
||||
zinit.ServiceStats{}
|
||||
}
|
||||
if stats.name != '' {
|
||||
println('✓ Service statistics:')
|
||||
@@ -208,7 +208,7 @@ if subscription_id != 0 {
|
||||
// Get fresh status to make sure service is still running
|
||||
fresh_status := client.service_status(test_service_name) or {
|
||||
println('\n12. Skipping signal test (cannot get service status)')
|
||||
zinit_rpc.ServiceStatus{}
|
||||
zinit.ServiceStatus{}
|
||||
}
|
||||
if fresh_status.state == 'Running' && fresh_status.pid > 0 {
|
||||
println('\n12. Sending SIGTERM signal to service...')
|
||||
@@ -258,7 +258,6 @@ server_result := client.system_start_http_server('127.0.0.1:9999') or {
|
||||
}
|
||||
if server_result != '' {
|
||||
println('✓ HTTP server started: ${server_result}')
|
||||
|
||||
// Stop the HTTP server
|
||||
client.system_stop_http_server() or { println('Failed to stop HTTP server: ${err}') }
|
||||
println('✓ HTTP server stopped')
|
||||
@@ -4,7 +4,7 @@ import freeflowuniverse.herolib.core.generator.generic as generator
|
||||
import freeflowuniverse.herolib.core.pathlib
|
||||
|
||||
mut args := generator.GeneratorArgs{
|
||||
path: '~/code/github/freeflowuniverse/herolib/lib/installers'
|
||||
path: '~/code/github/freeflowuniverse/herolib/lib/clients'
|
||||
force: true
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ pub fn new(args ArgsGet) !&GiteaClient {
|
||||
name: args.name
|
||||
}
|
||||
set(obj)!
|
||||
return &obj
|
||||
return get(name: args.name)!
|
||||
}
|
||||
|
||||
pub fn get(args ArgsGet) !&GiteaClient {
|
||||
@@ -36,7 +36,7 @@ pub fn get(args ArgsGet) !&GiteaClient {
|
||||
if r.hexists('context:giteaclient', args.name)! {
|
||||
data := r.hget('context:giteaclient', args.name)!
|
||||
if data.len == 0 {
|
||||
return error('giteaclient with name: giteaclient does not exist, prob bug.')
|
||||
return error('GiteaClient with name: giteaclient does not exist, prob bug.')
|
||||
}
|
||||
mut obj := json.decode(GiteaClient, data)!
|
||||
set_in_mem(obj)!
|
||||
@@ -56,11 +56,11 @@ pub fn get(args ArgsGet) !&GiteaClient {
|
||||
|
||||
// register the config for the future
|
||||
pub fn set(o GiteaClient) ! {
|
||||
set_in_mem(o)!
|
||||
giteaclient_default = o.name
|
||||
mut o2 := set_in_mem(o)!
|
||||
giteaclient_default = o2.name
|
||||
mut context := base.context()!
|
||||
mut r := context.redis()!
|
||||
r.hset('context:giteaclient', o.name, json.encode(o))!
|
||||
r.hset('context:giteaclient', o2.name, json.encode(o2))!
|
||||
}
|
||||
|
||||
// does the config exists?
|
||||
@@ -109,18 +109,17 @@ pub fn list(args ArgsList) ![]&GiteaClient {
|
||||
}
|
||||
|
||||
// only sets in mem, does not set as config
|
||||
fn set_in_mem(o GiteaClient) ! {
|
||||
fn set_in_mem(o GiteaClient) !GiteaClient {
|
||||
mut o2 := obj_init(o)!
|
||||
giteaclient_global[o.name] = &o2
|
||||
giteaclient_default = o.name
|
||||
}
|
||||
|
||||
// switch instance to be used for giteaclient
|
||||
pub fn switch(name string) {
|
||||
giteaclient_default = name
|
||||
giteaclient_global[o2.name] = &o2
|
||||
giteaclient_default = o2.name
|
||||
return o2
|
||||
}
|
||||
|
||||
pub fn play(mut plbook PlayBook) ! {
|
||||
if !plbook.exists(filter: 'giteaclient.') {
|
||||
return
|
||||
}
|
||||
mut install_actions := plbook.find(filter: 'giteaclient.configure')!
|
||||
if install_actions.len > 0 {
|
||||
for install_action in install_actions {
|
||||
@@ -130,3 +129,8 @@ pub fn play(mut plbook PlayBook) ! {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// switch instance to be used for giteaclient
|
||||
pub fn switch(name string) {
|
||||
giteaclient_default = name
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ pub fn new(args ArgsGet) !&IPApi {
|
||||
name: args.name
|
||||
}
|
||||
set(obj)!
|
||||
return &obj
|
||||
return get(name: args.name)!
|
||||
}
|
||||
|
||||
pub fn get(args ArgsGet) !&IPApi {
|
||||
@@ -36,7 +36,7 @@ pub fn get(args ArgsGet) !&IPApi {
|
||||
if r.hexists('context:ipapi', args.name)! {
|
||||
data := r.hget('context:ipapi', args.name)!
|
||||
if data.len == 0 {
|
||||
return error('ipapi with name: ipapi does not exist, prob bug.')
|
||||
return error('IPApi with name: ipapi does not exist, prob bug.')
|
||||
}
|
||||
mut obj := json.decode(IPApi, data)!
|
||||
set_in_mem(obj)!
|
||||
@@ -56,11 +56,11 @@ pub fn get(args ArgsGet) !&IPApi {
|
||||
|
||||
// register the config for the future
|
||||
pub fn set(o IPApi) ! {
|
||||
set_in_mem(o)!
|
||||
ipapi_default = o.name
|
||||
mut o2 := set_in_mem(o)!
|
||||
ipapi_default = o2.name
|
||||
mut context := base.context()!
|
||||
mut r := context.redis()!
|
||||
r.hset('context:ipapi', o.name, json.encode(o))!
|
||||
r.hset('context:ipapi', o2.name, json.encode(o2))!
|
||||
}
|
||||
|
||||
// does the config exists?
|
||||
@@ -109,18 +109,17 @@ pub fn list(args ArgsList) ![]&IPApi {
|
||||
}
|
||||
|
||||
// only sets in mem, does not set as config
|
||||
fn set_in_mem(o IPApi) ! {
|
||||
fn set_in_mem(o IPApi) !IPApi {
|
||||
mut o2 := obj_init(o)!
|
||||
ipapi_global[o.name] = &o2
|
||||
ipapi_default = o.name
|
||||
}
|
||||
|
||||
// switch instance to be used for ipapi
|
||||
pub fn switch(name string) {
|
||||
ipapi_default = name
|
||||
ipapi_global[o2.name] = &o2
|
||||
ipapi_default = o2.name
|
||||
return o2
|
||||
}
|
||||
|
||||
pub fn play(mut plbook PlayBook) ! {
|
||||
if !plbook.exists(filter: 'ipapi.') {
|
||||
return
|
||||
}
|
||||
mut install_actions := plbook.find(filter: 'ipapi.configure')!
|
||||
if install_actions.len > 0 {
|
||||
for install_action in install_actions {
|
||||
@@ -130,3 +129,8 @@ pub fn play(mut plbook PlayBook) ! {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// switch instance to be used for ipapi
|
||||
pub fn switch(name string) {
|
||||
ipapi_default = name
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ pub fn new(args ArgsGet) !&Jina {
|
||||
name: args.name
|
||||
}
|
||||
set(obj)!
|
||||
return &obj
|
||||
return get(name: args.name)!
|
||||
}
|
||||
|
||||
pub fn get(args ArgsGet) !&Jina {
|
||||
@@ -36,7 +36,7 @@ pub fn get(args ArgsGet) !&Jina {
|
||||
if r.hexists('context:jina', args.name)! {
|
||||
data := r.hget('context:jina', args.name)!
|
||||
if data.len == 0 {
|
||||
return error('jina with name: jina does not exist, prob bug.')
|
||||
return error('Jina with name: jina does not exist, prob bug.')
|
||||
}
|
||||
mut obj := json.decode(Jina, data)!
|
||||
set_in_mem(obj)!
|
||||
@@ -56,11 +56,11 @@ pub fn get(args ArgsGet) !&Jina {
|
||||
|
||||
// register the config for the future
|
||||
pub fn set(o Jina) ! {
|
||||
set_in_mem(o)!
|
||||
jina_default = o.name
|
||||
mut o2 := set_in_mem(o)!
|
||||
jina_default = o2.name
|
||||
mut context := base.context()!
|
||||
mut r := context.redis()!
|
||||
r.hset('context:jina', o.name, json.encode(o))!
|
||||
r.hset('context:jina', o2.name, json.encode(o2))!
|
||||
}
|
||||
|
||||
// does the config exists?
|
||||
@@ -109,18 +109,17 @@ pub fn list(args ArgsList) ![]&Jina {
|
||||
}
|
||||
|
||||
// only sets in mem, does not set as config
|
||||
fn set_in_mem(o Jina) ! {
|
||||
fn set_in_mem(o Jina) !Jina {
|
||||
mut o2 := obj_init(o)!
|
||||
jina_global[o.name] = &o2
|
||||
jina_default = o.name
|
||||
}
|
||||
|
||||
// switch instance to be used for jina
|
||||
pub fn switch(name string) {
|
||||
jina_default = name
|
||||
jina_global[o2.name] = &o2
|
||||
jina_default = o2.name
|
||||
return o2
|
||||
}
|
||||
|
||||
pub fn play(mut plbook PlayBook) ! {
|
||||
if !plbook.exists(filter: 'jina.') {
|
||||
return
|
||||
}
|
||||
mut install_actions := plbook.find(filter: 'jina.configure')!
|
||||
if install_actions.len > 0 {
|
||||
for install_action in install_actions {
|
||||
@@ -130,3 +129,8 @@ pub fn play(mut plbook PlayBook) ! {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// switch instance to be used for jina
|
||||
pub fn switch(name string) {
|
||||
jina_default = name
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ pub fn new(args ArgsGet) !&LivekitClient {
|
||||
name: args.name
|
||||
}
|
||||
set(obj)!
|
||||
return &obj
|
||||
return get(name: args.name)!
|
||||
}
|
||||
|
||||
pub fn get(args ArgsGet) !&LivekitClient {
|
||||
@@ -36,7 +36,7 @@ pub fn get(args ArgsGet) !&LivekitClient {
|
||||
if r.hexists('context:livekit', args.name)! {
|
||||
data := r.hget('context:livekit', args.name)!
|
||||
if data.len == 0 {
|
||||
return error('livekit with name: livekit does not exist, prob bug.')
|
||||
return error('LivekitClient with name: livekit does not exist, prob bug.')
|
||||
}
|
||||
mut obj := json.decode(LivekitClient, data)!
|
||||
set_in_mem(obj)!
|
||||
@@ -56,11 +56,11 @@ pub fn get(args ArgsGet) !&LivekitClient {
|
||||
|
||||
// register the config for the future
|
||||
pub fn set(o LivekitClient) ! {
|
||||
set_in_mem(o)!
|
||||
livekit_default = o.name
|
||||
mut o2 := set_in_mem(o)!
|
||||
livekit_default = o2.name
|
||||
mut context := base.context()!
|
||||
mut r := context.redis()!
|
||||
r.hset('context:livekit', o.name, json.encode(o))!
|
||||
r.hset('context:livekit', o2.name, json.encode(o2))!
|
||||
}
|
||||
|
||||
// does the config exists?
|
||||
@@ -109,18 +109,17 @@ pub fn list(args ArgsList) ![]&LivekitClient {
|
||||
}
|
||||
|
||||
// only sets in mem, does not set as config
|
||||
fn set_in_mem(o LivekitClient) ! {
|
||||
fn set_in_mem(o LivekitClient) !LivekitClient {
|
||||
mut o2 := obj_init(o)!
|
||||
livekit_global[o.name] = &o2
|
||||
livekit_default = o.name
|
||||
}
|
||||
|
||||
// switch instance to be used for livekit
|
||||
pub fn switch(name string) {
|
||||
livekit_default = name
|
||||
livekit_global[o2.name] = &o2
|
||||
livekit_default = o2.name
|
||||
return o2
|
||||
}
|
||||
|
||||
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 {
|
||||
@@ -130,3 +129,8 @@ pub fn play(mut plbook PlayBook) ! {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// switch instance to be used for livekit
|
||||
pub fn switch(name string) {
|
||||
livekit_default = name
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ pub fn new(args ArgsGet) !&MailClient {
|
||||
name: args.name
|
||||
}
|
||||
set(obj)!
|
||||
return &obj
|
||||
return get(name: args.name)!
|
||||
}
|
||||
|
||||
pub fn get(args ArgsGet) !&MailClient {
|
||||
@@ -36,7 +36,7 @@ pub fn get(args ArgsGet) !&MailClient {
|
||||
if r.hexists('context:mailclient', args.name)! {
|
||||
data := r.hget('context:mailclient', args.name)!
|
||||
if data.len == 0 {
|
||||
return error('mailclient with name: mailclient does not exist, prob bug.')
|
||||
return error('MailClient with name: mailclient does not exist, prob bug.')
|
||||
}
|
||||
mut obj := json.decode(MailClient, data)!
|
||||
set_in_mem(obj)!
|
||||
@@ -56,11 +56,11 @@ pub fn get(args ArgsGet) !&MailClient {
|
||||
|
||||
// register the config for the future
|
||||
pub fn set(o MailClient) ! {
|
||||
set_in_mem(o)!
|
||||
mailclient_default = o.name
|
||||
mut o2 := set_in_mem(o)!
|
||||
mailclient_default = o2.name
|
||||
mut context := base.context()!
|
||||
mut r := context.redis()!
|
||||
r.hset('context:mailclient', o.name, json.encode(o))!
|
||||
r.hset('context:mailclient', o2.name, json.encode(o2))!
|
||||
}
|
||||
|
||||
// does the config exists?
|
||||
@@ -109,18 +109,17 @@ pub fn list(args ArgsList) ![]&MailClient {
|
||||
}
|
||||
|
||||
// only sets in mem, does not set as config
|
||||
fn set_in_mem(o MailClient) ! {
|
||||
fn set_in_mem(o MailClient) !MailClient {
|
||||
mut o2 := obj_init(o)!
|
||||
mailclient_global[o.name] = &o2
|
||||
mailclient_default = o.name
|
||||
}
|
||||
|
||||
// switch instance to be used for mailclient
|
||||
pub fn switch(name string) {
|
||||
mailclient_default = name
|
||||
mailclient_global[o2.name] = &o2
|
||||
mailclient_default = o2.name
|
||||
return o2
|
||||
}
|
||||
|
||||
pub fn play(mut plbook PlayBook) ! {
|
||||
if !plbook.exists(filter: 'mailclient.') {
|
||||
return
|
||||
}
|
||||
mut install_actions := plbook.find(filter: 'mailclient.configure')!
|
||||
if install_actions.len > 0 {
|
||||
for install_action in install_actions {
|
||||
@@ -130,3 +129,8 @@ pub fn play(mut plbook PlayBook) ! {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// switch instance to be used for mailclient
|
||||
pub fn switch(name string) {
|
||||
mailclient_default = name
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ pub fn new(args ArgsGet) !&MeilisearchClient {
|
||||
name: args.name
|
||||
}
|
||||
set(obj)!
|
||||
return &obj
|
||||
return get(name: args.name)!
|
||||
}
|
||||
|
||||
pub fn get(args ArgsGet) !&MeilisearchClient {
|
||||
@@ -36,7 +36,7 @@ pub fn get(args ArgsGet) !&MeilisearchClient {
|
||||
if r.hexists('context:meilisearch', args.name)! {
|
||||
data := r.hget('context:meilisearch', args.name)!
|
||||
if data.len == 0 {
|
||||
return error('meilisearch with name: meilisearch does not exist, prob bug.')
|
||||
return error('MeilisearchClient with name: meilisearch does not exist, prob bug.')
|
||||
}
|
||||
mut obj := json.decode(MeilisearchClient, data)!
|
||||
set_in_mem(obj)!
|
||||
@@ -56,11 +56,11 @@ pub fn get(args ArgsGet) !&MeilisearchClient {
|
||||
|
||||
// register the config for the future
|
||||
pub fn set(o MeilisearchClient) ! {
|
||||
set_in_mem(o)!
|
||||
meilisearch_default = o.name
|
||||
mut o2 := set_in_mem(o)!
|
||||
meilisearch_default = o2.name
|
||||
mut context := base.context()!
|
||||
mut r := context.redis()!
|
||||
r.hset('context:meilisearch', o.name, json.encode(o))!
|
||||
r.hset('context:meilisearch', o2.name, json.encode(o2))!
|
||||
}
|
||||
|
||||
// does the config exists?
|
||||
@@ -109,18 +109,17 @@ pub fn list(args ArgsList) ![]&MeilisearchClient {
|
||||
}
|
||||
|
||||
// only sets in mem, does not set as config
|
||||
fn set_in_mem(o MeilisearchClient) ! {
|
||||
fn set_in_mem(o MeilisearchClient) !MeilisearchClient {
|
||||
mut o2 := obj_init(o)!
|
||||
meilisearch_global[o.name] = &o2
|
||||
meilisearch_default = o.name
|
||||
}
|
||||
|
||||
// switch instance to be used for meilisearch
|
||||
pub fn switch(name string) {
|
||||
meilisearch_default = name
|
||||
meilisearch_global[o2.name] = &o2
|
||||
meilisearch_default = o2.name
|
||||
return o2
|
||||
}
|
||||
|
||||
pub fn play(mut plbook PlayBook) ! {
|
||||
if !plbook.exists(filter: 'meilisearch.') {
|
||||
return
|
||||
}
|
||||
mut install_actions := plbook.find(filter: 'meilisearch.configure')!
|
||||
if install_actions.len > 0 {
|
||||
for install_action in install_actions {
|
||||
@@ -130,3 +129,8 @@ pub fn play(mut plbook PlayBook) ! {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// switch instance to be used for meilisearch
|
||||
pub fn switch(name string) {
|
||||
meilisearch_default = name
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ pub fn new(args ArgsGet) !&Mycelium {
|
||||
name: args.name
|
||||
}
|
||||
set(obj)!
|
||||
return &obj
|
||||
return get(name: args.name)!
|
||||
}
|
||||
|
||||
pub fn get(args ArgsGet) !&Mycelium {
|
||||
@@ -36,7 +36,7 @@ pub fn get(args ArgsGet) !&Mycelium {
|
||||
if r.hexists('context:mycelium', args.name)! {
|
||||
data := r.hget('context:mycelium', args.name)!
|
||||
if data.len == 0 {
|
||||
return error('mycelium with name: mycelium does not exist, prob bug.')
|
||||
return error('Mycelium with name: mycelium does not exist, prob bug.')
|
||||
}
|
||||
mut obj := json.decode(Mycelium, data)!
|
||||
set_in_mem(obj)!
|
||||
@@ -56,11 +56,11 @@ pub fn get(args ArgsGet) !&Mycelium {
|
||||
|
||||
// register the config for the future
|
||||
pub fn set(o Mycelium) ! {
|
||||
set_in_mem(o)!
|
||||
mycelium_default = o.name
|
||||
mut o2 := set_in_mem(o)!
|
||||
mycelium_default = o2.name
|
||||
mut context := base.context()!
|
||||
mut r := context.redis()!
|
||||
r.hset('context:mycelium', o.name, json.encode(o))!
|
||||
r.hset('context:mycelium', o2.name, json.encode(o2))!
|
||||
}
|
||||
|
||||
// does the config exists?
|
||||
@@ -109,18 +109,17 @@ pub fn list(args ArgsList) ![]&Mycelium {
|
||||
}
|
||||
|
||||
// only sets in mem, does not set as config
|
||||
fn set_in_mem(o Mycelium) ! {
|
||||
fn set_in_mem(o Mycelium) !Mycelium {
|
||||
mut o2 := obj_init(o)!
|
||||
mycelium_global[o.name] = &o2
|
||||
mycelium_default = o.name
|
||||
}
|
||||
|
||||
// switch instance to be used for mycelium
|
||||
pub fn switch(name string) {
|
||||
mycelium_default = name
|
||||
mycelium_global[o2.name] = &o2
|
||||
mycelium_default = o2.name
|
||||
return o2
|
||||
}
|
||||
|
||||
pub fn play(mut plbook PlayBook) ! {
|
||||
if !plbook.exists(filter: 'mycelium.') {
|
||||
return
|
||||
}
|
||||
mut install_actions := plbook.find(filter: 'mycelium.configure')!
|
||||
if install_actions.len > 0 {
|
||||
for install_action in install_actions {
|
||||
@@ -130,3 +129,7 @@ pub fn play(mut plbook PlayBook) ! {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// switch instance to be used for mycelium
|
||||
pub fn switch(name string) {
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ pub fn new(args ArgsGet) !&MyceliumRPC {
|
||||
name: args.name
|
||||
}
|
||||
set(obj)!
|
||||
return &obj
|
||||
return get(name: args.name)!
|
||||
}
|
||||
|
||||
pub fn get(args ArgsGet) !&MyceliumRPC {
|
||||
@@ -36,7 +36,7 @@ pub fn get(args ArgsGet) !&MyceliumRPC {
|
||||
if r.hexists('context:mycelium_rpc', args.name)! {
|
||||
data := r.hget('context:mycelium_rpc', args.name)!
|
||||
if data.len == 0 {
|
||||
return error('mycelium_rpc with name: mycelium_rpc does not exist, prob bug.')
|
||||
return error('MyceliumRPC with name: mycelium_rpc does not exist, prob bug.')
|
||||
}
|
||||
mut obj := json.decode(MyceliumRPC, data)!
|
||||
set_in_mem(obj)!
|
||||
@@ -56,11 +56,11 @@ pub fn get(args ArgsGet) !&MyceliumRPC {
|
||||
|
||||
// register the config for the future
|
||||
pub fn set(o MyceliumRPC) ! {
|
||||
set_in_mem(o)!
|
||||
mycelium_rpc_default = o.name
|
||||
mut o2 := set_in_mem(o)!
|
||||
mycelium_rpc_default = o2.name
|
||||
mut context := base.context()!
|
||||
mut r := context.redis()!
|
||||
r.hset('context:mycelium_rpc', o.name, json.encode(o))!
|
||||
r.hset('context:mycelium_rpc', o2.name, json.encode(o2))!
|
||||
}
|
||||
|
||||
// does the config exists?
|
||||
@@ -109,18 +109,17 @@ pub fn list(args ArgsList) ![]&MyceliumRPC {
|
||||
}
|
||||
|
||||
// only sets in mem, does not set as config
|
||||
fn set_in_mem(o MyceliumRPC) ! {
|
||||
fn set_in_mem(o MyceliumRPC) !MyceliumRPC {
|
||||
mut o2 := obj_init(o)!
|
||||
mycelium_rpc_global[o.name] = &o2
|
||||
mycelium_rpc_default = o.name
|
||||
}
|
||||
|
||||
// switch instance to be used for mycelium_rpc
|
||||
pub fn switch(name string) {
|
||||
mycelium_rpc_default = name
|
||||
mycelium_rpc_global[o2.name] = &o2
|
||||
mycelium_rpc_default = o2.name
|
||||
return o2
|
||||
}
|
||||
|
||||
pub fn play(mut plbook PlayBook) ! {
|
||||
if !plbook.exists(filter: 'mycelium_rpc.') {
|
||||
return
|
||||
}
|
||||
mut install_actions := plbook.find(filter: 'mycelium_rpc.configure')!
|
||||
if install_actions.len > 0 {
|
||||
for install_action in install_actions {
|
||||
@@ -130,3 +129,7 @@ pub fn play(mut plbook PlayBook) ! {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// switch instance to be used for mycelium_rpc
|
||||
pub fn switch(name string) {
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ pub fn new(args ArgsGet) !&OpenAI {
|
||||
name: args.name
|
||||
}
|
||||
set(obj)!
|
||||
return &obj
|
||||
return get(name: args.name)!
|
||||
}
|
||||
|
||||
pub fn get(args ArgsGet) !&OpenAI {
|
||||
@@ -36,7 +36,7 @@ pub fn get(args ArgsGet) !&OpenAI {
|
||||
if r.hexists('context:openai', args.name)! {
|
||||
data := r.hget('context:openai', args.name)!
|
||||
if data.len == 0 {
|
||||
return error('openai with name: openai does not exist, prob bug.')
|
||||
return error('OpenAI with name: openai does not exist, prob bug.')
|
||||
}
|
||||
mut obj := json.decode(OpenAI, data)!
|
||||
set_in_mem(obj)!
|
||||
@@ -56,11 +56,11 @@ pub fn get(args ArgsGet) !&OpenAI {
|
||||
|
||||
// register the config for the future
|
||||
pub fn set(o OpenAI) ! {
|
||||
set_in_mem(o)!
|
||||
openai_default = o.name
|
||||
mut o2 := set_in_mem(o)!
|
||||
openai_default = o2.name
|
||||
mut context := base.context()!
|
||||
mut r := context.redis()!
|
||||
r.hset('context:openai', o.name, json.encode(o))!
|
||||
r.hset('context:openai', o2.name, json.encode(o2))!
|
||||
}
|
||||
|
||||
// does the config exists?
|
||||
@@ -109,18 +109,17 @@ pub fn list(args ArgsList) ![]&OpenAI {
|
||||
}
|
||||
|
||||
// only sets in mem, does not set as config
|
||||
fn set_in_mem(o OpenAI) ! {
|
||||
fn set_in_mem(o OpenAI) !OpenAI {
|
||||
mut o2 := obj_init(o)!
|
||||
openai_global[o.name] = &o2
|
||||
openai_default = o.name
|
||||
}
|
||||
|
||||
// switch instance to be used for openai
|
||||
pub fn switch(name string) {
|
||||
openai_default = name
|
||||
openai_global[o2.name] = &o2
|
||||
openai_default = o2.name
|
||||
return o2
|
||||
}
|
||||
|
||||
pub fn play(mut plbook PlayBook) ! {
|
||||
if !plbook.exists(filter: 'openai.') {
|
||||
return
|
||||
}
|
||||
mut install_actions := plbook.find(filter: 'openai.configure')!
|
||||
if install_actions.len > 0 {
|
||||
for install_action in install_actions {
|
||||
@@ -130,3 +129,8 @@ pub fn play(mut plbook PlayBook) ! {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// switch instance to be used for openai
|
||||
pub fn switch(name string) {
|
||||
openai_default = name
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ pub fn new(args ArgsGet) !&PostgresqlClient {
|
||||
name: args.name
|
||||
}
|
||||
set(obj)!
|
||||
return &obj
|
||||
return get(name: args.name)!
|
||||
}
|
||||
|
||||
pub fn get(args ArgsGet) !&PostgresqlClient {
|
||||
@@ -36,7 +36,7 @@ pub fn get(args ArgsGet) !&PostgresqlClient {
|
||||
if r.hexists('context:postgresql_client', args.name)! {
|
||||
data := r.hget('context:postgresql_client', args.name)!
|
||||
if data.len == 0 {
|
||||
return error('postgresql_client with name: postgresql_client does not exist, prob bug.')
|
||||
return error('PostgresqlClient with name: postgresql_client does not exist, prob bug.')
|
||||
}
|
||||
mut obj := json.decode(PostgresqlClient, data)!
|
||||
set_in_mem(obj)!
|
||||
@@ -56,11 +56,11 @@ pub fn get(args ArgsGet) !&PostgresqlClient {
|
||||
|
||||
// register the config for the future
|
||||
pub fn set(o PostgresqlClient) ! {
|
||||
set_in_mem(o)!
|
||||
postgresql_client_default = o.name
|
||||
mut o2 := set_in_mem(o)!
|
||||
postgresql_client_default = o2.name
|
||||
mut context := base.context()!
|
||||
mut r := context.redis()!
|
||||
r.hset('context:postgresql_client', o.name, json.encode(o))!
|
||||
r.hset('context:postgresql_client', o2.name, json.encode(o2))!
|
||||
}
|
||||
|
||||
// does the config exists?
|
||||
@@ -109,18 +109,17 @@ pub fn list(args ArgsList) ![]&PostgresqlClient {
|
||||
}
|
||||
|
||||
// only sets in mem, does not set as config
|
||||
fn set_in_mem(o PostgresqlClient) ! {
|
||||
fn set_in_mem(o PostgresqlClient) !PostgresqlClient {
|
||||
mut o2 := obj_init(o)!
|
||||
postgresql_client_global[o.name] = &o2
|
||||
postgresql_client_default = o.name
|
||||
}
|
||||
|
||||
// switch instance to be used for postgresql_client
|
||||
pub fn switch(name string) {
|
||||
postgresql_client_default = name
|
||||
postgresql_client_global[o2.name] = &o2
|
||||
postgresql_client_default = o2.name
|
||||
return o2
|
||||
}
|
||||
|
||||
pub fn play(mut plbook PlayBook) ! {
|
||||
if !plbook.exists(filter: 'postgresql_client.') {
|
||||
return
|
||||
}
|
||||
mut install_actions := plbook.find(filter: 'postgresql_client.configure')!
|
||||
if install_actions.len > 0 {
|
||||
for install_action in install_actions {
|
||||
@@ -130,3 +129,8 @@ pub fn play(mut plbook PlayBook) ! {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// switch instance to be used for postgresql_client
|
||||
pub fn switch(name string) {
|
||||
postgresql_client_default = name
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ pub fn new(args ArgsGet) !&QDrantClient {
|
||||
name: args.name
|
||||
}
|
||||
set(obj)!
|
||||
return &obj
|
||||
return get(name: args.name)!
|
||||
}
|
||||
|
||||
pub fn get(args ArgsGet) !&QDrantClient {
|
||||
@@ -36,7 +36,7 @@ pub fn get(args ArgsGet) !&QDrantClient {
|
||||
if r.hexists('context:qdrant', args.name)! {
|
||||
data := r.hget('context:qdrant', args.name)!
|
||||
if data.len == 0 {
|
||||
return error('qdrant with name: qdrant does not exist, prob bug.')
|
||||
return error('QDrantClient with name: qdrant does not exist, prob bug.')
|
||||
}
|
||||
mut obj := json.decode(QDrantClient, data)!
|
||||
set_in_mem(obj)!
|
||||
@@ -56,11 +56,11 @@ pub fn get(args ArgsGet) !&QDrantClient {
|
||||
|
||||
// register the config for the future
|
||||
pub fn set(o QDrantClient) ! {
|
||||
set_in_mem(o)!
|
||||
qdrant_default = o.name
|
||||
mut o2 := set_in_mem(o)!
|
||||
qdrant_default = o2.name
|
||||
mut context := base.context()!
|
||||
mut r := context.redis()!
|
||||
r.hset('context:qdrant', o.name, json.encode(o))!
|
||||
r.hset('context:qdrant', o2.name, json.encode(o2))!
|
||||
}
|
||||
|
||||
// does the config exists?
|
||||
@@ -109,18 +109,17 @@ pub fn list(args ArgsList) ![]&QDrantClient {
|
||||
}
|
||||
|
||||
// only sets in mem, does not set as config
|
||||
fn set_in_mem(o QDrantClient) ! {
|
||||
fn set_in_mem(o QDrantClient) !QDrantClient {
|
||||
mut o2 := obj_init(o)!
|
||||
qdrant_global[o.name] = &o2
|
||||
qdrant_default = o.name
|
||||
}
|
||||
|
||||
// switch instance to be used for qdrant
|
||||
pub fn switch(name string) {
|
||||
qdrant_default = name
|
||||
qdrant_global[o2.name] = &o2
|
||||
qdrant_default = o2.name
|
||||
return o2
|
||||
}
|
||||
|
||||
pub fn play(mut plbook PlayBook) ! {
|
||||
if !plbook.exists(filter: 'qdrant.') {
|
||||
return
|
||||
}
|
||||
mut install_actions := plbook.find(filter: 'qdrant.configure')!
|
||||
if install_actions.len > 0 {
|
||||
for install_action in install_actions {
|
||||
@@ -130,3 +129,8 @@ pub fn play(mut plbook PlayBook) ! {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// switch instance to be used for qdrant
|
||||
pub fn switch(name string) {
|
||||
qdrant_default = name
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ pub fn new(args ArgsGet) !&RCloneClient {
|
||||
name: args.name
|
||||
}
|
||||
set(obj)!
|
||||
return &obj
|
||||
return get(name: args.name)!
|
||||
}
|
||||
|
||||
pub fn get(args ArgsGet) !&RCloneClient {
|
||||
@@ -36,7 +36,7 @@ pub fn get(args ArgsGet) !&RCloneClient {
|
||||
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.')
|
||||
return error('RCloneClient with name: rclone does not exist, prob bug.')
|
||||
}
|
||||
mut obj := json.decode(RCloneClient, data)!
|
||||
set_in_mem(obj)!
|
||||
@@ -56,11 +56,11 @@ pub fn get(args ArgsGet) !&RCloneClient {
|
||||
|
||||
// register the config for the future
|
||||
pub fn set(o RCloneClient) ! {
|
||||
set_in_mem(o)!
|
||||
rclone_default = o.name
|
||||
mut o2 := set_in_mem(o)!
|
||||
rclone_default = o2.name
|
||||
mut context := base.context()!
|
||||
mut r := context.redis()!
|
||||
r.hset('context:rclone', o.name, json.encode(o))!
|
||||
r.hset('context:rclone', o2.name, json.encode(o2))!
|
||||
}
|
||||
|
||||
// does the config exists?
|
||||
@@ -109,18 +109,17 @@ pub fn list(args ArgsList) ![]&RCloneClient {
|
||||
}
|
||||
|
||||
// only sets in mem, does not set as config
|
||||
fn set_in_mem(o RCloneClient) ! {
|
||||
fn set_in_mem(o RCloneClient) !RCloneClient {
|
||||
mut o2 := obj_init(o)!
|
||||
rclone_global[o.name] = &o2
|
||||
rclone_default = o.name
|
||||
}
|
||||
|
||||
// switch instance to be used for rclone
|
||||
pub fn switch(name string) {
|
||||
rclone_default = name
|
||||
rclone_global[o2.name] = &o2
|
||||
rclone_default = o2.name
|
||||
return o2
|
||||
}
|
||||
|
||||
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 {
|
||||
@@ -130,3 +129,7 @@ pub fn play(mut plbook PlayBook) ! {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// switch instance to be used for rclone
|
||||
pub fn switch(name string) {
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ pub fn new(args ArgsGet) !&RunPod {
|
||||
name: args.name
|
||||
}
|
||||
set(obj)!
|
||||
return &obj
|
||||
return get(name: args.name)!
|
||||
}
|
||||
|
||||
pub fn get(args ArgsGet) !&RunPod {
|
||||
@@ -36,7 +36,7 @@ pub fn get(args ArgsGet) !&RunPod {
|
||||
if r.hexists('context:runpod', args.name)! {
|
||||
data := r.hget('context:runpod', args.name)!
|
||||
if data.len == 0 {
|
||||
return error('runpod with name: runpod does not exist, prob bug.')
|
||||
return error('RunPod with name: runpod does not exist, prob bug.')
|
||||
}
|
||||
mut obj := json.decode(RunPod, data)!
|
||||
set_in_mem(obj)!
|
||||
@@ -56,11 +56,11 @@ pub fn get(args ArgsGet) !&RunPod {
|
||||
|
||||
// register the config for the future
|
||||
pub fn set(o RunPod) ! {
|
||||
set_in_mem(o)!
|
||||
runpod_default = o.name
|
||||
mut o2 := set_in_mem(o)!
|
||||
runpod_default = o2.name
|
||||
mut context := base.context()!
|
||||
mut r := context.redis()!
|
||||
r.hset('context:runpod', o.name, json.encode(o))!
|
||||
r.hset('context:runpod', o2.name, json.encode(o2))!
|
||||
}
|
||||
|
||||
// does the config exists?
|
||||
@@ -109,18 +109,17 @@ pub fn list(args ArgsList) ![]&RunPod {
|
||||
}
|
||||
|
||||
// only sets in mem, does not set as config
|
||||
fn set_in_mem(o RunPod) ! {
|
||||
fn set_in_mem(o RunPod) !RunPod {
|
||||
mut o2 := obj_init(o)!
|
||||
runpod_global[o.name] = &o2
|
||||
runpod_default = o.name
|
||||
}
|
||||
|
||||
// switch instance to be used for runpod
|
||||
pub fn switch(name string) {
|
||||
runpod_default = name
|
||||
runpod_global[o2.name] = &o2
|
||||
runpod_default = o2.name
|
||||
return o2
|
||||
}
|
||||
|
||||
pub fn play(mut plbook PlayBook) ! {
|
||||
if !plbook.exists(filter: 'runpod.') {
|
||||
return
|
||||
}
|
||||
mut install_actions := plbook.find(filter: 'runpod.configure')!
|
||||
if install_actions.len > 0 {
|
||||
for install_action in install_actions {
|
||||
@@ -130,3 +129,8 @@ pub fn play(mut plbook PlayBook) ! {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// switch instance to be used for runpod
|
||||
pub fn switch(name string) {
|
||||
runpod_default = name
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ pub fn new(args ArgsGet) !&SendGrid {
|
||||
name: args.name
|
||||
}
|
||||
set(obj)!
|
||||
return &obj
|
||||
return get(name: args.name)!
|
||||
}
|
||||
|
||||
pub fn get(args ArgsGet) !&SendGrid {
|
||||
@@ -36,7 +36,7 @@ pub fn get(args ArgsGet) !&SendGrid {
|
||||
if r.hexists('context:sendgrid', args.name)! {
|
||||
data := r.hget('context:sendgrid', args.name)!
|
||||
if data.len == 0 {
|
||||
return error('sendgrid with name: sendgrid does not exist, prob bug.')
|
||||
return error('SendGrid with name: sendgrid does not exist, prob bug.')
|
||||
}
|
||||
mut obj := json.decode(SendGrid, data)!
|
||||
set_in_mem(obj)!
|
||||
@@ -56,11 +56,11 @@ pub fn get(args ArgsGet) !&SendGrid {
|
||||
|
||||
// register the config for the future
|
||||
pub fn set(o SendGrid) ! {
|
||||
set_in_mem(o)!
|
||||
sendgrid_default = o.name
|
||||
mut o2 := set_in_mem(o)!
|
||||
sendgrid_default = o2.name
|
||||
mut context := base.context()!
|
||||
mut r := context.redis()!
|
||||
r.hset('context:sendgrid', o.name, json.encode(o))!
|
||||
r.hset('context:sendgrid', o2.name, json.encode(o2))!
|
||||
}
|
||||
|
||||
// does the config exists?
|
||||
@@ -109,18 +109,17 @@ pub fn list(args ArgsList) ![]&SendGrid {
|
||||
}
|
||||
|
||||
// only sets in mem, does not set as config
|
||||
fn set_in_mem(o SendGrid) ! {
|
||||
fn set_in_mem(o SendGrid) !SendGrid {
|
||||
mut o2 := obj_init(o)!
|
||||
sendgrid_global[o.name] = &o2
|
||||
sendgrid_default = o.name
|
||||
}
|
||||
|
||||
// switch instance to be used for sendgrid
|
||||
pub fn switch(name string) {
|
||||
sendgrid_default = name
|
||||
sendgrid_global[o2.name] = &o2
|
||||
sendgrid_default = o2.name
|
||||
return o2
|
||||
}
|
||||
|
||||
pub fn play(mut plbook PlayBook) ! {
|
||||
if !plbook.exists(filter: 'sendgrid.') {
|
||||
return
|
||||
}
|
||||
mut install_actions := plbook.find(filter: 'sendgrid.configure')!
|
||||
if install_actions.len > 0 {
|
||||
for install_action in install_actions {
|
||||
@@ -130,3 +129,7 @@ pub fn play(mut plbook PlayBook) ! {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// switch instance to be used for sendgrid
|
||||
pub fn switch(name string) {
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ pub fn new(args ArgsGet) !&VastAI {
|
||||
name: args.name
|
||||
}
|
||||
set(obj)!
|
||||
return &obj
|
||||
return get(name: args.name)!
|
||||
}
|
||||
|
||||
pub fn get(args ArgsGet) !&VastAI {
|
||||
@@ -36,7 +36,7 @@ pub fn get(args ArgsGet) !&VastAI {
|
||||
if r.hexists('context:vastai', args.name)! {
|
||||
data := r.hget('context:vastai', args.name)!
|
||||
if data.len == 0 {
|
||||
return error('vastai with name: vastai does not exist, prob bug.')
|
||||
return error('VastAI with name: vastai does not exist, prob bug.')
|
||||
}
|
||||
mut obj := json.decode(VastAI, data)!
|
||||
set_in_mem(obj)!
|
||||
@@ -56,11 +56,11 @@ pub fn get(args ArgsGet) !&VastAI {
|
||||
|
||||
// register the config for the future
|
||||
pub fn set(o VastAI) ! {
|
||||
set_in_mem(o)!
|
||||
vastai_default = o.name
|
||||
mut o2 := set_in_mem(o)!
|
||||
vastai_default = o2.name
|
||||
mut context := base.context()!
|
||||
mut r := context.redis()!
|
||||
r.hset('context:vastai', o.name, json.encode(o))!
|
||||
r.hset('context:vastai', o2.name, json.encode(o2))!
|
||||
}
|
||||
|
||||
// does the config exists?
|
||||
@@ -109,18 +109,17 @@ pub fn list(args ArgsList) ![]&VastAI {
|
||||
}
|
||||
|
||||
// only sets in mem, does not set as config
|
||||
fn set_in_mem(o VastAI) ! {
|
||||
fn set_in_mem(o VastAI) !VastAI {
|
||||
mut o2 := obj_init(o)!
|
||||
vastai_global[o.name] = &o2
|
||||
vastai_default = o.name
|
||||
}
|
||||
|
||||
// switch instance to be used for vastai
|
||||
pub fn switch(name string) {
|
||||
vastai_default = name
|
||||
vastai_global[o2.name] = &o2
|
||||
vastai_default = o2.name
|
||||
return o2
|
||||
}
|
||||
|
||||
pub fn play(mut plbook PlayBook) ! {
|
||||
if !plbook.exists(filter: 'vastai.') {
|
||||
return
|
||||
}
|
||||
mut install_actions := plbook.find(filter: 'vastai.configure')!
|
||||
if install_actions.len > 0 {
|
||||
for install_action in install_actions {
|
||||
@@ -130,3 +129,7 @@ pub fn play(mut plbook PlayBook) ! {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// switch instance to be used for vastai
|
||||
pub fn switch(name string) {
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ pub fn new(args ArgsGet) !&WireGuard {
|
||||
name: args.name
|
||||
}
|
||||
set(obj)!
|
||||
return &obj
|
||||
return get(name: args.name)!
|
||||
}
|
||||
|
||||
pub fn get(args ArgsGet) !&WireGuard {
|
||||
@@ -36,7 +36,7 @@ pub fn get(args ArgsGet) !&WireGuard {
|
||||
if r.hexists('context:wireguard', args.name)! {
|
||||
data := r.hget('context:wireguard', args.name)!
|
||||
if data.len == 0 {
|
||||
return error('wireguard with name: wireguard does not exist, prob bug.')
|
||||
return error('WireGuard with name: wireguard does not exist, prob bug.')
|
||||
}
|
||||
mut obj := json.decode(WireGuard, data)!
|
||||
set_in_mem(obj)!
|
||||
@@ -56,11 +56,11 @@ pub fn get(args ArgsGet) !&WireGuard {
|
||||
|
||||
// register the config for the future
|
||||
pub fn set(o WireGuard) ! {
|
||||
set_in_mem(o)!
|
||||
wireguard_default = o.name
|
||||
mut o2 := set_in_mem(o)!
|
||||
wireguard_default = o2.name
|
||||
mut context := base.context()!
|
||||
mut r := context.redis()!
|
||||
r.hset('context:wireguard', o.name, json.encode(o))!
|
||||
r.hset('context:wireguard', o2.name, json.encode(o2))!
|
||||
}
|
||||
|
||||
// does the config exists?
|
||||
@@ -109,18 +109,17 @@ pub fn list(args ArgsList) ![]&WireGuard {
|
||||
}
|
||||
|
||||
// only sets in mem, does not set as config
|
||||
fn set_in_mem(o WireGuard) ! {
|
||||
fn set_in_mem(o WireGuard) !WireGuard {
|
||||
mut o2 := obj_init(o)!
|
||||
wireguard_global[o.name] = &o2
|
||||
wireguard_default = o.name
|
||||
}
|
||||
|
||||
// switch instance to be used for wireguard
|
||||
pub fn switch(name string) {
|
||||
wireguard_default = name
|
||||
wireguard_global[o2.name] = &o2
|
||||
wireguard_default = o2.name
|
||||
return o2
|
||||
}
|
||||
|
||||
pub fn play(mut plbook PlayBook) ! {
|
||||
if !plbook.exists(filter: 'wireguard.') {
|
||||
return
|
||||
}
|
||||
mut install_actions := plbook.find(filter: 'wireguard.configure')!
|
||||
if install_actions.len > 0 {
|
||||
for install_action in install_actions {
|
||||
@@ -130,3 +129,8 @@ pub fn play(mut plbook PlayBook) ! {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// switch instance to be used for wireguard
|
||||
pub fn switch(name string) {
|
||||
wireguard_default = name
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ pub fn new(args ArgsGet) !&ZeroDBClient {
|
||||
name: args.name
|
||||
}
|
||||
set(obj)!
|
||||
return &obj
|
||||
return get(name: args.name)!
|
||||
}
|
||||
|
||||
pub fn get(args ArgsGet) !&ZeroDBClient {
|
||||
@@ -36,7 +36,7 @@ pub fn get(args ArgsGet) !&ZeroDBClient {
|
||||
if r.hexists('context:zerodb_client', args.name)! {
|
||||
data := r.hget('context:zerodb_client', args.name)!
|
||||
if data.len == 0 {
|
||||
return error('zerodb_client with name: zerodb_client does not exist, prob bug.')
|
||||
return error('ZeroDBClient with name: zerodb_client does not exist, prob bug.')
|
||||
}
|
||||
mut obj := json.decode(ZeroDBClient, data)!
|
||||
set_in_mem(obj)!
|
||||
@@ -56,11 +56,11 @@ pub fn get(args ArgsGet) !&ZeroDBClient {
|
||||
|
||||
// register the config for the future
|
||||
pub fn set(o ZeroDBClient) ! {
|
||||
set_in_mem(o)!
|
||||
zerodb_client_default = o.name
|
||||
mut o2 := set_in_mem(o)!
|
||||
zerodb_client_default = o2.name
|
||||
mut context := base.context()!
|
||||
mut r := context.redis()!
|
||||
r.hset('context:zerodb_client', o.name, json.encode(o))!
|
||||
r.hset('context:zerodb_client', o2.name, json.encode(o2))!
|
||||
}
|
||||
|
||||
// does the config exists?
|
||||
@@ -109,18 +109,17 @@ pub fn list(args ArgsList) ![]&ZeroDBClient {
|
||||
}
|
||||
|
||||
// only sets in mem, does not set as config
|
||||
fn set_in_mem(o ZeroDBClient) ! {
|
||||
fn set_in_mem(o ZeroDBClient) !ZeroDBClient {
|
||||
mut o2 := obj_init(o)!
|
||||
zerodb_client_global[o.name] = &o2
|
||||
zerodb_client_default = o.name
|
||||
}
|
||||
|
||||
// switch instance to be used for zerodb_client
|
||||
pub fn switch(name string) {
|
||||
zerodb_client_default = name
|
||||
zerodb_client_global[o2.name] = &o2
|
||||
zerodb_client_default = o2.name
|
||||
return o2
|
||||
}
|
||||
|
||||
pub fn play(mut plbook PlayBook) ! {
|
||||
if !plbook.exists(filter: 'zerodb_client.') {
|
||||
return
|
||||
}
|
||||
mut install_actions := plbook.find(filter: 'zerodb_client.configure')!
|
||||
if install_actions.len > 0 {
|
||||
for install_action in install_actions {
|
||||
@@ -130,3 +129,7 @@ pub fn play(mut plbook PlayBook) ! {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// switch instance to be used for zerodb_client
|
||||
pub fn switch(name string) {
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
|
||||
!!hero_code.generate_client
|
||||
name:'zinit_rpc'
|
||||
name:'zinit'
|
||||
classname:'ZinitRPC'
|
||||
singleton:1
|
||||
default:0
|
||||
singleton:0
|
||||
default:1
|
||||
hasconfig:1
|
||||
reset:0
|
||||
@@ -1,152 +1,219 @@
|
||||
# Zinit OpenRPC Client
|
||||
# Zinit RPC Client
|
||||
|
||||
This is a V language client for the Zinit service manager, implementing the OpenRPC specification.
|
||||
This is a V language client for the Zinit process manager, implementing the JSON-RPC API specification for service management operations.
|
||||
|
||||
## Overview
|
||||
|
||||
Zinit is a service manager that allows you to manage and monitor services on your system. This client provides a comprehensive API to interact with Zinit via its JSON-RPC interface.
|
||||
Zinit is a process manager that provides service monitoring, dependency management, and system control capabilities. This client provides a comprehensive API to interact with Zinit via its JSON-RPC interface for administrative tasks such as:
|
||||
|
||||
- Service lifecycle management (start, stop, monitor, forget)
|
||||
- Service configuration management (create, delete, get)
|
||||
- Service status and statistics monitoring
|
||||
- System operations (shutdown, reboot, HTTP server control)
|
||||
- Log streaming and monitoring
|
||||
|
||||
## Features
|
||||
|
||||
- Complete implementation of all methods in the Zinit OpenRPC specification
|
||||
- Type-safe API with proper error handling
|
||||
- Comprehensive documentation
|
||||
- Helper functions for common operations
|
||||
- Example code for all operations
|
||||
- **✅ 100% API Coverage**: Complete implementation of all 18 methods in the Zinit JSON-RPC specification
|
||||
- **✅ Production Tested**: All methods tested and working against real Zinit instances
|
||||
- **✅ Type-safe API**: Proper V struct definitions with comprehensive error handling
|
||||
- **✅ Subscription Support**: Proper handling of streaming/subscription methods
|
||||
- **✅ Unix Socket Transport**: Reliable communication via Unix domain sockets
|
||||
- **✅ Comprehensive Documentation**: Extensive documentation with working examples
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic Example
|
||||
|
||||
```v
|
||||
import freeflowuniverse.heroweb.clients.zinit
|
||||
import freeflowuniverse.herolib.clients.zinit
|
||||
|
||||
fn main() {
|
||||
// Create a new client with the default socket path
|
||||
mut client := zinit.new_default_client()
|
||||
|
||||
// List all services
|
||||
services := client.service_list() or {
|
||||
println('Error: ${err}')
|
||||
return
|
||||
}
|
||||
|
||||
// Print the services
|
||||
for name, state in services {
|
||||
println('${name}: ${state}')
|
||||
}
|
||||
|
||||
// Get status of a specific service
|
||||
if services.len > 0 {
|
||||
service_name := services.keys()[0]
|
||||
status := client.service_status(service_name) or {
|
||||
println('Error: ${err}')
|
||||
return
|
||||
}
|
||||
|
||||
println('Service: ${status.name}')
|
||||
println('State: ${status.state}')
|
||||
println('PID: ${status.pid}')
|
||||
// Create a new client
|
||||
mut client := zinit.get(create:true)!
|
||||
|
||||
// List all services
|
||||
services := client.service_list()!
|
||||
for service_name, state in services {
|
||||
println('Service: ${service_name}, State: ${state}')
|
||||
}
|
||||
|
||||
// Get detailed status of a specific service
|
||||
status := client.service_status('redis')!
|
||||
println('Service: ${status.name}')
|
||||
println('PID: ${status.pid}')
|
||||
println('State: ${status.state}')
|
||||
println('Target: ${status.target}')
|
||||
|
||||
// Start a service
|
||||
client.service_start('redis')!
|
||||
|
||||
// Stop a service
|
||||
client.service_stop('redis')!
|
||||
```
|
||||
|
||||
### Service Configuration Management
|
||||
|
||||
```v
|
||||
import freeflowuniverse.herolib.clients.zinit
|
||||
|
||||
mut client := zinit.new_client()!
|
||||
|
||||
// Create a new service configuration
|
||||
config := zinit.ServiceConfig{
|
||||
exec: '/usr/bin/redis-server'
|
||||
oneshot: false
|
||||
log: 'stdout'
|
||||
env: {
|
||||
'REDIS_PORT': '6379'
|
||||
'REDIS_HOST': '0.0.0.0'
|
||||
}
|
||||
shutdown_timeout: 30
|
||||
}
|
||||
|
||||
// Create the service
|
||||
path := client.service_create('redis', config)!
|
||||
println('Service created at: ${path}')
|
||||
|
||||
// Get service configuration
|
||||
retrieved_config := client.service_get('redis')!
|
||||
println('Service exec: ${retrieved_config.exec}')
|
||||
|
||||
// Delete service configuration
|
||||
result := client.service_delete('redis')!
|
||||
println('Delete result: ${result}')
|
||||
```
|
||||
|
||||
### Service Statistics
|
||||
|
||||
```v
|
||||
import freeflowuniverse.herolib.clients.zinit
|
||||
|
||||
mut client := zinit.new_client()!
|
||||
|
||||
// Get service statistics
|
||||
stats := client.service_stats('redis')!
|
||||
println('Service: ${stats.name}')
|
||||
println('PID: ${stats.pid}')
|
||||
println('Memory Usage: ${stats.memory_usage} bytes')
|
||||
println('CPU Usage: ${stats.cpu_usage}%')
|
||||
|
||||
// Print child process statistics
|
||||
for child in stats.children {
|
||||
println('Child PID: ${child.pid}, Memory: ${child.memory_usage}, CPU: ${child.cpu_usage}%')
|
||||
}
|
||||
```
|
||||
|
||||
### Creating and Managing Services
|
||||
### Log Streaming
|
||||
|
||||
```v
|
||||
import freeflowuniverse.heroweb.clients.zinit
|
||||
import freeflowuniverse.herolib.clients.zinit
|
||||
|
||||
fn main() {
|
||||
mut client := zinit.new_default_client()
|
||||
|
||||
// Create a new service configuration
|
||||
config := zinit.ServiceConfig{
|
||||
exec: '/bin/echo "Hello, World!"'
|
||||
oneshot: true
|
||||
log: zinit.log_stdout
|
||||
env: {
|
||||
'ENV_VAR': 'value'
|
||||
}
|
||||
}
|
||||
|
||||
// Create the service
|
||||
client.service_create('hello', config) or {
|
||||
println('Error creating service: ${err}')
|
||||
return
|
||||
}
|
||||
|
||||
// Start the service
|
||||
client.service_start('hello') or {
|
||||
println('Error starting service: ${err}')
|
||||
return
|
||||
}
|
||||
|
||||
// Get the service logs
|
||||
logs := client.stream_current_logs('hello') or {
|
||||
println('Error getting logs: ${err}')
|
||||
return
|
||||
}
|
||||
|
||||
for log in logs {
|
||||
println(log)
|
||||
}
|
||||
|
||||
// Clean up
|
||||
client.service_stop('hello') or {}
|
||||
client.service_forget('hello') or {}
|
||||
client.service_delete('hello') or {}
|
||||
mut client := zinit.new_client()!
|
||||
|
||||
// Get current logs for all services
|
||||
logs := client.stream_current_logs(name: '')!
|
||||
for log in logs {
|
||||
println(log)
|
||||
}
|
||||
|
||||
// Get current logs for a specific service
|
||||
redis_logs := client.stream_current_logs(name: 'redis')!
|
||||
for log in redis_logs {
|
||||
println('Redis: ${log}')
|
||||
}
|
||||
|
||||
// Subscribe to log stream (returns subscription ID)
|
||||
subscription_id := client.stream_subscribe_logs(name: 'redis')!
|
||||
println('Subscribed to logs with ID: ${subscription_id}')
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### Client Creation
|
||||
### Service Management Methods
|
||||
|
||||
- `new_client(socket_path string) &Client` - Create a new client with a custom socket path
|
||||
- `new_default_client() &Client` - Create a new client with the default socket path (`/tmp/zinit.sock`)
|
||||
- `service_list()` - List all services and their states
|
||||
- `service_status(name)` - Get detailed status of a service
|
||||
- `service_start(name)` - Start a service
|
||||
- `service_stop(name)` - Stop a service
|
||||
- `service_monitor(name)` - Start monitoring a service
|
||||
- `service_forget(name)` - Stop monitoring a service
|
||||
- `service_kill(name, signal)` - Send signal to a service
|
||||
|
||||
### Service Management
|
||||
### Service Configuration Methods
|
||||
|
||||
- `service_list() !map[string]string` - List all services and their states
|
||||
- `service_status(name string) !ServiceStatus` - Get detailed status of a service
|
||||
- `service_start(name string) !` - Start a service
|
||||
- `service_stop(name string) !` - Stop a service
|
||||
- `service_monitor(name string) !` - Start monitoring a service
|
||||
- `service_forget(name string) !` - Stop monitoring a service
|
||||
- `service_kill(name string, signal string) !` - Send a signal to a service
|
||||
- `service_create(name string, config ServiceConfig) !string` - Create a new service
|
||||
- `service_delete(name string) !string` - Delete a service
|
||||
- `service_get(name string) !ServiceConfig` - Get a service configuration
|
||||
- `service_stats(name string) !ServiceStats` - Get memory and CPU usage statistics
|
||||
- `service_create(name, config)` - Create service configuration
|
||||
- `service_delete(name)` - Delete service configuration
|
||||
- `service_get(name)` - Get service configuration
|
||||
|
||||
### System Operations
|
||||
### Monitoring Methods
|
||||
|
||||
- `system_shutdown() !` - Stop all services and power off the system
|
||||
- `system_reboot() !` - Stop all services and reboot the system
|
||||
- `system_start_http_server(address string) !string` - Start an HTTP/RPC server
|
||||
- `system_stop_http_server() !` - Stop the HTTP/RPC server
|
||||
- `service_stats(name)` - Get service statistics
|
||||
|
||||
### Logs
|
||||
### System Methods
|
||||
|
||||
- `stream_current_logs(name ?string) ![]string` - Get current logs
|
||||
- `stream_subscribe_logs(name ?string) !string` - Subscribe to log messages
|
||||
- `system_shutdown()` - Shutdown the system
|
||||
- `system_reboot()` - Reboot the system
|
||||
- `system_start_http_server(address)` - Start HTTP server
|
||||
- `system_stop_http_server()` - Stop HTTP server
|
||||
|
||||
## Constants
|
||||
### Streaming Methods
|
||||
|
||||
- `default_socket_path` - Default Unix socket path (`/tmp/zinit.sock`)
|
||||
- `state_running`, `state_success`, `state_error`, etc. - Common service states
|
||||
- `target_up`, `target_down` - Common service targets
|
||||
- `log_null`, `log_ring`, `log_stdout` - Common log types
|
||||
- `signal_term`, `signal_kill`, etc. - Common signals
|
||||
- `stream_current_logs(args)` - Get current logs (returns array of log lines)
|
||||
- `stream_subscribe_logs(args)` - Subscribe to log stream (returns subscription ID)
|
||||
|
||||
## Helper Functions
|
||||
### Discovery Methods
|
||||
|
||||
- `new_service_config(exec string) ServiceConfig` - Create a basic service configuration
|
||||
- `new_oneshot_service_config(exec string) ServiceConfig` - Create a oneshot service configuration
|
||||
- `is_service_not_found_error(err IError) bool` - Check if an error is a "service not found" error
|
||||
- `format_memory_usage(bytes i64) string` - Format memory usage in human-readable format
|
||||
- `format_cpu_usage(cpu_percent f64) string` - Format CPU usage
|
||||
- `rpc_discover()` - Get OpenRPC specification
|
||||
|
||||
## Configuration
|
||||
|
||||
### Using the Factory Pattern
|
||||
|
||||
```v
|
||||
import freeflowuniverse.herolib.clients.zinit
|
||||
|
||||
// Get client using factory (recommended)
|
||||
mut client := zinit.get()!
|
||||
|
||||
// Use the client
|
||||
services := client.service_list()!
|
||||
```
|
||||
|
||||
### Example Heroscript Configuration
|
||||
|
||||
```hero
|
||||
!!zinit.configure
|
||||
name: 'production'
|
||||
socket_path: '/tmp/zinit.sock'
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
The client provides comprehensive error handling for all Zinit-specific error codes:
|
||||
|
||||
- `-32000`: Service not found
|
||||
- `-32001`: Service already monitored
|
||||
- `-32002`: Service is up
|
||||
- `-32003`: Service is down
|
||||
- `-32004`: Invalid signal
|
||||
- `-32005`: Config error
|
||||
- `-32006`: Shutting down
|
||||
- `-32007`: Service already exists
|
||||
- `-32008`: Service file error
|
||||
|
||||
```v
|
||||
import freeflowuniverse.herolib.clients.zinit
|
||||
|
||||
mut client := zinit.new_client()!
|
||||
|
||||
// Handle specific errors
|
||||
client.service_start('nonexistent') or {
|
||||
if err.msg().contains('Service not found') {
|
||||
println('Service does not exist')
|
||||
} else {
|
||||
println('Other error: ${err}')
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
@@ -1,18 +0,0 @@
|
||||
module zinit
|
||||
|
||||
// Request Types for Zinit API
|
||||
//
|
||||
// This file contains all the request types used by the Zinit API.
|
||||
|
||||
// ZinitError represents an error returned by the zinit API
|
||||
pub struct ZinitError {
|
||||
pub mut:
|
||||
code int // Error code
|
||||
message string // Error message
|
||||
data string // Additional error data
|
||||
}
|
||||
|
||||
// Error implements the error interface for ZinitError
|
||||
pub fn (e ZinitError) msg() string {
|
||||
return 'Zinit Error ${e.code}: ${e.message} - ${e.data}'
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
module zinit
|
||||
|
||||
import freeflowuniverse.herolib.schemas.jsonrpc
|
||||
|
||||
// Client is an OpenRPC client for Zinit
|
||||
pub struct Client {
|
||||
mut:
|
||||
rpc_client &jsonrpc.Client
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct ClientParams {
|
||||
path string = '/tmp/zinit.sock' // Path to the Zinit RPC socket
|
||||
}
|
||||
|
||||
// new_client creates a new Zinit RPC client with a custom socket path
|
||||
pub fn new_client(args_ ClientParams) &Client {
|
||||
mut args := args_
|
||||
mut cl := jsonrpc.new_unix_socket_client(args.path)
|
||||
return &Client{
|
||||
rpc_client: cl
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
module zinit
|
||||
|
||||
// ServiceCreateResponse represents the response from service_create
|
||||
pub struct ServiceCreateResponse {
|
||||
pub mut:
|
||||
path string // Path to the created service file
|
||||
}
|
||||
|
||||
// ServiceDeleteResponse represents the response from service_delete
|
||||
pub struct ServiceDeleteResponse {
|
||||
pub mut:
|
||||
result string // Result of the delete operation
|
||||
}
|
||||
|
||||
// SystemStartHttpServerResponse represents the response from system_start_http_server
|
||||
pub struct SystemStartHttpServerResponse {
|
||||
pub mut:
|
||||
result string // Result of starting the HTTP server
|
||||
}
|
||||
|
||||
// StreamCurrentLogsResponse represents the response from stream_currentLogs
|
||||
pub struct StreamCurrentLogsResponse {
|
||||
pub mut:
|
||||
logs []string // Log entries
|
||||
}
|
||||
|
||||
// StreamSubscribeLogsResponse represents the response from stream_subscribeLogs
|
||||
pub struct StreamSubscribeLogsResponse {
|
||||
pub mut:
|
||||
subscription_id string // ID of the log subscription
|
||||
}
|
||||
|
||||
// Module version information
|
||||
pub const version = '1.0.0'
|
||||
pub const author = 'Hero Code'
|
||||
pub const license = 'MIT'
|
||||
|
||||
// Default socket path for zinit
|
||||
pub const default_socket_path = '/tmp/zinit.sock'
|
||||
|
||||
// Common service states
|
||||
pub const state_running = 'Running'
|
||||
pub const state_success = 'Success'
|
||||
pub const state_error = 'Error'
|
||||
pub const state_stopped = 'Stopped'
|
||||
pub const state_failed = 'Failed'
|
||||
|
||||
// Common service targets
|
||||
pub const target_up = 'Up'
|
||||
pub const target_down = 'Down'
|
||||
|
||||
// Common log types
|
||||
pub const log_null = 'null'
|
||||
pub const log_ring = 'ring'
|
||||
pub const log_stdout = 'stdout'
|
||||
|
||||
// Common signals
|
||||
pub const signal_term = 'SIGTERM'
|
||||
pub const signal_kill = 'SIGKILL'
|
||||
pub const signal_hup = 'SIGHUP'
|
||||
pub const signal_usr1 = 'SIGUSR1'
|
||||
pub const signal_usr2 = 'SIGUSR2'
|
||||
|
||||
// JSON-RPC error codes as defined in the OpenRPC specification
|
||||
pub const error_service_not_found = -32000
|
||||
pub const error_service_already_monitored = -32001
|
||||
pub const error_service_is_up = -32002
|
||||
pub const error_service_is_down = -32003
|
||||
pub const error_invalid_signal = -32004
|
||||
pub const error_config_error = -32005
|
||||
pub const error_shutting_down = -32006
|
||||
pub const error_service_already_exists = -32007
|
||||
pub const error_service_file_error = -32008
|
||||
63
lib/clients/zinit/model_openrpc.v
Normal file
63
lib/clients/zinit/model_openrpc.v
Normal file
@@ -0,0 +1,63 @@
|
||||
module zinit
|
||||
|
||||
// ServiceStatus represents detailed status information for a service
|
||||
pub struct ServiceStatus {
|
||||
pub mut:
|
||||
name string // Service name
|
||||
pid u32 // Process ID of the running service (if running)
|
||||
state string // Current state of the service (Running, Success, Error, etc.)
|
||||
target string // Target state of the service (Up, Down)
|
||||
after map[string]string // Dependencies of the service and their states
|
||||
}
|
||||
|
||||
// ServiceConfig represents the configuration for a zinit service
|
||||
pub struct ServiceConfig {
|
||||
pub mut:
|
||||
exec string // Command to run
|
||||
test string // Test command (optional)
|
||||
oneshot bool // Whether the service should be restarted (maps to one_shot in Zinit)
|
||||
after []string // Services that must be running before this one starts
|
||||
log string // How to handle service output (null, ring, stdout)
|
||||
env map[string]string // Environment variables for the service
|
||||
dir string // Working directory for the service
|
||||
shutdown_timeout u64 // Maximum time to wait for service to stop during shutdown
|
||||
}
|
||||
|
||||
// ServiceStats represents memory and CPU usage statistics for a service
|
||||
pub struct ServiceStats {
|
||||
pub mut:
|
||||
name string // Service name
|
||||
pid u32 // Process ID of the service
|
||||
memory_usage u64 // Memory usage in bytes
|
||||
cpu_usage f32 // CPU usage as a percentage (0-100)
|
||||
children []ChildStats // Stats for child processes
|
||||
}
|
||||
|
||||
// ChildStats represents statistics for a child process
|
||||
pub struct ChildStats {
|
||||
pub mut:
|
||||
pid u32 // Process ID of the child process
|
||||
memory_usage u64 // Memory usage in bytes
|
||||
cpu_usage f32 // CPU usage as a percentage (0-100)
|
||||
}
|
||||
|
||||
// ServiceCreateParams represents parameters for service_create method
|
||||
pub struct ServiceCreateParams {
|
||||
pub mut:
|
||||
name string // Name of the service to create
|
||||
content ServiceConfig // Configuration for the service
|
||||
}
|
||||
|
||||
// ServiceKillParams represents parameters for service_kill method
|
||||
pub struct ServiceKillParams {
|
||||
pub mut:
|
||||
name string // Name of the service to kill
|
||||
signal string // Signal to send (e.g., SIGTERM, SIGKILL)
|
||||
}
|
||||
|
||||
// LogParams represents parameters for log streaming methods
|
||||
@[params]
|
||||
pub struct LogParams {
|
||||
pub mut:
|
||||
name string // Optional service name filter
|
||||
}
|
||||
@@ -1,175 +0,0 @@
|
||||
module zinit
|
||||
|
||||
import freeflowuniverse.herolib.schemas.jsonrpc
|
||||
|
||||
// ServiceConfig represents the configuration for a zinit service
|
||||
pub struct ServiceConfig {
|
||||
pub mut:
|
||||
exec string // Command to run
|
||||
oneshot bool // Whether the service should be restarted
|
||||
after []string // Services that must be running before this one starts
|
||||
log string // How to handle service output (null, ring, stdout)
|
||||
env map[string]string // Environment variables for the service
|
||||
shutdown_timeout int // Maximum time to wait for service to stop during shutdown
|
||||
}
|
||||
|
||||
// KillParams represents the parameters for the service_kill method
|
||||
pub struct KillParams {
|
||||
pub:
|
||||
name string // Name of the service to kill
|
||||
signal string // Signal to send (e.g., SIGTERM, SIGKILL)
|
||||
}
|
||||
|
||||
// RpcDiscoverResponse represents the response from rpc.discover
|
||||
pub struct RpcDiscoverResponse {
|
||||
pub mut:
|
||||
spec map[string]string // OpenRPC specification
|
||||
}
|
||||
|
||||
// rpc_discover returns the OpenRPC specification for the API
|
||||
pub fn (mut c Client) rpc_discover() !RpcDiscoverResponse {
|
||||
request := jsonrpc.new_request_generic('rpc.discover', []string{})
|
||||
response := c.rpc_client.send[[]string, map[string]string](request)!
|
||||
return RpcDiscoverResponse{
|
||||
spec: response
|
||||
}
|
||||
}
|
||||
|
||||
// // Response Models for Zinit API
|
||||
// //
|
||||
// // This file contains all the response models used by the Zinit API.
|
||||
// // These models are used as type parameters in the response generics.
|
||||
|
||||
// // ServiceListResponse represents the response from service_list
|
||||
// pub struct ServiceListResponse {
|
||||
// pub mut:
|
||||
// // Map of service names to their current states
|
||||
// services map[string]string
|
||||
// }
|
||||
|
||||
// service_list lists all services managed by Zinit
|
||||
// Returns a map of service names to their current states
|
||||
pub fn (mut c Client) service_list() !map[string]string {
|
||||
request := jsonrpc.new_request_generic('service_list', map[string]string{})
|
||||
services := c.rpc_client.send[map[string]string, map[string]string](request)!
|
||||
// return ServiceListResponse{
|
||||
// services: services
|
||||
// }
|
||||
return services
|
||||
}
|
||||
|
||||
// ServiceStatusResponse represents the response from service_status
|
||||
pub struct ServiceStatusResponse {
|
||||
pub mut:
|
||||
name string // Service name
|
||||
pid int // Process ID of the running service (if running)
|
||||
state string // Current state of the service (Running, Success, Error, etc.)
|
||||
target string // Target state of the service (Up, Down)
|
||||
after map[string]string // Dependencies of the service and their states
|
||||
}
|
||||
|
||||
// service_status shows detailed status information for a specific service
|
||||
// name: the name of the service
|
||||
pub fn (mut c Client) service_status(name string) !ServiceStatusResponse {
|
||||
request := jsonrpc.new_request_generic('service_status', name)
|
||||
|
||||
// Use a direct struct mapping instead of manual conversion
|
||||
return c.rpc_client.send[string, ServiceStatusResponse](request)!
|
||||
}
|
||||
|
||||
// service_start starts a service
|
||||
// name: the name of the service to start
|
||||
pub fn (mut c Client) service_start(name string) ! {
|
||||
request := jsonrpc.new_request_generic('service_start', name)
|
||||
c.rpc_client.send[string, string](request)!
|
||||
}
|
||||
|
||||
// service_stop stops a service
|
||||
// name: the name of the service to stop
|
||||
pub fn (mut c Client) service_stop(name string) ! {
|
||||
request := jsonrpc.new_request_generic('service_stop', name)
|
||||
c.rpc_client.send[string, string](request)!
|
||||
}
|
||||
|
||||
// service_monitor starts monitoring a service
|
||||
// The service configuration is loaded from the config directory
|
||||
// name: the name of the service to monitor
|
||||
pub fn (mut c Client) service_monitor(name string) ! {
|
||||
request := jsonrpc.new_request_generic('service_monitor', name)
|
||||
c.rpc_client.send[string, string](request)!
|
||||
}
|
||||
|
||||
// service_delete deletes a service configuration file
|
||||
// name: the name of the service to delete
|
||||
pub fn (mut c Client) service_delete(name string) !ServiceDeleteResponse {
|
||||
request := jsonrpc.new_request_generic('service_delete', name)
|
||||
result := c.rpc_client.send[string, string](request)!
|
||||
return ServiceDeleteResponse{
|
||||
result: result
|
||||
}
|
||||
}
|
||||
|
||||
// service_forget stops monitoring a service
|
||||
// You can only forget a stopped service
|
||||
// name: the name of the service to forget
|
||||
pub fn (mut c Client) service_forget(name string) ! {
|
||||
request := jsonrpc.new_request_generic('service_forget', name)
|
||||
c.rpc_client.send[string, string](request)!
|
||||
}
|
||||
|
||||
// TODO: make sure the signal is a valid signal and enumerator do as @[params] so its optional
|
||||
|
||||
// service_kill sends a signal to a running service
|
||||
// name: the name of the service to send the signal to
|
||||
// signal: the signal to send (e.g., SIGTERM, SIGKILL)
|
||||
pub fn (mut c Client) service_kill(name string, signal string) ! {
|
||||
params := KillParams{
|
||||
name: name
|
||||
signal: signal
|
||||
}
|
||||
|
||||
request := jsonrpc.new_request_generic('service_kill', params)
|
||||
c.rpc_client.send[KillParams, string](request)!
|
||||
}
|
||||
|
||||
// CreateServiceParams represents the parameters for the service_create method
|
||||
struct CreateServiceParams {
|
||||
name string // Name of the service to create
|
||||
content ServiceConfig // Configuration for the service
|
||||
}
|
||||
|
||||
// service_create creates a new service configuration file
|
||||
// name: the name of the service to create
|
||||
// config: the service configuration
|
||||
pub fn (mut c Client) service_create(name string, config ServiceConfig) !ServiceCreateResponse {
|
||||
params := CreateServiceParams{
|
||||
name: name
|
||||
content: config
|
||||
}
|
||||
|
||||
request := jsonrpc.new_request_generic('service_create', params)
|
||||
path := c.rpc_client.send[CreateServiceParams, string](request)!
|
||||
return ServiceCreateResponse{
|
||||
path: path
|
||||
}
|
||||
}
|
||||
|
||||
// service_get gets a service configuration file
|
||||
// name: the name of the service to get
|
||||
pub fn (mut c Client) service_get(name string) !ServiceConfigResponse {
|
||||
request := jsonrpc.new_request_generic('service_get', {
|
||||
'name': name
|
||||
})
|
||||
|
||||
// We need to handle the conversion from ServiceConfig to ServiceConfigResponse
|
||||
config := c.rpc_client.send[map[string]string, ServiceConfig](request)!
|
||||
|
||||
return ServiceConfigResponse{
|
||||
exec: config.exec
|
||||
oneshot: config.oneshot
|
||||
after: config.after
|
||||
log: config.log
|
||||
env: config.env
|
||||
shutdown_timeout: config.shutdown_timeout
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
module zinit
|
||||
|
||||
pub struct ServiceConfigResponse {
|
||||
pub mut:
|
||||
exec string // Command to run
|
||||
oneshot bool // Whether the service should be restarted
|
||||
after []string // Services that must be running before this one starts
|
||||
log string // How to handle service output (null, ring, stdout)
|
||||
env map[string]string // Environment variables for the service
|
||||
shutdown_timeout int // Maximum time to wait for service to stop during shutdown
|
||||
}
|
||||
|
||||
// Helper function to create a basic service configuration
|
||||
pub fn new_service_config(exec string) ServiceConfig {
|
||||
return ServiceConfig{
|
||||
exec: exec
|
||||
oneshot: false
|
||||
log: log_stdout
|
||||
env: map[string]string{}
|
||||
shutdown_timeout: 30
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to create a oneshot service configuration
|
||||
pub fn new_oneshot_service_config(exec string) ServiceConfig {
|
||||
return ServiceConfig{
|
||||
exec: exec
|
||||
oneshot: true
|
||||
log: log_stdout
|
||||
env: map[string]string{}
|
||||
shutdown_timeout: 30
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
module zinit
|
||||
|
||||
import freeflowuniverse.herolib.schemas.jsonrpc
|
||||
|
||||
// ServiceStatsResponse represents the response from service_stats
|
||||
pub struct ServiceStatsResponse {
|
||||
pub mut:
|
||||
name string // Service name
|
||||
pid int // Process ID of the service
|
||||
memory_usage i64 // Memory usage in bytes
|
||||
cpu_usage f64 // CPU usage as a percentage (0-100)
|
||||
children []ChildStatsResponse // Stats for child processes
|
||||
}
|
||||
|
||||
// ChildStatsResponse represents statistics for a child process
|
||||
pub struct ChildStatsResponse {
|
||||
pub mut:
|
||||
pid int // Process ID of the child process
|
||||
memory_usage i64 // Memory usage in bytes
|
||||
cpu_usage f64 // CPU usage as a percentage (0-100)
|
||||
}
|
||||
|
||||
// Serv
|
||||
|
||||
// service_stats gets memory and CPU usage statistics for a service
|
||||
// name: the name of the service to get stats for
|
||||
pub fn (mut c Client) service_stats(name string) !ServiceStatsResponse {
|
||||
request := jsonrpc.new_request_generic('service_stats', name)
|
||||
|
||||
// We need to handle the conversion from the raw response to our model
|
||||
raw_stats := c.rpc_client.send[string, map[string]string](request)!
|
||||
|
||||
// Parse the raw stats into our response model
|
||||
mut children := []ChildStatsResponse{}
|
||||
// In a real implementation, we would parse the children from the raw response
|
||||
|
||||
return ServiceStatsResponse{
|
||||
name: raw_stats['name'] or { '' }
|
||||
pid: raw_stats['pid'].int()
|
||||
memory_usage: raw_stats['memory_usage'].i64()
|
||||
cpu_usage: raw_stats['cpu_usage'].f64()
|
||||
children: children
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
module zinit
|
||||
|
||||
import freeflowuniverse.herolib.schemas.jsonrpc
|
||||
|
||||
// system_shutdown stops all services and powers off the system
|
||||
pub fn (mut c Client) system_shutdown() ! {
|
||||
request := jsonrpc.new_request_generic('system_shutdown', []string{})
|
||||
c.rpc_client.send[[]string, string](request)!
|
||||
}
|
||||
|
||||
// system_reboot stops all services and reboots the system
|
||||
pub fn (mut c Client) system_reboot() ! {
|
||||
request := jsonrpc.new_request_generic('system_reboot', []string{})
|
||||
c.rpc_client.send[[]string, string](request)!
|
||||
}
|
||||
|
||||
// system_start_http_server starts an HTTP/RPC server at the specified address
|
||||
// address: the network address to bind the server to (e.g., '127.0.0.1:8080')
|
||||
pub fn (mut c Client) system_start_http_server(address string) !SystemStartHttpServerResponse {
|
||||
request := jsonrpc.new_request_generic('system_start_http_server', address)
|
||||
result := c.rpc_client.send[string, string](request)!
|
||||
return SystemStartHttpServerResponse{
|
||||
result: result
|
||||
}
|
||||
}
|
||||
|
||||
// system_stop_http_server stops the HTTP/RPC server if running
|
||||
pub fn (mut c Client) system_stop_http_server() ! {
|
||||
request := jsonrpc.new_request_generic('system_stop_http_server', []string{})
|
||||
c.rpc_client.send[[]string, string](request)!
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct LogParams {
|
||||
name string
|
||||
}
|
||||
|
||||
// stream_current_logs gets current logs from zinit and monitored services
|
||||
// name: optional service name filter. If provided, only logs from this service will be returned
|
||||
pub fn (mut c Client) stream_current_logs(args LogParams) ![]string {
|
||||
mut logs := []string{}
|
||||
|
||||
if args.name != '' {
|
||||
request := jsonrpc.new_request_generic('stream_currentLogs', {
|
||||
'name': args.name
|
||||
})
|
||||
logs = c.rpc_client.send[map[string]string, map[string]string](request)!
|
||||
} else {
|
||||
request := jsonrpc.new_request_generic('stream_currentLogs', map[string]string{})
|
||||
logs = c.rpc_client.send[[]map[string]string, map[string]string](request)!
|
||||
}
|
||||
return logs
|
||||
}
|
||||
|
||||
// stream_subscribe_logs subscribes to log messages generated by zinit and monitored services
|
||||
// name: optional service name filter. If provided, only logs from this service will be returned
|
||||
pub fn (mut c Client) stream_subscribe_logs(name ?string) !StreamSubscribeLogsResponse {
|
||||
mut subscription_id := ''
|
||||
|
||||
if service_name := name {
|
||||
request := jsonrpc.new_request_generic('stream_subscribeLogs', service_name)
|
||||
subscription_id = c.rpc_client.send[string, string](request)!
|
||||
} else {
|
||||
request := jsonrpc.new_request_generic('stream_subscribeLogs', []string{})
|
||||
subscription_id = c.rpc_client.send[[]string, string](request)!
|
||||
}
|
||||
|
||||
return StreamSubscribeLogsResponse{
|
||||
subscription_id: subscription_id
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
module zinit
|
||||
|
||||
// Helper function to format memory usage in human-readable format
|
||||
pub fn format_memory_usage(bytes i64) string {
|
||||
if bytes < 1024 {
|
||||
return '${bytes} B'
|
||||
} else if bytes < 1024 * 1024 {
|
||||
return '${bytes / 1024} KB'
|
||||
} else if bytes < 1024 * 1024 * 1024 {
|
||||
return '${bytes / 1024 / 1024} MB'
|
||||
} else {
|
||||
return '${bytes / 1024 / 1024 / 1024} GB'
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to format CPU usage
|
||||
pub fn format_cpu_usage(cpu_percent f64) string {
|
||||
return '${cpu_percent:.1f}%'
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
module zinit_rpc
|
||||
module zinit
|
||||
|
||||
import freeflowuniverse.herolib.schemas.jsonrpc
|
||||
import freeflowuniverse.herolib.schemas.jsonrpcmodel
|
||||
|
||||
// Helper function to get or create the RPC client
|
||||
fn (mut c ZinitRPC) get_client() !&jsonrpc.Client {
|
||||
fn (mut c ZinitRPC) client_() !&jsonrpc.Client {
|
||||
if client := c.rpc_client {
|
||||
return client
|
||||
}
|
||||
@@ -16,23 +17,23 @@ fn (mut c ZinitRPC) get_client() !&jsonrpc.Client {
|
||||
// Admin methods
|
||||
|
||||
// rpc_discover returns the OpenRPC specification for the API
|
||||
pub fn (mut c ZinitRPC) rpc_discover() !OpenRPCSpec {
|
||||
mut client := c.get_client()!
|
||||
pub fn (mut c ZinitRPC) rpc_discover() !jsonrpcmodel.OpenRPCSpec {
|
||||
mut client := c.client_()!
|
||||
request := jsonrpc.new_request_generic('rpc.discover', []string{})
|
||||
return client.send[[]string, OpenRPCSpec](request)!
|
||||
return client.send[[]string, jsonrpcmodel.OpenRPCSpec](request)!
|
||||
}
|
||||
|
||||
// service_list lists all services managed by Zinit
|
||||
// Returns a map of service names to their current states
|
||||
pub fn (mut c ZinitRPC) service_list() !map[string]string {
|
||||
mut client := c.get_client()!
|
||||
mut client := c.client_()!
|
||||
request := jsonrpc.new_request_generic('service_list', []string{})
|
||||
return client.send[[]string, map[string]string](request)!
|
||||
}
|
||||
|
||||
// service_status shows detailed status information for a specific service
|
||||
pub fn (mut c ZinitRPC) service_status(name string) !ServiceStatus {
|
||||
mut client := c.get_client()!
|
||||
mut client := c.client_()!
|
||||
params := {
|
||||
'name': name
|
||||
}
|
||||
@@ -42,7 +43,7 @@ pub fn (mut c ZinitRPC) service_status(name string) !ServiceStatus {
|
||||
|
||||
// service_start starts a service
|
||||
pub fn (mut c ZinitRPC) service_start(name string) ! {
|
||||
mut client := c.get_client()!
|
||||
mut client := c.client_()!
|
||||
params := {
|
||||
'name': name
|
||||
}
|
||||
@@ -52,7 +53,7 @@ pub fn (mut c ZinitRPC) service_start(name string) ! {
|
||||
|
||||
// service_stop stops a service
|
||||
pub fn (mut c ZinitRPC) service_stop(name string) ! {
|
||||
mut client := c.get_client()!
|
||||
mut client := c.client_()!
|
||||
params := {
|
||||
'name': name
|
||||
}
|
||||
@@ -63,7 +64,7 @@ pub fn (mut c ZinitRPC) service_stop(name string) ! {
|
||||
// service_monitor starts monitoring a service
|
||||
// The service configuration is loaded from the config directory
|
||||
pub fn (mut c ZinitRPC) service_monitor(name string) ! {
|
||||
mut client := c.get_client()!
|
||||
mut client := c.client_()!
|
||||
params := {
|
||||
'name': name
|
||||
}
|
||||
@@ -74,7 +75,7 @@ pub fn (mut c ZinitRPC) service_monitor(name string) ! {
|
||||
// service_forget stops monitoring a service
|
||||
// You can only forget a stopped service
|
||||
pub fn (mut c ZinitRPC) service_forget(name string) ! {
|
||||
mut client := c.get_client()!
|
||||
mut client := c.client_()!
|
||||
params := {
|
||||
'name': name
|
||||
}
|
||||
@@ -84,7 +85,7 @@ pub fn (mut c ZinitRPC) service_forget(name string) ! {
|
||||
|
||||
// service_kill sends a signal to a running service
|
||||
pub fn (mut c ZinitRPC) service_kill(name string, signal string) ! {
|
||||
mut client := c.get_client()!
|
||||
mut client := c.client_()!
|
||||
params := ServiceKillParams{
|
||||
name: name
|
||||
signal: signal
|
||||
@@ -95,7 +96,7 @@ pub fn (mut c ZinitRPC) service_kill(name string, signal string) ! {
|
||||
|
||||
// service_create creates a new service configuration file
|
||||
pub fn (mut c ZinitRPC) service_create(name string, config ServiceConfig) !string {
|
||||
mut client := c.get_client()!
|
||||
mut client := c.client_()!
|
||||
params := ServiceCreateParams{
|
||||
name: name
|
||||
content: config
|
||||
@@ -106,7 +107,7 @@ pub fn (mut c ZinitRPC) service_create(name string, config ServiceConfig) !strin
|
||||
|
||||
// service_delete deletes a service configuration file
|
||||
pub fn (mut c ZinitRPC) service_delete(name string) !string {
|
||||
mut client := c.get_client()!
|
||||
mut client := c.client_()!
|
||||
params := {
|
||||
'name': name
|
||||
}
|
||||
@@ -116,7 +117,7 @@ pub fn (mut c ZinitRPC) service_delete(name string) !string {
|
||||
|
||||
// service_get gets a service configuration file
|
||||
pub fn (mut c ZinitRPC) service_get(name string) !ServiceConfig {
|
||||
mut client := c.get_client()!
|
||||
mut client := c.client_()!
|
||||
params := {
|
||||
'name': name
|
||||
}
|
||||
@@ -126,7 +127,7 @@ pub fn (mut c ZinitRPC) service_get(name string) !ServiceConfig {
|
||||
|
||||
// service_stats gets memory and CPU usage statistics for a service
|
||||
pub fn (mut c ZinitRPC) service_stats(name string) !ServiceStats {
|
||||
mut client := c.get_client()!
|
||||
mut client := c.client_()!
|
||||
params := {
|
||||
'name': name
|
||||
}
|
||||
@@ -138,21 +139,21 @@ pub fn (mut c ZinitRPC) service_stats(name string) !ServiceStats {
|
||||
|
||||
// system_shutdown stops all services and powers off the system
|
||||
pub fn (mut c ZinitRPC) system_shutdown() ! {
|
||||
mut client := c.get_client()!
|
||||
mut client := c.client_()!
|
||||
request := jsonrpc.new_request_generic('system_shutdown', []string{})
|
||||
client.send[[]string, string](request)!
|
||||
}
|
||||
|
||||
// system_reboot stops all services and reboots the system
|
||||
pub fn (mut c ZinitRPC) system_reboot() ! {
|
||||
mut client := c.get_client()!
|
||||
mut client := c.client_()!
|
||||
request := jsonrpc.new_request_generic('system_reboot', []string{})
|
||||
client.send[[]string, string](request)!
|
||||
}
|
||||
|
||||
// system_start_http_server starts an HTTP/RPC server at the specified address
|
||||
pub fn (mut c ZinitRPC) system_start_http_server(address string) !string {
|
||||
mut client := c.get_client()!
|
||||
mut client := c.client_()!
|
||||
params := {
|
||||
'address': address
|
||||
}
|
||||
@@ -162,7 +163,7 @@ pub fn (mut c ZinitRPC) system_start_http_server(address string) !string {
|
||||
|
||||
// system_stop_http_server stops the HTTP/RPC server if running
|
||||
pub fn (mut c ZinitRPC) system_stop_http_server() ! {
|
||||
mut client := c.get_client()!
|
||||
mut client := c.client_()!
|
||||
request := jsonrpc.new_request_generic('system_stop_http_server', []string{})
|
||||
client.send[[]string, string](request)!
|
||||
}
|
||||
@@ -171,7 +172,7 @@ pub fn (mut c ZinitRPC) system_stop_http_server() ! {
|
||||
|
||||
// stream_current_logs gets current logs from zinit and monitored services
|
||||
pub fn (mut c ZinitRPC) stream_current_logs(args LogParams) ![]string {
|
||||
mut client := c.get_client()!
|
||||
mut client := c.client_()!
|
||||
if args.name != '' {
|
||||
params := {
|
||||
'name': args.name
|
||||
@@ -187,7 +188,7 @@ pub fn (mut c ZinitRPC) stream_current_logs(args LogParams) ![]string {
|
||||
// stream_subscribe_logs subscribes to log messages generated by zinit and monitored services
|
||||
// Returns a subscription ID that can be used to manage the subscription
|
||||
pub fn (mut c ZinitRPC) stream_subscribe_logs(args LogParams) !u64 {
|
||||
mut client := c.get_client()!
|
||||
mut client := c.client_()!
|
||||
if args.name != '' {
|
||||
params := {
|
||||
'name': args.name
|
||||
@@ -1,4 +1,4 @@
|
||||
module zinit_rpc
|
||||
module zinit
|
||||
|
||||
import freeflowuniverse.herolib.core.base
|
||||
import freeflowuniverse.herolib.core.playbook { PlayBook }
|
||||
@@ -6,8 +6,8 @@ import freeflowuniverse.herolib.ui.console
|
||||
import json
|
||||
|
||||
__global (
|
||||
zinit_rpc_global map[string]&ZinitRPC
|
||||
zinit_rpc_default string
|
||||
zinit_global map[string]&ZinitRPC
|
||||
zinit_default string
|
||||
)
|
||||
|
||||
/////////FACTORY
|
||||
@@ -25,18 +25,18 @@ pub fn new(args ArgsGet) !&ZinitRPC {
|
||||
name: args.name
|
||||
}
|
||||
set(obj)!
|
||||
return &obj
|
||||
return get(name: args.name)!
|
||||
}
|
||||
|
||||
pub fn get(args ArgsGet) !&ZinitRPC {
|
||||
mut context := base.context()!
|
||||
zinit_rpc_default = args.name
|
||||
if args.fromdb || args.name !in zinit_rpc_global {
|
||||
zinit_default = args.name
|
||||
if args.fromdb || args.name !in zinit_global {
|
||||
mut r := context.redis()!
|
||||
if r.hexists('context:zinit_rpc', args.name)! {
|
||||
data := r.hget('context:zinit_rpc', args.name)!
|
||||
if r.hexists('context:zinit', args.name)! {
|
||||
data := r.hget('context:zinit', args.name)!
|
||||
if data.len == 0 {
|
||||
return error('zinit_rpc with name: zinit_rpc does not exist, prob bug.')
|
||||
return error('ZinitRPC with name: zinit does not exist, prob bug.')
|
||||
}
|
||||
mut obj := json.decode(ZinitRPC, data)!
|
||||
set_in_mem(obj)!
|
||||
@@ -44,36 +44,36 @@ pub fn get(args ArgsGet) !&ZinitRPC {
|
||||
if args.create {
|
||||
new(args)!
|
||||
} else {
|
||||
return error("ZinitRPC with name 'zinit_rpc' does not exist")
|
||||
return error("ZinitRPC with name 'zinit' does not exist")
|
||||
}
|
||||
}
|
||||
return get(name: args.name)! // no longer from db nor create
|
||||
}
|
||||
return zinit_rpc_global[args.name] or {
|
||||
return error('could not get config for zinit_rpc with name:zinit_rpc')
|
||||
return zinit_global[args.name] or {
|
||||
return error('could not get config for zinit with name:zinit')
|
||||
}
|
||||
}
|
||||
|
||||
// register the config for the future
|
||||
pub fn set(o ZinitRPC) ! {
|
||||
set_in_mem(o)!
|
||||
zinit_rpc_default = o.name
|
||||
mut o2 := set_in_mem(o)!
|
||||
zinit_default = o2.name
|
||||
mut context := base.context()!
|
||||
mut r := context.redis()!
|
||||
r.hset('context:zinit_rpc', o.name, json.encode(o))!
|
||||
r.hset('context:zinit', o2.name, json.encode(o2))!
|
||||
}
|
||||
|
||||
// does the config exists?
|
||||
pub fn exists(args ArgsGet) !bool {
|
||||
mut context := base.context()!
|
||||
mut r := context.redis()!
|
||||
return r.hexists('context:zinit_rpc', args.name)!
|
||||
return r.hexists('context:zinit', args.name)!
|
||||
}
|
||||
|
||||
pub fn delete(args ArgsGet) ! {
|
||||
mut context := base.context()!
|
||||
mut r := context.redis()!
|
||||
r.hdel('context:zinit_rpc', args.name)!
|
||||
r.hdel('context:zinit', args.name)!
|
||||
}
|
||||
|
||||
@[params]
|
||||
@@ -88,12 +88,12 @@ pub fn list(args ArgsList) ![]&ZinitRPC {
|
||||
mut context := base.context()!
|
||||
if args.fromdb {
|
||||
// reset what is in mem
|
||||
zinit_rpc_global = map[string]&ZinitRPC{}
|
||||
zinit_rpc_default = ''
|
||||
zinit_global = map[string]&ZinitRPC{}
|
||||
zinit_default = ''
|
||||
}
|
||||
if args.fromdb {
|
||||
mut r := context.redis()!
|
||||
mut l := r.hkeys('context:zinit_rpc')!
|
||||
mut l := r.hkeys('context:zinit')!
|
||||
|
||||
for name in l {
|
||||
res << get(name: name, fromdb: true)!
|
||||
@@ -101,7 +101,7 @@ pub fn list(args ArgsList) ![]&ZinitRPC {
|
||||
return res
|
||||
} else {
|
||||
// load from memory
|
||||
for _, client in zinit_rpc_global {
|
||||
for _, client in zinit_global {
|
||||
res << client
|
||||
}
|
||||
}
|
||||
@@ -109,19 +109,18 @@ pub fn list(args ArgsList) ![]&ZinitRPC {
|
||||
}
|
||||
|
||||
// only sets in mem, does not set as config
|
||||
fn set_in_mem(o ZinitRPC) ! {
|
||||
fn set_in_mem(o ZinitRPC) !ZinitRPC {
|
||||
mut o2 := obj_init(o)!
|
||||
zinit_rpc_global[o.name] = &o2
|
||||
zinit_rpc_default = o.name
|
||||
}
|
||||
|
||||
// switch instance to be used for zinit_rpc
|
||||
pub fn switch(name string) {
|
||||
zinit_rpc_default = name
|
||||
zinit_global[o2.name] = &o2
|
||||
zinit_default = o2.name
|
||||
return o2
|
||||
}
|
||||
|
||||
pub fn play(mut plbook PlayBook) ! {
|
||||
mut install_actions := plbook.find(filter: 'zinit_rpc.configure')!
|
||||
if !plbook.exists(filter: 'zinit.') {
|
||||
return
|
||||
}
|
||||
mut install_actions := plbook.find(filter: 'zinit.configure')!
|
||||
if install_actions.len > 0 {
|
||||
for install_action in install_actions {
|
||||
heroscript := install_action.heroscript()
|
||||
@@ -130,3 +129,8 @@ pub fn play(mut plbook PlayBook) ! {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// switch instance to be used for zinit
|
||||
pub fn switch(name string) {
|
||||
zinit_default = name
|
||||
}
|
||||
48
lib/clients/zinit/zinit_model.v
Normal file
48
lib/clients/zinit/zinit_model.v
Normal file
@@ -0,0 +1,48 @@
|
||||
module zinit
|
||||
|
||||
import freeflowuniverse.herolib.data.encoderhero
|
||||
import freeflowuniverse.herolib.schemas.jsonrpc
|
||||
import os
|
||||
|
||||
pub const version = '0.0.0'
|
||||
const singleton = true
|
||||
const default = false
|
||||
|
||||
// // Factory function to create a new ZinitRPC client instance
|
||||
// @[params]
|
||||
// pub struct NewClientArgs {
|
||||
// pub mut:
|
||||
// name string = 'default'
|
||||
// socket_path string
|
||||
// }
|
||||
|
||||
// pub fn new_client(args NewClientArgs) !&ZinitRPC {
|
||||
// mut client := ZinitRPC{
|
||||
// name: args.name
|
||||
// socket_path: args.socket_path
|
||||
// }
|
||||
// client = obj_init(client)!
|
||||
// return &client
|
||||
// }
|
||||
|
||||
@[heap]
|
||||
pub struct ZinitRPC {
|
||||
pub mut:
|
||||
name string = 'default'
|
||||
socket_path string
|
||||
rpc_client ?&jsonrpc.Client @[skip]
|
||||
}
|
||||
|
||||
// your checking & initialization code if needed
|
||||
fn obj_init(mycfg_ ZinitRPC) !ZinitRPC {
|
||||
mut mycfg := mycfg_
|
||||
if mycfg.socket_path == '' {
|
||||
mycfg.socket_path = '/tmp/zinit.sock'
|
||||
}
|
||||
return mycfg
|
||||
}
|
||||
|
||||
pub fn heroscript_loads(heroscript string) !ZinitRPC {
|
||||
mut obj := encoderhero.decode[ZinitRPC](heroscript)!
|
||||
return obj
|
||||
}
|
||||
@@ -1,873 +0,0 @@
|
||||
{
|
||||
"openrpc": "1.2.6",
|
||||
"info": {
|
||||
"version": "1.0.0",
|
||||
"title": "Zinit JSON-RPC API",
|
||||
"description": "JSON-RPC 2.0 API for controlling and querying Zinit services",
|
||||
"license": {
|
||||
"name": "MIT"
|
||||
}
|
||||
},
|
||||
"servers": [
|
||||
{
|
||||
"name": "Unix Socket",
|
||||
"url": "unix:///tmp/zinit.sock"
|
||||
}
|
||||
],
|
||||
"methods": [
|
||||
{
|
||||
"name": "rpc.discover",
|
||||
"description": "Returns the OpenRPC specification for the API",
|
||||
"params": [],
|
||||
"result": {
|
||||
"name": "OpenRPCSpec",
|
||||
"description": "The OpenRPC specification",
|
||||
"schema": {
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"examples": [
|
||||
{
|
||||
"name": "Get API specification",
|
||||
"params": [],
|
||||
"result": {
|
||||
"name": "OpenRPCSpecResult",
|
||||
"value": {
|
||||
"openrpc": "1.2.6",
|
||||
"info": {
|
||||
"version": "1.0.0",
|
||||
"title": "Zinit JSON-RPC API"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "service_list",
|
||||
"description": "Lists all services managed by Zinit",
|
||||
"params": [],
|
||||
"result": {
|
||||
"name": "ServiceList",
|
||||
"description": "A map of service names to their current states",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string",
|
||||
"description": "Service state (Running, Success, Error, etc.)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"examples": [
|
||||
{
|
||||
"name": "List all services",
|
||||
"params": [],
|
||||
"result": {
|
||||
"name": "ServiceListResult",
|
||||
"value": {
|
||||
"service1": "Running",
|
||||
"service2": "Success",
|
||||
"service3": "Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "service_status",
|
||||
"description": "Shows detailed status information for a specific service",
|
||||
"params": [
|
||||
{
|
||||
"name": "name",
|
||||
"description": "The name of the service",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"name": "ServiceStatus",
|
||||
"description": "Detailed status information for the service",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Service name"
|
||||
},
|
||||
"pid": {
|
||||
"type": "integer",
|
||||
"description": "Process ID of the running service (if running)"
|
||||
},
|
||||
"state": {
|
||||
"type": "string",
|
||||
"description": "Current state of the service (Running, Success, Error, etc.)"
|
||||
},
|
||||
"target": {
|
||||
"type": "string",
|
||||
"description": "Target state of the service (Up, Down)"
|
||||
},
|
||||
"after": {
|
||||
"type": "object",
|
||||
"description": "Dependencies of the service and their states",
|
||||
"additionalProperties": {
|
||||
"type": "string",
|
||||
"description": "State of the dependency"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"examples": [
|
||||
{
|
||||
"name": "Get status of redis service",
|
||||
"params": [
|
||||
{
|
||||
"name": "name",
|
||||
"value": "redis"
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"name": "ServiceStatusResult",
|
||||
"value": {
|
||||
"name": "redis",
|
||||
"pid": 1234,
|
||||
"state": "Running",
|
||||
"target": "Up",
|
||||
"after": {
|
||||
"dependency1": "Success",
|
||||
"dependency2": "Running"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"errors": [
|
||||
{
|
||||
"code": -32000,
|
||||
"message": "Service not found",
|
||||
"data": "service name \"unknown\" unknown"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "service_start",
|
||||
"description": "Starts a service",
|
||||
"params": [
|
||||
{
|
||||
"name": "name",
|
||||
"description": "The name of the service to start",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"name": "StartResult",
|
||||
"description": "Result of the start operation",
|
||||
"schema": {
|
||||
"type": "null"
|
||||
}
|
||||
},
|
||||
"examples": [
|
||||
{
|
||||
"name": "Start redis service",
|
||||
"params": [
|
||||
{
|
||||
"name": "name",
|
||||
"value": "redis"
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"name": "StartResult",
|
||||
"value": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"errors": [
|
||||
{
|
||||
"code": -32000,
|
||||
"message": "Service not found",
|
||||
"data": "service name \"unknown\" unknown"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "service_stop",
|
||||
"description": "Stops a service",
|
||||
"params": [
|
||||
{
|
||||
"name": "name",
|
||||
"description": "The name of the service to stop",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"name": "StopResult",
|
||||
"description": "Result of the stop operation",
|
||||
"schema": {
|
||||
"type": "null"
|
||||
}
|
||||
},
|
||||
"examples": [
|
||||
{
|
||||
"name": "Stop redis service",
|
||||
"params": [
|
||||
{
|
||||
"name": "name",
|
||||
"value": "redis"
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"name": "StopResult",
|
||||
"value": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"errors": [
|
||||
{
|
||||
"code": -32000,
|
||||
"message": "Service not found",
|
||||
"data": "service name \"unknown\" unknown"
|
||||
},
|
||||
{
|
||||
"code": -32003,
|
||||
"message": "Service is down",
|
||||
"data": "service \"redis\" is down"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "service_monitor",
|
||||
"description": "Starts monitoring a service. The service configuration is loaded from the config directory.",
|
||||
"params": [
|
||||
{
|
||||
"name": "name",
|
||||
"description": "The name of the service to monitor",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"name": "MonitorResult",
|
||||
"description": "Result of the monitor operation",
|
||||
"schema": {
|
||||
"type": "null"
|
||||
}
|
||||
},
|
||||
"examples": [
|
||||
{
|
||||
"name": "Monitor redis service",
|
||||
"params": [
|
||||
{
|
||||
"name": "name",
|
||||
"value": "redis"
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"name": "MonitorResult",
|
||||
"value": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"errors": [
|
||||
{
|
||||
"code": -32001,
|
||||
"message": "Service already monitored",
|
||||
"data": "service \"redis\" already monitored"
|
||||
},
|
||||
{
|
||||
"code": -32005,
|
||||
"message": "Config error",
|
||||
"data": "failed to load service configuration"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "service_forget",
|
||||
"description": "Stops monitoring a service. You can only forget a stopped service.",
|
||||
"params": [
|
||||
{
|
||||
"name": "name",
|
||||
"description": "The name of the service to forget",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"name": "ForgetResult",
|
||||
"description": "Result of the forget operation",
|
||||
"schema": {
|
||||
"type": "null"
|
||||
}
|
||||
},
|
||||
"examples": [
|
||||
{
|
||||
"name": "Forget redis service",
|
||||
"params": [
|
||||
{
|
||||
"name": "name",
|
||||
"value": "redis"
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"name": "ForgetResult",
|
||||
"value": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"errors": [
|
||||
{
|
||||
"code": -32000,
|
||||
"message": "Service not found",
|
||||
"data": "service name \"unknown\" unknown"
|
||||
},
|
||||
{
|
||||
"code": -32002,
|
||||
"message": "Service is up",
|
||||
"data": "service \"redis\" is up"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "service_kill",
|
||||
"description": "Sends a signal to a running service",
|
||||
"params": [
|
||||
{
|
||||
"name": "name",
|
||||
"description": "The name of the service to send the signal to",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "signal",
|
||||
"description": "The signal to send (e.g., SIGTERM, SIGKILL)",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"name": "KillResult",
|
||||
"description": "Result of the kill operation",
|
||||
"schema": {
|
||||
"type": "null"
|
||||
}
|
||||
},
|
||||
"examples": [
|
||||
{
|
||||
"name": "Send SIGTERM to redis service",
|
||||
"params": [
|
||||
{
|
||||
"name": "name",
|
||||
"value": "redis"
|
||||
},
|
||||
{
|
||||
"name": "signal",
|
||||
"value": "SIGTERM"
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"name": "KillResult",
|
||||
"value": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"errors": [
|
||||
{
|
||||
"code": -32000,
|
||||
"message": "Service not found",
|
||||
"data": "service name \"unknown\" unknown"
|
||||
},
|
||||
{
|
||||
"code": -32003,
|
||||
"message": "Service is down",
|
||||
"data": "service \"redis\" is down"
|
||||
},
|
||||
{
|
||||
"code": -32004,
|
||||
"message": "Invalid signal",
|
||||
"data": "invalid signal: INVALID"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "system_shutdown",
|
||||
"description": "Stops all services and powers off the system",
|
||||
"params": [],
|
||||
"result": {
|
||||
"name": "ShutdownResult",
|
||||
"description": "Result of the shutdown operation",
|
||||
"schema": {
|
||||
"type": "null"
|
||||
}
|
||||
},
|
||||
"examples": [
|
||||
{
|
||||
"name": "Shutdown the system",
|
||||
"params": [],
|
||||
"result": {
|
||||
"name": "ShutdownResult",
|
||||
"value": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"errors": [
|
||||
{
|
||||
"code": -32006,
|
||||
"message": "Shutting down",
|
||||
"data": "system is already shutting down"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "system_reboot",
|
||||
"description": "Stops all services and reboots the system",
|
||||
"params": [],
|
||||
"result": {
|
||||
"name": "RebootResult",
|
||||
"description": "Result of the reboot operation",
|
||||
"schema": {
|
||||
"type": "null"
|
||||
}
|
||||
},
|
||||
"examples": [
|
||||
{
|
||||
"name": "Reboot the system",
|
||||
"params": [],
|
||||
"result": {
|
||||
"name": "RebootResult",
|
||||
"value": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"errors": [
|
||||
{
|
||||
"code": -32006,
|
||||
"message": "Shutting down",
|
||||
"data": "system is already shutting down"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "service_create",
|
||||
"description": "Creates a new service configuration file",
|
||||
"params": [
|
||||
{
|
||||
"name": "name",
|
||||
"description": "The name of the service to create",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "content",
|
||||
"description": "The service configuration content",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"exec": {
|
||||
"type": "string",
|
||||
"description": "Command to run"
|
||||
},
|
||||
"oneshot": {
|
||||
"type": "boolean",
|
||||
"description": "Whether the service should be restarted"
|
||||
},
|
||||
"after": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Services that must be running before this one starts"
|
||||
},
|
||||
"log": {
|
||||
"type": "string",
|
||||
"enum": ["null", "ring", "stdout"],
|
||||
"description": "How to handle service output"
|
||||
},
|
||||
"env": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Environment variables for the service"
|
||||
},
|
||||
"shutdown_timeout": {
|
||||
"type": "integer",
|
||||
"description": "Maximum time to wait for service to stop during shutdown"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"name": "CreateServiceResult",
|
||||
"description": "Result of the create operation",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"errors": [
|
||||
{
|
||||
"code": -32007,
|
||||
"message": "Service already exists",
|
||||
"data": "Service 'name' already exists"
|
||||
},
|
||||
{
|
||||
"code": -32008,
|
||||
"message": "Service file error",
|
||||
"data": "Failed to create service file"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "service_delete",
|
||||
"description": "Deletes a service configuration file",
|
||||
"params": [
|
||||
{
|
||||
"name": "name",
|
||||
"description": "The name of the service to delete",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"name": "DeleteServiceResult",
|
||||
"description": "Result of the delete operation",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"errors": [
|
||||
{
|
||||
"code": -32000,
|
||||
"message": "Service not found",
|
||||
"data": "Service 'name' not found"
|
||||
},
|
||||
{
|
||||
"code": -32008,
|
||||
"message": "Service file error",
|
||||
"data": "Failed to delete service file"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "service_get",
|
||||
"description": "Gets a service configuration file",
|
||||
"params": [
|
||||
{
|
||||
"name": "name",
|
||||
"description": "The name of the service to get",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"name": "GetServiceResult",
|
||||
"description": "The service configuration",
|
||||
"schema": {
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"errors": [
|
||||
{
|
||||
"code": -32000,
|
||||
"message": "Service not found",
|
||||
"data": "Service 'name' not found"
|
||||
},
|
||||
{
|
||||
"code": -32008,
|
||||
"message": "Service file error",
|
||||
"data": "Failed to read service file"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "service_stats",
|
||||
"description": "Get memory and CPU usage statistics for a service",
|
||||
"params": [
|
||||
{
|
||||
"name": "name",
|
||||
"description": "The name of the service to get stats for",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"name": "ServiceStats",
|
||||
"description": "Memory and CPU usage statistics for the service",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Service name"
|
||||
},
|
||||
"pid": {
|
||||
"type": "integer",
|
||||
"description": "Process ID of the service"
|
||||
},
|
||||
"memory_usage": {
|
||||
"type": "integer",
|
||||
"description": "Memory usage in bytes"
|
||||
},
|
||||
"cpu_usage": {
|
||||
"type": "number",
|
||||
"description": "CPU usage as a percentage (0-100)"
|
||||
},
|
||||
"children": {
|
||||
"type": "array",
|
||||
"description": "Stats for child processes",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"pid": {
|
||||
"type": "integer",
|
||||
"description": "Process ID of the child process"
|
||||
},
|
||||
"memory_usage": {
|
||||
"type": "integer",
|
||||
"description": "Memory usage in bytes"
|
||||
},
|
||||
"cpu_usage": {
|
||||
"type": "number",
|
||||
"description": "CPU usage as a percentage (0-100)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"examples": [
|
||||
{
|
||||
"name": "Get stats for redis service",
|
||||
"params": [
|
||||
{
|
||||
"name": "name",
|
||||
"value": "redis"
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"name": "ServiceStatsResult",
|
||||
"value": {
|
||||
"name": "redis",
|
||||
"pid": 1234,
|
||||
"memory_usage": 10485760,
|
||||
"cpu_usage": 2.5,
|
||||
"children": [
|
||||
{
|
||||
"pid": 1235,
|
||||
"memory_usage": 5242880,
|
||||
"cpu_usage": 1.2
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"errors": [
|
||||
{
|
||||
"code": -32000,
|
||||
"message": "Service not found",
|
||||
"data": "service name \"unknown\" unknown"
|
||||
},
|
||||
{
|
||||
"code": -32003,
|
||||
"message": "Service is down",
|
||||
"data": "service \"redis\" is down"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "system_start_http_server",
|
||||
"description": "Start an HTTP/RPC server at the specified address",
|
||||
"params": [
|
||||
{
|
||||
"name": "address",
|
||||
"description": "The network address to bind the server to (e.g., '127.0.0.1:8080')",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"name": "StartHttpServerResult",
|
||||
"description": "Result of the start HTTP server operation",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"examples": [
|
||||
{
|
||||
"name": "Start HTTP server on localhost:8080",
|
||||
"params": [
|
||||
{
|
||||
"name": "address",
|
||||
"value": "127.0.0.1:8080"
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"name": "StartHttpServerResult",
|
||||
"value": "HTTP server started at 127.0.0.1:8080"
|
||||
}
|
||||
}
|
||||
],
|
||||
"errors": [
|
||||
{
|
||||
"code": -32602,
|
||||
"message": "Invalid address",
|
||||
"data": "Invalid network address format"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "system_stop_http_server",
|
||||
"description": "Stop the HTTP/RPC server if running",
|
||||
"params": [],
|
||||
"result": {
|
||||
"name": "StopHttpServerResult",
|
||||
"description": "Result of the stop HTTP server operation",
|
||||
"schema": {
|
||||
"type": "null"
|
||||
}
|
||||
},
|
||||
"examples": [
|
||||
{
|
||||
"name": "Stop the HTTP server",
|
||||
"params": [],
|
||||
"result": {
|
||||
"name": "StopHttpServerResult",
|
||||
"value": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"errors": [
|
||||
{
|
||||
"code": -32602,
|
||||
"message": "Server not running",
|
||||
"data": "No HTTP server is currently running"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stream_currentLogs",
|
||||
"description": "Get current logs from zinit and monitored services",
|
||||
"params": [
|
||||
{
|
||||
"name": "name",
|
||||
"description": "Optional service name filter. If provided, only logs from this service will be returned",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"name": "LogsResult",
|
||||
"description": "Array of log strings",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"examples": [
|
||||
{
|
||||
"name": "Get all logs",
|
||||
"params": [],
|
||||
"result": {
|
||||
"name": "LogsResult",
|
||||
"value": [
|
||||
"2023-01-01T12:00:00 redis: Starting service",
|
||||
"2023-01-01T12:00:01 nginx: Starting service"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Get logs for a specific service",
|
||||
"params": [
|
||||
{
|
||||
"name": "name",
|
||||
"value": "redis"
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"name": "LogsResult",
|
||||
"value": [
|
||||
"2023-01-01T12:00:00 redis: Starting service",
|
||||
"2023-01-01T12:00:02 redis: Service started"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stream_subscribeLogs",
|
||||
"description": "Subscribe to log messages generated by zinit and monitored services",
|
||||
"params": [
|
||||
{
|
||||
"name": "name",
|
||||
"description": "Optional service name filter. If provided, only logs from this service will be returned",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"name": "LogSubscription",
|
||||
"description": "A subscription to log messages",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"examples": [
|
||||
{
|
||||
"name": "Subscribe to all logs",
|
||||
"params": [],
|
||||
"result": {
|
||||
"name": "LogSubscription",
|
||||
"value": "2023-01-01T12:00:00 redis: Service started"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Subscribe to filtered logs",
|
||||
"params": [
|
||||
{
|
||||
"name": "name",
|
||||
"value": "redis"
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"name": "LogSubscription",
|
||||
"value": "2023-01-01T12:00:00 redis: Service started"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,222 +0,0 @@
|
||||
# Zinit RPC Client
|
||||
|
||||
This is a V language client for the Zinit process manager, implementing the JSON-RPC API specification for service management operations.
|
||||
|
||||
## Overview
|
||||
|
||||
Zinit is a process manager that provides service monitoring, dependency management, and system control capabilities. This client provides a comprehensive API to interact with Zinit via its JSON-RPC interface for administrative tasks such as:
|
||||
|
||||
- Service lifecycle management (start, stop, monitor, forget)
|
||||
- Service configuration management (create, delete, get)
|
||||
- Service status and statistics monitoring
|
||||
- System operations (shutdown, reboot, HTTP server control)
|
||||
- Log streaming and monitoring
|
||||
|
||||
## Features
|
||||
|
||||
- **✅ 100% API Coverage**: Complete implementation of all 18 methods in the Zinit JSON-RPC specification
|
||||
- **✅ Production Tested**: All methods tested and working against real Zinit instances
|
||||
- **✅ Type-safe API**: Proper V struct definitions with comprehensive error handling
|
||||
- **✅ Subscription Support**: Proper handling of streaming/subscription methods
|
||||
- **✅ Unix Socket Transport**: Reliable communication via Unix domain sockets
|
||||
- **✅ Comprehensive Documentation**: Extensive documentation with working examples
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic Example
|
||||
|
||||
```v
|
||||
import freeflowuniverse.herolib.clients.zinit_rpc
|
||||
|
||||
// Create a new client
|
||||
mut client := zinit_rpc.new_client(
|
||||
name: 'my_client'
|
||||
socket_path: '/tmp/zinit.sock'
|
||||
)!
|
||||
|
||||
// List all services
|
||||
services := client.service_list()!
|
||||
for service_name, state in services {
|
||||
println('Service: ${service_name}, State: ${state}')
|
||||
}
|
||||
|
||||
// Get detailed status of a specific service
|
||||
status := client.service_status('redis')!
|
||||
println('Service: ${status.name}')
|
||||
println('PID: ${status.pid}')
|
||||
println('State: ${status.state}')
|
||||
println('Target: ${status.target}')
|
||||
|
||||
// Start a service
|
||||
client.service_start('redis')!
|
||||
|
||||
// Stop a service
|
||||
client.service_stop('redis')!
|
||||
```
|
||||
|
||||
### Service Configuration Management
|
||||
|
||||
```v
|
||||
import freeflowuniverse.herolib.clients.zinit_rpc
|
||||
|
||||
mut client := zinit_rpc.new_client()!
|
||||
|
||||
// Create a new service configuration
|
||||
config := zinit_rpc.ServiceConfig{
|
||||
exec: '/usr/bin/redis-server'
|
||||
oneshot: false
|
||||
log: 'stdout'
|
||||
env: {
|
||||
'REDIS_PORT': '6379'
|
||||
'REDIS_HOST': '0.0.0.0'
|
||||
}
|
||||
shutdown_timeout: 30
|
||||
}
|
||||
|
||||
// Create the service
|
||||
path := client.service_create('redis', config)!
|
||||
println('Service created at: ${path}')
|
||||
|
||||
// Get service configuration
|
||||
retrieved_config := client.service_get('redis')!
|
||||
println('Service exec: ${retrieved_config.exec}')
|
||||
|
||||
// Delete service configuration
|
||||
result := client.service_delete('redis')!
|
||||
println('Delete result: ${result}')
|
||||
```
|
||||
|
||||
### Service Statistics
|
||||
|
||||
```v
|
||||
import freeflowuniverse.herolib.clients.zinit_rpc
|
||||
|
||||
mut client := zinit_rpc.new_client()!
|
||||
|
||||
// Get service statistics
|
||||
stats := client.service_stats('redis')!
|
||||
println('Service: ${stats.name}')
|
||||
println('PID: ${stats.pid}')
|
||||
println('Memory Usage: ${stats.memory_usage} bytes')
|
||||
println('CPU Usage: ${stats.cpu_usage}%')
|
||||
|
||||
// Print child process statistics
|
||||
for child in stats.children {
|
||||
println('Child PID: ${child.pid}, Memory: ${child.memory_usage}, CPU: ${child.cpu_usage}%')
|
||||
}
|
||||
```
|
||||
|
||||
### Log Streaming
|
||||
|
||||
```v
|
||||
import freeflowuniverse.herolib.clients.zinit_rpc
|
||||
|
||||
mut client := zinit_rpc.new_client()!
|
||||
|
||||
// Get current logs for all services
|
||||
logs := client.stream_current_logs(name: '')!
|
||||
for log in logs {
|
||||
println(log)
|
||||
}
|
||||
|
||||
// Get current logs for a specific service
|
||||
redis_logs := client.stream_current_logs(name: 'redis')!
|
||||
for log in redis_logs {
|
||||
println('Redis: ${log}')
|
||||
}
|
||||
|
||||
// Subscribe to log stream (returns subscription ID)
|
||||
subscription_id := client.stream_subscribe_logs(name: 'redis')!
|
||||
println('Subscribed to logs with ID: ${subscription_id}')
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### Service Management Methods
|
||||
|
||||
- `service_list()` - List all services and their states
|
||||
- `service_status(name)` - Get detailed status of a service
|
||||
- `service_start(name)` - Start a service
|
||||
- `service_stop(name)` - Stop a service
|
||||
- `service_monitor(name)` - Start monitoring a service
|
||||
- `service_forget(name)` - Stop monitoring a service
|
||||
- `service_kill(name, signal)` - Send signal to a service
|
||||
|
||||
### Service Configuration Methods
|
||||
|
||||
- `service_create(name, config)` - Create service configuration
|
||||
- `service_delete(name)` - Delete service configuration
|
||||
- `service_get(name)` - Get service configuration
|
||||
|
||||
### Monitoring Methods
|
||||
|
||||
- `service_stats(name)` - Get service statistics
|
||||
|
||||
### System Methods
|
||||
|
||||
- `system_shutdown()` - Shutdown the system
|
||||
- `system_reboot()` - Reboot the system
|
||||
- `system_start_http_server(address)` - Start HTTP server
|
||||
- `system_stop_http_server()` - Stop HTTP server
|
||||
|
||||
### Streaming Methods
|
||||
|
||||
- `stream_current_logs(args)` - Get current logs (returns array of log lines)
|
||||
- `stream_subscribe_logs(args)` - Subscribe to log stream (returns subscription ID)
|
||||
|
||||
### Discovery Methods
|
||||
|
||||
- `rpc_discover()` - Get OpenRPC specification
|
||||
|
||||
## Configuration
|
||||
|
||||
### Using the Factory Pattern
|
||||
|
||||
```v
|
||||
import freeflowuniverse.herolib.clients.zinit_rpc
|
||||
|
||||
// Get client using factory (recommended)
|
||||
mut client := zinit_rpc.get()!
|
||||
|
||||
// Use the client
|
||||
services := client.service_list()!
|
||||
```
|
||||
|
||||
### Example Heroscript Configuration
|
||||
|
||||
```hero
|
||||
!!zinit_rpc.configure
|
||||
name: 'production'
|
||||
socket_path: '/tmp/zinit.sock'
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
The client provides comprehensive error handling for all Zinit-specific error codes:
|
||||
|
||||
- `-32000`: Service not found
|
||||
- `-32001`: Service already monitored
|
||||
- `-32002`: Service is up
|
||||
- `-32003`: Service is down
|
||||
- `-32004`: Invalid signal
|
||||
- `-32005`: Config error
|
||||
- `-32006`: Shutting down
|
||||
- `-32007`: Service already exists
|
||||
- `-32008`: Service file error
|
||||
|
||||
```v
|
||||
import freeflowuniverse.herolib.clients.zinit_rpc
|
||||
|
||||
mut client := zinit_rpc.new_client()!
|
||||
|
||||
// Handle specific errors
|
||||
client.service_start('nonexistent') or {
|
||||
if err.msg().contains('Service not found') {
|
||||
println('Service does not exist')
|
||||
} else {
|
||||
println('Other error: ${err}')
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -1,163 +0,0 @@
|
||||
module zinit_rpc
|
||||
|
||||
import freeflowuniverse.herolib.data.encoderhero
|
||||
import freeflowuniverse.herolib.schemas.jsonrpc
|
||||
|
||||
pub const version = '0.0.0'
|
||||
const singleton = true
|
||||
const default = false
|
||||
|
||||
// Default configuration for Zinit JSON-RPC API
|
||||
pub const default_socket_path = '/tmp/zinit.sock'
|
||||
|
||||
// THIS THE THE SOURCE OF THE INFORMATION OF THIS FILE, HERE WE HAVE THE CONFIG OBJECT CONFIGURED AND MODELLED
|
||||
|
||||
@[heap]
|
||||
pub struct ZinitRPC {
|
||||
pub mut:
|
||||
name string = 'default'
|
||||
socket_path string = default_socket_path // Unix socket path for RPC server
|
||||
rpc_client ?&jsonrpc.Client @[skip]
|
||||
}
|
||||
|
||||
// your checking & initialization code if needed
|
||||
fn obj_init(mycfg_ ZinitRPC) !ZinitRPC {
|
||||
mut mycfg := mycfg_
|
||||
if mycfg.socket_path == '' {
|
||||
mycfg.socket_path = default_socket_path
|
||||
}
|
||||
// For now, we'll initialize the client when needed
|
||||
// The actual client will be created in the factory
|
||||
return mycfg
|
||||
}
|
||||
|
||||
// Response structs based on OpenRPC specification
|
||||
|
||||
// OpenRPCSpec represents the OpenRPC specification structure
|
||||
pub struct OpenRPCSpec {
|
||||
pub mut:
|
||||
openrpc string @[json: 'openrpc'] // OpenRPC version
|
||||
info OpenRPCInfo @[json: 'info'] // API information
|
||||
methods []OpenRPCMethod @[json: 'methods'] // Available methods
|
||||
servers []OpenRPCServer @[json: 'servers'] // Server information
|
||||
}
|
||||
|
||||
// OpenRPCInfo represents API information
|
||||
pub struct OpenRPCInfo {
|
||||
pub mut:
|
||||
version string @[json: 'version'] // API version
|
||||
title string @[json: 'title'] // API title
|
||||
description string @[json: 'description'] // API description
|
||||
license OpenRPCLicense @[json: 'license'] // License information
|
||||
}
|
||||
|
||||
// OpenRPCLicense represents license information
|
||||
pub struct OpenRPCLicense {
|
||||
pub mut:
|
||||
name string @[json: 'name'] // License name
|
||||
}
|
||||
|
||||
// OpenRPCMethod represents an RPC method
|
||||
pub struct OpenRPCMethod {
|
||||
pub mut:
|
||||
name string @[json: 'name'] // Method name
|
||||
description string @[json: 'description'] // Method description
|
||||
// Note: params and result are dynamic and would need more complex handling
|
||||
}
|
||||
|
||||
// OpenRPCServer represents server information
|
||||
pub struct OpenRPCServer {
|
||||
pub mut:
|
||||
name string @[json: 'name'] // Server name
|
||||
url string @[json: 'url'] // Server URL
|
||||
}
|
||||
|
||||
// ServiceStatus represents detailed status information for a service
|
||||
pub struct ServiceStatus {
|
||||
pub mut:
|
||||
name string @[json: 'name'] // Service name
|
||||
pid u32 @[json: 'pid'] // Process ID of the running service (if running)
|
||||
state string @[json: 'state'] // Current state of the service (Running, Success, Error, etc.)
|
||||
target string @[json: 'target'] // Target state of the service (Up, Down)
|
||||
after map[string]string @[json: 'after'] // Dependencies of the service and their states
|
||||
}
|
||||
|
||||
// ServiceConfig represents the configuration for a zinit service
|
||||
pub struct ServiceConfig {
|
||||
pub mut:
|
||||
exec string @[json: 'exec'] // Command to run
|
||||
test string @[json: 'test'] // Test command (optional)
|
||||
oneshot bool @[json: 'oneshot'] // Whether the service should be restarted (maps to one_shot in Zinit)
|
||||
after []string @[json: 'after'] // Services that must be running before this one starts
|
||||
log string @[json: 'log'] // How to handle service output (null, ring, stdout)
|
||||
env map[string]string @[json: 'env'] // Environment variables for the service
|
||||
dir string @[json: 'dir'] // Working directory for the service
|
||||
shutdown_timeout u64 @[json: 'shutdown_timeout'] // Maximum time to wait for service to stop during shutdown
|
||||
}
|
||||
|
||||
// ServiceStats represents memory and CPU usage statistics for a service
|
||||
pub struct ServiceStats {
|
||||
pub mut:
|
||||
name string @[json: 'name'] // Service name
|
||||
pid u32 @[json: 'pid'] // Process ID of the service
|
||||
memory_usage u64 @[json: 'memory_usage'] // Memory usage in bytes
|
||||
cpu_usage f32 @[json: 'cpu_usage'] // CPU usage as a percentage (0-100)
|
||||
children []ChildStats @[json: 'children'] // Stats for child processes
|
||||
}
|
||||
|
||||
// ChildStats represents statistics for a child process
|
||||
pub struct ChildStats {
|
||||
pub mut:
|
||||
pid u32 @[json: 'pid'] // Process ID of the child process
|
||||
memory_usage u64 @[json: 'memory_usage'] // Memory usage in bytes
|
||||
cpu_usage f32 @[json: 'cpu_usage'] // CPU usage as a percentage (0-100)
|
||||
}
|
||||
|
||||
// ServiceCreateParams represents parameters for service_create method
|
||||
pub struct ServiceCreateParams {
|
||||
pub mut:
|
||||
name string @[json: 'name'] // Name of the service to create
|
||||
content ServiceConfig @[json: 'content'] // Configuration for the service
|
||||
}
|
||||
|
||||
// ServiceKillParams represents parameters for service_kill method
|
||||
pub struct ServiceKillParams {
|
||||
pub mut:
|
||||
name string @[json: 'name'] // Name of the service to kill
|
||||
signal string @[json: 'signal'] // Signal to send (e.g., SIGTERM, SIGKILL)
|
||||
}
|
||||
|
||||
// LogParams represents parameters for log streaming methods
|
||||
@[params]
|
||||
pub struct LogParams {
|
||||
pub mut:
|
||||
name string // Optional service name filter
|
||||
}
|
||||
|
||||
/////////////NORMALLY NO NEED TO TOUCH
|
||||
|
||||
pub fn heroscript_dumps(obj ZinitRPC) !string {
|
||||
return encoderhero.encode[ZinitRPC](obj)!
|
||||
}
|
||||
|
||||
pub fn heroscript_loads(heroscript string) !ZinitRPC {
|
||||
mut obj := encoderhero.decode[ZinitRPC](heroscript)!
|
||||
return obj
|
||||
}
|
||||
|
||||
// Factory function to create a new ZinitRPC client instance
|
||||
@[params]
|
||||
pub struct NewClientArgs {
|
||||
pub mut:
|
||||
name string = 'default'
|
||||
socket_path string = default_socket_path
|
||||
}
|
||||
|
||||
pub fn new_client(args NewClientArgs) !&ZinitRPC {
|
||||
mut client := ZinitRPC{
|
||||
name: args.name
|
||||
socket_path: args.socket_path
|
||||
}
|
||||
client = obj_init(client)!
|
||||
return &client
|
||||
}
|
||||
@@ -14,12 +14,10 @@ import time
|
||||
@end
|
||||
@end
|
||||
|
||||
@if ! args.singleton
|
||||
__global (
|
||||
${args.name}_global map[string]&${args.classname}
|
||||
${args.name}_default string
|
||||
)
|
||||
@end
|
||||
|
||||
/////////FACTORY
|
||||
|
||||
@@ -45,7 +43,7 @@ pub fn new(args ArgsGet) !&${args.classname} {
|
||||
name: args.name
|
||||
}
|
||||
set(obj)!
|
||||
return &obj
|
||||
return get(name:args.name)!
|
||||
}
|
||||
|
||||
pub fn get(args ArgsGet) !&${args.classname} {
|
||||
@@ -76,11 +74,11 @@ pub fn get(args ArgsGet) !&${args.classname} {
|
||||
|
||||
// register the config for the future
|
||||
pub fn set(o ${args.classname}) ! {
|
||||
set_in_mem(o)!
|
||||
${args.name}_default = o.name
|
||||
mut o2:=set_in_mem(o)!
|
||||
${args.name}_default = o2.name
|
||||
mut context := base.context()!
|
||||
mut r := context.redis()!
|
||||
r.hset('context:${args.name}', o.name, json.encode(o))!
|
||||
r.hset('context:${args.name}', o2.name, json.encode(o2))!
|
||||
}
|
||||
|
||||
// does the config exists?
|
||||
@@ -130,10 +128,11 @@ pub fn list(args ArgsList) ![]&${args.classname} {
|
||||
|
||||
|
||||
// only sets in mem, does not set as config
|
||||
fn set_in_mem(o ${args.classname}) ! {
|
||||
fn set_in_mem(o ${args.classname}) ! ${args.classname} {
|
||||
mut o2 := obj_init(o)!
|
||||
${args.name}_global[o.name] = &o2
|
||||
${args.name}_default = o.name
|
||||
${args.name}_global[o2.name] = &o2
|
||||
${args.name}_default = o2.name
|
||||
return o2
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -58,11 +58,11 @@ pub fn get(args ArgsGet) !&CometBFT {
|
||||
|
||||
// register the config for the future
|
||||
pub fn set(o CometBFT) ! {
|
||||
set_in_mem(o)!
|
||||
cometbft_default = o.name
|
||||
mut o2 := set_in_mem(o)!
|
||||
cometbft_default = o2.name
|
||||
mut context := base.context()!
|
||||
mut r := context.redis()!
|
||||
r.hset('context:cometbft', o.name, json.encode(o))!
|
||||
r.hset('context:cometbft', o2.name, json.encode(o2))!
|
||||
}
|
||||
|
||||
// does the config exists?
|
||||
@@ -111,10 +111,11 @@ pub fn list(args ArgsList) ![]&CometBFT {
|
||||
}
|
||||
|
||||
// only sets in mem, does not set as config
|
||||
fn set_in_mem(o CometBFT) ! {
|
||||
fn set_in_mem(o CometBFT) !CometBFT {
|
||||
mut o2 := obj_init(o)!
|
||||
cometbft_global[o.name] = &o2
|
||||
cometbft_default = o.name
|
||||
cometbft_global[o2.name] = &o2
|
||||
cometbft_default = o2.name
|
||||
return o2
|
||||
}
|
||||
|
||||
pub fn play(mut plbook PlayBook) ! {
|
||||
|
||||
@@ -29,8 +29,7 @@ fn startupcmd() ![]startupmanager.ZProcessNewArgs {
|
||||
if installer.production {
|
||||
env = 'production'
|
||||
}
|
||||
res << startupmanager.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
|
||||
|
||||
@@ -58,11 +58,11 @@ pub fn get(args ArgsGet) !&MeilisearchInstaller {
|
||||
|
||||
// register the config for the future
|
||||
pub fn set(o MeilisearchInstaller) ! {
|
||||
set_in_mem(o)!
|
||||
meilisearch_installer_default = o.name
|
||||
mut o2 := set_in_mem(o)!
|
||||
meilisearch_installer_default = o2.name
|
||||
mut context := base.context()!
|
||||
mut r := context.redis()!
|
||||
r.hset('context:meilisearch_installer', o.name, json.encode(o))!
|
||||
r.hset('context:meilisearch_installer', o2.name, json.encode(o2))!
|
||||
}
|
||||
|
||||
// does the config exists?
|
||||
@@ -111,10 +111,11 @@ pub fn list(args ArgsList) ![]&MeilisearchInstaller {
|
||||
}
|
||||
|
||||
// only sets in mem, does not set as config
|
||||
fn set_in_mem(o MeilisearchInstaller) ! {
|
||||
fn set_in_mem(o MeilisearchInstaller) !MeilisearchInstaller {
|
||||
mut o2 := obj_init(o)!
|
||||
meilisearch_installer_global[o.name] = &o2
|
||||
meilisearch_installer_default = o.name
|
||||
meilisearch_installer_global[o2.name] = &o2
|
||||
meilisearch_installer_default = o2.name
|
||||
return o2
|
||||
}
|
||||
|
||||
pub fn play(mut plbook PlayBook) ! {
|
||||
|
||||
@@ -15,8 +15,7 @@ fn startupcmd() ![]startupmanager.ZProcessNewArgs {
|
||||
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 << startupmanager.ZProcessNewArgs
|
||||
{
|
||||
res << startupmanager.ZProcessNewArgs{
|
||||
name: 'postgresql'
|
||||
cmd: cmd
|
||||
startuptype: .zinit
|
||||
|
||||
@@ -53,11 +53,11 @@ pub fn get(args ArgsGet) !&Postgresql {
|
||||
|
||||
// register the config for the future
|
||||
pub fn set(o Postgresql) ! {
|
||||
set_in_mem(o)!
|
||||
postgresql_default = o.name
|
||||
mut o2 := set_in_mem(o)!
|
||||
postgresql_default = o2.name
|
||||
mut context := base.context()!
|
||||
mut r := context.redis()!
|
||||
r.hset('context:postgresql', o.name, json.encode(o))!
|
||||
r.hset('context:postgresql', o2.name, json.encode(o2))!
|
||||
}
|
||||
|
||||
// does the config exists?
|
||||
@@ -106,10 +106,11 @@ pub fn list(args ArgsList) ![]&Postgresql {
|
||||
}
|
||||
|
||||
// only sets in mem, does not set as config
|
||||
fn set_in_mem(o Postgresql) ! {
|
||||
fn set_in_mem(o Postgresql) !Postgresql {
|
||||
mut o2 := obj_init(o)!
|
||||
postgresql_global[o.name] = &o2
|
||||
postgresql_default = o.name
|
||||
postgresql_global[o2.name] = &o2
|
||||
postgresql_default = o2.name
|
||||
return o2
|
||||
}
|
||||
|
||||
pub fn play(mut plbook PlayBook) ! {
|
||||
|
||||
@@ -7,8 +7,7 @@ import os
|
||||
|
||||
fn startupcmd() ![]startupmanager.ZProcessNewArgs {
|
||||
mut res := []startupmanager.ZProcessNewArgs{}
|
||||
res << startupmanager.ZProcessNewArgs
|
||||
{
|
||||
res << startupmanager.ZProcessNewArgs{
|
||||
name: 'qdrant'
|
||||
cmd: 'sleep 5 && qdrant --config-path ${os.home_dir()}/hero/var/qdrant/config.yaml'
|
||||
startuptype: .zinit
|
||||
|
||||
@@ -58,11 +58,11 @@ pub fn get(args ArgsGet) !&QDrant {
|
||||
|
||||
// register the config for the future
|
||||
pub fn set(o QDrant) ! {
|
||||
set_in_mem(o)!
|
||||
qdrant_installer_default = o.name
|
||||
mut o2 := set_in_mem(o)!
|
||||
qdrant_installer_default = o2.name
|
||||
mut context := base.context()!
|
||||
mut r := context.redis()!
|
||||
r.hset('context:qdrant_installer', o.name, json.encode(o))!
|
||||
r.hset('context:qdrant_installer', o2.name, json.encode(o2))!
|
||||
}
|
||||
|
||||
// does the config exists?
|
||||
@@ -111,10 +111,11 @@ pub fn list(args ArgsList) ![]&QDrant {
|
||||
}
|
||||
|
||||
// only sets in mem, does not set as config
|
||||
fn set_in_mem(o QDrant) ! {
|
||||
fn set_in_mem(o QDrant) !QDrant {
|
||||
mut o2 := obj_init(o)!
|
||||
qdrant_installer_global[o.name] = &o2
|
||||
qdrant_installer_default = o.name
|
||||
qdrant_installer_global[o2.name] = &o2
|
||||
qdrant_installer_default = o2.name
|
||||
return o2
|
||||
}
|
||||
|
||||
pub fn play(mut plbook PlayBook) ! {
|
||||
|
||||
@@ -22,8 +22,7 @@ fn startupcmd() ![]startupmanager.ZProcessNewArgs {
|
||||
}
|
||||
|
||||
mut res := []startupmanager.ZProcessNewArgs{}
|
||||
res << startupmanager.ZProcessNewArgs
|
||||
{
|
||||
res << startupmanager.ZProcessNewArgs{
|
||||
name: 'zdb'
|
||||
cmd: cmd
|
||||
startuptype: .zinit
|
||||
|
||||
@@ -53,11 +53,11 @@ pub fn get(args ArgsGet) !&ZeroDB {
|
||||
|
||||
// register the config for the future
|
||||
pub fn set(o ZeroDB) ! {
|
||||
set_in_mem(o)!
|
||||
zerodb_default = o.name
|
||||
mut o2 := set_in_mem(o)!
|
||||
zerodb_default = o2.name
|
||||
mut context := base.context()!
|
||||
mut r := context.redis()!
|
||||
r.hset('context:zerodb', o.name, json.encode(o))!
|
||||
r.hset('context:zerodb', o2.name, json.encode(o2))!
|
||||
}
|
||||
|
||||
// does the config exists?
|
||||
@@ -106,10 +106,11 @@ pub fn list(args ArgsList) ![]&ZeroDB {
|
||||
}
|
||||
|
||||
// only sets in mem, does not set as config
|
||||
fn set_in_mem(o ZeroDB) ! {
|
||||
fn set_in_mem(o ZeroDB) !ZeroDB {
|
||||
mut o2 := obj_init(o)!
|
||||
zerodb_global[o.name] = &o2
|
||||
zerodb_default = o.name
|
||||
zerodb_global[o2.name] = &o2
|
||||
zerodb_default = o2.name
|
||||
return o2
|
||||
}
|
||||
|
||||
pub fn play(mut plbook PlayBook) ! {
|
||||
|
||||
@@ -16,8 +16,7 @@ fn startupcmd() ![]startupmanager.ZProcessNewArgs {
|
||||
mut args := get()!
|
||||
mut res := []startupmanager.ZProcessNewArgs{}
|
||||
cmd := "coredns -conf '${args.config_path}'"
|
||||
res << startupmanager.ZProcessNewArgs
|
||||
{
|
||||
res << startupmanager.ZProcessNewArgs{
|
||||
name: 'coredns'
|
||||
cmd: cmd
|
||||
}
|
||||
|
||||
@@ -53,11 +53,11 @@ pub fn get(args ArgsGet) !&CoreDNS {
|
||||
|
||||
// register the config for the future
|
||||
pub fn set(o CoreDNS) ! {
|
||||
set_in_mem(o)!
|
||||
coredns_default = o.name
|
||||
mut o2 := set_in_mem(o)!
|
||||
coredns_default = o2.name
|
||||
mut context := base.context()!
|
||||
mut r := context.redis()!
|
||||
r.hset('context:coredns', o.name, json.encode(o))!
|
||||
r.hset('context:coredns', o2.name, json.encode(o2))!
|
||||
}
|
||||
|
||||
// does the config exists?
|
||||
@@ -106,10 +106,11 @@ pub fn list(args ArgsList) ![]&CoreDNS {
|
||||
}
|
||||
|
||||
// only sets in mem, does not set as config
|
||||
fn set_in_mem(o CoreDNS) ! {
|
||||
fn set_in_mem(o CoreDNS) !CoreDNS {
|
||||
mut o2 := obj_init(o)!
|
||||
coredns_global[o.name] = &o2
|
||||
coredns_default = o.name
|
||||
coredns_global[o2.name] = &o2
|
||||
coredns_default = o2.name
|
||||
return o2
|
||||
}
|
||||
|
||||
pub fn play(mut plbook PlayBook) ! {
|
||||
|
||||
@@ -89,8 +89,7 @@ fn upload() ! {}
|
||||
fn startupcmd() ![]startupmanager.ZProcessNewArgs {
|
||||
mut cfg := get()!
|
||||
mut res := []startupmanager.ZProcessNewArgs{}
|
||||
res << startupmanager.ZProcessNewArgs
|
||||
{
|
||||
res << startupmanager.ZProcessNewArgs{
|
||||
name: 'gitea'
|
||||
cmd: 'gitea server'
|
||||
env: {
|
||||
|
||||
@@ -53,11 +53,11 @@ pub fn get(args ArgsGet) !&GiteaServer {
|
||||
|
||||
// register the config for the future
|
||||
pub fn set(o GiteaServer) ! {
|
||||
set_in_mem(o)!
|
||||
gitea_default = o.name
|
||||
mut o2 := set_in_mem(o)!
|
||||
gitea_default = o2.name
|
||||
mut context := base.context()!
|
||||
mut r := context.redis()!
|
||||
r.hset('context:gitea', o.name, json.encode(o))!
|
||||
r.hset('context:gitea', o2.name, json.encode(o2))!
|
||||
}
|
||||
|
||||
// does the config exists?
|
||||
@@ -106,10 +106,11 @@ pub fn list(args ArgsList) ![]&GiteaServer {
|
||||
}
|
||||
|
||||
// only sets in mem, does not set as config
|
||||
fn set_in_mem(o GiteaServer) ! {
|
||||
fn set_in_mem(o GiteaServer) !GiteaServer {
|
||||
mut o2 := obj_init(o)!
|
||||
gitea_global[o.name] = &o2
|
||||
gitea_default = o.name
|
||||
gitea_global[o2.name] = &o2
|
||||
gitea_default = o2.name
|
||||
return o2
|
||||
}
|
||||
|
||||
pub fn play(mut plbook PlayBook) ! {
|
||||
|
||||
@@ -48,8 +48,7 @@ fn generate_keys() ! {
|
||||
fn startupcmd() ![]startupmanager.ZProcessNewArgs {
|
||||
mut res := []startupmanager.ZProcessNewArgs{}
|
||||
mut installer := get()!
|
||||
res << startupmanager.ZProcessNewArgs
|
||||
{
|
||||
res << startupmanager.ZProcessNewArgs{
|
||||
name: 'livekit'
|
||||
cmd: 'livekit-server --config ${installer.configpath} --bind 0.0.0.0'
|
||||
startuptype: .zinit
|
||||
|
||||
@@ -58,11 +58,11 @@ pub fn get(args ArgsGet) !&LivekitServer {
|
||||
|
||||
// register the config for the future
|
||||
pub fn set(o LivekitServer) ! {
|
||||
set_in_mem(o)!
|
||||
livekit_default = o.name
|
||||
mut o2 := set_in_mem(o)!
|
||||
livekit_default = o2.name
|
||||
mut context := base.context()!
|
||||
mut r := context.redis()!
|
||||
r.hset('context:livekit', o.name, json.encode(o))!
|
||||
r.hset('context:livekit', o2.name, json.encode(o2))!
|
||||
}
|
||||
|
||||
// does the config exists?
|
||||
@@ -111,10 +111,11 @@ pub fn list(args ArgsList) ![]&LivekitServer {
|
||||
}
|
||||
|
||||
// only sets in mem, does not set as config
|
||||
fn set_in_mem(o LivekitServer) ! {
|
||||
fn set_in_mem(o LivekitServer) !LivekitServer {
|
||||
mut o2 := obj_init(o)!
|
||||
livekit_global[o.name] = &o2
|
||||
livekit_default = o.name
|
||||
livekit_global[o2.name] = &o2
|
||||
livekit_default = o2.name
|
||||
return o2
|
||||
}
|
||||
|
||||
pub fn play(mut plbook PlayBook) ! {
|
||||
|
||||
@@ -16,7 +16,7 @@ fn startupcmd() ![]startupmanager.ZProcessNewArgs {
|
||||
if core.is_linux()! {
|
||||
res << startupmanager.ZProcessNewArgs{
|
||||
name: 'zinit'
|
||||
cmd: '/usr/local/bin/zinit init'
|
||||
cmd: '/usr/local/bin/zinit init ~/hero/cfg/zinit'
|
||||
startuptype: .systemd
|
||||
start: true
|
||||
restart: true
|
||||
|
||||
@@ -58,11 +58,11 @@ pub fn get(args ArgsGet) !&MyceliumInstaller {
|
||||
|
||||
// register the config for the future
|
||||
pub fn set(o MyceliumInstaller) ! {
|
||||
set_in_mem(o)!
|
||||
mycelium_installer_default = o.name
|
||||
mut o2 := set_in_mem(o)!
|
||||
mycelium_installer_default = o2.name
|
||||
mut context := base.context()!
|
||||
mut r := context.redis()!
|
||||
r.hset('context:mycelium_installer', o.name, json.encode(o))!
|
||||
r.hset('context:mycelium_installer', o2.name, json.encode(o2))!
|
||||
}
|
||||
|
||||
// does the config exists?
|
||||
@@ -111,10 +111,11 @@ pub fn list(args ArgsList) ![]&MyceliumInstaller {
|
||||
}
|
||||
|
||||
// only sets in mem, does not set as config
|
||||
fn set_in_mem(o MyceliumInstaller) ! {
|
||||
fn set_in_mem(o MyceliumInstaller) !MyceliumInstaller {
|
||||
mut o2 := obj_init(o)!
|
||||
mycelium_installer_global[o.name] = &o2
|
||||
mycelium_installer_default = o.name
|
||||
mycelium_installer_global[o2.name] = &o2
|
||||
mycelium_installer_default = o2.name
|
||||
return o2
|
||||
}
|
||||
|
||||
pub fn play(mut plbook PlayBook) ! {
|
||||
|
||||
42
lib/schemas/jsonrpcmodel/model_openrpc_spec.v
Normal file
42
lib/schemas/jsonrpcmodel/model_openrpc_spec.v
Normal file
@@ -0,0 +1,42 @@
|
||||
module jsonrpcmodel
|
||||
|
||||
|
||||
|
||||
// OpenRPCSpec represents the OpenRPC specification structure
|
||||
pub struct OpenRPCSpec {
|
||||
pub mut:
|
||||
openrpc string @[json: 'openrpc'] // OpenRPC version
|
||||
info OpenRPCInfo @[json: 'info'] // API information
|
||||
methods []OpenRPCMethod @[json: 'methods'] // Available methods
|
||||
servers []OpenRPCServer @[json: 'servers'] // Server information
|
||||
}
|
||||
|
||||
// OpenRPCInfo represents API information
|
||||
pub struct OpenRPCInfo {
|
||||
pub mut:
|
||||
version string @[json: 'version'] // API version
|
||||
title string @[json: 'title'] // API title
|
||||
description string @[json: 'description'] // API description
|
||||
license OpenRPCLicense @[json: 'license'] // License information
|
||||
}
|
||||
|
||||
// OpenRPCLicense represents license information
|
||||
pub struct OpenRPCLicense {
|
||||
pub mut:
|
||||
name string @[json: 'name'] // License name
|
||||
}
|
||||
|
||||
// OpenRPCMethod represents an RPC method
|
||||
pub struct OpenRPCMethod {
|
||||
pub mut:
|
||||
name string @[json: 'name'] // Method name
|
||||
description string @[json: 'description'] // Method description
|
||||
// Note: params and result are dynamic and would need more complex handling
|
||||
}
|
||||
|
||||
// OpenRPCServer represents server information
|
||||
pub struct OpenRPCServer {
|
||||
pub mut:
|
||||
name string @[json: 'name'] // Server name
|
||||
url string @[json: 'url'] // Server URL
|
||||
}
|
||||
Reference in New Issue
Block a user