osal.core #
Operating System Abstraction Layer (OSAL) - Core Module
The lib/osal/core
module provides a comprehensive, platform-independent abstraction layer for common operating system functionalities in V. It simplifies interactions with the underlying system, offering robust tools for process management, network operations, file system manipulation, environment variable handling, and more.
Capabilities & Usage
This module encapsulates essential OS-level features, making system programming more consistent and reliable across different environments.
1. Process Execution (exec.v
)
Execute shell commands with fine-grained control and robust error handling.
osal.exec(cmd: Command)
: Executes a command with extensive options.Command
struct fields:cmd
(string): The command string.timeout
(int): Max execution time in seconds (default: 3600).retry
(int): Number of retries on failure.work_folder
(string): Working directory for the command.environment
(map[string]string): Environment variables for the command.stdout
(bool): Show command output (default: true).raise_error
(bool): Raise V error on failure (default: true).ignore_error
(bool): Do not raise error, just report.debug
(bool): Enable debug output.shell
(bool): Execute in interactive shell.async
(bool): Run command asynchronously.runtime
(RunTime): Specify runtime (e.g.,.bash
,.python
).- Returns
Job
struct withstatus
,output
,error
,exit_code
, etc. osal.execute_silent(cmd string)
: Executes a command silently, returns output.osal.execute_debug(cmd string)
: Executes a command with debug output, returns output.osal.execute_stdout(cmd string)
: Executes a command and prints output to stdout, returns output.osal.execute_interactive(cmd string)
: Executes a command in an interactive shell.osal.cmd_exists(cmd string)
: Checks if a command exists in the system's PATH.
Example: Flexible Command Execution
import freeflowuniverse.herolib.osal.core as osal
// Simple command execution
job := osal.exec(cmd: 'ls -la')!
println(job.output)
// Execute with error handling and custom options
job := osal.exec(osal.Command{
cmd: 'complex_command_that_might_fail'
timeout: 60 // seconds
retry: 2
work_folder: '/tmp'
environment: {
'MY_VAR': 'some_value'
}
stdout: true
raise_error: true
})!
// Check job status and handle specific errors
if job.status == .done {
println('Command executed successfully!')
} else if job.status == .error_timeout {
println('Command timed out.')
} else {
println('Command failed with exit code: ${job.exit_code}, Error: ${job.error}')
}
// Example of error handling with match
job_result := osal.exec(cmd: 'non_existent_command')
if job_result.is_err() {
err := job_result.err
match err.error_type {
.exec { println('Execution error: ${err.msg()}') }
.timeout { println('Command timed out: ${err.msg()}') }
.args { println('Invalid arguments: ${err.msg()}') }
else { println('An unexpected error occurred: ${err.msg()}') }
}
}
2. Network Utilities (net.v
)
Tools for network diagnostics and information.
osal.ping(args: PingArgs)
: Checks host reachability.PingArgs
struct fields:address
(string, required),count
(u8),timeout
(u16),retry
(u8).- Returns
PingResult
enum:.ok
,.timeout
,.unknownhost
. osal.tcp_port_test(args: TcpPortTestArgs)
: Tests if a TCP port is open.TcpPortTestArgs
struct fields:address
(string, required),port
(int),timeout
(u16 in milliseconds).- Returns
bool
. osal.ipaddr_pub_get()
: Retrieves the public IP address. Returnsstring
.osal.is_ip_on_local_interface(ip string)
: Checks if an IP is on a local interface. Returnsbool
.
3. File System Operations (file.v
)
Functions for managing files and directories.
osal.file_write(path string, text string)
: Writes text to a file.osal.file_read(path string)
: Reads content from a file. Returnsstring
.osal.dir_ensure(path string)
: Ensures a directory exists, creates if not.osal.dir_delete(path string)
: Deletes a directory if it exists.osal.dir_reset(path string)
: Deletes and recreates a directory.osal.rm(todelete string)
: Removes files/directories (supports~
, comma/newline separated paths, sudo).
4. Environment Variables (env.v
)
Manage system environment variables.
osal.env_set(args: EnvSet)
: Sets an environment variable.EnvSet
struct fields:key
(string, required),value
(string, required),overwrite
(bool).osal.env_unset(key string)
: Unsets an environment variable.osal.env_unset_all()
: Unsets all environment variables.osal.env_set_all(args: EnvSetAll)
: Sets multiple environment variables.EnvSetAll
struct fields:env
(map[string]string),clear_before_set
(bool),overwrite_if_exists
(bool).osal.env_get(key string)
: Retrieves an environment variable's value. Returnsstring
.osal.env_exists(key string)
: Checks if an environment variable exists. Returnsbool
.osal.env_get_default(key string, def string)
: Gets an environment variable or a default value. Returnsstring
.osal.load_env_file(file_path string)
: Loads environment variables from a file.
5. Command & Profile Management (cmds.v
)
Manage system commands and shell profile paths.
osal.cmd_add(args: CmdAddArgs)
: Adds a binary to system paths and updates profiles.CmdAddArgs
struct fields:cmdname
(string),source
(string, required),symlink
(bool),reset
(bool).osal.profile_path_add_hero()
: Adds~/hero/bin
to profile. Returnsstring
(path).osal.bin_path()
: Returns the preferred binary installation path. Returnsstring
.osal.hero_path()
: Returns the~/hero
directory path. Returnsstring
.osal.usr_local_path()
: Returns/usr/local
(Linux) or~/hero
(macOS). Returnsstring
.osal.profile_path_source()
: Returns a source command for the preferred profile. Returnsstring
.osal.profile_path_source_and()
: Returns a source command followed by&&
. Returnsstring
.osal.profile_path_add_remove(args: ProfilePathAddRemoveArgs)
: Adds/removes paths from profiles.ProfilePathAddRemoveArgs
struct fields:paths_profile
(string),paths2add
(string),paths2delete
(string),allprofiles
(bool).osal.cmd_path(cmd string)
: Returns the full path of an executable command. Returnsstring
.osal.cmd_delete(cmd string)
: Deletes commands from their locations.osal.profile_paths_all()
: Lists all possible profile file paths. Returns[]string
.osal.profile_paths_preferred()
: Lists preferred profile file paths for the OS. Returns[]string
.osal.profile_path()
: Returns the most preferred profile file path. Returnsstring
.
6. System Information & Utilities (ps_tool.v
, sleep.v
, downloader.v
, users.v
, etc.)
Miscellaneous system functionalities.
osal.processmap_get()
: Gets a map of all running processes. ReturnsProcessMap
.osal.processinfo_get(pid int)
: Gets info for a specific process. ReturnsProcessInfo
.osal.processinfo_get_byname(name string)
: Gets info for processes by name. Returns[]ProcessInfo
.osal.process_exists(pid int)
: Checks if a process exists by PID. Returnsbool
.osal.processinfo_with_children(pid int)
: Gets a process and its children. ReturnsProcessMap
.osal.processinfo_children(pid int)
: Gets children of a process. ReturnsProcessMap
.osal.process_kill_recursive(args: ProcessKillArgs)
: Kills a process and its children.ProcessKillArgs
struct fields:name
(string),pid
(int).osal.whoami()
: Returns the current username. Returnsstring
.osal.sleep(duration int)
: Pauses execution forduration
seconds.osal.download(args: DownloadArgs)
: Downloads a file from a URL.DownloadArgs
struct fields:url
(string),name
(string),reset
(bool),hash
(string),dest
(string),timeout
(int),retry
(int),minsize_kb
(u32),maxsize_kb
(u32),expand_dir
(string),expand_file
(string).- Returns
pathlib.Path
. osal.user_exists(username string)
: Checks if a user exists. Returnsbool
.osal.user_id_get(username string)
: Gets user ID. Returnsint
.osal.user_add(args: UserArgs)
: Adds a user.UserArgs
struct fields:name
(string, required). Returnsint
(user ID).
Notes on the CMD Job Execution
- Commands are executed from temporary scripts in
/tmp/execscripts
. - Failed script executions are preserved for debugging.
- Successful script executions are automatically cleaned up.
- Platform-specific behavior is automatically handled.
- Timeout and retry mechanisms are available for robust execution.
- Environment variables and working directories can be specified per command.
- Interactive and non-interactive modes are supported.
fn bin_path #
fn bin_path() !string
fn cmd_add #
fn cmd_add(args_ CmdAddArgs) !
copy a binary to the right location on the local computer . e.g. is /usr/local/bin on linux . e.g. is ~/hero/bin on osx . will also add the bin location to the path of .zprofile and .zshrc (different per platform)
fn cmd_delete #
fn cmd_delete(cmd string) !
delete cmds from found locations can be one command of multiple
fn cmd_exists #
fn cmd_exists(cmd string) bool
fn cmd_exists_profile #
fn cmd_exists_profile(cmd string) bool
fn cmd_path #
fn cmd_path(cmd string) !string
is same as executing which in OS returns path or error
fn cmd_to_script_path #
fn cmd_to_script_path(cmd Command) !string
will return temporary path which then can be executed, is a helper function for making script out of command
fn dir_delete #
fn dir_delete(path string) !
remove all if it exists
fn dir_ensure #
fn dir_ensure(path string) !
remove all if it exists
fn dir_reset #
fn dir_reset(path string) !
remove all if it exists and then (re-)create
fn done_delete #
fn done_delete(key string) !
fn done_exists #
fn done_exists(key string) bool
fn done_get #
fn done_get(key string) ?string
fn done_get_int #
fn done_get_int(key string) int
fn done_get_str #
fn done_get_str(key string) string
fn done_print #
fn done_print() !
fn done_reset #
fn done_reset() !
fn done_set #
fn done_set(key string, val string) !
fn download #
fn download(args_ DownloadArgs) !pathlib.Path
if name is not specified, then will be the filename part if the last ends in an extension like .md .txt .log .text ... the file will be downloaded
fn env_exists #
fn env_exists(key string) !bool
fn env_get #
fn env_get(key string) !string
Returns the requested environment variable if it exists or throws an error if it does not
fn env_get_all #
fn env_get_all() map[string]string
Returns all existing environment variables
fn env_get_default #
fn env_get_default(key string, def string) string
Returns the requested environment variable if it exists or returns the provided default value if it does not
fn env_set #
fn env_set(args EnvSet)
Sets an environment if it was not set before, it overwrites the enviroment variable if it exists and if overwrite was set to true (default)
fn env_set_all #
fn env_set_all(args EnvSetAll)
Allows to set multiple enviroment variables in one go, if clear_before_set is true all existing environment variables will be unset before the operation, if overwrite_if_exists is set to true it will overwrite all existing enviromnent variables
fn env_unset #
fn env_unset(key string)
Unsets an environment variable
fn env_unset_all #
fn env_unset_all()
Unsets all environment variables
fn exec #
fn exec(cmd_ Command) !Job
cmd is the cmd to execute can use ' ' and spaces . if \n in cmd it will write it to ext and then execute with bash . if die==false then will just return returncode,out but not return error . if stdout will show stderr and stdout . . if cmd starts with find or ls, will give to bash -c so it can execute . if cmd has no path, path will be found . . Command argument: .
name string // to give a name to your command, good to see logs...
cmd string
description string
timeout int = 3600 // timeout in sec
stdout bool = true
stdout_log bool = true
raise_error bool = true // if false, will not raise an error but still error report
ignore_error bool // means if error will just exit and not raise, there will be no error reporting
work_folder string // location where cmd will be executed
environment map[string]string // env variables
ignore_error_codes []int
scriptpath string // is the path where the script will be put which is executed
scriptkeep bool // means we don't remove the script
debug bool // if debug will put +ex in the script which is being executed and will make sure script stays
shell bool // means we will execute it in a shell interactive
retry int
interactive bool = true // make sure we run on non interactive way
async bool
runtime RunTime (.bash, .python)
returns Job:
start time.Time
end time.Time
cmd Command
output []string
error []string
exit_code int
status JobStatus
process os.Process
return Job .
fn exec_string #
fn exec_string(cmd Command) !string
cmd is the cmd to execute can use ' ' and spaces if \n in cmd it will write it to ext and then execute with bash if die==false then will just return returncode,out but not return error if stdout will show stderr and stdout
if cmd starts with find or ls, will give to bash -c so it can execute if cmd has no path, path will be found $... are remplaced by environment arguments TODO:implement
Command argument: cmd string timeout int = 600 stdout bool = true die bool = true debug bool
return what needs to be executed can give it to bash -c ...
fn execute_debug #
fn execute_debug(cmd string) !string
fn execute_interactive #
fn execute_interactive(cmd string) !
shortcut to execute a job interactive means in shell
fn execute_ok #
fn execute_ok(cmd string) bool
executes a cmd, if not error return true
fn execute_silent #
fn execute_silent(cmd string) !string
shortcut to execute a job silent
fn execute_stdout #
fn execute_stdout(cmd string) !string
shortcut to execute a job to stdout
fn file_read #
fn file_read(path string) !string
fn file_write #
fn file_write(path string, text string) !
fn get_ssh_key #
fn get_ssh_key(key_name string, config SSHConfig) ?SSHKey
Returns a specific SSH key with the given name from the default SSH directory (~/.ssh)
fn hero_path #
fn hero_path() !string
fn ipaddr_pub_get #
fn ipaddr_pub_get() !string
Returns the public IP address as known on the public side Uses resolver4.opendns.com to fetch the IP address
fn ipaddr_pub_get_check #
fn ipaddr_pub_get_check() !string
also check the address is on local interface
fn is_ip_on_local_interface #
fn is_ip_on_local_interface(public_ip string) !bool
Check if the public IP matches any of the local network interfaces
fn load_env_file #
fn load_env_file(file_path string) !
fn new_ssh_key #
fn new_ssh_key(key_name string, config SSHConfig) !SSHKey
Creates a new SSH key pair to the specified directory
fn package_install #
fn package_install(name_ string) !
install a package using the right commands per platform
fn package_refresh #
fn package_refresh() !
update the package list
fn package_remove #
fn package_remove(name_ string) !
remove a package using the right commands per platform
fn ping #
fn ping(args PingArgs) !PingResult
if reached in timout result will be True address is e.g. 8.8.8.8 ping means we check if the destination responds
fn process_exists #
fn process_exists(pid int) bool
fn process_exists_byname #
fn process_exists_byname(name string) !bool
fn process_kill_recursive #
fn process_kill_recursive(args ProcessKillArgs) !
kill process and all the ones underneith
fn processinfo_children #
fn processinfo_children(pid int) !ProcessMap
get all children of 1 process
fn processinfo_get #
fn processinfo_get(pid int) !ProcessInfo
get process info from 1 specific process returns
pub struct ProcessInfo {
pub mut:
cpu_perc f32
mem_perc f32
cmd string
pid int
ppid int
//resident memory
rss int
}
fn processinfo_get_byname #
fn processinfo_get_byname(name string) ![]ProcessInfo
fn processinfo_with_children #
fn processinfo_with_children(pid int) !ProcessMap
return the process and its children
fn processmap_get #
fn processmap_get() !ProcessMap
make sure to use new first, so that the connection has been initted then you can get it everywhere
fn profile_path #
fn profile_path() !string
fn profile_path_add_hero #
fn profile_path_add_hero() !string
fn profile_path_add_remove #
fn profile_path_add_remove(args_ ProfilePathAddRemoveArgs) !
add and/or remove paths from profiles if paths_profile not specified it will walk over all of them
fn profile_path_source #
fn profile_path_source() !string
return the source statement if the profile exists
fn profile_path_source_and #
fn profile_path_source_and() !string
return source $path && . or empty if it doesn't exist
fn profile_paths_all #
fn profile_paths_all() ![]string
return possible profile paths in OS
fn profile_paths_preferred #
fn profile_paths_preferred() ![]string
fn rm #
fn rm(todelete_ string) !
can be list of dirs, files ~ supported can be \n or , separated
fn sleep #
fn sleep(duration int)
sleep in seconds
fn tcp_port_test #
fn tcp_port_test(args TcpPortTestArgs) bool
test if a tcp port answers
address string //192.168.8.8
port int = 22
timeout u16 = 2000 // total time in milliseconds to keep on trying
fn user_add #
fn user_add(args UserArgs) !int
add's a user if the user does not exist yet
fn user_exists #
fn user_exists(username string) bool
fn user_id_get #
fn user_id_get(username string) !int
fn usr_local_path #
fn usr_local_path() !string
/usr/local on linux, ${os.home_dir()}/hero on osx
fn whoami #
fn whoami() !string
enum ErrorType #
enum ErrorType {
exec
timeout
args
}
enum JobStatus #
enum JobStatus {
init
running
error_exec
error_timeout
error_args
done
}
enum PMState #
enum PMState {
init
ok
old
}
enum PingResult #
enum PingResult {
ok
timeout // timeout from ping
unknownhost // means we don't know the hostname its a dns issue
}
enum RunTime #
enum RunTime {
bash
python
heroscript
herocmd
v
}
struct CmdAddArgs #
struct CmdAddArgs {
pub mut:
cmdname string
source string @[required] // path where the binary is
symlink bool // if rather than copy do a symlink
reset bool = true // if existing cmd will delete
// bin_repo_url string = 'https://github.com/freeflowuniverse/freeflow_binary' // binary where we put the results
}
struct Command #
struct Command {
pub mut:
name string // to give a name to your command, good to see logs...
cmd string
description string
timeout int = 3600 // timeout in sec
stdout bool = true
stdout_log bool = true
raise_error bool = true // if false, will not raise an error but still error report
ignore_error bool // means if error will just exit and not raise, there will be no error reporting
work_folder string // location where cmd will be executed
environment map[string]string // env variables
ignore_error_codes []int
scriptpath string // is the path where the script will be put which is executed
scriptkeep bool // means we don't remove the script
debug bool // if debug will put +ex in the script which is being executed and will make sure script stays
shell bool // means we will execute it in a shell interactive
retry int
interactive bool = true
async bool
runtime RunTime
}
struct DownloadArgs #
struct DownloadArgs {
pub mut:
name string // optional (otherwise derived out of filename)
url string
reset bool // will remove
hash string // if hash is known, will verify what hash is
dest string // if specified will copy to that destination
timeout int = 180
retry int = 3
minsize_kb u32 = 10 // is always in kb
maxsize_kb u32
expand_dir string
expand_file string
}
struct EnvSet #
struct EnvSet {
pub mut:
key string @[required]
value string @[required]
overwrite bool = true
}
struct EnvSetAll #
struct EnvSetAll {
pub mut:
env map[string]string
clear_before_set bool
overwrite_if_exists bool = true
}
struct Job #
struct Job {
pub mut:
start time.Time
end time.Time
cmd Command
output string
error string
exit_code int
status JobStatus
process ?&os.Process @[skip; str: skip]
runnr int // nr of time it runs, is for retry
}
fn (Job) execute_retry #
fn (mut job Job) execute_retry() !
execute the job and wait on result will retry as specified
fn (Job) execute #
fn (mut job Job) execute() !
execute the job, start process, process will not be closed . important you need to close the process later by job.close()! otherwise we get zombie processes
fn (Job) wait #
fn (mut job Job) wait() !
wait till the job finishes or goes in error
fn (Job) process #
fn (mut job Job) process() !
process (read std.err and std.out of process)
fn (Job) close #
fn (mut job Job) close() !
will wait & close
struct JobError #
struct JobError {
Error
pub mut:
job Job
error_type ErrorType
}
struct PingArgs #
struct PingArgs {
pub mut:
address string @[required]
count u8 = 1 // the ping is successful if it got count amount of replies from the other side
timeout u16 = 1 // the time in which the other side should respond in seconds
retry u8
}
struct ProcessInfo #
struct ProcessInfo {
pub mut:
cpu_perc f32
mem_perc f32
cmd string
pid int
ppid int // parentpid
// resident memory
rss int
}
fn (ProcessInfo) str #
fn (mut p ProcessInfo) str() string
struct ProcessKillArgs #
struct ProcessKillArgs {
pub mut:
name string
pid int
}
struct ProcessMap #
struct ProcessMap {
pub mut:
processes []ProcessInfo
lastscan time.Time
state PMState
pids []int
}
struct ProfilePathAddRemoveArgs #
struct ProfilePathAddRemoveArgs {
pub mut:
paths_profile string
paths2add string
paths2delete string
allprofiles bool
}
struct SSHConfig #
struct SSHConfig {
pub:
directory string = os.join_path(os.home_dir(), '.ssh')
}
struct SSHKey #
struct SSHKey {
pub:
name string
directory string
}
fn (SSHKey) public_key_path #
fn (key SSHKey) public_key_path() !pathlib.Path
returns the public ssh key's path of the keypair
fn (SSHKey) private_key_path #
fn (key SSHKey) private_key_path() !pathlib.Path
returns the private ssh key's path of the keypair
fn (SSHKey) public_key #
fn (key SSHKey) public_key() !string
returns the public ssh key of the keypair
fn (SSHKey) private_key #
fn (key SSHKey) private_key() !string
returns the private ssh key of the keypair
struct TcpPortTestArgs #
struct TcpPortTestArgs {
pub mut:
address string @[required] // 192.168.8.8
port int = 22
timeout u16 = 2000 // total time in milliseconds to keep on trying
}
struct UserArgs #
struct UserArgs {
pub mut:
name string @[required]
}
- README
- fn bin_path
- fn cmd_add
- fn cmd_delete
- fn cmd_exists
- fn cmd_exists_profile
- fn cmd_path
- fn cmd_to_script_path
- fn dir_delete
- fn dir_ensure
- fn dir_reset
- fn done_delete
- fn done_exists
- fn done_get
- fn done_get_int
- fn done_get_str
- fn done_print
- fn done_reset
- fn done_set
- fn download
- fn env_exists
- fn env_get
- fn env_get_all
- fn env_get_default
- fn env_set
- fn env_set_all
- fn env_unset
- fn env_unset_all
- fn exec
- fn exec_string
- fn execute_debug
- fn execute_interactive
- fn execute_ok
- fn execute_silent
- fn execute_stdout
- fn file_read
- fn file_write
- fn get_ssh_key
- fn hero_path
- fn ipaddr_pub_get
- fn ipaddr_pub_get_check
- fn is_ip_on_local_interface
- fn load_env_file
- fn new_ssh_key
- fn package_install
- fn package_refresh
- fn package_remove
- fn ping
- fn process_exists
- fn process_exists_byname
- fn process_kill_recursive
- fn processinfo_children
- fn processinfo_get
- fn processinfo_get_byname
- fn processinfo_with_children
- fn processmap_get
- fn profile_path
- fn profile_path_add_hero
- fn profile_path_add_remove
- fn profile_path_source
- fn profile_path_source_and
- fn profile_paths_all
- fn profile_paths_preferred
- fn rm
- fn sleep
- fn tcp_port_test
- fn user_add
- fn user_exists
- fn user_id_get
- fn usr_local_path
- fn whoami
- enum ErrorType
- enum JobStatus
- enum PMState
- enum PingResult
- enum RunTime
- struct CmdAddArgs
- struct Command
- struct DownloadArgs
- struct EnvSet
- struct EnvSetAll
- struct Job
- struct JobError
- struct PingArgs
- struct ProcessInfo
- struct ProcessKillArgs
- struct ProcessMap
- struct ProfilePathAddRemoveArgs
- struct SSHConfig
- struct SSHKey
- struct TcpPortTestArgs
- struct UserArgs