Beispiel #1
0
def unmount_main(args):
    """
    run util.umount(target, recursive=True)
    """
    if args.target is None:
        msg = "Missing target.  Please provide target path parameter"
        raise ValueError(msg)

    if not os.path.exists(args.target):
        msg = "Cannot unmount target path %s: it does not exist" % args.target
        raise util.FileMissingError(msg)

    LOG.info("Unmounting devices from target path: %s", args.target)
    recursive_mode = not args.disable_recursive_mounts
    util.do_umount(args.target, recursive=recursive_mode)
Beispiel #2
0
def get_root_device(dev, paths=None):
    """
    Get root partition for specified device, based on presence of any
    paths in the provided paths list:
    """
    if paths is None:
        paths = ["curtin"]
    LOG.debug('Searching for filesystem on %s containing one of: %s',
              dev, paths)
    partitions = get_pardevs_on_blockdevs(dev)
    target = None
    tmp_mount = tempfile.mkdtemp()
    for i in partitions:
        dev_path = partitions[i]['device_path']
        mp = None
        try:
            util.do_mount(dev_path, tmp_mount)
            mp = tmp_mount
            for path in paths:
                fullpath = os.path.join(tmp_mount, path)
                if os.path.isdir(fullpath):
                    target = dev_path
                    LOG.debug("Found path '%s' on device '%s'",
                              path, dev_path)
                    break
        except Exception:
            pass
        finally:
            if mp:
                util.do_umount(mp)

    os.rmdir(tmp_mount)
    if target is None:
        raise ValueError(
            "Did not find any filesystem on %s that contained one of %s" %
            (dev, paths))
    return target
Beispiel #3
0
def cmd_install(args):
    from .collect_logs import create_log_tarfile
    cfg = deepcopy(CONFIG_BUILTIN)
    config.merge_config(cfg, args.config)

    for source in args.source:
        src = util.sanitize_source(source)
        cfg['sources']["%02d_cmdline" % len(cfg['sources'])] = src

    LOG.info(INSTALL_START_MSG)
    LOG.debug('LANG=%s', os.environ.get('LANG'))
    LOG.debug("merged config: %s" % cfg)
    if not len(cfg.get('sources', [])):
        raise util.BadUsage("no sources provided to install")

    for i in cfg['sources']:
        # we default to tgz for old style sources config
        cfg['sources'][i] = util.sanitize_source(cfg['sources'][i])

    migrate_proxy_settings(cfg)
    for k in ('http_proxy', 'https_proxy', 'no_proxy'):
        if k in cfg['proxy']:
            os.environ[k] = cfg['proxy'][k]

    instcfg = cfg.get('install', {})
    logfile = instcfg.get('log_file')
    error_tarfile = instcfg.get('error_tarfile')
    post_files = instcfg.get('post_files', [logfile])

    # Generate curtin configuration dump and add to write_files unless
    # installation config disables dump
    yaml_dump_file = instcfg.get('save_install_config', SAVE_INSTALL_CONFIG)
    if yaml_dump_file:
        write_files = cfg.get('write_files', {})
        write_files['curtin_install_cfg'] = {
            'path': yaml_dump_file,
            'permissions': '0400',
            'owner': 'root:root',
            'content': config.dump_config(cfg)
        }
        cfg['write_files'] = write_files

    # Load reporter
    clear_install_log(logfile)
    legacy_reporter = load_reporter(cfg)
    legacy_reporter.files = post_files

    writeline_and_stdout(logfile, INSTALL_START_MSG)
    args.reportstack.post_files = post_files
    workingd = None
    try:
        workingd = WorkingDir(cfg)
        dd_images = util.get_dd_images(cfg.get('sources', {}))
        if len(dd_images) > 1:
            raise ValueError("You may not use more than one disk image")

        LOG.debug(workingd.env())
        env = os.environ.copy()
        env.update(workingd.env())

        for name in cfg.get('stages'):
            desc = STAGE_DESCRIPTIONS.get(name, "stage %s" % name)
            reportstack = events.ReportEventStack(
                "stage-%s" % name, description=desc,
                parent=args.reportstack)
            env['CURTIN_REPORTSTACK'] = reportstack.fullname

            with reportstack:
                commands_name = '%s_commands' % name
                with util.LogTimer(LOG.debug, 'stage_%s' % name):
                    stage = Stage(name, cfg.get(commands_name, {}), env,
                                  reportstack=reportstack, logfile=logfile)
                    stage.run()

        if apply_kexec(cfg.get('kexec'), workingd.target):
            cfg['power_state'] = {'mode': 'reboot', 'delay': 'now',
                                  'message': "'rebooting with kexec'"}

        writeline_and_stdout(logfile, INSTALL_PASS_MSG)
        legacy_reporter.report_success()
    except Exception as e:
        exp_msg = INSTALL_FAIL_MSG.format(exception=e)
        writeline(logfile, exp_msg)
        LOG.error(exp_msg)
        legacy_reporter.report_failure(exp_msg)
        if error_tarfile:
            create_log_tarfile(error_tarfile, cfg)
        raise e
    finally:
        log_target_path = instcfg.get('save_install_log', SAVE_INSTALL_LOG)
        if log_target_path and workingd:
            copy_install_log(logfile, workingd.target, log_target_path)

        if instcfg.get('unmount', "") == "disabled":
            LOG.info('Skipping unmount: config disabled target unmounting')
        elif workingd:
            # unmount everything (including iscsi disks)
            util.do_umount(workingd.target, recursive=True)

            # The open-iscsi service in the ephemeral environment handles
            # disconnecting active sessions.  On Artful release the systemd
            # unit file has conditionals that are not met at boot time and
            # results in open-iscsi service not being started; This breaks
            # shutdown on Artful releases.
            # Additionally, in release < Artful, if the storage configuration
            # is layered, like RAID over iscsi volumes, then disconnecting
            # iscsi sessions before stopping the raid device hangs.
            # As it turns out, letting the open-iscsi service take down the
            # session last is the cleanest way to handle all releases
            # regardless of what may be layered on top of the iscsi disks.
            #
            # Check if storage configuration has iscsi volumes and if so ensure
            # iscsi service is active before exiting install
            if iscsi.get_iscsi_disks_from_config(cfg):
                iscsi.restart_iscsi_service()

            shutil.rmtree(workingd.top)

    apply_power_state(cfg.get('power_state'))

    sys.exit(0)