1 |
This commit fixes the following issues:
|
2 |
|
3 |
* The PORTDIR_OVERLAY variable has been deprecated by Gentoo.
|
4 |
|
5 |
With this commit, the variable is no longer written to the
|
6 |
generated make.conf. Instead, a config file
|
7 |
/etc/portage/repos.conf/<repo-name>.conf
|
8 |
is generated for each overlay. The repo name is read from the
|
9 |
overlay using the portage API. Internally, portage parses
|
10 |
metadata/layout.conf and profiles/repo_name to obtain the name.
|
11 |
|
12 |
References:
|
13 |
https://wiki.gentoo.org/wiki//etc/portage/make.conf
|
14 |
https://wiki.gentoo.org/wiki//etc/portage/repos.conf
|
15 |
|
16 |
* All overlays were copied into the same target directory. If the
|
17 |
same file name occurred in multiple overlays, the last overlay
|
18 |
would overwrite all previous files with this name. In particular,
|
19 |
only the metadata/layout.conf of the last overlay was retained,
|
20 |
so it was not possible to reference the other overlays e.g. via
|
21 |
the masters entry in the layout.conf or the portage-2 syntax
|
22 |
for specifying a parent profile from another overlay. Also,
|
23 |
this created problems when the overlays contained ebuilds
|
24 |
for the same package, but with differing versions, because
|
25 |
after copying, the target directory contained both versions of the
|
26 |
ebuild but only the manifest file of the last overlay.
|
27 |
|
28 |
With this commit, each overlay is copied into a separate
|
29 |
sub-directory, e.g. /var/db/repos/<repo-name>.
|
30 |
This directory is referenced via the location entry in the
|
31 |
generated /etc/portage/repos.conf/<repo-name>.conf.
|
32 |
|
33 |
Signed-off-by: Felix Bier <felix.bier@×××××××××××××.com>
|
34 |
---
|
35 |
catalyst/base/stagebase.py | 84 ++++++++++++++++++++++++++++----------
|
36 |
catalyst/defaults.py | 2 +-
|
37 |
catalyst/support.py | 18 ++++++++
|
38 |
3 files changed, 81 insertions(+), 23 deletions(-)
|
39 |
|
40 |
diff --git a/catalyst/base/stagebase.py b/catalyst/base/stagebase.py
|
41 |
index 21cf96a0..fe79b55a 100644
|
42 |
--- a/catalyst/base/stagebase.py
|
43 |
+++ b/catalyst/base/stagebase.py
|
44 |
@@ -1,4 +1,5 @@
|
45 |
|
46 |
+import configparser
|
47 |
import copy
|
48 |
import os
|
49 |
import platform
|
50 |
@@ -19,8 +20,8 @@ from catalyst import log
|
51 |
from catalyst.context import namespace
|
52 |
from catalyst.defaults import (confdefaults, MOUNT_DEFAULTS, PORT_LOGDIR_CLEAN)
|
53 |
from catalyst.support import (CatalystError, file_locate, normpath,
|
54 |
- cmd, read_makeconf, ismount, file_check,
|
55 |
- sanitize_name)
|
56 |
+ cmd, read_makeconf, get_repo_name, ismount,
|
57 |
+ file_check, sanitize_name)
|
58 |
from catalyst.base.targetbase import TargetBase
|
59 |
from catalyst.base.clearbase import ClearBase
|
60 |
from catalyst.base.genbase import GenBase
|
61 |
@@ -786,17 +787,55 @@ class StageBase(TargetBase, ClearBase, GenBase):
|
62 |
env=self.env)
|
63 |
self.resume.enable("setup_confdir")
|
64 |
|
65 |
+ def to_chroot(self, path):
|
66 |
+ """ Prepend chroot path to the given path. """
|
67 |
+
|
68 |
+ chroot = Path(self.settings['chroot_path'])
|
69 |
+ return chroot / path.relative_to(path.anchor)
|
70 |
+
|
71 |
+ def get_repo_conf_path(self, repo_name):
|
72 |
+ """ Construct repo conf path: {repos_conf}/{name}.conf """
|
73 |
+ return Path(self.settings['repos_conf'], repo_name + ".conf")
|
74 |
+
|
75 |
+ def get_repo_location(self, repo_name):
|
76 |
+ """ Construct overlay repo path: {repo_basedir}/{name} """
|
77 |
+ return Path(self.settings['repo_basedir'], repo_name)
|
78 |
+
|
79 |
+ def write_repo_conf(self, repo_name, config):
|
80 |
+ """ Write ConfigParser to {chroot}/{repos_conf}/{name}.conf """
|
81 |
+
|
82 |
+ repo_conf = self.get_repo_conf_path(repo_name)
|
83 |
+
|
84 |
+ repo_conf_chroot = self.to_chroot(repo_conf)
|
85 |
+ repo_conf_chroot.parent.mkdir(mode=0o755, parents=True, exist_ok=True)
|
86 |
+
|
87 |
+ log.info(f'Creating repo config {repo_conf_chroot}.')
|
88 |
+
|
89 |
+ try:
|
90 |
+ with open(repo_conf_chroot, 'w') as f:
|
91 |
+ config.write(f)
|
92 |
+ except OSError as e:
|
93 |
+ raise CatalystError(f'Could not write {repo_conf_chroot}: {e}') from e
|
94 |
+
|
95 |
def portage_overlay(self):
|
96 |
- """ We copy the contents of our overlays to /usr/local/portage """
|
97 |
+ """ We copy the contents of our repos to get_repo_location(repo_name) """
|
98 |
if "portage_overlay" in self.settings:
|
99 |
for x in self.settings["portage_overlay"]:
|
100 |
if os.path.exists(x):
|
101 |
- log.info('Copying overlay dir %s', x)
|
102 |
- ensure_dirs(
|
103 |
- self.settings['chroot_path'] + self.settings['local_overlay'])
|
104 |
- cmd("cp -a " + x + "/* " + self.settings["chroot_path"] +
|
105 |
- self.settings["local_overlay"],
|
106 |
- env=self.env)
|
107 |
+ name = get_repo_name(x)
|
108 |
+
|
109 |
+ location = self.get_repo_location(name)
|
110 |
+ config = configparser.ConfigParser()
|
111 |
+ config[name] = {'location': location}
|
112 |
+ self.write_repo_conf(name, config)
|
113 |
+
|
114 |
+ location_chroot = self.to_chroot(location)
|
115 |
+ location_chroot.mkdir(mode=0o755, parents=True, exist_ok=True)
|
116 |
+
|
117 |
+ log.info(f'Copying overlay dir {x} to {location_chroot}')
|
118 |
+ cmd(f'cp -a {x}/* {location_chroot}', env=self.env)
|
119 |
+ else:
|
120 |
+ log.warning(f'Skipping missing overlay {x}.')
|
121 |
|
122 |
def root_overlay(self):
|
123 |
""" Copy over the root_overlay """
|
124 |
@@ -852,8 +891,8 @@ class StageBase(TargetBase, ClearBase, GenBase):
|
125 |
cxt = libmount.Context(source=source, target=target,
|
126 |
fstype=fstype, options=options)
|
127 |
cxt.mount()
|
128 |
- except OSError as e:
|
129 |
- raise CatalystError(f"Couldn't mount: {source}, {e.strerror}")
|
130 |
+ except Exception as e:
|
131 |
+ raise CatalystError(f"Couldn't mount: {source}, {e}")
|
132 |
|
133 |
def chroot_setup(self):
|
134 |
self.makeconf = read_makeconf(normpath(self.settings["chroot_path"] +
|
135 |
@@ -1018,12 +1057,6 @@ class StageBase(TargetBase, ClearBase, GenBase):
|
136 |
varname = x.split('_')[1].upper()
|
137 |
myf.write(f'{varname}="{self.settings[x]}"\n')
|
138 |
|
139 |
- if setup:
|
140 |
- # Setup the portage overlay
|
141 |
- if "portage_overlay" in self.settings:
|
142 |
- myf.write('PORTDIR_OVERLAY="%s"\n' %
|
143 |
- self.settings["local_overlay"])
|
144 |
-
|
145 |
# Set default locale for system responses. #478382
|
146 |
myf.write(
|
147 |
'\n'
|
148 |
@@ -1097,11 +1130,18 @@ class StageBase(TargetBase, ClearBase, GenBase):
|
149 |
log.warning("You've been hacking. Clearing target patches: %s", target)
|
150 |
clear_path(target)
|
151 |
|
152 |
- # Remove our overlay
|
153 |
- overlay = normpath(
|
154 |
- self.settings["chroot_path"] + self.settings["local_overlay"])
|
155 |
- if os.path.exists(overlay):
|
156 |
- clear_path(overlay)
|
157 |
+ # Remove our overlays
|
158 |
+ if "portage_overlay" in self.settings:
|
159 |
+ for repo_path in self.settings["portage_overlay"]:
|
160 |
+ repo_name = get_repo_name(repo_path)
|
161 |
+
|
162 |
+ repo_conf = self.get_repo_conf_path(repo_name)
|
163 |
+ chroot_repo_conf = self.to_chroot(repo_conf)
|
164 |
+ chroot_repo_conf.unlink()
|
165 |
+
|
166 |
+ location = self.get_repo_location(repo_name)
|
167 |
+ chroot_location = self.to_chroot(location)
|
168 |
+ clear_path(str(chroot_location))
|
169 |
|
170 |
if "sticky-config" not in self.settings["options"]:
|
171 |
# re-write the make.conf to be sure it is clean
|
172 |
diff --git a/catalyst/defaults.py b/catalyst/defaults.py
|
173 |
index 0f399b56..3f12b8d5 100644
|
174 |
--- a/catalyst/defaults.py
|
175 |
+++ b/catalyst/defaults.py
|
176 |
@@ -38,9 +38,9 @@ confdefaults = {
|
177 |
"distdir": portage.settings['DISTDIR'],
|
178 |
"icecream": "/var/cache/icecream",
|
179 |
'list_xattrs_opt': LIST_XATTRS_OPTIONS['linux'],
|
180 |
- "local_overlay": "/var/db/repos/local",
|
181 |
"port_conf": "/etc/portage",
|
182 |
"make_conf": "%(port_conf)s/make.conf",
|
183 |
+ "repos_conf": "%(port_conf)s/repos.conf",
|
184 |
"options": set(),
|
185 |
"pkgdir": "/var/cache/binpkgs",
|
186 |
"port_tmpdir": "/var/tmp/portage",
|
187 |
diff --git a/catalyst/support.py b/catalyst/support.py
|
188 |
index ddbd9ab9..f3a865a7 100644
|
189 |
--- a/catalyst/support.py
|
190 |
+++ b/catalyst/support.py
|
191 |
@@ -10,6 +10,8 @@ from subprocess import Popen
|
192 |
|
193 |
import libmount
|
194 |
|
195 |
+from portage.repository.config import RepoConfig
|
196 |
+
|
197 |
from catalyst import log
|
198 |
|
199 |
BASH_BINARY = "/bin/bash"
|
200 |
@@ -182,6 +184,22 @@ def read_makeconf(mymakeconffile):
|
201 |
return makeconf
|
202 |
|
203 |
|
204 |
+def get_repo_name(repo_path):
|
205 |
+ """ Get the name of the repo at the given repo_path.
|
206 |
+
|
207 |
+ References:
|
208 |
+ https://wiki.gentoo.org/wiki/Repository_format/profiles/repo_name
|
209 |
+ https://wiki.gentoo.org/wiki/Repository_format/metadata/layout.conf#repo-name
|
210 |
+ """
|
211 |
+
|
212 |
+ repo_config = RepoConfig(None, {"location": repo_path})
|
213 |
+
|
214 |
+ if repo_config.missing_repo_name:
|
215 |
+ raise CatalystError(f"Missing name in repository {repo_path}")
|
216 |
+
|
217 |
+ return repo_config.name
|
218 |
+
|
219 |
+
|
220 |
def ismount(path):
|
221 |
"""Like os.path.ismount, but also support bind mounts"""
|
222 |
path = Path(path)
|
223 |
--
|
224 |
2.29.2 |