[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