[lxc-devel] [patch 2/6] [draft] add variables resolution interface
Andrian Nord
nightnord at gmail.com
Tue Nov 17 23:11:58 UTC 2009
Updated for new git - lxc.h usage removed, missing header protection
added. It's still usable only with config.include patch
This is interface, very similar to confile.c, that aims to provide a set
of predefined variables (mostly, syntax of variables). It could be nice
to have ability of specifying arbitrary variables, in syntax of
var.<custom var name> (there is lxcpath with such syntax, as it's not and
configuration-extracted variable), but it requires to have some kind of
fast lxc_dict, i.e. it needs some hash function.
Disadvantages are that there is need of lxc_conf in every function that
will need variable extraction.
Signed-off-by: Andrian Nord <NightNord at gmail.com>
diff --git a/src/lxc/variables.c b/src/lxc/variables.c
new file mode 100644
index 0000000..5a53d9c
--- /dev/null
+++ b/src/lxc/variables.c
@@ -0,0 +1,218 @@
+/*
+ * lxc: linux Container library
+ *
+ * (C) Copyright IBM Corp. 2007, 2008
+ *
+ * Authors:
+ * Daniel Lezcano <dlezcano at fr.ibm.com>
+ * File by:
+ * Andrian Nord <nightnord at gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include <lxc/log.h>
+#include <lxc/conf.h>
+
+#include "parse.h"
+#include "config.h"
+
+lxc_log_define(lxc_variables, lxc);
+
+static char *resolve_var_lxcpath(const char *, struct lxc_conf *);
+static char *resolve_lxc_name(const char *, struct lxc_conf *);
+static char *resolve_lxc_rootfs(const char *, struct lxc_conf *);
+
+typedef char *(*resolve_cb)(const char *, struct lxc_conf *);
+
+struct map {
+ char *key;
+ resolve_cb cb;
+};
+
+static struct map map[] = {
+ { "var.lxcpath", resolve_var_lxcpath },
+ { "lxc.name", resolve_lxc_name },
+ { "lxc.rootfs", resolve_lxc_rootfs },
+};
+
+static const size_t map_size = sizeof(map)/sizeof(struct map);
+
+static const struct map *getmap(const char* key)
+{
+ int i;
+
+ for (i = 0; i < map_size; i++) {
+ if (strncmp(map[i].key, key, strlen(key)) == 0)
+ return &map[i];
+ }
+
+ return NULL;
+}
+
+static char *resolve_var_lxcpath(const char *key, struct lxc_conf *lxc_conf)
+{
+ char *lxcpath = LXCPATH;
+
+ return lxcpath;
+}
+
+static char *resolve_lxc_name(const char *key, struct lxc_conf *lxc_conf)
+{
+ return lxc_conf->name;
+}
+
+static char *resolve_lxc_rootfs(const char *key, struct lxc_conf *lxc_conf)
+{
+ return lxc_conf->rootfs;
+}
+
+static int lxc_resolve_variable(const char *key, char** value,
+ struct lxc_conf *conf)
+{
+ const struct map *map;
+
+ *value = NULL;
+
+ map = getmap(key);
+
+ if (!map)
+ return -1;
+
+ *value = map->cb(key, conf);
+
+ if (!value)
+ return -1;
+
+ return 0;
+}
+
+int lxc_resolve_variables(const char *string, char **result,
+ struct lxc_conf *lxc_conf)
+{
+ char *buffer;
+ char *var, *tmp, *skipped;
+ char *key, *key_end, *space;
+ char *value;
+
+ int ret = -1;
+
+ buffer = strdup(string);
+
+ if (!buffer) {
+ SYSERROR("failed to allocate memory");
+ goto out;
+ }
+
+ skipped = var = buffer;
+ *result = malloc(sizeof(char));
+
+ if (!*result) {
+ SYSERROR("failed to allocate memory for single character 0o");
+ goto fail;
+ }
+
+ **result = '\0';
+
+ while ((var = strstr(var, "$"))) {
+ if (var != buffer && *(var-1) == '\\') {
+ var++;
+
+ continue;
+ }
+
+ *var = '\0';
+ key = var + 1;
+ key_end = NULL;
+
+ if (*key == '{') {
+ key_end = strchr(key + 1, '}');
+
+ if (!key_end) {
+ ERROR("no closing '}' in '%s'", key);
+ goto fail;
+ }
+
+ *key = '\0';
+ *key_end = '\0';
+ key++;
+
+ space = "";
+ } else {
+ key_end = key + lxc_char_next_space(key, strlen(key));
+
+ if ( *key_end == ' ' )
+ space = " ";
+ else if ( *key_end == '\t' )
+ space = "\t";
+ else
+ space = "";
+
+ *key_end = '\0';
+ }
+
+ if (lxc_resolve_variable(key, &value, lxc_conf)) {
+ ERROR("variable '%s' not found", key);
+ goto fail;
+ }
+
+ if (!key_end) {
+ skipped = value;
+ break;
+ }
+
+ var = key_end + 1;
+
+ if (!asprintf(&tmp, "%s%s%s%s", *result,
+ skipped, value, space)) {
+ SYSERROR("failed to allocate memory");
+ goto fail;
+ }
+
+ free(*result);
+ *result = tmp;
+
+ skipped = var;
+ }
+
+ if (skipped != buffer) {
+ if (!asprintf(&tmp, "%s%s", *result, skipped)) {
+ SYSERROR("failed to allocate memory");
+ goto fail;
+ }
+
+ *result = tmp;
+ } else {
+ free(*result);
+
+ *result = buffer;
+
+ return 0;
+ }
+
+ ret = 0;
+
+ goto out;
+
+fail:
+ free(*result);
+out:
+ free(buffer);
+ return ret;
+}
diff --git a/src/lxc/variables.h b/src/lxc/variables.h
new file mode 100644
index 0000000..0e8c450
--- /dev/null
+++ b/src/lxc/variables.h
@@ -0,0 +1,34 @@
+/*
+ * lxc: linux Container library
+ *
+ * (C) Copyright IBM Corp. 2007, 2008
+ *
+ * Authors:
+ * Daniel Lezcano <dlezcano at fr.ibm.com>
+ * File by:
+ * Andrian Nord <NightNord at gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __variables_h
+#define __variables_h
+
+struct lxc_conf;
+
+extern int lxc_resolve_variables(const char* string, char** result,
+ struct lxc_conf *lxc_conf);
+
+#endif
More information about the lxc-devel
mailing list