def download_cloudbase_init( # pylint: disable=no-self-use self, workdir, arch, cloudbase_init=None): """Downloads cloudbase init.""" output_path = os.path.join(workdir, 'cloudbase_init.msi') if arch == 'amd64': msi_file = "CloudbaseInitSetup_x64.msi" elif arch == 'i386': msi_file = "CloudbaseInitSetup_x86.msi" download_path = "http://www.cloudbase.it/downloads/" + msi_file # --cloudbase-init passed in, don't download. if cloudbase_init: shutil.copyfile(cloudbase_init, output_path) return output_path # Remove me, testing only tmp_path = os.path.join('/tmp', msi_file) if os.path.exists(tmp_path): shutil.copyfile(tmp_path, output_path) return output_path utils.subp(['wget', '-O', output_path, download_path]) return output_path
def umount_partition( # pylint: disable=no-self-use self, disk_path, target, partition): """Un-mounts the target, marks ntfs as clean, and removes loopback.""" utils.subp(['umount', target]) devs = utils.kpartx_list(disk_path) utils.subp(['ntfsfix', '-d', devs[partition]]) utils.kpartx_del(disk_path) os.rmdir(target)
def unzip_archive(self, src, dest): # pylint: disable=no-self-use """Un-zips an archive into destination.""" utils.subp([ 'unzip', '-q', src, '-d', dest, ])
def download_ps_windows_update( # pylint: disable=no-self-use self, workdir): """Downloads the PSWindowsUpdate package.""" output_path = os.path.join(workdir, 'pswindowsupdate.zip') download_path = ("http://gallery.technet.microsoft.com/scriptcenter/" "2d191bcd-3308-4edd-9de2-88dff796b0bc/file/41459/43/" "PSWindowsUpdate.zip") utils.subp(['wget', '-O', output_path, download_path]) return output_path
def create_floppy_disk(self, output_path): # pylint: disable=no-self-use """Creates an empty floppy disk, formatted with vfat.""" utils.subp([ 'dd', 'if=/dev/zero', 'of=%s' % output_path, 'bs=1024', 'count=1440', ]) utils.subp(['mkfs.vfat', output_path])
def mount_iso(self, workdir, source): # pylint: disable=no-self-use """Mounts iso in 'iso' directory under workdir.""" iso_dir = os.path.join(workdir, 'iso') os.mkdir(iso_dir) utils.subp([ 'mount', source, iso_dir, ]) return iso_dir
def qemu_convert( # pylint: disable=no-self-use self, disk_path, output_path): """Converts the disk path to output path.""" utils.subp([ 'qemu-img', 'convert', '-O', 'raw', disk_path, output_path, ])
def create_disk(path, size, disk_format='qcow2'): """Creates disk using qemu-img.""" args = [ 'qemu-img', 'create', '-f', disk_format, path, '%sG' % size, ] utils.subp(args)
def create_tarball( # pylint: disable=no-self-use self, disk_path, output_path): """Creates tarball of the disk.""" disk_dir = os.path.dirname(os.path.abspath(disk_path)) disk_filename = os.path.basename(disk_path) utils.subp([ 'tar', 'Szcf', output_path, '-C', disk_dir, disk_filename, ])
def delete_tap(tap_name): """Deletes the tap device.""" try: utils.subp([ 'ip', 'tuntap', 'del', 'mode', 'tap', tap_name, ]) except utils.ProcessExecutionError: raise NetworkError('Failed to delete tap %s.' % tap_name)
def spawn_vm( # pylint: disable=no-self-use self, ram, vcpus, cdrom, floppy, install_iso, disk, tap=None): """Spawns the qemu vm for Windows to install.""" args = [ 'kvm-spice', '-m', '%s' % ram, '-smp', vcpus, '-cdrom', cdrom, '-drive', 'file=%s,index=0,format=raw,if=ide,media=disk' % disk, '-drive', 'file=%s,index=1,format=raw,if=floppy' % floppy, '-drive', 'file=%s,index=3,format=raw,if=ide,media=cdrom' % install_iso, ] if tap is not None: mac = net.get_random_qemu_mac() args.extend([ '-device', 'rtl8139,netdev=net00,mac=%s' % mac, '-netdev', 'type=tap,id=net00,script=no,downscript=no,ifname=%s' % tap, ]) args.extend([ '-boot', 'd', '-vga', 'std', '-k', 'en-us', # Debug *Remove* '-vnc', ':1', ]) utils.subp(args)
def prepare_floppy_disk(self, workdir, arch, edition, language, license_key=None, enable_updates=False): """Prepares the working directory with Autounattend.vfd.""" # Create the disk vfd_path = os.path.join(workdir, 'Autounattend.vfd') self.create_floppy_disk(vfd_path) # Mount the disk mount_path = os.path.join(workdir, 'vfd_mount') os.mkdir(mount_path) utils.subp([ 'mount', '-t', 'vfat', '-o', 'loop', vfd_path, mount_path, ]) # Place the generated Autounattend.xml file xml_path = os.path.join(mount_path, 'Autounattend.xml') try: self.write_unattended(xml_path, arch, edition, language, license_key=license_key, enable_updates=enable_updates) finally: utils.subp(['umount', mount_path]) os.rmdir(mount_path) return vfd_path
def create_iso(self, workdir, source): # pylint: disable=no-self-use """Creates iso at output, containing files at source.""" output = os.path.join(workdir, 'output.iso') utils.subp([ 'mkisofs', '-o', output, '-b', 'isolinux/isolinux.bin', '-c', 'isolinux/boot.cat', '-no-emul-boot', '-boot-load-size', '4', '-boot-info-table', '-R', '-J', '-v', '-T', source ]) utils.subp(['chmod', '777', workdir]) utils.subp(['chmod', '777', output]) return output
def create_tap(bridge): """Creates the tap device on bridge.""" tap_name = get_avaliable_tap_name() owner = utils.get_sudo_user() # Create the tap device try: utils.subp([ 'ip', 'tuntap', 'add', 'mode', 'tap', 'user', owner, tap_name, ]) except utils.ProcessExecutionError: raise NetworkError('Failed to create tap %s for %s.' % (tap_name, owner)) # Bring the tap device up try: utils.subp([ 'ip', 'link', 'set', tap_name, 'up', ]) except utils.ProcessExecutionError: delete_tap(tap_name) raise NetworkError('Failed to bring up %s.' % tap_name) # Add the tap device to the bridge try: utils.subp([ 'ip', 'link', 'set', tap_name, 'master', bridge, ]) except utils.ProcessExecutionError: delete_tap(tap_name) raise NetworkError('Failed to add tap %s to %s.' % (tap_name, bridge)) return tap_name
def convert_to_unix(self, file_path): # pylint: disable=no-self-use """Converts file to unix to easily view.""" try: utils.subp(['dos2unix', file_path]) except utils.ProcessExecutionError: pass
def create_disk_image( # pylint: disable=no-self-use self, output_path, size): """Creates the disk image that Windows will install to.""" utils.subp(['qemu-img', 'create', '-f', 'raw', output_path, size])
def build_image(self, params): """Builds the image with virt-install.""" # Check for valid location if self.install_location is None and self.install_cdrom is None: raise BuildError( "Missing install_location or install_cdrom for virt-install.") # Naming full_name = self.full_name(params) # Create work space with utils.tempdir() as workdir: # virt-install fails to access the directory # unless the following permissions are used utils.subp(['chmod', '777', workdir]) # Create the disk, and set the permissions # that will allow virt-install to access it disk_path = os.path.join(workdir, 'disk.img') virt.create_disk(disk_path, self.disk_size, disk_format='raw') utils.subp(['chmod', '777', disk_path]) disk_str = "path=%s,format=raw" % disk_path # Start the installation vm_name = 'img-build-%s' % full_name network_str = 'bridge=%s' % params.interface if self.nic_model is not None: network_str = '%s,model=%s' % (network_str, self.nic_model) if self.install_location: virt.install_location(vm_name, params.ram, params.arch, params.vcpus, self.os_type, self.os_variant, disk_str, network_str, self.install_location, initrd_inject=self.initrd_inject, extra_args=self.extra_arguments) else: virt.install_cdrom(vm_name, params.ram, params.arch, params.vcpus, self.os_type, self.os_variant, disk_str, network_str, self.install_cdrom) # Remove the finished installation from virsh virt.undefine(vm_name) # Mount the disk image mount_path = os.path.join(workdir, "mount") os.mkdir(mount_path) try: utils.mount_loop(disk_path, mount_path) # Allow the osystem module to install any needed files # into the filesystem self.modify_mount(mount_path) # Create the tarball output_path = os.path.join(workdir, "output.tar.gz") utils.create_tarball(output_path, mount_path) finally: utils.umount_loop(disk_path, mount_path) # Place in output shutil.move(output_path, params.output)
def undefine(name): """Undefines the virtual machine from virsh without deleting the storage volume. """ utils.subp(['virsh', 'undefine', name])
def umount_iso(self, iso_dir): # pylint: disable=no-self-use """Unmounts iso at path.""" utils.subp(['umount', iso_dir])
def create_iso(self, output, source): # pylint: disable=no-self-use """Creates iso at output, containing files at source.""" utils.subp( ['genisoimage', '-o', output, '-V', 'SCRIPTS', '-J', source])