diff --git a/board/common/rootfs/usr/sbin/container b/board/common/rootfs/usr/sbin/container
index 4dc4a06d..12c836b0 100755
--- a/board/common/rootfs/usr/sbin/container
+++ b/board/common/rootfs/usr/sbin/container
@@ -43,10 +43,10 @@ create()
fi
# --syslog --log-level info
- log "Calling \"podman create --name $name --conmon-pidfile=$pidfn $ro $hostname $entrypoint $env $network $port $args $image $*\""
+ log "Calling \"podman create --name $name --conmon-pidfile=$pidfn $ro $vol $hostname $entrypoint $env $network $port $args $image $*\""
set -x
# shellcheck disable=SC2048
- if podman create --name "$name" --conmon-pidfile="$pidfn" $ro $hostname $entrypoint $env $network $port $args "$image" $*; then
+ if podman create --name "$name" --conmon-pidfile="$pidfn" $ro $vol $hostname $entrypoint $env $network $port $args "$image" $*; then
log "Successfully created container $name from $image"
rm -f "/run/containers/env/${name}.env"
initctl show "container:$name" |grep -q manual:yes || initctl -bq start "container:$name"
@@ -93,6 +93,7 @@ options:
Syntax: [[ip:][hostPort]:]containerPort[/protocol]
--read-only Do not create a writable layer
-s, --simple Show output in simplified format
+ -v, --volume NAME:PATH Create named volume mounted inside container on PATH
commands:
create NAME IMAGE NET Create container NAME using IMAGE with networks NET
@@ -102,9 +103,10 @@ commands:
remove IMAGE Remove an (unused) container image
restart NAME Restart a crashed container
run NAME CMD Execute a command (interactively) in container
- show [image] Show containers or container images
+ show [image | volume] Show containers, images, or volumes
start NAME Start a container
stop NAME Stop a container
+ volume [prune] Prune unused volumes
EOF
}
@@ -153,6 +155,10 @@ while [ "$1" != "" ]; do
-s | --simple)
simple=true
;;
+ -v | --volume)
+ shift
+ vol="$vol -v $1"
+ ;;
*)
break
;;
@@ -214,6 +220,13 @@ case $cmd in
podman images $all
fi
;;
+ volume*)
+ printf "%-20s CONTAINER\n" "VOLUME"
+ for v in $(podman volume ls --format "{{.Name}}"); do
+ printf "%-20s" "$v"
+ podman ps -a --filter volume="$v" --format '{{.Names}}' | sed 's/^/ /'
+ done
+ ;;
*)
if [ -n "$simple" ]; then
podman ps $all --format "{{.ID}} {{.Names}} {{.Image}}" \
@@ -233,6 +246,18 @@ case $cmd in
stop)
initctl -bq stop "container:$1" || podman kill "$1"
;;
+ volume)
+ cmd=$1
+ shift
+ case $cmd in
+ prune)
+ podman $force volume prune
+ ;;
+ *)
+ false
+ ;;
+ esac
+ ;;
*)
usage
exit 1
diff --git a/src/confd/src/infix-containers.c b/src/confd/src/infix-containers.c
index 74172e16..95f8a022 100644
--- a/src/confd/src/infix-containers.c
+++ b/src/confd/src/infix-containers.c
@@ -62,6 +62,9 @@ static int add(const char *name, struct lyd_node *cif)
if (lydx_is_enabled(cif, "read-only"))
fprintf(fp, " --read-only");
+ LYX_LIST_FOR_EACH(lyd_child(cif), node, "volume")
+ fprintf(fp, " -v %s-%s:%s", name, lydx_get_cattr(node, "name"), lydx_get_cattr(node, "dir"));
+
ap = NULL;
LYX_LIST_FOR_EACH(lyd_child(cif), node, "env") {
if (!ap) {
@@ -243,6 +246,8 @@ void infix_containers_launch(void)
if (movefile(next, JOB_QUEUE))
ERRNO("Failed moving %s to job queue %s", next, JOB_QUEUE);
}
+
+ systemf("container -f volume prune");
}
int infix_containers_init(struct confd *confd)
diff --git a/src/confd/yang/infix-containers@2023-12-14.yang b/src/confd/yang/infix-containers@2023-12-14.yang
index c3dc5589..62282d90 100644
--- a/src/confd/yang/infix-containers@2023-12-14.yang
+++ b/src/confd/yang/infix-containers@2023-12-14.yang
@@ -163,10 +163,36 @@ module infix-containers {
}
leaf read-only {
- description "Create a read-only container.";
+ description "Create a read-only container. Use volumes for writable directories.";
type boolean;
}
+ list volume {
+ description "Create a writable volume that survive container upgrades.
+
+ Volumes are retained over the lifetime of a container and survive
+ both upgrading the image as well as configuration changes, which
+ otherwise wipe the default writable layer a container is given.
+
+ Volumes combine well with 'read-only' containers, when you know
+ which files/directories you want to persist.";
+ key name;
+
+ leaf name {
+ description "Single word, [A-Za-z_], to identify this volume.
+ For example, a volume for /etc may be labled etc.
+
+ Note: will be prefixed with container name globally.";
+ type string;
+ }
+
+ leaf dir {
+ description "Directory to mount the volume on inside the container, e.g., /etc";
+ mandatory true;
+ type string;
+ }
+ }
+
container statistics {
description "Statistics of the container";
config false;
diff --git a/src/klish-plugin-infix/xml/infix.xml b/src/klish-plugin-infix/xml/infix.xml
index a1d8384c..c74abe7d 100644
--- a/src/klish-plugin-infix/xml/infix.xml
+++ b/src/klish-plugin-infix/xml/infix.xml
@@ -183,7 +183,7 @@
replace config
-
+
@@ -327,23 +327,26 @@
- podman ps
+ container show
-
- podman images
-
-
- podman images -a
-
-
-
- podman ps -a
+ container -a show
cat /log/container
+
+ container show images
+
+
+ container -a show images
+
+
+
+
+ container show volumes
+