tools/mpp: substitute vars in mpp blocks

Allow the manifest variables, defined via mpp-vars, to be used from
within the mpp blocks. For this template strings are used, where
variables are marked via `$`. We cannot use the `mpp-format` logic
easily there, since that is processed after other mpp directives
have been processed.
As a result remove the built-in substitution from support from dnf
dep-solving, since we had to post-process the resulting urls with
variable substitution afterwards. Now that is covered with this
more generic mechanism.
This commit is contained in:
Christian Kellner 2021-07-14 14:22:57 +02:00
parent 4a00895ba5
commit c4db24c481
2 changed files with 42 additions and 27 deletions

View file

@ -1,4 +1,10 @@
{
"mpp-vars": {
"arch": "x86_64",
"release": 34,
"releasever": "f$release",
"snapshot": "20210512"
},
"pipeline": {
"build": {
"mpp-import-pipeline": {
@ -21,13 +27,13 @@
"-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nmQINBF1RVqsBEADWMBqYv/G1r4PwyiPQCfg5fXFGXV1FCZ32qMi9gLUTv1CX7rYy\nH4Inj93oic+lt1kQ0kQCkINOwQczOkm6XDkEekmMrHknJpFLwrTK4AS28bYF2RjL\nM+QJ/dGXDMPYsP0tkLvoxaHr9WTRq89A+AmONcUAQIMJg3JxXAAafBi2UszUUEPI\nU35MyufFt2ePd1k/6hVAO8S2VT72TxXSY7Ha4X2J0pGzbqQ6Dq3AVzogsnoIi09A\n7fYutYZPVVAEGRUqavl0th8LyuZShASZ38CdAHBMvWV4bVZghd/wDV5ev3LXUE0o\nitLAqNSeiDJ3grKWN6v0qdU0l3Ya60sugABd3xaE+ROe8kDCy3WmAaO51Q880ZA2\niXOTJFObqkBTP9j9+ZeQ+KNE8SBoiH1EybKtBU8HmygZvu8ZC1TKUyL5gwGUJt8v\nergy5Bw3Q7av520sNGD3cIWr4fBAVYwdBoZT8RcsnU1PP67NmOGFcwSFJ/LpiOMC\npZ1IBvjOC7KyKEZY2/63kjW73mB7OHOd18BHtGVkA3QAdVlcSule/z68VOAy6bih\nE6mdxP28D4INsts8w6yr4G+3aEIN8u0qRQq66Ri5mOXTyle+ONudtfGg3U9lgicg\nz6oVk17RT0jV9uL6K41sGZ1sH/6yTXQKagdAYr3w1ix2L46JgzC+/+6SSwARAQAB\ntDFGZWRvcmEgKDMyKSA8ZmVkb3JhLTMyLXByaW1hcnlAZmVkb3JhcHJvamVjdC5v\ncmc+iQI4BBMBAgAiBQJdUVarAhsPBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAK\nCRBsEwJtEslE0LdAD/wKdAMtfzr7O2y06/sOPnrb3D39Y2DXbB8y0iEmRdBL29Bq\n5btxwmAka7JZRJVFxPsOVqZ6KARjS0/oCBmJc0jCRANFCtM4UjVHTSsxrJfuPkel\nvrlNE9tcR6OCRpuj/PZgUa39iifF/FTUfDgh4Q91xiQoLqfBxOJzravQHoK9VzrM\nNTOu6J6l4zeGzY/ocj6DpT+5fdUO/3HgGFNiNYPC6GVzeiA3AAVR0sCyGENuqqdg\nwUxV3BIht05M5Wcdvxg1U9x5I3yjkLQw+idvX4pevTiCh9/0u+4g80cT/21Cxsdx\n7+DVHaewXbF87QQIcOAing0S5QE67r2uPVxmWy/56TKUqDoyP8SNsV62lT2jutsj\nLevNxUky011g5w3bc61UeaeKrrurFdRs+RwBVkXmtqm/i6g0ZTWZyWGO6gJd+HWA\nqY1NYiq4+cMvNLatmA2sOoCsRNmE9q6jM/ESVgaH8hSp8GcLuzt9/r4PZZGl5CvU\neldOiD221u8rzuHmLs4dsgwJJ9pgLT0cUAsOpbMPI0JpGIPQ2SG6yK7LmO6HFOxb\nAkz7IGUt0gy1MzPTyBvnB+WgD1I+IQXXsJbhP5+d+d3mOnqsd6oDM/grKBzrhoUe\noNadc9uzjqKlOrmrdIR3Bz38SSiWlde5fu6xPqJdmGZRNjXtcyJlbSPVDIloxw==\n=QWRO\n-----END PGP PUBLIC KEY BLOCK-----\n"
],
"mpp-depsolve": {
"architecture": "x86_64",
"architecture": "$arch",
"module-platform-id": "f34",
"releasever": "f34",
"repos": [
{
"id": "default",
"baseurl": "https://rpmrepo.osbuild.org/v2/mirror/public/$releasever/$releasever-$basearch-fedora-20210512/"
"baseurl": "https://rpmrepo.osbuild.org/v2/mirror/public/$releasever/$releasever-$arch-fedora-$snapshot/"
}
],
"packages": [

View file

@ -95,11 +95,15 @@ The parameters for this pre-processor, version "2", look like this:
...
```
String expansion:
Variable expansion and substitution:
The variables can be set in the mpp-vars toplevel dict (which is removed from
the final results) or overridden by the -D,--define commandline option.
They can then be used from within the manifest via f-string formatting using
the `mpp-format-{int,string,json}` directives. Additionally the variables
will be substituted via template string substitution a la `$variable` inside
the mpp blocks.
You can expand string with using python f-string formatting and variables. The variables
can be set in the mpp-vars toplevel dict (which is removed from the final results) or
overridden by the --var commandline option.
Example:
@ -108,7 +112,9 @@ Example:
{
"mpp-vars": {
"variable": "some string",
"rootfs_size": 20480
"rootfs_size": 20480,
"arch:": "x86_64",
"ref": "fedora/$arch/osbuild"
},
...
{
@ -219,7 +225,7 @@ class DepSolver:
self.base = dnf.Base()
def reset(self, basedir, module_platform_id, ignore_weak_deps):
def reset(self, arch, basedir, module_platform_id, ignore_weak_deps):
base = self.base
base.reset(goal=True, repos=True, sack=True)
self.secrets.clear()
@ -230,20 +236,11 @@ class DepSolver:
base.conf.persistdir = self.persistdir
base.conf.module_platform_id = module_platform_id
base.conf.install_weak_deps = not ignore_weak_deps
base.conf.arch = arch
self.base = base
self.basedir = basedir
def set_substitutions(self, arch, releasever):
base = self.base
if arch:
base.conf.substitutions['arch'] = arch
base.conf.substitutions['basearch'] = dnf.rpm.basearch(arch)
if releasever:
base.conf.substitutions['releasever'] = releasever
def expand_baseurl(self, baseurl):
"""Expand non-uris as paths relative to basedir into a file:/// uri"""
basedir = self.basedir
@ -339,8 +336,7 @@ class DepSolver:
path = tsi.pkg.relativepath
reponame = tsi.pkg.reponame
baseurl = string.Template(self.base.repos[reponame].baseurl[0])
baseurl = baseurl.substitute(self.base.conf.substitutions)
baseurl = self.base.repos[reponame].baseurl[0]
# dep["path"] often starts with a "/", even though it's meant to be
# relative to `baseurl`. Strip any leading slashes, but ensure there's
# exactly one between `baseurl` and the path.
@ -549,7 +545,8 @@ class ManifestFile:
return None
del parent[name]
return desc
return self.substitute_vars(desc)
def init_vars(self):
variables = self.get_mpp_node(self.root, "vars")
@ -558,6 +555,7 @@ class ManifestFile:
return
self.vars.update(variables)
self.substitute_vars(self.vars)
def set_vars(self, args):
for arg in args:
@ -569,6 +567,21 @@ class ManifestFile:
value = True
self.vars[key] = value
def substitute_vars(self, node):
"""Expand variables in `node` with the manifest variables"""
if isinstance(node, dict):
for k, v in node.items():
node[k] = self.substitute_vars(v)
elif isinstance(node, list):
for i, v in enumerate(node):
node[i] = self.substitute_vars(v)
elif isinstance(node, str):
tpl = string.Template(node)
node = tpl.safe_substitute(self.vars)
return node
def load_import(self, path, search_dirs):
m = self.find_and_load_manifest(path, search_dirs)
if m.version != self.version:
@ -589,6 +602,7 @@ class ManifestFile:
packages = desc.get("packages", [])
excludes = desc.get("excludes", [])
baseurl = desc.get("baseurl")
arch = desc.get("architecture")
if not packages:
return []
@ -596,12 +610,7 @@ class ManifestFile:
module_platform_id = desc["module-platform-id"]
ignore_weak_deps = bool(desc.get("ignore-weak-deps"))
solver.reset(self.basedir, module_platform_id, ignore_weak_deps)
arch = desc["architecture"]
releasever = desc.get("releasever")
solver.set_substitutions(arch, releasever)
solver.reset(arch, self.basedir, module_platform_id, ignore_weak_deps)
for repo in repos:
solver.add_repo(repo, baseurl)