Example #1
0
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)
Example #2
0
def min_version_validator(value=None,
                          project=None,
                          hotfix=None,
                          product=Product.BIGIP,
                          iso=None,
                          min_ver='bigip 11.4.0',
                          **kwargs):
    if hotfix and 'eng' == str(hotfix).lower() and not value:
        return 'Invalid ENG hotfix build'
    if iso:
        isofile = sanitize_atom_path(iso)
    elif value and project:
        try:
            project2, hotfix2 = split_hf(project)
            isofile = create_finder(identifier=project2,
                                    build=value,
                                    hotfix=hotfix or hotfix2,
                                    product=product).find_file()
        except IsoNotFoundError:
            if hotfix:
                return 'Invalid build for {0} hotfix {1}'.format(
                    project, hotfix)
            return 'Invalid build for %s' % project
    else:
        raise NotImplementedError('Need build and project or iso')
    iso_version = version_from_metadata(isofile)
    return iso_version >= Version(min_ver)
Example #3
0
def max_version_validator(value=None,
                          project=None,
                          hotfix=None,
                          product=Product.BIGIP,
                          iso=None,
                          max_ver='bigip 14',
                          **kwargs):
    """ Make sure that we aren't trying to run tests on a BIG-IP version that
        is too new to be supported.
    """
    if hotfix and 'eng' == str(hotfix).lower() and not value:
        return 'Invalid ENG hotfix build'
    if iso:
        isofile = sanitize_atom_path(iso)
    elif value and project:
        try:
            project2, hotfix2 = split_hf(project)
            isofile = create_finder(identifier=project2,
                                    build=value,
                                    hotfix=hotfix or hotfix2,
                                    product=product).find_file()
        except IsoNotFoundError:
            if hotfix:
                return 'Invalid build for {0} hotfix {1}'.format(
                    project, hotfix)
            return 'Invalid build for %s' % project
    else:
        raise NotImplementedError('Need build and project or iso')
    iso_version = version_from_metadata(isofile)
    return iso_version < Version(max_ver)
Example #4
0
    def setup(self):
        # Set the admin and root usernames and passwords
        self.set_defaults()

        if self.options.image:
            title = 'Installing custom base image on %s' % self.address
        else:
            title = 'Installing %s %s on %s' % (self.options.product,
                                                self.options.pversion,
                                                self.address)
        LOG.info(title)
        filename, hfiso = self._find_iso()
        iso_version = cm.version_from_metadata(filename)

        if self.options.copy_only:
            self.copy_only(filename, hfiso)
            return

        #LOG.info('Disabling the 14.0+ password policy...')
        #RCMD.system.DisablePasswordPolicy(address=self.address,
        #                                  port=self.options.ssl_port).run_wait(timeout=self.options.timeout)

        if self.options.format_partitions or self.options.format_volumes:
            with SSHInterface(address=self.address,
                              username=self.options.root_username,
                              password=self.options.root_password,
                              port=self.options.ssh_port) as sshifc:
                version = SCMD.ssh.get_version(ifc=sshifc)
        else:
            with IcontrolInterface(address=self.address,
                                   username=self.options.admin_username,
                                   password=self.options.admin_password,
                                   port=self.options.ssl_port) as icifc:
                version = ICMD.system.get_version(ifc=icifc)

        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' or
                iso_version.product.is_bigiq or iso_version.product.is_iworkflow):
            if self.options.format_partitions or self.options.format_volumes or \
               (version.product.is_bigip and version < 'bigip 10.0.0' or
                    version.product.is_em and version < 'em 2.0.0'):
                ret = self.by_image2disk(filename, hfiso)
            else:
                ret = self.by_icontrol(filename, hfiso)
        elif (iso_version.product.is_bigip and iso_version < 'bigip 9.6.0' or
              iso_version.product.is_em and iso_version < 'em 2.0.0'):
            assert self.options.em_address, "--em-address is needed for legacy installations."
            ret = self.by_em_api(filename, hfiso)
        else:
            raise VersionNotSupported('%s is not supported' % iso_version)

        LOG.debug('done')
        return ret
Example #5
0
    def setup(self):
        # Set the admin and root usernames and passwords
        self.set_defaults()

        if self.options.image:
            title = 'Installing custom base image on %s' % self.address
        else:
            title = 'Installing %s %s on %s' % (self.options.product,
                                                self.options.pversion,
                                                self.address)
        LOG.info(title)
        filename, hfiso = self._find_iso()
        iso_version = cm.version_from_metadata(filename)

        if self.options.copy_only:
            self.copy_only(filename, hfiso)
            return

        if self.options.format_partitions or self.options.format_volumes:
            with SSHInterface(address=self.address,
                              username=self.options.root_username,
                              password=self.options.root_password,
                              port=self.options.ssh_port) as sshifc:
                version = SCMD.ssh.get_version(ifc=sshifc)
        else:
            with IcontrolInterface(address=self.address,
                                   username=self.options.admin_username,
                                   password=self.options.admin_password,
                                   port=self.options.ssl_port) as icifc:
                version = ICMD.system.get_version(ifc=icifc)

        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' or
                iso_version.product.is_bigiq):
            if self.options.format_partitions or self.options.format_volumes or \
               (version.product.is_bigip and version < 'bigip 10.0.0' or
                    version.product.is_em and version < 'em 2.0.0'):
                ret = self.by_image2disk(filename, hfiso)
            else:
                ret = self.by_icontrol(filename, hfiso)
        elif (iso_version.product.is_bigip and iso_version < 'bigip 9.6.0' or
              iso_version.product.is_em and iso_version < 'em 2.0.0'):
            assert self.options.em_address, "--em-address is needed for legacy installations."
            ret = self.by_em_api(filename, hfiso)
        else:
            raise VersionNotSupported('%s is not supported' % iso_version)

        LOG.debug('done')
        return ret
Example #6
0
def min_version_validator(value=None, project=None, hotfix=None, product=Product.BIGIP,
                          iso=None, min_ver='bigip 11.4.0', **kwargs):
    if hotfix and 'eng' == hotfix.lower() and not value:
        return 'Invalid ENG hotfix build'
    if iso:
        isofile = sanitize_atom_path(iso)
    elif value and project:
        try:
            project2, hotfix2 = split_hf(project)
            isofile = create_finder(identifier=project2, build=value,
                                    hotfix=hotfix or hotfix2, product=product).find_file()
        except IsoNotFoundError:
            if hotfix:
                return 'Invalid build for {0} hotfix {1}'.format(project, hotfix)
            return 'Invalid build for %s' % project
    else:
        raise NotImplementedError('Need build and project or iso')
    iso_version = version_from_metadata(isofile)
    return iso_version >= Version(min_ver)
Example #7
0
    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
Example #8
0
    def by_icontrol(self, filename, hfiso=None):
        iso_version = cm.version_from_metadata(filename)
        timeout = self.options.timeout
        if hfiso:
            hfiso_version = cm.version_from_metadata(hfiso)
        else:
            hfiso_version = None

        LOG.debug('iso: %s', iso_version)

        icifc = IcontrolInterface(address=self.address,
                                  username=self.options.admin_username,
                                  password=self.options.admin_password,
                                  port=self.options.ssl_port)
        ic = icifc.open()
        running_volume = ICMD.software.get_active_volume(ifc=icifc)
        assert running_volume != self.options.volume, \
            "Can't install on the active volume"

        version = ICMD.system.get_version(ifc=icifc)
        base = os.path.basename(filename)

        LOG.debug('running: %s', version)
        essential = self.options.essential_config
        if not essential and abs(iso_version) < abs(version):
            LOG.warning('Enforcing --esential-config')
            essential = True

        LOG.info('Setting the global DB vars...')
        ic.Management.Partition.set_active_partition(active_partition='Common')
        ic.Management.DBVariable.modify(variables=[
            {'name': 'LiveInstall.MoveConfig',
             'value': essential and 'disable' or 'enable'},
            {'name': 'LiveInstall.SaveConfig',
             'value': essential and 'disable' or 'enable'}
        ])
        # =======================================================================
        # Copy the ISO over to the device in /shared/images if it's not already
        # in the software repository.
        # =======================================================================
        images = ICMD.software.get_software_image(ifc=icifc)
        haz_it = any(filter(lambda x: x['verified'] and
                            x['product'] == iso_version.product.to_tmos and
                            x['version'] == iso_version.version and
                            x['build'] == iso_version.build, images))

        volume = self.options.volume or ICMD.software.get_inactive_volume(ifc=icifc)
        LOG.info('Preparing volume %s...', volume)
        ICMD.software.clear_volume(volume=volume, ifc=icifc)

        def is_available(items):
            all_count = len(items)
            return sum(bool(x['verified']) for x in items) == all_count

        is_clustered = ic.System.Cluster.is_clustered_environment()

        LOG.info('Timeout: %d', timeout)

        if essential:
            with SSHInterface(address=self.address,
                              username=self.options.root_username,
                              password=self.options.root_password,
                              timeout=timeout, port=self.options.ssh_port) as sshifc:
                ssh = sshifc.api
                lines = ssh.run('ls ' + SHARED_IMAGES).stdout.split()
                images = [x for x in lines if '.iso' in x]

            hfbase = os.path.basename(hfiso) if hfiso else None
            for image in images:
                if base != image and hfbase != image:
                    # If the image is a hotfix image
                    if 'hotfix' in image.lower():
                        LOG.info('Deleting hotfix image: %s' % image)
                        ICMD.software.delete_software_image(image, is_hf=True,
                                                            ifc=icifc)

                    # Otherwise assume it is a base image
                    else:
                        LOG.info('Deleting base image: %s' % image)
                        ICMD.software.delete_software_image(image, ifc=icifc)

        if not haz_it:
            LOG.info('Importing base iso %s', base)
            SCMD.ssh.scp_put(address=self.address,
                             username=self.options.root_username,
                             password=self.options.root_password,
                             port=self.options.ssh_port,
                             source=filename, nokex=False, timeout=timeout)

            LOG.info('Wait for image to be imported %s', base)
            ICMD.software.GetSoftwareImage(filename=base, ifc=icifc) \
                .run_wait(is_available, timeout=timeout,
                          timeout_message="Timeout ({0}s) while waiting for the software image to be imported.")

        if hfiso:
            images = ICMD.software.get_software_image(ifc=icifc, is_hf=True)
            haz_it = any(filter(lambda x: x['verified'] and
                                x['product'] == hfiso_version.product.to_tmos and
                                x['version'] == hfiso_version.version and
                                x['build'] == hfiso_version.build, images))

            if not haz_it:
                hfbase = os.path.basename(hfiso)
                LOG.info('Importing hotfix iso %s', hfiso)
                SCMD.ssh.scp_put(address=self.address,
                                 username=self.options.root_username,
                                 password=self.options.root_password,
                                 port=self.options.ssh_port,
                                 source=hfiso, nokex=False)

                LOG.info('Wait for image to be imported %s', hfbase)
                ICMD.software.GetSoftwareImage(filename=hfbase, ifc=icifc, is_hf=True) \
                    .run_wait(is_available, timeout_message="Timeout ({0}s) while waiting for the hotfix image to be imported.")

        def is_still_removing(items):
            return not any(filter(lambda x: x['status'].startswith('removing'),
                                  items))

        def is_still_installing(items):
            return not any(filter(lambda x: x['status'].startswith('installing') or
                                  x['status'].startswith('waiting') or
                                  x['status'].startswith('testing') or
                                  x['status'] in ('audited', 'auditing',
                                                  'upgrade needed'),
                                  items))

        volumes = ICMD.software.get_software_status(ifc=icifc)
        assert is_still_installing(volumes), "An install is already in " \
                                             "progress on another slot: %s" % volumes

        ICMD.software.GetSoftwareStatus(volume=volume, ifc=icifc) \
                     .run_wait(is_still_removing,
                               # CAVEAT: tracks progress only for the first blade
                               progress_cb=lambda x: x[0]['status'],
                               timeout=timeout)

        LOG.info('Installing %s...', iso_version)

        ICMD.software.install_software(hfiso_version or iso_version,
                                       volume=volume, ifc=icifc)

        ret = ICMD.software.GetSoftwareStatus(volume=volume, ifc=icifc) \
            .run_wait(is_still_installing,
                      # CAVEAT: tracks progress only for the first blade
                      progress_cb=lambda x: x[0]['status'],
                      timeout=timeout,
                      timeout_message="Timeout ({0}s) while waiting software install to finish.",
                      stabilize=10)

        LOG.info('Resetting the global DB vars...')
        ic.Management.DBVariable.modify(variables=[
            {'name': 'LiveInstall.MoveConfig',
             'value': essential and 'enable' or 'disable'},
            {'name': 'LiveInstall.SaveConfig',
             'value': essential and 'enable' or 'disable'}
        ])

        if sum(x['status'] == 'complete' for x in ret) != len(ret):
            raise InstallFailed('Install did not succeed: %s' % ret)

        LOG.info('Setting the active boot location %s.', volume)
        if is_clustered:
            # ===================================================================
            # Apparently on chassis systems the device is rebooted automatically
            # upon setting the active location, just like `b software desired
            # HD1.N active enable`.
            # ===================================================================
            uptime = ic.System.SystemInfo.get_uptime()
            ic.System.SoftwareManagement.set_cluster_boot_location(location=volume)
            time.sleep(60)
        else:
            ic.System.SoftwareManagement.set_boot_location(location=volume)
            LOG.info('Rebooting...')
            uptime = ICMD.system.reboot(ifc=icifc)

        # Grab a new iControl handle that uses the default admin credentials.
        if essential:
            icifc.close()
            icifc = IcontrolInterface(address=self.address,
                                      port=self.options.ssl_port)
            icifc.open()

        if uptime:
            ICMD.system.HasRebooted(uptime, ifc=icifc).run_wait(timeout=timeout)
            LOG.info('Device is rebooting...')

        LOG.info('Wait for box to be ready...')
        ICMD.system.IsServiceUp('MCPD', ifc=icifc).\
            run_wait(timeout=timeout,
                     timeout_message="Timeout ({0}s) while waiting for MCPD to come up")
        ICMD.system.IsServiceUp('TMM', ifc=icifc).\
            run_wait(timeout_message="Timeout ({0}s) while waiting for TMM to come up")

        ICMD.management.GetDbvar('Configsync.LocalConfigTime', ifc=icifc).\
            run_wait(lambda x: int(x) > 0,
                     progress_cb=lambda x: 'waiting configsync...',
                     timeout=timeout)
        ICMD.system.FileExists('/var/run/mprov.pid', ifc=icifc).\
            run_wait(lambda x: x is False,
                     progress_cb=lambda x: 'mprov still running...',
                     timeout=timeout)
        ICMD.system.FileExists('/var/run/grub.conf.lock', ifc=icifc).\
            run_wait(lambda x: x is False,
                     progress_cb=lambda x: 'grub.lock still present...',
                     timeout=timeout)

        current_version = ICMD.system.get_version(ifc=icifc)
        expected_version = hfiso_version or iso_version
        try:
            if expected_version != current_version:
                raise InstallFailed('Version expected: %s but found %s' %
                                    (expected_version, current_version))
        finally:
            icifc.close()

        # Will use SSH!
        if essential:
            self._initialize_big3d()

        if essential and current_version.product.is_em:
            self._initialize_em()

        self.has_essential_config = essential
Example #9
0
    def by_image2disk(self, filename, hfiso=None):
        iso_version = cm.version_from_metadata(filename)

        if hfiso:
            hfiso_version = cm.version_from_metadata(hfiso)
            reboot = False
        else:
            hfiso_version = None
            reboot = True

        LOG.debug('iso: %s', iso_version)

        base = os.path.basename(filename)
        essential = self.options.essential_config
        timeout = self.options.timeout

        if self.options.format_partitions or self.options.format_volumes:
            reboot = True

        with SSHInterface(address=self.address,
                          username=self.options.root_username,
                          password=self.options.root_password,
                          timeout=timeout, port=self.options.ssh_port) as sshifc:
            ssh = sshifc.api
            version = SCMD.ssh.get_version(ifc=sshifc)
            LOG.info('running on %s', version)

            if version > 'bigip 9.6.0':
                try:
                    ret = SCMD.tmsh.list('sys cluster', ifc=sshifc)
                except:
                    ret = None
                if ret:
                    raise NotImplementedError('Due to potential complications image2disk '
                                              'installations on clustered '
                                              'systems are not supported by this tool '
                                              'and should be done by hand. Sorry!')

            if not essential and abs(iso_version) < abs(version) or \
               iso_version.product != version.product:
                LOG.warning('Enforcing --esential-config')
                essential = True

            if essential:
                lines = ssh.run('ls ' + SHARED_IMAGES).stdout.split()
                images = [x for x in lines if '.iso' in x]

                hfbase = os.path.basename(hfiso) if hfiso else None
                for image in images:
                    if base != image and hfbase != image:
                        LOG.info('Deleting image: %s' % image)
                        ssh.run('rm -rf %s/%s' % (SHARED_IMAGES, image))

            # XXX: Image checksum is not verified!!
            if (base not in ssh.run('ls ' + SHARED_IMAGES).stdout.split()):
                LOG.info('Importing iso %s', filename)
                SCMD.ssh.scp_put(ifc=sshifc, source=filename, nokex=False)

            filename = os.path.join(SHARED_IMAGES, base)

            if self.options.format_volumes:
                fmt = 'lvm'
            elif self.options.format_partitions:
                fmt = 'partitions'
            else:
                fmt = None

            def log_progress(stdout, stderr):
                output = ''
                if stdout:
                    output += stdout
                if stderr:
                    output += '\n'
                    output += stderr

                # An in-house grep.
                for line in output.splitlines():
                    line = line.strip()
                    if line and not line.startswith('info: '):
                        LOG.debug(line)

            try:
                audit = SCMD.ssh.audit_software(version=version, ifc=sshifc)
                volume = get_inactive_volume(audit)
            except:
                volume = 'HD1.1'
                LOG.warning('Assuming destination slot %s', volume)
            LOG.info('Installing %s on %s...', iso_version, volume)
            SCMD.ssh.install_software(version=version, ifc=sshifc,
                                      repository=filename, format=fmt,
                                      essential=essential, volume=volume,
                                      progress_cb=log_progress,
                                      reboot=reboot,
                                      repo_version=iso_version)

        if reboot:
            # Grab a new iControl handle that uses the default admin credentials.
            self._wait_after_reboot(essential)

        if hfiso:
            if essential:
                sshifc = SSHInterface(address=self.address, timeout=timeout,
                                      port=self.options.ssh_port)
            else:
                sshifc = SSHInterface(address=self.address, timeout=timeout,
                                      username=self.options.root_username,
                                      password=self.options.root_password,
                                      port=self.options.ssh_port)

            with sshifc:
                version = SCMD.ssh.get_version(ifc=sshifc)
                LOG.info('running on %s', version)
                if reboot:
                    audit = SCMD.ssh.audit_software(version=version, ifc=sshifc)
                    volume = get_inactive_volume(audit)
                    LOG.info('Installing image on %s...', volume)
                    SCMD.ssh.install_software(version=version, ifc=sshifc,
                                              repository=filename, reboot=False,
                                              essential=essential, volume=volume,
                                              progress_cb=log_progress,
                                              repo_version=iso_version)
                hfbase = os.path.basename(hfiso)
                if (hfbase not in sshifc.api.run('ls ' + SHARED_IMAGES).stdout.split()):
                    LOG.info('Importing hotfix %s', hfiso)
                    SCMD.ssh.scp_put(ifc=sshifc, source=hfiso, nokex=not reboot)
                hfiso = os.path.join(SHARED_IMAGES, hfbase)

                LOG.info('Installing hotfix on %s...', volume)
                SCMD.ssh.install_software(version=version, ifc=sshifc,
                                          repository=hfiso, is_hf=True,
                                          essential=essential, volume=volume,
                                          progress_cb=log_progress,
                                          repo_version=hfiso_version,
                                          reboot=False)
                LOG.info('Rebooting...')
                SCMD.ssh.switchboot(ifc=sshifc, volume=volume)
                SCMD.ssh.reboot(ifc=sshifc)

        # Grab a new iControl handle that uses the default admin credentials.
        current_version = self._wait_after_reboot(essential)
        expected_version = hfiso_version or iso_version

        if expected_version != current_version:
            raise InstallFailed('Version expected: %s but found %s' %
                                (expected_version, current_version))

        if essential:
            self._initialize_big3d()

        if essential and current_version.product.is_em:
            self._initialize_em()

        self.has_essential_config = essential
Example #10
0
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
Example #11
0
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)
Example #12
0
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
Example #13
0
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)