From: Eren Yagdiran <erenyagdiran(a)gmail.com>
Add the config gobject to store custom environment variables.
This will allow creating custom environment variables on a sandbox
with a parameter formatted like --env key1=val1
Add testcase for custom environment variables
"make check" now includes testcase for environment variables
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
libvirt-sandbox/libvirt-sandbox-config.c | 171 ++++++++++++++++++++++++++++++-
libvirt-sandbox/libvirt-sandbox-config.h | 13 +++
libvirt-sandbox/libvirt-sandbox.sym | 9 ++
libvirt-sandbox/tests/test-config.c | 10 ++
4 files changed, 202 insertions(+), 1 deletion(-)
diff --git a/libvirt-sandbox/libvirt-sandbox-config.c
b/libvirt-sandbox/libvirt-sandbox-config.c
index 2506072..780d174 100644
--- a/libvirt-sandbox/libvirt-sandbox-config.c
+++ b/libvirt-sandbox/libvirt-sandbox-config.c
@@ -64,6 +64,7 @@ struct _GVirSandboxConfigPrivate
GList *networks;
GList *mounts;
GList *disks;
+ GHashTable* envs;
gchar *secLabel;
gboolean secDynamic;
@@ -276,6 +277,8 @@ static void gvir_sandbox_config_finalize(GObject *object)
g_list_foreach(priv->networks, (GFunc)g_object_unref, NULL);
g_list_free(priv->networks);
+ g_hash_table_destroy(priv->envs);
+
g_list_foreach(priv->disks, (GFunc)g_object_unref, NULL);
g_list_free(priv->disks);
@@ -483,6 +486,7 @@ static void gvir_sandbox_config_init(GVirSandboxConfig *config)
priv->arch = g_strdup(uts.machine);
priv->secDynamic = TRUE;
+ priv->envs = g_hash_table_new(g_str_hash, g_str_equal);
priv->uid = geteuid();
priv->gid = getegid();
priv->username = g_strdup(g_get_user_name());
@@ -1144,6 +1148,102 @@ gboolean gvir_sandbox_config_has_networks(GVirSandboxConfig
*config)
return priv->networks ? TRUE : FALSE;
}
+/**
+ * gvir_sandbox_config_add_env:
+ * @config: (transfer none): the sandbox config
+ * @key: (transfer none): the key for environment variable
+ * @value: (transfer none): the value for environment variable
+ *
+ * Adds a new environment variable to the sandbox
+ *
+ */
+void gvir_sandbox_config_add_env(GVirSandboxConfig *config,
+ gchar *k,
+ gchar *v)
+{
+ gchar * key = g_strdup(k);
+ gchar * value = g_strdup(v);
+ GVirSandboxConfigPrivate *priv = config->priv;
+ g_hash_table_insert(priv->envs,key,value);
+}
+
+/**
+ * gvir_sandbox_config_get_envs:
+ * @config: (transfer none): the sandbox config
+ *
+ * Retrieves the hashtable of custom environment variables in the sandbox
+ *
+ * Returns: (transfer full) (element-type gchar gchar): the hashtable of environment
variables
+ */
+GHashTable *gvir_sandbox_config_get_envs(GVirSandboxConfig *config)
+{
+ GVirSandboxConfigPrivate *priv = config->priv;
+ return priv->envs;
+}
+
+/**
+ * gvir_sandbox_config_add_env_strv:
+ * @config: (transfer none): the sandbox config
+ * @envs: (transfer none)(array zero-terminated=1): the list of environment variables
+ *
+ * Parses @envs whose elements are in the format KEY=VALUE
+ *
+ * --env KEY=VALUE
+ */
+gboolean gvir_sandbox_config_add_env_strv(GVirSandboxConfig *config,
+ gchar **envs,
+ GError **error)
+{
+ gsize i = 0;
+ while (envs && envs[i]) {
+ if (!gvir_sandbox_config_add_env_opts(config,
+ envs[i],
+ error))
+ return FALSE;
+ i++;
+ }
+ return TRUE;
+}
+
+/**
+ * gvir_sandbox_config_add_env_opts:
+ * @config: (transfer none): the sandbox config
+ * @env: (transfer none): the env config
+ *
+ * Parses @env in the format KEY=VALUE
+ * creating #GVirSandboxConfigEnv instances for each element. For
+ * example
+ *
+ * --env KEY=VALUE
+ */
+
+gboolean gvir_sandbox_config_add_env_opts(GVirSandboxConfig *config,
+ const char *opt,
+ GError **error)
+{
+ gchar *tmp = NULL;
+ gchar *key = NULL;
+ gchar *value = NULL;
+
+ if (!(tmp = g_strdup(opt)))
+ return FALSE;
+
+ key = strchr(tmp, '=');
+
+ if (!key) {
+ g_set_error(error, GVIR_SANDBOX_CONFIG_ERROR, 0,
+ _("Wrong environment format on %s"), opt);
+ return FALSE;
+ }
+
+ *key = '\0';
+ value = key + 1;
+
+ gvir_sandbox_config_add_env(config, tmp, value);
+
+ g_free(tmp);
+ return TRUE;
+}
/**
* gvir_sandbox_config_add_disk:
@@ -1163,7 +1263,6 @@ void gvir_sandbox_config_add_disk(GVirSandboxConfig *config,
priv->disks = g_list_append(priv->disks, dsk);
}
-
/**
* gvir_sandbox_config_get_disks:
* @config: (transfer none): the sandbox config
@@ -1172,6 +1271,7 @@ void gvir_sandbox_config_add_disk(GVirSandboxConfig *config,
*
* Returns: (transfer full) (element-type GVirSandboxConfigMount): the list of disks
*/
+
GList *gvir_sandbox_config_get_disks(GVirSandboxConfig *config)
{
GVirSandboxConfigPrivate *priv = config->priv;
@@ -1949,6 +2049,39 @@ static GVirSandboxConfigMount
*gvir_sandbox_config_load_config_mount(GKeyFile *f
goto cleanup;
}
+static gboolean gvir_sandbox_config_load_config_env(GKeyFile *file,
+ guint i,
+ GError **error,
+ gchar **key,
+ gchar **value)
+{
+ gboolean ret = TRUE;
+ gchar *index = NULL;
+ GError *e = NULL;
+ index = g_strdup_printf("env.%u", i);
+ if ((*key = g_key_file_get_string(file, index, "key", &e)) == NULL) {
+ if (e->code == G_KEY_FILE_ERROR_GROUP_NOT_FOUND) {
+ g_error_free(e);
+ ret = FALSE;
+ goto cleanup;
+ }
+ g_error_free(e);
+ g_set_error(error, GVIR_SANDBOX_CONFIG_ERROR, 0,
+ "%s", _("Missing environment key in config
file"));
+ ret = FALSE;
+ goto cleanup;
+ }
+ if ((*value = g_key_file_get_string(file, index, "value", NULL)) == NULL)
{
+ g_set_error(error, GVIR_SANDBOX_CONFIG_ERROR, 0,
+ "%s", _("Missing environment value in config
file"));
+ ret = FALSE;
+ goto cleanup;
+ }
+
+ cleanup:
+ g_free(index);
+ return ret;
+}
static GVirSandboxConfigDisk *gvir_sandbox_config_load_config_disk(GKeyFile *file,
guint i,
@@ -2244,6 +2377,19 @@ static gboolean gvir_sandbox_config_load_config(GVirSandboxConfig
*config,
priv->mounts = g_list_append(priv->mounts, mount);
}
+ for (i = 0 ; i < 1024; i++) {
+ gchar *key = NULL;
+ gchar *value = NULL;
+ if (!(gvir_sandbox_config_load_config_env(file, i, error,&key,&value))
&& *error){
+ g_free(key);
+ g_free(value);
+ ret = FALSE;
+ goto cleanup;
+ }
+ if (key){
+ g_hash_table_insert(priv->envs,key,value);
+ }
+ }
for (i = 0 ; i < 1024 ; i++) {
GVirSandboxConfigDisk *disk;
@@ -2274,6 +2420,19 @@ static gboolean gvir_sandbox_config_load_config(GVirSandboxConfig
*config,
return ret;
}
+static void gvir_sandbox_config_save_config_env(gchar *key,
+ gchar *value,
+ GKeyFile *file,
+ guint i)
+{
+ gchar *index = NULL;
+ index = g_strdup_printf("env.%u", i);
+ g_key_file_set_string(file, index, "key",key);
+ g_key_file_set_string(file, index, "value",value);
+ g_free(index);
+ g_free(key);
+ g_free(value);
+}
static void gvir_sandbox_config_save_config_disk(GVirSandboxConfigDisk *config,
GKeyFile *file,
@@ -2484,6 +2643,16 @@ static void gvir_sandbox_config_save_config(GVirSandboxConfig
*config,
i++;
}
+
+ GHashTableIter iter;
+ gpointer key, value;
+ i = 0;
+ g_hash_table_iter_init (&iter, priv->envs);
+ while (g_hash_table_iter_next (&iter, &key, &value)){
+ gvir_sandbox_config_save_config_env(key,value,file,i);
+ i++;
+ }
+
i = 0;
tmp = priv->disks;
while (tmp) {
diff --git a/libvirt-sandbox/libvirt-sandbox-config.h
b/libvirt-sandbox/libvirt-sandbox-config.h
index 2c5f0a6..e5e53f7 100644
--- a/libvirt-sandbox/libvirt-sandbox-config.h
+++ b/libvirt-sandbox/libvirt-sandbox-config.h
@@ -122,6 +122,19 @@ gboolean gvir_sandbox_config_add_network_strv(GVirSandboxConfig
*config,
GError **error);
gboolean gvir_sandbox_config_has_networks(GVirSandboxConfig *config);
+void gvir_sandbox_config_add_env(GVirSandboxConfig *config,
+ gchar *key,
+ gchar *value);
+GHashTable *gvir_sandbox_config_get_envs(GVirSandboxConfig *config);
+gboolean gvir_sandbox_config_add_env_strv(GVirSandboxConfig *config,
+ gchar **envs,
+ GError **error);
+gboolean gvir_sandbox_config_add_env_opts(GVirSandboxConfig *config,
+ const char *env,
+ GError **error);
+gboolean gvir_sandbox_config_has_envs(GVirSandboxConfig *config);
+
+
void gvir_sandbox_config_add_disk(GVirSandboxConfig *config,
GVirSandboxConfigDisk *dsk);
GList *gvir_sandbox_config_get_disks(GVirSandboxConfig *config);
diff --git a/libvirt-sandbox/libvirt-sandbox.sym b/libvirt-sandbox/libvirt-sandbox.sym
index 6f8097a..b7c5921 100644
--- a/libvirt-sandbox/libvirt-sandbox.sym
+++ b/libvirt-sandbox/libvirt-sandbox.sym
@@ -217,3 +217,12 @@ LIBVIRT_SANDBOX_0.6.0 {
local:
*;
};
+
+LIBVIRT_SANDBOX_0.6.1 {
+ global:
+ gvir_sandbox_config_add_env;
+ gvir_sandbox_config_add_env_strv;
+ gvir_sandbox_config_add_env_opts;
+ gvir_sandbox_config_env_get_type;
+ gvir_sandbox_config_has_envs;
+} LIBVIRT_SANDBOX_0.6.0;
diff --git a/libvirt-sandbox/tests/test-config.c b/libvirt-sandbox/tests/test-config.c
index da05187..ac10bab 100644
--- a/libvirt-sandbox/tests/test-config.c
+++ b/libvirt-sandbox/tests/test-config.c
@@ -58,6 +58,13 @@ int main(int argc, char **argv)
"host-bind:/tmp=",
NULL
};
+
+ const gchar *envs[] = {
+ "key1=val1",
+ "key2=val2",
+ NULL
+ };
+
const gchar *disks[] = {
"file:dbdata=/tmp/img.blah,format=qcow2",
"file:cache=/tmp/img.qcow2",
@@ -103,6 +110,9 @@ int main(int argc, char **argv)
if (!gvir_sandbox_config_add_mount_strv(cfg1, (gchar**)mounts, &err))
goto cleanup;
+ if (!gvir_sandbox_config_add_env_strv(cfg1, (gchar**)envs, &err))
+ goto cleanup;
+
if (!gvir_sandbox_config_add_disk_strv(cfg1, (gchar**)disks, &err))
goto cleanup;
--
2.4.3