This is catalyst-2.0_rc2.
[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.103 2005/11/30 21:42:19 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_rc2"
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 def import_modules():
138         # import catalyst's own modules (i.e. catalyst_support and the arch modules)
139         targetmap={}
140         
141         try:
142                 for x in required_build_targets:
143                         try:
144                                 fh=open(conf_values["sharedir"]+"/modules/"+x+".py")
145                                 module=imp.load_module(x,fh,"modules/"+x+".py",(".py","r",imp.PY_SOURCE))
146                                 fh.close()
147                 
148                         except IOError:
149                                 raise CatalystError,"Can't find "+x+".py plugin in "+\
150                                         conf_values.settings["sharedir"]+"/modules/"
151
152                 for x in valid_build_targets:
153                         try:
154                                 fh=open(conf_values["sharedir"]+"/modules/"+x+".py")
155                                 module=imp.load_module(x,fh,"modules/"+x+".py",(".py","r",imp.PY_SOURCE))
156                                 module.register(targetmap)
157                                 fh.close()
158                 
159                         except IOError:
160                                 raise CatalystError,"Can't find "+x+".py plugin in "+\
161                                         conf_values.settings["sharedir"]+"/modules/"
162
163         except ImportError:
164                 print "!!! catalyst: Python modules not found in "+\
165                         conf_values["sharedir"]+"/modules; exiting."
166                 sys.exit(1)
167
168         return targetmap
169
170 def do_spec(myspecfile):
171         try:
172                 addlargs=read_spec(myspecfile)
173         except:
174                 sys.exit(1)
175                 
176         return addlargs
177
178 def do_cli(cmdline):
179         try:
180                 return arg_parse(cmdline)
181         
182         except CatalystError:
183                 print "!!! catalyst: Could not parse commandline, exiting."
184                 sys.exit(1)
185         
186 def build_target(addlargs, targetmap):
187         try:
188                 if not targetmap.has_key(addlargs["target"]):
189                         raise CatalystError,"Target \""+addlargs["target"]+"\" not available."
190                 
191                 mytarget=targetmap[addlargs["target"]](conf_values, addlargs)
192         
193                 mytarget.run()
194
195         except:
196                 raise
197
198 if __name__ == "__main__":
199         targetmap={}
200         
201         version()
202         if os.getuid() != 0:
203                 # catalyst cannot be run as a normal user due to chroots, mounts, etc
204                 print "!!! catalyst: This script requires root privileges to operate"
205                 sys.exit(2)
206
207         # we need some options in order to work correctly
208         if len(sys.argv) < 2:
209                 usage()
210                 sys.exit(2)
211
212         # parse out the command line arguments
213         try:
214                 opts,args = getopt.getopt(sys.argv[1:], "apxhvdc:C:f:FVs:", ["purge","help", "version", "debug",\
215                         "clear_autoresume", "config=", "cli=", "file=", "fetch", "verbose","snapshot="])
216         
217         except getopt.GetoptError:
218                 usage()
219                 sys.exit(2)
220         
221         # defaults for commandline opts
222         debug=False
223         verbose=False
224         fetch=False
225         myconfig=""
226         myspecfile=""
227         mycmdline=[]
228         myopts=[]
229
230         # check preconditions
231         if len(opts) == 0:
232                 print "!!! catalyst: please specify one of either -f or -C\n"
233                 usage()
234                 sys.exit(2)
235         run=0   
236         for o, a in opts:
237                 if o in ("-h", "--help"):
238                         usage()
239                         sys.exit(1)
240                 
241                 if o in ("-v", "--version"):
242                         print "Catalyst version "+__version__
243                         sys.exit(1)
244
245                 if o in ("-d", "--debug"):
246                         if len(sys.argv) < 3:
247                                 print "!!! catalyst: please specify one of either -f or -C\n"
248                                 usage()
249                                 sys.exit(2)
250                         else:
251                                 conf_values["DEBUG"]="1"
252
253                 if o in ("-c", "--config"):
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                                 myconfig=a
260
261                 if o in ("-C", "--cli"):
262                         run=1   
263                         x=sys.argv.index(o)+1
264                         while x < len(sys.argv):
265                                 mycmdline.append(sys.argv[x])
266                                 x=x+1
267                         
268                 if o in ("-f", "--file"):
269                         run=1   
270                         myspecfile=a
271
272                 if o in ("-F", "--fetchonly"):
273                         if len(sys.argv) < 3:
274                                 print "!!! catalyst: please specify one of either -f or -C\n"
275                                 usage()
276                                 sys.exit(2)
277                         else:
278                                 conf_values["FETCH"]="1"
279                         
280                 if o in ("-V", "--verbose"):
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["VERBOSE"]="1"
287
288                 if o in ("-s", "--snapshot"):
289                         if len(sys.argv) < 3:
290                                 print "!!! catalyst: missing snapshot identifier\n"
291                                 usage()
292                                 sys.exit(2)
293                         else:
294                                 run=1
295                                 mycmdline.append("target=snapshot")
296                                 mycmdline.append("version_stamp="+a)
297                 
298                 if o in ("-p", "--purge"):
299                         if len(sys.argv) < 3:
300                                 print "!!! catalyst: please specify one of either -f or -C\n"
301                                 usage()
302                                 sys.exit(2)
303                         else:
304                                 conf_values["PURGE"]="1"
305                 if o in ("-a", "--clear-autoresume"):
306                         if len(sys.argv) < 3:
307                                 print "!!! catalyst: please specify one of either -f or -C\n"
308                                 usage()
309                                 sys.exit(2)
310                         else:
311                                 conf_values["CLEAR_AUTORESUME"]="1"
312         if run != 1:
313                 print "!!! catalyst: please specify one of either -f or -C\n"
314                 usage()
315                 sys.exit(2)
316
317         # import configuration file and import our main module using those settings
318         parse_config(myconfig)
319         sys.path.append(conf_values["sharedir"]+"/modules")
320         from catalyst_support import *
321                 
322         # import the rest of the catalyst modules
323         targetmap=import_modules()
324
325         addlargs={}
326         
327         if myspecfile:
328                 addlargs.update(do_spec(myspecfile))
329         
330         if mycmdline:
331                 addlargs.update(do_cli(mycmdline))
332         
333         if not addlargs.has_key("target"):
334                 raise CatalystError, "Required value \"target\" not specified."
335
336         # everything is setup, so the build is a go
337         try:
338                 build_target(addlargs, targetmap)
339                         
340         except CatalystError:
341                 print
342                 print "Catalyst aborting...."
343                 sys.exit(2)
344         except KeyboardInterrupt:
345                 print "\nCatalyst build aborted due to user interrupt ( Ctrl-C )"
346                 print
347                 print "Catalyst aborting...."
348         except LockInUse:
349                 print "Catalyst aborting...."
350                 sys.exit(2)
351         except:
352                 print "Catalyst aborting...."
353                 raise
354                 sys.exit(2)
355
356         #except CatalystError:
357         #       print
358         #       print "Catalyst aborting...."
359         #       sys.exit(2)
360         #except KeyError:
361         #       print "\nproblem with command line or spec file ( Key Error )"
362         #       print "Key: "+str(sys.exc_value)+" was not found"
363         #       print "Catalyst aborting...."
364         #       sys.exit(2)
365         #except UnboundLocalError:
366         #       print
367         #       print "UnboundLocalError: "+str(sys.exc_value)+" was not found"
368         #       raise
369         #       print
370         #       print "Catalyst aborting...."
371         #       sys.exit(2)