Made EMERGE_WARNING_DELAY=0 for all stages. This is 2.0_rc7.
[catalyst.git] / catalyst
1 #!/usr/bin/python
2 # Copyright 1999-2005 Gentoo Foundation
3 # Distributed under the terms of the GNU General Public License v2
4 # $Header: /var/cvsroot/gentoo/src/catalyst/catalyst,v 1.110 2005/12/07 21:33:43 wolf31o2 Exp $
5
6 # Maintained in full by:
7 # Eric Edgar <rocket@gentoo.org>
8 # Chris Gianelloni <wolf31o2@gentoo.org>
9
10 import os,sys,imp,string,getopt
11 import pdb
12 __maintainer__="Chris Gianelloni <wolf31o2@gentoo.org>"
13 __version__="2.0_rc7"
14
15 conf_values={}
16
17 def usage():
18         print "Usage catalyst [options] [-C variable=value...] [ -s identifier]"
19         print " -a --clear-autoresume   clear autoresume flags"
20         print " -c --config             use specified configuration file"
21         print " -C --cli                catalyst commandline (MUST BE LAST OPTION)"
22         print " -d --debug              enable debugging"
23         print " -f --file               read specfile"
24         print " -F --fetchonly          fetch files only"
25         print " -h --help               print this help message"
26         print " -p --purge              clear tmp dirs,package cache and autoresume flags"
27         print " -s --snapshot           generate a Portage snapshot"
28         print " -V --version            display version information"
29         print " -v --verbose            verbose output"
30         print
31         print "Usage examples:"
32         print
33         print "Using the commandline option (-C, --cli) to build a Portage snapshot:"
34         print "catalyst -C target=snapshot version_stamp=my_date"
35         print
36         print "Using the snapshot option (-s, --snapshot) to build a Portage snapshot:"
37         print "catalyst -s 2005.0"
38         print
39         print "Using the specfile option (-f, --file) to build a stage target:"
40         print "catalyst -f stage1-specfile.spec"
41
42 def version():
43         print "Gentoo Catalyst, version "+__version__
44         print "Copyright 2003-2005 The Gentoo Foundation"
45         print "Distributed under the GNU General Public License version 2\n"
46         
47
48 def parse_config(myconfig):
49         # search a couple of different areas for the main config file
50         myconf={}
51         config_file=""
52
53         confdefaults={ "storedir":"/var/tmp/catalyst",\
54                 "sharedir":"/usr/share/catalyst","distdir":"/usr/portage/distfiles",\
55                 "portdir":"/usr/portage","options":"",\
56                 "snapshot_cache":"/var/tmp/catalyst/snapshot_cache" }
57                 
58         # first, try the one passed (presumably from the cmdline)
59         if myconfig:
60                 if os.path.exists(myconfig):
61                         print "Using command line specified Catalyst configuration file, "+myconfig
62                         config_file=myconfig
63
64                 else:
65                         print "!!! catalyst: Could not use specified configuration file "+\
66                                 myconfig
67                         sys.exit(1)
68         
69         # next, try the default location
70         elif os.path.exists("/etc/catalyst/catalyst.conf"):
71                 print "Using default Catalyst configuration file, /etc/catalyst/catalyst.conf"
72                 config_file="/etc/catalyst/catalyst.conf"
73         
74         # can't find a config file (we are screwed), so bail out
75         else:
76                 print "!!! catalyst: Could not find a suitable configuration file"
77                 sys.exit(1)
78
79         # now, try and parse the config file "config_file"
80         try:
81                 execfile(config_file, myconf, myconf)
82         
83         except:
84                 print "!!! catalyst: Unable to parse configuration file, "+myconfig
85                 sys.exit(1)
86         
87         # now, load up the values into conf_values so that we can use them
88         for x in confdefaults.keys():
89                 if myconf.has_key(x):
90                         print "Setting",x,"to config file value \""+myconf[x]+"\""
91                         conf_values[x]=myconf[x]
92                 else:
93                         print "Setting",x,"to default value \""+confdefaults[x]+"\""
94                         conf_values[x]=confdefaults[x]
95
96         # parse out the rest of the options from the config file
97         if "ccache" in string.split(conf_values["options"]):
98                 print "Compiler cache support enabled."
99                 conf_values["CCACHE"]="1"
100
101         if "pkgcache" in string.split(conf_values["options"]):
102                 print "Package cache support enabled."
103                 conf_values["PKGCACHE"]="1"
104         
105         if "snapcache" in string.split(conf_values["options"]):
106                 print "Snapshot cache support enabled."
107                 conf_values["SNAPCACHE"]="1"
108         
109         if "seedcache" in string.split(conf_values["options"]):
110                 print "Seed cache support enabled."
111                 conf_values["SEEDCACHE"]="1"
112
113         if "kerncache" in string.split(conf_values["options"]):
114                 print "Kernel cache support enabled."
115                 conf_values["KERNCACHE"]="1"
116         
117         if "distcc" in string.split(conf_values["options"]):
118                 print "Distcc support enabled."
119                 conf_values["DISTCC"]="1"
120
121         if "autoresume" in string.split(conf_values["options"]):
122                 print "Autoresuming support enabled."
123                 conf_values["AUTORESUME"]="1"
124
125         if "purge" in string.split(conf_values["options"]):
126                 print "Purge support enabled."
127                 conf_values["PURGE"]="1"
128         
129         if "clear-autoresume" in string.split(conf_values["options"]):
130                 print "Cleaning autoresume flags support enabled."
131                 conf_values["CLEAR_AUTORESUME"]="1"
132         
133         if myconf.has_key("envscript"):
134                 print "Envscript support enabled."
135                 conf_values["ENVSCRIPT"]=myconf["envscript"]
136         
137         if "md5" in string.split(conf_values["options"]):
138                 print "MD5 .digests file creation support enabled."
139                 conf_values["MD5"]="1"
140         
141         if "sha" in string.split(conf_values["options"]):
142                 print "SHA .digests file creation support enabled."
143                 conf_values["SHA"]="1"
144
145 def import_modules():
146         # import catalyst's own modules (i.e. catalyst_support and the arch modules)
147         targetmap={}
148         
149         try:
150                 for x in required_build_targets:
151                         try:
152                                 fh=open(conf_values["sharedir"]+"/modules/"+x+".py")
153                                 module=imp.load_module(x,fh,"modules/"+x+".py",(".py","r",imp.PY_SOURCE))
154                                 fh.close()
155                 
156                         except IOError:
157                                 raise CatalystError,"Can't find "+x+".py plugin in "+\
158                                         conf_values.settings["sharedir"]+"/modules/"
159
160                 for x in valid_build_targets:
161                         try:
162                                 fh=open(conf_values["sharedir"]+"/modules/"+x+".py")
163                                 module=imp.load_module(x,fh,"modules/"+x+".py",(".py","r",imp.PY_SOURCE))
164                                 module.register(targetmap)
165                                 fh.close()
166                 
167                         except IOError:
168                                 raise CatalystError,"Can't find "+x+".py plugin in "+\
169                                         conf_values.settings["sharedir"]+"/modules/"
170
171         except ImportError:
172                 print "!!! catalyst: Python modules not found in "+\
173                         conf_values["sharedir"]+"/modules; exiting."
174                 sys.exit(1)
175
176         return targetmap
177
178 def do_spec(myspecfile):
179         try:
180                 addlargs=read_spec(myspecfile)
181         except:
182                 sys.exit(1)
183                 
184         return addlargs
185
186 def do_cli(cmdline):
187         try:
188                 return arg_parse(cmdline)
189         
190         except CatalystError:
191                 print "!!! catalyst: Could not parse commandline, exiting."
192                 sys.exit(1)
193         
194 def build_target(addlargs, targetmap):
195         try:
196                 if not targetmap.has_key(addlargs["target"]):
197                         raise CatalystError,"Target \""+addlargs["target"]+"\" not available."
198                 
199                 mytarget=targetmap[addlargs["target"]](conf_values, addlargs)
200         
201                 mytarget.run()
202
203         except:
204                 raise
205
206 if __name__ == "__main__":
207         targetmap={}
208         
209         version()
210         if os.getuid() != 0:
211                 # catalyst cannot be run as a normal user due to chroots, mounts, etc
212                 print "!!! catalyst: This script requires root privileges to operate"
213                 sys.exit(2)
214
215         # we need some options in order to work correctly
216         if len(sys.argv) < 2:
217                 usage()
218                 sys.exit(2)
219
220         # parse out the command line arguments
221         try:
222                 opts,args = getopt.getopt(sys.argv[1:], "apxhvdc:C:f:FVs:", ["purge","help", "version", "debug",\
223                         "clear_autoresume", "config=", "cli=", "file=", "fetch", "verbose","snapshot="])
224         
225         except getopt.GetoptError:
226                 usage()
227                 sys.exit(2)
228         
229         # defaults for commandline opts
230         debug=False
231         verbose=False
232         fetch=False
233         myconfig=""
234         myspecfile=""
235         mycmdline=[]
236         myopts=[]
237
238         # check preconditions
239         if len(opts) == 0:
240                 print "!!! catalyst: please specify one of either -f or -C\n"
241                 usage()
242                 sys.exit(2)
243         run=0   
244         for o, a in opts:
245                 if o in ("-h", "--help"):
246                         usage()
247                         sys.exit(1)
248                 
249                 if o in ("-V", "--version"):
250                         print "Catalyst version "+__version__
251                         sys.exit(1)
252
253                 if o in ("-d", "--debug"):
254                         if len(sys.argv) < 3:
255                                 print "!!! catalyst: please specify one of either -f or -C\n"
256                                 usage()
257                                 sys.exit(2)
258                         else:
259                                 conf_values["DEBUG"]="1"
260
261                 if o in ("-c", "--config"):
262                         if len(sys.argv) < 3:
263                                 print "!!! catalyst: please specify one of either -f or -C\n"
264                                 usage()
265                                 sys.exit(2)
266                         else:
267                                 myconfig=a
268
269                 if o in ("-C", "--cli"):
270                         run=1   
271                         x=sys.argv.index(o)+1
272                         while x < len(sys.argv):
273                                 mycmdline.append(sys.argv[x])
274                                 x=x+1
275                         
276                 if o in ("-f", "--file"):
277                         run=1   
278                         myspecfile=a
279
280                 if o in ("-F", "--fetchonly"):
281                         if len(sys.argv) < 3:
282                                 print "!!! catalyst: please specify one of either -f or -C\n"
283                                 usage()
284                                 sys.exit(2)
285                         else:
286                                 conf_values["FETCH"]="1"
287                         
288                 if o in ("-v", "--verbose"):
289                         if len(sys.argv) < 3:
290                                 print "!!! catalyst: please specify one of either -f or -C\n"
291                                 usage()
292                                 sys.exit(2)
293                         else:
294                                 conf_values["VERBOSE"]="1"
295
296                 if o in ("-s", "--snapshot"):
297                         if len(sys.argv) < 3:
298                                 print "!!! catalyst: missing snapshot identifier\n"
299                                 usage()
300                                 sys.exit(2)
301                         else:
302                                 run=1
303                                 mycmdline.append("target=snapshot")
304                                 mycmdline.append("version_stamp="+a)
305                 
306                 if o in ("-p", "--purge"):
307                         if len(sys.argv) < 3:
308                                 print "!!! catalyst: please specify one of either -f or -C\n"
309                                 usage()
310                                 sys.exit(2)
311                         else:
312                                 conf_values["PURGE"]="1"
313                 if o in ("-a", "--clear-autoresume"):
314                         if len(sys.argv) < 3:
315                                 print "!!! catalyst: please specify one of either -f or -C\n"
316                                 usage()
317                                 sys.exit(2)
318                         else:
319                                 conf_values["CLEAR_AUTORESUME"]="1"
320         if run != 1:
321                 print "!!! catalyst: please specify one of either -f or -C\n"
322                 usage()
323                 sys.exit(2)
324
325         # import configuration file and import our main module using those settings
326         parse_config(myconfig)
327         sys.path.append(conf_values["sharedir"]+"/modules")
328         from catalyst_support import *
329                 
330         # import the rest of the catalyst modules
331         targetmap=import_modules()
332
333         addlargs={}
334         
335         if myspecfile:
336                 addlargs.update(do_spec(myspecfile))
337         
338         if mycmdline:
339                 addlargs.update(do_cli(mycmdline))
340         
341         if not addlargs.has_key("target"):
342                 raise CatalystError, "Required value \"target\" not specified."
343
344         # everything is setup, so the build is a go
345         try:
346                 build_target(addlargs, targetmap)
347                         
348         except CatalystError:
349                 print
350                 print "Catalyst aborting...."
351                 sys.exit(2)
352         except KeyboardInterrupt:
353                 print "\nCatalyst build aborted due to user interrupt ( Ctrl-C )"
354                 print
355                 print "Catalyst aborting...."
356         except LockInUse:
357                 print "Catalyst aborting...."
358                 sys.exit(2)
359         except:
360                 print "Catalyst aborting...."
361                 raise
362                 sys.exit(2)
363
364         #except CatalystError:
365         #       print
366         #       print "Catalyst aborting...."
367         #       sys.exit(2)
368         #except KeyError:
369         #       print "\nproblem with command line or spec file ( Key Error )"
370         #       print "Key: "+str(sys.exc_value)+" was not found"
371         #       print "Catalyst aborting...."
372         #       sys.exit(2)
373         #except UnboundLocalError:
374         #       print
375         #       print "UnboundLocalError: "+str(sys.exc_value)+" was not found"
376         #       raise
377         #       print
378         #       print "Catalyst aborting...."
379         #       sys.exit(2)