Exemplo n.º 1
0
def config_worker():
    """
    Enable worker functionality for AIO system.
    :return: True if worker-config-complete is executed
    """
    if utils.get_system_type() == si_const.TIS_AIO_BUILD:
        console_log("Applying worker manifests for {}. "
                    "Node will reboot on completion.".format(
                        utils.get_controller_hostname()))
        sysinv.do_worker_config_complete(utils.get_controller_hostname())
        time.sleep(30)
        # worker-config-complete has no logs to console. So, wait
        # for some time before showing the login prompt.
        for i in range(1, 10):
            console_log("worker-config in progress..")
            time.sleep(30)
        console_log("Timed out on do_worker_config_complete")
        raise CloneFail("Timed out on do_worker_config_complete")
        return True
    else:
        # worker_config_complete is not needed.
        return False
Exemplo n.º 2
0
def validate_controller_state():
    """ Cloning allowed now? """
    # Check if this Controller is enabled and provisioned
    try:
        if not sysinv_api.controller_enabled_provisioned(
                utils.get_controller_hostname()):
            raise CloneFail("Controller is not enabled/provisioned")
        if (tsconfig.system_mode == si_const.SYSTEM_MODE_DUPLEX
                or tsconfig.system_mode == si_const.SYSTEM_MODE_DUPLEX_DIRECT):
            if not sysinv_api.controller_enabled_provisioned(
                    utils.get_mate_controller_hostname()):
                raise CloneFail("Mate controller is not enabled/provisioned")
    except CloneFail:
        raise
    except Exception:
        raise CloneFail("Controller is not enabled/provisioned")

    if utils.get_system_type() != si_const.TIS_AIO_BUILD:
        raise CloneFail("Cloning supported only on All-in-one systems")

    if len(sysinv_api.get_alarms()) > 0:
        raise CloneFail("There are active alarms on this system!")
Exemplo n.º 3
0
def create_iso(iso_name, archive_dir):
    """ Create iso image. This is modelled after
        the cgcs-root/build-tools/build-iso tool. """
    try:
        controller_0 = sysinv_api.get_host_data('controller-0')
    except Exception as e:
        e_log = "Failed to retrieve controller-0 inventory details."
        LOG.exception(e_log)
        raise CloneFail(e_log)

    iso_dir = os.path.join(archive_dir, 'isolinux')
    clone_archive_dir = os.path.join(iso_dir, CLONE_ARCHIVE_DIR)
    output = None
    tmpdir = None
    total_steps = 6
    step = 1
    print("\nCreating ISO:")

    # Add the correct kick-start file to the image
    ks_file = "controller_ks.cfg"
    if utils.get_system_type() == si_const.TIS_AIO_BUILD:
        if si_const.LOWLATENCY in tsconfig.subfunctions:
            ks_file = "smallsystem_lowlatency_ks.cfg"
        else:
            ks_file = "smallsystem_ks.cfg"

    try:
        # prepare the iso files
        images_dir = os.path.join(iso_dir, 'images')
        os.mkdir(images_dir, 0o644)
        pxe_dir = os.path.join('/pxeboot', 'rel-' + tsconfig.SW_VERSION)
        os.symlink(pxe_dir + '/installer-bzImage', iso_dir + '/vmlinuz')
        os.symlink(pxe_dir + '/installer-initrd', iso_dir + '/initrd.img')
        utils.progress(total_steps, step, 'preparing files', 'DONE')
        step += 1

        feed_dir = os.path.join('/www', 'pages', 'feed',
                                'rel-' + tsconfig.SW_VERSION)
        os.symlink(feed_dir + '/Packages', iso_dir + '/Packages')
        os.symlink(feed_dir + '/repodata', iso_dir + '/repodata')
        os.symlink(feed_dir + '/LiveOS', iso_dir + '/LiveOS')
        shutil.copy2(feed_dir + '/isolinux.cfg', iso_dir)
        update_bootloader_default(iso_dir + '/isolinux.cfg', controller_0)
        shutil.copyfile('/usr/share/syslinux/isolinux.bin',
                        iso_dir + '/isolinux.bin')
        os.symlink('/usr/share/syslinux/vesamenu.c32',
                   iso_dir + '/vesamenu.c32')
        for filename in glob.glob(os.path.join(feed_dir, '*ks.cfg')):
            shutil.copy(os.path.join(feed_dir, filename), iso_dir)
        utils.progress(total_steps, step, 'preparing files', 'DONE')
        step += 1

        efiboot_dir = os.path.join(iso_dir, 'EFI', 'BOOT')
        os.makedirs(efiboot_dir, 0o644)
        l_efi_dir = os.path.join('/boot', 'efi', 'EFI')
        shutil.copy2(l_efi_dir + '/BOOT/BOOTX64.EFI', efiboot_dir)
        shutil.copy2(l_efi_dir + '/centos/MokManager.efi', efiboot_dir)
        shutil.copy2(l_efi_dir + '/centos/grubx64.efi', efiboot_dir)
        shutil.copy2('/pxeboot/EFI/grub.cfg', efiboot_dir)
        update_bootloader_default(efiboot_dir + '/grub.cfg', controller_0)
        shutil.copytree(l_efi_dir + '/centos/fonts', efiboot_dir + '/fonts')
        # copy EFI boot image and update the grub.cfg file
        efi_img = images_dir + '/efiboot.img'
        shutil.copy2(pxe_dir + '/efiboot.img', efi_img)
        tmpdir = tempfile.mkdtemp(dir=archive_dir)
        output = subprocess.check_output(
            ["mount", "-t", "vfat", "-o", "loop", efi_img, tmpdir],
            stderr=subprocess.STDOUT)
        # replace the grub.cfg file with the updated file
        efi_grub_f = os.path.join(tmpdir, 'EFI', 'BOOT', 'grub.cfg')
        os.remove(efi_grub_f)
        shutil.copy2(efiboot_dir + '/grub.cfg', efi_grub_f)
        subprocess.call(['umount', tmpdir])
        shutil.rmtree(tmpdir, ignore_errors=True)
        tmpdir = None

        epoch_time = "%.9f" % time.time()
        disc_info = [epoch_time, tsconfig.SW_VERSION, "x86_64"]
        with open(iso_dir + '/.discinfo', 'w') as f:
            f.write('\n'.join(disc_info))

        # copy the latest install_clone executable
        shutil.copy2('/usr/bin/install_clone', iso_dir)
        subprocess.check_output("cat /pxeboot/post_clone_iso_ks.cfg >> " +
                                iso_dir + "/" + ks_file,
                                shell=True)
        utils.progress(total_steps, step, 'preparing files', 'DONE')
        step += 1

        # copy patches
        iso_patches_dir = os.path.join(iso_dir, 'patches')
        iso_patch_repo_dir = os.path.join(iso_patches_dir, 'repodata')
        iso_patch_pkgs_dir = os.path.join(iso_patches_dir, 'Packages')
        iso_patch_metadata_dir = os.path.join(iso_patches_dir, 'metadata')
        iso_patch_applied_dir = os.path.join(iso_patch_metadata_dir, 'applied')
        iso_patch_committed_dir = os.path.join(iso_patch_metadata_dir,
                                               'committed')

        os.mkdir(iso_patches_dir, 0o755)
        os.mkdir(iso_patch_repo_dir, 0o755)
        os.mkdir(iso_patch_pkgs_dir, 0o755)
        os.mkdir(iso_patch_metadata_dir, 0o755)
        os.mkdir(iso_patch_applied_dir, 0o755)
        os.mkdir(iso_patch_committed_dir, 0o755)

        repodata = '/www/pages/updates/rel-%s/repodata/' % tsconfig.SW_VERSION
        pkgsdir = '/www/pages/updates/rel-%s/Packages/' % tsconfig.SW_VERSION
        patch_applied_dir = '/opt/patching/metadata/applied/'
        patch_committed_dir = '/opt/patching/metadata/committed/'
        subprocess.check_call(
            ['rsync', '-a', repodata,
             '%s/' % iso_patch_repo_dir])
        if os.path.exists(pkgsdir):
            subprocess.check_call(
                ['rsync', '-a', pkgsdir,
                 '%s/' % iso_patch_pkgs_dir])
        if os.path.exists(patch_applied_dir):
            subprocess.check_call([
                'rsync', '-a', patch_applied_dir,
                '%s/' % iso_patch_applied_dir
            ])
        if os.path.exists(patch_committed_dir):
            subprocess.check_call([
                'rsync', '-a', patch_committed_dir,
                '%s/' % iso_patch_committed_dir
            ])
        utils.progress(total_steps, step, 'preparing files', 'DONE')
        step += 1

        create_ini_file(clone_archive_dir, iso_name)

        os.chmod(iso_dir + '/isolinux.bin', 0o664)
        iso_file = os.path.join(archive_dir, iso_name + ".iso")
        output = subprocess.check_output([
            "nice", "mkisofs", "-o", iso_file, "-R", "-D", "-A", "oe_iso_boot",
            "-V", "oe_iso_boot", "-f", "-quiet", "-b", "isolinux.bin", "-c",
            "boot.cat", "-no-emul-boot", "-boot-load-size", "4",
            "-boot-info-table", "-eltorito-alt-boot", "-e",
            "images/efiboot.img", "-no-emul-boot", iso_dir
        ],
                                         stderr=subprocess.STDOUT)
        LOG.info("{} created: [{}]".format(iso_file, output))
        utils.progress(total_steps, step, 'iso created', 'DONE')
        step += 1

        output = subprocess.check_output(
            ["nice", "isohybrid", "--uefi", iso_file],
            stderr=subprocess.STDOUT)
        LOG.debug("isohybrid: {}".format(output))

        output = subprocess.check_output(["nice", "implantisomd5", iso_file],
                                         stderr=subprocess.STDOUT)
        LOG.debug("implantisomd5: {}".format(output))
        utils.progress(total_steps, step, 'checksum implanted', 'DONE')
        print("Cloned iso image created: {}".format(iso_file))

    except Exception as e:
        LOG.exception(e)
        e_log = "ISO creation ({}) failed".format(iso_name)
        if output:
            e_log += ' [' + output + ']'
        LOG.error(e_log)
        raise CloneFail("ISO creation failed.")

    finally:
        if tmpdir:
            subprocess.call(['umount', tmpdir], stderr=DEVNULL)
            shutil.rmtree(tmpdir, ignore_errors=True)
Exemplo n.º 4
0
def update_bootloader_default(bl_file, host):
    """ Update bootloader files for cloned image """
    if not os.path.exists(bl_file):
        LOG.error("{} does not exist".format(bl_file))
        raise CloneFail("{} does not exist".format(os.path.basename(bl_file)))

    # Tags should be in sync with common-bsp/files/centos.syslinux.cfg
    # and common-bsp/files/grub.cfg
    STANDARD_STANDARD = '0'
    STANDARD_EXTENDED = 'S0'
    AIO_STANDARD = '2'
    AIO_EXTENDED = 'S2'
    AIO_LL_STANDARD = '4'
    AIO_LL_EXTENDED = 'S4'
    if "grub.cfg" in bl_file:
        STANDARD_STANDARD = 'standard>serial>' + \
            si_const.SYSTEM_SECURITY_PROFILE_STANDARD
        STANDARD_EXTENDED = 'standard>serial>' + \
            si_const.SYSTEM_SECURITY_PROFILE_EXTENDED
        AIO_STANDARD = 'aio>serial>' + \
            si_const.SYSTEM_SECURITY_PROFILE_STANDARD
        AIO_EXTENDED = 'aio>serial>' + \
            si_const.SYSTEM_SECURITY_PROFILE_EXTENDED
        AIO_LL_STANDARD = 'aio-lowlat>serial>' + \
            si_const.SYSTEM_SECURITY_PROFILE_STANDARD
        AIO_LL_EXTENDED = 'aio-lowlat>serial>' + \
            si_const.SYSTEM_SECURITY_PROFILE_EXTENDED
        SUBMENUITEM_TBOOT = 'tboot'
        SUBMENUITEM_SECUREBOOT = 'secureboot'

    timeout_line = None
    default_line = None
    default_label_num = STANDARD_STANDARD
    if utils.get_system_type() == si_const.TIS_AIO_BUILD:
        if si_const.LOWLATENCY in tsconfig.subfunctions:
            default_label_num = AIO_LL_STANDARD
        else:
            default_label_num = AIO_STANDARD
    if (tsconfig.security_profile == si_const.SYSTEM_SECURITY_PROFILE_EXTENDED
        ):
        default_label_num = STANDARD_EXTENDED
        if utils.get_system_type() == si_const.TIS_AIO_BUILD:
            if si_const.LOWLATENCY in tsconfig.subfunctions:
                default_label_num = AIO_LL_EXTENDED
            else:
                default_label_num = AIO_EXTENDED
        if "grub.cfg" in bl_file:
            if host.tboot is not None:
                if host.tboot == "true":
                    default_label_num = default_label_num + '>' + \
                        SUBMENUITEM_TBOOT
                else:
                    default_label_num = default_label_num + '>' + \
                        SUBMENUITEM_SECUREBOOT

    try:
        with open(bl_file) as f:
            s = f.read()
            for line in s.split("\n"):
                if line.startswith("timeout"):
                    timeout_line = line
                elif line.startswith("default"):
                    default_line = line

            if "grub.cfg" in bl_file:
                replace = "default='{}'\ntimeout=10".format(default_label_num)
            else:  # isolinux format
                replace = "default {}\ntimeout 10".format(default_label_num)

            if default_line and timeout_line:
                s = s.replace(default_line, "")
                s = s.replace(timeout_line, replace)
            elif default_line:
                s = s.replace(default_line, replace)
            elif timeout_line:
                s = s.replace(timeout_line, replace)
            else:
                s = replace + s

            s = re.sub(r'boot_device=[^\s]*',
                       'boot_device=%s' % host.boot_device, s)
            s = re.sub(r'rootfs_device=[^\s]*',
                       'rootfs_device=%s' % host.rootfs_device, s)
            s = re.sub(r'console=[^\s]*', 'console=%s' % host.console, s)

        with open(bl_file, "w") as f:
            LOG.info(
                "rewriting {}: label={} find=[{}][{}] replace=[{}]".format(
                    bl_file, default_label_num, timeout_line, default_line,
                    replace.replace('\n', '<newline>')))
            f.write(s)

    except Exception as e:
        LOG.error("update_bootloader_default failed: {}".format(e))
        raise CloneFail("Failed to update bootloader files")