Skip to content

Commit

Permalink
Merge pull request rauc#1505 from jluebbe/meta-data-in-handler
Browse files Browse the repository at this point in the history
expose manifest meta-data in handler environment
  • Loading branch information
jluebbe authored Aug 29, 2024
2 parents d3423f1 + 38552ca commit 893187f
Show file tree
Hide file tree
Showing 10 changed files with 147 additions and 27 deletions.
16 changes: 16 additions & 0 deletions include/shell.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma once

#include <glib.h>

#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);
1 change: 1 addition & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
7 changes: 6 additions & 1 deletion src/install.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -620,7 +621,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
Expand Down Expand Up @@ -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;
}

Expand Down
27 changes: 2 additions & 25 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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) {
Expand Down
35 changes: 35 additions & 0 deletions src/shell.c
Original file line number Diff line number Diff line change
@@ -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);
}
}
}
37 changes: 37 additions & 0 deletions test/adaptive-test.conf
Original file line number Diff line number Diff line change
@@ -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
4 changes: 4 additions & 0 deletions test/bin/postinstall.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 4 additions & 0 deletions test/bin/preinstall.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
16 changes: 15 additions & 1 deletion test/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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()
27 changes: 27 additions & 0 deletions test/test_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down

0 comments on commit 893187f

Please sign in to comment.