From 6854e54768d27752888efe98dc66bcbb6645a147 Mon Sep 17 00:00:00 2001 From: Richard W.M. Jones Date: Mar 27 2014 12:15:45 +0000 Subject: Libguestfs 1.26. - Sync with Rawhide. - This requires supermin >= 5. --- diff --git a/0001-builder-Don-t-run-virt-resize-when-not-necessary.patch b/0001-builder-Don-t-run-virt-resize-when-not-necessary.patch deleted file mode 100644 index d824bc3..0000000 --- a/0001-builder-Don-t-run-virt-resize-when-not-necessary.patch +++ /dev/null @@ -1,155 +0,0 @@ -From 45069d2a894e680441b670e751efb8b35c13f38f Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 22 Oct 2013 13:52:25 +0100 -Subject: [PATCH] builder: Don't run virt-resize when not necessary. - -If: - - the output is a regular file - - the output format is raw - - the user didn't specify the --size option -then we don't need to run virt-resize. Simply uncompress -the template directly to the output file. - -(cherry picked from commit 2f3a3e308af8012501437f723471a66537ecbf64) ---- - builder/builder.ml | 70 +++++++++++++++++++++++++++++++++++++----------------- - 1 file changed, 48 insertions(+), 22 deletions(-) - -diff --git a/builder/builder.ml b/builder/builder.ml -index 18c07fc..5f6ff3b 100644 ---- a/builder/builder.ml -+++ b/builder/builder.ml -@@ -234,7 +234,12 @@ let main () = - - Sigchecker.verify_detached sigchecker template sigfile in - -- let output, size, format, delete_output_file, resize_sparse = -+ (* Plan how to create the output. This depends on: -+ * - did the user specify --output? -+ * - is the output a block device? -+ * - did the user specify --size? -+ *) -+ let output, size, format, delete_output_file, do_resize, resize_sparse = - let headroom = 256L *^ 1024L *^ 1024L in - - match output with -@@ -256,22 +261,22 @@ let main () = - (* Dummy: The output file is never deleted in this case. *) - let delete_output_file = ref false in - -- output, None, format, delete_output_file, false -+ output, None, format, delete_output_file, true, false - - (* Regular file output. Note the file gets deleted. *) - | _ -> - (* Check the --size option. *) -- let size = -+ let size, do_resize = - let { Index_parser.size = default_size } = entry in - match size with -- | None -> default_size +^ headroom -+ | None -> default_size, false - | Some size -> - if size < default_size +^ headroom then ( - eprintf (f_"%s: --size is too small for this disk image, minimum size is %s\n") - prog (human_size default_size); - exit 1 - ); -- size in -+ size, true in - - (* Create the output file. *) - let output, format = -@@ -282,6 +287,14 @@ let main () = - | Some output, None -> output, "raw" - | Some output, Some format -> output, format in - -+ (* If the input format != output format then we must run virt-resize. *) -+ let do_resize = -+ let input_format = -+ match entry with -+ | { Index_parser.format = Some format } -> format -+ | { Index_parser.format = None } -> "raw" in -+ if input_format <> format then true else do_resize in -+ - msg (f_"Creating disk image: %s") output; - let cmd = - sprintf "qemu-img create -f %s%s %s %Ld%s" -@@ -305,30 +318,42 @@ let main () = - in - at_exit delete_file; - -- output, Some size, format, delete_output_file, true in -+ output, Some size, format, delete_output_file, do_resize, true in - -- if is_char_device output then ( -- eprintf (f_"%s: cannot output to a character device or /dev/null\n") prog; -- exit 1 -- ); -- -- let source = -- (* Uncompress it to a temporary file. *) -+ if not do_resize then ( -+ (* If the user did not specify --size and the output is a regular -+ * file and the format is raw, then we just uncompress the template -+ * directly to the output file. This is fast but less flexible. -+ *) - let { Index_parser.file_uri = file_uri } = entry in -- let tmpfile = Filename.temp_file "vbsrc" ".img" in -- let cmd = sprintf "xzcat %s > %s" (quote template) (quote tmpfile) in -+ let cmd = sprintf "xzcat %s > %s" (quote template) (quote output) in - if debug then eprintf "%s\n%!" cmd; - msg (f_"Uncompressing: %s") file_uri; - let r = Sys.command cmd in - if r <> 0 then ( - eprintf (f_"%s: error: failed to uncompress template\n") prog; - exit 1 -- ); -- unlink_on_exit tmpfile; -- tmpfile in -+ ) -+ ) else ( -+ (* If none of the above apply, uncompress to a temporary file and -+ * run virt-resize on the result. -+ *) -+ let tmpfile = -+ (* Uncompress it to a temporary file. *) -+ let { Index_parser.file_uri = file_uri } = entry in -+ let tmpfile = Filename.temp_file "vbsrc" ".img" in -+ let cmd = sprintf "xzcat %s > %s" (quote template) (quote tmpfile) in -+ if debug then eprintf "%s\n%!" cmd; -+ msg (f_"Uncompressing: %s") file_uri; -+ let r = Sys.command cmd in -+ if r <> 0 then ( -+ eprintf (f_"%s: error: failed to uncompress template\n") prog; -+ exit 1 -+ ); -+ unlink_on_exit tmpfile; -+ tmpfile in - -- (* Resize the source to the output file. *) -- let () = -+ (* Resize the source to the output file. *) - (match size with - | None -> - msg (f_"Running virt-resize to expand the disk") -@@ -353,13 +378,14 @@ let main () = - (match lvexpand with - | None -> "" - | Some lvexpand -> sprintf " --lv-expand %s" (quote lvexpand)) -- (quote source) (quote output) in -+ (quote tmpfile) (quote output) in - if debug then eprintf "%s\n%!" cmd; - let r = Sys.command cmd in - if r <> 0 then ( - eprintf (f_"%s: error: virt-resize failed\n") prog; - exit 1 -- ) in -+ ) -+ ); - - (* Now mount the output disk so we can make changes. *) - msg (f_"Opening the new disk"); --- -1.8.5.3 - diff --git a/0002-builder-Make-xzcat-binary-configurable-and-use-AC_PA.patch b/0002-builder-Make-xzcat-binary-configurable-and-use-AC_PA.patch deleted file mode 100644 index 933810c..0000000 --- a/0002-builder-Make-xzcat-binary-configurable-and-use-AC_PA.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 43799a9fd9253da29496bb5e0647ee970bb80b34 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 22 Oct 2013 14:09:20 +0100 -Subject: [PATCH] builder: Make xzcat binary configurable and use AC_PATH_PROG. - -(cherry picked from commit 0e18bccb648f8c96366ae53746d83bd009f924f7) ---- - builder/builder.ml | 9 +++++++-- - configure.ac | 4 ++++ - mllib/config.ml.in | 2 ++ - 3 files changed, 13 insertions(+), 2 deletions(-) - -diff --git a/builder/builder.ml b/builder/builder.ml -index 5f6ff3b..b1cc1f0 100644 ---- a/builder/builder.ml -+++ b/builder/builder.ml -@@ -320,13 +320,18 @@ let main () = - - output, Some size, format, delete_output_file, do_resize, true in - -+ (* Create xzcat command to uncompress from input to output. *) -+ let xzcat_command input output = -+ sprintf "%s %s > %s" Config.xzcat input output -+ in -+ - if not do_resize then ( - (* If the user did not specify --size and the output is a regular - * file and the format is raw, then we just uncompress the template - * directly to the output file. This is fast but less flexible. - *) - let { Index_parser.file_uri = file_uri } = entry in -- let cmd = sprintf "xzcat %s > %s" (quote template) (quote output) in -+ let cmd = xzcat_command template output in - if debug then eprintf "%s\n%!" cmd; - msg (f_"Uncompressing: %s") file_uri; - let r = Sys.command cmd in -@@ -342,7 +347,7 @@ let main () = - (* Uncompress it to a temporary file. *) - let { Index_parser.file_uri = file_uri } = entry in - let tmpfile = Filename.temp_file "vbsrc" ".img" in -- let cmd = sprintf "xzcat %s > %s" (quote template) (quote tmpfile) in -+ let cmd = xzcat_command template tmpfile in - if debug then eprintf "%s\n%!" cmd; - msg (f_"Uncompressing: %s") file_uri; - let r = Sys.command cmd in -diff --git a/configure.ac b/configure.ac -index 57d0ca3..c10e7bb 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -704,6 +704,10 @@ if test "x$WRESTOOL" != "xno"; then - AC_DEFINE_UNQUOTED([WRESTOOL],["$WRESTOOL"],[Name of wrestool program.]) - fi - -+dnl Check for xzcat (required). -+AC_PATH_PROGS([XZCAT],[xzcat],[no]) -+test "x$XZCAT" = "xno" && AC_MSG_ERROR([xzcat must be installed]) -+ - dnl Check for QEMU for running binaries on this $host_cpu, fall - dnl back to basic 'qemu'. Allow the user to override it. - qemu_system="$( -diff --git a/mllib/config.ml.in b/mllib/config.ml.in -index d18bf7b..129741d 100644 ---- a/mllib/config.ml.in -+++ b/mllib/config.ml.in -@@ -18,3 +18,5 @@ - - let package_name = "@PACKAGE_NAME@" - let package_version = "@PACKAGE_VERSION@" -+ -+let xzcat = "@XZCAT@" --- -1.8.5.3 - diff --git a/0003-builder-Use-pxzcat-optionally-to-speed-up-xzcat-step.patch b/0003-builder-Use-pxzcat-optionally-to-speed-up-xzcat-step.patch deleted file mode 100644 index e3d4d29..0000000 --- a/0003-builder-Use-pxzcat-optionally-to-speed-up-xzcat-step.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 56a6b1ad64c0fa388406fa3064cc4abdf0159ca6 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 22 Oct 2013 14:22:46 +0100 -Subject: [PATCH] builder: Use pxzcat (optionally) to speed up xzcat step. - -(cherry picked from commit d4450c6590744ab96c7e0c3b21325d1eff666f29) ---- - README | 3 +++ - builder/builder.ml | 6 ++++-- - configure.ac | 3 +++ - mllib/config.ml.in | 4 ++++ - 4 files changed, 14 insertions(+), 2 deletions(-) - -diff --git a/README b/README -index d9c0219..0e442e1 100644 ---- a/README -+++ b/README -@@ -170,6 +170,9 @@ The full requirements are described below. - | gpg | | O | Used by virt-builder for digital | - | | | | signatures | - +--------------+-------------+---+-----------------------------------------+ -+| pxzcat | | O | Can be used by virt-builder for fast | -+| | | | uncompression of templates. | -++--------------+-------------+---+-----------------------------------------+ - | findlib | | O | For the OCaml bindings. | - +--------------+-------------+---+-----------------------------------------+ - | ocaml-gettext| | O | For localizing OCaml virt-* tools. | -diff --git a/builder/builder.ml b/builder/builder.ml -index b1cc1f0..4fc8a71 100644 ---- a/builder/builder.ml -+++ b/builder/builder.ml -@@ -320,9 +320,11 @@ let main () = - - output, Some size, format, delete_output_file, do_resize, true in - -- (* Create xzcat command to uncompress from input to output. *) -+ (* Create xzcat/pxzcat command to uncompress from input to output. *) - let xzcat_command input output = -- sprintf "%s %s > %s" Config.xzcat input output -+ match Config.pxzcat with -+ | None -> sprintf "%s %s > %s" Config.xzcat input output -+ | Some pxzcat -> sprintf "%s %s -o %s" pxzcat input output - in - - if not do_resize then ( -diff --git a/configure.ac b/configure.ac -index c10e7bb..da777d4 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -708,6 +708,9 @@ dnl Check for xzcat (required). - AC_PATH_PROGS([XZCAT],[xzcat],[no]) - test "x$XZCAT" = "xno" && AC_MSG_ERROR([xzcat must be installed]) - -+dnl Check for pxzcat (optional). -+AC_PATH_PROGS([PXZCAT],[pxzcat],[no]) -+ - dnl Check for QEMU for running binaries on this $host_cpu, fall - dnl back to basic 'qemu'. Allow the user to override it. - qemu_system="$( -diff --git a/mllib/config.ml.in b/mllib/config.ml.in -index 129741d..5586c5c 100644 ---- a/mllib/config.ml.in -+++ b/mllib/config.ml.in -@@ -20,3 +20,7 @@ let package_name = "@PACKAGE_NAME@" - let package_version = "@PACKAGE_VERSION@" - - let xzcat = "@XZCAT@" -+let pxzcat = -+ match "@PXZCAT@" with -+ | "no" -> None -+ | path -> Some path --- -1.8.5.3 - diff --git a/0004-builder-Add-no-sync-option-to-avoid-sync-on-exit.patch b/0004-builder-Add-no-sync-option-to-avoid-sync-on-exit.patch deleted file mode 100644 index 2298f1a..0000000 --- a/0004-builder-Add-no-sync-option-to-avoid-sync-on-exit.patch +++ /dev/null @@ -1,101 +0,0 @@ -From 575242580f9c4c1ffb52a8887ac6e2e85becb3b6 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 22 Oct 2013 22:28:27 +0100 -Subject: [PATCH] builder: Add --no-sync option to avoid sync on exit. - -(cherry picked from commit 3f46a92ed5737bb8d75630a39729f95bc96417f6) ---- - builder/builder.ml | 5 +++-- - builder/cmdline.ml | 6 +++++- - builder/virt-builder.pod | 17 +++++++++++++++++ - 3 files changed, 25 insertions(+), 3 deletions(-) - -diff --git a/builder/builder.ml b/builder/builder.ml -index 4fc8a71..9e41d39 100644 ---- a/builder/builder.ml -+++ b/builder/builder.ml -@@ -40,7 +40,7 @@ let main () = - attach, cache, check_signature, curl, debug, delete, edit, fingerprint, - firstboot, run, format, gpg, hostname, install, list_long, network, output, - password_crypto, quiet, root_password, scrub, scrub_logfile, size, source, -- upload = -+ sync, upload = - parse_cmdline () in - - (* Timestamped messages in ordinary, non-debug non-quiet mode. *) -@@ -732,7 +732,8 @@ exec >>%s 2>&1 - * and therefore bypasses the host cache). In general you should not - * use cache=none. - *) -- Fsync.file output; -+ if sync then -+ Fsync.file output; - - (* Now that we've finished the build, don't delete the output file on - * exit. -diff --git a/builder/cmdline.ml b/builder/cmdline.ml -index 7bbde70..c8e9c46 100644 ---- a/builder/cmdline.ml -+++ b/builder/cmdline.ml -@@ -161,6 +161,8 @@ let parse_cmdline () = - with Not_found -> "http://libguestfs.org/download/builder/index.asc" in - let source = ref source in - -+ let sync = ref true in -+ - let upload = ref [] in - let add_upload arg = - let i = -@@ -232,6 +234,7 @@ let parse_cmdline () = - "--scrub", Arg.String add_scrub, "name" ^ " " ^ s_"Scrub a file"; - "--size", Arg.String set_size, "size" ^ " " ^ s_"Set output disk size"; - "--source", Arg.Set_string source, "URL" ^ " " ^ s_"Set source URL"; -+ "--no-sync", Arg.Clear sync, " " ^ s_"Do not fsync output file on exit"; - "--upload", Arg.String add_upload, "file:dest" ^ " " ^ s_"Upload file to dest"; - "-v", Arg.Set debug, " " ^ s_"Enable debugging messages"; - "--verbose", Arg.Set debug, ditto; -@@ -287,6 +290,7 @@ read the man page virt-builder(1). - let scrub_logfile = !scrub_logfile in - let size = !size in - let source = !source in -+ let sync = !sync in - let upload = List.rev !upload in - - (* Check options. *) -@@ -343,4 +347,4 @@ read the man page virt-builder(1). - attach, cache, check_signature, curl, debug, delete, edit, fingerprint, - firstboot, run, format, gpg, hostname, install, list_long, network, output, - password_crypto, quiet, root_password, scrub, scrub_logfile, size, source, -- upload -+ sync, upload -diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod -index d31640e..ee53a8a 100644 ---- a/builder/virt-builder.pod -+++ b/builder/virt-builder.pod -@@ -410,6 +410,23 @@ You don't have a host network (eg. in secure/restricted environments). - - =back - -+=item B<--no-sync> -+ -+Do not sync the output file on exit. -+ -+Virt-builder fsync's the output file or disk image when it exits. -+ -+The reason is that qemu/KVM's default caching mode is C or -+C, both of which bypass the host page cache. Therefore -+these would not work correctly if you immediately started the guest -+after running virt-builder - they would not see the complete output -+file. (Note that you should not use these caching modes - they are -+fundamentally broken for this and other reasons.) -+ -+If you are not using these broken caching modes, you can use -+I<--no-sync> to avoid this unnecessary sync and gain considerable -+extra performance. -+ - =item B<--notes> os-version - - List any notes associated with this guest, then exit (this does not do --- -1.8.5.3 - diff --git a/0005-builder-Add-mkdir-option-to-create-directories.patch b/0005-builder-Add-mkdir-option-to-create-directories.patch deleted file mode 100644 index d8cdb91..0000000 --- a/0005-builder-Add-mkdir-option-to-create-directories.patch +++ /dev/null @@ -1,137 +0,0 @@ -From 041ae7e3b947f4d5024fd2c1f0484430d2adbc31 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 25 Oct 2013 13:35:51 +0100 -Subject: [PATCH] builder: Add --mkdir option to create directories. - -(cherry picked from commit 99840550d5508b228ee4b2533ad94da517873f76) ---- - builder/builder.ml | 13 ++++++++++--- - builder/cmdline.ml | 12 +++++++++--- - builder/test-virt-builder.sh | 1 + - builder/virt-builder.pod | 12 ++++++++++++ - 4 files changed, 32 insertions(+), 6 deletions(-) - -diff --git a/builder/builder.ml b/builder/builder.ml -index 9e41d39..acd016d 100644 ---- a/builder/builder.ml -+++ b/builder/builder.ml -@@ -38,9 +38,9 @@ let main () = - (* Command line argument parsing - see cmdline.ml. *) - let mode, arg, - attach, cache, check_signature, curl, debug, delete, edit, fingerprint, -- firstboot, run, format, gpg, hostname, install, list_long, network, output, -- password_crypto, quiet, root_password, scrub, scrub_logfile, size, source, -- sync, upload = -+ firstboot, run, format, gpg, hostname, install, list_long, mkdirs, -+ network, output, password_crypto, quiet, root_password, scrub, -+ scrub_logfile, size, source, sync, upload = - parse_cmdline () in - - (* Timestamped messages in ordinary, non-debug non-quiet mode. *) -@@ -572,6 +572,13 @@ exec >>%s 2>&1 - do_run ~display:cmd cmd - ); - -+ (* Make directories. *) -+ List.iter ( -+ fun dir -> -+ msg (f_"Making directory: %s") dir; -+ g#mkdir_p dir -+ ) mkdirs; -+ - (* Upload files. *) - List.iter ( - fun (file, dest) -> -diff --git a/builder/cmdline.ml b/builder/cmdline.ml -index c8e9c46..7ac114a 100644 ---- a/builder/cmdline.ml -+++ b/builder/cmdline.ml -@@ -119,6 +119,10 @@ let parse_cmdline () = - in - - let list_long = ref false in -+ -+ let mkdirs = ref [] in -+ let add_mkdir arg = mkdirs := arg :: !mkdirs in -+ - let network = ref true in - let output = ref "" in - -@@ -217,6 +221,7 @@ let parse_cmdline () = - "--long", Arg.Set list_long, ditto; - "--no-logfile", Arg.Set scrub_logfile, " " ^ s_"Scrub build log file"; - "--long-options", Arg.Unit display_long_options, " " ^ s_"List long options"; -+ "--mkdir", Arg.String add_mkdir, "dir" ^ " " ^ s_"Create directory"; - "--network", Arg.Set network, " " ^ s_"Enable appliance network (default)"; - "--no-network", Arg.Clear network, " " ^ s_"Disable appliance network"; - "--notes", Arg.Unit notes_mode, " " ^ s_"Display installation notes"; -@@ -281,6 +286,7 @@ read the man page virt-builder(1). - let hostname = !hostname in - let install = List.rev !install in - let list_long = !list_long in -+ let mkdirs = List.rev !mkdirs in - let network = !network in - let output = match !output with "" -> None | s -> Some s in - let password_crypto = !password_crypto in -@@ -345,6 +351,6 @@ read the man page virt-builder(1). - - mode, arg, - attach, cache, check_signature, curl, debug, delete, edit, fingerprint, -- firstboot, run, format, gpg, hostname, install, list_long, network, output, -- password_crypto, quiet, root_password, scrub, scrub_logfile, size, source, -- sync, upload -+ firstboot, run, format, gpg, hostname, install, list_long, mkdirs, -+ network, output, password_crypto, quiet, root_password, scrub, -+ scrub_logfile, size, source, sync, upload -diff --git a/builder/test-virt-builder.sh b/builder/test-virt-builder.sh -index c8d2e58..6f76972 100755 ---- a/builder/test-virt-builder.sh -+++ b/builder/test-virt-builder.sh -@@ -54,6 +54,7 @@ $VG ./virt-builder phony-fedora \ - -o $output --size 2G --format $format \ - --hostname test.example.com \ - --root-password password:123456 \ -+ --mkdir /etc/foo/bar/baz \ - --upload Makefile:/Makefile \ - --upload Makefile:/etc \ - --delete /Makefile \ -diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod -index ee53a8a..dc08a6d 100644 ---- a/builder/virt-builder.pod -+++ b/builder/virt-builder.pod -@@ -19,6 +19,7 @@ virt-builder - Build virtual machine images quickly - [--root-password SELECTOR] - [--hostname HOSTNAME] - [--install PKG,[PKG...]] -+ [--mkdir DIR] - [--upload FILE:DEST] - [--edit FILE:EXPR] - [--delete FILE] [--scrub FILE] -@@ -364,6 +365,13 @@ the image was built, use this option. - - See also: L. - -+=item B<--mkdir> DIR -+ -+Create a directory in the guest. -+ -+This uses S> so any intermediate directories are created, -+and it also works if the directory already exists. -+ - =item B<--network> - - =item B<--no-network> -@@ -763,6 +771,10 @@ Packages are installed (I<--install>). - - =item * - -+Directories are created (I<--mkdir>). -+ -+=item * -+ - Files are uploaded (I<--upload>). - - =item * --- -1.8.5.3 - diff --git a/0006-builder-Allow-upload-to-a-directory.patch b/0006-builder-Allow-upload-to-a-directory.patch deleted file mode 100644 index cae7d35..0000000 --- a/0006-builder-Allow-upload-to-a-directory.patch +++ /dev/null @@ -1,28 +0,0 @@ -From bff4cf7f7ce67b7506570d74226949aa76bea80d Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 26 Oct 2013 11:27:06 +0100 -Subject: [PATCH] builder: Allow --upload to a directory. - -Also set the owner and permissions on the destination file correctly. - -(cherry picked from commit 10c849ed1cb4375c5ef811197fa0a3206d365b86) ---- - builder/test-virt-builder.sh | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/builder/test-virt-builder.sh b/builder/test-virt-builder.sh -index 6f76972..30c3cf8 100755 ---- a/builder/test-virt-builder.sh -+++ b/builder/test-virt-builder.sh -@@ -56,7 +56,7 @@ $VG ./virt-builder phony-fedora \ - --root-password password:123456 \ - --mkdir /etc/foo/bar/baz \ - --upload Makefile:/Makefile \ -- --upload Makefile:/etc \ -+ --upload Makefile:/etc/foo/bar/baz \ - --delete /Makefile \ - --firstboot Makefile --firstboot-command 'echo "hello"' \ - --firstboot-install "minicom,inkscape" --- -1.8.5.3 - diff --git a/0007-builder-Add-write-option-to-write-a-literal-file.patch b/0007-builder-Add-write-option-to-write-a-literal-file.patch deleted file mode 100644 index b8f71a9..0000000 --- a/0007-builder-Add-write-option-to-write-a-literal-file.patch +++ /dev/null @@ -1,135 +0,0 @@ -From 74aff54da61301859bf9f0ef744adf7672093f5f Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 26 Oct 2013 11:40:48 +0100 -Subject: [PATCH] builder: Add --write option to write a literal file. - -(cherry picked from commit 0520aa3c42fbb174be37ef75b19390855d225897) ---- - builder/builder.ml | 9 ++++++++- - builder/cmdline.ml | 17 ++++++++++++++++- - builder/test-virt-builder.sh | 1 + - builder/virt-builder.pod | 9 +++++++++ - 4 files changed, 34 insertions(+), 2 deletions(-) - -diff --git a/builder/builder.ml b/builder/builder.ml -index acd016d..f247cd2 100644 ---- a/builder/builder.ml -+++ b/builder/builder.ml -@@ -40,7 +40,7 @@ let main () = - attach, cache, check_signature, curl, debug, delete, edit, fingerprint, - firstboot, run, format, gpg, hostname, install, list_long, mkdirs, - network, output, password_crypto, quiet, root_password, scrub, -- scrub_logfile, size, source, sync, upload = -+ scrub_logfile, size, source, sync, upload, writes = - parse_cmdline () in - - (* Timestamped messages in ordinary, non-debug non-quiet mode. *) -@@ -579,6 +579,13 @@ exec >>%s 2>&1 - g#mkdir_p dir - ) mkdirs; - -+ (* Write files. *) -+ List.iter ( -+ fun (file, content) -> -+ msg (f_"Writing: %s") file; -+ g#write file content -+ ) writes; -+ - (* Upload files. *) - List.iter ( - fun (file, dest) -> -diff --git a/builder/cmdline.ml b/builder/cmdline.ml -index 7ac114a..28a1643 100644 ---- a/builder/cmdline.ml -+++ b/builder/cmdline.ml -@@ -184,6 +184,19 @@ let parse_cmdline () = - upload := (file, dest) :: !upload - in - -+ let writes = ref [] in -+ let add_write arg = -+ let i = -+ try String.index arg ':' -+ with Not_found -> -+ eprintf (f_"%s: invalid --write format, see the man page.\n") prog; -+ exit 1 in -+ let len = String.length arg in -+ let file = String.sub arg 0 i in -+ let content = String.sub arg (i+1) (len-(i+1)) in -+ writes := (file, content) :: !writes -+ in -+ - let ditto = " -\"-" in - let argspec = Arg.align [ - "--attach", Arg.String attach_disk, "iso" ^ " " ^ s_"Attach data disk/ISO during install"; -@@ -245,6 +258,7 @@ let parse_cmdline () = - "--verbose", Arg.Set debug, ditto; - "-V", Arg.Unit display_version, " " ^ s_"Display version and exit"; - "--version", Arg.Unit display_version, ditto; -+ "--write", Arg.String add_write, "file:content" ^ " " ^ s_"Write file"; - ] in - long_options := argspec; - -@@ -298,6 +312,7 @@ read the man page virt-builder(1). - let source = !source in - let sync = !sync in - let upload = List.rev !upload in -+ let writes = List.rev !writes in - - (* Check options. *) - let arg = -@@ -353,4 +368,4 @@ read the man page virt-builder(1). - attach, cache, check_signature, curl, debug, delete, edit, fingerprint, - firstboot, run, format, gpg, hostname, install, list_long, mkdirs, - network, output, password_crypto, quiet, root_password, scrub, -- scrub_logfile, size, source, sync, upload -+ scrub_logfile, size, source, sync, upload, writes -diff --git a/builder/test-virt-builder.sh b/builder/test-virt-builder.sh -index 30c3cf8..438f2e9 100755 ---- a/builder/test-virt-builder.sh -+++ b/builder/test-virt-builder.sh -@@ -55,6 +55,7 @@ $VG ./virt-builder phony-fedora \ - --hostname test.example.com \ - --root-password password:123456 \ - --mkdir /etc/foo/bar/baz \ -+ --write '/etc/foo/bar/baz/foo:Hello World' \ - --upload Makefile:/Makefile \ - --upload Makefile:/etc/foo/bar/baz \ - --delete /Makefile \ -diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod -index dc08a6d..e40dfd4 100644 ---- a/builder/virt-builder.pod -+++ b/builder/virt-builder.pod -@@ -20,6 +20,7 @@ virt-builder - Build virtual machine images quickly - [--hostname HOSTNAME] - [--install PKG,[PKG...]] - [--mkdir DIR] -+ [--write FILE:CONTENT] - [--upload FILE:DEST] - [--edit FILE:EXPR] - [--delete FILE] [--scrub FILE] -@@ -586,6 +587,10 @@ your bug report. - - Display version number and exit. - -+=item B<--write> FILE:CONTENT -+ -+Write C to C. -+ - =back - - =head1 REFERENCE -@@ -775,6 +780,10 @@ Directories are created (I<--mkdir>). - - =item * - -+Files are written (I<--write>). -+ -+=item * -+ - Files are uploaded (I<--upload>). - - =item * --- -1.8.5.3 - diff --git a/0008-builder-Document-how-to-boot-VMs-directly-in-qemu-or.patch b/0008-builder-Document-how-to-boot-VMs-directly-in-qemu-or.patch deleted file mode 100644 index faf3c0c..0000000 --- a/0008-builder-Document-how-to-boot-VMs-directly-in-qemu-or.patch +++ /dev/null @@ -1,39 +0,0 @@ -From dad52974ac7e1127ed1ca56a01a22cbbfcb8a7c8 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 26 Oct 2013 14:45:30 +0100 -Subject: [PATCH] builder: Document how to boot VMs directly in qemu or KVM. - -(cherry picked from commit 8b34855684fb660823a2801a4a5e8be32a6cc40f) ---- - builder/virt-builder.pod | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - -diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod -index e40dfd4..a5f766d 100644 ---- a/builder/virt-builder.pod -+++ b/builder/virt-builder.pod -@@ -865,6 +865,21 @@ To boot up an instance of your image on a Nova compute node, do: - Use S> to list possible machine flavors. Use - S> to list running instances. - -+=head3 Booting directly using qemu or KVM -+ -+The qemu command line is not very stable or easy to use, hence libvirt -+should be used if possible. However a command line similar to the -+following could be used to boot the virtual machine: -+ -+ qemu-system-x86_64 \ -+ -machine accel=kvm:tcg \ -+ -cpu host \ -+ -m 2048 \ -+ -drive file=disk.img,format=raw,if=virtio -+ -+As with libvirt, it is very important that the correct format is -+chosen. It will be C unless the I<--format> option was used. -+ - =head2 DEBUGGING BUILDS - - If virt-builder fails with an error, then enable debugging (I<-v>) and --- -1.8.5.3 - diff --git a/0009-firstboot-Send-the-output-to-the-console-as-well-as-.patch b/0009-firstboot-Send-the-output-to-the-console-as-well-as-.patch deleted file mode 100644 index b1eb204..0000000 --- a/0009-firstboot-Send-the-output-to-the-console-as-well-as-.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 0b19f922eecd5fe5b8274e0a6355ab323ce53920 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 26 Oct 2013 17:09:06 +0100 -Subject: [PATCH] firstboot: Send the output to the console as well as to the - log file. - -For systemd: -Currently stdout+stderr go to the journal (these are effectively -empty unless there are gross errors). The output of the commands -goes to the log file. - -With this change, the output goes to the journal, the console and -the log file. - -For SysV-init: -Currently stdout+stderr go to the console (but these are effectively -empty). The output of the commands goes to the log file. - -With this change, the output goes to the console and the log file. - -(cherry picked from commit f114e28cc80eabdcf47c97e7e3895065cdfe4886) ---- - mllib/firstboot.ml | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - -diff --git a/mllib/firstboot.ml b/mllib/firstboot.ml -index 0207cc1..9e4c7b6 100644 ---- a/mllib/firstboot.ml -+++ b/mllib/firstboot.ml -@@ -45,16 +45,16 @@ let firstboot_sh = sprintf "\ - d=%s/scripts - logfile=~root/virt-sysprep-firstboot.log - --echo \"$0\" \"$@\" >>$logfile --echo \"Scripts dir: $d\" >>$logfile -+echo \"$0\" \"$@\" 2>&1 | tee $logfile -+echo \"Scripts dir: $d\" 2>&1 | tee $logfile - - if test \"$1\" = \"start\" - then - for f in $d/* ; do - if test -x \"$f\" - then -- echo '=== Running' $f '===' >>$logfile -- $f >>$logfile 2>&1 -+ echo '=== Running' $f '===' 2>&1 | tee $logfile -+ $f 2>&1 | tee $logfile - rm -f $f - fi - done -@@ -71,6 +71,8 @@ Before=prefdm.service - Type=oneshot - ExecStart=%s/firstboot.sh start - RemainAfterExit=yes -+StandardOutput=journal+console -+StandardError=inherit - - [Install] - WantedBy=default.target --- -1.8.5.3 - diff --git a/0010-builder-Add-a-section-on-performance-to-the-manual.patch b/0010-builder-Add-a-section-on-performance-to-the-manual.patch deleted file mode 100644 index 6608b1f..0000000 --- a/0010-builder-Add-a-section-on-performance-to-the-manual.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 699aa8c4bd1926b2de3e9b10354a3f17d5929c92 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sun, 27 Oct 2013 14:59:39 +0000 -Subject: [PATCH] builder: Add a section on performance to the manual. - -(cherry picked from commit 2937c035958f84986e84c47df49f79d19c4b5b59) ---- - builder/virt-builder.pod | 43 +++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 43 insertions(+) - -diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod -index a5f766d..cd20043 100644 ---- a/builder/virt-builder.pod -+++ b/builder/virt-builder.pod -@@ -1330,6 +1330,49 @@ want clones to have duplicate identities. - - See also: L. - -+=head2 PERFORMANCE -+ -+The most important aspect of getting good performance is caching. -+Templates gets downloaded into the cache the first time they are used, -+or if you use the I<--cache-all-templates> option. See L -+above for further information. -+ -+Packages required for the I<--install> option are downloaded using the -+host network connection. Setting the C, C -+and C environment variables to point to a local web cache -+may ensure they only need to be downloaded once. You can also try -+using a local package repository, although this can be complex to set -+up and varies according to which Linux distro you are trying to -+install. -+ -+=head3 Skipping virt-resize -+ -+Virt-builder can skip the virt-resize step under certain conditions. -+This makes virt-builder much faster. The conditions are: -+ -+=over 4 -+ -+=item * -+ -+the output must be a regular file (not a block device), B -+ -+=item * -+ -+the user did B use the I<--size> option, B -+ -+=item * -+ -+the output format is the same as the template format (usually raw). -+ -+=back -+ -+=head3 pxzcat -+ -+Virt-builder can use C (parallel xzcat) if available to -+uncompress the templates. The default is to use regular C -+which is single-threaded. Currently this has to be compiled in, -+ie. virt-builder will probably need to be recompiled to use pxzcat. -+ - =head2 USER MODE LINUX - - You can use virt-builder with the User-Mode Linux (UML) backend. This --- -1.8.5.3 - diff --git a/0011-builder-Add-m-memsize-and-smp-command-line-options.patch b/0011-builder-Add-m-memsize-and-smp-command-line-options.patch deleted file mode 100644 index 5c1db45..0000000 --- a/0011-builder-Add-m-memsize-and-smp-command-line-options.patch +++ /dev/null @@ -1,153 +0,0 @@ -From 4d47befa91da660e97cb71a63a362b85c9cc7fa4 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 29 Oct 2013 19:23:33 +0000 -Subject: [PATCH] builder: Add -m/--memsize and --smp command line options. - -(cherry picked from commit 42e445f98692c6344baafaab1da10e821288ac0a) ---- - builder/builder.ml | 6 ++++-- - builder/cmdline.ml | 15 +++++++++++++-- - builder/virt-builder.pod | 22 ++++++++++++++++------ - 3 files changed, 33 insertions(+), 10 deletions(-) - -diff --git a/builder/builder.ml b/builder/builder.ml -index f247cd2..2437d56 100644 ---- a/builder/builder.ml -+++ b/builder/builder.ml -@@ -38,9 +38,9 @@ let main () = - (* Command line argument parsing - see cmdline.ml. *) - let mode, arg, - attach, cache, check_signature, curl, debug, delete, edit, fingerprint, -- firstboot, run, format, gpg, hostname, install, list_long, mkdirs, -+ firstboot, run, format, gpg, hostname, install, list_long, memsize, mkdirs, - network, output, password_crypto, quiet, root_password, scrub, -- scrub_logfile, size, source, sync, upload, writes = -+ scrub_logfile, size, smp, source, sync, upload, writes = - parse_cmdline () in - - (* Timestamped messages in ordinary, non-debug non-quiet mode. *) -@@ -400,6 +400,8 @@ let main () = - let g = new G.guestfs () in - if debug then g#set_trace true; - -+ (match memsize with None -> () | Some memsize -> g#set_memsize memsize); -+ (match smp with None -> () | Some smp -> g#set_smp smp); - g#set_network network; - - (* The output disk is being created, so use cache=unsafe here. *) -diff --git a/builder/cmdline.ml b/builder/cmdline.ml -index 28a1643..97ccd89 100644 ---- a/builder/cmdline.ml -+++ b/builder/cmdline.ml -@@ -120,6 +120,9 @@ let parse_cmdline () = - - let list_long = ref false in - -+ let memsize = ref None in -+ let set_memsize arg = memsize := Some arg in -+ - let mkdirs = ref [] in - let add_mkdir arg = mkdirs := arg :: !mkdirs in - -@@ -160,6 +163,9 @@ let parse_cmdline () = - let size = ref None in - let set_size arg = size := Some (parse_size ~prog arg) in - -+ let smp = ref None in -+ let set_smp arg = smp := Some arg in -+ - let source = - try Sys.getenv "VIRT_BUILDER_SOURCE" - with Not_found -> "http://libguestfs.org/download/builder/index.asc" in -@@ -234,6 +240,8 @@ let parse_cmdline () = - "--long", Arg.Set list_long, ditto; - "--no-logfile", Arg.Set scrub_logfile, " " ^ s_"Scrub build log file"; - "--long-options", Arg.Unit display_long_options, " " ^ s_"List long options"; -+ "-m", Arg.Int set_memsize, "mb" ^ " " ^ s_"Set memory size"; -+ "--memsize", Arg.Int set_memsize, "mb" ^ ditto; - "--mkdir", Arg.String add_mkdir, "dir" ^ " " ^ s_"Create directory"; - "--network", Arg.Set network, " " ^ s_"Enable appliance network (default)"; - "--no-network", Arg.Clear network, " " ^ s_"Disable appliance network"; -@@ -251,6 +259,7 @@ let parse_cmdline () = - "--run-command", Arg.String add_run_cmd, "cmd+args" ^ " " ^ s_"Run command in disk image"; - "--scrub", Arg.String add_scrub, "name" ^ " " ^ s_"Scrub a file"; - "--size", Arg.String set_size, "size" ^ " " ^ s_"Set output disk size"; -+ "--smp", Arg.Int set_smp, "vcpus" ^ " " ^ s_"Set number of vCPUs"; - "--source", Arg.Set_string source, "URL" ^ " " ^ s_"Set source URL"; - "--no-sync", Arg.Clear sync, " " ^ s_"Do not fsync output file on exit"; - "--upload", Arg.String add_upload, "file:dest" ^ " " ^ s_"Upload file to dest"; -@@ -300,6 +309,7 @@ read the man page virt-builder(1). - let hostname = !hostname in - let install = List.rev !install in - let list_long = !list_long in -+ let memsize = !memsize in - let mkdirs = List.rev !mkdirs in - let network = !network in - let output = match !output with "" -> None | s -> Some s in -@@ -309,6 +319,7 @@ read the man page virt-builder(1). - let scrub = List.rev !scrub in - let scrub_logfile = !scrub_logfile in - let size = !size in -+ let smp = !smp in - let source = !source in - let sync = !sync in - let upload = List.rev !upload in -@@ -366,6 +377,6 @@ read the man page virt-builder(1). - - mode, arg, - attach, cache, check_signature, curl, debug, delete, edit, fingerprint, -- firstboot, run, format, gpg, hostname, install, list_long, mkdirs, -+ firstboot, run, format, gpg, hostname, install, list_long, memsize, mkdirs, - network, output, password_crypto, quiet, root_password, scrub, -- scrub_logfile, size, source, sync, upload, writes -+ scrub_logfile, size, smp, source, sync, upload, writes -diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod -index cd20043..66ed030 100644 ---- a/builder/virt-builder.pod -+++ b/builder/virt-builder.pod -@@ -366,6 +366,18 @@ the image was built, use this option. - - See also: L. - -+=item B<-m> MB -+ -+=item B<--memsize> MB -+ -+Change the amount of memory allocated to I<--run> scripts. Increase -+this if you find that I<--run> scripts or the I<--install> option are -+running out of memory. -+ -+The default can be found with this command: -+ -+ guestfish get-memsize -+ - =item B<--mkdir> DIR - - Create a directory in the guest. -@@ -544,6 +556,10 @@ used. - To specify size in bytes, the number must be followed by the lowercase - letter I, eg: S>. - -+=item B<--smp> N -+ -+Enable N E 2 virtual CPUs for I<--run> scripts to use. -+ - =item B<--source> URL - - Set the source URL to look for templates. If not specified it -@@ -1438,12 +1454,6 @@ are actually interpreted by L, not virt-builder. - - Used to determine the location of the template cache. See L. - --=item C -- --The size (in megabytes) of the appliance. The default can be found --using the command S>. Increase this if you --find that I<--run> scripts are running out of memory. -- - =item C - - Set the default value for the GPG signature fingerprint (see --- -1.8.5.3 - diff --git a/0012-builder-Allow-multiple-source-paths-to-be-specified.patch b/0012-builder-Allow-multiple-source-paths-to-be-specified.patch deleted file mode 100644 index cc48345..0000000 --- a/0012-builder-Allow-multiple-source-paths-to-be-specified.patch +++ /dev/null @@ -1,450 +0,0 @@ -From 476b858c15762d4e1bf04449c5c03385702f8ba3 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 1 Nov 2013 14:16:34 +0000 -Subject: [PATCH] builder: Allow multiple source paths to be specified. - -Users can now specify multiple source paths, eg: - - virt-builder --source http://example.com/foo \ - --source http://example.com/bar - -to get templates from multiple places. - -There is still only one built-in path, but we can add more later. - -(cherry picked from commit bb4e882d61b49045aabd35912ae7e3a18cd6028b) ---- - builder/builder.ml | 32 +++++++++++------- - builder/cmdline.ml | 69 ++++++++++++++++++++++++++++++--------- - builder/index_parser.ml | 5 ++- - builder/index_parser.mli | 2 ++ - builder/list_entries.ml | 10 ++++-- - builder/list_entries.mli | 2 +- - builder/sigchecker.ml | 7 ++-- - builder/sigchecker.mli | 4 ++- - builder/test-virt-builder-list.sh | 1 + - builder/virt-builder.pod | 57 ++++++++++++++++++++++++++------ - 10 files changed, 143 insertions(+), 46 deletions(-) - -diff --git a/builder/builder.ml b/builder/builder.ml -index 2437d56..b375de4 100644 ---- a/builder/builder.ml -+++ b/builder/builder.ml -@@ -37,22 +37,27 @@ let () = Random.self_init () - let main () = - (* Command line argument parsing - see cmdline.ml. *) - let mode, arg, -- attach, cache, check_signature, curl, debug, delete, edit, fingerprint, -+ attach, cache, check_signature, curl, debug, delete, edit, - firstboot, run, format, gpg, hostname, install, list_long, memsize, mkdirs, - network, output, password_crypto, quiet, root_password, scrub, -- scrub_logfile, size, smp, source, sync, upload, writes = -+ scrub_logfile, size, smp, sources, sync, upload, writes = - parse_cmdline () in - - (* Timestamped messages in ordinary, non-debug non-quiet mode. *) - let msg fs = make_message_function ~quiet fs in - -- (* If debugging, echo the command line arguments. *) -+ (* If debugging, echo the command line arguments and the sources. *) - if debug then ( - eprintf "command line:"; - List.iter (eprintf " %s") (Array.to_list Sys.argv); -- prerr_newline () -+ prerr_newline (); -+ List.iteri ( -+ fun i (source, fingerprint) -> -+ eprintf "source[%d] = (%S, %S)\n" i source fingerprint -+ ) sources - ); - -+ - (* Handle some modes here, some later on. *) - let mode = - match mode with -@@ -127,19 +132,23 @@ let main () = - ) - in - -- (* Make the downloader and signature checker abstract data types. *) -+ (* Download the sources. *) - let downloader = Downloader.create ~debug ~curl ~cache in -- let sigchecker = -- Sigchecker.create ~debug ~gpg ?fingerprint ~check_signature in -- -- (* Download the source (index) file. *) -- let index = Index_parser.get_index ~prog ~debug ~downloader ~sigchecker source in -+ let index : Index_parser.index = -+ List.concat ( -+ List.map ( -+ fun (source, fingerprint) -> -+ let sigchecker = -+ Sigchecker.create ~debug ~gpg ~fingerprint ~check_signature in -+ Index_parser.get_index ~prog ~debug ~downloader ~sigchecker source -+ ) sources -+ ) in - - (* Now handle the remaining modes. *) - let mode = - match mode with - | `List -> (* --list *) -- List_entries.list_entries ~list_long ~source index; -+ List_entries.list_entries ~list_long ~sources index; - exit 0 - - | `Print_cache -> (* --print-cache *) -@@ -186,6 +195,7 @@ let main () = - eprintf (f_"%s: cannot find os-version '%s'.\nUse --list to list available guest types.\n") - prog arg; - exit 1 in -+ let sigchecker = entry.Index_parser.sigchecker in - - (match mode with - | `Notes -> (* --notes *) -diff --git a/builder/cmdline.ml b/builder/cmdline.ml -index 97ccd89..b4e21fc 100644 ---- a/builder/cmdline.ml -+++ b/builder/cmdline.ml -@@ -37,6 +37,8 @@ let default_cachedir = - with Not_found -> - None (* no cache directory *) - -+let default_source = "http://libguestfs.org/download/builder/index.asc" -+ - let parse_cmdline () = - let display_version () = - printf "virt-builder %s\n" Config.package_version; -@@ -83,11 +85,8 @@ let parse_cmdline () = - edit := (file, expr) :: !edit - in - -- let fingerprint = -- try Some (Sys.getenv "VIRT_BUILDER_FINGERPRINT") -- with Not_found -> None in -- let fingerprint = ref fingerprint in -- let set_fingerprint fp = fingerprint := Some fp in -+ let fingerprints = ref [] in -+ let add_fingerprint arg = fingerprints := arg :: !fingerprints in - - let firstboot = ref [] in - let add_firstboot s = -@@ -166,10 +165,8 @@ let parse_cmdline () = - let smp = ref None in - let set_smp arg = smp := Some arg in - -- let source = -- try Sys.getenv "VIRT_BUILDER_SOURCE" -- with Not_found -> "http://libguestfs.org/download/builder/index.asc" in -- let source = ref source in -+ let sources = ref [] in -+ let add_source arg = sources := arg :: !sources in - - let sync = ref true in - -@@ -223,7 +220,7 @@ let parse_cmdline () = - "--delete-cache", Arg.Unit delete_cache_mode, - " " ^ s_"Delete the template cache"; - "--edit", Arg.String add_edit, "file:expr" ^ " " ^ s_"Edit file with Perl expr"; -- "--fingerprint", Arg.String set_fingerprint, -+ "--fingerprint", Arg.String add_fingerprint, - "AAAA.." ^ " " ^ s_"Fingerprint of valid signing key"; - "--firstboot", Arg.String add_firstboot, "script" ^ " " ^ s_"Run script at first guest boot"; - "--firstboot-command", Arg.String add_firstboot_cmd, "cmd+args" ^ " " ^ s_"Run command at first guest boot"; -@@ -260,7 +257,7 @@ let parse_cmdline () = - "--scrub", Arg.String add_scrub, "name" ^ " " ^ s_"Scrub a file"; - "--size", Arg.String set_size, "size" ^ " " ^ s_"Set output disk size"; - "--smp", Arg.Int set_smp, "vcpus" ^ " " ^ s_"Set number of vCPUs"; -- "--source", Arg.Set_string source, "URL" ^ " " ^ s_"Set source URL"; -+ "--source", Arg.String add_source, "URL" ^ " " ^ s_"Set source URL"; - "--no-sync", Arg.Clear sync, " " ^ s_"Do not fsync output file on exit"; - "--upload", Arg.String add_upload, "file:dest" ^ " " ^ s_"Upload file to dest"; - "-v", Arg.Set debug, " " ^ s_"Enable debugging messages"; -@@ -301,7 +298,7 @@ read the man page virt-builder(1). - let debug = !debug in - let delete = List.rev !delete in - let edit = List.rev !edit in -- let fingerprint = !fingerprint in -+ let fingerprints = List.rev !fingerprints in - let firstboot = List.rev !firstboot in - let run = List.rev !run in - let format = match !format with "" -> None | s -> Some s in -@@ -320,7 +317,7 @@ read the man page virt-builder(1). - let scrub_logfile = !scrub_logfile in - let size = !size in - let smp = !smp in -- let source = !source in -+ let sources = List.rev !sources in - let sync = !sync in - let upload = List.rev !upload in - let writes = List.rev !writes in -@@ -375,8 +372,50 @@ read the man page virt-builder(1). - exit 1 - ) in - -+ (* Check source(s) and fingerprint(s), or use environment or default. *) -+ let sources = -+ let list_split = function "" -> [] | str -> string_nsplit "," str in -+ let rec repeat x = function -+ | 0 -> [] | 1 -> [x] -+ | n -> x :: repeat x (n-1) -+ in -+ -+ let sources = -+ if sources <> [] then sources -+ else ( -+ try list_split (Sys.getenv "VIRT_BUILDER_SOURCE") -+ with Not_found -> [ default_source ] -+ ) in -+ let fingerprints = -+ if fingerprints <> [] then fingerprints -+ else ( -+ try list_split (Sys.getenv "VIRT_BUILDER_FINGERPRINT") -+ with Not_found -> [ Sigchecker.default_fingerprint ] -+ ) in -+ -+ let nr_sources = List.length sources in -+ let fingerprints = -+ match fingerprints with -+ | [fingerprint] -> -+ (* You're allowed to have multiple sources and one fingerprint: it -+ * means that the same fingerprint is used for all sources. -+ *) -+ repeat fingerprint nr_sources -+ | xs -> xs in -+ -+ if List.length fingerprints <> nr_sources then ( -+ eprintf (f_"%s: source and fingerprint lists are not the same length\n") -+ prog; -+ exit 1 -+ ); -+ -+ assert (nr_sources > 0); -+ -+ (* Combine the sources and fingerprints into a single list of pairs. *) -+ List.combine sources fingerprints in -+ - mode, arg, -- attach, cache, check_signature, curl, debug, delete, edit, fingerprint, -+ attach, cache, check_signature, curl, debug, delete, edit, - firstboot, run, format, gpg, hostname, install, list_long, memsize, mkdirs, - network, output, password_crypto, quiet, root_password, scrub, -- scrub_logfile, size, smp, source, sync, upload, writes -+ scrub_logfile, size, smp, sources, sync, upload, writes -diff --git a/builder/index_parser.ml b/builder/index_parser.ml -index 326b395..5f07902 100644 ---- a/builder/index_parser.ml -+++ b/builder/index_parser.ml -@@ -37,6 +37,8 @@ and entry = { - lvexpand : string option; - notes : string option; - hidden : bool; -+ -+ sigchecker : Sigchecker.t; - } - - let print_entry chan (name, { printable_name = printable_name; -@@ -348,7 +350,8 @@ let get_index ~prog ~debug ~downloader ~sigchecker source = - expand = expand; - lvexpand = lvexpand; - notes = notes; -- hidden = hidden } in -+ hidden = hidden; -+ sigchecker = sigchecker } in - n, entry - ) sections in - -diff --git a/builder/index_parser.mli b/builder/index_parser.mli -index a9b328a..54f1807 100644 ---- a/builder/index_parser.mli -+++ b/builder/index_parser.mli -@@ -31,6 +31,8 @@ and entry = { - lvexpand : string option; - notes : string option; - hidden : bool; -+ -+ sigchecker : Sigchecker.t; - } - - val get_index : prog:string -> debug:bool -> downloader:Downloader.t -> sigchecker:Sigchecker.t -> string -> index -diff --git a/builder/list_entries.ml b/builder/list_entries.ml -index cf97142..5940d79 100644 ---- a/builder/list_entries.ml -+++ b/builder/list_entries.ml -@@ -21,10 +21,14 @@ open Common_utils - - open Printf - --let list_entries ?(list_long = false) ~source index = -+let list_entries ?(list_long = false) ~sources index = - if list_long then ( -- printf (f_"Source URI: %s\n") source; -- printf "\n" -+ List.iter ( -+ fun (source, fingerprint) -> -+ printf (f_"Source URI: %s\n") source; -+ printf (f_"Fingerprint: %s\n") fingerprint; -+ printf "\n" -+ ) sources - ); - - List.iter ( -diff --git a/builder/list_entries.mli b/builder/list_entries.mli -index e1d5c06..d9486b0 100644 ---- a/builder/list_entries.mli -+++ b/builder/list_entries.mli -@@ -16,4 +16,4 @@ - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - *) - --val list_entries : ?list_long:bool -> source:string -> Index_parser.index -> unit -+val list_entries : ?list_long:bool -> sources:(string * string) list -> Index_parser.index -> unit -diff --git a/builder/sigchecker.ml b/builder/sigchecker.ml -index 2bd3c11..b20a186 100644 ---- a/builder/sigchecker.ml -+++ b/builder/sigchecker.ml -@@ -104,7 +104,7 @@ type t = { - check_signature : bool; - } - --let create ~debug ~gpg ?(fingerprint = default_fingerprint) ~check_signature = -+let create ~debug ~gpg ~fingerprint ~check_signature = - { - debug = debug; - gpg = gpg; -@@ -188,10 +188,9 @@ and do_verify t args = - exit 1 - ) - --(* Import the default public key, if it's the default fingerprint. *) -+(* Import the default public key. *) - and import_key t = -- if not !key_imported && equal_fingerprints t.fingerprint default_fingerprint -- then ( -+ if not !key_imported then ( - let filename, chan = Filename.open_temp_file "vbpubkey" ".asc" in - unlink_on_exit filename; - output_string chan default_pubkey; -diff --git a/builder/sigchecker.mli b/builder/sigchecker.mli -index 4d89129..cdd800e 100644 ---- a/builder/sigchecker.mli -+++ b/builder/sigchecker.mli -@@ -16,9 +16,11 @@ - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - *) - -+val default_fingerprint : string -+ - type t - --val create : debug:bool -> gpg:string -> ?fingerprint:string -> check_signature:bool -> t -+val create : debug:bool -> gpg:string -> fingerprint:string -> check_signature:bool -> t - - val verify : t -> string -> unit - (** Verify the file is signed (if check_signature is true). *) -diff --git a/builder/test-virt-builder-list.sh b/builder/test-virt-builder-list.sh -index 3a159bb..3077b23 100755 ---- a/builder/test-virt-builder-list.sh -+++ b/builder/test-virt-builder-list.sh -@@ -39,6 +39,7 @@ fi - long_list=$(./virt-builder --no-check-signature --no-cache --list --long) - - if [ "$long_list" != "Source URI: $VIRT_BUILDER_SOURCE -+Fingerprint: F777 4FB1 AD07 4A7E 8C87 67EA 9173 8F73 E1B7 68A0 - - os-version: phony-debian - Full name: Phony Debian -diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod -index 66ed030..39729d6 100644 ---- a/builder/virt-builder.pod -+++ b/builder/virt-builder.pod -@@ -264,10 +264,14 @@ Check that the index and templates are signed by the key with the - given fingerprint. (The fingerprint is a long string, usually written - as 10 groups of 4 hexadecimal digits). - --If signature checking is enabled and the I<--fingerprint> option is --not given, then this checks the download was signed by --S (which is --S key). -+You can give this option multiple times. If you have multiple source -+URLs, then you can have either no fingerprint, one fingerprint or -+multiple fingerprints. If you have multiple, then each must -+correspond 1-1 with a source URL. -+ -+The default fingerprint (if none are supplied) is -+S -+(which is S key). - - You can also set the C environment variable. - -@@ -562,8 +566,11 @@ Enable N E 2 virtual CPUs for I<--run> scripts to use. - - =item B<--source> URL - --Set the source URL to look for templates. If not specified it --defaults to L -+Set the source URL to look for indexes. -+ -+You can give this option multiple times to specify multiple sources. -+If not specified it defaults to -+L - - See also L below. - -@@ -1225,6 +1232,36 @@ Now run virt-builder commands as normal, eg: - - To debug problems, add the C<-v> option to these commands. - -+=head3 Running virt-builder against multiple sources -+ -+It is possible to use multiple sources with virt-builder. Use either -+multiple I<--source> and/or I<--fingerprint> options, or a -+comma-separated list in the C / -+C environment variables: -+ -+ virt-builder \ -+ --source http://example.com/s1/index.asc \ -+ --source http://example.com/s2/index.asc -+ -+or equivalently: -+ -+ export VIRT_BUILDER_SOURCE=http://example.com/s1/index.asc,http://example.com/s2/index.asc -+ virt-builder [...] -+ -+You can provide N, 1 or 0 fingerprints. In the case where you -+provide N fingerprints, N = number of sources and there is a 1-1 -+correspondence between each source and each fingerprint: -+ -+ virt-builder \ -+ --source http://example.com/s1/index.asc --fingerprint '0123 ...' \ -+ --source http://example.com/s2/index.asc --fingerprint '9876 ...' -+ -+In the case where you provide 1 fingerprint, the same fingerprint -+is used for all sources. -+ -+In the case where you provide no fingerprints, the default fingerprint -+built into virt-builder is used for all sources. -+ - =head3 Licensing of templates - - You should be aware of the licensing of images that you distribute. -@@ -1456,13 +1493,13 @@ Used to determine the location of the template cache. See L. - - =item C - --Set the default value for the GPG signature fingerprint (see --I<--fingerprint> option). -+Set the default value for the GPG signature fingerprint or -+comma-separated list of fingerprints (see I<--fingerprint> option). - - =item C - --Set the default value for the source URL for the template repository --(see I<--source> option). -+Set the default value for the source URL (or comma-separated list of -+URLs) for the template repository (see I<--source> option). - - =item C - --- -1.8.5.3 - diff --git a/0013-builder-Add-a-real-scanner-parser-for-index-files.patch b/0013-builder-Add-a-real-scanner-parser-for-index-files.patch deleted file mode 100644 index 111a4a0..0000000 --- a/0013-builder-Add-a-real-scanner-parser-for-index-files.patch +++ /dev/null @@ -1,1232 +0,0 @@ -From 987c6ed3bee14341615134b8a4148f409cf78d3f Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 4 Nov 2013 14:53:41 +0000 -Subject: [PATCH] builder: Add a real scanner/parser for index files. - -This adds a tool called virt-index-validate to validate index files. - -(cherry picked from commit a4800e2d4fc50f372a8b626333c4fbb9b8ca9633) ---- - .gitignore | 7 ++ - README | 4 + - builder/Makefile.am | 56 +++++++++---- - builder/index-parse.y | 123 +++++++++++++++++++++++++++++ - builder/index-parser-c.c | 105 +++++++++++++++++++++++++ - builder/index-scan.l | 103 ++++++++++++++++++++++++ - builder/index-struct.c | 58 ++++++++++++++ - builder/index-struct.h | 48 ++++++++++++ - builder/index-validate.c | 161 ++++++++++++++++++++++++++++++++++++++ - builder/index_parser.ml | 143 ++++----------------------------- - builder/list_entries.ml | 2 +- - builder/test-virt-builder-list.sh | 12 ++- - builder/virt-builder.pod | 17 ++++ - builder/virt-index-validate.pod | 92 ++++++++++++++++++++++ - configure.ac | 4 + - po-docs/ja/Makefile.am | 1 + - po-docs/podfiles | 1 + - po-docs/uk/Makefile.am | 1 + - po/POTFILES | 5 ++ - 19 files changed, 793 insertions(+), 150 deletions(-) - create mode 100644 builder/index-parse.y - create mode 100644 builder/index-parser-c.c - create mode 100644 builder/index-scan.l - create mode 100644 builder/index-struct.c - create mode 100644 builder/index-struct.h - create mode 100644 builder/index-validate.c - create mode 100644 builder/virt-index-validate.pod - -diff --git a/.gitignore b/.gitignore -index 7bcd500..8f0cda3 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -58,10 +58,16 @@ Makefile.in - /bash/virt-sparsify - /build-aux - /builder/.depend -+/builder/index-parse.c -+/builder/index-parse.h -+/builder/index-scan.c - /builder/stamp-virt-builder.pod -+/builder/stamp-virt-index-validate.pod - /builder/test-index - /builder/virt-builder - /builder/virt-builder.1 -+/builder/virt-index-validate -+/builder/virt-index-validate.1 - /builder/*.xz - /cat/stamp-virt-*.pod - /cat/virt-cat -@@ -224,6 +230,7 @@ Makefile.in - /html/virt-edit.1.html - /html/virt-filesystems.1.html - /html/virt-format.1.html -+/html/virt-index-validate.1.html - /html/virt-inspector.1.html - /html/virt-list-filesystems.1.html - /html/virt-list-partitions.1.html -diff --git a/README b/README -index 0e442e1..dee3bd4 100644 ---- a/README -+++ b/README -@@ -94,6 +94,10 @@ The full requirements are described below. - +--------------+-------------+---+-----------------------------------------+ - | gperf | | R | | - +--------------+-------------+---+-----------------------------------------+ -+| flex | | R | flex & bison are required for virt- | -++--------------+-------------+---| builder. We could make these | -+| bison | | R | optional but automakes makes it hard. | -++--------------+-------------+---+-----------------------------------------+ - | PCRE | | R | Perl-compatible Regular Expression lib. | - +--------------+-------------+---+-----------------------------------------+ - | genisoimage | | R | mkisofs may work. | -diff --git a/builder/Makefile.am b/builder/Makefile.am -index b8bf6ac..ff27318 100644 ---- a/builder/Makefile.am -+++ b/builder/Makefile.am -@@ -17,6 +17,12 @@ - - include $(top_srcdir)/subdir-rules.mk - -+AM_YFLAGS = -d -+AM_CFLAGS = \ -+ -I$(shell $(OCAMLC) -where) \ -+ -I$(top_srcdir)/src \ -+ -I$(top_srcdir)/fish -+ - EXTRA_DIST = \ - $(SOURCES) \ - virt-builder.pod \ -@@ -40,6 +46,9 @@ SOURCES = \ - sigchecker.mli \ - sigchecker.ml - -+man_MANS = -+noinst_DATA = -+ - if HAVE_OCAML - - # Note this list must be in dependency order. -@@ -58,6 +67,10 @@ OBJECTS = \ - $(top_builddir)/mllib/fsync.cmx \ - $(top_builddir)/mllib/password.cmx \ - $(top_builddir)/mllib/config.cmx \ -+ index-scan.o \ -+ index-struct.o \ -+ index-parse.o \ -+ index-parser-c.o \ - get_kernel.cmx \ - downloader.cmx \ - sigchecker.cmx \ -@@ -97,24 +110,10 @@ virt-builder: $(OBJECTS) - .ml.cmx: - $(OCAMLFIND) ocamlopt $(OCAMLOPTFLAGS) -c $< -o $@ - --# automake will decide we don't need C support in this file. Really --# we do, so we have to provide it ourselves. -- --DEFAULT_INCLUDES = \ -- -I. \ -- -I$(top_builddir) \ -- -I$(shell $(OCAMLC) -where) \ -- -I$(top_srcdir)/src \ -- -I$(top_srcdir)/fish -- --.c.o: -- $(CC) $(CFLAGS) $(PROF_CFLAGS) $(DEFAULT_INCLUDES) -c $< -o $@ -- - # Manual pages and HTML files for the website. - --man_MANS = virt-builder.1 -- --noinst_DATA = $(top_builddir)/html/virt-builder.1.html -+man_MANS += virt-builder.1 -+noinst_DATA += $(top_builddir)/html/virt-builder.1.html - - virt-builder.1 $(top_builddir)/html/virt-builder.1.html: stamp-virt-builder.pod - -@@ -170,3 +169,28 @@ endif - DISTCLEANFILES = .depend - - .PHONY: depend docs -+ -+# Build a small C index validator program. -+bin_PROGRAMS = virt-index-validate -+ -+virt_index_validate_SOURCES = \ -+ index-parse.y \ -+ index-scan.l \ -+ index-struct.h \ -+ index-struct.c \ -+ index-validate.c -+ -+man_MANS += virt-index-validate.1 -+noinst_DATA += $(top_builddir)/html/virt-index-validate.1.html -+ -+virt-index-validate.1 $(top_builddir)/html/virt-index-validate.1.html: stamp-virt-index-validate.pod -+ -+stamp-virt-index-validate.pod: virt-index-validate.pod -+ $(PODWRAPPER) \ -+ --man virt-index-validate.1 \ -+ --html $(top_builddir)/html/virt-index-validate.1.html \ -+ --license GPLv2+ \ -+ $< -+ touch $@ -+ -+CLEANFILES += stamp-virt-index-validate.pod -diff --git a/builder/index-parse.y b/builder/index-parse.y -new file mode 100644 -index 0000000..f5e551b ---- /dev/null -+++ b/builder/index-parse.y -@@ -0,0 +1,123 @@ -+/* libguestfs virt-builder tool -*- fundamental -*- -+ * Copyright (C) 2013 Red Hat Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ */ -+ -+%{ -+#include -+ -+#include -+#include -+#include -+ -+#include "index-struct.h" -+ -+extern void yyerror (const char *); -+extern int yylex (void); -+ -+/* Join two strings with \n */ -+static char * -+concat_newline (const char *str1, const char *str2) -+{ -+ size_t len1, len2, len; -+ char *ret; -+ -+ if (str2 == NULL) -+ return strdup (str1); -+ -+ len1 = strlen (str1); -+ len2 = strlen (str2); -+ len = len1 + 1 /* \n */ + len2 + 1 /* \0 */; -+ ret = malloc (len); -+ memcpy (ret, str1, len1); -+ ret[len1] = '\n'; -+ memcpy (ret + len1 + 1, str2, len2); -+ ret[len-1] = '\0'; -+ -+ return ret; -+} -+ -+%} -+ -+%locations -+ -+%union { -+ struct section *section; -+ struct field *field; -+ char *str; -+} -+ -+%token SECTION_HEADER -+%token FIELD -+%token VALUE_CONT -+%token EMPTY_LINE -+%token PGP_PROLOGUE -+%token PGP_EPILOGUE -+ -+%type
sections section -+%type fields field -+%type continuations -+ -+%% -+ -+index: -+ sections -+ { parsed_index = $1; } -+ | PGP_PROLOGUE sections PGP_EPILOGUE -+ { parsed_index = $2; } -+ -+sections: -+ section -+ { $$ = $1; } -+ | section EMPTY_LINE sections -+ { $$ = $1; $$->next = $3; } -+ -+section: -+ SECTION_HEADER fields -+ { $$ = malloc (sizeof (struct section)); -+ $$->next = NULL; -+ $$->name = $1; -+ $$->fields = $2; } -+ -+fields: -+ /* empty */ -+ { $$ = NULL; } -+ | field fields -+ { $$ = $1; $$->next = $2; } -+ -+field: FIELD continuations -+ { $$ = $1; -+ char *old_value = $$->value; -+ $$->value = concat_newline (old_value, $2); -+ free (old_value); -+ free ($2); } -+ -+continuations: -+ /* empty */ -+ { $$ = NULL; } -+ | VALUE_CONT continuations -+ { $$ = concat_newline ($1, $2); -+ free ($1); -+ free ($2); } -+ -+%% -+ -+void -+yyerror (const char *msg) -+{ -+ fprintf (stderr, "syntax error at line %d: %s\n", -+ yylloc.first_line, msg); -+} -diff --git a/builder/index-parser-c.c b/builder/index-parser-c.c -new file mode 100644 -index 0000000..17e680b ---- /dev/null -+++ b/builder/index-parser-c.c -@@ -0,0 +1,105 @@ -+/* virt-builder -+ * Copyright (C) 2013 Red Hat Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ */ -+ -+/* This file handles the interface between the C/lex/yacc index file -+ * parser, and the OCaml world. See index_parser.ml for the OCaml -+ * type definition. -+ */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#ifdef HAVE_CAML_UNIXSUPPORT_H -+#include -+#else -+#define Nothing ((value) 0) -+extern void unix_error (int errcode, char * cmdname, value arg) Noreturn; -+#endif -+ -+#include "index-struct.h" -+#include "index-parse.h" -+ -+extern FILE *yyin; -+ -+value -+virt_builder_parse_index (value filenamev) -+{ -+ CAMLparam1 (filenamev); -+ CAMLlocal4 (rv, v, sv, fv); -+ struct section *sections; -+ size_t i, nr_sections; -+ -+ yyin = fopen (String_val (filenamev), "r"); -+ if (yyin == NULL) -+ unix_error (errno, (char *) "fopen", filenamev); -+ -+ if (yyparse () != 0) { -+ fclose (yyin); -+ caml_invalid_argument ("parse error"); -+ } -+ -+ if (fclose (yyin) == EOF) -+ unix_error (errno, (char *) "fclose", filenamev); -+ -+ /* Convert the parsed data to OCaml structures. */ -+ nr_sections = 0; -+ for (sections = parsed_index; sections != NULL; sections = sections->next) -+ nr_sections++; -+ rv = caml_alloc (nr_sections, 0); -+ -+ for (i = 0, sections = parsed_index; sections != NULL; -+ i++, sections = sections->next) { -+ struct field *fields; -+ size_t j, nr_fields; -+ -+ nr_fields = 0; -+ for (fields = sections->fields; fields != NULL; fields = fields->next) -+ nr_fields++; -+ fv = caml_alloc (nr_fields, 0); -+ -+ for (j = 0, fields = sections->fields; fields != NULL; -+ j++, fields = fields->next) { -+ v = caml_alloc_tuple (2); -+ sv = caml_copy_string (fields->key); -+ Store_field (v, 0, sv); /* (key, value) */ -+ sv = caml_copy_string (fields->value); -+ Store_field (v, 1, sv); -+ Store_field (fv, j, v); /* assign to return array of fields */ -+ } -+ -+ v = caml_alloc_tuple (2); -+ sv = caml_copy_string (sections->name); -+ Store_field (v, 0, sv); /* (name, fields) */ -+ Store_field (v, 1, fv); -+ Store_field (rv, i, v); /* assign to return array of sections */ -+ } -+ -+ /* Free parsed global data. */ -+ free_index (); -+ -+ CAMLreturn (rv); -+} -diff --git a/builder/index-scan.l b/builder/index-scan.l -new file mode 100644 -index 0000000..9a6a0e3 ---- /dev/null -+++ b/builder/index-scan.l -@@ -0,0 +1,103 @@ -+/* libguestfs virt-builder tool -*- fundamental -*- -+ * Copyright (C) 2013 Red Hat Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ */ -+ -+%{ -+#include -+ -+#include -+#include -+#include -+ -+#include "index-parse.h" -+#include "index-struct.h" -+ -+#define YY_USER_ACTION yylloc.first_line = yylloc.last_line = yylineno; -+ -+extern void yyerror (const char *); -+ -+%} -+ -+%option noyywrap -+%option yylineno -+ -+%% -+ -+ /* Apart from the PGP prologue/epilogue which is a hack, the -+ * scanning strategy is to deal with the file strictly line by -+ * line, and pass those lines up to the parser which deals with -+ * whether they appear in the right order to be meaningful. -+ * Note that flex does longest-match. -+ */ -+ -+ /* Ignore comments - '#' MUST appear at the start of a line. */ -+^"#".*\n { seen_comments++; } -+ -+ /* An empty line is significant. */ -+^\n { return EMPTY_LINE; } -+ -+ /* [...] marks beginning of a section. */ -+^"["[-A-Za-z0-9.]+"]"\n { -+ yylval.str = strndup (yytext+1, yyleng-3); -+ return SECTION_HEADER; -+ } -+ -+ /* field=value or field[subfield]=value */ -+^[A-Za-z0-9_.]+("["[A-Za-z0-9_,.]+"]")?"=".*\n { -+ size_t i = strcspn (yytext, "="); -+ yylval.field = malloc (sizeof (struct field)); -+ yylval.field->next = NULL; -+ yylval.field->key = strndup (yytext, i); -+ /* Note we chop the final \n off here. */ -+ yylval.field->value = strndup (yytext+i+1, yyleng-(i+2)); -+ return FIELD; -+ } -+ -+ /* Continuation line for multi-line values. */ -+^[[:blank:]].*\n { -+ yylval.str = strndup (yytext+1, yyleng-2); -+ return VALUE_CONT; -+ } -+ -+ /* Hack to eat the PGP prologue. */ -+^"-----BEGIN PGP SIGNED MESSAGE-----\n" { -+ int c, prevnl = 0; -+ -+ /* Eat everything to the first blank line. */ -+ while ((c = input ()) != EOF) { -+ if (c == '\n' && prevnl) -+ break; -+ prevnl = c == '\n'; -+ } -+ -+ return PGP_PROLOGUE; -+} -+ -+ /* Hack to eat the PGP epilogue. */ -+^"-----BEGIN PGP SIGNATURE-----\n" { -+ /* Eat everything to the end of the file. */ -+ while (input () != EOF) -+ ; -+ -+ return PGP_EPILOGUE; -+} -+ -+ /* anything else is an error */ -+. { -+ yyerror ("unexpected character in input"); -+ exit (EXIT_FAILURE); -+} -diff --git a/builder/index-struct.c b/builder/index-struct.c -new file mode 100644 -index 0000000..26bed24 ---- /dev/null -+++ b/builder/index-struct.c -@@ -0,0 +1,58 @@ -+/* libguestfs virt-builder tool -+ * Copyright (C) 2013 Red Hat Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ */ -+ -+#include -+ -+#include -+#include -+ -+#include "index-struct.h" -+ -+struct section *parsed_index = NULL; -+int seen_comments = 0; -+ -+static void free_section (struct section *section); -+static void free_field (struct field *field); -+ -+void -+free_index (void) -+{ -+ free_section (parsed_index); -+} -+ -+static void -+free_section (struct section *section) -+{ -+ if (section) { -+ free_section (section->next); -+ free (section->name); -+ free_field (section->fields); -+ free (section); -+ } -+} -+ -+static void -+free_field (struct field *field) -+{ -+ if (field) { -+ free_field (field->next); -+ free (field->key); -+ free (field->value); -+ free (field); -+ } -+} -diff --git a/builder/index-struct.h b/builder/index-struct.h -new file mode 100644 -index 0000000..ac8a3dd ---- /dev/null -+++ b/builder/index-struct.h -@@ -0,0 +1,48 @@ -+/* libguestfs virt-builder tool -+ * Copyright (C) 2013 Red Hat Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ */ -+ -+/* The data structures produced when parsing the index file. */ -+ -+#ifndef INDEX_STRUCT_H -+#define INDEX_STRUCT_H -+ -+/* A section or list of sections. */ -+struct section { -+ struct section *next; -+ char *name; -+ struct field *fields; -+}; -+ -+/* A field or list of fields. */ -+struct field { -+ struct field *next; -+ char *key; -+ char *value; -+}; -+ -+/* The parser (yyparse) stores the result here. */ -+extern struct section *parsed_index; -+ -+/* yyparse sets this if any comments were seen. Required for checking -+ * compatibility with virt-builder 1.24. -+ */ -+extern int seen_comments; -+ -+extern void free_index (void); -+ -+#endif /* INDEX_STRUCT_H */ -diff --git a/builder/index-validate.c b/builder/index-validate.c -new file mode 100644 -index 0000000..d156c43 ---- /dev/null -+++ b/builder/index-validate.c -@@ -0,0 +1,161 @@ -+/* libguestfs virt-builder tool -+ * Copyright (C) 2013 Red Hat Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "guestfs-internal-frontend.h" -+ -+#include "index-struct.h" -+#include "index-parse.h" -+ -+extern FILE *yyin; -+ -+static void -+usage (int exit_status) -+{ -+ printf ("%s index\n", program_name); -+ exit (exit_status); -+} -+ -+int -+main (int argc, char *argv[]) -+{ -+ enum { HELP_OPTION = CHAR_MAX + 1 }; -+ static const char *options = "V"; -+ static const struct option long_options[] = { -+ { "help", 0, 0, HELP_OPTION }, -+ { "compat-1.24.0", 0, 0, 0 }, -+ { "compat-1.24.1", 0, 0, 0 }, -+ { "version", 0, 0, 'V' }, -+ { 0, 0, 0, 0 } -+ }; -+ int c; -+ int option_index; -+ int compat_1_24_0 = 0; -+ int compat_1_24_1 = 0; -+ const char *input; -+ struct section *sections; -+ -+ for (;;) { -+ c = getopt_long (argc, argv, options, long_options, &option_index); -+ if (c == -1) break; -+ -+ switch (c) { -+ case 0: /* options which are long only */ -+ if (STREQ (long_options[option_index].name, "compat-1.24.0")) -+ compat_1_24_0 = compat_1_24_1 = 1; -+ else if (STREQ (long_options[option_index].name, "compat-1.24.1")) -+ compat_1_24_1 = 1; -+ else { -+ fprintf (stderr, _("%s: unknown long option: %s (%d)\n"), -+ program_name, long_options[option_index].name, option_index); -+ exit (EXIT_FAILURE); -+ } -+ break; -+ -+ case 'V': -+ printf ("%s %s\n", PACKAGE_NAME, PACKAGE_VERSION); -+ exit (EXIT_SUCCESS); -+ -+ case HELP_OPTION: -+ usage (EXIT_SUCCESS); -+ -+ default: -+ usage (EXIT_FAILURE); -+ } -+ } -+ -+ if (optind != argc-1) -+ usage (EXIT_FAILURE); -+ -+ input = argv[optind++]; -+ -+ yyin = fopen (input, "r"); -+ if (yyin == NULL) { -+ perror (input); -+ exit (EXIT_FAILURE); -+ } -+ -+ if (yyparse () != 0) { -+ fprintf (stderr, _("%s: '%s' could not be validated, see errors above\n"), -+ program_name, input); -+ exit (EXIT_FAILURE); -+ } -+ -+ if (fclose (yyin) == EOF) { -+ fprintf (stderr, _("%s: %s: error reading input file: %m\n"), -+ program_name, input); -+ exit (EXIT_FAILURE); -+ } -+ -+ if (compat_1_24_1 && seen_comments) { -+ fprintf (stderr, _("%s: %s contains comments which will not work with virt-builder 1.24.1\n"), -+ program_name, input); -+ exit (EXIT_FAILURE); -+ } -+ -+ /* Iterate over the parsed sections, semantically validating it. */ -+ for (sections = parsed_index; sections != NULL; sections = sections->next) { -+ int seen_sig = 0; -+ struct field *fields; -+ -+ for (fields = sections->fields; fields != NULL; fields = fields->next) { -+ if (compat_1_24_0) { -+ if (strchr (fields->key, '[') || -+ strchr (fields->key, ']')) { -+ fprintf (stderr, _("%s: %s: section [%s], field '%s' has invalid characters which will not work with virt-builder 1.24.0\n"), -+ program_name, input, sections->name, fields->key); -+ exit (EXIT_FAILURE); -+ } -+ } -+ if (compat_1_24_1) { -+ if (strchr (fields->key, '.') || -+ strchr (fields->key, ',')) { -+ fprintf (stderr, _("%s: %s: section [%s], field '%s' has invalid characters which will not work with virt-builder 1.24.1\n"), -+ program_name, input, sections->name, fields->key); -+ exit (EXIT_FAILURE); -+ } -+ } -+ if (STREQ (fields->key, "sig")) -+ seen_sig = 1; -+ } -+ -+ if (compat_1_24_0 && !seen_sig) { -+ fprintf (stderr, _("%s: %s: section [%s] is missing a 'sig' field which will not work with virt-builder 1.24.0\n"), -+ program_name, input, sections->name); -+ exit (EXIT_FAILURE); -+ } -+ } -+ -+ /* Free the parsed data. */ -+ free_index (); -+ -+ printf ("%s validated OK\n", input); -+ -+ exit (EXIT_SUCCESS); -+} -diff --git a/builder/index_parser.ml b/builder/index_parser.ml -index 5f07902..453a3a1 100644 ---- a/builder/index_parser.ml -+++ b/builder/index_parser.ml -@@ -97,14 +97,17 @@ let print_entry chan (name, { printable_name = printable_name; - ); - if hidden then fp "hidden=true\n" - --let fieldname_rex = Str.regexp "^\\([][a-z0-9_]+\\)=\\(.*\\)$" -+(* Types returned by the C index parser. *) -+type sections = section array -+and section = string * fields (* [name] + fields *) -+and fields = field array -+and field = string * string (* key + value *) -+ -+(* Calls yyparse in the C code. *) -+external parse_index : string -> sections = "virt_builder_parse_index" - - let get_index ~prog ~debug ~downloader ~sigchecker source = -- let rec corrupt_line line = -- eprintf (f_"%s: error parsing index near this line:\n\n%s\n") -- prog line; -- corrupt_file () -- and corrupt_file () = -+ let corrupt_file () = - eprintf (f_"\nThe index file downloaded from '%s' is corrupt.\nYou need to ask the supplier of this file to fix it and upload a fixed version.\n") - source; - exit 1 -@@ -119,133 +122,15 @@ let get_index ~prog ~debug ~downloader ~sigchecker source = - *) - Sigchecker.verify sigchecker tmpfile; - -- (* Check the index page is not too huge. *) -- let st = stat tmpfile in -- if st.st_size > 1_000_000 then ( -- eprintf (f_"virt-builder: index page '%s' is too large (size %d bytes)\n") -- source st.st_size; -- exit 1 -- ); -- -- (* Load the file into memory. *) -- let index = read_whole_file tmpfile in -+ (* Try parsing the file. *) -+ let sections = parse_index tmpfile in - if delete_tmpfile then - (try Unix.unlink tmpfile with _ -> ()); - -- (* Split file into lines. *) -- let index = string_nsplit "\n" index in -- -- (* If there is a signature (checked above) then remove it. *) -- let index = -- match index with -- | "-----BEGIN PGP SIGNED MESSAGE-----" :: lines -> -- (* Ignore all lines until we get to first blank. *) -- let lines = dropwhile ((<>) "") lines in -- (* Ignore the blank line too. *) -- let lines = List.tl lines in -- (* Take lines until we get to the end signature. *) -- let lines = takewhile ((<>) "-----BEGIN PGP SIGNATURE-----") lines in -- lines -- | _ -> index in -- -- (* Split into sections around each /^[/ *) -- let rec loop = function -- | [] -> [] -- | x :: xs when String.length x >= 1 && x.[0] = '[' -> -- let lines = takewhile ((<>) "") xs in -- let rest = dropwhile ((<>) "") xs in -- if rest = [] then -- [x, lines] -- else ( -- let rest = List.tl rest in -- let rest = loop rest in -- (x, lines) :: rest -- ) -- | x :: _ -> corrupt_line x -- in -- let sections = loop index in -- -- (* Parse the fields in each section. *) -- let isspace = function ' ' | '\t' -> true | _ -> false in -- let starts_space str = String.length str >= 1 && isspace str.[0] in -- let rec loop = function -- | [] -> [] -- | x :: xs when not (starts_space x) && String.contains x '=' -> -- let xs' = takewhile starts_space xs in -- let ys = dropwhile starts_space xs in -- (x :: xs') :: loop ys -- | x :: _ -> corrupt_line x -- in -- let sections = List.map (fun (n, lines) -> n, loop lines) sections in -- -- if debug then ( -- eprintf "index file (%s) after splitting:\n" source; -- List.iter ( -- fun (n, fields) -> -- eprintf " os-version: %s\n" n; -- let i = ref 0 in -- List.iter ( -- fun field -> -- eprintf " %d: " !i; -- List.iter prerr_endline field; -- incr i -- ) fields -- ) sections -- ); -- -- (* Now we've parsed the file into the correct sections, we -- * interpret the meaning of the fields. -- *) -+ let sections = Array.to_list sections in - let sections = List.map ( - fun (n, fields) -> -- let len = String.length n in -- if len < 3 || n.[0] <> '[' || n.[len-1] <> ']' then -- corrupt_line n; -- let n = String.sub n 1 (len-2) in -- -- let fields = List.map ( -- function -- | [] -> assert false (* can never happen, I think? *) -- | x :: xs when Str.string_match fieldname_rex x 0 -> -- let field = Str.matched_group 1 x in -- let rest_of_line = Str.matched_group 2 x in -- let allow_multiline = -- match field with -- | "name" -> false -- | "osinfo" -> false -- | "file" -> false -- | "sig" -> false -- | "checksum" | "checksum[sha512]" -> false -- | "revision" -> false -- | "format" -> false -- | "size" -> false -- | "compressed_size" -> false -- | "expand" -> false -- | "lvexpand" -> false -- | "notes" -> true -- | "hidden" -> false -- | _ -> -- if debug then -- eprintf "warning: unknown field '%s' in index (ignored)\n%!" -- field; -- true in -- let value = -- if not allow_multiline then ( -- if xs <> [] then ( -- eprintf (f_"virt-builder: field '%s' cannot span multiple lines\n") -- field; -- corrupt_line (List.hd xs) -- ); -- rest_of_line -- ) else ( -- String.concat "\n" (rest_of_line :: xs) -- ) in -- field, value -- | x :: _ -> -- corrupt_line x -- ) fields in -- -- (n, fields) -+ n, Array.to_list fields - ) sections in - - (* Check for repeated os-version names. *) -@@ -356,7 +241,7 @@ let get_index ~prog ~debug ~downloader ~sigchecker source = - ) sections in - - if debug then ( -- eprintf "index file (%s) after parsing:\n" source; -+ eprintf "index file (%s) after parsing (C parser):\n" source; - List.iter (print_entry Pervasives.stderr) entries - ); - -diff --git a/builder/list_entries.ml b/builder/list_entries.ml -index 5940d79..87001c0 100644 ---- a/builder/list_entries.ml -+++ b/builder/list_entries.ml -@@ -62,7 +62,7 @@ let list_entries ?(list_long = false) ~sources index = - | None -> () - | Some notes -> - printf "\n"; -- printf (f_"Notes:\n %s\n") notes -+ printf (f_"Notes:\n\n%s\n") notes - ); - printf "\n" - ) -diff --git a/builder/test-virt-builder-list.sh b/builder/test-virt-builder-list.sh -index 3077b23..ff16abe 100755 ---- a/builder/test-virt-builder-list.sh -+++ b/builder/test-virt-builder-list.sh -@@ -46,28 +46,32 @@ Full name: Phony Debian - Minimum/default size: 512.0M - - Notes: -- Phony Debian look-alike used for testing. -+ -+Phony Debian look-alike used for testing. - - os-version: phony-fedora - Full name: Phony Fedora - Minimum/default size: 1.0G - - Notes: -- Phony Fedora look-alike used for testing. -+ -+Phony Fedora look-alike used for testing. - - os-version: phony-ubuntu - Full name: Phony Ubuntu - Minimum/default size: 512.0M - - Notes: -- Phony Ubuntu look-alike used for testing. -+ -+Phony Ubuntu look-alike used for testing. - - os-version: phony-windows - Full name: Phony Windows - Minimum/default size: 512.0M - - Notes: -- Phony Windows look-alike used for testing." ]; then -+ -+Phony Windows look-alike used for testing." ]; then - echo "$0: unexpected --list --long output:" - echo "$long_list" - exit 1 -diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod -index 39729d6..ce22920 100644 ---- a/builder/virt-builder.pod -+++ b/builder/virt-builder.pod -@@ -1269,6 +1269,23 @@ For open source guests, provide a link to the source code in the - C field and comply with other requirements (eg. around - trademarks). - -+=head3 Formal specification of the index file -+ -+The index file format has a formal specification defined by the flex -+scanner and bison parser used to parse the file. This can be found in -+the following files in the libguestfs source tree: -+ -+ builder/index-scan.l -+ builder/index-parse.y -+ -+A tool called L is available to validate the -+index file to ensure it is correct. -+ -+Note that the parser and tool can work on either the signed or -+unsigned index file (ie. C or C). -+ -+The index is always encoded in UTF-8. -+ - =head2 CACHING - - Since the templates are usually very large, downloaded templates are -diff --git a/builder/virt-index-validate.pod b/builder/virt-index-validate.pod -new file mode 100644 -index 0000000..6b03703 ---- /dev/null -+++ b/builder/virt-index-validate.pod -@@ -0,0 +1,92 @@ -+=encoding utf8 -+ -+=head1 NAME -+ -+virt-index-validate - Validate virt-builder index file -+ -+=head1 SYNOPSIS -+ -+ virt-index-validate index -+ -+=head1 DESCRIPTION -+ -+L uses an index file to store metadata about templates -+that it knows how to use. This index file has a specific format which -+virt-index-validate knows how to validate. -+ -+Note that virt-index-validate can validate either the signed or -+unsigned index file (ie. either C or C). It can -+only validate a local file, not a URL. -+ -+=head1 OPTIONS -+ -+=over 4 -+ -+=item B<--compat-1.24.0> -+ -+Check for compatibility with virt-builder 1.24.0. (Using this option -+implies I<--compat-1.24.1>, so you don't need to use both.) -+ -+In particular: -+ -+=over 4 -+ -+=item * -+ -+This version of virt-builder could not handle C<[...]> -+(square brackets) in field names (eg. C). -+ -+=item * -+ -+It required detached signatures (C). -+ -+=back -+ -+=item B<--compat-1.24.1> -+ -+Check for compatibility with virt-builder E 1.24.1. -+ -+In particular: -+ -+=over 4 -+ -+=item * -+ -+This version of virt-builder could not handle C<.> (period) in field -+names or C<,> (comma) in subfield names. -+ -+=item * -+ -+It could not handle comments appearing in the file. -+ -+=back -+ -+=item B<--help> -+ -+Display help. -+ -+=item B<-V> -+ -+=item B<--version> -+ -+Display version number and exit. -+ -+=back -+ -+=head1 EXIT STATUS -+ -+This program returns 0 if the index file validates, or non-zero if -+there was an error. -+ -+=head1 SEE ALSO -+ -+L, -+L. -+ -+=head1 AUTHOR -+ -+Richard W.M. Jones L -+ -+=head1 COPYRIGHT -+ -+Copyright (C) 2013 Red Hat Inc. -diff --git a/configure.ac b/configure.ac -index da777d4..21d89a0 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -711,6 +711,10 @@ test "x$XZCAT" = "xno" && AC_MSG_ERROR([xzcat must be installed]) - dnl Check for pxzcat (optional). - AC_PATH_PROGS([PXZCAT],[pxzcat],[no]) - -+dnl (f)lex and bison are required for virt-builder. -+AC_PROG_LEX -+AC_PROG_YACC -+ - dnl Check for QEMU for running binaries on this $host_cpu, fall - dnl back to basic 'qemu'. Allow the user to override it. - qemu_system="$( -diff --git a/po-docs/ja/Makefile.am b/po-docs/ja/Makefile.am -index 23857bd..e954f04 100644 ---- a/po-docs/ja/Makefile.am -+++ b/po-docs/ja/Makefile.am -@@ -60,6 +60,7 @@ MANPAGES = \ - virt-edit.1 \ - virt-filesystems.1 \ - virt-format.1 \ -+ virt-index-validate.1 \ - virt-inspector.1 \ - virt-list-filesystems.1 \ - virt-list-partitions.1 \ -diff --git a/po-docs/podfiles b/po-docs/podfiles -index 5ff9447..dd2898c 100644 ---- a/po-docs/podfiles -+++ b/po-docs/podfiles -@@ -1,6 +1,7 @@ - ../align/virt-alignment-scan.pod - ../appliance/libguestfs-make-fixed-appliance.pod - ../builder/virt-builder.pod -+../builder/virt-index-validate.pod - ../cat/virt-cat.pod - ../cat/virt-filesystems.pod - ../cat/virt-ls.pod -diff --git a/po-docs/uk/Makefile.am b/po-docs/uk/Makefile.am -index 23857bd..e954f04 100644 ---- a/po-docs/uk/Makefile.am -+++ b/po-docs/uk/Makefile.am -@@ -60,6 +60,7 @@ MANPAGES = \ - virt-edit.1 \ - virt-filesystems.1 \ - virt-format.1 \ -+ virt-index-validate.1 \ - virt-inspector.1 \ - virt-list-filesystems.1 \ - virt-list-partitions.1 \ -diff --git a/po/POTFILES b/po/POTFILES -index d8edd99..ebbea3d 100644 ---- a/po/POTFILES -+++ b/po/POTFILES -@@ -1,4 +1,9 @@ - align/scan.c -+builder/index-parse.c -+builder/index-parser-c.c -+builder/index-scan.c -+builder/index-struct.c -+builder/index-validate.c - cat/cat.c - cat/filesystems.c - cat/ls.c --- -1.8.5.3 - diff --git a/0014-builder-Fix-missing-files-in-EXTRA_DIST.patch b/0014-builder-Fix-missing-files-in-EXTRA_DIST.patch deleted file mode 100644 index 512dc23..0000000 --- a/0014-builder-Fix-missing-files-in-EXTRA_DIST.patch +++ /dev/null @@ -1,35 +0,0 @@ -From dbaeece80c13c7ab30f56c97a84ccf7152cc7f88 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 5 Nov 2013 07:15:19 +0000 -Subject: [PATCH] builder: Fix missing files in EXTRA_DIST. - -This fixes commit a4800e2d4fc50f372a8b626333c4fbb9b8ca9633. - -(cherry picked from commit 2035a75d66676c5fb2cc047a36c174dd953cd1b9) ---- - builder/Makefile.am | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/builder/Makefile.am b/builder/Makefile.am -index ff27318..b892477 100644 ---- a/builder/Makefile.am -+++ b/builder/Makefile.am -@@ -26,6 +26,7 @@ AM_CFLAGS = \ - EXTRA_DIST = \ - $(SOURCES) \ - virt-builder.pod \ -+ virt-index-validate.pod \ - test-virt-builder.sh \ - test-virt-builder-list.sh - -@@ -41,6 +42,7 @@ SOURCES = \ - get_kernel.ml \ - index_parser.mli \ - index_parser.ml \ -+ index-parser-c.c \ - list_entries.mli \ - list_entries.ml \ - sigchecker.mli \ --- -1.8.5.3 - diff --git a/0015-builder-website-Add-index-validation-test-script.patch b/0015-builder-website-Add-index-validation-test-script.patch deleted file mode 100644 index 1f9b322..0000000 --- a/0015-builder-website-Add-index-validation-test-script.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 103931fd696131bba8debad14ea3aa0d47d96d0c Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 5 Nov 2013 07:25:46 +0000 -Subject: [PATCH] builder/website: Add index validation test script. - -(cherry picked from commit 154bfb7dd46e7998eed1d40ead95923590763739) ---- - builder/website/Makefile.am | 4 ++++ - builder/website/validate.sh | 24 ++++++++++++++++++++++++ - 2 files changed, 28 insertions(+) - create mode 100755 builder/website/validate.sh - -diff --git a/builder/website/Makefile.am b/builder/website/Makefile.am -index 9cec356..cf13ed4 100644 ---- a/builder/website/Makefile.am -+++ b/builder/website/Makefile.am -@@ -40,3 +40,7 @@ EXTRA_DIST = \ - ubuntu-*.*.xz.sig - - CLEANFILES = *~ -+ -+# Validates the index file. -+TESTS_ENVIRONMENT = $(top_builddir)/run --test -+TESTS = validate.sh -diff --git a/builder/website/validate.sh b/builder/website/validate.sh -new file mode 100755 -index 0000000..f09e30c ---- /dev/null -+++ b/builder/website/validate.sh -@@ -0,0 +1,24 @@ -+#!/bin/bash - -+# libguestfs virt-builder validate index -+# Copyright (C) 2013 Red Hat Inc. -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program 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 General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; if not, write to the Free Software -+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ -+export LANG=C -+set -e -+ -+../virt-index-validate index -+../virt-index-validate index.asc -+ --- -1.8.5.3 - diff --git a/0016-builder-Internal-implementation-of-parallel-xzcat-px.patch b/0016-builder-Internal-implementation-of-parallel-xzcat-px.patch deleted file mode 100644 index 0b1ee41..0000000 --- a/0016-builder-Internal-implementation-of-parallel-xzcat-px.patch +++ /dev/null @@ -1,942 +0,0 @@ -From 9187a6b7d94ec564cfe617faa7d0b3d34978349e Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 5 Nov 2013 10:21:32 +0000 -Subject: [PATCH] builder: Internal implementation of parallel xzcat (pxzcat). - -Instead of calling out to the pxzcat program, use an internal -implementation. This requires liblzma to be available at build time. -If it's not available, fall back to using regular xzcat. - -It is intended that eventually this code will go away when regular -xzcat / unxz is able to use threads. - -(cherry picked from commit 681c88ef5d69b1dec4b929ff3451c45968023e5a) ---- - README | 2 +- - builder/Makefile.am | 11 +- - builder/builder.ml | 24 +- - builder/pxzcat-c.c | 650 +++++++++++++++++++++++++++++++++++++++++++++++ - builder/pxzcat.ml | 19 ++ - builder/pxzcat.mli | 31 +++ - builder/virt-builder.pod | 7 +- - configure.ac | 10 +- - mllib/config.ml.in | 6 - - po/POTFILES | 1 + - po/POTFILES-ml | 1 + - 11 files changed, 726 insertions(+), 36 deletions(-) - create mode 100644 builder/pxzcat-c.c - create mode 100644 builder/pxzcat.ml - create mode 100644 builder/pxzcat.mli - -diff --git a/README b/README -index dee3bd4..8192086 100644 ---- a/README -+++ b/README -@@ -174,7 +174,7 @@ The full requirements are described below. - | gpg | | O | Used by virt-builder for digital | - | | | | signatures | - +--------------+-------------+---+-----------------------------------------+ --| pxzcat | | O | Can be used by virt-builder for fast | -+| liblzma | | O | Can be used by virt-builder for fast | - | | | | uncompression of templates. | - +--------------+-------------+---+-----------------------------------------+ - | findlib | | O | For the OCaml bindings. | -diff --git a/builder/Makefile.am b/builder/Makefile.am -index b892477..1c469ac 100644 ---- a/builder/Makefile.am -+++ b/builder/Makefile.am -@@ -21,7 +21,9 @@ AM_YFLAGS = -d - AM_CFLAGS = \ - -I$(shell $(OCAMLC) -where) \ - -I$(top_srcdir)/src \ -- -I$(top_srcdir)/fish -+ -I$(top_srcdir)/fish \ -+ -pthread \ -+ $(LIBLZMA_CFLAGS) - - EXTRA_DIST = \ - $(SOURCES) \ -@@ -45,6 +47,9 @@ SOURCES = \ - index-parser-c.c \ - list_entries.mli \ - list_entries.ml \ -+ pxzcat.ml \ -+ pxzcat.mli \ -+ pxzcat-c.c \ - sigchecker.mli \ - sigchecker.ml - -@@ -73,6 +78,8 @@ OBJECTS = \ - index-struct.o \ - index-parse.o \ - index-parser-c.o \ -+ pxzcat-c.o \ -+ pxzcat.cmx \ - get_kernel.cmx \ - downloader.cmx \ - sigchecker.cmx \ -@@ -101,7 +108,7 @@ OCAMLOPTFLAGS = $(OCAMLCFLAGS) - virt-builder: $(OBJECTS) - $(OCAMLFIND) ocamlopt $(OCAMLOPTFLAGS) \ - mlguestfs.cmxa -linkpkg $^ \ -- -cclib '-lncurses -lcrypt' \ -+ -cclib '-pthread $(LIBLZMA_LIBS) -lncurses -lcrypt -lpthread' \ - $(OCAML_GCOV_LDFLAGS) \ - -o $@ - -diff --git a/builder/builder.ml b/builder/builder.ml -index b375de4..7cbc539 100644 ---- a/builder/builder.ml -+++ b/builder/builder.ml -@@ -24,6 +24,7 @@ open Common_utils - open Password - - open Cmdline -+open Pxzcat - - open Unix - open Printf -@@ -330,27 +331,14 @@ let main () = - - output, Some size, format, delete_output_file, do_resize, true in - -- (* Create xzcat/pxzcat command to uncompress from input to output. *) -- let xzcat_command input output = -- match Config.pxzcat with -- | None -> sprintf "%s %s > %s" Config.xzcat input output -- | Some pxzcat -> sprintf "%s %s -o %s" pxzcat input output -- in -- - if not do_resize then ( - (* If the user did not specify --size and the output is a regular - * file and the format is raw, then we just uncompress the template - * directly to the output file. This is fast but less flexible. - *) - let { Index_parser.file_uri = file_uri } = entry in -- let cmd = xzcat_command template output in -- if debug then eprintf "%s\n%!" cmd; - msg (f_"Uncompressing: %s") file_uri; -- let r = Sys.command cmd in -- if r <> 0 then ( -- eprintf (f_"%s: error: failed to uncompress template\n") prog; -- exit 1 -- ) -+ pxzcat template output - ) else ( - (* If none of the above apply, uncompress to a temporary file and - * run virt-resize on the result. -@@ -359,14 +347,8 @@ let main () = - (* Uncompress it to a temporary file. *) - let { Index_parser.file_uri = file_uri } = entry in - let tmpfile = Filename.temp_file "vbsrc" ".img" in -- let cmd = xzcat_command template tmpfile in -- if debug then eprintf "%s\n%!" cmd; - msg (f_"Uncompressing: %s") file_uri; -- let r = Sys.command cmd in -- if r <> 0 then ( -- eprintf (f_"%s: error: failed to uncompress template\n") prog; -- exit 1 -- ); -+ pxzcat template tmpfile; - unlink_on_exit tmpfile; - tmpfile in - -diff --git a/builder/pxzcat-c.c b/builder/pxzcat-c.c -new file mode 100644 -index 0000000..5ffc9d9 ---- /dev/null -+++ b/builder/pxzcat-c.c -@@ -0,0 +1,650 @@ -+/* virt-builder -+ * Copyright (C) 2013 Red Hat Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include -+#include -+#include -+#include -+ -+#ifdef HAVE_CAML_UNIXSUPPORT_H -+#include -+#else -+#define Nothing ((value) 0) -+extern void unix_error (int errcode, char * cmdname, value arg) Noreturn; -+#endif -+ -+#ifdef HAVE_LIBLZMA -+#include -+ -+static void pxzcat (value filenamev, value outputfilev, unsigned nr_threads); -+#endif -+ -+value -+virt_builder_pxzcat (value inputfilev, value outputfilev) -+{ -+ CAMLparam2 (inputfilev, outputfilev); -+ -+#ifdef HAVE_LIBLZMA -+ -+ /* Parallel implementation of xzcat (pxzcat). */ -+ /* XXX Make number of threads configurable? */ -+ long i; -+ unsigned nr_threads; -+ -+ i = sysconf (_SC_NPROCESSORS_ONLN); -+ if (i <= 0) { -+ perror ("could not get number of cores"); -+ i = 1; -+ } -+ nr_threads = (unsigned) i; -+ -+ /* NB: This might throw an exception if something fails. If it -+ * does, this function won't return as a regular C function. -+ */ -+ pxzcat (inputfilev, outputfilev, nr_threads); -+ -+#else -+ -+ /* Fallback: use regular xzcat. */ -+ int fd; -+ pid_t pid; -+ int status; -+ -+ fd = open (String_val (outputfilev), O_WRONLY|O_CREAT|O_TRUNC|O_NOCTTY, 0666); -+ if (fd == -1) -+ unix_error (errno, "open", outputfilev); -+ -+ pid = fork (); -+ if (pid == -1) { -+ int err = errno; -+ close (fd); -+ unix_error (err, "fork", Nothing); -+ } -+ -+ if (pid == 0) { /* child - run xzcat */ -+ dup2 (fd, 1); -+ execlp (XZCAT, XZCAT, String_val (inputfilev), NULL); -+ perror (XZCAT); -+ _exit (EXIT_FAILURE); -+ } -+ -+ close (fd); -+ -+ if (waitpid (pid, &status, 0) == -1) -+ unix_error (errno, "waitpid", Nothing); -+ if (!WIFEXITED (status) || WEXITSTATUS (status) != 0) -+ caml_failwith (XZCAT " program failed, see earlier error messages"); -+ -+#endif -+ -+ CAMLreturn (Val_unit); -+} -+ -+#ifdef HAVE_LIBLZMA -+ -+#define DEBUG 0 -+ -+#if DEBUG -+#define debug(fs,...) fprintf (stderr, "pxzcat: debug: " fs "\n", ## __VA_ARGS__) -+#else -+#define debug(fs,...) /* nothing */ -+#endif -+ -+/* Size of buffers used in decompression loop. */ -+#define BUFFER_SIZE (64*1024) -+ -+#define XZ_HEADER_MAGIC "\xfd" "7zXZ\0" -+#define XZ_HEADER_MAGIC_LEN 6 -+#define XZ_FOOTER_MAGIC "YZ" -+#define XZ_FOOTER_MAGIC_LEN 2 -+ -+static int check_header_magic (int fd); -+static lzma_index *parse_indexes (value filenamev, int fd); -+static void iter_blocks (lzma_index *idx, unsigned nr_threads, value filenamev, int fd, value outputfilev, int ofd); -+ -+static void -+pxzcat (value filenamev, value outputfilev, unsigned nr_threads) -+{ -+ int fd, ofd; -+ uint64_t size; -+ lzma_index *idx; -+ -+ /* Open the file. */ -+ fd = open (String_val (filenamev), O_RDONLY); -+ if (fd == -1) -+ unix_error (errno, "open", filenamev); -+ -+ /* Check file magic. */ -+ if (!check_header_magic (fd)) { -+ close (fd); -+ caml_invalid_argument ("input file is not an xz file"); -+ } -+ -+ /* Read and parse the indexes. */ -+ idx = parse_indexes (filenamev, fd); -+ -+ /* Get the file uncompressed size, create the output file. */ -+ size = lzma_index_uncompressed_size (idx); -+ debug ("uncompressed size = %" PRIu64 " bytes", size); -+ -+ /* Avoid annoying ext4 auto_da_alloc which causes a flush on close -+ * unless we are very careful about not truncating a regular file -+ * from non-zero size to zero size. (Thanks Eric Sandeen) -+ */ -+ ofd = open (String_val (outputfilev), O_WRONLY|O_CREAT|O_NOCTTY, 0644); -+ if (ofd == -1) { -+ int err = errno; -+ close (fd); -+ unix_error (err, "open", outputfilev); -+ } -+ -+ if (ftruncate (ofd, 1) == -1) { -+ int err = errno; -+ close (fd); -+ unix_error (err, "ftruncate", outputfilev); -+ } -+ -+ if (lseek (ofd, 0, SEEK_SET) == -1) { -+ int err = errno; -+ close (fd); -+ unix_error (err, "lseek", outputfilev); -+ } -+ -+ if (write (ofd, "\0", 1) == -1) { -+ int err = errno; -+ close (fd); -+ unix_error (err, "write", outputfilev); -+ } -+ -+ if (ftruncate (ofd, size) == -1) { -+ int err = errno; -+ close (fd); -+ unix_error (err, "ftruncate", outputfilev); -+ } -+ -+ /* Tell the kernel we won't read the output file. */ -+ posix_fadvise (fd, 0, 0, POSIX_FADV_RANDOM|POSIX_FADV_DONTNEED); -+ -+ /* Iterate over blocks. */ -+ iter_blocks (idx, nr_threads, filenamev, fd, outputfilev, ofd); -+ -+ lzma_index_end (idx, NULL); -+ -+ if (close (fd) == -1) -+ unix_error (errno, "close", filenamev); -+} -+ -+static int -+check_header_magic (int fd) -+{ -+ char buf[XZ_HEADER_MAGIC_LEN]; -+ -+ if (lseek (fd, 0, SEEK_SET) == -1) -+ return 0; -+ if (read (fd, buf, XZ_HEADER_MAGIC_LEN) != XZ_HEADER_MAGIC_LEN) -+ return 0; -+ if (memcmp (buf, XZ_HEADER_MAGIC, XZ_HEADER_MAGIC_LEN) != 0) -+ return 0; -+ return 1; -+} -+ -+/* For explanation of this function, see src/xz/list.c:parse_indexes -+ * in the xz sources. -+ */ -+static lzma_index * -+parse_indexes (value filenamev, int fd) -+{ -+ lzma_ret r; -+ off_t pos, index_size; -+ uint8_t footer[LZMA_STREAM_HEADER_SIZE]; -+ uint8_t header[LZMA_STREAM_HEADER_SIZE]; -+ lzma_stream_flags footer_flags; -+ lzma_stream_flags header_flags; -+ lzma_stream strm = LZMA_STREAM_INIT; -+ ssize_t n; -+ lzma_index *combined_index = NULL; -+ lzma_index *this_index = NULL; -+ lzma_vli stream_padding = 0; -+ size_t nr_streams = 0; -+ -+ /* Check file size is a multiple of 4 bytes. */ -+ pos = lseek (fd, 0, SEEK_END); -+ if (pos == (off_t) -1) -+ unix_error (errno, "lseek", filenamev); -+ -+ if ((pos & 3) != 0) -+ caml_invalid_argument ("input not an xz file: size is not a multiple of 4 bytes"); -+ -+ /* Jump backwards through the file identifying each stream. */ -+ while (pos > 0) { -+ debug ("looping through streams: pos = %" PRIu64, (uint64_t) pos); -+ -+ if (pos < LZMA_STREAM_HEADER_SIZE) -+ caml_invalid_argument ("corrupted xz file"); -+ -+ if (lseek (fd, -LZMA_STREAM_HEADER_SIZE, SEEK_CUR) == -1) -+ unix_error (errno, "lseek", filenamev); -+ -+ if (read (fd, footer, LZMA_STREAM_HEADER_SIZE) != LZMA_STREAM_HEADER_SIZE) -+ unix_error (errno, "read", filenamev); -+ -+ /* Skip stream padding. */ -+ if (footer[8] == 0 && footer[9] == 0 && -+ footer[10] == 0 && footer[11] == 0) { -+ stream_padding += 4; -+ pos -= 4; -+ continue; -+ } -+ -+ pos -= LZMA_STREAM_HEADER_SIZE; -+ nr_streams++; -+ -+ debug ("decode stream footer at pos = %" PRIu64, (uint64_t) pos); -+ -+ /* Does the stream footer look reasonable? */ -+ r = lzma_stream_footer_decode (&footer_flags, footer); -+ if (r != LZMA_OK) { -+ fprintf (stderr, "invalid stream footer - error %d\n", r); -+ caml_invalid_argument ("invalid stream footer"); -+ } -+ -+ debug ("backward_size = %" PRIu64, (uint64_t) footer_flags.backward_size); -+ index_size = footer_flags.backward_size; -+ if (pos < index_size + LZMA_STREAM_HEADER_SIZE) -+ caml_invalid_argument ("invalid stream footer"); -+ -+ pos -= index_size; -+ debug ("decode index at pos = %" PRIu64, (uint64_t) pos); -+ -+ /* Seek backwards to the index of this stream. */ -+ if (lseek (fd, pos, SEEK_SET) == -1) -+ unix_error (errno, "lseek", filenamev); -+ -+ /* Decode the index. */ -+ r = lzma_index_decoder (&strm, &this_index, UINT64_MAX); -+ if (r != LZMA_OK) { -+ fprintf (stderr, "invalid stream index - error %d\n", r); -+ caml_invalid_argument ("invalid stream index"); -+ } -+ -+ do { -+ uint8_t buf[BUFSIZ]; -+ -+ strm.avail_in = index_size; -+ if (strm.avail_in > BUFSIZ) -+ strm.avail_in = BUFSIZ; -+ -+ n = read (fd, &buf, strm.avail_in); -+ if (n == -1) -+ unix_error (errno, "read", filenamev); -+ -+ index_size -= strm.avail_in; -+ -+ strm.next_in = buf; -+ r = lzma_code (&strm, LZMA_RUN); -+ } while (r == LZMA_OK); -+ -+ if (r != LZMA_STREAM_END) { -+ fprintf (stderr, "could not parse index - error %d\n", r); -+ caml_invalid_argument ("could not parse index"); -+ } -+ -+ pos -= lzma_index_total_size (this_index) + LZMA_STREAM_HEADER_SIZE; -+ -+ debug ("decode stream header at pos = %" PRIu64, (uint64_t) pos); -+ -+ /* Read and decode the stream header. */ -+ if (lseek (fd, pos, SEEK_SET) == -1) -+ unix_error (errno, "lseek", filenamev); -+ -+ if (read (fd, header, LZMA_STREAM_HEADER_SIZE) != LZMA_STREAM_HEADER_SIZE) -+ unix_error (errno, "read stream header", filenamev); -+ -+ r = lzma_stream_header_decode (&header_flags, header); -+ if (r != LZMA_OK) { -+ fprintf (stderr, "invalid stream header - error %d\n", r); -+ caml_invalid_argument ("invalid stream header"); -+ } -+ -+ /* Header and footer of the stream should be equal. */ -+ r = lzma_stream_flags_compare (&header_flags, &footer_flags); -+ if (r != LZMA_OK) { -+ fprintf (stderr, "header and footer of stream are not equal - error %d\n", -+ r); -+ caml_invalid_argument ("header and footer of stream are not equal"); -+ } -+ -+ /* Store the decoded stream flags in this_index. */ -+ r = lzma_index_stream_flags (this_index, &footer_flags); -+ if (r != LZMA_OK) { -+ fprintf (stderr, "cannot read stream_flags from index - error %d\n", r); -+ caml_invalid_argument ("cannot read stream_flags from index"); -+ } -+ -+ /* Store the amount of stream padding so far. Needed to calculate -+ * compressed offsets correctly in multi-stream files. -+ */ -+ r = lzma_index_stream_padding (this_index, stream_padding); -+ if (r != LZMA_OK) { -+ fprintf (stderr, "cannot set stream_padding in index - error %d\n", r); -+ caml_invalid_argument ("cannot set stream_padding in index"); -+ } -+ -+ if (combined_index != NULL) { -+ r = lzma_index_cat (this_index, combined_index, NULL); -+ if (r != LZMA_OK) { -+ fprintf (stderr, "cannot combine indexes - error %d\n", r); -+ caml_invalid_argument ("cannot combine indexes"); -+ } -+ } -+ -+ combined_index = this_index; -+ this_index = NULL; -+ } -+ -+ lzma_end (&strm); -+ -+ return combined_index; -+} -+ -+/* Return true iff the buffer is all zero bytes. -+ * -+ * Note that gcc is smart enough to optimize this properly: -+ * http://stackoverflow.com/questions/1493936/faster-means-of-checking-for-an-empty-buffer-in-c/1493989#1493989 -+ */ -+static inline int -+is_zero (const char *buffer, size_t size) -+{ -+ size_t i; -+ -+ for (i = 0; i < size; ++i) { -+ if (buffer[i] != 0) -+ return 0; -+ } -+ -+ return 1; -+} -+ -+struct global_state { -+ /* Current iterator. Threads update this, but it is protected by a -+ * mutex, and each thread takes a copy of it when working on it. -+ */ -+ lzma_index_iter iter; -+ lzma_bool iter_finished; -+ pthread_mutex_t iter_mutex; -+ -+ /* Note that all threads are accessing these fds, so you have -+ * to use pread/pwrite instead of lseek! -+ */ -+ -+ /* Input file. */ -+ const char *filename; -+ int fd; -+ -+ /* Output file. */ -+ const char *outputfile; -+ int ofd; -+}; -+ -+struct per_thread_state { -+ unsigned thread_num; -+ struct global_state *global; -+ int status; -+}; -+ -+/* Create threads to iterate over the blocks and uncompress. */ -+static void *worker_thread (void *vp); -+ -+static void -+iter_blocks (lzma_index *idx, unsigned nr_threads, -+ value filenamev, int fd, value outputfilev, int ofd) -+{ -+ struct global_state global; -+ struct per_thread_state per_thread[nr_threads]; -+ pthread_t thread[nr_threads]; -+ unsigned u, nr_errors; -+ int err; -+ void *status; -+ -+ lzma_index_iter_init (&global.iter, idx); -+ global.iter_finished = 0; -+ err = pthread_mutex_init (&global.iter_mutex, NULL); -+ if (err != 0) -+ unix_error (err, "pthread_mutex_init", Nothing); -+ -+ global.filename = String_val (filenamev); -+ global.fd = fd; -+ global.outputfile = String_val (outputfilev); -+ global.ofd = ofd; -+ -+ for (u = 0; u < nr_threads; ++u) { -+ per_thread[u].thread_num = u; -+ per_thread[u].global = &global; -+ } -+ -+ /* Start the threads. */ -+ for (u = 0; u < nr_threads; ++u) { -+ err = pthread_create (&thread[u], NULL, worker_thread, &per_thread[u]); -+ if (err != 0) -+ unix_error (err, "pthread_create", Nothing); -+ } -+ -+ /* Wait for the threads to exit. */ -+ nr_errors = 0; -+ for (u = 0; u < nr_threads; ++u) { -+ err = pthread_join (thread[u], &status); -+ if (err != 0) { -+ fprintf (stderr, "pthread_join (%u): %s\n", u, strerror (err)); -+ nr_errors++; -+ } -+ if (*(int *)status == -1) -+ nr_errors++; -+ } -+ -+ if (nr_errors > 0) -+ caml_invalid_argument ("some threads failed, see earlier errors"); -+} -+ -+/* Iterate over the blocks and uncompress. */ -+static void * -+worker_thread (void *vp) -+{ -+ struct per_thread_state *state = vp; -+ struct global_state *global = state->global; -+ lzma_index_iter iter; -+ int err; -+ off_t position, oposition; -+ uint8_t header[LZMA_BLOCK_HEADER_SIZE_MAX]; -+ ssize_t n; -+ lzma_block block; -+ lzma_filter filters[LZMA_FILTERS_MAX + 1]; -+ lzma_ret r; -+ lzma_stream strm = LZMA_STREAM_INIT; -+ uint8_t buf[BUFFER_SIZE]; -+ char outbuf[BUFFER_SIZE]; -+ size_t i; -+ lzma_bool iter_finished; -+ -+ state->status = -1; -+ -+ for (;;) { -+ /* Get the next block. */ -+ err = pthread_mutex_lock (&global->iter_mutex); -+ if (err != 0) abort (); -+ iter_finished = global->iter_finished; -+ if (!iter_finished) { -+ iter_finished = global->iter_finished = -+ lzma_index_iter_next (&global->iter, LZMA_INDEX_ITER_NONEMPTY_BLOCK); -+ if (!iter_finished) -+ /* Take a local copy of this iterator since another thread will -+ * update the global version. -+ */ -+ iter = global->iter; -+ } -+ err = pthread_mutex_unlock (&global->iter_mutex); -+ if (err != 0) abort (); -+ if (iter_finished) -+ break; -+ -+ /* Read the block header. Start by reading a single byte which -+ * tell us how big the block header is. -+ */ -+ position = iter.block.compressed_file_offset; -+ n = pread (global->fd, header, 1, position); -+ if (n == 0) { -+ fprintf (stderr, -+ "%s: read: unexpected end of file reading block header byte\n", -+ global->filename); -+ return &state->status; -+ } -+ if (n == -1) { -+ perror (String_val (global->filename)); -+ return &state->status; -+ } -+ position++; -+ -+ if (header[0] == '\0') { -+ fprintf (stderr, -+ "%s: read: unexpected invalid block in file, header[0] = 0\n", -+ global->filename); -+ return &state->status; -+ } -+ -+ block.version = 0; -+ block.check = iter.stream.flags->check; -+ block.filters = filters; -+ block.header_size = lzma_block_header_size_decode (header[0]); -+ -+ /* Now read and decode the block header. */ -+ n = pread (global->fd, &header[1], block.header_size-1, position); -+ if (n >= 0 && n != block.header_size-1) { -+ fprintf (stderr, -+ "%s: read: unexpected end of file reading block header\n", -+ global->filename); -+ return &state->status; -+ } -+ if (n == -1) { -+ perror (global->filename); -+ return &state->status; -+ } -+ position += n; -+ -+ r = lzma_block_header_decode (&block, NULL, header); -+ if (r != LZMA_OK) { -+ fprintf (stderr, "%s: invalid block header (error %d)\n", -+ global->filename, r); -+ return &state->status; -+ } -+ -+ /* What this actually does is it checks that the block header -+ * matches the index. -+ */ -+ r = lzma_block_compressed_size (&block, iter.block.unpadded_size); -+ if (r != LZMA_OK) { -+ fprintf (stderr, -+ "%s: cannot calculate compressed size (error %d)\n", -+ global->filename, r); -+ return &state->status; -+ } -+ -+ /* Where we will start writing to. */ -+ oposition = iter.block.uncompressed_file_offset; -+ -+ /* Read the block data and uncompress it. */ -+ r = lzma_block_decoder (&strm, &block); -+ if (r != LZMA_OK) { -+ fprintf (stderr, "%s: invalid block (error %d)\n", global->filename, r); -+ return &state->status; -+ } -+ -+ strm.next_in = NULL; -+ strm.avail_in = 0; -+ strm.next_out = outbuf; -+ strm.avail_out = sizeof outbuf; -+ -+ for (;;) { -+ lzma_action action = LZMA_RUN; -+ -+ if (strm.avail_in == 0) { -+ strm.next_in = buf; -+ n = pread (global->fd, buf, sizeof buf, position); -+ if (n == -1) { -+ perror (global->filename); -+ return &state->status; -+ } -+ position += n; -+ strm.avail_in = n; -+ if (n == 0) -+ action = LZMA_FINISH; -+ } -+ -+ r = lzma_code (&strm, action); -+ -+ if (strm.avail_out == 0 || r == LZMA_STREAM_END) { -+ size_t wsz = sizeof outbuf - strm.avail_out; -+ -+ /* Don't write if the block is all zero, to preserve output file -+ * sparseness. However we have to update oposition. -+ */ -+ if (!is_zero (outbuf, wsz)) { -+ if (pwrite (global->ofd, outbuf, wsz, oposition) != wsz) { -+ /* XXX Handle short writes. */ -+ perror (global->filename); -+ return &state->status; -+ } -+ } -+ oposition += wsz; -+ -+ strm.next_out = outbuf; -+ strm.avail_out = sizeof outbuf; -+ } -+ -+ if (r == LZMA_STREAM_END) -+ break; -+ if (r != LZMA_OK) { -+ fprintf (stderr, -+ "%s: could not parse block data (error %d)\n", -+ global->filename, r); -+ return &state->status; -+ } -+ } -+ -+ lzma_end (&strm); -+ -+ for (i = 0; filters[i].id != LZMA_VLI_UNKNOWN; ++i) -+ free (filters[i].options); -+ } -+ -+ state->status = 0; -+ return &state->status; -+} -+ -+#endif /* HAVE_LIBLZMA */ -diff --git a/builder/pxzcat.ml b/builder/pxzcat.ml -new file mode 100644 -index 0000000..5645370 ---- /dev/null -+++ b/builder/pxzcat.ml -@@ -0,0 +1,19 @@ -+(* virt-builder -+ * Copyright (C) 2013 Red Hat Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ *) -+ -+external pxzcat : string -> string -> unit = "virt_builder_pxzcat" -diff --git a/builder/pxzcat.mli b/builder/pxzcat.mli -new file mode 100644 -index 0000000..a2830f0 ---- /dev/null -+++ b/builder/pxzcat.mli -@@ -0,0 +1,31 @@ -+(* virt-builder -+ * Copyright (C) 2013 Red Hat Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ *) -+ -+(** {1 Parallel xzcat (or fall back to regular xzcat).} -+ -+ Eventually regular xzcat will be able to work in parallel and this -+ code can go away. -+*) -+ -+val pxzcat : string -> string -> unit -+ (** [pxzcat input output] uncompresses the file [input] to the file -+ [output]. The input and output must both be seekable. -+ -+ If liblzma was found at compile time, this uses an internal -+ implementation of parallel xzcat. Otherwise regular xzcat is -+ used. *) -diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod -index ce22920..e84d87f 100644 ---- a/builder/virt-builder.pod -+++ b/builder/virt-builder.pod -@@ -1438,10 +1438,9 @@ the output format is the same as the template format (usually raw). - - =head3 pxzcat - --Virt-builder can use C (parallel xzcat) if available to --uncompress the templates. The default is to use regular C --which is single-threaded. Currently this has to be compiled in, --ie. virt-builder will probably need to be recompiled to use pxzcat. -+Virt-builder uses an internal implementation of pxzcat (parallel -+xzcat) if liblzma was found at build time. If liblzma was not found -+at build time, regular C is used which is single-threaded. - - =head2 USER MODE LINUX - -diff --git a/configure.ac b/configure.ac -index 21d89a0..922ab6b 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -707,9 +707,15 @@ fi - dnl Check for xzcat (required). - AC_PATH_PROGS([XZCAT],[xzcat],[no]) - test "x$XZCAT" = "xno" && AC_MSG_ERROR([xzcat must be installed]) -+AC_DEFINE_UNQUOTED([XZCAT],["$XZCAT"],[Name of xzcat program.]) - --dnl Check for pxzcat (optional). --AC_PATH_PROGS([PXZCAT],[pxzcat],[no]) -+dnl liblzma can be used by virt-builder (optional). -+PKG_CHECK_MODULES([LIBLZMA], [liblzma],[ -+ AC_SUBST([LIBLZMA_CFLAGS]) -+ AC_SUBST([LIBLZMA_LIBS]) -+ AC_DEFINE([HAVE_LIBLZMA],[1],[liblzma found at compile time.]) -+], -+[AC_MSG_WARN([liblzma not found, virt-builder will be slower])]) - - dnl (f)lex and bison are required for virt-builder. - AC_PROG_LEX -diff --git a/mllib/config.ml.in b/mllib/config.ml.in -index 5586c5c..d18bf7b 100644 ---- a/mllib/config.ml.in -+++ b/mllib/config.ml.in -@@ -18,9 +18,3 @@ - - let package_name = "@PACKAGE_NAME@" - let package_version = "@PACKAGE_VERSION@" -- --let xzcat = "@XZCAT@" --let pxzcat = -- match "@PXZCAT@" with -- | "no" -> None -- | path -> Some path -diff --git a/po/POTFILES b/po/POTFILES -index ebbea3d..c743fa9 100644 ---- a/po/POTFILES -+++ b/po/POTFILES -@@ -4,6 +4,7 @@ builder/index-parser-c.c - builder/index-scan.c - builder/index-struct.c - builder/index-validate.c -+builder/pxzcat-c.c - cat/cat.c - cat/filesystems.c - cat/ls.c -diff --git a/po/POTFILES-ml b/po/POTFILES-ml -index 04b88be..c4ea888 100644 ---- a/po/POTFILES-ml -+++ b/po/POTFILES-ml -@@ -4,6 +4,7 @@ builder/downloader.ml - builder/get_kernel.ml - builder/index_parser.ml - builder/list_entries.ml -+builder/pxzcat.ml - builder/sigchecker.ml - mllib/common_gettext.ml - mllib/common_utils.ml --- -1.8.5.3 - diff --git a/0017-builder-website-Add-validate.sh-test-script-to-EXTRA.patch b/0017-builder-website-Add-validate.sh-test-script-to-EXTRA.patch deleted file mode 100644 index e2da28e..0000000 --- a/0017-builder-website-Add-validate.sh-test-script-to-EXTRA.patch +++ /dev/null @@ -1,27 +0,0 @@ -From e4fe80938fe6f4a2b2a92ce131455de3e219718e Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 5 Nov 2013 15:15:17 +0000 -Subject: [PATCH] builder/website: Add validate.sh test script to EXTRA_DIST. - -This fixes commit 154bfb7dd46e7998eed1d40ead95923590763739. - -(cherry picked from commit 92206e8d09455b3ec63d44e4b55d5eef415681af) ---- - builder/website/Makefile.am | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/builder/website/Makefile.am b/builder/website/Makefile.am -index cf13ed4..a5b1bcf 100644 ---- a/builder/website/Makefile.am -+++ b/builder/website/Makefile.am -@@ -21,6 +21,7 @@ EXTRA_DIST = \ - .gitignore \ - compress.sh \ - test-guest.sh \ -+ validate.sh \ - README \ - index \ - index.asc \ --- -1.8.5.3 - diff --git a/0018-builder-Add-missing-dependency.patch b/0018-builder-Add-missing-dependency.patch deleted file mode 100644 index 834289a..0000000 --- a/0018-builder-Add-missing-dependency.patch +++ /dev/null @@ -1,33 +0,0 @@ -From d23c5f8b33831724c9b0f067373fde48f897f439 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 5 Nov 2013 15:42:05 +0000 -Subject: [PATCH] builder: Add missing dependency. - -index-parser-c.c depends on index-parse.h being created first. -However without an explicit dependency, this is not done (and implicit -deps don't work because automake doesn't sufficiently understand OCaml -programs). - -This fixes commit a4800e2d4fc50f372a8b626333c4fbb9b8ca9633. - -(cherry picked from commit dfe97b352d6b398c3cb3ddb1c9984767722e514b) ---- - builder/Makefile.am | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/builder/Makefile.am b/builder/Makefile.am -index 1c469ac..30741a0 100644 ---- a/builder/Makefile.am -+++ b/builder/Makefile.am -@@ -119,6 +119,8 @@ virt-builder: $(OBJECTS) - .ml.cmx: - $(OCAMLFIND) ocamlopt $(OCAMLOPTFLAGS) -c $< -o $@ - -+index-parser-c.o: index-parse.h -+ - # Manual pages and HTML files for the website. - - man_MANS += virt-builder.1 --- -1.8.5.3 - diff --git a/0019-builder-Add-some-generated-files-to-CLEANFILES.patch b/0019-builder-Add-some-generated-files-to-CLEANFILES.patch deleted file mode 100644 index aacb39c..0000000 --- a/0019-builder-Add-some-generated-files-to-CLEANFILES.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 764516c4512ec8e45013520417172e4409803f55 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 5 Nov 2013 15:43:24 +0000 -Subject: [PATCH] builder: Add some generated files to CLEANFILES. - -This updates commit a4800e2d4fc50f372a8b626333c4fbb9b8ca9633. - -(cherry picked from commit 01551e546293bbbd094d4d4acfdaf421f7758251) ---- - builder/Makefile.am | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/builder/Makefile.am b/builder/Makefile.am -index 30741a0..244214b 100644 ---- a/builder/Makefile.am -+++ b/builder/Makefile.am -@@ -204,4 +204,8 @@ stamp-virt-index-validate.pod: virt-index-validate.pod - $< - touch $@ - --CLEANFILES += stamp-virt-index-validate.pod -+CLEANFILES += \ -+ index-parse.c \ -+ index-parse.h \ -+ index-scan.c \ -+ stamp-virt-index-validate.pod --- -1.8.5.3 - diff --git a/0020-builder-Add-dependency-from-index-parse.h-to-index-v.patch b/0020-builder-Add-dependency-from-index-parse.h-to-index-v.patch deleted file mode 100644 index ab166b9..0000000 --- a/0020-builder-Add-dependency-from-index-parse.h-to-index-v.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 3ae2ab0a49b6b23e883dd1eb66e6a5a408c70143 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 5 Nov 2013 15:56:34 +0000 -Subject: [PATCH] builder: Add dependency from index-parse.h to index-validate. - -For some reason automake doesn't get this dependency right, -resulting in occasional build failures if yacc races the -rest of the build. - -(cherry picked from commit e3ac293e869a4c69225e3d954b812e9bf21588a1) ---- - builder/Makefile.am | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/builder/Makefile.am b/builder/Makefile.am -index 244214b..09401af 100644 ---- a/builder/Makefile.am -+++ b/builder/Makefile.am -@@ -191,6 +191,8 @@ virt_index_validate_SOURCES = \ - index-struct.c \ - index-validate.c - -+index-validate.o: index-parse.h -+ - man_MANS += virt-index-validate.1 - noinst_DATA += $(top_builddir)/html/virt-index-validate.1.html - --- -1.8.5.3 - diff --git a/0021-builder-Add-dependencies-which-automake-doesn-t-gene.patch b/0021-builder-Add-dependencies-which-automake-doesn-t-gene.patch deleted file mode 100644 index 496e7ec..0000000 --- a/0021-builder-Add-dependencies-which-automake-doesn-t-gene.patch +++ /dev/null @@ -1,51 +0,0 @@ -From d1d175746af6611ecfc52aa2eaa97152c22ecffc Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 5 Nov 2013 17:40:20 +0000 -Subject: [PATCH] builder: Add dependencies which automake doesn't generate - correctly. - -This is a further attempt, earlier commits: -commit e3ac293e869a4c69225e3d954b812e9bf21588a1 -commit dfe97b352d6b398c3cb3ddb1c9984767722e514b - -(cherry picked from commit 4339b55d105eab6eba2756bffff42a1c34f9f656) ---- - builder/Makefile.am | 11 +++++++---- - 1 file changed, 7 insertions(+), 4 deletions(-) - -diff --git a/builder/Makefile.am b/builder/Makefile.am -index 09401af..8e7f104 100644 ---- a/builder/Makefile.am -+++ b/builder/Makefile.am -@@ -119,8 +119,6 @@ virt-builder: $(OBJECTS) - .ml.cmx: - $(OCAMLFIND) ocamlopt $(OCAMLOPTFLAGS) -c $< -o $@ - --index-parser-c.o: index-parse.h -- - # Manual pages and HTML files for the website. - - man_MANS += virt-builder.1 -@@ -191,8 +189,6 @@ virt_index_validate_SOURCES = \ - index-struct.c \ - index-validate.c - --index-validate.o: index-parse.h -- - man_MANS += virt-index-validate.1 - noinst_DATA += $(top_builddir)/html/virt-index-validate.1.html - -@@ -211,3 +207,10 @@ CLEANFILES += \ - index-parse.h \ - index-scan.c \ - stamp-virt-index-validate.pod -+ -+# Fix dependencies which automake doesn't generate correctly. -+if HAVE_OCAML -+index-parser-c.o: index-parse.h -+index-scan.o: index-parse.h -+endif -+index-validate.o: index-parse.h --- -1.8.5.3 - diff --git a/0022-builder-Fail-if-bison-is-not-installed.patch b/0022-builder-Fail-if-bison-is-not-installed.patch deleted file mode 100644 index ab20d98..0000000 --- a/0022-builder-Fail-if-bison-is-not-installed.patch +++ /dev/null @@ -1,35 +0,0 @@ -From c1d06a3c80572dbdfdce91d0646f87284a3b5306 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 5 Nov 2013 22:25:59 +0000 -Subject: [PATCH] builder: Fail if bison is not installed. - -This partially fixes commit a4800e2d4fc50f372a8b626333c4fbb9b8ca9633. - -(cherry picked from commit f526fe1766471b51b92cad74af0103d1889db83a) ---- - configure.ac | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/configure.ac b/configure.ac -index 922ab6b..e691542 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -717,9 +717,14 @@ PKG_CHECK_MODULES([LIBLZMA], [liblzma],[ - ], - [AC_MSG_WARN([liblzma not found, virt-builder will be slower])]) - --dnl (f)lex and bison are required for virt-builder. -+dnl (f)lex and bison for virt-builder (required). -+dnl XXX Could be optional with some work. - AC_PROG_LEX - AC_PROG_YACC -+dnl These macros don't fail, instead they set some useless defaults. -+if test "x$YACC" = "xyacc"; then -+ AC_MSG_FAILURE([GNU 'bison' is required (yacc won't work).]) -+fi - - dnl Check for QEMU for running binaries on this $host_cpu, fall - dnl back to basic 'qemu'. Allow the user to override it. --- -1.8.5.3 - diff --git a/0023-builder-Fail-if-lex-is-not-installed.patch b/0023-builder-Fail-if-lex-is-not-installed.patch deleted file mode 100644 index 47417e4..0000000 --- a/0023-builder-Fail-if-lex-is-not-installed.patch +++ /dev/null @@ -1,29 +0,0 @@ -From ea8ea5d05a17fb068efcb91c0fae01660d1d937a Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 6 Nov 2013 15:08:08 +0000 -Subject: [PATCH] builder: Fail if lex is not installed. - -This completes the fix for commit a4800e2d4fc50f372a8b626333c4fbb9b8ca9633. - -(cherry picked from commit b3a106cefc5dcb356ffb66ef53eba19452ebb60e) ---- - configure.ac | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/configure.ac b/configure.ac -index e691542..56b6b37 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -722,6 +722,9 @@ dnl XXX Could be optional with some work. - AC_PROG_LEX - AC_PROG_YACC - dnl These macros don't fail, instead they set some useless defaults. -+if test "x$LEX" = "x:"; then -+ AC_MSG_FAILURE([GNU 'flex' is required.]) -+fi - if test "x$YACC" = "xyacc"; then - AC_MSG_FAILURE([GNU 'bison' is required (yacc won't work).]) - fi --- -1.8.5.3 - diff --git a/0024-builder-sysprep-Allow-random-as-a-password-selector.patch b/0024-builder-sysprep-Allow-random-as-a-password-selector.patch deleted file mode 100644 index 1401113..0000000 --- a/0024-builder-sysprep-Allow-random-as-a-password-selector.patch +++ /dev/null @@ -1,192 +0,0 @@ -From 1c7ce324c1329326f71542b22172c8fef7508b3c Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 21 Nov 2013 17:34:44 +0000 -Subject: [PATCH] builder/sysprep: Allow 'random' as a password selector. - -This chooses a random password. - -(cherry picked from commit 02b5f00b2bf563d87134ad5f90ec06dbb9535bea) ---- - builder/builder.ml | 34 +++++++++------------------- - builder/virt-builder.pod | 7 ++++++ - mllib/password.ml | 42 +++++++++++++++++++++-------------- - mllib/password.mli | 4 +++- - sysprep/sysprep_operation_password.ml | 7 ++++++ - 5 files changed, 53 insertions(+), 41 deletions(-) - -diff --git a/builder/builder.ml b/builder/builder.ml -index 7cbc539..57e903c 100644 ---- a/builder/builder.ml -+++ b/builder/builder.ml -@@ -445,31 +445,19 @@ let main () = - * Note 'None' means that we randomize the root password. - *) - let () = -- let make_random_password () = -- (* Get random characters from the set [A-Za-z0-9] with some -- * homoglyphs removed. -- *) -- let chars = -- "ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz0123456789" in -- Urandom.urandom_uniform 16 chars -- in -- -- let root_password = -- match root_password with -- | Some pw -> -- msg (f_"Setting root password"); -- pw -- | None -> -- let pw = make_random_password () in -- msg (f_"Random root password: %s [did you mean to use --root-password?]") -- pw; -- Password.Set_password pw in -- - match g#inspect_get_type root with - | "linux" -> -- let h = Hashtbl.create 1 in -- Hashtbl.replace h "root" root_password; -- set_linux_passwords ~prog ?password_crypto g root h -+ let password_map = Hashtbl.create 1 in -+ let pw = -+ match root_password with -+ | Some pw -> -+ msg (f_"Setting root password"); -+ pw -+ | None -> -+ msg (f_"Setting random root password [did you mean to use --root-password?]"); -+ Password.Set_random_password in -+ Hashtbl.replace password_map "root" pw; -+ set_linux_passwords ~prog ?password_crypto g root password_map - | _ -> - eprintf (f_"%s: warning: root password could not be set for this type of guest\n%!") prog in - -diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod -index e84d87f..2803142 100644 ---- a/builder/virt-builder.pod -+++ b/builder/virt-builder.pod -@@ -712,6 +712,13 @@ Set the root password to the literal string C. - B since any user on the same machine can - see the cleartext password using L. - -+=item B<--root-password> random -+ -+Choose a random password, which is printed on stdout. The password -+has approximately 120 bits of randomness. -+ -+This is the default. -+ - =back - - =head3 Creating user accounts -diff --git a/mllib/password.ml b/mllib/password.ml -index 8cadc9d..99923d7 100644 ---- a/mllib/password.ml -+++ b/mllib/password.ml -@@ -17,14 +17,24 @@ - *) - - open Common_gettext.Gettext -+open Common_utils - open Printf - - type password_crypto = [`MD5 | `SHA256 | `SHA512 ] - --type password_selector = Set_password of string -+type password_selector = -+| Set_password of string -+| Set_random_password - - type password_map = (string, password_selector) Hashtbl.t - -+let make_random_password = -+ (* Get random characters from the set [A-Za-z0-9] with some -+ * homoglyphs removed. -+ *) -+ let chars = "ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz0123456789" in -+ fun () -> Urandom.urandom_uniform 16 chars -+ - let password_crypto_of_string ~prog = function - | "md5" -> `MD5 - | "sha256" -> `SHA256 -@@ -35,20 +45,12 @@ let password_crypto_of_string ~prog = function - exit 1 - - let rec parse_selector ~prog arg = -- let i = -- try String.index arg ':' -- with Not_found -> -- eprintf (f_"%s: invalid password format; see the man page.\n") prog; -- exit 1 in -- let key, value = -- let len = String.length arg in -- String.sub arg 0 i, String.sub arg (i+1) (len-(i+1)) in -- -- match key with -- | "file" -> Set_password (read_password_from_file value) -- | "password" -> Set_password value -+ match string_nsplit ":" arg with -+ | [ "file"; filename ] -> Set_password (read_password_from_file filename) -+ | "password" :: password -> Set_password (String.concat ":" password) -+ | [ "random" ] -> Set_random_password - | _ -> -- eprintf (f_"%s: password format, \"%s:...\" is not recognized; see the man page.\n") prog key; -+ eprintf (f_"%s: invalid password selector '%s'; see the man page.\n") prog arg; - exit 1 - - and read_password_from_file filename = -@@ -83,9 +85,15 @@ let rec set_linux_passwords ~prog ?password_crypto g root passwords = - let selector = Hashtbl.find passwords user in - let j = String.index_from line (i+1) ':' in - let rest = String.sub line j (String.length line - j) in -- match selector with -- | Set_password password -> -- user ^ ":" ^ encrypt password crypto ^ rest -+ let pwfield = -+ match selector with -+ | Set_password password -> encrypt password crypto -+ | Set_random_password -> -+ let password = make_random_password () in -+ printf (f_"Setting random password of %s to %s\n%!") -+ user password; -+ encrypt password crypto in -+ user ^ ":" ^ pwfield ^ rest - with Not_found -> line - ) shadow in - -diff --git a/mllib/password.mli b/mllib/password.mli -index 4c72ed7..dce9486 100644 ---- a/mllib/password.mli -+++ b/mllib/password.mli -@@ -21,7 +21,9 @@ type password_crypto = [ `MD5 | `SHA256 | `SHA512 ] - val password_crypto_of_string : prog:string -> string -> password_crypto - (** Parse --password-crypto parameter on command line. *) - --type password_selector = Set_password of string -+type password_selector = -+| Set_password of string -+| Set_random_password - - val parse_selector : prog:string -> string -> password_selector - (** Parse the selector field in --password/--root-password. Note this -diff --git a/sysprep/sysprep_operation_password.ml b/sysprep/sysprep_operation_password.ml -index a5c894f..0cd834a 100644 ---- a/sysprep/sysprep_operation_password.ml -+++ b/sysprep/sysprep_operation_password.ml -@@ -136,6 +136,13 @@ Set the password to the literal string C. - B since any user on the same machine - can see the cleartext password using L. - -+=item B<--password USERNAME:random> -+ -+=item B<--root-password random> -+ -+Choose a random password, which is printed on stdout. The password -+has approximately 120 bits of randomness. -+ - =back" - }; - --- -1.8.5.3 - diff --git a/0025-builder-sysprep-Allow-accounts-to-be-locked-RHBZ-102.patch b/0025-builder-sysprep-Allow-accounts-to-be-locked-RHBZ-102.patch deleted file mode 100644 index f2dacb0..0000000 --- a/0025-builder-sysprep-Allow-accounts-to-be-locked-RHBZ-102.patch +++ /dev/null @@ -1,227 +0,0 @@ -From 3803dd9b2bcd07d061c16f043c4044807ce68595 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 21 Nov 2013 17:13:22 +0000 -Subject: [PATCH] builder/sysprep: Allow accounts to be locked (RHBZ#1028660). - -This allows you to select both locked accounts and disabled -passwords. The two are subtly different concepts. - -A locked account [cf. passwd -l] puts "!!" at the beginning of the -shadow password field. Locking is reversible, because the "!!" can -be removed, restoring the original password. Therefore "locked" -acts as a flag in front of an existing selector. - -A disabled account has "*" in the password field. Therefore it has no -password. - -Note that an account may be both locked and disabled, although this is -probably not useful. The shadow password field will contain "!!*". - -(cherry picked from commit 3712249f9659121277a0d2ca0549e02bc38e0cad) ---- - builder/builder.ml | 2 +- - builder/virt-builder.pod | 21 +++++++++++++++ - mllib/password.ml | 49 ++++++++++++++++++++++++++--------- - mllib/password.mli | 11 +++++--- - sysprep/sysprep_operation_password.ml | 33 +++++++++++++++++++++++ - 5 files changed, 100 insertions(+), 16 deletions(-) - -diff --git a/builder/builder.ml b/builder/builder.ml -index 57e903c..690f3e2 100644 ---- a/builder/builder.ml -+++ b/builder/builder.ml -@@ -455,7 +455,7 @@ let main () = - pw - | None -> - msg (f_"Setting random root password [did you mean to use --root-password?]"); -- Password.Set_random_password in -+ parse_selector ~prog "random" in - Hashtbl.replace password_map "root" pw; - set_linux_passwords ~prog ?password_crypto g root password_map - | _ -> -diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod -index 2803142..817ddd4 100644 ---- a/builder/virt-builder.pod -+++ b/builder/virt-builder.pod -@@ -719,6 +719,27 @@ has approximately 120 bits of randomness. - - This is the default. - -+=item B<--root-password> disabled -+ -+The root account password is disabled. This is like putting C<*> -+in the password field. -+ -+=item B<--root-password> locked:file:FILENAME -+ -+=item B<--root-password> locked:password:PASSWORD -+ -+=item B<--root-password> locked:random -+ -+The root account is locked, but a password is placed on the -+account. If first unlocked (using C) then logins will -+use the given password. -+ -+=item B<--root-password> locked -+ -+=item B<--root-password> locked:disabled -+ -+The root account is locked I password is disabled. -+ - =back - - =head3 Creating user accounts -diff --git a/mllib/password.ml b/mllib/password.ml -index 99923d7..6527138 100644 ---- a/mllib/password.ml -+++ b/mllib/password.ml -@@ -22,9 +22,14 @@ open Printf - - type password_crypto = [`MD5 | `SHA256 | `SHA512 ] - --type password_selector = --| Set_password of string --| Set_random_password -+type password_selector = { -+ pw_password : password; -+ pw_locked : bool; -+} -+and password = -+| Password of string -+| Random_password -+| Disabled_password - - type password_map = (string, password_selector) Hashtbl.t - -@@ -45,12 +50,26 @@ let password_crypto_of_string ~prog = function - exit 1 - - let rec parse_selector ~prog arg = -- match string_nsplit ":" arg with -- | [ "file"; filename ] -> Set_password (read_password_from_file filename) -- | "password" :: password -> Set_password (String.concat ":" password) -- | [ "random" ] -> Set_random_password -+ parse_selector_list ~prog arg (string_nsplit ":" arg) -+ -+and parse_selector_list ~prog orig_arg = function -+ | [ "lock"|"locked" ] -> -+ { pw_locked = true; pw_password = Disabled_password } -+ | ("lock"|"locked") :: rest -> -+ let pw = parse_selector_list ~prog orig_arg rest in -+ { pw with pw_locked = true } -+ | [ "file"; filename ] -> -+ { pw_password = Password (read_password_from_file filename); -+ pw_locked = false } -+ | "password" :: password -> -+ { pw_password = Password (String.concat ":" password); pw_locked = false } -+ | [ "random" ] -> -+ { pw_password = Random_password; pw_locked = false } -+ | [ "disable"|"disabled" ] -> -+ { pw_password = Disabled_password; pw_locked = false } - | _ -> -- eprintf (f_"%s: invalid password selector '%s'; see the man page.\n") prog arg; -+ eprintf (f_"%s: invalid password selector '%s'; see the man page.\n") -+ prog orig_arg; - exit 1 - - and read_password_from_file filename = -@@ -77,7 +96,8 @@ let rec set_linux_passwords ~prog ?password_crypto g root passwords = - List.map ( - fun line -> - try -- (* Each line is: "user:password:..." -+ (* Each line is: "user:[!!]password:..." -+ * !! at the front of the password field means the account is locked. - * 'i' points to the first colon, 'j' to the second colon. - *) - let i = String.index line ':' in -@@ -87,12 +107,17 @@ let rec set_linux_passwords ~prog ?password_crypto g root passwords = - let rest = String.sub line j (String.length line - j) in - let pwfield = - match selector with -- | Set_password password -> encrypt password crypto -- | Set_random_password -> -+ | { pw_locked = locked; -+ pw_password = Password password } -> -+ if locked then "!!" else "" ^ encrypt password crypto -+ | { pw_locked = locked; -+ pw_password = Random_password } -> - let password = make_random_password () in - printf (f_"Setting random password of %s to %s\n%!") - user password; -- encrypt password crypto in -+ if locked then "!!" else "" ^ encrypt password crypto -+ | { pw_locked = true; pw_password = Disabled_password } -> "!!*" -+ | { pw_locked = false; pw_password = Disabled_password } -> "*" in - user ^ ":" ^ pwfield ^ rest - with Not_found -> line - ) shadow in -diff --git a/mllib/password.mli b/mllib/password.mli -index dce9486..c662b1b 100644 ---- a/mllib/password.mli -+++ b/mllib/password.mli -@@ -21,9 +21,14 @@ type password_crypto = [ `MD5 | `SHA256 | `SHA512 ] - val password_crypto_of_string : prog:string -> string -> password_crypto - (** Parse --password-crypto parameter on command line. *) - --type password_selector = --| Set_password of string --| Set_random_password -+type password_selector = { -+ pw_password : password; (** The password. *) -+ pw_locked : bool; (** If the account should be locked. *) -+} -+and password = -+| Password of string (** Password (literal string). *) -+| Random_password (** Choose a random password. *) -+| Disabled_password (** [*] in the password field. *) - - val parse_selector : prog:string -> string -> password_selector - (** Parse the selector field in --password/--root-password. Note this -diff --git a/sysprep/sysprep_operation_password.ml b/sysprep/sysprep_operation_password.ml -index 0cd834a..ef0e985 100644 ---- a/sysprep/sysprep_operation_password.ml -+++ b/sysprep/sysprep_operation_password.ml -@@ -143,6 +143,39 @@ can see the cleartext password using L. - Choose a random password, which is printed on stdout. The password - has approximately 120 bits of randomness. - -+=item B<--password> USERNAME:disabled -+ -+=item B<--root-password> disabled -+ -+The account password is disabled. This is like putting C<*> -+in the password field. -+ -+=item B<--password> USERNAME:locked:file:FILENAME -+ -+=item B<--password> USERNAME:locked:password:PASSWORD -+ -+=item B<--password> USERNAME:locked:random -+ -+=item B<--root-password> locked:file:FILENAME -+ -+=item B<--root-password> locked:password:PASSWORD -+ -+=item B<--root-password> locked:random -+ -+The account is locked, but a password is placed on the -+account. If first unlocked (using C) then logins will -+use the given password. -+ -+=item B<--password> USERNAME:locked -+ -+=item B<--password> USERNAME:locked:disabled -+ -+=item B<--root-password> locked -+ -+=item B<--root-password> locked:disabled -+ -+The account is locked I password is disabled. -+ - =back" - }; - --- -1.8.5.3 - diff --git a/0026-builder-Use-a-planner-to-work-out-how-to-convert-the.patch b/0026-builder-Use-a-planner-to-work-out-how-to-convert-the.patch deleted file mode 100644 index fcfc635..0000000 --- a/0026-builder-Use-a-planner-to-work-out-how-to-convert-the.patch +++ /dev/null @@ -1,731 +0,0 @@ -From 1caf8a6ca300f09bf7ffa631c51f6ee0940e24f6 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 13 Dec 2013 13:18:47 +0000 -Subject: [PATCH] builder: Use a planner to work out how to convert the - template to the final image. - -The original template might be, say, xz-compressed raw of a certain -size. We need to work out how to convert it to, say, qcow2 with a -larger size, in as few operations as possible. - -Instead of using a nasty aggregation of special cases to do this, use -a breadth-first search over all possible trees to try to find an -optimal plan. - -(Actually the current implementation isn't optimal, but it's fine for -virt-builder.) - -(cherry picked from commit 62cc7d3361127b4e007f8e23028213852be09124) ---- - builder/Makefile.am | 1 + - builder/builder.ml | 407 +++++++++++++++++++++++++++++++++----------------- - mllib/Makefile.am | 6 +- - mllib/common_utils.ml | 12 ++ - mllib/planner.ml | 80 ++++++++++ - mllib/planner.mli | 78 ++++++++++ - po/POTFILES-ml | 1 + - 7 files changed, 449 insertions(+), 136 deletions(-) - create mode 100644 mllib/planner.ml - create mode 100644 mllib/planner.mli - -diff --git a/builder/Makefile.am b/builder/Makefile.am -index 8e7f104..0d9ea75 100644 ---- a/builder/Makefile.am -+++ b/builder/Makefile.am -@@ -73,6 +73,7 @@ OBJECTS = \ - $(top_builddir)/mllib/fsync-c.o \ - $(top_builddir)/mllib/fsync.cmx \ - $(top_builddir)/mllib/password.cmx \ -+ $(top_builddir)/mllib/planner.cmx \ - $(top_builddir)/mllib/config.cmx \ - index-scan.o \ - index-struct.o \ -diff --git a/builder/builder.ml b/builder/builder.ml -index 690f3e2..71dfe13 100644 ---- a/builder/builder.ml -+++ b/builder/builder.ml -@@ -22,9 +22,9 @@ module G = Guestfs - - open Common_utils - open Password -+open Planner - - open Cmdline --open Pxzcat - - open Unix - open Printf -@@ -245,146 +245,281 @@ let main () = - - Sigchecker.verify_detached sigchecker template sigfile in - -- (* Plan how to create the output. This depends on: -- * - did the user specify --output? -- * - is the output a block device? -- * - did the user specify --size? -- *) -- let output, size, format, delete_output_file, do_resize, resize_sparse = -- let headroom = 256L *^ 1024L *^ 1024L in -- -- match output with -- (* If the output file was specified and it exists and it's a block -- * device, then we should skip the creation step. -+ (* Planner: Input tags. *) -+ let itags = -+ let { Index_parser.size = size; format = format } = entry in -+ let format = match format with None -> "auto" | Some format -> format in -+ let compression_tags = -+ match detect_compression template with -+ | `XZ -> [ `XZ, "" ] -+ | `Unknown -> [] -+ in -+ [ `Template, ""; `Filename, template; `Size, Int64.to_string size; -+ `Format, format ] @ compression_tags in -+ -+ (* Planner: Goal. *) -+ let output_size = -+ let { Index_parser.size = default_size } = entry in -+ match size with None -> default_size | Some size -> size in -+ let output_filename, output_format = -+ match output, format with -+ | None, None -> sprintf "%s.img" arg, "raw" -+ | None, Some "raw" -> sprintf "%s.img" arg, "raw" -+ | None, Some format -> sprintf "%s.%s" arg format, format -+ | Some output, None -> output, "raw" -+ | Some output, Some format -> output, format in -+ let output_is_block_dev = is_block_device output_filename in -+ -+ if output_is_block_dev && size <> None then ( -+ eprintf (f_"%s: you cannot use --size option with block devices\n") prog; -+ exit 1 -+ ); -+ -+ let goal = -+ (* MUST *) -+ let goal_must = [ -+ `Filename, output_filename; -+ `Size, Int64.to_string output_size; -+ `Format, output_format -+ ] in -+ -+ (* MUST NOT *) -+ let goal_must_not = [ `Template, ""; `XZ, ""; `Format, "auto" ] in -+ -+ goal_must, goal_must_not in -+ -+ (* Planner: Transitions. *) -+ let transitions itags = -+ let is t = List.mem_assoc t itags in -+ let is_not t = not (is t) in -+ let remove = List.remove_assoc in -+ let ret = ref [] in -+ let tr task weight otags = ret := (task, weight, otags) :: !ret in -+ -+ (* XXX Weights are not very smartly chosen. At the moment I'm -+ * using a range [0..100] where 0 = free and 100 = expensive. We -+ * could estimate weights better by looking at file sizes. - *) -- | Some output when is_block_device output -> -- if size <> None then ( -- eprintf (f_"%s: you cannot use --size option with block devices\n") -- prog; -- exit 1 -+ -+ (* Since the final plan won't run in parallel, we don't only need -+ * to choose unique tempfiles per transition, so this is OK: -+ *) -+ let tempfile = Filename.temp_file "vb" ".img" in -+ unlink_on_exit tempfile; -+ -+ (* Always possible to copy from one place to another. The only -+ * thing a copy does is to remove the template tag (since it's always -+ * copied out of the cache directory). -+ *) -+ tr `Copy 50 ((`Filename, output_filename) :: remove `Template itags); -+ tr `Copy 50 ((`Filename, tempfile) :: remove `Template itags); -+ -+ (* We can rename a file instead of copying, but don't rename the -+ * cache copy! (XXX Also this is not free if copying across -+ * filesystems) -+ *) -+ if is_not `Template then ( -+ if not output_is_block_dev then -+ tr `Rename 0 ((`Filename, output_filename) :: itags); -+ tr `Rename 0 ((`Filename, tempfile) :: itags); -+ ); -+ -+ if is `XZ then ( -+ (* If the input is XZ-compressed, then we can run xzcat, either -+ * to the output file or to a temp file. -+ *) -+ if not output_is_block_dev then -+ tr `Pxzcat 80 -+ ((`Filename, output_filename) :: remove `XZ (remove `Template itags)); -+ tr `Pxzcat 80 -+ ((`Filename, tempfile) :: remove `XZ (remove `Template itags)); -+ ) -+ else ( -+ (* If the input is NOT compressed then we could run virt-resize -+ * if it makes sense to resize the image. Note that virt-resize -+ * can do both size and format conversions. -+ *) -+ let old_size = Int64.of_string (List.assoc `Size itags) in -+ let headroom = 256L *^ 1024L *^ 1024L in -+ if output_size >= old_size +^ headroom then ( -+ tr `Virt_resize 100 -+ ((`Size, Int64.to_string output_size) :: -+ (`Filename, output_filename) :: -+ (`Format, output_format) :: (remove `Template itags)); -+ tr `Virt_resize 100 -+ ((`Size, Int64.to_string output_size) :: -+ (`Filename, tempfile) :: -+ (`Format, output_format) :: (remove `Template itags)) -+ ) -+ -+ (* If the size increase is smaller than the amount of headroom -+ * inside the disk image, then virt-resize won't work. However -+ * we can do a disk resize (using 'qemu-img resize') instead, -+ * although it won't resize the filesystems for the user. -+ * -+ * 'qemu-img resize' works on the file in-place and won't change -+ * the format. It must not be run on a template directly. -+ *) -+ else if output_size > old_size && is_not `Template then ( -+ tr `Disk_resize 60 ((`Size, Int64.to_string output_size) :: itags); -+ tr `Disk_resize 60 ((`Size, Int64.to_string output_size) :: itags); - ); -- (* XXX Should check the output size is big enough. However this -- * requires running 'blockdev --getsize64 '. -+ -+ (* qemu-img convert is always possible, and quicker. It doesn't -+ * resize, but it does change the format. - *) -+ tr `Convert 60 -+ ((`Filename, output_filename) :: (`Format, output_format) :: -+ (remove `Template itags)); -+ tr `Convert 60 -+ ((`Filename, tempfile) :: (`Format, output_format) :: -+ (remove `Template itags)); -+ ); - -- let format = match format with None -> "raw" | Some f -> f in -- -- (* Dummy: The output file is never deleted in this case. *) -- let delete_output_file = ref false in -- -- output, None, format, delete_output_file, true, false -- -- (* Regular file output. Note the file gets deleted. *) -- | _ -> -- (* Check the --size option. *) -- let size, do_resize = -- let { Index_parser.size = default_size } = entry in -- match size with -- | None -> default_size, false -- | Some size -> -- if size < default_size +^ headroom then ( -- eprintf (f_"%s: --size is too small for this disk image, minimum size is %s\n") -- prog (human_size default_size); -- exit 1 -- ); -- size, true in -- -- (* Create the output file. *) -- let output, format = -- match output, format with -- | None, None -> sprintf "%s.img" arg, "raw" -- | None, Some "raw" -> sprintf "%s.img" arg, "raw" -- | None, Some format -> sprintf "%s.%s" arg format, format -- | Some output, None -> output, "raw" -- | Some output, Some format -> output, format in -- -- (* If the input format != output format then we must run virt-resize. *) -- let do_resize = -- let input_format = -- match entry with -- | { Index_parser.format = Some format } -> format -- | { Index_parser.format = None } -> "raw" in -- if input_format <> format then true else do_resize in -- -- msg (f_"Creating disk image: %s") output; -+ (* Return the list of possible transitions. *) -+ !ret -+ in -+ -+ (* Plan how to create the disk image. *) -+ msg (f_"Planning how to build this image"); -+ let plan = -+ try plan ~max_depth:5 transitions itags goal -+ with -+ Failure "plan" -> -+ eprintf (f_"%s: no plan could be found for making a disk image with\nthe required size, format etc. This is a bug in libguestfs!\nPlease file a bug, giving the command line arguments you used.\n") prog; -+ exit 1 -+ in -+ -+ (* Print out the plan. *) -+ if debug then ( -+ let print_tags tags = -+ (try -+ let v = List.assoc `Filename tags in eprintf " +filename=%s" v -+ with Not_found -> ()); -+ (try -+ let v = List.assoc `Size tags in eprintf " +size=%s" v -+ with Not_found -> ()); -+ (try -+ let v = List.assoc `Format tags in eprintf " +format=%s" v -+ with Not_found -> ()); -+ if List.mem_assoc `Template tags then eprintf " +template"; -+ if List.mem_assoc `XZ tags then eprintf " +xz" -+ in -+ let print_task = function -+ | `Copy -> eprintf "cp" -+ | `Rename -> eprintf "mv" -+ | `Pxzcat -> eprintf "pxzcat" -+ | `Virt_resize -> eprintf "virt-resize" -+ | `Disk_resize -> eprintf "qemu-img resize" -+ | `Convert -> eprintf "qemu-img convert" -+ in -+ -+ List.iteri ( -+ fun i (itags, task, otags) -> -+ eprintf "%d: itags:" i; -+ print_tags itags; -+ eprintf "\n"; -+ eprintf "%d: task : " i; -+ print_task task; -+ eprintf "\n"; -+ eprintf "%d: otags:" i; -+ print_tags otags; -+ eprintf "\n\n" -+ ) plan -+ ); -+ -+ (* Delete the output file before we finish. However don't delete it -+ * if it's block device. -+ *) -+ let delete_output_file = ref (not output_is_block_dev) in -+ let delete_file () = -+ if !delete_output_file then -+ try unlink output_filename with _ -> () -+ in -+ at_exit delete_file; -+ -+ (* Carry out the plan. *) -+ List.iter ( -+ function -+ | itags, `Copy, otags -> -+ let ifile = List.assoc `Filename itags in -+ let ofile = List.assoc `Filename otags in -+ msg (f_"Copying"); -+ let cmd = sprintf "cp %s %s" (quote ifile) (quote ofile) in -+ if debug then eprintf "%s\n%!" cmd; -+ if Sys.command cmd <> 0 then exit 1 -+ -+ | itags, `Rename, otags -> -+ let ifile = List.assoc `Filename itags in -+ let ofile = List.assoc `Filename otags in -+ let cmd = sprintf "mv %s %s" (quote ifile) (quote ofile) in -+ if debug then eprintf "%s\n%!" cmd; -+ if Sys.command cmd <> 0 then exit 1 -+ -+ | itags, `Pxzcat, otags -> -+ let ifile = List.assoc `Filename itags in -+ let ofile = List.assoc `Filename otags in -+ msg (f_"Uncompressing"); -+ Pxzcat.pxzcat ifile ofile -+ -+ | itags, `Virt_resize, otags -> -+ let ifile = List.assoc `Filename itags in -+ let iformat = List.assoc `Format itags in -+ let ofile = List.assoc `Filename otags in -+ let osize = Int64.of_string (List.assoc `Size otags) in -+ let osize = roundup64 osize 512L in -+ let oformat = List.assoc `Format otags in -+ let { Index_parser.expand = expand; lvexpand = lvexpand } = entry in -+ msg (f_"Resizing (using virt-resize) to expand the disk to %s") -+ (human_size osize); - let cmd = - sprintf "qemu-img create -f %s%s %s %Ld%s" -- (quote format) -- (if format = "qcow2" then " -o preallocation=metadata" else "") -- (quote output) size -+ (quote oformat) -+ (if oformat = "qcow2" then " -o preallocation=metadata" else "") -+ (quote ofile) osize - (if debug then "" else " >/dev/null 2>&1") in -- let r = Sys.command cmd in -- if r <> 0 then ( -- eprintf (f_"%s: error: could not create output file '%s'\n") -- prog output; -- exit 1 -- ); -- (* This ensures the output file will be deleted on failure, -- * until we set !delete_output_file = false at the end of the build. -- *) -- let delete_output_file = ref true in -- let delete_file () = -- if !delete_output_file then -- try unlink output with _ -> () -- in -- at_exit delete_file; -+ if debug then eprintf "%s\n%!" cmd; -+ if Sys.command cmd <> 0 then exit 1; -+ let cmd = -+ sprintf "virt-resize%s%s --format %s --output-format %s%s%s %s %s" -+ (if debug then " --verbose" else " --quiet") -+ (if output_is_block_dev then " --no-sparse" else "") -+ (quote iformat) -+ (quote oformat) -+ (match expand with -+ | None -> "" -+ | Some expand -> sprintf " --expand %s" (quote expand)) -+ (match lvexpand with -+ | None -> "" -+ | Some lvexpand -> sprintf " --lv-expand %s" (quote lvexpand)) -+ (quote ifile) (quote ofile) in -+ if debug then eprintf "%s\n%!" cmd; -+ if Sys.command cmd <> 0 then exit 1 - -- output, Some size, format, delete_output_file, do_resize, true in -+ | itags, `Disk_resize, otags -> -+ let ofile = List.assoc `Filename otags in -+ let osize = Int64.of_string (List.assoc `Size otags) in -+ let osize = roundup64 osize 512L in -+ msg (f_"Resizing container (but not filesystems) to expand the disk to %s") -+ (human_size osize); -+ let cmd = sprintf "qemu-img resize %s %Ld%s" -+ (quote ofile) osize (if debug then "" else " >/dev/null") in -+ if debug then eprintf "%s\n%!" cmd; -+ if Sys.command cmd <> 0 then exit 1 - -- if not do_resize then ( -- (* If the user did not specify --size and the output is a regular -- * file and the format is raw, then we just uncompress the template -- * directly to the output file. This is fast but less flexible. -- *) -- let { Index_parser.file_uri = file_uri } = entry in -- msg (f_"Uncompressing: %s") file_uri; -- pxzcat template output -- ) else ( -- (* If none of the above apply, uncompress to a temporary file and -- * run virt-resize on the result. -- *) -- let tmpfile = -- (* Uncompress it to a temporary file. *) -- let { Index_parser.file_uri = file_uri } = entry in -- let tmpfile = Filename.temp_file "vbsrc" ".img" in -- msg (f_"Uncompressing: %s") file_uri; -- pxzcat template tmpfile; -- unlink_on_exit tmpfile; -- tmpfile in -- -- (* Resize the source to the output file. *) -- (match size with -- | None -> -- msg (f_"Running virt-resize to expand the disk") -- | Some size -> -- msg (f_"Running virt-resize to expand the disk to %s") (human_size size) -- ); -- -- let { Index_parser.expand = expand; lvexpand = lvexpand; -- format = input_format } = -- entry in -- let cmd = -- sprintf "virt-resize%s%s%s --output-format %s%s%s %s %s" -- (if debug then " --verbose" else " --quiet") -- (if not resize_sparse then " --no-sparse" else "") -- (match input_format with -- | None -> "" -- | Some input_format -> sprintf " --format %s" (quote input_format)) -- (quote format) -- (match expand with -- | None -> "" -- | Some expand -> sprintf " --expand %s" (quote expand)) -- (match lvexpand with -- | None -> "" -- | Some lvexpand -> sprintf " --lv-expand %s" (quote lvexpand)) -- (quote tmpfile) (quote output) in -- if debug then eprintf "%s\n%!" cmd; -- let r = Sys.command cmd in -- if r <> 0 then ( -- eprintf (f_"%s: error: virt-resize failed\n") prog; -- exit 1 -- ) -- ); -+ | itags, `Convert, otags -> -+ let ifile = List.assoc `Filename itags in -+ let iformat = List.assoc `Format itags in -+ let ofile = List.assoc `Filename otags in -+ let oformat = List.assoc `Format otags in -+ msg (f_"Converting %s to %s") iformat oformat; -+ let cmd = sprintf "qemu-img convert -f %s %s -O %s %s%s" -+ (quote iformat) (quote ifile) -+ (quote oformat) (quote ofile) -+ (if debug then "" else " >/dev/null 2>&1") in -+ if debug then eprintf "%s\n%!" cmd; -+ if Sys.command cmd <> 0 then exit 1 -+ ) plan; - - (* Now mount the output disk so we can make changes. *) - msg (f_"Opening the new disk"); -@@ -397,7 +532,7 @@ let main () = - g#set_network network; - - (* The output disk is being created, so use cache=unsafe here. *) -- g#add_drive_opts ~format ~cachemode:"unsafe" output; -+ g#add_drive_opts ~format:output_format ~cachemode:"unsafe" output_filename; - - (* Attach ISOs, if we have any. *) - List.iter ( -@@ -690,7 +825,9 @@ exec >>%s 2>&1 - - Some ( - String.concat "\n" [ -- sprintf (f_"Output: %s") output; -+ sprintf (f_"Output: %s") output_filename; -+ sprintf (f_"Output size: %s") (human_size output_size); -+ sprintf (f_"Output format: %s") output_format; - sprintf (f_"Total usable space: %s") - (human_size total_bytes); - sprintf (f_"Free space: %s (%Ld%%)") -@@ -729,7 +866,7 @@ exec >>%s 2>&1 - * use cache=none. - *) - if sync then -- Fsync.file output; -+ Fsync.file output_filename; - - (* Now that we've finished the build, don't delete the output file on - * exit. -diff --git a/mllib/Makefile.am b/mllib/Makefile.am -index 7664150..62d0f68 100644 ---- a/mllib/Makefile.am -+++ b/mllib/Makefile.am -@@ -45,6 +45,8 @@ SOURCES = \ - password.ml \ - perl_edit.mli \ - perl_edit.ml \ -+ planner.mli \ -+ planner.ml \ - progress-c.c \ - progress.mli \ - progress.ml \ -@@ -89,7 +91,9 @@ OBJECTS = \ - uRI.cmx \ - crypt.cmx \ - password.cmx \ -- mkdtemp.cmx -+ password.cmx \ -+ mkdtemp.cmx \ -+ planner.cmx - - noinst_SCRIPTS = dummy - -diff --git a/mllib/common_utils.ml b/mllib/common_utils.ml -index 357ffba..3943417 100644 ---- a/mllib/common_utils.ml -+++ b/mllib/common_utils.ml -@@ -401,6 +401,18 @@ let rm_rf_only_files (g : Guestfs.guestfs) dir = - List.iter g#rm files - ) - -+(* Detect compression of a file. -+ * -+ * Only detects the formats we need in virt-builder so far. -+ *) -+let detect_compression filename = -+ let chan = open_in filename in -+ let buf = String.create 6 in -+ really_input chan buf 0 6; -+ close_in chan; -+ if buf = "\2537zXZ\000" then `XZ -+ else `Unknown -+ - let is_block_device file = - try (Unix.stat file).Unix.st_kind = Unix.S_BLK - with Unix.Unix_error _ -> false -diff --git a/mllib/planner.ml b/mllib/planner.ml -new file mode 100644 -index 0000000..0121b84 ---- /dev/null -+++ b/mllib/planner.ml -@@ -0,0 +1,80 @@ -+(* virt-builder -+ * Copyright (C) 2012-2013 Red Hat Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ *) -+ -+type ('name, 'value) tag = 'name * 'value -+ -+type ('name, 'value) tags = ('name, 'value) tag list -+ -+type ('name, 'value, 'task) plan = -+ (('name, 'value) tags * 'task * ('name, 'value) tags) list -+ -+type ('name, 'value, 'task) transitions_function = ('name, 'value) tags -> ('task * int * ('name, 'value) tags) list -+ -+let plan ?(max_depth = 10) transitions itags (goal_must, goal_must_not) = -+ (* Do the given output tags match the finish condition? *) -+ let finished (otags, _, _) = -+ let must = -+ (* All tags from the MUST list must be present with the given values. *) -+ List.for_all ( -+ fun (name, value) -> -+ try List.assoc name otags = value with Not_found -> false -+ ) goal_must in -+ -+ let must_not = -+ (* No tag from the MUST NOT list can appear. *) -+ List.for_all ( -+ fun (name, value) -> -+ try List.assoc name otags <> value with Not_found -> true -+ ) goal_must_not in -+ -+ must && must_not -+ in -+ -+ (* Breadth-first search. *) -+ let rec search depth paths = -+ if depth >= max_depth then failwith "plan" -+ else ( -+ let paths = -+ List.map ( -+ fun (itags, weight, preds) -> -+ let ts = transitions itags in -+ List.map (fun (task, w, otags) -> -+ otags, weight + w, (itags, task, otags) :: preds -+ ) ts -+ ) paths in -+ let paths = List.flatten paths in -+ -+ (* Did any path reach the finish? If so, pick the path with the -+ * smallest weight and we're done. -+ *) -+ let finished_paths = List.filter finished paths in -+ let finished_paths = -+ List.sort (fun (_,w1,_) (_,w2,_) -> compare w1 w2) finished_paths in -+ match finished_paths with -+ | [] -> -+ (* No path reached the finish, so go deeper. *) -+ search (depth+1) paths -+ | (_, _, ret) :: _ -> -+ (* Return the shortest path, but we have to reverse it because -+ * we built it backwards. -+ *) -+ List.rev ret -+ ) -+ in -+ -+ search 0 [itags, 0, []] -diff --git a/mllib/planner.mli b/mllib/planner.mli -new file mode 100644 -index 0000000..770a00f ---- /dev/null -+++ b/mllib/planner.mli -@@ -0,0 +1,78 @@ -+(* virt-builder -+ * Copyright (C) 2012-2013 Red Hat Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ *) -+ -+(** The Planner can plan how to reach a goal by carrying out a series -+ of operations. You tag the input state and the output state, and -+ give it a list of permitted transitions, and it will return a -+ multi-step plan (list of transitions) from the input state to the -+ output state. -+ -+ For example: -+ -+ Input tags: xz cached size=4G format=raw -+ -+ Output tags: -xz -cached +size=8G +format=raw -+ -+ (In this case the "-" before an output tag means the tag MUST NOT -+ appear, and the "+" before an output tag means the tag MUST -+ appear). -+ -+ The plan produced might be: -+ -+ (1) Run xzcat (removes xz and cached tags). -+ -+ (2) Run virt-resize (changes size=4G to size=8G) -+ -+ Tags are described as OCaml association lists. See the OCaml -+ {!List} module. -+ -+ Transitions are defined by a function (that the caller supplies) -+ which returns the possible transitions for a given set of tags, -+ and for each possible transition, the weight (higher number = -+ higher cost), and the tag state after that transition. -+ -+ The returned plan is a list of transitions. -+ -+ The implementation is a simple breadth-first search of the tree of -+ states (each edge in the tree is a transition). It doesn't work -+ very hard to optimize the weights, so the returned plan is -+ possible, but might not be optimal. *) -+ -+type ('name, 'value) tag = 'name * 'value -+ -+type ('name, 'value) tags = ('name, 'value) tag list -+ (** An assoc-list of tags. *) -+ -+type ('name, 'value, 'task) plan = -+ (('name, 'value) tags * 'task * ('name, 'value) tags) list -+ -+type ('name, 'value, 'task) transitions_function = ('name, 'value) tags -> ('task * int * ('name, 'value) tags) list -+ -+val plan : ?max_depth:int -> ('name, 'value, 'task) transitions_function -> ('name, 'value) tags -> ('name, 'value) tags * ('name, 'value) tags -> ('name, 'value, 'task) plan -+(** Make a plan. -+ -+ [plan transitions itags (goal_must, goal_must_not)] works out a -+ plan, which is a list of tasks that have to be carried out in -+ order to go from the input tags to the goal. The goal is passed -+ in as a pair of lists: tags that MUST appear and tags that MUST -+ NOT appear. -+ -+ The returned value is a {!plan}. -+ -+ Raises [Failure "plan"] if no plan was found within [max_depth] -+ transitions. *) -diff --git a/po/POTFILES-ml b/po/POTFILES-ml -index c4ea888..6372f7e 100644 ---- a/po/POTFILES-ml -+++ b/po/POTFILES-ml -@@ -18,6 +18,7 @@ mllib/libdir.ml - mllib/mkdtemp.ml - mllib/password.ml - mllib/perl_edit.ml -+mllib/planner.ml - mllib/progress.ml - mllib/random_seed.ml - mllib/tTY.ml --- -1.8.5.3 - diff --git a/0027-builder-planner-Handle-no-format-in-source-case-corr.patch b/0027-builder-planner-Handle-no-format-in-source-case-corr.patch deleted file mode 100644 index 0ea6a81..0000000 --- a/0027-builder-planner-Handle-no-format-in-source-case-corr.patch +++ /dev/null @@ -1,110 +0,0 @@ -From dda6462eba80da2b8806fb1980147c525fa81fb4 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 14 Dec 2013 15:49:25 +0000 -Subject: [PATCH] builder: planner: Handle no format= in source case correctly. - -(cherry picked from commit 0af1e55e68c7cdaecc0af22e8bc41b8cff197e44) ---- - builder/builder.ml | 44 ++++++++++++++++++++++++++++---------------- - 1 file changed, 28 insertions(+), 16 deletions(-) - -diff --git a/builder/builder.ml b/builder/builder.ml -index 71dfe13..4176457 100644 ---- a/builder/builder.ml -+++ b/builder/builder.ml -@@ -248,14 +248,16 @@ let main () = - (* Planner: Input tags. *) - let itags = - let { Index_parser.size = size; format = format } = entry in -- let format = match format with None -> "auto" | Some format -> format in -- let compression_tags = -+ let format_tag = -+ match format with -+ | None -> [] -+ | Some format -> [`Format, format] in -+ let compression_tag = - match detect_compression template with - | `XZ -> [ `XZ, "" ] -- | `Unknown -> [] -- in -- [ `Template, ""; `Filename, template; `Size, Int64.to_string size; -- `Format, format ] @ compression_tags in -+ | `Unknown -> [] in -+ [ `Template, ""; `Filename, template; `Size, Int64.to_string size ] @ -+ format_tag @ compression_tag in - - (* Planner: Goal. *) - let output_size = -@@ -284,7 +286,7 @@ let main () = - ] in - - (* MUST NOT *) -- let goal_must_not = [ `Template, ""; `XZ, ""; `Format, "auto" ] in -+ let goal_must_not = [ `Template, ""; `XZ, "" ] in - - goal_must, goal_must_not in - -@@ -359,8 +361,11 @@ let main () = - * - * 'qemu-img resize' works on the file in-place and won't change - * the format. It must not be run on a template directly. -+ * -+ * Don't run 'qemu-img resize' on an auto format. This is to -+ * force an explicit conversion step to a real format. - *) -- else if output_size > old_size && is_not `Template then ( -+ else if output_size > old_size && is_not `Template && List.mem_assoc `Format itags then ( - tr `Disk_resize 60 ((`Size, Int64.to_string output_size) :: itags); - tr `Disk_resize 60 ((`Size, Int64.to_string output_size) :: itags); - ); -@@ -464,7 +469,8 @@ let main () = - - | itags, `Virt_resize, otags -> - let ifile = List.assoc `Filename itags in -- let iformat = List.assoc `Format itags in -+ let iformat = -+ try Some (List.assoc `Format itags) with Not_found -> None in - let ofile = List.assoc `Filename otags in - let osize = Int64.of_string (List.assoc `Size otags) in - let osize = roundup64 osize 512L in -@@ -481,10 +487,12 @@ let main () = - if debug then eprintf "%s\n%!" cmd; - if Sys.command cmd <> 0 then exit 1; - let cmd = -- sprintf "virt-resize%s%s --format %s --output-format %s%s%s %s %s" -+ sprintf "virt-resize%s%s%s --output-format %s%s%s %s %s" - (if debug then " --verbose" else " --quiet") - (if output_is_block_dev then " --no-sparse" else "") -- (quote iformat) -+ (match iformat with -+ | None -> "" -+ | Some iformat -> sprintf " --format %s" (quote iformat)) - (quote oformat) - (match expand with - | None -> "" -@@ -509,13 +517,17 @@ let main () = - - | itags, `Convert, otags -> - let ifile = List.assoc `Filename itags in -- let iformat = List.assoc `Format itags in -+ let iformat = -+ try Some (List.assoc `Format itags) with Not_found -> None in - let ofile = List.assoc `Filename otags in - let oformat = List.assoc `Format otags in -- msg (f_"Converting %s to %s") iformat oformat; -- let cmd = sprintf "qemu-img convert -f %s %s -O %s %s%s" -- (quote iformat) (quote ifile) -- (quote oformat) (quote ofile) -+ msg (f_"Converting %s to %s") -+ (match iformat with None -> "auto" | Some f -> f) oformat; -+ let cmd = sprintf "qemu-img convert%s %s -O %s %s%s" -+ (match iformat with -+ | None -> "" -+ | Some iformat -> sprintf " -f %s" (quote iformat)) -+ (quote ifile) (quote oformat) (quote ofile) - (if debug then "" else " >/dev/null 2>&1") in - if debug then eprintf "%s\n%!" cmd; - if Sys.command cmd <> 0 then exit 1 --- -1.8.5.3 - diff --git a/0028-builder-Flush-debug-info-after-printing-it.patch b/0028-builder-Flush-debug-info-after-printing-it.patch deleted file mode 100644 index cae381e..0000000 --- a/0028-builder-Flush-debug-info-after-printing-it.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 4491401005a31adac5edf1836b2efe20cb16299a Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 14 Dec 2013 15:50:04 +0000 -Subject: [PATCH] builder: Flush debug info after printing it. - -(cherry picked from commit 7af9cabadeb1da329de4411d7eaea2e347496446) ---- - builder/builder.ml | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/builder/builder.ml b/builder/builder.ml -index 4176457..854093d 100644 ---- a/builder/builder.ml -+++ b/builder/builder.ml -@@ -429,7 +429,7 @@ let main () = - eprintf "\n"; - eprintf "%d: otags:" i; - print_tags otags; -- eprintf "\n\n" -+ eprintf "\n\n%!" - ) plan - ); - --- -1.8.5.3 - diff --git a/0029-builder-Add-a-test-of-the-planner.patch b/0029-builder-Add-a-test-of-the-planner.patch deleted file mode 100644 index 8c0ec7a..0000000 --- a/0029-builder-Add-a-test-of-the-planner.patch +++ /dev/null @@ -1,173 +0,0 @@ -From 66bf3e30591b88b473c316adb5b6f1f06ff648fd Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 14 Dec 2013 15:50:37 +0000 -Subject: [PATCH] builder: Add a test of the planner. - -This tries out many combinations of size/format and ensures -that the planner can deal with them. - -(cherry picked from commit a27963b67ba1140c29c145a1ce14dbfc05f8d7da) ---- - .gitignore | 1 + - builder/Makefile.am | 24 ++++++++++++++--- - builder/test-index.in | 26 ++++++++++++++++++ - builder/test-virt-builder-planner.sh | 51 ++++++++++++++++++++++++++++++++++++ - 4 files changed, 98 insertions(+), 4 deletions(-) - create mode 100755 builder/test-virt-builder-planner.sh - -diff --git a/.gitignore b/.gitignore -index 8f0cda3..6e04072 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -61,6 +61,7 @@ Makefile.in - /builder/index-parse.c - /builder/index-parse.h - /builder/index-scan.c -+/builder/*.qcow2 - /builder/stamp-virt-builder.pod - /builder/stamp-virt-index-validate.pod - /builder/test-index -diff --git a/builder/Makefile.am b/builder/Makefile.am -index 0d9ea75..6ec4b2b 100644 ---- a/builder/Makefile.am -+++ b/builder/Makefile.am -@@ -141,15 +141,28 @@ CLEANFILES += stamp-virt-builder.pod - - TESTS_ENVIRONMENT = $(top_builddir)/run --test - --all_disk_images := debian.xz fedora.xz ubuntu.xz windows.xz --disk_images := $(shell for f in $(all_disk_images); do b=`basename $$f .xz`; if [ -f "../tests/guests/$$b.img" ]; then echo $$f; fi; done) -+disk_images := \ -+ $(shell for f in debian fedora ubuntu windows; do if [ -s "../tests/guests/$$f.img" ]; then echo $$f.xz; fi; done) \ -+ $(shell if [ -s "../tests/guests/fedora.img" ]; then echo fedora.qcow2 fedora.qcow2.xz; fi) - --CLEANFILES += $(all_disk_images) -+CLEANFILES += *.qcow2 *.xz - - check_DATA = $(disk_images) - -+fedora.qcow2: ../tests/guests/fedora.img -+ rm -f $@ $@-t -+ qemu-img convert -f raw -O qcow2 $< $@-t -+ mv $@-t $@ -+ -+fedora.qcow2.xz: fedora.qcow2 -+ rm -f $@ $@-t -+ xz --best --block-size=16777216 -c $< > $@-t -+ mv $@-t $@ -+ - %.xz: ../tests/guests/%.img -- xz --best --block-size=16777216 -c $< > $@ -+ rm -f $@ $@-t -+ xz --best --block-size=16777216 -c $< > $@-t -+ mv $@-t $@ - - TESTS = test-virt-builder-list.sh - -@@ -160,6 +173,9 @@ endif ENABLE_APPLIANCE - check-valgrind: - $(MAKE) VG="$(top_builddir)/run @VG@" check - -+check-slow: -+ $(MAKE) TESTS="test-virt-builder-planner.sh" check -+ - # Dependencies. - depend: .depend - -diff --git a/builder/test-index.in b/builder/test-index.in -index 21e2ca3..1bca6b8 100644 ---- a/builder/test-index.in -+++ b/builder/test-index.in -@@ -16,6 +16,32 @@ expand=/dev/sda2 - lvexpand=/dev/VG/Root - notes=Phony Fedora look-alike used for testing. - -+[phony-fedora-qcow2] -+name=Phony Fedora qcow2 -+file=fedora.qcow2.xz -+format=qcow2 -+size=1073741824 -+expand=/dev/sda2 -+lvexpand=/dev/VG/Root -+notes=Phony Fedora look-alike used for testing. -+ -+[phony-fedora-qcow2-uncompressed] -+name=Phony Fedora qcow2 uncompressed -+file=fedora.qcow2 -+format=qcow2 -+size=1073741824 -+expand=/dev/sda2 -+lvexpand=/dev/VG/Root -+notes=Phony Fedora look-alike used for testing. -+ -+[phony-fedora-no-format] -+name=Phony Fedora -+file=fedora.qcow2.xz -+size=1073741824 -+expand=/dev/sda2 -+lvexpand=/dev/VG/Root -+notes=Phony Fedora look-alike used for testing. -+ - [phony-ubuntu] - name=Phony Ubuntu - file=ubuntu.xz -diff --git a/builder/test-virt-builder-planner.sh b/builder/test-virt-builder-planner.sh -new file mode 100755 -index 0000000..738b299 ---- /dev/null -+++ b/builder/test-virt-builder-planner.sh -@@ -0,0 +1,51 @@ -+#!/bin/bash - -+# libguestfs virt-builder test script -+# Copyright (C) 2013 Red Hat Inc. -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program 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 General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; if not, write to the Free Software -+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ -+export LANG=C -+set -e -+ -+abs_builddir=$(pwd) -+ -+export VIRT_BUILDER_SOURCE=file://$abs_builddir/test-index -+ -+if [ ! -f fedora.xz -o ! -f fedora.qcow2 -o ! -f fedora.qcow2.xz ]; then -+ echo "$0: test skipped because there is no fedora.xz, fedora.qcow2 or fedora.qcow2.xz in the build directory" -+ exit 77 -+fi -+ -+if [ "$(../fish/guestfish get-backend)" = "uml" ]; then -+ echo "$0: test skipped because backend is UML" -+ exit 77 -+fi -+ -+rm -f planner-output -+ -+for input in phony-fedora phony-fedora-qcow2 phony-fedora-qcow2-uncompressed phony-fedora-no-format; do -+ for size in none 1G 1.1G 2G; do -+ for format in none raw qcow2; do -+ args="--output planner-output --no-cache --no-check-signature" -+ if [ "$size" != "none" ]; then args="$args --size $size"; fi -+ if [ "$format" != "none" ]; then args="$args --format $format"; fi -+ -+ echo $VG ./virt-builder $input $args -+ $VG ./virt-builder $input $args -+ done -+ done -+done -+ -+rm planner-output --- -1.8.5.3 - diff --git a/0030-builder-tests-Fix-virt-builder-list-output.patch b/0030-builder-tests-Fix-virt-builder-list-output.patch deleted file mode 100644 index 3f479db..0000000 --- a/0030-builder-tests-Fix-virt-builder-list-output.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 2f85ca812f4bf36c2462b03d92d78b5619176b01 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 14 Dec 2013 16:18:23 +0000 -Subject: [PATCH] builder: tests: Fix virt-builder --list output. - -This fixes commit a27963b67ba1140c29c145a1ce14dbfc05f8d7da. - -(cherry picked from commit 3f433d90f208da8e2b7ea397485dfd8d415726a0) ---- - builder/test-virt-builder-list.sh | 27 +++++++++++++++++++++++++++ - 1 file changed, 27 insertions(+) - -diff --git a/builder/test-virt-builder-list.sh b/builder/test-virt-builder-list.sh -index ff16abe..083c035 100755 ---- a/builder/test-virt-builder-list.sh -+++ b/builder/test-virt-builder-list.sh -@@ -29,6 +29,9 @@ short_list=$($VG ./virt-builder --no-check-signature --no-cache --list) - - if [ "$short_list" != "phony-debian Phony Debian - phony-fedora Phony Fedora -+phony-fedora-qcow2 Phony Fedora qcow2 -+phony-fedora-qcow2-uncompressed Phony Fedora qcow2 uncompressed -+phony-fedora-no-format Phony Fedora - phony-ubuntu Phony Ubuntu - phony-windows Phony Windows" ]; then - echo "$0: unexpected --list output:" -@@ -57,6 +60,30 @@ Notes: - - Phony Fedora look-alike used for testing. - -+os-version: phony-fedora-qcow2 -+Full name: Phony Fedora qcow2 -+Minimum/default size: 1.0G -+ -+Notes: -+ -+Phony Fedora look-alike used for testing. -+ -+os-version: phony-fedora-qcow2-uncompressed -+Full name: Phony Fedora qcow2 uncompressed -+Minimum/default size: 1.0G -+ -+Notes: -+ -+Phony Fedora look-alike used for testing. -+ -+os-version: phony-fedora-no-format -+Full name: Phony Fedora -+Minimum/default size: 1.0G -+ -+Notes: -+ -+Phony Fedora look-alike used for testing. -+ - os-version: phony-ubuntu - Full name: Phony Ubuntu - Minimum/default size: 512.0M --- -1.8.5.3 - diff --git a/0031-builder-tests-Add-test-virt-builder-planner.sh-to-EX.patch b/0031-builder-tests-Add-test-virt-builder-planner.sh-to-EX.patch deleted file mode 100644 index 56a9244..0000000 --- a/0031-builder-tests-Add-test-virt-builder-planner.sh-to-EX.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 5e931b23d64746e99f9a666c3ccc44d3806059ee Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 14 Dec 2013 16:18:50 +0000 -Subject: [PATCH] builder: tests: Add test-virt-builder-planner.sh to - EXTRA_DIST. - -This fixes commit a27963b67ba1140c29c145a1ce14dbfc05f8d7da. - -(cherry picked from commit 6901cd2250fc25c1761f191fb02db74fecf4703d) ---- - builder/Makefile.am | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/builder/Makefile.am b/builder/Makefile.am -index 6ec4b2b..f5e7d80 100644 ---- a/builder/Makefile.am -+++ b/builder/Makefile.am -@@ -30,7 +30,8 @@ EXTRA_DIST = \ - virt-builder.pod \ - virt-index-validate.pod \ - test-virt-builder.sh \ -- test-virt-builder-list.sh -+ test-virt-builder-list.sh \ -+ test-virt-builder-planner.sh - - CLEANFILES = *~ *.cmi *.cmo *.cmx *.cmxa *.o virt-builder - --- -1.8.5.3 - diff --git a/0032-builder-Add-a-link-to-blog-posting-about-the-planner.patch b/0032-builder-Add-a-link-to-blog-posting-about-the-planner.patch deleted file mode 100644 index da477e6..0000000 --- a/0032-builder-Add-a-link-to-blog-posting-about-the-planner.patch +++ /dev/null @@ -1,60 +0,0 @@ -From e1c18deaa1bd4964430f9de546bc24fa06f54797 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 14 Dec 2013 16:43:40 +0000 -Subject: [PATCH] builder: Add a link to blog posting about the planner. - -http://rwmj.wordpress.com/2013/12/14/writing-a-planner-to-solve-a-tricky-programming-optimization-problem/ -should help people to understand how this code works. - -(cherry picked from commit d5d1dac3ac1e3027dc507b1343022f6bcea20822) ---- - builder/builder.ml | 4 ++++ - mllib/planner.mli | 17 ++--------------- - 2 files changed, 6 insertions(+), 15 deletions(-) - -diff --git a/builder/builder.ml b/builder/builder.ml -index 854093d..8951be5 100644 ---- a/builder/builder.ml -+++ b/builder/builder.ml -@@ -245,6 +245,10 @@ let main () = - - Sigchecker.verify_detached sigchecker template sigfile in - -+ (* For an explanation of the Planner, see: -+ * http://rwmj.wordpress.com/2013/12/14/writing-a-planner-to-solve-a-tricky-programming-optimization-problem/ -+ *) -+ - (* Planner: Input tags. *) - let itags = - let { Index_parser.size = size; format = format } = entry in -diff --git a/mllib/planner.mli b/mllib/planner.mli -index 770a00f..8c77acd 100644 ---- a/mllib/planner.mli -+++ b/mllib/planner.mli -@@ -22,21 +22,8 @@ - multi-step plan (list of transitions) from the input state to the - output state. - -- For example: -- -- Input tags: xz cached size=4G format=raw -- -- Output tags: -xz -cached +size=8G +format=raw -- -- (In this case the "-" before an output tag means the tag MUST NOT -- appear, and the "+" before an output tag means the tag MUST -- appear). -- -- The plan produced might be: -- -- (1) Run xzcat (removes xz and cached tags). -- -- (2) Run virt-resize (changes size=4G to size=8G) -+ For an explanation of the Planner, see: -+ http://rwmj.wordpress.com/2013/12/14/writing-a-planner-to-solve-a-tricky-programming-optimization-problem/ - - Tags are described as OCaml association lists. See the OCaml - {!List} module. --- -1.8.5.3 - diff --git a/0033-builder-Only-use-virt-resize-no-sparse-when-writing-.patch b/0033-builder-Only-use-virt-resize-no-sparse-when-writing-.patch deleted file mode 100644 index 06b59fe..0000000 --- a/0033-builder-Only-use-virt-resize-no-sparse-when-writing-.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 6131ed03b3f3e66f26eb4b384fc1ab888db47f27 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 14 Dec 2013 18:53:20 +0000 -Subject: [PATCH] builder: Only use virt-resize --no-sparse when writing to a - block device. - -Previously we would use the virt-resize --no-sparse option if the -final output file was a block device. This is safe, but unnecessary -for example if virt-resize was used as an intermediate step. So only -use this option if virt-resize is actually writing to the block -device. - -(cherry picked from commit 0037820ee003bfbc71bf35b18fb3a066cbf298f8) ---- - builder/builder.ml | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/builder/builder.ml b/builder/builder.ml -index 8951be5..148c9bf 100644 ---- a/builder/builder.ml -+++ b/builder/builder.ml -@@ -493,7 +493,7 @@ let main () = - let cmd = - sprintf "virt-resize%s%s%s --output-format %s%s%s %s %s" - (if debug then " --verbose" else " --quiet") -- (if output_is_block_dev then " --no-sparse" else "") -+ (if is_block_device ofile then " --no-sparse" else "") - (match iformat with - | None -> "" - | Some iformat -> sprintf " --format %s" (quote iformat)) --- -1.8.5.3 - diff --git a/0034-builder-Refuse-to-write-to-a-char-device-or-dev-null.patch b/0034-builder-Refuse-to-write-to-a-char-device-or-dev-null.patch deleted file mode 100644 index 953d22a..0000000 --- a/0034-builder-Refuse-to-write-to-a-char-device-or-dev-null.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 97e2f2c86c5da6f5ad604307e95abcb66b65319b Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 14 Dec 2013 18:54:56 +0000 -Subject: [PATCH] builder: Refuse to write to a char device or /dev/null. - -virt-builder --output /dev/null is tempting, but not possible, and -might result in /dev/null being deleted(!) Check for this case and -prevent it happening. - -(cherry picked from commit 3cf5a25e3f63ea6832b96468a94cdb13dbd26e92) ---- - builder/builder.ml | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/builder/builder.ml b/builder/builder.ml -index 148c9bf..5d8ad09 100644 ---- a/builder/builder.ml -+++ b/builder/builder.ml -@@ -281,6 +281,11 @@ let main () = - exit 1 - ); - -+ if is_char_device output_filename then ( -+ eprintf (f_"%s: cannot output to a character device or /dev/null\n") prog; -+ exit 1 -+ ); -+ - let goal = - (* MUST *) - let goal_must = [ --- -1.8.5.3 - diff --git a/0035-builder-Remove-blank-line.patch b/0035-builder-Remove-blank-line.patch deleted file mode 100644 index 96023be..0000000 --- a/0035-builder-Remove-blank-line.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 233267fc8a5d318415a93a2e184f4d7bac667306 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 16 Dec 2013 14:14:01 +0000 -Subject: [PATCH] builder: Remove blank line. - -(cherry picked from commit c4fdb4023eed45dbf905526da4a91b846792079d) ---- - builder/builder.ml | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/builder/builder.ml b/builder/builder.ml -index 5d8ad09..1551b72 100644 ---- a/builder/builder.ml -+++ b/builder/builder.ml -@@ -58,7 +58,6 @@ let main () = - ) sources - ); - -- - (* Handle some modes here, some later on. *) - let mode = - match mode with --- -1.8.5.3 - diff --git a/0036-builder-Add-update-option-to-update-template-core-pa.patch b/0036-builder-Add-update-option-to-update-template-core-pa.patch deleted file mode 100644 index fe4e3ab..0000000 --- a/0036-builder-Add-update-option-to-update-template-core-pa.patch +++ /dev/null @@ -1,265 +0,0 @@ -From c89fc8f073498ea515f7acb666b9a2d970f46a93 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 19 Dec 2013 11:17:43 +0000 -Subject: [PATCH] builder: Add --update option to update template/core - packages. - -(cherry picked from commit b46a5511b3a98c0d811353b1bc0c7745fa972dc6) ---- - builder/builder.ml | 40 ++++++++++++++++++++++++++++- - builder/cmdline.ml | 5 +++- - builder/virt-builder.pod | 67 +++++++++++++++++++++++++++++++++--------------- - 3 files changed, 90 insertions(+), 22 deletions(-) - -diff --git a/builder/builder.ml b/builder/builder.ml -index 1551b72..1cd007f 100644 ---- a/builder/builder.ml -+++ b/builder/builder.ml -@@ -41,7 +41,7 @@ let main () = - attach, cache, check_signature, curl, debug, delete, edit, - firstboot, run, format, gpg, hostname, install, list_long, memsize, mkdirs, - network, output, password_crypto, quiet, root_password, scrub, -- scrub_logfile, size, smp, sources, sync, upload, writes = -+ scrub_logfile, size, smp, sources, sync, update, upload, writes = - parse_cmdline () in - - (* Timestamped messages in ordinary, non-debug non-quiet mode. *) -@@ -669,6 +669,7 @@ exec >>%s 2>&1 - exit 1 - in - -+ (* http://distrowatch.com/dwres.php?resource=package-management *) - let guest_install_command packages = - let quoted_args = String.concat " " (List.map quote packages) in - match g#inspect_get_package_management root with -@@ -699,8 +700,45 @@ exec >>%s 2>&1 - eprintf (f_"%s: sorry, don't know how to use --install with the '%s' package manager\n") - prog pm; - exit 1 -+ -+ and guest_update_command () = -+ match g#inspect_get_package_management root with -+ | "apt" -> -+ (* http://unix.stackexchange.com/questions/22820 *) -+ sprintf " -+ export DEBIAN_FRONTEND=noninteractive -+ apt_opts='-q -y -o Dpkg::Options::=--force-confnew' -+ apt-get $apt_opts update -+ apt-get $apt_opts upgrade -+ " -+ | "pisi" -> -+ sprintf "pisi upgrade" -+ | "pacman" -> -+ sprintf "pacman -Su" -+ | "urpmi" -> -+ sprintf "urpmi --auto-select" -+ | "yum" -> -+ sprintf "yum -y update" -+ | "zypper" -> -+ sprintf "zypper update" -+ | "unknown" -> -+ eprintf (f_"%s: --update is not supported for this guest operating system\n") -+ prog; -+ exit 1 -+ | pm -> -+ eprintf (f_"%s: sorry, don't know how to use --update with the '%s' package manager\n") -+ prog pm; -+ exit 1 - in - -+ (* Update core/template packages. *) -+ if update then ( -+ msg (f_"Updating core packages"); -+ -+ let cmd = guest_update_command () in -+ do_run ~display:cmd cmd -+ ); -+ - (* Install packages. *) - if install <> [] then ( - msg (f_"Installing packages: %s") (String.concat " " install); -diff --git a/builder/cmdline.ml b/builder/cmdline.ml -index b4e21fc..f25280c 100644 ---- a/builder/cmdline.ml -+++ b/builder/cmdline.ml -@@ -169,6 +169,7 @@ let parse_cmdline () = - let add_source arg = sources := arg :: !sources in - - let sync = ref true in -+ let update = ref false in - - let upload = ref [] in - let add_upload arg = -@@ -259,6 +260,7 @@ let parse_cmdline () = - "--smp", Arg.Int set_smp, "vcpus" ^ " " ^ s_"Set number of vCPUs"; - "--source", Arg.String add_source, "URL" ^ " " ^ s_"Set source URL"; - "--no-sync", Arg.Clear sync, " " ^ s_"Do not fsync output file on exit"; -+ "--update", Arg.Set update, " " ^ s_"Update core packages"; - "--upload", Arg.String add_upload, "file:dest" ^ " " ^ s_"Upload file to dest"; - "-v", Arg.Set debug, " " ^ s_"Enable debugging messages"; - "--verbose", Arg.Set debug, ditto; -@@ -319,6 +321,7 @@ read the man page virt-builder(1). - let smp = !smp in - let sources = List.rev !sources in - let sync = !sync in -+ let update = !update in - let upload = List.rev !upload in - let writes = List.rev !writes in - -@@ -418,4 +421,4 @@ read the man page virt-builder(1). - attach, cache, check_signature, curl, debug, delete, edit, - firstboot, run, format, gpg, hostname, install, list_long, memsize, mkdirs, - network, output, password_crypto, quiet, root_password, scrub, -- scrub_logfile, size, smp, sources, sync, upload, writes -+ scrub_logfile, size, smp, sources, sync, update, upload, writes -diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod -index 817ddd4..094f028 100644 ---- a/builder/virt-builder.pod -+++ b/builder/virt-builder.pod -@@ -18,6 +18,7 @@ virt-builder - Build virtual machine images quickly - [--attach ISOFILE] - [--root-password SELECTOR] - [--hostname HOSTNAME] -+ [--update] - [--install PKG,[PKG...]] - [--mkdir DIR] - [--write FILE:CONTENT] -@@ -215,7 +216,7 @@ I<--no-cache> disables template caching. - Download all templates to the cache and then exit. See L. - - Note this doesn't cache everything. More templates might be uploaded. --Also this doesn't cache packages (the I<--install> option). -+Also this doesn't cache packages (the I<--install>, I<--update> options). - - =item B<--check-signature> - -@@ -349,6 +350,8 @@ installed during the image build using the guest's package manager - For an overview on the different ways to install packages, see - L. - -+See also I<--update>. -+ - =item B<-l> - - =item B<--list> -@@ -580,6 +583,14 @@ Note that you should not point I<--source> to sources that you don't - trust (unless the source is signed by someone you do trust). See also - the I<--no-network> option. - -+=item B<--update> -+ -+Do the equivalent of C, C, or whatever -+command is required to update the packages already installed in the -+template to their latest versions. -+ -+See also I<--install>. -+ - =item B<--upload> FILE:DEST - - Upload local file C to destination C in the disk image. -@@ -634,6 +645,18 @@ you can use I<--install> to install packages like this: - This uses the guest's package manager and the host's network - connection. - -+=head3 Updating packages at build time -+ -+To update the core set of packages in the template at build time: -+ -+ virt-builder fedora-20 --update -+ -+Most of the templates that ship with virt-builder come with a very -+minimal selection of packages (known as a "JEOS" or "Just Enough -+Operating System"), which are up to date at the time the template is -+created, but could be out of date by the time you come to install an -+OS from the template. This option updates those template packages. -+ - =head3 Installing packages at first boot - - Another option is to install the packages when the guest first boots: -@@ -757,8 +780,8 @@ are other ways to manage passwords, see L for details. - =head2 LOG FILE - - Scripts and package installation that runs at build time (I<--run>, --I<--run-command>, I<--install>, but I firstboot) is logged in one --of the following locations: -+I<--run-command>, I<--install>, I<--update>, but I firstboot) is -+logged in one of the following locations: - - =over 4 - -@@ -823,6 +846,10 @@ The root password is changed (I<--root-password>). - - =item * - -+Core packages are updated (I<--update>). -+ -+=item * -+ - Packages are installed (I<--install>). - - =item * -@@ -1342,9 +1369,9 @@ are not cached. - - Virt-builder uses L to download files and it also uses the - current C (etc) settings when installing packages --(I<--install>). You may therefore want to set those environment --variables in order to maximize the amount of local caching that --happens. See L and L. -+(I<--install>, I<--update>). You may therefore want to set those -+environment variables in order to maximize the amount of local caching -+that happens. See L and L. - - =head2 DIGITAL SIGNATURES - -@@ -1379,8 +1406,8 @@ host architecture is. For example an x86-64 guest on an ARM host. - - However certain options may not work correctly, specifically options - that require running commands in the guest during the build process: --I<--install>, I<--run>, I<--run-command>. You may need to replace --these with their firstboot-equivalents. -+I<--install>, I<--update>, I<--run>, I<--run-command>. You may need -+to replace these with their firstboot-equivalents. - - An x86-64 host building 32 bit i686 guests should work without any - special steps. -@@ -1390,11 +1417,11 @@ special steps. - Virt-builder does not need to run as root (in fact, should not be run - as root), and doesn't use setuid, C or any similar mechanism. - --I<--install>, I<--run> and I<--run-command> are implemented using an --appliance (a small virtual machine) so these commands do not run on --the host. If you are using the libguestfs libvirt backend and have --SELinux enabled then the virtual machine is additionally encapsulated --in an SELinux container (sVirt). -+I<--install>, I<--update>, I<--run> and I<--run-command> are -+implemented using an appliance (a small virtual machine) so these -+commands do not run on the host. If you are using the libguestfs -+libvirt backend and have SELinux enabled then the virtual machine is -+additionally encapsulated in an SELinux container (sVirt). - - However these options will have access to the host's network and since - the template may contain untrusted code, the code might try to access -@@ -1435,13 +1462,13 @@ Templates gets downloaded into the cache the first time they are used, - or if you use the I<--cache-all-templates> option. See L - above for further information. - --Packages required for the I<--install> option are downloaded using the --host network connection. Setting the C, C --and C environment variables to point to a local web cache --may ensure they only need to be downloaded once. You can also try --using a local package repository, although this can be complex to set --up and varies according to which Linux distro you are trying to --install. -+Packages required for the I<--install> and I<--update> options are -+downloaded using the host network connection. Setting the -+C, C and C environment variables -+to point to a local web cache may ensure they only need to be -+downloaded once. You can also try using a local package repository, -+although this can be complex to set up and varies according to which -+Linux distro you are trying to install. - - =head3 Skipping virt-resize - --- -1.8.5.3 - diff --git a/0037-launch-libvirt-Don-t-default-to-using-NULL-for-libvi.patch b/0037-launch-libvirt-Don-t-default-to-using-NULL-for-libvi.patch deleted file mode 100644 index ae82059..0000000 --- a/0037-launch-libvirt-Don-t-default-to-using-NULL-for-libvi.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 592ad2e9e6bca314308389a60da421597f6c7d38 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 19 Dec 2013 14:22:26 +0000 -Subject: [PATCH] launch: libvirt: Don't default to using NULL for libvirt - connection URI (RHBZ#1045033). - -NULL means that libvirt gets to guess what connection URI we meant. -Currently it guesses qemu:///session for non-root and qemu:///system -for root. Except if LIBVIRT_DEFAULT_URI is set in which case this is -used even if it's not appropriate. Except if Xen is installed in -which case it guesses xen:/// which is not helpful at all. - -Instead use qemu:///session (or qemu:///system for root -- that's -likely to be wrong, but we can't help that). - -If the user really wants to use NULL and let libvirt guess, then they -can now specify the libvirt:null backend. - -See: - -https://bugzilla.redhat.com/show_bug.cgi?id=1045033 -https://bugzilla.redhat.com/show_bug.cgi?id=886915 - -A good way to test this is: - -LIBVIRT_DEFAULT_URI=iambroken libguestfs-test-tool - -The libguestfs libvirt backend should (after this commit) ignore -LIBVIRT_DEFAULT_URI. However other parts of libguestfs will still use -it, eg. guestfs_add_drive_opts, guestfish '-d' option. - -(cherry picked from commit d16db5a6180305543658f3a50657c70bbdf81b40) ---- - src/guestfs.pod | 16 +++++++++++++--- - src/launch-libvirt.c | 10 ++++++++++ - 2 files changed, 23 insertions(+), 3 deletions(-) - -diff --git a/src/guestfs.pod b/src/guestfs.pod -index 6909b50..1931055 100644 ---- a/src/guestfs.pod -+++ b/src/guestfs.pod -@@ -1429,13 +1429,23 @@ note below. - - =item C - -+=item C -+ - =item C> - - Use libvirt to launch and manage the appliance. - --The optional I is the libvirt connection URI to use (see --L). The typical libvirt backend --with a URI would be C -+C causes libguestfs to choose a suitable URI for creating -+session guests. If using the libvirt backend, you almost always -+should use this. -+ -+C causes libguestfs to use the C connection URI, -+which causes libvirt to try to guess what the user meant. You -+probably don't want to use this. -+ -+C> uses I as the libvirt connection URI (see -+L). The typical libvirt backend with a -+URI would be C - - The libvirt backend supports more features, including - hotplugging (see L) and sVirt. -diff --git a/src/launch-libvirt.c b/src/launch-libvirt.c -index b78590a..729f437 100644 ---- a/src/launch-libvirt.c -+++ b/src/launch-libvirt.c -@@ -216,6 +216,16 @@ launch_libvirt (guestfs_h *g, void *datav, const char *libvirt_uri) - if (g->verbose) - guestfs___print_timestamped_message (g, "connect to libvirt"); - -+ /* Decode the URI string. */ -+ if (!libvirt_uri) { /* "libvirt" */ -+ if (!params.current_proc_is_root) -+ libvirt_uri = "qemu:///session"; -+ else -+ libvirt_uri = "qemu:///system"; -+ } else if (STREQ (libvirt_uri, "null")) { /* libvirt:null */ -+ libvirt_uri = NULL; -+ } /* else nothing */ -+ - /* Connect to libvirt, get capabilities. */ - conn = guestfs___open_libvirt_connection (g, libvirt_uri, 0); - if (!conn) { --- -1.8.5.3 - diff --git a/0038-builder-Fix-handling-of-size-parameter.patch b/0038-builder-Fix-handling-of-size-parameter.patch deleted file mode 100644 index 84a0500..0000000 --- a/0038-builder-Fix-handling-of-size-parameter.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 1745a756c962ec90a6418203098666bb5823ce3b Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 7 Jan 2014 17:32:04 +0000 -Subject: [PATCH] builder: Fix handling of --size parameter. - -It now matches the documentation: - - "Select the size of the output disk, [...] - - Virt-builder will resize filesystems inside the disk image - automatically. - - If the size is not specified, then one of two things happens. If - the output is a file, then the size is the same as the template. If - the output is a device, partition, etc then the size of that device - is used." - -This also adds checks to make sure that users don't try to shrink a -disk (which is not possible), and they don't try to resize larger than -the output block device. - -(cherry picked from commit 06f7bea14883c4903c58077757179341c0e1471a) ---- - builder/builder.ml | 43 ++++++++++++++++++++++++++++++++++--------- - 1 file changed, 34 insertions(+), 9 deletions(-) - -diff --git a/builder/builder.ml b/builder/builder.ml -index 1cd007f..0c1f1e0 100644 ---- a/builder/builder.ml -+++ b/builder/builder.ml -@@ -263,9 +263,6 @@ let main () = - format_tag @ compression_tag in - - (* Planner: Goal. *) -- let output_size = -- let { Index_parser.size = default_size } = entry in -- match size with None -> default_size | Some size -> size in - let output_filename, output_format = - match output, format with - | None, None -> sprintf "%s.img" arg, "raw" -@@ -273,18 +270,46 @@ let main () = - | None, Some format -> sprintf "%s.%s" arg format, format - | Some output, None -> output, "raw" - | Some output, Some format -> output, format in -- let output_is_block_dev = is_block_device output_filename in -- -- if output_is_block_dev && size <> None then ( -- eprintf (f_"%s: you cannot use --size option with block devices\n") prog; -- exit 1 -- ); - - if is_char_device output_filename then ( - eprintf (f_"%s: cannot output to a character device or /dev/null\n") prog; - exit 1 - ); - -+ let blockdev_getsize64 dev = -+ let cmd = sprintf "blockdev --getsize64 %s" (quote dev) in -+ let lines = external_command ~prog cmd in -+ assert (List.length lines >= 1); -+ Int64.of_string (List.hd lines) -+ in -+ let output_is_block_dev, blockdev_size = -+ let b = is_block_device output_filename in -+ let sz = if b then blockdev_getsize64 output_filename else 0L in -+ b, sz in -+ -+ let output_size = -+ let { Index_parser.size = original_image_size } = entry in -+ -+ let size = -+ match size with -+ | Some size -> size -+ (* --size parameter missing, output to file: use original image size *) -+ | None when not output_is_block_dev -> original_image_size -+ (* --size parameter missing, block device: use block device size *) -+ | None -> blockdev_size in -+ -+ if size < original_image_size then ( -+ eprintf (f_"%s: images cannot be shrunk, the output size is too small for this image. Requested size = %s, minimum size = %s\n") -+ prog (human_size size) (human_size original_image_size); -+ exit 1 -+ ) -+ else if output_is_block_dev && output_format = "raw" && size > blockdev_size then ( -+ eprintf (f_"%s: output size is too large for this block device. Requested size = %s, output block device = %s, output block device size = %s\n") -+ prog (human_size size) output_filename (human_size blockdev_size); -+ exit 1 -+ ); -+ size in -+ - let goal = - (* MUST *) - let goal_must = [ --- -1.8.5.3 - diff --git a/0039-libvirt-auth-Provide-a-friendlier-wrapper-around-vir.patch b/0039-libvirt-auth-Provide-a-friendlier-wrapper-around-vir.patch deleted file mode 100644 index 3a9bf6f..0000000 --- a/0039-libvirt-auth-Provide-a-friendlier-wrapper-around-vir.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 4ee4296d5bd5ca9788974810918e31aa12e3cd61 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 2 Jan 2014 12:20:18 +0000 -Subject: [PATCH] libvirt-auth: Provide a friendlier wrapper around - virConnectAuthPtrDefault (RHBZ#1044014). - -(cherry picked from commit 4125064554c8cb1b96680e24e49d74ee6024f761) ---- - src/guestfs-internal.h | 1 + - src/libvirt-auth.c | 55 +++++++++++++++++++++++++++++++++++++++++--------- - 2 files changed, 46 insertions(+), 10 deletions(-) - -diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h -index 3501ed5..cde1277 100644 ---- a/src/guestfs-internal.h -+++ b/src/guestfs-internal.h -@@ -469,6 +469,7 @@ struct guestfs_h - unsigned int nr_supported_credentials; - int supported_credentials[NR_CREDENTIAL_TYPES]; - const char *saved_libvirt_uri; /* Doesn't need to be freed. */ -+ bool wrapper_warning_done; - unsigned int nr_requested_credentials; - virConnectCredentialPtr requested_credentials; - #endif -diff --git a/src/libvirt-auth.c b/src/libvirt-auth.c -index fb18f8a..f8ed1b1 100644 ---- a/src/libvirt-auth.c -+++ b/src/libvirt-auth.c -@@ -20,6 +20,7 @@ - - #include - #include -+#include - - #ifdef HAVE_LIBVIRT - #include -@@ -147,6 +148,34 @@ libvirt_auth_callback (virConnectCredentialPtr cred, - return 0; - } - -+/* Libvirt provides a default authentication handler. However it is -+ * confusing to end-users -+ * (https://bugzilla.redhat.com/show_bug.cgi?id=1044014#c0). -+ * -+ * Unfortunately #1 the libvirt handler cannot easily be modified to -+ * make it non-confusing, but unfortunately #2 we have to actually -+ * call it because it handles all the policykit crap. -+ * -+ * Therefore we add a wrapper around it here. -+ */ -+static int -+libvirt_auth_default_wrapper (virConnectCredentialPtr cred, -+ unsigned int ncred, -+ void *gv) -+{ -+ guestfs_h *g = gv; -+ -+ if (!g->wrapper_warning_done) { -+ printf (_("libvirt needs authentication to connect to libvirt URI %s\n" -+ "(see also: http://libvirt.org/auth.html http://libvirt.org/uri.html)\n"), -+ g->saved_libvirt_uri ? g->saved_libvirt_uri : "NULL"); -+ g->wrapper_warning_done = true; -+ } -+ -+ return virConnectAuthPtrDefault->cb (cred, ncred, -+ virConnectAuthPtrDefault->cbdata); -+} -+ - static int - exists_libvirt_auth_event (guestfs_h *g) - { -@@ -165,31 +194,37 @@ guestfs___open_libvirt_connection (guestfs_h *g, const char *uri, - unsigned int flags) - { - virConnectAuth authdata; -- virConnectAuthPtr authdataptr; - virConnectPtr conn; -+ const char *authtype; -+ -+ g->saved_libvirt_uri = uri; -+ g->wrapper_warning_done = false; - - /* Did the caller register a GUESTFS_EVENT_LIBVIRT_AUTH event and - * call guestfs_set_libvirt_supported_credentials? - */ - if (g->nr_supported_credentials > 0 && exists_libvirt_auth_event (g)) { -+ authtype = "custom"; - memset (&authdata, 0, sizeof authdata); - authdata.credtype = g->supported_credentials; - authdata.ncredtype = g->nr_supported_credentials; - authdata.cb = libvirt_auth_callback; - authdata.cbdata = g; -- authdataptr = &authdata; -- g->saved_libvirt_uri = uri; - } -- else -- authdataptr = virConnectAuthPtrDefault; -+ else { -+ /* Wrapper around libvirt's virConnectAuthPtrDefault, see comment -+ * above. -+ */ -+ authtype = "default+wrapper"; -+ authdata = *virConnectAuthPtrDefault; -+ authdata.cb = libvirt_auth_default_wrapper; -+ authdata.cbdata = g; -+ } - - debug (g, "opening libvirt handle: URI = %s, auth = %s, flags = %u", -- uri ? uri : "NULL", -- authdataptr == virConnectAuthPtrDefault -- ? "virConnectAuthPtrDefault" : "", -- flags); -+ uri ? uri : "NULL", authtype, flags); - -- conn = virConnectOpenAuth (uri, authdataptr, flags); -+ conn = virConnectOpenAuth (uri, &authdata, flags); - - if (conn) - debug (g, "successfully opened libvirt handle: conn = %p", conn); --- -1.8.5.3 - diff --git a/0040-tests-Add-a-regression-test-of-libvirt-authenticatio.patch b/0040-tests-Add-a-regression-test-of-libvirt-authenticatio.patch deleted file mode 100644 index 5ef58be..0000000 --- a/0040-tests-Add-a-regression-test-of-libvirt-authenticatio.patch +++ /dev/null @@ -1,303 +0,0 @@ -From ba28105660674addc4730985a08f885030a62c7c Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 8 Jan 2014 19:36:00 +0000 -Subject: [PATCH] tests: Add a regression test of libvirt authentication - events. - -This requires a change to libvirt (in libvirt >= 1.2.1), see: - -https://www.redhat.com/archives/libvir-list/2014-January/msg00378.html -(cherry picked from commit 873db60c0e52893a38c374d867d0a305e5419d6a) ---- - .gitignore | 1 + - tests/events/Makefile.am | 36 ++++-- - tests/events/libvirt-auth.xml | 22 ++++ - tests/events/test-libvirt-auth-callbacks.c | 185 +++++++++++++++++++++++++++++ - 4 files changed, 237 insertions(+), 7 deletions(-) - create mode 100644 tests/events/libvirt-auth.xml - create mode 100644 tests/events/test-libvirt-auth-callbacks.c - -diff --git a/.gitignore b/.gitignore -index 6e04072..bce35f0 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -463,6 +463,7 @@ Makefile.in - /tests/data/initrd-x86_64.img.gz - /tests/data/test-grep.txt.gz - /tests/data/test.iso -+/tests/events/test-libvirt-auth-callbacks - /tests/guests/blank-*.img - /tests/guests/debian.img - /tests/guests/fedora.img -diff --git a/tests/events/Makefile.am b/tests/events/Makefile.am -index 9f6e5aa..9751edc 100644 ---- a/tests/events/Makefile.am -+++ b/tests/events/Makefile.am -@@ -1,5 +1,5 @@ - # libguestfs --# Copyright (C) 2013 Red Hat Inc. -+# Copyright (C) 2013-2014 Red Hat Inc. - # - # This program is free software; you can redistribute it and/or modify - # it under the terms of the GNU General Public License as published by -@@ -17,10 +17,32 @@ - - include $(top_srcdir)/subdir-rules.mk - --TESTS = \ -- test-console-debug.pl -- --TESTS_ENVIRONMENT = $(top_builddir)/run --test -- - EXTRA_DIST = \ -- $(TESTS) -+ test-console-debug.pl \ -+ libvirt-auth.xml -+ -+TESTS_ENVIRONMENT = $(top_builddir)/run --test -+ -+check_PROGRAMS = -+ -+TESTS = test-console-debug.pl -+ -+if HAVE_LIBVIRT -+TESTS += test-libvirt-auth-callbacks -+check_PROGRAMS += test-libvirt-auth-callbacks -+ -+test_libvirt_auth_callbacks_SOURCES = test-libvirt-auth-callbacks.c -+test_libvirt_auth_callbacks_CPPFLAGS = \ -+ -I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \ -+ -I$(top_srcdir)/src -I$(top_builddir)/src -+test_libvirt_auth_callbacks_CFLAGS = \ -+ $(WARN_CFLAGS) $(WERROR_CFLAGS) \ -+ $(GPROF_CFLAGS) $(GCOV_CFLAGS) \ -+ $(LIBVIRT_CFLAGS) -+test_libvirt_auth_callbacks_LDADD = \ -+ $(top_builddir)/src/libutils.la \ -+ $(top_builddir)/src/libguestfs.la \ -+ $(LIBVIRT_LIBS) \ -+ $(LIBXML2_LIBS) \ -+ $(top_builddir)/gnulib/lib/libgnu.la -+endif -diff --git a/tests/events/libvirt-auth.xml b/tests/events/libvirt-auth.xml -new file mode 100644 -index 0000000..d138d4d ---- /dev/null -+++ b/tests/events/libvirt-auth.xml -@@ -0,0 +1,22 @@ -+ -+ -+ test -+ 1048576 -+ -+ hvm -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ rich -+ jane -+ -+ -diff --git a/tests/events/test-libvirt-auth-callbacks.c b/tests/events/test-libvirt-auth-callbacks.c -new file mode 100644 -index 0000000..7c26bbe ---- /dev/null -+++ b/tests/events/test-libvirt-auth-callbacks.c -@@ -0,0 +1,185 @@ -+/* libguestfs -+ * Copyright (C) 2014 Red Hat Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "guestfs.h" -+#include "guestfs-internal-frontend.h" -+ -+#define EXPECT_OK 1 -+#define EXPECT_FAIL -1 -+ -+struct auth_data { -+ const char *username; -+ const char *password; -+}; -+ -+static void do_test (const char *prog, const char *libvirt_uri, const struct auth_data *auth_data, int expected); -+static void auth_callback (guestfs_h *g, void *opaque, uint64_t event, int event_handle, int flags, const char *buf, size_t buf_len, const uint64_t *array, size_t array_len); -+ -+int -+main (int argc, char *argv[]) -+{ -+ unsigned long ver; -+ const char *srcdir; -+ char *cwd; -+ char *test_uri; -+ -+ virInitialize (); -+ -+ /* Check that the version of libvirt we are linked against -+ * supports the new test-driver auth feature. -+ */ -+ virGetVersion (&ver, NULL, NULL); -+ if (ver < 1002001) { -+ fprintf (stderr, "%s: test skipped because libvirt is too old (%lu)\n", -+ argv[0], ver); -+ exit (77); -+ } -+ -+ /* $srcdir must have been passed (by automake). */ -+ srcdir = getenv ("srcdir"); -+ if (!srcdir) { -+ fprintf (stderr, -+ "%s: environment variable $srcdir is not defined.\n" -+ "Normally it is defined by automake. If you are running the\n" -+ "tests directly, set $srcdir to point to the source tests/events\n" -+ "directory.\n", argv[0]); -+ exit (EXIT_FAILURE); -+ } -+ -+ cwd = get_current_dir_name (); -+ if (cwd == NULL) { -+ perror ("get_current_dir_name"); -+ exit (EXIT_FAILURE); -+ } -+ -+ if (asprintf (&test_uri, "test://%s/%s/libvirt-auth.xml", cwd, srcdir) == -1) { -+ perror ("asprintf"); -+ exit (EXIT_FAILURE); -+ } -+ -+ free (cwd); -+ -+ /* Perform the tests. */ -+ struct auth_data ad1 = { .username = "rich", .password = "123456" }; -+ do_test (argv[0], test_uri, &ad1, EXPECT_OK); -+ struct auth_data ad2 = { .username = "rich", .password = "654321" }; -+ do_test (argv[0], test_uri, &ad2, EXPECT_FAIL); -+ struct auth_data ad3 = { .username = "jane", .password = NULL }; -+ do_test (argv[0], test_uri, &ad3, EXPECT_OK); -+ struct auth_data ad4 = { .username = "nouser", .password = "123456" }; -+ do_test (argv[0], test_uri, &ad4, EXPECT_FAIL); -+ -+ free (test_uri); -+ exit (EXIT_SUCCESS); -+} -+ -+static void -+do_test (const char *prog, const char *libvirt_uri, -+ const struct auth_data *auth_data, -+ int expected) -+{ -+ guestfs_h *g; -+ const char *creds[] = -+ { "authname", "passphrase", "noechoprompt", NULL }; -+ int r, eh; -+ -+ g = guestfs_create (); -+ if (!g) -+ exit (EXIT_FAILURE); -+ -+ r = guestfs_set_libvirt_supported_credentials (g, (char **) creds); -+ if (r == -1) -+ exit (EXIT_FAILURE); -+ -+ eh = guestfs_set_event_callback (g, auth_callback, -+ GUESTFS_EVENT_LIBVIRT_AUTH, 0, -+ (void *) auth_data); -+ if (eh == -1) -+ exit (EXIT_FAILURE); -+ -+ r = guestfs_add_domain (g, "test", -+ GUESTFS_ADD_DOMAIN_LIBVIRTURI, libvirt_uri, -+ GUESTFS_ADD_DOMAIN_READONLY, 1, -+ -1); -+ if (r != expected) { -+ fprintf (stderr, -+ "%s: test failed: u=%s p=%s: got %d expected %d\n", -+ prog, auth_data->username, auth_data->password ? : "(none)", -+ r, expected); -+ exit (EXIT_FAILURE); -+ } -+ -+ guestfs_close (g); -+} -+ -+static void -+auth_callback (guestfs_h *g, void *opaque, -+ uint64_t event, int event_handle, -+ int flags, -+ const char *buf, size_t buf_len, -+ const uint64_t *array, size_t array_len) -+{ -+ CLEANUP_FREE_STRING_LIST char **creds = NULL; -+ const struct auth_data *auth_data = opaque; -+ size_t i; -+ int r; -+ const char *reply; -+ size_t len; -+ -+ /* Ask libguestfs what credentials libvirt is demanding. */ -+ creds = guestfs_get_libvirt_requested_credentials (g); -+ if (creds == NULL) -+ exit (EXIT_FAILURE); -+ -+ /* Try to answer from the authentication data. */ -+ for (i = 0; creds[i] != NULL; ++i) { -+ if (STREQ (creds[i], "authname")) { -+ reply = auth_data->username; -+ len = strlen (reply); -+ } -+ else if (STREQ (creds[i], "passphrase") || -+ STREQ (creds[i], "noechoprompt")) { -+ if (!auth_data->password) { -+ fprintf (stderr, "test failed: libvirt asked for a password, but auth_data->password == NULL\n"); -+ exit (EXIT_FAILURE); -+ } -+ -+ reply = auth_data->password; -+ len = strlen (reply); -+ } -+ else { -+ fprintf (stderr, "test failed: libvirt asked for '%s' which is not in creds list\n(This is probably a libvirt bug)\n", -+ creds[i]); -+ exit (EXIT_FAILURE); -+ } -+ -+ r = guestfs_set_libvirt_requested_credential (g, i, -+ reply, len); -+ if (r == -1) -+ exit (EXIT_FAILURE); -+ } -+} --- -1.8.5.3 - diff --git a/0041-tests-Add-a-regression-test-for-libvirt-authenticati.patch b/0041-tests-Add-a-regression-test-for-libvirt-authenticati.patch deleted file mode 100644 index 289c585..0000000 --- a/0041-tests-Add-a-regression-test-for-libvirt-authenticati.patch +++ /dev/null @@ -1,267 +0,0 @@ -From eb10843058334e17735e7e90ad40a8ef1fdfaa32 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 8 Jan 2014 20:22:21 +0000 -Subject: [PATCH] tests: Add a regression test for libvirt authentication - (RHBZ#1044014). - -This tests the virConnectAuthPtrDefault wrapper path. - -(cherry picked from commit 746a0b1f19667606ee63c8d3ab6a75531a8bd71c) ---- - .gitignore | 2 ++ - tests/regressions/Makefile.am | 28 ++++++++++++++++ - tests/regressions/rhbz1044014.c | 69 ++++++++++++++++++++++++++++++++++++++ - tests/regressions/rhbz1044014.in | 1 + - tests/regressions/rhbz1044014.sh | 70 +++++++++++++++++++++++++++++++++++++++ - tests/regressions/rhbz1044014.xml | 5 +++ - 6 files changed, 175 insertions(+) - create mode 100644 tests/regressions/rhbz1044014.c - create mode 100644 tests/regressions/rhbz1044014.in - create mode 100755 tests/regressions/rhbz1044014.sh - create mode 100644 tests/regressions/rhbz1044014.xml - -diff --git a/.gitignore b/.gitignore -index bce35f0..2d61d77 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -485,6 +485,8 @@ Makefile.in - /tests/regressions/rhbz501893 - /tests/regressions/rhbz790721 - /tests/regressions/rhbz914931 -+/tests/regressions/rhbz1044014 -+/tests/regressions/rhbz1044014.out - /tests/regressions/rhbz1055452 - /tests/rsync/rsyncd.pid - /tests/syslinux/extlinux-guest.img -diff --git a/tests/regressions/Makefile.am b/tests/regressions/Makefile.am -index 15333b7..563f87f 100644 ---- a/tests/regressions/Makefile.am -+++ b/tests/regressions/Makefile.am -@@ -35,6 +35,9 @@ EXTRA_DIST = \ - rhbz957772.sh \ - rhbz975797.sh \ - rhbz1001875.sh \ -+ rhbz1044014.sh \ -+ rhbz1044014.in \ -+ rhbz1044014.xml \ - test-noexec-stack.pl - - TESTS = \ -@@ -57,6 +60,10 @@ TESTS = \ - rhbz1055452 \ - test-noexec-stack.pl - -+if HAVE_LIBVIRT -+TESTS += rhbz1044014.sh -+endif -+ - tests_not_run = \ - rhbz727178.sh \ - rhbz909624.sh -@@ -71,6 +78,10 @@ check_PROGRAMS = \ - rhbz914931 \ - rhbz1055452 - -+if HAVE_LIBVIRT -+check_PROGRAMS += rhbz1044014 -+endif -+ - rhbz501893_SOURCES = rhbz501893.c - rhbz501893_CPPFLAGS = \ - -I$(top_srcdir)/src -I$(top_builddir)/src -@@ -101,6 +112,23 @@ rhbz914931_CFLAGS = \ - rhbz914931_LDADD = \ - $(top_builddir)/src/libguestfs.la - -+if HAVE_LIBVIRT -+rhbz1044014_SOURCES = rhbz1044014.c -+rhbz1044014_CPPFLAGS = \ -+ -I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \ -+ -I$(top_srcdir)/src -I$(top_builddir)/src -+rhbz1044014_CFLAGS = \ -+ $(WARN_CFLAGS) $(WERROR_CFLAGS) \ -+ $(GPROF_CFLAGS) $(GCOV_CFLAGS) \ -+ $(LIBVIRT_CFLAGS) -+rhbz1044014_LDADD = \ -+ $(top_builddir)/src/libutils.la \ -+ $(top_builddir)/src/libguestfs.la \ -+ $(LIBVIRT_LIBS) \ -+ $(LIBXML2_LIBS) \ -+ $(top_builddir)/gnulib/lib/libgnu.la -+endif -+ - rhbz1055452_SOURCES = rhbz1055452.c - rhbz1055452_CPPFLAGS = \ - -I$(top_srcdir)/src -I$(top_builddir)/src \ -diff --git a/tests/regressions/rhbz1044014.c b/tests/regressions/rhbz1044014.c -new file mode 100644 -index 0000000..18ce4a7 ---- /dev/null -+++ b/tests/regressions/rhbz1044014.c -@@ -0,0 +1,69 @@ -+/* libguestfs -+ * Copyright (C) 2014 Red Hat Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ */ -+ -+/* Regression test for RHBZ#1044014. -+ * -+ * The only reason to write this in C is so we can easily check the -+ * version of libvirt >= 1.2.1. In the future when we can assume a -+ * newer libvirt, we can just have the main rhbz1044014.sh script set -+ * some environment variables and use guestfish. -+ */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "guestfs.h" -+#include "guestfs-internal-frontend.h" -+ -+int -+main (int argc, char *argv[]) -+{ -+ unsigned long ver; -+ guestfs_h *g; -+ -+ virInitialize (); -+ -+ /* Check that the version of libvirt we are linked against -+ * supports the new test-driver auth feature. -+ */ -+ virGetVersion (&ver, NULL, NULL); -+ if (ver < 1002001) { -+ fprintf (stderr, "%s: test skipped because libvirt is too old (%lu)\n", -+ argv[0], ver); -+ exit (77); -+ } -+ -+ g = guestfs_create (); -+ if (!g) -+ exit (EXIT_FAILURE); -+ -+ /* This will ask the user for credentials. It will also fail -+ * (expectedly) because the test driver does not support qemu/KVM. -+ */ -+ guestfs_launch (g); -+ -+ guestfs_close (g); -+ exit (EXIT_SUCCESS); -+} -diff --git a/tests/regressions/rhbz1044014.in b/tests/regressions/rhbz1044014.in -new file mode 100644 -index 0000000..3f382dd ---- /dev/null -+++ b/tests/regressions/rhbz1044014.in -@@ -0,0 +1 @@ -+rich -diff --git a/tests/regressions/rhbz1044014.sh b/tests/regressions/rhbz1044014.sh -new file mode 100755 -index 0000000..f1e458c ---- /dev/null -+++ b/tests/regressions/rhbz1044014.sh -@@ -0,0 +1,70 @@ -+#!/bin/bash - -+# libguestfs -+# Copyright (C) 2014 Red Hat Inc. -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program 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 General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; if not, write to the Free Software -+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ -+# Regression test for: -+# https://bugzilla.redhat.com/show_bug.cgi?id=1044014 -+ -+set -e -+export LANG=C -+ -+if [ -n "$SKIP_TEST_RHBZ1044014_SH" ]; then -+ echo "$0: test skipped because environment variable is set." -+ exit 77 -+fi -+ -+# Check we are running against the libvirt backend. -+backend="$(../../fish/guestfish get-backend)" -+if [[ ! ( "$backend" =~ ^libvirt ) ]]; then -+ echo "$0: test skipped because backend ($backend) is not libvirt." -+ exit 77 -+fi -+ -+# Set the backend to the test driver. -+export LIBGUESTFS_BACKEND="libvirt:test://$(pwd)/$srcdir/rhbz1044014.xml" -+ -+rm -f rhbz1044014.out -+ -+./rhbz1044014 < $srcdir/rhbz1044014.in > rhbz1044014.out 2>&1 || { -+ r=$? -+ if [ $r -ne 0 ]; then -+ cat rhbz1044014.out -+ exit $r -+ fi -+} -+ -+# We are expecting this message to be printed (see commit which fixed -+# RHBZ#1044014). -+grep "libvirt needs authentication to connect to libvirt URI" rhbz1044014.out || { -+ echo "$0: expecting to see message from commit which fixed RHBZ#1044014" -+ echo -+ echo "actual output was:" -+ echo -+ cat rhbz1044014.out -+ exit 1 -+} -+ -+# This is the error we are expecting to see. If we see it then it -+# indicates that authentication was successful. -+grep "error: libvirt hypervisor doesn't support qemu or KVM" rhbz1044014.out || { -+ echo "$0: unexpected output:" -+ echo -+ cat rhbz1044014.out -+ exit 1 -+} -+ -+rm rhbz1044014.out -diff --git a/tests/regressions/rhbz1044014.xml b/tests/regressions/rhbz1044014.xml -new file mode 100644 -index 0000000..72feaf4 ---- /dev/null -+++ b/tests/regressions/rhbz1044014.xml -@@ -0,0 +1,5 @@ -+ -+ -+ rich -+ -+ --- -1.8.5.3 - diff --git a/0042-sysprep-builder-Add-timezone-option-to-set-timezone-.patch b/0042-sysprep-builder-Add-timezone-option-to-set-timezone-.patch deleted file mode 100644 index ade4b69..0000000 --- a/0042-sysprep-builder-Add-timezone-option-to-set-timezone-.patch +++ /dev/null @@ -1,363 +0,0 @@ -From d3f306817fa180205d3be3d206a441478dfebe88 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 10 Jan 2014 12:12:30 +0000 -Subject: [PATCH] sysprep, builder: Add --timezone option to set timezone of - guest. - -You can use it like this: - - virt-sysprep --timezone Europe/London ... - virt-builder --timezone Europe/London ... - -(cherry picked from commit dd1bfea513658368afd3728e0c5bf8ab6041cd1f) ---- - builder/Makefile.am | 1 + - builder/builder.ml | 12 ++++++- - builder/cmdline.ml | 9 ++++- - builder/test-virt-builder.sh | 1 + - builder/virt-builder.pod | 8 ++++- - mllib/Makefile.am | 3 ++ - mllib/timezone.ml | 39 +++++++++++++++++++++ - mllib/timezone.mli | 22 ++++++++++++ - po/POTFILES-ml | 2 ++ - sysprep/Makefile.am | 2 ++ - sysprep/sysprep_operation_timezone.ml | 66 +++++++++++++++++++++++++++++++++++ - 11 files changed, 162 insertions(+), 3 deletions(-) - create mode 100644 mllib/timezone.ml - create mode 100644 mllib/timezone.mli - create mode 100644 sysprep/sysprep_operation_timezone.ml - -diff --git a/builder/Makefile.am b/builder/Makefile.am -index f5e7d80..d718c22 100644 ---- a/builder/Makefile.am -+++ b/builder/Makefile.am -@@ -67,6 +67,7 @@ OBJECTS = \ - $(top_builddir)/mllib/urandom.cmx \ - $(top_builddir)/mllib/random_seed.cmx \ - $(top_builddir)/mllib/hostname.cmx \ -+ $(top_builddir)/mllib/timezone.cmx \ - $(top_builddir)/mllib/firstboot.cmx \ - $(top_builddir)/mllib/perl_edit.cmx \ - $(top_builddir)/mllib/crypt-c.o \ -diff --git a/builder/builder.ml b/builder/builder.ml -index 0c1f1e0..daf355c 100644 ---- a/builder/builder.ml -+++ b/builder/builder.ml -@@ -41,7 +41,8 @@ let main () = - attach, cache, check_signature, curl, debug, delete, edit, - firstboot, run, format, gpg, hostname, install, list_long, memsize, mkdirs, - network, output, password_crypto, quiet, root_password, scrub, -- scrub_logfile, size, smp, sources, sync, update, upload, writes = -+ scrub_logfile, size, smp, sources, sync, timezone, update, upload, -+ writes = - parse_cmdline () in - - (* Timestamped messages in ordinary, non-debug non-quiet mode. *) -@@ -621,6 +622,15 @@ let main () = - eprintf (f_"%s: warning: hostname could not be set for this type of guest\n%!") prog - ); - -+ (* Set the timezone. *) -+ (match timezone with -+ | None -> () -+ | Some timezone -> -+ msg (f_"Setting the timezone: %s") timezone; -+ if not (Timezone.set_timezone ~prog g root timezone) then -+ eprintf (f_"%s: warning: timezone could not be set for this type of guest\n%!") prog -+ ); -+ - (* Root password. - * Note 'None' means that we randomize the root password. - *) -diff --git a/builder/cmdline.ml b/builder/cmdline.ml -index f25280c..813fbd8 100644 ---- a/builder/cmdline.ml -+++ b/builder/cmdline.ml -@@ -169,6 +169,10 @@ let parse_cmdline () = - let add_source arg = sources := arg :: !sources in - - let sync = ref true in -+ -+ let timezone = ref None in -+ let set_timezone s = timezone := Some s in -+ - let update = ref false in - - let upload = ref [] in -@@ -260,6 +264,7 @@ let parse_cmdline () = - "--smp", Arg.Int set_smp, "vcpus" ^ " " ^ s_"Set number of vCPUs"; - "--source", Arg.String add_source, "URL" ^ " " ^ s_"Set source URL"; - "--no-sync", Arg.Clear sync, " " ^ s_"Do not fsync output file on exit"; -+ "--timezone",Arg.String set_timezone, "timezone" ^ " " ^ s_"Set the default timezone"; - "--update", Arg.Set update, " " ^ s_"Update core packages"; - "--upload", Arg.String add_upload, "file:dest" ^ " " ^ s_"Upload file to dest"; - "-v", Arg.Set debug, " " ^ s_"Enable debugging messages"; -@@ -321,6 +326,7 @@ read the man page virt-builder(1). - let smp = !smp in - let sources = List.rev !sources in - let sync = !sync in -+ let timezone = !timezone in - let update = !update in - let upload = List.rev !upload in - let writes = List.rev !writes in -@@ -421,4 +427,5 @@ read the man page virt-builder(1). - attach, cache, check_signature, curl, debug, delete, edit, - firstboot, run, format, gpg, hostname, install, list_long, memsize, mkdirs, - network, output, password_crypto, quiet, root_password, scrub, -- scrub_logfile, size, smp, sources, sync, update, upload, writes -+ scrub_logfile, size, smp, sources, sync, timezone, update, upload, -+ writes -diff --git a/builder/test-virt-builder.sh b/builder/test-virt-builder.sh -index 438f2e9..8d2766a 100755 ---- a/builder/test-virt-builder.sh -+++ b/builder/test-virt-builder.sh -@@ -53,6 +53,7 @@ $VG ./virt-builder phony-fedora \ - -v --no-cache --no-check-signature $no_network \ - -o $output --size 2G --format $format \ - --hostname test.example.com \ -+ --timezone Europe/London \ - --root-password password:123456 \ - --mkdir /etc/foo/bar/baz \ - --write '/etc/foo/bar/baz/foo:Hello World' \ -diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod -index 094f028..f98ffdb 100644 ---- a/builder/virt-builder.pod -+++ b/builder/virt-builder.pod -@@ -18,6 +18,7 @@ virt-builder - Build virtual machine images quickly - [--attach ISOFILE] - [--root-password SELECTOR] - [--hostname HOSTNAME] -+ [--timezone TIMEZONE] - [--update] - [--install PKG,[PKG...]] - [--mkdir DIR] -@@ -583,6 +584,11 @@ Note that you should not point I<--source> to sources that you don't - trust (unless the source is signed by someone you do trust). See also - the I<--no-network> option. - -+=item B<--timezone> TIMEZONE -+ -+Set the default timezone of the guest to C. Use a location -+string like C -+ - =item B<--update> - - Do the equivalent of C, C, or whatever -@@ -838,7 +844,7 @@ A new random seed is generated for the guest. - - =item * - --The hostname is set (I<--hostname>). -+The hostname and timezone are set (I<--hostname>, I<--timezone>). - - =item * - -diff --git a/mllib/Makefile.am b/mllib/Makefile.am -index 62d0f68..f10efad 100644 ---- a/mllib/Makefile.am -+++ b/mllib/Makefile.am -@@ -52,6 +52,8 @@ SOURCES = \ - progress.ml \ - random_seed.mli \ - random_seed.ml \ -+ timezone.mli \ -+ timezone.ml \ - tty-c.c \ - tTY.mli \ - tTY.ml \ -@@ -83,6 +85,7 @@ OBJECTS = \ - urandom.cmx \ - random_seed.cmx \ - hostname.cmx \ -+ timezone.cmx \ - firstboot.cmx \ - perl_edit.cmx \ - tTY.cmx \ -diff --git a/mllib/timezone.ml b/mllib/timezone.ml -new file mode 100644 -index 0000000..8b302d9 ---- /dev/null -+++ b/mllib/timezone.ml -@@ -0,0 +1,39 @@ -+(* Set timezone in virt-sysprep and virt-builder. -+ * Copyright (C) 2014 Red Hat Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ *) -+ -+open Common_utils -+ -+open Printf -+ -+let set_timezone ~prog (g : Guestfs.guestfs) root timezone = -+ let typ = g#inspect_get_type root in -+ -+ match typ with -+ (* Every known Linux has /etc/localtime be either a copy of or a -+ * symlink to a timezone file in /usr/share/zoneinfo. -+ * Even systemd didn't fuck this up. -+ *) -+ | "linux" -> -+ let target = sprintf "/usr/share/zoneinfo/%s" timezone in -+ if not (g#exists target) then -+ error ~prog "timezone '%s' does not exist, use a location like 'Europe/London'" timezone; -+ g#ln_sf target "/etc/localtime"; -+ true -+ -+ | _ -> -+ false -diff --git a/mllib/timezone.mli b/mllib/timezone.mli -new file mode 100644 -index 0000000..ad0d4b2 ---- /dev/null -+++ b/mllib/timezone.mli -@@ -0,0 +1,22 @@ -+(* Set timezone in virt-sysprep and virt-builder. -+ * Copyright (C) 2014 Red Hat Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ *) -+ -+val set_timezone : prog:string -> Guestfs.guestfs -> string -> string -> bool -+(** [set_timezone ~prog g root "Europe/London"] sets the default timezone -+ of the guest. Returns [true] if it was able to set the -+ timezone or [false] if not. *) -diff --git a/po/POTFILES-ml b/po/POTFILES-ml -index 6372f7e..3b2f297 100644 ---- a/po/POTFILES-ml -+++ b/po/POTFILES-ml -@@ -22,6 +22,7 @@ mllib/planner.ml - mllib/progress.ml - mllib/random_seed.ml - mllib/tTY.ml -+mllib/timezone.ml - mllib/uRI.ml - mllib/urandom.ml - resize/resize.ml -@@ -63,6 +64,7 @@ sysprep/sysprep_operation_smolt_uuid.ml - sysprep/sysprep_operation_ssh_hostkeys.ml - sysprep/sysprep_operation_ssh_userdir.ml - sysprep/sysprep_operation_sssd_db_log.ml -+sysprep/sysprep_operation_timezone.ml - sysprep/sysprep_operation_tmp_files.ml - sysprep/sysprep_operation_udev_persistent_net.ml - sysprep/sysprep_operation_user_account.ml -diff --git a/sysprep/Makefile.am b/sysprep/Makefile.am -index 60572fe..8840ca8 100644 ---- a/sysprep/Makefile.am -+++ b/sysprep/Makefile.am -@@ -66,6 +66,7 @@ operations = \ - ssh_hostkeys \ - ssh_userdir \ - sssd_db_log \ -+ timezone \ - tmp_files \ - udev_persistent_net \ - user_account \ -@@ -93,6 +94,7 @@ OBJECTS = \ - $(top_builddir)/mllib/password.cmx \ - $(top_builddir)/mllib/random_seed.cmx \ - $(top_builddir)/mllib/hostname.cmx \ -+ $(top_builddir)/mllib/timezone.cmx \ - $(top_builddir)/mllib/firstboot.cmx \ - $(top_builddir)/mllib/config.cmx \ - $(top_builddir)/mllib/mkdtemp-c.o \ -diff --git a/sysprep/sysprep_operation_timezone.ml b/sysprep/sysprep_operation_timezone.ml -new file mode 100644 -index 0000000..7557f44 ---- /dev/null -+++ b/sysprep/sysprep_operation_timezone.ml -@@ -0,0 +1,66 @@ -+(* virt-sysprep -+ * Copyright (C) 2014 Red Hat Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ *) -+ -+open Printf -+ -+open Common_utils -+open Sysprep_operation -+open Common_gettext.Gettext -+ -+module G = Guestfs -+ -+let timezone = ref None -+ -+let timezone_perform (g : Guestfs.guestfs) root = -+ match !timezone with -+ | None -> [] -+ | Some tz -> -+ if Timezone.set_timezone ~prog g root tz then [ `Created_files ] else [] -+ -+let op = { -+ defaults with -+ name = "timezone"; -+ enabled_by_default = true; -+ heading = s_"Change the default timezone of the guest"; -+ -+ pod_description = Some (s_"\ -+This operation changes the default timezone of the guest to the value -+given in the I<--timezone> parameter. -+ -+If the I<--timezone> parameter is not given, then the timezone is not -+changed. -+ -+This parameter affects the default timezone that users see when they log -+in, but they can still change their timezone per-user account."); -+ -+ pod_notes = Some (s_"\ -+Currently this can only set the timezone on Linux guests."); -+ -+ extra_args = [ -+ let set_timezone str = timezone := Some str in -+ { extra_argspec = "--timezone", Arg.String set_timezone, s_"timezone" ^ " " ^ s_"New timezone"; -+ extra_pod_argval = Some "TIMEZONE"; -+ extra_pod_description = s_"\ -+Change the timezone. Use a location string such as C" -+ } -+ ]; -+ -+ perform_on_filesystems = Some timezone_perform; -+} -+ -+let () = register_operation op --- -1.8.5.3 - diff --git a/0043-builder-Document-how-to-change-keyboard-layout.patch b/0043-builder-Document-how-to-change-keyboard-layout.patch deleted file mode 100644 index 4614653..0000000 --- a/0043-builder-Document-how-to-change-keyboard-layout.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 26e6121f4fd93e7d40b8281153986d510b63aaa3 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 10 Jan 2014 14:21:17 +0000 -Subject: [PATCH] builder: Document how to change keyboard layout. - -This is too complex to implement directly in virt-builder. - -Instead we just document how to do it for some common Linux distros -using --run-command, --edit etc. - -(cherry picked from commit 8ae6b6c9ff855f5eaf3f16188b1bcb4ddba095c5) ---- - builder/virt-builder.pod | 40 ++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 40 insertions(+) - -diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod -index f98ffdb..fc6ad40 100644 ---- a/builder/virt-builder.pod -+++ b/builder/virt-builder.pod -@@ -783,6 +783,46 @@ The above command will create an C account with no password, - and force the user to set a password when they first log in. There - are other ways to manage passwords, see L for details. - -+=head2 KEYBOARD LAYOUT -+ -+Because there are so many different ways to set the keyboard layout in -+Linux distributions, virt-builder does not yet attempt to have a -+simple command line option. This section describes how to set the -+keyboard for some common Linux distributions. -+ -+=head3 Keyboard layout with systemd -+ -+For distros that use systemd C, use a command like this: -+ -+ virt-builder fedora-20 \ -+ --firstboot-command 'localectl set-keymap uk' -+ -+See L and -+L -+for more details. -+ -+=head3 Keyboard layout using C -+ -+For RHEL E 6, Fedora E 18 and similar, upload or modify the -+keyboard configuration file using the I<--upload>, I<--write> or -+I<--edit> options. For example: -+ -+ virt-builder centos-6 \ -+ --edit '/etc/sysconfig/keyboard: s/^KEYTABLE=.*/KEYTABLE="uk"/' -+ -+The format of this file can be found documented in many places online. -+ -+=head3 Keyboard layout with Debian-derived distros -+ -+For Debian-derived distros using C, upload or -+modify the keyboard file using the I<--upload>, I<--write> or -+I<--edit> options. For example: -+ -+ virt-builder debian-7 \ -+ --edit '/etc/default/keyboard: s/^XKBLAYOUT=.*/XKBLAYOUT="gb"/' -+ -+See L. -+ - =head2 LOG FILE - - Scripts and package installation that runs at build time (I<--run>, --- -1.8.5.3 - diff --git a/0044-builder-Add-link-option-for-creating-symbolic-links.patch b/0044-builder-Add-link-option-for-creating-symbolic-links.patch deleted file mode 100644 index 7d8efd7..0000000 --- a/0044-builder-Add-link-option-for-creating-symbolic-links.patch +++ /dev/null @@ -1,147 +0,0 @@ -From 16ab6472fb1d78b6e051057d157d7249ea13b08a Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 10 Jan 2014 21:18:07 +0000 -Subject: [PATCH] builder: Add --link option for creating symbolic links. - -This is useful for configuring systemd services. - -(cherry picked from commit 6d4ac696e54902baf7d76de527b3df3d66c7dfa1) ---- - builder/builder.ml | 13 ++++++++++++- - builder/cmdline.ml | 16 +++++++++++++++- - builder/test-virt-builder.sh | 2 ++ - builder/virt-builder.pod | 12 ++++++++++++ - 4 files changed, 41 insertions(+), 2 deletions(-) - -diff --git a/builder/builder.ml b/builder/builder.ml -index daf355c..6105c75 100644 ---- a/builder/builder.ml -+++ b/builder/builder.ml -@@ -39,7 +39,8 @@ let main () = - (* Command line argument parsing - see cmdline.ml. *) - let mode, arg, - attach, cache, check_signature, curl, debug, delete, edit, -- firstboot, run, format, gpg, hostname, install, list_long, memsize, mkdirs, -+ firstboot, run, format, gpg, hostname, install, list_long, links, -+ memsize, mkdirs, - network, output, password_crypto, quiet, root_password, scrub, - scrub_logfile, size, smp, sources, sync, timezone, update, upload, - writes = -@@ -839,6 +840,16 @@ exec >>%s 2>&1 - g#rm_rf file - ) delete; - -+ (* Symbolic links. *) -+ List.iter ( -+ fun (target, links) -> -+ List.iter ( -+ fun link -> -+ msg (f_"Linking: %s -> %s") link target; -+ g#ln_sf target link -+ ) links -+ ) links; -+ - (* Scrub files. *) - List.iter ( - fun file -> -diff --git a/builder/cmdline.ml b/builder/cmdline.ml -index 813fbd8..58e8a6b 100644 ---- a/builder/cmdline.ml -+++ b/builder/cmdline.ml -@@ -117,6 +117,17 @@ let parse_cmdline () = - install := pkgs @ !install - in - -+ let links = ref [] in -+ let add_link arg = -+ let target, lns = -+ match string_nsplit ":" arg with -+ | [] | [_] -> -+ eprintf (f_"%s: invalid --link format, see the man page.\n") prog; -+ exit 1 -+ | target :: lns -> target, lns in -+ links := (target, lns) :: !links -+ in -+ - let list_long = ref false in - - let memsize = ref None in -@@ -237,6 +248,7 @@ let parse_cmdline () = - "--gpg", Arg.Set_string gpg, "gpg" ^ " " ^ s_"Set GPG binary/command"; - "--hostname", Arg.String set_hostname, "hostname" ^ " " ^ s_"Set the hostname"; - "--install", Arg.String add_install, "pkg,pkg" ^ " " ^ s_"Add package(s) to install"; -+ "--link", Arg.String add_link, "target:link.." ^ " " ^ s_"Create symbolic links"; - "-l", Arg.Unit list_mode, " " ^ s_"List available templates"; - "--list", Arg.Unit list_mode, ditto; - "--long", Arg.Set list_long, ditto; -@@ -313,6 +325,7 @@ read the man page virt-builder(1). - let hostname = !hostname in - let install = List.rev !install in - let list_long = !list_long in -+ let links = List.rev !links in - let memsize = !memsize in - let mkdirs = List.rev !mkdirs in - let network = !network in -@@ -425,7 +438,8 @@ read the man page virt-builder(1). - - mode, arg, - attach, cache, check_signature, curl, debug, delete, edit, -- firstboot, run, format, gpg, hostname, install, list_long, memsize, mkdirs, -+ firstboot, run, format, gpg, hostname, install, list_long, links, -+ memsize, mkdirs, - network, output, password_crypto, quiet, root_password, scrub, - scrub_logfile, size, smp, sources, sync, timezone, update, upload, - writes -diff --git a/builder/test-virt-builder.sh b/builder/test-virt-builder.sh -index 8d2766a..47d20a4 100755 ---- a/builder/test-virt-builder.sh -+++ b/builder/test-virt-builder.sh -@@ -60,6 +60,8 @@ $VG ./virt-builder phony-fedora \ - --upload Makefile:/Makefile \ - --upload Makefile:/etc/foo/bar/baz \ - --delete /Makefile \ -+ --link /etc/foo/bar/baz/foo:/foo \ -+ --link /etc/foo/bar/baz/foo:/foo1:/foo2:/foo3 \ - --firstboot Makefile --firstboot-command 'echo "hello"' \ - --firstboot-install "minicom,inkscape" - -diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod -index fc6ad40..0fd865f 100644 ---- a/builder/virt-builder.pod -+++ b/builder/virt-builder.pod -@@ -24,6 +24,7 @@ virt-builder - Build virtual machine images quickly - [--mkdir DIR] - [--write FILE:CONTENT] - [--upload FILE:DEST] -+ [--link TARGET:LINK[:LINK]] - [--edit FILE:EXPR] - [--delete FILE] [--scrub FILE] - [--run SCRIPT] [--run-command 'CMD ARGS ...'] -@@ -353,6 +354,13 @@ L. - - See also I<--update>. - -+=item B<--link TARGET:LINK> -+ -+=item B<--link TARGET:LINK[:LINK...]> -+ -+Create symbolic link(s) in the guest, starting at C and -+pointing at C. -+ - =item B<-l> - - =item B<--list> -@@ -920,6 +928,10 @@ Files are deleted (I<--delete>, I<--scrub>). - - =item * - -+Symbolic links are created (I<--link). -+ -+=item * -+ - Firstboot scripts are installed (I<--firstboot>, - I<--firstboot-command>, I<--firstboot-install>). - --- -1.8.5.3 - diff --git a/0045-builder-Document-how-to-change-the-language-locale-o.patch b/0045-builder-Document-how-to-change-the-language-locale-o.patch deleted file mode 100644 index 7182be9..0000000 --- a/0045-builder-Document-how-to-change-the-language-locale-o.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 1c2e356b705a9586ad3256d54f21b4d871d6852b Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 10 Jan 2014 19:48:28 +0000 -Subject: [PATCH] builder: Document how to change the language/locale of a new - guest. - -(cherry picked from commit 7e8ad13e863a5c87e3da47288bcecdb88ca0e4cb) ---- - builder/virt-builder.pod | 30 ++++++++++++++++++++++++++++++ - 1 file changed, 30 insertions(+) - -diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod -index 0fd865f..4a86fd1 100644 ---- a/builder/virt-builder.pod -+++ b/builder/virt-builder.pod -@@ -831,6 +831,36 @@ I<--edit> options. For example: - - See L. - -+=head2 LANGUAGE -+ -+Most Linux distributions support multiple locale settings so that you -+can have guest messages printed in another language such as Russian. -+However there is no single setting which controls this, since extra -+packages may need to be installed to support console and X fonts and -+keyboard input methods. The packages required, and their -+configuration is highly distro-specific, and it is outside the scope -+of virt-builder to do this. -+ -+=begin comment -+ -+This section contains examples for some common Linux distributions. -+ -+=head3 Setting Japanese in Fedora 20 -+ -+XXX This does not work. -+ -+ virt-builder fedora-20 \ -+ --size 20G \ -+ --update \ -+ --install @gnome-desktop --install @japanese-support \ -+ --firstboot-command 'localectl set-locale LANG=ja_JP.utf8' \ -+ --firstboot-command 'localectl set-keymap jp' \ -+ --firstboot-command 'systemctl enable gdm.service' \ -+ --firstboot-command 'systemctl start gdm.service' \ -+ --link /usr/lib/systemd/system/graphical.target:/etc/systemd/system/default.target -+ -+=end comment -+ - =head2 LOG FILE - - Scripts and package installation that runs at build time (I<--run>, --- -1.8.5.3 - diff --git a/0046-builder-Document-how-to-set-up-local-mirrors-for-per.patch b/0046-builder-Document-how-to-set-up-local-mirrors-for-per.patch deleted file mode 100644 index 7dc6387..0000000 --- a/0046-builder-Document-how-to-set-up-local-mirrors-for-per.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 44f6623b89df42fdfbb7a70532eb70c1e941b6b8 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 10 Jan 2014 19:49:02 +0000 -Subject: [PATCH] builder: Document how to set up local mirrors for performance - and reliability. - -(cherry picked from commit f40e44c2f97a7fa17e6078d958ae2779b7ca83c7) ---- - builder/virt-builder.pod | 52 +++++++++++++++++++++++++++++++++++++++++++++--- - 1 file changed, 49 insertions(+), 3 deletions(-) - -diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod -index 4a86fd1..e539f2d 100644 ---- a/builder/virt-builder.pod -+++ b/builder/virt-builder.pod -@@ -1431,6 +1431,8 @@ The index is always encoded in UTF-8. - - =head2 CACHING - -+=head3 Caching templates -+ - Since the templates are usually very large, downloaded templates are - cached in the user's home directory. - -@@ -1455,11 +1457,55 @@ To disable the template cache, use I<--no-cache>. - Only templates are cached. The index and detached digital signatures - are not cached. - -+=head3 Caching packages -+ - Virt-builder uses L to download files and it also uses the - current C (etc) settings when installing packages --(I<--install>, I<--update>). You may therefore want to set those --environment variables in order to maximize the amount of local caching --that happens. See L and L. -+(I<--install>, I<--update>). -+ -+You may therefore want to set those environment variables in order to -+maximize the amount of local caching that happens. See -+L and L. -+ -+=head3 Local mirrors -+ -+To increase both speed and reliability of installing packages, you can -+set up a local mirror of the target distribution, and point the guest -+package manager at that. -+ -+Because of the order in which each phase of installation happens, you -+cannot use I<--write> (to point the package manager at a repo) -+followed by I<--install> (to install from that repo). The I<--write> -+and I<--install> steps run in the opposite order, regardless of their -+order on the command line. You have to do this using I<--run-command> -+instead of I<--install>. -+ -+=head4 Using a local mirror with Fedora -+ -+To install a Fedora guest using a local mirror: -+ -+ virt-builder fedora 20 \ -+ --edit '/etc/yum.repos.d/fedora.repo: -+ s{.*baseurl=.*}{baseurl=http://example.com/mirror/}; -+ s{.*metalink=.*}{}; -+ ' \ -+ --edit '/etc/yum.repos.d/fedora-updates.repo: -+ s{.*baseurl=.*}{baseurl=http://example.com/mirror-updates/}; -+ s{.*metalink=.*}{}; -+ ' \ -+ --run-command 'yum -y update' \ -+ --run-command 'yum -y install pkg1 pkg2 ...' -+ -+=head4 Using a local mirror with Debian -+ -+Assuming that you are using C to mirror the repository, you -+should create a new C file to point to your proxy (see -+L) and then do: -+ -+ virt-builder fedora 20 \ -+ --upload sources.list:/etc/apt/sources.list \ -+ --run-command 'apt-get -y update' \ -+ --run-command 'apt-get -y install pkg1 pkg2 ...' - - =head2 DIGITAL SIGNATURES - --- -1.8.5.3 - diff --git a/0047-builder-Document-how-to-set-Japanese-language-suppor.patch b/0047-builder-Document-how-to-set-Japanese-language-suppor.patch deleted file mode 100644 index f2c62be..0000000 --- a/0047-builder-Document-how-to-set-Japanese-language-suppor.patch +++ /dev/null @@ -1,59 +0,0 @@ -From ed116cd23b29b50ed12a2e5401d37d74f3f002e4 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sun, 12 Jan 2014 17:06:02 +0000 -Subject: [PATCH] builder: Document how to set Japanese language support in - Fedora 20. - -This updates/fixes commit 7e8ad13e863a5c87e3da47288bcecdb88ca0e4cb. - -(cherry picked from commit fcdea83c6b9dc94a565a819a9f42e0c4721166e8) ---- - builder/virt-builder.pod | 18 +++++++----------- - 1 file changed, 7 insertions(+), 11 deletions(-) - -diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod -index e539f2d..38e26a8 100644 ---- a/builder/virt-builder.pod -+++ b/builder/virt-builder.pod -@@ -835,31 +835,27 @@ See L. - - Most Linux distributions support multiple locale settings so that you - can have guest messages printed in another language such as Russian. -+ - However there is no single setting which controls this, since extra --packages may need to be installed to support console and X fonts and -+packages may need to be installed to support console and X fonts, and - keyboard input methods. The packages required, and their - configuration is highly distro-specific, and it is outside the scope - of virt-builder to do this. - --=begin comment -- - This section contains examples for some common Linux distributions. - - =head3 Setting Japanese in Fedora 20 - --XXX This does not work. -- - virt-builder fedora-20 \ - --size 20G \ - --update \ -- --install @gnome-desktop --install @japanese-support \ -+ --install @japanese-support \ -+ --install @xfce \ -+ --install xorg-x11-server-Xorg,xorg-x11-drivers,rsyslog \ -+ --link /usr/lib/systemd/system/graphical.target:/etc/systemd/system/default.target \ - --firstboot-command 'localectl set-locale LANG=ja_JP.utf8' \ - --firstboot-command 'localectl set-keymap jp' \ -- --firstboot-command 'systemctl enable gdm.service' \ -- --firstboot-command 'systemctl start gdm.service' \ -- --link /usr/lib/systemd/system/graphical.target:/etc/systemd/system/default.target -- --=end comment -+ --firstboot-command 'systemctl isolate graphical.target' - - =head2 LOG FILE - --- -1.8.5.3 - diff --git a/0048-builder-Fix-virt-builder-test.patch b/0048-builder-Fix-virt-builder-test.patch deleted file mode 100644 index 94033d0..0000000 --- a/0048-builder-Fix-virt-builder-test.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 55d1e6272fa9fa96af4ab86d396b97d0b6fba6c5 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sun, 12 Jan 2014 17:49:48 +0000 -Subject: [PATCH] builder: Fix virt-builder test. - -Add Europe/London timezone to phony Fedora guest. - -This fixes commit dd1bfea513658368afd3728e0c5bf8ab6041cd1f. - -(cherry picked from commit 7500ae3f75f4650c18f2a8433c6b5edcca6e88a6) ---- - tests/guests/guest-aux/make-fedora-img.pl | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/tests/guests/guest-aux/make-fedora-img.pl b/tests/guests/guest-aux/make-fedora-img.pl -index 7c96eb8..0537bd2 100755 ---- a/tests/guests/guest-aux/make-fedora-img.pl -+++ b/tests/guests/guest-aux/make-fedora-img.pl -@@ -1,6 +1,6 @@ - #!/usr/bin/perl - # libguestfs --# Copyright (C) 2010-2012 Red Hat Inc. -+# Copyright (C) 2010-2014 Red Hat Inc. - # - # This program is free software; you can redistribute it and/or modify - # it under the terms of the GNU General Public License as published by -@@ -201,6 +201,10 @@ $g->mkdir ('/bin'); - $g->mkdir ('/etc'); - $g->mkdir ('/etc/sysconfig'); - $g->mkdir ('/usr'); -+$g->mkdir ('/usr/share'); -+$g->mkdir ('/usr/share/zoneinfo'); -+$g->mkdir ('/usr/share/zoneinfo/Europe'); -+$g->touch ('/usr/share/zoneinfo/Europe/London'); - $g->mkdir_p ('/var/lib/rpm'); - $g->mkdir_p ('/var/log/journal'); - --- -1.8.5.3 - diff --git a/0049-builder-Document-how-to-set-Japanese-in-Debian-7.patch b/0049-builder-Document-how-to-set-Japanese-in-Debian-7.patch deleted file mode 100644 index 08c253c..0000000 --- a/0049-builder-Document-how-to-set-Japanese-in-Debian-7.patch +++ /dev/null @@ -1,45 +0,0 @@ -From b61c9b9b639e321bf82b21b444fdcf6dacb972b1 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 13 Jan 2014 16:19:51 +0000 -Subject: [PATCH] builder: Document how to set Japanese in Debian 7. - -(cherry picked from commit d885d6f6a97ee119fe1751df6f7d04844bfbf6be) ---- - builder/virt-builder.pod | 21 +++++++++++++++++++++ - 1 file changed, 21 insertions(+) - -diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod -index 38e26a8..ec41078 100644 ---- a/builder/virt-builder.pod -+++ b/builder/virt-builder.pod -@@ -857,6 +857,27 @@ This section contains examples for some common Linux distributions. - --firstboot-command 'localectl set-keymap jp' \ - --firstboot-command 'systemctl isolate graphical.target' - -+=head3 Setting Japanese in Debian 7 (Wheezy) -+ -+Note that although this enables Japanese in the text console too, it -+is unlikely that you will see properly rendered Japanese there. -+However Japanese is properly rendered in X applications and terminals. -+ -+ pkgs=locales,xfce4,\ -+ ibus,ibus-anthy,\ -+ ttf-sazanami-gothic,ttf-sazanami-mincho,\ -+ fonts-takao-mincho,\ -+ xfonts-intl-japanese,xfonts-intl-japanese-big,\ -+ iceweasel-l10n-ja,manpages-ja -+ -+ virt-builder debian-7 \ -+ --size 20G \ -+ --install $pkgs \ -+ --edit '/etc/inittab: s,^#([1-9].*respawn.*/sbin/getty.*),$1,' \ -+ --edit '/etc/locale.gen: s,^#\s*ja,ja,' \ -+ --write '/etc/default/locale:LANG="ja_JP.UTF-8"' \ -+ --run-command "locale-gen" -+ - =head2 LOG FILE - - Scripts and package installation that runs at build time (I<--run>, --- -1.8.5.3 - diff --git a/0050-builder-Add-no-delete-on-failure-option-to-aid-debug.patch b/0050-builder-Add-no-delete-on-failure-option-to-aid-debug.patch deleted file mode 100644 index 57d07c3..0000000 --- a/0050-builder-Add-no-delete-on-failure-option-to-aid-debug.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 0777aa0b2e29f451e15e6e8c40f66112059aa957 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 13 Jan 2014 20:29:50 +0000 -Subject: [PATCH] builder: Add --no-delete-on-failure option to aid debugging. - -This lets you debug failures in virt-builder, especially when scripts -or installing packages fails. - -(cherry picked from commit 5136de98e7f4bd7a967da5b3ede72c729aa7805e) ---- - builder/builder.ml | 9 +++++---- - builder/cmdline.ml | 9 +++++++-- - builder/virt-builder.pod | 17 +++++++++++++++-- - 3 files changed, 27 insertions(+), 8 deletions(-) - -diff --git a/builder/builder.ml b/builder/builder.ml -index 6105c75..79f82a2 100644 ---- a/builder/builder.ml -+++ b/builder/builder.ml -@@ -38,8 +38,8 @@ let () = Random.self_init () - let main () = - (* Command line argument parsing - see cmdline.ml. *) - let mode, arg, -- attach, cache, check_signature, curl, debug, delete, edit, -- firstboot, run, format, gpg, hostname, install, list_long, links, -+ attach, cache, check_signature, curl, debug, delete, delete_on_failure, -+ edit, firstboot, run, format, gpg, hostname, install, list_long, links, - memsize, mkdirs, - network, output, password_crypto, quiet, root_password, scrub, - scrub_logfile, size, smp, sources, sync, timezone, update, upload, -@@ -469,9 +469,10 @@ let main () = - ); - - (* Delete the output file before we finish. However don't delete it -- * if it's block device. -+ * if it's block device, or if --no-delete-on-failure is set. - *) -- let delete_output_file = ref (not output_is_block_dev) in -+ let delete_output_file = -+ ref (delete_on_failure && not output_is_block_dev) in - let delete_file () = - if !delete_output_file then - try unlink output_filename with _ -> () -diff --git a/builder/cmdline.ml b/builder/cmdline.ml -index 58e8a6b..67b142a 100644 ---- a/builder/cmdline.ml -+++ b/builder/cmdline.ml -@@ -72,6 +72,8 @@ let parse_cmdline () = - let delete = ref [] in - let add_delete s = delete := s :: !delete in - -+ let delete_on_failure = ref true in -+ - let edit = ref [] in - let add_edit arg = - let i = -@@ -235,6 +237,8 @@ let parse_cmdline () = - "--delete", Arg.String add_delete, "name" ^ " " ^ s_"Delete a file or dir"; - "--delete-cache", Arg.Unit delete_cache_mode, - " " ^ s_"Delete the template cache"; -+ "--no-delete-on-failure", Arg.Clear delete_on_failure, -+ " " ^ s_"Don't delete output file on failure"; - "--edit", Arg.String add_edit, "file:expr" ^ " " ^ s_"Edit file with Perl expr"; - "--fingerprint", Arg.String add_fingerprint, - "AAAA.." ^ " " ^ s_"Fingerprint of valid signing key"; -@@ -316,6 +320,7 @@ read the man page virt-builder(1). - let curl = !curl in - let debug = !debug in - let delete = List.rev !delete in -+ let delete_on_failure = !delete_on_failure in - let edit = List.rev !edit in - let fingerprints = List.rev !fingerprints in - let firstboot = List.rev !firstboot in -@@ -437,8 +442,8 @@ read the man page virt-builder(1). - List.combine sources fingerprints in - - mode, arg, -- attach, cache, check_signature, curl, debug, delete, edit, -- firstboot, run, format, gpg, hostname, install, list_long, links, -+ attach, cache, check_signature, curl, debug, delete, delete_on_failure, -+ edit, firstboot, run, format, gpg, hostname, install, list_long, links, - memsize, mkdirs, - network, output, password_crypto, quiet, root_password, scrub, - scrub_logfile, size, smp, sources, sync, timezone, update, upload, -diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod -index ec41078..f3ddce5 100644 ---- a/builder/virt-builder.pod -+++ b/builder/virt-builder.pod -@@ -250,6 +250,15 @@ See also: I<--upload>, I<--scrub>. - - Delete the template cache. See L. - -+=item B<--no-delete-on-failure> -+ -+Don't delete the output file on failure to build. You can use this to -+debug failures to run scripts. See L for ways to -+debug images. -+ -+The default is to delete the output file if virt-builder fails (or, -+for example, some script that it runs fails). -+ - =item B<--edit> FILE:EXPR - - Edit C using the Perl expression C. -@@ -1065,8 +1074,12 @@ chosen. It will be C unless the I<--format> option was used. - - =head2 DEBUGGING BUILDS - --If virt-builder fails with an error, then enable debugging (I<-v>) and --report a bug (see L below). -+If virt-builder itself fails, then enable debugging (I<-v>) and report -+a bug (see L below). -+ -+If virt-builder fails because some script or package it is installing -+fails, try using I<--no-delete-on-failure> to preserve the output -+file, and continue reading this section. - - If virt-builder is successful but the image doesn't work, here are - some things to try: --- -1.8.5.3 - diff --git a/0051-builder-For-performance-recommend-using-the-no-sync-.patch b/0051-builder-For-performance-recommend-using-the-no-sync-.patch deleted file mode 100644 index cb50e07..0000000 --- a/0051-builder-For-performance-recommend-using-the-no-sync-.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 806b8e010038335e5cf9a6a57974829741ae374e Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 13 Jan 2014 20:42:48 +0000 -Subject: [PATCH] builder: For performance, recommend using the --no-sync - option. - -(cherry picked from commit 69d9c8515c32dcc67e4ce752215e18eb811f8029) ---- - builder/virt-builder.pod | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod -index f3ddce5..0d9b33f 100644 ---- a/builder/virt-builder.pod -+++ b/builder/virt-builder.pod -@@ -1634,6 +1634,11 @@ downloaded once. You can also try using a local package repository, - although this can be complex to set up and varies according to which - Linux distro you are trying to install. - -+=head3 Using I<--no-sync> -+ -+Use I<--no-sync>. However read the caveats in the L section -+above, since this can cause disk corruption if not used correctly. -+ - =head3 Skipping virt-resize - - Virt-builder can skip the virt-resize step under certain conditions. --- -1.8.5.3 - diff --git a/0052-builder-planner-Whitespace-change.patch b/0052-builder-planner-Whitespace-change.patch deleted file mode 100644 index 7c5a997..0000000 --- a/0052-builder-planner-Whitespace-change.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 91dd1f49d573191a1e9f2d4eabaa5657e3309af7 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 13 Jan 2014 20:58:08 +0000 -Subject: [PATCH] builder: planner: Whitespace change. - -(cherry picked from commit e664739a578f31c3f97073e713f9f33d4eb62d8d) ---- - mllib/planner.ml | 3 ++- - mllib/planner.mli | 3 ++- - 2 files changed, 4 insertions(+), 2 deletions(-) - -diff --git a/mllib/planner.ml b/mllib/planner.ml -index 0121b84..9405dab 100644 ---- a/mllib/planner.ml -+++ b/mllib/planner.ml -@@ -23,7 +23,8 @@ type ('name, 'value) tags = ('name, 'value) tag list - type ('name, 'value, 'task) plan = - (('name, 'value) tags * 'task * ('name, 'value) tags) list - --type ('name, 'value, 'task) transitions_function = ('name, 'value) tags -> ('task * int * ('name, 'value) tags) list -+type ('name, 'value, 'task) transitions_function = -+ ('name, 'value) tags -> ('task * int * ('name, 'value) tags) list - - let plan ?(max_depth = 10) transitions itags (goal_must, goal_must_not) = - (* Do the given output tags match the finish condition? *) -diff --git a/mllib/planner.mli b/mllib/planner.mli -index 8c77acd..7a502fb 100644 ---- a/mllib/planner.mli -+++ b/mllib/planner.mli -@@ -48,7 +48,8 @@ type ('name, 'value) tags = ('name, 'value) tag list - type ('name, 'value, 'task) plan = - (('name, 'value) tags * 'task * ('name, 'value) tags) list - --type ('name, 'value, 'task) transitions_function = ('name, 'value) tags -> ('task * int * ('name, 'value) tags) list -+type ('name, 'value, 'task) transitions_function = -+ ('name, 'value) tags -> ('task * int * ('name, 'value) tags) list - - val plan : ?max_depth:int -> ('name, 'value, 'task) transitions_function -> ('name, 'value) tags -> ('name, 'value) tags * ('name, 'value) tags -> ('name, 'value, 'task) plan - (** Make a plan. --- -1.8.5.3 - diff --git a/0053-daemon-xattr-simplify-the-enabling-of-the-linuxxattr.patch b/0053-daemon-xattr-simplify-the-enabling-of-the-linuxxattr.patch deleted file mode 100644 index 0ba3150..0000000 --- a/0053-daemon-xattr-simplify-the-enabling-of-the-linuxxattr.patch +++ /dev/null @@ -1,142 +0,0 @@ -From 81690922dc99d84720c6a9a8fda7717c958611b7 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Thu, 9 Jan 2014 18:59:19 +0100 -Subject: [PATCH] daemon: xattr: simplify the enabling of the linuxxattrs - features - -Instead of enable them when having one of the two headers for it but -still checking for the HAVE_* availability of each *xattr() function -used, just enable the linuxxattrs as a whole when having any of the -needed headers (like before) and all the needed functions. - -This might cause the linuxxattrs to not be available anymore on systems -without the whole set of *xattr() functions implemented, but OTOH it -simplifies the xattr.c implementations. - -(cherry picked from commit 7630a7bbbdceee8e6aad08511e752f5fcb273416) ---- - daemon/xattr.c | 49 +++++++++++-------------------------------------- - 1 file changed, 11 insertions(+), 38 deletions(-) - -diff --git a/daemon/xattr.c b/daemon/xattr.c -index 7004566..2f642db 100644 ---- a/daemon/xattr.c -+++ b/daemon/xattr.c -@@ -27,7 +27,15 @@ - #include "actions.h" - #include "optgroups.h" - --#if defined(HAVE_ATTR_XATTR_H) || defined(HAVE_SYS_XATTR_H) -+#if (defined(HAVE_ATTR_XATTR_H) || defined(HAVE_SYS_XATTR_H)) && \ -+ defined(HAVE_LISTXATTR) && defined(HAVE_LLISTXATTR) && \ -+ defined(HAVE_GETXATTR) && defined(HAVE_LGETXATTR) && \ -+ defined(HAVE_REMOVEXATTR) && defined(HAVE_LREMOVEXATTR) && \ -+ defined(HAVE_SETXATTR) && defined(HAVE_LSETXATTR) -+# define HAVE_LINUX_XATTRS -+#endif -+ -+#ifdef HAVE_LINUX_XATTRS - - # ifdef HAVE_ATTR_XATTR_H - # include -@@ -50,67 +58,37 @@ static int _removexattr (const char *xattr, const char *path, int (*removexattr) - guestfs_int_xattr_list * - do_getxattrs (const char *path) - { --#if defined(HAVE_LISTXATTR) && defined(HAVE_GETXATTR) - return getxattrs (path, listxattr, getxattr); --#else -- reply_with_error ("no support for listxattr and getxattr"); -- return NULL; --#endif - } - - guestfs_int_xattr_list * - do_lgetxattrs (const char *path) - { --#if defined(HAVE_LLISTXATTR) && defined(HAVE_LGETXATTR) - return getxattrs (path, llistxattr, lgetxattr); --#else -- reply_with_error ("no support for llistxattr and lgetxattr"); -- return NULL; --#endif - } - - int - do_setxattr (const char *xattr, const char *val, int vallen, const char *path) - { --#if defined(HAVE_SETXATTR) - return _setxattr (xattr, val, vallen, path, setxattr); --#else -- reply_with_error ("no support for setxattr"); -- return -1; --#endif - } - - int - do_lsetxattr (const char *xattr, const char *val, int vallen, const char *path) - { --#if defined(HAVE_LSETXATTR) - return _setxattr (xattr, val, vallen, path, lsetxattr); --#else -- reply_with_error ("no support for lsetxattr"); -- return -1; --#endif - } - - int - do_removexattr (const char *xattr, const char *path) - { --#if defined(HAVE_REMOVEXATTR) - return _removexattr (xattr, path, removexattr); --#else -- reply_with_error ("no support for removexattr"); -- return -1; --#endif - } - - int - do_lremovexattr (const char *xattr, const char *path) - { --#if defined(HAVE_LREMOVEXATTR) - return _removexattr (xattr, path, lremovexattr); --#else -- reply_with_error ("no support for lremovexattr"); -- return -1; --#endif - } - - static guestfs_int_xattr_list * -@@ -262,7 +240,6 @@ _removexattr (const char *xattr, const char *path, - guestfs_int_xattr_list * - do_internal_lxattrlist (const char *path, char *const *names) - { --#if defined(HAVE_LLISTXATTR) && defined(HAVE_LGETXATTR) - guestfs_int_xattr_list *ret = NULL; - size_t i, j; - size_t k, m, nr_attrs; -@@ -425,10 +402,6 @@ do_internal_lxattrlist (const char *path, char *const *names) - free (ret); - } - return NULL; --#else -- reply_with_error ("no support for llistxattr and lgetxattr"); -- return NULL; --#endif - } - - char * -@@ -527,8 +500,8 @@ do_lgetxattr (const char *path, const char *name, size_t *size_r) - return buf; /* caller frees */ - } - --#else /* no xattr.h */ -+#else /* no HAVE_LINUX_XATTRS */ - - OPTGROUP_LINUXXATTRS_NOT_AVAILABLE - --#endif /* no xattr.h */ -+#endif /* no HAVE_LINUX_XATTRS */ --- -1.8.5.3 - diff --git a/0054-daemon-xattr-move-the-listxattrs-code-in-an-own-func.patch b/0054-daemon-xattr-move-the-listxattrs-code-in-an-own-func.patch deleted file mode 100644 index 7b1f0e7..0000000 --- a/0054-daemon-xattr-move-the-listxattrs-code-in-an-own-func.patch +++ /dev/null @@ -1,108 +0,0 @@ -From 44cd429c03d283237f718c6dab96dc9f3279d95c Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Fri, 10 Jan 2014 15:10:03 +0100 -Subject: [PATCH] daemon: xattr: move the listxattrs code in an own function - -Move in an own function the code that does the (l)listxattrs allocating -the buffer of the right legth, as it will be useful later. - -No functional changes, just code motion. - -(cherry picked from commit 59d8cf62cb67688cea42a985029adea874f0b7a2) ---- - daemon/xattr.c | 64 ++++++++++++++++++++++++++++++++++++++++------------------ - 1 file changed, 44 insertions(+), 20 deletions(-) - -diff --git a/daemon/xattr.c b/daemon/xattr.c -index 2f642db..768f780 100644 ---- a/daemon/xattr.c -+++ b/daemon/xattr.c -@@ -54,6 +54,7 @@ optgroup_linuxxattrs_available (void) - static guestfs_int_xattr_list *getxattrs (const char *path, ssize_t (*listxattr) (const char *path, char *list, size_t size), ssize_t (*getxattr) (const char *path, const char *name, void *value, size_t size)); - static int _setxattr (const char *xattr, const char *val, int vallen, const char *path, int (*setxattr) (const char *path, const char *name, const void *value, size_t size, int flags)); - static int _removexattr (const char *xattr, const char *path, int (*removexattr) (const char *path, const char *name)); -+static char *_listxattrs (const char *path, ssize_t (*listxattr) (const char *path, char *list, size_t size), ssize_t *size); - - guestfs_int_xattr_list * - do_getxattrs (const char *path) -@@ -102,27 +103,10 @@ getxattrs (const char *path, - size_t i, j; - guestfs_int_xattr_list *r = NULL; - -- CHROOT_IN; -- len = listxattr (path, NULL, 0); -- CHROOT_OUT; -- if (len == -1) { -- reply_with_perror ("listxattr: %s", path); -+ buf = _listxattrs (path, listxattr, &len); -+ if (buf == NULL) -+ /* _listxattrs issues reply_with_perror already. */ - goto error; -- } -- -- buf = malloc (len); -- if (buf == NULL) { -- reply_with_perror ("malloc"); -- goto error; -- } -- -- CHROOT_IN; -- len = listxattr (path, buf, len); -- CHROOT_OUT; -- if (len == -1) { -- reply_with_perror ("listxattr: %s", path); -- goto error; -- } - - r = calloc (1, sizeof (*r)); - if (r == NULL) { -@@ -237,6 +221,46 @@ _removexattr (const char *xattr, const char *path, - return 0; - } - -+static char * -+_listxattrs (const char *path, -+ ssize_t (*listxattr) (const char *path, char *list, size_t size), -+ ssize_t *size) -+{ -+ int r; -+ char *buf = NULL; -+ ssize_t len; -+ -+ CHROOT_IN; -+ len = listxattr (path, NULL, 0); -+ CHROOT_OUT; -+ if (len == -1) { -+ reply_with_perror ("listxattr: %s", path); -+ goto error; -+ } -+ -+ buf = malloc (len); -+ if (buf == NULL) { -+ reply_with_perror ("malloc"); -+ goto error; -+ } -+ -+ CHROOT_IN; -+ len = listxattr (path, buf, len); -+ CHROOT_OUT; -+ if (len == -1) { -+ reply_with_perror ("listxattr: %s", path); -+ goto error; -+ } -+ -+ if (size) -+ *size = len; -+ return buf; -+ -+ error: -+ free (buf); -+ return NULL; -+} -+ - guestfs_int_xattr_list * - do_internal_lxattrlist (const char *path, char *const *names) - { --- -1.8.5.3 - diff --git a/0055-daemon-xattr-Remove-unused-variable.patch b/0055-daemon-xattr-Remove-unused-variable.patch deleted file mode 100644 index f149dd5..0000000 --- a/0055-daemon-xattr-Remove-unused-variable.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0cd83538f5e334f3c424dfefdee026bc190e0c07 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 10 Jan 2014 21:19:43 +0000 -Subject: [PATCH] daemon: xattr: Remove unused variable. - -Revealed by using ./configure --enable-gcc-warnings. - -(cherry picked from commit cea270de3be3ca3c2b2e6555418c4b4eb8da7509) ---- - daemon/xattr.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/daemon/xattr.c b/daemon/xattr.c -index 768f780..dc024d3 100644 ---- a/daemon/xattr.c -+++ b/daemon/xattr.c -@@ -226,7 +226,6 @@ _listxattrs (const char *path, - ssize_t (*listxattr) (const char *path, char *list, size_t size), - ssize_t *size) - { -- int r; - char *buf = NULL; - ssize_t len; - --- -1.8.5.3 - diff --git a/0056-New-API-copy-attributes.patch b/0056-New-API-copy-attributes.patch deleted file mode 100644 index e4fdb25..0000000 --- a/0056-New-API-copy-attributes.patch +++ /dev/null @@ -1,437 +0,0 @@ -From 018ddf720665c8f7ddf6b4bba927939d075f6237 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Mon, 13 Jan 2014 14:41:28 +0100 -Subject: [PATCH] New API: copy-attributes. - -This allows one to copy attributes (like permissions, xattrs, -ownership) from a file to another. - -(cherry picked from commit efb5f1841524ec75d765368b447270b8a3aff8ac) ---- - daemon/daemon.h | 3 + - daemon/file.c | 72 ++++++++++++++++++++++ - daemon/xattr.c | 69 +++++++++++++++++++++ - fish/Makefile.am | 1 + - fish/test-file-attrs.sh | 157 ++++++++++++++++++++++++++++++++++++++++++++++++ - generator/actions.ml | 38 ++++++++++++ - src/MAX_PROC_NR | 2 +- - 7 files changed, 341 insertions(+), 1 deletion(-) - create mode 100755 fish/test-file-attrs.sh - -diff --git a/daemon/daemon.h b/daemon/daemon.h -index b77d764..6535658 100644 ---- a/daemon/daemon.h -+++ b/daemon/daemon.h -@@ -231,6 +231,9 @@ extern void journal_finalize (void); - /*-- in proto.c --*/ - extern void main_loop (int sock) __attribute__((noreturn)); - -+/*-- in xattr.c --*/ -+extern int copy_xattrs (const char *src, const char *dest); -+ - /* ordinary daemon functions use these to indicate errors - * NB: you don't need to prefix the string with the current command, - * it is added automatically by the client-side RPC stubs. -diff --git a/daemon/file.c b/daemon/file.c -index f348f87..856ab5f 100644 ---- a/daemon/file.c -+++ b/daemon/file.c -@@ -28,6 +28,7 @@ - #include "guestfs_protocol.h" - #include "daemon.h" - #include "actions.h" -+#include "optgroups.h" - - GUESTFSD_EXT_CMD(str_file, file); - GUESTFSD_EXT_CMD(str_zcat, zcat); -@@ -584,3 +585,74 @@ do_filesize (const char *path) - - return buf.st_size; - } -+ -+int -+do_copy_attributes (const char *src, const char *dest, int all, int mode, int xattributes, int ownership) -+{ -+ int r; -+ struct stat srcstat, deststat; -+ -+ static const unsigned int file_mask = 07777; -+ -+ /* If it was specified to copy everything, manually enable all the flags -+ * not manually specified to avoid checking for flag || all everytime. -+ */ -+ if (all) { -+ if (!(optargs_bitmask & GUESTFS_COPY_ATTRIBUTES_MODE_BITMASK)) -+ mode = 1; -+ if (!(optargs_bitmask & GUESTFS_COPY_ATTRIBUTES_XATTRIBUTES_BITMASK)) -+ xattributes = 1; -+ if (!(optargs_bitmask & GUESTFS_COPY_ATTRIBUTES_OWNERSHIP_BITMASK)) -+ ownership = 1; -+ } -+ -+ CHROOT_IN; -+ r = stat (src, &srcstat); -+ CHROOT_OUT; -+ -+ if (r == -1) { -+ reply_with_perror ("stat: %s", src); -+ return -1; -+ } -+ -+ CHROOT_IN; -+ r = stat (dest, &deststat); -+ CHROOT_OUT; -+ -+ if (r == -1) { -+ reply_with_perror ("stat: %s", dest); -+ return -1; -+ } -+ -+ if (mode && -+ ((srcstat.st_mode & file_mask) != (deststat.st_mode & file_mask))) { -+ CHROOT_IN; -+ r = chmod (dest, (srcstat.st_mode & file_mask)); -+ CHROOT_OUT; -+ -+ if (r == -1) { -+ reply_with_perror ("chmod: %s", dest); -+ return -1; -+ } -+ } -+ -+ if (ownership && -+ (srcstat.st_uid != deststat.st_uid || srcstat.st_gid != deststat.st_gid)) { -+ CHROOT_IN; -+ r = chown (dest, srcstat.st_uid, srcstat.st_gid); -+ CHROOT_OUT; -+ -+ if (r == -1) { -+ reply_with_perror ("chown: %s", dest); -+ return -1; -+ } -+ } -+ -+ if (xattributes && optgroup_linuxxattrs_available ()) { -+ if (!copy_xattrs (src, dest)) -+ /* copy_xattrs replies with an error already. */ -+ return -1; -+ } -+ -+ return 0; -+} -diff --git a/daemon/xattr.c b/daemon/xattr.c -index dc024d3..fdc43b3 100644 ---- a/daemon/xattr.c -+++ b/daemon/xattr.c -@@ -523,8 +523,77 @@ do_lgetxattr (const char *path, const char *name, size_t *size_r) - return buf; /* caller frees */ - } - -+int -+copy_xattrs (const char *src, const char *dest) -+{ -+ ssize_t len, vlen, ret, attrval_len = 0; -+ CLEANUP_FREE char *buf = NULL, *attrval = NULL; -+ size_t i; -+ -+ buf = _listxattrs (src, listxattr, &len); -+ if (buf == NULL) -+ /* _listxattrs issues reply_with_perror already. */ -+ goto error; -+ -+ /* What we get from the kernel is a string "foo\0bar\0baz" of length -+ * len. -+ */ -+ for (i = 0; i < (size_t) len; i += strlen (&buf[i]) + 1) { -+ CHROOT_IN; -+ vlen = getxattr (src, &buf[i], NULL, 0); -+ CHROOT_OUT; -+ if (vlen == -1) { -+ reply_with_perror ("getxattr: %s, %s", src, &buf[i]); -+ goto error; -+ } -+ -+ if (vlen > XATTR_SIZE_MAX) { -+ /* The next call to getxattr will fail anyway, so ... */ -+ reply_with_error ("extended attribute is too large"); -+ goto error; -+ } -+ -+ if (vlen > attrval_len) { -+ char *new = realloc (attrval, vlen); -+ if (new == NULL) { -+ reply_with_perror ("realloc"); -+ goto error; -+ } -+ attrval = new; -+ attrval_len = vlen; -+ } -+ -+ CHROOT_IN; -+ vlen = getxattr (src, &buf[i], attrval, vlen); -+ CHROOT_OUT; -+ if (vlen == -1) { -+ reply_with_perror ("getxattr: %s, %s", src, &buf[i]); -+ goto error; -+ } -+ -+ CHROOT_IN; -+ ret = setxattr (dest, &buf[i], attrval, vlen, 0); -+ CHROOT_OUT; -+ if (ret == -1) { -+ reply_with_perror ("setxattr: %s, %s", dest, &buf[i]); -+ goto error; -+ } -+ } -+ -+ return 1; -+ -+ error: -+ return 0; -+} -+ - #else /* no HAVE_LINUX_XATTRS */ - - OPTGROUP_LINUXXATTRS_NOT_AVAILABLE - -+int -+copy_xattrs (const char *src, const char *dest) -+{ -+ abort (); -+} -+ - #endif /* no HAVE_LINUX_XATTRS */ -diff --git a/fish/Makefile.am b/fish/Makefile.am -index bd0485f..fb0e99e 100644 ---- a/fish/Makefile.am -+++ b/fish/Makefile.am -@@ -279,6 +279,7 @@ if ENABLE_APPLIANCE - TESTS += \ - test-copy.sh \ - test-edit.sh \ -+ test-file-attrs.sh \ - test-find0.sh \ - test-inspect.sh \ - test-glob.sh \ -diff --git a/fish/test-file-attrs.sh b/fish/test-file-attrs.sh -new file mode 100755 -index 0000000..78bd817 ---- /dev/null -+++ b/fish/test-file-attrs.sh -@@ -0,0 +1,157 @@ -+#!/bin/bash - -+# libguestfs -+# Copyright (C) 2014 Red Hat Inc. -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program 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 General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; if not, write to the Free Software -+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ -+# Test guestfish file attributes commands (chmod, copy-attributes, etc). -+ -+set -e -+export LANG=C -+ -+rm -f test.out -+ -+$VG ./guestfish > test.out < -Date: Mon, 13 Jan 2014 22:10:39 +0000 -Subject: [PATCH] fish: Add test-file-attrs.sh to EXTRA_DIST. - -This fixes commit efb5f1841524ec75d765368b447270b8a3aff8ac. - -(cherry picked from commit aba64a0327094b6a82686411c4dfa7a30d64ecee) ---- - fish/Makefile.am | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/fish/Makefile.am b/fish/Makefile.am -index fb0e99e..54ba875 100644 ---- a/fish/Makefile.am -+++ b/fish/Makefile.am -@@ -306,6 +306,7 @@ EXTRA_DIST += \ - test-edit.sh \ - test-escapes.sh \ - test-events.sh \ -+ test-file-attrs.sh \ - test-find0.sh \ - test-glob.sh \ - test-inspect.sh \ --- -1.8.5.3 - diff --git a/0058-builder-edit-fish-use-copy-attributes.patch b/0058-builder-edit-fish-use-copy-attributes.patch deleted file mode 100644 index 867d9c8..0000000 --- a/0058-builder-edit-fish-use-copy-attributes.patch +++ /dev/null @@ -1,212 +0,0 @@ -From a8dc88c71d65fe34843a6fa2770055806a155140 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Tue, 14 Jan 2014 11:08:25 +0100 -Subject: [PATCH] builder, edit, fish: use copy-attributes - -Make use of the new copy-attributes command to properly copy all file -attributes from a file to the new version of it. - -(cherry picked from commit b7bb1f6cee19da143996c13e6cc019a039f3ee4f) ---- - edit/edit.c | 49 ++----------------------------------------------- - fish/edit.c | 54 ++---------------------------------------------------- - mllib/perl_edit.ml | 29 +---------------------------- - 3 files changed, 5 insertions(+), 127 deletions(-) - -diff --git a/edit/edit.c b/edit/edit.c -index e5e3a29..07790be 100644 ---- a/edit/edit.c -+++ b/edit/edit.c -@@ -56,7 +56,6 @@ static void edit_files (int argc, char *argv[]); - static void edit (const char *filename, const char *root); - static char *edit_interactively (const char *tmpfile); - static char *edit_non_interactively (const char *tmpfile); --static int copy_attributes (const char *src, const char *dest); - static int is_windows (guestfs_h *g, const char *root); - static char *windows_path (guestfs_h *g, const char *root, const char *filename); - static char *generate_random_name (const char *filename); -@@ -361,7 +360,8 @@ edit (const char *filename, const char *root) - /* Set the permissions, UID, GID and SELinux context of the new - * file to match the old file (RHBZ#788641). - */ -- if (copy_attributes (filename, newname) == -1) -+ if (guestfs_copy_attributes (g, filename, newname, -+ GUESTFS_COPY_ATTRIBUTES_ALL, 1, -1) == -1) - goto error; - - /* Backup or overwrite the file. */ -@@ -510,51 +510,6 @@ edit_non_interactively (const char *tmpfile) - } - - static int --copy_attributes (const char *src, const char *dest) --{ -- CLEANUP_FREE_STAT struct guestfs_stat *stat = NULL; -- const char *linuxxattrs[] = { "linuxxattrs", NULL }; -- int has_linuxxattrs; -- CLEANUP_FREE char *selinux_context = NULL; -- size_t selinux_context_size; -- -- has_linuxxattrs = guestfs_feature_available (g, (char **) linuxxattrs); -- -- /* Get the mode. */ -- stat = guestfs_stat (g, src); -- if (stat == NULL) -- return -1; -- -- /* Get the SELinux context. XXX Should we copy over other extended -- * attributes too? -- */ -- if (has_linuxxattrs) { -- guestfs_push_error_handler (g, NULL, NULL); -- -- selinux_context = guestfs_getxattr (g, src, "security.selinux", -- &selinux_context_size); -- /* selinux_context could be NULL. This isn't an error. */ -- -- guestfs_pop_error_handler (g); -- } -- -- /* Set the permissions (inc. sticky and set*id bits), UID, GID. */ -- if (guestfs_chmod (g, stat->mode & 07777, dest) == -1) -- return -1; -- if (guestfs_chown (g, stat->uid, stat->gid, dest) == -1) -- return -1; -- -- /* Set the SELinux context. */ -- if (has_linuxxattrs && selinux_context) { -- if (guestfs_setxattr (g, "security.selinux", selinux_context, -- (int) selinux_context_size, dest) == -1) -- return -1; -- } -- -- return 0; --} -- --static int - is_windows (guestfs_h *g, const char *root) - { - int w; -diff --git a/fish/edit.c b/fish/edit.c -index 754a34a..bd02f4b 100644 ---- a/fish/edit.c -+++ b/fish/edit.c -@@ -32,7 +32,6 @@ - #include "fish.h" - - static char *generate_random_name (const char *filename); --static int copy_attributes (const char *src, const char *dest); - - /* guestfish edit command, suggested by Ján Ondrej, implemented by RWMJ */ - -@@ -135,7 +134,8 @@ run_edit (const char *cmd, size_t argc, char *argv[]) - /* Set the permissions, UID, GID and SELinux context of the new - * file to match the old file (RHBZ#788641). - */ -- if (copy_attributes (remotefilename, newname) == -1) -+ if (guestfs_copy_attributes (g, remotefilename, newname, -+ GUESTFS_COPY_ATTRIBUTES_ALL, 1, -1) == -1) - return -1; - - if (guestfs_mv (g, newname, remotefilename) == -1) -@@ -177,53 +177,3 @@ generate_random_name (const char *filename) - - return ret; /* caller will free */ - } -- --static int --copy_attributes (const char *src, const char *dest) --{ -- struct guestfs_stat *stat; -- const char *linuxxattrs[] = { "linuxxattrs", NULL }; -- int has_linuxxattrs; -- CLEANUP_FREE char *selinux_context = NULL; -- size_t selinux_context_size; -- -- has_linuxxattrs = guestfs_feature_available (g, (char **) linuxxattrs); -- -- /* Get the mode. */ -- stat = guestfs_stat (g, src); -- if (stat == NULL) -- return -1; -- -- /* Get the SELinux context. XXX Should we copy over other extended -- * attributes too? -- */ -- if (has_linuxxattrs) { -- guestfs_push_error_handler (g, NULL, NULL); -- -- selinux_context = guestfs_getxattr (g, src, "security.selinux", -- &selinux_context_size); -- /* selinux_context could be NULL. This isn't an error. */ -- -- guestfs_pop_error_handler (g); -- } -- -- /* Set the permissions (inc. sticky and set*id bits), UID, GID. */ -- if (guestfs_chmod (g, stat->mode & 07777, dest) == -1) { -- guestfs_free_stat (stat); -- return -1; -- } -- if (guestfs_chown (g, stat->uid, stat->gid, dest) == -1) { -- guestfs_free_stat (stat); -- return -1; -- } -- guestfs_free_stat (stat); -- -- /* Set the SELinux context. */ -- if (has_linuxxattrs && selinux_context) { -- if (guestfs_setxattr (g, "security.selinux", selinux_context, -- (int) selinux_context_size, dest) == -1) -- return -1; -- } -- -- return 0; --} -diff --git a/mllib/perl_edit.ml b/mllib/perl_edit.ml -index aa4c2e6..28e5dea 100644 ---- a/mllib/perl_edit.ml -+++ b/mllib/perl_edit.ml -@@ -42,7 +42,7 @@ let rec edit_file ~debug (g : Guestfs.guestfs) file expr = - g#upload tmpfile file; - - (* However like virt-edit we do need to copy attributes. *) -- copy_attributes g file_old file; -+ g#copy_attributes ~all:true file_old file; - g#rm file_old - - and do_perl_edit ~debug g file expr = -@@ -76,30 +76,3 @@ and do_perl_edit ~debug g file expr = - ); - - Unix.rename (file ^ ".out") file -- --and copy_attributes g src dest = -- let has_linuxxattrs = g#feature_available [|"linuxxattrs"|] in -- -- (* Get the mode. *) -- let stat = g#stat src in -- -- (* Get the SELinux context. XXX Should we copy over other extended -- * attributes too? -- *) -- let selinux_context = -- if has_linuxxattrs then ( -- try Some (g#getxattr src "security.selinux") with _ -> None -- ) else None in -- -- (* Set the permissions (inc. sticky and set*id bits), UID, GID. *) -- let mode = Int64.to_int stat.G.mode -- and uid = Int64.to_int stat.G.uid and gid = Int64.to_int stat.G.gid in -- g#chmod (mode land 0o7777) dest; -- g#chown uid gid dest; -- -- (* Set the SELinux context. *) -- match selinux_context with -- | None -> () -- | Some selinux_context -> -- g#setxattr "security.selinux" -- selinux_context (String.length selinux_context) dest --- -1.8.5.3 - diff --git a/0059-builder-test-virt-builder-check-some-results.patch b/0059-builder-test-virt-builder-check-some-results.patch deleted file mode 100644 index 91f7dc2..0000000 --- a/0059-builder-test-virt-builder-check-some-results.patch +++ /dev/null @@ -1,73 +0,0 @@ -From a859445b8842a3a3d8ecd52e3fa30e08628812dd Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Tue, 14 Jan 2014 13:30:19 +0100 -Subject: [PATCH] builder: test-virt-builder: check some results - -Check at least some basic modifications in the image created with -virt-builder. - -(cherry picked from commit 775c6daf22884edad8ede4b0916024d3d7c04585) ---- - builder/test-virt-builder.sh | 47 +++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 46 insertions(+), 1 deletion(-) - -diff --git a/builder/test-virt-builder.sh b/builder/test-virt-builder.sh -index 47d20a4..3c8eb60 100755 ---- a/builder/test-virt-builder.sh -+++ b/builder/test-virt-builder.sh -@@ -65,6 +65,51 @@ $VG ./virt-builder phony-fedora \ - --firstboot Makefile --firstboot-command 'echo "hello"' \ - --firstboot-install "minicom,inkscape" - --# XXX Test that the modifications were made. -+# Check that some modifications were made. -+$VG ../fish/guestfish --ro -i -a $output > test.out < -Date: Thu, 16 Jan 2014 11:49:05 +0100 -Subject: [PATCH] builder: small refactor of the list output - -Switch from a boolean for the short/long list output to labels for the -actual format. Also, split the output of each list format to an own -function for easier maintaineance. - -(cherry picked from commit 91aae893c70b3877b31803800ba77836fd7a45e8) ---- - builder/builder.ml | 4 +-- - builder/cmdline.ml | 9 +++--- - builder/list_entries.ml | 82 +++++++++++++++++++++++++++--------------------- - builder/list_entries.mli | 2 +- - 4 files changed, 54 insertions(+), 43 deletions(-) - -diff --git a/builder/builder.ml b/builder/builder.ml -index 79f82a2..7e1c614 100644 ---- a/builder/builder.ml -+++ b/builder/builder.ml -@@ -39,7 +39,7 @@ let main () = - (* Command line argument parsing - see cmdline.ml. *) - let mode, arg, - attach, cache, check_signature, curl, debug, delete, delete_on_failure, -- edit, firstboot, run, format, gpg, hostname, install, list_long, links, -+ edit, firstboot, run, format, gpg, hostname, install, list_format, links, - memsize, mkdirs, - network, output, password_crypto, quiet, root_password, scrub, - scrub_logfile, size, smp, sources, sync, timezone, update, upload, -@@ -150,7 +150,7 @@ let main () = - let mode = - match mode with - | `List -> (* --list *) -- List_entries.list_entries ~list_long ~sources index; -+ List_entries.list_entries ~list_format ~sources index; - exit 0 - - | `Print_cache -> (* --print-cache *) -diff --git a/builder/cmdline.ml b/builder/cmdline.ml -index 67b142a..f199f03 100644 ---- a/builder/cmdline.ml -+++ b/builder/cmdline.ml -@@ -130,7 +130,8 @@ let parse_cmdline () = - links := (target, lns) :: !links - in - -- let list_long = ref false in -+ let list_format = ref `Short in -+ let list_set_long () = list_format := `Long in - - let memsize = ref None in - let set_memsize arg = memsize := Some arg in -@@ -255,7 +256,7 @@ let parse_cmdline () = - "--link", Arg.String add_link, "target:link.." ^ " " ^ s_"Create symbolic links"; - "-l", Arg.Unit list_mode, " " ^ s_"List available templates"; - "--list", Arg.Unit list_mode, ditto; -- "--long", Arg.Set list_long, ditto; -+ "--long", Arg.Unit list_set_long, " " ^ s_"List available templates, in long textual form"; - "--no-logfile", Arg.Set scrub_logfile, " " ^ s_"Scrub build log file"; - "--long-options", Arg.Unit display_long_options, " " ^ s_"List long options"; - "-m", Arg.Int set_memsize, "mb" ^ " " ^ s_"Set memory size"; -@@ -329,7 +330,7 @@ read the man page virt-builder(1). - let gpg = !gpg in - let hostname = !hostname in - let install = List.rev !install in -- let list_long = !list_long in -+ let list_format = !list_format in - let links = List.rev !links in - let memsize = !memsize in - let mkdirs = List.rev !mkdirs in -@@ -443,7 +444,7 @@ read the man page virt-builder(1). - - mode, arg, - attach, cache, check_signature, curl, debug, delete, delete_on_failure, -- edit, firstboot, run, format, gpg, hostname, install, list_long, links, -+ edit, firstboot, run, format, gpg, hostname, install, list_format, links, - memsize, mkdirs, - network, output, password_crypto, quiet, root_password, scrub, - scrub_logfile, size, smp, sources, sync, timezone, update, upload, -diff --git a/builder/list_entries.ml b/builder/list_entries.ml -index 87001c0..97ab201 100644 ---- a/builder/list_entries.ml -+++ b/builder/list_entries.ml -@@ -21,15 +21,35 @@ open Common_utils - - open Printf - --let list_entries ?(list_long = false) ~sources index = -- if list_long then ( -- List.iter ( -- fun (source, fingerprint) -> -- printf (f_"Source URI: %s\n") source; -- printf (f_"Fingerprint: %s\n") fingerprint; -+let rec list_entries ~list_format ~sources index = -+ match list_format with -+ | `Short -> list_entries_short index -+ | `Long -> list_entries_long ~sources index -+ -+and list_entries_short index = -+ List.iter ( -+ fun (name, { Index_parser.printable_name = printable_name; -+ size = size; -+ compressed_size = compressed_size; -+ notes = notes; -+ hidden = hidden }) -> -+ if not hidden then ( -+ printf "%-24s" name; -+ (match printable_name with -+ | None -> () -+ | Some s -> printf " %s" s -+ ); - printf "\n" -- ) sources -- ); -+ ) -+ ) index -+ -+and list_entries_long ~sources index = -+ List.iter ( -+ fun (source, fingerprint) -> -+ printf (f_"Source URI: %s\n") source; -+ printf (f_"Fingerprint: %s\n") fingerprint; -+ printf "\n" -+ ) sources; - - List.iter ( - fun (name, { Index_parser.printable_name = printable_name; -@@ -38,33 +58,23 @@ let list_entries ?(list_long = false) ~sources index = - notes = notes; - hidden = hidden }) -> - if not hidden then ( -- if not list_long then ( (* Short *) -- printf "%-24s" name; -- (match printable_name with -- | None -> () -- | Some s -> printf " %s" s -- ); -- printf "\n" -- ) -- else ( (* Long *) -- printf "%-24s %s\n" "os-version:" name; -- (match printable_name with -- | None -> () -- | Some name -> printf "%-24s %s\n" (s_"Full name:") name; -- ); -- printf "%-24s %s\n" (s_"Minimum/default size:") (human_size size); -- (match compressed_size with -- | None -> () -- | Some size -> -- printf "%-24s %s\n" (s_"Download size:") (human_size size); -- ); -- (match notes with -- | None -> () -- | Some notes -> -- printf "\n"; -- printf (f_"Notes:\n\n%s\n") notes -- ); -- printf "\n" -- ) -+ printf "%-24s %s\n" "os-version:" name; -+ (match printable_name with -+ | None -> () -+ | Some name -> printf "%-24s %s\n" (s_"Full name:") name; -+ ); -+ printf "%-24s %s\n" (s_"Minimum/default size:") (human_size size); -+ (match compressed_size with -+ | None -> () -+ | Some size -> -+ printf "%-24s %s\n" (s_"Download size:") (human_size size); -+ ); -+ (match notes with -+ | None -> () -+ | Some notes -> -+ printf "\n"; -+ printf (f_"Notes:\n\n%s\n") notes -+ ); -+ printf "\n" - ) - ) index -diff --git a/builder/list_entries.mli b/builder/list_entries.mli -index d9486b0..41d0bff 100644 ---- a/builder/list_entries.mli -+++ b/builder/list_entries.mli -@@ -16,4 +16,4 @@ - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - *) - --val list_entries : ?list_long:bool -> sources:(string * string) list -> Index_parser.index -> unit -+val list_entries : list_format:([ `Short | `Long ]) -> sources:(string * string) list -> Index_parser.index -> unit --- -1.8.5.3 - diff --git a/0061-builder-add-list-format.patch b/0061-builder-add-list-format.patch deleted file mode 100644 index d38e894..0000000 --- a/0061-builder-add-list-format.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 9a636393a6f1e5444e9e4f74468f64161d19732e Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Thu, 16 Jan 2014 12:34:48 +0100 -Subject: [PATCH] builder: add --list-format - -Add a --list-format which allows to choose which in format should be the -output of --list. - -(cherry picked from commit e45bfe0d36c9f50143b13921a498f00ee06ca27d) ---- - builder/cmdline.ml | 11 ++++++++++- - builder/virt-builder.pod | 24 +++++++++++++++++++++--- - 2 files changed, 31 insertions(+), 4 deletions(-) - -diff --git a/builder/cmdline.ml b/builder/cmdline.ml -index f199f03..6d6439f 100644 ---- a/builder/cmdline.ml -+++ b/builder/cmdline.ml -@@ -132,6 +132,13 @@ let parse_cmdline () = - - let list_format = ref `Short in - let list_set_long () = list_format := `Long in -+ let list_set_format arg = -+ list_format := match arg with -+ | "short" -> `Short -+ | "long" -> `Long -+ | fmt -> -+ eprintf (f_"%s: invalid --list-format type '%s', see the man page.\n") prog fmt; -+ exit 1 in - - let memsize = ref None in - let set_memsize arg = memsize := Some arg in -@@ -256,7 +263,9 @@ let parse_cmdline () = - "--link", Arg.String add_link, "target:link.." ^ " " ^ s_"Create symbolic links"; - "-l", Arg.Unit list_mode, " " ^ s_"List available templates"; - "--list", Arg.Unit list_mode, ditto; -- "--long", Arg.Unit list_set_long, " " ^ s_"List available templates, in long textual form"; -+ "--long", Arg.Unit list_set_long, " " ^ s_"Shortcut for --list-format short"; -+ "--list-format", Arg.String list_set_format, -+ "short|long" ^ " " ^ s_"Set the format for --list (default: short)"; - "--no-logfile", Arg.Set scrub_logfile, " " ^ s_"Scrub build log file"; - "--long-options", Arg.Unit display_long_options, " " ^ s_"List long options"; - "-m", Arg.Int set_memsize, "mb" ^ " " ^ s_"Set memory size"; -diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod -index 0d9b33f..8e60d30 100644 ---- a/builder/virt-builder.pod -+++ b/builder/virt-builder.pod -@@ -31,7 +31,7 @@ virt-builder - Build virtual machine images quickly - [--firstboot SCRIPT] [--firstboot-command 'CMD ARGS ...'] - [--firstboot-install PKG,[PKG...]] - -- virt-builder -l|--list [--long] -+ virt-builder -l|--list [--long] [--list-format short|long] - - virt-builder --notes os-version - -@@ -374,12 +374,30 @@ pointing at C. - - =item B<--list> - -+=item B<--list --format> format -+ - =item B<--list --long> - - List available templates. - --The alternative I<--list --long> form shows lots more details about --each operating system option. -+It is possible to choose with I<--format> the output format for the list -+templates: -+ -+=over 4 -+ -+=item B -+ -+The default format, prints only the template identifier and, next to it, -+its short description. -+ -+=item B -+ -+Prints a textual list with the details of the available sources, followed -+by the details of the available templates. -+ -+=back -+ -+I<--long> is a shorthand for the C format. - - See also: I<--source>, I<--notes>, L. - --- -1.8.5.3 - diff --git a/0062-builder-add-a-JSON-output-for-list.patch b/0062-builder-add-a-JSON-output-for-list.patch deleted file mode 100644 index af42c17..0000000 --- a/0062-builder-add-a-JSON-output-for-list.patch +++ /dev/null @@ -1,232 +0,0 @@ -From 1d0c6895d96d6b444664edb9f41464ce9b433b4f Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Thu, 16 Jan 2014 14:58:25 +0100 -Subject: [PATCH] builder: add a JSON output for --list - -Simple JSON output for sources and templates, to be able to query them -with no need to parse unstructured outputs like the "--list-format long" -one. - -(cherry picked from commit 5b42351294f4d0ace6960b9f31215f3f97c5259d) ---- - builder/cmdline.ml | 3 +- - builder/list_entries.ml | 60 +++++++++++++++++++++++++++++++++++ - builder/list_entries.mli | 2 +- - builder/test-virt-builder-list.sh | 67 +++++++++++++++++++++++++++++++++++++++ - builder/virt-builder.pod | 12 ++++++- - 5 files changed, 141 insertions(+), 3 deletions(-) - -diff --git a/builder/cmdline.ml b/builder/cmdline.ml -index 6d6439f..e3b1484 100644 ---- a/builder/cmdline.ml -+++ b/builder/cmdline.ml -@@ -136,6 +136,7 @@ let parse_cmdline () = - list_format := match arg with - | "short" -> `Short - | "long" -> `Long -+ | "json" -> `Json - | fmt -> - eprintf (f_"%s: invalid --list-format type '%s', see the man page.\n") prog fmt; - exit 1 in -@@ -265,7 +266,7 @@ let parse_cmdline () = - "--list", Arg.Unit list_mode, ditto; - "--long", Arg.Unit list_set_long, " " ^ s_"Shortcut for --list-format short"; - "--list-format", Arg.String list_set_format, -- "short|long" ^ " " ^ s_"Set the format for --list (default: short)"; -+ "short|long|json" ^ " " ^ s_"Set the format for --list (default: short)"; - "--no-logfile", Arg.Set scrub_logfile, " " ^ s_"Scrub build log file"; - "--long-options", Arg.Unit display_long_options, " " ^ s_"List long options"; - "-m", Arg.Int set_memsize, "mb" ^ " " ^ s_"Set memory size"; -diff --git a/builder/list_entries.ml b/builder/list_entries.ml -index 97ab201..7369e6c 100644 ---- a/builder/list_entries.ml -+++ b/builder/list_entries.ml -@@ -25,6 +25,7 @@ let rec list_entries ~list_format ~sources index = - match list_format with - | `Short -> list_entries_short index - | `Long -> list_entries_long ~sources index -+ | `Json -> list_entries_json ~sources index - - and list_entries_short index = - List.iter ( -@@ -78,3 +79,62 @@ and list_entries_long ~sources index = - printf "\n" - ) - ) index -+ -+and list_entries_json ~sources index = -+ let trailing_comma index size = -+ if index = size - 1 then "" else "," in -+ let json_string_of_bool b = -+ if b then "true" else "false" in -+ let json_string_escape str = -+ let res = ref "" in -+ for i = 0 to String.length str - 1 do -+ res := !res ^ (match str.[i] with -+ | '"' -> "\\\"" -+ | '\\' -> "\\\\" -+ | '\b' -> "\\b" -+ | '\n' -> "\\n" -+ | '\r' -> "\\r" -+ | '\t' -> "\\t" -+ | c -> String.make 1 c) -+ done; -+ !res in -+ let json_optional_printf_string key value = -+ match value with -+ | None -> () -+ | Some str -> -+ printf " \"%s\": \"%s\",\n" key (json_string_escape str) in -+ let json_optional_printf_int64 key value = -+ match value with -+ | None -> () -+ | Some n -> -+ printf " \"%s\": \"%Ld\",\n" key n in -+ -+ printf "{\n"; -+ printf " \"version\": %d,\n" 1; -+ printf " \"sources\": [\n"; -+ iteri ( -+ fun i (source, fingerprint) -> -+ printf " {\n"; -+ printf " \"uri\": \"%s\",\n" source; -+ printf " \"fingerprint\": \"%s\"\n" fingerprint; -+ printf " }%s\n" (trailing_comma i (List.length sources)) -+ ) sources; -+ printf " ],\n"; -+ printf " \"templates\": [\n"; -+ iteri ( -+ fun i (name, { Index_parser.printable_name = printable_name; -+ size = size; -+ compressed_size = compressed_size; -+ notes = notes; -+ hidden = hidden }) -> -+ printf " {\n"; -+ printf " \"os-version\": \"%s\",\n" name; -+ json_optional_printf_string "full-name" printable_name; -+ printf " \"size\": %Ld,\n" size; -+ json_optional_printf_int64 "compressed-size" compressed_size; -+ json_optional_printf_string "notes" notes; -+ printf " \"hidden\": %s\n" (json_string_of_bool hidden); -+ printf " }%s\n" (trailing_comma i (List.length index)) -+ ) index; -+ printf " ]\n"; -+ printf "}\n" -diff --git a/builder/list_entries.mli b/builder/list_entries.mli -index 41d0bff..e7c32f1 100644 ---- a/builder/list_entries.mli -+++ b/builder/list_entries.mli -@@ -16,4 +16,4 @@ - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - *) - --val list_entries : list_format:([ `Short | `Long ]) -> sources:(string * string) list -> Index_parser.index -> unit -+val list_entries : list_format:([ `Short | `Long | `Json ]) -> sources:(string * string) list -> Index_parser.index -> unit -diff --git a/builder/test-virt-builder-list.sh b/builder/test-virt-builder-list.sh -index 083c035..c3b791f 100755 ---- a/builder/test-virt-builder-list.sh -+++ b/builder/test-virt-builder-list.sh -@@ -103,3 +103,70 @@ Phony Windows look-alike used for testing." ]; then - echo "$long_list" - exit 1 - fi -+ -+json_list=$(./virt-builder --no-check-signature --no-cache --list --list-format json) -+ -+if [ "$json_list" != "{ -+ \"version\": 1, -+ \"sources\": [ -+ { -+ \"uri\": \"$VIRT_BUILDER_SOURCE\", -+ \"fingerprint\": \"F777 4FB1 AD07 4A7E 8C87 67EA 9173 8F73 E1B7 68A0\" -+ } -+ ], -+ \"templates\": [ -+ { -+ \"os-version\": \"phony-debian\", -+ \"full-name\": \"Phony Debian\", -+ \"size\": 536870912, -+ \"notes\": \"Phony Debian look-alike used for testing.\", -+ \"hidden\": false -+ }, -+ { -+ \"os-version\": \"phony-fedora\", -+ \"full-name\": \"Phony Fedora\", -+ \"size\": 1073741824, -+ \"notes\": \"Phony Fedora look-alike used for testing.\", -+ \"hidden\": false -+ }, -+ { -+ \"os-version\": \"phony-fedora-qcow2\", -+ \"full-name\": \"Phony Fedora qcow2\", -+ \"size\": 1073741824, -+ \"notes\": \"Phony Fedora look-alike used for testing.\", -+ \"hidden\": false -+ }, -+ { -+ \"os-version\": \"phony-fedora-qcow2-uncompressed\", -+ \"full-name\": \"Phony Fedora qcow2 uncompressed\", -+ \"size\": 1073741824, -+ \"notes\": \"Phony Fedora look-alike used for testing.\", -+ \"hidden\": false -+ }, -+ { -+ \"os-version\": \"phony-fedora-no-format\", -+ \"full-name\": \"Phony Fedora\", -+ \"size\": 1073741824, -+ \"notes\": \"Phony Fedora look-alike used for testing.\", -+ \"hidden\": false -+ }, -+ { -+ \"os-version\": \"phony-ubuntu\", -+ \"full-name\": \"Phony Ubuntu\", -+ \"size\": 536870912, -+ \"notes\": \"Phony Ubuntu look-alike used for testing.\", -+ \"hidden\": false -+ }, -+ { -+ \"os-version\": \"phony-windows\", -+ \"full-name\": \"Phony Windows\", -+ \"size\": 536870912, -+ \"notes\": \"Phony Windows look-alike used for testing.\", -+ \"hidden\": false -+ } -+ ] -+}" ]; then -+ echo "$0: unexpected --list --format json output:" -+ echo "$json_list" -+ exit 1 -+fi -diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod -index 8e60d30..6f835ed 100644 ---- a/builder/virt-builder.pod -+++ b/builder/virt-builder.pod -@@ -31,7 +31,7 @@ virt-builder - Build virtual machine images quickly - [--firstboot SCRIPT] [--firstboot-command 'CMD ARGS ...'] - [--firstboot-install PKG,[PKG...]] - -- virt-builder -l|--list [--long] [--list-format short|long] -+ virt-builder -l|--list [--long] [--list-format short|long|json] - - virt-builder --notes os-version - -@@ -395,6 +395,16 @@ its short description. - Prints a textual list with the details of the available sources, followed - by the details of the available templates. - -+=item B -+ -+Prints a JSON object with the details of the available sources and -+the details of the available templates. -+ -+The C key in the main object represents the "compatibility version", -+and it is bumped every time the resulting JSON output is incompatible with -+the previous versions (for example the structure has changed, or non-optional -+keys are no more present). -+ - =back - - I<--long> is a shorthand for the C format. --- -1.8.5.3 - diff --git a/0063-builder-Fix-unterminated-I-.-in-man-page.patch b/0063-builder-Fix-unterminated-I-.-in-man-page.patch deleted file mode 100644 index 016e480..0000000 --- a/0063-builder-Fix-unterminated-I-.-in-man-page.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 6b6ce89d059c7148f6d6cb6f485e7ebcfdfb34bb Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 16 Jan 2014 18:01:20 +0000 -Subject: [PATCH] builder: Fix unterminated I<...> in man page. - -Thanks: Lukas Zapletal. -(cherry picked from commit b3cf877e58cbcc4f6fd5d228028e19c1b294b1ac) ---- - builder/virt-builder.pod | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod -index 6f835ed..918f372 100644 ---- a/builder/virt-builder.pod -+++ b/builder/virt-builder.pod -@@ -1012,7 +1012,7 @@ Files are deleted (I<--delete>, I<--scrub>). - - =item * - --Symbolic links are created (I<--link). -+Symbolic links are created (I<--link>). - - =item * - --- -1.8.5.3 - diff --git a/0064-builder-add-index-struct.h-as-dependency-for-index-p.patch b/0064-builder-add-index-struct.h-as-dependency-for-index-p.patch deleted file mode 100644 index 9ed01b2..0000000 --- a/0064-builder-add-index-struct.h-as-dependency-for-index-p.patch +++ /dev/null @@ -1,31 +0,0 @@ -From ee214e1f750478cf76ae98997d1545a5fd70d6b2 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Tue, 21 Jan 2014 10:54:19 +0100 -Subject: [PATCH] builder: add index-struct.h as dependency for - index-parser-c.c - -Just like with index-parse.h, also index-struct.h is a dependency of -index-parser-c.c which automake cannot generate correctly. -Thus, add it manually. - -(cherry picked from commit e2cc8b6465a400024fe2f0fcce0d0ff5f7e7719c) ---- - builder/Makefile.am | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/builder/Makefile.am b/builder/Makefile.am -index d718c22..4777619 100644 ---- a/builder/Makefile.am -+++ b/builder/Makefile.am -@@ -229,7 +229,7 @@ CLEANFILES += \ - - # Fix dependencies which automake doesn't generate correctly. - if HAVE_OCAML --index-parser-c.o: index-parse.h -+index-parser-c.o: index-parse.h index-struct.h - index-scan.o: index-parse.h - endif - index-validate.o: index-parse.h --- -1.8.5.3 - diff --git a/0065-builder-allow-more-empty-lines-in-index-files.patch b/0065-builder-allow-more-empty-lines-in-index-files.patch deleted file mode 100644 index 147b2a4..0000000 --- a/0065-builder-allow-more-empty-lines-in-index-files.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 5327e6988d3a5e79197b0338a592e8f4b41044ac Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Tue, 21 Jan 2014 17:54:23 +0100 -Subject: [PATCH] builder: allow more empty lines in index files - -Improve the index grammar to allow more than one empty line between -sections, and to allow any number of empty lines at the end of the file -(after the last section). - -(cherry picked from commit 4505f61979a9737da53cdad419ae6d22538780d5) ---- - builder/index-parse.y | 12 +++++++++--- - 1 file changed, 9 insertions(+), 3 deletions(-) - -diff --git a/builder/index-parse.y b/builder/index-parse.y -index f5e551b..a8d2f62 100644 ---- a/builder/index-parse.y -+++ b/builder/index-parse.y -@@ -80,10 +80,10 @@ index: - { parsed_index = $2; } - - sections: -- section -+ section emptylines - { $$ = $1; } -- | section EMPTY_LINE sections -- { $$ = $1; $$->next = $3; } -+ | section EMPTY_LINE emptylines sections -+ { $$ = $1; $$->next = $4; } - - section: - SECTION_HEADER fields -@@ -113,6 +113,12 @@ continuations: - free ($1); - free ($2); } - -+emptylines: -+ /* empty */ -+ {} -+ | EMPTY_LINE emptylines -+ {} -+ - %% - - void --- -1.8.5.3 - diff --git a/0066-builder-proper-consider-subkeys-in-index-files.patch b/0066-builder-proper-consider-subkeys-in-index-files.patch deleted file mode 100644 index d29d1ff..0000000 --- a/0066-builder-proper-consider-subkeys-in-index-files.patch +++ /dev/null @@ -1,214 +0,0 @@ -From 765382e254aed95e3d402d3d0a8b9aebbce2b3db Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Tue, 21 Jan 2014 18:52:42 +0100 -Subject: [PATCH] builder: proper consider subkeys in index files - -The index files already allowed the 'key[subkey]=...' syntax for keys, -but considering such string as whole key. Proper split the parsing and -the handling of the subkeys, so they can be searched a bit easier. - -This causes no actual behaviour changes, it is just internal -micro-refactoring. (Thanks Rich for the hints, too.) - -(cherry picked from commit 5cbdf35d651b6c730d62d9af4876039faa122efc) ---- - builder/index-parser-c.c | 15 +++++++++++---- - builder/index-scan.l | 9 ++++++++- - builder/index-struct.c | 1 + - builder/index-struct.h | 1 + - builder/index_parser.ml | 44 +++++++++++++++++++++++++------------------- - 5 files changed, 46 insertions(+), 24 deletions(-) - -diff --git a/builder/index-parser-c.c b/builder/index-parser-c.c -index 17e680b..fbbebff 100644 ---- a/builder/index-parser-c.c -+++ b/builder/index-parser-c.c -@@ -49,7 +49,7 @@ value - virt_builder_parse_index (value filenamev) - { - CAMLparam1 (filenamev); -- CAMLlocal4 (rv, v, sv, fv); -+ CAMLlocal5 (rv, v, sv, sv2, fv); - struct section *sections; - size_t i, nr_sections; - -@@ -83,11 +83,18 @@ virt_builder_parse_index (value filenamev) - - for (j = 0, fields = sections->fields; fields != NULL; - j++, fields = fields->next) { -- v = caml_alloc_tuple (2); -+ v = caml_alloc_tuple (3); - sv = caml_copy_string (fields->key); -- Store_field (v, 0, sv); /* (key, value) */ -- sv = caml_copy_string (fields->value); -+ Store_field (v, 0, sv); /* (key, Some subkey, value) */ -+ if (fields->subkey) { -+ sv2 = caml_copy_string (fields->subkey); -+ sv = caml_alloc (1, 0); -+ Store_field (sv, 0, sv2); -+ } else -+ sv = Val_int (0); - Store_field (v, 1, sv); -+ sv = caml_copy_string (fields->value); -+ Store_field (v, 2, sv); - Store_field (fv, j, v); /* assign to return array of fields */ - } - -diff --git a/builder/index-scan.l b/builder/index-scan.l -index 9a6a0e3..7a9618f 100644 ---- a/builder/index-scan.l -+++ b/builder/index-scan.l -@@ -58,10 +58,17 @@ extern void yyerror (const char *); - - /* field=value or field[subfield]=value */ - ^[A-Za-z0-9_.]+("["[A-Za-z0-9_,.]+"]")?"=".*\n { -- size_t i = strcspn (yytext, "="); -+ size_t i = strcspn (yytext, "=["); - yylval.field = malloc (sizeof (struct field)); - yylval.field->next = NULL; - yylval.field->key = strndup (yytext, i); -+ if (yytext[i] == '[') { -+ size_t j = strcspn (yytext+i+1, "]"); -+ yylval.field->subkey = strndup (yytext+i+1, j); -+ i += 1+j+2; -+ } else { -+ yylval.field->subkey = NULL; -+ } - /* Note we chop the final \n off here. */ - yylval.field->value = strndup (yytext+i+1, yyleng-(i+2)); - return FIELD; -diff --git a/builder/index-struct.c b/builder/index-struct.c -index 26bed24..fe5b0e3 100644 ---- a/builder/index-struct.c -+++ b/builder/index-struct.c -@@ -52,6 +52,7 @@ free_field (struct field *field) - if (field) { - free_field (field->next); - free (field->key); -+ free (field->subkey); - free (field->value); - free (field); - } -diff --git a/builder/index-struct.h b/builder/index-struct.h -index ac8a3dd..f92e01d 100644 ---- a/builder/index-struct.h -+++ b/builder/index-struct.h -@@ -32,6 +32,7 @@ struct section { - struct field { - struct field *next; - char *key; -+ char *subkey; - char *value; - }; - -diff --git a/builder/index_parser.ml b/builder/index_parser.ml -index 453a3a1..da44b21 100644 ---- a/builder/index_parser.ml -+++ b/builder/index_parser.ml -@@ -101,7 +101,7 @@ let print_entry chan (name, { printable_name = printable_name; - type sections = section array - and section = string * fields (* [name] + fields *) - and fields = field array --and field = string * string (* key + value *) -+and field = string * string option * string (* key + subkey + value *) - - (* Calls yyparse in the C code. *) - external parse_index : string -> sections = "virt_builder_parse_index" -@@ -149,12 +149,17 @@ let get_index ~prog ~debug ~downloader ~sigchecker source = - fun (n, fields) -> - let fseen = Hashtbl.create 13 in - List.iter ( -- fun (field, _) -> -- if Hashtbl.mem fseen field then ( -- eprintf (f_"virt-builder: index is corrupt: %s: field '%s' appears two or more times\n") n field; -+ fun (field, subkey, _) -> -+ let hashkey = (field, subkey) in -+ if Hashtbl.mem fseen hashkey then ( -+ (match subkey with -+ | Some value -> -+ eprintf (f_"virt-builder: index is corrupt: %s: field '%s[%s]' appears two or more times\n") n field value -+ | None -> -+ eprintf (f_"virt-builder: index is corrupt: %s: field '%s' appears two or more times\n") n field); - corrupt_file () - ); -- Hashtbl.add fseen field true -+ Hashtbl.add fseen hashkey true - ) fields - ) sections; - -@@ -162,25 +167,26 @@ let get_index ~prog ~debug ~downloader ~sigchecker source = - let entries = - List.map ( - fun (n, fields) -> -+ let fields = List.map (fun (k, sk, v) -> (k, sk), v) fields in - let printable_name = -- try Some (List.assoc "name" fields) with Not_found -> None in -+ try Some (List.assoc ("name", None) fields) with Not_found -> None in - let osinfo = -- try Some (List.assoc "osinfo" fields) with Not_found -> None in -+ try Some (List.assoc ("osinfo", None) fields) with Not_found -> None in - let file_uri = -- try make_absolute_uri (List.assoc "file" fields) -+ try make_absolute_uri (List.assoc ("file", None) fields) - with Not_found -> - eprintf (f_"virt-builder: no 'file' (URI) entry for '%s'\n") n; - corrupt_file () in - let signature_uri = -- try Some (make_absolute_uri (List.assoc "sig" fields)) -+ try Some (make_absolute_uri (List.assoc ("sig", None) fields)) - with Not_found -> None in - let checksum_sha512 = -- try Some (List.assoc "checksum[sha512]" fields) -+ try Some (List.assoc ("checksum", Some "sha512") fields) - with Not_found -> -- try Some (List.assoc "checksum" fields) -+ try Some (List.assoc ("checksum", None) fields) - with Not_found -> None in - let revision = -- try int_of_string (List.assoc "revision" fields) -+ try int_of_string (List.assoc ("revision", None) fields) - with - | Not_found -> 1 - | Failure "int_of_string" -> -@@ -188,9 +194,9 @@ let get_index ~prog ~debug ~downloader ~sigchecker source = - n; - corrupt_file () in - let format = -- try Some (List.assoc "format" fields) with Not_found -> None in -+ try Some (List.assoc ("format", None) fields) with Not_found -> None in - let size = -- try Int64.of_string (List.assoc "size" fields) -+ try Int64.of_string (List.assoc ("size", None) fields) - with - | Not_found -> - eprintf (f_"virt-builder: no 'size' field for '%s'\n") n; -@@ -200,7 +206,7 @@ let get_index ~prog ~debug ~downloader ~sigchecker source = - n; - corrupt_file () in - let compressed_size = -- try Some (Int64.of_string (List.assoc "compressed_size" fields)) -+ try Some (Int64.of_string (List.assoc ("compressed_size", None) fields)) - with - | Not_found -> - None -@@ -209,13 +215,13 @@ let get_index ~prog ~debug ~downloader ~sigchecker source = - n; - corrupt_file () in - let expand = -- try Some (List.assoc "expand" fields) with Not_found -> None in -+ try Some (List.assoc ("expand", None) fields) with Not_found -> None in - let lvexpand = -- try Some (List.assoc "lvexpand" fields) with Not_found -> None in -+ try Some (List.assoc ("lvexpand", None) fields) with Not_found -> None in - let notes = -- try Some (List.assoc "notes" fields) with Not_found -> None in -+ try Some (List.assoc ("notes", None) fields) with Not_found -> None in - let hidden = -- try bool_of_string (List.assoc "hidden" fields) -+ try bool_of_string (List.assoc ("hidden", None) fields) - with - | Not_found -> false - | Failure "bool_of_string" -> --- -1.8.5.3 - diff --git a/0067-builder-fix-small-regression-in-subkey-parsing.patch b/0067-builder-fix-small-regression-in-subkey-parsing.patch deleted file mode 100644 index 078251f..0000000 --- a/0067-builder-fix-small-regression-in-subkey-parsing.patch +++ /dev/null @@ -1,29 +0,0 @@ -From a299cf6d211cfa38d4e07281750770c3efac379b Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Wed, 22 Jan 2014 15:34:22 +0100 -Subject: [PATCH] builder: fix small regression in subkey parsing - -Introduced in 5cbdf35d651b6c730d62d9af4876039faa122efc, it caused the -first character of the value to be skipped if the key has a subkey. - -(cherry picked from commit 9e4357ca54282c1ab053dd5a8ebd64a323830cf4) ---- - builder/index-scan.l | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/builder/index-scan.l b/builder/index-scan.l -index 7a9618f..e43f82e 100644 ---- a/builder/index-scan.l -+++ b/builder/index-scan.l -@@ -65,7 +65,7 @@ extern void yyerror (const char *); - if (yytext[i] == '[') { - size_t j = strcspn (yytext+i+1, "]"); - yylval.field->subkey = strndup (yytext+i+1, j); -- i += 1+j+2; -+ i += 1+j+1; - } else { - yylval.field->subkey = NULL; - } --- -1.8.5.3 - diff --git a/0068-builder-small-code-simplification.patch b/0068-builder-small-code-simplification.patch deleted file mode 100644 index b0e5923..0000000 --- a/0068-builder-small-code-simplification.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 30e387cfed1244f2ea5f5222e0e32dd846893157 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Wed, 22 Jan 2014 23:13:24 +0100 -Subject: [PATCH] builder: small code simplification - -No actual behaviour changes, just remove extra match statements. - -(cherry picked from commit 958e84d69960faf5b321bdec92283a0b37abd858) ---- - builder/list_entries.ml | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/builder/list_entries.ml b/builder/list_entries.ml -index 7369e6c..9da7664 100644 ---- a/builder/list_entries.ml -+++ b/builder/list_entries.ml -@@ -98,13 +98,11 @@ and list_entries_json ~sources index = - | c -> String.make 1 c) - done; - !res in -- let json_optional_printf_string key value = -- match value with -+ let json_optional_printf_string key = function - | None -> () - | Some str -> - printf " \"%s\": \"%s\",\n" key (json_string_escape str) in -- let json_optional_printf_int64 key value = -- match value with -+ let json_optional_printf_int64 key = function - | None -> () - | Some n -> - printf " \"%s\": \"%Ld\",\n" key n in --- -1.8.5.3 - diff --git a/0069-builder-read-all-the-available-notes-from-the-index.patch b/0069-builder-read-all-the-available-notes-from-the-index.patch deleted file mode 100644 index 424eef6..0000000 --- a/0069-builder-read-all-the-available-notes-from-the-index.patch +++ /dev/null @@ -1,136 +0,0 @@ -From 0766c47cfd6eaca6e351cde79a9eba2a27c2d56e Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Thu, 23 Jan 2014 15:36:15 +0100 -Subject: [PATCH] builder: read all the available notes from the index - -Switch the internal storage for the notes of each entry to a sorted list -with all the subkeys available (which should represent the translations -to various languages). -The current outputs are the same (i.e. still the untranslated notes), so -this is just internal refactoring/preparation. - -(cherry picked from commit b7cd63fc1dc031914e110a46de3faa431387d959) ---- - builder/builder.ml | 5 +++-- - builder/index_parser.ml | 20 ++++++++++++++++---- - builder/index_parser.mli | 2 +- - builder/list_entries.ml | 12 +++++++++--- - 4 files changed, 29 insertions(+), 10 deletions(-) - -diff --git a/builder/builder.ml b/builder/builder.ml -index 7e1c614..c0dc06d 100644 ---- a/builder/builder.ml -+++ b/builder/builder.ml -@@ -202,9 +202,10 @@ let main () = - (match mode with - | `Notes -> (* --notes *) - (match entry with -- | { Index_parser.notes = Some notes } -> -+ | { Index_parser.notes = ("", notes) :: _ } -> - print_endline notes; -- | { Index_parser.notes = None } -> -+ | { Index_parser.notes = _ :: _ } -+ | { Index_parser.notes = [] } -> - printf (f_"There are no notes for %s\n") arg - ); - exit 0 -diff --git a/builder/index_parser.ml b/builder/index_parser.ml -index da44b21..d5b48ae 100644 ---- a/builder/index_parser.ml -+++ b/builder/index_parser.ml -@@ -35,7 +35,7 @@ and entry = { - compressed_size : int64 option; - expand : string option; - lvexpand : string option; -- notes : string option; -+ notes : (string * string) list; - hidden : bool; - - sigchecker : Sigchecker.t; -@@ -92,8 +92,9 @@ let print_entry chan (name, { printable_name = printable_name; - | Some lvexpand -> fp "lvexpand=%s\n" lvexpand - ); - (match notes with -- | None -> () -- | Some notes -> fp "notes=%s\n" notes -+ | ("", notes) :: _ -> fp "notes=%s\n" notes -+ | _ :: _ -+ | [] -> () - ); - if hidden then fp "hidden=true\n" - -@@ -219,7 +220,18 @@ let get_index ~prog ~debug ~downloader ~sigchecker source = - let lvexpand = - try Some (List.assoc ("lvexpand", None) fields) with Not_found -> None in - let notes = -- try Some (List.assoc ("notes", None) fields) with Not_found -> None in -+ let rec loop = function -+ | [] -> [] -+ | (("notes", subkey), value) :: xs -> -+ let subkey = match subkey with -+ | None -> "" -+ | Some v -> v in -+ (subkey, value) :: loop xs -+ | _ :: xs -> loop xs in -+ List.sort ( -+ fun (k1, _) (k2, _) -> -+ String.compare k1 k2 -+ ) (loop fields) in - let hidden = - try bool_of_string (List.assoc ("hidden", None) fields) - with -diff --git a/builder/index_parser.mli b/builder/index_parser.mli -index 54f1807..3c679b3 100644 ---- a/builder/index_parser.mli -+++ b/builder/index_parser.mli -@@ -29,7 +29,7 @@ and entry = { - compressed_size : int64 option; - expand : string option; - lvexpand : string option; -- notes : string option; -+ notes : (string * string) list; - hidden : bool; - - sigchecker : Sigchecker.t; -diff --git a/builder/list_entries.ml b/builder/list_entries.ml -index 9da7664..b947cc8 100644 ---- a/builder/list_entries.ml -+++ b/builder/list_entries.ml -@@ -71,10 +71,11 @@ and list_entries_long ~sources index = - printf "%-24s %s\n" (s_"Download size:") (human_size size); - ); - (match notes with -- | None -> () -- | Some notes -> -+ | ("", notes) :: _ -> - printf "\n"; - printf (f_"Notes:\n\n%s\n") notes -+ | _ :: _ -+ | [] -> () - ); - printf "\n" - ) -@@ -106,6 +107,11 @@ and list_entries_json ~sources index = - | None -> () - | Some n -> - printf " \"%s\": \"%Ld\",\n" key n in -+ let print_notes = function -+ | ("", notes) :: _ -> -+ printf " \"notes\": \"%s\",\n" (json_string_escape notes) -+ | _ :: _ -+ | _ -> () in - - printf "{\n"; - printf " \"version\": %d,\n" 1; -@@ -130,7 +136,7 @@ and list_entries_json ~sources index = - json_optional_printf_string "full-name" printable_name; - printf " \"size\": %Ld,\n" size; - json_optional_printf_int64 "compressed-size" compressed_size; -- json_optional_printf_string "notes" notes; -+ print_notes notes; - printf " \"hidden\": %s\n" (json_string_of_bool hidden); - printf " }%s\n" (trailing_comma i (List.length index)) - ) index; --- -1.8.5.3 - diff --git a/0070-builder-Add-selinux-relabel-option-to-perform-SELinu.patch b/0070-builder-Add-selinux-relabel-option-to-perform-SELinu.patch deleted file mode 100644 index dda238c..0000000 --- a/0070-builder-Add-selinux-relabel-option-to-perform-SELinu.patch +++ /dev/null @@ -1,251 +0,0 @@ -From 48f09e1bbdc91cee4d9d8da7e78542072951d89a Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 24 Jan 2014 19:38:26 +0000 -Subject: [PATCH] builder: Add --selinux-relabel option to perform SELinux - relabelling. - -This adds the --selinux-relabel option which enables selinux in the -appliance and runs: - - if load_policy && fixfiles restore; then - rm -f /.autorelabel - else - touch /.autorelabel - fi - -at the end of installation. - -When possible this fixes SELinux labels in the guest and makes the -autorelabel step unnecessary. - -Notes: - - - The previous commit is required so that load_policy works. - - - During the build, SELinux is enabled but no policy is loaded. This - works because SELinux is in permissive mode. - - - This flag does not work if the appliance kernel and the guest have - greatly differing versions, eg. a RHEL 6 guest with a Fedora 20 - appliance. This is because SELinux changes the policy format and - breaks backwards compatibility. You would see errors like this: - - libsepol.policydb_write: policy version 15 cannot support MLS - libsepol.policydb_to_image: could not compute policy length - libsepol.policydb_to_image: could not create policy image - SELinux: Could not downgrade policy file /etc/selinux/targeted/policy/policy.24, searching for an older version. - SELinux: Could not open policy file <= /etc/selinux/targeted/policy/policy.24: No such file or directory - - These errors are ignored (they go to the log file) and relabelling - is done at boot instead. - - - It's not clear if loading guest policy is safe. You should trust - the virt-builder templates and to use libguestfs confinement for - additional protection. - -(cherry picked from commit 90e23b4e566f88595ac697b45d2531de851be6df) ---- - builder/builder.ml | 19 +++++++++++-- - builder/cmdline.ml | 8 ++++-- - builder/virt-builder.pod | 69 +++++++++++++++++++++++++++++++----------------- - 3 files changed, 68 insertions(+), 28 deletions(-) - -diff --git a/builder/builder.ml b/builder/builder.ml -index c0dc06d..b43bc4f 100644 ---- a/builder/builder.ml -+++ b/builder/builder.ml -@@ -42,8 +42,8 @@ let main () = - edit, firstboot, run, format, gpg, hostname, install, list_format, links, - memsize, mkdirs, - network, output, password_crypto, quiet, root_password, scrub, -- scrub_logfile, size, smp, sources, sync, timezone, update, upload, -- writes = -+ scrub_logfile, selinux_relabel, size, smp, sources, sync, timezone, -+ update, upload, writes = - parse_cmdline () in - - (* Timestamped messages in ordinary, non-debug non-quiet mode. *) -@@ -580,6 +580,8 @@ let main () = - (match smp with None -> () | Some smp -> g#set_smp smp); - g#set_network network; - -+ g#set_selinux selinux_relabel; -+ - (* The output disk is being created, so use cache=unsafe here. *) - g#add_drive_opts ~format:output_format ~cachemode:"unsafe" output_filename; - -@@ -892,6 +894,19 @@ exec >>%s 2>&1 - do_run ~display:cmd cmd - ) run; - -+ if selinux_relabel then ( -+ msg (f_"SELinux relabelling"); -+ let cmd = sprintf " -+ if load_policy && fixfiles restore; then -+ rm -f /.autorelabel -+ else -+ touch /.autorelabel -+ echo '%s: SELinux relabelling failed, will relabel at boot instead.' -+ fi -+ " prog in -+ do_run ~display:"load_policy && fixfiles restore" cmd -+ ); -+ - (* Clean up the log file: - * - * If debugging, dump out the log file. -diff --git a/builder/cmdline.ml b/builder/cmdline.ml -index e3b1484..a6cb6c5 100644 ---- a/builder/cmdline.ml -+++ b/builder/cmdline.ml -@@ -180,6 +180,7 @@ let parse_cmdline () = - let add_scrub s = scrub := s :: !scrub in - - let scrub_logfile = ref false in -+ let selinux_relabel = ref false in - - let size = ref None in - let set_size arg = size := Some (parse_size ~prog arg) in -@@ -287,6 +288,8 @@ let parse_cmdline () = - "--run", Arg.String add_run, "script" ^ " " ^ s_"Run script in disk image"; - "--run-command", Arg.String add_run_cmd, "cmd+args" ^ " " ^ s_"Run command in disk image"; - "--scrub", Arg.String add_scrub, "name" ^ " " ^ s_"Scrub a file"; -+ "--selinux-relabel", Arg.Set selinux_relabel, -+ " " ^ s_"Relabel files with correct SELinux labels"; - "--size", Arg.String set_size, "size" ^ " " ^ s_"Set output disk size"; - "--smp", Arg.Int set_smp, "vcpus" ^ " " ^ s_"Set number of vCPUs"; - "--source", Arg.String add_source, "URL" ^ " " ^ s_"Set source URL"; -@@ -351,6 +354,7 @@ read the man page virt-builder(1). - let root_password = !root_password in - let scrub = List.rev !scrub in - let scrub_logfile = !scrub_logfile in -+ let selinux_relabel = !selinux_relabel in - let size = !size in - let smp = !smp in - let sources = List.rev !sources in -@@ -457,5 +461,5 @@ read the man page virt-builder(1). - edit, firstboot, run, format, gpg, hostname, install, list_format, links, - memsize, mkdirs, - network, output, password_crypto, quiet, root_password, scrub, -- scrub_logfile, size, smp, sources, sync, timezone, update, upload, -- writes -+ scrub_logfile, selinux_relabel, size, smp, sources, sync, timezone, -+ update, upload, writes -diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod -index 918f372..52bf536 100644 ---- a/builder/virt-builder.pod -+++ b/builder/virt-builder.pod -@@ -27,6 +27,7 @@ virt-builder - Build virtual machine images quickly - [--link TARGET:LINK[:LINK]] - [--edit FILE:EXPR] - [--delete FILE] [--scrub FILE] -+ [--selinux-relabel] - [--run SCRIPT] [--run-command 'CMD ARGS ...'] - [--firstboot SCRIPT] [--firstboot-command 'CMD ARGS ...'] - [--firstboot-install PKG,[PKG...]] -@@ -136,6 +137,16 @@ To install packages from the ordinary (guest) software repository - (In Fedora, C<@> is used to install groups of packages. On Debian - you would install a meta-package instead.) - -+To update the core packages to the latest version: -+ -+ virt-builder debian-7 --update -+ -+For guests which use SELinux, like Fedora and Red Hat Enterprise -+Linux, you may need to do SELinux relabelling after installing or -+updating packages (see L below): -+ -+ virt-builder fedora-20 --update --selinux-relabel -+ - =head2 Customizing the installation - - There are many options that let you customize the installation. These -@@ -593,6 +604,12 @@ It cannot delete directories, only regular files. - - =back - -+=item B<--selinux-relabel> -+ -+Relabel files in the guest so that they have the correct SELinux label. -+ -+You should only use this option for guests which support SELinux. -+ - =item B<--size> SIZE - - Select the size of the output disk, where the size can be specified -@@ -1029,6 +1046,10 @@ Scripts are run (I<--run>, I<--run-command>). - - Scripts run in the order they appear on the command line. - -+=item * -+ -+SELinux relabelling is done (I<--selinux-relabel>). -+ - =back - - =head2 IMPORTING THE DISK IMAGE -@@ -1714,30 +1735,29 @@ raw-format guests. - Guests which use SELinux (such as Fedora and Red Hat Enterprise Linux) - require that each file has a correct SELinux label. - --Since virt-builder does not know how to give new files a correct --label, the guest templates have an empty file C and --this causes the guest to relabel itself at first boot. -- --This usually means that these guests will reboot themselves once the --first time you use them. B However if --you want to perform the relabelling at build time instead of delaying --it to the first boot, you can boot the guest with the qemu --I<-no-reboot> option (which means it will shut down after the relabel --is complete without booting "for real"). Only do this if you are sure --it is an SELinux guest: -- -- qemu-system-x86_64 \ -- -no-reboot \ -- -nographic \ -- -machine accel=kvm:tcg \ -- -cpu host \ -- -m 2048 \ -- -drive file=disk.img,format=raw,if=virtio \ -- -serial stdio \ -- -monitor none -- --(For further information on the topic of SELinux labelling, see: --L) -+Virt-builder does not know how to give new files a label, so there are -+two possible strategies it can use to ensure correct labelling: -+ -+=over 4 -+ -+=item Using I<--selinux-relabel> -+ -+This runs L just before finalizing the guest, which sets -+SELinux labels correctly in the disk image. -+ -+Sometimes fixfiles is not possible during installation, in which case -+this option falls back on: -+ -+=item Touching C -+ -+Guest templates may already contain a file called C, or -+it is touched if I<--selinux-relabel> cannot run fixfiles. -+ -+For guests that use SELinux, this causes fixfiles to run at first -+boot. Guests will reboot themselves once the first time you use them, -+which is normal and harmless. -+ -+=back - - =head1 ENVIRONMENT VARIABLES - -@@ -1795,6 +1815,7 @@ L, - L, - L, - L, -+L, - L. - - =head1 AUTHOR --- -1.8.5.3 - diff --git a/0071-builder-Add-documentation-for-enabling-Puppet-agent-.patch b/0071-builder-Add-documentation-for-enabling-Puppet-agent-.patch deleted file mode 100644 index 434976a..0000000 --- a/0071-builder-Add-documentation-for-enabling-Puppet-agent-.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 942656546cd307829e0359d9a89fb6f012a155de Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 24 Jan 2014 19:43:05 +0000 -Subject: [PATCH] builder: Add documentation for enabling Puppet (agent) in a - guest. - -(cherry picked from commit 080300dfec1dd603da2f7d53e72dd3e056317fb8) ---- - builder/virt-builder.pod | 23 +++++++++++++++++++++++ - 1 file changed, 23 insertions(+) - -diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod -index 52bf536..ed08f3d 100644 ---- a/builder/virt-builder.pod -+++ b/builder/virt-builder.pod -@@ -1121,6 +1121,29 @@ following could be used to boot the virtual machine: - As with libvirt, it is very important that the correct format is - chosen. It will be C unless the I<--format> option was used. - -+=head2 CONFIGURATION MANAGEMENT -+ -+=head3 Puppet -+ -+To enable the Puppet agent in a guest, install the package, point -+the configuration at your Puppetmaster, and ensure the agent runs -+at boot. -+ -+A typical virt-builder command would be: -+ -+ virt-builder fedora-20 \ -+ --hostname client.example.com \ -+ --update \ -+ --install puppet \ -+ --edit '/etc/puppet/puppet.conf: -+ s/^\[agent\]/[agent]\n server = puppetmaster.example.com/' \ -+ --run-command 'systemctl enable puppet' \ -+ --selinux-relabel -+ -+The precise instructions vary according to the Linux distro. For -+further information see: -+L -+ - =head2 DEBUGGING BUILDS - - If virt-builder itself fails, then enable debugging (I<-v>) and report --- -1.8.5.3 - diff --git a/0072-daemon-Bind-mount-sys-fs-selinux-into-sysroot-when-r.patch b/0072-daemon-Bind-mount-sys-fs-selinux-into-sysroot-when-r.patch deleted file mode 100644 index 7bcf704..0000000 --- a/0072-daemon-Bind-mount-sys-fs-selinux-into-sysroot-when-r.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 215bb1426cb28ea3e54ce12fe3167e9b5d09d74a Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 24 Jan 2014 19:36:33 +0000 -Subject: [PATCH] daemon: Bind-mount /sys/fs/selinux into sysroot when running - commands. - -Even though we are already bind-mounting /sys, it is necessary to also -bind-mount /sys/fs/selinux in order for SELinux commands (in -particular, 'load_policy') to work. - -This fixes/reverts commit 7367729ec7a5d016878dd00b32cce45cec372931. - -(cherry picked from commit ab33653ef312e18042be08854aa0dec2c7254fc2) ---- - daemon/command.c | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - -diff --git a/daemon/command.c b/daemon/command.c -index 066c773..1aa1a52 100644 ---- a/daemon/command.c -+++ b/daemon/command.c -@@ -48,7 +48,8 @@ struct bind_state { - char *sysroot_dev_pts; - char *sysroot_proc; - char *sysroot_sys; -- bool dev_ok, dev_pts_ok, proc_ok, sys_ok; -+ char *sysroot_sys_fs_selinux; -+ bool dev_ok, dev_pts_ok, proc_ok, sys_ok, sys_fs_selinux_ok; - }; - - struct resolver_state { -@@ -76,14 +77,17 @@ bind_mount (struct bind_state *bs) - bs->sysroot_dev_pts = sysroot_path ("/dev/pts"); - bs->sysroot_proc = sysroot_path ("/proc"); - bs->sysroot_sys = sysroot_path ("/sys"); -+ bs->sysroot_sys_fs_selinux = sysroot_path ("/sys/fs/selinux"); - - if (bs->sysroot_dev == NULL || bs->sysroot_dev_pts == NULL || -- bs->sysroot_proc == NULL || bs->sysroot_sys == NULL) { -+ bs->sysroot_proc == NULL || bs->sysroot_sys == NULL || -+ bs->sysroot_sys_fs_selinux == NULL) { - reply_with_perror ("malloc"); - free (bs->sysroot_dev); - free (bs->sysroot_dev_pts); - free (bs->sysroot_proc); - free (bs->sysroot_sys); -+ free (bs->sysroot_sys_fs_selinux); - return -1; - } - -@@ -95,6 +99,8 @@ bind_mount (struct bind_state *bs) - bs->proc_ok = r != -1; - r = command (NULL, NULL, str_mount, "--bind", "/sys", bs->sysroot_sys, NULL); - bs->sys_ok = r != -1; -+ r = command (NULL, NULL, str_mount, "--bind", "/sys/fs/selinux", bs->sysroot_sys_fs_selinux, NULL); -+ bs->sys_fs_selinux_ok = r != -1; - - bs->mounted = true; - -@@ -111,6 +117,8 @@ static void - free_bind_state (struct bind_state *bs) - { - if (bs->mounted) { -+ if (bs->sys_fs_selinux_ok) umount_ignore_fail (bs->sysroot_sys_fs_selinux); -+ free (bs->sysroot_sys_fs_selinux); - if (bs->sys_ok) umount_ignore_fail (bs->sysroot_sys); - free (bs->sysroot_sys); - if (bs->proc_ok) umount_ignore_fail (bs->sysroot_proc); --- -1.8.5.3 - diff --git a/0073-daemon-If-selinux-exists-in-the-guest-bind-mount-sys.patch b/0073-daemon-If-selinux-exists-in-the-guest-bind-mount-sys.patch deleted file mode 100644 index 6540e54..0000000 --- a/0073-daemon-If-selinux-exists-in-the-guest-bind-mount-sys.patch +++ /dev/null @@ -1,77 +0,0 @@ -From cc3baf20c7fea0fb6faf248a04bfd3807e480170 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 27 Jan 2014 20:22:23 +0000 -Subject: [PATCH] daemon: If /selinux exists in the guest, bind-mount - /sys/fs/selinux to there. - -Commit 72afcf450a78b7e58f65b4a7aaf94d71cd25fca5 was partially -incorrect. If the guest userspace is expecting /selinux to exist, -then we should bind-mount /sys/fs/selinux from the appliance kernel -there. - -(cherry picked from commit 9df50877f8b61106248acd2375d011acc209c6b5) ---- - daemon/command.c | 16 +++++++++++++--- - 1 file changed, 13 insertions(+), 3 deletions(-) - -diff --git a/daemon/command.c b/daemon/command.c -index 1aa1a52..939bf87 100644 ---- a/daemon/command.c -+++ b/daemon/command.c -@@ -47,9 +47,10 @@ struct bind_state { - char *sysroot_dev; - char *sysroot_dev_pts; - char *sysroot_proc; -+ char *sysroot_selinux; - char *sysroot_sys; - char *sysroot_sys_fs_selinux; -- bool dev_ok, dev_pts_ok, proc_ok, sys_ok, sys_fs_selinux_ok; -+ bool dev_ok, dev_pts_ok, proc_ok, selinux_ok, sys_ok, sys_fs_selinux_ok; - }; - - struct resolver_state { -@@ -76,16 +77,18 @@ bind_mount (struct bind_state *bs) - bs->sysroot_dev = sysroot_path ("/dev"); - bs->sysroot_dev_pts = sysroot_path ("/dev/pts"); - bs->sysroot_proc = sysroot_path ("/proc"); -+ bs->sysroot_selinux = sysroot_path ("/selinux"); - bs->sysroot_sys = sysroot_path ("/sys"); - bs->sysroot_sys_fs_selinux = sysroot_path ("/sys/fs/selinux"); - - if (bs->sysroot_dev == NULL || bs->sysroot_dev_pts == NULL || -- bs->sysroot_proc == NULL || bs->sysroot_sys == NULL || -- bs->sysroot_sys_fs_selinux == NULL) { -+ bs->sysroot_proc == NULL || bs->sysroot_selinux == NULL || -+ bs->sysroot_sys == NULL || bs->sysroot_sys_fs_selinux == NULL) { - reply_with_perror ("malloc"); - free (bs->sysroot_dev); - free (bs->sysroot_dev_pts); - free (bs->sysroot_proc); -+ free (bs->sysroot_selinux); - free (bs->sysroot_sys); - free (bs->sysroot_sys_fs_selinux); - return -1; -@@ -97,6 +100,11 @@ bind_mount (struct bind_state *bs) - bs->dev_pts_ok = r != -1; - r = command (NULL, NULL, str_mount, "--bind", "/proc", bs->sysroot_proc, NULL); - bs->proc_ok = r != -1; -+ /* Note on the next line we have to bind-mount /sys/fs/selinux (appliance -+ * kernel) on top of /selinux (where guest is expecting selinux). -+ */ -+ r = command (NULL, NULL, str_mount, "--bind", "/sys/fs/selinux", bs->sysroot_selinux, NULL); -+ bs->selinux_ok = r != -1; - r = command (NULL, NULL, str_mount, "--bind", "/sys", bs->sysroot_sys, NULL); - bs->sys_ok = r != -1; - r = command (NULL, NULL, str_mount, "--bind", "/sys/fs/selinux", bs->sysroot_sys_fs_selinux, NULL); -@@ -121,6 +129,8 @@ free_bind_state (struct bind_state *bs) - free (bs->sysroot_sys_fs_selinux); - if (bs->sys_ok) umount_ignore_fail (bs->sysroot_sys); - free (bs->sysroot_sys); -+ if (bs->selinux_ok) umount_ignore_fail (bs->sysroot_selinux); -+ free (bs->sysroot_selinux); - if (bs->proc_ok) umount_ignore_fail (bs->sysroot_proc); - free (bs->sysroot_proc); - if (bs->dev_pts_ok) umount_ignore_fail (bs->sysroot_dev_pts); --- -1.8.5.3 - diff --git a/0074-daemon-Add-a-note-about-how-mount-rbind-doesn-t-work.patch b/0074-daemon-Add-a-note-about-how-mount-rbind-doesn-t-work.patch deleted file mode 100644 index 0f077f1..0000000 --- a/0074-daemon-Add-a-note-about-how-mount-rbind-doesn-t-work.patch +++ /dev/null @@ -1,28 +0,0 @@ -From e0d039574b622d61403ec8975a996088fee1f5e0 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 27 Jan 2014 21:20:32 +0000 -Subject: [PATCH] daemon: Add a note about how 'mount --rbind' doesn't work. - -(cherry picked from commit d9cd2dc9b0e847fda3831c9ff13def616ca5043d) ---- - daemon/command.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/daemon/command.c b/daemon/command.c -index 939bf87..1593de9 100644 ---- a/daemon/command.c -+++ b/daemon/command.c -@@ -94,6 +94,10 @@ bind_mount (struct bind_state *bs) - return -1; - } - -+ /* Note it is tempting to use --rbind here (to bind submounts). -+ * However I have not found a reliable way to unmount the same set -+ * of directories (umount -R does NOT work). -+ */ - r = command (NULL, NULL, str_mount, "--bind", "/dev", bs->sysroot_dev, NULL); - bs->dev_ok = r != -1; - r = command (NULL, NULL, str_mount, "--bind", "/dev/pts", bs->sysroot_dev_pts, NULL); --- -1.8.5.3 - diff --git a/0075-builder-output-translated-notes.patch b/0075-builder-output-translated-notes.patch deleted file mode 100644 index cf30ebb..0000000 --- a/0075-builder-output-translated-notes.patch +++ /dev/null @@ -1,404 +0,0 @@ -From 16e4cb121e895a508fb4fda8c8c5a39f97bdf1bc Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Thu, 30 Jan 2014 17:05:34 +0100 -Subject: [PATCH] builder: output translated notes - -Output all the translations available for the notes in the "verbose" -output and the JSON output, while trying to match the system langauge in -the "show notes" output. - -The JSON output is slightly changed to handle translations, with the -"untranslated" notes being matched as "C". The version is not bumped -though, since there have been no stable releases with the former output -yet. - -(cherry picked from commit 07ef60c63f5fd635306d199622d36f9089c75ecc) ---- - builder/Makefile.am | 5 ++++ - builder/index_parser.ml | 11 ++++---- - builder/list_entries.ml | 56 +++++++++++++++++++++++++++++++++---- - builder/setlocale-c.c | 59 +++++++++++++++++++++++++++++++++++++++ - builder/setlocale.ml | 29 +++++++++++++++++++ - builder/setlocale.mli | 30 ++++++++++++++++++++ - builder/test-virt-builder-list.sh | 28 ++++++++++++++----- - po/POTFILES | 1 + - po/POTFILES-ml | 1 + - 9 files changed, 202 insertions(+), 18 deletions(-) - create mode 100644 builder/setlocale-c.c - create mode 100644 builder/setlocale.ml - create mode 100644 builder/setlocale.mli - -diff --git a/builder/Makefile.am b/builder/Makefile.am -index 4777619..2be495b 100644 ---- a/builder/Makefile.am -+++ b/builder/Makefile.am -@@ -51,6 +51,9 @@ SOURCES = \ - pxzcat.ml \ - pxzcat.mli \ - pxzcat-c.c \ -+ setlocale.ml \ -+ setlocale.mli \ -+ setlocale-c.c \ - sigchecker.mli \ - sigchecker.ml - -@@ -83,6 +86,8 @@ OBJECTS = \ - index-parser-c.o \ - pxzcat-c.o \ - pxzcat.cmx \ -+ setlocale-c.o \ -+ setlocale.cmx \ - get_kernel.cmx \ - downloader.cmx \ - sigchecker.cmx \ -diff --git a/builder/index_parser.ml b/builder/index_parser.ml -index d5b48ae..2d4a642 100644 ---- a/builder/index_parser.ml -+++ b/builder/index_parser.ml -@@ -91,11 +91,12 @@ let print_entry chan (name, { printable_name = printable_name; - | None -> () - | Some lvexpand -> fp "lvexpand=%s\n" lvexpand - ); -- (match notes with -- | ("", notes) :: _ -> fp "notes=%s\n" notes -- | _ :: _ -- | [] -> () -- ); -+ List.iter ( -+ fun (lang, notes) -> -+ match lang with -+ | "" -> fp "notes=%s\n" notes -+ | lang -> fp "notes[%s]=%s\n" lang notes -+ ) notes; - if hidden then fp "hidden=true\n" - - (* Types returned by the C index parser. *) -diff --git a/builder/list_entries.ml b/builder/list_entries.ml -index b947cc8..7317cc7 100644 ---- a/builder/list_entries.ml -+++ b/builder/list_entries.ml -@@ -21,6 +21,24 @@ open Common_utils - - open Printf - -+let split_locale loc = -+ let regex = Str.regexp "^\\([A-Za-z]+\\)\\(_\\([A-Za-z]+\\)\\)?\\(\\.\\([A-Za-z0-9-]+\\)\\)?\\(@\\([A-Za-z]+\\)\\)?$" in -+ let l = ref [] in -+ if Str.string_match regex loc 0 then ( -+ let match_or_empty n = -+ try Str.matched_group n loc with -+ | Not_found -> "" -+ in -+ let lang = Str.matched_group 1 loc in -+ let territory = match_or_empty 3 in -+ (match territory with -+ | "" -> () -+ | territory -> l := (lang ^ "_" ^ territory) :: !l); -+ l := lang :: !l; -+ ); -+ l := "" :: !l; -+ List.rev !l -+ - let rec list_entries ~list_format ~sources index = - match list_format with - | `Short -> list_entries_short index -@@ -45,6 +63,10 @@ and list_entries_short index = - ) index - - and list_entries_long ~sources index = -+ let langs = match Setlocale.setlocale Setlocale.LC_MESSAGES None with -+ | None -> [""] -+ | Some locale -> split_locale locale in -+ - List.iter ( - fun (source, fingerprint) -> - printf (f_"Source URI: %s\n") source; -@@ -70,11 +92,23 @@ and list_entries_long ~sources index = - | Some size -> - printf "%-24s %s\n" (s_"Download size:") (human_size size); - ); -+ let notes = List.fold_left ( -+ fun acc lang -> -+ let res = List.filter ( -+ fun (langkey, _) -> -+ match langkey with -+ | "C" -> lang = "" -+ | langkey -> langkey = lang -+ ) notes in -+ match res with -+ | (_, noteskey) :: _ -> noteskey :: acc -+ | [] -> acc -+ ) [] langs in -+ let notes = List.rev notes in - (match notes with -- | ("", notes) :: _ -> -+ | notes :: _ -> - printf "\n"; - printf (f_"Notes:\n\n%s\n") notes -- | _ :: _ - | [] -> () - ); - printf "\n" -@@ -108,10 +142,20 @@ and list_entries_json ~sources index = - | Some n -> - printf " \"%s\": \"%Ld\",\n" key n in - let print_notes = function -- | ("", notes) :: _ -> -- printf " \"notes\": \"%s\",\n" (json_string_escape notes) -- | _ :: _ -- | _ -> () in -+ | [] -> () -+ | notes -> -+ printf " \"notes\": {\n"; -+ iteri ( -+ fun i (lang, langnotes) -> -+ let lang = -+ match lang with -+ | "" -> "C" -+ | x -> x in -+ printf " \"%s\": \"%s\"%s\n" -+ (json_string_escape lang) (json_string_escape langnotes) -+ (trailing_comma i (List.length notes)) -+ ) notes; -+ printf " },\n" in - - printf "{\n"; - printf " \"version\": %d,\n" 1; -diff --git a/builder/setlocale-c.c b/builder/setlocale-c.c -new file mode 100644 -index 0000000..e1ad75d ---- /dev/null -+++ b/builder/setlocale-c.c -@@ -0,0 +1,59 @@ -+/* virt-builder -+ * Copyright (C) 2014 Red Hat Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ */ -+ -+#include -+ -+#include -+ -+#include -+#include -+#include -+#include -+ -+static const int lc_string_table[7] = { -+ LC_ALL, -+ LC_CTYPE, -+ LC_NUMERIC, -+ LC_TIME, -+ LC_COLLATE, -+ LC_MONETARY, -+ LC_MESSAGES -+}; -+ -+#define Val_none (Val_int (0)) -+ -+value -+virt_builder_setlocale (value val_category, value val_name) -+{ -+ CAMLparam2 (val_category, val_name); -+ CAMLlocal2 (rv, rv2); -+ char *ret, *locstring; -+ int category; -+ -+ category = lc_string_table[Int_val (val_category)]; -+ locstring = val_name == Val_none ? NULL : String_val (Field (val_name, 0)); -+ ret = setlocale (category, locstring); -+ if (ret) { -+ rv2 = caml_copy_string (ret); -+ rv = caml_alloc (1, 0); -+ Store_field (rv, 0, rv2); -+ } else -+ rv = Val_none; -+ -+ CAMLreturn (rv); -+} -diff --git a/builder/setlocale.ml b/builder/setlocale.ml -new file mode 100644 -index 0000000..9b3289d ---- /dev/null -+++ b/builder/setlocale.ml -@@ -0,0 +1,29 @@ -+(* virt-builder -+ * Copyright (C) 2014 Red Hat Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ *) -+ -+type localecategory = -+ | LC_ALL -+ | LC_CTYPE -+ | LC_NUMERIC -+ | LC_TIME -+ | LC_COLLATE -+ | LC_MONETARY -+ | LC_MESSAGES -+;; -+ -+external setlocale : localecategory -> string option -> string option = "virt_builder_setlocale" -diff --git a/builder/setlocale.mli b/builder/setlocale.mli -new file mode 100644 -index 0000000..1e34204 ---- /dev/null -+++ b/builder/setlocale.mli -@@ -0,0 +1,30 @@ -+(* virt-builder -+ * Copyright (C) 2014 Red Hat Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ *) -+ -+type localecategory = -+ | LC_ALL -+ | LC_CTYPE -+ | LC_NUMERIC -+ | LC_TIME -+ | LC_COLLATE -+ | LC_MONETARY -+ | LC_MESSAGES -+;; -+ -+val setlocale : localecategory -> string option -> string option -+(** [setlocale category newlocale] Tiny wrapper to the C [setlocale]. *) -diff --git a/builder/test-virt-builder-list.sh b/builder/test-virt-builder-list.sh -index c3b791f..634254d 100755 ---- a/builder/test-virt-builder-list.sh -+++ b/builder/test-virt-builder-list.sh -@@ -119,49 +119,63 @@ if [ "$json_list" != "{ - \"os-version\": \"phony-debian\", - \"full-name\": \"Phony Debian\", - \"size\": 536870912, -- \"notes\": \"Phony Debian look-alike used for testing.\", -+ \"notes\": { -+ \"C\": \"Phony Debian look-alike used for testing.\" -+ }, - \"hidden\": false - }, - { - \"os-version\": \"phony-fedora\", - \"full-name\": \"Phony Fedora\", - \"size\": 1073741824, -- \"notes\": \"Phony Fedora look-alike used for testing.\", -+ \"notes\": { -+ \"C\": \"Phony Fedora look-alike used for testing.\" -+ }, - \"hidden\": false - }, - { - \"os-version\": \"phony-fedora-qcow2\", - \"full-name\": \"Phony Fedora qcow2\", - \"size\": 1073741824, -- \"notes\": \"Phony Fedora look-alike used for testing.\", -+ \"notes\": { -+ \"C\": \"Phony Fedora look-alike used for testing.\" -+ }, - \"hidden\": false - }, - { - \"os-version\": \"phony-fedora-qcow2-uncompressed\", - \"full-name\": \"Phony Fedora qcow2 uncompressed\", - \"size\": 1073741824, -- \"notes\": \"Phony Fedora look-alike used for testing.\", -+ \"notes\": { -+ \"C\": \"Phony Fedora look-alike used for testing.\" -+ }, - \"hidden\": false - }, - { - \"os-version\": \"phony-fedora-no-format\", - \"full-name\": \"Phony Fedora\", - \"size\": 1073741824, -- \"notes\": \"Phony Fedora look-alike used for testing.\", -+ \"notes\": { -+ \"C\": \"Phony Fedora look-alike used for testing.\" -+ }, - \"hidden\": false - }, - { - \"os-version\": \"phony-ubuntu\", - \"full-name\": \"Phony Ubuntu\", - \"size\": 536870912, -- \"notes\": \"Phony Ubuntu look-alike used for testing.\", -+ \"notes\": { -+ \"C\": \"Phony Ubuntu look-alike used for testing.\" -+ }, - \"hidden\": false - }, - { - \"os-version\": \"phony-windows\", - \"full-name\": \"Phony Windows\", - \"size\": 536870912, -- \"notes\": \"Phony Windows look-alike used for testing.\", -+ \"notes\": { -+ \"C\": \"Phony Windows look-alike used for testing.\" -+ }, - \"hidden\": false - } - ] -diff --git a/po/POTFILES b/po/POTFILES -index c743fa9..090871b 100644 ---- a/po/POTFILES -+++ b/po/POTFILES -@@ -5,6 +5,7 @@ builder/index-scan.c - builder/index-struct.c - builder/index-validate.c - builder/pxzcat-c.c -+builder/setlocale-c.c - cat/cat.c - cat/filesystems.c - cat/ls.c -diff --git a/po/POTFILES-ml b/po/POTFILES-ml -index 3b2f297..bba9a42 100644 ---- a/po/POTFILES-ml -+++ b/po/POTFILES-ml -@@ -5,6 +5,7 @@ builder/get_kernel.ml - builder/index_parser.ml - builder/list_entries.ml - builder/pxzcat.ml -+builder/setlocale.ml - builder/sigchecker.ml - mllib/common_gettext.ml - mllib/common_utils.ml --- -1.8.5.3 - diff --git a/0076-builder-remove-unused-variables.patch b/0076-builder-remove-unused-variables.patch deleted file mode 100644 index 5ce7936..0000000 --- a/0076-builder-remove-unused-variables.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 31bfed9c750f6a149fc6b1602d9426e94886a05d Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Thu, 30 Jan 2014 17:06:42 +0100 -Subject: [PATCH] builder: remove unused variables - -Leftovers of the list_entries_short+list_entries_long split done in -commit 91aae893c70b3877b31803800ba77836fd7a45e8. - -(cherry picked from commit bed8a168c0ed76e784adcc046256432f615e3314) ---- - builder/list_entries.ml | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/builder/list_entries.ml b/builder/list_entries.ml -index 7317cc7..27ea95e 100644 ---- a/builder/list_entries.ml -+++ b/builder/list_entries.ml -@@ -48,9 +48,6 @@ let rec list_entries ~list_format ~sources index = - and list_entries_short index = - List.iter ( - fun (name, { Index_parser.printable_name = printable_name; -- size = size; -- compressed_size = compressed_size; -- notes = notes; - hidden = hidden }) -> - if not hidden then ( - printf "%-24s" name; --- -1.8.5.3 - diff --git a/0077-builder-isolate-C-libraries-in-an-own-OCAMLCLIBS.patch b/0077-builder-isolate-C-libraries-in-an-own-OCAMLCLIBS.patch deleted file mode 100644 index e3eec5c..0000000 --- a/0077-builder-isolate-C-libraries-in-an-own-OCAMLCLIBS.patch +++ /dev/null @@ -1,36 +0,0 @@ -From e8cddd39da8d691a4075d91996de1ab04fa1664e Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Tue, 11 Feb 2014 10:40:31 +0100 -Subject: [PATCH] builder: isolate C libraries in an own OCAMLCLIBS - -Just moving stuff within Makefile.am, no functional changes. - -(cherry picked from commit c66cec6ffac2af400487b7fb4ff437eddc6e7aa7) ---- - builder/Makefile.am | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/builder/Makefile.am b/builder/Makefile.am -index 2be495b..78a9e72 100644 ---- a/builder/Makefile.am -+++ b/builder/Makefile.am -@@ -113,10 +113,15 @@ endif - OCAMLCFLAGS = -g -warn-error CDEFLMPSUVYZX $(OCAMLPACKAGES) - OCAMLOPTFLAGS = $(OCAMLCFLAGS) - -+OCAMLCLIBS = \ -+ $(LIBLZMA_LIBS) \ -+ -pthread -lpthread \ -+ -lncurses -lcrypt -+ - virt-builder: $(OBJECTS) - $(OCAMLFIND) ocamlopt $(OCAMLOPTFLAGS) \ - mlguestfs.cmxa -linkpkg $^ \ -- -cclib '-pthread $(LIBLZMA_LIBS) -lncurses -lcrypt -lpthread' \ -+ -cclib '$(OCAMLCLIBS)' \ - $(OCAML_GCOV_LDFLAGS) \ - -o $@ - --- -1.8.5.3 - diff --git a/0078-builder-prepare-for-different-per-protocol-download-.patch b/0078-builder-prepare-for-different-per-protocol-download-.patch deleted file mode 100644 index d296130..0000000 --- a/0078-builder-prepare-for-different-per-protocol-download-.patch +++ /dev/null @@ -1,145 +0,0 @@ -From bdf45e434fe41ad68d016d679a65f0fc9de21c53 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Tue, 11 Feb 2014 12:39:56 +0100 -Subject: [PATCH] builder: prepare for different per-protocol download actions - -Small refactor of Downloader.download_to to allow different download -actions depending on the protocol of the URI (which is now parsed). - -No actual behaviour changes, just mostly code motion. - -(cherry picked from commit ba3569704cf5f381c618b6b07c8b001bac88e18a) ---- - builder/Makefile.am | 6 ++++ - builder/downloader.ml | 84 ++++++++++++++++++++++++++++----------------------- - 2 files changed, 53 insertions(+), 37 deletions(-) - -diff --git a/builder/Makefile.am b/builder/Makefile.am -index 78a9e72..9d2dbc5 100644 ---- a/builder/Makefile.am -+++ b/builder/Makefile.am -@@ -80,6 +80,9 @@ OBJECTS = \ - $(top_builddir)/mllib/password.cmx \ - $(top_builddir)/mllib/planner.cmx \ - $(top_builddir)/mllib/config.cmx \ -+ $(top_builddir)/fish/guestfish-uri.o \ -+ $(top_builddir)/mllib/uri-c.o \ -+ $(top_builddir)/mllib/uRI.cmx \ - index-scan.o \ - index-struct.o \ - index-parse.o \ -@@ -115,6 +118,9 @@ OCAMLOPTFLAGS = $(OCAMLCFLAGS) - - OCAMLCLIBS = \ - $(LIBLZMA_LIBS) \ -+ $(LIBXML2_LIBS) \ -+ -L../src/.libs -lutils \ -+ -L../gnulib/lib/.libs -lgnu \ - -pthread -lpthread \ - -lncurses -lcrypt - -diff --git a/builder/downloader.ml b/builder/downloader.ml -index 77f48ae..95b5817 100644 ---- a/builder/downloader.ml -+++ b/builder/downloader.ml -@@ -69,50 +69,60 @@ let rec download ~prog t ?template ?progress_bar uri = - (filename, false) - - and download_to ~prog t ?(progress_bar = false) uri filename = -- (* Get the status code first to ensure the file exists. *) -- let cmd = sprintf "%s%s -g -o /dev/null -I -w '%%{http_code}' %s" -- t.curl -- (if t.debug then "" else " -s -S") -- (quote uri) in -- if t.debug then eprintf "%s\n%!" cmd; -- let lines = external_command ~prog cmd in -- if List.length lines < 1 then ( -- eprintf (f_"%s: unexpected output from curl command, enable debug and look at previous messages\n") prog; -- exit 1 -- ); -- let status_code = List.hd lines in -- let bad_status_code = function -- | "" -> true -- | s when s.[0] = '4' -> true (* 4xx *) -- | s when s.[0] = '5' -> true (* 5xx *) -- | _ -> false -- in -- if bad_status_code status_code then ( -- eprintf (f_"%s: failed to download %s: HTTP status code %s\n") -- prog uri status_code; -- exit 1 -- ); -+ let parseduri = -+ try URI.parse_uri uri -+ with Invalid_argument "URI.parse_uri" -> -+ eprintf (f_"Error parsing URI '%s'. Look for error messages printed above.\n") uri; -+ exit 1 in - -- (* Now download the file. -- * -- * Note because there may be parallel virt-builder instances running -+ (* Note because there may be parallel virt-builder instances running - * and also to avoid partial downloads in the cachedir if the network - * fails, we download to a random name in the cache and then - * atomically rename it to the final filename. - *) - let filename_new = filename ^ "." ^ string_random8 () in - unlink_on_exit filename_new; -- let cmd = sprintf "%s%s -g -o %s %s" -- t.curl -- (if t.debug then "" else if progress_bar then " -#" else " -s -S") -- (quote filename_new) (quote uri) in -- if t.debug then eprintf "%s\n%!" cmd; -- let r = Sys.command cmd in -- if r <> 0 then ( -- eprintf (f_"%s: curl (download) command failed downloading '%s'\n") -- prog uri; -- exit 1 -+ -+ (match parseduri.URI.protocol with -+ | _ -> (* Any other protocol. *) -+ (* Get the status code first to ensure the file exists. *) -+ let cmd = sprintf "%s%s -g -o /dev/null -I -w '%%{http_code}' %s" -+ t.curl -+ (if t.debug then "" else " -s -S") -+ (quote uri) in -+ if t.debug then eprintf "%s\n%!" cmd; -+ let lines = external_command ~prog cmd in -+ if List.length lines < 1 then ( -+ eprintf (f_"%s: unexpected output from curl command, enable debug and look at previous messages\n") -+ prog; -+ exit 1 -+ ); -+ let status_code = List.hd lines in -+ let bad_status_code = function -+ | "" -> true -+ | s when s.[0] = '4' -> true (* 4xx *) -+ | s when s.[0] = '5' -> true (* 5xx *) -+ | _ -> false -+ in -+ if bad_status_code status_code then ( -+ eprintf (f_"%s: failed to download %s: HTTP status code %s\n") -+ prog uri status_code; -+ exit 1 -+ ); -+ -+ (* Now download the file. *) -+ let cmd = sprintf "%s%s -g -o %s %s" -+ t.curl -+ (if t.debug then "" else if progress_bar then " -#" else " -s -S") -+ (quote filename_new) (quote uri) in -+ if t.debug then eprintf "%s\n%!" cmd; -+ let r = Sys.command cmd in -+ if r <> 0 then ( -+ eprintf (f_"%s: curl (download) command failed downloading '%s'\n") -+ prog uri; -+ exit 1 -+ ) - ); - -- (* Rename the file if curl was successful. *) -+ (* Rename the file if the download was successful. *) - rename filename_new filename --- -1.8.5.3 - diff --git a/0079-builder-do-a-copy-when-downloading-local-files.patch b/0079-builder-do-a-copy-when-downloading-local-files.patch deleted file mode 100644 index 938d274..0000000 --- a/0079-builder-do-a-copy-when-downloading-local-files.patch +++ /dev/null @@ -1,38 +0,0 @@ -From b9f40ee0a08c2722964e47efa692c50b269c5e67 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Tue, 11 Feb 2014 12:52:10 +0100 -Subject: [PATCH] builder: do a copy when downloading local files - -Instead of spawning curl even to "download" file:// URIs, just copy -them. - -(cherry picked from commit 76e3e15d031df77db71b11ac1c40199eff80fa4d) ---- - builder/downloader.ml | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/builder/downloader.ml b/builder/downloader.ml -index 95b5817..e386c06 100644 ---- a/builder/downloader.ml -+++ b/builder/downloader.ml -@@ -84,6 +84,17 @@ and download_to ~prog t ?(progress_bar = false) uri filename = - unlink_on_exit filename_new; - - (match parseduri.URI.protocol with -+ | "file" -> -+ let path = parseduri.URI.path in -+ let cmd = sprintf "cp%s %s %s" -+ (if t.debug then " -v" else "") -+ (quote path) (quote filename_new) in -+ let r = Sys.command cmd in -+ if r <> 0 then ( -+ eprintf (f_"%s: cp (download) command failed copying '%s'\n") -+ prog path; -+ exit 1 -+ ) - | _ -> (* Any other protocol. *) - (* Get the status code first to ensure the file exists. *) - let cmd = sprintf "%s%s -g -o /dev/null -I -w '%%{http_code}' %s" --- -1.8.5.3 - diff --git a/0080-mllib-hostname-on-Debian-replace-it-also-in-etc-host.patch b/0080-mllib-hostname-on-Debian-replace-it-also-in-etc-host.patch deleted file mode 100644 index a84b067..0000000 --- a/0080-mllib-hostname-on-Debian-replace-it-also-in-etc-host.patch +++ /dev/null @@ -1,63 +0,0 @@ -From a38e43d316b6673332110a344032b518794c037e Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Thu, 13 Feb 2014 14:52:50 +0100 -Subject: [PATCH] mllib: hostname: on Debian replace it also in /etc/hosts - (RHBZ#953907). - -In Debian/Ubuntu systems, read the previous hostname from /etc/hostname -before replacing it, and replace it in /etc/hosts with the new hostname. - -(cherry picked from commit ab2df2e6598d421067d600f89a3d225162424d9b) ---- - mllib/hostname.ml | 30 ++++++++++++++++++++++++++++++ - 1 file changed, 30 insertions(+) - -diff --git a/mllib/hostname.ml b/mllib/hostname.ml -index fce16ff..70ca934 100644 ---- a/mllib/hostname.ml -+++ b/mllib/hostname.ml -@@ -42,7 +42,12 @@ let rec set_hostname (g : Guestfs.guestfs) root hostname = - true - - | "linux", ("debian"|"ubuntu"), _ -> -+ let old_hostname = read_etc_hostname g in - update_etc_hostname g hostname; -+ (match old_hostname with -+ | Some old_hostname -> replace_host_in_etc_hosts g old_hostname hostname -+ | None -> () -+ ); - true - - | "linux", ("fedora"|"rhel"|"centos"|"scientificlinux"|"redhat-based"), _ -> -@@ -78,3 +83,28 @@ and update_etc_hostname g hostname = - - and update_etc_machine_info g hostname = - replace_line_in_file g "/etc/machine-info" "PRETTY_HOSTNAME" hostname -+ -+and read_etc_hostname g = -+ let filename = "/etc/hostname" in -+ if g#is_file filename then ( -+ let lines = Array.to_list (g#read_lines filename) in -+ match lines with -+ | hd :: _ -> Some hd -+ | [] -> None -+ ) else -+ None -+ -+and replace_host_in_etc_hosts g oldhost newhost = -+ if g#is_file "/etc/hosts" then ( -+ let expr = "/files/etc/hosts/*[label() != '#comment']/*[label() != 'ipaddr']" in -+ g#aug_init "/" 0; -+ let matches = Array.to_list (g#aug_match expr) in -+ List.iter ( -+ fun m -> -+ let value = g#aug_get m in -+ if value = oldhost then ( -+ g#aug_set m newhost -+ ) -+ ) matches; -+ g#aug_save () -+ ) --- -1.8.5.3 - diff --git a/0081-builder-pxzcat-Fix-char-signedness-warning.patch b/0081-builder-pxzcat-Fix-char-signedness-warning.patch deleted file mode 100644 index 338e6ba..0000000 --- a/0081-builder-pxzcat-Fix-char-signedness-warning.patch +++ /dev/null @@ -1,35 +0,0 @@ -From d1f9407a92ba3bec2e1efe1b3ba0544358e5d6be Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 13 Feb 2014 17:48:06 +0000 -Subject: [PATCH] builder: pxzcat: Fix char * signedness warning. - -(cherry picked from commit e4fe09c5ae28ee34d87bceecf58f72cc43af6249) ---- - builder/pxzcat-c.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/builder/pxzcat-c.c b/builder/pxzcat-c.c -index 5ffc9d9..06d46fc 100644 ---- a/builder/pxzcat-c.c -+++ b/builder/pxzcat-c.c -@@ -381,7 +381,7 @@ parse_indexes (value filenamev, int fd) - * http://stackoverflow.com/questions/1493936/faster-means-of-checking-for-an-empty-buffer-in-c/1493989#1493989 - */ - static inline int --is_zero (const char *buffer, size_t size) -+is_zero (const unsigned char *buffer, size_t size) - { - size_t i; - -@@ -489,7 +489,7 @@ worker_thread (void *vp) - lzma_ret r; - lzma_stream strm = LZMA_STREAM_INIT; - uint8_t buf[BUFFER_SIZE]; -- char outbuf[BUFFER_SIZE]; -+ unsigned char outbuf[BUFFER_SIZE]; - size_t i; - lzma_bool iter_finished; - --- -1.8.5.3 - diff --git a/0082-builder-Suppress-warning-about-unused-yyunput.patch b/0082-builder-Suppress-warning-about-unused-yyunput.patch deleted file mode 100644 index 497972b..0000000 --- a/0082-builder-Suppress-warning-about-unused-yyunput.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 6592e59f309e70d638cc5cf3f6c2b13fb0325159 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 13 Feb 2014 21:38:42 +0000 -Subject: [PATCH] builder: Suppress warning about unused yyunput. - - CC virt_index_validate-index-validate.o -index-scan.c:1270:17: warning: 'yyunput' defined but not used [-Wunused-function] - static void yyunput (int c, register char * yy_bp ) - ^ - CCLD virt-index-validate - -By using %option nounput we can prevent this from being generated in -the first place. - -(cherry picked from commit e3d23cccf4099680a4335db97fe2ccf2d3c950f4) ---- - builder/index-scan.l | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/builder/index-scan.l b/builder/index-scan.l -index e43f82e..b120590 100644 ---- a/builder/index-scan.l -+++ b/builder/index-scan.l -@@ -32,6 +32,7 @@ extern void yyerror (const char *); - - %} - -+%option nounput - %option noyywrap - %option yylineno - --- -1.8.5.3 - diff --git a/0083-Use-bindtextdomain-in-some-programs-where-it-was-mis.patch b/0083-Use-bindtextdomain-in-some-programs-where-it-was-mis.patch deleted file mode 100644 index 1da373f..0000000 --- a/0083-Use-bindtextdomain-in-some-programs-where-it-was-mis.patch +++ /dev/null @@ -1,45 +0,0 @@ -From e48c2b8f3fdc4cd0c2d89a5ea99ea4647f16d7ee Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 13 Feb 2014 21:39:50 +0000 -Subject: [PATCH] Use bindtextdomain in some programs where it was missing. - -Found by make syntax-check. - -(cherry picked from commit 9018356a67eb644126814e4ef41555c56e884a79) ---- - builder/Makefile.am | 3 +++ - builder/index-validate.c | 4 ++++ - 2 files changed, 7 insertions(+) - -diff --git a/builder/Makefile.am b/builder/Makefile.am -index 9d2dbc5..3087ac4 100644 ---- a/builder/Makefile.am -+++ b/builder/Makefile.am -@@ -224,6 +224,9 @@ virt_index_validate_SOURCES = \ - index-struct.c \ - index-validate.c - -+virt_index_validate_CPPFLAGS = \ -+ -DLOCALEBASEDIR=\""$(datadir)/locale"\" -+ - man_MANS += virt-index-validate.1 - noinst_DATA += $(top_builddir)/html/virt-index-validate.1.html - -diff --git a/builder/index-validate.c b/builder/index-validate.c -index d156c43..26abaa8 100644 ---- a/builder/index-validate.c -+++ b/builder/index-validate.c -@@ -61,6 +61,10 @@ main (int argc, char *argv[]) - const char *input; - struct section *sections; - -+ setlocale (LC_ALL, ""); -+ bindtextdomain (PACKAGE, LOCALEBASEDIR); -+ textdomain (PACKAGE); -+ - for (;;) { - c = getopt_long (argc, argv, options, long_options, &option_index); - if (c == -1) break; --- -1.8.5.3 - diff --git a/0084-builder-Fix-dependencies-which-are-not-generated-cor.patch b/0084-builder-Fix-dependencies-which-are-not-generated-cor.patch deleted file mode 100644 index df76c37..0000000 --- a/0084-builder-Fix-dependencies-which-are-not-generated-cor.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 1b1430bcb773223882baa4192010c60ace5350cb Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 17 Feb 2014 09:13:42 +0000 -Subject: [PATCH] builder: Fix dependencies which are not generated correctly - by automake. - -See the error messages here: -https://www.redhat.com/archives/libguestfs/2014-February/msg00148.html - -This fixes commit e2cc8b6465a400024fe2f0fcce0d0ff5f7e7719c. - -(cherry picked from commit 360abeebda97e9940a4045a331ce181d1a370719) ---- - builder/Makefile.am | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - -diff --git a/builder/Makefile.am b/builder/Makefile.am -index 3087ac4..6313bad 100644 ---- a/builder/Makefile.am -+++ b/builder/Makefile.am -@@ -246,9 +246,11 @@ CLEANFILES += \ - index-scan.c \ - stamp-virt-index-validate.pod - --# Fix dependencies which automake doesn't generate correctly. - if HAVE_OCAML --index-parser-c.o: index-parse.h index-struct.h --index-scan.o: index-parse.h -+# Automake-generated makefile has a rule ".l.c:" but lacks a rule ".l.h:". -+# Also it doesn't generate dependencies for the C files that include -+# index-parse.h. -+index-parser-c.c index-scan.c index-validate.c: index-parse.h -+index-parse.h: index-parse.y -+ $(MAKE) index-parse.c - endif --index-validate.o: index-parse.h --- -1.8.5.3 - diff --git a/0085-fish-use-XDG-paths-for-the-config-file.patch b/0085-fish-use-XDG-paths-for-the-config-file.patch deleted file mode 100644 index 1a04738..0000000 --- a/0085-fish-use-XDG-paths-for-the-config-file.patch +++ /dev/null @@ -1,264 +0,0 @@ -From b18d073221fced0db8d600006cfb0991b569c388 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Tue, 18 Feb 2014 10:44:49 +0100 -Subject: [PATCH] fish: use XDG paths for the config file - -Read the configuration file from XDG paths for both global and -user-local locations, keeping the old paths as fallback. - -(cherry picked from commit 8b1f1c15f5dfdeea122784d8c4d97e75b335989a) ---- - fish/config.c | 68 ++++++++++++++++++++++++++++++++++++++---- - fish/guestfish.pod | 9 ++++-- - fish/libguestfs-tools.conf.pod | 52 ++++++++++++++++++++++++++------ - fuse/guestmount.pod | 4 +++ - rescue/virt-rescue.pod | 4 +++ - 5 files changed, 119 insertions(+), 18 deletions(-) - -diff --git a/fish/config.c b/fish/config.c -index 9e5da87..7d319ad 100644 ---- a/fish/config.c -+++ b/fish/config.c -@@ -34,8 +34,9 @@ - - #ifdef HAVE_LIBCONFIG - -+#define GLOBAL_CONFIG_FILENAME "libguestfs-tools.conf" - static const char *home_filename = /* $HOME/ */ ".libguestfs-tools.rc"; --static const char *etc_filename = "/etc/libguestfs-tools.conf"; -+static const char *etc_filename = "/etc/" GLOBAL_CONFIG_FILENAME; - - /* Note that parse_config is called very early, before command line - * parsing, before the verbose flag has been set, even before the -@@ -86,17 +87,72 @@ parse_config (void) - /* Try the global configuration first. */ - read_config_from_file (etc_filename); - -+ { -+ /* Then read the configuration from XDG system paths. */ -+ const char *xdg_env, *var; -+ CLEANUP_FREE_STRING_LIST char **xdg_config_dirs = NULL; -+ size_t xdg_config_dirs_count; -+ -+ xdg_env = getenv ("XDG_CONFIG_DIRS"); -+ var = xdg_env != NULL && xdg_env[0] != 0 ? xdg_env : "/etc/xdg"; -+ xdg_config_dirs = guestfs___split_string (':', var); -+ xdg_config_dirs_count = guestfs___count_strings (xdg_config_dirs); -+ for (size_t i = xdg_config_dirs_count; i > 0; --i) { -+ CLEANUP_FREE char *path = NULL; -+ const char *dir = xdg_config_dirs[i - 1]; -+ -+ if (asprintf (&path, "%s/libguestfs/" GLOBAL_CONFIG_FILENAME, dir) == -1) { -+ perror ("asprintf"); -+ exit (EXIT_FAILURE); -+ } -+ -+ read_config_from_file (path); -+ } -+ } -+ - /* Read the configuration from $HOME, to override system settings. */ - home = getenv ("HOME"); - if (home != NULL) { -- CLEANUP_FREE char *path = NULL; -+ { -+ /* Old-style configuration file first. */ -+ CLEANUP_FREE char *path = NULL; - -- if (asprintf (&path, "%s/%s", home, home_filename) == -1) { -- perror ("asprintf"); -- exit (EXIT_FAILURE); -+ if (asprintf (&path, "%s/%s", home, home_filename) == -1) { -+ perror ("asprintf"); -+ exit (EXIT_FAILURE); -+ } -+ -+ read_config_from_file (path); - } - -- read_config_from_file (path); -+ { -+ /* Then, XDG_CONFIG_HOME path. */ -+ CLEANUP_FREE char *path = NULL; -+ CLEANUP_FREE char *home_copy = strdup (home); -+ const char *xdg_env; -+ -+ if (home_copy == NULL) { -+ perror ("strdup"); -+ exit (EXIT_FAILURE); -+ } -+ -+ xdg_env = getenv ("XDG_CONFIG_HOME"); -+ if (xdg_env == NULL) { -+ if (asprintf (&path, "%s/.config/libguestfs/" GLOBAL_CONFIG_FILENAME, -+ home_copy) == -1) { -+ perror ("asprintf"); -+ exit (EXIT_FAILURE); -+ } -+ } else { -+ if (asprintf (&path, "%s/libguestfs/" GLOBAL_CONFIG_FILENAME, -+ xdg_env) == -1) { -+ perror ("asprintf"); -+ exit (EXIT_FAILURE); -+ } -+ } -+ -+ read_config_from_file (path); -+ } - } - } - -diff --git a/fish/guestfish.pod b/fish/guestfish.pod -index f6afda1..b954005 100644 ---- a/fish/guestfish.pod -+++ b/fish/guestfish.pod -@@ -516,9 +516,8 @@ then you will cause irreversible disk corruption. - In a future libguestfs we intend to change the default the other way. - Disk images will be opened read-only. You will have to either specify - I, I, I, or change --the configuration file C in order to get --write access for disk images specified by those other command line --options. -+the configuration file in order to get write access for disk images -+specified by those other command line options. - - This version of guestfish, guestmount and virt-rescue has a I<--rw> - option which does nothing (it is already the default). However it is -@@ -1497,8 +1496,12 @@ See L, L. - - =over 4 - -+=item $XDG_CONFIG_HOME/libguestfs/libguestfs-tools.conf -+ - =item $HOME/.libguestfs-tools.rc - -+=item $XDG_CONFIG_DIRS/libguestfs/libguestfs-tools.conf -+ - =item /etc/libguestfs-tools.conf - - This configuration file controls the default read-only or read-write -diff --git a/fish/libguestfs-tools.conf.pod b/fish/libguestfs-tools.conf.pod -index 771eb50..bba00e3 100644 ---- a/fish/libguestfs-tools.conf.pod -+++ b/fish/libguestfs-tools.conf.pod -@@ -2,18 +2,22 @@ - - =head1 NAME - --/etc/libguestfs-tools.conf - configuration file for guestfish, guestmount, virt-rescue -+libguestfs-tools.conf - configuration file for guestfish, guestmount, virt-rescue - - =head1 SYNOPSIS - - /etc/libguestfs-tools.conf - -+ $XDG_CONFIG_DIRS/libguestfs/libguestfs-tools.conf -+ - $HOME/.libguestfs-tools.rc - -+ $XDG_CONFIG_HOME/libguestfs/libguestfs-tools.conf -+ - =head1 DESCRIPTION - --C or C<$HOME/.libguestfs-tools.rc> changes --the defaults for the following programs only: -+C (or C<$HOME/.libguestfs-tools.rc>) changes the -+defaults for the following programs only: - - =over 4 - -@@ -45,21 +49,51 @@ See also L. - - Note that B. - --C is the global configuration file for all --of the above programs. Local users can override the global --configuration by copying this file into C<.libguestfs-tools.rc> in --their home directory and modifying it accordingly. -- - This file is parsed by the libconfig library. For more information - about the format, see: - L - -+=head1 FILE LOCATION -+ -+The order of the configuration files being read is, by importance: -+ -+=over 4 -+ -+=item * -+ -+$XDG_CONFIG_HOME/libguestfs/libguestfs-tools.conf (C<$XDG_CONFIG_HOME> is -+C<$HOME/.config> if not set). -+ -+=item * -+ -+$HOME/.libguestfs-tools.rc -+ -+=item * -+ -+$XDG_CONFIG_DIRS/libguestfs/libguestfs-tools.conf (where C<$XDG_CONFIG_DIRS> -+means any of the directories in that environment variable, or just C -+if not set) -+ -+=item * -+ -+/etc/libguestfs-tools.conf -+ -+=back -+ -+This means local users can override the system configuration by copying -+the configuration file (or creating it anew) into -+C<$XDG_CONFIG_HOME/libguestfs/libguestfs-tools.conf>. -+ -+C and C<$HOME/.libguestfs-tools.rc> are the old -+non-XDG paths which are read for compatibility. -+ - =head1 SEE ALSO - - L, - L, - L, --L. -+L, -+L. - - =head1 AUTHORS - -diff --git a/fuse/guestmount.pod b/fuse/guestmount.pod -index 9586a76..6ebf51f 100644 ---- a/fuse/guestmount.pod -+++ b/fuse/guestmount.pod -@@ -387,8 +387,12 @@ This also stops the daemon from forking into the background - - =over 4 - -+=item $XDG_CONFIG_HOME/libguestfs/libguestfs-tools.conf -+ - =item $HOME/.libguestfs-tools.rc - -+=item $XDG_CONFIG_DIRS/libguestfs/libguestfs-tools.conf -+ - =item /etc/libguestfs-tools.conf - - This configuration file controls the default read-only or read-write -diff --git a/rescue/virt-rescue.pod b/rescue/virt-rescue.pod -index 9a55d48..c295bda 100644 ---- a/rescue/virt-rescue.pod -+++ b/rescue/virt-rescue.pod -@@ -403,8 +403,12 @@ manual page L for details. - - =over 4 - -+=item $XDG_CONFIG_HOME/libguestfs/libguestfs-tools.conf -+ - =item $HOME/.libguestfs-tools.rc - -+=item $XDG_CONFIG_DIRS/libguestfs/libguestfs-tools.conf -+ - =item /etc/libguestfs-tools.conf - - This configuration file controls the default read-only or read-write --- -1.8.5.3 - diff --git a/0086-builder-move-the-XDG-path-handling-in-an-own-file.patch b/0086-builder-move-the-XDG-path-handling-in-an-own-file.patch deleted file mode 100644 index 8cebcc9..0000000 --- a/0086-builder-move-the-XDG-path-handling-in-an-own-file.patch +++ /dev/null @@ -1,110 +0,0 @@ -From b3190becb6fb3c2a52f2957f2951102c1fb41042 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Tue, 18 Feb 2014 12:54:23 +0100 -Subject: [PATCH] builder: move the XDG path handling in an own file - -Just code motion and renaming, no actual behaviour changes. - -(cherry picked from commit bb35e725035d3d8e73604a95a8b055cc1073416a) ---- - builder/Makefile.am | 2 ++ - builder/cmdline.ml | 9 +-------- - builder/paths.ml | 26 ++++++++++++++++++++++++++ - po/POTFILES-ml | 1 + - 4 files changed, 30 insertions(+), 8 deletions(-) - create mode 100644 builder/paths.ml - -diff --git a/builder/Makefile.am b/builder/Makefile.am -index 6313bad..23336c0 100644 ---- a/builder/Makefile.am -+++ b/builder/Makefile.am -@@ -48,6 +48,7 @@ SOURCES = \ - index-parser-c.c \ - list_entries.mli \ - list_entries.ml \ -+ paths.ml \ - pxzcat.ml \ - pxzcat.mli \ - pxzcat-c.c \ -@@ -91,6 +92,7 @@ OBJECTS = \ - pxzcat.cmx \ - setlocale-c.o \ - setlocale.cmx \ -+ paths.cmx \ - get_kernel.cmx \ - downloader.cmx \ - sigchecker.cmx \ -diff --git a/builder/cmdline.ml b/builder/cmdline.ml -index a6cb6c5..e9e47ae 100644 ---- a/builder/cmdline.ml -+++ b/builder/cmdline.ml -@@ -30,13 +30,6 @@ open Printf - - let prog = Filename.basename Sys.executable_name - --let default_cachedir = -- try Some (Sys.getenv "XDG_CACHE_HOME" // "virt-builder") -- with Not_found -> -- try Some (Sys.getenv "HOME" // ".cache" // "virt-builder") -- with Not_found -> -- None (* no cache directory *) -- - let default_source = "http://libguestfs.org/download/builder/index.asc" - - let parse_cmdline () = -@@ -61,7 +54,7 @@ let parse_cmdline () = - in - let attach_disk s = attach := (!attach_format, s) :: !attach in - -- let cache = ref default_cachedir in -+ let cache = ref Paths.xdg_cache_home in - let set_cache arg = cache := Some arg in - let no_cache () = cache := None in - -diff --git a/builder/paths.ml b/builder/paths.ml -new file mode 100644 -index 0000000..66e8922 ---- /dev/null -+++ b/builder/paths.ml -@@ -0,0 +1,26 @@ -+(* virt-builder -+ * Copyright (C) 2014 Red Hat Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ *) -+ -+open Common_utils -+ -+let xdg_cache_home = -+ try Some (Sys.getenv "XDG_CACHE_HOME" // "virt-builder") -+ with Not_found -> -+ try Some (Sys.getenv "HOME" // ".cache" // "virt-builder") -+ with Not_found -> -+ None (* no cache directory *) -diff --git a/po/POTFILES-ml b/po/POTFILES-ml -index bba9a42..ea357e4 100644 ---- a/po/POTFILES-ml -+++ b/po/POTFILES-ml -@@ -4,6 +4,7 @@ builder/downloader.ml - builder/get_kernel.ml - builder/index_parser.ml - builder/list_entries.ml -+builder/paths.ml - builder/pxzcat.ml - builder/setlocale.ml - builder/sigchecker.ml --- -1.8.5.3 - diff --git a/0087-builder-accept-also-_-in-group-names.patch b/0087-builder-accept-also-_-in-group-names.patch deleted file mode 100644 index 6453b6c..0000000 --- a/0087-builder-accept-also-_-in-group-names.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 87dcb7e7d48fac7225848966b3573637c57ca3d3 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Wed, 19 Feb 2014 16:40:00 +0100 -Subject: [PATCH] builder: accept also '_' in group names - -(cherry picked from commit 4c5a6afc848b556999fee1c0ebd246496cdb023b) ---- - builder/index-scan.l | 2 +- - builder/index-validate.c | 8 ++++++++ - 2 files changed, 9 insertions(+), 1 deletion(-) - -diff --git a/builder/index-scan.l b/builder/index-scan.l -index b120590..832ea51 100644 ---- a/builder/index-scan.l -+++ b/builder/index-scan.l -@@ -52,7 +52,7 @@ extern void yyerror (const char *); - ^\n { return EMPTY_LINE; } - - /* [...] marks beginning of a section. */ --^"["[-A-Za-z0-9.]+"]"\n { -+^"["[-A-Za-z0-9._]+"]"\n { - yylval.str = strndup (yytext+1, yyleng-3); - return SECTION_HEADER; - } -diff --git a/builder/index-validate.c b/builder/index-validate.c -index 26abaa8..7f02ffb 100644 ---- a/builder/index-validate.c -+++ b/builder/index-validate.c -@@ -128,6 +128,14 @@ main (int argc, char *argv[]) - int seen_sig = 0; - struct field *fields; - -+ if (compat_1_24_0) { -+ if (strchr (sections->name, '_')) { -+ fprintf (stderr, _("%s: %s: section [%s] has invalid characters which will not work with virt-builder 1.24.0\n"), -+ program_name, input, sections->name); -+ exit (EXIT_FAILURE); -+ } -+ } -+ - for (fields = sections->fields; fields != NULL; fields = fields->next) { - if (compat_1_24_0) { - if (strchr (fields->key, '[') || --- -1.8.5.3 - diff --git a/0088-mllib-add-an-hook-to-cleanup-directories-on-exit.patch b/0088-mllib-add-an-hook-to-cleanup-directories-on-exit.patch deleted file mode 100644 index 0ac6f7a..0000000 --- a/0088-mllib-add-an-hook-to-cleanup-directories-on-exit.patch +++ /dev/null @@ -1,49 +0,0 @@ -From da72572e9959a696864153deab666cea1e386ee8 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Thu, 20 Feb 2014 11:37:49 +0100 -Subject: [PATCH] mllib: add an hook to cleanup directories on exit - -Much similar to unlink_on_exit, but recursively cleaning directories. - -(cherry picked from commit 7f77f4fb28ca3320fd63c157537a332ef97533ac) ---- - mllib/common_utils.ml | 23 +++++++++++++++++++++++ - 1 file changed, 23 insertions(+) - -diff --git a/mllib/common_utils.ml b/mllib/common_utils.ml -index 3943417..de3bd40 100644 ---- a/mllib/common_utils.ml -+++ b/mllib/common_utils.ml -@@ -386,6 +386,29 @@ let unlink_on_exit = - registered_handlers := true - ) - -+(* Remove a temporary directory on exit. *) -+let rmdir_on_exit = -+ let dirs = ref [] in -+ let registered_handlers = ref false in -+ -+ let rec rmdirs () = -+ List.iter ( -+ fun dir -> -+ let cmd = sprintf "rm -rf %s" (Filename.quote dir) in -+ ignore (Sys.command cmd) -+ ) !dirs -+ and register_handlers () = -+ (* Remove on exit. *) -+ at_exit rmdirs -+ in -+ -+ fun dir -> -+ dirs := dir :: !dirs; -+ if not !registered_handlers then ( -+ register_handlers (); -+ registered_handlers := true -+ ) -+ - (* Using the libguestfs API, recursively remove only files from the - * given directory. Useful for cleaning /var/cache etc in sysprep - * without removing the actual directory structure. Also if 'dir' is --- -1.8.5.3 - diff --git a/0089-builder-use-a-disposable-GPG-keyring-for-every-Sigch.patch b/0089-builder-use-a-disposable-GPG-keyring-for-every-Sigch.patch deleted file mode 100644 index 049ac4b..0000000 --- a/0089-builder-use-a-disposable-GPG-keyring-for-every-Sigch.patch +++ /dev/null @@ -1,141 +0,0 @@ -From fa17328234182ad14000ca4f2dd5e18f4024670a Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Fri, 21 Feb 2014 14:39:57 +0100 -Subject: [PATCH] builder: use a disposable GPG keyring for every Sigchecker - -Create a temporary directory and tell gpg to use it as homedir, so -imported keys do not get into the user's keyring. This also avoid -importing the default key when a different one is needed to check the -signature. - -The only exception is when a non-default fingerprint is used: in this -case, that key is read from the user's keyring, since it is where it is. - -(cherry picked from commit dd03d38be39fdf195ae3e4943b53921a28cc4536) ---- - builder/Makefile.am | 2 ++ - builder/sigchecker.ml | 59 ++++++++++++++++++++++++++++++++++++++++----------- - 2 files changed, 49 insertions(+), 12 deletions(-) - -diff --git a/builder/Makefile.am b/builder/Makefile.am -index 23336c0..8c48be5 100644 ---- a/builder/Makefile.am -+++ b/builder/Makefile.am -@@ -84,6 +84,8 @@ OBJECTS = \ - $(top_builddir)/fish/guestfish-uri.o \ - $(top_builddir)/mllib/uri-c.o \ - $(top_builddir)/mllib/uRI.cmx \ -+ $(top_builddir)/mllib/mkdtemp-c.o \ -+ $(top_builddir)/mllib/mkdtemp.cmx \ - index-scan.o \ - index-struct.o \ - index-parse.o \ -diff --git a/builder/sigchecker.ml b/builder/sigchecker.ml -index b20a186..10e342e 100644 ---- a/builder/sigchecker.ml -+++ b/builder/sigchecker.ml -@@ -95,21 +95,38 @@ ZvXkQ3FVJwZoLmHw47vvlVpLD/4gi1SuHWieRvZ+UdDq00E348pm - =neBW - -----END PGP PUBLIC KEY BLOCK----- - " --let key_imported = ref false - - type t = { - debug : bool; - gpg : string; - fingerprint : string; - check_signature : bool; -+ gpghome : string; -+ mutable key_imported : bool; - } - - let create ~debug ~gpg ~fingerprint ~check_signature = -+ (* Create a temporary directory for gnupg. *) -+ let tmpdir = Mkdtemp.mkdtemp (Filename.temp_dir_name // "vb.gpghome.XXXXXX") in -+ rmdir_on_exit tmpdir; -+ (* Run gpg once, so it can setup its own home directory, failing -+ * if it cannot. -+ *) -+ let cmd = sprintf "%s --homedir %s --list-keys%s" -+ gpg tmpdir (if debug then "" else " >/dev/null 2>&1") in -+ if debug then eprintf "%s\n%!" cmd; -+ let r = Sys.command cmd in -+ if r <> 0 then ( -+ eprintf (f_"virt-builder: error: GPG failure: could not run GPG the first time\nUse the '-v' option and look for earlier error messages.\n"); -+ exit 1 -+ ); - { - debug = debug; - gpg = gpg; - fingerprint = fingerprint; - check_signature = check_signature; -+ gpghome = tmpdir; -+ key_imported = false; - } - - (* Compare two strings of hex digits ignoring whitespace and case. *) -@@ -159,8 +176,9 @@ and do_verify t args = - let status_file = Filename.temp_file "vbstat" ".txt" in - unlink_on_exit status_file; - let cmd = -- sprintf "%s --verify%s --status-file %s %s" -- t.gpg (if t.debug then "" else " -q --logger-file /dev/null") -+ sprintf "%s --homedir %s --verify%s --status-file %s %s" -+ t.gpg t.gpghome -+ (if t.debug then "" else " -q --logger-file /dev/null") - (quote status_file) args in - if t.debug then eprintf "%s\n%!" cmd; - let r = Sys.command cmd in -@@ -188,23 +206,40 @@ and do_verify t args = - exit 1 - ) - --(* Import the default public key. *) -+(* Import the requested public key. *) - and import_key t = -- if not !key_imported then ( -- let filename, chan = Filename.open_temp_file "vbpubkey" ".asc" in -- unlink_on_exit filename; -- output_string chan default_pubkey; -- close_out chan; -+ if not t.key_imported then ( -+ let keyfile = ref "" in -+ if equal_fingerprints default_fingerprint t.fingerprint then ( -+ let filename, chan = Filename.open_temp_file "vbpubkey" ".asc" in -+ unlink_on_exit filename; -+ output_string chan default_pubkey; -+ close_out chan; -+ keyfile := filename -+ ) else ( -+ let filename = Filename.temp_file "vbpubkey" ".asc" in -+ unlink_on_exit filename; -+ let cmd = sprintf "%s --yes --armor --output %s --export %s%s" -+ t.gpg (quote filename) (quote t.fingerprint) -+ (if t.debug then "" else " >/dev/null 2>&1") in -+ if t.debug then eprintf "%s\n%!" cmd; -+ let r = Sys.command cmd in -+ if r <> 0 then ( -+ eprintf (f_"virt-builder: error: could not export public key\nUse the '-v' option and look for earlier error messages.\n"); -+ exit 1 -+ ); -+ keyfile := filename -+ ); - -- let cmd = sprintf "%s --import %s%s" -- t.gpg (quote filename) -+ let cmd = sprintf "%s --homedir %s --import %s%s" -+ t.gpg t.gpghome (quote !keyfile) - (if t.debug then "" else " >/dev/null 2>&1") in - let r = Sys.command cmd in - if r <> 0 then ( - eprintf (f_"virt-builder: error: could not import public key\nUse the '-v' option and look for earlier error messages.\n"); - exit 1 - ); -- key_imported := true -+ t.key_imported <- true - ) - - type csum_t = SHA512 of string --- -1.8.5.3 - diff --git a/0090-builder-allow-Sigchecker-to-import-keys-from-file.patch b/0090-builder-allow-Sigchecker-to-import-keys-from-file.patch deleted file mode 100644 index 896bd2d..0000000 --- a/0090-builder-allow-Sigchecker-to-import-keys-from-file.patch +++ /dev/null @@ -1,220 +0,0 @@ -From 5ef57835174ab6fbb152217b1b147170b53d54b7 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Fri, 21 Feb 2014 15:21:08 +0100 -Subject: [PATCH] builder: allow Sigchecker to import keys from file - -Extend Sigchecker so it allows both fingerprints (to be imported from -user's keyring, as before) and keys stored in files. To simplify this -process (and have the fingerprint always around), the key is imported -on Sigchecker.create time, instead of lazily at the first verification. - -(cherry picked from commit 35e53c0381acc51908211fc6058c552029371e3e) ---- - builder/builder.ml | 3 +- - builder/sigchecker.ml | 124 ++++++++++++++++++++++++++++--------------------- - builder/sigchecker.mli | 6 ++- - 3 files changed, 78 insertions(+), 55 deletions(-) - -diff --git a/builder/builder.ml b/builder/builder.ml -index b43bc4f..ec1fc2b 100644 ---- a/builder/builder.ml -+++ b/builder/builder.ml -@@ -141,7 +141,8 @@ let main () = - List.map ( - fun (source, fingerprint) -> - let sigchecker = -- Sigchecker.create ~debug ~gpg ~fingerprint ~check_signature in -+ Sigchecker.create ~debug ~gpg ~check_signature -+ ~gpgkey:(Sigchecker.Fingerprint fingerprint) in - Index_parser.get_index ~prog ~debug ~downloader ~sigchecker source - ) sources - ) in -diff --git a/builder/sigchecker.ml b/builder/sigchecker.ml -index 10e342e..7459e4b 100644 ---- a/builder/sigchecker.ml -+++ b/builder/sigchecker.ml -@@ -96,41 +96,97 @@ ZvXkQ3FVJwZoLmHw47vvlVpLD/4gi1SuHWieRvZ+UdDq00E348pm - -----END PGP PUBLIC KEY BLOCK----- - " - -+type gpgkey_type = -+ | Fingerprint of string -+ | KeyFile of string -+ - type t = { - debug : bool; - gpg : string; - fingerprint : string; - check_signature : bool; - gpghome : string; -- mutable key_imported : bool; - } - --let create ~debug ~gpg ~fingerprint ~check_signature = -+(* Import the specified key file. *) -+let import_keyfile ~gpg ~gpghome ~debug keyfile = -+ let status_file = Filename.temp_file "vbstat" ".txt" in -+ unlink_on_exit status_file; -+ let cmd = sprintf "%s --homedir %s --status-file %s --import %s%s" -+ gpg gpghome (quote status_file) (quote keyfile) -+ (if debug then "" else " >/dev/null 2>&1") in -+ if debug then eprintf "%s\n%!" cmd; -+ let r = Sys.command cmd in -+ if r <> 0 then ( -+ eprintf (f_"virt-builder: error: could not import public key\nUse the '-v' option and look for earlier error messages.\n"); -+ exit 1 -+ ); -+ status_file -+ -+let rec create ~debug ~gpg ~gpgkey ~check_signature = - (* Create a temporary directory for gnupg. *) - let tmpdir = Mkdtemp.mkdtemp (Filename.temp_dir_name // "vb.gpghome.XXXXXX") in - rmdir_on_exit tmpdir; -- (* Run gpg once, so it can setup its own home directory, failing -- * if it cannot. -- *) -- let cmd = sprintf "%s --homedir %s --list-keys%s" -- gpg tmpdir (if debug then "" else " >/dev/null 2>&1") in -- if debug then eprintf "%s\n%!" cmd; -- let r = Sys.command cmd in -- if r <> 0 then ( -- eprintf (f_"virt-builder: error: GPG failure: could not run GPG the first time\nUse the '-v' option and look for earlier error messages.\n"); -- exit 1 -- ); -+ let fingerprint = -+ if check_signature then ( -+ (* Run gpg so it can setup its own home directory, failing if it -+ * cannot. -+ *) -+ let cmd = sprintf "%s --homedir %s --list-keys%s" -+ gpg tmpdir (if debug then "" else " >/dev/null 2>&1") in -+ if debug then eprintf "%s\n%!" cmd; -+ let r = Sys.command cmd in -+ if r <> 0 then ( -+ eprintf (f_"virt-builder: error: GPG failure: could not run GPG the first time\nUse the '-v' option and look for earlier error messages.\n"); -+ exit 1 -+ ); -+ match gpgkey with -+ | KeyFile kf -> -+ let status_file = import_keyfile gpg tmpdir debug kf in -+ let status = read_whole_file status_file in -+ let status = string_nsplit "\n" status in -+ let fingerprint = ref "" in -+ List.iter ( -+ fun line -> -+ let line = string_nsplit " " line in -+ match line with -+ | "[GNUPG:]" :: "IMPORT_OK" :: _ :: fp :: _ -> fingerprint := fp -+ | _ -> () -+ ) status; -+ !fingerprint -+ | Fingerprint fp when equal_fingerprints default_fingerprint fp -> -+ let filename, chan = Filename.open_temp_file "vbpubkey" ".asc" in -+ unlink_on_exit filename; -+ output_string chan default_pubkey; -+ close_out chan; -+ ignore (import_keyfile gpg tmpdir debug filename); -+ fp -+ | Fingerprint fp -> -+ let filename = Filename.temp_file "vbpubkey" ".asc" in -+ unlink_on_exit filename; -+ let cmd = sprintf "%s --yes --armor --output %s --export %s%s" -+ gpg (quote filename) (quote fp) -+ (if debug then "" else " >/dev/null 2>&1") in -+ if debug then eprintf "%s\n%!" cmd; -+ let r = Sys.command cmd in -+ if r <> 0 then ( -+ eprintf (f_"virt-builder: error: could not export public key\nUse the '-v' option and look for earlier error messages.\n"); -+ exit 1 -+ ); -+ ignore (import_keyfile gpg tmpdir debug filename); -+ fp -+ ) else -+ "" in - { - debug = debug; - gpg = gpg; - fingerprint = fingerprint; - check_signature = check_signature; - gpghome = tmpdir; -- key_imported = false; - } - - (* Compare two strings of hex digits ignoring whitespace and case. *) --let rec equal_fingerprints fp1 fp2 = -+and equal_fingerprints fp1 fp2 = - let len1 = String.length fp1 and len2 = String.length fp2 in - let rec loop i j = - if i = len1 && j = len2 then true (* match! *) -@@ -171,8 +227,6 @@ and verify_detached t filename sigfile = - ) - - and do_verify t args = -- import_key t; -- - let status_file = Filename.temp_file "vbstat" ".txt" in - unlink_on_exit status_file; - let cmd = -@@ -206,42 +260,6 @@ and do_verify t args = - exit 1 - ) - --(* Import the requested public key. *) --and import_key t = -- if not t.key_imported then ( -- let keyfile = ref "" in -- if equal_fingerprints default_fingerprint t.fingerprint then ( -- let filename, chan = Filename.open_temp_file "vbpubkey" ".asc" in -- unlink_on_exit filename; -- output_string chan default_pubkey; -- close_out chan; -- keyfile := filename -- ) else ( -- let filename = Filename.temp_file "vbpubkey" ".asc" in -- unlink_on_exit filename; -- let cmd = sprintf "%s --yes --armor --output %s --export %s%s" -- t.gpg (quote filename) (quote t.fingerprint) -- (if t.debug then "" else " >/dev/null 2>&1") in -- if t.debug then eprintf "%s\n%!" cmd; -- let r = Sys.command cmd in -- if r <> 0 then ( -- eprintf (f_"virt-builder: error: could not export public key\nUse the '-v' option and look for earlier error messages.\n"); -- exit 1 -- ); -- keyfile := filename -- ); -- -- let cmd = sprintf "%s --homedir %s --import %s%s" -- t.gpg t.gpghome (quote !keyfile) -- (if t.debug then "" else " >/dev/null 2>&1") in -- let r = Sys.command cmd in -- if r <> 0 then ( -- eprintf (f_"virt-builder: error: could not import public key\nUse the '-v' option and look for earlier error messages.\n"); -- exit 1 -- ); -- t.key_imported <- true -- ) -- - type csum_t = SHA512 of string - - let verify_checksum t (SHA512 csum) filename = -diff --git a/builder/sigchecker.mli b/builder/sigchecker.mli -index cdd800e..f4e817e 100644 ---- a/builder/sigchecker.mli -+++ b/builder/sigchecker.mli -@@ -20,7 +20,11 @@ val default_fingerprint : string - - type t - --val create : debug:bool -> gpg:string -> fingerprint:string -> check_signature:bool -> t -+type gpgkey_type = -+ | Fingerprint of string -+ | KeyFile of string -+ -+val create : debug:bool -> gpg:string -> gpgkey:gpgkey_type -> check_signature:bool -> t - - val verify : t -> string -> unit - (** Verify the file is signed (if check_signature is true). *) --- -1.8.5.3 - diff --git a/0091-builder-add-a-mandatory-arch-key-in-index-files.patch b/0091-builder-add-a-mandatory-arch-key-in-index-files.patch deleted file mode 100644 index 0444132..0000000 --- a/0091-builder-add-a-mandatory-arch-key-in-index-files.patch +++ /dev/null @@ -1,297 +0,0 @@ -From 05a998cb54d1f6cd83c2c12451f75bbe5976a6eb Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Mon, 24 Feb 2014 11:31:35 +0100 -Subject: [PATCH] builder: add a mandatory 'arch' key in index files - -Introduce a mandatory arch= key in all the entries of index files, to -identify which architecture is each. Adapt the long and JSON list -outputs to print also this new field. - -This introduces an incompatibility with index files created with -virt-builder < 1.26, as they will be rejected until entries will have -the arch= key added (which is ignored by older virt-builder, so adding -it will not create backward-compatibility issues). - -(cherry picked from commit 61323fabafdcab10abaf6b7002e5e1bb38ddbc5e) ---- - builder/index_parser.ml | 9 +++++++++ - builder/index_parser.mli | 1 + - builder/list_entries.ml | 4 ++++ - builder/test-index.in | 7 +++++++ - builder/test-virt-builder-list.sh | 14 ++++++++++++++ - 5 files changed, 35 insertions(+) - -diff --git a/builder/index_parser.ml b/builder/index_parser.ml -index 2d4a642..de4d72e 100644 ---- a/builder/index_parser.ml -+++ b/builder/index_parser.ml -@@ -27,6 +27,7 @@ and entry = { - printable_name : string option; (* the name= field *) - osinfo : string option; - file_uri : string; -+ arch : string; - signature_uri : string option; (* deprecated, will be removed in 1.26 *) - checksum_sha512 : string option; - revision : int; -@@ -43,6 +44,7 @@ and entry = { - - let print_entry chan (name, { printable_name = printable_name; - file_uri = file_uri; -+ arch = arch; - osinfo = osinfo; - signature_uri = signature_uri; - checksum_sha512 = checksum_sha512; -@@ -65,6 +67,7 @@ let print_entry chan (name, { printable_name = printable_name; - | Some id -> fp "osinfo=%s\n" id - ); - fp "file=%s\n" file_uri; -+ fp "arch=%s\n" arch; - (match signature_uri with - | None -> () - | Some uri -> fp "sig=%s\n" uri -@@ -179,6 +182,11 @@ let get_index ~prog ~debug ~downloader ~sigchecker source = - with Not_found -> - eprintf (f_"virt-builder: no 'file' (URI) entry for '%s'\n") n; - corrupt_file () in -+ let arch = -+ try List.assoc ("arch", None) fields -+ with Not_found -> -+ eprintf (f_"virt-builder: no 'arch' entry for '%s'\n") n; -+ corrupt_file () in - let signature_uri = - try Some (make_absolute_uri (List.assoc ("sig", None) fields)) - with Not_found -> None in -@@ -245,6 +253,7 @@ let get_index ~prog ~debug ~downloader ~sigchecker source = - let entry = { printable_name = printable_name; - osinfo = osinfo; - file_uri = file_uri; -+ arch = arch; - signature_uri = signature_uri; - checksum_sha512 = checksum_sha512; - revision = revision; -diff --git a/builder/index_parser.mli b/builder/index_parser.mli -index 3c679b3..0575dc4 100644 ---- a/builder/index_parser.mli -+++ b/builder/index_parser.mli -@@ -21,6 +21,7 @@ and entry = { - printable_name : string option; (* the name= field *) - osinfo : string option; - file_uri : string; -+ arch : string; - signature_uri : string option; (* deprecated, will be removed in 1.26 *) - checksum_sha512 : string option; - revision : int; -diff --git a/builder/list_entries.ml b/builder/list_entries.ml -index 27ea95e..edf7dfb 100644 ---- a/builder/list_entries.ml -+++ b/builder/list_entries.ml -@@ -73,6 +73,7 @@ and list_entries_long ~sources index = - - List.iter ( - fun (name, { Index_parser.printable_name = printable_name; -+ arch = arch; - size = size; - compressed_size = compressed_size; - notes = notes; -@@ -83,6 +84,7 @@ and list_entries_long ~sources index = - | None -> () - | Some name -> printf "%-24s %s\n" (s_"Full name:") name; - ); -+ printf "%-24s %s\n" (s_"Architecture:") arch; - printf "%-24s %s\n" (s_"Minimum/default size:") (human_size size); - (match compressed_size with - | None -> () -@@ -168,6 +170,7 @@ and list_entries_json ~sources index = - printf " \"templates\": [\n"; - iteri ( - fun i (name, { Index_parser.printable_name = printable_name; -+ arch = arch; - size = size; - compressed_size = compressed_size; - notes = notes; -@@ -175,6 +178,7 @@ and list_entries_json ~sources index = - printf " {\n"; - printf " \"os-version\": \"%s\",\n" name; - json_optional_printf_string "full-name" printable_name; -+ printf " \"arch\": \"%s\",\n" arch; - printf " \"size\": %Ld,\n" size; - json_optional_printf_int64 "compressed-size" compressed_size; - print_notes notes; -diff --git a/builder/test-index.in b/builder/test-index.in -index 1bca6b8..3efebc4 100644 ---- a/builder/test-index.in -+++ b/builder/test-index.in -@@ -1,5 +1,6 @@ - [phony-debian] - name=Phony Debian -+arch=x86_64 - file=debian.xz - format=raw - size=536870912 -@@ -9,6 +10,7 @@ notes=Phony Debian look-alike used for testing. - - [phony-fedora] - name=Phony Fedora -+arch=x86_64 - file=fedora.xz - format=raw - size=1073741824 -@@ -18,6 +20,7 @@ notes=Phony Fedora look-alike used for testing. - - [phony-fedora-qcow2] - name=Phony Fedora qcow2 -+arch=x86_64 - file=fedora.qcow2.xz - format=qcow2 - size=1073741824 -@@ -27,6 +30,7 @@ notes=Phony Fedora look-alike used for testing. - - [phony-fedora-qcow2-uncompressed] - name=Phony Fedora qcow2 uncompressed -+arch=x86_64 - file=fedora.qcow2 - format=qcow2 - size=1073741824 -@@ -36,6 +40,7 @@ notes=Phony Fedora look-alike used for testing. - - [phony-fedora-no-format] - name=Phony Fedora -+arch=x86_64 - file=fedora.qcow2.xz - size=1073741824 - expand=/dev/sda2 -@@ -44,6 +49,7 @@ notes=Phony Fedora look-alike used for testing. - - [phony-ubuntu] - name=Phony Ubuntu -+arch=x86_64 - file=ubuntu.xz - format=raw - size=536870912 -@@ -52,6 +58,7 @@ notes=Phony Ubuntu look-alike used for testing. - - [phony-windows] - name=Phony Windows -+arch=x86_64 - file=windows.xz - format=raw - size=536870912 -diff --git a/builder/test-virt-builder-list.sh b/builder/test-virt-builder-list.sh -index 634254d..7174152 100755 ---- a/builder/test-virt-builder-list.sh -+++ b/builder/test-virt-builder-list.sh -@@ -46,6 +46,7 @@ Fingerprint: F777 4FB1 AD07 4A7E 8C87 67EA 9173 8F73 E1B7 68A0 - - os-version: phony-debian - Full name: Phony Debian -+Architecture: x86_64 - Minimum/default size: 512.0M - - Notes: -@@ -54,6 +55,7 @@ Phony Debian look-alike used for testing. - - os-version: phony-fedora - Full name: Phony Fedora -+Architecture: x86_64 - Minimum/default size: 1.0G - - Notes: -@@ -62,6 +64,7 @@ Phony Fedora look-alike used for testing. - - os-version: phony-fedora-qcow2 - Full name: Phony Fedora qcow2 -+Architecture: x86_64 - Minimum/default size: 1.0G - - Notes: -@@ -70,6 +73,7 @@ Phony Fedora look-alike used for testing. - - os-version: phony-fedora-qcow2-uncompressed - Full name: Phony Fedora qcow2 uncompressed -+Architecture: x86_64 - Minimum/default size: 1.0G - - Notes: -@@ -78,6 +82,7 @@ Phony Fedora look-alike used for testing. - - os-version: phony-fedora-no-format - Full name: Phony Fedora -+Architecture: x86_64 - Minimum/default size: 1.0G - - Notes: -@@ -86,6 +91,7 @@ Phony Fedora look-alike used for testing. - - os-version: phony-ubuntu - Full name: Phony Ubuntu -+Architecture: x86_64 - Minimum/default size: 512.0M - - Notes: -@@ -94,6 +100,7 @@ Phony Ubuntu look-alike used for testing. - - os-version: phony-windows - Full name: Phony Windows -+Architecture: x86_64 - Minimum/default size: 512.0M - - Notes: -@@ -118,6 +125,7 @@ if [ "$json_list" != "{ - { - \"os-version\": \"phony-debian\", - \"full-name\": \"Phony Debian\", -+ \"arch\": \"x86_64\", - \"size\": 536870912, - \"notes\": { - \"C\": \"Phony Debian look-alike used for testing.\" -@@ -127,6 +135,7 @@ if [ "$json_list" != "{ - { - \"os-version\": \"phony-fedora\", - \"full-name\": \"Phony Fedora\", -+ \"arch\": \"x86_64\", - \"size\": 1073741824, - \"notes\": { - \"C\": \"Phony Fedora look-alike used for testing.\" -@@ -136,6 +145,7 @@ if [ "$json_list" != "{ - { - \"os-version\": \"phony-fedora-qcow2\", - \"full-name\": \"Phony Fedora qcow2\", -+ \"arch\": \"x86_64\", - \"size\": 1073741824, - \"notes\": { - \"C\": \"Phony Fedora look-alike used for testing.\" -@@ -145,6 +155,7 @@ if [ "$json_list" != "{ - { - \"os-version\": \"phony-fedora-qcow2-uncompressed\", - \"full-name\": \"Phony Fedora qcow2 uncompressed\", -+ \"arch\": \"x86_64\", - \"size\": 1073741824, - \"notes\": { - \"C\": \"Phony Fedora look-alike used for testing.\" -@@ -154,6 +165,7 @@ if [ "$json_list" != "{ - { - \"os-version\": \"phony-fedora-no-format\", - \"full-name\": \"Phony Fedora\", -+ \"arch\": \"x86_64\", - \"size\": 1073741824, - \"notes\": { - \"C\": \"Phony Fedora look-alike used for testing.\" -@@ -163,6 +175,7 @@ if [ "$json_list" != "{ - { - \"os-version\": \"phony-ubuntu\", - \"full-name\": \"Phony Ubuntu\", -+ \"arch\": \"x86_64\", - \"size\": 536870912, - \"notes\": { - \"C\": \"Phony Ubuntu look-alike used for testing.\" -@@ -172,6 +185,7 @@ if [ "$json_list" != "{ - { - \"os-version\": \"phony-windows\", - \"full-name\": \"Phony Windows\", -+ \"arch\": \"x86_64\", - \"size\": 536870912, - \"notes\": { - \"C\": \"Phony Windows look-alike used for testing.\" --- -1.8.5.3 - diff --git a/0092-builder-split-INI-C-OCaml-glue-code-in-own-module.patch b/0092-builder-split-INI-C-OCaml-glue-code-in-own-module.patch deleted file mode 100644 index 2d47bd7..0000000 --- a/0092-builder-split-INI-C-OCaml-glue-code-in-own-module.patch +++ /dev/null @@ -1,171 +0,0 @@ -From 623c36262943f6f1e3c3df56d5c56e34ed658e48 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Mon, 24 Feb 2014 15:08:03 +0100 -Subject: [PATCH] builder: split INI C <-> OCaml glue code in own module - -Move in an own module the code which calls the C -virt_builder_parse_index and does the array -> list conversion of the -result. This way this code can be easily called also in places different -than Index_parser without the need to copy the types mapping, etc. - -Just code motion, no actual behaviour changes. - -(cherry picked from commit 8ed905c7e6a837887a758417bdfd1822b86a214f) ---- - builder/Makefile.am | 3 +++ - builder/index_parser.ml | 17 +---------------- - builder/ini_reader.ml | 38 ++++++++++++++++++++++++++++++++++++++ - builder/ini_reader.mli | 24 ++++++++++++++++++++++++ - po/POTFILES-ml | 1 + - 5 files changed, 67 insertions(+), 16 deletions(-) - create mode 100644 builder/ini_reader.ml - create mode 100644 builder/ini_reader.mli - -diff --git a/builder/Makefile.am b/builder/Makefile.am -index 8c48be5..a72b7ac 100644 ---- a/builder/Makefile.am -+++ b/builder/Makefile.am -@@ -46,6 +46,8 @@ SOURCES = \ - index_parser.mli \ - index_parser.ml \ - index-parser-c.c \ -+ ini_reader.mli \ -+ ini_reader.ml \ - list_entries.mli \ - list_entries.ml \ - paths.ml \ -@@ -94,6 +96,7 @@ OBJECTS = \ - pxzcat.cmx \ - setlocale-c.o \ - setlocale.cmx \ -+ ini_reader.cmx \ - paths.cmx \ - get_kernel.cmx \ - downloader.cmx \ -diff --git a/builder/index_parser.ml b/builder/index_parser.ml -index de4d72e..9fd9cda 100644 ---- a/builder/index_parser.ml -+++ b/builder/index_parser.ml -@@ -102,15 +102,6 @@ let print_entry chan (name, { printable_name = printable_name; - ) notes; - if hidden then fp "hidden=true\n" - --(* Types returned by the C index parser. *) --type sections = section array --and section = string * fields (* [name] + fields *) --and fields = field array --and field = string * string option * string (* key + subkey + value *) -- --(* Calls yyparse in the C code. *) --external parse_index : string -> sections = "virt_builder_parse_index" -- - let get_index ~prog ~debug ~downloader ~sigchecker source = - let corrupt_file () = - eprintf (f_"\nThe index file downloaded from '%s' is corrupt.\nYou need to ask the supplier of this file to fix it and upload a fixed version.\n") -@@ -128,16 +119,10 @@ let get_index ~prog ~debug ~downloader ~sigchecker source = - Sigchecker.verify sigchecker tmpfile; - - (* Try parsing the file. *) -- let sections = parse_index tmpfile in -+ let sections = Ini_reader.read_ini tmpfile in - if delete_tmpfile then - (try Unix.unlink tmpfile with _ -> ()); - -- let sections = Array.to_list sections in -- let sections = List.map ( -- fun (n, fields) -> -- n, Array.to_list fields -- ) sections in -- - (* Check for repeated os-version names. *) - let nseen = Hashtbl.create 13 in - List.iter ( -diff --git a/builder/ini_reader.ml b/builder/ini_reader.ml -new file mode 100644 -index 0000000..fbd4d2f ---- /dev/null -+++ b/builder/ini_reader.ml -@@ -0,0 +1,38 @@ -+(* virt-builder -+ * Copyright (C) 2013-2014 Red Hat Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ *) -+ -+type sections = section list -+and section = string * fields (* [name] + fields *) -+and fields = field list -+and field = string * string option * string (* key + subkey + value *) -+ -+(* Types returned by the C index parser. *) -+type c_sections = c_section array -+and c_section = string * c_fields (* [name] + fields *) -+and c_fields = field array -+ -+(* Calls yyparse in the C code. *) -+external parse_index : string -> c_sections = "virt_builder_parse_index" -+ -+let read_ini file = -+ let sections = parse_index file in -+ let sections = Array.to_list sections in -+ List.map ( -+ fun (n, fields) -> -+ n, Array.to_list fields -+ ) sections -diff --git a/builder/ini_reader.mli b/builder/ini_reader.mli -new file mode 100644 -index 0000000..992a1cb ---- /dev/null -+++ b/builder/ini_reader.mli -@@ -0,0 +1,24 @@ -+(* virt-builder -+ * Copyright (C) 2013-2014 Red Hat Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ *) -+ -+type sections = section list -+and section = string * fields (* [name] + fields *) -+and fields = field list -+and field = string * string option * string (* key + subkey + value *) -+ -+val read_ini : string -> sections -diff --git a/po/POTFILES-ml b/po/POTFILES-ml -index ea357e4..94230f8 100644 ---- a/po/POTFILES-ml -+++ b/po/POTFILES-ml -@@ -3,6 +3,7 @@ builder/cmdline.ml - builder/downloader.ml - builder/get_kernel.ml - builder/index_parser.ml -+builder/ini_reader.ml - builder/list_entries.ml - builder/paths.ml - builder/pxzcat.ml --- -1.8.5.3 - diff --git a/0093-builder-allow-no-key-as-key-in-Sigchecker.patch b/0093-builder-allow-no-key-as-key-in-Sigchecker.patch deleted file mode 100644 index d5921fa..0000000 --- a/0093-builder-allow-no-key-as-key-in-Sigchecker.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 07ee461bda703b988346ca0bec39a4b5cbe19a21 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Tue, 25 Feb 2014 17:29:06 +0100 -Subject: [PATCH] builder: allow "no key" as key in Sigchecker - -Additional way to distinguish no actual key available for signature -checking; make sure to not allow signing in such situation. - -(cherry picked from commit c09f5bbc708bbed772570ba63a706efcedf68cac) ---- - builder/sigchecker.ml | 8 ++++++++ - builder/sigchecker.mli | 1 + - 2 files changed, 9 insertions(+) - -diff --git a/builder/sigchecker.ml b/builder/sigchecker.ml -index 7459e4b..67d1600 100644 ---- a/builder/sigchecker.ml -+++ b/builder/sigchecker.ml -@@ -97,6 +97,7 @@ ZvXkQ3FVJwZoLmHw47vvlVpLD/4gi1SuHWieRvZ+UdDq00E348pm - " - - type gpgkey_type = -+ | No_Key - | Fingerprint of string - | KeyFile of string - -@@ -127,6 +128,11 @@ let rec create ~debug ~gpg ~gpgkey ~check_signature = - (* Create a temporary directory for gnupg. *) - let tmpdir = Mkdtemp.mkdtemp (Filename.temp_dir_name // "vb.gpghome.XXXXXX") in - rmdir_on_exit tmpdir; -+ (* Make sure we have no check_signature=true with no actual key. *) -+ let check_signature, gpgkey = -+ match check_signature, gpgkey with -+ | true, No_Key -> false, No_Key -+ | x, y -> x, y in - let fingerprint = - if check_signature then ( - (* Run gpg so it can setup its own home directory, failing if it -@@ -141,6 +147,8 @@ let rec create ~debug ~gpg ~gpgkey ~check_signature = - exit 1 - ); - match gpgkey with -+ | No_Key -> -+ assert false - | KeyFile kf -> - let status_file = import_keyfile gpg tmpdir debug kf in - let status = read_whole_file status_file in -diff --git a/builder/sigchecker.mli b/builder/sigchecker.mli -index f4e817e..ab44a5c 100644 ---- a/builder/sigchecker.mli -+++ b/builder/sigchecker.mli -@@ -21,6 +21,7 @@ val default_fingerprint : string - type t - - type gpgkey_type = -+ | No_Key - | Fingerprint of string - | KeyFile of string - --- -1.8.5.3 - diff --git a/0094-builder-use-Sigchecker.gpgkey_type-for-the-fingerpri.patch b/0094-builder-use-Sigchecker.gpgkey_type-for-the-fingerpri.patch deleted file mode 100644 index 87f8aa7..0000000 --- a/0094-builder-use-Sigchecker.gpgkey_type-for-the-fingerpri.patch +++ /dev/null @@ -1,113 +0,0 @@ -From 32e1da26d4ab6e2eea0e08c4b26fd9e988c18edf Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Tue, 25 Feb 2014 17:29:07 +0100 -Subject: [PATCH] builder: use Sigchecker.gpgkey_type for the fingerprint - -Use Sigchecker.gpgkey_type instead of just string as type in the -sources list; adapt the listing code (and its expected output) to that. - -No behaviour change which eases a bit the addition of new sources with -other key types. - -(cherry picked from commit ad38e68c34d3d15fb02901e3fbdd68bfe9887ebf) ---- - builder/builder.ml | 9 ++++++--- - builder/list_entries.ml | 22 +++++++++++++++++----- - builder/list_entries.mli | 2 +- - builder/test-virt-builder-list.sh | 4 ++-- - 4 files changed, 26 insertions(+), 11 deletions(-) - -diff --git a/builder/builder.ml b/builder/builder.ml -index ec1fc2b..f4d70b1 100644 ---- a/builder/builder.ml -+++ b/builder/builder.ml -@@ -136,13 +136,16 @@ let main () = - - (* Download the sources. *) - let downloader = Downloader.create ~debug ~curl ~cache in -+ let sources = List.map ( -+ fun (source, fingerprint) -> -+ source, Sigchecker.Fingerprint fingerprint -+ ) sources in - let index : Index_parser.index = - List.concat ( - List.map ( -- fun (source, fingerprint) -> -+ fun (source, key) -> - let sigchecker = -- Sigchecker.create ~debug ~gpg ~check_signature -- ~gpgkey:(Sigchecker.Fingerprint fingerprint) in -+ Sigchecker.create ~debug ~gpg ~check_signature ~gpgkey:key in - Index_parser.get_index ~prog ~debug ~downloader ~sigchecker source - ) sources - ) in -diff --git a/builder/list_entries.ml b/builder/list_entries.ml -index edf7dfb..476bf14 100644 ---- a/builder/list_entries.ml -+++ b/builder/list_entries.ml -@@ -65,9 +65,15 @@ and list_entries_long ~sources index = - | Some locale -> split_locale locale in - - List.iter ( -- fun (source, fingerprint) -> -+ fun (source, key) -> - printf (f_"Source URI: %s\n") source; -- printf (f_"Fingerprint: %s\n") fingerprint; -+ (match key with -+ | Sigchecker.No_Key -> () -+ | Sigchecker.Fingerprint fp -> -+ printf (f_"Fingerprint: %s\n") fp; -+ | Sigchecker.KeyFile kf -> -+ printf (f_"Key: %s\n") kf; -+ ); - printf "\n" - ) sources; - -@@ -160,10 +166,16 @@ and list_entries_json ~sources index = - printf " \"version\": %d,\n" 1; - printf " \"sources\": [\n"; - iteri ( -- fun i (source, fingerprint) -> -+ fun i (source, key) -> - printf " {\n"; -- printf " \"uri\": \"%s\",\n" source; -- printf " \"fingerprint\": \"%s\"\n" fingerprint; -+ (match key with -+ | Sigchecker.No_Key -> () -+ | Sigchecker.Fingerprint fp -> -+ printf " \"fingerprint\": \"%s\",\n" fp; -+ | Sigchecker.KeyFile kf -> -+ printf " \"key\": \"%s\",\n" kf; -+ ); -+ printf " \"uri\": \"%s\"\n" source; - printf " }%s\n" (trailing_comma i (List.length sources)) - ) sources; - printf " ],\n"; -diff --git a/builder/list_entries.mli b/builder/list_entries.mli -index e7c32f1..b53ccec 100644 ---- a/builder/list_entries.mli -+++ b/builder/list_entries.mli -@@ -16,4 +16,4 @@ - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - *) - --val list_entries : list_format:([ `Short | `Long | `Json ]) -> sources:(string * string) list -> Index_parser.index -> unit -+val list_entries : list_format:([ `Short | `Long | `Json ]) -> sources:(string * Sigchecker.gpgkey_type) list -> Index_parser.index -> unit -diff --git a/builder/test-virt-builder-list.sh b/builder/test-virt-builder-list.sh -index 7174152..6db9b78 100755 ---- a/builder/test-virt-builder-list.sh -+++ b/builder/test-virt-builder-list.sh -@@ -117,8 +117,8 @@ if [ "$json_list" != "{ - \"version\": 1, - \"sources\": [ - { -- \"uri\": \"$VIRT_BUILDER_SOURCE\", -- \"fingerprint\": \"F777 4FB1 AD07 4A7E 8C87 67EA 9173 8F73 E1B7 68A0\" -+ \"fingerprint\": \"F777 4FB1 AD07 4A7E 8C87 67EA 9173 8F73 E1B7 68A0\", -+ \"uri\": \"$VIRT_BUILDER_SOURCE\" - } - ], - \"templates\": [ --- -1.8.5.3 - diff --git a/0095-builder-add-functions-to-read-XDG_CONFIG_DIRS-and-XD.patch b/0095-builder-add-functions-to-read-XDG_CONFIG_DIRS-and-XD.patch deleted file mode 100644 index 4d13ec4..0000000 --- a/0095-builder-add-functions-to-read-XDG_CONFIG_DIRS-and-XD.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 145a3367cb4ed5d46a0bf3d9153a675bce0cb49c Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Tue, 25 Feb 2014 17:29:08 +0100 -Subject: [PATCH] builder: add functions to read XDG_CONFIG_DIRS and - XDG_CONFIG_PATH - -(cherry picked from commit a21da3c8013e2658b41de962c4fb98df3c8896e4) ---- - builder/paths.ml | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - -diff --git a/builder/paths.ml b/builder/paths.ml -index 66e8922..e4f0c7b 100644 ---- a/builder/paths.ml -+++ b/builder/paths.ml -@@ -24,3 +24,18 @@ let xdg_cache_home = - try Some (Sys.getenv "HOME" // ".cache" // "virt-builder") - with Not_found -> - None (* no cache directory *) -+ -+let xdg_config_home ~prog = -+ try Some (Sys.getenv "XDG_CONFIG_HOME" // prog) -+ with Not_found -> -+ try Some (Sys.getenv "HOME" // ".config" // prog) -+ with Not_found -> -+ None (* no config directory *) -+ -+let xdg_config_dirs ~prog = -+ let dirs = -+ try Sys.getenv "XDG_CONFIG_DIRS" -+ with Not_found -> "/etc/xdg" in -+ let dirs = string_nsplit ":" dirs in -+ let dirs = List.filter (fun x -> x <> "") dirs in -+ List.map (fun x -> x // prog) dirs --- -1.8.5.3 - diff --git a/0096-builder-extract-the-default-key-to-file.patch b/0096-builder-extract-the-default-key-to-file.patch deleted file mode 100644 index 7d73a96..0000000 --- a/0096-builder-extract-the-default-key-to-file.patch +++ /dev/null @@ -1,87 +0,0 @@ -From f1d2b2b6006fc6a84619ad8f2327623b81d63c54 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Tue, 25 Feb 2014 17:29:09 +0100 -Subject: [PATCH] builder: extract the default key to file - -This is basically default_pubkey from sigchecker.ml, just extracted as -file. Not used right now, but will be in the future. - -(cherry picked from commit a3f1ac9a2dacd96003688e8125dae7d012d3b942) ---- - builder/libguestfs.gpg | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 64 insertions(+) - create mode 100644 builder/libguestfs.gpg - -diff --git a/builder/libguestfs.gpg b/builder/libguestfs.gpg -new file mode 100644 -index 0000000..306a234 ---- /dev/null -+++ b/builder/libguestfs.gpg -@@ -0,0 +1,64 @@ -+-----BEGIN PGP PUBLIC KEY BLOCK----- -+Version: GnuPG v1.4.14 (GNU/Linux) -+ -+mQINBE6UMMEBEADM811hfTulaF4JpkVpAI10FImyb4ArvOiu8NdcUwTFo+cyWno3 -+U85B86H1Bsk/LgLTYtthSrTgsCtdxy+i5OaMjxZDIwKQ2+IYI3FCn9T3Mn28Idyh -+kLHzrO9ph0Dv0BNfrlDZhQEC53aAFe/QxN7+A49BNBV7D1VAOOCsHjxMEDzcZkCa -+oCrtXw1aNm2vkkj5ukbfukHAyLcQL7kow0qKPSVa1G4lfQP0WiG259Ydy+sUmbVb -+TGdb6MEC84PQRDuw6/ZeoV04tn7ZNtQEMOS0uiciHOGfr2hBxQf9VIPNrHg42yaL -+dOv51D99GuaxZ9E0HSoH/RwB1oXgd6rFdqVNYaBIQnnkwJANUEeGBArtIOZNCADT -+Bt8vkSDm+lLEAFS+V8CACyW/LMIrGCvLdHeqtoAv0GDVyR2GPxldYfdtEmCUMWcb -+Jlf71V9iAse2gUdoiHp5FfpGMkA5j7idKuxIws11XxRZJXXbBqiBqmVEAQ/v0m6p -+kdo0MYTHydmecLuUK2bAGhpysfX97EfTSrxfrYphYWjTfKRD9GrADeZNfuz1DbKs -+7LSqVaQJSjQrfgAwcnZLRaU0V4P5zxiz50gz1Aj3AZRL+Y3meZenzZTXcLFdnusg -+wUfhhCuL3tluMtEh6tznumyxb43WO1yLwj6J6LtveiuJN1Z+KSQ6OieZcwARAQAB -+tCVSaWNoYXJkIFcuTS4gSm9uZXMgPHJpY2hAYW5uZXhpYS5vcmc+iQI4BBMBAgAi -+BQJOlDDBAhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRCRc49z4bdooHQY -+D/wJLklSZNyXIW+rG5sUbg7j9cTIF5p/lB9kI2yx6KodJp/2knKyvnmzz0gBw/OE -+HL4E4UW26oWKo+36I8wkBnuGa6UtANeITcJqFE19VpHEXHsxre64jNQnO8/w748W -+1ROW+Ry43xmrlRWKuCm4oPYUzlp0fq9ATAne8eblfG+NOs8DYuA8xZNQzFaI2kDC -+QLD4YoXLoNsP27Koga36b0KwxPFD9tyVZiu9XDH/3hMN7Nb15B66PFr+HcMmQ67G -+nUIN5ulcIwj38i40cyaTs1VRheOzTHXE/a6Q2AhMKiKqOoEjQ73/mV7cAVoPtM3o -+83Q/8aVKBH0bVRwAeV1tju6b14fqKoG0zNBEcXdlSkht6ScxJYIc/LPUxAMDwgSE -+OWshjmeRzKXypBbHn/DP8QVyM2gk5wY+mMSH7MpR0p/hgj+rFO8H9L7pC4dCog3E -+qzrYhRN+TaP6MPH3WkOwPH4d4IfQRFnHp+VPYPijKEiLrUl/o8k3DyAanAPBpJ/x -+na4wXAjlFBctOq6g+SrCUiHpwk7b2YNwGgr5Vl3GmZELzK/G8gg3uJYKQ9Bpv16t -+WWOz+IFiOFa0UULeo0QPmFAIMZiDojNsY1SwBKB3ZL1YWZezgMdQAbpze/IXoSt7 -+zxWJoKH2jK7q9mvFiaY12l2YnKuCcegWVAViLxRpBnrbz7QmUmljaGFyZCBXLk0u -+IEpvbmVzIDxyam9uZXNAcmVkaGF0LmNvbT6JAjgEEwECACIFAk6UOQsCGwMGCwkI -+BwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEJFzj3Pht2igIUYQAKomI0edLakahsUQ -+MxOZuhBbXJ4/VWF8bXYChDNPKvJp5nB7fBXujJ+39cIUM5fe2ViO6qSDpFC29imx -+F5pPbAqspZBPBkLLiZLji8R42hGarntdtTW0UWSBpq+nC5+G1psrnATI3uXGNxKQ -+R99c5HoMY7dBC2Y8TCGE64NINZ/XVh472s6IGLPn8MTn26YdRKC9BrVkCFMP2OBr -+6D4IprnyTAWAzb68ew20QmyWO+NBi9MplaDNQVl8PIOgfpyWlkgX1z9m67pcSDkw -+46hksp0yuOD1VwR4iVZ2/CmIsGRUlx41vWD6BIp9KxKyDIU1CYTRhq72dahHsl/8 -+BjCndV5PO0GphqfCzmCv4DXjUwmrMTbH/GFnt5rfwcMcXUgcK0vV9vQ2SOU56Zd1 -+fb27ZCFJKZc0Fu8krwFldCp/NYILf6ogUL/C1hfuCGSSuyDVY16Gg3dla1x+6zpF -+asnWQlaw8xT5LlMWvTZs5WsoSVHu7dVZWlgxINP++hlZrTz/S8l38yyQ15YFFl3W -+9M7dzkegOeDTPfx6B89WgfvfJjA/D0/FYxxWPXEtrn9DlJ4daEJqNsrvfLErz9R8 -+4IQmfmhR93j+rdotner+6keC/wVByEfbW1wmXtmFKXQ6srdpj8VKRFrvkyXVgepM -+DypLgRH2v7lL2kdWhUu2y4EAgrwzuQINBE6UMMEBEADxQxMgUuDrw5GT4tqARTPI -+SSdNcUsRxRhVA8srYOyECliE+B3TwcRDFBs+MyPFJVEuX8fi4eGj/AK5t1GHerfk -+orUGlz72q4c7LLhkfZrsuJbk2dgkjvldKJnIazQJa6epGLqdsE5RlmSgwedIbtMd -+naGJBQH8aKP/Wi1+wUxsm5N3p7+R2WRx48VfpEhYB+Zf/FkFm1Ycjwh57KQ0+OHw -+ykf8VfMisxuH30tDxOCV+VptWKfOF2rDNdaNPWhij2YIjhJXRpkuRR+1PpI4jLaD -+JxcVZmG/0zucacupUN2g5OUH59ySU/totD6YMnmp3FONoyF1uIEJo6Vs30npHGkO -+XgBo3Pxt7oLJeykLPtdSLgm3cwXIYMWarVsAkKNXitQIVGpVRLeaK373VwmXFqoi -+M2SMHeawTUdOORFjpQzkknlJWM1TmUVtHHKt8Pl9+/5+wXKyt2IDdcUkMrB6K5qF -+fb7EwVhoI8ehJQK+eeDCjFwCAiwB3iV8JlyW+tEU7JuyXOQlwY1VWm/WqMD8gaRi -+rT+RFDFliZ3tQbW2pqUoZBROV5HN4tieDfwxGKCvk6Tsdb30zA9DPQp93+238bYf -+312sg9R+CD0AqxoxFG5FJu4HShcPRrPnYtRZqKRe40GDWvBEArXZprwL1qrP+Kl/ -+mRrEQpxAGIoFG8HbVvD3EQARAQABiQIfBBgBAgAJBQJOlDDBAhsMAAoJEJFzj3Ph -+t2igSLQP/2uIrAY2CDr0kWBJiD3TztiHy8IdxwUpyTBTebwmAbi44/EvtJfIisrG -+YjKIEv/w0E61gO7O1JBG4+IG93W+v9fTT/e39JMyxsYqoZZHUhP11Okx5grDS5b0 -+O8VXOmXVRMdVNfstRBr10HD9uNDq7ruKD18TxYTwN0GPD4gj1dbHQDR77Tr5cyBs -+6Ou5PBOH4r3qcqf/cJUSMeUUu75xLwixux6E7tD2S+t6F07wlWxntUcPtzyAHj20 -+J89orUC+dT6r6MypBoI0jdJCp9JPGtR7i+fE5Gm4E5+AUSubLPtZGRY9Um2eMoS2 -+DnQpGOKx1VvsixR/Kw44j2tRAvmYMS4iDKcuZU+nZ+xokAgObILj/b9n/Qe2/fXy -+CFdcgSvbm+dV1fZxsdMF/P9OU8aqdT9A9Fv5y+cDMEg4DVnhwMJTxGh/TCkw/H+A -+frHEtRc98lSQN5odpITNG17mG6JOdHM+wA57qHH0uy4+5RsbyAJahcdBcmObK/RF -+i4WZlThpbHftX5O/LH98aYQ2fJayIxv1EAjzOBOQ0MfBHI0KCJR1pysEisX28sJA -+Ic73gnJJ3BLZbqfBRgxjNMNroxC+5Tw6uPGFHa3YnuIAxxw0HcDVZ9vnTWBWFPGw -+ZvXkQ3FVJwZoLmHw47vvlVpLD/4gi1SuHWieRvZ+UdDq00E348pm -+=neBW -+-----END PGP PUBLIC KEY BLOCK----- --- -1.8.5.3 - diff --git a/0097-builder-switch-sources-to-.conf-files.patch b/0097-builder-switch-sources-to-.conf-files.patch deleted file mode 100644 index ca17120..0000000 --- a/0097-builder-switch-sources-to-.conf-files.patch +++ /dev/null @@ -1,428 +0,0 @@ -From 53596d0926910a0b5c331479d45998bb1d8eb016 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Tue, 25 Feb 2014 17:29:10 +0100 -Subject: [PATCH] builder: switch sources to .conf files - -Introduce and use simple .conf files to configure the sources of indexes -for virt-builder. The location of these files is in XDG_CONFIG_DIRS / -XDG_CONFIG_HOME, so it can be easily overridden. - -There are three .conf(.in) files shipped with this commit: -- "test-index.conf.in" (in "test-config"), which points to the - "test-index" index (used in tests only); the tests are adapted to - point to the hierarchy containing this .conf -- "libguestfs.conf.in" (in "test-website"), which points to the local - "index.asc" (i.e. the offline copy of the libguestfs.org index); - run(.in) will point to the hierarchy providing this .conf -- "libguestfs.conf.in" (directly among the other sources), which points - to the online "index.asc" and it is installed in sysconfdir, along - with the key of this repository - -The tests are adapted, other than to the different way to pick sources, -to the different output of --list, as "test-index" is not signed. - -(cherry picked from commit f4990bef1c2cffb878f472023b01895ee326e4b3) ---- - .gitignore | 3 + - builder/Makefile.am | 10 +- - builder/builder.ml | 10 ++ - builder/libguestfs.conf.in | 3 + - builder/sources.ml | 122 +++++++++++++++++++++ - builder/sources.mli | 25 +++++ - .../virt-builder/repos.d/test-index.conf.in | 2 + - builder/test-virt-builder-list.sh | 8 +- - builder/test-virt-builder-planner.sh | 2 +- - builder/test-virt-builder.sh | 2 +- - .../virt-builder/repos.d/libguestfs.conf.in | 3 + - configure.ac | 9 ++ - po/POTFILES-ml | 1 + - run.in | 6 +- - 14 files changed, 195 insertions(+), 11 deletions(-) - create mode 100644 builder/libguestfs.conf.in - create mode 100644 builder/sources.ml - create mode 100644 builder/sources.mli - create mode 100644 builder/test-config/virt-builder/repos.d/test-index.conf.in - create mode 100644 builder/test-website/virt-builder/repos.d/libguestfs.conf.in - -diff --git a/.gitignore b/.gitignore -index 2d61d77..02bfecc 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -61,10 +61,13 @@ Makefile.in - /builder/index-parse.c - /builder/index-parse.h - /builder/index-scan.c -+/builder/libguestfs.conf - /builder/*.qcow2 - /builder/stamp-virt-builder.pod - /builder/stamp-virt-index-validate.pod -+/builder/test-config/virt-builder/repos.d/test-index.conf - /builder/test-index -+/builder/test-website/virt-builder/repos.d/libguestfs.conf - /builder/virt-builder - /builder/virt-builder.1 - /builder/virt-index-validate -diff --git a/builder/Makefile.am b/builder/Makefile.am -index a72b7ac..f0cb1dd 100644 ---- a/builder/Makefile.am -+++ b/builder/Makefile.am -@@ -58,7 +58,9 @@ SOURCES = \ - setlocale.mli \ - setlocale-c.c \ - sigchecker.mli \ -- sigchecker.ml -+ sigchecker.ml \ -+ sources.mli \ -+ sources.ml - - man_MANS = - noinst_DATA = -@@ -103,6 +105,7 @@ OBJECTS = \ - sigchecker.cmx \ - index_parser.cmx \ - list_entries.cmx \ -+ sources.cmx \ - cmdline.cmx \ - builder.cmx - -@@ -221,6 +224,11 @@ DISTCLEANFILES = .depend - - .PHONY: depend docs - -+# virt-builder's default repository -+ -+repoconfdir = $(sysconfdir)/xdg/virt-builder/repos.d -+repoconf_DATA = libguestfs.conf libguestfs.gpg -+ - # Build a small C index validator program. - bin_PROGRAMS = virt-index-validate - -diff --git a/builder/builder.ml b/builder/builder.ml -index f4d70b1..917e298 100644 ---- a/builder/builder.ml -+++ b/builder/builder.ml -@@ -136,10 +136,20 @@ let main () = - - (* Download the sources. *) - let downloader = Downloader.create ~debug ~curl ~cache in -+ let repos = Sources.read_sources ~prog ~debug in -+ let repos = List.map ( -+ fun { Sources.uri = uri; Sources.gpgkey = gpgkey } -> -+ let gpgkey = -+ match gpgkey with -+ | None -> Sigchecker.No_Key -+ | Some key -> Sigchecker.KeyFile key in -+ uri, gpgkey -+ ) repos in - let sources = List.map ( - fun (source, fingerprint) -> - source, Sigchecker.Fingerprint fingerprint - ) sources in -+ let sources = List.append repos sources in - let index : Index_parser.index = - List.concat ( - List.map ( -diff --git a/builder/libguestfs.conf.in b/builder/libguestfs.conf.in -new file mode 100644 -index 0000000..633a0ab ---- /dev/null -+++ b/builder/libguestfs.conf.in -@@ -0,0 +1,3 @@ -+[libguestfs.org] -+uri=http://libguestfs.org/download/builder/index.asc -+gpgkey=file://@SYSCONFDIR@/xdg/virt-builder/repos.d/libguestfs.gpg -diff --git a/builder/sources.ml b/builder/sources.ml -new file mode 100644 -index 0000000..fd0b236 ---- /dev/null -+++ b/builder/sources.ml -@@ -0,0 +1,122 @@ -+(* virt-builder -+ * Copyright (C) 2014 Red Hat Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ *) -+ -+open Common_gettext.Gettext -+open Common_utils -+ -+open Printf -+open Unix -+ -+type source = { -+ name : string; -+ uri : string; -+ gpgkey : string option; -+} -+ -+let parse_conf ~prog ~debug file = -+ if debug then ( -+ eprintf (f_"%s: trying to read %s\n") prog file; -+ ); -+ let sections = Ini_reader.read_ini file in -+ -+ let sources = List.fold_right ( -+ fun (n, fields) acc -> -+ let give_source n fields = -+ let fields = List.map (fun (k, sk, v) -> (k, sk), v) fields in -+ let uri = -+ try List.assoc ("uri", None) fields -+ with Not_found as ex -> -+ eprintf (f_"%s: no 'uri' entry for '%s' in %s, skipping it\n") prog n file; -+ raise ex in -+ let gpgkey = -+ let k = -+ try Some (URI.parse_uri (List.assoc ("gpgkey", None) fields)) with -+ | Not_found -> None -+ | Invalid_argument "URI.parse_uri" as ex -> -+ if debug then ( -+ eprintf (f_"%s: '%s' has invalid gpgkey URI\n") prog n; -+ ); -+ raise ex in -+ match k with -+ | None -> None -+ | Some uri -> -+ (match uri.URI.protocol with -+ | "file" -> Some uri.URI.path -+ | _ -> -+ if debug then ( -+ eprintf (f_"%s: '%s' has non-local gpgkey URI\n") prog n; -+ ); -+ None -+ ) in -+ { -+ name = n; uri = uri; gpgkey = gpgkey; -+ } -+ in -+ try (give_source n fields) :: acc -+ with Not_found | Invalid_argument _ -> acc -+ ) sections [] in -+ -+ if debug then ( -+ eprintf (f_"%s: ... read %d sources\n") prog (List.length sources); -+ ); -+ -+ sources -+ -+let merge_sources current_sources new_sources = -+ List.fold_right ( -+ fun source acc -> -+ if List.exists (fun { name = n } -> n = source.name) acc then -+ acc -+ else -+ source :: acc -+ ) new_sources current_sources -+ -+let filter_filenames filename = -+ let suffix = ".conf" in -+ let n = String.length filename in -+ let ns = String.length suffix in -+ n >= ns && String.sub filename (n - ns) ns = suffix -+ -+let read_sources ~prog ~debug = -+ let dirs = Paths.xdg_config_dirs ~prog in -+ let dirs = -+ match Paths.xdg_config_home ~prog with -+ | None -> dirs -+ | Some dir -> dir :: dirs in -+ let dirs = List.map (fun x -> x // "repos.d") dirs in -+ List.fold_right ( -+ fun dir acc -> -+ let files = -+ try List.filter filter_filenames (Array.to_list (Sys.readdir dir)) -+ with Sys_error _ -> [] in -+ let files = List.map (fun x -> dir // x) files in -+ List.fold_left ( -+ fun acc file -> -+ try merge_sources acc (parse_conf ~prog ~debug file) with -+ | Unix_error (code, fname, _) -> -+ if debug then ( -+ eprintf (f_"%s: file error: %s: %s\n") prog fname (error_message code) -+ ); -+ acc -+ | Invalid_argument msg -> -+ if debug then ( -+ eprintf (f_"%s: internal error: invalid argument: %s\n") prog msg -+ ); -+ acc -+ ) acc files -+ ) dirs [] -diff --git a/builder/sources.mli b/builder/sources.mli -new file mode 100644 -index 0000000..76feeda ---- /dev/null -+++ b/builder/sources.mli -@@ -0,0 +1,25 @@ -+(* virt-builder -+ * Copyright (C) 2014 Red Hat Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ *) -+ -+type source = { -+ name : string; -+ uri : string; -+ gpgkey : string option; -+} -+ -+val read_sources : prog:string -> debug:bool -> source list -diff --git a/builder/test-config/virt-builder/repos.d/test-index.conf.in b/builder/test-config/virt-builder/repos.d/test-index.conf.in -new file mode 100644 -index 0000000..3755e75 ---- /dev/null -+++ b/builder/test-config/virt-builder/repos.d/test-index.conf.in -@@ -0,0 +1,2 @@ -+[test-index] -+uri=file://@abs_top_srcdir@/builder/test-index -diff --git a/builder/test-virt-builder-list.sh b/builder/test-virt-builder-list.sh -index 6db9b78..2f9b319 100755 ---- a/builder/test-virt-builder-list.sh -+++ b/builder/test-virt-builder-list.sh -@@ -23,7 +23,7 @@ set -e - - abs_builddir=$(pwd) - --export VIRT_BUILDER_SOURCE=file://$abs_builddir/test-index -+export XDG_CONFIG_DIRS="$abs_builddir/test-config" - - short_list=$($VG ./virt-builder --no-check-signature --no-cache --list) - -@@ -41,8 +41,7 @@ fi - - long_list=$(./virt-builder --no-check-signature --no-cache --list --long) - --if [ "$long_list" != "Source URI: $VIRT_BUILDER_SOURCE --Fingerprint: F777 4FB1 AD07 4A7E 8C87 67EA 9173 8F73 E1B7 68A0 -+if [ "$long_list" != "Source URI: file://$abs_builddir/test-index - - os-version: phony-debian - Full name: Phony Debian -@@ -117,8 +116,7 @@ if [ "$json_list" != "{ - \"version\": 1, - \"sources\": [ - { -- \"fingerprint\": \"F777 4FB1 AD07 4A7E 8C87 67EA 9173 8F73 E1B7 68A0\", -- \"uri\": \"$VIRT_BUILDER_SOURCE\" -+ \"uri\": \"file://$abs_builddir/test-index\" - } - ], - \"templates\": [ -diff --git a/builder/test-virt-builder-planner.sh b/builder/test-virt-builder-planner.sh -index 738b299..386de5c 100755 ---- a/builder/test-virt-builder-planner.sh -+++ b/builder/test-virt-builder-planner.sh -@@ -21,7 +21,7 @@ set -e - - abs_builddir=$(pwd) - --export VIRT_BUILDER_SOURCE=file://$abs_builddir/test-index -+export XDG_CONFIG_DIRS="$abs_builddir/test-config" - - if [ ! -f fedora.xz -o ! -f fedora.qcow2 -o ! -f fedora.qcow2.xz ]; then - echo "$0: test skipped because there is no fedora.xz, fedora.qcow2 or fedora.qcow2.xz in the build directory" -diff --git a/builder/test-virt-builder.sh b/builder/test-virt-builder.sh -index 3c8eb60..85a7888 100755 ---- a/builder/test-virt-builder.sh -+++ b/builder/test-virt-builder.sh -@@ -21,7 +21,7 @@ set -e - - abs_builddir=$(pwd) - --export VIRT_BUILDER_SOURCE=file://$abs_builddir/test-index -+export XDG_CONFIG_DIRS="$abs_builddir/test-config" - - if [ ! -f fedora.xz ]; then - echo "$0: test skipped because there is no fedora.xz in the build directory" -diff --git a/builder/test-website/virt-builder/repos.d/libguestfs.conf.in b/builder/test-website/virt-builder/repos.d/libguestfs.conf.in -new file mode 100644 -index 0000000..7bbc28d ---- /dev/null -+++ b/builder/test-website/virt-builder/repos.d/libguestfs.conf.in -@@ -0,0 +1,3 @@ -+[libguestfs.org] -+uri=file://@abs_top_srcdir@/builder/website/index.asc -+gpgkey=file://@abs_top_srcdir@/builder/libguestfs.gpg -diff --git a/configure.ac b/configure.ac -index 56b6b37..e05ad5f 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1575,6 +1575,12 @@ dnl http://lists.fedoraproject.org/pipermail/devel/2010-November/146343.html - LIBTOOL='bash $(top_srcdir)/libtool-kill-dependency_libs.sh $(top_builddir)/libtool' - AC_SUBST([LIBTOOL]) - -+dnl Work around autoconf's lack of expanded variables. -+eval my_sysconfdir="\"[$]sysconfdir\"" -+eval my_sysconfdir="\"$my_sysconfdir\"" -+SYSCONFDIR="${my_sysconfdir}" -+AC_SUBST(SYSCONFDIR) -+ - dnl Produce output files. - - AC_CONFIG_HEADERS([config.h]) -@@ -1606,7 +1612,10 @@ AC_CONFIG_FILES([Makefile - appliance/Makefile - bash/Makefile - builder/Makefile -+ builder/libguestfs.conf -+ builder/test-config/virt-builder/repos.d/test-index.conf - builder/test-index -+ builder/test-website/virt-builder/repos.d/libguestfs.conf - builder/website/Makefile - cat/Makefile - csharp/Makefile -diff --git a/po/POTFILES-ml b/po/POTFILES-ml -index 94230f8..a20c058 100644 ---- a/po/POTFILES-ml -+++ b/po/POTFILES-ml -@@ -9,6 +9,7 @@ builder/paths.ml - builder/pxzcat.ml - builder/setlocale.ml - builder/sigchecker.ml -+builder/sources.ml - mllib/common_gettext.ml - mllib/common_utils.ml - mllib/common_utils_tests.ml -diff --git a/run.in b/run.in -index 84af430..f0b722a 100755 ---- a/run.in -+++ b/run.in -@@ -87,9 +87,9 @@ export LD_LIBRARY_PATH - - # Make virt-builder use the local website copy to avoid hitting - # the network all the time. --if [ -z "$VIRT_BUILDER_SOURCE" ]; then -- VIRT_BUILDER_SOURCE="file://$s/builder/website/index.asc" -- export VIRT_BUILDER_SOURCE -+if [ -z "$XDG_CONFIG_DIRS" ]; then -+ XDG_CONFIG_DIRS="$b/builder/test-website" -+ export XDG_CONFIG_DIRS - fi - - # For Perl. --- -1.8.5.3 - diff --git a/0098-builder-remove-VIRT_BUILDER_SOURCE-and-VIRT_BUILDER_.patch b/0098-builder-remove-VIRT_BUILDER_SOURCE-and-VIRT_BUILDER_.patch deleted file mode 100644 index e535b57..0000000 --- a/0098-builder-remove-VIRT_BUILDER_SOURCE-and-VIRT_BUILDER_.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 2c5349eff420febc91aa166ccd677142f39ec62a Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Tue, 25 Feb 2014 17:29:11 +0100 -Subject: [PATCH] builder: remove VIRT_BUILDER_SOURCE and - VIRT_BUILDER_FINGERPRINT - -Drop these two environment variables, and the implicit hardcoded source -hosted at libguestfs.org. -This means all the sources must be provided as .conf files, or at each -invocation with --source. - -(cherry picked from commit 573cae45c3490ddbd04a39aaf63dbe0cd0518cb1) ---- - builder/cmdline.ml | 20 +------------------- - 1 file changed, 1 insertion(+), 19 deletions(-) - -diff --git a/builder/cmdline.ml b/builder/cmdline.ml -index e9e47ae..6e8bfd8 100644 ---- a/builder/cmdline.ml -+++ b/builder/cmdline.ml -@@ -30,8 +30,6 @@ open Printf - - let prog = Filename.basename Sys.executable_name - --let default_source = "http://libguestfs.org/download/builder/index.asc" -- - let parse_cmdline () = - let display_version () = - printf "virt-builder %s\n" Config.package_version; -@@ -407,27 +405,13 @@ read the man page virt-builder(1). - exit 1 - ) in - -- (* Check source(s) and fingerprint(s), or use environment or default. *) -+ (* Check source(s) and fingerprint(s). *) - let sources = -- let list_split = function "" -> [] | str -> string_nsplit "," str in - let rec repeat x = function - | 0 -> [] | 1 -> [x] - | n -> x :: repeat x (n-1) - in - -- let sources = -- if sources <> [] then sources -- else ( -- try list_split (Sys.getenv "VIRT_BUILDER_SOURCE") -- with Not_found -> [ default_source ] -- ) in -- let fingerprints = -- if fingerprints <> [] then fingerprints -- else ( -- try list_split (Sys.getenv "VIRT_BUILDER_FINGERPRINT") -- with Not_found -> [ Sigchecker.default_fingerprint ] -- ) in -- - let nr_sources = List.length sources in - let fingerprints = - match fingerprints with -@@ -444,8 +428,6 @@ read the man page virt-builder(1). - exit 1 - ); - -- assert (nr_sources > 0); -- - (* Combine the sources and fingerprints into a single list of pairs. *) - List.combine sources fingerprints in - --- -1.8.5.3 - diff --git a/0099-builder-remove-the-default-fingerprint-pubkey.patch b/0099-builder-remove-the-default-fingerprint-pubkey.patch deleted file mode 100644 index 8af1070..0000000 --- a/0099-builder-remove-the-default-fingerprint-pubkey.patch +++ /dev/null @@ -1,128 +0,0 @@ -From 28a9ed1d1ffb3ce4dd2c5d9d15d4c6b2747ac37d Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Tue, 25 Feb 2014 17:29:12 +0100 -Subject: [PATCH] builder: remove the default fingerprint/pubkey - -Sigchecker can still import keys from the user's keyring, so there is no -need to hardcode fingerprint and key of the index hosted on -libguestfs.org (which is now pointed to using a .conf file). - -(cherry picked from commit 47538865f2e6d82f7fff6e0ef0f48cba48acfc64) ---- - builder/sigchecker.ml | 79 -------------------------------------------------- - builder/sigchecker.mli | 2 -- - 2 files changed, 81 deletions(-) - -diff --git a/builder/sigchecker.ml b/builder/sigchecker.ml -index 67d1600..ae8e413 100644 ---- a/builder/sigchecker.ml -+++ b/builder/sigchecker.ml -@@ -24,78 +24,6 @@ open Unix - - let quote = Filename.quote - --(* These are the public key and fingerprint belonging to -- * Richard W.M. Jones who signs the templates on -- * http://libguestfs.org/download/builder. -- *) --let default_fingerprint = "F777 4FB1 AD07 4A7E 8C87 67EA 9173 8F73 E1B7 68A0" --let default_pubkey = "\ -------BEGIN PGP PUBLIC KEY BLOCK----- --Version: GnuPG v1.4.14 (GNU/Linux) -- --mQINBE6UMMEBEADM811hfTulaF4JpkVpAI10FImyb4ArvOiu8NdcUwTFo+cyWno3 --U85B86H1Bsk/LgLTYtthSrTgsCtdxy+i5OaMjxZDIwKQ2+IYI3FCn9T3Mn28Idyh --kLHzrO9ph0Dv0BNfrlDZhQEC53aAFe/QxN7+A49BNBV7D1VAOOCsHjxMEDzcZkCa --oCrtXw1aNm2vkkj5ukbfukHAyLcQL7kow0qKPSVa1G4lfQP0WiG259Ydy+sUmbVb --TGdb6MEC84PQRDuw6/ZeoV04tn7ZNtQEMOS0uiciHOGfr2hBxQf9VIPNrHg42yaL --dOv51D99GuaxZ9E0HSoH/RwB1oXgd6rFdqVNYaBIQnnkwJANUEeGBArtIOZNCADT --Bt8vkSDm+lLEAFS+V8CACyW/LMIrGCvLdHeqtoAv0GDVyR2GPxldYfdtEmCUMWcb --Jlf71V9iAse2gUdoiHp5FfpGMkA5j7idKuxIws11XxRZJXXbBqiBqmVEAQ/v0m6p --kdo0MYTHydmecLuUK2bAGhpysfX97EfTSrxfrYphYWjTfKRD9GrADeZNfuz1DbKs --7LSqVaQJSjQrfgAwcnZLRaU0V4P5zxiz50gz1Aj3AZRL+Y3meZenzZTXcLFdnusg --wUfhhCuL3tluMtEh6tznumyxb43WO1yLwj6J6LtveiuJN1Z+KSQ6OieZcwARAQAB --tCVSaWNoYXJkIFcuTS4gSm9uZXMgPHJpY2hAYW5uZXhpYS5vcmc+iQI4BBMBAgAi --BQJOlDDBAhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRCRc49z4bdooHQY --D/wJLklSZNyXIW+rG5sUbg7j9cTIF5p/lB9kI2yx6KodJp/2knKyvnmzz0gBw/OE --HL4E4UW26oWKo+36I8wkBnuGa6UtANeITcJqFE19VpHEXHsxre64jNQnO8/w748W --1ROW+Ry43xmrlRWKuCm4oPYUzlp0fq9ATAne8eblfG+NOs8DYuA8xZNQzFaI2kDC --QLD4YoXLoNsP27Koga36b0KwxPFD9tyVZiu9XDH/3hMN7Nb15B66PFr+HcMmQ67G --nUIN5ulcIwj38i40cyaTs1VRheOzTHXE/a6Q2AhMKiKqOoEjQ73/mV7cAVoPtM3o --83Q/8aVKBH0bVRwAeV1tju6b14fqKoG0zNBEcXdlSkht6ScxJYIc/LPUxAMDwgSE --OWshjmeRzKXypBbHn/DP8QVyM2gk5wY+mMSH7MpR0p/hgj+rFO8H9L7pC4dCog3E --qzrYhRN+TaP6MPH3WkOwPH4d4IfQRFnHp+VPYPijKEiLrUl/o8k3DyAanAPBpJ/x --na4wXAjlFBctOq6g+SrCUiHpwk7b2YNwGgr5Vl3GmZELzK/G8gg3uJYKQ9Bpv16t --WWOz+IFiOFa0UULeo0QPmFAIMZiDojNsY1SwBKB3ZL1YWZezgMdQAbpze/IXoSt7 --zxWJoKH2jK7q9mvFiaY12l2YnKuCcegWVAViLxRpBnrbz7QmUmljaGFyZCBXLk0u --IEpvbmVzIDxyam9uZXNAcmVkaGF0LmNvbT6JAjgEEwECACIFAk6UOQsCGwMGCwkI --BwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEJFzj3Pht2igIUYQAKomI0edLakahsUQ --MxOZuhBbXJ4/VWF8bXYChDNPKvJp5nB7fBXujJ+39cIUM5fe2ViO6qSDpFC29imx --F5pPbAqspZBPBkLLiZLji8R42hGarntdtTW0UWSBpq+nC5+G1psrnATI3uXGNxKQ --R99c5HoMY7dBC2Y8TCGE64NINZ/XVh472s6IGLPn8MTn26YdRKC9BrVkCFMP2OBr --6D4IprnyTAWAzb68ew20QmyWO+NBi9MplaDNQVl8PIOgfpyWlkgX1z9m67pcSDkw --46hksp0yuOD1VwR4iVZ2/CmIsGRUlx41vWD6BIp9KxKyDIU1CYTRhq72dahHsl/8 --BjCndV5PO0GphqfCzmCv4DXjUwmrMTbH/GFnt5rfwcMcXUgcK0vV9vQ2SOU56Zd1 --fb27ZCFJKZc0Fu8krwFldCp/NYILf6ogUL/C1hfuCGSSuyDVY16Gg3dla1x+6zpF --asnWQlaw8xT5LlMWvTZs5WsoSVHu7dVZWlgxINP++hlZrTz/S8l38yyQ15YFFl3W --9M7dzkegOeDTPfx6B89WgfvfJjA/D0/FYxxWPXEtrn9DlJ4daEJqNsrvfLErz9R8 --4IQmfmhR93j+rdotner+6keC/wVByEfbW1wmXtmFKXQ6srdpj8VKRFrvkyXVgepM --DypLgRH2v7lL2kdWhUu2y4EAgrwzuQINBE6UMMEBEADxQxMgUuDrw5GT4tqARTPI --SSdNcUsRxRhVA8srYOyECliE+B3TwcRDFBs+MyPFJVEuX8fi4eGj/AK5t1GHerfk --orUGlz72q4c7LLhkfZrsuJbk2dgkjvldKJnIazQJa6epGLqdsE5RlmSgwedIbtMd --naGJBQH8aKP/Wi1+wUxsm5N3p7+R2WRx48VfpEhYB+Zf/FkFm1Ycjwh57KQ0+OHw --ykf8VfMisxuH30tDxOCV+VptWKfOF2rDNdaNPWhij2YIjhJXRpkuRR+1PpI4jLaD --JxcVZmG/0zucacupUN2g5OUH59ySU/totD6YMnmp3FONoyF1uIEJo6Vs30npHGkO --XgBo3Pxt7oLJeykLPtdSLgm3cwXIYMWarVsAkKNXitQIVGpVRLeaK373VwmXFqoi --M2SMHeawTUdOORFjpQzkknlJWM1TmUVtHHKt8Pl9+/5+wXKyt2IDdcUkMrB6K5qF --fb7EwVhoI8ehJQK+eeDCjFwCAiwB3iV8JlyW+tEU7JuyXOQlwY1VWm/WqMD8gaRi --rT+RFDFliZ3tQbW2pqUoZBROV5HN4tieDfwxGKCvk6Tsdb30zA9DPQp93+238bYf --312sg9R+CD0AqxoxFG5FJu4HShcPRrPnYtRZqKRe40GDWvBEArXZprwL1qrP+Kl/ --mRrEQpxAGIoFG8HbVvD3EQARAQABiQIfBBgBAgAJBQJOlDDBAhsMAAoJEJFzj3Ph --t2igSLQP/2uIrAY2CDr0kWBJiD3TztiHy8IdxwUpyTBTebwmAbi44/EvtJfIisrG --YjKIEv/w0E61gO7O1JBG4+IG93W+v9fTT/e39JMyxsYqoZZHUhP11Okx5grDS5b0 --O8VXOmXVRMdVNfstRBr10HD9uNDq7ruKD18TxYTwN0GPD4gj1dbHQDR77Tr5cyBs --6Ou5PBOH4r3qcqf/cJUSMeUUu75xLwixux6E7tD2S+t6F07wlWxntUcPtzyAHj20 --J89orUC+dT6r6MypBoI0jdJCp9JPGtR7i+fE5Gm4E5+AUSubLPtZGRY9Um2eMoS2 --DnQpGOKx1VvsixR/Kw44j2tRAvmYMS4iDKcuZU+nZ+xokAgObILj/b9n/Qe2/fXy --CFdcgSvbm+dV1fZxsdMF/P9OU8aqdT9A9Fv5y+cDMEg4DVnhwMJTxGh/TCkw/H+A --frHEtRc98lSQN5odpITNG17mG6JOdHM+wA57qHH0uy4+5RsbyAJahcdBcmObK/RF --i4WZlThpbHftX5O/LH98aYQ2fJayIxv1EAjzOBOQ0MfBHI0KCJR1pysEisX28sJA --Ic73gnJJ3BLZbqfBRgxjNMNroxC+5Tw6uPGFHa3YnuIAxxw0HcDVZ9vnTWBWFPGw --ZvXkQ3FVJwZoLmHw47vvlVpLD/4gi1SuHWieRvZ+UdDq00E348pm --=neBW -------END PGP PUBLIC KEY BLOCK----- --" -- - type gpgkey_type = - | No_Key - | Fingerprint of string -@@ -162,13 +90,6 @@ let rec create ~debug ~gpg ~gpgkey ~check_signature = - | _ -> () - ) status; - !fingerprint -- | Fingerprint fp when equal_fingerprints default_fingerprint fp -> -- let filename, chan = Filename.open_temp_file "vbpubkey" ".asc" in -- unlink_on_exit filename; -- output_string chan default_pubkey; -- close_out chan; -- ignore (import_keyfile gpg tmpdir debug filename); -- fp - | Fingerprint fp -> - let filename = Filename.temp_file "vbpubkey" ".asc" in - unlink_on_exit filename; -diff --git a/builder/sigchecker.mli b/builder/sigchecker.mli -index ab44a5c..8c6ba7f 100644 ---- a/builder/sigchecker.mli -+++ b/builder/sigchecker.mli -@@ -16,8 +16,6 @@ - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - *) - --val default_fingerprint : string -- - type t - - type gpgkey_type = --- -1.8.5.3 - diff --git a/0100-builder-update-documentation.patch b/0100-builder-update-documentation.patch deleted file mode 100644 index 282ec32..0000000 --- a/0100-builder-update-documentation.patch +++ /dev/null @@ -1,277 +0,0 @@ -From eaba93cf3873be36f335e01bc353b1571ce9b87c Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Tue, 25 Feb 2014 17:29:13 +0100 -Subject: [PATCH] builder: update documentation - -Update the documentation according to the new .conf files structure, the -drop of VIRT_BUILDER_SOURCE and VIRT_BUILDER_FINGERPRINT, the drop of -hardcoded source and its key, etc. - -(cherry picked from commit 963b0341e26ddc4ddc0e0f0fa13deacecdd5ab0f) ---- - builder/virt-builder.pod | 158 +++++++++++++++++++++++------------------------ - 1 file changed, 77 insertions(+), 81 deletions(-) - -diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod -index ed08f3d..dbfb36f 100644 ---- a/builder/virt-builder.pod -+++ b/builder/virt-builder.pod -@@ -292,12 +292,6 @@ URLs, then you can have either no fingerprint, one fingerprint or - multiple fingerprints. If you have multiple, then each must - correspond 1-1 with a source URL. - --The default fingerprint (if none are supplied) is --S --(which is S key). -- --You can also set the C environment variable. -- - =item B<--firstboot> SCRIPT - - =item B<--firstboot-command> 'CMD ARGS ...' -@@ -420,7 +414,7 @@ keys are no more present). - - I<--long> is a shorthand for the C format. - --See also: I<--source>, I<--notes>, L. -+See also: I<--source>, I<--notes>, L. - - =item B<--no-logfile> - -@@ -635,12 +629,8 @@ Enable N E 2 virtual CPUs for I<--run> scripts to use. - Set the source URL to look for indexes. - - You can give this option multiple times to specify multiple sources. --If not specified it defaults to --L - --See also L below. -- --You can also set the C environment variable. -+See also L below. - - Note that you should not point I<--source> to sources that you don't - trust (unless the source is signed by someone you do trust). See also -@@ -1203,7 +1193,53 @@ serial console, add the following on the kernel command line: - - =back - --=head2 CREATING YOUR OWN TEMPLATES -+=head2 SOURCES OF TEMPLATES -+ -+virt-builder reads the available sources from configuration files, -+with the I<.conf> extension and located in the following paths: -+ -+=over 4 -+ -+=item * -+ -+$XDG_CONFIG_HOME/virt-builder/repos.d/ (C<$XDG_CONFIG_HOME> is -+C<$HOME/.config> if not set). -+ -+=item * -+ -+$XDG_CONFIG_DIRS/virt-builder/repos.d/ (where C<$XDG_CONFIG_DIRS> -+means any of the directories in that environment variable, or just C -+if not set) -+ -+=back -+ -+Each I<.conf> file in those paths has a simple text format like the -+following: -+ -+ [libguestfs.org] -+ uri=http://libguestfs.org/download/builder/index.asc -+ gpgkey=file:///etc/xdg/virt-builder/repos.d/libguestfs.gpg -+ -+The part in square brackets is the repository identifier, which is -+used as unique identifier. -+ -+The following fields can appear: -+ -+=over 4 -+ -+=item C -+ -+The URI of the index file which this repository refers to. -+ -+This field is required. -+ -+=item C -+ -+This optional field represents the URI (although only I URIs -+are accepted) of the key used to sign the index file. -+If not present, the index file referred by I is not signed. -+ -+=back - - For serious virt-builder use, you may want to create your own - repository of templates. -@@ -1223,16 +1259,17 @@ libguestfs source tree, in C. - =head3 Setting up the repository - - You can set up your own site containing an index file and some --templates, and then point virt-builder at the site by using the --I<--source> option: -+templates, and then point virt-builder at the site by creating a -+I<.conf> file pointing to it. -+ -+Note that if your index is signed, you will need to properly fill -+I in your I<.conf> file, making sure to deploy also the -+GPG key file. - - virt-builder --source https://example.com/builder/index.asc \ - --fingerprint 'AAAA BBBB ...' \ - --list - --(Note setting the environment variables C and --C may be easier to type!) -- - You can host this on any web or FTP server, or a local or network - filesystem. - -@@ -1246,18 +1283,10 @@ I<--no-check-signature> flag every time they use virt-builder.) - To create a key, see the GPG manual - L. - --Export your GPG public key and add it to the keyring of all --virt-builder users: -+Export your GPG public key: - - gpg --export -a "you@example.com" > pubkey - -- # For each virt-builder user: -- gpg --import pubkey -- --Also find the fingerprint of your key: -- -- gpg --list-keys --fingerprint -- - =head3 Create the templates - - There are many ways to create the templates. For example you could -@@ -1305,7 +1334,7 @@ using the following command: - gpg --clearsign --armor index - - This will create the final file called C which can be --uploaded to the server (and is the I<--source> URL). As noted above, -+uploaded to the server (and is the I URL). As noted above, - signing the index file is optional, but recommended. - - The following fields can appear: -@@ -1449,51 +1478,18 @@ images. - - =back - --=head3 Running virt-builder against the alternate repository -- --Ensure each virt-builder user has imported your public key into --their gpg keyring (see above). -- --Each virt-builder user should export these environment variables: -- --=over 4 -- --=item * -- --C to point to the URL of the C file. -- --=item * -- --C to contain the fingerprint (long hex --string) of the user who signed the index file and the templates. -- --=back -- --Now run virt-builder commands as normal, eg: -- -- virt-builder --list --long -- -- virt-builder os-version -- --To debug problems, add the C<-v> option to these commands. -- - =head3 Running virt-builder against multiple sources - --It is possible to use multiple sources with virt-builder. Use either --multiple I<--source> and/or I<--fingerprint> options, or a --comma-separated list in the C / --C environment variables: -+It is possible to use multiple sources with virt-builder. -+The recommended way is to deploy I<.conf> files pointing to the -+index files. Another way is to specify the sources using -+multiple I<--source> and/or I<--fingerprint> options: - - virt-builder \ - --source http://example.com/s1/index.asc \ - --source http://example.com/s2/index.asc - --or equivalently: -- -- export VIRT_BUILDER_SOURCE=http://example.com/s1/index.asc,http://example.com/s2/index.asc -- virt-builder [...] -- --You can provide N, 1 or 0 fingerprints. In the case where you -+You can provide N or 1 fingerprints. In the case where you - provide N fingerprints, N = number of sources and there is a 1-1 - correspondence between each source and each fingerprint: - -@@ -1504,8 +1500,7 @@ correspondence between each source and each fingerprint: - In the case where you provide 1 fingerprint, the same fingerprint - is used for all sources. - --In the case where you provide no fingerprints, the default fingerprint --built into virt-builder is used for all sources. -+You C provide at least 1 fingerprint. - - =head3 Licensing of templates - -@@ -1618,8 +1613,8 @@ The source points to an index file, which is optionally signed. - - Virt-builder downloads the index and checks that the signature is - valid and the signer's fingerprint matches the specified fingerprint --(ie. I<--fingerprint>, C, or a built-in --fingerprint, in that order). -+(ie. the one specified in I in the I<.conf>, or with -+I<--fingerprint>, in that order). - - For checking against the built-in public key/fingerprint, this - requires importing the public key into the user's local gpg keyring -@@ -1800,22 +1795,23 @@ are actually interpreted by L, not virt-builder. - - =item C - --Used to determine the location of the template cache. See L. -- --=item C -- --Set the default value for the GPG signature fingerprint or --comma-separated list of fingerprints (see I<--fingerprint> option). -- --=item C -- --Set the default value for the source URL (or comma-separated list of --URLs) for the template repository (see I<--source> option). -+Used to determine the location of the template cache, and the location -+of the user' sources. See L and L. - - =item C - - Used to determine the location of the template cache. See L. - -+=item C -+ -+Used to determine the location of the user' sources. See -+L. -+ -+=item C -+ -+Used to determine the location of the system sources. See -+L. -+ - =back - - =head1 EXIT STATUS --- -1.8.5.3 - diff --git a/0101-builder-add-libguestfs.gpg-to-EXTRA_DIST.patch b/0101-builder-add-libguestfs.gpg-to-EXTRA_DIST.patch deleted file mode 100644 index 26a8192..0000000 --- a/0101-builder-add-libguestfs.gpg-to-EXTRA_DIST.patch +++ /dev/null @@ -1,27 +0,0 @@ -From d4ddc6b9d5f9477550b627def0399a5eb6b0b7e2 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Fri, 28 Feb 2014 14:20:08 +0100 -Subject: [PATCH] builder: add libguestfs.gpg to EXTRA_DIST - -It needs to be in EXTRA_DIST, otherwise it is not put in the dist. - -(cherry picked from commit 962837650cfb95e50d3c44578cbf47f7ec625271) ---- - builder/Makefile.am | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/builder/Makefile.am b/builder/Makefile.am -index f0cb1dd..2dc9d23 100644 ---- a/builder/Makefile.am -+++ b/builder/Makefile.am -@@ -27,6 +27,7 @@ AM_CFLAGS = \ - - EXTRA_DIST = \ - $(SOURCES) \ -+ libguestfs.gpg \ - virt-builder.pod \ - virt-index-validate.pod \ - test-virt-builder.sh \ --- -1.8.5.3 - diff --git a/0102-builder-install-a-sysconfdir-virt-builder-xdg-virt-b.patch b/0102-builder-install-a-sysconfdir-virt-builder-xdg-virt-b.patch deleted file mode 100644 index 115da79..0000000 --- a/0102-builder-install-a-sysconfdir-virt-builder-xdg-virt-b.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 1b5d4fb3349733294f50cb7a6840c09dbd2598fb Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Mon, 3 Mar 2014 16:28:14 +0100 -Subject: [PATCH] builder: install a $sysconfdir/virt-builder -> - xdg-virt-builder symlink - -This way "virt-builder" appears directly in the sysconfdir. - -(cherry picked from commit 631c7d9241febcc7889d0fcb88aa07858174dbe1) ---- - builder/Makefile.am | 3 +++ - configure.ac | 1 + - 2 files changed, 4 insertions(+) - -diff --git a/builder/Makefile.am b/builder/Makefile.am -index 2dc9d23..7548599 100644 ---- a/builder/Makefile.am -+++ b/builder/Makefile.am -@@ -230,6 +230,9 @@ DISTCLEANFILES = .depend - repoconfdir = $(sysconfdir)/xdg/virt-builder/repos.d - repoconf_DATA = libguestfs.conf libguestfs.gpg - -+install-exec-hook: -+ $(LN_S) xdg/virt-builder $(DESTDIR)$(sysconfdir)/virt-builder -+ - # Build a small C index validator program. - bin_PROGRAMS = virt-index-validate - -diff --git a/configure.ac b/configure.ac -index e05ad5f..299cb29 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -116,6 +116,7 @@ gl_EARLY - gl_INIT - - AC_PROG_LIBTOOL -+AC_PROG_LN_S - - # Define $(SED). - m4_ifdef([AC_PROG_SED],[ --- -1.8.5.3 - diff --git a/0103-Update-generated-files.patch b/0103-Update-generated-files.patch deleted file mode 100644 index 945b15b..0000000 --- a/0103-Update-generated-files.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 73cf29101f55e766c781dc241ae6e33228070cf9 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 8 Mar 2014 17:56:43 +0000 -Subject: [PATCH] Update generated files. - ---- - gobject/Makefile.inc | 2 ++ - po/POTFILES | 1 + - 2 files changed, 3 insertions(+) - -diff --git a/gobject/Makefile.inc b/gobject/Makefile.inc -index 4f2927e..8a068d8 100644 ---- a/gobject/Makefile.inc -+++ b/gobject/Makefile.inc -@@ -50,6 +50,7 @@ guestfs_gobject_headers= \ - include/guestfs-gobject/optargs-btrfs_fsck.h \ - include/guestfs-gobject/optargs-compress_device_out.h \ - include/guestfs-gobject/optargs-compress_out.h \ -+ include/guestfs-gobject/optargs-copy_attributes.h \ - include/guestfs-gobject/optargs-copy_device_to_device.h \ - include/guestfs-gobject/optargs-copy_device_to_file.h \ - include/guestfs-gobject/optargs-copy_file_to_device.h \ -@@ -124,6 +125,7 @@ guestfs_gobject_sources= \ - src/optargs-btrfs_fsck.c \ - src/optargs-compress_device_out.c \ - src/optargs-compress_out.c \ -+ src/optargs-copy_attributes.c \ - src/optargs-copy_device_to_device.c \ - src/optargs-copy_device_to_file.c \ - src/optargs-copy_file_to_device.c \ -diff --git a/po/POTFILES b/po/POTFILES -index 090871b..fd35411 100644 ---- a/po/POTFILES -+++ b/po/POTFILES -@@ -164,6 +164,7 @@ gobject/src/optargs-btrfs_filesystem_resize.c - gobject/src/optargs-btrfs_fsck.c - gobject/src/optargs-compress_device_out.c - gobject/src/optargs-compress_out.c -+gobject/src/optargs-copy_attributes.c - gobject/src/optargs-copy_device_to_device.c - gobject/src/optargs-copy_device_to_file.c - gobject/src/optargs-copy_file_to_device.c --- -1.8.5.3 - diff --git a/copy-patches.sh b/copy-patches.sh deleted file mode 100755 index e242cd2..0000000 --- a/copy-patches.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/bash - - -set -e - -# Maintainer script to copy patches from the git repo to the current -# directory. Use it like this: -# ./copy-patches.sh - -# Check we're in the right directory. -if [ ! -f libguestfs.spec ]; then - echo "$0: run this from the directory containing 'libguestfs.spec'" - exit 1 -fi - -git_checkout=$HOME/d/libguestfs-fedora-20 -if [ ! -d $git_checkout ]; then - echo "$0: $git_checkout does not exist" - echo "This script is only for use by the maintainer when preparing a" - echo "libguestfs release for Fedora 20." - exit 1 -fi - -# Get the base version of libguestfs. -version=`grep '^Version:' libguestfs.spec | awk '{print $2}'` - -# Remove any existing patches. -git rm -f [0-9]*.patch ||: -rm -f [0-9]*.patch - -# Get the patches. -(cd $git_checkout; rm -f [0-9]*.patch; git format-patch -N $version) -mv $git_checkout/[0-9]*.patch . - -# Remove any not to be applied. -rm -f *NOT-FOR-RPM*.patch - -# Add the patches. -git add [0-9]*.patch - -# Print out the patch lines. -echo -echo "--- Copy the following text into libguestfs.spec file" -echo - -echo "# Git-managed patches." -for f in [0-9]*.patch; do - n=`echo $f | awk -F- '{print $1}'` - echo "Patch$n: $f" -done - -echo "# Add any non-git patches here." -echo -echo "--- End of text" diff --git a/libguestfs.spec b/libguestfs.spec index ecda8b4..6c4e35b 100644 --- a/libguestfs.spec +++ b/libguestfs.spec @@ -1,9 +1,16 @@ -# Enable to run tests during check -# Default is enabled +# Run tests during check. Default is enabled on most architectures. +# You can override this by putting '%libguestfs_runtests 0' into +# '~/.rpmmacros' %if %{defined libguestfs_runtests} %global runtests %{libguestfs_runtests} %else +%ifnarch %{arm} ppc ppc64 %global runtests 1 +%else +# Disabled on arm, see RHBZ#1066581. +# Disabled on ppc, ppc64 (secondary arches), see RHBZ#1036742. +%global runtests 0 +%endif %endif %global _hardened_build 1 @@ -11,136 +18,19 @@ Summary: Access and modify virtual machine disk images Name: libguestfs Epoch: 1 -Version: 1.24.8 +Version: 1.26.0 Release: 1%{?dist} License: LGPLv2+ # Source and patches. URL: http://libguestfs.org/ -Source0: http://libguestfs.org/download/1.24-stable/%{name}-%{version}.tar.gz - -# Note we use the fedora-20 branch from the upstream repo which -# contains only upstream, backported patches, but conveniently manages -# them in git. In order to update this list, run the -# 'copy-patches.sh' script. - -# Git-managed patches. -Patch0001: 0001-builder-Don-t-run-virt-resize-when-not-necessary.patch -Patch0002: 0002-builder-Make-xzcat-binary-configurable-and-use-AC_PA.patch -Patch0003: 0003-builder-Use-pxzcat-optionally-to-speed-up-xzcat-step.patch -Patch0004: 0004-builder-Add-no-sync-option-to-avoid-sync-on-exit.patch -Patch0005: 0005-builder-Add-mkdir-option-to-create-directories.patch -Patch0006: 0006-builder-Allow-upload-to-a-directory.patch -Patch0007: 0007-builder-Add-write-option-to-write-a-literal-file.patch -Patch0008: 0008-builder-Document-how-to-boot-VMs-directly-in-qemu-or.patch -Patch0009: 0009-firstboot-Send-the-output-to-the-console-as-well-as-.patch -Patch0010: 0010-builder-Add-a-section-on-performance-to-the-manual.patch -Patch0011: 0011-builder-Add-m-memsize-and-smp-command-line-options.patch -Patch0012: 0012-builder-Allow-multiple-source-paths-to-be-specified.patch -Patch0013: 0013-builder-Add-a-real-scanner-parser-for-index-files.patch -Patch0014: 0014-builder-Fix-missing-files-in-EXTRA_DIST.patch -Patch0015: 0015-builder-website-Add-index-validation-test-script.patch -Patch0016: 0016-builder-Internal-implementation-of-parallel-xzcat-px.patch -Patch0017: 0017-builder-website-Add-validate.sh-test-script-to-EXTRA.patch -Patch0018: 0018-builder-Add-missing-dependency.patch -Patch0019: 0019-builder-Add-some-generated-files-to-CLEANFILES.patch -Patch0020: 0020-builder-Add-dependency-from-index-parse.h-to-index-v.patch -Patch0021: 0021-builder-Add-dependencies-which-automake-doesn-t-gene.patch -Patch0022: 0022-builder-Fail-if-bison-is-not-installed.patch -Patch0023: 0023-builder-Fail-if-lex-is-not-installed.patch -Patch0024: 0024-builder-sysprep-Allow-random-as-a-password-selector.patch -Patch0025: 0025-builder-sysprep-Allow-accounts-to-be-locked-RHBZ-102.patch -Patch0026: 0026-builder-Use-a-planner-to-work-out-how-to-convert-the.patch -Patch0027: 0027-builder-planner-Handle-no-format-in-source-case-corr.patch -Patch0028: 0028-builder-Flush-debug-info-after-printing-it.patch -Patch0029: 0029-builder-Add-a-test-of-the-planner.patch -Patch0030: 0030-builder-tests-Fix-virt-builder-list-output.patch -Patch0031: 0031-builder-tests-Add-test-virt-builder-planner.sh-to-EX.patch -Patch0032: 0032-builder-Add-a-link-to-blog-posting-about-the-planner.patch -Patch0033: 0033-builder-Only-use-virt-resize-no-sparse-when-writing-.patch -Patch0034: 0034-builder-Refuse-to-write-to-a-char-device-or-dev-null.patch -Patch0035: 0035-builder-Remove-blank-line.patch -Patch0036: 0036-builder-Add-update-option-to-update-template-core-pa.patch -Patch0037: 0037-launch-libvirt-Don-t-default-to-using-NULL-for-libvi.patch -Patch0038: 0038-builder-Fix-handling-of-size-parameter.patch -Patch0039: 0039-libvirt-auth-Provide-a-friendlier-wrapper-around-vir.patch -Patch0040: 0040-tests-Add-a-regression-test-of-libvirt-authenticatio.patch -Patch0041: 0041-tests-Add-a-regression-test-for-libvirt-authenticati.patch -Patch0042: 0042-sysprep-builder-Add-timezone-option-to-set-timezone-.patch -Patch0043: 0043-builder-Document-how-to-change-keyboard-layout.patch -Patch0044: 0044-builder-Add-link-option-for-creating-symbolic-links.patch -Patch0045: 0045-builder-Document-how-to-change-the-language-locale-o.patch -Patch0046: 0046-builder-Document-how-to-set-up-local-mirrors-for-per.patch -Patch0047: 0047-builder-Document-how-to-set-Japanese-language-suppor.patch -Patch0048: 0048-builder-Fix-virt-builder-test.patch -Patch0049: 0049-builder-Document-how-to-set-Japanese-in-Debian-7.patch -Patch0050: 0050-builder-Add-no-delete-on-failure-option-to-aid-debug.patch -Patch0051: 0051-builder-For-performance-recommend-using-the-no-sync-.patch -Patch0052: 0052-builder-planner-Whitespace-change.patch -Patch0053: 0053-daemon-xattr-simplify-the-enabling-of-the-linuxxattr.patch -Patch0054: 0054-daemon-xattr-move-the-listxattrs-code-in-an-own-func.patch -Patch0055: 0055-daemon-xattr-Remove-unused-variable.patch -Patch0056: 0056-New-API-copy-attributes.patch -Patch0057: 0057-fish-Add-test-file-attrs.sh-to-EXTRA_DIST.patch -Patch0058: 0058-builder-edit-fish-use-copy-attributes.patch -Patch0059: 0059-builder-test-virt-builder-check-some-results.patch -Patch0060: 0060-builder-small-refactor-of-the-list-output.patch -Patch0061: 0061-builder-add-list-format.patch -Patch0062: 0062-builder-add-a-JSON-output-for-list.patch -Patch0063: 0063-builder-Fix-unterminated-I-.-in-man-page.patch -Patch0064: 0064-builder-add-index-struct.h-as-dependency-for-index-p.patch -Patch0065: 0065-builder-allow-more-empty-lines-in-index-files.patch -Patch0066: 0066-builder-proper-consider-subkeys-in-index-files.patch -Patch0067: 0067-builder-fix-small-regression-in-subkey-parsing.patch -Patch0068: 0068-builder-small-code-simplification.patch -Patch0069: 0069-builder-read-all-the-available-notes-from-the-index.patch -Patch0070: 0070-builder-Add-selinux-relabel-option-to-perform-SELinu.patch -Patch0071: 0071-builder-Add-documentation-for-enabling-Puppet-agent-.patch -Patch0072: 0072-daemon-Bind-mount-sys-fs-selinux-into-sysroot-when-r.patch -Patch0073: 0073-daemon-If-selinux-exists-in-the-guest-bind-mount-sys.patch -Patch0074: 0074-daemon-Add-a-note-about-how-mount-rbind-doesn-t-work.patch -Patch0075: 0075-builder-output-translated-notes.patch -Patch0076: 0076-builder-remove-unused-variables.patch -Patch0077: 0077-builder-isolate-C-libraries-in-an-own-OCAMLCLIBS.patch -Patch0078: 0078-builder-prepare-for-different-per-protocol-download-.patch -Patch0079: 0079-builder-do-a-copy-when-downloading-local-files.patch -Patch0080: 0080-mllib-hostname-on-Debian-replace-it-also-in-etc-host.patch -Patch0081: 0081-builder-pxzcat-Fix-char-signedness-warning.patch -Patch0082: 0082-builder-Suppress-warning-about-unused-yyunput.patch -Patch0083: 0083-Use-bindtextdomain-in-some-programs-where-it-was-mis.patch -Patch0084: 0084-builder-Fix-dependencies-which-are-not-generated-cor.patch -Patch0085: 0085-fish-use-XDG-paths-for-the-config-file.patch -Patch0086: 0086-builder-move-the-XDG-path-handling-in-an-own-file.patch -Patch0087: 0087-builder-accept-also-_-in-group-names.patch -Patch0088: 0088-mllib-add-an-hook-to-cleanup-directories-on-exit.patch -Patch0089: 0089-builder-use-a-disposable-GPG-keyring-for-every-Sigch.patch -Patch0090: 0090-builder-allow-Sigchecker-to-import-keys-from-file.patch -Patch0091: 0091-builder-add-a-mandatory-arch-key-in-index-files.patch -Patch0092: 0092-builder-split-INI-C-OCaml-glue-code-in-own-module.patch -Patch0093: 0093-builder-allow-no-key-as-key-in-Sigchecker.patch -Patch0094: 0094-builder-use-Sigchecker.gpgkey_type-for-the-fingerpri.patch -Patch0095: 0095-builder-add-functions-to-read-XDG_CONFIG_DIRS-and-XD.patch -Patch0096: 0096-builder-extract-the-default-key-to-file.patch -Patch0097: 0097-builder-switch-sources-to-.conf-files.patch -Patch0098: 0098-builder-remove-VIRT_BUILDER_SOURCE-and-VIRT_BUILDER_.patch -Patch0099: 0099-builder-remove-the-default-fingerprint-pubkey.patch -Patch0100: 0100-builder-update-documentation.patch -Patch0101: 0101-builder-add-libguestfs.gpg-to-EXTRA_DIST.patch -Patch0102: 0102-builder-install-a-sysconfdir-virt-builder-xdg-virt-b.patch -Patch0103: 0103-Update-generated-files.patch -# Add any non-git patches here. - -# Use git for patch management. -BuildRequires: git - -# Run autotools after applying the patches. -BuildRequires: autoconf, automake, libtool, gettext-devel +Source0: http://libguestfs.org/download/1.26-stable/%{name}-%{version}.tar.gz # Basic build requirements: BuildRequires: perl(Pod::Simple) BuildRequires: perl(Pod::Man) BuildRequires: /usr/bin/pod2text -BuildRequires: supermin >= 4.1.5 +BuildRequires: supermin >= 5.1.0 BuildRequires: hivex-devel >= 1.2.7-7 BuildRequires: perl(Win::Hivex) BuildRequires: perl(Win::Hivex::Regedit) @@ -192,7 +82,6 @@ BuildRequires: perl(Test::More) BuildRequires: perl(Test::Pod) >= 1.00 BuildRequires: perl(Test::Pod::Coverage) >= 1.00 BuildRequires: perl(ExtUtils::MakeMaker) -BuildRequires: perl(String::ShellQuote) BuildRequires: perl(Locale::TextDomain) BuildRequires: python-devel BuildRequires: ruby-devel @@ -213,24 +102,25 @@ BuildRequires: golang %endif # Build requirements for the appliance. -# sed 's/^ *//' < appliance/packagelist | sort -%global appliance_buildreqs0 acl attr augeas-libs bash binutils btrfs-progs bzip2 coreutils cpio cryptsetup diffutils dosfstools e2fsprogs file findutils gawk gdisk gfs2-utils grep gzip hivex iproute iputils jfsutils kernel kmod less libcap libldm libselinux libxml2 lsof lsscsi lvm2 lzop mdadm nilfs-utils ntfs-3g openssh-clients parted pcre procps psmisc reiserfs-utils rsync scrub sed strace systemd tar udev util-linux vim-minimal xfsprogs xz yajl zerofree +# +# Get the initial list by doing: +# for f in `cat appliance/packagelist`; do echo $f; done | sort -u +# However you have to edit the list down to packages which exist in +# current Fedora, since supermin ignores non-existent packages. +BuildRequires: acl attr augeas-libs bash binutils btrfs-progs bzip2 coreutils cpio cryptsetup diffutils dosfstools e2fsprogs file findutils gawk gdisk genisoimage gfs2-utils grep gzip hivex iproute iputils jfsutils kernel kmod less libcap libldm libselinux libxml2 lsof lsscsi lvm2 lzop mdadm nilfs-utils openssh-clients parted pcre procps psmisc reiserfs-utils rsync scrub sed strace systemd tar udev util-linux vim-minimal xfsprogs xz yajl zerofree %ifnarch %{arm} ppc -%global appliance_buildreqs1 hfsplus-tools +BuildRequires: hfsplus-tools %endif %ifnarch %{arm} # http://zfs-fuse.net/issues/94 -%global appliance_buildreqs2 zfs-fuse +BuildRequires: zfs-fuse %endif %ifarch %{ix86} x86_64 -%global appliance_buildreqs3 ntfsprogs syslinux syslinux-extlinux +BuildRequires: ntfs-3g ntfsprogs syslinux syslinux-extlinux %endif -%global appliance_buildreqs %{appliance_buildreqs0} %{?appliance_buildreqs1} %{?appliance_buildreqs2} %{?appliance_buildreqs3} -BuildRequires: %{appliance_buildreqs} -Requires: %{appliance_buildreqs} # For building the appliance. -Requires: supermin-helper >= 4.1.5 +Requires: supermin >= 5.1.0 # For core inspection API. Requires: libdb-utils @@ -241,6 +131,9 @@ Requires: libosinfo # For core mount-local (FUSE) API. Requires: fuse +# For core disk-create API. +Requires: /usr/bin/qemu-img + # For libvirt backend. %ifarch %{ix86} x86_64 Requires: libvirt-daemon-kvm >= 0.10.2-3 @@ -267,8 +160,6 @@ Source3: 99-guestfsd.rules # Replacement README file for Fedora users. Source4: README-replacement.in -Source5: copy-patches.sh - # https://fedoraproject.org/wiki/Packaging:No_Bundled_Libraries#Packages_granted_exceptions Provides: bundled(gnulib) @@ -307,6 +198,11 @@ For shell scripting and command line access, install 'guestfish'. To mount guest filesystems on the host using FUSE, install '%{name}-mount'. +For extra features, install 'libguestfs-gfs2', 'libguestfs-hfsplus', +'libguestfs-jfs', 'libguestfs-nilfs', 'libguestfs-reiserfs', +'libguestfs-rescue', 'libguestfs-rsync', 'libguestfs-xfs', +'libguestfs-zfs'. + For Erlang bindings, install 'erlang-libguestfs'. For GObject bindings and GObject Introspection, install @@ -344,6 +240,113 @@ Requires: %{name}-tools-c = %{epoch}:%{version}-%{release} for %{name}. +%package gfs2 +Summary: GFS2 support for %{name} +License: LGPLv2+ +Requires: %{name} = %{epoch}:%{version}-%{release} +Requires: gfs2-utils + +%description gfs2 +This adds GFS2 support to %{name}. Install it if you want to process +disk images containing GFS2. + + +%ifnarch %{arm} ppc +%package hfsplus +Summary: HFS+ support for %{name} +License: LGPLv2+ +Requires: %{name} = %{epoch}:%{version}-%{release} +Requires: hfsplus-tools + +%description hfsplus +This adds HFS+ support to %{name}. Install it if you want to process +disk images containing HFS+ / Mac OS Extended filesystems. +%endif + + +%package jfs +Summary: JFS support for %{name} +License: LGPLv2+ +Requires: %{name} = %{epoch}:%{version}-%{release} +Requires: jfsutils + +%description jfs +This adds JFS support to %{name}. Install it if you want to process +disk images containing JFS. + + +%package nilfs +Summary: NILFS support for %{name} +License: LGPLv2+ +Requires: %{name} = %{epoch}:%{version}-%{release} +Requires: nilfs-utils + +%description nilfs +This adds NILFS v2 support to %{name}. Install it if you want to process +disk images containing NILFS v2. + + +%package reiserfs +Summary: ReiserFS support for %{name} +License: LGPLv2+ +Requires: %{name} = %{epoch}:%{version}-%{release} +Requires: reiserfs-utils + +%description reiserfs +This adds ReiserFS support to %{name}. Install it if you want to process +disk images containing ReiserFS. + + +%package rsync +Summary: rsync support for %{name} +License: LGPLv2+ +Requires: %{name} = %{epoch}:%{version}-%{release} +Requires: 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 rescue +Summary: Additional tools for virt-rescue +License: LGPLv2+ +Requires: %{name}-tools-c = %{epoch}:%{version}-%{release} +Requires: iputils +Requires: lsof +Requires: openssh-clients +Requires: strace +Requires: vim-minimal + +%description rescue +This adds additional tools to use inside the virt-rescue shell, +such as ssh, network utilities, editors and debugging utilities. + + +%package xfs +Summary: XFS support for %{name} +License: LGPLv2+ +Requires: %{name} = %{epoch}:%{version}-%{release} +Requires: xfsprogs + +%description xfs +This adds XFS support to %{name}. Install it if you want to process +disk images containing XFS. + + +%ifnarch %{arm} +%package zfs +Summary: ZFS support for %{name} +License: LGPLv2+ +Requires: %{name} = %{epoch}:%{version}-%{release} +Requires: zfs-fuse + +%description zfs +This adds ZFS support to %{name}. Install it if you want to process +disk images containing ZFS. +%endif + + %package tools-c Summary: System administration tools for virtual machines License: GPLv2+ @@ -356,21 +359,12 @@ Requires: /usr/bin/less Requires: /usr/bin/man Requires: /usr/bin/vi -# for virt-sparsify: -Requires: /usr/bin/qemu-img - # for virt-builder: Requires: curl Requires: gnupg Requires: xz #Requires: nbdkit, nbdkit-plugin-xz -# Obsolete and replace earlier packages. -Provides: guestfish = %{epoch}:%{version}-%{release} -Obsoletes: guestfish < %{epoch}:%{version}-%{release} -Provides: libguestfs-mount = %{epoch}:%{version}-%{release} -Obsoletes: libguestfs-mount < %{epoch}:%{version}-%{release} - %description tools-c This package contains miscellaneous system administrator command line @@ -394,9 +388,6 @@ Requires: perl(String::ShellQuote) Requires: perl(XML::Writer) Requires: perl(Win::Hivex) >= 1.2.7 -# for virt-make-fs: -Requires: /usr/bin/qemu-img - %description tools This package contains miscellaneous system administrator command line @@ -421,6 +412,9 @@ virtual machine. Virt-copy-in and virt-copy-out are command line tools for uploading and downloading files and directories to and from virtual machines. +Virt-customize is a command line tool for customizing virtual machine +disk images. + Virt-df is a command line tool to display free space on virtual machine filesystems. Unlike other tools, it doesn’t just display the amount of space allocated to a virtual machine, but can look inside @@ -428,6 +422,8 @@ the virtual machine to see how much space is really being used. It is like the df(1) command, but for virtual machines, except that it also works for Windows virtual machines. +Virt-diff shows the differences between virtual machines. + Virt-edit is a command line tool to edit the contents of a file in a virtual machine. @@ -530,9 +526,6 @@ Requires: %{name} = %{epoch}:%{version}-%{release} Requires: perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version)) # RHBZ#523547 Requires: perl(XML::XPath) -# RHBZ#652587 - for backwards compat with the old name -Provides: perl-%{name} = %{epoch}:%{version}-%{release} -Obsoletes: perl-%{name} < %{epoch}:%{version}-%{release} %description -n perl-Sys-Guestfs @@ -664,8 +657,10 @@ Requires: %{name}-gobject-devel = %{epoch}:%{version}-%{release} %ifarch %{arm} %{ix86} x86_64 %package -n golang-guestfs Summary: Golang bindings for %{name} +BuildArch: noarch Requires: %{name} = %{epoch}:%{version}-%{release} Requires: golang +Provides: golang(libguestfs.org) = %{epoch}:%{version}-%{release} %description -n golang-guestfs golang-%{name} contains Go language bindings for %{name}. @@ -695,19 +690,6 @@ for %{name}. %prep %setup -q -# Use git to manage patches. -# http://rwmj.wordpress.com/2011/08/09/nice-rpm-git-patch-management-trick/ -git init -git config user.email "libguestfs@redhat.com" -git config user.name "libguestfs" -git add . -git commit -a -q -m "%{version} baseline" -git am %{patches} - -# Patches affect Makefile.am and configure.ac, so rerun autotools. -autoreconf -i -autoconf - if [ "$(getenforce | tr '[A-Z]' '[a-z]')" != "disabled" ]; then # For sVirt to work, the local temporary directory we use in the # tests must be labelled the same way as /tmp. @@ -721,12 +703,6 @@ mkdir -p daemon/m4 mv README README.orig sed 's/@VERSION@/%{version}/g' < %{SOURCE4} > README -# Remove udev from the packagelist. systemd now 'obsoletes' udev, but -# supermin doesn't get this relationship right. When udev disappears -# from the repository we can stop doing this. -cp appliance/packagelist.in appliance/packagelist.in.orig -grep -Ev '\budev\b' < appliance/packagelist.in.orig > appliance/packagelist.in - %build # Test if network is available. @@ -765,9 +741,6 @@ fi --enable-install-daemon \ $extra -# Patches above add man pages, so this is needed. -make -C po-docs update-po - # 'INSTALLDIRS' ensures that Perl and Ruby libs are installed in the # vendor dir not the site dir. make V=1 INSTALLDIRS=vendor %{?_smp_mflags} @@ -779,6 +752,9 @@ gzip -9 ChangeLog %check + +%if %{runtests} + # Enable debugging - very useful if a test does fail, although # it produces masses of output in the build.log. export LIBGUESTFS_DEBUG=1 @@ -806,6 +782,19 @@ export SKIP_TEST_SET_LABEL=1 export SKIP_TEST_BTRFS_DEVICES_SH=1 %endif +# Disable mdadm test, buggy in kernel 3.13 (RHBZ#1033971). +export SKIP_TEST_MDADM_SH=1 + +# Disable NBD test, buggy in qemu 1.7.0 (RHBZ#1034433). +export SKIP_TEST_NBD_PL=1 + +# Virt-sparsify --in-place cannot sparsify as much as it should (RHBZ#1079210). +export SKIP_TEST_VIRT_SPARSIFY_IN_PLACE_SH=1 + +# Disable parallel virt-alignment-scan & virt-df tests (RHBZ#1025942). +export SKIP_TEST_VIRT_ALIGNMENT_SCAN_GUESTS_SH=1 +export SKIP_TEST_VIRT_DF_GUESTS_SH=1 + # Skip gnulib tests which fail (probably these are kernel/glibc bugs). pushd gnulib/tests make -k check ||: @@ -817,17 +806,17 @@ for f in test-getaddrinfo test-utimens ; do done popd -# Disable parallel virt-alignment-scan & virt-df tests (RHBZ#1025942). -export SKIP_TEST_VIRT_ALIGNMENT_SCAN_GUESTS_SH=1 -export SKIP_TEST_VIRT_DF_GUESTS_SH=1 +# Do make quickcheck first, to fail early if the appliance or libvirt +# is obviously broken. Also dump libvirt log files if this happens. +# Since it's most likely libvirt which is broken, make sure libvirt +# debugging is enabled here. +if ! make quickcheck LIBVIRT_DEBUG=1; then + cat $HOME/.cache/libvirt/qemu/log/* + exit 1 +fi -# Disabled on ARM because of RHBZ#990258. -# Disabled on 32 bit x86 because of RHBZ#998722 & RHBZ#998692. -# Disabled on ppc, ppc64 (secondary arches), see RHBZ#1036742. -%ifnarch armv7hl %{ix86} ppc ppc64 -%if %{runtests} make check -k -%endif + %endif @@ -848,23 +837,46 @@ find $RPM_BUILD_ROOT -name .packlist -delete find $RPM_BUILD_ROOT -name '*.bs' -delete find $RPM_BUILD_ROOT -name 'bindtests.pl' -delete -# Move Python libraries to sitelib. -if [ "$RPM_BUILD_ROOT%{python_sitearch}" != "$RPM_BUILD_ROOT%{python_sitelib}" ]; then - mkdir -p $RPM_BUILD_ROOT%{python_sitelib} - mv $RPM_BUILD_ROOT%{python_sitearch}/guestfs.py* \ - $RPM_BUILD_ROOT%{python_sitelib}/ -fi - # Don't use versioned jar file (RHBZ#1022133). # See: https://bugzilla.redhat.com/show_bug.cgi?id=1022184#c4 mv $RPM_BUILD_ROOT%{_datadir}/java/%{name}-%{version}.jar \ $RPM_BUILD_ROOT%{_datadir}/java/%{name}.jar +# golang: Ignore what libguestfs upstream installs, and just copy the +# source files to %{_datadir}/gocode/src. +%ifarch %{arm} %{ix86} x86_64 +rm -r $RPM_BUILD_ROOT%{_libdir}/golang +mkdir -p $RPM_BUILD_ROOT%{_datadir}/gocode/src +cp -a golang/src/libguestfs.org $RPM_BUILD_ROOT%{_datadir}/gocode/src +%endif + # Move installed documentation back to the source directory so # we can install it using a %%doc rule. mv $RPM_BUILD_ROOT%{_docdir}/libguestfs installed-docs gzip --best installed-docs/*.xml +# Split up the monolithic packages file in the supermin appliance so +# we can install dependencies in subpackages. +pushd $RPM_BUILD_ROOT%{_libdir}/guestfs/supermin.d +grep -Ev '^(gfs2-utils|hfsplus-tools|jfsutils|nilfs-utils|reiserfs-utils|iputils|lsof|openssh-clients|strace|vim-minimal|rsync|xfsprogs|zfs-fuse)$' < packages > packages.new +mv packages.new packages +echo gfs2-utils > zz-packages-gfs2 +echo hfsplus-tools > zz-packages-hfsplus +echo jfsutils > zz-packages-jfs +echo nilfs-utils > zz-packages-nilfs +echo reiserfs-utils > zz-packages-reiserfs +cat < zz-packages-rescue +iputils +lsof +openssh-clients +strace +vim-minimal +EOF +echo rsync > zz-packages-rsync +echo xfsprogs > zz-packages-xfs +echo zfs-fuse > zz-packages-zfs +popd + # For the libguestfs-live-service subpackage install the systemd # service and udev rules. mkdir -p $RPM_BUILD_ROOT%{_unitdir} @@ -895,6 +907,7 @@ mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/run/libguestfs %doc COPYING README %{_bindir}/libguestfs-test-tool %{_libdir}/guestfs/ +%exclude %{_libdir}/guestfs/supermin.d/zz-packages-* %{_libdir}/libguestfs.so.* %{_mandir}/man1/guestfs-faq.1* %{_mandir}/man1/guestfs-performance.1* @@ -918,6 +931,36 @@ mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/run/libguestfs %{_includedir}/guestfs.h %{_libdir}/pkgconfig/libguestfs.pc +%files gfs2 +%{_libdir}/guestfs/supermin.d/zz-packages-gfs2 + +%ifnarch %{arm} ppc +%files hfsplus +%{_libdir}/guestfs/supermin.d/zz-packages-hfsplus +%endif + +%files jfs +%{_libdir}/guestfs/supermin.d/zz-packages-jfs + +%files nilfs +%{_libdir}/guestfs/supermin.d/zz-packages-nilfs + +%files reiserfs +%{_libdir}/guestfs/supermin.d/zz-packages-reiserfs + +%files rsync +%{_libdir}/guestfs/supermin.d/zz-packages-rsync + +%files rescue +%{_libdir}/guestfs/supermin.d/zz-packages-rescue + +%files xfs +%{_libdir}/guestfs/supermin.d/zz-packages-xfs + +%ifnarch %{arm} +%files zfs +%{_libdir}/guestfs/supermin.d/zz-packages-zfs +%endif %files tools-c %doc README @@ -944,8 +987,12 @@ mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/run/libguestfs %{_mandir}/man1/virt-copy-in.1* %{_bindir}/virt-copy-out %{_mandir}/man1/virt-copy-out.1* +%{_bindir}/virt-customize +%{_mandir}/man1/virt-customize.1* %{_bindir}/virt-df %{_mandir}/man1/virt-df.1* +%{_bindir}/virt-diff +%{_mandir}/man1/virt-diff.1* %{_bindir}/virt-edit %{_mandir}/man1/virt-edit.1* %{_bindir}/virt-filesystems @@ -958,6 +1005,8 @@ mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/run/libguestfs %{_mandir}/man1/virt-inspector.1* %{_bindir}/virt-ls %{_mandir}/man1/virt-ls.1* +%{_bindir}/virt-make-fs +%{_mandir}/man1/virt-make-fs.1* %{_bindir}/virt-rescue %{_mandir}/man1/virt-rescue.1* %{_bindir}/virt-resize @@ -978,8 +1027,6 @@ mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/run/libguestfs %{_mandir}/man1/virt-list-filesystems.1* %{_bindir}/virt-list-partitions %{_mandir}/man1/virt-list-partitions.1* -%{_bindir}/virt-make-fs -%{_mandir}/man1/virt-make-fs.1* %{_bindir}/virt-tar %{_mandir}/man1/virt-tar.1* %{_bindir}/virt-win-reg @@ -1030,10 +1077,10 @@ mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/run/libguestfs %files -n python-%{name} %doc python/examples/*.py -%{python_sitearch}/* -%{python_sitelib}/*.py -%{python_sitelib}/*.pyc -%{python_sitelib}/*.pyo +%{python_sitearch}/libguestfsmod.so +%{python_sitearch}/guestfs.py +%{python_sitearch}/guestfs.pyc +%{python_sitearch}/guestfs.pyo %{_mandir}/man3/guestfs-python.3* @@ -1105,8 +1152,7 @@ mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/run/libguestfs %files -n golang-guestfs %doc golang/examples/*.go %doc golang/examples/LICENSE -%{_libdir}/golang/pkg/linux_*/libguestfs.org -%{_libdir}/golang/src/pkg/libguestfs.org +%{_datadir}/gocode/src/libguestfs.org %{_mandir}/man3/guestfs-golang.3* %endif @@ -1124,6 +1170,10 @@ mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/run/libguestfs %changelog +* Thu Mar 27 2014 Richard W.M. Jones - 1:1.26.0-1 +- New stable branch version 1.26.0. +- New features are covered in the release notes. + * Sat Mar 8 2014 Richard W.M. Jones - 1:1.24.8-1 - New stable branch version 1.24.8. - Backport more virt-builder patches from upstream to Fedora 20.