Add a new option to create files with the MD5 and SHA512 checksums of
all the disk image types produced.
This was implemented in diskimage-builder upstream as
commit 2ea5feca5c4b64867ac327736edfb20408f8840e and
commit 22952b7ea0543bb4f446752976d1d8ba232b021a.
---
dib/cmdline.ml | 7 +++++-
dib/cmdline.mli | 1 +
dib/dib.ml | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
dib/virt-dib.pod | 13 +++++++++++
4 files changed, 85 insertions(+), 5 deletions(-)
diff --git a/dib/cmdline.ml b/dib/cmdline.ml
index 144e5a7..418dbbd 100644
--- a/dib/cmdline.ml
+++ b/dib/cmdline.ml
@@ -56,6 +56,7 @@ type cmdline = {
arch : string;
envvars : string list;
docker_target : string option;
+ checksum : bool;
}
let parse_cmdline () =
@@ -158,6 +159,8 @@ read the man page virt-dib(1).
let docker_target = ref None in
let set_docker_target arg = docker_target := Some arg in
+ let checksum = ref false in
+
let argspec = [
[ S 'p'; L"element-path" ], Getopt.String
("path", append_element_path), s_"Add new a elements location";
[ L"exclude-element" ], Getopt.String ("element",
append_excluded_element),
@@ -177,6 +180,7 @@ read the man page virt-dib(1).
[ L"extra-packages" ], Getopt.String ("pkg,...",
append_extra_packages),
s_"Add extra packages to install";
[ L"docker-target" ], Getopt.String ("target",
set_docker_target), s_"Repo and tag for docker";
+ [ L"checksum" ], Getopt.Set checksum, s_"Generate MD5 and
SHA256 checksum files";
[ L"ramdisk" ], Getopt.Set is_ramdisk, "Switch to a ramdisk
build";
[ L"ramdisk-element" ], Getopt.Set_string ("name",
ramdisk_element), s_"Main element for building ramdisks";
@@ -234,6 +238,7 @@ read the man page virt-dib(1).
let machine_readable = !machine_readable in
let extra_packages = List.rev !extra_packages in
let docker_target = !docker_target in
+ let checksum = !checksum in
(* No elements and machine-readable mode? Print some facts. *)
if elements = [] && machine_readable then (
@@ -266,5 +271,5 @@ read the man page virt-dib(1).
extra_packages = extra_packages; memsize = memsize; network = network;
smp = smp; delete_on_failure = delete_on_failure;
formats = formats; arch = arch; envvars = envvars;
- docker_target = docker_target;
+ docker_target = docker_target; checksum = checksum;
}
diff --git a/dib/cmdline.mli b/dib/cmdline.mli
index 79364fb..2e004a0 100644
--- a/dib/cmdline.mli
+++ b/dib/cmdline.mli
@@ -48,6 +48,7 @@ type cmdline = {
arch : string;
envvars : string list;
docker_target : string option;
+ checksum : bool;
}
val parse_cmdline : unit -> cmdline
diff --git a/dib/dib.ml b/dib/dib.ml
index 9505c52..7f05870 100644
--- a/dib/dib.ml
+++ b/dib/dib.ml
@@ -27,6 +27,10 @@ open Printf
module G = Guestfs
+let checksums = [ "md5"; "sha512" ]
+and tool_of_checksum csum =
+ csum ^ "sum"
+
let exclude_elements elements = function
| [] ->
(* No elements to filter out, so just don't bother iterating through
@@ -68,9 +72,10 @@ let envvars_string l =
String.concat "\n" l
let prepare_external ~envvars ~dib_args ~dib_vars ~out_name ~root_label
- ~rootfs_uuid ~image_cache ~arch ~network ~debug ~fs_type
+ ~rootfs_uuid ~image_cache ~arch ~network ~debug ~fs_type ~checksum
destdir libdir hooksdir fakebindir all_elements element_paths =
let network_string = if network then "" else "1" in
+ let checksum_string = if checksum then "1" else "" in
let run_extra = sprintf "\
#!/bin/bash
@@ -106,6 +111,7 @@ export TMPDIR=\"${TMP_MOUNT_PATH}/tmp\"
export TMP_DIR=\"${TMPDIR}\"
export DIB_DEBUG_TRACE=%d
export FS_TYPE=%s
+export DIB_CHECKSUM=%s
ENVIRONMENT_D_DIR=$target_dir/../environment.d
@@ -136,13 +142,15 @@ $target_dir/$script
(String.concat ":" element_paths)
(quote dib_vars)
debug
- fs_type in
+ fs_type
+ checksum_string in
write_script (destdir // "run-part-extra.sh") run_extra
let prepare_aux ~envvars ~dib_args ~dib_vars ~log_file ~out_name ~rootfs_uuid
~arch ~network ~root_label ~install_type ~debug ~extra_packages ~fs_type
- destdir all_elements =
+ ~checksum destdir all_elements =
let network_string = if network then "" else "1" in
+ let checksum_string = if checksum then "1" else "" in
let script_run_part = sprintf "\
#!/bin/bash
@@ -191,6 +199,7 @@ export DIB_ENV=%s
export DIB_DEBUG_TRACE=%d
export DIB_NO_TMPFS=1
export FS_TYPE=%s
+export DIB_CHECKSUM=%s
export TMP_BUILD_DIR=$mysysroot/tmp/aux
export TMP_IMAGE_DIR=$mysysroot/tmp/aux
@@ -229,7 +238,8 @@ $target_dir/$script
(String.concat " " (StringSet.elements all_elements))
(quote dib_vars)
debug
- fs_type in
+ fs_type
+ checksum_string in
write_script (destdir // "run-part.sh") script_run_part;
let script_run_and_log = "\
#!/bin/bash
@@ -487,6 +497,8 @@ let main () =
require_tool "qemu-img";
if List.mem "vhd" cmdline.formats then
require_tool "vhd-util";
+ if cmdline.checksum then
+ List.iter (fun x -> require_tool (tool_of_checksum x)) checksums;
let image_basename = Filename.basename cmdline.image_name in
let image_basename_d = image_basename ^ ".d" in
@@ -600,6 +612,7 @@ let main () =
~install_type:cmdline.install_type ~debug
~extra_packages:cmdline.extra_packages
~fs_type:cmdline.fs_type
+ ~checksum:cmdline.checksum
auxtmpdir all_elements;
let delete_output_file = ref cmdline.delete_on_failure in
@@ -617,6 +630,7 @@ let main () =
~root_label ~rootfs_uuid ~image_cache ~arch
~network:cmdline.network ~debug
~fs_type:cmdline.fs_type
+ ~checksum:cmdline.checksum
tmpdir cmdline.basepath hookstmpdir
(auxtmpdir // "fake-bin")
all_elements cmdline.element_paths;
@@ -939,6 +953,53 @@ let main () =
) formats_img_nonraw;
);
+ if not is_ramdisk_build && cmdline.checksum then (
+ let file_flags = [ Unix.O_WRONLY; Unix.O_CREAT; Unix.O_TRUNC; Unix.O_CLOEXEC; ] in
+ List.iter (
+ fun fmt ->
+ let fn = output_filename cmdline.image_name fmt in
+ message (f_"Generating checksums for %s") fn;
+ let pids =
+ List.map (
+ fun csum ->
+ let csum_fn = fn ^ "." ^ csum in
+ let csum_tool = tool_of_checksum csum in
+ let outfd = Unix.openfile csum_fn file_flags 0o640 in
+ let args = [| csum_tool; fn; |] in
+ Common_utils.debug "%s" (stringify_args (Array.to_list args));
+ let pid = Unix.create_process csum_tool args Unix.stdin
+ outfd Unix.stderr in
+ (pid, csum_tool, outfd)
+ ) checksums in
+ let pids = ref pids in
+ while !pids <> [] do
+ let pid, stat = Unix.waitpid [] 0 in
+ let matching_pair, new_pids =
+ List.partition (
+ fun (p, tool, outfd) ->
+ pid = p
+ ) !pids in
+ if matching_pair <> [] then (
+ let matching_pair = List.hd matching_pair in
+ let _, csum_tool, outfd = matching_pair in
+ Unix.close outfd;
+ pids := new_pids;
+ match stat with
+ | Unix.WEXITED 0 -> ()
+ | Unix.WEXITED i ->
+ error (f_"external command '%s' exited with error %d")
+ csum_tool i
+ | Unix.WSIGNALED i ->
+ error (f_"external command '%s' killed by signal %d")
+ csum_tool i
+ | Unix.WSTOPPED i ->
+ error (f_"external command '%s' stopped by signal %d")
+ csum_tool i
+ );
+ done;
+ ) formats_img;
+ );
+
message (f_"Done")
let () = run_main_and_handle_errors main
diff --git a/dib/virt-dib.pod b/dib/virt-dib.pod
index eca3768..09251c7 100644
--- a/dib/virt-dib.pod
+++ b/dib/virt-dib.pod
@@ -72,6 +72,11 @@ Right now this option does nothing more than setting the C<ARCH>
environment variable for the elements, and it's up to them to
produce an image for the requested architecture.
+=item B<--checksum>
+
+Generate checksum files for the generated image. The supported
+checksums are MD5, and SHA256.
+
=item B<--colors>
=item B<--colours>
@@ -320,6 +325,14 @@ A directory containing any files created by the elements, for
example
F<dib-manifests> directory (created by the C<manifests> element),
ramdisks and kernels in ramdisk mode, and so on.
+=item F<$NAME.ext.checksum>
+
+When I<--checksum> is specified, there will be files for each
+supported checksum type; for example: F<$NAME.ext.md5>,
+F<$NAME.ext.sha256>, etc.
+
+Not applicable in ramdisk mode, see L</RAMDISK BUILDING>.
+
=back
=item B<--no-delete-on-failure>
--
2.9.3