def _find_iso(self): identifier = self.options.pversion build = self.options.pbuild if identifier: identifier = str(identifier) if build: build = str(build) # BotD mode - All constants hardcoded here for now. if build and build.lower() in ('bod', 'botd', 'auto'): assert self.options.product, "A product identifier needs to be specified for BotD mode." if self.options.phf: LOG.warning("Hotfix parameter ignored in BotD mode.") with RestInterface(address=BOTD_HOST, proto='http') as restifc: r = restifc.api LOG.info('Querying build of the day...') response = r.get(BOTD_PATH) botd_product = self.options.product.upper() if self.options.phf: botd_branch = "%s-%s" % (identifier, self.options.phf) else: botd_branch = identifier build = response.products[botd_product].branches[botd_branch].build_id LOG.info("Found: %s", build) if self.options.image: filename = self.options.image.strip() else: base_build = None if self.options.phf else build filename = cm.isofile(identifier=identifier, build=base_build, product=self.options.product, root=self.options.build_path) if self.options.hfimage: hfiso = self.options.hfimage.strip() elif self.options.phf: hfiso = cm.isofile(identifier=identifier, build=build, hotfix=self.options.phf, product=self.options.product, root=self.options.build_path) else: hfiso = None return filename, hfiso
def bvt_emdeviso_post(): """Handles requests from BIGIP teams. All the logic needed to translate the user input into what makes sense to us happens right here. """ CONFIG_FILE = 'config/shared/web_emdeviso_request.yaml' # For people who don't like to set the application/json header. data = AttrDict(json.load(bottle.request.body)) data._referer = bottle.request.url our_config = AttrDict(yaml.load(open(get_harness('em')).read())) # Prepare placeholders in our config our_config.update({'stages': {'main': {'setup': {'install': {'parameters': {}}}}}}) our_config.update({'plugins': {'email': {'to': [], 'variables': {}}}}) plugins = our_config.plugins # Append submitter's email to recipient list if data.get('email'): plugins.email.to.append(data['email']) plugins.email.to.extend(CONFIG.web.recipients) # Set version and build in the install stage v = None if data.get('iso'): params = our_config.stages.main.setup['install'].parameters params['custom iso'] = data['iso'] v = version_from_metadata(data['iso']) if data.get('hfiso'): params = our_config.stages.main.setup['install'].parameters params['custom hf iso'] = data['hfiso'] v = version_from_metadata(data['hfiso']) # Find the RTM ISO that goes with this HF image. if not data.get('iso'): params['custom iso'] = isofile(v.version, product=str(v.product)) args = [] args[:] = NOSETESTS_ARGS args.append('--tc-file={VENV}/%s' % CONFIG_FILE) args.append('--tc=stages.enabled:1') args.append('--eval-attr=rank > 0 and rank < 11') args.append('--with-email') #args.append('--with-bvtinfo') args.append('--with-irack') args.append('{VENV}/%s' % CONFIG.paths.em) result = nosetests.delay(our_config, args, data) # @UndefinedVariable link = app.router.build('status', task_id=result.id) return dict(status=result.status, id=result.id, link=link)
def by_api(self): o = self.options timeout = o.timeout identifier = self.options.pversion build = self.options.pbuild if identifier: identifier = str(identifier) if build: build = str(build) if self.options.image: filename = self.options.image else: filename = cm.isofile(identifier=identifier, build=build, product=o.product, root=o.build_path) if self.options.hfimage: hfiso = self.options.hfimage elif self.options.phf: hfiso = cm.isofile(identifier=identifier, build=build, hotfix=o.phf, product=o.product, root=o.build_path) else: hfiso = None iso_version = cm.version_from_metadata(filename) if (iso_version.product.is_bigip and iso_version >= 'bigip 10.0.0' or iso_version.product.is_em and iso_version >= 'em 2.0.0'): raise VersionNotSupported('Only legacy images supported through EMInstaller.') emifc = EMInterface(device=o.device, address=o.address, username=o.admin_username, password=o.admin_password) emifc.open() with SSHInterface(device=o.device, address=o.address, username=o.root_username, password=o.root_password, port=self.options.ssh_port) as ssh: status = SCMD.ssh.get_prompt(ifc=ssh) if status in ['LICENSE EXPIRED', 'REACTIVATE LICENSE']: SCMD.ssh.relicense(ifc=ssh) elif status in ['LICENSE INOPERATIVE', 'NO LICENSE']: raise MacroError('Device at %s needs to be licensed.' % ssh) reachable_devices = [x['access_address'] for x in EMSQL.device.get_reachable_devices(ifc=ssh)] for x in self.devices: x.address = net.resolv(x.address) to_discover = [x for x in self.devices if x.address not in reachable_devices] if to_discover: uid = EMAPI.device.discover(to_discover, ifc=emifc) task = EMSQL.device.GetDiscoveryTask(uid, ifc=ssh) \ .run_wait(lambda x: x['status'] != 'started', timeout=timeout, progress_cb=lambda x: 'discovery: %d%%' % x.progress_percent) assert task['error_count'] == 0, 'Discovery failed: %s' % task targets = [] for device in self.devices: mgmtip = device.address version = EMSQL.device.get_device_version(mgmtip, ifc=ssh) if not o.essential_config and abs(iso_version) < abs(version): LOG.warning('Enforcing --esential-config') o.essential_config = True device_info = EMSQL.device.get_device_info(mgmtip, ifc=ssh) active_slot = EMSQL.device.get_device_active_slot(mgmtip, ifc=ssh) targets.append(dict(device_uid=device_info['uid'], slot_uid=active_slot['uid'])) image_list = EMSQL.software.get_image_list(ifc=ssh) if iso_version not in image_list: base = os.path.basename(filename) destination = '%s.%d' % (os.path.join(SHARED_TMP, base), os.getpid()) LOG.info('Importing base iso %s', base) SCMD.ssh.scp_put(device=o.device, address=o.address, destination=destination, username=self.options.root_username, password=self.options.root_password, port=self.options.ssh_port, source=filename, nokex=False) imuid = EMAPI.software.import_image(destination, ifc=emifc) else: imuid = image_list[iso_version] LOG.info('Image already imported: %d', imuid) if hfiso: hf_list = EMSQL.software.get_hotfix_list(ifc=ssh) hfiso_version = cm.version_from_metadata(hfiso) if hfiso_version not in hf_list: hfbase = os.path.basename(hfiso) destination = '%s.%d' % (os.path.join(SHARED_TMP, hfbase), os.getpid()) LOG.info('Importing hotfix iso %s', hfbase) SCMD.ssh.scp_put(device=o.device, address=o.address, destination=destination, username=self.options.root_username, password=self.options.root_password, port=self.options.ssh_port, source=hfiso, nokex=False) hfuid = EMAPI.software.import_image(destination, ifc=emifc) else: hfuid = hf_list[hfiso_version] else: hfuid = None EMSQL.software.get_hotfix_list(ifc=ssh) EMSQL.device.CountActiveTasks(ifc=ssh) \ .run_wait(lambda x: x == 0, timeout=timeout, progress_cb=lambda x: 'waiting for other tasks') LOG.info('Installing %s...', iso_version) ret = EMAPI.software.install_image(targets, imuid, hfuid, o, ifc=emifc) ret = EMSQL.software.GetInstallationTask(ret['uid'], ifc=ssh).\ run_wait(lambda x: x['status'] != 'started', progress_cb=lambda x: 'install: %d%%' % x.progress_percent, timeout=o.timeout) LOG.info('Deleting %d device(s)...', len(targets)) EMAPI.device.delete(uids=[x['device_uid'] for x in targets], ifc=emifc) emifc.close() messages = [] for d in ret['details']: if int(d['error_code']): messages.append("%(display_device_address)s:%(error_message)s" % d) if int(d['hf_error_code'] or 0): messages.append("%(display_device_address)s:%(hf_error_message)s" % d) if messages: raise InstallFailed('Install did not succeed: %s' % ', '.join(messages)) self.has_essential_config = o.essential_config return ret
def bvt_emdeviso_post(): """Handles requests from BIGIP teams. All the logic needed to translate the user input into what makes sense to us happens right here. """ LOG.info("EMDEVISO: Called") CONFIG_FILE = 'config/shared/web_emdeviso_request.yaml' # For people who don't like to set the application/json header. data = AttrDict(json.load(bottle.request.body)) LOG.info("EMDEVISO: POST Request: " + str(data)) data._referer = bottle.request.url our_config = AttrDict(yaml.load(open(get_harness('em')).read())) # Prepare placeholders in our config our_config.update( {'stages': { 'main': { 'setup': { 'install': { 'parameters': {} } } } }}) our_config.update({'plugins': {'email': {'to': [], 'variables': {}}}}) plugins = our_config.plugins # Append submitter's email to recipient list if data.get('email'): plugins.email.to.append(data['email']) plugins.email.to.extend(CONFIG.web.recipients) # Set version and build in the install stage v = None if data.get('iso'): params = our_config.stages.main.setup['install'].parameters params['custom iso'] = data['iso'] v = version_from_metadata(data['iso']) if data.get('hfiso'): params = our_config.stages.main.setup['install'].parameters params['custom hf iso'] = data['hfiso'] v = version_from_metadata(data['hfiso']) # Find the RTM ISO that goes with this HF image. if not data.get('iso'): params['custom iso'] = isofile(v.version, product=str(v.product)) args = [] args[:] = NOSETESTS_ARGS args.append('--tc-file={VENV}/%s' % CONFIG_FILE) args.append('--tc=stages.enabled:1') args.append('--eval-attr=rank > 0 and rank < 11') args.append('--with-email') # args.append('--with-bvtinfo') args.append('--with-irack') args.append('{VENV}/%s' % CONFIG.paths.em) LOG.info("EMDEVISO: Nose Args: " + str(args)) LOG.info("EMDEVISO: our_config: " + str(our_config)) result = nosetests.delay(our_config, args, data) # @UndefinedVariable link = common_app.router.build('status', task_id=result.id) emdeviso_result = dict(status=result.status, id=result.id, link=link) LOG.info("EMDEVISO: Result: " + str(emdeviso_result)) return emdeviso_result
def _find_iso(self): identifier = self.options.pversion build = self.options.pbuild if identifier: identifier = str(identifier) if build: build = str(build) # BotD mode - All constants hardcoded here for now. if build and build.lower() in ('bod', 'botd', 'auto'): assert self.options.product, "A product identifier needs to be specified for BotD mode." if self.options.phf: LOG.warning("Hotfix parameter ignored in BotD mode.") with RestInterface(address=BOTD_HOST) as restifc: r = restifc.api LOG.info('Querying for build of the day...') response = r.get(BOTD_PATH) LOG.debug("BOTD response: " + str(response)) botd_product = self.options.product.upper() if self.options.phf: botd_branch = "%s-%s" % (identifier, self.options.phf) else: botd_branch = identifier LOG.info("Looking for the BOTD for Product=" + botd_product + ", Branch=" + botd_branch) # Make sure data actually exists before trying to use it if response and response.products[botd_product] and\ response.products[botd_product].branches[botd_branch] and\ response.products[botd_product].branches[botd_branch].build_id: build = response.products[botd_product].branches[botd_branch].build_id LOG.info("Found BOTD: %s", build) else: LOG.info("BOTD info is not available, defaulting to the highest build number.") # Let the call to cm.isofile() find the latest one build = None if self.options.image: filename = self.options.image.strip() else: # Don't change this logic without considering the BOTD logic above base_build = None if self.options.phf else build filename = cm.isofile(identifier=identifier, build=base_build, product=self.options.product, root=self.options.build_path) if self.options.hfimage: hfiso = self.options.hfimage.strip() elif self.options.phf: hfiso = cm.isofile(identifier=identifier, build=build, hotfix=self.options.phf, product=self.options.product, root=self.options.build_path) else: hfiso = None return filename, hfiso
def bvt_deviso_post(): """Handles requests from Dev team for user builds ISOs. """ # BVTINFO_PROJECT_PATTERN = '(\D+)?(\d+\.\d+\.\d+)-?(hf\d+)?' DEFAULT_SUITE = 'bvt' SUITES = {'bvt': '%s/' % CONFIG.paths.current, 'dev': '%s/cloud/external/devtest_wrapper.py' % CONFIG.paths.current, 'dev-cloud': '%s/cloud/external/restservicebus.py' % CONFIG.paths.current } CONFIG_FILE = 'config/shared/web_deviso_request.yaml' # For people who don't like to set the application/json header. data = AttrDict(json.load(bottle.request.body)) # data = bottle.request.json data._referer = bottle.request.url our_config = AttrDict(yaml.load(open(get_harness('bigiq')).read())) # Prepare placeholders in our config our_config.update({'stages': {'main': {'setup': {'install': {'parameters': {}}}}}}) our_config.update({'stages': {'main': {'setup': {'install-bigips': {'parameters': {}}}}}}) our_config.update({'plugins': {'email': {'to': [], 'variables': {}}}}) plugins = our_config.plugins # Append submitter's email to recipient list if data.get('email'): plugins.email.to.append(data['email']) plugins.email.to.extend(CONFIG.web.recipients) # Set version and build in the install stage v = None if data.get('iso'): params = our_config.stages.main.setup['install'].parameters params['custom iso'] = data['iso'] v = version_from_metadata(data['iso']) if data.get('hfiso'): params = our_config.stages.main.setup['install'].parameters params['custom hf iso'] = data['hfiso'] v = version_from_metadata(data['hfiso']) # Find the RTM ISO that goes with this HF image. if not data.get('iso'): params['custom iso'] = isofile(v.version, product=str(v.product)) args = [] args[:] = NOSETESTS_ARGS rank = Literal('rank') expr = (rank > Literal(0)) & (rank < Literal(11)) # Include all migrated tests, example: functional/standalone/security/migrated/... # Assumption is that all tests are rank=505 expr |= rank == Literal(505) # Only Greenflash tests have extended attributes if v is None or v >= 'bigiq 4.5': # build hamode argument if data.ha: hamode = Literal('hamode') expr2 = Or() for x in data.ha: if x != 'standalone': expr2 += [In(String(x.upper()), hamode)] if 'standalone' in data.ha: expr &= (~hamode | expr2) else: expr &= hamode & expr2 if data.ui: uimode = Literal('uimode') if data.ui == 'api': expr &= ~uimode elif data.ui == 'ui': expr &= uimode & (uimode > Literal(0)) else: raise ValueError('Unknown value {}'.format(data.ui)) if data.module: module = Literal('module') expr2 = Or() for x in data.module: expr2 += [In(String(x.upper()), module)] expr &= (module & expr2) args.append('--tc-file={VENV}/%s' % CONFIG_FILE) # Default is our BVT suite. if v: suite = os.path.join(CONFIG.suites.root, CONFIG.suites[v.version]) else: suite = SUITES[data.get('suite', DEFAULT_SUITE)] args.append('--tc=stages.enabled:1') # XXX: No quotes around the long argument value! args.append('--eval-attr={}'.format(str(expr))) args.append('--with-email') # args.append('--collect-only') args.append('--with-irack') args.append('{VENV}/%s' % suite) v = plugins.email.variables v.args = args v.iso = data.iso v.module = data.module result = nosetests.delay(our_config, args, data) # @UndefinedVariable link = app.router.build('status', task_id=result.id) return dict(status=result.status, id=result.id, link=link)
def bvt_deviso_post(): """ Handles requests from Dev team for user builds ISOs. Input POST request looks similar to this: { '_referer': 'http://shiraz/internaltest', u 'module': [u 'access', u 'adc', u 'afm', u 'asm', u 'avr', u 'cloud', u 'device', u 'system', u 'platform'], u 'bigip_v': u '12.0.0', u 'hfiso': u '/path/to/hf.iso', u 'iso': u '/path/to/base.iso', u 'custom iso': u'/path/to/custom.iso', u 'custom hf iso': u'/path/to/custom-hf.iso', u 'ui': False, u 'testruntype': u 'biq-standard-bvt', u 'ha': [u 'standalone'], u 'email': u '*****@*****.**' } """ LOG.info("DEVISO: Called") # BVTINFO_PROJECT_PATTERN = '(\D+)?(\d+\.\d+\.\d+)-?(hf\d+)?' DEFAULT_SUITE = 'bvt' SUITES = { 'bvt': '%s/' % CONFIG.paths.current, 'dev': '%s/cloud/external/devtest_wrapper.py' % CONFIG.paths.current, 'dev-cloud': '%s/cloud/external/restservicebus.py' % CONFIG.paths.current } CONFIG_FILE = 'config/shared/web_deviso_request.yaml' BIGIP_V = CONFIG.bigip_versions AUTOMATION_RUN_TYPES = CONFIG.automation_run_types # For people who don't like to set the application/json header. data = AttrDict(json.load(bottle.request.body)) # data = bottle.request.json LOG.info("DEVISO: POST Request: " + str(data)) data._referer = bottle.request.url our_config = AttrDict(yaml.load(open(get_harness('bigiq')).read())) # Prepare placeholders in our config our_config.update( {'stages': { 'main': { 'setup': { 'install': { 'parameters': {} } } } }}) our_config.update({ 'stages': { 'main': { 'setup': { 'install-bigips': { 'parameters': {} } } } } }) our_config.update({'plugins': {'email': {'to': [], 'variables': {}}}}) plugins = our_config.plugins # Append submitter's email to recipient list if data.get('email'): plugins.email.to.append(data['email']) plugins.email.to.extend(CONFIG.web.recipients) # Set BIGIP version config if data.get('bigip_v') in BIGIP_V: bigip_cfg = BIGIP_V[data['bigip_v']] else: bigip_cfg = BIGIP_V['default'] # If a custom BIG-IP Base is specified, then do NOT append this .yaml if data.get('custom_bigip_iso') is None: our_config.setdefault('$extends', []).append(bigip_cfg) # Set BIG-IQ version and build in the install stage v = None if data.get('iso'): params = our_config.stages.main.setup['install'].parameters params['custom iso'] = data['iso'] v = version_from_metadata(data['iso']) if data.get('hfiso'): params = our_config.stages.main.setup['install'].parameters params['custom hf iso'] = data['hfiso'] v = version_from_metadata(data['hfiso']) # Find the RTM ISO that goes with this HF image. if not data.get('iso'): params['custom iso'] = isofile(v.version, product=str(v.product)) # Set the BIG-IP version and build in the install stage, if it was # specified in the POST request. if data.get('custom_bigip_iso'): params = our_config.stages.main.setup['install-bigips'].parameters params['custom iso'] = data['custom_bigip_iso'] # Only append BIG-IP HF info if a Base was specified if data.get('custom_bigip_hf_iso'): params = our_config.stages.main.setup['install-bigips'].parameters params['custom hf iso'] = data['custom_bigip_hf_iso'] args = [] args[:] = NOSETESTS_ARGS # Set the NOSE rank string based on the automation type expr = Literal(AUTOMATION_RUN_TYPES[data['testruntype']]) # Only Greenflash tests have extended attributes if v is None or v >= 'bigiq 4.5': # build hamode argument if data.ha: hamode = Literal('hamode') expr2 = Or() for x in data.ha: if x != 'standalone': expr2 += [In(String(x.upper()), hamode)] if 'standalone' in data.ha: expr &= (~hamode | expr2) else: expr &= hamode & expr2 if data.ui: uimode = Literal('uimode') if data.ui == 'api': expr &= ~uimode elif data.ui == 'ui': expr &= uimode & (uimode > Literal(0)) else: raise ValueError('Unknown value {}'.format(data.ui)) if data.module: module = Literal('module') expr2 = Or() for x in data.module: expr2 += [In(String(x.upper()), module)] expr &= (module & expr2) args.append('--tc-file={VENV}/%s' % CONFIG_FILE) # Default is our BVT suite. if v: suite = os.path.join(CONFIG.suites.root, CONFIG.suites[v.version]) else: suite = SUITES[data.get('suite', DEFAULT_SUITE)] args.append('--tc=stages.enabled:1') # XXX: No quotes around the long argument value! args.append('--eval-attr={}'.format(str(expr))) args.append('--with-email') # args.append('--collect-only') args.append('--with-irack') args.append('{VENV}/%s' % suite) v = plugins.email.variables v.args = args v.iso = data.iso v.module = data.module LOG.info("DEVISO: Nose Args: " + str(v)) LOG.info("DEVISO: our_config: " + str(our_config)) result = nosetests.delay(our_config, args, data) # @UndefinedVariable link = common_app.router.build('status', task_id=result.id) deviso_result = dict(status=result.status, id=result.id, link=link) LOG.info("DEVISO: Result: " + str(deviso_result)) return deviso_result
def bvt_deviso_post(): """Handles requests from Dev team for user builds ISOs. """ # BVTINFO_PROJECT_PATTERN = '(\D+)?(\d+\.\d+\.\d+)-?(hf\d+)?' DEFAULT_SUITE = 'bvt' SUITES = { 'bvt': '%s/' % CONFIG.paths.current, 'dev': '%s/cloud/external/devtest_wrapper.py' % CONFIG.paths.current, 'dev-cloud': '%s/cloud/external/restservicebus.py' % CONFIG.paths.current } CONFIG_FILE = 'config/shared/web_deviso_request.yaml' # For people who don't like to set the application/json header. data = AttrDict(json.load(bottle.request.body)) # data = bottle.request.json data._referer = bottle.request.url our_config = AttrDict(yaml.load(open(get_harness('bigiq')).read())) # Prepare placeholders in our config our_config.update( {'stages': { 'main': { 'setup': { 'install': { 'parameters': {} } } } }}) our_config.update({ 'stages': { 'main': { 'setup': { 'install-bigips': { 'parameters': {} } } } } }) our_config.update({'plugins': {'email': {'to': [], 'variables': {}}}}) plugins = our_config.plugins # Append submitter's email to recipient list if data.get('email'): plugins.email.to.append(data['email']) plugins.email.to.extend(CONFIG.web.recipients) # Set version and build in the install stage v = None if data.get('iso'): params = our_config.stages.main.setup['install'].parameters params['custom iso'] = data['iso'] v = version_from_metadata(data['iso']) if data.get('hfiso'): params = our_config.stages.main.setup['install'].parameters params['custom hf iso'] = data['hfiso'] v = version_from_metadata(data['hfiso']) # Find the RTM ISO that goes with this HF image. if not data.get('iso'): params['custom iso'] = isofile(v.version, product=str(v.product)) args = [] args[:] = NOSETESTS_ARGS rank = Literal('rank') expr = (rank > Literal(0)) & (rank < Literal(11)) # Include all migrated tests, example: functional/standalone/security/migrated/... # Assumption is that all tests are rank=505 expr |= rank == Literal(505) # Only Greenflash tests have extended attributes if v is None or v >= 'bigiq 4.5': # build hamode argument if data.ha: hamode = Literal('hamode') expr2 = Or() for x in data.ha: if x != 'standalone': expr2 += [In(String(x.upper()), hamode)] if 'standalone' in data.ha: expr &= (~hamode | expr2) else: expr &= hamode & expr2 if data.ui: uimode = Literal('uimode') if data.ui == 'api': expr &= ~uimode elif data.ui == 'ui': expr &= uimode & (uimode > Literal(0)) else: raise ValueError('Unknown value {}'.format(data.ui)) if data.module: module = Literal('module') expr2 = Or() for x in data.module: expr2 += [In(String(x.upper()), module)] expr &= (module & expr2) args.append('--tc-file={VENV}/%s' % CONFIG_FILE) # Default is our BVT suite. if v: suite = os.path.join(CONFIG.suites.root, CONFIG.suites[v.version]) else: suite = SUITES[data.get('suite', DEFAULT_SUITE)] args.append('--tc=stages.enabled:1') # XXX: No quotes around the long argument value! args.append('--eval-attr={}'.format(str(expr))) args.append('--with-email') # args.append('--collect-only') args.append('--with-irack') args.append('{VENV}/%s' % suite) v = plugins.email.variables v.args = args v.iso = data.iso v.module = data.module result = nosetests.delay(our_config, args, data) # @UndefinedVariable link = app.router.build('status', task_id=result.id) return dict(status=result.status, id=result.id, link=link)