Esempio n. 1
0
 async def start(self):
     status = await self.connect()
     self.interactive = status.interactive
     if self.interactive:
         if self.opts.ssh:
             from subiquity.ui.views.help import (
                 ssh_help_texts, get_installer_password)
             from subiquitycore.ssh import get_ips_standalone
             texts = ssh_help_texts(
                 get_ips_standalone(),
                 get_installer_password(self.opts.dry_run))
             for line in texts:
                 if hasattr(line, 'text'):
                     if line.text.startswith('installer@'):
                         print(' ' * 4 + line.text)
                     else:
                         print(line.text)
                 else:
                     print(line)
             return
         await super().start()
         journald_listen(
             self.aio_loop,
             [status.event_syslog_id],
             self.controllers.Progress.event)
         journald_listen(
             self.aio_loop,
             [status.log_syslog_id],
             self.controllers.Progress.log_line)
         if not status.cloud_init_ok:
             self.add_global_overlay(CloudInitFail(self))
         self.error_reporter.load_reports()
         for report in self.error_reporter.reports:
             if report.kind == ErrorReportKind.UI and not report.seen:
                 self.show_error_report(report.ref())
                 break
     else:
         if self.opts.run_on_serial:
             # Thanks to the fact that we are launched with agetty's
             # --skip-login option, on serial lines we can end up starting
             # with some strange terminal settings (see the docs for
             # --skip-login in agetty(8)). For an interactive install this
             # does not matter as the settings will soon be clobbered but
             # for a non-interactive one we need to clear things up or the
             # prompting for confirmation will be confusing.
             os.system('stty sane')
         journald_listen(
             self.aio_loop,
             [status.event_syslog_id],
             self.subiquity_event_noninteractive,
             seek=True)
         self.aio_loop.create_task(
             self.noninteractive_watch_app_state(status))
Esempio n. 2
0
def write_login_details_standalone():
    owner = get_device_owner()
    if owner is None:
        print("No device owner details found.")
        return 0
    ips = get_ips_standalone()
    if len(ips) == 0:
        tty_name = os.ttyname(0)[5:]
        version = get_core_version() or "16"
        print(
            login_details_tmpl_no_ip.format(tty_name=tty_name,
                                            version=version))
        return 2
    write_login_details(sys.stdout, owner['username'], ips)
    return 0
Esempio n. 3
0
def write_login_details_standalone():
    owner = get_device_owner()
    ips = get_ips_standalone()
    if len(ips) == 0:
        if owner is None:
            print("device managed without user")
            return 2
        else:
            tty_name = os.ttyname(0)[5:]
            version = get_core_version() or "16"
            print(
                login_details_tmpl_no_ip.format(tty_name=tty_name,
                                                version=version))
            return 2
    if owner is None:
        print("device managed without user @ {}".format(', '.join(ips)))
    else:
        write_login_details(sys.stdout, owner['username'], ips)
    return 0
Esempio n. 4
0
def main():
    # Python 3.7+ does more or less this by default, but we need to
    # work with the Python 3.6 in bionic.
    try:
        locale.setlocale(locale.LC_ALL, "")
    except locale.Error:
        locale.setlocale(locale.LC_CTYPE, "C.UTF-8")

    # Prefer utils from $SNAP, over system-wide
    snap = os.environ.get('SNAP')
    if snap:
        os.environ['PATH'] = os.pathsep.join([
            os.path.join(snap, 'bin'),
            os.path.join(snap, 'usr', 'bin'),
            os.environ['PATH'],
        ])
        os.environ["APPORT_DATA_DIR"] = os.path.join(snap, 'share/apport')
    # This must come after setting $APPORT_DATA_DIR.
    from subiquity.core import Subiquity
    opts = parse_options(sys.argv[1:])
    global LOGDIR
    if opts.dry_run:
        LOGDIR = ".subiquity"
        if opts.snaps_from_examples is None:
            opts.snaps_from_examples = True
    logfiles = setup_logger(dir=LOGDIR)

    logger = logging.getLogger('subiquity')
    version = os.environ.get("SNAP_REVISION", "unknown")
    logger.info("Starting Subiquity revision {}".format(version))
    logger.info("Arguments passed: {}".format(sys.argv))

    if not opts.dry_run:
        ci_start = time.time()
        status_txt = run_command(["cloud-init", "status", "--wait"]).stdout
        logger.debug("waited %ss for cloud-init", time.time() - ci_start)
        if "status: done" in status_txt:
            logger.debug("loading cloud config")
            init = stages.Init()
            init.read_cfg()
            init.fetch(existing="trust")
            cloud = init.cloudify()
            autoinstall_path = '/autoinstall.yaml'
            if 'autoinstall' in cloud.cfg:
                if not os.path.exists(autoinstall_path):
                    atomic_helper.write_file(
                        autoinstall_path,
                        safeyaml.dumps(
                            cloud.cfg['autoinstall']).encode('utf-8'),
                        mode=0o600)
            if os.path.exists(autoinstall_path):
                opts.autoinstall = autoinstall_path
        else:
            logger.debug("cloud-init status: %r, assumed disabled", status_txt)

    block_log_dir = os.path.join(LOGDIR, "block")
    os.makedirs(block_log_dir, exist_ok=True)
    handler = logging.FileHandler(os.path.join(block_log_dir, 'discover.log'))
    handler.setLevel('DEBUG')
    handler.setFormatter(
        logging.Formatter("%(asctime)s %(name)s:%(lineno)d %(message)s"))
    logging.getLogger('probert').addHandler(handler)
    handler.addFilter(lambda rec: rec.name != 'probert.network')
    logging.getLogger('curtin').addHandler(handler)
    logging.getLogger('block-discover').addHandler(handler)

    if opts.ssh:
        from subiquity.ui.views.help import (ssh_help_texts,
                                             get_installer_password)
        from subiquitycore.ssh import get_ips_standalone
        texts = ssh_help_texts(get_ips_standalone(),
                               get_installer_password(opts.dry_run))
        for line in texts:
            if hasattr(line, 'text'):
                if line.text.startswith('installer@'):
                    print(' ' * 4 + line.text)
                else:
                    print(line.text)
            else:
                print(line)
        return 0

    if opts.answers is None and os.path.exists(AUTO_ANSWERS_FILE):
        logger.debug("Autoloading answers from %s", AUTO_ANSWERS_FILE)
        opts.answers = AUTO_ANSWERS_FILE

    if opts.answers:
        opts.answers = open(opts.answers)
        try:
            fcntl.flock(opts.answers, fcntl.LOCK_EX | fcntl.LOCK_NB)
        except OSError:
            logger.exception(
                'Failed to lock auto answers file, proceding without it.')
            opts.answers.close()
            opts.answers = None

    subiquity_interface = Subiquity(opts, block_log_dir)

    subiquity_interface.note_file_for_apport("InstallerLog", logfiles['debug'])
    subiquity_interface.note_file_for_apport("InstallerLogInfo",
                                             logfiles['info'])

    subiquity_interface.run()
Esempio n. 5
0
def main():
    setup_environment()
    # setup_environment sets $APPORT_DATA_DIR which must be set before
    # apport is imported, which is done by this import:
    from subiquity.core import Subiquity
    parser = make_client_args_parser()
    args = sys.argv[1:]
    if '--dry-run' in args:
        opts, unknown = parser.parse_known_args(args)
        if opts.socket is None:
            os.makedirs('.subiquity', exist_ok=True)
            sock_path = '.subiquity/socket'
            opts.socket = sock_path
            server_args = ['--dry-run', '--socket=' + sock_path] + unknown
            server_parser = make_server_args_parser()
            server_parser.parse_args(server_args)  # just to check
            server_output = open('.subiquity/server-output', 'w')
            server_cmd = [sys.executable, '-m', 'subiquity.cmd.server'] + \
                server_args
            server_proc = subprocess.Popen(server_cmd,
                                           stdout=server_output,
                                           stderr=subprocess.STDOUT)
            opts.server_pid = str(server_proc.pid)
            print("running server pid {}".format(server_proc.pid))
        elif opts.server_pid is not None:
            print("reconnecting to server pid {}".format(opts.server_pid))
        else:
            opts = parser.parse_args(args)
    else:
        opts = parser.parse_args(args)
        if opts.socket is None:
            opts.socket = '/run/subiquity/socket'
    os.makedirs(os.path.basename(opts.socket), exist_ok=True)
    logdir = LOGDIR
    if opts.dry_run:
        if opts.snaps_from_examples is None:
            opts.snaps_from_examples = True
        logdir = ".subiquity"
    logfiles = setup_logger(dir=logdir, base='subiquity')

    logger = logging.getLogger('subiquity')
    version = os.environ.get("SNAP_REVISION", "unknown")
    logger.info("Starting Subiquity revision {}".format(version))
    logger.info("Arguments passed: {}".format(sys.argv))

    if not opts.dry_run:
        ci_start = time.time()
        status_txt = run_command(["cloud-init", "status", "--wait"]).stdout
        logger.debug("waited %ss for cloud-init", time.time() - ci_start)
        if "status: done" in status_txt:
            logger.debug("loading cloud config")
            init = stages.Init()
            init.read_cfg()
            init.fetch(existing="trust")
            cloud = init.cloudify()
            autoinstall_path = '/autoinstall.yaml'
            if 'autoinstall' in cloud.cfg:
                if not os.path.exists(autoinstall_path):
                    atomic_helper.write_file(
                        autoinstall_path,
                        safeyaml.dumps(
                            cloud.cfg['autoinstall']).encode('utf-8'),
                        mode=0o600)
            if os.path.exists(autoinstall_path):
                opts.autoinstall = autoinstall_path
        else:
            logger.debug("cloud-init status: %r, assumed disabled", status_txt)

    block_log_dir = os.path.join(logdir, "block")
    os.makedirs(block_log_dir, exist_ok=True)
    handler = logging.FileHandler(os.path.join(block_log_dir, 'discover.log'))
    handler.setLevel('DEBUG')
    handler.setFormatter(
        logging.Formatter("%(asctime)s %(name)s:%(lineno)d %(message)s"))
    logging.getLogger('probert').addHandler(handler)
    handler.addFilter(lambda rec: rec.name != 'probert.network')
    logging.getLogger('curtin').addHandler(handler)
    logging.getLogger('block-discover').addHandler(handler)

    if opts.ssh:
        from subiquity.ui.views.help import (ssh_help_texts,
                                             get_installer_password)
        from subiquitycore.ssh import get_ips_standalone
        texts = ssh_help_texts(get_ips_standalone(),
                               get_installer_password(opts.dry_run))
        for line in texts:
            if hasattr(line, 'text'):
                if line.text.startswith('installer@'):
                    print(' ' * 4 + line.text)
                else:
                    print(line.text)
            else:
                print(line)
        return 0

    if opts.answers is None and os.path.exists(AUTO_ANSWERS_FILE):
        logger.debug("Autoloading answers from %s", AUTO_ANSWERS_FILE)
        opts.answers = AUTO_ANSWERS_FILE

    if opts.answers:
        opts.answers = open(opts.answers)
        try:
            fcntl.flock(opts.answers, fcntl.LOCK_EX | fcntl.LOCK_NB)
        except OSError:
            logger.exception(
                'Failed to lock auto answers file, proceding without it.')
            opts.answers.close()
            opts.answers = None

    subiquity_interface = Subiquity(opts, block_log_dir)

    subiquity_interface.note_file_for_apport("InstallerLog", logfiles['debug'])
    subiquity_interface.note_file_for_apport("InstallerLogInfo",
                                             logfiles['info'])

    subiquity_interface.run()