13 image_types = ['node-iso', 'node-usb', 'generic-iso', 'generic-usb']
17 os.kill(pid, signal.SIGKILL)
18 os.waitpid(pid,os.WNOHANG)
22 class boot_node(Test):
24 Attempts to boot the specified node using qemu.
27 def state_nanny(self):
28 hostname = self.hostname
29 nodes = self.config.api.GetNodes(self.config.auth, [hostname], ['boot_state'])
31 boot_state = node['boot_state']
32 if self.config.verbose:
33 utils.header("%(hostname)s boot_state is %(boot_state)s" % locals())
35 if boot_state in ['boot', 'debug']:
38 if self.config.verbose:
39 if boot_state in ['boot']:
40 utils.header("%(hostname)s correctly installed and booted" % locals())
42 utils.header("%(hostname)s not fully booted" % locals())
43 self.boot_state = boot_state
46 def console_nanny(self,console_states):
47 ready = select.select([],[self.stdout],[],1)[1]
51 line = self.stdout.readline()
52 for searchstring in console_states.keys():
53 result = line.find(searchstring)
54 # if result... ret = console_states[searchstring]
56 # check result for whether we found it
58 # for now just print it out
60 # should be parsing for special strings that indicate whether
61 # we've reached a particular state within the boot sequence
65 def call(self, hostname, image_type = 'node-iso', disk_size="4G", wait = 30):
66 # wait up to 30 minutes for a node to boot and install itself correctly
67 self.hostname = hostname
68 self.totaltime = 60*60*wait
71 auth = self.config.auth
75 nodes = api.GetNodes(auth, [hostname], ['hostname'])
77 raise Exception, "No such node %(hostname)s" % locals()
79 bootimage = api.GetBootMedium(auth, hostname, image_type, '')
80 bootimage_path = '/%(tdir)s/%(hostname)s-bootcd.iso' % locals()
82 if self.config.verbose:
83 utils.header("Creating bootcd for %(hostname)s at %(bootimage_path)s" % locals())
84 # Create a temporary bootcd file
85 fp = open(bootimage_path, 'w')
86 fp.write(base64.b64decode(bootimage))
89 # Create a temporary disk image
90 diskimage_path = "/%(tdir)s/%(hostname)s-hda.img" % locals()
91 qemu_img_cmd = "qemu-img create -f qcow2 %(diskimage_path)s %(disk_size)s" % locals()
92 (stdin, stdout, stderr) = os.popen3(qemu_img_cmd)
93 self.errors = stderr.readlines()
95 raise Exception, "Unable to create disk image\n" + \
96 "\n".join(self.errors)
98 if self.config.verbose:
99 utils.header("Booting %(hostname)s" % locals())
101 # Attempt to boot this node image
103 # generate a temp filename to which qemu should store its pid (crappy approach)
104 tmp = tempfile.mkstemp(".pid","qemu_")
109 # boot node with ramsize memory
112 # always use the 64 bit version of qemu, as this will work on both 32 & 64 bit host kernels
113 bootcmd = "qemu-system-x86_64"
114 # tell qemu to store its pid ina file
115 bootcmd = bootcmd + " -pidfile %(pidfile)s " % locals()
116 # boot with ramsize memory
117 bootcmd = bootcmd + " -m %(ramsize)s" % locals()
119 bootcmd = bootcmd + " -smp 1"
120 # no graphics support -> assume we are booting via serial console
121 bootcmd = bootcmd + " -nographic"
122 # boot from the supplied cdrom iso file
123 bootcmd = bootcmd + " -boot d"
124 bootcmd = bootcmd + " -cdrom %(bootimage_path)s" % locals()
125 # hard disk image to use for the node
126 bootcmd = bootcmd + " %(diskimage_path)s" % locals()
128 (self.stdin, self.stdout, self.stderr) = os.popen3(bootcmd)
130 # wait for qemu to start up
133 # get qemu's pid from its pidfile (crappy approach)
140 # loop until the node is either fully booted, some error
141 # occured, or we've reached our totaltime out
142 def catch(sig, frame):
143 self.totaltime = self.totaltime -1
144 total = self.totaltime
146 (((total % 60)==0) and self.state_nanny()):
153 signal.signal(signal.SIGALRM, catch)
157 console_states = {"login:":1}
160 self.console_nanny(console_states)
161 except: # need a better way to catch exceptions
171 if __name__ == '__main__':
172 args = tuple(sys.argv[1:])