Exemple #1
0
    def test_non_matching_query(self):
        """Sync a repository with a query that doesn't match any units.

        Assert that:

        * None of the sync tasks has an error message.
        * Searching for module ``pulp_2_tests.constants.PUPPET_MODULE_2``
          yields no results.
        """
        # Create and sync a repository.
        cfg = config.get_config()
        client = api.Client(cfg, api.json_handler)
        body = gen_repo()
        body['importer_config'] = {
            'feed': PUPPET_FEED_2,
            'queries': [PUPPET_QUERY_2.replace('-', '_')],
        }
        body['distributors'] = [gen_distributor()]
        repo = client.post(REPOSITORY_PATH, body)
        self.addCleanup(client.delete, repo['_href'])
        repo = client.get(repo['_href'], params={'details': True})
        self._sync_repo(repo)

        # Publish the repository.
        publish_repo(cfg, repo)
        module = '/'.join((PUPPET_MODULE_2['author'], PUPPET_MODULE_2['name']))
        with self.assertRaises(HTTPError):
            client.get(
                '/v3/releases',
                auth=('repository', repo['id']),
                params={'module': module},
            )
Exemple #2
0
    def test_all(self):
        """Create and sync a puppet repository with no feed."""
        cfg = config.get_config()
        if not selectors.bug_is_fixed(2628, cfg.pulp_version):
            self.skipTest('https://pulp.plan.io/issues/2628')

        # Create a repository.
        client = api.Client(cfg, api.json_handler)
        repo = client.post(REPOSITORY_PATH, gen_repo())
        self.addCleanup(client.delete, repo['_href'])

        # Sync the repository. An error *should* occur. We just want the error
        # to be sane.
        with self.assertRaises(exceptions.TaskReportError) as err:
            sync_repo(cfg, repo)
        with self.subTest(comment='check task "error" field'):
            self.assertIsNotNone(err.exception.task['error'])
            self.assertNotEqual(
                err.exception.task['error']['description'],
                "'NoneType' object has no attribute 'endswith'"
            )
            self.assertNotEqual(err.exception.task['error']['code'], 'PLP0000')
        with self.subTest(comment='check task "exception" field'):
            self.assertIsNone(err.exception.task['exception'])
        with self.subTest(comment='check task "traceback" field'):
            self.assertIsNone(err.exception.task['traceback'])
 def setUpClass(cls):
     """Create a Puppet repository."""
     super().setUpClass()
     unit = utils.http_get(PUPPET_MODULE_URL_1)
     import_params = {'unit_type_id': 'puppet_module'}
     repo = api.Client(cls.cfg).post(REPOSITORY_PATH, gen_repo()).json()
     cls.upload_import_unit_args = (cls.cfg, unit, import_params, repo)
     cls.resources.add(repo['_href'])
Exemple #4
0
 def setUpClass(cls):
     """Create a Puppet repository."""
     cls.cfg = config.get_config()
     cls.resources = set()
     unit = utils.http_get(PUPPET_MODULE_URL_1)
     import_params = {'unit_type_id': 'puppet_module'}
     cls.client = api.Client(cls.cfg, api.json_handler)
     repo = cls.client.post(REPOSITORY_PATH, gen_repo())
     cls.upload_import_unit_args = (cls.cfg, unit, import_params, repo)
     cls.resources.add(repo['_href'])
Exemple #5
0
    def test_matching_query(self):
        """Sync a repository with a query that matches units.

        Assert that:

        * None of the sync tasks has an error message.
        * Searching for module ``pulp_2_tests.constants.PUPPET_MODULE_2``
          yields one result.
        * The synced-in module can be downloaded.
        """
        cfg = config.get_config()
        if not selectors.bug_is_fixed(3692, cfg.pulp_version):
            self.skipTest('https://pulp.plan.io/issues/3692')

        # Create and sync a repository.
        client = api.Client(cfg, api.json_handler)
        body = gen_repo()
        body['importer_config'] = {
            'feed': PUPPET_FEED_2,
            'queries': [PUPPET_QUERY_2],
        }
        body['distributors'] = [gen_distributor()]
        repo = client.post(REPOSITORY_PATH, body)
        self.addCleanup(client.delete, repo['_href'])
        repo = client.get(repo['_href'], params={'details': True})
        self._sync_repo(repo)

        # Publish the repository.
        publish_repo(cfg, repo)
        module = '/'.join((PUPPET_MODULE_2['author'], PUPPET_MODULE_2['name']))
        response = client.get(
            '/v3/releases',
            auth=('repository', repo['id']),
            params={'module': module},
        )
        self.assertEqual(len(response['results']), 1)

        # Download the Puppet module directly from feed url.
        latest_version = response['results'][0]['metadata']['version']
        module_file = utils.http_get(PUPPET_MODULE_URL_2 % latest_version)

        client.response_handler = api.safe_handler
        # Download the Puppet module stored by Pulp.
        file_response = client.get(response['results'][0]['file_uri'])

        # Assert the files are the same.
        with self.subTest():
            self.assertEqual(module_file, file_response.content)
        with self.subTest():
            self.assertIn(
                file_response.headers['content-type'],
                ('application/gzip', 'application/x-gzip')
            )
    def setUpClass(cls):
        """Create a puppet repository with an invalid feed and sync it."""
        super().setUpClass()
        client = api.Client(cls.cfg, api.json_handler)
        body = gen_repo()
        body['importer_config'] = {'feed': 'http://' + utils.uuid4()}
        repo = client.post(REPOSITORY_PATH, body)
        cls.resources.add(repo['_href'])

        # Trigger a repository sync and collect completed tasks.
        client.response_handler = api.code_handler
        cls.report = client.post(urljoin(repo['_href'], 'actions/sync/'))
        cls.tasks = list(api.poll_spawned_tasks(cls.cfg, cls.report.json()))
    def setUpClass(cls):
        """Create repository with the feed pointing to a valid manifest."""
        super().setUpClass()
        client = api.Client(cls.cfg)
        body = gen_repo()
        body['importer_config'] = {
            'feed': 'http://repos.fedorapeople.org/repos/pulp/pulp/demo_repos/puppet_manifest/modules/'  # pylint:disable=line-too-long
        }
        repo = client.post(REPOSITORY_PATH, body).json()
        cls.resources.add(repo['_href'])

        # Trigger a repository sync and collect completed tasks.
        cls.report = sync_repo(cls.cfg, repo)
        cls.tasks = list(api.poll_spawned_tasks(cls.cfg, cls.report.json()))
Exemple #8
0
    def test_all(self):
        """Test puppet_install_distributor.

        Do the following:

        1. Create a puppet repository with a puppet_install_distributor
        2. Upload a puppet module
        3. Publish the repository
        4. Check if the puppet_install_distributor config was properly used
        """
        cfg = config.get_config()
        if (not selectors.bug_is_fixed(3314, cfg.pulp_version)
                and os_is_f27(cfg)):
            self.skipTest('https://pulp.plan.io/issues/3314')
        cli_client = cli.Client(cfg)

        # Create a directory and make sure Pulp can write to it.
        install_path = cli_client.run(('mktemp', '--directory')).stdout.strip()
        self.addCleanup(cli_client.run, ('rm', '-rf', install_path), sudo=True)
        cli_client.run(('chown', 'apache:apache', install_path), sudo=True)
        cli_client.run(('chcon', '-t', 'puppet_etc_t', install_path),
                       sudo=True)

        # Make sure the pulp_manage_puppet boolean is enabled
        cli_client.run(('setsebool', 'pulp_manage_puppet', 'on'), sudo=True)

        self.addCleanup(cli_client.run,
                        ('setsebool', 'pulp_manage_puppet', 'off'),
                        sudo=True)

        # Create and populate a Puppet repository.
        distributor = gen_install_distributor()
        distributor['distributor_config']['install_path'] = install_path
        body = gen_repo()
        body['distributors'] = [distributor]
        client = api.Client(cfg, api.json_handler)
        repo = client.post(REPOSITORY_PATH, body)
        self.addCleanup(client.delete, repo['_href'])
        repo = client.get(repo['_href'], params={'details': True})
        unit = utils.http_get(PUPPET_MODULE_URL_1)
        upload_import_unit(cfg, unit, {'unit_type_id': 'puppet_module'}, repo)

        # Publish, and verify the module is present. (Dir has 700 permissions.)
        publish_repo(cfg, repo)
        proc = cli_client.run(('runuser', '--shell', '/bin/sh', '--command',
                               'ls -1 {}'.format(install_path), '-', 'apache'),
                              sudo=True)
        self.assertIn(PUPPET_MODULE_1['name'], proc.stdout.split('\n'), proc)
Exemple #9
0
    def test_upload_modules_with_extra_files(self):
        """Test upload puppet modules with extraneous files are successfull.

         Specifically, this method does the following:

         1. Create a puppet repo.
         2. Upload ``PUPPET_MODULE_EXTRANEOUS_FILE``
            which has extraneous files to the repo.
         3. Verify the repo upload is successful.

        This test case targets:

        * `Pulp-2-tests #83 <https://github.com/PulpQE/Pulp-2-Tests/issues/83>`_
        * `Pulp #2769 <https://pulp.plan.io/issues/2769>`_
        * `Pulp #4140 <https://pulp.plan.io/issues/4140>`_
        """
        cfg = config.get_config()
        if cfg.pulp_version < Version('2.18'):
            raise unittest.SkipTest('This test requires Pulp 2.18 or newer')
        client = api.Client(cfg, api.json_handler)

        # Create a puppet repo
        repo = client.post(REPOSITORY_PATH, gen_repo())
        self.addCleanup(client.delete, repo['_href'])

        # upload puppet module with extraneous file to the repo.
        module = utils.http_get(PUPPET_MODULE_EXTRANEOUS_FILE)
        upload_response = client.post(CONTENT_UPLOAD_PATH)
        self.addCleanup(client.delete, upload_response['_href'])

        client.put(
            urljoin(upload_response['_href'], '0/'),
            data=module,
        )

        # Import the uploaded object in the repo
        client.post(
            urljoin(repo['_href'], 'actions/import_upload/'),
            {
                'unit_key': {},
                'unit_type_id': 'puppet_module',
                'upload_id': upload_response['upload_id'],
            },
        )

        repo = client.get(repo['_href'], params={'details': True})
        self.assertEqual(repo['content_unit_counts']['puppet_module'], 1)
    def setUpClass(cls):
        """Create two puppet repositories, with and without feed URLs."""
        super().setUpClass()
        cls.bodies = tuple((gen_repo() for _ in range(2)))
        cls.bodies[1]['importer_config'] = {
            'feed': 'http://' + utils.uuid4(),  # Pulp checks for a URI scheme
            'queries': [PUPPET_QUERY_2],
        }

        client = api.Client(cls.cfg, api.json_handler)
        cls.repos = []
        cls.importers_iter = []
        for body in cls.bodies:
            repo = client.post(REPOSITORY_PATH, body)
            cls.resources.add(repo['_href'])
            cls.repos.append(repo)
            cls.importers_iter.append(client.get(repo['_href'] + 'importers/'))
    def test_all(self):
        """Creating a repo with an invalid distributor should throw an error.

        This test targets `Pulp #1237 <https://pulp.plan.io/issues/1237>`_.
        Do the following:

        1. Create a puppet repo
        2. Make an API call to create a distributor WITHOUT non-optional
            install_path
        3. Assert that an error is thrown
        4. Assert that no repo is created
        """
        if not selectors.bug_is_fixed(1237, self.cfg.pulp_version):
            self.skipTest('https://pulp.plan.io/issues/1237')
        distributor = gen_install_distributor()
        distributor['distributor_config']['install_path'] = ''
        body = gen_repo()
        body['distributors'] = [distributor]
        client = api.Client(self.cfg, api.json_handler)
        with self.assertRaises(HTTPError):
            repo = client.post(REPOSITORY_PATH, body)
            self.addCleanup(client.delete, repo['_href'])
Exemple #12
0
    def setUpClass(cls):
        """Upload puppet module to a repo, copy it to another repo, publish and download.

        Create two puppet repositories, both without feeds. Upload a module to
        the first repository. Copy its content to the second repository. Add
        distributors to the repositories, publish repositories and download
        modules back from them.
        """
        cls.cfg = config.get_config()
        cls.resources = set()
        reset_pulp(cls.cfg)  # See: https://pulp.plan.io/issues/1406
        cls.responses = {}
        cls.modules = []  # Raw puppet modules.

        # Download a puppet module and create two repositories.
        cls.client = api.Client(cls.cfg, api.json_handler)
        repos = [cls.client.post(REPOSITORY_PATH, gen_repo()) for _ in range(2)]
        for repo in repos:
            cls.resources.add(repo['_href'])
        cls.client.response_handler = api.safe_handler
        cls.modules.append(utils.http_get(PUPPET_MODULE_URL_1))

        # Begin an upload request, upload a puppet module, move the puppet
        # module into a repository, and end the upload request.
        cls.responses['malloc'] = cls.client.post(CONTENT_UPLOAD_PATH)
        cls.responses['upload'] = cls.client.put(
            urljoin(cls.responses['malloc'].json()['_href'], '0/'),
            data=cls.modules[0],
        )
        cls.responses['import'] = cls.client.post(
            urljoin(repos[0]['_href'], 'actions/import_upload/'),
            {
                'unit_key': {},
                'unit_type_id': 'puppet_module',
                'upload_id': cls.responses['malloc'].json()['upload_id'],
            },
        )
        cls.responses['free'] = cls.client.delete(
            cls.responses['malloc'].json()['_href']
        )

        # Copy content from the first puppet repository to the second.
        cls.responses['copy'] = cls.client.post(
            urljoin(repos[1]['_href'], 'actions/associate/'),
            {'source_repo_id': repos[0]['id']}
        )

        # Add a distributor to each repository. Publish each repository.
        for key in {'distribute', 'publish'}:
            cls.responses[key] = []
        for repo in repos:
            cls.responses['distribute'].append(cls.client.post(
                urljoin(repo['_href'], 'distributors/'),
                {
                    'auto_publish': False,
                    'distributor_id': utils.uuid4(),
                    'distributor_type_id': 'puppet_distributor',
                    'distributor_config': {
                        'serve_http': True,
                        'serve_https': True,
                        'relative_url': '/' + utils.uuid4(),
                    },
                }
            ))
            cls.responses['publish'].append(cls.client.post(
                urljoin(repo['_href'], 'actions/publish/'),
                {'id': cls.responses['distribute'][-1].json()['id']},
            ))

        # Query both distributors using all three query forms.
        cls.responses['puppet releases'] = []
        author_name = PUPPET_MODULE_1['author'] + '/' + PUPPET_MODULE_1['name']
        for repo in repos:
            if not selectors.bug_is_fixed(1440, cls.cfg.pulp_version):
                continue
            cls.responses['puppet releases'].append(cls.client.get(
                '/api/v1/releases.json',
                params={'module': author_name},
                auth=('.', repo['id']),
            ))
            cls.responses['puppet releases'].append(cls.client.get(
                '/pulp_puppet/forge/repository/{}/api/v1/releases.json'
                .format(repo['id']),
                params={'module': author_name},
            ))
            if cls.cfg.pulp_version < Version('2.8'):
                continue
            cls.responses['puppet releases'].append(cls.client.get(
                '/v3/releases',
                params={'module': author_name},
                auth=('repository', repo['id']),
            ))

        # Download each unit referenced by the queries above.
        for response in cls.responses['puppet releases']:
            body = response.json()
            if set(body.keys()) == {'pagination', 'results'}:  # Puppet >= 3.6
                path = body['results'][0]['file_uri']
            else:
                path = body[author_name][0]['file']
            cls.modules.append(cls.client.get(path).content)

        # Search for all units in each of the two repositories.
        cls.responses['repo units'] = [
            search_units(cls.cfg, repo, {}, api.safe_handler)
            for repo in repos
        ]
Exemple #13
0
 def create_body():
     """Return a dict for creating a repository."""
     return gen_repo()