From c5c1705cd7379d5c747b78064ad5605ad533432b Mon Sep 17 00:00:00 2001 From: Reyk Floeter Date: Wed, 5 Jun 2019 18:18:49 +0200 Subject: [PATCH] Add support for OpenNebula's userdata START_SCRIPT and START_SCRIPT_BASE64 --- agent/main.c | 20 ++++++++++++++++---- agent/opennebula.c | 22 ++++++++++++++++++---- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/agent/main.c b/agent/main.c index 4632c97..2ac73b1 100644 --- a/agent/main.c +++ b/agent/main.c @@ -49,7 +49,8 @@ static int agent_configure(struct system_config *); static int agent_network(struct system_config *); static void agent_free(struct system_config *); static int agent_pf(struct system_config *, int); -static int agent_userdata(const unsigned char *, size_t); +static int agent_userdata(struct system_config *, + const unsigned char *, size_t); static void agent_unconfigure(void); static char *metadata_parse(char *, size_t, enum strtype); @@ -713,7 +714,7 @@ agent_configure(struct system_config *sc) } if (sc->sc_userdata) { - if (agent_userdata(sc->sc_userdata, + if (agent_userdata(sc, sc->sc_userdata, strlen(sc->sc_userdata)) != 0) log_warnx("user-data failed"); } @@ -737,7 +738,8 @@ agent_configure(struct system_config *sc) } static int -agent_userdata(const unsigned char *userdata, size_t len) +agent_userdata(struct system_config *sc, + const unsigned char *userdata, size_t len) { char *shebang = NULL, *str = NULL, *line = NULL; const char *file; @@ -760,7 +762,7 @@ agent_userdata(const unsigned char *userdata, size_t len) /* Decode user-data and call the function again */ if ((str = calloc(1, len + 1)) == NULL || (len = b64_pton(userdata, str, len)) < 1 || - agent_userdata(str, len) != 0) { + agent_userdata(sc, str, len) != 0) { log_warnx("failed to decode user-data"); goto fail; } @@ -780,6 +782,9 @@ agent_userdata(const unsigned char *userdata, size_t len) goto fail; } + if (sc->sc_dryrun) + goto done; + /* write user-data script into file */ file = "/etc/rc.user-data"; if (fileout(str, "w", file) != 0) { @@ -1212,6 +1217,13 @@ main(int argc, char *const *argv) else ret = openstack(sc); + /* Debug userdata */ + if (sc->sc_dryrun && sc->sc_userdata) { + if (agent_userdata(sc, sc->sc_userdata, + strlen(sc->sc_userdata)) != 0) + log_warnx("user-data failed"); + } + if (sc->sc_stack != NULL) log_debug("%s: %s", __func__, sc->sc_stack); diff --git a/agent/opennebula.c b/agent/opennebula.c index e9da666..8395920 100644 --- a/agent/opennebula.c +++ b/agent/opennebula.c @@ -49,11 +49,11 @@ opennebula(struct system_config *sc) while ((line = fparseln(fp, &len, &lineno, delim, FPARSELN_UNESCALL)) != NULL) { /* key */ - k = line; + k = line + strspn(line, " \t\r"); /* a context always starts with this header */ if (lineno == 1) { - ret = strcmp(line, + ret = strcmp(k, "# Context variables generated by OpenNebula"); if (ret != 0) { log_debug("%s: unsupported context", __func__); @@ -62,7 +62,12 @@ opennebula(struct system_config *sc) free(line); continue; } - line[strcspn(line, "#")] = '\0'; + + /* Strip comments that do not occur within a value */ + if (*k == '#') { + free(line); + continue; + } /* value */ if ((v = strchr(line, '=')) == NULL || *(v + 1) == '\0') { @@ -120,7 +125,9 @@ opennebula(struct system_config *sc) } /* print key/value unless it is a multi-line value */ - if (strcasecmp("SSH_PUBLIC_KEY", k) != 0) + if (strcasecmp("SSH_PUBLIC_KEY", k) != 0 && + strcasecmp("START_SCRIPT", k) != 0 && + strcasecmp("START_SCRIPT_BASE64", k) != 0) log_debug("%s: %s = %s", __func__, k, v); if (strcasecmp("NETWORK", k) == 0) { @@ -224,6 +231,13 @@ opennebula(struct system_config *sc) log_warnx("failed to set ssh pubkey"); v = p + strspn(p, "\n"); } while (*v != '\0'); + } else if (strcasecmp("START_SCRIPT", k) == 0 || + strcasecmp("START_SCRIPT_BASE64", k) == 0) { + log_debug("%s: %s = ...", __func__, k); + + /* We will detect and decode base64 later */ + if ((sc->sc_userdata = strdup(v)) == NULL) + log_warnx("failed to set userdata"); } free(line);