[libvirt] [PATCH sandbox v5 16/20] Add config for environment variables

Daniel P. Berrange berrange at redhat.com
Tue Sep 8 16:29:47 UTC 2015


From: Eren Yagdiran <erenyagdiran at 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 at 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




More information about the libvir-list mailing list