mirror of
https://github.com/kernelkit/infix.git
synced 2026-08-01 21:33:02 +02:00
confd: drop fragile asynchronous container create/delete using execd
This is a complete redesign of how the system creates/deletes containers from the running-config. Containers are now removed synchronously from confd before any interfaces they may be using are removed, and created in parallel, using a Finit task, well after confd has finished setting up interfaces. The logic previously provided by execd to retry container create on any route/address changes, or periodically every 60 seconds, is now handled by a new 'setup' command in the container wrapper script. Additionally, container create is now split in wget/curl/podman pull of the image and 'podman create'. This to both consolidate image fetching and improve user feedback since most of the retry logic (above) revolves around the image download. Fixes #835 Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
@@ -22,7 +22,6 @@
|
||||
|
||||
#define _PATH_CONT "/run/containers"
|
||||
#define _PATH_INBOX _PATH_CONT "/INBOX"
|
||||
#define _PATH_QUEUE _PATH_CONT "/queue"
|
||||
|
||||
|
||||
static int add(const char *name, struct lyd_node *cif)
|
||||
@@ -40,11 +39,15 @@ static int add(const char *name, struct lyd_node *cif)
|
||||
return SR_ERR_SYS;
|
||||
}
|
||||
|
||||
/* Stop any running container gracefully so it releases its IP addresses. */
|
||||
/*
|
||||
* Create /run/containers/<NAME>.sh it is used both for initial
|
||||
* setup at creation/boot and for manual upgrade. The delete
|
||||
* command ensures any already running container is stopped and
|
||||
* deleted so that it releases all claimed resources.
|
||||
*/
|
||||
fprintf(fp, "#!/bin/sh\n"
|
||||
"container --quiet stop %s >/dev/null\n" /* Silence "not running" on upgrade */
|
||||
"container --quiet delete %s >/dev/null\n" /* Silence any hashes when deleting */
|
||||
"container --quiet", name, name);
|
||||
"container --quiet delete %s >/dev/null\n"
|
||||
"container --quiet", name);
|
||||
|
||||
LYX_LIST_FOR_EACH(lyd_child(cif), node, "dns")
|
||||
fprintf(fp, " --dns %s", lyd_get_value(node));
|
||||
@@ -191,55 +194,27 @@ static int add(const char *name, struct lyd_node *cif)
|
||||
fprintf(fp, " %s", string);
|
||||
|
||||
fprintf(fp, "\n");
|
||||
|
||||
if (lydx_is_enabled(cif, "manual"))
|
||||
fprintf(fp, "initctl -bnq cond set container:%s\n", name);
|
||||
|
||||
fchmod(fileno(fp), 0700);
|
||||
fclose(fp);
|
||||
|
||||
/* Enable, or update, container -- both trigger setup script. */
|
||||
systemf("initctl -bnq enable container@%s.conf", name);
|
||||
|
||||
/*
|
||||
* All start scripts must wait for the rest of confd to complete
|
||||
* before being enqueued to execd, so we postpone it using this
|
||||
* "inbox" to the post hook.
|
||||
*/
|
||||
writesf(script, "a", "%s", _PATH_INBOX);
|
||||
systemf("initctl -bnq touch container@%s.conf", name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int del(const char *name)
|
||||
{
|
||||
char fn[strlen(_PATH_QUEUE) + strlen(name) + 10];
|
||||
FILE *fp;
|
||||
char fn[strlen(_PATH_CONT) + strlen(name) + 10];
|
||||
|
||||
/* Remove any pending download/create job first */
|
||||
snprintf(fn, sizeof(fn), "%s/S01-%s.sh", _PATH_QUEUE, name);
|
||||
erase(fn);
|
||||
|
||||
/* Remove container script itself */
|
||||
/* Remove container setup script */
|
||||
snprintf(fn, sizeof(fn), "%s/%s.sh", _PATH_CONT, name);
|
||||
erase(fn);
|
||||
|
||||
/* Disable service and schedule for deletion. */
|
||||
systemf("initctl -bnq disable container@%s.conf", name);
|
||||
|
||||
snprintf(fn, sizeof(fn), "%s/K01-%s.sh", _PATH_CONT, name);
|
||||
fp = fopen(fn, "w");
|
||||
if (!fp) {
|
||||
ERRNO("Failed creating container stop script %s", fn);
|
||||
return SR_ERR_SYS;
|
||||
}
|
||||
|
||||
fprintf(fp, "#!/bin/sh\n"
|
||||
"container delete %s\n", name);
|
||||
fchmod(fileno(fp), 0700);
|
||||
fclose(fp);
|
||||
|
||||
/* Enqueue kill job immediately on execd */
|
||||
movefile(fn, _PATH_QUEUE);
|
||||
/* Stop and schedule for deletion */
|
||||
systemf("initctl -bnq stop container:%s", name);
|
||||
writesf(name, "a", "%s", _PATH_INBOX);
|
||||
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
@@ -364,34 +339,24 @@ static int oci_load(sr_session_ctx_t *session, uint32_t sub_id, const char *xpat
|
||||
*/
|
||||
void infix_containers_post_hook(sr_session_ctx_t *session, struct confd *confd)
|
||||
{
|
||||
char script[256];
|
||||
char name[256];
|
||||
FILE *fp;
|
||||
|
||||
fp = fopen(_PATH_INBOX, "r");
|
||||
if (!fp)
|
||||
return; /* nothing to do today */
|
||||
return; /* nothing to delete */
|
||||
|
||||
while (fgets(script, sizeof(script), fp)) {
|
||||
char link[strlen(_PATH_QUEUE) + strlen(script) + 10];
|
||||
char path[strlen(script) + 10];
|
||||
|
||||
chomp(script);
|
||||
|
||||
/*
|
||||
* Enqueue start job on execd, use a symlink since we
|
||||
* want to be able to reuse the script for manual image
|
||||
* uprgade (and debugging) purposes.
|
||||
*/
|
||||
snprintf(link, sizeof(link), "%s/S01-%s", _PATH_QUEUE, script);
|
||||
snprintf(path, sizeof(path), "../%s", script);
|
||||
if (symlink(path, link) && errno != EEXIST)
|
||||
ERRNO("Creating symlink %s -> %s", link, path);
|
||||
while (fgets(name, sizeof(name), fp)) {
|
||||
chomp(name);
|
||||
systemf("initctl -bnq disable container@%s.conf", name);
|
||||
systemf("container delete %s", name);
|
||||
systemf("initctl -bnq cond clr container:%s", name);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
erase(_PATH_INBOX);
|
||||
|
||||
systemf("initctl -bnq touch execd");
|
||||
systemf("podman volume prune -f");
|
||||
}
|
||||
|
||||
int infix_containers_init(struct confd *confd)
|
||||
|
||||
Reference in New Issue
Block a user