tools/osbuild-depsolve-dnf: load repos from dir
Support loading repositories from a root tree instead of supplying them
with the request. The repositories should be in the standard yum repo
format. Both repository sources can be defined simultaneously, but at
least one is required.
The root_dir is expected to contain files necessary for depsolving in
the standard paths.
These files are:
- Repository (.repo) configurations in <root_dir>/etc/yum.repos.d/
- GPG key files in <root_dir>/etc/pki/rpm-gpg/
- This will be used to resolve gpg key paths specified in the .repo
files that are relative to the root_dir.
- (Optional) Custom dnf config variables in <root_dir>/etc/dnf/vars or
<root_dir>/etc/yum/vars.
- This is used by CentOS Stream to set the value of $stream.
Custom repository configurations in arbitrary (non-root) paths will have
to follow this directory structure.
A new variable is added to the request, `releasever`, which is mandatory
when using `root_dir`. This variable is used in repository URLs and GPG
key paths. In the default case, dnf reads this variable by inspecting
the rpm database. We will override it in the Solver the same way we
override the arch and basearch for variable substitution. In the
future, we will make this variable mandatory in all cases, which will
make the variable available for repo configs defined in the request as
well.
The root_dir is used in two ways:
- Set the base.conf.reposdir to <root_dir>/etc/yum.repos.d.
- Call update_from_etc() with root_dir to read custom variables in
<root_dir>/etc/yum/vars and <root_dir>/etc/dnf/vars.
This commit is contained in:
parent
06c8aca871
commit
38f5964205
1 changed files with 37 additions and 14 deletions
|
|
@ -20,8 +20,15 @@ import hawkey
|
|||
|
||||
class Solver():
|
||||
|
||||
# pylint: disable=too-many-arguments
|
||||
def __init__(self, repos, module_platform_id, persistdir, cachedir, arch):
|
||||
def __init__(self, request, persistdir, cache_dir):
|
||||
arch = request["arch"]
|
||||
releasever = request.get("releasever")
|
||||
module_platform_id = request["module_platform_id"]
|
||||
|
||||
arguments = request["arguments"]
|
||||
repos = arguments.get("repos", [])
|
||||
root_dir = arguments.get("root_dir")
|
||||
|
||||
self.base = dnf.Base()
|
||||
|
||||
# Enable fastestmirror to ensure we choose the fastest mirrors for
|
||||
|
|
@ -49,12 +56,24 @@ class Solver():
|
|||
self.base.conf.module_platform_id = module_platform_id
|
||||
self.base.conf.config_file_path = "/dev/null"
|
||||
self.base.conf.persistdir = persistdir
|
||||
self.base.conf.cachedir = cachedir
|
||||
self.base.conf.cachedir = cache_dir
|
||||
self.base.conf.substitutions['arch'] = arch
|
||||
self.base.conf.substitutions['basearch'] = dnf.rpm.basearch(arch)
|
||||
if releasever:
|
||||
self.base.conf.substitutions['releasever'] = releasever
|
||||
|
||||
for repo in repos:
|
||||
self.base.repos.add(self._dnfrepo(repo, self.base.conf))
|
||||
|
||||
if root_dir:
|
||||
# This sets the varsdir to ("{root_dir}/etc/yum/vars/", "{root_dir}/etc/dnf/vars/") for custom variable
|
||||
# substitution (e.g. CentOS Stream 9's $stream variable)
|
||||
self.base.conf.substitutions.update_from_etc(root_dir)
|
||||
|
||||
repos_dir = os.path.join(root_dir, "etc/yum.repos.d")
|
||||
self.base.conf.reposdir = repos_dir
|
||||
self.base.read_all_repos()
|
||||
|
||||
self.base.fill_sack(load_system_repo=False)
|
||||
|
||||
# pylint: disable=too-many-branches
|
||||
|
|
@ -271,20 +290,12 @@ def setup_cachedir(request):
|
|||
|
||||
def solve(request, cache_dir):
|
||||
command = request["command"]
|
||||
arch = request["arch"]
|
||||
module_platform_id = request["module_platform_id"]
|
||||
arguments = request["arguments"]
|
||||
|
||||
transactions = arguments.get("transactions")
|
||||
with tempfile.TemporaryDirectory() as persistdir:
|
||||
try:
|
||||
solver = Solver(
|
||||
arguments["repos"],
|
||||
module_platform_id,
|
||||
persistdir,
|
||||
cache_dir,
|
||||
arch
|
||||
)
|
||||
solver = Solver(request, persistdir, cache_dir)
|
||||
if command == "dump":
|
||||
result = solver.dump()
|
||||
elif command == "depsolve":
|
||||
|
|
@ -336,6 +347,7 @@ def respond(result):
|
|||
print(json.dumps(result))
|
||||
|
||||
|
||||
# pylint: disable=too-many-return-statements
|
||||
def validate_request(request):
|
||||
command = request.get("command")
|
||||
valid_cmds = ("depsolve", "dump", "search")
|
||||
|
|
@ -356,6 +368,7 @@ def validate_request(request):
|
|||
"kind": "InvalidRequest",
|
||||
"reason": "no 'module_platform_id' specified"
|
||||
}
|
||||
|
||||
arguments = request.get("arguments")
|
||||
if not arguments:
|
||||
return {
|
||||
|
|
@ -363,10 +376,20 @@ def validate_request(request):
|
|||
"reason": "empty 'arguments'"
|
||||
}
|
||||
|
||||
if not arguments.get("repos"):
|
||||
if not arguments.get("repos") and not arguments.get("root_dir"):
|
||||
return {
|
||||
"kind": "InvalidRequest",
|
||||
"reason": "no 'repos' specified"
|
||||
"reason": "no 'repos' or 'root_dir' specified"
|
||||
}
|
||||
|
||||
# if root_dir is used, we also need releasever
|
||||
# pylint: disable=fixme
|
||||
# TODO: Make releasever mandatory in all cases.
|
||||
# We temporarily keep it tied to root_dir for short-term backwards compatibility
|
||||
if arguments.get("root_dir") and not request.get("releasever"):
|
||||
return {
|
||||
"kind": "InvalidRequest",
|
||||
"reason": "'root_dir' requires setting 'releasever'"
|
||||
}
|
||||
|
||||
return None
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue