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 # Copy over /etc/hosts from the host in case there are any
869 # specialties in there
870 if os.path.exists(self.settings["chroot_path"]+"/etc/hosts"):
871 cmd("mv "+self.settings["chroot_path"]+"/etc/hosts "+self.settings["chroot_path"]+\
872 "/etc/hosts.bck", "Could not backup /etc/hosts",env=self.env)
873 cmd("cp /etc/hosts "+self.settings["chroot_path"]+"/etc/hosts", "Could not copy /etc/hosts",env=self.env)
874 #self.override_cbuild()
875 #self.override_chost()
876 #self.override_cflags()
877 #self.override_cxxflags()
878 #self.override_ldflags()
879 # Modify and write out make.conf (for the chroot)
880 cmd("rm -f "+self.settings["chroot_path"]+"/etc/make.conf","Could not remove "+self.settings["chroot_path"]+"/etc/make.conf",\
882 myf=open(self.settings["chroot_path"]+"/etc/make.conf","w")
883 myf.write("# These settings were set by the catalyst build script that automatically\n# built this stage.\n")
884 myf.write("# Please consult /etc/make.conf.example for a more detailed example.\n")
885 if self.settings.has_key("CFLAGS"):
886 myf.write('CFLAGS="'+self.settings["CFLAGS"]+'"\n')
887 if self.settings.has_key("CXXFLAGS"):
888 myf.write('CXXFLAGS="'+self.settings["CXXFLAGS"]+'"\n')
890 myf.write('CXXFLAGS="${CFLAGS}"\n')
892 if self.settings.has_key("LDFLAGS"):
893 myf.write('LDFLAGS="'+self.settings["LDFLAGS"]+'"\n')
894 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")
895 if self.settings.has_key("CBUILD"):
896 myf.write('CBUILD="'+self.settings["CBUILD"]+'"\n')
897 myf.write('CHOST="'+self.settings["CHOST"]+'"\n')
899 # Figure out what our USE vars are for building
901 if self.settings.has_key("HOSTUSE"):
902 myusevars.extend(self.settings["HOSTUSE"])
904 if self.settings.has_key("use"):
905 myusevars.extend(self.settings["use"])
906 myf.write('USE="'+string.join(myusevars)+'"\n')
908 # Setup the portage overlay
909 if self.settings.has_key("portage_overlay"):
910 # myf.write('PORTDIR_OVERLAY="'+string.join(self.settings["portage_overlay"])+'"\n')
911 myf.write('PORTDIR_OVERLAY="/usr/local/portage"\n')
914 touch(self.settings["autoresume_path"]+"chroot_setup")
917 if self.settings.has_key("AUTORESUME") \
918 and os.path.exists(self.settings["autoresume_path"]+"fsscript"):
919 print "Resume point detected, skipping fsscript operation..."
921 if self.settings.has_key("fsscript"):
922 if os.path.exists(self.settings["controller_file"]):
923 cmd("/bin/bash "+self.settings["controller_file"]+" fsscript","fsscript script failed.",env=self.env)
924 touch(self.settings["autoresume_path"]+"fsscript")
927 if self.settings.has_key("AUTORESUME") \
928 and os.path.exists(self.settings["autoresume_path"]+"rcupdate"):
929 print "Resume point detected, skipping rcupdate operation..."
931 if os.path.exists(self.settings["controller_file"]):
932 cmd("/bin/bash "+self.settings["controller_file"]+" rc-update","rc-update script failed.",env=self.env)
933 touch(self.settings["autoresume_path"]+"rcupdate")
936 if self.settings.has_key("AUTORESUME") \
937 and os.path.exists(self.settings["autoresume_path"]+"clean"):
938 print "Resume point detected, skipping clean operation..."
940 for x in self.settings["cleanables"]:
941 print "Cleaning chroot: "+x+"... "
942 cmd("rm -rf "+self.settings["destpath"]+x,"Couldn't clean "+x,env=self.env)
944 # put /etc/hosts back into place
945 if os.path.exists(self.settings["chroot_path"]+"/etc/hosts.bck"):
946 cmd("mv -f "+self.settings["chroot_path"]+"/etc/hosts.bck "+self.settings["chroot_path"]+"/etc/hosts", "Could not replace /etc/hosts",env=self.env)
949 if os.path.exists(self.settings["chroot_path"]+"/usr/local/portage"):
950 cmd("rm -rf "+self.settings["chroot_path"]+"/usr/local/portage", "Could not remove /usr/local/portage",env=self.env)
951 cmd("sed -i '/^PORTDIR_OVERLAY/d' "+self.settings["chroot_path"]+"/etc/make.conf", "Could not remove PORTDIR_OVERLAY from make.conf",env=self.env)
953 # clean up old and obsoleted files in /etc
954 if os.path.exists(self.settings["stage_path"]+"/etc"):
955 cmd("find "+self.settings["stage_path"]+"/etc -maxdepth 1 -name \"*-\" | xargs rm -f", "Could not remove stray files in /etc",env=self.env)
957 if os.path.exists(self.settings["controller_file"]):
958 cmd("/bin/bash "+self.settings["controller_file"]+" clean","clean script failed.",env=self.env)
959 touch(self.settings["autoresume_path"]+"clean")
962 if self.settings.has_key("AUTORESUME") \
963 and os.path.exists(self.settings["autoresume_path"]+"empty"):
964 print "Resume point detected, skipping empty operation..."
966 if self.settings.has_key(self.settings["spec_prefix"]+"/empty"):
967 if type(self.settings[self.settings["spec_prefix"]+"/empty"])==types.StringType:
968 self.settings[self.settings["spec_prefix"]+"/empty"]=self.settings[self.settings["spec_prefix"]+"/empty"].split()
969 for x in self.settings[self.settings["spec_prefix"]+"/empty"]:
970 myemp=self.settings["destpath"]+x
971 if not os.path.isdir(myemp):
972 print x,"not a directory or does not exist, skipping 'empty' operation."
974 print "Emptying directory",x
975 # stat the dir, delete the dir, recreate the dir and set
976 # the proper perms and ownership
977 mystat=os.stat(myemp)
979 os.makedirs(myemp,0755)
980 os.chown(myemp,mystat[ST_UID],mystat[ST_GID])
981 os.chmod(myemp,mystat[ST_MODE])
982 touch(self.settings["autoresume_path"]+"empty")
985 if self.settings.has_key("AUTORESUME") \
986 and os.path.exists(self.settings["autoresume_path"]+"remove"):
987 print "Resume point detected, skipping remove operation..."
989 if self.settings.has_key(self.settings["spec_prefix"]+"/rm"):
990 for x in self.settings[self.settings["spec_prefix"]+"/rm"]:
991 # we're going to shell out for all these cleaning operations,
992 # so we get easy glob handling
993 print "livecd: removing "+x
994 os.system("rm -rf "+self.settings["chroot_path"]+x)
996 if os.path.exists(self.settings["controller_file"]):
997 cmd("/bin/bash "+self.settings["controller_file"]+" clean",\
998 "Clean failed.",env=self.env)
999 touch(self.settings["autoresume_path"]+"remove")
1006 if self.settings.has_key("AUTORESUME") \
1007 and os.path.exists(self.settings["autoresume_path"]+"preclean"):
1008 print "Resume point detected, skipping preclean operation..."
1011 if os.path.exists(self.settings["controller_file"]):
1012 cmd("/bin/bash "+self.settings["controller_file"]+" preclean","preclean script failed.",env=self.env)
1013 touch(self.settings["autoresume_path"]+"preclean")
1017 raise CatalystError, "Build failed, could not execute preclean"
1020 if self.settings.has_key("AUTORESUME") \
1021 and os.path.exists(self.settings["autoresume_path"]+"capture"):
1022 print "Resume point detected, skipping capture operation..."
1024 """capture target in a tarball"""
1025 mypath=self.settings["target_path"].split("/")
1026 # remove filename from path
1027 mypath=string.join(mypath[:-1],"/")
1029 # now make sure path exists
1030 if not os.path.exists(mypath):
1033 print "Creating stage tarball..."
1035 cmd("tar cjpf "+self.settings["target_path"]+" -C "+self.settings["stage_path"]+\
1036 " .","Couldn't create stage tarball",env=self.env)
1038 self.gen_digest_file(self.settings["target_path"])
1040 touch(self.settings["autoresume_path"]+"capture")
1042 def run_local(self):
1043 if self.settings.has_key("AUTORESUME") \
1044 and os.path.exists(self.settings["autoresume_path"]+"run_local"):
1045 print "Resume point detected, skipping run_local operation..."
1048 if os.path.exists(self.settings["controller_file"]):
1049 cmd("/bin/bash "+self.settings["controller_file"]+" run","run script failed.",env=self.env)
1050 touch(self.settings["autoresume_path"]+"run_local")
1052 except CatalystError:
1054 raise CatalystError,"Stage build aborting due to error."
1056 def setup_environment(self):
1057 # Modify the current environment. This is an ugly hack that should be
1058 # fixed. We need this to use the os.system() call since we can't
1059 # specify our own environ:
1060 for x in self.settings.keys():
1061 # sanitize var names by doing "s|/-.|_|g"
1062 varname="clst_"+string.replace(x,"/","_")
1063 varname=string.replace(varname,"-","_")
1064 varname=string.replace(varname,".","_")
1065 if type(self.settings[x])==types.StringType:
1066 # prefix to prevent namespace clashes:
1067 #os.environ[varname]=self.settings[x]
1068 self.env[varname]=self.settings[x]
1069 elif type(self.settings[x])==types.ListType:
1070 #os.environ[varname]=string.join(self.settings[x])
1071 self.env[varname]=string.join(self.settings[x])
1072 elif type(self.settings[x])==types.BooleanType:
1073 if self.settings[x]:
1074 self.env[varname]="true"
1076 self.env[varname]="false"
1077 if self.settings.has_key("makeopts"):
1078 self.env["MAKEOPTS"]=self.settings["makeopts"]
1081 self.chroot_lock.write_lock()
1083 # Kill any pids in the chroot
1084 self.kill_chroot_pids()
1086 # Check for mounts right away and abort if we cannot unmount them.
1087 self.mount_safety_check()
1089 if self.settings.has_key("CLEAR_AUTORESUME"):
1090 self.clear_autoresume()
1091 if self.settings.has_key("PURGE"):
1094 for x in self.settings["action_sequence"]:
1095 print "--- Running action sequence: "+x
1098 apply(getattr(self,x))
1100 self.mount_safety_check()
1103 self.chroot_lock.unlock()
1106 if self.settings.has_key("AUTORESUME") \
1107 and os.path.exists(self.settings["autoresume_path"]+"unmerge"):
1108 print "Resume point detected, skipping unmerge operation..."
1110 if self.settings.has_key(self.settings["spec_prefix"]+"/unmerge"):
1111 if type(self.settings[self.settings["spec_prefix"]+"/unmerge"])==types.StringType:
1112 self.settings[self.settings["spec_prefix"]+"/unmerge"]=[self.settings[self.settings["spec_prefix"]+"/unmerge"]]
1113 myunmerge=self.settings[self.settings["spec_prefix"]+"/unmerge"][:]
1115 for x in range(0,len(myunmerge)):
1116 #surround args with quotes for passing to bash,
1117 #allows things like "<" to remain intact
1118 myunmerge[x]="'"+myunmerge[x]+"'"
1119 myunmerge=string.join(myunmerge)
1121 #before cleaning, unmerge stuff:
1123 cmd("/bin/bash "+self.settings["controller_file"]+" unmerge "+ myunmerge,\
1124 "Unmerge script failed.",env=self.env)
1125 #cmd("/bin/bash "+self.settings["sharedir"]+"/targets/" \
1126 # +self.settings["target"]+"/unmerge.sh "+myunmerge,"Unmerge script failed.",env=self.env)
1127 print "unmerge shell script"
1128 except CatalystError:
1132 touch(self.settings["autoresume_path"]+"unmerge")
1134 def target_setup(self):
1135 if self.settings.has_key("AUTORESUME") \
1136 and os.path.exists(self.settings["autoresume_path"]+"target_setup"):
1137 print "Resume point detected, skipping target_setup operation..."
1139 print "Setting up filesystems per filesystem type"
1140 cmd("/bin/bash "+self.settings["controller_file"]+" target_image_setup "+ self.settings["target_path"],\
1141 "target_image_setup script failed.",env=self.env)
1142 touch(self.settings["autoresume_path"]+"target_setup")
1144 def setup_overlay(self):
1145 if self.settings.has_key("AUTORESUME") \
1146 and os.path.exists(self.settings["autoresume_path"]+"setup_overlay"):
1147 print "Resume point detected, skipping setup_overlay operation..."
1149 if self.settings.has_key(self.settings["spec_prefix"]+"/overlay"):
1150 for x in self.settings[self.settings["spec_prefix"]+"/overlay"]:
1151 if os.path.exists(x):
1152 cmd("rsync -a "+x+"/ "+\
1153 self.settings["target_path"], self.settings["spec_prefix"]+"overlay: "+x+" copy failed.",env=self.env)
1154 touch(self.settings["autoresume_path"]+"setup_overlay")
1156 def create_iso(self):
1157 if self.settings.has_key("AUTORESUME") \
1158 and os.path.exists(self.settings["autoresume_path"]+"create_iso"):
1159 print "Resume point detected, skipping create_iso operation..."
1161 # create the ISO - this is the preferred method (the iso scripts do not always work)
1162 if self.settings.has_key("iso"):
1163 cmd("/bin/bash "+self.settings["controller_file"]+" iso "+\
1164 self.settings["iso"],"ISO creation script failed.",env=self.env)
1165 self.gen_digest_file(self.settings["iso"])
1166 touch(self.settings["autoresume_path"]+"create_iso")
1170 print "WARNING livecd/iso was not defined."
1171 print "A CD Image will not be created, skipping create-iso.sh..."
1174 def build_packages(self):
1175 if self.settings.has_key("AUTORESUME") \
1176 and os.path.exists(self.settings["autoresume_path"]+"build_packages"):
1177 print "Resume point detected, skipping build_packages operation..."
1179 if self.settings.has_key(self.settings["spec_prefix"]+"/packages"):
1180 if self.settings.has_key("AUTORESUME") \
1181 and os.path.exists(self.settings["autoresume_path"]+"build_packages"):
1182 print "Resume point detected, skipping build_packages operation..."
1184 mypack=list_bashify(self.settings[self.settings["spec_prefix"]+"/packages"])
1186 cmd("/bin/bash "+self.settings["controller_file"]+\
1187 " build_packages "+mypack,"Error in attempt to build packages",env=self.env)
1188 touch(self.settings["autoresume_path"]+"build_packages")
1189 except CatalystError:
1191 raise CatalystError,self.settings["spec_prefix"] + "build aborting due to error."
1193 def build_kernel(self):
1194 if self.settings.has_key("AUTORESUME") \
1195 and os.path.exists(self.settings["autoresume_path"]+"build_kernel"):
1196 print "Resume point detected, skipping build_kernel operation..."
1198 if self.settings.has_key("boot/kernel"):
1200 mynames=self.settings["boot/kernel"]
1201 if type(mynames)==types.StringType:
1203 # execute the script that sets up the kernel build environment
1204 cmd("/bin/bash "+self.settings["controller_file"]+" pre-kmerge ",\
1205 "Runscript pre-kmerge failed",env=self.env)
1207 for kname in mynames:
1208 if self.settings.has_key("AUTORESUME") \
1209 and os.path.exists(self.settings["autoresume_path"]+"build_kernel_"+kname):
1210 print "Resume point detected, skipping build_kernel for "+kname+" operation..."
1213 if not os.path.exists(self.settings["boot/kernel/"+kname+"/config"]):
1215 raise CatalystError, "Can't find kernel config: " \
1216 +self.settings["boot/kernel/"+kname+"/config"]
1219 raise CatalystError, "Required value boot/kernel/config not specified"
1222 cmd("cp "+self.settings["boot/kernel/"+kname+"/config"]+" "+ \
1223 self.settings["chroot_path"]+"/var/tmp/"+kname+".config", \
1224 "Couldn't copy kernel config: "+self.settings["boot/kernel/"+kname+"/config"],\
1227 except CatalystError:
1230 # If we need to pass special options to the bootloader
1231 # for this kernel put them into the environment.
1232 if self.settings.has_key("boot/kernel/"+kname+"/kernelopts"):
1233 myopts=self.settings["boot/kernel/"+kname+"/kernelopts"]
1235 if type(myopts) != types.StringType:
1236 myopts = string.join(myopts)
1237 self.env[kname+"_kernelopts"]=myopts
1240 self.env[kname+"_kernelopts"]=""
1242 if not self.settings.has_key("boot/kernel/"+kname+"/extraversion"):
1243 self.settings["boot/kernel/"+kname+"/extraversion"]=""
1245 self.env["clst_kextraversion"]=self.settings["boot/kernel/"+kname+"/extraversion"]
1247 if self.settings.has_key("boot/kernel/"+kname+"/initramfs_overlay"):
1248 if os.path.exists(self.settings["boot/kernel/"+kname+"/initramfs_overlay"]):
1249 print "Copying initramfs_overlay dir " +self.settings["boot/kernel/"+kname+"/initramfs_overlay"]
1251 cmd("mkdir -p "+self.settings["chroot_path"]+"/tmp/initramfs_overlay/" + \
1252 self.settings["boot/kernel/"+kname+"/initramfs_overlay"],env=self.env)
1254 cmd("cp -R "+self.settings["boot/kernel/"+kname+"/initramfs_overlay"]+"/* " + \
1255 self.settings["chroot_path"] + "/tmp/initramfs_overlay/" + \
1256 self.settings["boot/kernel/"+kname+"/initramfs_overlay"],\
1260 # execute the script that builds the kernel
1261 cmd("/bin/bash "+self.settings["controller_file"]+" kernel "+kname,\
1262 "Runscript kernel build failed",env=self.env)
1264 if self.settings.has_key("boot/kernel/"+kname+"/initramfs_overlay"):
1265 if os.path.exists(self.settings["chroot_path"]+"/tmp/initramfs_overlay/"):
1266 print "Cleaning up temporary overlay dir"
1267 cmd("rm -R "+self.settings["chroot_path"]+"/tmp/initramfs_overlay/",env=self.env)
1269 touch(self.settings["autoresume_path"]+"build_kernel_"+kname)
1271 # execute the script that cleans up the kernel build environment
1272 cmd("/bin/bash "+self.settings["controller_file"]+" post-kmerge ",\
1273 "Runscript post-kmerge failed",env=self.env)
1275 touch(self.settings["autoresume_path"]+"build_kernel")
1277 except CatalystError:
1279 raise CatalystError,"build aborting due to kernel build error."
1281 def bootloader(self):
1282 if self.settings.has_key("AUTORESUME") \
1283 and os.path.exists(self.settings["autoresume_path"]+"bootloader"):
1284 print "Resume point detected, skipping bootloader operation..."
1287 cmd("/bin/bash "+self.settings["controller_file"]+" bootloader " + self.settings["target_path"],\
1288 "Bootloader runscript failed.",env=self.env)
1289 touch(self.settings["autoresume_path"]+"bootloader")
1290 except CatalystError:
1292 raise CatalystError,"Runscript aborting due to error."
1294 def livecd_update(self):
1295 if self.settings.has_key("AUTORESUME") \
1296 and os.path.exists(self.settings["autoresume_path"]+"livecd_update"):
1297 print "Resume point detected, skipping build_packages operation..."
1300 cmd("/bin/bash "+self.settings["controller_file"]+" livecd-update",\
1301 "livecd-update failed.",env=self.env)
1302 touch(self.settings["autoresume_path"]+"livecd_update")
1304 except CatalystError:
1306 raise CatalystError,"build aborting due to livecd_update error."
1308 def clear_chroot(self):
1309 myemp=self.settings["chroot_path"]
1310 if os.path.isdir(myemp):
1311 print "Emptying directory",myemp
1312 # stat the dir, delete the dir, recreate the dir and set
1313 # the proper perms and ownership
1314 mystat=os.stat(myemp)
1315 #cmd("rm -rf "+myemp, "Could not remove existing file: "+myemp,env=self.env)
1316 if os.uname()[0] == "FreeBSD": # There's no easy way to change flags recursively in python
1317 os.system("chflags -R noschg "+myemp)
1318 shutil.rmtree(myemp)
1319 os.makedirs(myemp,0755)
1320 os.chown(myemp,mystat[ST_UID],mystat[ST_GID])
1321 os.chmod(myemp,mystat[ST_MODE])
1323 def clear_packages(self):
1324 if self.settings.has_key("PKGCACHE"):
1325 print "purging the pkgcache ..."
1327 myemp=self.settings["pkgcache_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 shutil.rmtree(myemp)
1335 os.makedirs(myemp,0755)
1336 os.chown(myemp,mystat[ST_UID],mystat[ST_GID])
1337 os.chmod(myemp,mystat[ST_MODE])
1339 def clear_kerncache(self):
1340 if self.settings.has_key("KERNCACHE"):
1341 print "purging the kerncache ..."
1343 myemp=self.settings["kerncache_path"]
1344 if os.path.isdir(myemp):
1345 print "Emptying directory",myemp
1346 # stat the dir, delete the dir, recreate the dir and set
1347 # the proper perms and ownership
1348 mystat=os.stat(myemp)
1349 #cmd("rm -rf "+myemp, "Could not remove existing file: "+myemp,env=self.env)
1350 shutil.rmtree(myemp)
1351 os.makedirs(myemp,0755)
1352 os.chown(myemp,mystat[ST_UID],mystat[ST_GID])
1353 os.chmod(myemp,mystat[ST_MODE])
1355 def clear_autoresume(self):
1356 # clean resume points since they are no longer needed
1357 if self.settings.has_key("AUTORESUME"):
1358 print "Removing AutoResume Points: ..."
1359 myemp=self.settings["autoresume_path"]
1360 if os.path.isdir(myemp):
1361 if self.settings.has_key("AUTORESUME"):
1362 print "Emptying directory",myemp
1363 # stat the dir, delete the dir, recreate the dir and set
1364 # the proper perms and ownership
1365 mystat=os.stat(myemp)
1366 #cmd("rm -rf "+myemp, "Could not remove existing file: "+myemp,env-self.env)
1367 shutil.rmtree(myemp)
1368 os.makedirs(myemp,0755)
1369 os.chown(myemp,mystat[ST_UID],mystat[ST_GID])
1370 os.chmod(myemp,mystat[ST_MODE])
1372 def gen_digest_file(self,file):
1373 if os.path.exists(file+".DIGESTS"):
1374 os.remove(file+".DIGESTS")
1375 if self.settings.has_key("digests"):
1376 if os.path.exists(file):
1377 myf=open(file+".DIGESTS","w")
1379 for i in self.settings["digests"].split():
1384 if self.settings.has_key("VERBOSE"):
1385 hash=generate_hash(file,hash_function=j,verbose=True)
1387 hash=generate_hash(file,hash_function=j)
1392 countdown(10,"Purging Caches ...")
1393 if self.settings.has_key("PURGE"):
1394 print "clearing autoresume ..."
1395 self.clear_autoresume()
1397 print "clearing chroot ..."
1400 print "clearing package cache ..."
1401 self.clear_packages()
1403 print "clearing kerncache ..."
1404 self.clear_kerncache()
1406 #vim: ts=4 sw=4 sta et sts=4 ai