...
This commit is contained in:
@@ -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
|
||||
)!
|
||||
|
||||
|
||||
Reference in New Issue
Block a user