Skip to content

Commit

Permalink
libpriv/core: workaround libdnf vars path lookup
Browse files Browse the repository at this point in the history
libdnf internally adds an `install_root` prefix to vars directories,
resulting in misplaced lookups to `<install_root>/etc/dnf/vars`.
As a workaround, this inserts a relevant amount of `/..` in order to cancel
out the path prefix.
  • Loading branch information
lucab committed May 3, 2022
1 parent 360b85f commit 1778448
Showing 1 changed file with 53 additions and 0 deletions.
53 changes: 53 additions & 0 deletions src/libpriv/rpmostree-core.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,53 @@ core_libdnf_process_global_init ()

} /* namespace */

/* libdnf internally adds an `install_root` prefix to vars directories,
* resulting in misplaced lookups to `<install_root>/etc/dnf/vars`.
* As a workaround, this inserts a relevant amount of `..` in order to cancel
* out the path prefix.
*/
static void
rpmostree_dnfcontext_fix_vars_dir (DnfContext *context)
{
g_assert (context != NULL);

const gchar *install_root = dnf_context_get_install_root (context);

// Check whether we actually need to cancel out `install_root`.
if (install_root == NULL || strcmp (install_root, "/") == 0)
return; /* 🔚 Early return */

const gchar *const *orig_dirs = dnf_context_get_vars_dir (context);

// Check whether there are vars_dir entries to tweak.
if (orig_dirs == NULL || orig_dirs[0] == NULL)
return; /* 🔚 Early return */

// Count how many levels need to be canceled, prepare the prefix string.
g_autoptr (GString) slashdotdot_prefix = g_string_new (NULL);
for (int char_index = 0; char_index < strlen (install_root); char_index++)
if (install_root[char_index] == '/')
g_string_append (slashdotdot_prefix, "/..");

// Tweak each directory, prepending the relevant amount of `..`.
g_autoptr (GPtrArray) tweaked_dirs = g_ptr_array_new ();
for (int dir_index = 0; orig_dirs[dir_index] != NULL; dir_index++)
{
const gchar *dir = orig_dirs[dir_index];
g_warning ("original dir: %s + %s\n", install_root, dir);

g_autoptr (GString) tweaked_path = g_string_new (dir);
g_string_prepend (tweaked_path, slashdotdot_prefix->str);

g_warning ("tweaked dir: %s\n", tweaked_path->str);
g_ptr_array_add (tweaked_dirs, g_strdup (tweaked_path->str));
}
g_ptr_array_add (tweaked_dirs, NULL);

auto tweaked_vars_dir = (const gchar *const *)tweaked_dirs->pdata;
dnf_context_set_vars_dir (context, tweaked_vars_dir);
}

/* Wraps `dnf_context_setup()`, and initializes state based on the treespec
* @spec. Another way to say it is we pair `DnfContext` with an
* `RpmOstreeTreespec`. For example, we handle "instlangs", set the rpmdb root
Expand Down Expand Up @@ -601,6 +648,12 @@ rpmostree_context_setup (RpmOstreeContext *self, const char *install_root, const
dnf_context_set_install_root (self->dnfctx, install_root);
dnf_context_set_source_root (self->dnfctx, source_root);

/* Hackaround libdnf logic, ensuring that `/etc/dnf/vars` gets sourced
* from the host environment instead of the install_root:
* https://github.com/rpm-software-management/libdnf/issues/1503
*/
rpmostree_dnfcontext_fix_vars_dir (self->dnfctx);

/* Set the RPM _install_langs macro, which gets processed by librpm; this is
* currently only referenced in the traditional or non-"unified core" code.
*/
Expand Down

0 comments on commit 1778448

Please sign in to comment.