From 3d6d10603fb956e76dae945bc520af21f9f8a4fd Mon Sep 17 00:00:00 2001 From: Jan Luebbe Date: Thu, 29 Aug 2024 09:27:12 +0200 Subject: [PATCH 1/3] src/install: fix typo in comment Signed-off-by: Jan Luebbe --- src/install.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/install.c b/src/install.c index c4639e269..79df48084 100644 --- a/src/install.c +++ b/src/install.c @@ -620,7 +620,7 @@ static gchar **add_system_environment(gchar **envp) /** * Sets up an environment containing RAUC information, ready to be passed to e.g. handlers * - * Extends the system environment so that the result is save to be used with + * Extends the system environment so that the result is safe to be used with * g_subprocess_launcher_set_environ(). * * @param update_source Path to the current bundle mount point From 4efb2cfe7ea0cc9e6d00d65f32b13f22f17f50eb Mon Sep 17 00:00:00 2001 From: Jan Luebbe Date: Thu, 29 Aug 2024 09:54:47 +0200 Subject: [PATCH 2/3] shell: factor out shell variable formating for manifest meta-data This function will be used for exporting meta-data to handlers. Signed-off-by: Jan Luebbe --- include/shell.h | 16 ++++++++++++++++ meson.build | 1 + src/main.c | 27 ++------------------------- src/shell.c | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 25 deletions(-) create mode 100644 include/shell.h create mode 100644 src/shell.c diff --git a/include/shell.h b/include/shell.h new file mode 100644 index 000000000..a294cc8e3 --- /dev/null +++ b/include/shell.h @@ -0,0 +1,16 @@ +#pragma once + +#include + +#include "manifest.h" + +/** + * Add the meta-data contents from a manifest as newly allocated strings to a + * GPtrArray, formatted for use as shell variables. + * + * This is useful for the 'rauc info' command and hooks/handlers. + * + * @param ptrarray GPtrArray to add to + * @param manifest RaucManifest to use as input + */ +void r_shell_from_manifest_meta(GPtrArray *shell_vars, const RaucManifest *manifest); diff --git a/meson.build b/meson.build index a615fb678..1d1a63172 100644 --- a/meson.build +++ b/meson.build @@ -125,6 +125,7 @@ sources_rauc = files([ 'src/mbr.c', 'src/mount.c', 'src/service.c', + 'src/shell.c', 'src/signature.c', 'src/stats.c', 'src/status_file.c', diff --git a/src/main.c b/src/main.c index bd5a23262..d8a619aab 100644 --- a/src/main.c +++ b/src/main.c @@ -21,6 +21,7 @@ #include "install.h" #include "rauc-installer-generated.h" #include "service.h" +#include "shell.h" #include "signature.h" #include "status_file.h" #include "update_handler.h" @@ -893,31 +894,7 @@ static gchar *info_formatter_shell(RaucManifest *manifest) g_ptr_array_unref(hooks); - if (manifest->meta && g_hash_table_size(manifest->meta)) { - GHashTableIter iter; - GHashTable *kvs; - const gchar *group; - - g_hash_table_iter_init(&iter, manifest->meta); - while (g_hash_table_iter_next(&iter, (gpointer*)&group, (gpointer*)&kvs)) { - GHashTableIter kvs_iter; - const gchar *key, *value; - g_autofree gchar *env_group = r_prepare_env_key(group, NULL); - - if (!env_group) - continue; - - g_hash_table_iter_init(&kvs_iter, kvs); - while (g_hash_table_iter_next(&kvs_iter, (gpointer*)&key, (gpointer*)&value)) { - g_autofree gchar *env_key = r_prepare_env_key(key, NULL); - - if (!env_key) - continue; - - r_ptr_array_add_printf(entries, "RAUC_META_%s_%s=%s", env_group, env_key, value); - } - } - } + r_shell_from_manifest_meta(entries, manifest); cnt = 0; for (GList *l = manifest->images; l != NULL; l = l->next) { diff --git a/src/shell.c b/src/shell.c new file mode 100644 index 000000000..3aee74a90 --- /dev/null +++ b/src/shell.c @@ -0,0 +1,35 @@ +#include "shell.h" + +#include "utils.h" + +void r_shell_from_manifest_meta(GPtrArray *shell_vars, const RaucManifest *manifest) +{ + g_return_if_fail(shell_vars); + g_return_if_fail(manifest); + + if (!manifest->meta) + return; + + GHashTableIter iter; + g_hash_table_iter_init(&iter, manifest->meta); + GHashTable *kvs; + const gchar *group; + while (g_hash_table_iter_next(&iter, (gpointer*)&group, (gpointer*)&kvs)) { + g_autofree gchar *env_group = r_prepare_env_key(group, NULL); + + if (!env_group) + continue; + + GHashTableIter kvs_iter; + g_hash_table_iter_init(&kvs_iter, kvs); + const gchar *key, *value; + while (g_hash_table_iter_next(&kvs_iter, (gpointer*)&key, (gpointer*)&value)) { + g_autofree gchar *env_key = r_prepare_env_key(key, NULL); + + if (!env_key) + continue; + + r_ptr_array_add_printf(shell_vars, "RAUC_META_%s_%s=%s", env_group, env_key, value); + } + } +} From 38552ca10eba95c4bd5318da010807178ed7eb5c Mon Sep 17 00:00:00 2001 From: Jan Luebbe Date: Thu, 29 Aug 2024 10:56:26 +0200 Subject: [PATCH 3/3] install: expose manifest meta-data in handler environment This uses the same variable names (and implementation) as 'rauc info'. For testing, the handlers now write their environments to a file that can be inspected after the installation. Signed-off-by: Jan Luebbe --- src/install.c | 5 +++++ test/adaptive-test.conf | 37 +++++++++++++++++++++++++++++++++++++ test/bin/postinstall.sh | 4 ++++ test/bin/preinstall.sh | 4 ++++ test/conftest.py | 16 +++++++++++++++- test/test_install.py | 27 +++++++++++++++++++++++++++ 6 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 test/adaptive-test.conf diff --git a/src/install.c b/src/install.c index 79df48084..b81328689 100644 --- a/src/install.c +++ b/src/install.c @@ -21,6 +21,7 @@ #include "mark.h" #include "mount.h" #include "service.h" +#include "shell.h" #include "signature.h" #include "slot.h" #include "status_file.h" @@ -716,6 +717,10 @@ static gchar **prepare_environment(gchar *update_source, RaucManifest *manifest, envp = g_environ_setenv(envp, "RAUC_SLOTS", slots->str, TRUE); envp = g_environ_setenv(envp, "RAUC_TARGET_SLOTS", target_slots->str, TRUE); + g_autoptr(GPtrArray) shell_vars = g_ptr_array_new_with_free_func(g_free); + r_shell_from_manifest_meta(shell_vars, manifest); + envp = r_environ_setenv_ptr_array(envp, shell_vars, FALSE); + return envp; } diff --git a/test/adaptive-test.conf b/test/adaptive-test.conf new file mode 100644 index 000000000..9f6865ef2 --- /dev/null +++ b/test/adaptive-test.conf @@ -0,0 +1,37 @@ +# testsuite system configuration + +[system] +compatible=Test Config +bootloader=grub +grubenv=grubenv.test +variant-name=Default Variant +data-directory=data-dir + +[handlers] +system-info=bin/systeminfo.sh +pre-install=bin/preinstall.sh +post-install=bin/postinstall.sh + +[keyring] +path=openssl-ca/dev-ca.pem +check-crl=true + +[slot.rootfs.0] +device=images/rootfs-0 +type=raw +bootname=system0 + +[slot.rootfs.1] +device=images/rootfs-1 +type=raw +bootname=system1 + +[slot.appfs.0] +device=images/appfs-0 +type=raw +parent=rootfs.0 + +[slot.appfs.1] +device=images/appfs-1 +type=raw +parent=rootfs.1 diff --git a/test/bin/postinstall.sh b/test/bin/postinstall.sh index 0c8891167..9aa1cf241 100755 --- a/test/bin/postinstall.sh +++ b/test/bin/postinstall.sh @@ -3,4 +3,8 @@ [ "x$RAUC_CURRENT_BOOTNAME" != "xsystem0" ] && exit 1 [ "x$RAUC_TRANSACTION_ID" = "x" ] && exit 1 +if [ -n "$RAUC_PYTEST_TMP" ]; then + env | sort > "$RAUC_PYTEST_TMP/postinstall-env" +fi + exit 0 diff --git a/test/bin/preinstall.sh b/test/bin/preinstall.sh index 0c8891167..be9485493 100755 --- a/test/bin/preinstall.sh +++ b/test/bin/preinstall.sh @@ -3,4 +3,8 @@ [ "x$RAUC_CURRENT_BOOTNAME" != "xsystem0" ] && exit 1 [ "x$RAUC_TRANSACTION_ID" = "x" ] && exit 1 +if [ -n "$RAUC_PYTEST_TMP" ]; then + env | sort > "$RAUC_PYTEST_TMP/preinstall-env" +fi + exit 0 diff --git a/test/conftest.py b/test/conftest.py index 5bc2288e8..50debc5b8 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -292,8 +292,12 @@ def _rauc_dbus_service(tmp_path, conf_file, bootslot): tmp_conf_file = tmp_path / "system.conf" shutil.copy(conf_file, tmp_conf_file) + env = os.environ.copy() + env["RAUC_PYTEST_TMP"] = str(tmp_path) + service = subprocess.Popen( - f"rauc service --conf={tmp_conf_file} --mount={tmp_path}/mnt --override-boot-slot={bootslot}".split() + f"rauc service --conf={tmp_conf_file} --mount={tmp_path}/mnt --override-boot-slot={bootslot}".split(), + env=env, ) bus = SessionBus() @@ -351,3 +355,13 @@ def rauc_dbus_service_with_system_external(tmp_path, dbus_session_bus, create_sy service.kill() service.wait() + + +@pytest.fixture +def rauc_dbus_service_with_system_adaptive(tmp_path, dbus_session_bus, create_system_files): + service, bus = _rauc_dbus_service(tmp_path, "adaptive-test.conf", "system0") + + yield bus + + service.kill() + service.wait() diff --git a/test/test_install.py b/test/test_install.py index 9facd8173..1b33a6171 100644 --- a/test/test_install.py +++ b/test/test_install.py @@ -50,6 +50,33 @@ def test_install_crypt(rauc_dbus_service_with_system_crypt, tmp_path): assert os.path.getsize(tmp_path / "images/rootfs-1") > 0 +def test_install_env(rauc_dbus_service_with_system_adaptive, tmp_path): + assert (tmp_path / "images/rootfs-1").is_file() + assert (tmp_path / "images/rootfs-1").stat().st_size == 0 + + bundle_name = "good-adaptive-meta-bundle.raucb" + + # copy to tmp path for safe ownership check + shutil.copyfile(bundle_name, tmp_path / bundle_name) + + out, err, exitcode = run(f"rauc install {tmp_path}/{bundle_name}") + + assert exitcode == 0 + assert (tmp_path / "images/rootfs-1").stat().st_size > 0 + + with open(tmp_path / "preinstall-env") as f: + pre_lines = f.readlines() + assert "RAUC_CURRENT_BOOTNAME=system0\n" in pre_lines + assert "RAUC_TARGET_SLOTS=1 2\n" in pre_lines + assert "RAUC_META_UPDATE_POLL=86400\n" in pre_lines + assert "RAUC_META_VERSION_CHANNEL=beta\n" in pre_lines + + with open(tmp_path / "postinstall-env") as f: + post_lines = f.readlines() + + assert post_lines == pre_lines + + @have_casync def test_install_plain_casync_local(rauc_dbus_service_with_system, tmp_path): assert os.path.exists(tmp_path / "images/rootfs-1")