Ejemplo n.º 1
0
def install(storage_backend, disk_size, iso_path, zfs_tank_name, max_vms,
            unattended_xml):
    logging.info("Ensuring that drakrun@* services are stopped...")
    subprocess.check_output('systemctl stop \'drakrun@*\'',
                            shell=True,
                            stderr=subprocess.STDOUT)

    logging.info("Performing installation...")

    if unattended_xml:
        logging.info("Baking unattended.iso for automated installation")
        with tempfile.TemporaryDirectory() as tmpdir:
            tmp_xml_path = os.path.join(tmpdir, 'autounattend.xml')

            with open(tmp_xml_path, 'wb') as fw:
                with open(unattended_xml, 'rb') as fr:
                    fw.write(fr.read())

            try:
                subprocess.check_output([
                    'genisoimage', '-o',
                    os.path.join(LIB_DIR, "volumes/unattended.iso"), '-J',
                    '-r', tmp_xml_path
                ],
                                        stderr=subprocess.STDOUT)
            except subprocess.CalledProcessError:
                logging.exception("Failed to generate unattended.iso.")

    sha256_hash = hashlib.sha256()

    with open(iso_path, "rb") as f:
        for byte_block in iter(lambda: f.read(4096), b""):
            sha256_hash.update(byte_block)

        iso_sha256 = sha256_hash.hexdigest()

    install_info = InstallInfo(storage_backend=storage_backend,
                               disk_size=disk_size,
                               iso_path=os.path.abspath(iso_path),
                               zfs_tank_name=zfs_tank_name,
                               max_vms=max_vms,
                               enable_unattended=unattended_xml is not None,
                               iso_sha256=iso_sha256)
    install_info.save()

    logging.info("Checking xen-detect...")
    proc = subprocess.run('xen-detect -N', shell=True)

    if proc.returncode != 1:
        logging.error(
            'It looks like the system is not running on Xen. Please reboot your machine into Xen hypervisor.'
        )
        return

    logging.info("Testing if xl tool is sane...")

    try:
        subprocess.check_output('xl info',
                                shell=True,
                                stderr=subprocess.STDOUT)
    except subprocess.CalledProcessError:
        logging.exception("Failed to test xl command.")
        return

    try:
        subprocess.check_output('xl uptime vm-0',
                                shell=True,
                                stderr=subprocess.STDOUT)
    except subprocess.CalledProcessError:
        pass
    else:
        logging.info('Detected that vm-0 is already running, stopping it.')
        subprocess.run('xl destroy vm-0', shell=True, check=True)

    generate_vm_conf(install_info, 0)

    backend = get_storage_backend(install_info)
    backend.initialize_vm0_volume(disk_size)

    try:
        subprocess.check_output("brctl show", shell=True)
    except subprocess.CalledProcessError:
        logging.exception(
            "Failed to execute brctl show. Make sure you have bridge-utils installed."
        )
        return

    try:
        subprocess.check_output('brctl addbr drak0',
                                stderr=subprocess.STDOUT,
                                shell=True)
    except subprocess.CalledProcessError as e:
        if b'already exists' in e.output:
            logging.info("Bridge drak0 already exists.")
        else:
            logging.exception("Failed to create bridge drak0.")

    cfg_path = os.path.join(ETC_DIR, "configs/vm-0.cfg")

    try:
        subprocess.run('xl create {}'.format(shlex.quote(cfg_path)),
                       shell=True,
                       check=True)
    except subprocess.CalledProcessError:
        logging.exception("Failed to launch VM vm-0")
        return

    logging.info("-" * 80)
    logging.info("Initial VM setup is complete and the vm-0 was launched.")
    logging.info(
        "Please now VNC to the port 5900 on this machine to perform Windows installation."
    )
    logging.info(
        "After you have installed Windows and booted it to the desktop, please execute:"
    )
    logging.info("# draksetup postinstall")

    with open(cfg_path, "r") as f:
        data = f.read()
        m = re.search(r'vncpasswd[ ]*=(.*)', data)
        if m:
            passwd = m.group(1).strip()
            if passwd[0] == '"' and passwd[-1] == '"':
                passwd = passwd[1:-1]

            logging.info("Your configured VNC password is:")
            logging.info(passwd)

    logging.info(
        "Please note that on some machines, system installer may boot for up to 10 minutes"
    )
    logging.info(
        "and may look unresponsive during the process. Please be patient.")
    logging.info("-" * 80)
Ejemplo n.º 2
0
def install(vcpus, memory, storage_backend, disk_size, iso_path, zfs_tank_name,
            lvm_volume_group, unattended_xml):
    if not check_root():
        return

    if storage_backend == "lvm" and lvm_volume_group is None:
        raise Exception("lvm storage backend requires --lvm-volume-group")
    if storage_backend == "zfs" and zfs_tank_name is None:
        raise Exception("zfs storage backend requires --zfs-tank-name")

    if not sanity_check():
        logging.error("Sanity check failed.")
        return

    stop_all_drakruns()

    logging.info("Performing installation...")

    if vcpus < 1:
        logging.error("Your VM must have at least 1 vCPU.")
        return

    if memory < 512:
        logging.error("Your VM must have at least 512 MB RAM.")
        return

    if memory < 1536:
        logging.warning(
            "Using less than 1.5 GB RAM per VM is not recommended for any supported system."
        )

    if unattended_xml:
        logging.info("Baking unattended.iso for automated installation")
        with tempfile.TemporaryDirectory() as tmpdir:
            tmp_xml_path = os.path.join(tmpdir, 'autounattend.xml')

            with open(tmp_xml_path, 'wb') as fw:
                with open(unattended_xml, 'rb') as fr:
                    fw.write(fr.read())

            try:
                subprocess.check_output([
                    'genisoimage', '-o',
                    os.path.join(VOLUME_DIR, "unattended.iso"), '-J', '-r',
                    tmp_xml_path
                ],
                                        stderr=subprocess.STDOUT)
            except subprocess.CalledProcessError:
                logging.exception("Failed to generate unattended.iso.")

    sha256_hash = hashlib.sha256()

    logging.info("Calculating hash of iso")
    iso_file_size = os.stat(iso_path).st_size
    block_size = 128 * 1024
    with tqdm(total=iso_file_size, unit_scale=True) as pbar:
        with open(iso_path, "rb") as f:
            for byte_block in iter(lambda: f.read(block_size), b""):
                pbar.update(block_size)
                sha256_hash.update(byte_block)

            iso_sha256 = sha256_hash.hexdigest()

    install_info = InstallInfo(vcpus=vcpus,
                               memory=memory,
                               storage_backend=storage_backend,
                               disk_size=disk_size,
                               iso_path=os.path.abspath(iso_path),
                               zfs_tank_name=zfs_tank_name,
                               lvm_volume_group=lvm_volume_group,
                               enable_unattended=unattended_xml is not None,
                               iso_sha256=iso_sha256)
    install_info.save()

    try:
        subprocess.check_output('xl uptime vm-0',
                                shell=True,
                                stderr=subprocess.STDOUT)
    except subprocess.CalledProcessError:
        pass
    else:
        logging.info('Detected that vm-0 is already running, stopping it.')
        subprocess.run('xl destroy vm-0', shell=True, check=True)

    generate_vm_conf(install_info, 0)

    backend = get_storage_backend(install_info)
    backend.initialize_vm0_volume(disk_size)

    try:
        subprocess.check_output("brctl show", shell=True)
    except subprocess.CalledProcessError:
        logging.exception(
            "Failed to execute brctl show. Make sure you have bridge-utils installed."
        )
        return

    net_enable = conf['drakrun'].getboolean('net_enable', fallback=False)
    out_interface = conf['drakrun'].get('out_interface', '')
    dns_server = conf['drakrun'].get('dns_server', '')

    setup_vm_network(vm_id=0,
                     net_enable=net_enable,
                     out_interface=out_interface,
                     dns_server=dns_server)

    if net_enable:
        start_dnsmasq(vm_id=0, dns_server=dns_server, background=True)

    cfg_path = os.path.join(VM_CONFIG_DIR, "vm-0.cfg")

    try:
        subprocess.run('xl create {}'.format(shlex.quote(cfg_path)),
                       shell=True,
                       check=True)
    except subprocess.CalledProcessError:
        logging.exception("Failed to launch VM vm-0")
        return

    logging.info("-" * 80)
    logging.info("Initial VM setup is complete and the vm-0 was launched.")
    logging.info(
        "Please now VNC to the port 5900 on this machine to perform Windows installation."
    )
    logging.info(
        "After you have installed Windows and booted it to the desktop, please execute:"
    )
    logging.info("# draksetup postinstall")

    with open(cfg_path, "r") as f:
        data = f.read()
        m = re.search(r'vncpasswd[ ]*=(.*)', data)
        if m:
            passwd = m.group(1).strip()
            if passwd[0] == '"' and passwd[-1] == '"':
                passwd = passwd[1:-1]

            logging.info("Your configured VNC password is:")
            logging.info(passwd)

    logging.info(
        "Please note that on some machines, system installer may boot for up to 10 minutes"
    )
    logging.info(
        "and may look unresponsive during the process. Please be patient.")
    logging.info("-" * 80)