summaryrefslogtreecommitdiffstats
path: root/meta/classes-global
diff options
context:
space:
mode:
authorAlexander Kanavin <alex.kanavin@gmail.com>2024-01-26 14:34:51 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2024-01-27 08:20:02 +0000
commit347abb8c06b6a84ddd214d14964e049685a9be5f (patch)
treecb6b2b3c02bf253f1e172a83a5b25e19d2f33874 /meta/classes-global
parentd00682ab5c2d472b2fdddfe86198dc2816028359 (diff)
downloadpoky-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.bbclass34
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
104python write_specfile () { 104python 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):