def _prepare_args(self): # add --graphics none later # add whatever serial cmds are needed later args = [ "-n", self._virt_name, "-r", str(self._memory), "--noautoconsole", "--vcpus", str(self._vcpu_count), "--rng", "/dev/random" ] # CHECKME This seems to be necessary because of ipxe ibft chain booting, # otherwise the vm is created but it does not boot into installation if not self._boot: args.append("--noreboot") args.append("--graphics") if self._vnc: args.append(self._vnc) else: args.append("none") for ks in self._ks_paths: args.append("--initrd-inject") args.append(ks) for disk in self._disk_paths: args.append("--disk") args.append("path={0},bus=sata".format(disk)) for nic in self._nics or []: args.append("--network") args.append(nic) if self._iso.stage2: disk_opts = "path={0},device=cdrom,readonly=on,shareable=on".format( self._iso.iso_path) args.append("--disk") args.append(disk_opts) if self._ks_paths: extra_args = "ks=file:/{0}".format( os.path.basename(self._ks_paths[0])) else: extra_args = "" if not self._vnc: extra_args += " inst.cmdline" if self._kernel_args: extra_args += " " + self._kernel_args if self._iso.stage2: extra_args += " stage2=hd:CDLABEL={0}".format( udev_escape(self._iso.label)) if self._boot: # eg booting from ipxe to emulate ibft firmware args.append("--boot") args.append(self._boot) else: args.append("--extra-args") args.append(extra_args) args.append("--location") args.append(self._iso.iso_path + ",kernel=isolinux/vmlinuz,initrd=isolinux/initrd.img") channel_args = "tcp,host={0}:{1},mode=connect,target_type=virtio" \ ",name=org.fedoraproject.anaconda.log.0".format( self._virtio_host, self._virtio_port) args.append("--channel") args.append(channel_args) return args
def __init__(self, opts, iso, ks_paths, disk_img, img_size=2048, kernel_args=None, memory=1024, vcpus=None, vnc=None, arch=None, cancel_func=None, virtio_host="127.0.0.1", virtio_port=6080, image_type=None, boot_uefi=False, ovmf_path=None): """ Start the installation :param iso: Information about the iso to use for the installation :type iso: IsoMountpoint :param list ks_paths: Paths to kickstart files. All are injected, the first one is the one executed. :param str disk_img: Path to a disk image, created it it doesn't exist :param int img_size: The image size, in MiB, to create if it doesn't exist :param str kernel_args: Extra kernel arguments to pass on the kernel cmdline :param int memory: Amount of RAM to assign to the virt, in MiB :param int vcpus: Number of virtual cpus :param str vnc: Arguments to pass to qemu -display :param str arch: Optional architecture to use in the virt :param cancel_func: Function that returns True if the installation fails :type cancel_func: function :param str virtio_host: Hostname to connect virtio log to :param int virtio_port: Port to connect virtio log to :param str image_type: Type of qemu-img disk to create, or None. :param bool boot_uefi: Use OVMF to boot the VM in UEFI mode :param str ovmf_path: Path to the OVMF firmware """ # Lookup qemu-system- for arch if passed, or try to guess using host arch qemu_cmd = [ self.QEMU_CMDS.get(arch or os.uname().machine, "qemu-system-" + os.uname().machine) ] if not os.path.exists("/usr/bin/" + qemu_cmd[0]): raise InstallError("%s does not exist, cannot run qemu" % qemu_cmd[0]) qemu_cmd += ["-no-user-config"] qemu_cmd += ["-m", str(memory)] if vcpus: qemu_cmd += ["-smp", str(vcpus)] if not opts.no_kvm and os.path.exists("/dev/kvm"): qemu_cmd += ["--machine", "accel=kvm"] # Copy the initrd from the iso, create a cpio archive of the kickstart files # and append it to the temporary initrd. qemu_initrd = append_initrd(iso.initrd, ks_paths) qemu_cmd += ["-kernel", iso.kernel] qemu_cmd += ["-initrd", qemu_initrd] # Add the disk and cdrom if not os.path.isfile(disk_img): mksparse(disk_img, img_size * 1024**2) drive_args = "file=%s" % disk_img drive_args += ",cache=unsafe,discard=unmap" if image_type: drive_args += ",format=%s" % image_type else: drive_args += ",format=raw" qemu_cmd += ["-drive", drive_args] drive_args = "file=%s,media=cdrom,readonly=on" % iso.iso_path qemu_cmd += ["-drive", drive_args] # Setup the cmdline args # ====================== cmdline_args = "ks=file:/%s" % os.path.basename(ks_paths[0]) cmdline_args += " inst.stage2=hd:LABEL=%s" % udev_escape(iso.label) if opts.proxy: cmdline_args += " inst.proxy=%s" % opts.proxy if kernel_args: cmdline_args += " " + kernel_args cmdline_args += " inst.text inst.cmdline" qemu_cmd += ["-append", cmdline_args] if not opts.vnc: vnc_port = find_free_port() if vnc_port == -1: raise InstallError("No free VNC ports") display_args = "vnc=127.0.0.1:%d" % (vnc_port - 5900) else: display_args = opts.vnc log.info("qemu %s", display_args) qemu_cmd += ["-nographic", "-display", display_args] # Setup the virtio log port qemu_cmd += ["-device", "virtio-serial-pci,id=virtio-serial0"] qemu_cmd += [ "-device", "virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0" ",id=channel0,name=org.fedoraproject.anaconda.log.0" ] qemu_cmd += [ "-chardev", "socket,id=charchannel0,host=%s,port=%s" % (virtio_host, virtio_port) ] # PAss through rng from host if opts.with_rng != "none": qemu_cmd += [ "-object", "rng-random,id=virtio-rng0,filename=%s" % opts.with_rng ] qemu_cmd += [ "-device", "virtio-rng-pci,rng=virtio-rng0,id=rng0,bus=pci.0,addr=0x9" ] if boot_uefi and ovmf_path: qemu_cmd += [ "-drive", "file=%s/OVMF_CODE.fd,if=pflash,format=raw,unit=0,readonly=on" % ovmf_path ] # Make a copy of the OVMF_VARS.fd for this run ovmf_vars = tempfile.mktemp(prefix="lmc-OVMF_VARS-", suffix=".fd") shutil.copy2(joinpaths(ovmf_path, "/OVMF_VARS.fd"), ovmf_vars) qemu_cmd += [ "-drive", "file=%s,if=pflash,format=raw,unit=1" % ovmf_vars ] log.info("Running qemu") log.debug(qemu_cmd) try: execWithRedirect(qemu_cmd[0], qemu_cmd[1:], reset_lang=False, raise_err=True, callback=lambda p: not cancel_func()) except subprocess.CalledProcessError as e: log.error("Running qemu failed:") log.error("cmd: %s", " ".join(e.cmd)) log.error("output: %s", e.output or "") raise InstallError("QEMUInstall failed") except (OSError, KeyboardInterrupt) as e: log.error("Running qemu failed: %s", str(e)) raise InstallError("QEMUInstall failed") finally: os.unlink(qemu_initrd) if boot_uefi and ovmf_path: os.unlink(ovmf_vars) if cancel_func(): log.error("Installation error detected. See logfile for details.") raise InstallError("QEMUInstall failed") else: log.info("Installation finished without errors.")
#!/usr/bin/python3 import sys from pylorax.treebuilder import udev_escape if len(sys.argv) != 2: print("Usage: %s <string>" % sys.argv[0], file=sys.stderr) sys.exit(1) print(udev_escape(sys.argv[1]))