Ejemplo n.º 1
0
    def update_known_hosts(self, ssh_key_name, host, user=None):
        """Create host entry in vm ssh config and know_hosts files to allow vm
        to access host via ssh without password prompt

        :param robottelo.hosts.ContentHost vm: Virtual machine instance
        :param str ssh_key_name: The ssh key file name to use to access host,
            the file must already exist in /root/.ssh directory
        :param str host: the hostname to setup that will be accessed from vm
        :param str user: the user that will access the host
        """
        user = user or 'root'
        ssh_path = '/root/.ssh'
        ssh_key_file_path = f'{ssh_path}/{ssh_key_name}'
        # setup the config file
        ssh_config_file_path = f'{ssh_path}/config'
        result = self.run(f'touch {ssh_config_file_path}')
        if result.status != 0:
            raise CLIFactoryError(
                f'Failed to create ssh config file:\n{result.stderr}')
        result = self.run(
            f'echo "\nHost {host}\n\tHostname {host}\n\tUser {user}\n'
            f'\tIdentityFile {ssh_key_file_path}\n" >> {ssh_config_file_path}')
        if result.status != 0:
            raise CLIFactoryError(
                f'Failed to write to ssh config file:\n{result.stderr}')
        # add host entry to ssh known_hosts
        result = self.run(f'ssh-keyscan {host} >> {ssh_path}/known_hosts')
        if result.status != 0:
            raise CLIFactoryError(
                f'Failed to put hostname in ssh known_hosts files:\n{result.stderr}'
            )
Ejemplo n.º 2
0
    def contenthost_setup(
        self,
        org_label,
        rh_repo_ids=None,
        repo_labels=None,
        product_label=None,
        lce=None,
        activation_key=None,
        patch_os_release_distro=None,
        install_katello_agent=True,
    ):
        """
        Setup a Content Host with basic components and tasks.

        :param str org_label: The Organization label.
        :param list rh_repo_ids: a list of RH repositories ids to enable.
        :param list repo_labels: a list of custom repositories labels to enable.
        :param str product_label: product label if repos_label is applicable.
        :param str lce: Lifecycle environment label if applicable.
        :param str activation_key: Activation key name if applicable.
        :param str patch_os_release_distro: distro name, to patch the VM with os version.
        :param bool install_katello_agent: whether to install katello agent.
        """
        rh_repo_ids = rh_repo_ids or []
        repo_labels = repo_labels or []
        self.install_katello_ca()
        self.register_contenthost(org_label,
                                  activation_key=activation_key,
                                  lce=lce)
        if not self.subscribed:
            raise CLIFactoryError('Virtual machine failed subscription')
        if patch_os_release_distro:
            self.patch_os_release_version(distro=patch_os_release_distro)
        # Enable RH repositories
        for repo_id in rh_repo_ids:
            self.enable_repo(repo_id, force=True)
        if product_label:
            # Enable custom repositories
            for repo_label in repo_labels:
                result = self.run(
                    f'yum-config-manager --enable {org_label}_{product_label}_{repo_label}'
                )
                if result.status != 0:
                    raise CLIFactoryError(
                        f'Failed to enable custom repository {repo_label!s}\n{result.stderr}'
                    )
        if install_katello_agent:
            self.install_katello_agent()
Ejemplo n.º 3
0
    def make_file_repository_upload_contents(self, options=None):
        """Makes a new File repository, Upload File/Multiple Files
        and asserts its success.
        """
        if options is None:
            options = {
                'name': self.file_repo_name,
                'product-id': self.product['id'],
                'content-type': 'file',
            }
        if not options.get('content-type'):
            raise CLIFactoryError('Please provide a valid Content Type.')
        file_repo = make_repository(options)
        remote_path = "/tmp/{0}".format(RPM_TO_UPLOAD)
        if 'multi_upload' not in options or not options['multi_upload']:
            ssh.upload_file(local_file=get_data_file(RPM_TO_UPLOAD), remote_file=remote_path)
        else:
            remote_path = "/tmp/{}/".format(gen_string('alpha'))
            ssh.upload_files(local_dir=os.getcwd() + "/../data/", remote_dir=remote_path)

        result = Repository.upload_content(
            {
                'name': file_repo['name'],
                'organization': file_repo['organization'],
                'path': remote_path,
                'product-id': file_repo['product']['id'],
            }
        )
        self.assertIn(
            "Successfully uploaded file '{0}'".format(RPM_TO_UPLOAD), result[0]['message']
        )
        file_repo = Repository.info({'id': file_repo['id']})
        self.assertGreater(int(file_repo['content-counts']['files']), 0)
        return file_repo
Ejemplo n.º 4
0
    def put_ssh_key(self, source_key_path, destination_key_name):
        """Copy ssh key to virtual machine ssh path and ensure proper permission is
        set

        :param source_key_path: The ssh key file path to copy to vm
        :param destination_key_name: The ssh key file name when copied to vm
        """
        destination_key_path = f'/root/.ssh/{destination_key_name}'
        self.put(local_path=source_key_path, remote_path=destination_key_path)
        result = self.run(f'chmod 600 {destination_key_path}')
        if result.status != 0:
            raise CLIFactoryError(f'Failed to chmod ssh key file:\n{result.stderr}')
Ejemplo n.º 5
0
    def virt_who_hypervisor_config(
        self,
        config_id,
        org_id=None,
        lce_id=None,
        hypervisor_hostname=None,
        configure_ssh=False,
        hypervisor_user=None,
        subscription_name=None,
        exec_one_shot=False,
        upload_manifest=True,
        extra_repos=None,
    ):
        """
        Configure virtual machine as hypervisor virt-who service

        :param int config_id: virt-who config id
        :param int org_id: the organization id
        :param int lce_id: the lifecycle environment id to use
        :param str hypervisor_hostname: the hypervisor hostname
        :param str hypervisor_user: hypervisor user that connect with the ssh key
        :param bool configure_ssh: configure the ssh key to allow host to connect to hypervisor
        :param str subscription_name: the subscription name to assign to virt-who hypervisor guests
        :param bool exec_one_shot: whether to run the virt-who one-shot command after startup
        :param bool upload_manifest: whether to upload the organization manifest
        :param list extra_repos: (Optional) repositories dict options to setup additionally.
        """
        from robottelo.cli.org import Org
        from robottelo.cli import factory as cli_factory
        from robottelo.cli.lifecycleenvironment import LifecycleEnvironment
        from robottelo.cli.subscription import Subscription
        from robottelo.cli.virt_who_config import VirtWhoConfig

        org = cli_factory.make_org() if org_id is None else Org.info(
            {'id': org_id})

        if lce_id is None:
            lce = cli_factory.make_lifecycle_environment(
                {'organization-id': org['id']})
        else:
            lce = LifecycleEnvironment.info({
                'id': lce_id,
                'organization-id': org['id']
            })
        extra_repos = extra_repos or []
        repos = [
            # Red Hat Satellite Tools
            {
                'product': constants.PRDS['rhel'],
                'repository-set': constants.REPOSET['rhst7'],
                'repository': constants.REPOS['rhst7']['name'],
                'repository-id': constants.REPOS['rhst7']['id'],
                'url': settings.sattools_repo['rhel7'],
                'cdn': bool(settings.cdn
                            or not settings.sattools_repo['rhel7']),
            }
        ]
        repos.extend(extra_repos)
        content_setup_data = cli_factory.setup_cdn_and_custom_repos_content(
            org['id'],
            lce['id'],
            repos,
            upload_manifest=upload_manifest,
            rh_subscriptions=[constants.DEFAULT_SUBSCRIPTION_NAME],
        )
        activation_key = content_setup_data['activation_key']
        content_view = content_setup_data['content_view']
        self.contenthost_setup(
            org_label=org['label'],
            activation_key=activation_key['name'],
            patch_os_release_distro=constants.DISTRO_RHEL7,
            rh_repo_ids=[
                repo['repository-id'] for repo in repos if repo['cdn']
            ],
            install_katello_agent=False,
        )
        # configure manually RHEL custom repo url as sync time is very big
        # (more than 2 hours for RHEL 7Server) and not critical in this context.
        rhel_repo_option_name = (
            f'rhel{constants.DISTROS_MAJOR_VERSION[constants.DISTRO_RHEL7]}_repo'
        )
        rhel_repo_url = getattr(settings.repos, rhel_repo_option_name, None)
        if not rhel_repo_url:
            raise ValueError(
                f'Settings option "{rhel_repo_option_name}" is whether not set or does not exist'
            )
        self.configure_rhel_repo(rhel_repo_url)
        if hypervisor_hostname and configure_ssh:
            # configure ssh access of hypervisor from self
            hypervisor_ssh_key_name = f'hypervisor-{gen_alpha().lower()}.key'
            # upload the ssh key
            self.put_ssh_key(settings.server.ssh_key, hypervisor_ssh_key_name)
            # setup the ssh config and known_hosts files
            self.update_known_hosts(self,
                                    hypervisor_ssh_key_name,
                                    hypervisor_hostname,
                                    user=hypervisor_user)

        # upload the virt-who config deployment script
        virt_who_deploy_directory = '/root/virt_who_deploy_output'
        virt_who_deploy_filename = f'{gen_alpha(length=5)}-virt-who-deploy-{config_id}'
        virt_who_deploy_file = f'{virt_who_deploy_directory}/{virt_who_deploy_filename}'
        VirtWhoConfig.fetch({'id': config_id, 'output': virt_who_deploy_file})
        # remote_copy from satellite to self
        satellite = Satellite(settings.server.hostname)
        satellite.session.remote_copy(virt_who_deploy_file, self)

        # ensure the virt-who config deploy script is executable
        result = self.run(f'chmod +x {virt_who_deploy_file}')
        if result.status != 0:
            raise CLIFactoryError(
                f'Failed to set deployment script as executable:\n{result.stderr}'
            )
        # execute the deployment script
        result = self.run(f'{virt_who_deploy_file}')
        if result.status != 0:
            raise CLIFactoryError(
                f'Deployment script failure:\n{result.stderr}')
        # after this step, we should have virt-who service installed and started
        if exec_one_shot:
            # usually to be sure that the virt-who generated the report we need
            # to force a one shot report, for this we have to stop the virt-who
            # service
            result = self.run('service virt-who stop')
            if result.status != 0:
                raise CLIFactoryError(
                    f'Failed to stop the virt-who service:\n{result.stderr}')
            result = self.run('virt-who --one-shot', timeout=900)
            if result.status != 0:
                raise CLIFactoryError(
                    f'Failed when executing virt-who --one-shot:\n{result.stderr}'
                )
            result = self.run('service virt-who start')
            if result.status != 0:
                raise CLIFactoryError(
                    f'Failed to start the virt-who service:\n{result.stderr}')
        # after this step the hypervisor as a content host should be created
        # do not confuse virt-who host with hypervisor host as they can be
        # diffrent hosts and as per this setup we have only registered the virt-who
        # host, the hypervisor host should registered after virt-who send the
        # first report when started or with one shot command
        # the virt-who hypervisor will be registered to satellite with host name
        # like "virt-who-{hypervisor_hostname}-{organization_id}"
        virt_who_hypervisor_hostname = f'virt-who-{hypervisor_hostname}-{org["id"]}'
        # find the registered virt-who hypervisor host
        org_hosts = Host.list({
            'organization-id': org['id'],
            'search': f'name={virt_who_hypervisor_hostname}'
        })
        # Note: if one shot command was executed the report is immediately
        # generated, and the server must have already registered the virt-who
        # hypervisor host
        if not org_hosts and not exec_one_shot:
            # we have to wait until the first report was sent.
            # the report is generated after the virt-who service startup, but some
            # small delay can occur.
            max_time = time.time() + 60
            while time.time() <= max_time:
                time.sleep(5)
                org_hosts = Host.list({
                    'organization-id':
                    org['id'],
                    'search':
                    f'name={virt_who_hypervisor_hostname}',
                })
                if org_hosts:
                    break

        if len(org_hosts) == 0:
            raise CLIFactoryError(
                f'Failed to find hypervisor host:\n{result.stderr}')
        virt_who_hypervisor_host = org_hosts[0]
        subscription_id = None
        if hypervisor_hostname and subscription_name:
            subscriptions = Subscription.list({'organization-id': org_id},
                                              per_page=False)
            for subscription in subscriptions:
                if subscription['name'] == subscription_name:
                    subscription_id = subscription['id']
                    Host.subscription_attach({
                        'host': virt_who_hypervisor_hostname,
                        'subscription-id': subscription_id
                    })
                    break
        return {
            'subscription_id': subscription_id,
            'subscription_name': subscription_name,
            'activation_key_id': activation_key['id'],
            'organization_id': org['id'],
            'content_view_id': content_view['id'],
            'lifecycle_environment_id': lce['id'],
            'virt_who_hypervisor_host': virt_who_hypervisor_host,
        }