def run_machine(self, machine): # Check if machine is in accepting state. assert machine.current_state == VM_IS_LAUNCHED # Bake a shell command to spawn the machine. shell_command = self.get_kvm_call(machine) logger.debug('Running VM with shell command:\n%s' % shell_command) report_filepath = self.get_report_file(machine) pid_filepath = self.get_pid_file(machine) if ProcessUtil.process_runs(pid_filepath): logging.warning('Apparently, VM process is already running. ' 'Check %s ' % pid_filepath) machine.change_state(VM_HAS_FAILED) # TODO: kill the VM? return ProcessUtil.exec_process(shell_command, report_filepath, pid_filepath) # Update state. machine.change_state(VM_IS_RUNNING) # Put info into vnc target file. vnc_target_path = self.get_vnc_target_path(machine) with open(vnc_target_path, 'w+') as vnc_target: try: cmd = get_cmd_from_ps(needle=machine.disk_filename) except KeyError as error: logger.error('Failed to find VNC port of the vm: %s' % machine) logger.exception(error) return match = re.search(r'-vnc localhost:(\d+)', cmd, re.MULTILINE) local_vnc_port = 5900 + int(match.group(1)) # e.g 'test: localhost:5901' vnc_info = '%s: localhost:%s' % (machine.name, local_vnc_port) logger.info('Writing into VNC target file: %s' % vnc_info) vnc_target.write(vnc_info + "\n")
def stop_machine(self, machine): # Check if machine is in accepting state. assert machine.current_state == VM_IS_TERMINATING # Kill the machine by pid. cxt_pidfile_filepath = self.get_pid_file(machine) proc_pidfile_path = '%s_proc' % cxt_pidfile_filepath # First kill proc which is a child and then daemoncxt. if ProcessUtil.kill_process(proc_pidfile_path) \ and ProcessUtil.kill_process(cxt_pidfile_filepath): logging.info('Successfully stopping VM processes as in %s and %s' % (proc_pidfile_path, cxt_pidfile_filepath)) else: logging.warning('Expected VM process does not run anymore. ' 'Please check the log file for details: %s' % self.get_report_file(machine)) # Proc pid should be taken care of. if os.path.exists(proc_pidfile_path): os.unlink(proc_pidfile_path) # Update state. machine.change_state(VM_IS_STOPPED) # Remove vnc target file vnc_target_path = self.get_vnc_target_path(machine) if os.path.exists(vnc_target_path): logger.info('Removing VNC target file: %s' % vnc_target_path) os.remove(vnc_target_path)
def run_machine(self, machine): # Check if machine is in accepting state. assert machine.current_state == VM_IS_LAUNCHED # Bake a shell command to spawn the machine. shell_command = self.get_kvm_call(machine) logger.debug('Running VM with shell command:\n%s' % shell_command) #output = invoke(command) report_filepath = self.get_report_file(machine) pid_filepath = self.get_pid_file(machine) assert not ProcessUtil.process_runs(pid_filepath) ProcessUtil.exec_process(shell_command, report_filepath, pid_filepath) # Update state. machine.change_state(VM_IS_RUNNING)
def run_machine(self, machine): # Check if machine is in accepting state. assert machine.current_state == VM_IS_LAUNCHED # Bake a shell command to spawn the machine. shell_command = self.get_kvm_call(machine) logger.debug('Running VM with shell command:\n%s' % shell_command) #output = invoke(command) report_filepath = self.get_report_file(machine) pid_filepath = self.get_pid_file(machine) if ProcessUtil.process_runs(pid_filepath): logging.warning('Apparently, VM process is already running. ' 'Check %s ' % pid_filepath) machine.change_state(VM_HAS_FAILED) # TODO: kill the VM? return ProcessUtil.exec_process(shell_command, report_filepath, pid_filepath) # Update state. machine.change_state(VM_IS_RUNNING)
def check_heartbeat(self): ''' Check every pid that is tracked by picostack if the respective machine is actually running? If not, then stop the machine and remove the pid file. ''' instances = VmInstance.objects.filter(current_state=VM_IS_RUNNING) if not instances.exists(): logger.info('No machines are running to check the heartbeat..') return for machine in instances: pid_filepath = self.get_pid_file(machine) if ProcessUtil.process_runs(pid_filepath): logger.info('Heart beat of "%s" is OK - still running' % machine.name) continue logging.warning('DB contains a running VM entry with no ' 'corresponding process.') logging.info('Stopping the machine "%s" and removing pid files ' % machine.name) machine.change_state(VM_IS_TERMINATING) self.stop_machine(machine)