diff options
author | Alexander Kanavin <alex.kanavin@gmail.com> | 2024-01-26 14:34:51 +0100 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2024-01-27 08:20:02 +0000 |
commit | 347abb8c06b6a84ddd214d14964e049685a9be5f (patch) | |
tree | cb6b2b3c02bf253f1e172a83a5b25e19d2f33874 /meta/classes-global | |
parent | d00682ab5c2d472b2fdddfe86198dc2816028359 (diff) | |
download | poky-347abb8c06b6a84ddd214d14964e049685a9be5f.tar.gz |
classes/package_rpm: write file permissions and ownership explicitly into .spec
Per https://github.com/rpm-software-management/rpm/commit/77d3529c31ca090a40b8d3959a0bcdd721a556d6
rpm 4.19.1+ will not consider actual filesystem permissions and ownership, and will quietly default
to root if not expictly set otherwise in .spec file.
There's also additional diagnostics (printing what is in passwd/group)
when user/group name lookup against the sysroot fails.
That is never supposed to happen, and yet there was one report that it did:
https://autobuilder.yoctoproject.org/typhoon/#/builders/44/builds/8493/steps/23/logs/stdio
Investigating that issue led to the first three commits in this patchset:
sysroot user management postinsts: run with /bin/sh -e to report errors when they happen
classes/multilib: expand PACKAGE_WRITE_DEPS in addition to DEPENDS
classes/staging: capture output of sysroot postinsts into logs
(From OE-Core rev: a9db9a56617459e8f6f6dd466f2e18a7eed5c1e3)
Signed-off-by: Alexander Kanavin <alex@linutronix.de>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/classes-global')
-rw-r--r-- | meta/classes-global/package_rpm.bbclass | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/meta/classes-global/package_rpm.bbclass b/meta/classes-global/package_rpm.bbclass index 2fc18fe98c..a641dbdb29 100644 --- a/meta/classes-global/package_rpm.bbclass +++ b/meta/classes-global/package_rpm.bbclass | |||
@@ -103,6 +103,7 @@ def write_rpm_perfiledata(srcname, d): | |||
103 | 103 | ||
104 | python write_specfile () { | 104 | python write_specfile () { |
105 | import oe.packagedata | 105 | import oe.packagedata |
106 | import os,pwd,grp,stat | ||
106 | 107 | ||
107 | # append information for logs and patches to %prep | 108 | # append information for logs and patches to %prep |
108 | def add_prep(d, spec_files_bottom): | 109 | def add_prep(d, spec_files_bottom): |
@@ -198,6 +199,23 @@ python write_specfile () { | |||
198 | # of the walk, the isdir() test would then fail and the walk code would assume its a file | 199 | # of the walk, the isdir() test would then fail and the walk code would assume its a file |
199 | # hence we check for the names in files too. | 200 | # hence we check for the names in files too. |
200 | for rootpath, dirs, files in os.walk(walkpath): | 201 | for rootpath, dirs, files in os.walk(walkpath): |
202 | def get_attr(path): | ||
203 | stat_f = os.stat(rootpath + "/" + path, follow_symlinks=False) | ||
204 | mode = stat.S_IMODE(stat_f.st_mode) | ||
205 | try: | ||
206 | owner = pwd.getpwuid(stat_f.st_uid).pw_name | ||
207 | except Exception as e: | ||
208 | bb.error("Content of /etc/passwd in sysroot:\n{}".format( | ||
209 | open(d.getVar("RECIPE_SYSROOT") +"/etc/passwd").read())) | ||
210 | raise e | ||
211 | try: | ||
212 | group = grp.getgrgid(stat_f.st_gid).gr_name | ||
213 | except Exception as e: | ||
214 | bb.error("Content of /etc/group in sysroot:\n{}".format( | ||
215 | open(d.getVar("RECIPE_SYSROOT") +"/etc/group").read())) | ||
216 | raise e | ||
217 | return "%attr({:o},{},{}) ".format(mode, owner, group) | ||
218 | |||
201 | path = rootpath.replace(walkpath, "") | 219 | path = rootpath.replace(walkpath, "") |
202 | if path.endswith("DEBIAN") or path.endswith("CONTROL"): | 220 | if path.endswith("DEBIAN") or path.endswith("CONTROL"): |
203 | continue | 221 | continue |
@@ -221,24 +239,28 @@ python write_specfile () { | |||
221 | if dir == "CONTROL" or dir == "DEBIAN": | 239 | if dir == "CONTROL" or dir == "DEBIAN": |
222 | continue | 240 | continue |
223 | dir = dir.replace("%", "%%%%%%%%") | 241 | dir = dir.replace("%", "%%%%%%%%") |
242 | p = path + '/' + dir | ||
224 | # All packages own the directories their files are in... | 243 | # All packages own the directories their files are in... |
225 | target.append('%dir "' + path + '/' + dir + '"') | 244 | target.append(get_attr(dir) + '%dir "' + p + '"') |
226 | else: | 245 | else: |
227 | # packages own only empty directories or explict directory. | 246 | # packages own only empty directories or explict directory. |
228 | # This will prevent the overlapping of security permission. | 247 | # This will prevent the overlapping of security permission. |
248 | attr = get_attr(path) | ||
229 | if path and not files and not dirs: | 249 | if path and not files and not dirs: |
230 | target.append('%dir "' + path + '"') | 250 | target.append(attr + '%dir "' + path + '"') |
231 | elif path and path in dirfiles: | 251 | elif path and path in dirfiles: |
232 | target.append('%dir "' + path + '"') | 252 | target.append(attr + '%dir "' + path + '"') |
233 | 253 | ||
234 | for file in files: | 254 | for file in files: |
235 | if file == "CONTROL" or file == "DEBIAN": | 255 | if file == "CONTROL" or file == "DEBIAN": |
236 | continue | 256 | continue |
237 | file = file.replace("%", "%%%%%%%%") | 257 | file = file.replace("%", "%%%%%%%%") |
238 | if conffiles.count(path + '/' + file): | 258 | attr = get_attr(file) |
239 | target.append('%config "' + path + '/' + file + '"') | 259 | p = path + '/' + file |
260 | if conffiles.count(p): | ||
261 | target.append(attr + '%config "' + p + '"') | ||
240 | else: | 262 | else: |
241 | target.append('"' + path + '/' + file + '"') | 263 | target.append(attr + '"' + p + '"') |
242 | 264 | ||
243 | # Prevent the prerm/postrm scripts from being run during an upgrade | 265 | # Prevent the prerm/postrm scripts from being run during an upgrade |
244 | def wrap_uninstall(scriptvar): | 266 | def wrap_uninstall(scriptvar): |