osbuild-mpp: Add url option to mpp-embed

Allow the user to pass a URL to be embeded as org.osbuild.curl input

Signed-off-by: Ygal Blum <ygal.blum@gmail.com>
This commit is contained in:
Ygal Blum 2022-09-05 14:37:47 +03:00
parent f4bfce05e3
commit 42552e0436

View file

@ -251,13 +251,15 @@ Example:
Embedding data and files so they can be used in inputs:
This directive allows to generate `org.osbuild.inline` sources on the fly. They can
be generated by reading a file (via the `path` parameter) or by directly providing
the data (via the `text` parameter). The reference to the inline source will be
added to the array of references of the corresponding input. Any JSON specified
via the `options` parameter will be passed as value for the reference. Additionally,
a dictionary called `embedded` will be created and within a mapping from the `id` to
the checksum so that the source can be used in e.g. `mpp-format-string` directvies.
This directive allows to generate `org.osbuild.inline` and `org.osbuild.curl`
sources on the fly. `org.osbuild.inline` sources can be generated by reading
a file (via the `path` parameter) or by directly providing the data (via the `text` parameter).
`org.osbuild.curl` resources can be generated by fetching a public URL (via the `url` parameter)
The reference to the inline source will be added to the array of references of the
corresponding input. Any JSON specified via the `options` parameter will be passed
as value for the reference. Additionally, a dictionary called `embedded` will be
created and within a mapping from the `id` to the checksum so that the source can
be used in e.g. `mpp-format-string` directvies.
Example:
@ -311,6 +313,7 @@ import subprocess
import sys
import tempfile
import urllib.parse
import urllib.request
from typing import Dict, Optional
import rpm
@ -1406,28 +1409,40 @@ class ManifestFileV2(ManifestFile):
def embed_data(ip, mpp):
uid = mpp["id"]
path = mpp.get("path")
url = mpp.get("url")
text = mpp.get("text")
if path and text:
raise ValueError(f"Cannot specify both 'path' and 'text' for '{uid}'")
input_count = bool(text) + bool(path) + bool(url)
if input_count == 0:
raise ValueError(f"At least one of 'path', 'url' or 'text' must be specified for '{uid}'")
if input_count > 1:
raise ValueError(f"Only one of 'path', 'url' or 'text' may be specified for '{uid}'")
if path:
f, _ = self.find_and_open_file(path, [], mode="rb")
with f:
data = f.read()
elif url:
response = urllib.request.urlopen(url)
data = response.fp.read()
else:
data = bytes(text, "utf-8")
encoded = base64.b64encode(data).decode("utf-8")
checksum = hashlib.sha256(data).hexdigest()
digest = "sha256:" + checksum
source = element_enter(self.sources, "org.osbuild.inline", {})
items = element_enter(source, "items", {})
items[digest] = {
"encoding": "base64",
"data": encoded
}
if url:
source = element_enter(self.sources, "org.osbuild.curl", {})
items = element_enter(source, "items", {})
items[digest] = url
else:
encoded = base64.b64encode(data).decode("utf-8")
source = element_enter(self.sources, "org.osbuild.inline", {})
items = element_enter(source, "items", {})
items[digest] = {
"encoding": "base64",
"data": encoded
}
refs = element_enter(ip, "references", {})
refs[digest] = mpp.get("options", {})