def do_guest_install(dut, kind, guest, encrypt_vhd=False, busy_stop=False, url=None): """Inner guest install function""" os_name, name = name_split(guest) if kind == 'iso': iso_file = '/storage/isos/%s.iso' % os_name download_image(dut, kind, guest, iso_file) def vhd_path_callback(vhd_path): """vhd_path is now known""" if kind in ['vhd', 'with_tools']: download_image(dut, kind, guest, vhd_path, url) iso_name = ('xc-tools' if kind != 'iso' else os_name)+'.iso' print 'INSTALL_GUEST: using', iso_name, 'for', kind, guest vm_address = create_vm(dut, guest, iso_name=iso_name, vhd_path_callback=vhd_path_callback, encrypt_vhd=encrypt_vhd, start_timeout=7200 if kind == 'iso' else 1200, busy_stop=busy_stop) if kind == 'iso': # this is ugly... if os_name.startswith("ubuntu"): method = "ssh" else: method = "exec_daemon" # we cannot use xenmgr here as tools are not installed soft_shutdown_guest(dut, guest, timeout=600, method=method) archive_vhd(dut, guest, have_tools=False)
def wait_for_guest(host, guest, method=None, timeout=600): """Return address for guest on host, checking that it is responding and retrying as necessary""" if method is None: method = get_default_exec_method(host, guest) assert method in ['exec_daemon', "ssh"] print 'WAIT_FOR_SYSTEM: contacting', guest, 'using', method _, name = name_split(guest) start = time() run(['xec-vm', '-n', name, 'switch'], host=host) def check_running(): """check VM is running""" count = 0 while(1): out = run(['xec-vm', '-n', name, 'get', 'state'], word_split=True, host=host) print 'WAIT_FOR_SYSTEM: VM', name, 'state', out[0] if out[0] == 'stopped': if count > 4: raise SystemStoppedWhileWaitingForSystem(out, guest, host) else: count+=1 sleep(2) else: break def get_address(): """get address for VM """ check_running() return domain_address(host, guest, timeout=5) address = retry(get_address, 'get %s address on %s' % (guest, host), timeout=timeout, propagate=[SystemStoppedWhileWaitingForSystem]) delta = time() - start rtimeout = max(30, int(timeout - delta)) print 'WAIT_FOR_SYSTEM: remainining timeout', rtimeout, 'of', timeout def check_windows_version(): """Check that VM is still running""" check_running() out = call_exec_daemon('windowsVersion', [], host=address, timeout=60) print 'WAIT_FOR_SYSTEM: windows version returned', out def check_ssh_access(): """Check that VM is available over ssh""" check_running() run(['echo', 'test succeeded'], host=address, timeout=60, check_host_key=False) print 'WAIT_FOR_SYSTEM: ssh command execution succeeded' if method == "exec_daemon": try: ver = retry(check_windows_version, description='run windowsVersion on '+host+' '+guest, timeout=rtimeout, propagate=[SystemStoppedWhileWaitingForSystem]) except error: raise UnableToContactGuestService(host, guest, timeout, error) print 'WAIT_FOR_SYSTEM:', guest, 'on', host, \ 'replied with windows version', ver, 'from address', address elif method == "ssh": retry(check_ssh_access, description='run ssh check on '+host+' '+guest, timeout=rtimeout, propagate=[SystemStoppedWhileWaitingForSystem]) print 'WAIT_FOR_SYSTEM:', guest, 'on', host, \ 'ssh test succeed on', address return address
def do_guest_install(dut, kind, guest, encrypt_vhd=False, busy_stop=False, url=None): """Inner guest install function""" os_name, name = name_split(guest) if kind == 'iso': iso_file = '/storage/isos/%s.iso' % os_name download_image(dut, kind, guest, iso_file, url) def vhd_path_callback(vhd_path): """vhd_path is now known""" if kind in ['vhd', 'with_tools']: download_image(dut, kind, guest, vhd_path, url) iso_name = ('xc-tools' if kind != 'iso' else os_name)+'.iso' print 'INSTALL_GUEST: using', iso_name, 'for', kind, guest vm_address = create_vm(dut, guest, iso_name=iso_name, vhd_path_callback=vhd_path_callback, encrypt_vhd=encrypt_vhd, start_timeout=7200 if kind == 'iso' else 1200, busy_stop=busy_stop) if kind == 'iso': # this is ugly... if os_name.startswith("ubuntu"): method = "ssh" else: method = "exec_daemon" # we cannot use xenmgr here as tools are not installed soft_shutdown_guest(dut, guest, timeout=600, method=method) archive_vhd(dut, guest, have_tools=False)
def is_test_available(case, dut, current_install, domlist, build): """Can we run case on dut? Return boolean and a reason why not""" unsuitable = case.get('unsuitable_duts', list()) if dut in unsuitable: return False, dut+' unsuitable' if current_install and case['trigger'] in ['first', 'platform install']: return False, 'restricted to current install' guest = case.get('guest') if guest is not None: guest_os_name, _ = name_split(guest) else: guest_os_name = None if guest and case.get('trigger') != 'VM install': if not [dom for dom in domlist if dom['name'] == guest and dom['status'] == 'running']: return False, "requires "+guest+" VM" if 'futile' not in case: futile = '' else: try: with time_limit(10, 'futility check'): futile = case['futile'](dut, guest, guest_os_name, build, domlist) except Exception, exc: print_exc() futile = 'futility check failed %r' % exc
def reboot_windows_vm(dut, domain): """Triger a reboot of guest""" _, name = name_split(domain) domain = find_domain(dut, name) print 'INFO: rebooting guest', domain run(['xec-vm', '-n', name, 'reboot'], host=dut) wait_for_domid_change(dut, name, domain['dom_id']) print 'INFO: reboot of', domain, 'completed'
def install_tools(dut, guest): """Install tools on guest on dut""" if not isfile(XC_TOOLS_ISO, host=dut): raise ToolsIsoMissing(dut, XC_TOOLS_ISO) os, name = name_split(guest) domain = find_domain(dut, guest) start_vm_if_not_running(dut, domain['name']) return _proxy_call(dut, name, 'install_tools', dut, name)
def reboot_windows_vm(dut, domain): """Triger a reboot of guest""" _, name = name_split(domain) domain = find_domain(dut, name) print 'INFO: rebooting guest', domain run(['xec-vm', '-n', name, 'reboot'], host=dut) wait_for_domid_change(dut, name, domain['dom_id']) print 'INFO: reboot of', domain, 'completed'
def construct_arg_dict(options, guest, test_parameters, test_case, result_id, vhd_url, vhd_name): """Work out test arguments given options, guest and test parameters. Also returns an expanded test_paramters""" if guest is None: os_name = 'dom0' else: os_name, _ = name_split(guest) os_name = dict(test_names.ordering).get(os_name, os_name) specials = { '$(OS_NAME)': os_name, '$(VHD_URL)': vhd_url, #'$(PRESEVE_DATABASE)' : options.preserve_database, '$(RESULT_ID)': result_id, '$(GUEST)': guest, '$(VHD_NAME)': vhd_name } if options.machine: specials['$(DUT)'] = options.machine arg_dict = {} for name, value in test_case['arguments']: if type(value) == type('') and value.startswith('$('): print value if value == '$(BUILD)': if options.build: #if options.build or options.release: ov = options.build else: ov = determine_build(options.machine) #ov = get_build(options.machine) elif value == '$(RELEASE)': ov = options.release elif value == '$(MAC_ADDRESS)': ov = options.mac_address elif value in specials: ov = specials[value] elif value.startswith('$(') and value.endswith(')'): option_form = value[2:-1].lower() if hasattr(options, option_form): ov = getattr(options, option_form) else: raise NoValueForArgument(name, value) else: ov = value arg_dict[name] = ov des = test_case['description'] for specialk, value in specials.items(): if value is not None: des = des.replace(specialk, str(value)) tpout = dict(test_parameters) tpout['description'] = des for k in test_case: tpout.setdefault(k, test_case[k]) return arg_dict, tpout
def construct_arg_dict(options, guest, test_parameters, test_case, result_id, vhd_url, vhd_name): """Work out test arguments given options, guest and test parameters. Also returns an expanded test_paramters""" if guest is None: os_name = 'dom0' else: os_name, _ = name_split(guest) os_name = dict(test_names.ordering).get(os_name, os_name) specials = { '$(OS_NAME)' : os_name, '$(VHD_URL)': vhd_url, #'$(PRESEVE_DATABASE)' : options.preserve_database, '$(RESULT_ID)' : result_id, '$(GUEST)' : guest, '$(VHD_NAME)': vhd_name} if options.machine: specials['$(DUT)'] = options.machine arg_dict = {} for name, value in test_case['arguments']: if type(value) == type('') and value.startswith('$('): print value if value == '$(BUILD)': if options.build: #if options.build or options.release: ov = options.build else: ov = determine_build(options.machine) #ov = get_build(options.machine) elif value == '$(RELEASE)': ov = options.release elif value == '$(MAC_ADDRESS)': ov = options.mac_address elif value in specials: ov = specials[value] elif value.startswith('$(') and value.endswith(')'): option_form = value[2:-1].lower() if hasattr(options, option_form): ov = getattr(options, option_form) else: raise NoValueForArgument(name, value) else: ov = value arg_dict[name] = ov des = test_case['description'] for specialk, value in specials.items(): if value is not None: des = des.replace(specialk, str(value)) tpout = dict(test_parameters) tpout['description'] = des for k in test_case: tpout.setdefault(k, test_case[k]) return arg_dict, tpout
def install_guest(dut, guest='xp', kind='iso', busy_stop=False, encrypt_vhd=False, url=None): """Install guest on dut from media of type kind""" os_name, name = name_split(guest) print 'HEADLINE: installing', name, '('+os_name+')', 'on', dut, \ 'from', kind, 'BUSY_STOP' if busy_stop else 'STANDARD', \ 'ENCRYPTED' if encrypt_vhd else 'CLEAR' for already in list_vms(dut): if already['name'] == name_split(guest)[1]: if already['status'] == 'running': run(['xec-vm', '-u', already['uuid'], 'shutdown'], host=dut) run(['xec-vm', '-u', already['uuid'], 'delete'], host=dut) check_free(dut, target_os=guest) assert kind in ['iso', 'vhd', 'with_tools'] print 'INSTALL_GUEST: ready to install', name do_guest_install(dut, kind, guest, encrypt_vhd, busy_stop=busy_stop, url=url) print 'INSTALL_GUEST:', guest, 'installed on', dut return run(['xec-vm', '-n', name, 'get', 'uuid'], host = dut).strip()
def install_guest(dut, guest='xp', kind='iso', busy_stop=False, encrypt_vhd=False, url=None): """Install guest on dut from media of type kind""" os_name, name = name_split(guest) print 'HEADLINE: installing', name, '('+os_name+')', 'on', dut, \ 'from', kind, 'BUSY_STOP' if busy_stop else 'STANDARD', \ 'ENCRYPTED' if encrypt_vhd else 'CLEAR' for already in list_vms(dut): if already['name'] == name_split(guest)[1]: if already['status'] == 'running': run(['xec-vm', '-u', already['uuid'], 'shutdown'], host=dut) run(['xec-vm', '-u', already['uuid'], 'delete'], host=dut) check_free(dut, target_os=guest) assert kind in ['iso', 'vhd', 'with_tools'] print 'INSTALL_GUEST: ready to install', name do_guest_install(dut, kind, guest, encrypt_vhd, busy_stop=busy_stop, url=url) print 'INSTALL_GUEST:', guest, 'installed on', dut return run(['xec-vm', '-n', name, 'get', 'uuid'], host = dut).strip()
def start_vm_if_not_running(dut, guest, timeout=600, busy_stop=False): """Start guest if it is not already running on dut""" _, name = name_split(guest) for domain in list_vms(dut, timeout=timeout): if domain['name'] == name and domain['status'] == 'running': print 'START_VM:', dut, 'on', guest, 'already running' return print 'START_VM:', dut, 'on', guest, 'not running' try: return start_vm(dut, guest, timeout=timeout, busy_stop=busy_stop) except InsufficientMemoryToRunVM: if not busy_stop: raise
def resource_leakage_test(dut, guest): print 'INFO: starting test for guest resource leakage' loopback_text = run(['losetup'], host=dut, split=True) print 'INFO: loopback text is', loopback_text old_loopbacks = len(loopback_text) - 1 print 'INFO: there are', old_loopbacks, 'loopbacks' # there may be a loopback left over from the test framework # setting the VM up, so get rid of that if old_loopbacks > 0: for loopback in loopback_text: if len(loopback) > 0: loopback_device = rstrip(loopback[0], ':') print 'INFO: deleting', loopback_device run(['losetup', '-d', loopback_device], host=dut) loopback_text = run(['losetup'], host=dut, split=True) print 'INFO: new loopback text is', loopback_text old_loopbacks = len(loopback_text) - 1 xec_before_test = run(['xec-vm'], host=dut) print 'INFO: before the test, xec showed', xec_before_test x, name = name_split(guest) print 'INFO: guest is', guest, 'and x is', x, 'and name is', name # should shut the VM down first, but how does that interact with getting its address? run(['xec-vm', '-n', name, 'shutdown'], host=dut) print 'INFO: waiting for guest', name, 'to stop on', dut wait_for_vm_to_stop(dut, name) start_and_stop_guest(dut, name) new_loopbacks = len(run(['losetup'], host=dut, line_split=True)) - 1 vm_uuids = [ vm['uuid'] for vm in list_vms(dut) ] print 'INFO: vm uuids are', vm_uuids known_vm_taps = [] for uuid in vm_uuids: known_vm_taps.extend(list_vm_taps(dut, uuid)) all_taps = [x[3].split(':')[1] for x in run(['tap-ctl', 'list'], host=dut, split=True) [:-1]] print 'INFO: taps known to belong to vms are', known_vm_taps print 'INFO: all taps are', all_taps for tap in all_taps: if tap not in known_vm_taps: raise UnclaimedVHD(tap) for uuid in vm_uuids: if 'deadbeef' in uuid: raise VMHasDeadBeef(uuid ) print 'INFO: after starting and stopping guest, there are', new_loopbacks, 'loopbacks' if new_loopbacks > old_loopbacks: raise GuestLeakingLoopbacks(new_loopbacks - old_loopbacks) print 'HEADLINE: verified no loopback leakage from guest'
def install_network_test_vm(dut, name): if not have_fresh_vhd(NETWORK_TEST_OS_NAME): print 'HEADLINE: no fresh vhd for %s, building from scratch' % NETWORK_TEST_OS_NAME build_network_test_vm(dut, NETWORK_TEST_OS_NAME) soft_shutdown_guest(dut, NETWORK_TEST_OS_NAME, method='ssh') run(['xec-vm', '-n', NETWORK_TEST_OS_NAME, 'delete'], host=dut) assert have_fresh_vhd(NETWORK_TEST_OS_NAME) # won't work outside of CBG os_name, vm_name = name_split(name) assert os_name == NETWORK_TEST_OS_NAME, "Only %s is supported as a network test VM" % NETWORK_TEST_OS_NAME vm_uuid = install_guest(dut, guest=name, kind='vhd') configure_v4v_rules(dut, vm_name) soft_reboot_and_wait(dut, vm_name) # apply v4v rules return NetworkTestVM(dut, vm_uuid)
def install_network_test_vm(dut, name): if not have_fresh_vhd(NETWORK_TEST_OS_NAME): print 'HEADLINE: no fresh vhd for %s, building from scratch' % NETWORK_TEST_OS_NAME build_network_test_vm(dut, NETWORK_TEST_OS_NAME) soft_shutdown_guest(dut, NETWORK_TEST_OS_NAME, method='ssh') run(['xec-vm', '-n', NETWORK_TEST_OS_NAME, 'delete'], host=dut) assert have_fresh_vhd(NETWORK_TEST_OS_NAME) # won't work outside of CBG os_name, vm_name = name_split(name) assert os_name == NETWORK_TEST_OS_NAME, "Only %s is supported as a network test VM" % NETWORK_TEST_OS_NAME vm_uuid = install_guest(dut, guest=name, kind='vhd') configure_v4v_rules(dut, vm_name) soft_reboot_and_wait(dut, vm_name) # apply v4v rules return NetworkTestVM(dut, vm_uuid)
def stubdom_boot(dut, guest): """Test guest still boots on dut when running with studbom""" _, name = name_split(guest) vm_address = domain_address(dut, guest) run(['xec-vm', '-n', name, 'start'], host=dut) run(['xec-vm', '-n', name, 'switch'], host=dut) wait_for_windows_to_come_up(vm_address) shutdown_windows(vm_address) wait_for_vm_to_stop(dut, guest) status = find_domain(dut, guest) print 'INFO: domain status', status run(['xec-vm', '-n', name, 'set', 'cd', 'xc-tools.iso'], host=dut) run(['xec-vm', '-n', name, 'set', 'stubdom', 'true'], host=dut) print 'INFO: booting', guest, 'with stubdom' run(['xec-vm', '-n', name, 'start'], host=dut) run(['xec-vm', '-n', name, 'switch'], host=dut) wait_for_windows_to_come_up(vm_address) print 'HEADLINE: verified', guest, 'works with stubdom=true'
def stubdom_boot(dut, guest): """Test guest still boots on dut when running with studbom""" _, name = name_split(guest) vm_address = domain_address(dut, guest) run(['xec-vm', '-n', name, 'start'], host=dut) run(['xec-vm', '-n', name, 'switch'], host=dut) wait_for_windows_to_come_up(vm_address) shutdown_windows(vm_address) wait_for_vm_to_stop(dut, guest) status = find_domain(dut, guest) print 'INFO: domain status', status run(['xec-vm', '-n', name, 'set', 'cd', 'xc-tools.iso'], host=dut) run(['xec-vm', '-n', name, 'set', 'stubdom', 'true'], host=dut) print 'INFO: booting', guest, 'with stubdom' run(['xec-vm', '-n', name, 'start'], host=dut) run(['xec-vm', '-n', name, 'switch'], host=dut) wait_for_windows_to_come_up(vm_address) print 'HEADLINE: verified', guest, 'works with stubdom=true'
def start_vm(dut, guest, may_already_be_running=False, timeout=600, busy_stop=False, check_method=None): """Start guest on dut""" check_method = check_method or get_default_exec_method(dut, guest) print 'INFO: Guest is '+guest _, name = name_split(guest) print 'START_VM:', guest, '->', name for i in range(3, 0, -1): try: run(['xec-vm', '-n', name, 'start'], timeout=300, host=dut) except SubprocessError, exc: if 'VM is already created' in repr(exc) and may_already_be_running: print 'START_VM:', guest, 'is already running' elif 'Not enough free memory!' in repr(exc): print 'START_VM: not enough memory at the moment to run', \ guest, busy_stop if (not busy_stop) or i == 1: raise InsufficientMemoryToRunVM(dut, guest, busy_stop) do_busy_stop(dut, guest) else: raise else: break
def ensure(dut, guest, busy_stop=True): """Ensure guest is installed with tools on dut. If busy_stop is true and then shut down other VMs to make more memory""" print 'INFO: contacting and determining build on', dut build = try_get_build(dut) os_name, name = name_split(guest) try: print 'INFO: looking for domain', guest domain1 = find_domain(dut, guest) except CannotFindDomain: print 'INFO:', guest, 'does not exist yet' else: print 'INFO: found domain', domain1 if domain1['status'] != 'running': print 'INFO: starting', guest vm_address = start_vm(dut, guest, busy_stop=busy_stop) else: print 'INFO: contacting', guest vm_address = wait_for_guest(dut, name) problems = tools_install_problems(dut, guest) if problems is None: print 'HEADLINE: already have suitable VM with tools' maybe_kill_prompt_remover(dut, guest, vm_address) return vm_address else: print 'HEADLINE: already have', guest, 'but', problems install_tools(dut, guest) maybe_kill_prompt_remover(dut, guest, vm_address) return vm_address if VHD_WITH_TOOLS_PATTERN: with_tools_vhd = VHD_WITH_TOOLS_PATTERN % { 'build': build, 'name': os_name, 'encrypted': '' } suitable = exists(with_tools_vhd) else: print 'INFO: set VHD_WITH_TOOLS_PATTERN to enable use of VHDs with tools installed' suitable = False if suitable: age = (time() - (stat(with_tools_vhd).st_ctime)) / (24 * 60 * 60.0) print 'INFO: found prepared VHD', with_tools_vhd, 'which is', age, 'days old' if age > MAXIMUM_VHD_AGE_DAYS: print 'INFO: not using ready made VHD since it is', age, 'days old' valid = False else: valid = True else: valid = False if valid: print 'HEADLINE: have ready made VHD at', with_tools_vhd vhd_path_callback = lambda vhd_path: download_image( dut, 'with_tools', os_name, vhd_path) vm_address2 = create_vm(dut, guest, vhd_path_callback=vhd_path_callback) problem = retry(lambda: tools_install_problems(dut, guest), description='determine whether tools are installed', catch=[error]) if problem is not None: raise ToolsNotInstalledInImage(with_tools_vhd, problem) maybe_kill_prompt_remover(dut, guest, vm_address2) return vm_address2 sans_tools_vhd = VHD_SANS_TOOLS_PATTERN % { 'name': os_name, 'encrypted': '' } kind2 = 'vhd' if have_fresh_vhd(os_name) else 'iso' install_guest(dut, guest, kind2, busy_stop=True) install_tools(dut, guest)
def wait_for_guest(host, guest, method=None, timeout=600): """Return address for guest on host, checking that it is responding and retrying as necessary""" if method is None: method = get_default_exec_method(host, guest) assert method in ['exec_daemon', "ssh"] print 'WAIT_FOR_SYSTEM: contacting', guest, 'using', method _, name = name_split(guest) start = time() run(['xec-vm', '-n', name, 'switch'], host=host) def check_running(): """check VM is running""" count = 0 while (1): out = run(['xec-vm', '-n', name, 'get', 'state'], word_split=True, host=host) print 'WAIT_FOR_SYSTEM: VM', name, 'state', out[0] if out[0] == 'stopped': if count > 4: raise SystemStoppedWhileWaitingForSystem(out, guest, host) else: count += 1 sleep(2) else: break def get_address(): """get address for VM """ check_running() return domain_address(host, guest, timeout=5) address = retry(get_address, 'get %s address on %s' % (guest, host), timeout=timeout, propagate=[SystemStoppedWhileWaitingForSystem]) delta = time() - start rtimeout = max(30, int(timeout - delta)) print 'WAIT_FOR_SYSTEM: remainining timeout', rtimeout, 'of', timeout def check_windows_version(): """Check that VM is still running""" check_running() out = call_exec_daemon('windowsVersion', [], host=address, timeout=60) print 'WAIT_FOR_SYSTEM: windows version returned', out def check_ssh_access(): """Check that VM is available over ssh""" check_running() run(['echo', 'test succeeded'], host=address, timeout=60, check_host_key=False) print 'WAIT_FOR_SYSTEM: ssh command execution succeeded' if method == "exec_daemon": try: ver = retry(check_windows_version, description='run windowsVersion on ' + host + ' ' + guest, timeout=rtimeout, propagate=[SystemStoppedWhileWaitingForSystem]) except error: raise UnableToContactGuestService(host, guest, timeout, error) print 'WAIT_FOR_SYSTEM:', guest, 'on', host, \ 'replied with windows version', ver, 'from address', address elif method == "ssh": retry(check_ssh_access, description='run ssh check on ' + host + ' ' + guest, timeout=rtimeout, propagate=[SystemStoppedWhileWaitingForSystem]) print 'WAIT_FOR_SYSTEM:', guest, 'on', host, \ 'ssh test succeed on', address return address
def tools_install_problems(dut, guest): """Return a string describing reasons why the tools install is bad or None if it is good for vm_addresss""" os_name, name = name_split(guest) return _proxy_call(dut, name, 'tools_install_problems', dut, name)
def create_vm(dut, guest, encrypt_vhd=False, iso_name=None, vhd_path_callback = lambda x: None, start_timeout=1200, busy_stop=False, networked=True): """Create and boot VM on dut called guest, with access to iso_name if specified. Wait start_timeout for it to boot. Invoke vhd_path_callback between creating and booting it with its vhd_path""" os_name, name = name_split(guest) current = list_vms(dut) print 'INFO: have VMs', current for already in list_vms(dut): if already['name'] == name: raise DomainAlreadyExists(dut, guest) memsize = 256 if os_name == 'xp' else 1024 is_windows = not os_name.startswith("ubuntu") check_method = "exec_daemon" if is_windows else "ssh" go = specify(timeout=120, host=dut) dbus_path = go(["xec", "create-vm"], word_split=True)[0] print 'INSTALL_GUEST: dbus path', dbus_path vm_go = lambda x: go(['xec', '-o', dbus_path, '-i', 'com.citrix.xenclient.xenmgr.vm']+ x, word_split=True) vm_go(['set', 'name', name]) imgpath = IMAGE_PATHS.get(os_name) if imgpath: vm_go(['set', 'image-path', imgpath]) # set image-path correctly? vm_go(['set', 'memory', str(memsize)]) vm_go(['set', 'wired-network', 'brbridged']) vm_go(['set', 'vcpus', '2']) vm_go(['set', 'description', name]) vm_go(['set', 'stubdom', 'true']) if is_windows: vm_go(['set', 'os', 'windows']) else: vm_go(['set', 'os', 'linux']) vm_go(['set', 'xci-cpuid-signature', 'true']) vm_go(['set', 'viridian', 'false']) if iso_name: vm_go(['set', 'cd', iso_name]) if networked: nic_list = vm_go(['list-nics']) print 'INFO: nic list', repr(nic_list) num_existing_nics = len(nic_list) no_nics_expected = get_xc_config_field(dut, 'NoDefaultNicsInTemplates', default_value=False) print 'INFO: found', num_existing_nics, 'NICs' if num_existing_nics == 0: if not no_nics_expected: print 'WARNING: No NICs were present on the newly-created VM, but the config file does not indicate that there should be no NICs' wired_nic_path = vm_go(['add-nic'])[0] wireless = run(['xec', '-o', '/host', 'get', 'wireless-model'], host=dut, word_split=True) if len(wireless) > 0: wireless_nic_path = vm_go(['add-nic'])[0] go(['xec', '-o', wireless_nic_path, 'set', 'wireless-driver', 'true']) go(['xec', '-o', wireless_nic_path, 'set', 'network', '/wifi/0/shared']) print 'INFO: wired_nic_path is', wired_nic_path, 'and wireless_nic_path is', wireless_nic_path else: print 'INFO: wired_nic_path is', wired_nic_path else: if no_nics_expected: print 'WARNING: Some NICs were present on the newly-created VM, but the config file does not indicate that there should be any NICs' vhd_path = go(['xec', 'create-vhd', '80000'], split=True)[0][0] print 'INSTALL_GUEST:', 'VHD path', vhd_path assert vhd_path.endswith('.vhd') print 'INSTALL_GUEST: after configuration %r' % (go( ['xec-vm', '-n', name, 'getall'])) disk_dbus_path = (go(['xec-vm', '-n', name, 'add_disk'], split=True))[0][0] disk_number = disk_dbus_path.split('/')[-1] print 'INSTALL_GUEST: disk path', disk_dbus_path, 'number', disk_number go(['xec-vm', '-n', name, '--disk', disk_number, 'attach_vhd', vhd_path]) vhd_path_callback(vhd_path) if encrypt_vhd: key_dir = run(['xec', 'get', 'platform-crypto-key-dirs'], host=dut, line_split=True)[0] run(['mkdir', '-p', key_dir], host=dut) phys_path = run(['xec-vm', '-n', name, '--disk', '1', 'get', 'phys-path'], host=dut, line_split=True)[0] print 'INFO: VHD physical path', phys_path assert basename(phys_path).endswith('.vhd') vm_vhd_uuid = basename(phys_path)[:-4] key_file = (key_dir + '/'+vm_vhd_uuid+',aes-xts-plain,'+ str(DISK_ENCRYPTION_KEY_LENGTH)+'.key') print 'INFO: VHD key', key_file # /dev/random can take more than 60 seconds to generate 512 bits # of randomness run(['dd', 'if=/dev/urandom', 'of='+key_file, 'count='+str(DISK_ENCRYPTION_KEY_LENGTH/8), 'bs=1'], host=dut) run(['vhd-util', 'key', '-n', phys_path, '-k', key_file, '-s'], host=dut) print 'INFO: set up encryption' else: print 'INFO: using an un-encrypted vhd' print 'INSTALL_GUEST: starting', guest vm_address = start_vm(dut, guest, timeout=start_timeout, busy_stop=busy_stop, check_method=check_method) print 'INSTALL_GUEST: start_vm returned, address', vm_address ensure_stable(vm_address, 30, method=check_method, description = guest + ' on '+dut) print 'INSTALL_GUEST: VM stable' return vm_address
def ensure(dut, guest, busy_stop=True): """Ensure guest is installed with tools on dut. If busy_stop is true and then shut down other VMs to make more memory""" print 'INFO: contacting and determining build on', dut build = try_get_build(dut) os_name, name = name_split(guest) try: print 'INFO: looking for domain', guest domain1 = find_domain(dut, guest) except CannotFindDomain: print 'INFO:', guest, 'does not exist yet' else: print 'INFO: found domain', domain1 if domain1['status'] != 'running': print 'INFO: starting', guest vm_address = start_vm(dut, guest, busy_stop=busy_stop) else: print 'INFO: contacting', guest vm_address = wait_for_guest(dut, name) problems = tools_install_problems(dut, guest) if problems is None: print 'HEADLINE: already have suitable VM with tools' maybe_kill_prompt_remover(dut, guest, vm_address) return vm_address else: print 'HEADLINE: already have', guest, 'but', problems install_tools(dut, guest) maybe_kill_prompt_remover(dut, guest, vm_address) return vm_address if VHD_WITH_TOOLS_PATTERN: with_tools_vhd = VHD_WITH_TOOLS_PATTERN % {'build':build, 'name': os_name, 'encrypted':''} suitable = exists(with_tools_vhd) else: print 'INFO: set VHD_WITH_TOOLS_PATTERN to enable use of VHDs with tools installed' suitable = False if suitable: age = (time() - (stat(with_tools_vhd).st_ctime)) / (24*60*60.0) print 'INFO: found prepared VHD', with_tools_vhd, 'which is', age, 'days old' if age > MAXIMUM_VHD_AGE_DAYS: print 'INFO: not using ready made VHD since it is', age, 'days old' valid = False else: valid = True else: valid = False if valid: print 'HEADLINE: have ready made VHD at', with_tools_vhd vhd_path_callback = lambda vhd_path: download_image( dut, 'with_tools', os_name, vhd_path) vm_address2 = create_vm(dut, guest, vhd_path_callback=vhd_path_callback) problem = retry(lambda: tools_install_problems(dut, guest), description='determine whether tools are installed', catch=[error]) if problem is not None: raise ToolsNotInstalledInImage(with_tools_vhd, problem) maybe_kill_prompt_remover(dut, guest, vm_address2) return vm_address2 sans_tools_vhd = VHD_SANS_TOOLS_PATTERN % {'name': os_name, 'encrypted': ''} kind2 = 'vhd' if have_fresh_vhd(os_name) else 'iso' install_guest(dut, guest, kind2, busy_stop=True) install_tools(dut, guest)
def create_vm(dut, guest, encrypt_vhd=False, iso_name=None, vhd_path_callback = lambda x: None, start_timeout=1200, busy_stop=False, networked=True): """Create and boot VM on dut called guest, with access to iso_name if specified. Wait start_timeout for it to boot. Invoke vhd_path_callback between creating and booting it with its vhd_path""" os_name, name = name_split(guest) current = list_vms(dut) print 'INFO: have VMs', current for already in list_vms(dut): if already['name'] == name: raise DomainAlreadyExists(dut, guest) memsize = 256 if os_name == 'xp' else 1024 is_windows = not os_name.startswith("ubuntu") check_method = "exec_daemon" if is_windows else "ssh" go = specify(timeout=120, host=dut) dbus_path = go(["xec", "create-vm"], word_split=True)[0] print 'INSTALL_GUEST: dbus path', dbus_path vm_go = lambda x: go(['xec', '-o', dbus_path, '-i', 'com.citrix.xenclient.xenmgr.vm']+ x, word_split=True) vm_go(['set', 'name', name]) imgpath = IMAGE_PATHS.get(os_name) if imgpath: vm_go(['set', 'image-path', imgpath]) # set image-path correctly? vm_go(['set', 'memory', str(memsize)]) vm_go(['set', 'wired-network', 'brbridged']) vm_go(['set', 'vcpus', '2']) vm_go(['set', 'description', name]) vm_go(['set', 'stubdom', 'true']) if is_windows: vm_go(['set', 'os', 'windows']) else: vm_go(['set', 'os', 'linux']) vm_go(['set', 'xci-cpuid-signature', 'true']) vm_go(['set', 'viridian', 'false']) if iso_name: vm_go(['set', 'cd', iso_name]) if networked: nic_list = vm_go(['list-nics']) print 'INFO: nic list', repr(nic_list) num_existing_nics = len(nic_list) no_nics_expected = get_xc_config_field(dut, 'NoDefaultNicsInTemplates', default_value=False) print 'INFO: found', num_existing_nics, 'NICs' if num_existing_nics == 0: if not no_nics_expected: print 'WARNING: No NICs were present on the newly-created VM, but the config file does not indicate that there should be no NICs' wired_nic_path = vm_go(['add-nic'])[0] wireless = run(['xec', '-o', '/host', 'get', 'wireless-model'], host=dut, word_split=True) if len(wireless) > 0: wireless_nic_path = vm_go(['add-nic'])[0] go(['xec', '-o', wireless_nic_path, 'set', 'wireless-driver', 'true']) go(['xec', '-o', wireless_nic_path, 'set', 'network', '/wifi/0/shared']) print 'INFO: wired_nic_path is', wired_nic_path, 'and wireless_nic_path is', wireless_nic_path else: print 'INFO: wired_nic_path is', wired_nic_path else: if no_nics_expected: print 'WARNING: Some NICs were present on the newly-created VM, but the config file does not indicate that there should be any NICs' vhd_path = go(['xec', 'create-vhd', '80000'], split=True)[0][0] print 'INSTALL_GUEST:', 'VHD path', vhd_path assert vhd_path.endswith('.vhd') print 'INSTALL_GUEST: after configuration %r' % (go( ['xec-vm', '-n', name, 'getall'])) disk_dbus_path = (go(['xec-vm', '-n', name, 'add_disk'], split=True))[0][0] disk_number = disk_dbus_path.split('/')[-1] print 'INSTALL_GUEST: disk path', disk_dbus_path, 'number', disk_number go(['xec-vm', '-n', name, '--disk', disk_number, 'attach_vhd', vhd_path]) vhd_path_callback(vhd_path) if encrypt_vhd: key_dir = run(['xec', 'get', 'platform-crypto-key-dirs'], host=dut, line_split=True)[0] run(['mkdir', '-p', key_dir], host=dut) phys_path = run(['xec-vm', '-n', name, '--disk', '1', 'get', 'phys-path'], host=dut, line_split=True)[0] print 'INFO: VHD physical path', phys_path assert basename(phys_path).endswith('.vhd') vm_vhd_uuid = basename(phys_path)[:-4] key_file = (key_dir + '/'+vm_vhd_uuid+',aes-xts-plain,'+ str(DISK_ENCRYPTION_KEY_LENGTH)+'.key') print 'INFO: VHD key', key_file # /dev/random can take more than 60 seconds to generate 512 bits # of randomness run(['dd', 'if=/dev/urandom', 'of='+key_file, 'count='+str(DISK_ENCRYPTION_KEY_LENGTH/8), 'bs=1'], host=dut) run(['vhd-util', 'key', '-n', phys_path, '-k', key_file, '-s'], host=dut) print 'INFO: set up encryption' else: print 'INFO: using an un-encrypted vhd' print 'INSTALL_GUEST: starting', guest vm_address = start_vm(dut, guest, timeout=start_timeout, busy_stop=busy_stop, check_method=check_method) print 'INSTALL_GUEST: start_vm returned, address', vm_address ensure_stable(vm_address, 30, method=check_method, description = guest + ' on '+dut) print 'INSTALL_GUEST: VM stable' return vm_address
if build is None: raise NoMatchingBuilds(tag_regexp) print 'LATEST: latest build matching', tag_regexp, 'is', build['_id'] return build['_id'] def is_test_available(case, dut, current_install, domlist, build): """Can we run case on dut? Return boolean and a reason why not""" unsuitable = case.get('unsuitable_duts', list()) if dut in unsuitable: return False, dut + ' unsuitable' if current_install and case['trigger'] in ['first', 'platform install']: return False, 'restricted to current install' guest = case.get('guest') if guest is not None: guest_os_name, _ = name_split(guest) else: guest_os_name = None if guest and case.get('trigger') != 'VM install': if not [ dom for dom in domlist if dom['name'] == guest and dom['status'] == 'running' ]: return False, "requires " + guest + " VM" if 'futile' not in case: futile = '' else: try: with time_limit(10, 'futility check'): futile = case['futile'](dut, guest, guest_os_name, build, domlist)