From 34d4acd2641409cf785c6a69ece7c9c3bc38b0b7 Mon Sep 17 00:00:00 2001 From: Olivier Gayot Date: Mon, 8 Aug 2022 15:03:52 +0200 Subject: [PATCH] hooks: execute hook scripts as builtin late commands When executing late commands, we now start by executing run-parts over the /etc/subiquity/postinst.d directory (by default) if it exists. A failure in run-parts is not considered critical so any other late_commands will run no matter what. Signed-off-by: Olivier Gayot --- Makefile | 3 ++- examples/postinst.d/copy_nm_connections | 35 +++++++++++++++++++++++++ subiquity/cmd/server.py | 4 +++ subiquity/server/controllers/cmdlist.py | 18 ++++++++++++- 4 files changed, 58 insertions(+), 2 deletions(-) create mode 100755 examples/postinst.d/copy_nm_connections diff --git a/Makefile b/Makefile index d2bee3e7..209d6ecc 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,8 @@ PYTHONPATH=$(shell pwd):$(shell pwd)/probert:$(shell pwd)/curtin PROBERTDIR=./probert PROBERT_REPO=https://github.com/canonical/probert DRYRUN?=--dry-run --bootloader uefi --machine-config examples/simple.json \ - --source-catalog examples/install-sources.yaml + --source-catalog examples/install-sources.yaml \ + --postinst-hooks-dir examples/postinst.d/ SYSTEM_SETUP_DRYRUN?=--dry-run export PYTHONPATH CWD := $(shell pwd) diff --git a/examples/postinst.d/copy_nm_connections b/examples/postinst.d/copy_nm_connections new file mode 100755 index 00000000..ff7d637e --- /dev/null +++ b/examples/postinst.d/copy_nm_connections @@ -0,0 +1,35 @@ +#!/bin/bash + +prefix="$TARGET_MOUNT_POINT"/etc/NetworkManager/system-connections + +echo "Copying NM connections to target" + +mkdir --parents -- "$prefix" +cat > "$prefix"/subiquity-test.nmconnection << EOF +[connection] +id=Subiquity Test +uuid=5bbf9dda-f3a9-4967-970e-aba55c8b18f0 +type=wifi +interface-name=wlp0s20f3 +permissions= + +[wifi] +mode=infrastructure +ssid=TestConnection-5G + +[wifi-security] +auth-alg=open +key-mgmt=wpa-psk +psk=nCjIqJ4G + +[ipv4] +dns-search= +method=auto + +[ipv6] +addr-gen-mode=stable-privacy +dns-search= +method=auto + +[proxy] +EOF diff --git a/subiquity/cmd/server.py b/subiquity/cmd/server.py index e6634a1d..9a70843c 100644 --- a/subiquity/cmd/server.py +++ b/subiquity/cmd/server.py @@ -16,6 +16,7 @@ import argparse import logging import os +import pathlib import shlex import sys @@ -104,6 +105,9 @@ def make_server_args_parser(): '--storage-version', action='store', type=int) parser.add_argument( '--use-os-prober', action='store_true', default=False) + parser.add_argument( + '--postinst-hooks-dir', default='/etc/subiquity/postinst.d', + type=pathlib.Path) return parser diff --git a/subiquity/server/controllers/cmdlist.py b/subiquity/server/controllers/cmdlist.py index 9682bd77..35ba78fd 100644 --- a/subiquity/server/controllers/cmdlist.py +++ b/subiquity/server/controllers/cmdlist.py @@ -57,6 +57,7 @@ class CmdListController(NonInteractiveController): 'items': {'type': 'string'}, }, } + builtin_cmds: Sequence[Command] = () cmds: Sequence[Command] = () cmd_check = True syslog_id = None @@ -74,7 +75,7 @@ class CmdListController(NonInteractiveController): @with_context() async def run(self, context): env = self.env() - for i, cmd in enumerate(self.cmds): + for i, cmd in enumerate(tuple(self.builtin_cmds) + tuple(self.cmds)): desc = cmd.desc() with context.child("command_{}".format(i), desc): args = cmd.as_args_list() @@ -109,6 +110,21 @@ class LateController(CmdListController): super().__init__(app) self.syslog_id = app.log_syslog_id + try: + hooks_dir = self.app.opts.postinst_hooks_dir + except AttributeError: + # NOTE: system_setup imports this controller ; but does not use the + # postinst hooks mechanism. + pass + else: + if hooks_dir.is_dir(): + self.builtin_cmds = [ + Command( + args=["run-parts", "--debug", "--", str(hooks_dir)], + check=False, + ), + ] + def env(self): env = super().env() env['TARGET_MOUNT_POINT'] = self.app.base_model.target