compose: Introduce variable substitution for ${basearch}
This comes from the tradition of yum repo files. It's significantly easier for rpm-ostree users building multiple architectures if some core templating for the treefiles is built in. Otherwise, everyone needs to learn about a new wrapper tool for rpm-ostree, and said tool would need to re-do the same "basearch" evaluation that is already occuring inside libhif. This commit also paves the way for introducing `${releasever}` substitution. NOTE: This depends on pending changes to libhif git. Closes: #274 Approved by: jlebon
This commit is contained in:
parent
e2e754e94c
commit
4fc25d74a3
@ -213,6 +213,7 @@ set_keyfile_string_array_from_json (GKeyFile *keyfile,
|
||||
|
||||
static gboolean
|
||||
install_packages_in_root (RpmOstreeTreeComposeContext *self,
|
||||
RpmOstreeContext *ctx,
|
||||
JsonObject *treedata,
|
||||
GFile *yumroot,
|
||||
char **packages,
|
||||
@ -225,7 +226,6 @@ install_packages_in_root (RpmOstreeTreeComposeContext *self,
|
||||
guint progress_sigid;
|
||||
GFile *contextdir = self->treefile_context_dirs->pdata[0];
|
||||
g_autoptr(RpmOstreeInstall) hifinstall = { 0, };
|
||||
g_autoptr(RpmOstreeContext) ctx = NULL;
|
||||
HifContext *hifctx;
|
||||
gs_free char *ret_new_inputhash = NULL;
|
||||
g_autoptr(GKeyFile) treespec = g_key_file_new ();
|
||||
@ -245,9 +245,6 @@ install_packages_in_root (RpmOstreeTreeComposeContext *self,
|
||||
}
|
||||
#endif
|
||||
|
||||
ctx = rpmostree_context_new_unprivileged (self->cachedir_dfd, cancellable, error);
|
||||
if (!ctx)
|
||||
goto out;
|
||||
hifctx = rpmostree_context_get_hif (ctx);
|
||||
if (opt_proxy)
|
||||
hif_context_set_http_proxy (hifctx, opt_proxy);
|
||||
@ -577,6 +574,8 @@ rpmostree_compose_builtin_tree (int argc,
|
||||
gs_unref_object JsonParser *treefile_parser = NULL;
|
||||
gs_unref_variant_builder GVariantBuilder *metadata_builder =
|
||||
g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
|
||||
g_autoptr(RpmOstreeContext) corectx = NULL;
|
||||
g_autoptr(GHashTable) varsubsts = NULL;
|
||||
gboolean workdir_is_tmp = FALSE;
|
||||
|
||||
self->treefile_context_dirs = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);
|
||||
@ -676,6 +675,12 @@ rpmostree_compose_builtin_tree (int argc,
|
||||
goto out;
|
||||
}
|
||||
|
||||
corectx = rpmostree_context_new_unprivileged (self->cachedir_dfd, cancellable, error);
|
||||
if (!corectx)
|
||||
goto out;
|
||||
|
||||
varsubsts = rpmostree_context_get_varsubsts (corectx);
|
||||
|
||||
treefile_parser = json_parser_new ();
|
||||
if (!json_parser_load_from_file (treefile_parser,
|
||||
gs_file_get_path_cached (treefile_path),
|
||||
@ -708,9 +713,13 @@ rpmostree_compose_builtin_tree (int argc,
|
||||
goto out;
|
||||
}
|
||||
|
||||
self->ref = g_strdup (_rpmostree_jsonutil_object_require_string_member (treefile, "ref", error));
|
||||
if (!self->ref)
|
||||
goto out;
|
||||
{ const char *input_ref = _rpmostree_jsonutil_object_require_string_member (treefile, "ref", error);
|
||||
if (!input_ref)
|
||||
goto out;
|
||||
self->ref = _rpmostree_varsubst_string (input_ref, varsubsts, error);
|
||||
if (!self->ref)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!ostree_repo_read_commit (repo, self->ref, &previous_root, &previous_checksum,
|
||||
cancellable, &temp_error))
|
||||
@ -809,7 +818,7 @@ rpmostree_compose_builtin_tree (int argc,
|
||||
|
||||
{ gboolean unmodified = FALSE;
|
||||
|
||||
if (!install_packages_in_root (self, treefile, yumroot,
|
||||
if (!install_packages_in_root (self, corectx, treefile, yumroot,
|
||||
(char**)packages->pdata,
|
||||
opt_force_nocache ? NULL : &unmodified,
|
||||
&new_inputhash,
|
||||
|
@ -404,6 +404,16 @@ rpmostree_treespec_to_variant (RpmOstreeTreespec *spec)
|
||||
return g_variant_ref (spec->spec);
|
||||
}
|
||||
|
||||
GHashTable *
|
||||
rpmostree_context_get_varsubsts (RpmOstreeContext *context)
|
||||
{
|
||||
GHashTable *r = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
|
||||
|
||||
g_hash_table_insert (r, g_strdup ("basearch"), g_strdup (hif_context_get_base_arch (context->hifctx)));
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
enable_one_repo (RpmOstreeContext *context,
|
||||
GPtrArray *sources,
|
||||
|
@ -50,6 +50,8 @@ RpmOstreeTreespec *rpmostree_treespec_new_from_keyfile (GKeyFile *keyfile, GErro
|
||||
RpmOstreeTreespec *rpmostree_treespec_new_from_path (const char *path, GError **error);
|
||||
RpmOstreeTreespec *rpmostree_treespec_new (GVariant *variant);
|
||||
|
||||
GHashTable *rpmostree_context_get_varsubsts (RpmOstreeContext *context);
|
||||
|
||||
GVariant *rpmostree_treespec_to_variant (RpmOstreeTreespec *spec);
|
||||
const char *rpmostree_treespec_get_ref (RpmOstreeTreespec *spec);
|
||||
|
||||
|
@ -121,6 +121,70 @@ rpmostree_mkdtemp (const char *template,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Given a string of the form
|
||||
* "bla blah ${foo} blah ${bar}"
|
||||
* and a hash table of variables, substitute the variable values.
|
||||
*/
|
||||
char *
|
||||
_rpmostree_varsubst_string (const char *instr,
|
||||
GHashTable *substitutions,
|
||||
GError **error)
|
||||
{
|
||||
const char *s;
|
||||
const char *p;
|
||||
/* Acts as a reusable buffer space */
|
||||
g_autoptr(GString) varnamebuf = g_string_new ("");
|
||||
g_autoptr(GString) result = g_string_new ("");
|
||||
|
||||
s = instr;
|
||||
while ((p = strstr (s, "${")) != NULL)
|
||||
{
|
||||
const char *varstart = p + 2;
|
||||
const char *varend = strchr (varstart, '}');
|
||||
const char *value;
|
||||
if (!varend)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Unclosed variable reference starting at %u bytes",
|
||||
(guint)(p - instr));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Append leading bytes */
|
||||
g_string_append_len (result, s, p - s);
|
||||
|
||||
/* Get a NUL-terminated copy of the variable name */
|
||||
g_string_truncate (varnamebuf, 0);
|
||||
g_string_append_len (varnamebuf, varstart, varend - varstart);
|
||||
|
||||
value = g_hash_table_lookup (substitutions, varnamebuf->str);
|
||||
if (!value)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Unknown variable reference ${%s}",
|
||||
varnamebuf->str);
|
||||
return NULL;
|
||||
}
|
||||
/* Append the replaced value */
|
||||
g_string_append (result, value);
|
||||
|
||||
/* On to the next */
|
||||
s = varend+1;
|
||||
}
|
||||
|
||||
if (s != instr)
|
||||
{
|
||||
char *r;
|
||||
g_string_append_len (result, s, p - s);
|
||||
/* Steal the C string, NULL out the GString since we freed it */
|
||||
r = g_string_free (result, FALSE);
|
||||
result = NULL;
|
||||
return r;
|
||||
}
|
||||
else
|
||||
return g_strdup (instr);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_rpmostree_util_enumerate_directory_allow_noent (GFile *dirpath,
|
||||
const char *queryargs,
|
||||
|
@ -47,6 +47,11 @@ gboolean rpmostree_mkdtemp (const char *template,
|
||||
int *out_tmpdir_dfd, /* allow-none */
|
||||
GError **error);
|
||||
|
||||
char *
|
||||
_rpmostree_varsubst_string (const char *instr,
|
||||
GHashTable *substitutions,
|
||||
GError **error);
|
||||
|
||||
gboolean
|
||||
_rpmostree_util_enumerate_directory_allow_noent (GFile *dirpath,
|
||||
const char *queryargs,
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"ref": "fedora/test",
|
||||
"ref": "fedora/${basearch}/test",
|
||||
|
||||
"repos": ["test-repo"],
|
||||
|
||||
|
@ -27,7 +27,12 @@ check_root_test
|
||||
# Remove once it doesn't happen anymore.
|
||||
unset G_DEBUG
|
||||
|
||||
(arch | grep -q x86_64) || { echo 1>&2 "$0 can be run only on x86_64"; echo "1..0" ; exit 77; }
|
||||
arch=$(arch)
|
||||
if ! test "${arch}" = x86_64; then
|
||||
echo 1>&2 "$0 can be run only on x86_64"; echo "1..0" ; exit 77
|
||||
fi
|
||||
|
||||
testref=fedora/${arch}/test
|
||||
|
||||
echo "1..4"
|
||||
|
||||
@ -44,7 +49,7 @@ echo "ok dry run"
|
||||
|
||||
rpm-ostree --repo=repo compose tree $SRCDIR/test-repo.json
|
||||
ostree --repo=repo refs >refs.txt
|
||||
assert_file_has_content refs.txt fedora/test
|
||||
assert_file_has_content refs.txt ${testref}
|
||||
|
||||
echo "ok compose"
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user