On Tue, 2015-09-08 at 17:29 +0100, Daniel P. Berrange wrote: > From: Eren Yagdiran <erenyagdiran@xxxxxxxxx> > > 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@xxxxxxxxxx> > --- > 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; > ACK -- Cedric -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list