refactor: Rename ContainerFactory to HeroPods
- Rename ContainerFactory struct to HeroPods - Update method names and receiver types accordingly - Adjust imports and internal references
This commit is contained in:
7
lib/virt/heropods/.heroscript
Normal file
7
lib/virt/heropods/.heroscript
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
!!hero_code.generate_client
|
||||
name:''
|
||||
classname:'HeroPods'
|
||||
singleton:0
|
||||
default:1
|
||||
hasconfig:1
|
||||
@@ -15,7 +15,7 @@ pub mut:
|
||||
node ?&builder.Node
|
||||
tmux_pane ?&tmux.Pane
|
||||
crun_config ?&crun.CrunConfig
|
||||
factory &ContainerFactory
|
||||
factory &HeroPods
|
||||
}
|
||||
|
||||
// Struct to parse JSON output of `crun state`
|
||||
|
||||
@@ -24,7 +24,7 @@ pub:
|
||||
reset bool
|
||||
}
|
||||
|
||||
pub fn (mut self ContainerFactory) new(args ContainerNewArgs) !&Container {
|
||||
pub fn (mut self HeroPods) container_new(args ContainerNewArgs) !&Container {
|
||||
if args.name in self.containers && !args.reset {
|
||||
return self.containers[args.name] or { panic('bug: container should exist') }
|
||||
}
|
||||
@@ -88,7 +88,7 @@ pub fn (mut self ContainerFactory) new(args ContainerNewArgs) !&Container {
|
||||
}
|
||||
|
||||
// Create crun configuration using the crun module
|
||||
fn (mut self ContainerFactory) create_crun_config(container_name string, rootfs_path string) !&crun.CrunConfig {
|
||||
fn (mut self HeroPods) create_crun_config(container_name string, rootfs_path string) !&crun.CrunConfig {
|
||||
// Create crun configuration using the factory pattern
|
||||
mut config := crun.new(mut self.crun_configs, name: container_name)!
|
||||
|
||||
@@ -120,7 +120,7 @@ fn (mut self ContainerFactory) create_crun_config(container_name string, rootfs_
|
||||
}
|
||||
|
||||
// Use podman to pull image and extract rootfs
|
||||
fn (self ContainerFactory) podman_pull_and_export(docker_url string, image_name string, rootfs_path string) ! {
|
||||
fn (self HeroPods) podman_pull_and_export(docker_url string, image_name string, rootfs_path string) ! {
|
||||
// Pull image
|
||||
osal.exec(
|
||||
cmd: 'podman pull ${docker_url}'
|
||||
|
||||
@@ -2,10 +2,8 @@ module heropods
|
||||
|
||||
import incubaid.herolib.ui.console
|
||||
import incubaid.herolib.osal.core as osal
|
||||
import incubaid.herolib.core.pathlib
|
||||
import incubaid.herolib.core.texttools
|
||||
import os
|
||||
import json
|
||||
|
||||
@[heap]
|
||||
pub struct ContainerImage {
|
||||
@@ -15,7 +13,7 @@ pub mut:
|
||||
rootfs_path string // path to the extracted rootfs
|
||||
size_mb f64 // size in MB
|
||||
created_at string // creation timestamp
|
||||
factory &ContainerFactory @[skip; str: skip]
|
||||
factory &HeroPods @[skip; str: skip]
|
||||
}
|
||||
|
||||
@[params]
|
||||
@@ -41,7 +39,7 @@ pub mut:
|
||||
}
|
||||
|
||||
// Create new image or get existing
|
||||
pub fn (mut self ContainerFactory) image_new(args ContainerImageArgs) !&ContainerImage {
|
||||
pub fn (mut self HeroPods) image_new(args ContainerImageArgs) !&ContainerImage {
|
||||
mut image_name := texttools.name_fix(args.image_name)
|
||||
rootfs_path := '${self.base_dir}/images/${image_name}/rootfs'
|
||||
|
||||
@@ -138,7 +136,7 @@ fn (mut self ContainerImage) update_metadata() ! {
|
||||
}
|
||||
|
||||
// List all available images
|
||||
pub fn (mut self ContainerFactory) images_list() ![]&ContainerImage {
|
||||
pub fn (mut self HeroPods) images_list() ![]&ContainerImage {
|
||||
mut images := []&ContainerImage{}
|
||||
|
||||
images_base_dir := '${self.base_dir}/images'
|
||||
@@ -194,7 +192,7 @@ pub fn (mut self ContainerImage) export(args ImageExportArgs) ! {
|
||||
}
|
||||
|
||||
// Import image from .tgz file
|
||||
pub fn (mut self ContainerFactory) image_import(args ImageImportArgs) !&ContainerImage {
|
||||
pub fn (mut self HeroPods) image_import(args ImageImportArgs) !&ContainerImage {
|
||||
if !os.exists(args.source_path) {
|
||||
return error('Source file not found: ${args.source_path}')
|
||||
}
|
||||
|
||||
143
lib/virt/heropods/heropods_factory_.v
Normal file
143
lib/virt/heropods/heropods_factory_.v
Normal file
@@ -0,0 +1,143 @@
|
||||
module heropods
|
||||
|
||||
import incubaid.herolib.core.base
|
||||
import incubaid.herolib.core.playbook { PlayBook }
|
||||
import json
|
||||
|
||||
__global (
|
||||
heropods_global map[string]&HeroPods
|
||||
heropods_default string
|
||||
)
|
||||
|
||||
/////////FACTORY
|
||||
|
||||
@[params]
|
||||
pub struct ArgsGet {
|
||||
pub mut:
|
||||
name string = 'default' // name of the heropods
|
||||
fromdb bool // will load from filesystem
|
||||
create bool // default will not create if not exist
|
||||
reset bool // will reset the heropods
|
||||
use_podman bool = true // will use podman for image management
|
||||
}
|
||||
|
||||
pub fn new(args ArgsGet) !&HeroPods {
|
||||
mut obj := HeroPods{
|
||||
name: args.name
|
||||
reset: args.reset
|
||||
use_podman: args.use_podman
|
||||
}
|
||||
set(obj)!
|
||||
return get(name: args.name)!
|
||||
}
|
||||
|
||||
pub fn get(args ArgsGet) !&HeroPods {
|
||||
mut context := base.context()!
|
||||
heropods_default = args.name
|
||||
if args.fromdb || args.name !in heropods_global {
|
||||
mut r := context.redis()!
|
||||
if r.hexists('context:heropods', args.name)! {
|
||||
data := r.hget('context:heropods', args.name)!
|
||||
if data.len == 0 {
|
||||
print_backtrace()
|
||||
return error('HeroPods with name: ${args.name} does not exist, prob bug.')
|
||||
}
|
||||
mut obj := json.decode(HeroPods, data)!
|
||||
set_in_mem(obj)!
|
||||
} else {
|
||||
if args.create {
|
||||
new(args)!
|
||||
} else {
|
||||
print_backtrace()
|
||||
return error("HeroPods with name '${args.name}' does not exist")
|
||||
}
|
||||
}
|
||||
return get(args)! // no longer from db nor create
|
||||
}
|
||||
return heropods_global[args.name] or {
|
||||
print_backtrace()
|
||||
return error('could not get config for heropods with name:${args.name}')
|
||||
}
|
||||
}
|
||||
|
||||
// register the config for the future
|
||||
pub fn set(o HeroPods) ! {
|
||||
mut o2 := set_in_mem(o)!
|
||||
heropods_default = o2.name
|
||||
mut context := base.context()!
|
||||
mut r := context.redis()!
|
||||
r.hset('context:heropods', o2.name, json.encode(o2))!
|
||||
}
|
||||
|
||||
// does the config exists?
|
||||
pub fn exists(args ArgsGet) !bool {
|
||||
mut context := base.context()!
|
||||
mut r := context.redis()!
|
||||
return r.hexists('context:heropods', args.name)!
|
||||
}
|
||||
|
||||
pub fn delete(args ArgsGet) ! {
|
||||
mut context := base.context()!
|
||||
mut r := context.redis()!
|
||||
r.hdel('context:heropods', args.name)!
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct ArgsList {
|
||||
pub mut:
|
||||
fromdb bool // will load from filesystem
|
||||
}
|
||||
|
||||
// if fromdb set: load from filesystem, and not from mem, will also reset what is in mem
|
||||
pub fn list(args ArgsList) ![]&HeroPods {
|
||||
mut res := []&HeroPods{}
|
||||
mut context := base.context()!
|
||||
if args.fromdb {
|
||||
// reset what is in mem
|
||||
heropods_global = map[string]&HeroPods{}
|
||||
heropods_default = ''
|
||||
}
|
||||
if args.fromdb {
|
||||
mut r := context.redis()!
|
||||
mut l := r.hkeys('context:heropods')!
|
||||
|
||||
for name in l {
|
||||
res << get(name: name, fromdb: true)!
|
||||
}
|
||||
return res
|
||||
} else {
|
||||
// load from memory
|
||||
for _, client in heropods_global {
|
||||
res << client
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// only sets in mem, does not set as config
|
||||
fn set_in_mem(o HeroPods) !HeroPods {
|
||||
mut o2 := obj_init(o)!
|
||||
heropods_global[o2.name] = &o2
|
||||
heropods_default = o2.name
|
||||
return o2
|
||||
}
|
||||
|
||||
pub fn play(mut plbook PlayBook) ! {
|
||||
if !plbook.exists(filter: 'heropods.') {
|
||||
return
|
||||
}
|
||||
mut install_actions := plbook.find(filter: 'heropods.configure')!
|
||||
if install_actions.len > 0 {
|
||||
for mut install_action in install_actions {
|
||||
heroscript := install_action.heroscript()
|
||||
mut obj2 := heroscript_loads(heroscript)!
|
||||
set(obj2)!
|
||||
install_action.done = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// switch instance to be used for heropods
|
||||
pub fn switch(name string) {
|
||||
heropods_default = name
|
||||
}
|
||||
@@ -1,39 +1,39 @@
|
||||
module heropods
|
||||
|
||||
import incubaid.herolib.ui.console
|
||||
import incubaid.herolib.data.encoderhero
|
||||
import incubaid.herolib.osal.core as osal
|
||||
import incubaid.herolib.ui.console
|
||||
import incubaid.herolib.virt.crun
|
||||
import os
|
||||
|
||||
pub const version = '0.0.0'
|
||||
const singleton = false
|
||||
const default = true
|
||||
|
||||
// THIS THE THE SOURCE OF THE INFORMATION OF THIS FILE, HERE WE HAVE THE CONFIG OBJECT CONFIGURED AND MODELLED
|
||||
|
||||
@[heap]
|
||||
pub struct ContainerFactory {
|
||||
pub struct HeroPods {
|
||||
pub mut:
|
||||
tmux_session string
|
||||
containers map[string]&Container
|
||||
images map[string]&ContainerImage
|
||||
crun_configs map[string]&crun.CrunConfig
|
||||
base_dir string
|
||||
tmux_session string // tmux session name
|
||||
containers map[string]&Container // name -> container mapping
|
||||
images map[string]&ContainerImage // name -> image mapping
|
||||
crun_configs map[string]&crun.CrunConfig // name -> crun config mapping
|
||||
base_dir string // base directory for all container data
|
||||
reset bool // will reset the heropods
|
||||
use_podman bool = true // will use podman for image management
|
||||
name string // name of the heropods
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct FactoryInitArgs {
|
||||
pub:
|
||||
reset bool
|
||||
use_podman bool = true
|
||||
}
|
||||
// your checking & initialization code if needed
|
||||
fn obj_init(mycfg_ HeroPods) !HeroPods {
|
||||
mut args := mycfg_
|
||||
|
||||
pub fn new(args FactoryInitArgs) !ContainerFactory {
|
||||
mut f := ContainerFactory{}
|
||||
f.init(args)!
|
||||
return f
|
||||
}
|
||||
|
||||
fn (mut self ContainerFactory) init(args FactoryInitArgs) ! {
|
||||
// Ensure base directories exist
|
||||
self.base_dir = os.getenv_opt('CONTAINERS_DIR') or { os.home_dir() + '/.containers' }
|
||||
args.base_dir = os.getenv_opt('CONTAINERS_DIR') or { os.home_dir() + '/.containers' }
|
||||
|
||||
osal.exec(
|
||||
cmd: 'mkdir -p ${self.base_dir}/images ${self.base_dir}/configs ${self.base_dir}/runtime'
|
||||
cmd: 'mkdir -p ${args.base_dir}/images ${args.base_dir}/configs ${args.base_dir}/runtime'
|
||||
stdout: false
|
||||
)!
|
||||
|
||||
@@ -46,21 +46,41 @@ fn (mut self ContainerFactory) init(args FactoryInitArgs) ! {
|
||||
}
|
||||
}
|
||||
|
||||
mut heropods := HeroPods{
|
||||
tmux_session: args.name
|
||||
containers: map[string]&Container{}
|
||||
images: map[string]&ContainerImage{}
|
||||
crun_configs: map[string]&crun.CrunConfig{}
|
||||
base_dir: args.base_dir
|
||||
reset: args.reset
|
||||
use_podman: args.use_podman
|
||||
name: args.name
|
||||
}
|
||||
|
||||
// Clean up any leftover crun state if reset is requested
|
||||
if args.reset {
|
||||
self.cleanup_crun_state()!
|
||||
heropods.cleanup_crun_state()!
|
||||
}
|
||||
|
||||
// Load existing images into cache
|
||||
self.load_existing_images()!
|
||||
heropods.load_existing_images()!
|
||||
|
||||
// Setup default images if not using podman
|
||||
if !args.use_podman {
|
||||
self.setup_default_images(args.reset)!
|
||||
}
|
||||
heropods.setup_default_images(args.reset)!
|
||||
}
|
||||
|
||||
fn (mut self ContainerFactory) setup_default_images(reset bool) ! {
|
||||
return args
|
||||
}
|
||||
|
||||
/////////////NORMALLY NO NEED TO TOUCH
|
||||
|
||||
pub fn heroscript_loads(heroscript string) !HeroPods {
|
||||
mut obj := encoderhero.decode[HeroPods](heroscript)!
|
||||
return obj
|
||||
}
|
||||
|
||||
fn (mut self HeroPods) setup_default_images(reset bool) ! {
|
||||
console.print_header('Setting up default images...')
|
||||
|
||||
default_images := [ContainerImageType.alpine_3_20, .ubuntu_24_04, .ubuntu_25_04]
|
||||
@@ -78,7 +98,7 @@ fn (mut self ContainerFactory) setup_default_images(reset bool) ! {
|
||||
}
|
||||
|
||||
// Load existing images from filesystem into cache
|
||||
fn (mut self ContainerFactory) load_existing_images() ! {
|
||||
fn (mut self HeroPods) load_existing_images() ! {
|
||||
images_base_dir := '${self.base_dir}/containers/images'
|
||||
if !os.is_dir(images_base_dir) {
|
||||
return
|
||||
@@ -106,7 +126,7 @@ fn (mut self ContainerFactory) load_existing_images() ! {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut self ContainerFactory) get(args ContainerNewArgs) !&Container {
|
||||
pub fn (mut self HeroPods) get(args ContainerNewArgs) !&Container {
|
||||
if args.name !in self.containers {
|
||||
return error('Container "${args.name}" does not exist. Use factory.new() to create it first.')
|
||||
}
|
||||
@@ -114,7 +134,7 @@ pub fn (mut self ContainerFactory) get(args ContainerNewArgs) !&Container {
|
||||
}
|
||||
|
||||
// Get image by name
|
||||
pub fn (mut self ContainerFactory) image_get(name string) !&ContainerImage {
|
||||
pub fn (mut self HeroPods) image_get(name string) !&ContainerImage {
|
||||
if name !in self.images {
|
||||
return error('Image "${name}" not found in cache. Try importing or downloading it.')
|
||||
}
|
||||
@@ -122,7 +142,7 @@ pub fn (mut self ContainerFactory) image_get(name string) !&ContainerImage {
|
||||
}
|
||||
|
||||
// List all containers currently managed by crun
|
||||
pub fn (self ContainerFactory) list() ![]Container {
|
||||
pub fn (self HeroPods) list() ![]Container {
|
||||
mut containers := []Container{}
|
||||
result := osal.exec(cmd: 'crun list --format json', stdout: false)!
|
||||
|
||||
@@ -144,7 +164,7 @@ pub fn (self ContainerFactory) list() ![]Container {
|
||||
}
|
||||
|
||||
// Clean up any leftover crun state
|
||||
fn (mut self ContainerFactory) cleanup_crun_state() ! {
|
||||
fn (mut self HeroPods) cleanup_crun_state() ! {
|
||||
console.print_debug('Cleaning up leftover crun state...')
|
||||
crun_root := '${self.base_dir}/runtime'
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
# heropods
|
||||
|
||||
|
||||
|
||||
To get started
|
||||
|
||||
```v
|
||||
|
||||
|
||||
import incubaid.herolib.clients. heropods
|
||||
|
||||
mut client:= heropods.get()!
|
||||
|
||||
client...
|
||||
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
## example heroscript
|
||||
|
||||
|
||||
```hero
|
||||
!!heropods.configure
|
||||
secret: '...'
|
||||
host: 'localhost'
|
||||
port: 8888
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user