Make sure we always append bindist use flag to all targets.
[catalyst.git] / modules / generic_stage_target.py
1 import os,string,imp,types,shutil
2 from catalyst_support import *
3 from generic_target import *
4 from stat import *
5 import catalyst_lock
6
7 class generic_stage_target(generic_target):
8         """
9         This class does all of the chroot setup, copying of files, etc. It is
10         the driver class for pretty much everything that Catalyst does.
11         """
12         def __init__(self,myspec,addlargs):
13                 self.required_values.extend(["version_stamp","target","subarch",\
14                         "rel_type","profile","snapshot","source_subpath"])
15
16                 self.valid_values.extend(["version_stamp","target","subarch",\
17                         "rel_type","profile","snapshot","source_subpath","portage_confdir",\
18                         "cflags","cxxflags","ldflags","cbuild","hostuse","portage_overlay",\
19                         "distcc_hosts","makeopts","pkgcache_path","kerncache_path"])
20
21                 self.set_valid_build_kernel_vars(addlargs)
22                 generic_target.__init__(self,myspec,addlargs)
23
24                 """
25                 The semantics of subarchmap and machinemap changed a bit in 2.0.3 to
26                 work better with vapier's CBUILD stuff. I've removed the "monolithic"
27                 machinemap from this file and split up its contents amongst the
28                 various arch/foo.py files.
29
30                 When register() is called on each module in the arch/ dir, it now
31                 returns a tuple instead of acting on the subarchmap dict that is
32                 passed to it. The tuple contains the values that were previously
33                 added to subarchmap as well as a new list of CHOSTs that go along
34                 with that arch. This allows us to build machinemap on the fly based
35                 on the keys in subarchmap and the values of the 2nd list returned
36                 (tmpmachinemap).
37
38                 Also, after talking with vapier. I have a slightly better idea of what
39                 certain variables are used for and what they should be set to. Neither
40                 'buildarch' or 'hostarch' are used directly, so their value doesn't
41                 really matter. They are just compared to determine if we are
42                 cross-compiling. Because of this, they are just set to the name of the
43                 module in arch/ that the subarch is part of to make things simpler.
44                 The entire build process is still based off of 'subarch' like it was
45                 previously. -agaffney
46                 """
47
48                 self.archmap = {}
49                 self.subarchmap = {}
50                 machinemap = {}
51                 for x in [x[:-3] for x in os.listdir(self.settings["sharedir"]+\
52                         "/arch/") if x.endswith(".py")]:
53                         try:
54                                 fh=open(self.settings["sharedir"]+"/arch/"+x+".py")
55                                 """
56                                 This next line loads the plugin as a module and assigns it to
57                                 archmap[x]
58                                 """
59                                 self.archmap[x]=imp.load_module(x,fh,"arch/"+x+\
60                                         ".py",(".py","r",imp.PY_SOURCE))
61                                 """
62                                 This next line registers all the subarches supported in the
63                                 plugin
64                                 """
65                                 tmpsubarchmap, tmpmachinemap = self.archmap[x].register()
66                                 self.subarchmap.update(tmpsubarchmap)
67                                 for machine in tmpmachinemap:
68                                         machinemap[machine] = x
69                                 for subarch in tmpsubarchmap:
70                                         machinemap[subarch] = x
71                                 fh.close()
72                         except IOError:
73                                 """
74                                 This message should probably change a bit, since everything in
75                                 the dir should load just fine. If it doesn't, it's probably a
76                                 syntax error in the module
77                                 """
78                                 msg("Can't find/load "+x+".py plugin in "+\
79                                         self.settings["sharedir"]+"/arch/")
80
81                 if self.settings.has_key("chost"):
82                         hostmachine = self.settings["chost"].split("-")[0]
83                         if not machinemap.has_key(hostmachine):
84                                 raise CatalystError, "Unknown host machine type "+hostmachine
85                         self.settings["hostarch"]=machinemap[hostmachine]
86                 else:
87                         hostmachine = self.settings["subarch"]
88                         if machinemap.has_key(hostmachine):
89                                 hostmachine = machinemap[hostmachine]
90                         self.settings["hostarch"]=hostmachine
91                 if self.settings.has_key("cbuild"):
92                         buildmachine = self.settings["cbuild"].split("-")[0]
93                 else:
94                         buildmachine = os.uname()[4]
95                 if not machinemap.has_key(buildmachine):
96                         raise CatalystError, "Unknown build machine type "+buildmachine
97                 self.settings["buildarch"]=machinemap[buildmachine]
98                 self.settings["crosscompile"]=(self.settings["hostarch"]!=\
99                         self.settings["buildarch"])
100
101                 """ Call arch constructor, pass our settings """
102                 try:
103                         self.arch=self.subarchmap[self.settings["subarch"]](self.settings)
104                 except KeyError:
105                         print "Invalid subarch: "+self.settings["subarch"]
106                         print "Choose one of the following:",
107                         for x in self.subarchmap:
108                                 print x,
109                         print
110                         sys.exit(2)
111
112                 print "Using target:",self.settings["target"]
113                 """ Print a nice informational message """
114                 if self.settings["buildarch"]==self.settings["hostarch"]:
115                         print "Building natively for",self.settings["hostarch"]
116                 elif self.settings["crosscompile"]:
117                         print "Cross-compiling on",self.settings["buildarch"],\
118                                 "for different machine type",self.settings["hostarch"]
119                 else:
120                         print "Building on",self.settings["buildarch"],\
121                                 "for alternate personality type",self.settings["hostarch"]
122
123                 """ This must be set first as other set_ options depend on this """
124                 self.set_spec_prefix()
125
126                 """ Define all of our core variables """
127                 self.set_target_profile()
128                 self.set_target_subpath()
129                 self.set_source_subpath()
130
131                 """ Set paths """
132                 self.set_snapshot_path()
133                 self.set_root_path()
134                 self.set_source_path()
135                 self.set_snapcache_path()
136                 self.set_chroot_path()
137                 self.set_autoresume_path()
138                 self.set_dest_path()
139                 self.set_stage_path()
140                 self.set_target_path()
141
142                 self.set_controller_file()
143                 self.set_action_sequence()
144                 self.set_use()
145                 self.set_cleanables()
146                 self.set_iso_volume_id()
147                 self.set_build_kernel_vars()
148                 self.set_fsscript()
149                 self.set_install_mask()
150                 self.set_rcadd()
151                 self.set_rcdel()
152                 self.set_cdtar()
153                 self.set_fstype()
154                 self.set_fsops()
155                 self.set_iso()
156                 self.set_packages()
157                 self.set_rm()
158                 self.set_linuxrc()
159                 self.set_busybox_config()
160                 self.set_overlay()
161                 self.set_portage_overlay()
162                 self.set_root_overlay()
163
164                 """
165                 This next line checks to make sure that the specified variables exist
166                 on disk.
167                 """
168                 #pdb.set_trace()
169                 file_locate(self.settings,["source_path","snapshot_path","distdir"],\
170                         expand=0)
171                 """ If we are using portage_confdir, check that as well. """
172                 if self.settings.has_key("portage_confdir"):
173                         file_locate(self.settings,["portage_confdir"],expand=0)
174
175                 """ Setup our mount points """
176                 if self.settings.has_key("SNAPCACHE"):
177                         self.mounts=["/proc","/dev","/usr/portage","/usr/portage/distfiles","/var/tmp/portage"]
178                         self.mountmap={"/proc":"/proc","/dev":"/dev","/dev/pts":"/dev/pts",\
179                                 "/usr/portage":self.settings["snapshot_cache_path"]+"/portage",\
180                                 "/usr/portage/distfiles":self.settings["distdir"],"/var/tmp/portage":"tmpfs"}
181                 else:
182                         self.mounts=["/proc","/dev","/usr/portage/distfiles","/var/tmp/portage"]
183                         self.mountmap={"/proc":"/proc","/dev":"/dev","/dev/pts":"/dev/pts",\
184                                 "/usr/portage/distfiles":self.settings["distdir"],"/var/tmp/portage":"tmpfs"}
185                 if os.uname()[0] == "Linux":
186                         self.mounts.append("/dev/pts")
187
188                 self.set_mounts()
189
190                 """
191                 Configure any user specified options (either in catalyst.conf or on
192                 the command line).
193                 """
194                 if self.settings.has_key("PKGCACHE"):
195                         self.set_pkgcache_path()
196                         print "Location of the package cache is "+\
197                                 self.settings["pkgcache_path"]
198                         self.mounts.append("/usr/portage/packages")
199                         self.mountmap["/usr/portage/packages"]=\
200                                 self.settings["pkgcache_path"]
201
202                 if self.settings.has_key("KERNCACHE"):
203                         self.set_kerncache_path()
204                         print "Location of the kerncache is "+\
205                                 self.settings["kerncache_path"]
206                         self.mounts.append("/tmp/kerncache")
207                         self.mountmap["/tmp/kerncache"]=self.settings["kerncache_path"]
208
209                 if self.settings.has_key("CCACHE"):
210                         if os.environ.has_key("CCACHE_DIR"):
211                                 ccdir=os.environ["CCACHE_DIR"]
212                                 del os.environ["CCACHE_DIR"]
213                         else:
214                                 ccdir="/root/.ccache"
215                         if not os.path.isdir(ccdir):
216                                 raise CatalystError,\
217                                         "Compiler cache support can't be enabled (can't find "+\
218                                         ccdir+")"
219                         self.mounts.append("/var/tmp/ccache")
220                         self.mountmap["/var/tmp/ccache"]=ccdir
221                         """ for the chroot: """
222                         self.env["CCACHE_DIR"]="/var/tmp/ccache"
223
224                 if self.settings.has_key("ICECREAM"):
225                         self.mounts.append("/var/cache/icecream")
226                         self.mountmap["/var/cache/icecream"]="/var/cache/icecream"
227                         self.env["PATH"]="/usr/lib/icecc/bin:"+self.env["PATH"]
228
229                 if self.settings.has_key("port_logdir"):
230                         self.mounts.append("/var/log/portage")
231                         self.mountmap["/var/log/portage"]=self.settings["port_logdir"]
232                         self.env["PORT_LOGDIR"]="/var/log/portage"
233                         self.env["PORT_LOGDIR_CLEAN"]='find "${PORT_LOGDIR}" -type f ! -name "summary.log*" -mtime +30 -delete'
234
235         def override_cbuild(self):
236                 if self.makeconf.has_key("CBUILD"):
237                         self.settings["CBUILD"]=self.makeconf["CBUILD"]
238
239         def override_chost(self):
240                 if self.makeconf.has_key("CHOST"):
241                         self.settings["CHOST"]=self.makeconf["CHOST"]
242
243         def override_cflags(self):
244                 if self.makeconf.has_key("CFLAGS"):
245                         self.settings["CFLAGS"]=self.makeconf["CFLAGS"]
246
247         def override_cxxflags(self):
248                 if self.makeconf.has_key("CXXFLAGS"):
249                         self.settings["CXXFLAGS"]=self.makeconf["CXXFLAGS"]
250
251         def override_ldflags(self):
252                 if self.makeconf.has_key("LDFLAGS"):
253                         self.settings["LDFLAGS"]=self.makeconf["LDFLAGS"]
254
255         def set_install_mask(self):
256                 if self.settings.has_key("install_mask"):
257                         if type(self.settings["install_mask"])!=types.StringType:
258                                 self.settings["install_mask"]=\
259                                         string.join(self.settings["install_mask"])
260
261         def set_spec_prefix(self):
262                 self.settings["spec_prefix"]=self.settings["target"]
263
264         def set_target_profile(self):
265                 self.settings["target_profile"]=self.settings["profile"]
266
267         def set_target_subpath(self):
268                 self.settings["target_subpath"]=self.settings["rel_type"]+"/"+\
269                                 self.settings["target"]+"-"+self.settings["subarch"]+"-"+\
270                                 self.settings["version_stamp"]
271
272         def set_source_subpath(self):
273                 if type(self.settings["source_subpath"])!=types.StringType:
274                         raise CatalystError,\
275                                 "source_subpath should have been a string. Perhaps you have something wrong in your spec file?"
276
277         def set_pkgcache_path(self):
278                 if self.settings.has_key("pkgcache_path"):
279                         if type(self.settings["pkgcache_path"])!=types.StringType:
280                                 self.settings["pkgcache_path"]=\
281                                         normpath(string.join(self.settings["pkgcache_path"]))
282                 else:
283                         self.settings["pkgcache_path"]=\
284                                 normpath(self.settings["storedir"]+"/packages/"+\
285                                 self.settings["target_subpath"]+"/")
286
287         def set_kerncache_path(self):
288                 if self.settings.has_key("kerncache_path"):
289                         if type(self.settings["kerncache_path"])!=types.StringType:
290                                 self.settings["kerncache_path"]=\
291                                         normpath(string.join(self.settings["kerncache_path"]))
292                 else:
293                         self.settings["kerncache_path"]=normpath(self.settings["storedir"]+\
294                                 "/kerncache/"+self.settings["target_subpath"]+"/")
295
296         def set_target_path(self):
297                 self.settings["target_path"]=normpath(self.settings["storedir"]+\
298                         "/builds/"+self.settings["target_subpath"]+".tar.bz2")
299                 if self.settings.has_key("AUTORESUME")\
300                         and os.path.exists(self.settings["autoresume_path"]+\
301                                 "setup_target_path"):
302                         print \
303                                 "Resume point detected, skipping target path setup operation..."
304                 else:
305                         """ First clean up any existing target stuff """
306                         # XXX WTF are we removing the old tarball before we start building the
307                         # XXX new one? If the build fails, you don't want to be left with
308                         # XXX nothing at all
309 #                       if os.path.isfile(self.settings["target_path"]):
310 #                               cmd("rm -f "+self.settings["target_path"],\
311 #                                       "Could not remove existing file: "\
312 #                                       +self.settings["target_path"],env=self.env)
313                         touch(self.settings["autoresume_path"]+"setup_target_path")
314
315                         if not os.path.exists(self.settings["storedir"]+"/builds/"):
316                                 os.makedirs(self.settings["storedir"]+"/builds/")
317
318         def set_fsscript(self):
319                 if self.settings.has_key(self.settings["spec_prefix"]+"/fsscript"):
320                         self.settings["fsscript"]=\
321                                 self.settings[self.settings["spec_prefix"]+"/fsscript"]
322                         del self.settings[self.settings["spec_prefix"]+"/fsscript"]
323
324         def set_rcadd(self):
325                 if self.settings.has_key(self.settings["spec_prefix"]+"/rcadd"):
326                         self.settings["rcadd"]=\
327                                 self.settings[self.settings["spec_prefix"]+"/rcadd"]
328                         del self.settings[self.settings["spec_prefix"]+"/rcadd"]
329
330         def set_rcdel(self):
331                 if self.settings.has_key(self.settings["spec_prefix"]+"/rcdel"):
332                         self.settings["rcdel"]=\
333                                 self.settings[self.settings["spec_prefix"]+"/rcdel"]
334                         del self.settings[self.settings["spec_prefix"]+"/rcdel"]
335
336         def set_cdtar(self):
337                 if self.settings.has_key(self.settings["spec_prefix"]+"/cdtar"):
338                         self.settings["cdtar"]=\
339                                 normpath(self.settings[self.settings["spec_prefix"]+"/cdtar"])
340                         del self.settings[self.settings["spec_prefix"]+"/cdtar"]
341
342         def set_iso(self):
343                 if self.settings.has_key(self.settings["spec_prefix"]+"/iso"):
344                         if self.settings[self.settings["spec_prefix"]+"/iso"].startswith('/'):
345                                 self.settings["iso"]=\
346                                         normpath(self.settings[self.settings["spec_prefix"]+"/iso"])
347                         else:
348                                 # This automatically prepends the build dir to the ISO output path
349                                 # if it doesn't start with a /
350                                 self.settings["iso"] = normpath(self.settings["storedir"] + \
351                                         "/builds/" + self.settings["rel_type"] + "/" + \
352                                         self.settings[self.settings["spec_prefix"]+"/iso"])
353                         del self.settings[self.settings["spec_prefix"]+"/iso"]
354
355         def set_fstype(self):
356                 if self.settings.has_key(self.settings["spec_prefix"]+"/fstype"):
357                         self.settings["fstype"]=\
358                                 self.settings[self.settings["spec_prefix"]+"/fstype"]
359                         del self.settings[self.settings["spec_prefix"]+"/fstype"]
360
361                 if not self.settings.has_key("fstype"):
362                         self.settings["fstype"]="normal"
363                         for x in self.valid_values:
364                                 if x ==  self.settings["spec_prefix"]+"/fstype":
365                                         print "\n"+self.settings["spec_prefix"]+\
366                                                 "/fstype is being set to the default of \"normal\"\n"
367
368         def set_fsops(self):
369                 if self.settings.has_key("fstype"):
370                         self.valid_values.append("fsops")
371                         if self.settings.has_key(self.settings["spec_prefix"]+"/fsops"):
372                                 self.settings["fsops"]=\
373                                         self.settings[self.settings["spec_prefix"]+"/fsops"]
374                                 del self.settings[self.settings["spec_prefix"]+"/fsops"]
375
376         def set_source_path(self):
377                 if self.settings.has_key("SEEDCACHE")\
378                         and os.path.isdir(normpath(self.settings["storedir"]+"/tmp/"+\
379                                 self.settings["source_subpath"]+"/")):
380                         self.settings["source_path"]=normpath(self.settings["storedir"]+\
381                                 "/tmp/"+self.settings["source_subpath"]+"/")
382                 else:
383                         self.settings["source_path"]=normpath(self.settings["storedir"]+\
384                                 "/builds/"+self.settings["source_subpath"]+".tar.bz2")
385                         if os.path.isfile(self.settings["source_path"]):
386                                 # XXX: Is this even necessary if the previous check passes?
387                                 if os.path.exists(self.settings["source_path"]):
388                                         self.settings["source_path_hash"]=\
389                                                 generate_hash(self.settings["source_path"],\
390                                                 hash_function=self.settings["hash_function"],\
391                                                 verbose=False)
392                 print "Source path set to "+self.settings["source_path"]
393                 if os.path.isdir(self.settings["source_path"]):
394                         print "\tIf this is not desired, remove this directory or turn off"
395                         print "\tseedcache in the options of catalyst.conf the source path"
396                         print "\twill then be "+\
397                                 normpath(self.settings["storedir"]+"/builds/"+\
398                                 self.settings["source_subpath"]+".tar.bz2\n")
399
400         def set_dest_path(self):
401                 if self.settings.has_key("root_path"):
402                         self.settings["destpath"]=normpath(self.settings["chroot_path"]+\
403                                 self.settings["root_path"])
404                 else:
405                         self.settings["destpath"]=normpath(self.settings["chroot_path"])
406
407         def set_cleanables(self):
408                 self.settings["cleanables"]=["/etc/resolv.conf","/var/tmp/*","/tmp/*",\
409                         "/root/*","/usr/portage"]
410
411         def set_snapshot_path(self):
412                 self.settings["snapshot_path"]=normpath(self.settings["storedir"]+\
413                         "/snapshots/portage-"+self.settings["snapshot"]+".tar.xz")
414
415                 if os.path.exists(self.settings["snapshot_path"]):
416                         self.settings["snapshot_path_hash"]=\
417                                 generate_hash(self.settings["snapshot_path"],\
418                                 hash_function=self.settings["hash_function"],verbose=False)
419                 else:
420                         self.settings["snapshot_path"]=normpath(self.settings["storedir"]+\
421                                 "/snapshots/portage-"+self.settings["snapshot"]+".tar.bz2")
422
423                         if os.path.exists(self.settings["snapshot_path"]):
424                                 self.settings["snapshot_path_hash"]=\
425                                         generate_hash(self.settings["snapshot_path"],\
426                                         hash_function=self.settings["hash_function"],verbose=False)
427
428         def set_snapcache_path(self):
429                 if self.settings.has_key("SNAPCACHE"):
430                         self.settings["snapshot_cache_path"]=\
431                                 normpath(self.settings["snapshot_cache"]+"/"+\
432                                 self.settings["snapshot"]+"/")
433                         self.snapcache_lock=\
434                                 catalyst_lock.LockDir(self.settings["snapshot_cache_path"])
435                         print "Caching snapshot to "+self.settings["snapshot_cache_path"]
436
437         def set_chroot_path(self):
438                 """
439                 NOTE: the trailing slash is very important!
440                 Things *will* break without it!
441                 """
442                 self.settings["chroot_path"]=normpath(self.settings["storedir"]+\
443                         "/tmp/"+self.settings["target_subpath"]+"/")
444                 self.chroot_lock=catalyst_lock.LockDir(self.settings["chroot_path"])
445
446         def set_autoresume_path(self):
447                 self.settings["autoresume_path"]=normpath(self.settings["storedir"]+\
448                         "/tmp/"+self.settings["rel_type"]+"/"+".autoresume-"+\
449                         self.settings["target"]+"-"+self.settings["subarch"]+"-"+\
450                         self.settings["version_stamp"]+"/")
451                 if self.settings.has_key("AUTORESUME"):
452                         print "The autoresume path is " + self.settings["autoresume_path"]
453                 if not os.path.exists(self.settings["autoresume_path"]):
454                         os.makedirs(self.settings["autoresume_path"],0755)
455
456         def set_controller_file(self):
457                 self.settings["controller_file"]=normpath(self.settings["sharedir"]+\
458                         "/targets/"+self.settings["target"]+"/"+self.settings["target"]+\
459                         "-controller.sh")
460
461         def set_iso_volume_id(self):
462                 if self.settings.has_key(self.settings["spec_prefix"]+"/volid"):
463                         self.settings["iso_volume_id"]=\
464                                 self.settings[self.settings["spec_prefix"]+"/volid"]
465                         if len(self.settings["iso_volume_id"])>32:
466                                 raise CatalystError,\
467                                         "ISO volume ID must not exceed 32 characters."
468                 else:
469                         self.settings["iso_volume_id"]="catalyst "+self.settings["snapshot"]
470
471         def set_action_sequence(self):
472                 """ Default action sequence for run method """
473                 self.settings["action_sequence"]=["unpack","unpack_snapshot",\
474                                 "setup_confdir","portage_overlay",\
475                                 "base_dirs","bind","chroot_setup","setup_environment",\
476                                 "run_local","preclean","unbind","clean"]
477 #               if self.settings.has_key("TARBALL") or \
478 #                       not self.settings.has_key("FETCH"):
479                 if not self.settings.has_key("FETCH"):
480                         self.settings["action_sequence"].append("capture")
481                 self.settings["action_sequence"].append("clear_autoresume")
482
483         def set_use(self):
484                 if self.settings.has_key(self.settings["spec_prefix"]+"/use"):
485                         self.settings["use"]=\
486                                 self.settings[self.settings["spec_prefix"]+"/use"]
487                         del self.settings[self.settings["spec_prefix"]+"/use"]
488                 if not self.settings.has_key("use"):
489                         self.settings["use"]=""
490                 if type(self.settings["use"])==types.StringType:
491                         self.settings["use"]=self.settings["use"].split()
492
493                 # Force bindist for all targets
494                 self.settings["use"].append("bindist")
495
496         def set_stage_path(self):
497                 self.settings["stage_path"]=normpath(self.settings["chroot_path"])
498
499         def set_mounts(self):
500                 pass
501
502         def set_packages(self):
503                 pass
504
505         def set_rm(self):
506                 if self.settings.has_key(self.settings["spec_prefix"]+"/rm"):
507                         if type(self.settings[self.settings["spec_prefix"]+\
508                                 "/rm"])==types.StringType:
509                                 self.settings[self.settings["spec_prefix"]+"/rm"]=\
510                                         self.settings[self.settings["spec_prefix"]+"/rm"].split()
511
512         def set_linuxrc(self):
513                 if self.settings.has_key(self.settings["spec_prefix"]+"/linuxrc"):
514                         if type(self.settings[self.settings["spec_prefix"]+\
515                                 "/linuxrc"])==types.StringType:
516                                 self.settings["linuxrc"]=\
517                                         self.settings[self.settings["spec_prefix"]+"/linuxrc"]
518                                 del self.settings[self.settings["spec_prefix"]+"/linuxrc"]
519
520         def set_busybox_config(self):
521                 if self.settings.has_key(self.settings["spec_prefix"]+"/busybox_config"):
522                         if type(self.settings[self.settings["spec_prefix"]+\
523                                 "/busybox_config"])==types.StringType:
524                                 self.settings["busybox_config"]=\
525                                         self.settings[self.settings["spec_prefix"]+"/busybox_config"]
526                                 del self.settings[self.settings["spec_prefix"]+"/busybox_config"]
527
528         def set_portage_overlay(self):
529                 if self.settings.has_key("portage_overlay"):
530                         if type(self.settings["portage_overlay"])==types.StringType:
531                                 self.settings["portage_overlay"]=\
532                                         self.settings["portage_overlay"].split()
533                         print "portage_overlay directories are set to: \""+\
534                                 string.join(self.settings["portage_overlay"])+"\""
535
536         def set_overlay(self):
537                 if self.settings.has_key(self.settings["spec_prefix"]+"/overlay"):
538                         if type(self.settings[self.settings["spec_prefix"]+\
539                                 "/overlay"])==types.StringType:
540                                 self.settings[self.settings["spec_prefix"]+"/overlay"]=\
541                                         self.settings[self.settings["spec_prefix"]+\
542                                         "/overlay"].split()
543
544         def set_root_overlay(self):
545                 if self.settings.has_key(self.settings["spec_prefix"]+"/root_overlay"):
546                         if type(self.settings[self.settings["spec_prefix"]+\
547                                 "/root_overlay"])==types.StringType:
548                                 self.settings[self.settings["spec_prefix"]+"/root_overlay"]=\
549                                         self.settings[self.settings["spec_prefix"]+\
550                                         "/root_overlay"].split()
551
552         def set_root_path(self):
553                 """ ROOT= variable for emerges """
554                 self.settings["root_path"]="/"
555
556         def set_valid_build_kernel_vars(self,addlargs):
557                 if addlargs.has_key("boot/kernel"):
558                         if type(addlargs["boot/kernel"])==types.StringType:
559                                 loopy=[addlargs["boot/kernel"]]
560                         else:
561                                 loopy=addlargs["boot/kernel"]
562
563                         for x in loopy:
564                                 self.valid_values.append("boot/kernel/"+x+"/aliases")
565                                 self.valid_values.append("boot/kernel/"+x+"/config")
566                                 self.valid_values.append("boot/kernel/"+x+"/console")
567                                 self.valid_values.append("boot/kernel/"+x+"/extraversion")
568                                 self.valid_values.append("boot/kernel/"+x+"/gk_action")
569                                 self.valid_values.append("boot/kernel/"+x+"/gk_kernargs")
570                                 self.valid_values.append("boot/kernel/"+x+"/initramfs_overlay")
571                                 self.valid_values.append("boot/kernel/"+x+"/machine_type")
572                                 self.valid_values.append("boot/kernel/"+x+"/sources")
573                                 self.valid_values.append("boot/kernel/"+x+"/softlevel")
574                                 self.valid_values.append("boot/kernel/"+x+"/use")
575                                 self.valid_values.append("boot/kernel/"+x+"/packages")
576                                 if addlargs.has_key("boot/kernel/"+x+"/packages"):
577                                         if type(addlargs["boot/kernel/"+x+\
578                                                 "/packages"])==types.StringType:
579                                                 addlargs["boot/kernel/"+x+"/packages"]=\
580                                                         [addlargs["boot/kernel/"+x+"/packages"]]
581
582         def set_build_kernel_vars(self):
583                 if self.settings.has_key(self.settings["spec_prefix"]+"/gk_mainargs"):
584                         self.settings["gk_mainargs"]=\
585                                 self.settings[self.settings["spec_prefix"]+"/gk_mainargs"]
586                         del self.settings[self.settings["spec_prefix"]+"/gk_mainargs"]
587
588         def kill_chroot_pids(self):
589                 print "Checking for processes running in chroot and killing them."
590
591                 """
592                 Force environment variables to be exported so script can see them
593                 """
594                 self.setup_environment()
595
596                 if os.path.exists(self.settings["sharedir"]+\
597                         "/targets/support/kill-chroot-pids.sh"):
598                         cmd("/bin/bash "+self.settings["sharedir"]+\
599                                 "/targets/support/kill-chroot-pids.sh",\
600                                 "kill-chroot-pids script failed.",env=self.env)
601
602         def mount_safety_check(self):
603                 mypath=self.settings["chroot_path"]
604
605                 """
606                 Check and verify that none of our paths in mypath are mounted. We don't
607                 want to clean up with things still mounted, and this allows us to check.
608                 Returns 1 on ok, 0 on "something is still mounted" case.
609                 """
610
611                 if not os.path.exists(mypath):
612                         return
613
614                 for x in self.mounts:
615                         if not os.path.exists(mypath+x):
616                                 continue
617
618                         if ismount(mypath+x):
619                                 """ Something is still mounted "" """
620                                 try:
621                                         print x+" is still mounted; performing auto-bind-umount...",
622                                         """ Try to umount stuff ourselves """
623                                         self.unbind()
624                                         if ismount(mypath+x):
625                                                 raise CatalystError, "Auto-unbind failed for "+x
626                                         else:
627                                                 print "Auto-unbind successful..."
628                                 except CatalystError:
629                                         raise CatalystError, "Unable to auto-unbind "+x
630
631         def unpack(self):
632                 unpack=True
633
634                 clst_unpack_hash=read_from_clst(self.settings["autoresume_path"]+\
635                         "unpack")
636
637                 if self.settings.has_key("SEEDCACHE"):
638                         if os.path.isdir(self.settings["source_path"]):
639                                 """ SEEDCACHE Is a directory, use rsync """
640                                 unpack_cmd="rsync -a --delete "+self.settings["source_path"]+\
641                                         " "+self.settings["chroot_path"]
642                                 display_msg="\nStarting rsync from "+\
643                                         self.settings["source_path"]+"\nto "+\
644                                         self.settings["chroot_path"]+\
645                                         " (This may take some time) ...\n"
646                                 error_msg="Rsync of "+self.settings["source_path"]+" to "+\
647                                         self.settings["chroot_path"]+" failed."
648                         else:
649                                 """ SEEDCACHE is a not a directory, try untar'ing """
650                                 print "Referenced SEEDCACHE does not appear to be a directory, trying to untar..."
651                                 display_msg="\nStarting tar extract from "+\
652                                         self.settings["source_path"]+"\nto "+\
653                                         self.settings["chroot_path"]+\
654                                                 " (This may take some time) ...\n"
655                                 if "bz2" == self.settings["chroot_path"][-3:]:
656                                         unpack_cmd="tar -I lbzip2 -xpf "+self.settings["source_path"]+" -C "+\
657                                                 self.settings["chroot_path"]
658                                 else:
659                                         unpack_cmd="tar xpf "+self.settings["source_path"]+" -C "+\
660                                                 self.settings["chroot_path"]
661                                 error_msg="Tarball extraction of "+\
662                                         self.settings["source_path"]+" to "+\
663                                         self.settings["chroot_path"]+" failed."
664                 else:
665                         """ No SEEDCACHE, use tar """
666                         display_msg="\nStarting tar extract from "+\
667                                 self.settings["source_path"]+"\nto "+\
668                                 self.settings["chroot_path"]+\
669                                 " (This may take some time) ...\n"
670                         if "bz2" == self.settings["chroot_path"][-3:]:
671                                 unpack_cmd="tar -I lbzip2 -xpf "+self.settings["source_path"]+" -C "+\
672                                         self.settings["chroot_path"]
673                         else:
674                                 unpack_cmd="tar xpf "+self.settings["source_path"]+" -C "+\
675                                         self.settings["chroot_path"]
676                         error_msg="Tarball extraction of "+self.settings["source_path"]+\
677                                 " to "+self.settings["chroot_path"]+" failed."
678
679                 if self.settings.has_key("AUTORESUME"):
680                         if os.path.isdir(self.settings["source_path"]) \
681                                 and os.path.exists(self.settings["autoresume_path"]+"unpack"):
682                                 """ Autoresume is valid, SEEDCACHE is valid """
683                                 unpack=False
684                                 invalid_snapshot=False
685
686                         elif os.path.isfile(self.settings["source_path"]) \
687                                 and self.settings["source_path_hash"]==clst_unpack_hash:
688                                 """ Autoresume is valid, tarball is valid """
689                                 unpack=False
690                                 invalid_snapshot=True
691
692                         elif os.path.isdir(self.settings["source_path"]) \
693                                 and not os.path.exists(self.settings["autoresume_path"]+\
694                                 "unpack"):
695                                 """ Autoresume is invalid, SEEDCACHE """
696                                 unpack=True
697                                 invalid_snapshot=False
698
699                         elif os.path.isfile(self.settings["source_path"]) \
700                                 and self.settings["source_path_hash"]!=clst_unpack_hash:
701                                 """ Autoresume is invalid, tarball """
702                                 unpack=True
703                                 invalid_snapshot=True
704                 else:
705                         """ No autoresume, SEEDCACHE """
706                         if self.settings.has_key("SEEDCACHE"):
707                                 """ SEEDCACHE so let's run rsync and let it clean up """
708                                 if os.path.isdir(self.settings["source_path"]):
709                                         unpack=True
710                                         invalid_snapshot=False
711                                 elif os.path.isfile(self.settings["source_path"]):
712                                         """ Tarball so unpack and remove anything already there """
713                                         unpack=True
714                                         invalid_snapshot=True
715                                 """ No autoresume, no SEEDCACHE """
716                         else:
717                                 """ Tarball so unpack and remove anything already there """
718                                 if os.path.isfile(self.settings["source_path"]):
719                                         unpack=True
720                                         invalid_snapshot=True
721                                 elif os.path.isdir(self.settings["source_path"]):
722                                         """ We should never reach this, so something is very wrong """
723                                         raise CatalystError,\
724                                                 "source path is a dir but seedcache is not enabled"
725
726                 if unpack:
727                         self.mount_safety_check()
728
729                         if invalid_snapshot:
730                                 if self.settings.has_key("AUTORESUME"):
731                                         print "No Valid Resume point detected, cleaning up..."
732
733                                 self.clear_autoresume()
734                                 self.clear_chroot()
735
736                         if not os.path.exists(self.settings["chroot_path"]):
737                                 os.makedirs(self.settings["chroot_path"])
738
739                         if not os.path.exists(self.settings["chroot_path"]+"/tmp"):
740                                 os.makedirs(self.settings["chroot_path"]+"/tmp",1777)
741
742                         if self.settings.has_key("PKGCACHE"):
743                                 if not os.path.exists(self.settings["pkgcache_path"]):
744                                         os.makedirs(self.settings["pkgcache_path"],0755)
745
746                         if self.settings.has_key("KERNCACHE"):
747                                 if not os.path.exists(self.settings["kerncache_path"]):
748                                         os.makedirs(self.settings["kerncache_path"],0755)
749
750                         print display_msg
751                         cmd(unpack_cmd,error_msg,env=self.env)
752
753                         if self.settings.has_key("source_path_hash"):
754                                 myf=open(self.settings["autoresume_path"]+"unpack","w")
755                                 myf.write(self.settings["source_path_hash"])
756                                 myf.close()
757                         else:
758                                 touch(self.settings["autoresume_path"]+"unpack")
759                 else:
760                         print "Resume point detected, skipping unpack operation..."
761
762         def unpack_snapshot(self):
763                 unpack=True
764                 snapshot_hash=read_from_clst(self.settings["autoresume_path"]+\
765                         "unpack_portage")
766
767                 if self.settings.has_key("SNAPCACHE"):
768                         snapshot_cache_hash=\
769                                 read_from_clst(self.settings["snapshot_cache_path"]+\
770                                 "catalyst-hash")
771                         destdir=self.settings["snapshot_cache_path"]
772                         if "bz2" == self.settings["chroot_path"][-3:]:
773                                 unpack_cmd="tar -I lbzip2 -xpf "+self.settings["snapshot_path"]+" -C "+destdir
774                         else:
775                                 unpack_cmd="tar xpf "+self.settings["snapshot_path"]+" -C "+destdir
776                         unpack_errmsg="Error unpacking snapshot"
777                         cleanup_msg="Cleaning up invalid snapshot cache at \n\t"+\
778                                 self.settings["snapshot_cache_path"]+\
779                                 " (This can take a long time)..."
780                         cleanup_errmsg="Error removing existing snapshot cache directory."
781                         self.snapshot_lock_object=self.snapcache_lock
782
783                         if self.settings["snapshot_path_hash"]==snapshot_cache_hash:
784                                 print "Valid snapshot cache, skipping unpack of portage tree..."
785                                 unpack=False
786                 else:
787                         destdir=normpath(self.settings["chroot_path"]+"/usr/portage")
788                         cleanup_errmsg="Error removing existing snapshot directory."
789                         cleanup_msg=\
790                                 "Cleaning up existing portage tree (This can take a long time)..."
791                         if "bz2" == self.settings["chroot_path"][-3:]:
792                                 unpack_cmd="tar -I lbzip2 -xpf "+self.settings["snapshot_path"]+" -C "+\
793                                         self.settings["chroot_path"]+"/usr"
794                         else:
795                                 unpack_cmd="tar xpf "+self.settings["snapshot_path"]+" -C "+\
796                                         self.settings["chroot_path"]+"/usr"
797                         unpack_errmsg="Error unpacking snapshot"
798
799                         if self.settings.has_key("AUTORESUME") \
800                                 and os.path.exists(self.settings["chroot_path"]+\
801                                         "/usr/portage/") \
802                                 and os.path.exists(self.settings["autoresume_path"]\
803                                         +"unpack_portage") \
804                                 and self.settings["snapshot_path_hash"] == snapshot_hash:
805                                         print \
806                                                 "Valid Resume point detected, skipping unpack of portage tree..."
807                                         unpack=False
808
809                 if unpack:
810                         if self.settings.has_key("SNAPCACHE"):
811                                 self.snapshot_lock_object.write_lock()
812                         if os.path.exists(destdir):
813                                 print cleanup_msg
814                                 cleanup_cmd="rm -rf "+destdir
815                                 cmd(cleanup_cmd,cleanup_errmsg,env=self.env)
816                         if not os.path.exists(destdir):
817                                 os.makedirs(destdir,0755)
818
819                         print "Unpacking portage tree (This can take a long time) ..."
820                         cmd(unpack_cmd,unpack_errmsg,env=self.env)
821
822                         if self.settings.has_key("SNAPCACHE"):
823                                 myf=open(self.settings["snapshot_cache_path"]+"catalyst-hash","w")
824                                 myf.write(self.settings["snapshot_path_hash"])
825                                 myf.close()
826                         else:
827                                 print "Setting snapshot autoresume point"
828                                 myf=open(self.settings["autoresume_path"]+"unpack_portage","w")
829                                 myf.write(self.settings["snapshot_path_hash"])
830                                 myf.close()
831
832                         if self.settings.has_key("SNAPCACHE"):
833                                 self.snapshot_lock_object.unlock()
834
835         def config_profile_link(self):
836                 if self.settings.has_key("AUTORESUME") \
837                         and os.path.exists(self.settings["autoresume_path"]+\
838                                 "config_profile_link"):
839                         print \
840                                 "Resume point detected, skipping config_profile_link operation..."
841                 else:
842                         # TODO: zmedico and I discussed making this a directory and pushing
843                         # in a parent file, as well as other user-specified configuration.
844                         print "Configuring profile link..."
845                         cmd("rm -f "+self.settings["chroot_path"]+"/etc/portage/make.profile",\
846                                         "Error zapping profile link",env=self.env)
847                         cmd("mkdir -p "+self.settings["chroot_path"]+"/etc/portage/")
848                         cmd("ln -sf ../../usr/portage/profiles/"+\
849                                 self.settings["target_profile"]+" "+\
850                                 self.settings["chroot_path"]+"/etc/portage/make.profile",\
851                                 "Error creating profile link",env=self.env)
852                         touch(self.settings["autoresume_path"]+"config_profile_link")
853
854         def setup_confdir(self):
855                 if self.settings.has_key("AUTORESUME") \
856                         and os.path.exists(self.settings["autoresume_path"]+\
857                                 "setup_confdir"):
858                         print "Resume point detected, skipping setup_confdir operation..."
859                 else:
860                         if self.settings.has_key("portage_confdir"):
861                                 print "Configuring /etc/portage..."
862                                 cmd("rsync -a "+self.settings["portage_confdir"]+"/ "+\
863                                         self.settings["chroot_path"]+"/etc/portage/",\
864                                         "Error copying /etc/portage",env=self.env)
865                                 touch(self.settings["autoresume_path"]+"setup_confdir")
866
867         def portage_overlay(self):
868                 """ We copy the contents of our overlays to /usr/local/portage """
869                 if self.settings.has_key("portage_overlay"):
870                         for x in self.settings["portage_overlay"]:
871                                 if os.path.exists(x):
872                                         print "Copying overlay dir " +x
873                                         cmd("mkdir -p "+self.settings["chroot_path"]+\
874                                                 "/usr/local/portage",\
875                                                 "Could not make portage_overlay dir",env=self.env)
876                                         cmd("cp -R "+x+"/* "+self.settings["chroot_path"]+\
877                                                 "/usr/local/portage",\
878                                                 "Could not copy portage_overlay",env=self.env)
879
880         def root_overlay(self):
881                 """ Copy over the root_overlay """
882                 if self.settings.has_key(self.settings["spec_prefix"]+"/root_overlay"):
883                         for x in self.settings[self.settings["spec_prefix"]+\
884                                 "/root_overlay"]:
885                                 if os.path.exists(x):
886                                         print "Copying root_overlay: "+x
887                                         cmd("rsync -a "+x+"/ "+\
888                                                 self.settings["chroot_path"],\
889                                                 self.settings["spec_prefix"]+"/root_overlay: "+x+\
890                                                 " copy failed.",env=self.env)
891
892         def base_dirs(self):
893                 pass
894
895         def bind(self):
896                 for x in self.mounts:
897                         if not os.path.exists(self.settings["chroot_path"]+x):
898                                 os.makedirs(self.settings["chroot_path"]+x,0755)
899
900                         if not os.path.exists(self.mountmap[x]):
901                                 if not self.mountmap[x] == "tmpfs":
902                                         os.makedirs(self.mountmap[x],0755)
903
904                         src=self.mountmap[x]
905                         if self.settings.has_key("SNAPCACHE") and x == "/usr/portage":
906                                 self.snapshot_lock_object.read_lock()
907                         if os.uname()[0] == "FreeBSD":
908                                 if src == "/dev":
909                                         retval=os.system("mount -t devfs none "+\
910                                                 self.settings["chroot_path"]+x)
911                                 else:
912                                         retval=os.system("mount_nullfs "+src+" "+\
913                                                 self.settings["chroot_path"]+x)
914                         else:
915                                 if src == "tmpfs":
916                                         if self.settings.has_key("var_tmpfs_portage"):
917                                                 retval=os.system("mount -t tmpfs -o size="+\
918                                                         self.settings["var_tmpfs_portage"]+"G "+src+" "+\
919                                                         self.settings["chroot_path"]+x)
920                                 else:
921                                         retval=os.system("mount --bind "+src+" "+\
922                                                 self.settings["chroot_path"]+x)
923                         if retval!=0:
924                                 self.unbind()
925                                 raise CatalystError,"Couldn't bind mount "+src
926
927         def unbind(self):
928                 ouch=0
929                 mypath=self.settings["chroot_path"]
930                 myrevmounts=self.mounts[:]
931                 myrevmounts.reverse()
932                 """ Unmount in reverse order for nested bind-mounts """
933                 for x in myrevmounts:
934                         if not os.path.exists(mypath+x):
935                                 continue
936
937                         if not ismount(mypath+x):
938                                 continue
939
940                         retval=os.system("umount "+\
941                                 os.path.join(mypath,x.lstrip(os.path.sep)))
942
943                         if retval!=0:
944                                 warn("First attempt to unmount: "+mypath+x+" failed.")
945                                 warn("Killing any pids still running in the chroot")
946
947                                 self.kill_chroot_pids()
948
949                                 retval2=os.system("umount "+mypath+x)
950                                 if retval2!=0:
951                                         ouch=1
952                                         warn("Couldn't umount bind mount: "+mypath+x)
953
954                         if self.settings.has_key("SNAPCACHE") and x == "/usr/portage":
955                                 try:
956                                         """
957                                         It's possible the snapshot lock object isn't created yet.
958                                         This is because mount safety check calls unbind before the
959                                         target is fully initialized
960                                         """
961                                         self.snapshot_lock_object.unlock()
962                                 except:
963                                         pass
964                 if ouch:
965                         """
966                         if any bind mounts really failed, then we need to raise
967                         this to potentially prevent an upcoming bash stage cleanup script
968                         from wiping our bind mounts.
969                         """
970                         raise CatalystError,\
971                                 "Couldn't umount one or more bind-mounts; aborting for safety."
972
973         def chroot_setup(self):
974                 self.makeconf=read_makeconf(self.settings["chroot_path"]+\
975                         "/etc/portage/make.conf")
976                 self.override_cbuild()
977                 self.override_chost()
978                 self.override_cflags()
979                 self.override_cxxflags()
980                 self.override_ldflags()
981                 if self.settings.has_key("AUTORESUME") \
982                         and os.path.exists(self.settings["autoresume_path"]+"chroot_setup"):
983                         print "Resume point detected, skipping chroot_setup operation..."
984                 else:
985                         print "Setting up chroot..."
986
987                         #self.makeconf=read_makeconf(self.settings["chroot_path"]+"/etc/portage/make.conf")
988
989                         cmd("cp /etc/resolv.conf "+self.settings["chroot_path"]+"/etc",\
990                                 "Could not copy resolv.conf into place.",env=self.env)
991
992                         """ Copy over the envscript, if applicable """
993                         if self.settings.has_key("ENVSCRIPT"):
994                                 if not os.path.exists(self.settings["ENVSCRIPT"]):
995                                         raise CatalystError,\
996                                                 "Can't find envscript "+self.settings["ENVSCRIPT"]
997
998                                 print "\nWarning!!!!"
999                                 print "\tOverriding certain env variables may cause catastrophic failure."
1000                                 print "\tIf your build fails look here first as the possible problem."
1001                                 print "\tCatalyst assumes you know what you are doing when setting"
1002                                 print "\t\tthese variables."
1003                                 print "\tCatalyst Maintainers use VERY minimal envscripts if used at all"
1004                                 print "\tYou have been warned\n"
1005
1006                                 cmd("cp "+self.settings["ENVSCRIPT"]+" "+\
1007                                         self.settings["chroot_path"]+"/tmp/envscript",\
1008                                         "Could not copy envscript into place.",env=self.env)
1009
1010                         """
1011                         Copy over /etc/hosts from the host in case there are any
1012                         specialties in there
1013                         """
1014                         if os.path.exists(self.settings["chroot_path"]+"/etc/hosts"):
1015                                 cmd("mv "+self.settings["chroot_path"]+"/etc/hosts "+\
1016                                         self.settings["chroot_path"]+"/etc/hosts.catalyst",\
1017                                         "Could not backup /etc/hosts",env=self.env)
1018                                 cmd("cp /etc/hosts "+self.settings["chroot_path"]+"/etc/hosts",\
1019                                         "Could not copy /etc/hosts",env=self.env)
1020
1021                         """ Modify and write out make.conf (for the chroot) """
1022                         cmd("rm -f "+self.settings["chroot_path"]+"/etc/portage/make.conf",\
1023                                 "Could not remove "+self.settings["chroot_path"]+\
1024                                 "/etc/portage/make.conf",env=self.env)
1025                         myf=open(self.settings["chroot_path"]+"/etc/portage/make.conf","w")
1026                         myf.write("# These settings were set by the catalyst build script that automatically\n# built this stage.\n")
1027                         myf.write("# Please consult /usr/share/portage/config/make.conf.example for a more\n# detailed example.\n")
1028                         if self.settings.has_key("CFLAGS"):
1029                                 myf.write('CFLAGS="'+self.settings["CFLAGS"]+'"\n')
1030                         if self.settings.has_key("CXXFLAGS"):
1031                                 if self.settings["CXXFLAGS"]!=self.settings["CFLAGS"]:
1032                                         myf.write('CXXFLAGS="'+self.settings["CXXFLAGS"]+'"\n')
1033                                 else:
1034                                         myf.write('CXXFLAGS="${CFLAGS}"\n')
1035                         else:
1036                                 myf.write('CXXFLAGS="${CFLAGS}"\n')
1037
1038                         if self.settings.has_key("LDFLAGS"):
1039                                 myf.write("# LDFLAGS is unsupported.  USE AT YOUR OWN RISK!\n")
1040                                 myf.write('LDFLAGS="'+self.settings["LDFLAGS"]+'"\n')
1041                         if self.settings.has_key("CBUILD"):
1042                                 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")
1043                                 myf.write('CBUILD="'+self.settings["CBUILD"]+'"\n')
1044
1045                         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.\n")
1046                         myf.write('CHOST="'+self.settings["CHOST"]+'"\n')
1047
1048                         """ Figure out what our USE vars are for building """
1049                         myusevars=[]
1050                         if self.settings.has_key("HOSTUSE"):
1051                                 myusevars.extend(self.settings["HOSTUSE"])
1052
1053                         if self.settings.has_key("use"):
1054                                 myusevars.extend(self.settings["use"])
1055
1056                         if myusevars:
1057                                 myf.write("# These are the USE flags that were used in addition to what is provided by the\n# profile used for building.\n")
1058                                 myusevars = sorted(set(myusevars))
1059                                 myf.write('USE="'+string.join(myusevars)+'"\n')
1060                                 if '-*' in myusevars:
1061                                         print "\nWarning!!!  "
1062                                         print "\tThe use of -* in "+self.settings["spec_prefix"]+\
1063                                                 "/use will cause portage to ignore"
1064                                         print "\tpackage.use in the profile and portage_confdir. You've been warned!"
1065
1066                         """ Setup the portage overlay """
1067                         if self.settings.has_key("portage_overlay"):
1068                                 myf.write('PORTDIR_OVERLAY="/usr/local/portage"\n')
1069
1070                         myf.close()
1071                         cmd("cp "+self.settings["chroot_path"]+"/etc/portage/make.conf "+\
1072                                 self.settings["chroot_path"]+"/etc/portage/make.conf.catalyst",\
1073                                 "Could not backup /etc/portage/make.conf",env=self.env)
1074                         touch(self.settings["autoresume_path"]+"chroot_setup")
1075
1076         def fsscript(self):
1077                 if self.settings.has_key("AUTORESUME") \
1078                         and os.path.exists(self.settings["autoresume_path"]+"fsscript"):
1079                         print "Resume point detected, skipping fsscript operation..."
1080                 else:
1081                         if self.settings.has_key("fsscript"):
1082                                 if os.path.exists(self.settings["controller_file"]):
1083                                         cmd("/bin/bash "+self.settings["controller_file"]+\
1084                                                 " fsscript","fsscript script failed.",env=self.env)
1085                                         touch(self.settings["autoresume_path"]+"fsscript")
1086
1087         def rcupdate(self):
1088                 if self.settings.has_key("AUTORESUME") \
1089                         and os.path.exists(self.settings["autoresume_path"]+"rcupdate"):
1090                         print "Resume point detected, skipping rcupdate operation..."
1091                 else:
1092                         if os.path.exists(self.settings["controller_file"]):
1093                                 cmd("/bin/bash "+self.settings["controller_file"]+" rc-update",\
1094                                         "rc-update script failed.",env=self.env)
1095                                 touch(self.settings["autoresume_path"]+"rcupdate")
1096
1097         def clean(self):
1098                 if self.settings.has_key("AUTORESUME") \
1099                         and os.path.exists(self.settings["autoresume_path"]+"clean"):
1100                         print "Resume point detected, skipping clean operation..."
1101                 else:
1102                         for x in self.settings["cleanables"]:
1103                                 print "Cleaning chroot: "+x+"... "
1104                                 cmd("rm -rf "+self.settings["destpath"]+x,"Couldn't clean "+\
1105                                         x,env=self.env)
1106
1107                 """ Put /etc/hosts back into place """
1108                 if os.path.exists(self.settings["chroot_path"]+"/etc/hosts.catalyst"):
1109                         cmd("mv -f "+self.settings["chroot_path"]+"/etc/hosts.catalyst "+\
1110                                 self.settings["chroot_path"]+"/etc/hosts",\
1111                                 "Could not replace /etc/hosts",env=self.env)
1112
1113                 """ Remove our overlay """
1114                 if os.path.exists(self.settings["chroot_path"]+"/usr/local/portage"):
1115                         cmd("rm -rf "+self.settings["chroot_path"]+"/usr/local/portage",\
1116                                 "Could not remove /usr/local/portage",env=self.env)
1117                         cmd("sed -i '/^PORTDIR_OVERLAY/d' "+self.settings["chroot_path"]+\
1118                                 "/etc/portage/make.conf",\
1119                                 "Could not remove PORTDIR_OVERLAY from make.conf",env=self.env)
1120
1121                 """ Clean up old and obsoleted files in /etc """
1122                 if os.path.exists(self.settings["stage_path"]+"/etc"):
1123                         cmd("find "+self.settings["stage_path"]+\
1124                                 "/etc -maxdepth 1 -name \"*-\" | xargs rm -f",\
1125                                 "Could not remove stray files in /etc",env=self.env)
1126
1127                 if os.path.exists(self.settings["controller_file"]):
1128                         cmd("/bin/bash "+self.settings["controller_file"]+" clean",\
1129                                 "clean script failed.",env=self.env)
1130                         touch(self.settings["autoresume_path"]+"clean")
1131
1132         def empty(self):
1133                 if self.settings.has_key("AUTORESUME") \
1134                         and os.path.exists(self.settings["autoresume_path"]+"empty"):
1135                         print "Resume point detected, skipping empty operation..."
1136                 else:
1137                         if self.settings.has_key(self.settings["spec_prefix"]+"/empty"):
1138                                 if type(self.settings[self.settings["spec_prefix"]+\
1139                                         "/empty"])==types.StringType:
1140                                         self.settings[self.settings["spec_prefix"]+"/empty"]=\
1141                                                 self.settings[self.settings["spec_prefix"]+\
1142                                                 "/empty"].split()
1143                                 for x in self.settings[self.settings["spec_prefix"]+"/empty"]:
1144                                         myemp=self.settings["destpath"]+x
1145                                         if not os.path.isdir(myemp):
1146                                                 print x,"not a directory or does not exist, skipping 'empty' operation."
1147                                                 continue
1148                                         print "Emptying directory",x
1149                                         """
1150                                         stat the dir, delete the dir, recreate the dir and set
1151                                         the proper perms and ownership
1152                                         """
1153                                         mystat=os.stat(myemp)
1154                                         shutil.rmtree(myemp)
1155                                         os.makedirs(myemp,0755)
1156                                         os.chown(myemp,mystat[ST_UID],mystat[ST_GID])
1157                                         os.chmod(myemp,mystat[ST_MODE])
1158                         touch(self.settings["autoresume_path"]+"empty")
1159
1160         def remove(self):
1161                 if self.settings.has_key("AUTORESUME") \
1162                         and os.path.exists(self.settings["autoresume_path"]+"remove"):
1163                         print "Resume point detected, skipping remove operation..."
1164                 else:
1165                         if self.settings.has_key(self.settings["spec_prefix"]+"/rm"):
1166                                 for x in self.settings[self.settings["spec_prefix"]+"/rm"]:
1167                                         """
1168                                         We're going to shell out for all these cleaning
1169                                         operations, so we get easy glob handling.
1170                                         """
1171                                         print "livecd: removing "+x
1172                                         os.system("rm -rf "+self.settings["chroot_path"]+x)
1173                                 try:
1174                                         if os.path.exists(self.settings["controller_file"]):
1175                                                 cmd("/bin/bash "+self.settings["controller_file"]+\
1176                                                         " clean","Clean  failed.",env=self.env)
1177                                                 touch(self.settings["autoresume_path"]+"remove")
1178                                 except:
1179                                         self.unbind()
1180                                         raise
1181
1182         def preclean(self):
1183                 if self.settings.has_key("AUTORESUME") \
1184                         and os.path.exists(self.settings["autoresume_path"]+"preclean"):
1185                         print "Resume point detected, skipping preclean operation..."
1186                 else:
1187                         try:
1188                                 if os.path.exists(self.settings["controller_file"]):
1189                                         cmd("/bin/bash "+self.settings["controller_file"]+\
1190                                                 " preclean","preclean script failed.",env=self.env)
1191                                         touch(self.settings["autoresume_path"]+"preclean")
1192
1193                         except:
1194                                 self.unbind()
1195                                 raise CatalystError, "Build failed, could not execute preclean"
1196
1197         def capture(self):
1198                 if self.settings.has_key("AUTORESUME") \
1199                         and os.path.exists(self.settings["autoresume_path"]+"capture"):
1200                         print "Resume point detected, skipping capture operation..."
1201                 else:
1202                         """ Capture target in a tarball """
1203                         mypath=self.settings["target_path"].split("/")
1204                         """ Remove filename from path """
1205                         mypath=string.join(mypath[:-1],"/")
1206
1207                         """ Now make sure path exists """
1208                         if not os.path.exists(mypath):
1209                                 os.makedirs(mypath)
1210
1211                         print "Creating stage tarball..."
1212
1213                         cmd("tar -I lbzip2 -cpf "+self.settings["target_path"]+" -C "+\
1214                                 self.settings["stage_path"]+" .",\
1215                                 "Couldn't create stage tarball",env=self.env)
1216
1217                         self.gen_contents_file(self.settings["target_path"])
1218                         self.gen_digest_file(self.settings["target_path"])
1219
1220                         touch(self.settings["autoresume_path"]+"capture")
1221
1222         def run_local(self):
1223                 if self.settings.has_key("AUTORESUME") \
1224                         and os.path.exists(self.settings["autoresume_path"]+"run_local"):
1225                         print "Resume point detected, skipping run_local operation..."
1226                 else:
1227                         try:
1228                                 if os.path.exists(self.settings["controller_file"]):
1229                                         cmd("/bin/bash "+self.settings["controller_file"]+" run",\
1230                                                 "run script failed.",env=self.env)
1231                                         touch(self.settings["autoresume_path"]+"run_local")
1232
1233                         except CatalystError:
1234                                 self.unbind()
1235                                 raise CatalystError,"Stage build aborting due to error."
1236
1237         def setup_environment(self):
1238                 """
1239                 Modify the current environment. This is an ugly hack that should be
1240                 fixed. We need this to use the os.system() call since we can't
1241                 specify our own environ
1242                 """
1243                 for x in self.settings.keys():
1244                         """ Sanitize var names by doing "s|/-.|_|g" """
1245                         varname="clst_"+string.replace(x,"/","_")
1246                         varname=string.replace(varname,"-","_")
1247                         varname=string.replace(varname,".","_")
1248                         if type(self.settings[x])==types.StringType:
1249                                 """ Prefix to prevent namespace clashes """
1250                                 #os.environ[varname]=self.settings[x]
1251                                 self.env[varname]=self.settings[x]
1252                         elif type(self.settings[x])==types.ListType:
1253                                 #os.environ[varname]=string.join(self.settings[x])
1254                                 self.env[varname]=string.join(self.settings[x])
1255                         elif type(self.settings[x])==types.BooleanType:
1256                                 if self.settings[x]:
1257                                         self.env[varname]="true"
1258                                 else:
1259                                         self.env[varname]="false"
1260                 if self.settings.has_key("makeopts"):
1261                         self.env["MAKEOPTS"]=self.settings["makeopts"]
1262
1263         def run(self):
1264                 self.chroot_lock.write_lock()
1265
1266                 """ Kill any pids in the chroot "" """
1267                 self.kill_chroot_pids()
1268
1269                 """ Check for mounts right away and abort if we cannot unmount them """
1270                 self.mount_safety_check()
1271
1272                 if self.settings.has_key("CLEAR_AUTORESUME"):
1273                         self.clear_autoresume()
1274
1275                 if self.settings.has_key("PURGETMPONLY"):
1276                         self.purge()
1277                         return
1278
1279                 if self.settings.has_key("PURGEONLY"):
1280                         self.purge()
1281                         return
1282
1283                 if self.settings.has_key("PURGE"):
1284                         self.purge()
1285
1286                 for x in self.settings["action_sequence"]:
1287                         print "--- Running action sequence: "+x
1288                         sys.stdout.flush()
1289                         try:
1290                                 apply(getattr(self,x))
1291                         except:
1292                                 self.mount_safety_check()
1293                                 raise
1294
1295                 self.chroot_lock.unlock()
1296
1297         def unmerge(self):
1298                 if self.settings.has_key("AUTORESUME") \
1299                         and os.path.exists(self.settings["autoresume_path"]+"unmerge"):
1300                         print "Resume point detected, skipping unmerge operation..."
1301                 else:
1302                         if self.settings.has_key(self.settings["spec_prefix"]+"/unmerge"):
1303                                 if type(self.settings[self.settings["spec_prefix"]+\
1304                                         "/unmerge"])==types.StringType:
1305                                         self.settings[self.settings["spec_prefix"]+"/unmerge"]=\
1306                                                 [self.settings[self.settings["spec_prefix"]+"/unmerge"]]
1307                                 myunmerge=\
1308                                         self.settings[self.settings["spec_prefix"]+"/unmerge"][:]
1309
1310                                 for x in range(0,len(myunmerge)):
1311                                         """
1312                                         Surround args with quotes for passing to bash, allows
1313                                         things like "<" to remain intact
1314                                         """
1315                                         myunmerge[x]="'"+myunmerge[x]+"'"
1316                                 myunmerge=string.join(myunmerge)
1317
1318                                 """ Before cleaning, unmerge stuff """
1319                                 try:
1320                                         cmd("/bin/bash "+self.settings["controller_file"]+\
1321                                                 " unmerge "+ myunmerge,"Unmerge script failed.",\
1322                                                 env=self.env)
1323                                         print "unmerge shell script"
1324                                 except CatalystError:
1325                                         self.unbind()
1326                                         raise
1327                                 touch(self.settings["autoresume_path"]+"unmerge")
1328
1329         def target_setup(self):
1330                 if self.settings.has_key("AUTORESUME") \
1331                         and os.path.exists(self.settings["autoresume_path"]+"target_setup"):
1332                         print "Resume point detected, skipping target_setup operation..."
1333                 else:
1334                         print "Setting up filesystems per filesystem type"
1335                         cmd("/bin/bash "+self.settings["controller_file"]+\
1336                                 " target_image_setup "+ self.settings["target_path"],\
1337                                 "target_image_setup script failed.",env=self.env)
1338                         touch(self.settings["autoresume_path"]+"target_setup")
1339
1340         def setup_overlay(self):
1341                 if self.settings.has_key("AUTORESUME") \
1342                 and os.path.exists(self.settings["autoresume_path"]+"setup_overlay"):
1343                         print "Resume point detected, skipping setup_overlay operation..."
1344                 else:
1345                         if self.settings.has_key(self.settings["spec_prefix"]+"/overlay"):
1346                                 for x in self.settings[self.settings["spec_prefix"]+"/overlay"]:
1347                                         if os.path.exists(x):
1348                                                 cmd("rsync -a "+x+"/ "+\
1349                                                         self.settings["target_path"],\
1350                                                         self.settings["spec_prefix"]+"overlay: "+x+\
1351                                                         " copy failed.",env=self.env)
1352                                 touch(self.settings["autoresume_path"]+"setup_overlay")
1353
1354         def create_iso(self):
1355                 if self.settings.has_key("AUTORESUME") \
1356                         and os.path.exists(self.settings["autoresume_path"]+"create_iso"):
1357                         print "Resume point detected, skipping create_iso operation..."
1358                 else:
1359                         """ Create the ISO """
1360                         if self.settings.has_key("iso"):
1361                                 cmd("/bin/bash "+self.settings["controller_file"]+" iso "+\
1362                                         self.settings["iso"],"ISO creation script failed.",\
1363                                         env=self.env)
1364                                 self.gen_contents_file(self.settings["iso"])
1365                                 self.gen_digest_file(self.settings["iso"])
1366                                 touch(self.settings["autoresume_path"]+"create_iso")
1367                         else:
1368                                 print "WARNING: livecd/iso was not defined."
1369                                 print "An ISO Image will not be created."
1370
1371         def build_packages(self):
1372                 if self.settings.has_key("AUTORESUME") \
1373                         and os.path.exists(self.settings["autoresume_path"]+\
1374                                 "build_packages"):
1375                         print "Resume point detected, skipping build_packages operation..."
1376                 else:
1377                         if self.settings.has_key(self.settings["spec_prefix"]+"/packages"):
1378                                 if self.settings.has_key("AUTORESUME") \
1379                                         and os.path.exists(self.settings["autoresume_path"]+\
1380                                                 "build_packages"):
1381                                         print "Resume point detected, skipping build_packages operation..."
1382                                 else:
1383                                         mypack=\
1384                                                 list_bashify(self.settings[self.settings["spec_prefix"]\
1385                                                 +"/packages"])
1386                                         try:
1387                                                 cmd("/bin/bash "+self.settings["controller_file"]+\
1388                                                         " build_packages "+mypack,\
1389                                                         "Error in attempt to build packages",env=self.env)
1390                                                 touch(self.settings["autoresume_path"]+"build_packages")
1391                                         except CatalystError:
1392                                                 self.unbind()
1393                                                 raise CatalystError,self.settings["spec_prefix"]+\
1394                                                         "build aborting due to error."
1395
1396         def build_kernel(self):
1397                 if self.settings.has_key("AUTORESUME") \
1398                         and os.path.exists(self.settings["autoresume_path"]+"build_kernel"):
1399                         print "Resume point detected, skipping build_kernel operation..."
1400                 else:
1401                         if self.settings.has_key("boot/kernel"):
1402                                 try:
1403                                         mynames=self.settings["boot/kernel"]
1404                                         if type(mynames)==types.StringType:
1405                                                 mynames=[mynames]
1406                                         """
1407                                         Execute the script that sets up the kernel build environment
1408                                         """
1409                                         cmd("/bin/bash "+self.settings["controller_file"]+\
1410                                                 " pre-kmerge ","Runscript pre-kmerge failed",\
1411                                                 env=self.env)
1412
1413                                         for kname in mynames:
1414                                                 if self.settings.has_key("AUTORESUME") \
1415                                                         and os.path.exists(self.settings["autoresume_path"]\
1416                                                                 +"build_kernel_"+kname):
1417                                                         print "Resume point detected, skipping build_kernel for "+kname+" operation..."
1418                                                 else: # TODO: make this not require a kernel config
1419                                                         try:
1420                                                                 if not os.path.exists(self.settings["boot/kernel/"+kname+"/config"]):
1421                                                                         self.unbind()
1422                                                                         raise CatalystError,\
1423                                                                                 "Can't find kernel config: "+\
1424                                                                                 self.settings["boot/kernel/"+kname+\
1425                                                                                 "/config"]
1426
1427                                                         except TypeError:
1428                                                                 raise CatalystError,\
1429                                                                         "Required value boot/kernel/config not specified"
1430
1431                                                         try:
1432                                                                 cmd("cp "+self.settings["boot/kernel/"+kname+\
1433                                                                         "/config"]+" "+\
1434                                                                         self.settings["chroot_path"]+"/var/tmp/"+\
1435                                                                         kname+".config",\
1436                                                                         "Couldn't copy kernel config: "+\
1437                                                                         self.settings["boot/kernel/"+kname+\
1438                                                                         "/config"],env=self.env)
1439
1440                                                         except CatalystError:
1441                                                                 self.unbind()
1442
1443                                                         """
1444                                                         If we need to pass special options to the bootloader
1445                                                         for this kernel put them into the environment
1446                                                         """
1447                                                         if self.settings.has_key("boot/kernel/"+kname+\
1448                                                                 "/kernelopts"):
1449                                                                 myopts=self.settings["boot/kernel/"+kname+\
1450                                                                         "/kernelopts"]
1451
1452                                                                 if type(myopts) != types.StringType:
1453                                                                         myopts = string.join(myopts)
1454                                                                         self.env[kname+"_kernelopts"]=myopts
1455
1456                                                                 else:
1457                                                                         self.env[kname+"_kernelopts"]=""
1458
1459                                                         if not self.settings.has_key("boot/kernel/"+kname+\
1460                                                                 "/extraversion"):
1461                                                                 self.settings["boot/kernel/"+kname+\
1462                                                                         "/extraversion"]=""
1463
1464                                                         self.env["clst_kextraversion"]=\
1465                                                                 self.settings["boot/kernel/"+kname+\
1466                                                                 "/extraversion"]
1467
1468                                                         if self.settings.has_key("boot/kernel/"+kname+\
1469                                                                 "/initramfs_overlay"):
1470                                                                 if os.path.exists(self.settings["boot/kernel/"+\
1471                                                                         kname+"/initramfs_overlay"]):
1472                                                                         print "Copying initramfs_overlay dir "+\
1473                                                                                 self.settings["boot/kernel/"+kname+\
1474                                                                                 "/initramfs_overlay"]
1475
1476                                                                         cmd("mkdir -p "+\
1477                                                                                 self.settings["chroot_path"]+\
1478                                                                                 "/tmp/initramfs_overlay/"+\
1479                                                                                 self.settings["boot/kernel/"+kname+\
1480                                                                                 "/initramfs_overlay"],env=self.env)
1481
1482                                                                         cmd("cp -R "+self.settings["boot/kernel/"+\
1483                                                                                 kname+"/initramfs_overlay"]+"/* "+\
1484                                                                                 self.settings["chroot_path"]+\
1485                                                                                 "/tmp/initramfs_overlay/"+\
1486                                                                                 self.settings["boot/kernel/"+kname+\
1487                                                                                 "/initramfs_overlay"],env=self.env)
1488
1489                                                         """ Execute the script that builds the kernel """
1490                                                         cmd("/bin/bash "+self.settings["controller_file"]+\
1491                                                                 " kernel "+kname,\
1492                                                                 "Runscript kernel build failed",env=self.env)
1493
1494                                                         if self.settings.has_key("boot/kernel/"+kname+\
1495                                                                 "/initramfs_overlay"):
1496                                                                 if os.path.exists(self.settings["chroot_path"]+\
1497                                                                         "/tmp/initramfs_overlay/"):
1498                                                                         print "Cleaning up temporary overlay dir"
1499                                                                         cmd("rm -R "+self.settings["chroot_path"]+\
1500                                                                                 "/tmp/initramfs_overlay/",env=self.env)
1501
1502                                                         touch(self.settings["autoresume_path"]+\
1503                                                                 "build_kernel_"+kname)
1504
1505                                                         """
1506                                                         Execute the script that cleans up the kernel build
1507                                                         environment
1508                                                         """
1509                                                         cmd("/bin/bash "+self.settings["controller_file"]+\
1510                                                                 " post-kmerge ",
1511                                                                 "Runscript post-kmerge failed",env=self.env)
1512
1513                                         touch(self.settings["autoresume_path"]+"build_kernel")
1514
1515                                 except CatalystError:
1516                                         self.unbind()
1517                                         raise CatalystError,\
1518                                                 "build aborting due to kernel build error."
1519
1520         def bootloader(self):
1521                 if self.settings.has_key("AUTORESUME") \
1522                         and os.path.exists(self.settings["autoresume_path"]+"bootloader"):
1523                         print "Resume point detected, skipping bootloader operation..."
1524                 else:
1525                         try:
1526                                 cmd("/bin/bash "+self.settings["controller_file"]+\
1527                                         " bootloader " + self.settings["target_path"],\
1528                                         "Bootloader script failed.",env=self.env)
1529                                 touch(self.settings["autoresume_path"]+"bootloader")
1530                         except CatalystError:
1531                                 self.unbind()
1532                                 raise CatalystError,"Script aborting due to error."
1533
1534         def livecd_update(self):
1535                 if self.settings.has_key("AUTORESUME") \
1536                         and os.path.exists(self.settings["autoresume_path"]+\
1537                                 "livecd_update"):
1538                         print "Resume point detected, skipping build_packages operation..."
1539                 else:
1540                         try:
1541                                 cmd("/bin/bash "+self.settings["controller_file"]+\
1542                                         " livecd-update","livecd-update failed.",env=self.env)
1543                                 touch(self.settings["autoresume_path"]+"livecd_update")
1544
1545                         except CatalystError:
1546                                 self.unbind()
1547                                 raise CatalystError,"build aborting due to livecd_update error."
1548
1549         def clear_chroot(self):
1550                 myemp=self.settings["chroot_path"]
1551                 if os.path.isdir(myemp):
1552                         print "Emptying directory",myemp
1553                         """
1554                         stat the dir, delete the dir, recreate the dir and set
1555                         the proper perms and ownership
1556                         """
1557                         mystat=os.stat(myemp)
1558                         #cmd("rm -rf "+myemp, "Could not remove existing file: "+myemp,env=self.env)
1559                         """ There's no easy way to change flags recursively in python """
1560                         if os.uname()[0] == "FreeBSD":
1561                                 os.system("chflags -R noschg "+myemp)
1562                         shutil.rmtree(myemp)
1563                         os.makedirs(myemp,0755)
1564                         os.chown(myemp,mystat[ST_UID],mystat[ST_GID])
1565                         os.chmod(myemp,mystat[ST_MODE])
1566
1567         def clear_packages(self):
1568                 if self.settings.has_key("PKGCACHE"):
1569                         print "purging the pkgcache ..."
1570
1571                         myemp=self.settings["pkgcache_path"]
1572                         if os.path.isdir(myemp):
1573                                 print "Emptying directory",myemp
1574                                 """
1575                                 stat the dir, delete the dir, recreate the dir and set
1576                                 the proper perms and ownership
1577                                 """
1578                                 mystat=os.stat(myemp)
1579                                 #cmd("rm -rf "+myemp, "Could not remove existing file: "+myemp,env=self.env)
1580                                 shutil.rmtree(myemp)
1581                                 os.makedirs(myemp,0755)
1582                                 os.chown(myemp,mystat[ST_UID],mystat[ST_GID])
1583                                 os.chmod(myemp,mystat[ST_MODE])
1584
1585         def clear_kerncache(self):
1586                 if self.settings.has_key("KERNCACHE"):
1587                         print "purging the kerncache ..."
1588
1589                         myemp=self.settings["kerncache_path"]
1590                         if os.path.isdir(myemp):
1591                                 print "Emptying directory",myemp
1592                                 """
1593                                 stat the dir, delete the dir, recreate the dir and set
1594                                 the proper perms and ownership
1595                                 """
1596                                 mystat=os.stat(myemp)
1597                                 #cmd("rm -rf "+myemp, "Could not remove existing file: "+myemp,env=self.env)
1598                                 shutil.rmtree(myemp)
1599                                 os.makedirs(myemp,0755)
1600                                 os.chown(myemp,mystat[ST_UID],mystat[ST_GID])
1601                                 os.chmod(myemp,mystat[ST_MODE])
1602
1603         def clear_autoresume(self):
1604                 """ Clean resume points since they are no longer needed """
1605                 if self.settings.has_key("AUTORESUME"):
1606                         print "Removing AutoResume Points: ..."
1607                 myemp=self.settings["autoresume_path"]
1608                 if os.path.isdir(myemp):
1609                                 if self.settings.has_key("AUTORESUME"):
1610                                         print "Emptying directory",myemp
1611                                 """
1612                                 stat the dir, delete the dir, recreate the dir and set
1613                                 the proper perms and ownership
1614                                 """
1615                                 mystat=os.stat(myemp)
1616                                 if os.uname()[0] == "FreeBSD":
1617                                         cmd("chflags -R noschg "+myemp,\
1618                                                 "Could not remove immutable flag for file "\
1619                                                 +myemp)
1620                                 #cmd("rm -rf "+myemp, "Could not remove existing file: "+myemp,env-self.env)
1621                                 shutil.rmtree(myemp)
1622                                 os.makedirs(myemp,0755)
1623                                 os.chown(myemp,mystat[ST_UID],mystat[ST_GID])
1624                                 os.chmod(myemp,mystat[ST_MODE])
1625
1626         def gen_contents_file(self,file):
1627                 if os.path.exists(file+".CONTENTS"):
1628                         os.remove(file+".CONTENTS")
1629                 if self.settings.has_key("contents"):
1630                         if os.path.exists(file):
1631                                 myf=open(file+".CONTENTS","w")
1632                                 keys={}
1633                                 for i in self.settings["contents"].split():
1634                                         keys[i]=1
1635                                         array=keys.keys()
1636                                         array.sort()
1637                                 for j in array:
1638                                         contents=generate_contents(file,contents_function=j,\
1639                                                 verbose=self.settings.has_key("VERBOSE"))
1640                                         if contents:
1641                                                 myf.write(contents)
1642                                 myf.close()
1643
1644         def gen_digest_file(self,file):
1645                 if os.path.exists(file+".DIGESTS"):
1646                         os.remove(file+".DIGESTS")
1647                 if self.settings.has_key("digests"):
1648                         if os.path.exists(file):
1649                                 myf=open(file+".DIGESTS","w")
1650                                 keys={}
1651                                 for i in self.settings["digests"].split():
1652                                         keys[i]=1
1653                                         array=keys.keys()
1654                                         array.sort()
1655                                 for f in [file, file+'.CONTENTS']:
1656                                         if os.path.exists(f):
1657                                                 if "all" in array:
1658                                                         for k in hash_map.keys():
1659                                                                 hash=generate_hash(f,hash_function=k,verbose=\
1660                                                                         self.settings.has_key("VERBOSE"))
1661                                                                 myf.write(hash)
1662                                                 else:
1663                                                         for j in array:
1664                                                                 hash=generate_hash(f,hash_function=j,verbose=\
1665                                                                         self.settings.has_key("VERBOSE"))
1666                                                                 myf.write(hash)
1667                                 myf.close()
1668
1669         def purge(self):
1670                 countdown(10,"Purging Caches ...")
1671                 if self.settings.has_key("PURGE") or self.settings.has_key("PURGEONLY") or self.settings.has_key("PURGETMPONLY"):
1672                         print "clearing autoresume ..."
1673                         self.clear_autoresume()
1674
1675                         print "clearing chroot ..."
1676                         self.clear_chroot()
1677
1678                         if not self.settings.has_key("PURGETMPONLY"):
1679                                 print "clearing package cache ..."
1680                                 self.clear_packages()
1681
1682                         print "clearing kerncache ..."
1683                         self.clear_kerncache()
1684
1685 # vim: ts=4 sw=4 sta et sts=4 ai