diff --git a/0001-Introduce-a-wrapper-around-xmlParseURI.patch b/0001-Introduce-a-wrapper-around-xmlParseURI.patch new file mode 100644 index 0000000..d760b8b --- /dev/null +++ b/0001-Introduce-a-wrapper-around-xmlParseURI.patch @@ -0,0 +1,416 @@ +From 66dbffd38377abeb64144990421e52293613840a Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 15 Feb 2018 15:55:35 +0000 +Subject: [PATCH 1/3] Introduce a wrapper around xmlParseURI. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We only use xmlParseURI to parse our own "homebrew" URIs, for example +the ones used by guestfish --add or virt-v2v. Unfortunately +xmlParseURI cannot handle URIs with spaces or other non-RFC-compliant +characters so simple commands like these fail: + + $ guestfish -a 'ssh://example.com/virtual machine.img' + guestfish: --add: could not parse URI 'ssh://example.com/virtual machine.img' + + $ guestfish -a 'ssh://example.com/バーチャルマシン.img' + guestfish: --add: could not parse URI 'ssh://example.com/バーチャルマシン.img' + +This is a usability problem. However since these are not expected to +be generic RFC-compliant URIs we can perform the required +percent-escaping ourselves instead of demanding that the user does +this. + +Note that the wrapper function should not be used on real URLs or +libvirt URLs. +--- + common/mlxml/Makefile.am | 1 + + common/mlxml/xml-c.c | 45 +++++++++-- + common/mlxml/xml.ml | 1 + + common/mlxml/xml.mli | 4 + + common/options/uri.c | 5 +- + common/utils/Makefile.am | 2 + + common/utils/libxml2-utils.c | 178 +++++++++++++++++++++++++++++++++++++++++++ + common/utils/libxml2-utils.h | 27 +++++++ + 10 files changed, 258 insertions(+), 18 deletions(-) + create mode 100644 common/utils/libxml2-utils.c + create mode 100644 common/utils/libxml2-utils.h + +Index: libguestfs-1.44.2/common/mlxml/Makefile.am +=================================================================== +--- libguestfs-1.44.2.orig/common/mlxml/Makefile.am ++++ libguestfs-1.44.2/common/mlxml/Makefile.am +@@ -54,6 +54,7 @@ libmlxml_a_CPPFLAGS = \ + -I. \ + -I$(top_builddir) \ + -I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \ ++ -I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \ + -I$(shell $(OCAMLC) -where) + libmlxml_a_CFLAGS = \ + $(WARN_CFLAGS) $(WERROR_CFLAGS) \ +Index: libguestfs-1.44.2/common/mlxml/xml-c.c +=================================================================== +--- libguestfs-1.44.2.orig/common/mlxml/xml-c.c ++++ libguestfs-1.44.2/common/mlxml/xml-c.c +@@ -27,17 +27,21 @@ + #include + #include + #include ++#include + + #include + #include + #include + #include + #include ++#include + + #include + #include + #include + ++#include "libxml2-utils.h" ++ + #pragma GCC diagnostic ignored "-Wmissing-prototypes" + + /* Replacement if caml_alloc_initialized_string is missing, added +@@ -438,16 +442,11 @@ mllib_xml_doc_get_root_element (value do + } + } + +-value +-mllib_xml_parse_uri (value strv) ++static value ++Val_uri (xmlURIPtr uri) + { +- CAMLparam1 (strv); ++ CAMLparam0 (); + CAMLlocal3 (rv, sv, ov); +- xmlURIPtr uri; +- +- uri = xmlParseURI (String_val (strv)); +- if (uri == NULL) +- caml_invalid_argument ("parse_uri: unable to parse URI"); + + rv = caml_alloc_tuple (9); + +@@ -526,7 +525,37 @@ mllib_xml_parse_uri (value strv) + else ov = Val_int (0); + Store_field (rv, 8, ov); + ++ CAMLreturn (rv); ++} ++ ++value ++mllib_xml_parse_uri (value strv) ++{ ++ CAMLparam1 (strv); ++ CAMLlocal1 (rv); ++ xmlURIPtr uri; ++ ++ uri = xmlParseURI (String_val (strv)); ++ if (uri == NULL) ++ caml_invalid_argument ("parse_uri: unable to parse URI"); ++ ++ rv = Val_uri (uri); + xmlFreeURI (uri); ++ CAMLreturn (rv); ++} + ++value ++mllib_xml_parse_nonstandard_uri (value strv) ++{ ++ CAMLparam1 (strv); ++ CAMLlocal1 (rv); ++ xmlURIPtr uri; ++ ++ uri = guestfs_int_parse_nonstandard_uri (String_val (strv)); ++ if (uri == NULL) ++ unix_error (errno, (char *) "Xml.parse_uri", strv); ++ ++ rv = Val_uri (uri); ++ xmlFreeURI (uri); + CAMLreturn (rv); + } +Index: libguestfs-1.44.2/common/mlxml/xml.ml +=================================================================== +--- libguestfs-1.44.2.orig/common/mlxml/xml.ml ++++ libguestfs-1.44.2/common/mlxml/xml.ml +@@ -162,3 +162,4 @@ type uri = { + } + + external parse_uri : string -> uri = "mllib_xml_parse_uri" ++external parse_nonstandard_uri : string -> uri = "mllib_xml_parse_nonstandard_uri" +Index: libguestfs-1.44.2/common/mlxml/xml.mli +=================================================================== +--- libguestfs-1.44.2.orig/common/mlxml/xml.mli ++++ libguestfs-1.44.2/common/mlxml/xml.mli +@@ -115,3 +115,7 @@ val parse_uri : string -> uri + Note this is different from the {!URI} module which is specialized + for parsing the [-a] parameter on the command line. This function + exposes the full [xmlParseURI] interface. *) ++ ++val parse_nonstandard_uri : string -> uri ++(** Similar to {!parse_uri} but only for use with our non-standard ++ URIs. See [guestfs_int_parse_nonstandard_uri] in [common/utils]. *) +Index: libguestfs-1.44.2/common/options/uri.c +=================================================================== +--- libguestfs-1.44.2.orig/common/options/uri.c ++++ libguestfs-1.44.2/common/options/uri.c +@@ -38,6 +38,7 @@ + + #include "guestfs.h" + #include "guestfs-utils.h" ++#include "libxml2-utils.h" + #include "uri.h" + + static int is_uri (const char *arg); +@@ -114,9 +115,9 @@ parse (const char *arg, char **path_ret, + CLEANUP_FREE char *socket = NULL; + char *path; + +- uri = xmlParseURI (arg); ++ uri = guestfs_int_parse_nonstandard_uri (arg); + if (!uri) { +- fprintf (stderr, _("%s: --add: could not parse URI ‘%s’\n"), ++ fprintf (stderr, _("%s: --add: could not parse URI ‘%s’: %m\n"), + getprogname (), arg); + return -1; + } +Index: libguestfs-1.44.2/common/utils/Makefile.am +=================================================================== +--- libguestfs-1.44.2.orig/common/utils/Makefile.am ++++ libguestfs-1.44.2/common/utils/Makefile.am +@@ -29,12 +29,15 @@ libutils_la_SOURCES = \ + libxml2-writer-macros.h \ + pcre2-cleanups.c \ + stringlists-utils.c \ ++ libxml2-utils.c \ ++ libxml2-utils.h \ + utils.c + libutils_la_CPPFLAGS = \ + -DGUESTFS_NO_DEPRECATED=1 \ + -DGUESTFS_PRIVATE=1 \ + -I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \ +- -I$(top_srcdir)/lib -I$(top_builddir)/lib ++ -I$(top_srcdir)/lib -I$(top_builddir)/lib \ ++ -I$(top_builddir)/include + libutils_la_CFLAGS = \ + $(WARN_CFLAGS) $(WERROR_CFLAGS) \ + $(GCC_VISIBILITY_HIDDEN) \ +Index: libguestfs-1.44.2/common/utils/libxml2-utils.c +=================================================================== +--- /dev/null ++++ libguestfs-1.44.2/common/utils/libxml2-utils.c +@@ -0,0 +1,178 @@ ++/* libguestfs ++ * Copyright (C) 2017 Red Hat Inc. ++ * ++ * 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 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 ++ */ ++ ++/** ++ * Utility functions using libxml2. ++ * ++ * These functions these I call internal library functions ++ * such as C, C or C, or any C. ++ */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "c-ctype.h" ++ ++/* NB: MUST NOT include "guestfs-internal.h". */ ++#include "guestfs.h" ++#include "guestfs-utils.h" ++#include "libxml2-utils.h" ++ ++static char *local_string_to_utf8 (/* const */ char *input); ++ ++/** ++ * This is a wrapper around C. That function cannot ++ * handle spaces and some non-ASCII characters found in URIs. This ++ * wrapper URI-encodes those before calling C and returns ++ * the URI structure. ++ * ++ * This function should B be called for the URIs that libguestfs ++ * has invented, for things like guestfish I<--add> and virt-v2v. ++ * ++ * For real URIs or libvirt URIs this may cause corruption in corner ++ * cases. (See L ++ * describing some of the complexity involved in dealing with real ++ * URI). ++ * ++ * On error, returns C and sets C appropriately. ++ * ++ * Caller must call C on the returned structure or use the ++ * C cleanup macro. ++ */ ++xmlURIPtr ++guestfs_int_parse_nonstandard_uri (const char *arg) ++{ ++ CLEANUP_FREE char *uri = NULL; ++ CLEANUP_FREE char *escaped_uri = NULL; ++ static const char hexdigit[] = "0123456789abcdef"; ++ size_t i, j, len; ++ xmlURIPtr ret; ++ ++ /* Convert the string to UTF-8. */ ++ uri = local_string_to_utf8 ((char *) arg); ++ if (uri == NULL) ++ return NULL; ++ ++ /* Since we know the URI is in well-formed UTF-8 we can iterate over ++ * the bytes to do the escaping. The output of this will never be ++ * more than 3 times larger (each byte might be rewritten as ‘%XX’). ++ */ ++ len = strlen (uri); ++ escaped_uri = malloc (3*len + 1); ++ if (escaped_uri == NULL) ++ return NULL; ++ ++ for (i = j = 0; i < strlen (uri); ++i) { ++ /* See RFC 3986 appendix A. Note this leaves existing %-encoded ++ * escapes alone. ++ */ ++ if (c_isalnum (uri[i]) || ++ strchr ("%-._~:/?#[]@!$&'()*+,;=", uri[i]) != NULL) ++ escaped_uri[j++] = uri[i]; ++ else { ++ escaped_uri[j++] = '%'; ++ escaped_uri[j++] = hexdigit [(((unsigned char) uri[i]) >> 4) & 0xf]; ++ escaped_uri[j++] = hexdigit [((unsigned char) uri[i]) & 0xf]; ++ } ++ } ++ escaped_uri[j++] = '\0'; ++ ++ /* libxml2 xmlParseURI does not reliably set errno, so it's likely ++ * best to ignore whatever errno is returned and overwrite it with ++ * EINVAL. ++ */ ++ ret = xmlParseURI (escaped_uri); ++ if (ret == NULL) { ++ errno = EINVAL; ++ return NULL; ++ } ++ ++ return ret; ++} ++ ++/* Would be const, but the interface to iconv is not const-correct on ++ * all platforms. The input string is not touched. ++ */ ++static char * ++local_string_to_utf8 (/* const */ char *input) ++{ ++ iconv_t ic; ++ size_t len, inlen, outlen, outalloc, r, prev; ++ int err; ++ char *out, *inp, *outp; ++ ++ /* Convert from input locale to UTF-8. */ ++ ic = iconv_open ("UTF-8", nl_langinfo (CODESET)); ++ if (ic == (iconv_t) -1) ++ return NULL; ++ ++ len = strlen (input); ++ outalloc = len; /* Initial guess. */ ++ ++ again: ++ inlen = len; ++ outlen = outalloc; ++ out = malloc (outlen + 1); ++ if (out == NULL) { ++ err = errno; ++ iconv_close (ic); ++ errno = err; ++ return NULL; ++ } ++ inp = input; ++ outp = out; ++ ++ r = iconv (ic, (char **) &inp, &inlen, &outp, &outlen); ++ if (r == (size_t) -1) { ++ if (errno == E2BIG) { ++ err = errno; ++ prev = outalloc; ++ /* Try again with a larger output buffer. */ ++ free (out); ++ outalloc *= 2; ++ if (outalloc < prev) { ++ iconv_close (ic); ++ errno = err; ++ return NULL; ++ } ++ goto again; ++ } ++ else { ++ /* Else some other conversion failure, eg. EILSEQ, EINVAL. */ ++ err = errno; ++ iconv_close (ic); ++ free (out); ++ errno = err; ++ return NULL; ++ } ++ } ++ ++ *outp = '\0'; ++ iconv_close (ic); ++ ++ return out; ++} +Index: libguestfs-1.44.2/common/utils/libxml2-utils.h +=================================================================== +--- /dev/null ++++ libguestfs-1.44.2/common/utils/libxml2-utils.h +@@ -0,0 +1,27 @@ ++/* libguestfs ++ * Copyright (C) 2017 Red Hat Inc. ++ * ++ * 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 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 ++ */ ++ ++#ifndef GUESTFS_LIBXML2_UTILS_H_ ++#define GUESTFS_LIBXML2_UTILS_H_ ++ ++#include ++ ++/* libxml2-utils.c */ ++extern xmlURIPtr guestfs_int_parse_nonstandard_uri (const char *uri); ++ ++#endif /* GUESTFS_LIBXML2_UTILS_H_ */ diff --git a/0002-common-extract-UTF-8-conversion-function.patch b/0002-common-extract-UTF-8-conversion-function.patch new file mode 100644 index 0000000..d65d21b --- /dev/null +++ b/0002-common-extract-UTF-8-conversion-function.patch @@ -0,0 +1,222 @@ +From 10d1eacdac98575d0d8ce81bc04d74b12bf43cab Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?= +Date: Thu, 15 Feb 2018 17:38:19 +0100 +Subject: [PATCH 2/3] common: extract UTF-8 conversion function + +libxml2-utils.c local_string_to_utf8() function could easily be reused +in other places. This commit extracts it with a new parameter to allow +giving the encoding of the input string and publishes it in +guestfs-utils.h as guestfs_int_string_to_utf8() +--- + common/utils/guestfs-utils.h | 11 +++++++ + common/utils/libxml2-utils.c | 69 +------------------------------------------- + common/utils/utils.c | 64 ++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 76 insertions(+), 68 deletions(-) + +Index: libguestfs-1.43.1/common/utils/guestfs-utils.h +=================================================================== +--- libguestfs-1.43.1.orig/common/utils/guestfs-utils.h ++++ libguestfs-1.43.1/common/utils/guestfs-utils.h +@@ -33,6 +33,7 @@ + #define GUESTFS_UTILS_H_ + + #include ++#include + + #include "guestfs-internal-all.h" + #include "cleanups.h" +@@ -68,6 +69,17 @@ extern int guestfs_int_is_sock (int64_t + extern char *guestfs_int_full_path (const char *dir, const char *name); + extern void guestfs_int_hexdump (const void *data, size_t len, FILE *fp); + ++extern char *guestfs_int_string_to_utf8 (/* const */ char *input, const char *encoding); ++ ++/* Would be const, but the interface to iconv is not const-correct on ++ * all platforms. The input string is not touched. ++ */ ++static inline char * ++guestfs_int_local_string_to_utf8 (/* const */ char *input) ++{ ++ return guestfs_int_string_to_utf8 (input, nl_langinfo (CODESET)); ++} ++ + /* Not all language bindings know how to deal with Pointer arguments. + * Those that don't will use this macro which complains noisily and + * returns NULL. +Index: libguestfs-1.43.1/common/utils/libxml2-utils.c +=================================================================== +--- libguestfs-1.43.1.orig/common/utils/libxml2-utils.c ++++ libguestfs-1.43.1/common/utils/libxml2-utils.c +@@ -30,8 +30,6 @@ + #include + #include + #include +-#include +-#include + + #include + +@@ -42,8 +40,6 @@ + #include "guestfs-utils.h" + #include "libxml2-utils.h" + +-static char *local_string_to_utf8 (/* const */ char *input); +- + /** + * This is a wrapper around C. That function cannot + * handle spaces and some non-ASCII characters found in URIs. This +@@ -73,7 +69,7 @@ guestfs_int_parse_nonstandard_uri (const + xmlURIPtr ret; + + /* Convert the string to UTF-8. */ +- uri = local_string_to_utf8 ((char *) arg); ++ uri = guestfs_int_local_string_to_utf8 ((char *) arg); + if (uri == NULL) + return NULL; + +@@ -113,66 +109,3 @@ guestfs_int_parse_nonstandard_uri (const + + return ret; + } +- +-/* Would be const, but the interface to iconv is not const-correct on +- * all platforms. The input string is not touched. +- */ +-static char * +-local_string_to_utf8 (/* const */ char *input) +-{ +- iconv_t ic; +- size_t len, inlen, outlen, outalloc, r, prev; +- int err; +- char *out, *inp, *outp; +- +- /* Convert from input locale to UTF-8. */ +- ic = iconv_open ("UTF-8", nl_langinfo (CODESET)); +- if (ic == (iconv_t) -1) +- return NULL; +- +- len = strlen (input); +- outalloc = len; /* Initial guess. */ +- +- again: +- inlen = len; +- outlen = outalloc; +- out = malloc (outlen + 1); +- if (out == NULL) { +- err = errno; +- iconv_close (ic); +- errno = err; +- return NULL; +- } +- inp = input; +- outp = out; +- +- r = iconv (ic, (char **) &inp, &inlen, &outp, &outlen); +- if (r == (size_t) -1) { +- if (errno == E2BIG) { +- err = errno; +- prev = outalloc; +- /* Try again with a larger output buffer. */ +- free (out); +- outalloc *= 2; +- if (outalloc < prev) { +- iconv_close (ic); +- errno = err; +- return NULL; +- } +- goto again; +- } +- else { +- /* Else some other conversion failure, eg. EILSEQ, EINVAL. */ +- err = errno; +- iconv_close (ic); +- free (out); +- errno = err; +- return NULL; +- } +- } +- +- *outp = '\0'; +- iconv_close (ic); +- +- return out; +-} +Index: libguestfs-1.43.1/common/utils/utils.c +=================================================================== +--- libguestfs-1.43.1.orig/common/utils/utils.c ++++ libguestfs-1.43.1/common/utils/utils.c +@@ -35,6 +35,7 @@ + #include + #include + #include ++#include + + /* NB: MUST NOT require linking to gnulib, because that will break the + * Python 'sdist' which includes a copy of this file. It's OK to +@@ -640,3 +641,66 @@ guestfs_int_hexdump (const void *data, s + fprintf (fp, "|\n"); + } + } ++ ++/* Would be const, but the interface to iconv is not const-correct on ++ * all platforms. The input string is not touched. ++ */ ++char * ++guestfs_int_string_to_utf8 (/* const */ char *input, const char *encoding) ++{ ++ iconv_t ic; ++ size_t len, inlen, outlen, outalloc, r, prev; ++ int err; ++ char *out, *inp, *outp; ++ ++ /* Convert from input encoding to UTF-8. */ ++ ic = iconv_open ("UTF-8", encoding); ++ if (ic == (iconv_t) -1) ++ return NULL; ++ ++ len = strlen (input); ++ outalloc = len; /* Initial guess. */ ++ ++ again: ++ inlen = len; ++ outlen = outalloc; ++ out = malloc (outlen + 1); ++ if (out == NULL) { ++ err = errno; ++ iconv_close (ic); ++ errno = err; ++ return NULL; ++ } ++ inp = input; ++ outp = out; ++ ++ r = iconv (ic, (char **) &inp, &inlen, &outp, &outlen); ++ if (r == (size_t) -1) { ++ if (errno == E2BIG) { ++ err = errno; ++ prev = outalloc; ++ /* Try again with a larger output buffer. */ ++ free (out); ++ outalloc *= 2; ++ if (outalloc < prev) { ++ iconv_close (ic); ++ errno = err; ++ return NULL; ++ } ++ goto again; ++ } ++ else { ++ /* Else some other conversion failure, eg. EILSEQ, EINVAL. */ ++ err = errno; ++ iconv_close (ic); ++ free (out); ++ errno = err; ++ return NULL; ++ } ++ } ++ ++ *outp = '\0'; ++ iconv_close (ic); ++ ++ return out; ++} diff --git a/0003-inspector-rpm-summary-and-description-may-not-be-utf.patch b/0003-inspector-rpm-summary-and-description-may-not-be-utf.patch new file mode 100644 index 0000000..152f00e --- /dev/null +++ b/0003-inspector-rpm-summary-and-description-may-not-be-utf.patch @@ -0,0 +1,129 @@ +From 2a20ad737e4682b9f304b6c3ba6116f4cc195541 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?= +Date: Wed, 14 Feb 2018 10:21:42 +0100 +Subject: [PATCH 3/3] inspector: rpm summary and description may not be utf-8 + +The application inspection code assumes the data in the RPM database +are encoded in UTF-8. However this is not always the case. + +As a basic workaround, try to parse the string to UTF-8 and if that +fails, try converting it from latin-1. +--- + inspector/expected-fedora.img.xml | 4 ++++ + lib/inspect-apps.c | 30 +++++++++++++++++++++++---- + test-data/phony-guests/fedora-packages.db.txt | 4 ++-- + 3 files changed, 32 insertions(+), 6 deletions(-) + +Index: libguestfs-1.42.0/inspector/expected-fedora.img.xml +=================================================================== +--- libguestfs-1.42.0.orig/inspector/expected-fedora.img.xml ++++ libguestfs-1.42.0/inspector/expected-fedora.img.xml +@@ -34,12 +34,16 @@ + 1.0 + 1.fc14 + x86_64 ++ summary with ö ++ description with ö + + + test2 + 2.0 + 2.fc14 + x86_64 ++ summary with ö ++ description with ö + + + test3 +Index: libguestfs-1.42.0/lib/inspect-apps.c +=================================================================== +--- libguestfs-1.42.0.orig/lib/inspect-apps.c ++++ libguestfs-1.42.0/lib/inspect-apps.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + + #ifdef HAVE_ENDIAN_H + #include +@@ -43,6 +44,7 @@ + #include "guestfs.h" + #include "guestfs-internal.h" + #include "guestfs-internal-actions.h" ++#include "guestfs-utils.h" + #include "structs-cleanups.h" + + /* Some limits on what the inspection code will read, for safety. */ +@@ -266,7 +268,7 @@ get_rpm_header_tag (guestfs_h *g, const + /* This function parses the RPM header structure to pull out various + * tag strings (version, release, arch, etc.). For more detail on the + * header format, see: +- * http://www.rpm.org/max-rpm/s1-rpm-file-format-rpm-file-format.html#S2-RPM-FILE-FORMAT-HEADER ++ * http://rpm.org/devel_doc/file_format.html#24-header-format + */ + + /* The minimum header size that makes sense here is 24 bytes. Four +@@ -316,6 +318,20 @@ struct read_package_data { + struct guestfs_application2_list *apps; + }; + ++static char * ++to_utf8 (guestfs_h *g, char *input) ++{ ++ char *out = NULL; ++ ++ out = guestfs_int_string_to_utf8 (input, "UTF-8"); ++ if (!out) { ++ out = guestfs_int_string_to_utf8 (input, "ISO-8859-1"); ++ perrorf (g, "Not an UTF-8 or latin-1 string: '%s'", input); ++ } ++ ++ return out; ++} ++ + static int + read_package (guestfs_h *g, + const unsigned char *key, size_t keylen, +@@ -326,7 +342,7 @@ read_package (guestfs_h *g, + struct rpm_name nkey, *entry; + CLEANUP_FREE char *version = NULL, *release = NULL, + *epoch_str = NULL, *arch = NULL, *url = NULL, *summary = NULL, +- *description = NULL; ++ *description = NULL, *summary_raw = NULL, *description_raw = NULL; + int32_t epoch; + + /* This function reads one (key, value) pair from the Packages +@@ -357,8 +373,14 @@ read_package (guestfs_h *g, + epoch_str = get_rpm_header_tag (g, value, valuelen, RPMTAG_EPOCH, 'i'); + arch = get_rpm_header_tag (g, value, valuelen, RPMTAG_ARCH, 's'); + url = get_rpm_header_tag (g, value, valuelen, RPMTAG_URL, 's'); +- summary = get_rpm_header_tag (g, value, valuelen, RPMTAG_SUMMARY, 's'); +- description = get_rpm_header_tag (g, value, valuelen, RPMTAG_DESCRIPTION, 's'); ++ summary_raw = get_rpm_header_tag (g, value, valuelen, RPMTAG_SUMMARY, 's'); ++ description_raw = get_rpm_header_tag (g, value, valuelen, RPMTAG_DESCRIPTION, 's'); ++ ++ /* Try (not too hard) to get UTF-8 */ ++ if (summary_raw) ++ summary = to_utf8 (g, summary_raw); ++ if (description_raw) ++ description = to_utf8 (g, description_raw); + + /* The epoch is stored as big-endian integer. */ + if (epoch_str) +Index: libguestfs-1.42.0/test-data/phony-guests/fedora-packages.db.txt +=================================================================== +--- libguestfs-1.42.0.orig/test-data/phony-guests/fedora-packages.db.txt ++++ libguestfs-1.42.0/test-data/phony-guests/fedora-packages.db.txt +@@ -5,9 +5,9 @@ h_nelem=3 + db_pagesize=4096 + HEADER=END + \01\00\00\00 +- \00\00\00\03\00\00\00\11\00\00\03\e9\00\00\00\00\00\00\00\00\00\00\00\00\00\00\03\ea\00\00\00\00\00\00\00\04\00\00\00\00\00\00\03\fe\00\00\00\00\00\00\00\0b\00\00\00\001.0\001.fc14\00x86_64\00 ++ \00\00\00\05\00\00\00\33\00\00\03\e9\00\00\00\00\00\00\00\00\00\00\00\00\00\00\03\ea\00\00\00\00\00\00\00\04\00\00\00\00\00\00\03\fe\00\00\00\00\00\00\00\0b\00\00\00\00\00\00\03\ec\00\00\00\00\00\00\00\12\00\00\00\00\00\00\03\ed\00\00\00\00\00\00\00\21\00\00\00\001.0\001.fc14\00x86_64\00summary with \f6\00description with \f6\00 + \02\00\00\00 +- \00\00\00\03\00\00\00\11\00\00\03\e9\00\00\00\00\00\00\00\00\00\00\00\00\00\00\03\ea\00\00\00\00\00\00\00\04\00\00\00\00\00\00\03\fe\00\00\00\00\00\00\00\0b\00\00\00\002.0\002.fc14\00x86_64\00 ++ \00\00\00\05\00\00\00\35\00\00\03\e9\00\00\00\00\00\00\00\00\00\00\00\00\00\00\03\ea\00\00\00\00\00\00\00\04\00\00\00\00\00\00\03\fe\00\00\00\00\00\00\00\0b\00\00\00\00\00\00\03\ec\00\00\00\00\00\00\00\12\00\00\00\00\00\00\03\ed\00\00\00\00\00\00\00\22\00\00\00\002.0\002.fc14\00x86_64\00summary with \c3\b6\00description with \c3\b6\00 + \03\00\00\00 + \00\00\00\03\00\00\00\11\00\00\03\e9\00\00\00\00\00\00\00\00\00\00\00\00\00\00\03\ea\00\00\00\00\00\00\00\04\00\00\00\00\00\00\03\fe\00\00\00\00\00\00\00\0b\00\00\00\003.0\003.fc14\00x86_64\00 + DATA=END diff --git a/489b14b7-ocaml-examples-Link-examples-to-gnulib.patch b/489b14b7-ocaml-examples-Link-examples-to-gnulib.patch new file mode 100644 index 0000000..ef52a51 --- /dev/null +++ b/489b14b7-ocaml-examples-Link-examples-to-gnulib.patch @@ -0,0 +1,42 @@ +Subject: ocaml/examples: Link examples to gnulib +From: Richard W.M. Jones rjones@redhat.com Sat Sep 11 09:36:08 2021 +0100 +Date: Sat Sep 11 09:36:08 2021 +0100: +Git: 489b14b75e5f30010d8a8c8d3a10ecc52b629563 + +It's unclear why exactly the OCaml library is using replacement +symbols, but it is so we need gnulib. Note this only applies in the +stable-1.44 branch since upstream we have finally got rid of gnulib, +because of exactly these kinds of problems that it causes everyone. + +ocamlfind ocamlopt -cclib -L../../lib/.libs -package unix -linkpkg \ + -warn-error A -I .. mlguestfs.cmxa create_disk.ml -o create_disk +../libmlguestfs.a(libguestfsocaml_a-guestfs-c.o): In function `guestfs_finalize': +/home/rjones/d/libguestfs-1.44/ocaml/guestfs-c.c:86: undefined reference to `rpl_free' +/home/rjones/d/libguestfs-1.44/ocaml/guestfs-c.c:88: undefined reference to `rpl_free' +../libmlguestfs.a(libguestfsocaml_a-guestfs-c.o): In function `guestfs_int_ocaml_set_event_callback': +/home/rjones/d/libguestfs-1.44/ocaml/guestfs-c.c:239: undefined reference to `rpl_free' +../libmlguestfs.a(libguestfsocaml_a-guestfs-c.o): In function `guestfs_int_ocaml_delete_event_callback': +/home/rjones/d/libguestfs-1.44/ocaml/guestfs-c.c:266: undefined reference to `rpl_free' +../libmlguestfs.a(libguestfsocaml_a-guestfs-c.o): In function `guestfs_int_ocaml_event_to_string': +/home/rjones/d/libguestfs-1.44/ocaml/guestfs-c.c:290: undefined reference to `rpl_free' +../libmlguestfs.a(libguestfsocaml_a-guestfs-c-actions.o):/home/rjones/d/libguestfs-1.44/ocaml/guestfs-c-actions.c:1188: more undefined references to `rpl_free' follow +collect2: error: ld returned 1 exit status +File "caml_startup", line 1: +Error: Error during linking +make[2]: *** [Makefile:2272: create_disk] Error 2 + +diff --git a/ocaml/examples/Makefile.am b/ocaml/examples/Makefile.am +index 19cbebdf9..d8c3dd4c5 100644 +--- a/ocaml/examples/Makefile.am ++++ b/ocaml/examples/Makefile.am +@@ -48,7 +48,9 @@ if HAVE_OCAML + + noinst_SCRIPTS = create_disk debug_logging inspect_vm + +-OCAMLFINDFLAGS = -cclib -L$(top_builddir)/lib/.libs ++OCAMLFINDFLAGS = \ ++ -cclib -L$(top_builddir)/lib/.libs \ ++ -cclib -L$(top_builddir)/gnulib/lib/.libs -cclib -lgnu + + if HAVE_OCAMLOPT + create_disk: create_disk.ml diff --git a/63c9cd93-m4-guestfs-ocaml.m4-Fix-deprecated-warning-format.patch b/63c9cd93-m4-guestfs-ocaml.m4-Fix-deprecated-warning-format.patch new file mode 100644 index 0000000..6e64cf1 --- /dev/null +++ b/63c9cd93-m4-guestfs-ocaml.m4-Fix-deprecated-warning-format.patch @@ -0,0 +1,27 @@ +Subject: m4/guestfs-ocaml.m4: Fix deprecated warning format +From: Richard W.M. Jones rjones@redhat.com Tue Oct 5 20:51:19 2021 +0100 +Date: Tue Oct 5 21:08:07 2021 +0100: +Git: 63c9cd933af75ca759fa2f2bbdbb07a699df5b30 + +In OCaml 4.13: + +Alert ocaml_deprecated_cli: Setting a warning with a sequence of lowercase or uppercase letters, +like 'CDEFLMPSUVYZX', is deprecated. +Use the equivalent signed form: +C+D+E+F+L+M+P+S+U+V+Y+Z+X+52-3. + +(cherry picked from +guestfs-tools commit fa4f59e1d99c08d7e0bae2a7cb54f254a6506d67) + +diff --git a/m4/guestfs-ocaml.m4 b/m4/guestfs-ocaml.m4 +index 4b8a44dee..d7f9462ea 100644 +--- a/m4/guestfs-ocaml.m4 ++++ b/m4/guestfs-ocaml.m4 +@@ -232,7 +232,7 @@ EOF + ]) + + dnl Flags we want to pass to every OCaml compiler call. +-OCAML_WARN_ERROR="-warn-error CDEFLMPSUVYZX+52-3" ++OCAML_WARN_ERROR="-warn-error +C+D+E+F+L+M+P+S+U+V+Y+Z+X+52-3" + AC_SUBST([OCAML_WARN_ERROR]) + OCAML_FLAGS="-g -annot $safe_string_option" + AC_SUBST([OCAML_FLAGS]) diff --git a/68a02c2f-customize--resize--sparsify--sysprep-Link-explicitly-with-pthread.patch b/68a02c2f-customize--resize--sparsify--sysprep-Link-explicitly-with-pthread.patch new file mode 100644 index 0000000..75ed180 --- /dev/null +++ b/68a02c2f-customize--resize--sparsify--sysprep-Link-explicitly-with-pthread.patch @@ -0,0 +1,55 @@ +Subject: customize, resize, sparsify, sysprep: Link explicitly with pthread +From: Richard W.M. Jones rjones@redhat.com Thu Mar 4 11:57:44 2021 +0000 +Date: Sat Sep 11 09:42:12 2021 +0100: +Git: 68a02c2f6c7b4243ecb298c0d9539f0fc51a52ce + +Cherry picked from guestfs-tools commit 87543dad61. + +diff --git a/customize/Makefile.am b/customize/Makefile.am +index c926687b3..fb418d7bf 100644 +--- a/customize/Makefile.am ++++ b/customize/Makefile.am +@@ -169,6 +169,7 @@ OCAMLLINKFLAGS = \ + $(LINK_CUSTOM_OCAMLC_ONLY) + + OCAMLCLIBS = \ ++ -pthread -lpthread \ + -lutils \ + $(LIBTINFO_LIBS) \ + $(LIBCRYPT_LIBS) \ +diff --git a/resize/Makefile.am b/resize/Makefile.am +index fa88cc634..936d2b05e 100644 +--- a/resize/Makefile.am ++++ b/resize/Makefile.am +@@ -72,6 +72,7 @@ OCAMLPACKAGES += -package gettext-stub + endif + + OCAMLCLIBS = \ ++ -pthread -lpthread \ + -lprogress \ + -lutils \ + $(LIBTINFO_LIBS) \ +diff --git a/sparsify/Makefile.am b/sparsify/Makefile.am +index fa964e8af..4d1af85d6 100644 +--- a/sparsify/Makefile.am ++++ b/sparsify/Makefile.am +@@ -80,6 +80,7 @@ OCAMLPACKAGES += -package gettext-stub + endif + + OCAMLCLIBS = \ ++ -pthread -lpthread \ + -lprogress \ + -lutils \ + $(LIBTINFO_LIBS) \ +diff --git a/sysprep/Makefile.am b/sysprep/Makefile.am +index 69bb92820..250c74913 100644 +--- a/sysprep/Makefile.am ++++ b/sysprep/Makefile.am +@@ -129,6 +129,7 @@ OCAMLPACKAGES += -package gettext-stub + endif + + OCAMLCLIBS = \ ++ -pthread -lpthread \ + -lvisit \ + -lstructs \ + -lutils \ diff --git a/9db0c98c-appliance-enable-bashs-Process-Substitution-feature.patch b/9db0c98c-appliance-enable-bashs-Process-Substitution-feature.patch new file mode 100644 index 0000000..3d18789 --- /dev/null +++ b/9db0c98c-appliance-enable-bashs-Process-Substitution-feature.patch @@ -0,0 +1,31 @@ +Subject: appliance: enable bash's Process Substitution feature +From: Olaf Hering olaf@aepfle.de Wed Sep 15 12:20:42 2021 +0200 +Date: Wed Sep 15 12:37:08 2021 +0100: +Git: 9db0c98c99090e601d856c6795544f6967e6155f + +bash can read input from a spawned process, and even provide input to +such process. This feature relies on /dev/fd/ being present. In the +past udev silently created this symlink, so this bash feature worked +more or less by accident. With recent systemd versions, such as 246 +which is included in Leap 15.3, the symlink is not created anymore. As +a result scripts, such as /sbin/dhclient-script, fail to work +properly. + +This symlink should have been created in version 1 of this variant of /init. + +https://bugzilla.opensuse.org/show_bug.cgi?id=1190501 + +Signed-off-by: Olaf Hering + +diff --git a/appliance/init b/appliance/init +index b1c4d09ea..cdc39c3b9 100755 +--- a/appliance/init ++++ b/appliance/init +@@ -72,6 +72,7 @@ fi + + # devtmpfs is required since udev 176 + mount -t devtmpfs /dev /dev ++ln -s /proc/self/fd /dev/fd + mkdir -p /dev/pts + mount -t devpts /dev/pts /dev/pts + mkdir -p /dev/shm diff --git a/Pod-Simple-3.23.tar.xz b/Pod-Simple-3.23.tar.xz new file mode 100644 index 0000000..8de92e4 --- /dev/null +++ b/Pod-Simple-3.23.tar.xz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fab3872d3f424cec65995cf5decda99cb04f85aae654b1e199ec659bdbef0ab0 +size 185608 diff --git a/a4930f5f-customize-Suppress-OCaml-warning.patch b/a4930f5f-customize-Suppress-OCaml-warning.patch new file mode 100644 index 0000000..07ff01d --- /dev/null +++ b/a4930f5f-customize-Suppress-OCaml-warning.patch @@ -0,0 +1,23 @@ +Subject: customize: Suppress OCaml warning +From: Richard W.M. Jones rjones@redhat.com Tue Oct 5 20:53:25 2021 +0100 +Date: Tue Oct 5 20:53:25 2021 +0100: +Git: a4930f5fad82e5358d565b8cf3610970e9646259 + +In OCaml 4.13: + +File "perl_edit.ml", line 30, characters 2-13: +30 | c_edit_file (verbose ()) g (Guestfs.c_pointer g) file expr + ^^^^^^^^^^^ +Error (warning 6 [labels-omitted]): label verbose was omitted in the application of this function. + +--- a/m4/guestfs-ocaml.m4 ++++ b/m4/guestfs-ocaml.m4 +@@ -232,7 +232,7 @@ EOF + ]) + + dnl Flags we want to pass to every OCaml compiler call. +-OCAML_WARN_ERROR="-warn-error +C+D+E+F+L+M+P+S+U+V+Y+Z+X+52-3" ++OCAML_WARN_ERROR="-warn-error +C+D+E+F+L+M+P+S+U+V+Y+Z+X+52-3-6" + AC_SUBST([OCAML_WARN_ERROR]) + OCAML_FLAGS="-g -annot $safe_string_option" + AC_SUBST([OCAML_FLAGS]) diff --git a/appliance.patch b/appliance.patch new file mode 100644 index 0000000..dd1a063 --- /dev/null +++ b/appliance.patch @@ -0,0 +1,26 @@ +Index: libguestfs-1.44.2/appliance/init +=================================================================== +--- libguestfs-1.44.2.orig/appliance/init ++++ libguestfs-1.44.2/appliance/init +@@ -122,8 +122,10 @@ if test "$guestfs_network" = 1; then + rm -f /etc/dhcp/dhclient-enter-hooks.d/resolved + if dhclient --version >/dev/null 2>&1; then + dhclient $iface +- else ++ elif dhcpcd --version ; then + dhcpcd $iface ++ elif busybox udhcpc --help ; then ++ busybox udhcpc --quit -v + fi + fi + +@@ -240,7 +242,8 @@ else + echo "Note: The contents of / (root) are the rescue appliance." + if ! test -d "/sysroot/dev"; then + echo "You have to mount the guest’s partitions under /sysroot" +- echo "before you can examine them." ++ echo "before you can examine them. A helper script for that exists:" ++ echo "mount-rootfs-and-chroot.sh /dev/sda2" + else + echo "Use 'cd /sysroot' or 'chroot /sysroot' to see guest filesystems." + fi diff --git a/c0de4de9-appliance-add-reboot-and-netconfig-for-SUSE.patch b/c0de4de9-appliance-add-reboot-and-netconfig-for-SUSE.patch new file mode 100644 index 0000000..9286ab8 --- /dev/null +++ b/c0de4de9-appliance-add-reboot-and-netconfig-for-SUSE.patch @@ -0,0 +1,29 @@ +Subject: appliance: add reboot and netconfig for SUSE +From: Olaf Hering olaf@aepfle.de Tue Sep 14 17:57:43 2021 +0200 +Date: Tue Sep 14 20:49:02 2021 +0100: +Git: c0de4de9029c3e483f738a0f80a2c5066c6532db + +systemd-sysvinit contains the reboot command, which is used to +properly stop the VM. This was required by other packages, and as a +result always available. Since Leap 15.3 it will not be installed, and +as a result the VM will just panic because /init died. + +If the appliance is started with --network, dhclient will run +/usr/sbin/dhclient-script, which in turn may call /sbin/netconfig to +update /etc/resolv.conf. Install sysconfig-netconfig to make sure DNS +resolving actually works. + +Signed-off-by: Olaf Hering + +--- a/appliance/packagelist.in ++++ b/appliance/packagelist.in +@@ -133,7 +133,9 @@ ifelse(SUSE,1, + ntfs-3g + reiserfs + squashfs ++ sysconfig-netconfig + systemd ++ systemd-sysvinit + vim + xz + ) diff --git a/e26cfa44-daemon-Build-with--pthread.patch b/e26cfa44-daemon-Build-with--pthread.patch new file mode 100644 index 0000000..f99cd89 --- /dev/null +++ b/e26cfa44-daemon-Build-with--pthread.patch @@ -0,0 +1,26 @@ +Subject: daemon: Build with -pthread +From: Richard W.M. Jones rjones@redhat.com Sat Sep 11 09:27:17 2021 +0100 +Date: Sat Sep 11 09:27:17 2021 +0100: +Git: e26cfa445a1947503a03c55d8d65263530747062 + +The daemon failed to link with glibc < 2.34 because we didn't include +the separate pthread library. Adding -pthread fixes this. + +Note this change was also make upstream in commit 733d2182b6 ("Remove +the tools.") although I think either by accident or unrelated. + +Reported-by: Toolybird +Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2003326 + +diff --git a/daemon/Makefile.am b/daemon/Makefile.am +index 86aa920e8..b670bb1e2 100644 +--- a/daemon/Makefile.am ++++ b/daemon/Makefile.am +@@ -255,6 +255,7 @@ guestfsd_CPPFLAGS = \ + -I$(top_srcdir)/common/utils \ + -I$(top_builddir)/common/utils + guestfsd_CFLAGS = \ ++ -pthread \ + $(WARN_CFLAGS) $(WERROR_CFLAGS) \ + $(RPC_CFLAGS) \ + $(AUGEAS_CFLAGS) \ diff --git a/f47e0bb6-appliance-reorder-mounting-of-special-filesystems-in-init.patch b/f47e0bb6-appliance-reorder-mounting-of-special-filesystems-in-init.patch new file mode 100644 index 0000000..df21414 --- /dev/null +++ b/f47e0bb6-appliance-reorder-mounting-of-special-filesystems-in-init.patch @@ -0,0 +1,77 @@ +Subject: appliance: reorder mounting of special filesystems in init +From: Olaf Hering olaf@aepfle.de Wed Sep 15 12:58:23 2021 +0200 +Date: Wed Sep 15 12:37:08 2021 +0100: +Git: f47e0bb6725434778384cf79ba3b08610f8c3796 + +Make sure proc and dev are available early. +No change in behavior intended. + +Signed-off-by: Olaf Hering + +diff --git a/appliance/init b/appliance/init +index cdc39c3b9..7076821d2 100755 +--- a/appliance/init ++++ b/appliance/init +@@ -27,12 +27,12 @@ for d in /lib64 /lib; do + fi + done + +-mkdir -p /sysroot +- +-# Mount /proc. +-if [ ! -d /proc ]; then rm -f /proc; fi +-mkdir -p /proc ++mkdir -p /proc /sys + mount -t proc /proc /proc ++mount -t sysfs /sys /sys ++# devtmpfs is required since udev 176 ++mount -t devtmpfs /dev /dev ++ln -s /proc/self/fd /dev/fd + + # Parse the kernel command line early (must be after /proc is mounted). + cmdline=$( # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -14,68 +15,169 @@ # Please submit bugfixes or comments via https://bugs.opensuse.org/ # +# needsbinariesforbuild -Name: libguestfs -Version: 1.46.1 +Version: 1.44.2 Release: 0 -Summary: libguestfs -License: GPL-2.0-or-later -URL: http://libguestfs.org +%{?ocaml_preserve_bytecode} -Source0: %{name}-%{version}.tar.gz -Source1: %{name}-%{version}.tar.gz.sig -Source3: libguestfs.rpmlintrc -Source5: guestfish.sh -Source100: mount-rootfs-and-chroot.sh -Source101: README +%bcond_without ocaml_bindings +%bcond_without lua_bindings +%bcond_without python_bindings +%bcond_without perl_bindings +%bcond_without hivex -# Patches +%bcond_without fuse +%bcond_without ruby_bindings + +%bcond_with p2v + +%bcond_without bash_completion +# The following defines are overridden in the individual subpackages +%define _configure_fuse --disable-fuse +%define _configure_lua --disable-lua +%define _configure_ocaml --disable-ocaml +%define _configure_perl --disable-perl +%define _configure_python --disable-python +%define _configure_ruby --disable-ruby + +# +# use 'env LIBGUESTFS_HV=/path/to/kvm libguestfs-test-tool' to verify +%define kvm_binary /bin/false +%ifarch aarch64 +%define kvm_binary /usr/bin/qemu-system-aarch64 +%endif +%ifarch ppc64le +%define kvm_binary /usr/bin/qemu-system-ppc64 +%endif +%ifarch ppc64 +%define kvm_binary /usr/bin/qemu-system-ppc64 +%endif +%ifarch s390x +%define kvm_binary /usr/bin/qemu-system-s390x +%endif +%ifarch x86_64 +%define kvm_binary /usr/bin/qemu-system-x86_64 +%endif +# +%define guestfs_docdir %{_defaultdocdir}/%{name} +# +Name: libguestfs +%if "%{?_ignore_exclusive_arch}" == "" +ExclusiveArch: x86_64 ppc64 ppc64le s390x aarch64 +%endif +BuildRequires: aaa_base +BuildRequires: attr-devel +BuildRequires: augeas-devel >= 1.0.0 +BuildRequires: autoconf +BuildRequires: automake +%if %{with bash_completion} +BuildRequires: bash-completion >= 2.0 +%if 0%{?suse_version} >= 1330 +BuildRequires: bash-completion-devel >= 2.0 +%endif +%endif BuildRequires: bison BuildRequires: file-devel BuildRequires: flex -BuildRequires: gawk +BuildRequires: gcc BuildRequires: gcc-c++ -BuildRequires: gobject-introspection-devel BuildRequires: gperf +BuildRequires: libacl-devel +BuildRequires: libcap-devel +BuildRequires: libconfig-devel BuildRequires: libtool -BuildRequires: ocaml -BuildRequires: ocaml-hivex-devel -BuildRequires: pkgconf-pkg-config -BuildRequires: po4a -BuildRequires: readline-devel -BuildRequires: supermin >= 5.1.18 -BuildRequires: ocamlfind(findlib) -BuildRequires: perl(Getopt::Long) -BuildRequires: perl(Locale::TextDomain) -BuildRequires: perl(Module::Build) -BuildRequires: perl(Pod::Man) -BuildRequires: perl(Pod::Simple) -BuildRequires: perl(Pod::Usage) -BuildRequires: perl(Test::More) -BuildRequires: pkgconfig(augeas) -BuildRequires: pkgconfig(bash-completion) -BuildRequires: pkgconfig(fuse) -BuildRequires: pkgconfig(hivex) -BuildRequires: pkgconfig(jansson) -BuildRequires: pkgconfig(libacl) -BuildRequires: pkgconfig(libcap) -BuildRequires: pkgconfig(libconfig) -BuildRequires: pkgconfig(liblzma) -BuildRequires: pkgconfig(libpcre2-8) -BuildRequires: pkgconfig(libsystemd) +BuildRequires: libvirt-devel >= 1.2.20 +BuildRequires: libxml2-devel +BuildRequires: ncurses-devel BuildRequires: pkgconfig(libtirpc) -BuildRequires: pkgconfig(libvirt) -BuildRequires: pkgconfig(libxml-2.0) -BuildRequires: pkgconfig(ncurses) +%if %{with perl_bindings} +BuildRequires: perl(Module::Build) +%endif +BuildRequires: db48-utils +BuildRequires: dhcp-client +BuildRequires: libjansson-devel +BuildRequires: pcre2-devel +BuildRequires: pkg-config +BuildRequires: qemu-tools +BuildRequires: readline-devel +BuildRequires: supermin >= 5.1.6 +BuildRequires: pkgconfig(dbus-1) BuildRequires: pkgconfig(python3) -BuildRequires: pkgconfig(rpm) >= 4.6.0 -BuildRequires: pkgconfig(tinfo) +# Required to build tools, its independent from bindings +BuildRequires: glib2-devel +BuildRequires: ocaml >= 4.01 +BuildRequires: ocaml-findlib +BuildRequires: ocaml-gettext-devel +BuildRequires: ocaml-gettext-stub-devel +BuildRequires: ocaml-hivex-devel +BuildRequires: ocaml-libvirt-devel -Requires: supermin >= 5.1.18 -Provides: libguestfs0 = %{version} -Obsoletes: libguestfs0 < %{version} +# +BuildRequires: ocaml-rpm-macros +%if %{with ocaml_bindings} +%define _configure_ocaml --enable-ocaml +%endif +# +%if %{with fuse} +BuildRequires: fuse-devel +%define _configure_fuse --enable-fuse +%endif +# +%if %{with hivex} +BuildRequires: glibc-locale +BuildRequires: hivex +BuildRequires: hivex-devel +%endif +# +%if %{with p2v} +BuildRequires: gtk2-devel +%endif +# +URL: http://libguestfs.org/ +Summary: Compatibility package for guestfs-tools +# Upstream patches +License: GPL-2.0-or-later + +# Upstream +Patch1: e26cfa44-daemon-Build-with--pthread.patch +Patch2: 489b14b7-ocaml-examples-Link-examples-to-gnulib.patch +Patch3: 68a02c2f-customize--resize--sparsify--sysprep-Link-explicitly-with-pthread.patch +Patch4: c0de4de9-appliance-add-reboot-and-netconfig-for-SUSE.patch +Patch5: 9db0c98c-appliance-enable-bashs-Process-Substitution-feature.patch +Patch6: f47e0bb6-appliance-reorder-mounting-of-special-filesystems-in-init.patch +Patch7: 63c9cd93-m4-guestfs-ocaml.m4-Fix-deprecated-warning-format.patch +Patch8: a4930f5f-customize-Suppress-OCaml-warning.patch + +# Pending upstram review +Patch50: 0001-Introduce-a-wrapper-around-xmlParseURI.patch +Patch51: 0002-common-extract-UTF-8-conversion-function.patch +Patch52: 0003-inspector-rpm-summary-and-description-may-not-be-utf.patch +# Our patches +Patch100: appliance.patch +Patch101: netconfig.patch +Patch102: libguestfs.env.patch +Patch103: makefile-ocaml-find-guestfs.patch + +Source0: https://download.libguestfs.org/1.44-stable/libguestfs-%{version}.tar.gz +Source1: https://download.libguestfs.org/1.44-stable/libguestfs-%{version}.tar.gz.sig +Source3: libguestfs.rpmlintrc +Source100: mount-rootfs-and-chroot.sh +Source101: README +Source789653: Pod-Simple-3.23.tar.xz +# +Source10001: libguestfs.test.simple.run-libugestfs-test-tool.sh +Source10002: libguestfs.test.simple.create-opensuse-guest.sh +Source10003: libguestfs.test.simple.create-opensuse-guest-crypt-on-lvm.sh +Source10004: libguestfs.test.simple.create-sles12-guest.sh +Source10005: libguestfs.test.simple.create-sles12-guest-crypt-on-lvm.sh + +# +Requires: guestfs-tools +Requires: lvm2 +Requires: virt-v2v = %{version} %description libguestfs is a set of tools for accessing and modifying virtual machine (VM) @@ -83,92 +185,388 @@ disk images. You can use this for viewing and editing files inside guests, scripting changes to VMs, monitoring disk used/free statistics, P2V, V2V, performing partial backups, cloning VMs, and much else besides. +%package -n guestfs-tools +Summary: Tools for accessing and modifying virtual machine disk images +Provides: %{name} = %{version} +Obsoletes: %{name} < %{version} +Requires: libguestfs0 = %{version} +Requires: python3-evtx +%if %{with bash_completion} +Recommends: bash-completion >= 2.0 +%endif +%if %{with perl_bindings} +Requires: perl(Data::Dumper) +Requires: perl(File::Basename) +Requires: perl(File::Temp) +Requires: perl(Getopt::Long) +Requires: perl(Locale::TextDomain) +Requires: perl(Pod::Usage) +Requires: perl(String::ShellQuote) +Requires: perl(Sys::Guestfs) +%{perl_requires} +%if %{with hivex} +Requires: perl(Win::Hivex) +Requires: perl(Win::Hivex::Regedit) +%endif +%endif -%prep -%autosetup -p1 +%if %{with fuse} +Requires: fuse +%endif -%build -%define _lto_cflags %{nil} +# For virt-builder +Requires: curl +Requires: gpg2 +Requires: xz +Conflicts: libguestfs0 < %{version} -# use 'env LIBGUESTFS_HV=/path/to/kvm libguestfs-test-tool' to verify -%define kvm_binary /bin/false -%ifarch aarch64 -%define kvm_binary %{_bindir}/qemu-system-aarch64 -%endif -%ifarch ppc64le -%define kvm_binary %{_bindir}/qemu-system-ppc64 -%endif -%ifarch ppc64 -%define kvm_binary %{_bindir}/qemu-system-ppc64 -%endif -%ifarch s390x -%define kvm_binary %{_bindir}/qemu-system-s390x -%endif -%ifarch x86_64 -%define kvm_binary %{_bindir}/qemu-system-x86_64 +%description -n guestfs-tools +libguestfs is a set of tools for accessing and modifying virtual machine (VM) +disk images. You can use this for viewing and editing files inside guests, +scripting changes to VMs, monitoring disk used/free statistics, P2V, V2V, +performing partial backups, cloning VMs, and much else besides. + +libguestfs can access nearly any type of filesystem including: all known types +of Linux filesystem (ext2/3/4, XFS, btrfs etc), any Windows filesystem (VFAT +and NTFS), any Mac OS X and BSD filesystems, LVM2 volume management, MBR and +GPT disk partitions, raw disks, qcow2, VirtualBox VDI, VMWare VMDK, CD and DVD +ISOs, SD cards, and dozens more. libguestfs doesn't need root permissions. + +All this functionality is available through a convenient shell called +guestfish, or use virt-rescue to get a rescue shell for fixing unbootable +virtual machines. + +%package -n guestfsd +Summary: Daemon for the libguestfs appliance +Conflicts: libaugeas0 < 1.0.0 + +%description -n guestfsd +guestfsd runs within the libguestfs appliance. It receives commands from the host +and performs the requested action by calling the helper binaries. +This package is only required for building the appliance. + +# +%if %{with ocaml_bindings} +%package -n ocaml-libguestfs +Summary: OCaml bindings for libguestfs +# + +%description -n ocaml-libguestfs +Allows OCaml scripts to directly use libguestfs. + +%package -n ocaml-libguestfs-devel +Summary: Development files for libguesfs OCaml bindings + +%description -n ocaml-libguestfs-devel +Allows OCaml scripts to directly use libguestfs. %endif # -%define guestfs_docdir %{_defaultdocdir}/%{name} +%if %{with perl_bindings} +%package -n perl-Sys-Guestfs +Summary: Perl bindings for libguestfs +BuildRequires: perl +BuildRequires: perl(Data::Dumper) +BuildRequires: perl(Getopt::Long) +BuildRequires: perl(Locale::TextDomain) +BuildRequires: perl(Pod::Usage) +BuildRequires: perl(String::ShellQuote) +BuildRequires: perl(Sys::Virt) +%if %{with hivex} +BuildRequires: perl(Win::Hivex) +BuildRequires: perl(Win::Hivex::Regedit) +%endif +%define _configure_perl --enable-perl +# +Provides: libguestfs-perl = %{version} +Obsoletes: libguestfs-perl < %{version} +Requires: perl(File::Temp) +Requires: perl(Locale::TextDomain) +%perl_requires -export AWK='%{_bindir}/gawk' -export CPIO='%{_bindir}/cpio' -export GPERF='%{_bindir}/gperf' -export MKISOFS='%{_bindir}/xorrisofs' -export XMLLINT='%{_bindir}/xmllint' -export PO4A_GETTEXTIZE='%{_bindir}/po4a-gettextize' -export PO4A_TRANSLATE='%{_bindir}/po4a-translate' -export SQLITE3='%{_bindir}/sqlite3' -export PBMTEXT='%{_bindir}/pbmtext' -export PNMTOPNG='%{_bindir}/pnmtopng' -export BMPTOPNM='%{_bindir}/bmptopnm' -export PAMCUT='%{_bindir}/pamcut' -export WRESTOOL='%{_bindir}/wrestool' -export XZCAT='%{_bindir}/xzcat' -export VALGRIND='%{_bindir}/valgrind' -export FUSER='%{_bindir}/fuser' -export TOOL_TRUE='%{_bindir}/true' -export XGETTEXT='%{_bindir}/xgettext' -export MSGCAT='%{_bindir}/msgcat' -export MSGFMT='%{_bindir}/msgfmt' -export MSGMERGE='%{_bindir}/msgmerge' -export RPCGEN='%{_bindir}/rpcgen' -export SUPERMIN='%{_bindir}/supermin' -export QEMU="%{kvm_binary}" +%description -n perl-Sys-Guestfs +Allows Perl scripts to directly use libguestfs. +%endif +# +%if %{with lua_bindings} +%package -n lua-libguestfs +Summary: Lua bindings for libguestfs +BuildRequires: lua-devel +%define _configure_lua --enable-lua +# + +%description -n lua-libguestfs +Allows lua scripts to directly use libguestfs. +%endif +# + +%if %{with python_bindings} +%{?!python_module:%define python_module() python3-%{**}} +%package -n python3-libguestfs +Summary: Python 3 bindings for libguestfs +BuildRequires: pkgconfig(python3) +%define _configure_python --enable-python +# +Obsoletes: libguestfs-python < %{version} +Obsoletes: python-libguestfs < %{version} +Provides: python-libguestfs = %{version} + +%description -n python3-libguestfs +Allows Python 3 scripts to directly use libguestfs. +%endif +# +%if %{with ruby_bindings} +%package -n rubygem-libguestfs +Summary: Ruby bindings for libguestfs +BuildRequires: ruby +BuildRequires: ruby-devel +BuildRequires: rubygem(rake) +%define _configure_ruby --enable-ruby +# + +%description -n rubygem-libguestfs +Allows Ruby scripts to directly use libguestfs. +%endif + +%package test +Summary: Testcases for libguestfs +Requires: %{name} + +%description test +This package contains testcases to verify libguestfs functionality. + +%package -n guestfs-data +BuildRequires: augeas-lenses +BuildRequires: bc +BuildRequires: btrfsprogs +BuildRequires: bzip2 +BuildRequires: coreutils +BuildRequires: cpio +BuildRequires: cryptsetup +BuildRequires: diffutils +BuildRequires: dosfstools +BuildRequires: e2fsprogs +BuildRequires: file +BuildRequires: findutils +BuildRequires: gawk +%if 0%{?suse_version} >= 1500 +BuildRequires: mkisofs +%else +BuildRequires: cdrkit-cdrtools-compat +BuildRequires: genisoimage +%endif +BuildRequires: glibc +BuildRequires: gptfdisk +BuildRequires: grep +BuildRequires: gzip +BuildRequires: initviocons +BuildRequires: iproute2 +BuildRequires: jfsutils +BuildRequires: lvm2 +BuildRequires: mdadm +BuildRequires: module-init-tools +BuildRequires: ncurses-utils +BuildRequires: nfs-client +BuildRequires: ntfs-3g +BuildRequires: ntfsprogs +BuildRequires: pam-config +BuildRequires: parted +BuildRequires: pciutils +BuildRequires: pciutils-ids +BuildRequires: psmisc +BuildRequires: reiserfs +BuildRequires: rsync +BuildRequires: sg3_utils +BuildRequires: strace +%ifarch %ix86 x86_64 +BuildRequires: syslinux +%endif +BuildRequires: ldmtool +BuildRequires: tar +BuildRequires: terminfo-base +BuildRequires: tunctl +BuildRequires: udev +BuildRequires: util-linux +BuildRequires: util-linux-lang +BuildRequires: xfsprogs +BuildRequires: xz +BuildRequires: pkgconfig(systemd) + +# Needed by guestfsd which is burried in the appliance +# +# The problem with this design is that rpm can't find the +# library dependencies from the guestfsd hidden in the +# daemon.tar.gz tarball.Supermin will compute an appliance +# at runtime based on the packages it will find on the host. +# Thus if there is no libaugeas, libhivex, etc on the host, +# the appliance will fail to start the guestfsd. +Requires: augeas +Requires: augeas-lenses +Requires: libaugeas0 +Requires: libcap2 +Requires: libhivex0 +Requires: libpcre1 + +# For core disk features +Requires: qemu-tools + +# Optional packages that could be picked up by supermin +Recommends: btrfsprogs +Recommends: dosfstools +Recommends: e2fsprogs +Recommends: cryptsetup +Recommends: gptfdisk +Recommends: jfsutils +Recommends: reiserfs +Recommends: xfsprogs +Recommends: mdadm +Recommends: parted +Recommends: zerofree +%if 0%{?suse_version} >= 1500 +Recommends: mkisofs +%else +Recommends: genisoimage +%endif +Recommends: ldmtool +Recommends: guestfs-winsupport + +Summary: Virtual machine needed for libguestfs +Provides: libguestfs-data = %{version} +Obsoletes: libguestfs-data < %{version} + +%description -n guestfs-data +libguestfs needs for it's run a virtual machine image. +This package provides such an image, an initrd and a kernel. + +%package -n guestfs-winsupport +Summary: Windows guest support in libguestfs +Requires: libguestfs >= 1.32 +BuildRequires: ntfs-3g +BuildRequires: ntfsprogs +BuildRequires: rsync + +%description -n guestfs-winsupport +Provides the needed pieces for libguestfs to handle Windows guests. + +%package devel +Summary: Development files for libguestfs +Requires: libguestfs0 = %{version} + +%description devel +Development files for libguestfs. + +libguestfs is a set of tools for accessing and modifying virtual machine (VM) +disk images. You can use this for viewing and editing files inside guests, +scripting changes to VMs, monitoring disk used/free statistics, P2V, V2V, +performing partial backups, cloning VMs, and much else besides. + +%package -n libguestfs0 +Summary: Runtime library of libguestfs +Requires: %{kvm_binary} +Requires: db48-utils +Requires: guestfs-data >= %{version} +Requires: qemu >= 2.0 +Requires: qemu-tools +Requires: supermin >= 5.1.6 + +%description -n libguestfs0 +Library for libguestfs. + +libguestfs is a set of tools for accessing and modifying virtual machine (VM) +disk images. You can use this for viewing and editing files inside guests, +scripting changes to VMs, monitoring disk used/free statistics, P2V, V2V, +performing partial backups, cloning VMs, and much else besides. + +libguestfs can access nearly any type of filesystem including: all known types +of Linux filesystem (ext2/3/4, XFS, btrfs etc), any Windows filesystem (VFAT +and NTFS), any Mac OS X and BSD filesystems, LVM2 volume management, MBR and +GPT disk partitions, raw disks, qcow2, VirtualBox VDI, VMWare VMDK, CD and DVD +ISOs, SD cards, and dozens more. libguestfs doesn't need root permissions. + +All this functionality is available through a convenient shell called +guestfish, or use virt-rescue to get a rescue shell for fixing unbootable +virtual machines. + + +%package -n virt-v2v +Summary: Convert a virtual machine to run on KVM +Requires: libguestfs0 = %{version} +Requires: qemu-block-ssh +# Conflicts with the old perl version +Conflicts: virt-v2v <= 0.9.1 + +%description -n virt-v2v +virt-v2v is a tool for converting and importing virtual machines to +libvirt-managed KVM. It can import a variety of guest operating systems +from libvirt-managed hosts. + +%if %{with p2v} +%package -n virt-p2v +Summary: Convert a physical machine to run on KVM +Requires: gawk +Requires: virt-v2v = %{version} + +%description -n virt-p2v +virt-p2v is a tool for converting physical machines into libvirt-managed KVM machines. +It can import a variety of guest operating systems from libvirt-managed hosts. +%endif + +%prep +: _ignore_exclusive_arch '%{?_ignore_exclusive_arch}' +%autosetup -p1 -a 789653 + +%build +%global _lto_cflags %{_lto_cflags} -ffat-lto-objects +bison --version +# [Bug 789653] sles11 perl obsoletes perl-Pod-Simple unconditionally +export PERLLIB=`echo $PWD/Pod-Simple-*/lib` +# disable qemu test. +# If the package is built within kvm the configure test will fail because it starts kvm within kvm +# With QEMU in environment qemu and kvm packages are not needed at build time. +# With SUPERMIN and SUPERMIN_HELPER in environment, supermin package is not needed at build time. export vmchannel_test=no -export PERL='%{_bindir}/perl' -export PYTHON='%{_bindir}/python3' - -sed -i~ ' -/test-data/d -' configure.ac -diff -u "$_"~ "$_" && exit 0 -sed -i~ ' -/SUBDIRS/s@test-data@@ -' Makefile.am -diff -u "$_"~ "$_" && exit 0 +export QEMU="%{kvm_binary}" +export SUPERMIN=supermin +export SUPERMIN_HELPER=supermin-helper +# for configure macro below +export CFLAGS="%{optflags} -Wno-unused" +export CXXFLAGS="%{optflags} -Wno-unused" autoreconf -fi -%configure --help +# %configure \ - --docdir=%{guestfs_docdir} \ - --with-distro=SUSE \ - --with-readline \ - --with-guestfs-path=%{_libdir}/guestfs \ - --with-qemu=$QEMU \ - --with-supermin-packager-config="$PWD/zypper.priv.conf --use-installed --verbose" \ - --without-java \ - --enable-daemon \ - --enable-install-daemon \ - --enable-ocaml \ - --enable-perl \ - --enable-python \ - --disable-erlang \ - --disable-haskell \ - --disable-php \ - --disable-rpath \ - --disable-static \ - %nil + --help || : +# Defines these if using --with-distro=SUSE with configure +export HAVE_RPM_TRUE= +export HAVE_RPM_FALSE="#" +export HAVE_DPKG_TRUE="#" +export HAVE_DPKG_FALSE="#" +export HAVE_PACMAN_TRUE="#" +export HAVE_PACMAN_FALSE="#" + +#sed -i '1 s@^.*@#!/bin/sh -x@' configure +%configure \ + --docdir=%{guestfs_docdir} \ + --enable-daemon \ + --enable-install-daemon \ + --with-guestfs-path=%{_libdir}/guestfs \ + --with-qemu=$QEMU \ + --without-java \ + --with-supermin-packager-config="$PWD/zypper.priv.conf --use-installed --verbose" \ + --disable-haskell \ + --disable-php \ + %{_configure_fuse} \ + %{_configure_lua} \ + %{_configure_ocaml} \ + %{_configure_perl} \ + %{_configure_python} \ + %{_configure_ruby} \ + --disable-rpath \ + --disable-static \ + --with-distro=SUSE + +#Workaround an autotools bug +make -j1 -C builder index-parse.c # 'INSTALLDIRS' ensures that perl libs are installed in the vendor dir instead of the site dir build_it() { make \ @@ -180,58 +578,47 @@ make \ build_it %{?_smp_mflags} || build_it %install -%make_install \ +%makeinstall \ INSTALLDIRS=vendor \ udevrulesdir=%{_udevrulesdir} -find %buildroot -ls - -rm -f $( find %buildroot -name '*.a' | grep -v /ocaml/ ) - -find %buildroot -name '*.la' -delete - -mkdir -p %{buildroot}/etc/profile.d -cp %{S:5} %{buildroot}/etc/profile.d - -# Perl +find %{buildroot} -ls +mkdir -p %{buildroot}/%{_datadir}/guestfs +cp -avLt %{buildroot}/%{_datadir}/guestfs \ + %{S:10005} \ + %{S:10004} \ + %{S:10003} \ + %{S:10002} \ + %{S:10001} +chmod 0755 %{buildroot}/%{_datadir}/guestfs/* +#remove ocaml bindings files if they are disable via rpm macro +%if !%{with ocaml_bindings} +rm -rfv %{buildroot}/%{_libdir}/ocaml +%endif +rm -rfv %{buildroot}/%{guestfs_docdir} +rm -rfv %{buildroot}/etc/libguestfs-tools.conf +find %{buildroot}/ -type f \( \ + -name "virt-list-filesystems" -o -name "virt-list-filesystems.*" -o \ + -name "virt-list-partitions" -o -name "virt-list-partitions.*" -o \ + -name "virt-tar" -o -name "virt-tar.*" \ + \) -print -delete +%if %{with perl_bindings} +# Delete empty perl bootstrap files find %{buildroot}/ -name "*.bs" -size 0c -print -delete %perl_process_packlist %perl_gen_filelist -# The macro above packages everything, here only the perl files are desired +# the macro above packages everything, here only the perl files are desrired grep "%perl_vendorarch/" %{name}.files | tee t mv t %{name}.files +%endif -# Supermin -pushd $RPM_BUILD_ROOT%{_libdir}/guestfs/supermin.d - -function remove -{ - grep -Ev "^$1$" < packages > packages-t - mv packages-t packages -} - -function move_to -{ - if ! grep -Esq "^$1$" packages; then - echo "move_to $1: package name not found in packages file" - exit 1 - fi - remove "$1" - echo "$1" >> "$2" -} - -move_to iputils zz-packages-rescue -move_to lsof zz-packages-rescue -move_to pciutils zz-packages-rescue -move_to strace zz-packages-rescue -move_to vim zz-packages-rescue -move_to rsync zz-packages-rsync -move_to xfsprogs zz-packages-xfs - -popd - -# Remove the .gitignore file from ocaml/html which will be copied to docdir. -rm ocaml/html/.gitignore +# Don't package the test harness (yet) +rm -rf %{buildroot}/%{_libdir}/ocaml/v2v_test_harness +# +find %{buildroot}/ -name "*.la" -print -delete +rm -fv %{buildroot}/%{_libdir}/*.a +# +touch %{name}.lang %find_lang %{name} # Appliance NTFS files @@ -261,324 +648,18 @@ tar -czf %{buildroot}/%{_libdir}/guestfs/supermin.d/zz-scripts.tar.gz usr popd rm -rf %{buildroot}/tmp -%files -f %{name}.lang -%doc README COPYING -%{_bindir}/guestfish -%{_bindir}/guestmount -%{_bindir}/guestunmount -%{_bindir}/libguestfs-test-tool -%{_bindir}/virt-copy-in -%{_bindir}/virt-copy-out -%{_bindir}/virt-tar-in -%{_bindir}/virt-tar-out -%{_libdir}/libguestfs.so.* -%{_mandir}/man1/guestfish.1* -%{_mandir}/man1/guestfs-faq.1* -%{_mandir}/man1/guestfs-performance.1* -%{_mandir}/man1/guestfs-recipes.1* -%{_mandir}/man1/guestfs-release-notes-1*.1* -%{_mandir}/man1/guestfs-release-notes-historical.1* -%{_mandir}/man1/guestfs-security.1* -%{_mandir}/man1/guestmount.1* -%{_mandir}/man1/guestunmount.1* -%{_mandir}/man1/libguestfs-test-tool.1* -%{_mandir}/man1/virt-copy-in.1* -%{_mandir}/man1/virt-copy-out.1* -%{_mandir}/man1/virt-tar-in.1* -%{_mandir}/man1/virt-tar-out.1* -%{_mandir}/man5/libguestfs-tools.conf.5* -%config %{_sysconfdir}/profile.d/guestfish.sh -%config(noreplace) %{_sysconfdir}/libguestfs-tools.conf - -%package -n libguestfsd -Summary: Daemon for the libguestfs appliance -Conflicts: libaugeas0 < 1.0.0 -Provides: guestfsd = %{version} -Obsoletes: guestfsd < %{version} - -%description -n libguestfsd -guestfsd runs within the libguestfs appliance. It receives commands from the host -and performs the requested action by calling the helper binaries. -This package is only required for building the appliance. - - -%package -n libguestfs-appliance -BuildRequires: augeas-lenses -BuildRequires: bc -BuildRequires: btrfsprogs -BuildRequires: bzip2 -BuildRequires: coreutils -BuildRequires: cpio -BuildRequires: cryptsetup -BuildRequires: diffutils -BuildRequires: dosfstools -BuildRequires: e2fsprogs -BuildRequires: file -BuildRequires: findutils -BuildRequires: glibc -BuildRequires: gptfdisk -BuildRequires: grep -BuildRequires: gzip -BuildRequires: initviocons -BuildRequires: iproute2 -BuildRequires: jfsutils -BuildRequires: ldmtool -BuildRequires: lvm2 -BuildRequires: mdadm -BuildRequires: mkisofs -BuildRequires: module-init-tools -BuildRequires: ncurses-utils -BuildRequires: nfs-client -BuildRequires: ntfs-3g -BuildRequires: ntfsprogs -BuildRequires: pam-config -BuildRequires: parted -BuildRequires: psmisc -BuildRequires: reiserfs -BuildRequires: sg3_utils -BuildRequires: strace -BuildRequires: pkgconfig(systemd) -%ifarch %ix86 x86_64 -BuildRequires: syslinux +%if %{with p2v} +# Remove the kickstart files from p2v package +rm %{buildroot}/%{_datadir}/virt-p2v/p2v.ks.in %endif -BuildRequires: systemd-sysvinit -BuildRequires: tar -BuildRequires: terminfo-base -BuildRequires: tunctl -BuildRequires: udev -BuildRequires: util-linux -BuildRequires: util-linux-lang -BuildRequires: xfsprogs -BuildRequires: xz -# Needed by guestfsd which is burried in the appliance -# -# The problem with this design is that rpm can't find the -# library dependencies from the guestfsd hidden in the -# daemon.tar.gz tarball. Supermin will compute an appliance -# at runtime based on the packages it will find on the host. -# Thus if there is no libaugeas, libhivex, etc on the host, -# the appliance will fail to start the guestfsd. -Requires: augeas -Requires: augeas-lenses -Requires: libaugeas0 -Requires: libcap2 -Requires: libhivex0 -Requires: libpcre1 +%post -n libguestfs0 -p /sbin/ldconfig +%postun -n libguestfs0 -p /sbin/ldconfig -# For core disk features -Requires: qemu-tools +%files test +%{_datadir}/guestfs -# Optional packages that could be picked up by supermin -Recommends: btrfsprogs -Recommends: cryptsetup -Recommends: dosfstools -Recommends: e2fsprogs -Recommends: gptfdisk -Recommends: jfsutils -Recommends: ldmtool -Recommends: mdadm -Recommends: mkisofs -Recommends: parted -Recommends: reiserfs -Recommends: xfsprogs -Recommends: zerofree - -Summary: Virtual machine needed for libguestfs -Provides: guestfs-data = %{version} -Obsoletes: guestfs-data < %{version} - -%description -n libguestfs-appliance -libguestfs needs for it's run a virtual machine image. -This package provides such an image, an initrd and a kernel. - - -%package winsupport -Summary: Windows guest support in libguestfs -Requires: libguestfs >= 1.32 -BuildRequires: ntfs-3g -BuildRequires: ntfsprogs -BuildRequires: rsync -Provides: guestfs-winsupport = %{version} -Obsoletes: guestfs-winsupport < %{version} - -%description winsupport -Provides the needed pieces for libguestfs to handle Windows guests. - - -%package devel -Summary: Development files for libguestfs -Requires: libguestfs = %{version} - -%description devel -Development files for libguestfs. - -libguestfs is a set of tools for accessing and modifying virtual machine (VM) -disk images. You can use this for viewing and editing files inside guests, -scripting changes to VMs, monitoring disk used/free statistics, P2V, V2V, -performing partial backups, cloning VMs, and much else besides. - - -%package bash-completion -Summary: Bash tab-completion scripts for %{name} tools -BuildArch: noarch -Requires: bash-completion >= 2.0 - -%description bash-completion -Install this package if you want intelligent bash tab-completion -for guestfish, guestmount and various virt-* tools. - - -%package inspect-icons -Summary: Additional dependencies for inspecting guest icons -BuildArch: noarch -Requires: %{name} = %{version}-%{release} -Requires: icoutils - -%description inspect-icons -%{name}-inspect-icons is a metapackage that pulls in additional -dependencies required by libguestfs to pull icons out of non-Linux -guests. Install this package if you want libguestfs to be able to -inspect non-Linux guests and display icons from them. - -The only reason this is a separate package is to avoid core libguestfs -having to depend on Perl. - -%package -n ocaml-%{name} -Summary: OCaml bindings for %{name} -Requires: %{name}%{?_isa} = %{version}-%{release} - -%description -n ocaml-%{name} -ocaml-%{name} contains OCaml bindings for %{name}. - -This is for toplevel and scripting access only. To compile OCaml -programs which use %{name} you will also need ocaml-%{name}-devel. - - -%package -n ocaml-%{name}-devel -Summary: OCaml bindings for %{name} -Requires: ocaml-%{name}%{?_isa} = %{version}-%{release} - -%description -n ocaml-%{name}-devel -ocaml-%{name}-devel contains development libraries -required to use the OCaml bindings for %{name}. - - -%package -n perl-Sys-Guestfs -Summary: Perl bindings for %{name} (Sys::Guestfs) -Requires: %{name}%{?_isa} = %{version}-%{release} -Requires: perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version)) - -%description -n perl-Sys-Guestfs -perl-Sys-Guestfs contains Perl bindings for %{name} (Sys::Guestfs). - - -%package -n python3-%{name} -Summary: Python 3 bindings for %{name} -BuildRequires: python-rpm-macros -Requires: %{name}%{?_isa} = %{version}-%{release} -%{?python_provide:%python_provide python3-%{name}} - -%description -n python3-%{name} -python3-%{name} contains Python 3 bindings for %{name}. - - -%package -n rubygem-%{name} -Summary: Ruby bindings for %{name} -BuildRequires: ruby -BuildRequires: ruby-devel -BuildRequires: rubygem(rake) -Requires: %{name}%{?_isa} = %{version}-%{release} -Requires: ruby -Requires: ruby(release) -Provides: ruby(guestfs) = %{version} - -%description -n rubygem-%{name} -ruby-%{name} contains Ruby bindings for %{name}. - - -%package -n lua-guestfs -Summary: Lua bindings for %{name} -BuildRequires: lua-devel -Requires: %{name}%{?_isa} = %{version}-%{release} -Requires: lua - -%description -n lua-guestfs -lua-guestfs contains Lua bindings for %{name}. - - -%package gobject -Summary: GObject bindings for %{name} -Requires: %{name}%{?_isa} = %{version}-%{release} - -%description gobject -%{name}-gobject contains GObject bindings for %{name}. - -To develop software against these bindings, you need to install -%{name}-gobject-devel. - -%package gobject-devel -Summary: GObject bindings for %{name} -Requires: %{name}-gobject = %{version}-%{release} - -%description gobject-devel -%{name}-gobject contains GObject bindings for %{name}. - -This package is needed if you want to write software using the -GObject bindings. It also contains GObject Introspection information. - -%package rescue -Summary: virt-rescue shell -BuildRequires: iputils -BuildRequires: lsof -BuildRequires: pciutils -BuildRequires: strace -BuildRequires: vim - -%description rescue -This adds the virt-rescue shell which is a "rescue disk" for virtual -machines, and additional tools to use inside the shell such as ssh, -network utilities, editors and debugging utilities. - - -%package rsync -Summary: rsync support for %{name} -Requires: %{name}%{?_isa} = %{version}-%{release} -BuildRequires: rsync - -%description rsync -This adds rsync support to %{name}. Install it if you want to use -rsync to upload or download files into disk images. - - -%package xfs -Summary: XFS support for %{name} -Requires: %{name}%{?_isa} = %{version}-%{release} - -%description xfs -This adds XFS support to %{name}. Install it if you want to process -disk images containing XFS. - - -%package man-pages-ja -Summary: Japanese (ja) man pages for %{name} -BuildArch: noarch -Requires: %{name} = %{version}-%{release} - -%description man-pages-ja -%{name}-man-pages-ja contains Japanese (ja) man pages -for %{name}. - -%package man-pages-uk -Summary: Ukrainian (uk) man pages for %{name} -BuildArch: noarch -Requires: %{name} = %{version}-%{release} - -%description man-pages-uk -%{name}-man-pages-uk contains Ukrainian (uk) man pages -for %{name}. - -%files -n libguestfs-appliance +%files -n guestfs-data %dir %{_libdir}/guestfs %dir %{_libdir}/guestfs/supermin.d %{_libdir}/guestfs/supermin.d/base.tar.gz @@ -590,117 +671,80 @@ for %{name}. %{_libdir}/guestfs/supermin.d/packages %{_libdir}/guestfs/supermin.d/zz-scripts.tar.gz -%files winsupport +%files -n guestfs-winsupport %{_libdir}/guestfs/supermin.d/zz-*winsupport* -%files bash-completion -%dir %{_datadir}/bash-completion/completions -%{_datadir}/bash-completion/completions/guestfish -%{_datadir}/bash-completion/completions/guestmount -%{_datadir}/bash-completion/completions/guestunmount -%{_datadir}/bash-completion/completions/libguestfs-test-tool -%{_datadir}/bash-completion/completions/virt-copy-in -%{_datadir}/bash-completion/completions/virt-copy-out -%{_datadir}/bash-completion/completions/virt-rescue -%{_datadir}/bash-completion/completions/virt-tar-in -%{_datadir}/bash-completion/completions/virt-tar-out +%if %{with ocaml_bindings} +%files -n ocaml-libguestfs +%dir %{_libdir}/ocaml +%dir %{_libdir}/ocaml/guestfs +%{_libdir}/ocaml/guestfs/META +%{_libdir}/ocaml/guestfs/*.cmi +%{_libdir}/ocaml/guestfs/*.cma +%{_libdir}/ocaml/stublibs -%files inspect-icons -# no files - -%files -n ocaml-%{name} -%{_libdir}/ocaml/guestfs -%exclude %{_libdir}/ocaml/guestfs/*.a -%exclude %{_libdir}/ocaml/guestfs/*.cmxa -%exclude %{_libdir}/ocaml/guestfs/*.cmx -%exclude %{_libdir}/ocaml/guestfs/*.mli -%{_libdir}/ocaml/stublibs/dllmlguestfs.so -%{_libdir}/ocaml/stublibs/dllmlguestfs.so.owner - -%files -n ocaml-%{name}-devel -%doc ocaml/examples/*.ml ocaml/html +%files -n ocaml-libguestfs-devel +%dir %{_libdir}/ocaml +%dir %{_libdir}/ocaml/guestfs %{_libdir}/ocaml/guestfs/*.a -%{_libdir}/ocaml/guestfs/*.cmxa %{_libdir}/ocaml/guestfs/*.cmx +%{_libdir}/ocaml/guestfs/*.cmxa %{_libdir}/ocaml/guestfs/*.mli -%{_mandir}/man3/guestfs-ocaml.3* - -%files -n perl-Sys-Guestfs -%{perl_vendorarch}/* -%doc perl/examples/*.pl -%{_mandir}/man3/Sys::Guestfs.3pm* -%{_mandir}/man3/guestfs-perl.3* - -%files -n python3-%{name} -%doc python/examples/*.py -%{python3_sitearch}/libguestfsmod*.so -%{python3_sitearch}/guestfs.py -%{_mandir}/man3/guestfs-python.3* - -%files -n rubygem-%{name} -%doc ruby/examples/*.rb -%doc ruby/doc/site/* -%{_libdir}/ruby -%{_mandir}/man3/guestfs-ruby.3* - -%files -n lua-guestfs -%doc lua/examples/*.lua -%doc lua/examples/LICENSE +%endif +# +%if %{with lua_bindings} +%files -n lua-libguestfs %{_libdir}/lua -%{_mandir}/man3/guestfs-lua.3* +%endif +# +%if %{with perl_bindings} +%post -n perl-Sys-Guestfs -p /sbin/ldconfig -%files gobject -%{_libdir}/libguestfs-gobject-1.0.so.0* -%{_libdir}/girepository-1.0/Guestfs-1.0.typelib +%postun -n perl-Sys-Guestfs -p /sbin/ldconfig -%files gobject-devel -%{_libdir}/libguestfs-gobject-1.0.so -%{_includedir}/guestfs-gobject.h -%dir %{_includedir}/guestfs-gobject -%{_includedir}/guestfs-gobject/*.h -%{_datadir}/gir-1.0/Guestfs-1.0.gir -%{_libdir}/pkgconfig/libguestfs-gobject-1.0.pc -%{_mandir}/man3/guestfs-gobject.3* +%files -n perl-Sys-Guestfs -f %{name}.files +%endif +# +%if %{with python_bindings} + +%files -n python3-libguestfs +%{python3_sitearch}/* +%endif +# +%if %{with ruby_bindings} +%files -n rubygem-libguestfs +%{_libdir}/ruby +%endif + +%files -n libguestfs0 +%license COPYING.LIB +%{_libdir}/*.so.* %files devel -%doc examples/*.c -%{_sbindir}/libguestfs-make-fixed-appliance %{_libdir}/*.so -%{_libdir}/pkgconfig/libguestfs.pc +%{_libdir}/pkgconfig/* %{_includedir}/guestfs.h -%{_mandir}/man1/guestfs-building.1* -%{_mandir}/man1/guestfs-hacking.1* -%{_mandir}/man1/guestfs-internals.1* -%{_mandir}/man1/guestfs-testing.1* -%{_mandir}/man1/libguestfs-make-fixed-appliance.1* -%{_mandir}/man3/guestfs.3* -%{_mandir}/man3/guestfs-examples.3* -%{_mandir}/man3/libguestfs.3* +%{_includedir}/guestfs-gobject +%{_includedir}/guestfs-gobject.h +%{_mandir}/man3/* -%files -n libguestfsd +%files -n guestfsd %{_udevrulesdir} %{_sbindir}/guestfsd %{_mandir}/man8/* -%files rescue -%{_libdir}/guestfs/supermin.d/zz-packages-rescue -%{_bindir}/virt-rescue -%{_mandir}/man1/virt-rescue.1* - -%files rsync -%{_libdir}/guestfs/supermin.d/zz-packages-rsync - -%files xfs -%{_libdir}/guestfs/supermin.d/zz-packages-xfs - -%files man-pages-ja -%lang(ja) %{_mandir}/ja/man1/*.1* -%lang(ja) %{_mandir}/ja/man3/*.3* -%lang(ja) %{_mandir}/ja/man5/*.5* - -%files man-pages-uk -%lang(uk) %{_mandir}/uk/man1/*.1* -%lang(uk) %{_mandir}/uk/man3/*.3* -%lang(uk) %{_mandir}/uk/man5/*.5* +%files -n guestfs-tools -f %{name}.lang +%license COPYING +%{_sbindir}/libguestfs-make-fixed-appliance +%{_bindir}/* +/etc/virt-builder +%dir /etc/xdg/virt-builder +%dir /etc/xdg/virt-builder/repos.d +%config /etc/xdg/virt-builder/repos.d/* +%if %{with bash_completion} +%{_datadir}/bash-completion +%endif +%{_mandir}/man1/* +%{_mandir}/man5/* %changelog diff --git a/libguestfs.test.simple.create-opensuse-guest-crypt-on-lvm.sh b/libguestfs.test.simple.create-opensuse-guest-crypt-on-lvm.sh new file mode 100644 index 0000000..25fab1b --- /dev/null +++ b/libguestfs.test.simple.create-opensuse-guest-crypt-on-lvm.sh @@ -0,0 +1,333 @@ +#!/bin/bash +# Create an openSUSE image with lvm on dm-crypt partition +# +# Theory of operation: +# This script uses zypper from the host to resolve dependencies +# for zypper which runs within the appliance. If zypper on the host +# is too old, it will be unable to handle repo data from 13.1: +# http://lists.opensuse.org/zypp-devel/2013-11/msg00000.html +# "[zypp-devel] Package conflicting with itself" +# For this reason zypper from 12.3 can be used to install the pattern +# of the final repo. +# First the dependencies of zypper are resolved, the required packages +# are downloaded and extracted with unrpm. Now the guest is started and +# the partitions in the diskimage are prepared. Then the extracted +# package content is copied into the guest. Once that is done zypper +# inside the guest will install the base pattern and a few extra packages. +# Finally the bootloader grub is configured. Once all that is done +# kvm is started. If all goes well a login prompt appears. +# The password for the crypted partition is "123456". +# The password for root is "root". +# The guest has also network access to the outside. +# +# Expected runtime: ca. 200 seconds +# Requires at least 1.24.5 because this includes the required crypt modules +# +# Expected output: +# guest should start +# no "obvious" errors should be shown during the disk operation +# at the end kvm is started with the generated disk image +# login should be possible +# +set -e +unset LANG +unset ${!LC_*} +cpus=`grep -Ec 'cpu[0-9]' /proc/stat || echo 1` + +output_diskimage=/dev/shm/$LOGNAME/testcase.img +final_repo=http://download.opensuse.org/distribution/13.1/repo/oss/ +initial_repo=http://download.opensuse.org/distribution/12.3/repo/oss/ +force=false +guest_zypper_in__pattern_name="base" +guest_zypper_in__package_list=" +grub +less +master-boot-code +nfs-utils +parted +vim +" +guest_root_password="root" +guest_crypt_password="123456" +diskname_inside_vm=/dev/sda + +case "$0" in + /*) progname="$0" ;; + *) progname="$PWD/$0" ;; +esac + +_exit() { + echo "Exiting '$0 $*'." + exit 1 +} + +_unrpm() { + CPIO_OPTS="--extract --unconditional --preserve-modification-time --make-directories --extract-over-symlinks" + FILES="$@" + for f in $FILES; do + echo -ne "$f:\t" + rpm2cpio $f | cpio ${CPIO_OPTS} + done +} + +until test $# -lt 1 +do + case "$1" in + --unrpm) shift ; _unrpm "$@" ; exit 0 ;; + -n) diskname_inside_vm="$2" ; shift ;; + -o) output_diskimage="$2" ; shift ;; + -R) initial_repo="$2" ; shift ;; + -r) final_repo="$2" ; shift ;; + -f) force=true ;; + -x) set -x ;; + *) echo "Unknown option '$1'" ; exit 1 ;; + esac + shift +done +if test -z "${initial_repo}" +then + echo "URL to initial repo required. Wrong -R option." + _exit +fi +if test -z "${final_repo}" +then + echo "URL to final repo required. Wrong -r option." + _exit +fi +if test -z "${output_diskimage}" +then + echo "Filename for temporary disk image required. Wrong -o option." + _exit +fi +if test -e "${output_diskimage}" +then + if test "${force}" = "false" + then + echo "Output diskimage '${output_diskimage}' exists." + echo "It will not be overwritten. Option '-f' exists to force overwrite." + _exit + fi +fi +zypper --version +cpio --version +guestfish --version +kvm="qemu-system-`uname -m`" +if $kvm --version +then + : good +else + kvm="qemu-kvm" + if $kvm --version + then + : + else + echo "No qemu-kvm found." + _exit + fi +fi +guestfish_version="`guestfish --version | awk '{print \$2}'`" +case "${guestfish_version}" in + 1.20*) _exit ;; + 1.21*) _exit ;; + 1.22*) _exit ;; + 1.23*) _exit ;; + 1.24.[0-4]) _exit ;; + *) ;; +esac + +mkdir -vp "${output_diskimage%/*}" +td=`mktemp -d --tmpdir=/dev/shm/${LOGNAME}` +tf=`mktemp --tmpdir=/dev/shm/${LOGNAME}` +_exit() { +rm -rf "$tf" +rm -rf "$td" +} +trap _exit EXIT +dir_repo=${td}/repos.d +dir_root=${td}/root +dir_cache=${td}/cache +mkdir -vp \ + ${dir_root} \ + ${dir_cache} \ + ${dir_repo} +cat > ${tf} < ${dir_repo}/tmp.repo <> etc/resolv.conf +echo nameserver 169.254.2.3 >> etc/resolv.conf +grep -w root /etc/passwd > etc/passwd +grep -w root /etc/group > etc/group +echo 'root::15209::::::' > etc/shadow +cat > etc/fstab < etc/grub.conf < boot/grub/device.map +cat > boot/grub/menu.lst <&1 " : \ +sh "depmod -a \$(get_kernel_version /boot/vmlinuz) ; mkinitrd -B" : \ +sh "dd if=/usr/lib/boot/MBR of=${diskname_inside_vm}" : \ +sh "cp --verbose --sparse=never --remove-destination --target-directory=/boot/grub /usr/lib/grub/*" : \ +sh "grub --batch --verbose < /etc/grub.conf" : \ +sh "echo crypt_part4 ${diskname_inside_vm}4 none luks,timeout=0 >> /etc/crypttab" : \ +mkdir /LV_ROOT : \ +sh "echo LABEL=LV_ROOT /LV_ROOT ext4 noatime 1 2 >> /etc/fstab" : \ +mkdir /LV_WORK : \ +sh "echo LABEL=LV_WORK /LV_WORK ext4 noatime 1 2 >> /etc/fstab" : \ +mkdir /LV_HOME : \ +sh "echo LABEL=LV_HOME /LV_HOME ext4 noatime 1 2 >> /etc/fstab" : \ +mkdir /LV_MAIL : \ +sh "echo LABEL=LV_MAIL /LV_MAIL ext4 noatime 1 2 >> /etc/fstab" : \ +sh "echo BOOTPROTO='dhcp' >> /etc/sysconfig/network/ifcfg-eth0" : \ +sh "echo STARTMODE='auto' >> /etc/sysconfig/network/ifcfg-eth0" : \ +sh "echo 'Password for User root is: ${guest_root_password}' >> /etc/issue" : \ +cat /etc/fstab : \ +quit +ls -lhsS "${output_diskimage}" + +: ${diskname_inside_vm} +case "${diskname_inside_vm}" in + *vda*) + qemu_drive_options=" + -drive file=${output_diskimage},cache=writeback,id=hd0,if=none \ + -device virtio-blk-pci,drive=hd0 \ + " + ;; + *sda*) + qemu_drive_options=" + -device virtio-scsi-pci,id=scsi \ + -drive file=${output_diskimage},cache=unsafe,format=raw,id=hd0,if=none \ + -device scsi-hd,drive=hd0 \ + " + ;; + *) + echo "${diskname_inside_vm} not handled" + _exit +esac +$kvm -enable-kvm \ + -global virtio-blk-pci.scsi=off \ + -enable-fips \ + -machine accel=kvm:tcg \ + -cpu host,+kvmclock \ + -m 500 \ + -no-reboot \ + -no-hpet \ + ${qemu_drive_options} \ + -device virtio-serial-pci \ + -serial stdio \ + -device sga \ + -netdev user,id=usernet,net=169.254.0.0/16 \ + -device virtio-net-pci,netdev=usernet + +exit 0 diff --git a/libguestfs.test.simple.create-opensuse-guest.sh b/libguestfs.test.simple.create-opensuse-guest.sh new file mode 100644 index 0000000..3f7303e --- /dev/null +++ b/libguestfs.test.simple.create-opensuse-guest.sh @@ -0,0 +1,288 @@ +#!/bin/bash +# Create an openSUSE image with just enough packages to allow boot to login prompt +# +# Theory of operation: +# This script uses zypper from the host to resolve dependencies +# for zypper which runs within the appliance. If zypper on the host +# is too old, it will be unable to handle repo data from 13.1: +# http://lists.opensuse.org/zypp-devel/2013-11/msg00000.html +# "[zypp-devel] Package conflicting with itself" +# For this reason zypper from 12.3 can be used to install the pattern +# of the final repo. +# First the dependencies of zypper are resolved, the required packages +# are downloaded and extracted with unrpm. Now the guest is started and +# the partitions in the diskimage are prepared. Then the extracted +# package content is copied into the guest. Once that is done zypper +# inside the guest will install the base pattern and a few extra packages. +# Finally the bootloader grub is configured. Once all that is done +# kvm is started. If all goes well a login prompt appears. +# The password for root is "root". +# The guest has also network access to the outside. +# +# Expected runtime: ca. 180 seconds +# +# Expected output: +# guest should start +# no "obvious" errors should be shown during the disk operation +# at the end kvm is started with the generated disk image +# login should be possible +# +set -e +unset LANG +unset ${!LC_*} +cpus=`grep -Ec 'cpu[0-9]' /proc/stat || echo 1` + +output_diskimage=/dev/shm/$LOGNAME/testcase.img +final_repo=http://download.opensuse.org/distribution/13.1/repo/oss/ +initial_repo=http://download.opensuse.org/distribution/12.3/repo/oss/ +force=false +guest_zypper_in__pattern_name="base" +guest_zypper_in__package_list=" +grub +less +master-boot-code +nfs-utils +parted +vim +" +guest_root_password="root" +diskname_inside_vm=/dev/sda + +case "$0" in + /*) progname="$0" ;; + *) progname="$PWD/$0" ;; +esac + +_exit() { + echo "Exiting '$0 $*'." + exit 1 +} + +_unrpm() { + CPIO_OPTS="--extract --unconditional --preserve-modification-time --make-directories --extract-over-symlinks" + FILES="$@" + for f in $FILES; do + echo -ne "$f:\t" + rpm2cpio $f | cpio ${CPIO_OPTS} + done +} + +until test $# -lt 1 +do + case "$1" in + --unrpm) shift ; _unrpm "$@" ; exit 0 ;; + -n) diskname_inside_vm="$2" ; shift ;; + -o) output_diskimage="$2" ; shift ;; + -R) initial_repo="$2" ; shift ;; + -r) final_repo="$2" ; shift ;; + -f) force=true ;; + -x) set -x ;; + *) echo "Unknown option '$1'" ; exit 1 ;; + esac + shift +done +if test -z "${initial_repo}" +then + echo "URL to initial repo required. Wrong -R option." + _exit +fi +if test -z "${final_repo}" +then + echo "URL to final repo required. Wrong -r option." + _exit +fi +if test -z "${output_diskimage}" +then + echo "Filename for temporary disk image required. Wrong -o option." + _exit +fi +if test -e "${output_diskimage}" +then + if test "${force}" = "false" + then + echo "Output diskimage '${output_diskimage}' exists." + echo "It will not be overwritten. Option '-f' exists to force overwrite." + _exit + fi +fi +zypper --version +cpio --version +guestfish --version +kvm="qemu-system-`uname -m`" +if $kvm --version +then + : good +else + kvm="qemu-kvm" + if $kvm --version + then + : + else + echo "No qemu-kvm found." + _exit + fi +fi + +mkdir -vp "${output_diskimage%/*}" +td=`mktemp -d --tmpdir=/dev/shm/${LOGNAME}` +tf=`mktemp --tmpdir=/dev/shm/${LOGNAME}` +_exit() { +rm -rf "$tf" +rm -rf "$td" +} +trap _exit EXIT +dir_repo=${td}/repos.d +dir_root=${td}/root +dir_cache=${td}/cache +mkdir -vp \ + ${dir_root} \ + ${dir_cache} \ + ${dir_repo} +cat > ${tf} < ${dir_repo}/tmp.repo <> etc/resolv.conf +echo nameserver 169.254.2.3 >> etc/resolv.conf +grep -w root /etc/passwd > etc/passwd +grep -w root /etc/group > etc/group +echo 'root::15209::::::' > etc/shadow +cat > etc/fstab < etc/grub.conf < boot/grub/device.map +cat > boot/grub/menu.lst <&1 " : \ +sh "depmod -a \$(get_kernel_version /boot/vmlinuz) ; mkinitrd -B" : \ +sh "dd if=/usr/lib/boot/MBR of=${diskname_inside_vm}" : \ +sh "cp --verbose --sparse=never --remove-destination --target-directory=/boot/grub /usr/lib/grub/*" : \ +sh "grub --batch --verbose < /etc/grub.conf" : \ +sh "echo BOOTPROTO='dhcp' >> /etc/sysconfig/network/ifcfg-eth0" : \ +sh "echo STARTMODE='auto' >> /etc/sysconfig/network/ifcfg-eth0" : \ +sh "echo 'Password for User root is: ${guest_root_password}' >> /etc/issue" : \ +cat /etc/fstab : \ +quit +ls -lhsS "${output_diskimage}" + +: ${diskname_inside_vm} +case "${diskname_inside_vm}" in + *vda*) + qemu_drive_options=" + -drive file=${output_diskimage},cache=writeback,id=hd0,if=none \ + -device virtio-blk-pci,drive=hd0 \ + " + ;; + *sda*) + qemu_drive_options=" + -device virtio-scsi-pci,id=scsi \ + -drive file=${output_diskimage},cache=unsafe,format=raw,id=hd0,if=none \ + -device scsi-hd,drive=hd0 \ + " + ;; + *) + echo "${diskname_inside_vm} not handled" + _exit +esac +$kvm -enable-kvm \ + -global virtio-blk-pci.scsi=off \ + -enable-fips \ + -machine accel=kvm:tcg \ + -cpu host,+kvmclock \ + -m 500 \ + -no-reboot \ + -no-hpet \ + ${qemu_drive_options} \ + -device virtio-serial-pci \ + -serial stdio \ + -device sga \ + -netdev user,id=usernet,net=169.254.0.0/16 \ + -device virtio-net-pci,netdev=usernet + +exit 0 diff --git a/libguestfs.test.simple.create-sles12-guest-crypt-on-lvm.sh b/libguestfs.test.simple.create-sles12-guest-crypt-on-lvm.sh new file mode 100644 index 0000000..2e02910 --- /dev/null +++ b/libguestfs.test.simple.create-sles12-guest-crypt-on-lvm.sh @@ -0,0 +1,326 @@ +#!/bin/bash +# Create an openSUSE image with lvm on dm-crypt partition +# +# Theory of operation: +# This script uses zypper from the host to resolve dependencies +# for zypper which runs within the appliance. If zypper on the host +# is too old, it will be unable to handle repo data from 13.1: +# http://lists.opensuse.org/zypp-devel/2013-11/msg00000.html +# "[zypp-devel] Package conflicting with itself" +# For this reason zypper from 12.3 can be used to install the pattern +# of the final repo. +# First the dependencies of zypper are resolved, the required packages +# are downloaded and extracted with unrpm. Now the guest is started and +# the partitions in the diskimage are prepared. Then the extracted +# package content is copied into the guest. Once that is done zypper +# inside the guest will install the base pattern and a few extra packages. +# Finally the bootloader grub is configured. Once all that is done +# kvm is started. If all goes well a login prompt appears. +# The password for the crypted partition is "123456". +# The password for root is "root". +# The guest has also network access to the outside. +# +# Expected runtime: ca. 200 seconds +# Requires at least 1.24.5 because this includes the required crypt modules +# +# Expected output: +# guest should start +# no "obvious" errors should be shown during the disk operation +# at the end kvm is started with the generated disk image +# login should be possible +# +set -e +unset LANG +unset ${!LC_*} +cpus=`grep -Ec 'cpu[0-9]' /proc/stat || echo 1` + +output_diskimage=/dev/shm/$LOGNAME/testcase.img +final_repo=http://dist.suse.de/install/SLP/SLE-12-Server-LATEST/x86_64/DVD1 +initial_repo=http://dist.suse.de/install/SLP/SLE-12-Server-LATEST/x86_64/DVD1 +force=false +guest_zypper_in__pattern_name="base" +guest_zypper_in__package_list=" +grub2 +kernel-default +less +master-boot-code +nfs-utils +parted +vim +" +guest_root_password="root" +guest_crypt_password="123456" +diskname_inside_vm=/dev/sda + +case "$0" in + /*) progname="$0" ;; + *) progname="$PWD/$0" ;; +esac + +_exit() { + echo "Exiting '$0 $*'." + exit 1 +} + +_unrpm() { + CPIO_OPTS="--extract --unconditional --preserve-modification-time --make-directories --extract-over-symlinks" + FILES="$@" + for f in $FILES; do + echo -ne "$f:\t" + rpm2cpio $f | cpio ${CPIO_OPTS} + done +} + +until test $# -lt 1 +do + case "$1" in + --unrpm) shift ; _unrpm "$@" ; exit 0 ;; + -n) diskname_inside_vm="$2" ; shift ;; + -o) output_diskimage="$2" ; shift ;; + -R) initial_repo="$2" ; shift ;; + -r) final_repo="$2" ; shift ;; + -f) force=true ;; + -x) set -x ;; + *) echo "Unknown option '$1'" ; exit 1 ;; + esac + shift +done +if test -z "${initial_repo}" +then + echo "URL to initial repo required. Wrong -R option." + _exit +fi +if test -z "${final_repo}" +then + echo "URL to final repo required. Wrong -r option." + _exit +fi +if test -z "${output_diskimage}" +then + echo "Filename for temporary disk image required. Wrong -o option." + _exit +fi +if test -e "${output_diskimage}" +then + if test "${force}" = "false" + then + echo "Output diskimage '${output_diskimage}' exists." + echo "It will not be overwritten. Option '-f' exists to force overwrite." + _exit + fi +fi +zypper --version +cpio --version +guestfish --version +kvm="qemu-system-`uname -m`" +if $kvm --version +then + : good +else + kvm="qemu-kvm" + if $kvm --version + then + : + else + echo "No qemu-kvm found." + _exit + fi +fi +guestfish_version="`guestfish --version | awk '{print \$2}'`" +case "${guestfish_version}" in + 1.20*) _exit ;; + 1.21*) _exit ;; + 1.22*) _exit ;; + 1.23*) _exit ;; + 1.24.[0-4]) _exit ;; + *) ;; +esac + +mkdir -vp "${output_diskimage%/*}" +td=`mktemp -d --tmpdir=/dev/shm/${LOGNAME}` +tf=`mktemp --tmpdir=/dev/shm/${LOGNAME}` +_exit() { +rm -rf "$tf" +rm -rf "$td" +} +trap _exit EXIT +dir_repo=${td}/repos.d +dir_root=${td}/root +dir_cache=${td}/cache +mkdir -vp \ + ${dir_root} \ + ${dir_cache} \ + ${dir_repo} +cat > ${tf} < ${dir_repo}/tmp.repo <> etc/resolv.conf +echo nameserver 169.254.2.3 >> etc/resolv.conf +grep -w root /etc/passwd > etc/passwd +grep -w root /etc/group > etc/group +echo 'root::15209::::::' > etc/shadow +cat > etc/fstab <&1 " : \ +sh "depmod -a \$(get_kernel_version /boot/vmlinuz) ; mkinitrd -B" : \ +sh "dd if=/usr/lib/boot/MBR of=${diskname_inside_vm}" : \ +sh "echo GRUB_DISABLE_OS_PROBER=true >> /etc/default/grub " : \ +sh "echo GRUB_DISABLE_LINUX_RECOVERY=true >> /etc/default/grub " : \ +sh "echo GRUB_CMDLINE_LINUX_DEFAULT=\'quiet panic=9 video=800x600 \' >> /etc/default/grub " : \ +sh "grub2-mkconfig > /boot/grub2/grub.cfg " : \ +sh "grub2-install --force --verbose ${diskname_inside_vm}2 " : \ +sh "echo crypt_part4 ${diskname_inside_vm}4 none luks,timeout=0 >> /etc/crypttab" : \ +mkdir /LV_ROOT : \ +sh "echo LABEL=LV_ROOT /LV_ROOT ext4 noatime 1 2 >> /etc/fstab" : \ +mkdir /LV_WORK : \ +sh "echo LABEL=LV_WORK /LV_WORK ext4 noatime 1 2 >> /etc/fstab" : \ +mkdir /LV_HOME : \ +sh "echo LABEL=LV_HOME /LV_HOME ext4 noatime 1 2 >> /etc/fstab" : \ +mkdir /LV_MAIL : \ +sh "echo LABEL=LV_MAIL /LV_MAIL ext4 noatime 1 2 >> /etc/fstab" : \ +sh "echo BOOTPROTO='dhcp' >> /etc/sysconfig/network/ifcfg-eth0" : \ +sh "echo STARTMODE='auto' >> /etc/sysconfig/network/ifcfg-eth0" : \ +sh "echo 'Password for User root is: ${guest_root_password}' >> /etc/issue" : \ +sh "echo >> /etc/issue" : \ +cat /etc/fstab : \ +quit +ls -lhsS "${output_diskimage}" + +: ${diskname_inside_vm} +case "${diskname_inside_vm}" in + *vda*) + qemu_drive_options=" + -drive file=${output_diskimage},cache=writeback,id=hd0,if=none \ + -device virtio-blk-pci,drive=hd0 \ + " + ;; + *sda*) + qemu_drive_options=" + -device virtio-scsi-pci,id=scsi \ + -drive file=${output_diskimage},cache=unsafe,format=raw,id=hd0,if=none \ + -device scsi-hd,drive=hd0 \ + " + ;; + *) + echo "${diskname_inside_vm} not handled" + _exit +esac +$kvm -enable-kvm \ + -global virtio-blk-pci.scsi=off \ + -enable-fips \ + -machine accel=kvm:tcg \ + -cpu host,+kvmclock \ + -m 500 \ + -no-reboot \ + -no-hpet \ + ${qemu_drive_options} \ + -device virtio-serial-pci \ + -serial stdio \ + -device VGA \ + -netdev user,id=usernet,net=169.254.0.0/16 \ + -device virtio-net-pci,netdev=usernet + +exit 0 diff --git a/libguestfs.test.simple.create-sles12-guest.sh b/libguestfs.test.simple.create-sles12-guest.sh new file mode 100644 index 0000000..4c96c55 --- /dev/null +++ b/libguestfs.test.simple.create-sles12-guest.sh @@ -0,0 +1,281 @@ +#!/bin/bash +# Create an openSUSE image with just enough packages to allow boot to login prompt +# +# Theory of operation: +# This script uses zypper from the host to resolve dependencies +# for zypper which runs within the appliance. If zypper on the host +# is too old, it will be unable to handle repo data from 13.1: +# http://lists.opensuse.org/zypp-devel/2013-11/msg00000.html +# "[zypp-devel] Package conflicting with itself" +# For this reason zypper from 12.3 can be used to install the pattern +# of the final repo. +# First the dependencies of zypper are resolved, the required packages +# are downloaded and extracted with unrpm. Now the guest is started and +# the partitions in the diskimage are prepared. Then the extracted +# package content is copied into the guest. Once that is done zypper +# inside the guest will install the base pattern and a few extra packages. +# Finally the bootloader grub is configured. Once all that is done +# kvm is started. If all goes well a login prompt appears. +# The password for root is "root". +# The guest has also network access to the outside. +# +# Expected runtime: ca. 180 seconds +# +# Expected output: +# guest should start +# no "obvious" errors should be shown during the disk operation +# at the end kvm is started with the generated disk image +# login should be possible +# +set -e +unset LANG +unset ${!LC_*} +cpus=`grep -Ec 'cpu[0-9]' /proc/stat || echo 1` + +output_diskimage=/dev/shm/$LOGNAME/testcase.img +final_repo=http://dist.suse.de/install/SLP/SLE-12-Server-LATEST/x86_64/DVD1 +initial_repo=http://dist.suse.de/install/SLP/SLE-12-Server-LATEST/x86_64/DVD1 +force=false +guest_zypper_in__pattern_name="base" +guest_zypper_in__package_list=" +grub2 +kernel-default +less +master-boot-code +nfs-utils +parted +vim +" +guest_root_password="root" +diskname_inside_vm=/dev/sda + +case "$0" in + /*) progname="$0" ;; + *) progname="$PWD/$0" ;; +esac + +_exit() { + echo "Exiting '$0 $*'." + exit 1 +} + +_unrpm() { + CPIO_OPTS="--extract --unconditional --preserve-modification-time --make-directories --extract-over-symlinks" + FILES="$@" + for f in $FILES; do + echo -ne "$f:\t" + rpm2cpio $f | cpio ${CPIO_OPTS} + done +} + +until test $# -lt 1 +do + case "$1" in + --unrpm) shift ; _unrpm "$@" ; exit 0 ;; + -n) diskname_inside_vm="$2" ; shift ;; + -o) output_diskimage="$2" ; shift ;; + -R) initial_repo="$2" ; shift ;; + -r) final_repo="$2" ; shift ;; + -f) force=true ;; + -x) set -x ;; + *) echo "Unknown option '$1'" ; exit 1 ;; + esac + shift +done +if test -z "${initial_repo}" +then + echo "URL to initial repo required. Wrong -R option." + _exit +fi +if test -z "${final_repo}" +then + echo "URL to final repo required. Wrong -r option." + _exit +fi +if test -z "${output_diskimage}" +then + echo "Filename for temporary disk image required. Wrong -o option." + _exit +fi +if test -e "${output_diskimage}" +then + if test "${force}" = "false" + then + echo "Output diskimage '${output_diskimage}' exists." + echo "It will not be overwritten. Option '-f' exists to force overwrite." + _exit + fi +fi +zypper --version +cpio --version +guestfish --version +kvm="qemu-system-`uname -m`" +if $kvm --version +then + : good +else + kvm="qemu-kvm" + if $kvm --version + then + : + else + echo "No qemu-kvm found." + _exit + fi +fi + +mkdir -vp "${output_diskimage%/*}" +td=`mktemp -d --tmpdir=/dev/shm/${LOGNAME}` +tf=`mktemp --tmpdir=/dev/shm/${LOGNAME}` +_exit() { +rm -rf "$tf" +rm -rf "$td" +} +trap _exit EXIT +dir_repo=${td}/repos.d +dir_root=${td}/root +dir_cache=${td}/cache +mkdir -vp \ + ${dir_root} \ + ${dir_cache} \ + ${dir_repo} +cat > ${tf} < ${dir_repo}/tmp.repo <> etc/resolv.conf +echo nameserver 169.254.2.3 >> etc/resolv.conf +grep -w root /etc/passwd > etc/passwd +grep -w root /etc/group > etc/group +echo 'root::15209::::::' > etc/shadow +cat > etc/fstab </dev/kmsg " : \ +sh "depmod -a \$(get_kernel_version /boot/vmlinuz) ; mkinitrd -B" : \ +sh "dd if=/usr/lib/boot/MBR of=${diskname_inside_vm}" : \ +sh "echo GRUB_DISABLE_OS_PROBER=true >> /etc/default/grub " : \ +sh "echo GRUB_DISABLE_LINUX_RECOVERY=true >> /etc/default/grub " : \ +sh "echo GRUB_CMDLINE_LINUX_DEFAULT=\'quiet panic=9 video=800x600 \' >> /etc/default/grub " : \ +sh "grub2-mkconfig > /boot/grub2/grub.cfg " : \ +sh "grub2-install --force --verbose ${diskname_inside_vm}2 " : \ +sh "echo BOOTPROTO='dhcp' >> /etc/sysconfig/network/ifcfg-eth0" : \ +sh "echo STARTMODE='auto' >> /etc/sysconfig/network/ifcfg-eth0" : \ +sh "echo 'Password for User root is: ${guest_root_password}' >> /etc/issue" : \ +sh "echo >> /etc/issue" : \ +cat /etc/fstab : \ +quit +ls -lhsS "${output_diskimage}" + +: ${diskname_inside_vm} +case "${diskname_inside_vm}" in + *vda*) + qemu_drive_options=" + -drive file=${output_diskimage},cache=writeback,id=hd0,if=none \ + -device virtio-blk-pci,drive=hd0 \ + " + ;; + *sda*) + qemu_drive_options=" + -device virtio-scsi-pci,id=scsi \ + -drive file=${output_diskimage},cache=unsafe,format=raw,id=hd0,if=none \ + -device scsi-hd,drive=hd0 \ + " + ;; + *) + echo "${diskname_inside_vm} not handled" + _exit +esac +$kvm -enable-kvm \ + -global virtio-blk-pci.scsi=off \ + -enable-fips \ + -machine accel=kvm:tcg \ + -cpu host,+kvmclock \ + -m 500 \ + -no-reboot \ + -no-hpet \ + ${qemu_drive_options} \ + -device virtio-serial-pci \ + -serial stdio \ + -device VGA \ + -netdev user,id=usernet,net=169.254.0.0/16 \ + -device virtio-net-pci,netdev=usernet + +exit 0 diff --git a/libguestfs.test.simple.run-libugestfs-test-tool.sh b/libguestfs.test.simple.run-libugestfs-test-tool.sh new file mode 100644 index 0000000..2c37ea4 --- /dev/null +++ b/libguestfs.test.simple.run-libugestfs-test-tool.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# libguestfs-test-tool starts its temporary guest using a dummy disk image +# It creates a partition, a filesystem, mounts it and touches a file +# Once it is done the dummy image is removed again +# Per default it runs in --verbose mode, and our version trace the API calls +# +# Expected runtime: ca. 10 seconds +# +# Expected output: +# guest should start +# no "obvious" errors should be shown during the disk operation +# Somewhere at the end of the verbose output lines like this are expected: +# ... +# libguestfs: trace: touch "/hello" +# ... +# libguestfs: trace: touch = 0 +# +# +set -x +set -e +unset LANG +unset ${!LC_*} +cpus=`grep -Ec 'cpu[0-9]' /proc/stat || echo 1` + +libguestfs-test-tool -V +time libguestfs-test-tool diff --git a/makefile-ocaml-find-guestfs.patch b/makefile-ocaml-find-guestfs.patch new file mode 100644 index 0000000..fbe1ab5 --- /dev/null +++ b/makefile-ocaml-find-guestfs.patch @@ -0,0 +1,44 @@ +--- libguestfs-1.44.2/common/mlprogress/Makefile.am.orig 2021-09-14 10:01:16.710596638 -0600 ++++ libguestfs-1.44.2/common/mlprogress/Makefile.am 2021-09-14 10:01:25.526596848 -0600 +@@ -67,7 +67,7 @@ BOBJECTS = $(SOURCES_ML:.ml=.cmo) + XOBJECTS = $(BOBJECTS:.cmo=.cmx) + + OCAMLPACKAGES = \ +- -package str,unix,guestfs \ ++ -package str,unix \ + -I $(top_builddir)/common/utils/.libs \ + -I $(top_builddir)/ocaml \ + -I $(builddir) +--- libguestfs-1.44.2/common/mlvisit/Makefile.am.orig 2021-09-14 10:37:51.790648944 -0600 ++++ libguestfs-1.44.2/common/mlvisit/Makefile.am 2021-09-14 10:44:53.878659002 -0600 +@@ -68,7 +68,7 @@ BOBJECTS = $(SOURCES_ML:.ml=.cmo) + XOBJECTS = $(BOBJECTS:.cmo=.cmx) + + OCAMLPACKAGES = \ +- -package str,unix,guestfs \ ++ -package str,unix \ + -I $(top_builddir)/common/mlutils \ + -I $(top_builddir)/ocaml \ + -I $(top_builddir)/common/utils/.libs \ +--- libguestfs-1.44.2/common/mltools/Makefile.am.orig 2021-09-14 10:38:03.082649213 -0600 ++++ libguestfs-1.44.2/common/mltools/Makefile.am 2021-09-14 10:45:08.230659344 -0600 +@@ -114,7 +114,7 @@ BOBJECTS = $(SOURCES_ML:.ml=.cmo) + XOBJECTS = $(BOBJECTS:.cmo=.cmx) + + OCAMLPACKAGES = \ +- -package str,unix,guestfs \ ++ -package str,unix \ + -I $(top_builddir)/common/utils/.libs \ + -I $(top_builddir)/gnulib/lib/.libs \ + -I $(top_builddir)/ocaml \ +--- libguestfs-1.44.2/common/mlcustomize/Makefile.am.orig 2021-09-14 10:44:24.598658304 -0600 ++++ libguestfs-1.44.2/common/mlcustomize/Makefile.am 2021-09-14 10:44:35.654658567 -0600 +@@ -82,7 +82,7 @@ BOBJECTS = $(SOURCES_ML:.ml=.cmo) + XOBJECTS = $(BOBJECTS:.cmo=.cmx) + + OCAMLPACKAGES = \ +- -package str,unix,guestfs \ ++ -package str,unix \ + -I $(top_builddir)/common/utils/.libs \ + -I $(top_builddir)/ocaml \ + -I $(top_builddir)/common/mlstdutils \ diff --git a/netconfig.patch b/netconfig.patch new file mode 100644 index 0000000..63f0cfe --- /dev/null +++ b/netconfig.patch @@ -0,0 +1,12 @@ +Index: libguestfs-1.44.2/appliance/packagelist.in +=================================================================== +--- libguestfs-1.44.2.orig/appliance/packagelist.in ++++ libguestfs-1.44.2/appliance/packagelist.in +@@ -118,6 +118,7 @@ ifelse(SUSE,1, + dnl It seems no other augeas package depends on it. + augeas-lenses + btrfsprogs ++ busybox + cdrkit-cdrtools-compat + cryptsetup + dhcpcd