Added a patch from Andrew Gaffney <agaffney@gentoo.org> from bug #173826 to improve...
[catalyst.git] / modules / netboot2_target.py
1
2 """
3 Builder class for a netboot build, version 2
4 """
5
6 import os,string,types
7 from catalyst_support import *
8 from generic_stage_target import *
9
10 class netboot2_target(generic_stage_target):
11         def __init__(self,spec,addlargs):
12                 self.required_values=[
13                         "boot/kernel"
14                 ]
15                 self.valid_values=self.required_values[:]
16                 self.valid_values.extend([
17                         "netboot2/packages",
18                         "netboot2/use",
19                         "netboot2/extra_files",
20                         "netboot2/overlay",
21                         "netboot2/busybox_config"
22                 ])
23
24                 try:
25                         if addlargs.has_key("netboot2/packages"):
26                                 if type(addlargs["netboot2/packages"]) == types.StringType:
27                                         loopy=[addlargs["netboot2/packages"]]
28                                 else:
29                                         loopy=addlargs["netboot2/packages"]
30
31                                 for x in loopy:
32                                         self.valid_values.append("netboot2/packages/"+x+"/files")
33                 except:
34                         raise CatalystError,"configuration error in netboot2/packages."
35                 
36                 generic_stage_target.__init__(self,spec,addlargs)
37                 self.set_build_kernel_vars()
38                 self.settings["merge_path"]=normpath("/tmp/image/")
39
40         def set_target_path(self):
41                 self.settings["target_path"]=normpath(self.settings["storedir"]+"/builds/"+\
42                         self.settings["target_subpath"]+"/")
43                 if self.settings.has_key("AUTORESUME") \
44                         and os.path.exists(self.settings["autoresume_path"]+"setup_target_path"):
45                                 print "Resume point detected, skipping target path setup operation..."
46                 else:
47                         # first clean up any existing target stuff
48                         if os.path.isfile(self.settings["target_path"]):
49                                 cmd("rm -f "+self.settings["target_path"], \
50                                         "Could not remove existing file: "+self.settings["target_path"],env=self.env)
51                                 touch(self.settings["autoresume_path"]+"setup_target_path")
52
53                 if not os.path.exists(self.settings["storedir"]+"/builds/"):
54                         os.makedirs(self.settings["storedir"]+"/builds/")
55
56         def copy_files_to_image(self):
57                 # copies specific files from the buildroot to merge_path
58                 myfiles=[]
59
60                 # check for autoresume point
61                 if self.settings.has_key("AUTORESUME") \
62                         and os.path.exists(self.settings["autoresume_path"]+"copy_files_to_image"):
63                                 print "Resume point detected, skipping target path setup operation..."
64                 else:
65                         if self.settings.has_key("netboot2/packages"):
66                                 if type(self.settings["netboot2/packages"]) == types.StringType:
67                                         loopy=[self.settings["netboot2/packages"]]
68                                 else:
69                                         loopy=self.settings["netboot2/packages"]
70                 
71                         for x in loopy:
72                                 if self.settings.has_key("netboot2/packages/"+x+"/files"):
73                                     if type(self.settings["netboot2/packages/"+x+"/files"]) == types.ListType:
74                                             myfiles.extend(self.settings["netboot2/packages/"+x+"/files"])
75                                     else:
76                                             myfiles.append(self.settings["netboot2/packages/"+x+"/files"])
77
78                         if self.settings.has_key("netboot2/extra_files"):
79                                 if type(self.settings["netboot2/extra_files"]) == types.ListType:
80                                         myfiles.extend(self.settings["netboot2/extra_files"])
81                                 else:
82                                         myfiles.append(self.settings["netboot2/extra_files"])
83
84                         try:
85                                 cmd("/bin/bash "+self.settings["controller_file"]+\
86                                         " image " + list_bashify(myfiles),env=self.env)
87                         except CatalystError:
88                                 self.unbind()
89                                 raise CatalystError,"Failed to copy files to image!"
90
91                         touch(self.settings["autoresume_path"]+"copy_files_to_image")
92
93         def setup_overlay(self):        
94                 if self.settings.has_key("AUTORESUME") \
95                 and os.path.exists(self.settings["autoresume_path"]+"setup_overlay"):
96                         print "Resume point detected, skipping setup_overlay operation..."
97                 else:
98                         if self.settings.has_key("netboot2/overlay"):
99                                 for x in self.settings["netboot2/overlay"]: 
100                                         if os.path.exists(x):
101                                                 cmd("rsync -a "+x+"/ "+\
102                                                         self.settings["chroot_path"], "netboot2/overlay: "+x+" copy failed.",env=self.env)
103                                 touch(self.settings["autoresume_path"]+"setup_overlay")
104
105         def move_kernels(self):
106                 # we're done, move the kernels to builds/*
107                 # no auto resume here as we always want the
108                 # freshest images moved
109                 try:
110                         cmd("/bin/bash "+self.settings["controller_file"]+\
111                                 " final",env=self.env)
112                         print ">>> Netboot Build Finished!"
113                 except CatalystError:
114                         self.unbind()
115                         raise CatalystError,"Failed to move kernel images!"
116
117         def remove(self):
118                 if self.settings.has_key("AUTORESUME") \
119                         and os.path.exists(self.settings["autoresume_path"]+"remove"):
120                         print "Resume point detected, skipping remove operation..."
121                 else:
122                         if self.settings.has_key(self.settings["spec_prefix"]+"/rm"):
123                                 for x in self.settings[self.settings["spec_prefix"]+"/rm"]:
124                                         # we're going to shell out for all these cleaning operations,
125                                         # so we get easy glob handling
126                                         print "netboot2: removing " + x
127                                         os.system("rm -rf " + self.settings["chroot_path"] + self.settings["merge_path"] + x)
128
129         def empty(self):                
130                 if self.settings.has_key("AUTORESUME") \
131                         and os.path.exists(self.settings["autoresume_path"]+"empty"):
132                         print "Resume point detected, skipping empty operation..."
133                 else:
134                         if self.settings.has_key("netboot2/empty"):
135                                 if type(self.settings["netboot2/empty"])==types.StringType:
136                                         self.settings["netboot2/empty"]=self.settings["netboot2/empty"].split()
137                                 for x in self.settings["netboot2/empty"]:
138                                         myemp=self.settings["chroot_path"] + self.settings["merge_path"] + x
139                                         if not os.path.isdir(myemp):
140                                                 print x,"not a directory or does not exist, skipping 'empty' operation."
141                                                 continue
142                                         print "Emptying directory", x
143                                         # stat the dir, delete the dir, recreate the dir and set
144                                         # the proper perms and ownership
145                                         mystat=os.stat(myemp)
146                                         shutil.rmtree(myemp)
147                                         os.makedirs(myemp,0755)
148                                         os.chown(myemp,mystat[ST_UID],mystat[ST_GID])
149                                         os.chmod(myemp,mystat[ST_MODE])
150                 touch(self.settings["autoresume_path"]+"empty")
151
152         def set_action_sequence(self):
153             self.settings["action_sequence"]=["unpack","unpack_snapshot","config_profile_link",
154                                         "setup_confdir","bind","chroot_setup",\
155                                         "setup_environment","build_packages","root_overlay",\
156                                         "copy_files_to_image","setup_overlay","build_kernel","move_kernels",\
157                                         "remove","empty","unbind","clean","clear_autoresume"]
158
159 def register(foo):
160         foo.update({"netboot2":netboot2_target})
161         return foo