From 272ccfe7c9e38941103801461888f32102d60234 Mon Sep 17 00:00:00 2001 From: Nikos Skalkotos <skalkoto@grnet.gr> Date: Tue, 18 Nov 2014 16:54:01 +0200 Subject: [PATCH] snf-mkimage: Add --host-run option This can be used to define scripts to run on the guest media after mounting it under a directory in the host. This resolves #13, resolves #14 and resolves #15 --- image_creator/main.py | 49 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/image_creator/main.py b/image_creator/main.py index 3ff3b5b..6f85f0e 100644 --- a/image_creator/main.py +++ b/image_creator/main.py @@ -33,6 +33,9 @@ import StringIO import signal import json import textwrap +import tempfile +import subprocess +import time def check_writable_dir(option, opt_str, value, parser): @@ -77,6 +80,14 @@ def parse_options(input_args): action="store_true", help="overwrite output files if they exist") + parser.add_option("--host-run", dest="host_run", default=[], + help="mount the media in the host and run a script " + "against the guest media. This option may be defined " + "multiple times. The script's working directory will be " + "the guest's root directory. BE CAREFUL! DO NOT USE " + "ABSOLUTE PATHS INSIDE THE SCRIPT! YOU MAY HARM YOUR " + "SYSTEM!", metavar="SCRIPT", action="append") + parser.add_option("--install-virtio", dest="virtio", type="string", help="install VirtIO drivers hosted under DIR " "(Windows only)", metavar="DIR") @@ -284,6 +295,17 @@ def image_creator(): "not be cleared out of sensitive data and will " "not get customized during the deployment.")) + if len(options.host_run) != 0 and not image.mount_local_support: + raise FatalError("Running scripts against the guest media is not " + "supported for this build of libguestfs.") + + if len(options.host_run) != 0: + for script in options.host_run: + if not os.path.isfile(script): + raise FatalError("File: `%s' does not exist." % script) + if not os.access(script, os.X_OK): + raise FatalError("File: `%s' is not executable." % script) + for sysprep in options.disabled_syspreps: image.os.disable_sysprep(image.os.get_sysprep_by_name(sysprep)) @@ -309,6 +331,33 @@ def image_creator(): hasattr(image.os, 'install_virtio_drivers'): image.os.install_virtio_drivers() + if len(options.host_run) != 0: + out.output("Running scripts on the input media:") + mpoint = tempfile.mkdtemp() + try: + image.mount(mpoint) + if not image.is_mounted(): + raise FatalError("Mounting the media on the host failed.") + try: + size = len(options.host_run) + cnt = 1 + for script in options.host_run: + script = os.path.abspath(script) + out.output(("(%d/%d)" % (cnt, size)).ljust(7), False) + out.output("Running `%s'" % script) + ret = subprocess.Popen([script], cwd=mpoint).wait() + if ret != 0: + raise FatalError("Script: `%s' failed (rc=%d)" % + (script, ret)) + cnt += 1 + finally: + while not image.umount(): + out.warn("Unable to umount the media. Retrying ...") + time.sleep(1) + out.output() + finally: + os.rmdir + if options.sysprep: image.os.do_sysprep() -- GitLab