forked from pool/rpmlint
Dirk Mueller
1cdbc13b57
* test: Skip fedoradev GPG checks at least for now * test: Refresh fedora* packages on image build * test: Use assertEqual where appropriate, thanks to flake8/hacking * test: Update fedora24 config to fedora26, run it on Travis * Add a new test for tmpfiles.d snippets in the /etc/ tree. * Add new tests for systemd units and udev rules in /etc/ tree * test: Disable hacking for now until it's flake8 3.4+ compatible * test: Set up flake8-bugbear, enable it in fedoradev container * rpmlint: Avoid unused loop control variable * ZipCheck: Add TODO * *: Avoid mutable argument defaults * Be aware of -debugsource packages * rpmdiff: Fix unused variable from previous commit * rpmdiff: Support soft dependencies * BinariesCheck, FilesCheck: Ignore various .build-id dirs * Add python3-devel and rpm-build to fedoradev container to provoke some issues * BinariesCheck: Popen env consistency fix * Pkg.getstatusoutput: Set LC_ALL for all Popens, defaulting to C * rpmlint: Fix checking specfile from stdin * test.sh: Extract rpmlint command to run_rpmlint * Revert "Remove unused spec_lines check_spec argument" * BinariesCheck: Trivial cleanups * travis: Run make install too * FilesCheck: Allow multiple bytecode magic values per Python version * tests: Make output test tools easier to reuse * FilesCheck: hg.python.org -> github.com/python * Pkg: Return vendor and distribution as unicode strings * FilesCheck: Add Python 3.7 bytecode magic value * Pkg.b2s: Add some more test cases OBS-URL: https://build.opensuse.org/package/show/devel:openSUSE:Factory:rpmlint/rpmlint?expand=0&rev=482
169 lines
6.2 KiB
Diff
169 lines
6.2 KiB
Diff
From: Ludwig Nussel <ludwig.nussel@suse.de>
|
|
Date: Fri, 5 Sep 2014 12:53:40 +0200
|
|
Subject: [PATCH] add check for tmpfiles created at runtime
|
|
|
|
this check parses files in /usr/lib/tmpfiles.d and verifies that
|
|
entries that create files or directories are actually listed in
|
|
%files.
|
|
|
|
The check also handles the ghost file check as rpmlint shouldn't
|
|
complain about ghost files handled by the tmpfiles mechanism.
|
|
---
|
|
PostCheck.py | 18 ---------
|
|
TmpFilesCheck.py | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
2 files changed, 111 insertions(+), 18 deletions(-)
|
|
create mode 100644 TmpFilesCheck.py
|
|
|
|
Index: rpmlint-rpmlint-1.10/PostCheck.py
|
|
===================================================================
|
|
--- rpmlint-rpmlint-1.10.orig/PostCheck.py
|
|
+++ rpmlint-rpmlint-1.10/PostCheck.py
|
|
@@ -112,20 +112,6 @@ class PostCheck(AbstractCheck.AbstractCh
|
|
self.check_aux(
|
|
pkg, files, prog[idx], script[idx], tag[2], prereq)
|
|
|
|
- ghost_files = pkg.ghostFiles()
|
|
- if ghost_files:
|
|
- postin = pkg[rpm.RPMTAG_POSTIN]
|
|
- prein = pkg[rpm.RPMTAG_PREIN]
|
|
- for f in ghost_files:
|
|
- if f in pkg.missingOkFiles():
|
|
- continue
|
|
- if not postin and not prein:
|
|
- printWarning(pkg, 'ghost-files-without-postin')
|
|
- if (not postin or f not in postin) and \
|
|
- (not prein or f not in prein):
|
|
- printWarning(pkg,
|
|
- 'postin-without-ghost-file-creation', f)
|
|
-
|
|
def check_aux(self, pkg, files, prog, script, tag, prereq):
|
|
if script:
|
|
if prog:
|
|
@@ -195,10 +181,6 @@ class PostCheck(AbstractCheck.AbstractCh
|
|
check = PostCheck()
|
|
|
|
# Add information about checks
|
|
-addDetails(
|
|
-'postin-without-ghost-file-creation',
|
|
-'''A file tagged as ghost is not created during %prein nor during %postin.''',
|
|
-)
|
|
for scriptlet in map(lambda x: '%' + x, RPM_SCRIPTLETS):
|
|
addDetails(
|
|
'one-line-command-in-%s' % scriptlet,
|
|
Index: rpmlint-rpmlint-1.10/TmpFilesCheck.py
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ rpmlint-rpmlint-1.10/TmpFilesCheck.py
|
|
@@ -0,0 +1,111 @@
|
|
+# -*- coding: utf-8 -*-
|
|
+#############################################################################
|
|
+# File : TmpFilesCheck.py
|
|
+# Package : rpmlint
|
|
+# Author : Ludwig Nussel
|
|
+# Created on : Wed Sep 03 10:36 2014
|
|
+# Purpose : Check systemd created tmpfiles are included in filelist
|
|
+#############################################################################
|
|
+
|
|
+import os
|
|
+import re
|
|
+
|
|
+from Filter import addDetails, printError, printWarning
|
|
+import AbstractCheck
|
|
+import Pkg
|
|
+import stat
|
|
+import rpm
|
|
+
|
|
+class TmpFilesCheck(AbstractCheck.AbstractCheck):
|
|
+ '''Check systemd created tmpfiles are included in filelist'''
|
|
+
|
|
+ def __init__(self):
|
|
+ AbstractCheck.AbstractCheck.__init__(self, "TmpFilesCheck")
|
|
+ self._spec_file = None
|
|
+
|
|
+ def check(self, pkg):
|
|
+ if pkg.isSource():
|
|
+ return
|
|
+
|
|
+ # file names handled by systemd-tmpfiles
|
|
+ tmp_files = set()
|
|
+ postin = pkg[rpm.RPMTAG_POSTIN]
|
|
+ prein = pkg[rpm.RPMTAG_PREIN]
|
|
+
|
|
+ # see tmpfiles.d(5)
|
|
+ interesting_types = ('f', 'F', 'w', 'd', 'D', 'p', 'L', 'c', 'b')
|
|
+
|
|
+ for fn, pkgfile in pkg.files().items():
|
|
+ if not fn.startswith('/usr/lib/tmpfiles.d/'):
|
|
+ continue
|
|
+ if not stat.S_ISREG(pkgfile.mode):
|
|
+ printWarning(pkg, "tmpfile-not-regular-file", fn)
|
|
+ continue
|
|
+
|
|
+ pattern = re.compile(r'systemd-tmpfiles --create .*%s'%re.escape(fn))
|
|
+ if (not postin or not pattern.search(postin)) and \
|
|
+ (not prein or not pattern.search(prein)):
|
|
+ printWarning(pkg,
|
|
+ 'postin-without-tmpfile-creation', fn)
|
|
+
|
|
+ for line in open(pkgfile.path):
|
|
+ # skip comments
|
|
+ line = line.split('#')[0].split('\n')[0]
|
|
+ line = line.lstrip()
|
|
+ if not len(line):
|
|
+ continue
|
|
+ line = re.split(r'\s+', line)
|
|
+ # format is
|
|
+ #Type Path Mode UID GID Age Argument
|
|
+ # we only need type and path
|
|
+ if len(line) < 3:
|
|
+ continue
|
|
+ t = line[0]
|
|
+ p = line[1]
|
|
+ if t.endswith('!'):
|
|
+ t = t[:-1]
|
|
+ if not t in interesting_types:
|
|
+ continue
|
|
+
|
|
+ tmp_files.add(p)
|
|
+
|
|
+ if not p in pkg.files():
|
|
+ printWarning(pkg, "tmpfile-not-in-filelist", p)
|
|
+ continue
|
|
+ if not pkg.files()[p].is_ghost:
|
|
+ printWarning(pkg, "tmpfile-not-ghost", p)
|
|
+
|
|
+ # now check remaining ghost files that are not already
|
|
+ # handled by systemd-tmpfiles
|
|
+ ghost_files = set(pkg.ghostFiles()) - tmp_files
|
|
+ if ghost_files:
|
|
+ for f in ghost_files:
|
|
+ if f in pkg.missingOkFiles():
|
|
+ continue
|
|
+ if not postin and not prein:
|
|
+ printWarning(pkg, 'ghost-files-without-postin')
|
|
+ if (not postin or f not in postin) and \
|
|
+ (not prein or f not in prein):
|
|
+ printWarning(pkg,
|
|
+ 'postin-without-ghost-file-creation', f)
|
|
+
|
|
+
|
|
+
|
|
+check = TmpFilesCheck()
|
|
+
|
|
+addDetails(
|
|
+'postin-without-ghost-file-creation',
|
|
+'''A file tagged as ghost is not created during %prein nor during %postin.''',
|
|
+'postin-without-tmpfile-creation',
|
|
+'''Please use the %tmpfiles_create macro in %post for each of your tmpfiles.d files''',
|
|
+'tmpfile-not-regular-file',
|
|
+'''files in tmpfiles.d need to be regular files''', # otherwise we won't open it :-)
|
|
+'tmpfile-not-in-filelist',
|
|
+'''please add the specified file to your %files section as %ghost so
|
|
+users can easily query who created the file, it gets uninstalled on
|
|
+package removal and finally other rpmlint checks see it''',
|
|
+'tmpfile-not-ghost',
|
|
+'''the specified file is not marked as %ghost although created at
|
|
+runtime via tmpfiles mechanism.'''
|
|
+)
|
|
+# vim: sw=4 et
|