confd: add support for container volumes

This commit adds support for writable container volumes.  A volume, when
compared to a mount, is a writable directory created when the container
starts and is automatically rsync'ed with the underlying directory it
is mounted on on first use.  A mount otoh does not rsync so it results
only in an empty directory inside the container.

The podman/docker mount feature will be used later to bind mount single
files or sharing directories from the host, e.g., /sys/class/leds/ to
one of more containers.

Note: unused volumes are automatically pruned.  Hence, a volume
      currently cannot be moved to another container.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg
2024-02-25 19:49:27 +01:00
parent 414703e851
commit aafa88b648
4 changed files with 74 additions and 15 deletions
+28 -3
View File
@@ -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
+5
View File
@@ -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)
@@ -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;
+14 -11
View File
@@ -183,7 +183,7 @@
<ACTION sym="nav">replace config</ACTION>
</COMMAND>
<COMMAND name="container" help="Manage containers and their images" mode="switch">
<COMMAND name="container" help="Manage containers, images, and volumes" mode="switch">
<COMMAND name="attach" help="Attach to a running container (exec sh)">
<PARAM name="name" ptype="/CONTAINERS" help="Container name" />
<SWITCH name="optional" min="0">
@@ -327,23 +327,26 @@
</COMMAND>
<COMMAND name="container" help="Show container status">
<ACTION sym="script">podman ps</ACTION>
<ACTION sym="script">container show</ACTION>
<SWITCH name="optional" min="0">
<COMMAND name="images" help="Show container images">
<ACTION sym="script">podman images</ACTION>
<SWITCH name="optional" min="0">
<COMMAND name="all" help="All images (default hides intermediate imaages)">
<ACTION sym="script">podman images -a</ACTION>
</COMMAND>
</SWITCH>
</COMMAND>
<COMMAND name="all" help="Show all containers (default only running)">
<ACTION sym="script">podman ps -a</ACTION>
<ACTION sym="script">container -a show</ACTION>
</COMMAND>
<COMMAND name="log" help="Show container log (alias for show log container)">
<ACTION sym="script">cat /log/container</ACTION>
</COMMAND>
<COMMAND name="images" help="Show container images">
<ACTION sym="script">container show images</ACTION>
<SWITCH name="optional" min="0">
<COMMAND name="all" help="All images (default hides intermediate imaages)">
<ACTION sym="script">container -a show images</ACTION>
</COMMAND>
</SWITCH>
</COMMAND>
<COMMAND name="volumes" help="Show container volumes">
<ACTION sym="script">container show volumes</ACTION>
</COMMAND>
</SWITCH>
</COMMAND>