refactor: simplify console management and apply fixes

- Replace ConsoleFactory with global state and functions
- Fix container state check to use `result.output`
- Reformat `osal.exec` calls and map literals
- Streamline environment variable parsing
- Remove redundant blank lines and trailing characters
This commit is contained in:
Mahmoud-Emad
2025-09-07 14:52:17 +03:00
parent 145c6d8714
commit 9123c2bcb8
2 changed files with 54 additions and 53 deletions

View File

@@ -22,9 +22,9 @@ fn (mut executor ExecutorCrun) init() ! {
result := osal.exec(cmd: 'crun state ${executor.container_id}', stdout: false) or { result := osal.exec(cmd: 'crun state ${executor.container_id}', stdout: false) or {
return error('Container ${executor.container_id} not found or not accessible') return error('Container ${executor.container_id} not found or not accessible')
} }
// Parse state to ensure container is running // Parse state to ensure container is running
if !result.contains('"status":"running"') { if !result.output.contains('"status":"running"') {
return error('Container ${executor.container_id} is not running') return error('Container ${executor.container_id} is not running')
} }
} }
@@ -42,32 +42,32 @@ pub fn (mut executor ExecutorCrun) exec(args_ ExecArgs) !string {
if executor.debug { if executor.debug {
console.print_debug('execute in container ${executor.container_id}: ${args.cmd}') console.print_debug('execute in container ${executor.container_id}: ${args.cmd}')
} }
mut cmd := 'crun exec ${executor.container_id} ${args.cmd}' mut cmd := 'crun exec ${executor.container_id} ${args.cmd}'
if args.cmd.contains('\n') { if args.cmd.contains('\n') {
// For multiline commands, write to temp file first // For multiline commands, write to temp file first
temp_script := '/tmp/crun_script_${rand.uuid_v4()}.sh' temp_script := '/tmp/crun_script_${rand.uuid_v4()}.sh'
script_content := texttools.dedent(args.cmd) script_content := texttools.dedent(args.cmd)
os.write_file(temp_script, script_content)! os.write_file(temp_script, script_content)!
// Copy script into container and execute // Copy script into container and execute
executor.file_write('/tmp/exec_script.sh', script_content)! executor.file_write('/tmp/exec_script.sh', script_content)!
cmd = 'crun exec ${executor.container_id} bash /tmp/exec_script.sh' cmd = 'crun exec ${executor.container_id} bash /tmp/exec_script.sh'
} }
res := osal.exec(cmd: cmd, stdout: args.stdout, debug: executor.debug)! res := osal.exec(cmd: cmd, stdout: args.stdout, debug: executor.debug)!
return res.output return res.output
} }
pub fn (mut executor ExecutorCrun) exec_interactive(args_ ExecArgs) ! { pub fn (mut executor ExecutorCrun) exec_interactive(args_ ExecArgs) ! {
mut args := args_ mut args := args_
if args.cmd.contains('\n') { if args.cmd.contains('\n') {
args.cmd = texttools.dedent(args.cmd) args.cmd = texttools.dedent(args.cmd)
executor.file_write('/tmp/interactive_script.sh', args.cmd)! executor.file_write('/tmp/interactive_script.sh', args.cmd)!
args.cmd = 'bash /tmp/interactive_script.sh' args.cmd = 'bash /tmp/interactive_script.sh'
} }
cmd := 'crun exec -t ${executor.container_id} ${args.cmd}' cmd := 'crun exec -t ${executor.container_id} ${args.cmd}'
console.print_debug(cmd) console.print_debug(cmd)
osal.execute_interactive(cmd)! osal.execute_interactive(cmd)!
@@ -77,12 +77,12 @@ pub fn (mut executor ExecutorCrun) file_write(path string, text string) ! {
if executor.debug { if executor.debug {
console.print_debug('Container ${executor.container_id} file write: ${path}') console.print_debug('Container ${executor.container_id} file write: ${path}')
} }
// Write to temp file first, then copy into container // Write to temp file first, then copy into container
temp_file := '/tmp/crun_file_${rand.uuid_v4()}' temp_file := '/tmp/crun_file_${rand.uuid_v4()}'
os.write_file(temp_file, text)! os.write_file(temp_file, text)!
defer { os.rm(temp_file) or {} } defer { os.rm(temp_file) or {} }
// Use crun exec to copy file content // Use crun exec to copy file content
cmd := 'cat ${temp_file} | crun exec -i ${executor.container_id} tee ${path} > /dev/null' cmd := 'cat ${temp_file} | crun exec -i ${executor.container_id} tee ${path} > /dev/null'
osal.exec(cmd: cmd, stdout: false)! osal.exec(cmd: cmd, stdout: false)!
@@ -92,7 +92,7 @@ pub fn (mut executor ExecutorCrun) file_read(path string) !string {
if executor.debug { if executor.debug {
console.print_debug('Container ${executor.container_id} file read: ${path}') console.print_debug('Container ${executor.container_id} file read: ${path}')
} }
return executor.exec(cmd: 'cat ${path}', stdout: false) return executor.exec(cmd: 'cat ${path}', stdout: false)
} }
@@ -100,7 +100,7 @@ pub fn (mut executor ExecutorCrun) file_exists(path string) bool {
if executor.debug { if executor.debug {
console.print_debug('Container ${executor.container_id} file exists: ${path}') console.print_debug('Container ${executor.container_id} file exists: ${path}')
} }
output := executor.exec(cmd: 'test -f ${path} && echo found || echo not found', stdout: false) or { output := executor.exec(cmd: 'test -f ${path} && echo found || echo not found', stdout: false) or {
return false return false
} }
@@ -117,18 +117,21 @@ pub fn (mut executor ExecutorCrun) delete(path string) ! {
pub fn (mut executor ExecutorCrun) upload(args SyncArgs) ! { pub fn (mut executor ExecutorCrun) upload(args SyncArgs) ! {
// For container uploads, we need to copy files from host to container // For container uploads, we need to copy files from host to container
// Use crun exec with tar for efficient transfer // Use crun exec with tar for efficient transfer
mut src_path := pathlib.get(args.source) mut src_path := pathlib.get(args.source)
if !src_path.exists() { if !src_path.exists() {
return error('Source path ${args.source} does not exist') return error('Source path ${args.source} does not exist')
} }
if src_path.is_dir() { if src_path.is_dir() {
// For directories, use tar to transfer // For directories, use tar to transfer
temp_tar := '/tmp/crun_upload_${rand.uuid_v4()}.tar' temp_tar := '/tmp/crun_upload_${rand.uuid_v4()}.tar'
osal.exec(cmd: 'tar -cf ${temp_tar} -C ${src_path.path_dir()} ${src_path.name()}', stdout: false)! osal.exec(
cmd: 'tar -cf ${temp_tar} -C ${src_path.path_dir()} ${src_path.name()}'
stdout: false
)!
defer { os.rm(temp_tar) or {} } defer { os.rm(temp_tar) or {} }
// Extract in container // Extract in container
cmd := 'cat ${temp_tar} | crun exec -i ${executor.container_id} tar -xf - -C ${args.dest}' cmd := 'cat ${temp_tar} | crun exec -i ${executor.container_id} tar -xf - -C ${args.dest}'
osal.exec(cmd: cmd, stdout: args.stdout)! osal.exec(cmd: cmd, stdout: args.stdout)!
@@ -146,9 +149,12 @@ pub fn (mut executor ExecutorCrun) download(args SyncArgs) ! {
cmd := 'crun exec ${executor.container_id} tar -cf - -C ${args.source} . > ${temp_tar}' cmd := 'crun exec ${executor.container_id} tar -cf - -C ${args.source} . > ${temp_tar}'
osal.exec(cmd: cmd, stdout: false)! osal.exec(cmd: cmd, stdout: false)!
defer { os.rm(temp_tar) or {} } defer { os.rm(temp_tar) or {} }
// Extract on host // Extract on host
osal.exec(cmd: 'mkdir -p ${args.dest} && tar -xf ${temp_tar} -C ${args.dest}', stdout: args.stdout)! osal.exec(
cmd: 'mkdir -p ${args.dest} && tar -xf ${temp_tar} -C ${args.dest}'
stdout: args.stdout
)!
} else { } else {
// For single files // For single files
content := executor.file_read(args.source)! content := executor.file_read(args.source)!
@@ -157,16 +163,16 @@ pub fn (mut executor ExecutorCrun) download(args SyncArgs) ! {
} }
pub fn (mut executor ExecutorCrun) environ_get() !map[string]string { pub fn (mut executor ExecutorCrun) environ_get() !map[string]string {
env := executor.exec(cmd: 'env', stdout: false) or { env := executor.exec(cmd: 'env', stdout: false) or {
return error('Cannot get environment from container ${executor.container_id}') return error('Cannot get environment from container ${executor.container_id}')
} }
mut res := map[string]string{} mut res := map[string]string{}
for line in env.split('\n') { for line in env.split('\n') {
if line.contains('=') { if line.contains('=') {
parts := line.split_once('=') or { continue } mut key, mut val := line.split_once('=') or { continue }
key := parts[0].trim(' ') key = key.trim(' ')
val := parts[1].trim(' ') val = val.trim(' ')
res[key] = val res[key] = val
} }
} }
@@ -175,9 +181,9 @@ pub fn (mut executor ExecutorCrun) environ_get() !map[string]string {
pub fn (mut executor ExecutorCrun) info() map[string]string { pub fn (mut executor ExecutorCrun) info() map[string]string {
return { return {
'category': 'crun' 'category': 'crun'
'container_id': executor.container_id 'container_id': executor.container_id
'runtime': 'crun' 'runtime': 'crun'
} }
} }
@@ -193,7 +199,7 @@ pub fn (mut executor ExecutorCrun) list(path string) ![]string {
if !executor.dir_exists(path) { if !executor.dir_exists(path) {
return error('Directory ${path} does not exist in container') return error('Directory ${path} does not exist in container')
} }
output := executor.exec(cmd: 'ls ${path}', stdout: false)! output := executor.exec(cmd: 'ls ${path}', stdout: false)!
mut res := []string{} mut res := []string{}
for line in output.split('\n') { for line in output.split('\n') {
@@ -210,4 +216,4 @@ pub fn (mut executor ExecutorCrun) dir_exists(path string) bool {
return false return false
} }
return output.trim_space() == 'found' return output.trim_space() == 'found'
} }

View File

@@ -2,29 +2,21 @@ module console
import freeflowuniverse.herolib.core.texttools import freeflowuniverse.herolib.core.texttools
pub struct ConsoleFactory { __global (
pub mut:
consoles map[string]&UIConsole consoles map[string]&UIConsole
silent bool silent bool
)
pub fn silent_set() {
silent = true
} }
pub fn new_console_factory() &ConsoleFactory { pub fn silent_unset() {
return &ConsoleFactory{ silent = false
consoles: map[string]&UIConsole{}
silent: false
}
} }
pub fn (mut cf ConsoleFactory) silent_set() { pub fn silent_get() bool {
cf.silent = true return silent
}
pub fn (mut cf ConsoleFactory) silent_unset() {
cf.silent = false
}
pub fn (cf ConsoleFactory) silent_get() bool {
return cf.silent
} }
pub struct UIConsole { pub struct UIConsole {
@@ -56,14 +48,17 @@ pub fn (mut c UIConsole) status() string {
return out.trim_space() return out.trim_space()
} }
pub fn (mut cf ConsoleFactory) new_console() &UIConsole { pub fn new() UIConsole {
mut c := UIConsole{} return UIConsole{}
cf.consoles['main'] = &c
return &c
} }
pub fn (cf ConsoleFactory) get_console() &UIConsole { fn init() {
return cf.consoles['main'] or { panic('bug') } mut c := UIConsole{}
consoles['main'] = &c
}
fn get() &UIConsole {
return consoles['main'] or { panic('bug') }
} }
pub fn trim(c_ string) string { pub fn trim(c_ string) string {
@@ -72,12 +67,12 @@ pub fn trim(c_ string) string {
} }
// line feed // line feed
pub fn (mut cf ConsoleFactory) lf() { pub fn lf() {
mut c := cf.get_console() mut c := get()
if c.prev_lf { if c.prev_lf {
return return
} }
if !cf.silent_get() { if !silent_get() {
print('\n') print('\n')
} }
c.prev_lf = true c.prev_lf = true