This introduces the concept of "appliance flavour", i.e. a different
appliance whose configuration is based on the main appliance, with
additional packages.
The default appliance (and its configuration) is unchanged.
---
generator/actions.ml | 28 ++++++++++++++++++++++++++++
src/appliance.c | 22 +++++++++++++++++-----
src/guestfs-internal.h | 1 +
src/guestfs.pod | 18 ++++++++++++++++++
src/handle.c | 24 ++++++++++++++++++++++++
5 files changed, 88 insertions(+), 5 deletions(-)
diff --git a/generator/actions.ml b/generator/actions.ml
index eec3b94..e2c7303 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -3279,6 +3279,34 @@ refers to.
This is the same as the C<lstat(2)> system call." };
+ { defaults with
+ name = "set_flavour";
+ style = RErr, [String "flavour"], [];
+ fish_alias = ["flavour"]; config_only = true;
+ blocking = false;
+ shortdesc = "set the appliance flavour";
+ longdesc = "\
+Sets a different flavour for the libguestfs appliance.
+
+A flavour is a different appliance than the main one, usually
+with more packages to provide more features.
+
+See L<guestfs(3)/APPLIANCE FLAVOUR>." };
+
+ { defaults with
+ name = "get_flavour";
+ style = RString "flavour", [], [];
+ blocking = false;
+ tests = [
+ InitNone, Always, TestRun (
+ [["get_flavour"]]), []
+ ];
+ shortdesc = "get the appliance flavour";
+ longdesc = "\
+Returns the current flavour for the libguestfs appliance.
+
+See L<guestfs(3)/APPLIANCE FLAVOUR>." };
+
]
(* daemon_functions are any functions which cause some action
diff --git a/src/appliance.c b/src/appliance.c
index d7aa6b1..956cd88 100644
--- a/src/appliance.c
+++ b/src/appliance.c
@@ -52,7 +52,7 @@ static int contains_old_style_appliance (guestfs_h *g, const char *path,
void *d
static int contains_fixed_appliance (guestfs_h *g, const char *path, void *data);
static int contains_supermin_appliance (guestfs_h *g, const char *path, void *data);
static int build_supermin_appliance (guestfs_h *g, const char *supermin_path, uid_t uid,
char **kernel, char **dtb, char **initrd, char **appliance);
-static int run_supermin_build (guestfs_h *g, const char *lockfile, const char
*appliancedir, const char *supermin_path);
+static int run_supermin_build (guestfs_h *g, const char *flavour, const char *lockfile,
const char *appliancedir, const char *supermin_path);
/* Locate or build the appliance.
*
@@ -221,19 +221,27 @@ build_supermin_appliance (guestfs_h *g,
char **initrd, char **appliance)
{
CLEANUP_FREE char *tmpdir = guestfs_get_cachedir (g);
+ CLEANUP_FREE char *flavour = guestfs_get_flavour (g);
struct stat statbuf;
size_t len;
+ size_t flavourlen;
/* len must be longer than the length of any pathname we can
* generate in this function.
*/
- len = strlen (tmpdir) + 128;
+ flavourlen = strlen (flavour);
+ char flavoursuffix[1 + flavourlen + 1];
+ if (flavourlen > 0)
+ snprintf (flavoursuffix, sizeof flavoursuffix, "-%s", flavour);
+ else
+ flavoursuffix[0] = '\0';
+ len = strlen (tmpdir) + 128 + sizeof flavoursuffix;
char cachedir[len];
snprintf (cachedir, len, "%s/.guestfs-%d", tmpdir, uid);
char lockfile[len];
- snprintf (lockfile, len, "%s/lock", cachedir);
+ snprintf (lockfile, len, "%s/lock%s", cachedir, flavoursuffix);
char appliancedir[len];
- snprintf (appliancedir, len, "%s/appliance.d", cachedir);
+ snprintf (appliancedir, len, "%s/appliance%s.d", cachedir, flavoursuffix);
ignore_value (mkdir (cachedir, 0755));
ignore_value (chmod (cachedir, 0755)); /* RHBZ#921292 */
@@ -267,7 +275,8 @@ build_supermin_appliance (guestfs_h *g,
if (g->verbose)
guestfs___print_timestamped_message (g, "run supermin");
- if (run_supermin_build (g, lockfile, appliancedir, supermin_path) == -1)
+ if (run_supermin_build (g, flavour, lockfile, appliancedir,
+ supermin_path) == -1)
return -1;
if (g->verbose)
@@ -319,6 +328,7 @@ build_supermin_appliance (guestfs_h *g,
*/
static int
run_supermin_build (guestfs_h *g,
+ const char *flavour,
const char *lockfile,
const char *appliancedir,
const char *supermin_path)
@@ -358,6 +368,8 @@ run_supermin_build (guestfs_h *g,
guestfs___cmd_add_arg (cmd, DTB_WILDCARD);
#endif
guestfs___cmd_add_arg_format (cmd, "%s/supermin.d", supermin_path);
+ if (strlen (flavour) > 0)
+ guestfs___cmd_add_arg_format (cmd, "%s/supermin-%s.d", supermin_path,
flavour);
guestfs___cmd_add_arg (cmd, "-o");
guestfs___cmd_add_arg (cmd, appliancedir);
diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h
index fd0c4a1..9dd62b9 100644
--- a/src/guestfs-internal.h
+++ b/src/guestfs-internal.h
@@ -376,6 +376,7 @@ struct guestfs_h
char *path; /* Path to the appliance. */
char *hv; /* Hypervisor (HV) binary. */
char *append; /* Append to kernel command line. */
+ char *flavour; /* Appliance flavour. */
struct hv_param *hv_params; /* Extra hv parameters. */
diff --git a/src/guestfs.pod b/src/guestfs.pod
index e4f9b54..363abd2 100644
--- a/src/guestfs.pod
+++ b/src/guestfs.pod
@@ -1655,6 +1655,18 @@ Linux kernel, then we might remove it from libguestfs too.
=back
+=head2 APPLIANCE FLAVOUR
+
+A flavour is a different appliance for libguestfs, created from the
+main appliance with additional configuration files for extra packages
+in it. A typical usage for them is to provide appliances with more
+packages than the main one, so they can provide more functionalities
+without filling the main appliance.
+
+By default there is no flavour set, which means the main appliance
+is used. A different flavour can be set with L</guestfs_set_flavour>,
+or setting using the C<LIBGUESTFS_FLAVOUR> environment variable.
+
=head2 ABI GUARANTEE
We guarantee the libguestfs ABI (binary interface), for public,
@@ -4682,6 +4694,12 @@ See also L</LIBGUESTFS_TMPDIR>,
L</guestfs_set_cachedir>.
Set C<LIBGUESTFS_DEBUG=1> to enable verbose messages. This
has the same effect as calling C<guestfs_set_verbose (g, 1)>.
+=item LIBGUESTFS_FLAVOUR
+
+Set the appliance flavour used as libguestfs appliance.
+
+See also L</APPLIANCE FLAVOUR> above.
+
=item LIBGUESTFS_HV
Set the default hypervisor (usually qemu) binary that libguestfs uses.
diff --git a/src/handle.c b/src/handle.c
index 0200528..6c4c33e 100644
--- a/src/handle.c
+++ b/src/handle.c
@@ -262,6 +262,12 @@ parse_environment (guestfs_h *g,
return -1;
}
+ str = do_getenv (data, "LIBGUESTFS_FLAVOUR");
+ if (str) {
+ if (guestfs_set_flavour (g, str) == -1)
+ return -1;
+ }
+
return 0;
}
@@ -866,3 +872,21 @@ guestfs__get_smp (guestfs_h *g)
{
return g->smp;
}
+
+int
+guestfs__set_flavour (guestfs_h *g, const char *flavour)
+{
+ free (g->flavour);
+ if (flavour && flavour[0] != '\0')
+ g->flavour = safe_strdup (g, flavour);
+ else
+ g->flavour = NULL;
+
+ return 0;
+}
+
+char *
+guestfs__get_flavour (guestfs_h *g)
+{
+ return safe_strdup (g, g->flavour ? g->flavour : "");
+}
--
1.9.3