Gentoo Archives: gentoo-catalyst

From: Alec Warner <antarus@g.o>
To: gentoo-catalyst@l.g.o
Cc: Brian Dolbec <dolsen@g.o>
Subject: Re: [gentoo-catalyst] [PATCH 5/6] modules/generic_stage_target.py, modules/stage1_target.py: Add a target_mounts dictionary
Date: Sun, 29 Dec 2013 05:26:58
Message-Id: CAAr7Pr8ZrXARZK2+1-G9o8Z-3RiEto9aC70DH30j1msTv5Wa1g@mail.gmail.com
In Reply to: [gentoo-catalyst] [PATCH 5/6] modules/generic_stage_target.py, modules/stage1_target.py: Add a target_mounts dictionary by Brian Dolbec
1 On Sat, Dec 28, 2013 at 5:57 PM, Brian Dolbec <dolsen@g.o> wrote:
2
3 > Cleans up all self.mounts, self.mountmap usage.
4 > Replace multiple path additions with one instance at the beginning of the
5 > function, reuse the result multiple times.
6 > Add some extra debug prints (to be converted to logging later)
7 > ---
8 > modules/generic_stage_target.py | 94
9 > ++++++++++++++++++++++++++---------------
10 > modules/stage1_target.py | 5 ++-
11 > 2 files changed, 63 insertions(+), 36 deletions(-)
12 >
13 > diff --git a/modules/generic_stage_target.py
14 > b/modules/generic_stage_target.py
15 > index ce28ab8..c8d31e1 100644
16 > --- a/modules/generic_stage_target.py
17 > +++ b/modules/generic_stage_target.py
18 > @@ -4,6 +4,23 @@ from generic_target import *
19 > from stat import *
20 > import catalyst_lock
21 >
22 > +# temporary location. It will be moved to a
23 > +# new defaults file in a later comit
24 > +TARGET_MOUNTS_DEFAULTS = {
25 > + "proc": "/proc",
26 > + "dev": "/dev",
27 > + "devpts": "/dev/pts",
28 > + "portdir": "/usr/portage",
29 > + "distdir": "/usr/portage/distfiles",
30 > + "packagedir": "/usr/portage/packages",
31 > + "port_tmpdir": "/var/tmp/portage",
32 > + "kerncache": "/tmp/kerncache",
33 > + "ccache": "/var/tmp/ccache",
34 > + "icecream": "/usr/lib/icecc/bin",
35 > + "port_logdir": "/var/log/portage",
36 > + }
37 > +
38 > +
39 > class generic_stage_target(generic_target):
40 > """
41 > This class does all of the chroot setup, copying of files, etc. It
42 > is
43 > @@ -173,6 +190,10 @@ class generic_stage_target(generic_target):
44 >
45 > file_locate(self.settings,["portage_confdir"],expand=0)
46 >
47 > """ Setup our mount points """
48 > + # initialize our target mounts.
49 > + # later I plan to make these configurable so the
50 > + # defaults can be easily overridden if desired.
51 > + self.target_mounts = TARGET_MOUNTS_DEFAULTS.copy()
52 > if "SNAPCACHE" in self.settings:
53 > self.mounts=["proc", "dev", "portdir", "distdir",
54 > "port_tmpdir"]
55 > self.mountmap={"proc":"/proc", "dev":"/dev",
56 > "devpts":"/dev/pts",
57 > @@ -219,17 +240,18 @@ class generic_stage_target(generic_target):
58 > self.mounts.append("ccache")
59 > self.mountmap["ccache"] = ccdir
60 > """ for the chroot: """
61 > - self.env["CCACHE_DIR"]="/var/tmp/ccache"
62 > + self.env["CCACHE_DIR"] =
63 > self.target_mounts["ccache"]
64 >
65 > if "ICECREAM" in self.settings:
66 > self.mounts.append("/var/cache/icecream")
67 >
68 > self.mountmap["/var/cache/icecream"]="/var/cache/icecream"
69 > -
70 > self.env["PATH"]="/usr/lib/icecc/bin:"+self.env["PATH"]
71 > + self.env["PATH"] = self.target_mounts["icecream"]
72 > + ":" + \
73 > + self.env["PATH"]
74 >
75 if "port_logdir" in self.settings:
76 > - self.mounts.append("/var/log/portage")
77 > -
78 > self.mountmap["/var/log/portage"]=self.settings["port_logdir"]
79 > - self.env["PORT_LOGDIR"]="/var/log/portage"
80 > + self.mounts.append("port_logdir")
81 > +
82 > self.mountmap["port_logdir"]=self.settings["port_logdir"]
83 > +
84 > self.env["PORT_LOGDIR"]=self.target_mounts["port_logdir"]
85 > self.env["PORT_LOGDIR_CLEAN"]='find
86 > "${PORT_LOGDIR}" -type f ! -name "summary.log*" -mtime +30 -delete'
87 >
88
89 I've avoided commenting on + in strings, as my understanding was that we
90 were not doing style fixups in these CLs. I would argue that in general,
91 any time you use string + string in python, you are doing it wrong (e.g.
92 your code is not 'pythonic')
93
94 You can use
95
96 "%s:%s" % (string1, string2) or ":".join(string1, string2)
97
98 Either are fine, and are nominally better than string + string + string.
99
100
101
102 >
103 > def override_cbuild(self):
104 > @@ -603,33 +625,34 @@ class generic_stage_target(generic_target):
105 > "kill-chroot-pids script
106 > failed.",env=self.env)
107 >
108 > def mount_safety_check(self):
109 > - mypath=self.settings["chroot_path"]
110 > -
111 > """
112 > Check and verify that none of our paths in mypath are
113 > mounted. We don't
114 > want to clean up with things still mounted, and this
115 > allows us to check.
116 > Returns 1 on ok, 0 on "something is still mounted" case.
117 > """
118 >
119 > - if not os.path.exists(mypath):
120 > + if not os.path.exists(self.settings["chroot_path"]):
121 > return
122 >
123 > + print "self.mounts =", self.mounts
124 > for x in self.mounts:
125 > - if not os.path.exists(mypath + self.mountmap[x]):
126 > + target = normpath(self.settings["chroot_path"] +
127 > self.target_mounts[x])
128 > + print "mount_safety_check() x =", x, target
129 > + if not os.path.exists(target):
130 > continue
131 >
132 > - if ismount(mypath + self.mountmap[x]):
133 > + if ismount(target):
134 > """ Something is still mounted "" """
135 > try:
136 > - print self.mountmap[x] + " is
137 > still mounted; performing auto-bind-umount...",
138 > + print target + " is still mounted;
139 > performing auto-bind-umount...",
140 > """ Try to umount stuff ourselves
141 > """
142 > self.unbind()
143 > - if ismount(mypath +
144 > self.mountmap[x]):
145 > - raise CatalystError,
146 > "Auto-unbind failed for " + self.mountmap[x]
147 > + if ismount(target):
148 > + raise CatalystError,
149 > "Auto-unbind failed for " + target
150 > else:
151 > print "Auto-unbind
152 > successful..."
153 > except CatalystError:
154 > - raise CatalystError, "Unable to
155 > auto-unbind " + self.mountmap[x]
156 > + raise CatalystError, "Unable to
157 > auto-unbind " + target
158 >
159 > def unpack(self):
160 > unpack=True
161 > @@ -897,12 +920,14 @@ class generic_stage_target(generic_target):
162 >
163 > def bind(self):
164 > for x in self.mounts:
165 > - if not os.path.exists(self.settings["chroot_path"]
166 > + self.mountmap[x]):
167 > -
168 > os.makedirs(self.settings["chroot_path"]+x,0755)
169 > + #print "bind(); x =", x
170 > + target = normpath(self.settings["chroot_path"] +
171 > self.target_mounts[x])
172 > + if not os.path.exists(target):
173 > + os.makedirs(target, 0755)
174 >
175 > if not os.path.exists(self.mountmap[x]):
176 > if not self.mountmap[x] == "tmpfs":
177 > - os.makedirs(self.mountmap[x],0755)
178 > + os.makedirs(self.mountmap[x], 0755)
179 >
180 > src=self.mountmap[x]
181 > #print "bind(); src =", src
182 > @@ -910,20 +935,22 @@ class generic_stage_target(generic_target):
183 > self.snapshot_lock_object.read_lock()
184 > if os.uname()[0] == "FreeBSD":
185 > if src == "/dev":
186 > - retval = os.system("mount -t devfs
187 > none " +
188 > -
189 > self.settings["chroot_path"] + src)
190 > + cmd = "mount -t devfs none " +
191 > target
192 > + retval=os.system(cmd)
193 >
194
195 "because the code use to do it" aside, is there some compelling reason to
196 not use subprocess.Popen here? os.system is probably the worst syscall you
197 can use. It spawns a shell, it will select things like './mount' over
198 '/usr/bin/mount' because you failed to specify the full path to the binary,
199 its not clear what environment the shell is using.
200
201 Even something like:
202
203 import subprocess
204 retval = subprocess.call(cmd.split())
205
206 would likely avoid these problems unless you are relying on shell expansion
207 in cmd?
208
209
210
211
212 > else:
213 > - retval = os.system("mount_nullfs "
214 > + src + " " +
215 > -
216 > self.settings["chroot_path"] + src)
217 > + cmd = "mount_nullfs " + src + " "
218 > + target
219 > + retval=os.system(cmd)
220 > else:
221 > if src == "tmpfs":
222 > if "var_tmpfs_portage" in
223 > self.settings:
224 > - retval=os.system("mount -t
225 > tmpfs -o size="+\
226 > -
227 > self.settings["var_tmpfs_portage"]+"G "+src+" "+\
228 > -
229 > self.settings["chroot_path"]+x)
230 > + cmd = "mount -t tmpfs -o
231 > size=" + \
232 > +
233 > self.settings["var_tmpfs_portage"] + "G " + \
234 > + src + " " + target
235 > + retval=os.system(cmd)
236 > else:
237 > - retval = os.system("mount --bind "
238 > + src + " " +
239 > -
240 > self.settings["chroot_path"] + src)
241 > + cmd = "mount --bind " + src + " "
242 > + target
243 > + #print "bind(); cmd =", cmd
244 > + retval=os.system(cmd)
245 > if retval!=0:
246 > self.unbind()
247 > raise CatalystError,"Couldn't bind mount "
248 > + src
249 > @@ -935,26 +962,25 @@ class generic_stage_target(generic_target):
250 > myrevmounts.reverse()
251 > """ Unmount in reverse order for nested bind-mounts """
252 > for x in myrevmounts:
253 > - if not os.path.exists(mypath + self.mountmap[x]):
254 > + target = normpath(mypath + self.target_mounts[x])
255 > + if not os.path.exists(target):
256 > continue
257 >
258 > - if not ismount(mypath + self.mountmap[x]):
259 > + if not ismount(target):
260 > continue
261 >
262 > - retval=os.system("umount "+\
263 > - os.path.join(mypath,
264 > self.mountmap[x].lstrip(os.path.sep)))
265 > + retval=os.system("umount " + target)
266 >
267 > if retval!=0:
268 > - warn("First attempt to unmount: " + mypath
269 > +
270 > - self.mountmap[x] +" failed.")
271 > + warn("First attempt to unmount: " + target
272 > + " failed.")
273 > warn("Killing any pids still running in
274 > the chroot")
275 >
276 > self.kill_chroot_pids()
277 >
278 > - retval2 = os.system("umount " + mypath +
279 > self.mountmap[x])
280 > + retval2 = os.system("umount " + target)
281 > if retval2!=0:
282 > ouch=1
283 > - warn("Couldn't umount bind mount:
284 > " + mypath + self.mountmap[x])
285 > + warn("Couldn't umount bind mount:
286 > " + target)
287 >
288 > if "SNAPCACHE" in self.settings and x ==
289 > "/usr/portage":
290 > try:
291 > diff --git a/modules/stage1_target.py b/modules/stage1_target.py
292 > index aa43926..1e0d874 100644
293 > --- a/modules/stage1_target.py
294 > +++ b/modules/stage1_target.py
295 > @@ -88,8 +88,9 @@ class stage1_target(generic_stage_target):
296 > os.makedirs(self.settings["stage_path"]+"/proc")
297 >
298 > # alter the mount mappings to bind mount proc onto it
299 > - self.mounts.append("/tmp/stage1root/proc")
300 > - self.mountmap["/tmp/stage1root/proc"]="/proc"
301 > + self.mounts.append("stage1root/proc")
302 > + self.target_mounts["stage1root/proc"] =
303 > "/tmp/stage1root/proc"
304 > + self.mountmap["stage1root/proc"]="/proc"
305 >
306 > def register(foo):
307 > foo.update({"stage1":stage1_target})
308 > --
309 > 1.8.3.2
310 >
311 >
312 >

Replies