#!/usr/bin/env python # This file is part of Cockpit. # # Copyright (C) 2015 Red Hat, Inc. # # Cockpit is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; either version 2.1 of the License, or # (at your option) any later version. # # Cockpit is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with Cockpit; If not, see . import argparse import os import re import sys import subprocess BOTS = os.path.abspath(os.path.dirname(__file__)) BASE = os.path.normpath(os.path.join(BOTS, "..")) TEST = os.path.join(BASE, "test") os.environ["PATH"] = "{0}:{1}".format(os.environ.get("PATH"), BOTS) from machine import testvm parser = argparse.ArgumentParser( description='Run command inside or install packages into a Cockpit virtual machine', formatter_class=argparse.ArgumentDefaultsHelpFormatter ) parser.add_argument('-v', '--verbose', action='store_true', help='Display verbose progress details') parser.add_argument('-i', '--install', action='append', dest="packagelist", default=[], help='Install packages') parser.add_argument('-I', '--install-command', action='store', dest="installcommand", default="yum -y install", help="Command used to install packages in machine") parser.add_argument('-r', '--run-command', action='append', dest="commandlist", default=[], help='Run command inside virtual machine') parser.add_argument('-s', '--script', action='append', dest="scriptlist", default=[], help='Run selected script inside virtual machine') parser.add_argument('-u', '--upload', action='append', dest="uploadlist", default=[], help='Upload file/dir to destination file/dir separated by ":" example: -u file.txt:/var/lib') parser.add_argument('image', help='The image to use') args = parser.parse_args() # Create the necessary layered image for the build/install def prepare_install_image(base_image): if "/" not in base_image: base_image = os.path.join(BOTS, "images", base_image) test_images = os.path.join(TEST, "images") install_image = os.path.join(test_images, os.path.basename(base_image)) # In vm-customize we don't force recreate immages if not os.path.exists(install_image): if not os.path.exists(test_images): os.makedirs(test_images) base_image = os.path.realpath(base_image) qcow2_image = "{0}.qcow2".format(install_image) subprocess.check_call([ "qemu-img", "create", "-q", "-f", "qcow2", "-o", "backing_file={0},backing_fmt=qcow2".format(base_image), qcow2_image ]) if os.path.lexists(install_image): os.unlink(install_image) os.symlink(os.path.basename(qcow2_image), install_image) return install_image def run_command(machine_instance, commandlist): """Run command inside image""" for foo in commandlist: machine_instance.execute(foo) def run_script(machine_instance, scriptlist): """Run script inside image""" allscripts = [] for foo in scriptlist: if os.path.isfile(foo): pname = os.path.basename(foo) uploadpath = "/var/tmp/" + pname machine_instance.upload([foo], uploadpath) machine_instance.execute("chmod a+x %s" % uploadpath) machine_instance.execute(uploadpath) else: print >> sys.stderr, "Bad path to script:", foo def upload_files(machine_instance, uploadfiles): """Upload files/directories inside image""" for foo in uploadfiles: srcfile, dest = foo.split(":") src_absolute = os.path.join(os.getcwd(), srcfile) machine_instance.upload([src_absolute], dest) def install_packages(machine_instance, packagelist, install_command): """Install packages into a test image It could be done via local rpms or normal package installation """ allpackages = [] for foo in packagelist: if os.path.isfile(foo): pname = os.path.basename(foo) machine_instance.upload([foo], "/var/tmp/" + pname) allpackages.append("/var/tmp/" + pname) elif not re.search("/", foo): allpackages.append(foo) else: print >> sys.stderr, "Bad package name or path:", foo if allpackages: machine_instance.execute(install_command + " " + ' '.join(allpackages)) current_image = args.image if args.commandlist or args.packagelist or args.scriptlist or args.uploadlist: machine = testvm.VirtMachine( verbose=args.verbose, image=prepare_install_image(current_image), label="install") machine.start(maintain=True) machine.wait_boot() try: if args.commandlist: run_command(machine, args.commandlist) if args.packagelist: install_packages(machine, args.packagelist, args.installcommand) if args.scriptlist: run_script(machine, args.scriptlist) if args.uploadlist: upload_files(machine, args.uploadlist) finally: machine.stop()