Beispiel #1
0
    def __init__(self, host, bundle_dir, vmcfg, assignment):
        self.host = host
        self.bundle_dir = bundle_dir
        self.vmcfg = vmcfg
        self.assignment = assignment

        self.asscfg = vmcfg.assignments()
        self.machine = self.asscfg.get(assignment, 'Machine')
        self.machinecfg = VmwareMachineConfig(vmcfg, self.machine)
        self.vmwarecfg = VmwareConfig(vmcfg.testers(),
                                      self.machinecfg.get_tester_id())
        self.error_fname = os.path.join(bundle_dir, 'vmchecker-stderr.vmr')
        self.shell = self.machinecfg.guest_shell_path()

        self.username = self.machinecfg.guest_user()
        self.password = self.machinecfg.guest_pass()
Beispiel #2
0
    def __init__(self, host, bundle_dir, vmcfg, assignment):
        self.host = host
        self.bundle_dir = bundle_dir
        self.vmcfg = vmcfg
        self.assignment = assignment

        self.asscfg  = vmcfg.assignments()
        self.machine = self.asscfg.get(assignment, 'Machine')
        self.machinecfg = VmwareMachineConfig(vmcfg, self.machine)
        self.vmwarecfg = VmwareConfig(vmcfg.testers(), self.machinecfg.get_tester_id())
        self.error_fname = os.path.join(bundle_dir, 'vmchecker-stderr.vmr')
        self.shell = self.machinecfg.guest_shell_path()

        self.username = self.machinecfg.guest_user()
        self.password = self.machinecfg.guest_pass()
Beispiel #3
0
class VM():
    host = None
    path = None
    username = None
    password = None
    IP = None

    def __init__(self, host, bundle_dir, vmcfg, assignment):
        self.host = host
        self.bundle_dir = bundle_dir
        self.vmcfg = vmcfg
        self.assignment = assignment

        self.asscfg = vmcfg.assignments()
        self.machine = self.asscfg.get(assignment, 'Machine')
        self.machinecfg = VmwareMachineConfig(vmcfg, self.machine)
        self.vmwarecfg = VmwareConfig(vmcfg.testers(),
                                      self.machinecfg.get_tester_id())
        self.error_fname = os.path.join(bundle_dir, 'vmchecker-stderr.vmr')
        self.shell = self.machinecfg.guest_shell_path()

        self.username = self.machinecfg.guest_user()
        self.password = self.machinecfg.guest_pass()

    def executeCommand(self, cmd):
        # host.executeCommand(...)
        pass

    def executeNativeCommand(self, cmd):
        # there is no default need for native commands
        return self.executeCommand(cmd)

    def hasStarted(self):
        return False

    def start(self):
        pass

    def stop(self):
        pass

    def revert(self, number=None):
        pass

    def copyTo(self, targetDir, sourceDir, files):
        pass

    def copyFrom(self, targetDir, sourceDir, files):
        pass

    def run(self, shell, executable_file, timeout):
        pass

    def runTest(self, bundle_dir, machinecfg, test):
        """ originally named  def copy_files_and_run_script(vm, bundle_dir, machinecfg, test) """
        try:
            files_to_copy = test['input'] + test['script']
            guest_dest_dir = machinecfg.guest_base_path()
            self.copyTo(bundle_dir, guest_dest_dir, files_to_copy)
            for script in test['script']:
                shell = machinecfg.guest_shell_path()
                dest_in_guest_shell = machinecfg.guest_home_in_shell()
                script_in_guest_shell = dest_in_guest_shell + script
                timedout = self.run(shell, script_in_guest_shell,
                                    test['timeout'])
                self.copyFrom(guest_dest_dir, bundle_dir, test['output'])
                if timedout:
                    return False
        except:
            _logger.exception('error in copy_files_and_run_script')
        finally:
            return True

    def try_power_on_vm_and_login(self):
        if self.asscfg.revert_to_snapshot(self.assignment):
            self.revert()

        self.start()
        return True

    def test_submission(self, buildcfg=None):
        success = self.try_power_on_vm_and_login()
        if not success:
            _logger.error('Could not power on or login on the VM')
            self.stop()
            sys.exit(1)

        # start host commands
        host_command = self.vmcfg.get(self.machine, 'HostCommand', default='')
        host_command_data = self.host.start_host_commands(
            self.bundle_dir, host_command)

        timeout = self.asscfg.get(self.assignment, 'Timeout')
        try:
            if buildcfg == None:
                buildcfg = {
                    'input': ['archive.zip', 'tests.zip'],
                    'script': ['build.sh'],
                    'output': ['build-stdout.vmr', 'build-stderr.vmr'],
                    'timeout': int(timeout),
                }
                if not self.runTest(self.bundle_dir, self.machinecfg,
                                    buildcfg):
                    _logger.info('Build failed')
                    return

                testcfg = {
                    'input': [],
                    'script': ['run.sh'],
                    'output': ['run-stdout.vmr', 'run-stderr.vmr'],
                    'timeout': int(timeout)
                }
                self.runTest(self.bundle_dir, self.machinecfg, testcfg)
            else:
                self.runTest(self.bundle_dir, self.machinecfg, buildcfg)
        except Exception:
            _logger.exception('F**K! Exception!RUUUUUUUN!!!')
        finally:
            self.host.stop_host_commands(host_command_data)
            self.stop()
Beispiel #4
0
    def __init__(self, host, bundle_dir, sb_cfg):
        VM.__init__(self, host, bundle_dir, sb_cfg)
        self.machinecfg = VmwareMachineConfig(sb_cfg, 'Machine')
        self.vmwarecfg = VmwareConfig(sb_cfg, 'Tester')
        self.asscfg = AssignmentConfig(config = sb_cfg)
        self.testercfg = TesterConfig(config = sb_cfg)
        self.vmx_path = self.machinecfg.get_vmx_path()
        if self.vmx_path == None:
            self.vmx_path = self.get_submission_vmx_file()
        if self.vmx_path == None:
            # no vmx, nothing to do.
            _logger.error('Could not find a vmx to run')
            with open(self.error_fname, 'a') as handler:
                print >> handler, 'Error powering on the virtual machine.\n' + \
                                  'Unable to find .vmx file.\n'
            sys.exit(1)

        vmx_prefix = self.testercfg.vm_store_path('Tester')
        if vmx_prefix is not None:
            self.vmx_path = os.path.join(vmx_prefix, self.vmx_path)

        try:
            if self.vmwarecfg.vmware_type() == 3:
                self.vmhost = pyvix.vix.Host()
            elif self.vmwarecfg.vmware_type() == 2 or \
                    self.vmwarecfg.vmware_type() == 10:
                self.vmhost = pyvix.vix.Host(self.vmwarecfg.vmware_type(),
                                  self.vmwarecfg.vmware_url(),
                                  int(self.vmwarecfg.vmware_port()),
                                  self.vmwarecfg.vmware_username(),
                                  self.vmwarecfg.vmware_password())
        except pyvix.vix.VIXException:
            _logger.exception('Exception thrown: ' + type(e).__name__ + "\n" + ", ".join(e.args) + "\n" + e.__str__())
            with open(self.error_fname, 'a') as handler:
                print >> handler, 'Error powering on the virtual machine.\n' + \
                                  'Connecting to the host Vmware services failed.\n'
            sys.exit(1)

        if self.vmwarecfg.vmware_register_and_unregister():
            self.vmhost.registerVM(self.vmwarecfg.vmware_rel_vmx_path(self.vmx_path))

        vmx_path = self.vmx_path
        if not os.path.isfile(vmx_path):
            vmx_path = self.vmwarecfg.vmware_rel_vmx_path(self.vmx_path)

        if not os.path.isfile(vmx_path):
            # no vmx, nothing to do.
            _logger.error('Could not find a vmx to run')
            with open(self.error_fname, 'a') as handler:
                print >> handler, 'Error powering on the virtual machine.\n' + \
                                  'Unable to find .vmx file.\n'
            sys.exit(1)

        try:
            self.vminstance = self.vmhost.openVM(vmx_path)
        except pyvix.vix.VIXException:
            _logger.exception('Exception thrown: ' + type(e).__name__ + "\n" + ", ".join(e.args) + "\n" + e.__str__())
            with open(self.error_fname, 'a') as handler:
                print >> handler, 'Error powering on the virtual machine.\n' + \
                                  'Unable to open the .vmx file..\n'
            sys.exit(1)
Beispiel #5
0
class VmWareVM(VM):
    vmhost = None
    vminstance = None
            
    def __init__(self, host, bundle_dir, sb_cfg):
        VM.__init__(self, host, bundle_dir, sb_cfg)
        self.machinecfg = VmwareMachineConfig(sb_cfg, 'Machine')
        self.vmwarecfg = VmwareConfig(sb_cfg, 'Tester')
        self.asscfg = AssignmentConfig(config = sb_cfg)
        self.testercfg = TesterConfig(config = sb_cfg)
        self.vmx_path = self.machinecfg.get_vmx_path()
        if self.vmx_path == None:
            self.vmx_path = self.get_submission_vmx_file()
        if self.vmx_path == None:
            # no vmx, nothing to do.
            _logger.error('Could not find a vmx to run')
            with open(self.error_fname, 'a') as handler:
                print >> handler, 'Error powering on the virtual machine.\n' + \
                                  'Unable to find .vmx file.\n'
            sys.exit(1)

        vmx_prefix = self.testercfg.vm_store_path('Tester')
        if vmx_prefix is not None:
            self.vmx_path = os.path.join(vmx_prefix, self.vmx_path)

        try:
            if self.vmwarecfg.vmware_type() == 3:
                self.vmhost = pyvix.vix.Host()
            elif self.vmwarecfg.vmware_type() == 2 or \
                    self.vmwarecfg.vmware_type() == 10:
                self.vmhost = pyvix.vix.Host(self.vmwarecfg.vmware_type(),
                                  self.vmwarecfg.vmware_url(),
                                  int(self.vmwarecfg.vmware_port()),
                                  self.vmwarecfg.vmware_username(),
                                  self.vmwarecfg.vmware_password())
        except pyvix.vix.VIXException:
            _logger.exception('Exception thrown: ' + type(e).__name__ + "\n" + ", ".join(e.args) + "\n" + e.__str__())
            with open(self.error_fname, 'a') as handler:
                print >> handler, 'Error powering on the virtual machine.\n' + \
                                  'Connecting to the host Vmware services failed.\n'
            sys.exit(1)

        if self.vmwarecfg.vmware_register_and_unregister():
            self.vmhost.registerVM(self.vmwarecfg.vmware_rel_vmx_path(self.vmx_path))

        vmx_path = self.vmx_path
        if not os.path.isfile(vmx_path):
            vmx_path = self.vmwarecfg.vmware_rel_vmx_path(self.vmx_path)

        if not os.path.isfile(vmx_path):
            # no vmx, nothing to do.
            _logger.error('Could not find a vmx to run')
            with open(self.error_fname, 'a') as handler:
                print >> handler, 'Error powering on the virtual machine.\n' + \
                                  'Unable to find .vmx file.\n'
            sys.exit(1)

        try:
            self.vminstance = self.vmhost.openVM(vmx_path)
        except pyvix.vix.VIXException:
            _logger.exception('Exception thrown: ' + type(e).__name__ + "\n" + ", ".join(e.args) + "\n" + e.__str__())
            with open(self.error_fname, 'a') as handler:
                print >> handler, 'Error powering on the virtual machine.\n' + \
                                  'Unable to open the .vmx file..\n'
            sys.exit(1)



    def executeCommand(self,cmd):
        return self.vminstance.runProgramInGuest(self.shell,'--login -c "'+cmd+'"')
    
    def start(self):
        self.vminstance.powerOn()

    def stop(self):
        try:
            self.vminstance.powerOff()
        except pyvix.vix.VIXException:
            _logger.exception('Exception thrown: ' + type(e).__name__ + "\n" + ", ".join(e.args) + "\n" + e.__str__())
        if self.vmwarecfg.vmware_register_and_unregister():
            try:
                self.vmhost.unregisterVM(self.vmwarecfg.vmware_rel_vmx_path(self.vmx_path))
            except pyvix.vix.VIXException:
                _logger.exception('Exception thrown: ' + type(e).__name__ + "\n" + ", ".join(e.args) + "\n" + e.__str__())

    def _wait_for_tools(self):
        """Called by the thread that waits for the VMWare Tools to
           start. If the Tools do not start, there is no direct way of
           ending the Thread.  As a result, on powerOff(), the Thread
           would throw a VIXException on account of the VM not being
           powered on.
        """
        try:
            self.vminstance.waitForToolsInGuest()
        except pyvix.vix.VIXException:
            _logger.exception('Exception thrown: ' + type(e).__name__ + "\n" + ", ".join(e.args) + "\n" + e.__str__())


    def wait_for_tools_with_timeout(self, timeout, error_fname):
        """Wait for VMWare Tools to start.

        Returns True on success and False when the VMWare tools did not
        start properly in the given timeout. Writes error messages to
        `error_fname`.
        """

        if timeout > 0:
            _logger.info('Waiting for VMWare Tools with a timeout of %d seconds' % timeout)

        tools_thd = Thread(target = self._wait_for_tools)
        tools_thd.start()
        # normally the thread will end before the timeout expires, so a high timeout
        tools_thd.join(timeout)


        if not tools_thd.isAlive():
            return True


        _logger.error('Timeout waiting for VMWare Tools to start.' +
                      'Make sure your virtual machine boots up corectly' +
                      'and that you have VMWare Tools installed.')

        with open(error_fname, 'a') as handler:
            print >> handler, 'Timeout waiting for VMWare Tools to start.\n' + \
                      'Make sure your virtual machine boots up corectly\n' + \
                      'and that you have VMWare Tools installed.\n'
        return False

    def powerOn(self):
        """ see power_on_with_message_handler """
        power_thd = Thread(target = self.start)
        power_thd.start()

        if self.vmwarecfg.vmware_type() == 2 or \
                self.vmwarecfg.vmware_type() == 10:
            # VMWARE_SERVER or VMWARE_VI_SERVER
            # Wait for the VM to powr on in case it hangs on a message
            power_thd.join(VMWARE_VM_POWERON_TIMEOUT)

            if not power_thd.isAlive():
                # vm.powerOn() didn't hang: the machine has been powered on
                return

            # Run the message handler
            proc = Popen(['vmchecker-message-handler',
                      self.vmwarecfg.vmware_hostname(),
                      self.vmwarecfg.vmware_username(),
                      self.vmwarecfg.vmware_password(),
                      self.vmwarecfg.vmware_rel_vmx_path(self.vmx_path)])
            os.waitpid(proc.pid, 0)

            # Wait for the VM to power on again
            power_thd.join(VMWARE_VM_POWERON_TIMEOUT)

            if not power_thd.isAlive():
                # vm.powerOn() didn't hang: the machine has been powered on
                return

            _logger.error('Powering on VM timed out')
            with open(self.error_fname, 'a') as handler:
                print >> handler, 'Error powering on the virtual machine.\n' + \
                                  'Timed out while powering on.\n'
            sys.exit(1)
        else:
            # VMWARE_WORKSTATION
            # Just wait until the VM has powered on
            power_thd.join()

    def try_power_on_vm_and_login(self, revertSnapshot=None):
        if revertSnapshot == True or \
           (revertSnapshot == None and self.asscfg.revert_to_snapshot('Assignment')):
            self.revert(self.vminstance.nRootSnapshots - 1)

        tools_timeout = self.asscfg.delay_wait_for_tools('Assignment')
        self.powerOn()
        
        if not self.wait_for_tools_with_timeout(tools_timeout, self.error_fname):
            # no tools, nothing to do.
            return False

        try:
            self.vminstance.loginInGuest(self.machinecfg.guest_user(), self.machinecfg.guest_pass())
        except pyvix.vix.VIXSecurityException:
            _logger.error('Error logging in on the virtual machine.' +
                          'Make sure you have the accounts properly configured.')
            with open(error_fname, 'a') as handler:
                print >> handler,'Error logging in on the virtual machine.\n' + \
                        'Make sure you have the user accounts properly configured.\n'
                return False

        time.sleep(self.asscfg.delay_between_tools_and_tests('Assignment'))
        return True
        
        
    def revert(self, number = None):
        """Revert the vminstance to the number snapshot

        Note: snapshots are counted from 0.
        """
        if number==None:
            _logger.error('Snapshot number is needed')
            return
        if self.vminstance.nRootSnapshots <= number:
            err_str = ('Cannot revert to snapshot %d. Too few ' +
                       'snapshots (nr = %d) found on %s.' %
                       (number, self.vminstance.nRootSnapshots, self.vminstance.vmxPath))
            raise Exception(err_str)
        snaps = self.vminstance.rootSnapshots
	try:
	        self.vminstance.revertToSnapshot(snaps[number])
	except:
	        _logger.error('Could not revert to snapshot')
       
    def copyTo(self, sourceDir, targetDir, files):
        """ Copy files from host(source) to guest(target) """
        for f in files:
            host_path = os.path.join(sourceDir, f)
            guest_path = targetDir + f
            if not os.path.exists(host_path):
                _logger.error('host file (to send) "%s" does not exist' % host_path)
                return
            _logger.info('copy file %s from host to guest at %s' % (host_path, guest_path))
            self.vminstance.copyFileFromHostToGuest(host_path, guest_path)
        
    def copyFrom(self, sourceDir, targetDir, files):
        """ Copy files from guest(source) to host(target) """
        for f in files:
            host_path = os.path.join(targetDir, f)
            guest_path = sourceDir + f
            _logger.info('copy file %s from guest to host at %s' % (guest_path, host_path))
            self.vminstance.copyFileFromGuestToHost(guest_path, host_path)
            if not os.path.exists(host_path):
                _logger.error('host file (received) "%s" does not exist' % host_path)

    def run(self, shell, executable_file, timeout):
        args = ' --login -c ' + '"chmod +x ' + executable_file + '; ' + executable_file + '"'
        self.executeCommand("chmod +x "+ executable_file)
        _logger.info('executing on the remote: prog=%s args=[%s] timeout=%d' % (shell, executable_file, timeout))
        thd = Thread(target = self.vminstance.runProgramInGuest, args = (shell,args))
        thd.start()
        thd.join(timeout)
        return thd.isAlive()
        
    def get_submission_vmx_file(self):
        """Unzip search the bundle_dir and locate the .vmx file, no matter
        in what sub-folders it is located in. If the unzipped archive has
        multiple .vmx files, just pick the first.

        """
        for (root, _, files) in os.walk(self.bundle_dir):
            for f in files:
                if f.endswith(".vmx"):
                    return os.path.join(root, f)
        return None

    def hasStarted(self):
        return self.vminstance[VIX_PROPERTY_VM_POWER_STATE] & VIX_POWERSTATE_TOOLS_RUNNING != 0

    def hasStopped(self):
        return self.vminstance[VIX_PROPERTY_VM_POWER_STATE] & VIX_POWERSTATE_POWERED_OFF != 0
Beispiel #6
0
    def __init__(self, host, bundle_dir, sb_cfg):
        VM.__init__(self, host, bundle_dir, sb_cfg)
        self.machinecfg = VmwareMachineConfig(sb_cfg, 'Machine')
        self.vmwarecfg = VmwareConfig(sb_cfg, 'Tester')
        self.asscfg = AssignmentConfig(config = sb_cfg)
        self.testercfg = TesterConfig(config = sb_cfg)
        self.vmx_path = self.machinecfg.get_vmx_path()
        if self.vmx_path == None:
            self.vmx_path = self.get_submission_vmx_file()
        if self.vmx_path == None:
            # no vmx, nothing to do.
            _logger.error('Could not find a vmx to run')
            with open(self.error_fname, 'a') as handler:
                print >> handler, 'Error powering on the virtual machine.\n' + \
                                  'Unable to find .vmx file.\n'
            sys.exit(1)

        vmx_prefix = self.testercfg.vm_store_path('Tester')
        if vmx_prefix is not None:
            self.vmx_path = os.path.join(vmx_prefix, self.vmx_path)

        try:
            if self.vmwarecfg.vmware_type() == 3:
                self.vmhost = pyvix.vix.Host()
            elif self.vmwarecfg.vmware_type() == 2 or \
                    self.vmwarecfg.vmware_type() == 10:
                self.vmhost = pyvix.vix.Host(self.vmwarecfg.vmware_type(),
                                  self.vmwarecfg.vmware_url(),
                                  int(self.vmwarecfg.vmware_port()),
                                  self.vmwarecfg.vmware_username(),
                                  self.vmwarecfg.vmware_password())
        except pyvix.vix.VIXException as e:
            _logger.exception('Exception thrown: ' + type(e).__name__ + "\n" + ", ".join(e.args) + "\n" + e.__str__())
            with open(self.error_fname, 'a') as handler:
                print >> handler, 'Error powering on the virtual machine.\n' + \
                                  'Connecting to the host Vmware services failed.\n'
            sys.exit(1)

        if self.vmwarecfg.vmware_register_and_unregister():
            self.vmhost.registerVM(self.vmwarecfg.vmware_rel_vmx_path(self.vmx_path))

        vmx_path = self.vmx_path
        if not os.path.isfile(vmx_path):
            vmx_path = self.vmwarecfg.vmware_rel_vmx_path(self.vmx_path)

        if not os.path.isfile(vmx_path):
            # no vmx, nothing to do.
            _logger.error('Could not find a vmx to run')
            with open(self.error_fname, 'a') as handler:
                print >> handler, 'Error powering on the virtual machine.\n' + \
                                  'Unable to find .vmx file.\n'
            sys.exit(1)

        try:
            self.vminstance = self.vmhost.openVM(vmx_path)
        except pyvix.vix.VIXException as e:
            _logger.exception('Exception thrown: ' + type(e).__name__ + "\n" + ", ".join(e.args) + "\n" + e.__str__())
            with open(self.error_fname, 'a') as handler:
                print >> handler, 'Error powering on the virtual machine.\n' + \
                                  'Unable to open the .vmx file..\n'
            sys.exit(1)
Beispiel #7
0
class VmWareVM(VM):
    vmhost = None
    vminstance = None
            
    def __init__(self, host, bundle_dir, sb_cfg):
        VM.__init__(self, host, bundle_dir, sb_cfg)
        self.machinecfg = VmwareMachineConfig(sb_cfg, 'Machine')
        self.vmwarecfg = VmwareConfig(sb_cfg, 'Tester')
        self.asscfg = AssignmentConfig(config = sb_cfg)
        self.testercfg = TesterConfig(config = sb_cfg)
        self.vmx_path = self.machinecfg.get_vmx_path()
        if self.vmx_path == None:
            self.vmx_path = self.get_submission_vmx_file()
        if self.vmx_path == None:
            # no vmx, nothing to do.
            _logger.error('Could not find a vmx to run')
            with open(self.error_fname, 'a') as handler:
                print >> handler, 'Error powering on the virtual machine.\n' + \
                                  'Unable to find .vmx file.\n'
            sys.exit(1)

        vmx_prefix = self.testercfg.vm_store_path('Tester')
        if vmx_prefix is not None:
            self.vmx_path = os.path.join(vmx_prefix, self.vmx_path)

        try:
            if self.vmwarecfg.vmware_type() == 3:
                self.vmhost = pyvix.vix.Host()
            elif self.vmwarecfg.vmware_type() == 2 or \
                    self.vmwarecfg.vmware_type() == 10:
                self.vmhost = pyvix.vix.Host(self.vmwarecfg.vmware_type(),
                                  self.vmwarecfg.vmware_url(),
                                  int(self.vmwarecfg.vmware_port()),
                                  self.vmwarecfg.vmware_username(),
                                  self.vmwarecfg.vmware_password())
        except pyvix.vix.VIXException as e:
            _logger.exception('Exception thrown: ' + type(e).__name__ + "\n" + ", ".join(e.args) + "\n" + e.__str__())
            with open(self.error_fname, 'a') as handler:
                print >> handler, 'Error powering on the virtual machine.\n' + \
                                  'Connecting to the host Vmware services failed.\n'
            sys.exit(1)

        if self.vmwarecfg.vmware_register_and_unregister():
            self.vmhost.registerVM(self.vmwarecfg.vmware_rel_vmx_path(self.vmx_path))

        vmx_path = self.vmx_path
        if not os.path.isfile(vmx_path):
            vmx_path = self.vmwarecfg.vmware_rel_vmx_path(self.vmx_path)

        if not os.path.isfile(vmx_path):
            # no vmx, nothing to do.
            _logger.error('Could not find a vmx to run')
            with open(self.error_fname, 'a') as handler:
                print >> handler, 'Error powering on the virtual machine.\n' + \
                                  'Unable to find .vmx file.\n'
            sys.exit(1)

        try:
            self.vminstance = self.vmhost.openVM(vmx_path)
        except pyvix.vix.VIXException as e:
            _logger.exception('Exception thrown: ' + type(e).__name__ + "\n" + ", ".join(e.args) + "\n" + e.__str__())
            with open(self.error_fname, 'a') as handler:
                print >> handler, 'Error powering on the virtual machine.\n' + \
                                  'Unable to open the .vmx file..\n'
            sys.exit(1)



    def executeCommand(self,cmd):
        return self.vminstance.runProgramInGuest(self.shell,'--login -c "'+cmd+'"')
    
    def start(self):
        self.vminstance.powerOn()

    def stop(self):
        try:
            self.vminstance.powerOff()
        except pyvix.vix.VIXException as e:
            _logger.exception('Exception thrown: ' + type(e).__name__ + "\n" + ", ".join(e.args) + "\n" + e.__str__())
        if self.vmwarecfg.vmware_register_and_unregister():
            try:
                self.vmhost.unregisterVM(self.vmwarecfg.vmware_rel_vmx_path(self.vmx_path))
            except pyvix.vix.VIXException as e:
                _logger.exception('Exception thrown: ' + type(e).__name__ + "\n" + ", ".join(e.args) + "\n" + e.__str__())

    def _wait_for_tools(self):
        """Called by the thread that waits for the VMWare Tools to
           start. If the Tools do not start, there is no direct way of
           ending the Thread.  As a result, on powerOff(), the Thread
           would throw a VIXException on account of the VM not being
           powered on.
        """
        try:
            self.vminstance.waitForToolsInGuest()
        except pyvix.vix.VIXException as e:
            _logger.exception('Exception thrown: ' + type(e).__name__ + "\n" + ", ".join(e.args) + "\n" + e.__str__())


    def wait_for_tools_with_timeout(self, timeout, error_fname):
        """Wait for VMWare Tools to start.

        Returns True on success and False when the VMWare tools did not
        start properly in the given timeout. Writes error messages to
        `error_fname`.
        """

        if timeout > 0:
            _logger.info('Waiting for VMWare Tools with a timeout of %d seconds' % timeout)

        tools_thd = Thread(target = self._wait_for_tools)
        tools_thd.start()
        # normally the thread will end before the timeout expires, so a high timeout
        tools_thd.join(timeout)


        if not tools_thd.isAlive():
            return True


        _logger.error('Timeout waiting for VMWare Tools to start. ' +
                      'Make sure your virtual machine boots up correctly ' +
                      'and that you have VMWare Tools installed.')

        with open(error_fname, 'a') as handler:
            print >> handler, 'Timeout waiting for VMWare Tools to start.\n' + \
                      'Make sure your virtual machine boots up corectly\n' + \
                      'and that you have VMWare Tools installed.\n'
        return False

    def powerOn(self):
        """ see power_on_with_message_handler """
        power_thd = Thread(target = self.start)
        power_thd.start()

        if self.vmwarecfg.vmware_type() == 2 or \
                self.vmwarecfg.vmware_type() == 10:
            # VMWARE_SERVER or VMWARE_VI_SERVER
            # Wait for the VM to powr on in case it hangs on a message
            power_thd.join(VMWARE_VM_POWERON_TIMEOUT)

            if not power_thd.isAlive():
                # vm.powerOn() didn't hang: the machine has been powered on
                return

            # Run the message handler
            proc = Popen(['vmchecker-message-handler',
                      self.vmwarecfg.vmware_hostname(),
                      self.vmwarecfg.vmware_username(),
                      self.vmwarecfg.vmware_password(),
                      self.vmwarecfg.vmware_rel_vmx_path(self.vmx_path)])
            os.waitpid(proc.pid, 0)

            # Wait for the VM to power on again
            power_thd.join(VMWARE_VM_POWERON_TIMEOUT)

            if not power_thd.isAlive():
                # vm.powerOn() didn't hang: the machine has been powered on
                return

            _logger.error('Powering on VM timed out')
            with open(self.error_fname, 'a') as handler:
                print >> handler, 'Error powering on the virtual machine.\n' + \
                                  'Timed out while powering on.\n'
            sys.exit(1)
        else:
            # VMWARE_WORKSTATION
            # Just wait until the VM has powered on
            power_thd.join()

    def try_power_on_vm_and_login(self, revertSnapshot=None):
        if revertSnapshot == True or \
           (revertSnapshot == None and self.asscfg.revert_to_snapshot('Assignment')):
            self.revert(self.vminstance.nRootSnapshots - 1)

        tools_timeout = self.asscfg.delay_wait_for_tools('Assignment')
        self.powerOn()
        
        if not self.wait_for_tools_with_timeout(tools_timeout, self.error_fname):
            # no tools, nothing to do.
            return False

        try:
            self.vminstance.loginInGuest(self.machinecfg.guest_user(), self.machinecfg.guest_pass())
        except pyvix.vix.VIXSecurityException:
            _logger.error('Error logging in on the virtual machine.' +
                          'Make sure you have the accounts properly configured.')
            with open(error_fname, 'a') as handler:
                print >> handler,'Error logging in on the virtual machine.\n' + \
                        'Make sure you have the user accounts properly configured.\n'
                return False

        time.sleep(self.asscfg.delay_between_tools_and_tests('Assignment'))
        return True
        
        
    def revert(self, number = None):
        """Revert the vminstance to the number snapshot

        Note: snapshots are counted from 0.
        """
        if number==None:
            _logger.error('Snapshot number is needed')
            return
        if self.vminstance.nRootSnapshots <= number:
            err_str = ('Cannot revert to snapshot %d. Too few ' +
                       'snapshots (nr = %d) found on %s.' %
                       (number, self.vminstance.nRootSnapshots, self.vminstance.vmxPath))
            raise Exception(err_str)
        snaps = self.vminstance.rootSnapshots
	try:
	        self.vminstance.revertToSnapshot(snaps[number])
	except:
	        _logger.error('Could not revert to snapshot')
       
    def copyTo(self, sourceDir, targetDir, files):
        """ Copy files from host(source) to guest(target) """
        if self.vminstance[VIX_PROPERTY_VM_POWER_STATE] & VIX_POWERSTATE_TOOLS_RUNNING == 0:
            return
        for f in files:
            host_path = os.path.join(sourceDir, f)
            guest_path = targetDir + f
            if not os.path.exists(host_path):
                _logger.error('host file (to send) "%s" does not exist' % host_path)
                return
            _logger.info('copy file %s from host to guest at %s' % (host_path, guest_path))
            self.vminstance.copyFileFromHostToGuest(host_path, guest_path)
        
    def copyFrom(self, sourceDir, targetDir, files):
        """ Copy files from guest(source) to host(target) """
        if self.vminstance[VIX_PROPERTY_VM_POWER_STATE] & VIX_POWERSTATE_TOOLS_RUNNING == 0:
            return
        for f in files:
            host_path = os.path.join(targetDir, f)
            guest_path = sourceDir + f
            _logger.info('copy file %s from guest to host at %s' % (guest_path, host_path))
            self.vminstance.copyFileFromGuestToHost(guest_path, host_path)
            if not os.path.exists(host_path):
                _logger.error('host file (received) "%s" does not exist' % host_path)

    def run(self, shell, executable_file, timeout):
        args = ' --login -c ' + '"chmod +x ' + executable_file + '; ' + executable_file + '"'
        self.executeCommand("chmod +x "+ executable_file)
        _logger.info('executing on the remote: prog=%s args=[%s] timeout=%d' % (shell, executable_file, timeout))
        thd = Thread(target = self.vminstance.runProgramInGuest, args = (shell,args))
        thd.start()
        thd.join(timeout)
        return thd.isAlive()
        
    def get_submission_vmx_file(self):
        """Unzip search the bundle_dir and locate the .vmx file, no matter
        in what sub-folders it is located in. If the unzipped archive has
        multiple .vmx files, just pick the first.

        """
        for (root, _, files) in os.walk(self.bundle_dir):
            for f in files:
                if f.endswith(".vmx"):
                    return os.path.join(root, f)
        return None

    def hasStarted(self):
        return self.vminstance[VIX_PROPERTY_VM_POWER_STATE] & VIX_POWERSTATE_TOOLS_RUNNING != 0

    def hasStopped(self):
        return self.vminstance[VIX_PROPERTY_VM_POWER_STATE] & VIX_POWERSTATE_POWERED_OFF != 0
Beispiel #8
0
class VM():
    host 	= None
    path 	= None
    username	= None
    password	= None
    IP	= None
    def __init__(self, host, bundle_dir, vmcfg, assignment):
        self.host = host
        self.bundle_dir = bundle_dir
        self.vmcfg = vmcfg
        self.assignment = assignment

        self.asscfg  = vmcfg.assignments()
        self.machine = self.asscfg.get(assignment, 'Machine')
        self.machinecfg = VmwareMachineConfig(vmcfg, self.machine)
        self.vmwarecfg = VmwareConfig(vmcfg.testers(), self.machinecfg.get_tester_id())
        self.error_fname = os.path.join(bundle_dir, 'vmchecker-stderr.vmr')
        self.shell = self.machinecfg.guest_shell_path()

        self.username = self.machinecfg.guest_user()
        self.password = self.machinecfg.guest_pass()

    def executeCommand(self, cmd):
        # host.executeCommand(...)
        pass

    def executeNativeCommand(self, cmd):
        # there is no default need for native commands
        return self.executeCommand(cmd)

    def hasStarted(self):
        return False

    def start(self):
        pass
        
    def stop(self):
        pass
        
    def revert(self, number = None):
        pass
        
    def copyTo(self, targetDir, sourceDir, files):
        pass

    def copyFrom(self, targetDir, sourceDir, files):
        pass
        
    def run(self, shell, executable_file, timeout):
        pass
        
    def runTest(self, bundle_dir, machinecfg, test):
        """ originally named  def copy_files_and_run_script(vm, bundle_dir, machinecfg, test) """
        try:
            files_to_copy = test['input'] + test['script']
            guest_dest_dir = machinecfg.guest_base_path()
            self.copyTo(bundle_dir,guest_dest_dir,files_to_copy)
            for script in test['script']:
                shell = machinecfg.guest_shell_path()
                dest_in_guest_shell = machinecfg.guest_home_in_shell()
                script_in_guest_shell = dest_in_guest_shell  + script
                timedout = self.run(shell,script_in_guest_shell,test['timeout'])
                self.copyFrom(guest_dest_dir,bundle_dir,test['output'])
                if timedout:
                    return False
        except:
            _logger.exception('error in copy_files_and_run_script')
        finally:
            return True
        
    def try_power_on_vm_and_login(self):
        if self.asscfg.revert_to_snapshot(self.assignment):
            self.revert()

        self.start()
        return True
        
    def test_submission(self, buildcfg = None):
        success = self.try_power_on_vm_and_login()
        if not success:
            _logger.error('Could not power on or login on the VM')
            self.stop()
            sys.exit(1)

        # start host commands
        host_command = self.vmcfg.get(self.machine, 'HostCommand', default='')
        host_command_data = self.host.start_host_commands(self.bundle_dir, host_command)
        
        timeout = self.asscfg.get(self.assignment, 'Timeout')
        try:
            if buildcfg==None:
                buildcfg = {
                    'input'  : ['archive.zip', 'tests.zip'],
                    'script' : ['build.sh'],
                    'output' : ['build-stdout.vmr', 'build-stderr.vmr'],
                    'timeout': int(timeout),
                    }
                if not self.runTest(self.bundle_dir, self.machinecfg, buildcfg):
                    _logger.info('Build failed')
                    return
            
                testcfg = {
                    'input'  : [],
                    'script' : ['run.sh'],
                    'output' : ['run-stdout.vmr', 'run-stderr.vmr'],
                    'timeout': int(timeout)
                    }
                self.runTest(self.bundle_dir, self.machinecfg, testcfg) 
            else:
                self.runTest(self.bundle_dir, self.machinecfg, buildcfg)
        except Exception:
            _logger.exception('F**K! Exception!RUUUUUUUN!!!')
        finally:
            self.host.stop_host_commands(host_command_data)
            self.stop()