Bug 1166449 - RPMlint can not handle %ghost created in %trigger scripts
Summary: RPMlint can not handle %ghost created in %trigger scripts
Status: NEW
Alias: None
Product: openSUSE.org
Classification: openSUSE
Component: BuildService (show other bugs)
Version: unspecified
Hardware: All SUSE Other
: P5 - None : Critical (vote)
Target Milestone: ---
Assignee: Dirk Mueller
QA Contact: Adrian Schröter
URL:
Whiteboard:
Keywords:
Depends on: 1165987
Blocks:
  Show dependency treegraph
 
Reported: 2020-03-12 07:52 UTC by Dr. Werner Fink
Modified: 2020-09-27 16:09 UTC (History)
5 users (show)

See Also:
Found By: ---
Services Priority:
Business Priority:
Blocker: ---
Marketing QA Status: ---
IT Deployment: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Dr. Werner Fink 2020-03-12 07:52:39 UTC
+++ This bug was initially created as a clone of Bug #1165987 +++

I've verified that the resulting package nvidia-gfxG05-kmp-default does create the %ghost file

   noether:/ # ll /usr/lib/tmpfiles.d/nvidia-logind-acl-trick.conf 
   -rw-r--r-- 1 root root 222 Mar 12 07:44 /usr/lib/tmpfiles.d/nvidia-logind-acl-trick.conf


together with the path

   noether:/ # rpm -q --qf '[%{FILEFLAGS:fflags} %{FILEVERIFYFLAGS:vflags} %{FILENAMES}\n]' nvidia-gfxG05-kmp-default-440.64_k5.5.7_1-0.x86_64 | grep tmpf
   g M?D?UGP /usr/lib/tmpfiles.d/nvidia-logind-acl-trick.conf

but RPMlinit does not ddetect this:


  [  230s] RPMLINT report:
  [  230s] ===============
  [  232s] 0 packages and 0 specfiles checked; 0 errors, 29 warnings.
  [  232s] Traceback (most recent call last):
  [  232s]   File "rpmlint.py", line 378, in <module>
  [  232s]   File "rpmlint.py", line 166, in main
  [  232s]   File "rpmlint.py", line 224, in runChecks
  [  232s]   File "TmpFilesCheck.py", line 50, in check
  [  232s] FileNotFoundError: [Errno 2] No such file or directory: '/tmp/rpmlint.nvidia-gfxG05-kmp-default-440.64_k5.5.7_1-0.x86_64.rpm.npncim6_/usr/lib/tmpfiles.d/nvidia-logind-acl-trick.conf'

which is not very productive
Comment 1 Dr. Werner Fink 2020-03-12 08:01:21 UTC
Let's see

Now we have with TmpFilesCheck.py line 50ff

            with open(pkgfile.path) as inputf:
                for line in inputf:
                    # 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 t not in interesting_types:
                        continue

                    tmp_files.add(p)

                    if p not in pkg.files():
                        printWarning(pkg, "tmpfile-not-in-filelist", p)
                        continue
                    if not pkg.files()[p].is_ghost:
                        printWarning(pkg, "tmpfile-not-ghost", p)

taht is it tries to open the file and then check if it is a %ghost file ... but per definition a %ghost files does not exist at this point, hence this is a bug of RPMlint
Comment 2 Dr. Werner Fink 2020-03-12 08:04:12 UTC
Adding author of "TmpFilesCheck.py" to Carbon Copy
Comment 3 Dr. Werner Fink 2020-03-12 08:10:30 UTC
Not tested yet

--- TmpFilesCheck.py
+++ TmpFilesCheck.py    2020-03-12 08:09:38.292286701 +0000
@@ -34,16 +34,19 @@ class TmpFilesCheck(AbstractCheck.Abstra
 
         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
 
+            if pkgfile.is_ghost:
+                continue
+
             basename = os.path.basename(fn)
             pattern = re.compile(
                 r'systemd-tmpfiles --create .*%s' % re.escape(basename))
             if (not postin or not pattern.search(postin)) and \
                     (not prein or not pattern.search(prein)):
                 printWarning(pkg,
                              'postin-without-tmpfile-creation', fn)
Comment 4 Fabian Vogt 2020-03-12 08:11:05 UTC
(In reply to Dr. Werner Fink from comment #1)
> taht is it tries to open the file and then check if it is a %ghost file ...
> but per definition a %ghost files does not exist at this point

No, the issue is actually the

>             with open(pkgfile.path) as inputf:

which doesn't check for pkgfile.is_ghost. The loop below is iterating through the tmpfile's file content.
Comment 5 Dr. Werner Fink 2020-03-12 08:22:19 UTC
(In reply to Fabian Vogt from comment #4)
> (In reply to Dr. Werner Fink from comment #1)
> > taht is it tries to open the file and then check if it is a %ghost file ...
> > but per definition a %ghost files does not exist at this point
> 
> No, the issue is actually the
> 
> >             with open(pkgfile.path) as inputf:
> 
> which doesn't check for pkgfile.is_ghost. The loop below is iterating
> through the tmpfile's file content.

This is exactly what I said ...
Comment 6 Dr. Werner Fink 2020-03-12 08:32:25 UTC
(In reply to Dr. Werner Fink from comment #3)
> Not tested yet
> 
> --- TmpFilesCheck.py
> +++ TmpFilesCheck.py    2020-03-12 08:09:38.292286701 +0000
> @@ -34,16 +34,19 @@ class TmpFilesCheck(AbstractCheck.Abstra
>  
>          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
>  
> +            if pkgfile.is_ghost:
> +                continue
> +
>              basename = os.path.basename(fn)
>              pattern = re.compile(
>                  r'systemd-tmpfiles --create .*%s' % re.escape(basename))
>              if (not postin or not pattern.search(postin)) and \
>                      (not prein or not pattern.search(prein)):
>                  printWarning(pkg,
>                               'postin-without-tmpfile-creation', fn)

I've local build the rpmlint with this patch and copied the resulting

  /usr/share/rpmlint/__pycache__/TmpFilesCheck.cpython-38.opt-1.pyc

into the build environment for the nvidia package as

  /opt/testing/share/rpmlint/TmpFilesCheck.pyc

to override the rpmlinit-mini and now the pacakge build

  [  245s] nvidia-gfxG05-kmp-default.x86_64: W: unstripped-binary-or-object /usr/src/kernel-modules/nvidia-440.64-default/nvidia-modeset/nv-modeset-kernel.o_binary
[  245s] nvidia-gfxG05-kmp-default.x86_64: W: unstripped-binary-or-object /usr/src/kernel-modules/nvidia-440.64-default/nvidia/nv-kernel.o_binary
[  245s] stripping debug info from binaries happens automatically according to global
[  245s] project settings. So there's normally no need to manually strip binaries. Left
[  245s] over unstripped binaries could therefore indicate a bug in the automatic
[  245s] stripping process.
[  245s] 
[  245s] nvidia-gfxG05-kmp-default.x86_64: W: useless-provides nvidia-gfxG05-kmp
[  245s] nvidia-gfxG05-kmp-default.x86_64: W: useless-provides nvidia-gfxG05-kmp-default
[  245s] This package provides 2 times the same capacity. It should only provide it
[  245s] once.
[  245s] 
[  245s] 2 packages and 0 specfiles checked; 0 errors, 40 warnings.
[  245s]
Comment 7 Fabian Vogt 2020-03-12 08:32:52 UTC
(In reply to Dr. Werner Fink from comment #5)
> (In reply to Fabian Vogt from comment #4)
> > (In reply to Dr. Werner Fink from comment #1)
> > > taht is it tries to open the file and then check if it is a %ghost file ...
> > > but per definition a %ghost files does not exist at this point
> > 
> > No, the issue is actually the
> > 
> > >             with open(pkgfile.path) as inputf:
> > 
> > which doesn't check for pkgfile.is_ghost. The loop below is iterating
> > through the tmpfile's file content.
> 
> This is exactly what I said ...

Not really:

> taht is it tries to open the file and then check if it is a %ghost file

It never checks whether pkgfile was a %ghost file after opening.
It checks whether the paths mentioned in the tmpfile are %ghost, but it never opens those.
Comment 8 Dr. Werner Fink 2020-03-12 08:57:28 UTC
(In reply to Fabian Vogt from comment #7)
> (In reply to Dr. Werner Fink from comment #5)
> > (In reply to Fabian Vogt from comment #4)
> > > (In reply to Dr. Werner Fink from comment #1)
> > > > taht is it tries to open the file and then check if it is a %ghost file ...
> > > > but per definition a %ghost files does not exist at this point
> > > 
> > > No, the issue is actually the
> > > 
> > > >             with open(pkgfile.path) as inputf:
> > > 
> > > which doesn't check for pkgfile.is_ghost. The loop below is iterating
> > > through the tmpfile's file content.
> > 
> > This is exactly what I said ...
> 
> Not really:
> 
> > taht is it tries to open the file and then check if it is a %ghost file
> 
> It never checks whether pkgfile was a %ghost file after opening.
> It checks whether the paths mentioned in the tmpfile are %ghost, but it
> never opens those.

Read my diff with more context and you will see that I do

  if pkgfile.is_ghost:
      continue

*before* open the file ... nevertheless the chenck if it is a %ghost file and write out a warning is also there with "tmpfile-not-ghost"
Comment 9 Ludwig Nussel 2020-03-12 09:01:58 UTC
certainly I never anticipated a tmpfile created by some nasty trigger script.
Comment 10 Dr. Werner Fink 2020-03-12 09:14:01 UTC
(In reply to Ludwig Nussel from comment #9)
> certainly I never anticipated a tmpfile created by some nasty trigger script.

Than you might find the pull request

  https://github.com/openSUSE/rpmlint-checks/pull/57

useful
Comment 11 Stefan Dirsch 2020-07-17 15:15:54 UTC
(In reply to Ludwig Nussel from comment #9)
> certainly I never anticipated a tmpfile created by some nasty trigger script.

The issue is, that this tmpfile looks differently depending on the hardware. There could be more than a /dev/nvidia0 device (/dev/nvidia1, ...).
In theory the file could be patched instead during %post(Leap/sle) or %trigger (TW) and be regularly packaged instead of being marked as %ghost. This is correct.