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 various
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 def override_cbuild(self):
206 if self.makeconf.has_key("CBUILD"):
207 self.settings["CBUILD"]=self.makeconf["CBUILD"]
209 def override_chost(self):
210 if self.makeconf.has_key("CHOST"):
211 self.settings["CHOST"]=self.makeconf["CHOST"]
213 def override_cflags(self):
214 if self.makeconf.has_key("CFLAGS"):
215 self.settings["CFLAGS"]=self.makeconf["CFLAGS"]
217 def override_cxxflags(self):
218 if self.makeconf.has_key("CXXFLAGS"):
219 self.settings["CXXFLAGS"]=self.makeconf["CXXFLAGS"]
221 def override_ldflags(self):
222 if self.makeconf.has_key("LDFLAGS"):
223 self.settings["LDFLAGS"]=self.makeconf["LDFLAGS"]
225 def set_install_mask(self):
226 if self.settings.has_key("install_mask"):
227 if type(self.settings["install_mask"]) != types.StringType:
228 self.settings["install_mask"]=string.join(self.settings["install_mask"])
230 def set_spec_prefix(self):
231 self.settings["spec_prefix"]=self.settings["target"]
233 def set_target_profile(self):
234 self.settings["target_profile"]=self.settings["profile"]
236 def set_target_subpath(self):
237 self.settings["target_subpath"]=self.settings["rel_type"]+"/"+self.settings["target"]+\
238 "-"+self.settings["subarch"]+"-"+self.settings["version_stamp"]
240 def set_source_subpath(self):
241 if type(self.settings["source_subpath"]) != types.StringType:
242 raise CatalystError, "source_subpath should have been a string. Perhaps you have something wrong in your spec file?"
244 def set_pkgcache_path(self):
245 if self.settings.has_key("pkgcache_path"):
246 if type(self.settings["pkgcache_path"]) != types.StringType:
247 self.settings["pkgcache_path"]=normpath(string.join(self.settings["pkgcache_path"]))
249 self.settings["pkgcache_path"]=normpath(self.settings["storedir"]+"/packages/"+\
250 self.settings["target_subpath"]+"/")
252 def set_kerncache_path(self):
253 if self.settings.has_key("kerncache_path"):
254 if type(self.settings["kerncache_path"]) != types.StringType:
255 self.settings["kerncache_path"]=normpath(string.join(self.settings["kerncache_path"]))
257 self.settings["kerncache_path"]=normpath(self.settings["storedir"]+"/kerncache/"+\
258 self.settings["target_subpath"]+"/")
260 def set_target_path(self):
261 self.settings["target_path"]=normpath(self.settings["storedir"]+"/builds/"+\
262 self.settings["target_subpath"]+".tar.bz2")
263 if self.settings.has_key("AUTORESUME") \
264 and os.path.exists(self.settings["autoresume_path"]+"setup_target_path"):
265 print "Resume point detected, skipping target path setup operation..."
267 # first clean up any existing target stuff
268 if os.path.isfile(self.settings["target_path"]):
269 cmd("rm -f "+self.settings["target_path"], \
270 "Could not remove existing file: "+self.settings["target_path"],env=self.env)
271 touch(self.settings["autoresume_path"]+"setup_target_path")
273 if not os.path.exists(self.settings["storedir"]+"/builds/"):
274 os.makedirs(self.settings["storedir"]+"/builds/")
276 def set_archscript(self):
277 if self.settings.has_key(self.settings["spec_prefix"]+"/archscript"):
278 print "\nWarning!!! "
279 print "\t"+self.settings["spec_prefix"]+"/archscript" + " is deprecated and no longer used.\n"
280 def set_runscript(self):
281 if self.settings.has_key(self.settings["spec_prefix"]+"/runscript"):
282 print "\nWarning!!! "
283 print "\t"+self.settings["spec_prefix"]+"/runscript" + " is deprecated and no longer used.\n"
285 def set_fsscript(self):
286 if self.settings.has_key(self.settings["spec_prefix"]+"/fsscript"):
287 self.settings["fsscript"]=self.settings[self.settings["spec_prefix"]+"/fsscript"]
288 del self.settings[self.settings["spec_prefix"]+"/fsscript"]
291 if self.settings.has_key(self.settings["spec_prefix"]+"/rcadd"):
292 self.settings["rcadd"]=self.settings[self.settings["spec_prefix"]+"/rcadd"]
293 del self.settings[self.settings["spec_prefix"]+"/rcadd"]
296 if self.settings.has_key(self.settings["spec_prefix"]+"/rcdel"):
297 self.settings["rcdel"]=self.settings[self.settings["spec_prefix"]+"/rcdel"]
298 del self.settings[self.settings["spec_prefix"]+"/rcdel"]
301 if self.settings.has_key(self.settings["spec_prefix"]+"/cdtar"):
302 self.settings["cdtar"]=normpath(self.settings[self.settings["spec_prefix"]+"/cdtar"])
303 del self.settings[self.settings["spec_prefix"]+"/cdtar"]
306 if self.settings.has_key(self.settings["spec_prefix"]+"/iso"):
307 self.settings["iso"]=normpath(self.settings[self.settings["spec_prefix"]+"/iso"])
308 del self.settings[self.settings["spec_prefix"]+"/iso"]
310 def set_fstype(self):
311 if self.settings.has_key(self.settings["spec_prefix"]+"/cdfstype"):
312 print "\nWarning!!! "
313 print self.settings["spec_prefix"]+"/cdfstype" + " is deprecated and may be removed."
314 print "\tUse "+self.settings["spec_prefix"]+"/fstype" + " instead."
315 print "\tConverting to "+self.settings["spec_prefix"]+"/fstype" + " internally."
316 print "\tContinuing ....\n"
317 self.settings["fstype"]=self.settings[self.settings["spec_prefix"]+"/cdfstype"]
318 del self.settings[self.settings["spec_prefix"]+"/cdfstype"]
320 if self.settings.has_key(self.settings["spec_prefix"]+"/fstype"):
321 self.settings["fstype"]=self.settings[self.settings["spec_prefix"]+"/fstype"]
322 del self.settings[self.settings["spec_prefix"]+"/fstype"]
324 if not self.settings.has_key("fstype"):
325 self.settings["fstype"]="normal"
326 for x in self.valid_values:
327 if x == self.settings["spec_prefix"]+"/fstype" or x == self.settings["spec_prefix"]+"/cdfstype":
328 print "\n"+self.settings["spec_prefix"]+"/fstype is being set to the default of \"normal\"\n"
331 if self.settings.has_key("fstype"):
332 self.valid_values.append("fsops")
333 if self.settings.has_key(self.settings["spec_prefix"]+"/fsops"):
334 self.settings["fsops"]=self.settings[self.settings["spec_prefix"]+"/fsops"]
335 del self.settings[self.settings["spec_prefix"]+"/fsops"]
337 def set_source_path(self):
338 if self.settings.has_key("SEEDCACHE") and os.path.isdir(normpath(self.settings["storedir"]+"/tmp/"+self.settings["source_subpath"]+"/")):
339 self.settings["source_path"]=normpath(self.settings["storedir"]+"/tmp/"+self.settings["source_subpath"]+"/")
341 self.settings["source_path"]=normpath(self.settings["storedir"]+"/builds/"+self.settings["source_subpath"]+".tar.bz2")
342 if os.path.isfile(self.settings["source_path"]):
343 if os.path.exists(self.settings["source_path"]): # XXX: Is this even necessary if the previous check passes?
344 self.settings["source_path_hash"]=generate_hash(self.settings["source_path"],\
345 hash_function=self.settings["hash_function"],verbose=False)
346 print "Source path set to "+self.settings["source_path"]
347 if os.path.isdir(self.settings["source_path"]):
348 print "\tIf this is not desired, remove this directory or turn of seedcache in the options of catalyst.conf"
349 print "\tthe source path will then be "+normpath(self.settings["storedir"]+"/builds/"+self.settings["source_subpath"]+".tar.bz2\n")
351 def set_dest_path(self):
352 if self.settings.has_key("root_path"):
353 self.settings["destpath"]=normpath(self.settings["chroot_path"]+self.settings["root_path"])
355 self.settings["destpath"]=normpath(self.settings["chroot_path"])
357 def set_cleanables(self):
358 self.settings["cleanables"]=["/etc/resolv.conf","/var/tmp/*","/tmp/*","/root/*",\
361 def set_snapshot_path(self):
362 self.settings["snapshot_path"]=normpath(self.settings["storedir"]+"/snapshots/portage-"+self.settings["snapshot"]+".tar.bz2")
364 if os.path.exists(self.settings["snapshot_path"]):
365 self.settings["snapshot_path_hash"]=generate_hash(self.settings["snapshot_path"],\
366 hash_function=self.settings["hash_function"],verbose=False)
368 def set_snapcache_path(self):
369 if self.settings.has_key("SNAPCACHE"):
370 self.settings["snapshot_cache_path"]=normpath(self.settings["snapshot_cache"]+"/"+self.settings["snapshot"]+"/")
371 self.snapcache_lock=catalyst_lock.LockDir(self.settings["snapshot_cache_path"])
372 print "Caching snapshot to " + self.settings["snapshot_cache_path"]
374 def set_chroot_path(self):
375 # Note the trailing slash is very important and things would break without it
376 self.settings["chroot_path"]=normpath(self.settings["storedir"]+"/tmp/"+self.settings["target_subpath"]+"/")
377 self.chroot_lock=catalyst_lock.LockDir(self.settings["chroot_path"])
379 def set_autoresume_path(self):
380 self.settings["autoresume_path"]=normpath(self.settings["storedir"]+"/tmp/"+\
381 self.settings["rel_type"]+"/"+".autoresume-"+self.settings["target"]+\
382 "-"+self.settings["subarch"]+"-"+self.settings["version_stamp"]+"/")
383 if self.settings.has_key("AUTORESUME"):
384 print "The autoresume path is " + self.settings["autoresume_path"]
385 if not os.path.exists(self.settings["autoresume_path"]):
386 os.makedirs(self.settings["autoresume_path"],0755)
388 def set_controller_file(self):
389 self.settings["controller_file"]=normpath(self.settings["sharedir"]+"/targets/"+self.settings["target"]+"/"+self.settings["target"]+"-controller.sh")
391 def set_iso_volume_id(self):
392 if self.settings.has_key(self.settings["spec_prefix"]+"/volid"):
393 self.settings["iso_volume_id"] = self.settings[self.settings["spec_prefix"]+"/volid"]
394 if len(self.settings["iso_volume_id"])>32:
395 raise CatalystError,"ISO VOLUME ID: volid must not exceed 32 characters."
397 self.settings["iso_volume_id"] = "catalyst " + self.settings["snapshot"]
399 def set_action_sequence(self):
400 # Default action sequence for run method
401 self.settings["action_sequence"]=["unpack","unpack_snapshot",\
402 "config_profile_link","setup_confdir","portage_overlay",\
403 "base_dirs","bind","chroot_setup","setup_environment",\
404 "run_local","preclean","unbind","clean"]
405 # if self.settings.has_key("TARBALL") or \
406 # not self.settings.has_key("FETCH"):
407 if not self.settings.has_key("FETCH"):
408 self.settings["action_sequence"].append("capture")
409 self.settings["action_sequence"].append("clear_autoresume")
412 if self.settings.has_key(self.settings["spec_prefix"]+"/use"):
413 self.settings["use"]=self.settings[self.settings["spec_prefix"]+"/use"]
414 del self.settings[self.settings["spec_prefix"]+"/use"]
415 if self.settings.has_key("use"):
416 if type(self.settings["use"])==types.StringType:
417 self.settings["use"]=self.settings["use"].split()
419 def set_stage_path(self):
420 self.settings["stage_path"]=normpath(self.settings["chroot_path"])
422 def set_mounts(self):
425 def set_packages(self):
429 if self.settings.has_key(self.settings["spec_prefix"]+"/rm"):
430 if type(self.settings[self.settings["spec_prefix"]+"/rm"])==types.StringType:
431 self.settings[self.settings["spec_prefix"]+"/rm"]=self.settings[self.settings["spec_prefix"]+"/rm"].split()
433 def set_linuxrc(self):
434 if self.settings.has_key(self.settings["spec_prefix"]+"/linuxrc"):
435 if type(self.settings[self.settings["spec_prefix"]+"/linuxrc"])==types.StringType:
436 self.settings["linuxrc"]=self.settings[self.settings["spec_prefix"]+"/linuxrc"]
437 del self.settings[self.settings["spec_prefix"]+"/linuxrc"]
439 def set_portage_overlay(self):
440 if self.settings.has_key("portage_overlay"):
441 if type(self.settings["portage_overlay"])==types.StringType:
442 self.settings["portage_overlay"]=self.settings["portage_overlay"].split()
443 print "portage_overlay directories are set to: \"" + string.join(self.settings["portage_overlay"])+"\""
445 def set_overlay(self):
446 if self.settings.has_key(self.settings["spec_prefix"]+"/overlay"):
447 if type(self.settings[self.settings["spec_prefix"]+"/overlay"])==types.StringType:
448 self.settings[self.settings["spec_prefix"]+"/overlay"]=self.settings[self.settings["spec_prefix"]+"/overlay"].split()
450 def set_root_overlay(self):
451 if self.settings.has_key(self.settings["spec_prefix"]+"/root_overlay"):
452 if type(self.settings[self.settings["spec_prefix"]+"/root_overlay"])==types.StringType:
453 self.settings[self.settings["spec_prefix"]+"/root_overlay"]=self.settings[self.settings["spec_prefix"]+"/root_overlay"].split()
456 def set_root_path(self):
457 # ROOT= variable for emerges
458 self.settings["root_path"]="/"
460 def set_valid_build_kernel_vars(self,addlargs):
461 if addlargs.has_key("boot/kernel"):
462 if type(addlargs["boot/kernel"]) == types.StringType:
463 loopy=[addlargs["boot/kernel"]]
465 loopy=addlargs["boot/kernel"]
468 self.required_values.append("boot/kernel/"+x+"/sources")
469 self.required_values.append("boot/kernel/"+x+"/config")
470 self.valid_values.append("boot/kernel/"+x+"/aliases")
471 self.valid_values.append("boot/kernel/"+x+"/extraversion")
472 self.valid_values.append("boot/kernel/"+x+"/packages")
473 if addlargs.has_key("boot/kernel/"+x+"/packages"):
474 if type(addlargs["boot/kernel/"+x+"/packages"]) == types.StringType:
475 addlargs["boot/kernel/"+x+"/packages"]=[addlargs["boot/kernel/"+x+"/packages"]]
476 self.valid_values.append("boot/kernel/"+x+"/use")
477 self.valid_values.append("boot/kernel/"+x+"/gk_kernargs")
478 self.valid_values.append("boot/kernel/"+x+"/gk_action")
479 self.valid_values.append("boot/kernel/"+x+"/initramfs_overlay")
480 self.valid_values.append("boot/kernel/"+x+"/softlevel")
481 self.valid_values.append("boot/kernel/"+x+"/console")
482 self.valid_values.append("boot/kernel/"+x+"/machine_type")
483 self.valid_values.append("boot/kernel/"+x+"/postconf")
484 if addlargs.has_key("boot/kernel/"+x+"/postconf"):
485 print "boot/kernel/"+x+"/postconf is deprecated"
486 print "\tInternally moving these ebuilds to boot/kernel/"+x+"/packages"
487 print "\tPlease move them to boot/kernel/"+x+"/packages in your specfile"
488 if type(addlargs["boot/kernel/"+x+"/postconf"]) == types.StringType:
489 loop2=[addlargs["boot/kernel/"+x+"/postconf"]]
491 loop2=addlargs["boot/kernel/"+x+"/postconf"]
494 if not addlargs.has_key("boot/kernel/"+x+"/packages"):
495 addlargs["boot/kernel/"+x+"/packages"]=[y]
497 addlargs["boot/kernel/"+x+"/packages"].append(y)
499 def set_build_kernel_vars(self):
500 if self.settings.has_key(self.settings["spec_prefix"]+"/devmanager"):
501 self.settings["devmanager"]=self.settings[self.settings["spec_prefix"]+"/devmanager"]
502 del self.settings[self.settings["spec_prefix"]+"/devmanager"]
504 if self.settings.has_key(self.settings["spec_prefix"]+"/splashtype"):
505 self.settings["splashtype"]=self.settings[self.settings["spec_prefix"]+"/splashtype"]
506 del self.settings[self.settings["spec_prefix"]+"/splashtype"]
508 if self.settings.has_key(self.settings["spec_prefix"]+"/gk_mainargs"):
509 self.settings["gk_mainargs"]=self.settings[self.settings["spec_prefix"]+"/gk_mainargs"]
510 del self.settings[self.settings["spec_prefix"]+"/gk_mainargs"]
512 def kill_chroot_pids(self):
513 print "Checking for processes running in chroot and killing them."
515 # Force environment variables to be exported so script can see them
516 self.setup_environment()
518 if os.path.exists(self.settings["sharedir"]+"/targets/support/kill-chroot-pids.sh"):
519 cmd("/bin/bash "+self.settings["sharedir"]+"/targets/support/kill-chroot-pids.sh",\
520 "kill-chroot-pids script failed.",env=self.env)
522 def mount_safety_check(self):
523 mypath=self.settings["chroot_path"]
526 check and verify that none of our paths in mypath are mounted. We don't want to clean
527 up with things still mounted, and this allows us to check.
528 returns 1 on ok, 0 on "something is still mounted" case.
530 if not os.path.exists(mypath):
533 for x in self.mounts:
534 if not os.path.exists(mypath+x):
537 if ismount(mypath+x):
538 #something is still mounted
540 print x+" is still mounted; performing auto-bind-umount...",
541 # try to umount stuff ourselves
543 if ismount(mypath+x):
544 raise CatalystError, "Auto-unbind failed for "+x
547 print "Auto-unbind successful..."
549 except CatalystError:
550 raise CatalystError, "Unable to auto-unbind "+x
555 clst_unpack_hash=read_from_clst(self.settings["autoresume_path"]+"unpack")
557 if self.settings.has_key("SEEDCACHE"):
558 if os.path.isdir(self.settings["source_path"]):
559 # SEEDCACHE Is a directory, use Rsync
560 unpack_cmd="rsync -a --delete "+self.settings["source_path"]+" "+self.settings["chroot_path"]
561 display_msg="\nStarting rsync from "+self.settings["source_path"]+"\nto "+\
562 self.settings["chroot_path"]+" (This may take some time) ...\n"
563 error_msg="Rsync of "+self.settings["source_path"]+" to "+self.settings["chroot_path"]+" failed."
565 # SEEDCACHE is a not a directory, try untar'ing
566 print "Referenced SEEDCACHE does not appear to be a directory, trying to untar..."
567 display_msg="\nStarting tar extract from "+self.settings["source_path"]+"\nto "+\
568 self.settings["chroot_path"]+" (This may take some time) ...\n"
569 unpack_cmd="tar xjpf "+self.settings["source_path"]+" -C "+self.settings["chroot_path"]
570 error_msg="Tarball extraction of "+self.settings["source_path"]+" to "+self.settings["chroot_path"]+" failed."
572 # No SEEDCACHE, use tar
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."
579 if self.settings.has_key("AUTORESUME"):
580 # Autoresume is Valid, SeedCache is Valid
581 if os.path.isdir(self.settings["source_path"]) and os.path.exists(self.settings["autoresume_path"]+"unpack"):
583 invalid_snapshot=False
585 # Autoresume is Valid, Tarball is Valid
586 elif os.path.isfile(self.settings["source_path"]) and self.settings["source_path_hash"] == clst_unpack_hash:
588 invalid_snapshot=True
590 # Autoresume is InValid, SeedCache
591 elif os.path.isdir(self.settings["source_path"]) and not os.path.exists(self.settings["autoresume_path"]+"unpack"):
593 invalid_snapshot=False
595 # Autoresume is InValid, Tarball
596 elif os.path.isfile(self.settings["source_path"]) and self.settings["source_path_hash"] != clst_unpack_hash:
598 invalid_snapshot=True
600 # No Autoresume,SeedCache
601 if self.settings.has_key("SEEDCACHE"):
603 # Seed cache so lets run rsync and rsync can clean up extra junk
604 if os.path.isdir(self.settings["source_path"]):
606 invalid_snapshot=False
608 # Tarball so we better unpack and remove anything already there
609 elif os.path.isfile(self.settings["source_path"]):
611 invalid_snapshot=True
613 # No Autoresume,No SeedCache
616 # Tarball so we better unpack and remove anything already there
617 if os.path.isfile(self.settings["source_path"]):
619 invalid_snapshot=True
620 # Should never reach this if so something is very wrong
621 elif os.path.isdir(self.settings["source_path"]):
622 raise CatalystError,"source path is a dir but seedcache is not enabled"
625 self.mount_safety_check()
628 if self.settings.has_key("AUTORESUME"):
629 print "No Valid Resume point detected, cleaning up ..."
631 self.clear_autoresume()
634 if not os.path.exists(self.settings["chroot_path"]):
635 os.makedirs(self.settings["chroot_path"])
637 if not os.path.exists(self.settings["chroot_path"]+"/tmp"):
638 os.makedirs(self.settings["chroot_path"]+"/tmp",1777)
640 if self.settings.has_key("PKGCACHE"):
641 if not os.path.exists(self.settings["pkgcache_path"]):
642 os.makedirs(self.settings["pkgcache_path"],0755)
644 if self.settings.has_key("KERNCACHE"):
645 if not os.path.exists(self.settings["kerncache_path"]):
646 os.makedirs(self.settings["kerncache_path"],0755)
649 cmd(unpack_cmd,error_msg,env=self.env)
651 if self.settings.has_key("source_path_hash"):
652 myf=open(self.settings["autoresume_path"]+"unpack","w")
653 myf.write(self.settings["source_path_hash"])
656 touch(self.settings["autoresume_path"]+"unpack")
658 print "Resume point detected, skipping unpack operation..."
661 def unpack_snapshot(self):
663 snapshot_hash=read_from_clst(self.settings["autoresume_path"]+"unpack_portage")
665 if self.settings.has_key("SNAPCACHE"):
666 snapshot_cache_hash=read_from_clst(self.settings["snapshot_cache_path"]+"catalyst-hash")
667 destdir=self.settings["snapshot_cache_path"]
668 unpack_cmd="tar xjpf "+self.settings["snapshot_path"]+" -C "+destdir
669 unpack_errmsg="Error unpacking snapshot"
670 cleanup_msg="Cleaning up invalid snapshot cache at \n\t"+self.settings["snapshot_cache_path"]+" (This can take a long time)..."
671 cleanup_errmsg="Error removing existing snapshot cache directory."
672 self.snapshot_lock_object=self.snapcache_lock
674 if self.settings["snapshot_path_hash"] == snapshot_cache_hash:
675 print "Valid snapshot cache, skipping unpack of portage tree ..."
679 destdir=normpath(self.settings["chroot_path"]+"/usr/portage")
680 cleanup_errmsg="Error removing existing snapshot directory."
681 cleanup_msg="Cleaning up existing portage tree (This can take a long time) ..."
682 unpack_cmd="tar xjpf "+self.settings["snapshot_path"]+" -C "+self.settings["chroot_path"]+"/usr"
683 unpack_errmsg="Error unpacking snapshot"
685 if self.settings.has_key("AUTORESUME") \
686 and os.path.exists(self.settings["chroot_path"]+"/usr/portage/") \
687 and os.path.exists(self.settings["autoresume_path"]+"unpack_portage") \
688 and self.settings["snapshot_path_hash"] == snapshot_hash:
689 print "Valid Resume point detected, skipping unpack of portage tree..."
695 if self.settings.has_key("SNAPCACHE"):
696 self.snapshot_lock_object.write_lock()
697 if os.path.exists(destdir):
699 cleanup_cmd="rm -rf "+destdir
700 cmd(cleanup_cmd,cleanup_errmsg,env=self.env)
701 if not os.path.exists(destdir):
702 os.makedirs(destdir,0755)
704 print "Unpacking portage tree (This can take a long time) ..."
705 cmd(unpack_cmd,unpack_errmsg,env=self.env)
707 if self.settings.has_key("SNAPCACHE"):
708 myf=open(self.settings["snapshot_cache_path"]+"catalyst-hash","w")
709 myf.write(self.settings["snapshot_path_hash"])
713 print "Setting snapshot autoresume point"
714 myf=open(self.settings["autoresume_path"]+"unpack_portage","w")
715 myf.write(self.settings["snapshot_path_hash"])
718 if self.settings.has_key("SNAPCACHE"):
719 self.snapshot_lock_object.unlock()
721 def config_profile_link(self):
722 if self.settings.has_key("AUTORESUME") \
723 and os.path.exists(self.settings["autoresume_path"]+"config_profile_link"):
724 print "Resume point detected, skipping config_profile_link operation..."
726 print "Configuring profile link..."
727 cmd("rm -f "+self.settings["chroot_path"]+"/etc/make.profile",\
728 "Error zapping profile link",env=self.env)
729 cmd("ln -sf ../usr/portage/profiles/"+self.settings["target_profile"]+\
730 " "+self.settings["chroot_path"]+"/etc/make.profile","Error creating profile link",env=self.env)
731 touch(self.settings["autoresume_path"]+"config_profile_link")
733 def setup_confdir(self):
734 if self.settings.has_key("AUTORESUME") \
735 and os.path.exists(self.settings["autoresume_path"]+"setup_confdir"):
736 print "Resume point detected, skipping setup_confdir operation..."
738 if self.settings.has_key("portage_confdir"):
739 print "Configuring /etc/portage..."
740 cmd("rm -rf "+self.settings["chroot_path"]+"/etc/portage","Error zapping /etc/portage",env=self.env)
741 cmd("cp -R "+self.settings["portage_confdir"]+"/ "+self.settings["chroot_path"]+\
742 "/etc/portage","Error copying /etc/portage",env=self.env)
743 touch(self.settings["autoresume_path"]+"setup_confdir")
745 def portage_overlay(self):
746 # Here, we copy the contents of our overlays to /usr/local/portage. We
747 # always copy over the overlays in case it has changed.
748 if self.settings.has_key("portage_overlay"):
749 for x in self.settings["portage_overlay"]:
750 if os.path.exists(x):
751 print "Copying overlay dir " +x
752 cmd("mkdir -p "+self.settings["chroot_path"]+"/usr/local/portage","Could not make portage_overlay dir",env=self.env)
753 cmd("cp -R "+x+"/* "+self.settings["chroot_path"]+"/usr/local/portage","Could not copy portage_overlay",env=self.env)
755 def root_overlay(self):
756 # copy over the root_overlay
757 # Always copy over the overlay incase it has changed
758 if self.settings.has_key(self.settings["spec_prefix"]+"/root_overlay"):
759 for x in self.settings[self.settings["spec_prefix"]+"/root_overlay"]:
760 if os.path.exists(x):
761 print "Copying root_overlay: "+x
762 cmd("rsync -a "+x+"/ "+\
763 self.settings["chroot_path"], self.settings["spec_prefix"]+"/root_overlay: "+x+" copy failed.",env=self.env)
769 for x in self.mounts:
770 if not os.path.exists(self.settings["chroot_path"]+x):
771 os.makedirs(self.settings["chroot_path"]+x,0755)
773 if not os.path.exists(self.mountmap[x]):
774 os.makedirs(self.mountmap[x],0755)
777 if self.settings.has_key("SNAPCACHE") and x == "/usr/portage":
778 self.snapshot_lock_object.read_lock()
779 if os.uname()[0] == "FreeBSD":
781 retval=os.system("mount -t devfs none "+self.settings["chroot_path"]+x)
783 retval=os.system("mount_nullfs "+src+" "+self.settings["chroot_path"]+x)
785 retval=os.system("mount --bind "+src+" "+self.settings["chroot_path"]+x)
788 raise CatalystError,"Couldn't bind mount "+src
793 mypath=self.settings["chroot_path"]
794 myrevmounts=self.mounts[:]
795 myrevmounts.reverse()
796 # unmount in reverse order for nested bind-mounts
797 for x in myrevmounts:
798 if not os.path.exists(mypath+x):
801 if not ismount(mypath+x):
802 # it's not mounted, continue
805 retval=os.system("umount "+os.path.join(mypath,x.lstrip(os.path.sep)))
808 warn("First attempt to unmount: "+mypath+x+" failed.")
809 warn("Killing any pids still running in the chroot")
811 self.kill_chroot_pids()
813 retval2=os.system("umount "+mypath+x)
816 warn("Couldn't umount bind mount: "+mypath+x)
817 # keep trying to umount the others, to minimize damage if developer makes a mistake
819 if self.settings.has_key("SNAPCACHE") and x == "/usr/portage":
821 # Its possible the snapshot lock object isnt created yet
822 # this is because mount safety check calls unbind before the target is fully initialized
823 self.snapshot_lock_object.unlock()
828 if any bind mounts really failed, then we need to raise
829 this to potentially prevent an upcoming bash stage cleanup script
830 from wiping our bind mounts.
832 raise CatalystError,"Couldn't umount one or more bind-mounts; aborting for safety."
834 def chroot_setup(self):
835 self.makeconf=read_makeconf(self.settings["chroot_path"]+"/etc/make.conf")
836 self.override_cbuild()
837 self.override_chost()
838 self.override_cflags()
839 self.override_cxxflags()
840 self.override_ldflags()
841 if self.settings.has_key("AUTORESUME") \
842 and os.path.exists(self.settings["autoresume_path"]+"chroot_setup"):
843 print "Resume point detected, skipping chroot_setup operation..."
845 print "Setting up chroot..."
847 #self.makeconf=read_makeconf(self.settings["chroot_path"]+"/etc/make.conf")
849 cmd("cp /etc/resolv.conf "+self.settings["chroot_path"]+"/etc",\
850 "Could not copy resolv.conf into place.",env=self.env)
852 # copy over the envscript, if applicable
853 if self.settings.has_key("ENVSCRIPT"):
854 if not os.path.exists(self.settings["ENVSCRIPT"]):
855 raise CatalystError, "Can't find envscript "+self.settings["ENVSCRIPT"]
857 print "\nWarning!!!!"
858 print "\tOverriding certain env variables may cause catastrophic failure."
859 print "\tIf your build fails look here first as the possible problem."
860 print "\tCatalyst assumes you know what you are doing when setting"
861 print "\t\tthese variables."
862 print "\tCatalyst Maintainers use VERY minimal envscripts if used at all"
863 print "\tYou have been warned\n"
865 cmd("cp "+self.settings["ENVSCRIPT"]+" "+self.settings["chroot_path"]+"/tmp/envscript",\
866 "Could not copy envscript into place.",env=self.env)
868 # Setup metadata_overlay
869 if self.settings.has_key("METADATA_OVERLAY") and not self.settings.has_key("portage_confdir"):
870 if not os.path.exists(self.settings["chroot_path"] + "/etc/portage"):
871 cmd("mkdir " + self.settings["chroot_path"] + "/etc/portage")
872 myf = open(self.settings["chroot_path"] + "/etc/portage/modules", "a")
873 myf.write("portdbapi.auxdbmodule = cache.metadata_overlay.database\n")
876 # Copy over /etc/hosts from the host in case there are any
877 # specialties in there
878 if os.path.exists(self.settings["chroot_path"]+"/etc/hosts"):
879 cmd("mv "+self.settings["chroot_path"]+"/etc/hosts "+self.settings["chroot_path"]+\
880 "/etc/hosts.bck", "Could not backup /etc/hosts",env=self.env)
881 cmd("cp /etc/hosts "+self.settings["chroot_path"]+"/etc/hosts", "Could not copy /etc/hosts",env=self.env)
882 #self.override_cbuild()
883 #self.override_chost()
884 #self.override_cflags()
885 #self.override_cxxflags()
886 #self.override_ldflags()
887 # Modify and write out make.conf (for the chroot)
888 cmd("rm -f "+self.settings["chroot_path"]+"/etc/make.conf","Could not remove "+self.settings["chroot_path"]+"/etc/make.conf",\
890 myf=open(self.settings["chroot_path"]+"/etc/make.conf","w")
891 myf.write("# These settings were set by the catalyst build script that automatically\n# built this stage.\n")
892 myf.write("# Please consult /etc/make.conf.example for a more detailed example.\n")
893 if self.settings.has_key("CFLAGS"):
894 myf.write('CFLAGS="'+self.settings["CFLAGS"]+'"\n')
895 if self.settings.has_key("CXXFLAGS"):
896 myf.write('CXXFLAGS="'+self.settings["CXXFLAGS"]+'"\n')
898 myf.write('CXXFLAGS="${CFLAGS}"\n')
900 if self.settings.has_key("LDFLAGS"):
901 myf.write('LDFLAGS="'+self.settings["LDFLAGS"]+'"\n')
902 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")
903 if self.settings.has_key("CBUILD"):
904 myf.write('CBUILD="'+self.settings["CBUILD"]+'"\n')
905 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 it.\nCHOST="'+self.settings["CHOST"]+'"\n')
907 # Figure out what our USE vars are for building
909 if self.settings.has_key("HOSTUSE"):
910 myusevars.extend(self.settings["HOSTUSE"])
912 if self.settings.has_key("use"):
913 myusevars.extend(self.settings["use"])
914 myf.write('USE="'+string.join(myusevars)+'"\n')
916 # Setup the portage overlay
917 if self.settings.has_key("portage_overlay"):
918 # myf.write('PORTDIR_OVERLAY="'+string.join(self.settings["portage_overlay"])+'"\n')
919 myf.write('PORTDIR_OVERLAY="/usr/local/portage"\n')
922 touch(self.settings["autoresume_path"]+"chroot_setup")
925 if self.settings.has_key("AUTORESUME") \
926 and os.path.exists(self.settings["autoresume_path"]+"fsscript"):
927 print "Resume point detected, skipping fsscript operation..."
929 if self.settings.has_key("fsscript"):
930 if os.path.exists(self.settings["controller_file"]):
931 cmd("/bin/bash "+self.settings["controller_file"]+" fsscript","fsscript script failed.",env=self.env)
932 touch(self.settings["autoresume_path"]+"fsscript")
935 if self.settings.has_key("AUTORESUME") \
936 and os.path.exists(self.settings["autoresume_path"]+"rcupdate"):
937 print "Resume point detected, skipping rcupdate operation..."
939 if os.path.exists(self.settings["controller_file"]):
940 cmd("/bin/bash "+self.settings["controller_file"]+" rc-update","rc-update script failed.",env=self.env)
941 touch(self.settings["autoresume_path"]+"rcupdate")
944 if self.settings.has_key("AUTORESUME") \
945 and os.path.exists(self.settings["autoresume_path"]+"clean"):
946 print "Resume point detected, skipping clean operation..."
948 for x in self.settings["cleanables"]:
949 print "Cleaning chroot: "+x+"... "
950 cmd("rm -rf "+self.settings["destpath"]+x,"Couldn't clean "+x,env=self.env)
952 # put /etc/hosts back into place
953 if os.path.exists(self.settings["chroot_path"]+"/etc/hosts.bck"):
954 cmd("mv -f "+self.settings["chroot_path"]+"/etc/hosts.bck "+self.settings["chroot_path"]+"/etc/hosts", "Could not replace /etc/hosts",env=self.env)
957 if os.path.exists(self.settings["chroot_path"]+"/usr/local/portage"):
958 cmd("rm -rf "+self.settings["chroot_path"]+"/usr/local/portage", "Could not remove /usr/local/portage",env=self.env)
959 cmd("sed -i '/^PORTDIR_OVERLAY/d' "+self.settings["chroot_path"]+"/etc/make.conf", "Could not remove PORTDIR_OVERLAY from make.conf",env=self.env)
961 # clean up old and obsoleted files in /etc
962 if os.path.exists(self.settings["stage_path"]+"/etc"):
963 cmd("find "+self.settings["stage_path"]+"/etc -maxdepth 1 -name \"*-\" | xargs rm -f", "Could not remove stray files in /etc",env=self.env)
965 if os.path.exists(self.settings["controller_file"]):
966 cmd("/bin/bash "+self.settings["controller_file"]+" clean","clean script failed.",env=self.env)
967 touch(self.settings["autoresume_path"]+"clean")
970 if self.settings.has_key("AUTORESUME") \
971 and os.path.exists(self.settings["autoresume_path"]+"empty"):
972 print "Resume point detected, skipping empty operation..."
974 if self.settings.has_key(self.settings["spec_prefix"]+"/empty"):
975 if type(self.settings[self.settings["spec_prefix"]+"/empty"])==types.StringType:
976 self.settings[self.settings["spec_prefix"]+"/empty"]=self.settings[self.settings["spec_prefix"]+"/empty"].split()
977 for x in self.settings[self.settings["spec_prefix"]+"/empty"]:
978 myemp=self.settings["destpath"]+x
979 if not os.path.isdir(myemp):
980 print x,"not a directory or does not exist, skipping 'empty' operation."
982 print "Emptying directory",x
983 # stat the dir, delete the dir, recreate the dir and set
984 # the proper perms and ownership
985 mystat=os.stat(myemp)
987 os.makedirs(myemp,0755)
988 os.chown(myemp,mystat[ST_UID],mystat[ST_GID])
989 os.chmod(myemp,mystat[ST_MODE])
990 touch(self.settings["autoresume_path"]+"empty")
993 if self.settings.has_key("AUTORESUME") \
994 and os.path.exists(self.settings["autoresume_path"]+"remove"):
995 print "Resume point detected, skipping remove operation..."
997 if self.settings.has_key(self.settings["spec_prefix"]+"/rm"):
998 for x in self.settings[self.settings["spec_prefix"]+"/rm"]:
999 # we're going to shell out for all these cleaning operations,
1000 # so we get easy glob handling
1001 print "livecd: removing "+x
1002 os.system("rm -rf "+self.settings["chroot_path"]+x)
1004 if os.path.exists(self.settings["controller_file"]):
1005 cmd("/bin/bash "+self.settings["controller_file"]+" clean",\
1006 "Clean failed.",env=self.env)
1007 touch(self.settings["autoresume_path"]+"remove")
1014 if self.settings.has_key("AUTORESUME") \
1015 and os.path.exists(self.settings["autoresume_path"]+"preclean"):
1016 print "Resume point detected, skipping preclean operation..."
1019 if os.path.exists(self.settings["controller_file"]):
1020 cmd("/bin/bash "+self.settings["controller_file"]+" preclean","preclean script failed.",env=self.env)
1021 touch(self.settings["autoresume_path"]+"preclean")
1025 raise CatalystError, "Build failed, could not execute preclean"
1028 if self.settings.has_key("AUTORESUME") \
1029 and os.path.exists(self.settings["autoresume_path"]+"capture"):
1030 print "Resume point detected, skipping capture operation..."
1032 """capture target in a tarball"""
1033 mypath=self.settings["target_path"].split("/")
1034 # remove filename from path
1035 mypath=string.join(mypath[:-1],"/")
1037 # now make sure path exists
1038 if not os.path.exists(mypath):
1041 print "Creating stage tarball..."
1043 cmd("tar cjpf "+self.settings["target_path"]+" -C "+self.settings["stage_path"]+\
1044 " .","Couldn't create stage tarball",env=self.env)
1046 self.gen_digest_file(self.settings["target_path"])
1048 touch(self.settings["autoresume_path"]+"capture")
1050 def run_local(self):
1051 if self.settings.has_key("AUTORESUME") \
1052 and os.path.exists(self.settings["autoresume_path"]+"run_local"):
1053 print "Resume point detected, skipping run_local operation..."
1056 if os.path.exists(self.settings["controller_file"]):
1057 cmd("/bin/bash "+self.settings["controller_file"]+" run","run script failed.",env=self.env)
1058 touch(self.settings["autoresume_path"]+"run_local")
1060 except CatalystError:
1062 raise CatalystError,"Stage build aborting due to error."
1064 def setup_environment(self):
1065 # Modify the current environment. This is an ugly hack that should be
1066 # fixed. We need this to use the os.system() call since we can't
1067 # specify our own environ:
1068 for x in self.settings.keys():
1069 # sanitize var names by doing "s|/-.|_|g"
1070 varname="clst_"+string.replace(x,"/","_")
1071 varname=string.replace(varname,"-","_")
1072 varname=string.replace(varname,".","_")
1073 if type(self.settings[x])==types.StringType:
1074 # prefix to prevent namespace clashes:
1075 #os.environ[varname]=self.settings[x]
1076 self.env[varname]=self.settings[x]
1077 elif type(self.settings[x])==types.ListType:
1078 #os.environ[varname]=string.join(self.settings[x])
1079 self.env[varname]=string.join(self.settings[x])
1080 elif type(self.settings[x])==types.BooleanType:
1081 if self.settings[x]:
1082 self.env[varname]="true"
1084 self.env[varname]="false"
1085 if self.settings.has_key("makeopts"):
1086 self.env["MAKEOPTS"]=self.settings["makeopts"]
1089 self.chroot_lock.write_lock()
1091 # Kill any pids in the chroot
1092 self.kill_chroot_pids()
1094 # Check for mounts right away and abort if we cannot unmount them.
1095 self.mount_safety_check()
1097 if self.settings.has_key("CLEAR_AUTORESUME"):
1098 self.clear_autoresume()
1099 if self.settings.has_key("PURGE"):
1102 for x in self.settings["action_sequence"]:
1103 print "--- Running action sequence: "+x
1106 apply(getattr(self,x))
1108 self.mount_safety_check()
1111 self.chroot_lock.unlock()
1114 if self.settings.has_key("AUTORESUME") \
1115 and os.path.exists(self.settings["autoresume_path"]+"unmerge"):
1116 print "Resume point detected, skipping unmerge operation..."
1118 if self.settings.has_key(self.settings["spec_prefix"]+"/unmerge"):
1119 if type(self.settings[self.settings["spec_prefix"]+"/unmerge"])==types.StringType:
1120 self.settings[self.settings["spec_prefix"]+"/unmerge"]=[self.settings[self.settings["spec_prefix"]+"/unmerge"]]
1121 myunmerge=self.settings[self.settings["spec_prefix"]+"/unmerge"][:]
1123 for x in range(0,len(myunmerge)):
1124 #surround args with quotes for passing to bash,
1125 #allows things like "<" to remain intact
1126 myunmerge[x]="'"+myunmerge[x]+"'"
1127 myunmerge=string.join(myunmerge)
1129 #before cleaning, unmerge stuff:
1131 cmd("/bin/bash "+self.settings["controller_file"]+" unmerge "+ myunmerge,\
1132 "Unmerge script failed.",env=self.env)
1133 #cmd("/bin/bash "+self.settings["sharedir"]+"/targets/" \
1134 # +self.settings["target"]+"/unmerge.sh "+myunmerge,"Unmerge script failed.",env=self.env)
1135 print "unmerge shell script"
1136 except CatalystError:
1140 touch(self.settings["autoresume_path"]+"unmerge")
1142 def target_setup(self):
1143 if self.settings.has_key("AUTORESUME") \
1144 and os.path.exists(self.settings["autoresume_path"]+"target_setup"):
1145 print "Resume point detected, skipping target_setup operation..."
1147 print "Setting up filesystems per filesystem type"
1148 cmd("/bin/bash "+self.settings["controller_file"]+" target_image_setup "+ self.settings["target_path"],\
1149 "target_image_setup script failed.",env=self.env)
1150 touch(self.settings["autoresume_path"]+"target_setup")
1152 def setup_overlay(self):
1153 if self.settings.has_key("AUTORESUME") \
1154 and os.path.exists(self.settings["autoresume_path"]+"setup_overlay"):
1155 print "Resume point detected, skipping setup_overlay operation..."
1157 if self.settings.has_key(self.settings["spec_prefix"]+"/overlay"):
1158 for x in self.settings[self.settings["spec_prefix"]+"/overlay"]:
1159 if os.path.exists(x):
1160 cmd("rsync -a "+x+"/ "+\
1161 self.settings["target_path"], self.settings["spec_prefix"]+"overlay: "+x+" copy failed.",env=self.env)
1162 touch(self.settings["autoresume_path"]+"setup_overlay")
1164 def create_iso(self):
1165 if self.settings.has_key("AUTORESUME") \
1166 and os.path.exists(self.settings["autoresume_path"]+"create_iso"):
1167 print "Resume point detected, skipping create_iso operation..."
1169 # create the ISO - this is the preferred method (the iso scripts do not always work)
1170 if self.settings.has_key("iso"):
1171 cmd("/bin/bash "+self.settings["controller_file"]+" iso "+\
1172 self.settings["iso"],"ISO creation script failed.",env=self.env)
1173 self.gen_digest_file(self.settings["iso"])
1174 touch(self.settings["autoresume_path"]+"create_iso")
1178 print "WARNING livecd/iso was not defined."
1179 print "A CD Image will not be created, skipping create-iso.sh..."
1182 def build_packages(self):
1183 if self.settings.has_key("AUTORESUME") \
1184 and os.path.exists(self.settings["autoresume_path"]+"build_packages"):
1185 print "Resume point detected, skipping build_packages operation..."
1187 if self.settings.has_key(self.settings["spec_prefix"]+"/packages"):
1188 if self.settings.has_key("AUTORESUME") \
1189 and os.path.exists(self.settings["autoresume_path"]+"build_packages"):
1190 print "Resume point detected, skipping build_packages operation..."
1192 mypack=list_bashify(self.settings[self.settings["spec_prefix"]+"/packages"])
1194 cmd("/bin/bash "+self.settings["controller_file"]+\
1195 " build_packages "+mypack,"Error in attempt to build packages",env=self.env)
1196 touch(self.settings["autoresume_path"]+"build_packages")
1197 except CatalystError:
1199 raise CatalystError,self.settings["spec_prefix"] + "build aborting due to error."
1201 def build_kernel(self):
1202 if self.settings.has_key("AUTORESUME") \
1203 and os.path.exists(self.settings["autoresume_path"]+"build_kernel"):
1204 print "Resume point detected, skipping build_kernel operation..."
1206 if self.settings.has_key("boot/kernel"):
1208 mynames=self.settings["boot/kernel"]
1209 if type(mynames)==types.StringType:
1211 # execute the script that sets up the kernel build environment
1212 cmd("/bin/bash "+self.settings["controller_file"]+" pre-kmerge ",\
1213 "Runscript pre-kmerge failed",env=self.env)
1215 for kname in mynames:
1216 if self.settings.has_key("AUTORESUME") \
1217 and os.path.exists(self.settings["autoresume_path"]+"build_kernel_"+kname):
1218 print "Resume point detected, skipping build_kernel for "+kname+" operation..."
1221 if not os.path.exists(self.settings["boot/kernel/"+kname+"/config"]):
1223 raise CatalystError, "Can't find kernel config: " \
1224 +self.settings["boot/kernel/"+kname+"/config"]
1227 raise CatalystError, "Required value boot/kernel/config not specified"
1230 cmd("cp "+self.settings["boot/kernel/"+kname+"/config"]+" "+ \
1231 self.settings["chroot_path"]+"/var/tmp/"+kname+".config", \
1232 "Couldn't copy kernel config: "+self.settings["boot/kernel/"+kname+"/config"],\
1235 except CatalystError:
1238 # If we need to pass special options to the bootloader
1239 # for this kernel put them into the environment.
1240 if self.settings.has_key("boot/kernel/"+kname+"/kernelopts"):
1241 myopts=self.settings["boot/kernel/"+kname+"/kernelopts"]
1243 if type(myopts) != types.StringType:
1244 myopts = string.join(myopts)
1245 self.env[kname+"_kernelopts"]=myopts
1248 self.env[kname+"_kernelopts"]=""
1250 if not self.settings.has_key("boot/kernel/"+kname+"/extraversion"):
1251 self.settings["boot/kernel/"+kname+"/extraversion"]=""
1253 self.env["clst_kextraversion"]=self.settings["boot/kernel/"+kname+"/extraversion"]
1255 if self.settings.has_key("boot/kernel/"+kname+"/initramfs_overlay"):
1256 if os.path.exists(self.settings["boot/kernel/"+kname+"/initramfs_overlay"]):
1257 print "Copying initramfs_overlay dir " +self.settings["boot/kernel/"+kname+"/initramfs_overlay"]
1259 cmd("mkdir -p "+self.settings["chroot_path"]+"/tmp/initramfs_overlay/" + \
1260 self.settings["boot/kernel/"+kname+"/initramfs_overlay"],env=self.env)
1262 cmd("cp -R "+self.settings["boot/kernel/"+kname+"/initramfs_overlay"]+"/* " + \
1263 self.settings["chroot_path"] + "/tmp/initramfs_overlay/" + \
1264 self.settings["boot/kernel/"+kname+"/initramfs_overlay"],\
1268 # execute the script that builds the kernel
1269 cmd("/bin/bash "+self.settings["controller_file"]+" kernel "+kname,\
1270 "Runscript kernel build failed",env=self.env)
1272 if self.settings.has_key("boot/kernel/"+kname+"/initramfs_overlay"):
1273 if os.path.exists(self.settings["chroot_path"]+"/tmp/initramfs_overlay/"):
1274 print "Cleaning up temporary overlay dir"
1275 cmd("rm -R "+self.settings["chroot_path"]+"/tmp/initramfs_overlay/",env=self.env)
1277 touch(self.settings["autoresume_path"]+"build_kernel_"+kname)
1279 # execute the script that cleans up the kernel build environment
1280 cmd("/bin/bash "+self.settings["controller_file"]+" post-kmerge ",\
1281 "Runscript post-kmerge failed",env=self.env)
1283 touch(self.settings["autoresume_path"]+"build_kernel")
1285 except CatalystError:
1287 raise CatalystError,"build aborting due to kernel build error."
1289 def bootloader(self):
1290 if self.settings.has_key("AUTORESUME") \
1291 and os.path.exists(self.settings["autoresume_path"]+"bootloader"):
1292 print "Resume point detected, skipping bootloader operation..."
1295 cmd("/bin/bash "+self.settings["controller_file"]+" bootloader " + self.settings["target_path"],\
1296 "Bootloader runscript failed.",env=self.env)
1297 touch(self.settings["autoresume_path"]+"bootloader")
1298 except CatalystError:
1300 raise CatalystError,"Runscript aborting due to error."
1302 def livecd_update(self):
1303 if self.settings.has_key("AUTORESUME") \
1304 and os.path.exists(self.settings["autoresume_path"]+"livecd_update"):
1305 print "Resume point detected, skipping build_packages operation..."
1308 cmd("/bin/bash "+self.settings["controller_file"]+" livecd-update",\
1309 "livecd-update failed.",env=self.env)
1310 touch(self.settings["autoresume_path"]+"livecd_update")
1312 except CatalystError:
1314 raise CatalystError,"build aborting due to livecd_update error."
1316 def clear_chroot(self):
1317 myemp=self.settings["chroot_path"]
1318 if os.path.isdir(myemp):
1319 print "Emptying directory",myemp
1320 # stat the dir, delete the dir, recreate the dir and set
1321 # the proper perms and ownership
1322 mystat=os.stat(myemp)
1323 #cmd("rm -rf "+myemp, "Could not remove existing file: "+myemp,env=self.env)
1324 if os.uname()[0] == "FreeBSD": # There's no easy way to change flags recursively in python
1325 os.system("chflags -R noschg "+myemp)
1326 shutil.rmtree(myemp)
1327 os.makedirs(myemp,0755)
1328 os.chown(myemp,mystat[ST_UID],mystat[ST_GID])
1329 os.chmod(myemp,mystat[ST_MODE])
1331 def clear_packages(self):
1332 if self.settings.has_key("PKGCACHE"):
1333 print "purging the pkgcache ..."
1335 myemp=self.settings["pkgcache_path"]
1336 if os.path.isdir(myemp):
1337 print "Emptying directory",myemp
1338 # stat the dir, delete the dir, recreate the dir and set
1339 # the proper perms and ownership
1340 mystat=os.stat(myemp)
1341 #cmd("rm -rf "+myemp, "Could not remove existing file: "+myemp,env=self.env)
1342 shutil.rmtree(myemp)
1343 os.makedirs(myemp,0755)
1344 os.chown(myemp,mystat[ST_UID],mystat[ST_GID])
1345 os.chmod(myemp,mystat[ST_MODE])
1347 def clear_kerncache(self):
1348 if self.settings.has_key("KERNCACHE"):
1349 print "purging the kerncache ..."
1351 myemp=self.settings["kerncache_path"]
1352 if os.path.isdir(myemp):
1353 print "Emptying directory",myemp
1354 # stat the dir, delete the dir, recreate the dir and set
1355 # the proper perms and ownership
1356 mystat=os.stat(myemp)
1357 #cmd("rm -rf "+myemp, "Could not remove existing file: "+myemp,env=self.env)
1358 shutil.rmtree(myemp)
1359 os.makedirs(myemp,0755)
1360 os.chown(myemp,mystat[ST_UID],mystat[ST_GID])
1361 os.chmod(myemp,mystat[ST_MODE])
1363 def clear_autoresume(self):
1364 # clean resume points since they are no longer needed
1365 if self.settings.has_key("AUTORESUME"):
1366 print "Removing AutoResume Points: ..."
1367 myemp=self.settings["autoresume_path"]
1368 if os.path.isdir(myemp):
1369 if self.settings.has_key("AUTORESUME"):
1370 print "Emptying directory",myemp
1371 # stat the dir, delete the dir, recreate the dir and set
1372 # the proper perms and ownership
1373 mystat=os.stat(myemp)
1374 if os.uname()[0] == "FreeBSD":
1375 cmd("chflags -R noschg "+myemp, "Could not remove immutable flag for file " + myemp)
1376 #cmd("rm -rf "+myemp, "Could not remove existing file: "+myemp,env-self.env)
1377 shutil.rmtree(myemp)
1378 os.makedirs(myemp,0755)
1379 os.chown(myemp,mystat[ST_UID],mystat[ST_GID])
1380 os.chmod(myemp,mystat[ST_MODE])
1382 def gen_digest_file(self,file):
1383 if os.path.exists(file+".DIGESTS"):
1384 os.remove(file+".DIGESTS")
1385 if self.settings.has_key("digests"):
1386 if os.path.exists(file):
1387 myf=open(file+".DIGESTS","w")
1389 for i in self.settings["digests"].split():
1394 if self.settings.has_key("VERBOSE"):
1395 hash=generate_hash(file,hash_function=j,verbose=True)
1397 hash=generate_hash(file,hash_function=j)
1402 countdown(10,"Purging Caches ...")
1403 if self.settings.has_key("PURGE"):
1404 print "clearing autoresume ..."
1405 self.clear_autoresume()
1407 print "clearing chroot ..."
1410 print "clearing package cache ..."
1411 self.clear_packages()
1413 print "clearing kerncache ..."
1414 self.clear_kerncache()
1416 #vim: ts=4 sw=4 sta et sts=4 ai