Files
herolib/lib/virt/podman/podman_containers.v
Mahmoud-Emad 1228441fd6 feat: Add Buildah builder API and refactor module
- Introduce `Builder` struct for image creation
- Implement `PodmanFactory` methods for builder lifecycle
- Rename `herocontainers` module to `podman`
- Update `PodmanFactory.new` with platform checks
- Revise documentation for `podman` and Buildah usage
2025-08-26 20:28:38 +03:00

164 lines
4.3 KiB
V

module podman
import freeflowuniverse.herolib.osal.core as osal { exec }
// import freeflowuniverse.herolib.data.ipaddress { IPAddress }
import freeflowuniverse.herolib.core.texttools
import freeflowuniverse.herolib.virt.utils
// import freeflowuniverse.herolib.ui.console
// load all containers, they can be consulted in self.containers
// see obj: Container as result in self.containers
pub fn (mut self PodmanFactory) containers_load() ! {
self.containers = []Container{}
mut ljob := exec(
// we used || because sometimes the command has | in it and this will ruin all subsequent columns
cmd: "podman container list -a --no-trunc --size --format '{{.ID}}||{{.Names}}||{{.ImageID}}||{{.Command}}||{{.CreatedAt}}||{{.Ports}}||{{.State}}||{{.Size}}||{{.Mounts}}||{{.Networks}}||{{.Labels}}'"
ignore_error_codes: [6]
stdout: false
)!
lines := ljob.output.split_into_lines()
for line in lines {
if line.trim_space() == '' {
continue
}
fields := line.split('||').map(utils.clear_str)
if fields.len < 11 {
panic('podman ps needs to output 11 parts.\n${fields}')
}
id := fields[0]
// if image doesn't have id skip this container, maybe ran from filesystme
if fields[2] == '' {
continue
}
mut image := self.image_get(id_full: fields[2])!
mut container := Container{
engine: &self
image: &image
}
container.id = id
container.name = texttools.name_fix(fields[1])
container.command = fields[3]
container.created = utils.parse_time(fields[4])!
container.ports = utils.parse_ports(fields[5])!
container.status = utils.parse_container_state(fields[6])!
container.memsize = utils.parse_size_mb(fields[7])!
container.mounts = utils.parse_mounts(fields[8])!
container.mounts = []
container.networks = utils.parse_networks(fields[9])!
container.labels = utils.parse_labels(fields[10])!
container.ssh_enabled = utils.contains_ssh_port(container.ports)
self.containers << container
}
}
@[params]
pub struct ContainerGetArgs {
pub mut:
name string
id string
image_id string
// tag string
// digest string
}
// get containers from memory
// params:
// name string (can also be a glob self.g. use *,? and [])
// id string
// image_id string
pub fn (mut self PodmanFactory) containers_get(args_ ContainerGetArgs) ![]&Container {
mut args := args_
args.name = texttools.name_fix(args.name)
mut res := []&Container{}
for _, c in self.containers {
if args.name.contains('*') || args.name.contains('?') || args.name.contains('[') {
if c.name.match_glob(args.name) {
res << &c
continue
}
} else {
if c.name == args.name || c.id == args.id {
res << &c
continue
}
}
if args.image_id.len > 0 && c.image.id == args.image_id {
res << &c
}
}
if res.len == 0 {
return ContainerGetError{
args: args
notfound: true
}
}
return res
}
// get container from memory, can use match_glob see https://modules.vlang.io/index.html#string.match_glob
pub fn (mut self PodmanFactory) container_get(args_ ContainerGetArgs) !&Container {
mut args := args_
args.name = texttools.name_fix(args.name)
mut res := self.containers_get(args)!
if res.len > 1 {
return ContainerGetError{
args: args
notfound: true
}
}
return res[0]
}
pub fn (mut self PodmanFactory) container_exists(args ContainerGetArgs) !bool {
self.container_get(args) or {
if err.code() == 1 {
return false
}
return err
}
return true
}
pub fn (mut self PodmanFactory) container_delete(args ContainerGetArgs) ! {
mut c := self.container_get(args)!
c.delete()!
self.load()!
}
// remove one or more container
pub fn (mut self PodmanFactory) containers_delete(args ContainerGetArgs) ! {
mut cs := self.containers_get(args)!
for mut c in cs {
c.delete()!
}
self.load()!
}
pub struct ContainerGetError {
Error
pub:
args ContainerGetArgs
notfound bool
toomany bool
}
pub fn (err ContainerGetError) msg() string {
if err.notfound {
return 'Could not find image with args:\n${err.args}'
}
if err.toomany {
return 'can not get container, Found more than 1 container with args:\n${err.args}'
}
panic('unknown error for ContainerGetError')
}
pub fn (err ContainerGetError) code() int {
if err.notfound {
return 1
}
if err.toomany {
return 2
}
panic('unknown error for ContainerGetError')
}