subiquity/system_setup/cmd/tui.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

167 lines
5.7 KiB
Python
Raw Normal View History

2021-07-02 08:26:21 +00:00
#!/usr/bin/env python3
# Copyright 2015-2021 Canonical, Ltd.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import argparse
import asyncio
2021-07-02 08:26:21 +00:00
import fcntl
import logging
import os
import subprocess
import sys
from subiquity.cmd.common import LOGDIR, setup_environment
2021-07-02 08:26:21 +00:00
from subiquitycore.log import setup_logger
from system_setup.cmd.server import make_server_args_parser
2021-07-02 08:26:21 +00:00
class ClickAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
namespace.scripts.append("c(" + repr(values) + ")")
def make_client_args_parser():
# TODO WSL: update this. We have already done it on the past…
2021-07-02 08:26:21 +00:00
parser = argparse.ArgumentParser(
description="SUbiquity - Ubiquity for Servers", prog="subiquity"
)
try:
ascii_default = os.ttyname(0) == "/dev/ttysclp0"
except OSError:
ascii_default = False
parser.set_defaults(ascii=ascii_default)
parser.add_argument(
"--dry-run",
action="store_true",
dest="dry_run",
help="menu-only, do not call installer function",
)
parser.add_argument("--socket")
parser.add_argument("--answers")
parser.add_argument("--server-pid")
parser.add_argument("--autoinstall", action="store", dest="autoinstall")
parser.add_argument(
"--prefill",
dest="prefill",
help=(
"Prefills UI models with data provided in"
" a prefill.yaml file yet allowing overrides."
),
)
parser.add_argument(
"--output-base",
action="store",
dest="output_base",
default=".subiquity",
help="in dryrun, control basedir of files",
)
2021-07-02 08:26:21 +00:00
return parser
AUTO_ANSWERS_FILE = "/subiquity_config/answers.yaml"
def main():
2021-07-02 08:26:21 +00:00
setup_environment()
# setup_environment sets $APPORT_DATA_DIR which must be set before
# apport is imported, which is done by this import:
from system_setup.client.client import SystemSetupClient
2023-07-25 21:26:25 +00:00
2021-07-02 08:26:21 +00:00
parser = make_client_args_parser()
args = sys.argv[1:]
need_start_server = False
server_args = []
server_output_dir = "/var/log/installer"
server_state_file = "/run/subiquity/server-state"
opts, unknown = parser.parse_known_args(args)
2021-07-02 08:26:21 +00:00
if "--dry-run" in args:
server_state_file = opts.output_base + "/run/subiquity/server-state"
2021-07-02 08:26:21 +00:00
if opts.socket is None:
need_start_server = True
server_output_dir = opts.output_base
sock_path = os.path.join(server_output_dir, "socket")
2021-07-02 08:26:21 +00:00
opts.socket = sock_path
server_args = ["--dry-run", "--socket=" + sock_path] + unknown
server_args += ["--output-base", opts.output_base]
elif opts.socket is None:
need_start_server = True
opts.socket = "/run/subiquity/socket"
if opts.prefill:
server_args += ["--prefill=" + opts.prefill]
if opts.autoinstall:
server_args += ["--autoinstall=" + opts.autoinstall]
os.makedirs(server_output_dir, exist_ok=True)
server_stdout = open(os.path.join(server_output_dir, "server-stdout"), "w")
server_stderr = open(os.path.join(server_output_dir, "server-stderr"), "w")
if need_start_server:
if os.path.exists(server_state_file):
os.unlink(server_state_file)
server_parser = make_server_args_parser()
server_parser.parse_args(server_args) # just to check
server_cmd = [sys.executable, "-m", "system_setup.cmd.server"] + server_args
server_proc = subprocess.Popen(
server_cmd, stdout=server_stdout, stderr=server_stderr
)
opts.server_pid = str(server_proc.pid)
2021-10-28 18:54:07 +00:00
print("running server pid {} with args: {}".format(server_proc.pid, server_cmd))
elif opts.server_pid is not None:
print("reconnecting to server pid {}".format(opts.server_pid))
2021-07-02 08:26:21 +00:00
os.makedirs(os.path.basename(opts.socket), exist_ok=True)
logdir = LOGDIR
if opts.dry_run:
logdir = opts.output_base
2021-07-21 09:07:40 +00:00
logfiles = setup_logger(dir=logdir, base="systemsetup-client")
2021-07-02 08:26:21 +00:00
logger = logging.getLogger("subiquity")
version = "unknown"
logger.info("Starting System Setup revision {}".format(version))
2021-07-02 08:26:21 +00:00
logger.info("Arguments passed: {}".format(sys.argv))
opts.ssh = False
opts.screens = []
opts.scripts = []
opts.run_on_serial = False
2021-07-02 08:26:21 +00:00
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
async def run_with_loop():
subiquity_interface = SystemSetupClient(opts)
subiquity_interface.note_file_for_apport("InstallerLog", logfiles["debug"])
subiquity_interface.note_file_for_apport("InstallerLogInfo", logfiles["info"])
await subiquity_interface.run()
2021-07-02 08:26:21 +00:00
asyncio.run(run_with_loop())
2021-07-02 08:26:21 +00:00
if __name__ == "__main__":
sys.exit(main())