#!/usr/bin/python -tt # # Copyright(c) FUJITSU Limited 2007. # # Script to set up a cloning guest configuration and kick off an cloning # # 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., 675 Mass Ave, Cambridge, MA 02139, USA. import os, sys, string from optparse import OptionParser, OptionValueError import subprocess import libxml2 import virtinst import virtinst.CloneManager as clmgr ### Utility functions def prompt_for_input(prompt = "", val = None): if val is not None: return val print prompt + " ", return sys.stdin.readline().strip() ### General input gathering functions def get_clone_name(clone_name, design): design.clone_name = clone_name def get_name(name, design): while 1: name = prompt_for_input("What is the name of the source virtual machine?", name) try: design.guest_name = name break except ValueError, e: print "ERROR: ", e name = None def get_clone_macaddr(clone_mac, design): if clone_mac is None: pass elif clone_mac[0] == "RANDOM": clone_mac = None else: for i in clone_mac: design.set_clone_mac(i) def get_clone_diskfile(clone_diskfile, design): if clone_diskfile is None: raise ValueError, "The disk image file for the clone must be needed" for i in clone_diskfile: design.set_clone_devices(i) ### Option parsing def check_before_store(option, opt_str, value, parser): if len(value) == 0: raise OptionValueError, "%s option requires an argument" %opt_str setattr(parser.values, option.dest, value) def check_before_append(option, opt_str, value, parser): if len(value) == 0: raise OptionValueError, "%s option requires an argument" %opt_str parser.values.ensure_value(option.dest, []).append(value) def parse_args(): parser = OptionParser() # src vm parser.add_option("-n", "--name", type="string", dest="name", action="callback", callback=check_before_store, help="Name of the source guest instance; The status must be shutoff") # clone vm parser.add_option("-w", "--new", type="string", dest="clone_name", action="callback", callback=check_before_store, help="Name of the clone guest instance; if none, adding fixed string _CLONE to source guest name") # clone vm mac parser.add_option("-m", "--mac", type="string", dest="clone_mac", action="callback", callback=check_before_append, help="Fixed MAC address for the clone guest; if none or RANDOM is given a random address will be used") # disk options parser.add_option("-f", "--file", type="string", dest="clone_diskfile", action="callback", callback=check_before_append, help="File to use as the disk image for the clone guest instance") (options,args) = parser.parse_args() return options ### Let's do it! def main(): if os.geteuid() != 0: print >> sys.stderr, "Must be root to clone guests" sys.exit(1) options = parse_args() design = clmgr.CloneDesign() try: get_clone_diskfile(options.clone_diskfile, design) get_clone_macaddr(options.clone_mac, design) get_name(options.name, design) get_clone_name(options.clone_name, design) clmgr.start_dumplicate(design) except Exception, e: print "ERROR: ", e sys.exit(1) if __name__ == "__main__": main()