def panic(self, panic_line): panic_reason = self._hyper.readline() info("VM signalled PANIC. Reading until EOT (", hex(ord(EOT)), ")") print color.VM(panic_reason), remaining_output = self._hyper.read_until_EOT() for line in remaining_output.split("\n"): print color.VM(line) self.exit(exit_codes["VM_PANIC"], panic_reason)
def boot(self, timeout=60, multiboot=True, debug=False, kernel_args="booted with vmrunner", image_name=None): info("VM boot, timeout: ", timeout, "multiboot: ", multiboot, "Kernel_args: ", kernel_args, "image_name: ", image_name) # This might be a reboot self._exit_status = None self._exit_complete = False self._timeout_after = timeout # Start the timeout thread if (timeout): info("setting timeout to", timeout, "seconds") self._timer = threading.Timer(timeout, self._on_timeout) self._timer.start() # Boot via hypervisor try: self._hyper.boot(multiboot, debug, kernel_args, image_name) except Exception as err: print color.WARNING("Exception raised while booting: ") print_exception() if (timeout): self._timer.cancel() self.exit(exit_codes["BOOT_FAILED"], str(err)) # Start analyzing output while self._exit_status == None and self.poll() == None: try: line = self._hyper.readline() except Exception as e: print color.WARNING( "Exception thrown while waiting for vm output") break if line and self.find_exit_status(line) == None: print color.VM(line.rstrip()) self.trigger_event(line) # Empty line - should only happen if process exited else: pass # VM Done info("Event loop done. Exit status:", self._exit_status, "poll:", self.poll()) # If the VM process didn't exit by now we need to stop it. if (self.poll() == None): self.stop() # Process may have ended without EOT / exit message being read yet # possibly normal vm shutdown if self.poll() != None: info("No poll - getting final output") try: data, err = self._hyper.get_final_output() # Print stderr if exit status wasnt 0 if err and self.poll() != 0: print color.WARNING("Stderr: \n" + err) # Parse the last output from vm lines = data.split("\n") for line in lines: print color.VM(line) self.find_exit_status(line) # Note: keep going. Might find panic after service exit except Exception as e: pass # We should now have an exit status, either from a callback or VM EOT / exit msg. if self._exit_status != None: info("VM has exit status. Exiting.") self.exit(self._exit_status, self._exit_msg) else: self.exit(self._hyper.poll(), "process exited") # If everything went well we can return return self
def boot(self, timeout=60, multiboot=True, kernel_args="booted with vmrunner", image_name=None): # This might be a reboot self._exit_status = None self._timeout_after = timeout # Start the timeout thread if (timeout): info("setting timeout to", timeout, "seconds") self._timer = threading.Timer(timeout, self._on_timeout) self._timer.start() # Boot via hypervisor try: self._hyper.boot(multiboot, kernel_args, image_name) except Exception as err: print color.WARNING("Exception raised while booting: ") print_exception() if (timeout): self._timer.cancel() self.exit(exit_codes["BOOT_FAILED"], str(err)) # Start analyzing output while self._hyper.poll() == None and not self._exit_status: try: line = self._hyper.readline() except Exception as e: print color.WARNING( "Exception thrown while waiting for vm output") break if line: # Special case for end-of-transmission if line == EOT: if not self._exit_status: self._exit_status = exit_codes["VM_EOT"] break if line.startswith( " [ Kernel ] service exited with status"): self._exit_status = int(line.split(" ")[-1].rstrip()) self._exit_msg = "Service exited" break else: print color.VM(line.rstrip()) else: pass # TODO: Add event-trigger for EOF? for pattern, func in self._on_output.iteritems(): if re.search(pattern, line): try: res = func(line) except Exception as err: print color.WARNING( "Exception raised in event callback: ") print_exception() res = False self.stop() # NOTE: It can be 'None' without problem if res == False: self._exit_status = exit_codes["CALLBACK_FAILED"] self.exit(self._exit_status, " Event-triggered test failed") # If the VM process didn't exit by now we need to stop it. if (self.poll() == None): self.stop() # We might have an exit status, e.g. set by a callback noticing something wrong with VM output if self._exit_status: self.exit(self._exit_status, self._exit_msg) # Process might have ended prematurely elif self.poll(): self.exit(self._hyper.poll(), self._hyper.get_error_messages()) # If everything went well we can return return self