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))
async def start(self): status = await self.connect() self.interactive = status.interactive if self.interactive: if self.opts.ssh: ssh_info = await self.client.meta.ssh_info.GET() texts = ssh_help_texts(ssh_info) for line in texts: import urwid if isinstance(line, urwid.Widget): line = '\n'.join([ line.decode('utf-8').rstrip() for line in line.render((1000,)).text ]) 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))
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()
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()