Files
herolib/lib/virt/crun/tojson.v
despiegk cb125e8114 ...
Co-authored-by: Omdanii <mahmmoud.hassanein@gmail.com>
2025-09-07 15:15:41 +04:00

280 lines
8.1 KiB
V

module crun
import json
// Convert enum values to their string representations
fn (os OSType) to_json_string() string {
return match os {
.linux { 'linux' }
.windows { 'windows' }
.darwin { 'darwin' }
.solaris { 'solaris' }
}
}
fn (arch ArchType) to_json_string() string {
return match arch {
.amd64 { 'amd64' }
.arm64 { 'arm64' }
.arm { 'arm' }
.ppc64 { 'ppc64' }
.s390x { 's390x' }
}
}
fn (mount_type MountType) to_json_string() string {
return match mount_type {
.bind { 'bind' }
.tmpfs { 'tmpfs' }
.nfs { 'nfs' }
.overlay { 'overlay' }
.devpts { 'devpts' }
.proc { 'proc' }
.sysfs { 'sysfs' }
}
}
fn (option MountOption) to_json_string() string {
return match option {
.rw { 'rw' }
.ro { 'ro' }
.noexec { 'noexec' }
.nosuid { 'nosuid' }
.nodev { 'nodev' }
.rbind { 'rbind' }
.relatime { 'relatime' }
}
}
fn (cap Capability) to_json_string() string {
return match cap {
.cap_chown { 'CAP_CHOWN' }
.cap_dac_override { 'CAP_DAC_OVERRIDE' }
.cap_dac_read_search { 'CAP_DAC_READ_SEARCH' }
.cap_fowner { 'CAP_FOWNER' }
.cap_fsetid { 'CAP_FSETID' }
.cap_kill { 'CAP_KILL' }
.cap_setgid { 'CAP_SETGID' }
.cap_setuid { 'CAP_SETUID' }
.cap_setpcap { 'CAP_SETPCAP' }
.cap_linux_immutable { 'CAP_LINUX_IMMUTABLE' }
.cap_net_bind_service { 'CAP_NET_BIND_SERVICE' }
.cap_net_broadcast { 'CAP_NET_BROADCAST' }
.cap_net_admin { 'CAP_NET_ADMIN' }
.cap_net_raw { 'CAP_NET_RAW' }
.cap_ipc_lock { 'CAP_IPC_LOCK' }
.cap_ipc_owner { 'CAP_IPC_OWNER' }
.cap_sys_module { 'CAP_SYS_MODULE' }
.cap_sys_rawio { 'CAP_SYS_RAWIO' }
.cap_sys_chroot { 'CAP_SYS_CHROOT' }
.cap_sys_ptrace { 'CAP_SYS_PTRACE' }
.cap_sys_pacct { 'CAP_SYS_PACCT' }
.cap_sys_admin { 'CAP_SYS_ADMIN' }
.cap_sys_boot { 'CAP_SYS_BOOT' }
.cap_sys_nice { 'CAP_SYS_NICE' }
.cap_sys_resource { 'CAP_SYS_RESOURCE' }
.cap_sys_time { 'CAP_SYS_TIME' }
.cap_sys_tty_config { 'CAP_SYS_TTY_CONFIG' }
.cap_mknod { 'CAP_MKNOD' }
.cap_lease { 'CAP_LEASE' }
.cap_audit_write { 'CAP_AUDIT_WRITE' }
.cap_audit_control { 'CAP_AUDIT_CONTROL' }
.cap_setfcap { 'CAP_SETFCAP' }
.cap_mac_override { 'CAP_MAC_OVERRIDE' }
.cap_mac_admin { 'CAP_MAC_ADMIN' }
.cap_syslog { 'CAP_SYSLOG' }
.cap_wake_alarm { 'CAP_WAKE_ALARM' }
.cap_block_suspend { 'CAP_BLOCK_SUSPEND' }
.cap_audit_read { 'CAP_AUDIT_READ' }
}
}
fn (rlimit RlimitType) to_json_string() string {
return match rlimit {
.rlimit_cpu { 'RLIMIT_CPU' }
.rlimit_fsize { 'RLIMIT_FSIZE' }
.rlimit_data { 'RLIMIT_DATA' }
.rlimit_stack { 'RLIMIT_STACK' }
.rlimit_core { 'RLIMIT_CORE' }
.rlimit_rss { 'RLIMIT_RSS' }
.rlimit_nproc { 'RLIMIT_NPROC' }
.rlimit_nofile { 'RLIMIT_NOFILE' }
.rlimit_memlock { 'RLIMIT_MEMLOCK' }
.rlimit_as { 'RLIMIT_AS' }
.rlimit_lock { 'RLIMIT_LOCK' }
.rlimit_sigpending { 'RLIMIT_SIGPENDING' }
.rlimit_msgqueue { 'RLIMIT_MSGQUEUE' }
.rlimit_nice { 'RLIMIT_NICE' }
.rlimit_rtprio { 'RLIMIT_RTPRIO' }
.rlimit_rttime { 'RLIMIT_RTTIME' }
}
}
// Main method to generate complete OCI spec JSON
pub fn (config CrunConfig) to_json() !string {
spec_map := map[string]json.Any{}
// Basic spec fields
spec_map['ociVersion'] = config.spec.version
// Platform
spec_map['platform'] = map[string]json.Any{
'os': config.spec.platform.os.to_json_string()
'arch': config.spec.platform.arch.to_json_string()
}
// Process
process_map := map[string]json.Any{}
process_map['terminal'] = config.spec.process.terminal
process_map['user'] = map[string]json.Any{
'uid': int(config.spec.process.user.uid)
'gid': int(config.spec.process.user.gid)
'additionalGids': config.spec.process.user.additional_gids.map(int(it))
}
process_map['args'] = config.spec.process.args
process_map['env'] = config.spec.process.env
process_map['cwd'] = config.spec.process.cwd
// Capabilities
if config.spec.process.capabilities.bounding.len > 0 ||
config.spec.process.capabilities.effective.len > 0 ||
config.spec.process.capabilities.inheritable.len > 0 ||
config.spec.process.capabilities.permitted.len > 0 ||
config.spec.process.capabilities.ambient.len > 0 {
capabilities_map := map[string]json.Any{}
if config.spec.process.capabilities.bounding.len > 0 {
capabilities_map['bounding'] = config.spec.process.capabilities.bounding.map(it.to_json_string())
}
if config.spec.process.capabilities.effective.len > 0 {
capabilities_map['effective'] = config.spec.process.capabilities.effective.map(it.to_json_string())
}
if config.spec.process.capabilities.inheritable.len > 0 {
capabilities_map['inheritable'] = config.spec.process.capabilities.inheritable.map(it.to_json_string())
}
if config.spec.process.capabilities.permitted.len > 0 {
capabilities_map['permitted'] = config.spec.process.capabilities.permitted.map(it.to_json_string())
}
if config.spec.process.capabilities.ambient.len > 0 {
capabilities_map['ambient'] = config.spec.process.capabilities.ambient.map(it.to_json_string())
}
process_map['capabilities'] = capabilities_map
}
// Rlimits
if config.spec.process.rlimits.len > 0 {
rlimits_array := []json.Any{}
for rlimit in config.spec.process.rlimits {
rlimits_array << map[string]json.Any{
'type': rlimit.typ.to_json_string()
'hard': int(rlimit.hard)
'soft': int(rlimit.soft)
}
}
process_map['rlimits'] = rlimits_array
}
spec_map['process'] = process_map
// Root
spec_map['root'] = map[string]json.Any{
'path': config.spec.root.path
'readonly': config.spec.root.readonly
}
// Hostname
if config.spec.hostname != '' {
spec_map['hostname'] = config.spec.hostname
}
// Mounts
if config.spec.mounts.len > 0 {
mounts_array := []json.Any{}
for mount in config.spec.mounts {
mount_map := map[string]json.Any{
'destination': mount.destination
'type': mount.typ.to_json_string()
'source': mount.source
}
if mount.options.len > 0 {
mount_map['options'] = mount.options.map(it.to_json_string())
}
mounts_array << mount_map
}
spec_map['mounts'] = mounts_array
}
// Linux specific configuration
linux_map := map[string]json.Any{}
// Namespaces
if config.spec.linux.namespaces.len > 0 {
namespaces_array := []json.Any{}
for ns in config.spec.linux.namespaces {
ns_map := map[string]json.Any{
'type': ns.typ
}
if ns.path != '' {
ns_map['path'] = ns.path
}
namespaces_array << ns_map
}
linux_map['namespaces'] = namespaces_array
}
// Resources
resources_map := map[string]json.Any{}
has_resources := false
if config.spec.linux.resources.memory_limit > 0 {
memory_map := map[string]json.Any{
'limit': int(config.spec.linux.resources.memory_limit)
}
if config.spec.linux.resources.memory_reservation > 0 {
memory_map['reservation'] = int(config.spec.linux.resources.memory_reservation)
}
if config.spec.linux.resources.memory_swap_limit > 0 {
memory_map['swap'] = int(config.spec.linux.resources.memory_swap_limit)
}
resources_map['memory'] = memory_map
has_resources = true
}
if config.spec.linux.resources.cpu_period > 0 || config.spec.linux.resources.cpu_quota > 0 || config.spec.linux.resources.cpu_shares > 0 {
cpu_map := map[string]json.Any{}
if config.spec.linux.resources.cpu_period > 0 {
cpu_map['period'] = int(config.spec.linux.resources.cpu_period)
}
if config.spec.linux.resources.cpu_quota > 0 {
cpu_map['quota'] = int(config.spec.linux.resources.cpu_quota)
}
if config.spec.linux.resources.cpu_shares > 0 {
cpu_map['shares'] = int(config.spec.linux.resources.cpu_shares)
}
resources_map['cpu'] = cpu_map
has_resources = true
}
if config.spec.linux.resources.pids_limit > 0 {
resources_map['pids'] = map[string]json.Any{
'limit': int(config.spec.linux.resources.pids_limit)
}
has_resources = true
}
if has_resources {
linux_map['resources'] = resources_map
}
spec_map['linux'] = linux_map
return json.encode_pretty(spec_map)
}
// Convenience method to save JSON to file
pub fn (config CrunConfig) save_to_file(path string) ! {
json_content := config.to_json()!
import freeflowuniverse.herolib.core.pathlib
mut file := pathlib.get_file(path: path, create: true)!
file.write(json_content)!
}