...
This commit is contained in:
@@ -38,7 +38,6 @@ mut client := zinit.new()!
|
||||
|
||||
println(client)
|
||||
|
||||
|
||||
println('✓ Created Zinit RPC client')
|
||||
|
||||
// 1. Discover API specification
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import freeflowuniverse.herolib.installers.infra.livekit as livekit_installer
|
||||
|
||||
mut livekit := livekit_installer.get(create:true)!
|
||||
mut livekit := livekit_installer.get(create: true)!
|
||||
livekit.install()!
|
||||
livekit.start()!
|
||||
livekit.destroy()!
|
||||
|
||||
@@ -17,7 +17,7 @@ passwd := os.environ()['HETZNER_PASSWORD'] or {
|
||||
exit(1)
|
||||
}
|
||||
|
||||
hs:='
|
||||
hs := '
|
||||
!!hetznermanager.configure
|
||||
user:"${user}"
|
||||
whitelist:"2111181, 2392178, 2545053, 2542166, 2550508, 2550378,2550253"
|
||||
@@ -29,7 +29,6 @@ println(hs)
|
||||
|
||||
playcmds.run(heroscript: hs)!
|
||||
|
||||
|
||||
console.print_header('Hetzner Test.')
|
||||
|
||||
mut cl := hetznermanager.get()!
|
||||
@@ -66,5 +65,4 @@ mut cl := hetznermanager.get()!
|
||||
// cl.ubuntu_install(name: 'kristof20', wait: true, hero_install: true)!
|
||||
// cl.ubuntu_install(id:2550378, name: 'kristof21', wait: true, hero_install: true)!
|
||||
// cl.ubuntu_install(id:2550508, name: 'kristof22', wait: true, hero_install: true)!
|
||||
cl.ubuntu_install(id:2550253, name:'kristof23', wait: true, hero_install: true)!
|
||||
|
||||
cl.ubuntu_install(id: 2550253, name: 'kristof23', wait: true, hero_install: true)!
|
||||
|
||||
@@ -12,10 +12,10 @@ pub fn play(mut plbook playbook.PlayBook) ! {
|
||||
for action in actions {
|
||||
mut p := action.params
|
||||
mut n := b.node_new(
|
||||
name: p.get_default('name', '')!
|
||||
name: p.get_default('name', '')!
|
||||
ipaddr: p.get_default('ipaddr', '')!
|
||||
user: p.get_default('user', 'root')!
|
||||
debug: p.get_default_false('debug')
|
||||
user: p.get_default('user', 'root')!
|
||||
debug: p.get_default_false('debug')
|
||||
reload: p.get_default_false('reload')
|
||||
)!
|
||||
console.print_header('Created node: ${n.name}')
|
||||
@@ -31,16 +31,18 @@ pub fn play(mut plbook playbook.PlayBook) ! {
|
||||
// a bit ugly but we don't have node management in a central place yet
|
||||
// this will get the node created previously
|
||||
// we need a better way to get the nodes, maybe from a global scope
|
||||
mut found_node := &Node{factory: &b}
|
||||
mut found_node := &Node{
|
||||
factory: &b
|
||||
}
|
||||
mut found := false
|
||||
nodes_to_find := plbook.find(filter: 'node.new')!
|
||||
for node_action in nodes_to_find {
|
||||
mut node_p := node_action.params
|
||||
if node_p.get_default('name', '')! == node_name {
|
||||
found_node = b.node_new(
|
||||
name: node_p.get_default('name', '')!
|
||||
name: node_p.get_default('name', '')!
|
||||
ipaddr: node_p.get_default('ipaddr', '')!
|
||||
user: node_p.get_default('user', 'root')!
|
||||
user: node_p.get_default('user', 'root')!
|
||||
)!
|
||||
found = true
|
||||
break
|
||||
@@ -55,4 +57,4 @@ pub fn play(mut plbook playbook.PlayBook) ! {
|
||||
result := found_node.exec_cmd(cmd: cmd)!
|
||||
console.print_debug('Result:\n${result}')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ pub fn (mut c ZinitRPC) rpc_discover() !openrpc.OpenRPC {
|
||||
println(1)
|
||||
request := jsonrpc.new_request_generic('rpc.discover', []string{})
|
||||
println(2)
|
||||
mut r:= client.send[[]string, openrpc.OpenRPC](request)!
|
||||
mut r := client.send[[]string, openrpc.OpenRPC](request)!
|
||||
// dump(r)
|
||||
$dbg;
|
||||
return r
|
||||
|
||||
@@ -10,12 +10,10 @@ import freeflowuniverse.herolib.web.docusaurus
|
||||
import freeflowuniverse.herolib.clients.openai
|
||||
import freeflowuniverse.herolib.clients.giteaclient
|
||||
import freeflowuniverse.herolib.osal.tmux
|
||||
|
||||
import freeflowuniverse.herolib.installers.base
|
||||
import freeflowuniverse.herolib.installers.lang.vlang
|
||||
import freeflowuniverse.herolib.installers.lang.herolib
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// run – entry point for all HeroScript play‑commands
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
@@ -57,7 +57,7 @@ fn decode_struct[T](_ T, data string) !T {
|
||||
if attr.contains('skipdecode') {
|
||||
should_skip = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if !should_skip {
|
||||
$if field.is_struct {
|
||||
@@ -99,8 +99,8 @@ pub fn decode_array[T](_ []T, data string) ![]T {
|
||||
// for i in 0 .. val.len {
|
||||
value := T{}
|
||||
$if T is $struct {
|
||||
//arr << decode_struct(value, data)!
|
||||
}$else{
|
||||
// arr << decode_struct(value, data)!
|
||||
} $else {
|
||||
arr << decode[T](data)!
|
||||
}
|
||||
// }
|
||||
|
||||
@@ -9,7 +9,7 @@ pub fn play(mut plbook playbook.PlayBook) ! {
|
||||
for mut action in plbook.find(filter: 'base.install')! {
|
||||
mut p := action.params
|
||||
install(
|
||||
reset: p.get_default_false('reset')
|
||||
reset: p.get_default_false('reset')
|
||||
develop: p.get_default_false('develop')
|
||||
)!
|
||||
action.done = true
|
||||
@@ -30,10 +30,10 @@ pub fn play(mut plbook playbook.PlayBook) ! {
|
||||
for action in plbook.find(filter: 'base.redis_install')! {
|
||||
mut p := action.params
|
||||
redis_install(
|
||||
port: p.get_int_default('port', 6379)!
|
||||
port: p.get_int_default('port', 6379)!
|
||||
ipaddr: p.get_default('ipaddr', 'localhost')!
|
||||
reset: p.get_default_false('reset')
|
||||
start: p.get_default_true('start')
|
||||
reset: p.get_default_false('reset')
|
||||
start: p.get_default_true('start')
|
||||
)!
|
||||
}
|
||||
}
|
||||
@@ -46,4 +46,4 @@ pub fn play(mut plbook playbook.PlayBook) ! {
|
||||
// )!
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ pub fn install_multi(args_ InstallArgs) ! {
|
||||
}
|
||||
'hero' {
|
||||
herolib.install(
|
||||
reset: args.reset
|
||||
reset: args.reset
|
||||
)!
|
||||
}
|
||||
// 'hero' {
|
||||
|
||||
@@ -80,11 +80,11 @@ pub fn install(args InstallArgs) ! {
|
||||
console.print_header('install hero')
|
||||
base.install()!
|
||||
|
||||
cmd := "
|
||||
cmd := '
|
||||
cd /tmp
|
||||
export TERM=xterm
|
||||
curl https://raw.githubusercontent.com/freeflowuniverse/herolib/refs/heads/development/install_hero.sh | bash
|
||||
"
|
||||
'
|
||||
osal.execute_stdout(cmd) or { return error('Cannot install hero.\n${err}') }
|
||||
osal.done_set('install_hero', 'OK')!
|
||||
return
|
||||
|
||||
@@ -4,7 +4,7 @@ import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
|
||||
pub fn play(mut plbook playbook.PlayBook) ! {
|
||||
if ! plbook.exists(filter: 'herolib.') {
|
||||
if !plbook.exists(filter: 'herolib.') {
|
||||
return
|
||||
}
|
||||
if plbook.exists(filter: 'herolib.uninstall') {
|
||||
@@ -14,7 +14,6 @@ pub fn play(mut plbook playbook.PlayBook) ! {
|
||||
action.done = true
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
if plbook.exists(filter: 'herolib.install') {
|
||||
console.print_header('play herolib.install')
|
||||
@@ -22,7 +21,6 @@ pub fn play(mut plbook playbook.PlayBook) ! {
|
||||
mut p := action.params
|
||||
install(
|
||||
reset: p.get_default_false('reset')
|
||||
|
||||
)!
|
||||
action.done = true
|
||||
break
|
||||
@@ -33,12 +31,12 @@ pub fn play(mut plbook playbook.PlayBook) ! {
|
||||
for mut action in plbook.find(filter: 'herolib.compile')! {
|
||||
mut p := action.params
|
||||
compile(
|
||||
reset: p.get_default_false('reset')
|
||||
git_pull: p.get_default_false('git_pull')
|
||||
reset: p.get_default_false('reset')
|
||||
git_pull: p.get_default_false('git_pull')
|
||||
git_reset: p.get_default_false('git_reset')
|
||||
)!
|
||||
action.done = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,4 +24,4 @@ pub fn play(mut plbook playbook.PlayBook) ! {
|
||||
action.done = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,8 @@ pub fn install(args_ InstallArgs) ! {
|
||||
|
||||
base.develop()!
|
||||
|
||||
osal.exec(cmd:'
|
||||
osal.exec(
|
||||
cmd: '
|
||||
V_DIR="${os.home_dir()}/_code/v"
|
||||
|
||||
mkdir -p "${os.home_dir()}/_code"
|
||||
@@ -58,7 +59,8 @@ pub fn install(args_ InstallArgs) ! {
|
||||
fi
|
||||
cd "\${V_DIR}"
|
||||
make
|
||||
')!
|
||||
'
|
||||
)!
|
||||
|
||||
mut extra := 'cd ${os.home_dir()}/_code/v'
|
||||
if core.is_linux()! {
|
||||
@@ -67,7 +69,7 @@ pub fn install(args_ InstallArgs) ! {
|
||||
extra = '${extra}\ncp v ${os.home_dir()}/hero/bin/'
|
||||
}
|
||||
osal.exec(cmd: extra, stdout: true)!
|
||||
|
||||
|
||||
console.print_header('compile done')
|
||||
|
||||
osal.done_set('install_vlang', 'OK')!
|
||||
|
||||
@@ -42,7 +42,7 @@ pub fn ping(args PingArgs) !bool {
|
||||
if res.exit_code > 0 {
|
||||
nrerrors += 1
|
||||
}
|
||||
console.print_debug("${cmd} ${res.exit_code} ${nrerrors}")
|
||||
console.print_debug('${cmd} ${res.exit_code} ${nrerrors}')
|
||||
}
|
||||
successes := args.nr_ping - nrerrors
|
||||
if successes >= args.nr_ok {
|
||||
@@ -233,7 +233,7 @@ fn ssh_testrun_internal(args TcpPortTestArgs) !(string, SSHResult) {
|
||||
fi
|
||||
echo "ERROR: Host unreachable, over ping and ssh"
|
||||
exit 3
|
||||
'
|
||||
'
|
||||
|
||||
res := exec(cmd: cmd, ignore_error: true, stdout: false, debug: false)!
|
||||
// console.print_debug('ssh test ${res.exit_code}: ===== cmd:\n${cmd}\n=====\n${res.output}')
|
||||
|
||||
@@ -56,7 +56,7 @@ pub fn (mut sm StartupManager) new(args ZProcessNewArgs) ! {
|
||||
mut scr := screen.new(reset: false)!
|
||||
console.print_debug('screen startup manager ${args.name} cmd:${args.cmd}')
|
||||
_ = scr.add(name: args.name, cmd: args.cmd, reset: args.restart)!
|
||||
//because of how screen works the start is immediate
|
||||
// because of how screen works the start is immediate
|
||||
}
|
||||
.systemd {
|
||||
// console.print_debug('systemd start ${args.name}')
|
||||
@@ -74,7 +74,7 @@ pub fn (mut sm StartupManager) new(args ZProcessNewArgs) ! {
|
||||
// Get the Zinit RPC client instance.
|
||||
// We assume it's properly configured (e.g., socket_path) via its factory setup.
|
||||
mut zinit_client := zinit.get(create: true)!
|
||||
|
||||
|
||||
// Map ZProcessNewArgs to zinit.ServiceConfig
|
||||
mut service_config := zinit.ServiceConfig{
|
||||
exec: args.cmd
|
||||
@@ -90,16 +90,16 @@ pub fn (mut sm StartupManager) new(args ZProcessNewArgs) ! {
|
||||
// Create the service configuration file in zinit
|
||||
zinit_client.service_create(args.name, service_config) or {
|
||||
return error('startupmanager: failed to create zinit service ${args.name}: ${err}')
|
||||
}
|
||||
|
||||
} else {
|
||||
}
|
||||
}
|
||||
else {
|
||||
panic('to implement, startup manager only support screen & systemd for now: ${mycat}')
|
||||
}
|
||||
}
|
||||
// If 'start' is true, also monitor and start the service
|
||||
if args.start {
|
||||
sm.start(args.name)!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut sm StartupManager) start(name string) ! {
|
||||
@@ -129,7 +129,6 @@ pub fn (mut sm StartupManager) start(name string) ! {
|
||||
zinit_client.service_monitor(name) or {
|
||||
return error('startupmanager: Failed to monitor zinit service ${name}: ${err}')
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
panic('to implement, startup manager only support screen, systemd and zinit for now')
|
||||
@@ -355,7 +354,7 @@ pub fn (mut sm StartupManager) exists(name string) !bool {
|
||||
}
|
||||
.zinit {
|
||||
console.print_debug('zinit exists ${name} using clients.zinit')
|
||||
mut zinit_client := zinit.get(create:true)!
|
||||
mut zinit_client := zinit.get(create: true)!
|
||||
zinit_client.service_status(name) or { return false }
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -6,49 +6,49 @@ import freeflowuniverse.herolib.osal.core as osal
|
||||
@[params]
|
||||
pub struct JournalArgs {
|
||||
pub:
|
||||
service string // name of service for which logs will be retrieved
|
||||
limit int = 100 // number of last log lines to be shown
|
||||
since string // time since when to show logs (e.g., "1 hour ago", "2024-01-01")
|
||||
follow bool // follow logs in real-time
|
||||
priority string // log priority (emerg, alert, crit, err, warning, notice, info, debug)
|
||||
grep string // filter logs containing this text
|
||||
service string // name of service for which logs will be retrieved
|
||||
limit int = 100 // number of last log lines to be shown
|
||||
since string // time since when to show logs (e.g., "1 hour ago", "2024-01-01")
|
||||
follow bool // follow logs in real-time
|
||||
priority string // log priority (emerg, alert, crit, err, warning, notice, info, debug)
|
||||
grep string // filter logs containing this text
|
||||
}
|
||||
|
||||
pub fn journalctl(args JournalArgs) !string {
|
||||
mut cmd_parts := ['journalctl', '--no-pager']
|
||||
|
||||
|
||||
if args.limit > 0 {
|
||||
cmd_parts << ['-n', args.limit.str()]
|
||||
}
|
||||
|
||||
|
||||
if args.service != '' {
|
||||
cmd_parts << ['-u', name_fix(args.service)]
|
||||
}
|
||||
|
||||
|
||||
if args.since != '' {
|
||||
cmd_parts << ['--since', '"${args.since}"']
|
||||
}
|
||||
|
||||
|
||||
if args.follow {
|
||||
cmd_parts << ['-f']
|
||||
}
|
||||
|
||||
|
||||
if args.priority != '' {
|
||||
cmd_parts << ['-p', args.priority]
|
||||
}
|
||||
|
||||
|
||||
cmd := cmd_parts.join(' ')
|
||||
|
||||
|
||||
mut response := osal.execute_silent(cmd) or {
|
||||
return error('Failed to get journal logs for ${args.service}: ${err}')
|
||||
}
|
||||
|
||||
|
||||
if args.grep != '' {
|
||||
lines := response.split('\n')
|
||||
filtered_lines := lines.filter(it.contains(args.grep))
|
||||
response = filtered_lines.join('\n')
|
||||
}
|
||||
|
||||
|
||||
return response
|
||||
}
|
||||
|
||||
|
||||
@@ -179,7 +179,7 @@ pub fn (mut systemd Systemd) destroy(name_ string) ! {
|
||||
pub fn (mut systemd Systemd) validate_service(name string) !bool {
|
||||
service := systemd.get(name)!
|
||||
status := service.status()!
|
||||
|
||||
|
||||
match status {
|
||||
.active {
|
||||
console.print_item('✓ Service ${name} is running')
|
||||
@@ -200,14 +200,14 @@ pub fn (mut systemd Systemd) validate_service(name string) !bool {
|
||||
// Add method to check all services
|
||||
pub fn (mut systemd Systemd) health_check() !map[string]bool {
|
||||
mut results := map[string]bool{}
|
||||
|
||||
|
||||
for process in systemd.processes {
|
||||
if process.name.ends_with('_test') || process.name.ends_with('testservice') {
|
||||
continue // Skip test services
|
||||
}
|
||||
results[process.name] = systemd.validate_service(process.name) or { false }
|
||||
}
|
||||
|
||||
|
||||
return results
|
||||
}
|
||||
|
||||
|
||||
@@ -43,24 +43,24 @@ pub fn (mut self SystemdProcess) write() ! {
|
||||
|
||||
pub fn (mut self SystemdProcess) start() ! {
|
||||
console.print_header('starting systemd process: ${self.name}')
|
||||
|
||||
|
||||
cmd := '
|
||||
systemctl daemon-reload
|
||||
systemctl enable ${self.name}
|
||||
systemctl start ${self.name}
|
||||
'
|
||||
|
||||
|
||||
job := osal.exec(cmd: cmd, stdout: false)!
|
||||
|
||||
|
||||
// Wait for service to start with timeout
|
||||
mut attempts := 0
|
||||
max_attempts := 10
|
||||
wait_interval := 500 // milliseconds
|
||||
|
||||
|
||||
for attempts < max_attempts {
|
||||
time.sleep(wait_interval * time.millisecond)
|
||||
status := self.status()!
|
||||
|
||||
|
||||
match status {
|
||||
.active {
|
||||
console.print_header('✓ systemd process started successfully: ${self.name}')
|
||||
@@ -81,11 +81,10 @@ pub fn (mut self SystemdProcess) start() ! {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If we get here, service didn't start in time
|
||||
logs := self.get_logs(50)!
|
||||
return error('Service ${self.name} did not start within expected time. Status: ${self.status()!}. Recent logs:\n${logs}')
|
||||
|
||||
}
|
||||
|
||||
// get status from system
|
||||
@@ -109,30 +108,30 @@ pub fn (mut self SystemdProcess) delete() ! {
|
||||
|
||||
pub fn (mut self SystemdProcess) stop() ! {
|
||||
console.print_header('stopping systemd process: ${self.name}')
|
||||
|
||||
|
||||
cmd := '
|
||||
systemctl stop ${self.name}
|
||||
systemctl disable ${self.name}
|
||||
systemctl daemon-reload
|
||||
'
|
||||
|
||||
|
||||
_ = osal.exec(cmd: cmd, stdout: false, ignore_error: true)!
|
||||
|
||||
|
||||
// Wait for service to stop
|
||||
mut attempts := 0
|
||||
max_attempts := 10
|
||||
|
||||
|
||||
for attempts < max_attempts {
|
||||
time.sleep(500 * time.millisecond)
|
||||
status := self.status()!
|
||||
|
||||
|
||||
if status == .inactive {
|
||||
console.print_header('✓ systemd process stopped: ${self.name}')
|
||||
return
|
||||
}
|
||||
attempts++
|
||||
}
|
||||
|
||||
|
||||
console.print_header('⚠ systemd process may still be running: ${self.name}')
|
||||
}
|
||||
|
||||
@@ -161,11 +160,11 @@ pub fn (self SystemdProcess) get_logs(lines int) !string {
|
||||
// Improve status method with better error handling
|
||||
pub fn (self SystemdProcess) status() !SystemdStatus {
|
||||
cmd := 'systemctl is-active ${name_fix(self.name)}'
|
||||
|
||||
|
||||
job := osal.exec(cmd: cmd, stdout: false, ignore_error: true)!
|
||||
|
||||
// console.print_debug("${cmd} \n***\n${job.output}\n***")
|
||||
|
||||
|
||||
match job.output.trim_space() {
|
||||
'active' { return .active }
|
||||
'inactive' { return .inactive }
|
||||
@@ -182,4 +181,3 @@ pub fn (self SystemdProcess) status_detailed() !string {
|
||||
job := osal.exec(cmd: cmd, stdout: false, ignore_error: true)!
|
||||
return job.output
|
||||
}
|
||||
|
||||
|
||||
@@ -32,8 +32,8 @@ pub fn testsuite_end() ! {
|
||||
pub fn test_systemd_process_start_stop() ! {
|
||||
mut systemdfactory := new()!
|
||||
mut process := systemdfactory.new(
|
||||
cmd: 'redis-server'
|
||||
name: 'testservice'
|
||||
cmd: 'redis-server'
|
||||
name: 'testservice'
|
||||
start: false
|
||||
)!
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ mut:
|
||||
// Returns:
|
||||
// - The response string or an error if the send operation fails
|
||||
send(request string, params SendParams) !string
|
||||
url()string
|
||||
url() string
|
||||
}
|
||||
|
||||
// SendParams defines configuration options for sending JSON-RPC requests.
|
||||
@@ -68,8 +68,8 @@ pub fn (mut c Client) send[T, D](request RequestGeneric[T], params SendParams) !
|
||||
// Send the encoded request through the transport layer
|
||||
console.print_debug('Sending request: \n*****\n${request.encode()}\n*****\n')
|
||||
response_json := c.transport.send(request.encode(), params) or {
|
||||
if err.msg().contains("net: op timed out"){
|
||||
console.print_debug("time out")
|
||||
if err.msg().contains('net: op timed out') {
|
||||
console.print_debug('time out')
|
||||
}
|
||||
// print_backtrace()
|
||||
// println(err)
|
||||
@@ -91,15 +91,16 @@ pub fn (mut c Client) send[T, D](request RequestGeneric[T], params SendParams) !
|
||||
|
||||
// Return the result or propagate any error from the response
|
||||
return response.result() or {
|
||||
myerror := response.error_ or { return error('Failed to get error from response:\nRequest: ${request.encode()}\nResponse: ${response_json}\n${err}') }
|
||||
myerror := response.error_ or {
|
||||
return error('Failed to get error from response:\nRequest: ${request.encode()}\nResponse: ${response_json}\n${err}')
|
||||
}
|
||||
// print_backtrace()
|
||||
mut myreq:=request.encode()
|
||||
mut myreq := request.encode()
|
||||
if c.transport is UnixSocketTransport {
|
||||
myreq="To Test:\n**********\necho '\n${myreq}\n' | nc -U ${c.transport.url()}\n**********"
|
||||
myreq = "To Test:\n**********\necho '\n${myreq}\n' | nc -U ${c.transport.url()}\n**********"
|
||||
} else {
|
||||
myreq="Path:${c.transport.url()}\nRequest:\n${myreq}"
|
||||
myreq = 'Path:${c.transport.url()}\nRequest:\n${myreq}'
|
||||
}
|
||||
return error('\nRPC Request Failed.\n${myreq}\n${myerror}')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -120,13 +120,12 @@ pub fn (resp Response) encode() string {
|
||||
pub fn (resp Response) validate() ! {
|
||||
if resp.error_ != none && resp.result != none {
|
||||
return error('Response contains both error and result.\n- Error: ${resp.error_.str()}\n- Result: ${resp.result}')
|
||||
}
|
||||
}
|
||||
if resp.error_ == none && resp.result == none {
|
||||
return error('Response contains neither error nor result.')
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// is_error checks if the response contains an error.
|
||||
//
|
||||
// Returns:
|
||||
@@ -237,10 +236,10 @@ pub fn decode_response_generic[D](data string) !ResponseGeneric[D] {
|
||||
// Handle successful responses
|
||||
resp := json.decode(ResponseGeneric[D], data)!
|
||||
return ResponseGeneric[D]{
|
||||
id: raw_map['id'] or {
|
||||
print_backtrace()
|
||||
return error('Invalid JSONRPC response, no ID Field found')
|
||||
}.int()
|
||||
id: raw_map['id'] or {
|
||||
print_backtrace()
|
||||
return error('Invalid JSONRPC response, no ID Field found')
|
||||
}.int()
|
||||
jsonrpc: jsonrpc_version
|
||||
result: resp.result
|
||||
}
|
||||
|
||||
@@ -58,16 +58,16 @@ pub fn (mut t UnixSocketTransport) send(request string, params SendParams) !stri
|
||||
// Read up to 64000 bytes
|
||||
mut res := []u8{len: 64000, cap: 64000}
|
||||
n := socket.read(mut res) or {
|
||||
//can be timeout
|
||||
// can be timeout
|
||||
if err.code() == 11 { // Resource temporarily unavailable (EWOULDBLOCK)
|
||||
console.print_debug('Resource temporarily unavailable, retrying...')
|
||||
time.sleep(100 * time.millisecond)
|
||||
continue
|
||||
}
|
||||
if err.code() == 9 {
|
||||
if err.code() == 9 {
|
||||
console.print_debug('Timeout...')
|
||||
break
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
// console.print_debug('Read ${n} bytes from socket')
|
||||
@@ -79,12 +79,12 @@ pub fn (mut t UnixSocketTransport) send(request string, params SendParams) !stri
|
||||
res_total << res[..n]
|
||||
if n < 8192 {
|
||||
// console.print_debug('No more data to read, breaking loop after ${n} bytes')
|
||||
//TODO: this seems weird
|
||||
// TODO: this seems weird
|
||||
break
|
||||
}
|
||||
}
|
||||
unix.shutdown(socket.sock.handle)
|
||||
socket.close() or {}
|
||||
socket.close() or {}
|
||||
|
||||
// println(res_total.bytestr().trim_space())
|
||||
|
||||
|
||||
@@ -17,19 +17,18 @@ pub mut:
|
||||
whitelist []int // comma separated list of servers we whitelist to work on
|
||||
user string
|
||||
password string
|
||||
sshkey string
|
||||
nodes []HetznerNode
|
||||
sshkey string
|
||||
nodes []HetznerNode
|
||||
}
|
||||
|
||||
@[heap]
|
||||
pub struct HetznerNode {
|
||||
pub mut:
|
||||
id string
|
||||
id string
|
||||
name string = 'default'
|
||||
description string
|
||||
}
|
||||
|
||||
|
||||
pub fn (mut h HetznerManager) connection() !&httpconnection.HTTPConnection {
|
||||
mut c2 := httpconnection.new(
|
||||
name: 'hetzner_${h.name}'
|
||||
|
||||
@@ -6,8 +6,6 @@ import freeflowuniverse.herolib.core.playbook { PlayBook }
|
||||
// play processes playbook actions for the hetznermanager module.
|
||||
// It allows configuring and managing Hetzner servers through heroscript.
|
||||
pub fn play2(mut plbook PlayBook) ! {
|
||||
|
||||
|
||||
// Handle rescue actions
|
||||
for mut action in plbook.find(filter: 'hetznermanager.server_rescue')! {
|
||||
mut p := action.params
|
||||
@@ -25,12 +23,12 @@ pub fn play2(mut plbook PlayBook) ! {
|
||||
}
|
||||
|
||||
cl.server_rescue(
|
||||
id: id,
|
||||
name: server_name,
|
||||
wait: wait,
|
||||
hero_install: hero_install,
|
||||
reset: reset,
|
||||
retry: retry
|
||||
id: id
|
||||
name: server_name
|
||||
wait: wait
|
||||
hero_install: hero_install
|
||||
reset: reset
|
||||
retry: retry
|
||||
)!
|
||||
|
||||
action.done = true
|
||||
@@ -53,12 +51,12 @@ pub fn play2(mut plbook PlayBook) ! {
|
||||
}
|
||||
|
||||
cl.ubuntu_install(
|
||||
id: id,
|
||||
name: server_name,
|
||||
wait: wait,
|
||||
hero_install: hero_install,
|
||||
hero_install_compile: hero_install_compile,
|
||||
raid: raid
|
||||
id: id
|
||||
name: server_name
|
||||
wait: wait
|
||||
hero_install: hero_install
|
||||
hero_install_compile: hero_install_compile
|
||||
raid: raid
|
||||
)!
|
||||
|
||||
action.done = true
|
||||
@@ -78,10 +76,10 @@ pub fn play2(mut plbook PlayBook) ! {
|
||||
}
|
||||
|
||||
cl.server_reset(
|
||||
id: id,
|
||||
name: server_name,
|
||||
wait: wait,
|
||||
msg: msg
|
||||
id: id
|
||||
name: server_name
|
||||
wait: wait
|
||||
msg: msg
|
||||
)!
|
||||
|
||||
action.done = true
|
||||
@@ -107,8 +105,8 @@ pub fn play2(mut plbook PlayBook) ! {
|
||||
|
||||
key_name := p.get('key_name')!
|
||||
|
||||
cl.key_delete( key_name)!
|
||||
cl.key_delete(key_name)!
|
||||
|
||||
action.done = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
module hetznermanager
|
||||
|
||||
|
||||
|
||||
pub fn (mut h HetznerManager) check_whitelist(args_ ServerRescueArgs)! {
|
||||
|
||||
pub fn (mut h HetznerManager) check_whitelist(args_ ServerRescueArgs) ! {
|
||||
if h.whitelist.len == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
mut serverinfo := h.server_info_get(id: args_.id, name: args_.name)!
|
||||
|
||||
if ! h.whitelist.contains(serverinfo.server_number) {
|
||||
if !h.whitelist.contains(serverinfo.server_number) {
|
||||
return error('Server ${serverinfo}\nis not whitelisted')
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -69,9 +69,8 @@ fn (mut h HetznerManager) server_rescue_internal(args_ ServerRescueArgs) !Server
|
||||
if serverinfo.rescue == false || args.reset {
|
||||
console.print_header('server ${serverinfo.server_name} goes into rescue mode')
|
||||
|
||||
|
||||
mykey:=h.key_get(h.sshkey)!
|
||||
mykeyfp:=mykey.fingerprint
|
||||
mykey := h.key_get(h.sshkey)!
|
||||
mykeyfp := mykey.fingerprint
|
||||
|
||||
// println("Using SSH key fingerprint: ${mykey} ${mykeyfp}")
|
||||
|
||||
@@ -117,7 +116,6 @@ fn (mut h HetznerManager) server_rescue_internal(args_ ServerRescueArgs) !Server
|
||||
}
|
||||
|
||||
pub fn (mut h HetznerManager) server_rescue_node(args ServerRescueArgs) !&builder.Node {
|
||||
|
||||
mut serverinfo := h.server_rescue(args)!
|
||||
|
||||
mut b := builder.new()!
|
||||
@@ -137,11 +135,11 @@ pub mut:
|
||||
}
|
||||
|
||||
pub fn (mut h HetznerManager) ubuntu_install(args ServerInstallArgs) !&builder.Node {
|
||||
h.check_whitelist(name:args.name,id:args.id)!
|
||||
h.check_whitelist(name: args.name, id: args.id)!
|
||||
mut serverinfo := h.server_rescue(
|
||||
id: args.id
|
||||
name: args.name
|
||||
wait: true
|
||||
id: args.id
|
||||
name: args.name
|
||||
wait: true
|
||||
)!
|
||||
|
||||
mut b := builder.new()!
|
||||
@@ -153,7 +151,7 @@ pub fn (mut h HetznerManager) ubuntu_install(args ServerInstallArgs) !&builder.N
|
||||
|
||||
mut rstr := '-r no '
|
||||
if args.raid {
|
||||
panic("should not use RAID for now")
|
||||
panic('should not use RAID for now')
|
||||
rstr = '-r yes -l 1 '
|
||||
}
|
||||
|
||||
@@ -189,7 +187,7 @@ pub fn (mut h HetznerManager) ubuntu_install(args ServerInstallArgs) !&builder.N
|
||||
|
||||
console.print_debug('server ${serverinfo.server_name} is reacheable over ping, lets now try ssh.')
|
||||
|
||||
//wait 20 sec to make sure ssh is there
|
||||
// wait 20 sec to make sure ssh is there
|
||||
osal.ssh_wait(address: serverinfo.server_ip, timeout: 20)!
|
||||
|
||||
console.print_debug('server ${serverinfo.server_name} is reacheable over ssh, lets now install hero if asked for.')
|
||||
|
||||
@@ -77,7 +77,7 @@ pub fn (mut h HetznerManager) server_info_get(args_ ServerGetArgs) !ServerInfoDe
|
||||
continue
|
||||
}
|
||||
server_name := texttools.name_fix(item.server_name)
|
||||
//if id specified then we always use that one
|
||||
// if id specified then we always use that one
|
||||
if args.id == 0 && args.name.len > 0 && server_name != args.name {
|
||||
continue
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user