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 --- libvirt-sandbox/Makefile.am | 2 + libvirt-sandbox/libvirt-sandbox-config-all.h | 1 + libvirt-sandbox/libvirt-sandbox-config-env.c | 199 +++++++++++++++++++++++++++ libvirt-sandbox/libvirt-sandbox-config-env.h | 78 +++++++++++ libvirt-sandbox/libvirt-sandbox-config.c | 187 ++++++++++++++++++++++++- libvirt-sandbox/libvirt-sandbox-config.h | 12 ++ libvirt-sandbox/libvirt-sandbox.h | 1 + libvirt-sandbox/libvirt-sandbox.sym | 6 + 8 files changed, 485 insertions(+), 1 deletion(-) create mode 100644 libvirt-sandbox/libvirt-sandbox-config-env.c create mode 100644 libvirt-sandbox/libvirt-sandbox-config-env.h diff --git a/libvirt-sandbox/Makefile.am b/libvirt-sandbox/Makefile.am index 597803e..5383b0d 100644 --- a/libvirt-sandbox/Makefile.am +++ b/libvirt-sandbox/Makefile.am @@ -53,6 +53,7 @@ SANDBOX_RPC_FILES = \ SANDBOX_CONFIG_HEADER_FILES = \ libvirt-sandbox-config.h \ libvirt-sandbox-config-disk.h \ + libvirt-sandbox-config-env.h \ libvirt-sandbox-config-network.h \ libvirt-sandbox-config-network-address.h \ libvirt-sandbox-config-network-filterref-parameter.h \ @@ -92,6 +93,7 @@ SANDBOX_CONFIG_SOURCE_FILES = \ libvirt-sandbox-util.c \ libvirt-sandbox-config.c \ libvirt-sandbox-config-disk.c \ + libvirt-sandbox-config-env.c \ libvirt-sandbox-config-network.c \ libvirt-sandbox-config-network-address.c \ libvirt-sandbox-config-network-filterref.c \ diff --git a/libvirt-sandbox/libvirt-sandbox-config-all.h b/libvirt-sandbox/libvirt-sandbox-config-all.h index 8cb25c4..756bb3e 100644 --- a/libvirt-sandbox/libvirt-sandbox-config-all.h +++ b/libvirt-sandbox/libvirt-sandbox-config-all.h @@ -32,6 +32,7 @@ /* Local includes */ #include <libvirt-sandbox/libvirt-sandbox-util.h> #include <libvirt-sandbox/libvirt-sandbox-config-disk.h> +#include <libvirt-sandbox/libvirt-sandbox-config-env.h> #include <libvirt-sandbox/libvirt-sandbox-config-mount.h> #include <libvirt-sandbox/libvirt-sandbox-config-mount-file.h> #include <libvirt-sandbox/libvirt-sandbox-config-mount-host-bind.h> diff --git a/libvirt-sandbox/libvirt-sandbox-config-env.c b/libvirt-sandbox/libvirt-sandbox-config-env.c new file mode 100644 index 0000000..eaf0fb2 --- /dev/null +++ b/libvirt-sandbox/libvirt-sandbox-config-env.c @@ -0,0 +1,199 @@ +/* + * libvirt-sandbox-config-env.c: libvirt sandbox configuration + * + * Copyright (C) 2015 Universitat Politècnica de Catalunya. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Author: Eren Yagdiran <erenyagdiran@xxxxxxxxx> + */ + +#include <config.h> +#include <string.h> + +#include "libvirt-sandbox/libvirt-sandbox-config-all.h" + +/** + * SECTION: libvirt-sandbox-config-env + * @short_description: Disk attachment configuration details + * @include: libvirt-sandbox/libvirt-sandbox.h + * @see_aloso: #GVirSandboxConfig + * + * Provides an object to store information about a environment variable in the sandbox + * + */ + +#define GVIR_SANDBOX_CONFIG_ENV_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_SANDBOX_TYPE_CONFIG_ENV, GVirSandboxConfigEnvPrivate)) + + +struct _GVirSandboxConfigEnvPrivate +{ + gchar *key; + gchar *value; +}; + +G_DEFINE_TYPE(GVirSandboxConfigEnv, gvir_sandbox_config_env, G_TYPE_OBJECT); + + +enum { + PROP_0, + PROP_KEY, + PROP_VALUE +}; + +enum { + LAST_SIGNAL +}; + + + +static void gvir_sandbox_config_env_get_property(GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GVirSandboxConfigEnv *config = GVIR_SANDBOX_CONFIG_ENV(object); + GVirSandboxConfigEnvPrivate *priv = config->priv; + + switch (prop_id) { + case PROP_KEY: + g_value_set_string(value, priv->key); + break; + case PROP_VALUE: + g_value_set_string(value, priv->value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + } +} + + +static void gvir_sandbox_config_env_set_property(GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GVirSandboxConfigEnv *config = GVIR_SANDBOX_CONFIG_ENV(object); + GVirSandboxConfigEnvPrivate *priv = config->priv; + + switch (prop_id) { + case PROP_KEY: + g_free(priv->key); + priv->key = g_value_dup_string(value); + break; + case PROP_VALUE: + g_free(priv->value); + priv->value = g_value_dup_string(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + } +} + + +static void gvir_sandbox_config_env_finalize(GObject *object) +{ + GVirSandboxConfigEnv *config = GVIR_SANDBOX_CONFIG_ENV(object); + GVirSandboxConfigEnvPrivate *priv = config->priv; + + g_free(priv->key); + g_free(priv->value); + + G_OBJECT_CLASS(gvir_sandbox_config_env_parent_class)->finalize(object); +} + + +static void gvir_sandbox_config_env_class_init(GVirSandboxConfigEnvClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + + object_class->finalize = gvir_sandbox_config_env_finalize; + object_class->get_property = gvir_sandbox_config_env_get_property; + object_class->set_property = gvir_sandbox_config_env_set_property; + + g_object_class_install_property(object_class, + PROP_KEY, + g_param_spec_string("key", + "Key", + "The sandbox key property", + NULL, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + g_object_class_install_property(object_class, + PROP_VALUE, + g_param_spec_string("value", + "Value", + "The sandbox value property", + NULL, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + g_type_class_add_private(klass, sizeof(GVirSandboxConfigEnvPrivate)); +} + + +static void gvir_sandbox_config_env_init(GVirSandboxConfigEnv *config) +{ + config->priv = GVIR_SANDBOX_CONFIG_ENV_GET_PRIVATE(config); +} + + +/** + * gvir_sandbox_config_env_get_key: + * @config: (transfer none): the sandbox env config + * + * Retrieves the key property for the environment variable + * + * Returns: (transfer none): the key property + */ +const gchar *gvir_sandbox_config_env_get_key(GVirSandboxConfigEnv *config) +{ + GVirSandboxConfigEnvPrivate *priv = config->priv; + return priv->key; +} + + +/** + * gvir_sandbox_config_disk_get_value: + * @config: (transfer none): the sandbox env config + * + * Retrieves the value property for the environment variable + * + * Returns: (transfer none): the value property + */ +const gchar *gvir_sandbox_config_env_get_value(GVirSandboxConfigEnv *config) +{ + GVirSandboxConfigEnvPrivate *priv = config->priv; + return priv->value; +} + +/* + * Local variables: + * c-indent-level: 4 + * c-basic-offset: 4 + * indent-tabs-mode: nil + * tab-width: 8 + * End: + */ diff --git a/libvirt-sandbox/libvirt-sandbox-config-env.h b/libvirt-sandbox/libvirt-sandbox-config-env.h new file mode 100644 index 0000000..1386f10 --- /dev/null +++ b/libvirt-sandbox/libvirt-sandbox-config-env.h @@ -0,0 +1,78 @@ +/* + * libvirt-sandbox-config-env.h: libvirt sandbox configuration + * + * Copyright (C) 2015 Universitat Politècnica de Catalunya. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Author: Eren Yagdiran <erenyagdiran@xxxxxxxxx> + */ + +#if !defined(__LIBVIRT_SANDBOX_H__) && !defined(LIBVIRT_SANDBOX_BUILD) +#error "Only <libvirt-sandbox/libvirt-sandbox.h> can be included directly." +#endif + +#ifndef __LIBVIRT_SANDBOX_CONFIG_ENV_H__ +#define __LIBVIRT_SANDBOX_CONFIG_ENV_H__ + +G_BEGIN_DECLS + +#define GVIR_SANDBOX_TYPE_CONFIG_ENV (gvir_sandbox_config_env_get_type ()) +#define GVIR_SANDBOX_CONFIG_ENV(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GVIR_SANDBOX_TYPE_CONFIG_ENV, GVirSandboxConfigEnv)) +#define GVIR_SANDBOX_CONFIG_ENV_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GVIR_SANDBOX_TYPE_CONFIG_ENV, GVirSandboxConfigEnvClass)) +#define GVIR_SANDBOX_IS_CONFIG_ENV(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GVIR_SANDBOX_TYPE_CONFIG_ENV)) +#define GVIR_SANDBOX_IS_CONFIG_ENV_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GVIR_SANDBOX_TYPE_CONFIG_ENV)) +#define GVIR_SANDBOX_CONFIG_ENV_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GVIR_SANDBOX_TYPE_CONFIG_ENV, GVirSandboxConfigEnvClass)) + +#define GVIR_SANDBOX_TYPE_CONFIG_ENV_HANDLE (gvir_sandbox_config_env_handle_get_type ()) + +typedef struct _GVirSandboxConfigEnv GVirSandboxConfigEnv; +typedef struct _GVirSandboxConfigEnvPrivate GVirSandboxConfigEnvPrivate; +typedef struct _GVirSandboxConfigEnvClass GVirSandboxConfigEnvClass; + +struct _GVirSandboxConfigEnv +{ + GObject parent; + + GVirSandboxConfigEnvPrivate *priv; + + /* Do not add fields to this struct */ +}; + +struct _GVirSandboxConfigEnvClass +{ + GObjectClass parent_class; + + gpointer padding[LIBVIRT_SANDBOX_CLASS_PADDING]; +}; + +GType gvir_sandbox_config_env_get_type(void); + +const gchar *gvir_sandbox_config_env_get_key(GVirSandboxConfigEnv *config); + +const gchar *gvir_sandbox_config_env_get_value(GVirSandboxConfigEnv *config); + +G_END_DECLS + +#endif /* __LIBVIRT_SANDBOX_CONFIG_DISK_H__ */ + +/* + * Local variables: + * c-indent-level: 4 + * c-basic-offset: 4 + * indent-tabs-mode: nil + * tab-width: 8 + * End: + */ diff --git a/libvirt-sandbox/libvirt-sandbox-config.c b/libvirt-sandbox/libvirt-sandbox-config.c index 2506072..980a50b 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; + GList *envs; gchar *secLabel; gboolean secDynamic; @@ -276,6 +277,9 @@ static void gvir_sandbox_config_finalize(GObject *object) g_list_foreach(priv->networks, (GFunc)g_object_unref, NULL); g_list_free(priv->networks); + g_list_foreach(priv->envs, (GFunc)g_object_unref, NULL); + g_list_free(priv->envs); + g_list_foreach(priv->disks, (GFunc)g_object_unref, NULL); g_list_free(priv->disks); @@ -1144,6 +1148,114 @@ gboolean gvir_sandbox_config_has_networks(GVirSandboxConfig *config) return priv->networks ? TRUE : FALSE; } +/** + * gvir_sandbox_config_add_env: + * @config: (transfer none): the sandbox config + * @dsk: (transfer none): the env configuration + * + * Adds a new environment variable to the sandbox + * + */ +void gvir_sandbox_config_add_env(GVirSandboxConfig *config, + GVirSandboxConfigEnv *env) +{ + GVirSandboxConfigPrivate *priv = config->priv; + + g_object_ref(env); + + priv->envs = g_list_append(priv->envs, env); +} + +/** + * gvir_sandbox_config_get_envs: + * @config: (transfer none): the sandbox config + * + * Retrieves the list of custom environment list in the sandbox + * + * Returns: (transfer full) (element-type GVirSandboxConfigMount): the list of environment variables + */ +GList *gvir_sandbox_config_get_envs(GVirSandboxConfig *config) +{ + GVirSandboxConfigPrivate *priv = config->priv; + g_list_foreach(priv->envs, (GFunc)g_object_ref, NULL); + return g_list_copy(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 + * @disk: (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; + GVirSandboxConfigEnv *envConfig; + + 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; + envConfig = GVIR_SANDBOX_CONFIG_ENV(g_object_new(GVIR_SANDBOX_TYPE_CONFIG_ENV, + "key", tmp, + "value", value, + NULL)); + + gvir_sandbox_config_add_env(config, envConfig); + + g_object_unref(envConfig); + g_free(tmp); + return TRUE; +} + +gboolean gvir_sandbox_config_has_envs(GVirSandboxConfig *config) +{ + GVirSandboxConfigPrivate *priv = config->priv; + return priv->envs != NULL; +} /** * gvir_sandbox_config_add_disk: @@ -1163,7 +1275,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 @@ -1949,6 +2060,44 @@ static GVirSandboxConfigMount *gvir_sandbox_config_load_config_mount(GKeyFile *f goto cleanup; } +static GVirSandboxConfigEnv *gvir_sandbox_config_load_config_env(GKeyFile *file, + guint i, + GError **error) +{ + GVirSandboxConfigEnv *config = NULL; + gchar *index = NULL; + gchar *key = NULL; + gchar *value = 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); + return NULL; + } + g_error_free(e); + g_set_error(error, GVIR_SANDBOX_CONFIG_ERROR, 0, + "%s", _("Missing environment key in config file")); + 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")); + goto cleanup; + } + + config = GVIR_SANDBOX_CONFIG_ENV(g_object_new(GVIR_SANDBOX_TYPE_CONFIG_ENV, + "key", key, + "value", value, + NULL)); + + cleanup: + g_free(key); + g_free(value); + g_free(index); + return config; +} static GVirSandboxConfigDisk *gvir_sandbox_config_load_config_disk(GKeyFile *file, guint i, @@ -2244,6 +2393,14 @@ static gboolean gvir_sandbox_config_load_config(GVirSandboxConfig *config, priv->mounts = g_list_append(priv->mounts, mount); } + for (i = 0 ; i < 1024 ; i++) { + GVirSandboxConfigEnv *env; + if (!(env = gvir_sandbox_config_load_config_env(file, i, error)) && + *error) + goto cleanup; + if (env) + priv->envs = g_list_append(priv->envs, env); + } for (i = 0 ; i < 1024 ; i++) { GVirSandboxConfigDisk *disk; @@ -2274,6 +2431,24 @@ static gboolean gvir_sandbox_config_load_config(GVirSandboxConfig *config, return ret; } +static void gvir_sandbox_config_save_config_env(GVirSandboxConfigEnv *config, + GKeyFile *file, + guint i) +{ + gchar *index = NULL; + gchar *key = NULL; + gchar *value = NULL; + + index = g_strdup_printf("env.%u", i); + key = g_strdup(gvir_sandbox_config_env_get_key(config)); + value = g_strdup(gvir_sandbox_config_env_get_value(config)); + 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, @@ -2485,6 +2660,16 @@ static void gvir_sandbox_config_save_config(GVirSandboxConfig *config, } i = 0; + tmp = priv->envs; + while (tmp) { + gvir_sandbox_config_save_config_env(tmp->data, + file, + i); + tmp = tmp->next; + i++; + } + + i = 0; tmp = priv->disks; while (tmp) { gvir_sandbox_config_save_config_disk(tmp->data, diff --git a/libvirt-sandbox/libvirt-sandbox-config.h b/libvirt-sandbox/libvirt-sandbox-config.h index 2c5f0a6..d39bb2b 100644 --- a/libvirt-sandbox/libvirt-sandbox-config.h +++ b/libvirt-sandbox/libvirt-sandbox-config.h @@ -122,6 +122,18 @@ 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, + GVirSandboxConfigEnv *env); +GList *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.h b/libvirt-sandbox/libvirt-sandbox.h index 20dc871..05d7485 100644 --- a/libvirt-sandbox/libvirt-sandbox.h +++ b/libvirt-sandbox/libvirt-sandbox.h @@ -32,6 +32,7 @@ #include <libvirt-sandbox/libvirt-sandbox-util.h> #include <libvirt-sandbox/libvirt-sandbox-enum-types.h> #include <libvirt-sandbox/libvirt-sandbox-config-disk.h> +#include <libvirt-sandbox/libvirt-sandbox-config-env.h> #include <libvirt-sandbox/libvirt-sandbox-config-mount.h> #include <libvirt-sandbox/libvirt-sandbox-config-mount-file.h> #include <libvirt-sandbox/libvirt-sandbox-config-mount-host-bind.h> diff --git a/libvirt-sandbox/libvirt-sandbox.sym b/libvirt-sandbox/libvirt-sandbox.sym index 6f8097a..a09a6c2 100644 --- a/libvirt-sandbox/libvirt-sandbox.sym +++ b/libvirt-sandbox/libvirt-sandbox.sym @@ -26,6 +26,12 @@ LIBVIRT_SANDBOX_0.6.0 { gvir_sandbox_config_disk_get_type; gvir_sandbox_config_has_disks; + 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; + gvir_sandbox_config_mount_add_include; gvir_sandbox_config_mount_get_includes; gvir_sandbox_config_mount_get_target; -- 2.1.0
-- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list