simpler arg passing to the start-qemu-node script
[tests.git] / system / TestNode.py
1 import os, sys, time, base64
2 import xmlrpclib
3
4 import utils
5 from TestUser import TestUser
6 from TestBox import TestBox
7
8 class TestNode:
9
10     def __init__ (self,test_plc,test_site,node_spec):
11         self.test_plc=test_plc
12         self.test_site=test_site
13         self.node_spec=node_spec
14
15     def name(self):
16         return self.node_spec['node_fields']['hostname']
17     
18     @staticmethod
19     def is_qemu_model (model):
20         return model.find("qemu") >= 0
21     def is_qemu (self):
22         return TestNode.is_qemu_model(self.node_spec['node_fields']['model'])
23
24     @staticmethod
25     def is_real_model (model):
26         return not TestNode.is_qemu_model(model)
27     def is_real (self):
28         return TestNode.is_real_model (self.node_spec['node_fields']['model'])
29
30     @staticmethod
31     def is_local(host_box):
32         if (host_box == "localhost"): return True
33         else: return False
34
35     def buildname(self):
36         return self.test_plc.options.buildname
37         
38     def host_box (self):
39         if self.is_real ():
40             utils.header("WARNING : real nodes dont have a host box")
41             return None
42         else:
43             try:
44                 return self.node_spec['host_box']
45             except:
46                 utils.header("WARNING : qemu nodes need a host box")
47                 return 'localhost'
48
49     def create_node (self):
50         ownername = self.node_spec['owner']
51         user_spec = self.test_site.locate_user(ownername)
52         test_user = TestUser(self.test_plc,self.test_site,user_spec)
53         userauth = test_user.auth()
54         utils.header("node %s created by user %s"%(self.name(),test_user.name()))
55         rootauth=self.test_plc.auth_root()
56         server = self.test_plc.server
57         server.AddNode(userauth,
58                        self.test_site.site_spec['site_fields']['login_base'],
59                        self.node_spec['node_fields'])
60         # create as reinstall to avoid user confirmation
61         server.UpdateNode(userauth, self.name(), {'boot_state':'rins'})
62         # populate network interfaces - primary
63         server.AddNodeNetwork(userauth,self.name(),
64                                             self.node_spec['network_fields'])
65         # populate network interfaces - others
66         if self.node_spec.has_key('extra_interfaces'):
67             for interface in self.node_spec['extra_interfaces']:
68                 server.AddNodeNetwork(userauth,self.name(),
69                                                     interface['network_fields'])
70                 if interface.has_key('settings'):
71                     for (attribute,value) in interface['settings'].iteritems():
72                         # locate node network
73                         nn = server.GetNodeNetworks(userauth,{'ip':interface['network_fields']['ip']})[0]
74                         nnid=nn['nodenetwork_id']
75                         # locate or create node network attribute type
76                         try:
77                             nnst = server.GetNodeNetworkSettingTypes(userauth,{'name':attribute})[0]
78                         except:
79                             nnst = server.AddNodeNetworkSettingType(rootauth,{'category':'test',
80                                                                               'name':attribute})
81                         # attach value
82                         server.AddNodeNetworkSetting(userauth,nnid,attribute,value)
83
84     def delete_node (self):
85         # uses the right auth as far as poss.
86         try:
87             ownername = self.node_spec['owner']
88             user_spec = self.test_site.locate_user(ownername)
89             test_user = TestUser(self.test_plc,self.test_site,user_spec)
90             auth = test_user.auth()
91         except:
92             auth=self.test_plc.auth_root()
93         self.test_plc.server.DeleteNode(auth,self.name())
94
95     def get_node_status(self,hostname):
96         filter=['boot_state']
97         status=False
98         node_status=self.test_plc.server.GetNodes(self.test_plc.auth_root(),hostname, filter)
99         utils.header('Actual status for node %s is [%s]'%(hostname,node_status))
100         if (node_status[0]['boot_state'] == 'boot'):
101             utils.header('%s has reached boot state'%hostname)
102             status=True 
103         elif (node_status[0]['boot_state'] == 'dbg' ):
104             utils.header('%s has reached debug state'%hostname)
105         return status
106
107     def qemu_config(self,hostname,path):
108         model=self.node_spec['node_fields']['model']
109         if not self.is_qemu():
110             raise Exception,"wrong"
111         host_box=self.host_box()
112         mac=self.node_spec['network_fields']['mac']
113         # dest_dir is the path that needs to be relevant when qemu is invoked
114         conf_filename="%s/qemu-%s/start-qemu.conf"%(path,hostname)
115         utils.header('Storing qemu config for %s in %s'%(hostname,conf_filename))
116         file=open(conf_filename,'w')
117         file.write('MACADDR=%s\n'%mac)
118         file.write('NODE_ISO=%s.iso\n'%hostname)
119         file.close()
120         if ( not  self.is_local(host_box)):
121             dest_dir="%s/qemu-%s"%(self.buildname(),hostname)
122             utils.header ("Transferring configuration files for node %s"%hostname)
123             utils.header ("Using dir %s on %s"%(dest_dir,host_box))
124             self.test_plc.run_in_host("ssh root@%s rm -rf %s"%(host_box, dest_dir))
125             self.test_plc.run_in_host("ssh root@%s mkdir -p  %s"%(host_box, dest_dir))
126             self.test_plc.run_in_host("scp -r %s/qemu-%s/* root@%s:%s"%(path,hostname,host_box,dest_dir))
127
128     def create_boot_cd(self,path):
129         model=self.node_spec['node_fields']['model']
130         node_spec=self.node_spec
131         hostname=node_spec['node_fields']['hostname']
132         utils.header("Calling GetBootMedium for %s"%hostname)
133         encoded=self.test_plc.server.GetBootMedium(self.test_plc.auth_root(), hostname, 'node-iso', '', ['serial'])
134         if (encoded == ''):
135             raise Exception, 'boot.iso not found'
136
137         if  model.find("qemu") >= 0:
138             nodepath="%s/qemu-%s"%(path,hostname)
139             self.test_plc.run_in_host("rm -rf %s"%nodepath)
140             self.test_plc.run_in_host("mkdir -p %s"%nodepath)
141             template="%s/template-qemu"%path
142             self.test_plc.run_in_host("cp -r %s/* %s"%(template,nodepath))
143             self.qemu_config(hostname, path)
144         else:
145             nodepath="%s/real-%s"%(path,hostname)
146             self.test_plc.run_in_host("rm -rf %s"%nodepath)
147             self.test_plc.run_in_host("mkdir -p %s"%nodepath)
148
149         filename="%s/%s.iso"%(nodepath,hostname)
150         utils.header('Storing boot medium into %s'%filename)
151         file(filename,'w').write(base64.b64decode(encoded))
152     
153     def start_node (self,options):
154         model=self.node_spec['node_fields']['model']
155         #starting the Qemu nodes before 
156         if model.find("qemu") >= 0:
157             self.start_qemu(options)
158         else:
159             utils.header("TestNode.start_node : ignoring model %s"%model)
160
161     def start_qemu (self, options):
162         utils.header("Starting qemu node")
163         host_box=self.host_box()
164         hostname=self.node_spec['node_fields']['hostname']
165         dest_dir=self.buildname()+"/qemu-%s"%(hostname)
166         utils.header("Starting qemu for node %s on %s"%(hostname,host_box))
167
168         if (not self.is_local(host_box)):
169             host_string="ssh root@%s"%host_box
170         else:
171             host_string=""
172         
173         self.test_plc.run_in_host("%s ~/%s/env-qemu start >> ~/%s/%s.log "
174                                   %(host_string,  dest_dir, dest_dir, hostname ))
175         self.test_plc.run_in_host("%s ~/%s/start-qemu-node >> ~/%s/%s.log & "
176                                   %(host_string, dest_dir, dest_dir, hostname))
177
178     def kill_qemu (self):
179         hostname = self.name()
180         # kill the right processes 
181         command="./qemu_kill.sh %s"%hostname
182         utils.header("Stopping qemu for host %s on box %s"%(hostname,self.host_box()))
183         TestBox(self.host_box()).run(command)
184         return True