feat: Add run command for Heroscript execution

- Add `cmd_run` to execute heroscripts from files or inline
- Implement file path handling and inline script execution
- Add Linux platform check for HeroPods initialization
- Update documentation to reflect Linux-only requirement
This commit is contained in:
Mahmoud-Emad
2025-11-14 11:20:26 +02:00
parent d3f05c1834
commit fcb5964f8d
5 changed files with 136 additions and 8 deletions

114
lib/core/herocmds/run.v Normal file
View File

@@ -0,0 +1,114 @@
module herocmds
import incubaid.herolib.ui.console
import incubaid.herolib.core.playcmds
import os
import cli { Command, Flag }
pub fn cmd_run(mut cmdroot Command) {
mut cmd_run := Command{
name: 'run'
description: 'Run heroscript from inline string or file'
usage: '
Run HeroScript
USAGE:
hero run [flags] [file]
hero run -s "heroscript content"
EXAMPLES:
# Run from file
hero run script.heroscript
hero run examples/virt/heropods/demo.heroscript
# Run inline heroscript
hero run -s "!!heropods.configure name:\'demo\' reset:false use_podman:true"
# Run multi-line heroscript
hero run -s "
!!heropods.configure
name:\'demo\'
reset:false
use_podman:true
!!heropods.container_new
name:\'demo_container\'
image:\'alpine_3_20\'
"
'
required_args: 0
execute: cmd_run_execute
}
cmd_run.add_flag(Flag{
flag: .string
required: false
name: 'script'
abbrev: 's'
description: 'Inline heroscript to execute'
})
cmd_run.add_flag(Flag{
flag: .bool
required: false
name: 'reset'
abbrev: 'r'
description: 'Reset before running'
})
cmdroot.add_command(cmd_run)
}
fn cmd_run_execute(cmd Command) ! {
mut reset := cmd.flags.get_bool('reset') or { false }
mut inline_script := cmd.flags.get_string('script') or { '' }
// If inline script is provided via -s flag
if inline_script != '' {
console.print_header('Running inline heroscript...')
// Create a temporary file to hold the heroscript
temp_dir := os.temp_dir()
temp_file := '${temp_dir}/hero_inline_${os.getpid()}.heroscript'
// Write the inline script to temp file
os.write_file(temp_file, inline_script) or {
return error('Failed to write temporary heroscript file: ${err}')
}
// Ensure cleanup
defer {
os.rm(temp_file) or {}
}
// Run the heroscript
playcmds.run(heroscript_path: temp_file, reset: reset)!
return
}
// If file path is provided as argument
if cmd.args.len > 0 {
mut path := cmd.args[0]
// Handle "." as current working directory
if path == '.' {
path = os.getwd()
} else {
// Expand home directory
path = path.replace('~', os.home_dir())
// Validate that path exists
if !os.exists(path) {
return error('File does not exist: ${path}')
}
}
console.print_header('Running heroscript from file: ${path}')
playcmds.run(heroscript_path: path, reset: reset)!
return
}
// No script provided
return error('No heroscript provided. Use -s for inline script or provide a file path.\n\n${cmd.help_message()}')
}

View File

@@ -4,6 +4,7 @@ import incubaid.herolib.data.encoderhero
import incubaid.herolib.osal.core as osal
import incubaid.herolib.virt.crun
import incubaid.herolib.core.logger
import incubaid.herolib.core
import os
import sync
@@ -74,6 +75,11 @@ fn obj_init(mycfg_ HeroPods) !HeroPods {
// initialize performs heavy initialization operations
// This should be called after obj_init in the factory pattern
fn (mut self HeroPods) initialize() ! {
// Check platform - HeroPods requires Linux
if core.is_osx()! {
return error('HeroPods requires Linux. It uses Linux-specific tools (ip, iptables, nsenter, crun) that are not available on macOS. Please run HeroPods on a Linux system or use Docker/Podman directly on macOS.')
}
// Create base directories
osal.exec(
cmd: 'mkdir -p ${self.base_dir}/images ${self.base_dir}/configs ${self.base_dir}/runtime'

View File

@@ -2,6 +2,20 @@
HeroPods is a lightweight container management system built on crun (OCI runtime), providing Docker-like functionality with bridge networking, automatic IP allocation, and image management via Podman.
## Requirements
**Platform:** Linux only
HeroPods requires Linux-specific tools and will not work on macOS or Windows:
- `crun` (OCI runtime)
- `ip` (iproute2 package)
- `iptables` (for NAT)
- `nsenter` (for network namespace management)
- `podman` (optional, for image management)
On macOS/Windows, please use Docker or Podman directly instead of HeroPods.
## Quick Start
### Basic Usage
@@ -106,9 +120,3 @@ See `examples/virt/heropods/` for more detailed examples:
- `heropods.vsh` - Complete API demonstration
- `demo.heroscript` - HeroScript usage
- `runcommands.vsh` - Simple command execution
## Requirements
- **crun**: OCI container runtime (auto-installed if missing)
- **podman** (optional): For pulling Docker images
- **Linux**: Bridge networking requires Linux kernel features