3 This class does all of the chroot setup, copying of files, etc. It is
4 the driver class for pretty much everything that Catalyst does.
7 import os,string,imp,types,shutil
8 from catalyst_support import *
9 from generic_target import *
12 class generic_stage_target(generic_target):
14 def __init__(self,myspec,addlargs):
15 self.required_values.extend(["version_stamp","target","subarch",\
16 "rel_type","profile","snapshot","source_subpath"])
18 self.valid_values.extend(["version_stamp","target","subarch",\
19 "rel_type","profile","snapshot","source_subpath","portage_confdir",\
20 "cflags","cxxflags","ldflags","cbuild","hostuse","portage_overlay",\
21 "distcc_hosts","makeopts","pkgcache_path","kerncache_path"])
23 self.set_valid_build_kernel_vars(addlargs)
24 generic_target.__init__(self,myspec,addlargs)
26 # The semantics of subarchmap and machinemap changed a bit in 2.0.3 to
27 # work better with vapier's CBUILD stuff. I've removed the "monolithic"
28 # machinemap from this file and split up its contents amongst the
29 # various arch/foo.py files.
31 # When register() is called on each module in the arch/ dir, it now
32 # returns a tuple instead of acting on the subarchmap dict that is
33 # passed to it. The tuple contains the values that were previously
34 # added to subarchmap as well as a new list of CHOSTs that go along
35 # with that arch. This allows us to build machinemap on the fly based
36 # on the keys in subarchmap and the values of the 2nd list returned
39 # Also, after talking with vapier. I have a slightly better idea of what
40 # certain variables are used for and what they should be set to. Neither
41 # 'buildarch' or 'hostarch' are used directly, so their value doesn't
42 # really matter. They are just compared to determine if we are
43 # cross-compiling. Because of this, they are just set to the name of the
44 # module in arch/ that the subarch is part of to make things simpler.
45 # The entire build process is still based off of 'subarch' like it was
46 # previously. -agaffney
51 for x in [x[:-3] for x in os.listdir(self.settings["sharedir"]+"/arch/") if x.endswith(".py")]:
53 fh=open(self.settings["sharedir"]+"/arch/"+x+".py")
54 # This next line loads the plugin as a module and assigns it to
56 self.archmap[x]=imp.load_module(x,fh,"arch/"+x+".py",(".py","r",imp.PY_SOURCE))
57 # This next line registers all the subarches supported in the
59 tmpsubarchmap, tmpmachinemap = self.archmap[x].register()
60 self.subarchmap.update(tmpsubarchmap)
61 for machine in tmpmachinemap:
62 machinemap[machine] = x
63 for subarch in tmpsubarchmap:
64 machinemap[subarch] = x
67 # This message should probably change a bit, since everything in the dir should
68 # load just fine. If it doesn't, it's probably a syntax error in the module
69 msg("Can't find "+x+".py plugin in "+self.settings["sharedir"]+"/arch/")
71 if self.settings.has_key("chost"):
72 hostmachine = self.settings["chost"].split("-")[0]
73 if not machinemap.has_key(hostmachine):
74 raise CatalystError, "Unknown host machine type "+hostmachine
75 self.settings["hostarch"] = machinemap[hostmachine]
77 hostmachine = self.settings["subarch"]
78 if machinemap.has_key(hostmachine):
79 hostmachine = machinemap[hostmachine]
80 self.settings["hostarch"] = hostmachine
81 if self.settings.has_key("cbuild"):
82 buildmachine = self.settings["cbuild"].split("-")[0]
84 buildmachine = os.uname()[4]
85 if not machinemap.has_key(buildmachine):
86 raise CatalystError, "Unknown build machine type "+buildmachine
87 self.settings["buildarch"] = machinemap[buildmachine]
88 self.settings["crosscompile"] = (self.settings["hostarch"] != self.settings["buildarch"])
90 # Call arch constructor, pass our settings
92 self.arch=self.subarchmap[self.settings["subarch"]](self.settings)
94 print "Invalid subarch: "+self.settings["subarch"]
95 print "Choose one of the following:",
96 for x in self.subarchmap:
101 print "Using target:",self.settings["target"]
102 # print a nice informational message:
103 if self.settings["buildarch"]==self.settings["hostarch"]:
104 print "Building natively for",self.settings["hostarch"]
105 elif self.settings["crosscompile"]:
106 print "Cross-compiling on",self.settings["buildarch"],"for different machine type",\
107 self.settings["hostarch"]
109 print "Building on",self.settings["buildarch"],"for alternate personality type",\
110 self.settings["hostarch"]
112 # This should be first to be set as other set_ options depend on this
113 self.set_spec_prefix()
115 # define all of our core variables
116 self.set_target_profile()
117 self.set_target_subpath()
118 self.set_source_subpath()
121 self.set_snapshot_path()
123 self.set_source_path()
124 self.set_snapcache_path()
125 self.set_chroot_path()
126 self.set_autoresume_path()
128 self.set_stage_path()
129 self.set_target_path()
131 self.set_controller_file()
132 self.set_action_sequence()
134 self.set_cleanables()
135 self.set_iso_volume_id()
136 self.set_build_kernel_vars()
138 self.set_archscript()
140 self.set_install_mask()
151 self.set_portage_overlay()
152 self.set_root_overlay()
154 # This next line checks to make sure that the specified variables exist
157 file_locate(self.settings,["source_path","snapshot_path","distdir"],expand=0)
158 # If we are using portage_confdir, check that as well.
159 if self.settings.has_key("portage_confdir"):
160 file_locate(self.settings,["portage_confdir"],expand=0)
162 # setup our mount points
163 if self.settings.has_key("SNAPCACHE"):
164 self.mounts=[ "/proc","/dev","/usr/portage","/usr/portage/distfiles" ]
165 self.mountmap={"/proc":"/proc", "/dev":"/dev", "/dev/pts":"/dev/pts",\
166 "/usr/portage":self.settings["snapshot_cache_path"]+"/portage",\
167 "/usr/portage/distfiles":self.settings["distdir"]}
169 self.mounts=[ "/proc","/dev","/usr/portage/distfiles" ]
170 self.mountmap={"/proc":"/proc", "/dev":"/dev", "/dev/pts":"/dev/pts",\
171 "/usr/portage/distfiles":self.settings["distdir"]}
172 if os.uname()[0] == "Linux":
173 self.mounts.append("/dev/pts")
177 # Configure any user specified options (either in catalyst.conf or on
179 if self.settings.has_key("PKGCACHE"):
180 self.set_pkgcache_path()
181 print "Location of the package cache is " + self.settings["pkgcache_path"]
182 self.mounts.append("/usr/portage/packages")
183 self.mountmap["/usr/portage/packages"]=self.settings["pkgcache_path"]
185 if self.settings.has_key("KERNCACHE"):
186 self.set_kerncache_path()
187 print "Location of the kerncache is " + self.settings["kerncache_path"]
188 self.mounts.append("/tmp/kerncache")
189 self.mountmap["/tmp/kerncache"]=self.settings["kerncache_path"]
191 if self.settings.has_key("CCACHE"):
192 if os.environ.has_key("CCACHE_DIR"):
193 ccdir=os.environ["CCACHE_DIR"]
194 del os.environ["CCACHE_DIR"]
196 ccdir="/root/.ccache"
197 if not os.path.isdir(ccdir):
198 raise CatalystError,\
199 "Compiler cache support can't be enabled (can't find "+ccdir+")"
200 self.mounts.append("/var/tmp/ccache")
201 self.mountmap["/var/tmp/ccache"]=ccdir
203 self.env["CCACHE_DIR"]="/var/tmp/ccache"
205 if self.settings.has_key("ICECREAM"):
206 self.mounts.append("/var/cache/icecream")
207 self.mountmap["/var/cache/icecream"]="/var/cache/icecream"
208 self.env["PATH"]="/usr/lib/icecc/bin:"+self.env["PATH"]
210 def override_cbuild(self):
211 if self.makeconf.has_key("CBUILD"):
212 self.settings["CBUILD"]=self.makeconf["CBUILD"]
214 def override_chost(self):
215 if self.makeconf.has_key("CHOST"):
216 self.settings["CHOST"]=self.makeconf["CHOST"]
218 def override_cflags(self):
219 if self.makeconf.has_key("CFLAGS"):
220 self.settings["CFLAGS"]=self.makeconf["CFLAGS"]
222 def override_cxxflags(self):
223 if self.makeconf.has_key("CXXFLAGS"):
224 self.settings["CXXFLAGS"]=self.makeconf["CXXFLAGS"]
226 def override_ldflags(self):
227 if self.makeconf.has_key("LDFLAGS"):
228 self.settings["LDFLAGS"]=self.makeconf["LDFLAGS"]
230 def set_install_mask(self):
231 if self.settings.has_key("install_mask"):
232 if type(self.settings["install_mask"]) != types.StringType:
233 self.settings["install_mask"]=string.join(self.settings["install_mask"])
235 def set_spec_prefix(self):
236 self.settings["spec_prefix"]=self.settings["target"]
238 def set_target_profile(self):
239 self.settings["target_profile"]=self.settings["profile"]
241 def set_target_subpath(self):
242 self.settings["target_subpath"]=self.settings["rel_type"]+"/"+self.settings["target"]+\
243 "-"+self.settings["subarch"]+"-"+self.settings["version_stamp"]
245 def set_source_subpath(self):
246 if type(self.settings["source_subpath"]) != types.StringType:
247 raise CatalystError, "source_subpath should have been a string. Perhaps you have something wrong in your spec file?"
249 def set_pkgcache_path(self):
250 if self.settings.has_key("pkgcache_path"):
251 if type(self.settings["pkgcache_path"]) != types.StringType:
252 self.settings["pkgcache_path"]=normpath(string.join(self.settings["pkgcache_path"]))
254 self.settings["pkgcache_path"]=normpath(self.settings["storedir"]+"/packages/"+\
255 self.settings["target_subpath"]+"/")
257 def set_kerncache_path(self):
258 if self.settings.has_key("kerncache_path"):
259 if type(self.settings["kerncache_path"]) != types.StringType:
260 self.settings["kerncache_path"]=normpath(string.join(self.settings["kerncache_path"]))
262 self.settings["kerncache_path"]=normpath(self.settings["storedir"]+"/kerncache/"+\
263 self.settings["target_subpath"]+"/")
265 def set_target_path(self):
266 self.settings["target_path"]=normpath(self.settings["storedir"]+"/builds/"+\
267 self.settings["target_subpath"]+".tar.bz2")
268 if self.settings.has_key("AUTORESUME") \
269 and os.path.exists(self.settings["autoresume_path"]+"setup_target_path"):
270 print "Resume point detected, skipping target path setup operation..."
272 # first clean up any existing target stuff
273 if os.path.isfile(self.settings["target_path"]):
274 cmd("rm -f "+self.settings["target_path"], \
275 "Could not remove existing file: "+self.settings["target_path"],env=self.env)
276 touch(self.settings["autoresume_path"]+"setup_target_path")
278 if not os.path.exists(self.settings["storedir"]+"/builds/"):
279 os.makedirs(self.settings["storedir"]+"/builds/")
281 def set_archscript(self):
282 if self.settings.has_key(self.settings["spec_prefix"]+"/archscript"):
283 print "\nWarning!!! "
284 print "\t"+self.settings["spec_prefix"]+"/archscript" + " is deprecated and no longer used.\n"
285 def set_runscript(self):
286 if self.settings.has_key(self.settings["spec_prefix"]+"/runscript"):
287 print "\nWarning!!! "
288 print "\t"+self.settings["spec_prefix"]+"/runscript" + " is deprecated and no longer used.\n"
290 def set_fsscript(self):
291 if self.settings.has_key(self.settings["spec_prefix"]+"/fsscript"):
292 self.settings["fsscript"]=self.settings[self.settings["spec_prefix"]+"/fsscript"]
293 del self.settings[self.settings["spec_prefix"]+"/fsscript"]
296 if self.settings.has_key(self.settings["spec_prefix"]+"/rcadd"):
297 self.settings["rcadd"]=self.settings[self.settings["spec_prefix"]+"/rcadd"]
298 del self.settings[self.settings["spec_prefix"]+"/rcadd"]
301 if self.settings.has_key(self.settings["spec_prefix"]+"/rcdel"):
302 self.settings["rcdel"]=self.settings[self.settings["spec_prefix"]+"/rcdel"]
303 del self.settings[self.settings["spec_prefix"]+"/rcdel"]
306 if self.settings.has_key(self.settings["spec_prefix"]+"/cdtar"):
307 self.settings["cdtar"]=normpath(self.settings[self.settings["spec_prefix"]+"/cdtar"])
308 del self.settings[self.settings["spec_prefix"]+"/cdtar"]
311 if self.settings.has_key(self.settings["spec_prefix"]+"/iso"):
312 self.settings["iso"]=normpath(self.settings[self.settings["spec_prefix"]+"/iso"])
313 del self.settings[self.settings["spec_prefix"]+"/iso"]
315 def set_fstype(self):
316 if self.settings.has_key(self.settings["spec_prefix"]+"/cdfstype"):
317 print "\nWarning!!! "
318 print self.settings["spec_prefix"]+"/cdfstype" + " is deprecated and may be removed."
319 print "\tUse "+self.settings["spec_prefix"]+"/fstype" + " instead."
320 print "\tConverting to "+self.settings["spec_prefix"]+"/fstype" + " internally."
321 print "\tContinuing ....\n"
322 self.settings["fstype"]=self.settings[self.settings["spec_prefix"]+"/cdfstype"]
323 del self.settings[self.settings["spec_prefix"]+"/cdfstype"]
325 if self.settings.has_key(self.settings["spec_prefix"]+"/fstype"):
326 self.settings["fstype"]=self.settings[self.settings["spec_prefix"]+"/fstype"]
327 del self.settings[self.settings["spec_prefix"]+"/fstype"]
329 if not self.settings.has_key("fstype"):
330 self.settings["fstype"]="normal"
331 for x in self.valid_values:
332 if x == self.settings["spec_prefix"]+"/fstype" or x == self.settings["spec_prefix"]+"/cdfstype":
333 print "\n"+self.settings["spec_prefix"]+"/fstype is being set to the default of \"normal\"\n"
336 if self.settings.has_key("fstype"):
337 self.valid_values.append("fsops")
338 if self.settings.has_key(self.settings["spec_prefix"]+"/fsops"):
339 self.settings["fsops"]=self.settings[self.settings["spec_prefix"]+"/fsops"]
340 del self.settings[self.settings["spec_prefix"]+"/fsops"]
342 def set_source_path(self):
343 if self.settings.has_key("SEEDCACHE") and os.path.isdir(normpath(self.settings["storedir"]+"/tmp/"+self.settings["source_subpath"]+"/")):
344 self.settings["source_path"]=normpath(self.settings["storedir"]+"/tmp/"+self.settings["source_subpath"]+"/")
346 self.settings["source_path"]=normpath(self.settings["storedir"]+"/builds/"+self.settings["source_subpath"]+".tar.bz2")
347 if os.path.isfile(self.settings["source_path"]):
348 if os.path.exists(self.settings["source_path"]): # XXX: Is this even necessary if the previous check passes?
349 self.settings["source_path_hash"]=generate_hash(self.settings["source_path"],\
350 hash_function=self.settings["hash_function"],verbose=False)
351 print "Source path set to "+self.settings["source_path"]
352 if os.path.isdir(self.settings["source_path"]):
353 print "\tIf this is not desired, remove this directory or turn off seedcache in the options of catalyst.conf"
354 print "\tthe source path will then be "+normpath(self.settings["storedir"]+"/builds/"+self.settings["source_subpath"]+".tar.bz2\n")
356 def set_dest_path(self):
357 if self.settings.has_key("root_path"):
358 self.settings["destpath"]=normpath(self.settings["chroot_path"]+self.settings["root_path"])
360 self.settings["destpath"]=normpath(self.settings["chroot_path"])
362 def set_cleanables(self):
363 self.settings["cleanables"]=["/etc/resolv.conf","/var/tmp/*","/tmp/*","/root/*",\
366 def set_snapshot_path(self):
367 self.settings["snapshot_path"]=normpath(self.settings["storedir"]+"/snapshots/portage-"+self.settings["snapshot"]+".tar.bz2")
369 if os.path.exists(self.settings["snapshot_path"]):
370 self.settings["snapshot_path_hash"]=generate_hash(self.settings["snapshot_path"],\
371 hash_function=self.settings["hash_function"],verbose=False)
373 def set_snapcache_path(self):
374 if self.settings.has_key("SNAPCACHE"):
375 self.settings["snapshot_cache_path"]=normpath(self.settings["snapshot_cache"]+"/"+self.settings["snapshot"]+"/")
376 self.snapcache_lock=catalyst_lock.LockDir(self.settings["snapshot_cache_path"])
377 print "Caching snapshot to " + self.settings["snapshot_cache_path"]
379 def set_chroot_path(self):
380 # Note the trailing slash is very important and things would break without it
381 self.settings["chroot_path"]=normpath(self.settings["storedir"]+"/tmp/"+self.settings["target_subpath"]+"/")
382 self.chroot_lock=catalyst_lock.LockDir(self.settings["chroot_path"])
384 def set_autoresume_path(self):
385 self.settings["autoresume_path"]=normpath(self.settings["storedir"]+"/tmp/"+\
386 self.settings["rel_type"]+"/"+".autoresume-"+self.settings["target"]+\
387 "-"+self.settings["subarch"]+"-"+self.settings["version_stamp"]+"/")
388 if self.settings.has_key("AUTORESUME"):
389 print "The autoresume path is " + self.settings["autoresume_path"]
390 if not os.path.exists(self.settings["autoresume_path"]):
391 os.makedirs(self.settings["autoresume_path"],0755)
393 def set_controller_file(self):
394 self.settings["controller_file"]=normpath(self.settings["sharedir"]+"/targets/"+self.settings["target"]+"/"+self.settings["target"]+"-controller.sh")
396 def set_iso_volume_id(self):
397 if self.settings.has_key(self.settings["spec_prefix"]+"/volid"):
398 self.settings["iso_volume_id"] = self.settings[self.settings["spec_prefix"]+"/volid"]
399 if len(self.settings["iso_volume_id"])>32:
400 raise CatalystError,"ISO VOLUME ID: volid must not exceed 32 characters."
402 self.settings["iso_volume_id"] = "catalyst " + self.settings["snapshot"]
404 def set_action_sequence(self):
405 # Default action sequence for run method
406 self.settings["action_sequence"]=["unpack","unpack_snapshot",\
407 "config_profile_link","setup_confdir","portage_overlay",\
408 "base_dirs","bind","chroot_setup","setup_environment",\
409 "run_local","preclean","unbind","clean"]
410 # if self.settings.has_key("TARBALL") or \
411 # not self.settings.has_key("FETCH"):
412 if not self.settings.has_key("FETCH"):
413 self.settings["action_sequence"].append("capture")
414 self.settings["action_sequence"].append("clear_autoresume")
417 if self.settings.has_key(self.settings["spec_prefix"]+"/use"):
418 self.settings["use"]=self.settings[self.settings["spec_prefix"]+"/use"]
419 del self.settings[self.settings["spec_prefix"]+"/use"]
420 if self.settings.has_key("use"):
421 if type(self.settings["use"])==types.StringType:
422 self.settings["use"]=self.settings["use"].split()
423 self.settings["use"].append("bindist")
425 def set_stage_path(self):
426 self.settings["stage_path"]=normpath(self.settings["chroot_path"])
428 def set_mounts(self):
431 def set_packages(self):
435 if self.settings.has_key(self.settings["spec_prefix"]+"/rm"):
436 if type(self.settings[self.settings["spec_prefix"]+"/rm"])==types.StringType:
437 self.settings[self.settings["spec_prefix"]+"/rm"]=self.settings[self.settings["spec_prefix"]+"/rm"].split()
439 def set_linuxrc(self):
440 if self.settings.has_key(self.settings["spec_prefix"]+"/linuxrc"):
441 if type(self.settings[self.settings["spec_prefix"]+"/linuxrc"])==types.StringType:
442 self.settings["linuxrc"]=self.settings[self.settings["spec_prefix"]+"/linuxrc"]
443 del self.settings[self.settings["spec_prefix"]+"/linuxrc"]
445 def set_portage_overlay(self):
446 if self.settings.has_key("portage_overlay"):
447 if type(self.settings["portage_overlay"])==types.StringType:
448 self.settings["portage_overlay"]=self.settings["portage_overlay"].split()
449 print "portage_overlay directories are set to: \"" + string.join(self.settings["portage_overlay"])+"\""
451 def set_overlay(self):
452 if self.settings.has_key(self.settings["spec_prefix"]+"/overlay"):
453 if type(self.settings[self.settings["spec_prefix"]+"/overlay"])==types.StringType:
454 self.settings[self.settings["spec_prefix"]+"/overlay"]=self.settings[self.settings["spec_prefix"]+"/overlay"].split()
456 def set_root_overlay(self):
457 if self.settings.has_key(self.settings["spec_prefix"]+"/root_overlay"):
458 if type(self.settings[self.settings["spec_prefix"]+"/root_overlay"])==types.StringType:
459 self.settings[self.settings["spec_prefix"]+"/root_overlay"]=self.settings[self.settings["spec_prefix"]+"/root_overlay"].split()
462 def set_root_path(self):
463 # ROOT= variable for emerges
464 self.settings["root_path"]="/"
466 def set_valid_build_kernel_vars(self,addlargs):
467 if addlargs.has_key("boot/kernel"):
468 if type(addlargs["boot/kernel"]) == types.StringType:
469 loopy=[addlargs["boot/kernel"]]
471 loopy=addlargs["boot/kernel"]
474 self.required_values.append("boot/kernel/"+x+"/sources")
475 self.required_values.append("boot/kernel/"+x+"/config")
476 self.valid_values.append("boot/kernel/"+x+"/aliases")
477 self.valid_values.append("boot/kernel/"+x+"/extraversion")
478 self.valid_values.append("boot/kernel/"+x+"/packages")
479 if addlargs.has_key("boot/kernel/"+x+"/packages"):
480 if type(addlargs["boot/kernel/"+x+"/packages"]) == types.StringType:
481 addlargs["boot/kernel/"+x+"/packages"]=[addlargs["boot/kernel/"+x+"/packages"]]
482 self.valid_values.append("boot/kernel/"+x+"/use")
483 self.valid_values.append("boot/kernel/"+x+"/gk_kernargs")
484 self.valid_values.append("boot/kernel/"+x+"/gk_action")
485 self.valid_values.append("boot/kernel/"+x+"/initramfs_overlay")
486 self.valid_values.append("boot/kernel/"+x+"/softlevel")
487 self.valid_values.append("boot/kernel/"+x+"/console")
488 self.valid_values.append("boot/kernel/"+x+"/machine_type")
489 self.valid_values.append("boot/kernel/"+x+"/postconf")
490 if addlargs.has_key("boot/kernel/"+x+"/postconf"):
491 print "boot/kernel/"+x+"/postconf is deprecated"
492 print "\tInternally moving these ebuilds to boot/kernel/"+x+"/packages"
493 print "\tPlease move them to boot/kernel/"+x+"/packages in your specfile"
494 if type(addlargs["boot/kernel/"+x+"/postconf"]) == types.StringType:
495 loop2=[addlargs["boot/kernel/"+x+"/postconf"]]
497 loop2=addlargs["boot/kernel/"+x+"/postconf"]
500 if not addlargs.has_key("boot/kernel/"+x+"/packages"):
501 addlargs["boot/kernel/"+x+"/packages"]=[y]
503 addlargs["boot/kernel/"+x+"/packages"].append(y)
505 def set_build_kernel_vars(self):
506 if self.settings.has_key(self.settings["spec_prefix"]+"/devmanager"):
507 self.settings["devmanager"]=self.settings[self.settings["spec_prefix"]+"/devmanager"]
508 del self.settings[self.settings["spec_prefix"]+"/devmanager"]
510 if self.settings.has_key(self.settings["spec_prefix"]+"/splashtype"):
511 self.settings["splashtype"]=self.settings[self.settings["spec_prefix"]+"/splashtype"]
512 del self.settings[self.settings["spec_prefix"]+"/splashtype"]
514 if self.settings.has_key(self.settings["spec_prefix"]+"/gk_mainargs"):
515 self.settings["gk_mainargs"]=self.settings[self.settings["spec_prefix"]+"/gk_mainargs"]
516 del self.settings[self.settings["spec_prefix"]+"/gk_mainargs"]
518 def kill_chroot_pids(self):
519 print "Checking for processes running in chroot and killing them."
521 # Force environment variables to be exported so script can see them
522 self.setup_environment()
524 if os.path.exists(self.settings["sharedir"]+"/targets/support/kill-chroot-pids.sh"):
525 cmd("/bin/bash "+self.settings["sharedir"]+"/targets/support/kill-chroot-pids.sh",\
526 "kill-chroot-pids script failed.",env=self.env)
528 def mount_safety_check(self):
529 mypath=self.settings["chroot_path"]
532 check and verify that none of our paths in mypath are mounted. We don't want to clean
533 up with things still mounted, and this allows us to check.
534 returns 1 on ok, 0 on "something is still mounted" case.
536 if not os.path.exists(mypath):
539 for x in self.mounts:
540 if not os.path.exists(mypath+x):
543 if ismount(mypath+x):
544 #something is still mounted
546 print x+" is still mounted; performing auto-bind-umount...",
547 # try to umount stuff ourselves
549 if ismount(mypath+x):
550 raise CatalystError, "Auto-unbind failed for "+x
553 print "Auto-unbind successful..."
555 except CatalystError:
556 raise CatalystError, "Unable to auto-unbind "+x
561 clst_unpack_hash=read_from_clst(self.settings["autoresume_path"]+"unpack")
563 if self.settings.has_key("SEEDCACHE"):
564 if os.path.isdir(self.settings["source_path"]):
565 # SEEDCACHE Is a directory, use Rsync
566 unpack_cmd="rsync -a --delete "+self.settings["source_path"]+" "+self.settings["chroot_path"]
567 display_msg="\nStarting rsync from "+self.settings["source_path"]+"\nto "+\
568 self.settings["chroot_path"]+" (This may take some time) ...\n"
569 error_msg="Rsync of "+self.settings["source_path"]+" to "+self.settings["chroot_path"]+" failed."
571 # SEEDCACHE is a not a directory, try untar'ing
572 print "Referenced SEEDCACHE does not appear to be a directory, trying to untar..."
573 display_msg="\nStarting tar extract from "+self.settings["source_path"]+"\nto "+\
574 self.settings["chroot_path"]+" (This may take some time) ...\n"
575 unpack_cmd="tar xjpf "+self.settings["source_path"]+" -C "+self.settings["chroot_path"]
576 error_msg="Tarball extraction of "+self.settings["source_path"]+" to "+self.settings["chroot_path"]+" failed."
578 # No SEEDCACHE, use tar
579 display_msg="\nStarting tar extract from "+self.settings["source_path"]+"\nto "+\
580 self.settings["chroot_path"]+" (This may take some time) ...\n"
581 unpack_cmd="tar xjpf "+self.settings["source_path"]+" -C "+self.settings["chroot_path"]
582 error_msg="Tarball extraction of "+self.settings["source_path"]+" to "+self.settings["chroot_path"]+" failed."
585 if self.settings.has_key("AUTORESUME"):
586 # Autoresume is Valid, SeedCache is Valid
587 if os.path.isdir(self.settings["source_path"]) and os.path.exists(self.settings["autoresume_path"]+"unpack"):
589 invalid_snapshot=False
591 # Autoresume is Valid, Tarball is Valid
592 elif os.path.isfile(self.settings["source_path"]) and self.settings["source_path_hash"] == clst_unpack_hash:
594 invalid_snapshot=True
596 # Autoresume is InValid, SeedCache
597 elif os.path.isdir(self.settings["source_path"]) and not os.path.exists(self.settings["autoresume_path"]+"unpack"):
599 invalid_snapshot=False
601 # Autoresume is InValid, Tarball
602 elif os.path.isfile(self.settings["source_path"]) and self.settings["source_path_hash"] != clst_unpack_hash:
604 invalid_snapshot=True
606 # No Autoresume,SeedCache
607 if self.settings.has_key("SEEDCACHE"):
609 # Seed cache so lets run rsync and rsync can clean up extra junk
610 if os.path.isdir(self.settings["source_path"]):
612 invalid_snapshot=False
614 # Tarball so we better unpack and remove anything already there
615 elif os.path.isfile(self.settings["source_path"]):
617 invalid_snapshot=True
619 # No Autoresume,No SeedCache
622 # Tarball so we better unpack and remove anything already there
623 if os.path.isfile(self.settings["source_path"]):
625 invalid_snapshot=True
626 # Should never reach this if so something is very wrong
627 elif os.path.isdir(self.settings["source_path"]):
628 raise CatalystError,"source path is a dir but seedcache is not enabled"
631 self.mount_safety_check()
634 if self.settings.has_key("AUTORESUME"):
635 print "No Valid Resume point detected, cleaning up ..."
637 self.clear_autoresume()
640 if not os.path.exists(self.settings["chroot_path"]):
641 os.makedirs(self.settings["chroot_path"])
643 if not os.path.exists(self.settings["chroot_path"]+"/tmp"):
644 os.makedirs(self.settings["chroot_path"]+"/tmp",1777)
646 if self.settings.has_key("PKGCACHE"):
647 if not os.path.exists(self.settings["pkgcache_path"]):
648 os.makedirs(self.settings["pkgcache_path"],0755)
650 if self.settings.has_key("KERNCACHE"):
651 if not os.path.exists(self.settings["kerncache_path"]):
652 os.makedirs(self.settings["kerncache_path"],0755)
655 cmd(unpack_cmd,error_msg,env=self.env)
657 if self.settings.has_key("source_path_hash"):
658 myf=open(self.settings["autoresume_path"]+"unpack","w")
659 myf.write(self.settings["source_path_hash"])
662 touch(self.settings["autoresume_path"]+"unpack")
664 print "Resume point detected, skipping unpack operation..."
667 def unpack_snapshot(self):
669 snapshot_hash=read_from_clst(self.settings["autoresume_path"]+"unpack_portage")
671 if self.settings.has_key("SNAPCACHE"):
672 snapshot_cache_hash=read_from_clst(self.settings["snapshot_cache_path"]+"catalyst-hash")
673 destdir=self.settings["snapshot_cache_path"]
674 unpack_cmd="tar xjpf "+self.settings["snapshot_path"]+" -C "+destdir
675 unpack_errmsg="Error unpacking snapshot"
676 cleanup_msg="Cleaning up invalid snapshot cache at \n\t"+self.settings["snapshot_cache_path"]+" (This can take a long time)..."
677 cleanup_errmsg="Error removing existing snapshot cache directory."
678 self.snapshot_lock_object=self.snapcache_lock
680 if self.settings["snapshot_path_hash"] == snapshot_cache_hash:
681 print "Valid snapshot cache, skipping unpack of portage tree ..."
685 destdir=normpath(self.settings["chroot_path"]+"/usr/portage")
686 cleanup_errmsg="Error removing existing snapshot directory."
687 cleanup_msg="Cleaning up existing portage tree (This can take a long time) ..."
688 unpack_cmd="tar xjpf "+self.settings["snapshot_path"]+" -C "+self.settings["chroot_path"]+"/usr"
689 unpack_errmsg="Error unpacking snapshot"
691 if self.settings.has_key("AUTORESUME") \
692 and os.path.exists(self.settings["chroot_path"]+"/usr/portage/") \
693 and os.path.exists(self.settings["autoresume_path"]+"unpack_portage") \
694 and self.settings["snapshot_path_hash"] == snapshot_hash:
695 print "Valid Resume point detected, skipping unpack of portage tree..."
701 if self.settings.has_key("SNAPCACHE"):
702 self.snapshot_lock_object.write_lock()
703 if os.path.exists(destdir):
705 cleanup_cmd="rm -rf "+destdir
706 cmd(cleanup_cmd,cleanup_errmsg,env=self.env)
707 if not os.path.exists(destdir):
708 os.makedirs(destdir,0755)
710 print "Unpacking portage tree (This can take a long time) ..."
711 cmd(unpack_cmd,unpack_errmsg,env=self.env)
713 if self.settings.has_key("SNAPCACHE"):
714 myf=open(self.settings["snapshot_cache_path"]+"catalyst-hash","w")
715 myf.write(self.settings["snapshot_path_hash"])
719 print "Setting snapshot autoresume point"
720 myf=open(self.settings["autoresume_path"]+"unpack_portage","w")
721 myf.write(self.settings["snapshot_path_hash"])
724 if self.settings.has_key("SNAPCACHE"):
725 self.snapshot_lock_object.unlock()
727 def config_profile_link(self):
728 if self.settings.has_key("AUTORESUME") \
729 and os.path.exists(self.settings["autoresume_path"]+"config_profile_link"):
730 print "Resume point detected, skipping config_profile_link operation..."
732 print "Configuring profile link..."
733 cmd("rm -f "+self.settings["chroot_path"]+"/etc/make.profile",\
734 "Error zapping profile link",env=self.env)
735 cmd("ln -sf ../usr/portage/profiles/"+self.settings["target_profile"]+\
736 " "+self.settings["chroot_path"]+"/etc/make.profile","Error creating profile link",env=self.env)
737 touch(self.settings["autoresume_path"]+"config_profile_link")
739 def setup_confdir(self):
740 if self.settings.has_key("AUTORESUME") \
741 and os.path.exists(self.settings["autoresume_path"]+"setup_confdir"):
742 print "Resume point detected, skipping setup_confdir operation..."
744 if self.settings.has_key("portage_confdir"):
745 print "Configuring /etc/portage..."
746 cmd("rm -rf "+self.settings["chroot_path"]+"/etc/portage","Error zapping /etc/portage",env=self.env)
747 cmd("cp -R "+self.settings["portage_confdir"]+"/ "+self.settings["chroot_path"]+\
748 "/etc/portage","Error copying /etc/portage",env=self.env)
749 touch(self.settings["autoresume_path"]+"setup_confdir")
751 def portage_overlay(self):
752 # Here, we copy the contents of our overlays to /usr/local/portage. We
753 # always copy over the overlays in case it has changed.
754 if self.settings.has_key("portage_overlay"):
755 for x in self.settings["portage_overlay"]:
756 if os.path.exists(x):
757 print "Copying overlay dir " +x
758 cmd("mkdir -p "+self.settings["chroot_path"]+"/usr/local/portage","Could not make portage_overlay dir",env=self.env)
759 cmd("cp -R "+x+"/* "+self.settings["chroot_path"]+"/usr/local/portage","Could not copy portage_overlay",env=self.env)
761 def root_overlay(self):
762 # copy over the root_overlay
763 # Always copy over the overlay incase it has changed
764 if self.settings.has_key(self.settings["spec_prefix"]+"/root_overlay"):
765 for x in self.settings[self.settings["spec_prefix"]+"/root_overlay"]:
766 if os.path.exists(x):
767 print "Copying root_overlay: "+x
768 cmd("rsync -a "+x+"/ "+\
769 self.settings["chroot_path"], self.settings["spec_prefix"]+"/root_overlay: "+x+" copy failed.",env=self.env)
775 for x in self.mounts:
776 if not os.path.exists(self.settings["chroot_path"]+x):
777 os.makedirs(self.settings["chroot_path"]+x,0755)
779 if not os.path.exists(self.mountmap[x]):
780 os.makedirs(self.mountmap[x],0755)
783 if self.settings.has_key("SNAPCACHE") and x == "/usr/portage":
784 self.snapshot_lock_object.read_lock()
785 if os.uname()[0] == "FreeBSD":
787 retval=os.system("mount -t devfs none "+self.settings["chroot_path"]+x)
789 retval=os.system("mount_nullfs "+src+" "+self.settings["chroot_path"]+x)
791 retval=os.system("mount --bind "+src+" "+self.settings["chroot_path"]+x)
794 raise CatalystError,"Couldn't bind mount "+src
799 mypath=self.settings["chroot_path"]
800 myrevmounts=self.mounts[:]
801 myrevmounts.reverse()
802 # unmount in reverse order for nested bind-mounts
803 for x in myrevmounts:
804 if not os.path.exists(mypath+x):
807 if not ismount(mypath+x):
808 # it's not mounted, continue
811 retval=os.system("umount "+os.path.join(mypath,x.lstrip(os.path.sep)))
814 warn("First attempt to unmount: "+mypath+x+" failed.")
815 warn("Killing any pids still running in the chroot")
817 self.kill_chroot_pids()
819 retval2=os.system("umount "+mypath+x)
822 warn("Couldn't umount bind mount: "+mypath+x)
823 # keep trying to umount the others, to minimize damage if developer makes a mistake
825 if self.settings.has_key("SNAPCACHE") and x == "/usr/portage":
827 # Its possible the snapshot lock object isnt created yet
828 # this is because mount safety check calls unbind before the target is fully initialized
829 self.snapshot_lock_object.unlock()
834 if any bind mounts really failed, then we need to raise
835 this to potentially prevent an upcoming bash stage cleanup script
836 from wiping our bind mounts.
838 raise CatalystError,"Couldn't umount one or more bind-mounts; aborting for safety."
840 def chroot_setup(self):
841 self.makeconf=read_makeconf(self.settings["chroot_path"]+"/etc/make.conf")
842 self.override_cbuild()
843 self.override_chost()
844 self.override_cflags()
845 self.override_cxxflags()
846 self.override_ldflags()
847 if self.settings.has_key("AUTORESUME") \
848 and os.path.exists(self.settings["autoresume_path"]+"chroot_setup"):
849 print "Resume point detected, skipping chroot_setup operation..."
851 print "Setting up chroot..."
853 #self.makeconf=read_makeconf(self.settings["chroot_path"]+"/etc/make.conf")
855 cmd("cp /etc/resolv.conf "+self.settings["chroot_path"]+"/etc",\
856 "Could not copy resolv.conf into place.",env=self.env)
858 # copy over the envscript, if applicable
859 if self.settings.has_key("ENVSCRIPT"):
860 if not os.path.exists(self.settings["ENVSCRIPT"]):
861 raise CatalystError, "Can't find envscript "+self.settings["ENVSCRIPT"]
863 print "\nWarning!!!!"
864 print "\tOverriding certain env variables may cause catastrophic failure."
865 print "\tIf your build fails look here first as the possible problem."
866 print "\tCatalyst assumes you know what you are doing when setting"
867 print "\t\tthese variables."
868 print "\tCatalyst Maintainers use VERY minimal envscripts if used at all"
869 print "\tYou have been warned\n"
871 cmd("cp "+self.settings["ENVSCRIPT"]+" "+self.settings["chroot_path"]+"/tmp/envscript",\
872 "Could not copy envscript into place.",env=self.env)
874 # Setup metadata_overlay
875 if self.settings.has_key("METADATA_OVERLAY") and not self.settings.has_key("portage_confdir"):
876 if not os.path.exists(self.settings["chroot_path"] + "/etc/portage"):
877 cmd("mkdir " + self.settings["chroot_path"] + "/etc/portage")
878 myf = open(self.settings["chroot_path"] + "/etc/portage/modules", "a")
879 myf.write("portdbapi.auxdbmodule = cache.metadata_overlay.database\n")
882 # Copy over /etc/hosts from the host in case there are any
883 # specialties in there
884 if os.path.exists(self.settings["chroot_path"]+"/etc/hosts"):
885 cmd("mv "+self.settings["chroot_path"]+"/etc/hosts "+self.settings["chroot_path"]+\
886 "/etc/hosts.bck", "Could not backup /etc/hosts",env=self.env)
887 cmd("cp /etc/hosts "+self.settings["chroot_path"]+"/etc/hosts", "Could not copy /etc/hosts",env=self.env)
888 #self.override_cbuild()
889 #self.override_chost()
890 #self.override_cflags()
891 #self.override_cxxflags()
892 #self.override_ldflags()
893 # Modify and write out make.conf (for the chroot)
894 cmd("rm -f "+self.settings["chroot_path"]+"/etc/make.conf","Could not remove "+self.settings["chroot_path"]+"/etc/make.conf",\
896 myf=open(self.settings["chroot_path"]+"/etc/make.conf","w")
897 myf.write("# These settings were set by the catalyst build script that automatically\n# built this stage.\n")
898 myf.write("# Please consult /etc/make.conf.example for a more detailed example.\n")
899 if self.settings.has_key("CFLAGS"):
900 myf.write('CFLAGS="'+self.settings["CFLAGS"]+'"\n')
901 if self.settings.has_key("CXXFLAGS"):
902 myf.write('CXXFLAGS="'+self.settings["CXXFLAGS"]+'"\n')
904 myf.write('CXXFLAGS="${CFLAGS}"\n')
906 if self.settings.has_key("LDFLAGS"):
907 myf.write('LDFLAGS="'+self.settings["LDFLAGS"]+'"\n')
908 myf.write("# This should not be changed unless you know exactly what you are doing. You\n# should probably be using a different stage, instead.\n")
909 if self.settings.has_key("CBUILD"):
910 myf.write('CBUILD="'+self.settings["CBUILD"]+'"\n')
911 myf.write('# WARNING: Changing your CHOST is not something that should be done lightly.\n# Please consult http://www.gentoo.org/doc/en/change-chost.xml before changing.\nCHOST="'+self.settings["CHOST"]+'"\n')
913 # Figure out what our USE vars are for building
915 if self.settings.has_key("HOSTUSE"):
916 myusevars.extend(self.settings["HOSTUSE"])
918 if self.settings.has_key("use"):
919 myusevars.extend(self.settings["use"])
922 myf.write('USE="'+string.join(myusevars)+'"\n')
924 # Setup the portage overlay
925 if self.settings.has_key("portage_overlay"):
926 # myf.write('PORTDIR_OVERLAY="'+string.join(self.settings["portage_overlay"])+'"\n')
927 myf.write('PORTDIR_OVERLAY="/usr/local/portage"\n')
930 touch(self.settings["autoresume_path"]+"chroot_setup")
933 if self.settings.has_key("AUTORESUME") \
934 and os.path.exists(self.settings["autoresume_path"]+"fsscript"):
935 print "Resume point detected, skipping fsscript operation..."
937 if self.settings.has_key("fsscript"):
938 if os.path.exists(self.settings["controller_file"]):
939 cmd("/bin/bash "+self.settings["controller_file"]+" fsscript","fsscript script failed.",env=self.env)
940 touch(self.settings["autoresume_path"]+"fsscript")
943 if self.settings.has_key("AUTORESUME") \
944 and os.path.exists(self.settings["autoresume_path"]+"rcupdate"):
945 print "Resume point detected, skipping rcupdate operation..."
947 if os.path.exists(self.settings["controller_file"]):
948 cmd("/bin/bash "+self.settings["controller_file"]+" rc-update","rc-update script failed.",env=self.env)
949 touch(self.settings["autoresume_path"]+"rcupdate")
952 if self.settings.has_key("AUTORESUME") \
953 and os.path.exists(self.settings["autoresume_path"]+"clean"):
954 print "Resume point detected, skipping clean operation..."
956 for x in self.settings["cleanables"]:
957 print "Cleaning chroot: "+x+"... "
958 cmd("rm -rf "+self.settings["destpath"]+x,"Couldn't clean "+x,env=self.env)
960 # put /etc/hosts back into place
961 if os.path.exists(self.settings["chroot_path"]+"/etc/hosts.bck"):
962 cmd("mv -f "+self.settings["chroot_path"]+"/etc/hosts.bck "+self.settings["chroot_path"]+"/etc/hosts", "Could not replace /etc/hosts",env=self.env)
965 if os.path.exists(self.settings["chroot_path"]+"/usr/local/portage"):
966 cmd("rm -rf "+self.settings["chroot_path"]+"/usr/local/portage", "Could not remove /usr/local/portage",env=self.env)
967 cmd("sed -i '/^PORTDIR_OVERLAY/d' "+self.settings["chroot_path"]+"/etc/make.conf", "Could not remove PORTDIR_OVERLAY from make.conf",env=self.env)
969 # clean up old and obsoleted files in /etc
970 if os.path.exists(self.settings["stage_path"]+"/etc"):
971 cmd("find "+self.settings["stage_path"]+"/etc -maxdepth 1 -name \"*-\" | xargs rm -f", "Could not remove stray files in /etc",env=self.env)
973 if os.path.exists(self.settings["controller_file"]):
974 cmd("/bin/bash "+self.settings["controller_file"]+" clean","clean script failed.",env=self.env)
975 touch(self.settings["autoresume_path"]+"clean")
978 if self.settings.has_key("AUTORESUME") \
979 and os.path.exists(self.settings["autoresume_path"]+"empty"):
980 print "Resume point detected, skipping empty operation..."
982 if self.settings.has_key(self.settings["spec_prefix"]+"/empty"):
983 if type(self.settings[self.settings["spec_prefix"]+"/empty"])==types.StringType:
984 self.settings[self.settings["spec_prefix"]+"/empty"]=self.settings[self.settings["spec_prefix"]+"/empty"].split()
985 for x in self.settings[self.settings["spec_prefix"]+"/empty"]:
986 myemp=self.settings["destpath"]+x
987 if not os.path.isdir(myemp):
988 print x,"not a directory or does not exist, skipping 'empty' operation."
990 print "Emptying directory",x
991 # stat the dir, delete the dir, recreate the dir and set
992 # the proper perms and ownership
993 mystat=os.stat(myemp)
995 os.makedirs(myemp,0755)
996 os.chown(myemp,mystat[ST_UID],mystat[ST_GID])
997 os.chmod(myemp,mystat[ST_MODE])
998 touch(self.settings["autoresume_path"]+"empty")
1001 if self.settings.has_key("AUTORESUME") \
1002 and os.path.exists(self.settings["autoresume_path"]+"remove"):
1003 print "Resume point detected, skipping remove operation..."
1005 if self.settings.has_key(self.settings["spec_prefix"]+"/rm"):
1006 for x in self.settings[self.settings["spec_prefix"]+"/rm"]:
1007 # we're going to shell out for all these cleaning operations,
1008 # so we get easy glob handling
1009 print "livecd: removing "+x
1010 os.system("rm -rf "+self.settings["chroot_path"]+x)
1012 if os.path.exists(self.settings["controller_file"]):
1013 cmd("/bin/bash "+self.settings["controller_file"]+" clean",\
1014 "Clean failed.",env=self.env)
1015 touch(self.settings["autoresume_path"]+"remove")
1022 if self.settings.has_key("AUTORESUME") \
1023 and os.path.exists(self.settings["autoresume_path"]+"preclean"):
1024 print "Resume point detected, skipping preclean operation..."
1027 if os.path.exists(self.settings["controller_file"]):
1028 cmd("/bin/bash "+self.settings["controller_file"]+" preclean","preclean script failed.",env=self.env)
1029 touch(self.settings["autoresume_path"]+"preclean")
1033 raise CatalystError, "Build failed, could not execute preclean"
1036 if self.settings.has_key("AUTORESUME") \
1037 and os.path.exists(self.settings["autoresume_path"]+"capture"):
1038 print "Resume point detected, skipping capture operation..."
1040 """capture target in a tarball"""
1041 mypath=self.settings["target_path"].split("/")
1042 # remove filename from path
1043 mypath=string.join(mypath[:-1],"/")
1045 # now make sure path exists
1046 if not os.path.exists(mypath):
1049 print "Creating stage tarball..."
1051 cmd("tar cjpf "+self.settings["target_path"]+" -C "+self.settings["stage_path"]+\
1052 " .","Couldn't create stage tarball",env=self.env)
1054 self.gen_contents_file(self.settings["target_path"])
1055 self.gen_digest_file(self.settings["target_path"])
1057 touch(self.settings["autoresume_path"]+"capture")
1059 def run_local(self):
1060 if self.settings.has_key("AUTORESUME") \
1061 and os.path.exists(self.settings["autoresume_path"]+"run_local"):
1062 print "Resume point detected, skipping run_local operation..."
1065 if os.path.exists(self.settings["controller_file"]):
1066 cmd("/bin/bash "+self.settings["controller_file"]+" run","run script failed.",env=self.env)
1067 touch(self.settings["autoresume_path"]+"run_local")
1069 except CatalystError:
1071 raise CatalystError,"Stage build aborting due to error."
1073 def setup_environment(self):
1074 # Modify the current environment. This is an ugly hack that should be
1075 # fixed. We need this to use the os.system() call since we can't
1076 # specify our own environ:
1077 for x in self.settings.keys():
1078 # sanitize var names by doing "s|/-.|_|g"
1079 varname="clst_"+string.replace(x,"/","_")
1080 varname=string.replace(varname,"-","_")
1081 varname=string.replace(varname,".","_")
1082 if type(self.settings[x])==types.StringType:
1083 # prefix to prevent namespace clashes:
1084 #os.environ[varname]=self.settings[x]
1085 self.env[varname]=self.settings[x]
1086 elif type(self.settings[x])==types.ListType:
1087 #os.environ[varname]=string.join(self.settings[x])
1088 self.env[varname]=string.join(self.settings[x])
1089 elif type(self.settings[x])==types.BooleanType:
1090 if self.settings[x]:
1091 self.env[varname]="true"
1093 self.env[varname]="false"
1094 if self.settings.has_key("makeopts"):
1095 self.env["MAKEOPTS"]=self.settings["makeopts"]
1098 self.chroot_lock.write_lock()
1100 # Kill any pids in the chroot
1101 self.kill_chroot_pids()
1103 # Check for mounts right away and abort if we cannot unmount them.
1104 self.mount_safety_check()
1106 if self.settings.has_key("CLEAR_AUTORESUME"):
1107 self.clear_autoresume()
1108 if self.settings.has_key("PURGE"):
1111 for x in self.settings["action_sequence"]:
1112 print "--- Running action sequence: "+x
1115 apply(getattr(self,x))
1117 self.mount_safety_check()
1120 self.chroot_lock.unlock()
1123 if self.settings.has_key("AUTORESUME") \
1124 and os.path.exists(self.settings["autoresume_path"]+"unmerge"):
1125 print "Resume point detected, skipping unmerge operation..."
1127 if self.settings.has_key(self.settings["spec_prefix"]+"/unmerge"):
1128 if type(self.settings[self.settings["spec_prefix"]+"/unmerge"])==types.StringType:
1129 self.settings[self.settings["spec_prefix"]+"/unmerge"]=[self.settings[self.settings["spec_prefix"]+"/unmerge"]]
1130 myunmerge=self.settings[self.settings["spec_prefix"]+"/unmerge"][:]
1132 for x in range(0,len(myunmerge)):
1133 #surround args with quotes for passing to bash,
1134 #allows things like "<" to remain intact
1135 myunmerge[x]="'"+myunmerge[x]+"'"
1136 myunmerge=string.join(myunmerge)
1138 #before cleaning, unmerge stuff:
1140 cmd("/bin/bash "+self.settings["controller_file"]+" unmerge "+ myunmerge,\
1141 "Unmerge script failed.",env=self.env)
1142 #cmd("/bin/bash "+self.settings["sharedir"]+"/targets/" \
1143 # +self.settings["target"]+"/unmerge.sh "+myunmerge,"Unmerge script failed.",env=self.env)
1144 print "unmerge shell script"
1145 except CatalystError:
1149 touch(self.settings["autoresume_path"]+"unmerge")
1151 def target_setup(self):
1152 if self.settings.has_key("AUTORESUME") \
1153 and os.path.exists(self.settings["autoresume_path"]+"target_setup"):
1154 print "Resume point detected, skipping target_setup operation..."
1156 print "Setting up filesystems per filesystem type"
1157 cmd("/bin/bash "+self.settings["controller_file"]+" target_image_setup "+ self.settings["target_path"],\
1158 "target_image_setup script failed.",env=self.env)
1159 touch(self.settings["autoresume_path"]+"target_setup")
1161 def setup_overlay(self):
1162 if self.settings.has_key("AUTORESUME") \
1163 and os.path.exists(self.settings["autoresume_path"]+"setup_overlay"):
1164 print "Resume point detected, skipping setup_overlay operation..."
1166 if self.settings.has_key(self.settings["spec_prefix"]+"/overlay"):
1167 for x in self.settings[self.settings["spec_prefix"]+"/overlay"]:
1168 if os.path.exists(x):
1169 cmd("rsync -a "+x+"/ "+\
1170 self.settings["target_path"], self.settings["spec_prefix"]+"overlay: "+x+" copy failed.",env=self.env)
1171 touch(self.settings["autoresume_path"]+"setup_overlay")
1173 def create_iso(self):
1174 if self.settings.has_key("AUTORESUME") \
1175 and os.path.exists(self.settings["autoresume_path"]+"create_iso"):
1176 print "Resume point detected, skipping create_iso operation..."
1178 # create the ISO - this is the preferred method (the iso scripts do not always work)
1179 if self.settings.has_key("iso"):
1180 cmd("/bin/bash "+self.settings["controller_file"]+" iso "+\
1181 self.settings["iso"],"ISO creation script failed.",env=self.env)
1182 self.gen_contents_file(self.settings["iso"])
1183 self.gen_digest_file(self.settings["iso"])
1184 touch(self.settings["autoresume_path"]+"create_iso")
1188 print "WARNING livecd/iso was not defined."
1189 print "A CD Image will not be created, skipping create-iso.sh..."
1192 def build_packages(self):
1193 if self.settings.has_key("AUTORESUME") \
1194 and os.path.exists(self.settings["autoresume_path"]+"build_packages"):
1195 print "Resume point detected, skipping build_packages operation..."
1197 if self.settings.has_key(self.settings["spec_prefix"]+"/packages"):
1198 if self.settings.has_key("AUTORESUME") \
1199 and os.path.exists(self.settings["autoresume_path"]+"build_packages"):
1200 print "Resume point detected, skipping build_packages operation..."
1202 mypack=list_bashify(self.settings[self.settings["spec_prefix"]+"/packages"])
1204 cmd("/bin/bash "+self.settings["controller_file"]+\
1205 " build_packages "+mypack,"Error in attempt to build packages",env=self.env)
1206 touch(self.settings["autoresume_path"]+"build_packages")
1207 except CatalystError:
1209 raise CatalystError,self.settings["spec_prefix"] + "build aborting due to error."
1211 def build_kernel(self):
1212 if self.settings.has_key("AUTORESUME") \
1213 and os.path.exists(self.settings["autoresume_path"]+"build_kernel"):
1214 print "Resume point detected, skipping build_kernel operation..."
1216 if self.settings.has_key("boot/kernel"):
1218 mynames=self.settings["boot/kernel"]
1219 if type(mynames)==types.StringType:
1221 # execute the script that sets up the kernel build environment
1222 cmd("/bin/bash "+self.settings["controller_file"]+" pre-kmerge ",\
1223 "Runscript pre-kmerge failed",env=self.env)
1225 for kname in mynames:
1226 if self.settings.has_key("AUTORESUME") \
1227 and os.path.exists(self.settings["autoresume_path"]+"build_kernel_"+kname):
1228 print "Resume point detected, skipping build_kernel for "+kname+" operation..."
1231 if not os.path.exists(self.settings["boot/kernel/"+kname+"/config"]):
1233 raise CatalystError, "Can't find kernel config: " \
1234 +self.settings["boot/kernel/"+kname+"/config"]
1237 raise CatalystError, "Required value boot/kernel/config not specified"
1240 cmd("cp "+self.settings["boot/kernel/"+kname+"/config"]+" "+ \
1241 self.settings["chroot_path"]+"/var/tmp/"+kname+".config", \
1242 "Couldn't copy kernel config: "+self.settings["boot/kernel/"+kname+"/config"],\
1245 except CatalystError:
1248 # If we need to pass special options to the bootloader
1249 # for this kernel put them into the environment.
1250 if self.settings.has_key("boot/kernel/"+kname+"/kernelopts"):
1251 myopts=self.settings["boot/kernel/"+kname+"/kernelopts"]
1253 if type(myopts) != types.StringType:
1254 myopts = string.join(myopts)
1255 self.env[kname+"_kernelopts"]=myopts
1258 self.env[kname+"_kernelopts"]=""
1260 if not self.settings.has_key("boot/kernel/"+kname+"/extraversion"):
1261 self.settings["boot/kernel/"+kname+"/extraversion"]=""
1263 self.env["clst_kextraversion"]=self.settings["boot/kernel/"+kname+"/extraversion"]
1265 if self.settings.has_key("boot/kernel/"+kname+"/initramfs_overlay"):
1266 if os.path.exists(self.settings["boot/kernel/"+kname+"/initramfs_overlay"]):
1267 print "Copying initramfs_overlay dir " +self.settings["boot/kernel/"+kname+"/initramfs_overlay"]
1269 cmd("mkdir -p "+self.settings["chroot_path"]+"/tmp/initramfs_overlay/" + \
1270 self.settings["boot/kernel/"+kname+"/initramfs_overlay"],env=self.env)
1272 cmd("cp -R "+self.settings["boot/kernel/"+kname+"/initramfs_overlay"]+"/* " + \
1273 self.settings["chroot_path"] + "/tmp/initramfs_overlay/" + \
1274 self.settings["boot/kernel/"+kname+"/initramfs_overlay"],\
1278 # execute the script that builds the kernel
1279 cmd("/bin/bash "+self.settings["controller_file"]+" kernel "+kname,\
1280 "Runscript kernel build failed",env=self.env)
1282 if self.settings.has_key("boot/kernel/"+kname+"/initramfs_overlay"):
1283 if os.path.exists(self.settings["chroot_path"]+"/tmp/initramfs_overlay/"):
1284 print "Cleaning up temporary overlay dir"
1285 cmd("rm -R "+self.settings["chroot_path"]+"/tmp/initramfs_overlay/",env=self.env)
1287 touch(self.settings["autoresume_path"]+"build_kernel_"+kname)
1289 # execute the script that cleans up the kernel build environment
1290 cmd("/bin/bash "+self.settings["controller_file"]+" post-kmerge ",\
1291 "Runscript post-kmerge failed",env=self.env)
1293 touch(self.settings["autoresume_path"]+"build_kernel")
1295 except CatalystError:
1297 raise CatalystError,"build aborting due to kernel build error."
1299 def bootloader(self):
1300 if self.settings.has_key("AUTORESUME") \
1301 and os.path.exists(self.settings["autoresume_path"]+"bootloader"):
1302 print "Resume point detected, skipping bootloader operation..."
1305 cmd("/bin/bash "+self.settings["controller_file"]+" bootloader " + self.settings["target_path"],\
1306 "Bootloader runscript failed.",env=self.env)
1307 touch(self.settings["autoresume_path"]+"bootloader")
1308 except CatalystError:
1310 raise CatalystError,"Runscript aborting due to error."
1312 def livecd_update(self):
1313 if self.settings.has_key("AUTORESUME") \
1314 and os.path.exists(self.settings["autoresume_path"]+"livecd_update"):
1315 print "Resume point detected, skipping build_packages operation..."
1318 cmd("/bin/bash "+self.settings["controller_file"]+" livecd-update",\
1319 "livecd-update failed.",env=self.env)
1320 touch(self.settings["autoresume_path"]+"livecd_update")
1322 except CatalystError:
1324 raise CatalystError,"build aborting due to livecd_update error."
1326 def clear_chroot(self):
1327 myemp=self.settings["chroot_path"]
1328 if os.path.isdir(myemp):
1329 print "Emptying directory",myemp
1330 # stat the dir, delete the dir, recreate the dir and set
1331 # the proper perms and ownership
1332 mystat=os.stat(myemp)
1333 #cmd("rm -rf "+myemp, "Could not remove existing file: "+myemp,env=self.env)
1334 if os.uname()[0] == "FreeBSD": # There's no easy way to change flags recursively in python
1335 os.system("chflags -R noschg "+myemp)
1336 shutil.rmtree(myemp)
1337 os.makedirs(myemp,0755)
1338 os.chown(myemp,mystat[ST_UID],mystat[ST_GID])
1339 os.chmod(myemp,mystat[ST_MODE])
1341 def clear_packages(self):
1342 if self.settings.has_key("PKGCACHE"):
1343 print "purging the pkgcache ..."
1345 myemp=self.settings["pkgcache_path"]
1346 if os.path.isdir(myemp):
1347 print "Emptying directory",myemp
1348 # stat the dir, delete the dir, recreate the dir and set
1349 # the proper perms and ownership
1350 mystat=os.stat(myemp)
1351 #cmd("rm -rf "+myemp, "Could not remove existing file: "+myemp,env=self.env)
1352 shutil.rmtree(myemp)
1353 os.makedirs(myemp,0755)
1354 os.chown(myemp,mystat[ST_UID],mystat[ST_GID])
1355 os.chmod(myemp,mystat[ST_MODE])
1357 def clear_kerncache(self):
1358 if self.settings.has_key("KERNCACHE"):
1359 print "purging the kerncache ..."
1361 myemp=self.settings["kerncache_path"]
1362 if os.path.isdir(myemp):
1363 print "Emptying directory",myemp
1364 # stat the dir, delete the dir, recreate the dir and set
1365 # the proper perms and ownership
1366 mystat=os.stat(myemp)
1367 #cmd("rm -rf "+myemp, "Could not remove existing file: "+myemp,env=self.env)
1368 shutil.rmtree(myemp)
1369 os.makedirs(myemp,0755)
1370 os.chown(myemp,mystat[ST_UID],mystat[ST_GID])
1371 os.chmod(myemp,mystat[ST_MODE])
1373 def clear_autoresume(self):
1374 # clean resume points since they are no longer needed
1375 if self.settings.has_key("AUTORESUME"):
1376 print "Removing AutoResume Points: ..."
1377 myemp=self.settings["autoresume_path"]
1378 if os.path.isdir(myemp):
1379 if self.settings.has_key("AUTORESUME"):
1380 print "Emptying directory",myemp
1381 # stat the dir, delete the dir, recreate the dir and set
1382 # the proper perms and ownership
1383 mystat=os.stat(myemp)
1384 if os.uname()[0] == "FreeBSD":
1385 cmd("chflags -R noschg "+myemp, "Could not remove immutable flag for file " + myemp)
1386 #cmd("rm -rf "+myemp, "Could not remove existing file: "+myemp,env-self.env)
1387 shutil.rmtree(myemp)
1388 os.makedirs(myemp,0755)
1389 os.chown(myemp,mystat[ST_UID],mystat[ST_GID])
1390 os.chmod(myemp,mystat[ST_MODE])
1393 def gen_contents_file(self,file):
1394 if os.path.exists(file+".CONTENTS"):
1395 os.remove(file+".CONTENTS")
1396 if self.settings.has_key("contents"):
1397 if os.path.exists(file):
1398 myf=open(file+".CONTENTS","w")
1400 for i in self.settings["contents"].split():
1405 contents=generate_contents(file,contents_function=j,verbose=self.settings.has_key("VERBOSE"))
1409 def gen_digest_file(self,file):
1410 if os.path.exists(file+".DIGESTS"):
1411 os.remove(file+".DIGESTS")
1412 if self.settings.has_key("digests"):
1413 if os.path.exists(file):
1414 myf=open(file+".DIGESTS","w")
1416 for i in self.settings["digests"].split():
1420 for f in [file, file+'.CONTENTS']:
1421 if os.path.exists(f):
1423 hash=generate_hash(f,hash_function=j,verbose=self.settings.has_key("VERBOSE"))
1428 countdown(10,"Purging Caches ...")
1429 if self.settings.has_key("PURGE"):
1430 print "clearing autoresume ..."
1431 self.clear_autoresume()
1433 print "clearing chroot ..."
1436 print "clearing package cache ..."
1437 self.clear_packages()
1439 print "clearing kerncache ..."
1440 self.clear_kerncache()
1442 #vim: ts=4 sw=4 sta et sts=4 ai