Gentoo Archives: gentoo-portage-dev

From: Alec Warner <antarus@g.o>
To: gentoo-portage-dev@l.g.o
Cc: Sam James <sam@g.o>
Subject: Re: [gentoo-portage-dev] [PATCH] lib/_emerge/actions.py: warn on missing /run
Date: Fri, 08 Oct 2021 03:03:38
Message-Id: CAAr7Pr8k9bRpUqHpSJ776km15ffoHDF0DiJ0_=KBxu8rKcBwHg@mail.gmail.com
In Reply to: [gentoo-portage-dev] [PATCH] lib/_emerge/actions.py: warn on missing /run by Sam James
1 On Wed, Oct 6, 2021 at 8:20 PM Sam James <sam@g.o> wrote:
2 >
3 > Newer versions of build-docbook-catalog use
4 > /run/lock. This exposed that we weren't
5 > asking users to mount /run in the handbook.
6 >
7 > Check if it exists and warn if it doesn't.
8 >
9 > This should primarily (exclusively?) be a
10 > problem in chroots given an init system
11 > should be creating this.
12 >
13 > Bug: https://bugs.gentoo.org/816303
14 > Signed-off-by: Sam James <sam@g.o>
15 > ---
16 > lib/_emerge/actions.py | 34 ++++++++++++++++++++++------------
17 > 1 file changed, 22 insertions(+), 12 deletions(-)
18 >
19 > diff --git a/lib/_emerge/actions.py b/lib/_emerge/actions.py
20 > index 05a115250..1b40bebd3 100644
21 > --- a/lib/_emerge/actions.py
22 > +++ b/lib/_emerge/actions.py
23 > @@ -2986,17 +2986,26 @@ def validate_ebuild_environment(trees):
24 > check_locale()
25 >
26 >
27 > -def check_procfs():
28 > - procfs_path = "/proc"
29 > - if platform.system() not in ("Linux",) or os.path.ismount(procfs_path):
30 > - return os.EX_OK
31 > - msg = "It seems that %s is not mounted. You have been warned." % procfs_path
32 > - writemsg_level(
33 > - "".join("!!! %s\n" % l for l in textwrap.wrap(msg, 70)),
34 > - level=logging.ERROR,
35 > - noiselevel=-1,
36 > - )
37 > - return 1
38
39 Please add a docstring (""" comment) to the function describing why
40 it's doing what its doing.
41
42 > +def check_mounted_fs():
43 > + paths = {"/proc": False, "/run": False}
44
45 So on Linux, proc is necessary. Isn't /run necessary regardless of OS?
46 Will docbook build on prefix, or on BSD without /run (I'm guessing
47 not?)
48
49 We might go with something like:
50
51 def check_mounted_fs():
52 """Cheeky comment explaining why we probably need these mounts."""
53 required_paths = ['/run']
54 if platform.system() == 'Linux':
55 required_paths.append('/proc')
56
57 missing_mounts = False
58 for path in required_paths:
59 if not os.path.ismount(path):
60 msg = ....
61 writemsg = ...
62 missing_mounts = True
63 # else we do nothing, the mount is where we want it, etc.
64
65 return missing_mounts # true if mounts are missing, false otherwise.
66
67 > +
68 > + for path in paths.keys():
69 > + if platform.system() not in ("Linux",) or os.path.ismount(path):
70 > + paths[path] = True
71 > + continue
72 > +
73 > + msg = "It seems that %s is not mounted. You have been warned." % path
74 > + writemsg_level(
75 > + "".join("!!! %s\n" % l for l in textwrap.wrap(msg, 70)),
76 > + level=logging.ERROR,
77 > + noiselevel=-1,
78 > + )
79
80 Duncan covered this already, but I will +1 his concern about better
81 messaging being an option ;)
82
83 > +
84 > + # Were any of the mounts we were looking for missing?
85 > + if False in paths.values():
86 > + return 1
87
88 So a couple of nitpicks here. This is a common sort of "collect"
89 pattern; and I'd use python's any() / all() helpers for a more
90 pythonic experience.
91
92 E.g.
93
94 items = [some, list, of, items]
95 results = []
96 for j in items:
97 results.append(some_computation(j))
98
99 # Did any of the computations succeed?
100 return any(results) # at least 1 True
101 # Did all of the computations succeed?
102 return all(results) # all True
103 # Did none of the computations succeed?
104 return not any(results) # all False
105
106 So in this example you have elected to store the results in a dict,
107 and we want to return true if all the results are true:
108
109 return all(paths.values())
110
111 But see also earlier notes above.
112
113 > +
114 > + return os.EX_OK
115
116 This isn't shell, so return True or False (not 0 or 1.) (but see above comment.)
117
118 >
119 >
120 > def config_protect_check(trees):
121 > @@ -3474,7 +3483,8 @@ def run_action(emerge_config):
122 > repo_name_check(emerge_config.trees)
123 > repo_name_duplicate_check(emerge_config.trees)
124 > config_protect_check(emerge_config.trees)
125 > - check_procfs()
126 > +
127 > + check_mounted_fs()
128 >
129 > for mytrees in emerge_config.trees.values():
130 > mydb = mytrees["porttree"].dbapi
131 > --
132 > 2.33.0
133 >
134 >