예제 #1
0
 def __init__(self, aptly_server_url, timeout=None):
     if not timeout or timeout < 0:
         super().__init__(aptly_server_url)
     else:
         self.aptly_server_url = aptly_server_url
         self.files = FilesAPISection(self.aptly_server_url,
                                      timeout=timeout)
         self.misc = MiscAPISection(self.aptly_server_url, timeout=timeout)
         self.packages = PackageAPISection(self.aptly_server_url,
                                           timeout=timeout)
         self.publish = PublishAPISection(self.aptly_server_url,
                                          timeout=timeout)
         self.repos = ReposAPISection(self.aptly_server_url,
                                      timeout=timeout)
         self.snapshots = SnapshotAPISection(self.aptly_server_url,
                                             timeout=timeout)
 def __init__(self, aptly_server_url: str) -> None:
     self.aptly_server_url = aptly_server_url
     self.files = FilesAPISection(self.aptly_server_url)
     self.misc = MiscAPISection(self.aptly_server_url)
     self.packages = PackageAPISection(self.aptly_server_url)
     self.publish = PublishAPISection(self.aptly_server_url)
     self.repos = ReposAPISection(self.aptly_server_url)
     self.snapshots = SnapshotAPISection(self.aptly_server_url)
 def __init__(self, *args: Any) -> None:
     super().__init__(*args)
     self.rapi = ReposAPISection("http://test/")
예제 #4
0
class ExtendedAptlyClient(Client):
    def __init__(self, aptly_server_url, timeout=None):
        if not timeout or timeout < 0:
            super().__init__(aptly_server_url)
        else:
            self.aptly_server_url = aptly_server_url
            self.files = FilesAPISection(self.aptly_server_url,
                                         timeout=timeout)
            self.misc = MiscAPISection(self.aptly_server_url, timeout=timeout)
            self.packages = PackageAPISection(self.aptly_server_url,
                                              timeout=timeout)
            self.publish = PublishAPISection(self.aptly_server_url,
                                             timeout=timeout)
            self.repos = ReposAPISection(self.aptly_server_url,
                                         timeout=timeout)
            self.snapshots = SnapshotAPISection(self.aptly_server_url,
                                                timeout=timeout)

    def lookup_publish_by_repos(self, repos):
        "Find what publishes depend on specified repos"
        publish_list = self.publish.list()
        publishes_from_local_repo = (p for p in publish_list
                                     if p.source_kind == "local")
        dependent_pubs = []

        try:
            repos_names = [repo.name for repo in repos]
        except AttributeError:
            repos_names = repos

        for p in publishes_from_local_repo:
            for r in repos_names:
                if r in (source["Name"] for source in p.sources):
                    dependent_pubs.append(p)
                    break
        else:
            return dependent_pubs

    def search_by_PackageRef(self, ref, use_ref_repo=True, detailed=True):
        """
        Search for PackageRef in all repos. If use_ref_repo is True, search
        only in repo of PackageRef if it is not None. Returns list of new PackageRefs
        with hash set, and new attr details if detailed is True
        """
        if use_ref_repo and ref.repo:
            repos_list = [ref.repo]
        else:
            repos_list = [r.name for r in self.repos.list()]

        result = []
        for r in repos_list:
            search_result = self.repos.search_packages(r,
                                                       ref.dir_ref,
                                                       detailed=True)
            logger.debug('search for "{}" in "{}": {}'.format(
                ref.dir_ref, r, search_result))
            if len(search_result) > 1:
                raise AptlyCtlError(
                    'Search for direct reference "{}" in repo "{}" '
                    "returned more than 1 result.".format(ref.dir_ref, r))
            elif len(search_result) == 1:
                new_ref = PackageRef(search_result[0].key)
                new_ref.repo = r
                new_ref.details = search_result[0]
                result.append(new_ref)
        else:
            return result

    def update_dependent_publishes(self, repos, config, dry_run=False):
        pubs = self.lookup_publish_by_repos(repos)
        update_exceptions = []
        for p in pubs:
            logger.info('Updating publish with prefix "{}", dist "{}"'.format(
                p.prefix, p.distribution))
            if dry_run:
                continue
            try:
                update_result = self.publish.update(
                    prefix=p.prefix,
                    distribution=p.distribution,
                    **config.get_signing_config(
                        PubSpec(p.distribution,
                                p.prefix)).as_dict(prefix="sign_"))
            except AptlyAPIException as e:
                logger.error(
                    'Can\'t update publish with prefix "{}", dist "{}".'.
                    format(p.prefix, p.distribution))
                update_exceptions.append(e)
                logger.error(e)
                logger.debug("", exc_info=True)
            else:
                logger.debug("API returned: " + str(update_result))
                logger.info(
                    'Updated publish with prefix "{}", dist "{}".'.format(
                        p.prefix, p.distribution))
        return update_exceptions
class ReposAPISectionTests(TestCase):
    def __init__(self, *args: Any) -> None:
        super().__init__(*args)
        self.rapi = ReposAPISection("http://test/")

    def test_create(self, *, rmock: requests_mock.Mocker) -> None:
        rmock.post("http://test/api/repos",
                   text='{"Name":"aptly-repo","Comment":"test","DefaultDistribution":"test","DefaultComponent":"test"}')
        self.assertEqual(
            self.rapi.create("aptly-repo", comment="test", default_component="test", default_distribution="test"),
            Repo(
                name="aptly-repo",
                default_distribution="test",
                default_component="test",
                comment="test",
            )
        )

    def test_show(self, *, rmock: requests_mock.Mocker) -> None:
        rmock.get("http://test/api/repos/aptly-repo",
                  text='{"Name":"aptly-repo","Comment":"","DefaultDistribution":"","DefaultComponent":""}')
        self.assertEqual(
            self.rapi.show("aptly-repo"),
            Repo(
                name="aptly-repo",
                default_distribution="",
                default_component="",
                comment="",
            )
        )

    def test_search(self, *, rmock: requests_mock.Mocker) -> None:
        rmock.get("http://test/api/repos/aptly-repo/packages",
                  text='["Pamd64 authserver 0.1.14~dev0-1 1cc572a93625a9c9"]')
        self.assertListEqual(
            self.rapi.search_packages("aptly-repo"),
            [
                Package(
                    key="Pamd64 authserver 0.1.14~dev0-1 1cc572a93625a9c9",
                    short_key=None,
                    files_hash=None,
                    fields=None,
                )
            ],
        )

    def test_search_details(self, *, rmock: requests_mock.Mocker) -> None:
        rmock.get(
            "http://test/api/repos/aptly-repo/packages?format=details",
            text="""[{
                      "Architecture":"amd64",
                      "Depends":"python3, python3-pip, python3-virtualenv, adduser, cron-daemon",
                      "Description":" no description given\\n",
                      "Filename":"authserver_0.1.14~dev0-1.deb",
                      "FilesHash":"1cc572a93625a9c9",
                      "Homepage":"http://example.com/no-uri-given",
                      "Installed-Size":"74927",
                      "Key":"Pamd64 authserver 0.1.14~dev0-1 1cc572a93625a9c9",
                      "License":"unknown",
                      "MD5sum":"03cca0794e63cf147b879e0a3695f523",
                      "Maintainer":"Jonas Maurus",
                      "Package":"authserver",
                      "Priority":"extra",
                      "Provides":"maurusnet-authserver",
                      "SHA1":"9a77a31dba51f612ee08ee096381f0c7e8f97a42",
                      "SHA256":"63555a135bf0aa1762d09fc622881aaf352cdb3b244da5d78278c7efa2dba8b7",
                      "SHA512":"01f9ca888014599374bf7a2c8c46f895d7ef0dfea99dfd092007f9fc5d5fe57a2755b843eda296b65cb"""
                 """6ac0f64b9bd88b507221a71825f5329fdda0e58728cd7",
                      "Section":"default",
                      "ShortKey":"Pamd64 authserver 0.1.14~dev0-1",
                      "Size":"26623042",
                      "Vendor":"root@test",
                      "Version":"0.1.14~dev0-1"
                 }]"""
        )
        self.assertListEqual(
            self.rapi.search_packages("aptly-repo", detailed=True, with_deps=True, query="Name (authserver)"),
            [
                Package(
                    key='Pamd64 authserver 0.1.14~dev0-1 1cc572a93625a9c9',
                    short_key='Pamd64 authserver 0.1.14~dev0-1',
                    files_hash='1cc572a93625a9c9',
                    fields={
                        'Architecture': 'amd64',
                        'Depends': 'python3, python3-pip, python3-virtualenv, adduser, cron-daemon',
                        'Description': ' no description given\n',
                        'Filename': 'authserver_0.1.14~dev0-1.deb',
                        'FilesHash': '1cc572a93625a9c9',
                        'Homepage': 'http://example.com/no-uri-given',
                        'Installed-Size': '74927',
                        'Key': 'Pamd64 authserver 0.1.14~dev0-1 1cc572a93625a9c9',
                        'License': 'unknown',
                        'MD5sum': '03cca0794e63cf147b879e0a3695f523',
                        'Maintainer': 'Jonas Maurus',
                        'Package': 'authserver',
                        'Priority': 'extra',
                        'Provides': 'maurusnet-authserver',
                        'SHA1': '9a77a31dba51f612ee08ee096381f0c7e8f97a42',
                        'SHA256': '63555a135bf0aa1762d09fc622881aaf352cdb3b244da5d78278c7efa2dba8b7',
                        'SHA512': '01f9ca888014599374bf7a2c8c46f895d7ef0dfea99dfd092007f9fc5d5fe57a2755b843eda296b65'
                                  'cb6ac0f64b9bd88b507221a71825f5329fdda0e58728cd7',
                        'Section': 'default',
                        'ShortKey': 'Pamd64 authserver 0.1.14~dev0-1',
                        'Size': '26623042',
                        'Vendor': 'root@test',
                        'Version': '0.1.14~dev0-1'
                    }
                )
            ]
        )

    def test_repo_edit_validation(self, *, rmock: requests_mock.Mocker) -> None:
        with self.assertRaises(AptlyAPIException):
            self.rapi.edit("aptly-repo")

    def test_repo_edit(self, *, rmock: requests_mock.Mocker) -> None:
        rmock.put("http://test/api/repos/aptly-repo",
                  text='{"Name":"aptly-repo","Comment":"comment",'
                       '"DefaultDistribution":"stretch","DefaultComponent":"main"}')
        self.assertEqual(
            self.rapi.edit("aptly-repo", comment="comment", default_distribution="stretch", default_component="main"),
            Repo(name='aptly-repo', comment='comment', default_distribution='stretch', default_component='main')
        )

    def test_list(self, *, rmock: requests_mock.Mocker) -> None:
        rmock.get("http://test/api/repos",
                  text='[{"Name":"maurusnet","Comment":"","DefaultDistribution":"",'
                       '"DefaultComponent":"main"},{"Name":"aptly-repo","Comment":"comment",'
                       '"DefaultDistribution":"stretch","DefaultComponent":"main"}]')
        self.assertListEqual(
            self.rapi.list(),
            [
                Repo(name='maurusnet', comment='', default_distribution='', default_component='main'),
                Repo(name='aptly-repo', comment='comment', default_distribution='stretch', default_component='main'),
            ]
        )

    def test_delete(self, *, rmock: requests_mock.Mocker) -> None:
        with self.assertRaises(requests_mock.NoMockAddress):
            self.rapi.delete("aptly-repo", force=True)

    def test_add_file(self, *, rmock: requests_mock.Mocker) -> None:
        rmock.post("http://test/api/repos/aptly-repo/file/test/dirmngr_2.1.18-6_amd64.deb",
                   text='{"FailedFiles":[],"Report":{"Warnings":[],'
                        '"Added":["dirmngr_2.1.18-6_amd64 added"],"Removed":[]}}')
        self.assertEqual(
            self.rapi.add_uploaded_file("aptly-repo", "test", "dirmngr_2.1.18-6_amd64.deb", force_replace=True),
            FileReport(failed_files=[],
                       report={'Added': ['dirmngr_2.1.18-6_amd64 added'],
                               'Removed': [], 'Warnings': []})
        )

    def test_add_dir(self, *, rmock: requests_mock.Mocker) -> None:
        rmock.post("http://test/api/repos/aptly-repo/file/test",
                   text='{"FailedFiles":[],"Report":{"Warnings":[],'
                        '"Added":["dirmngr_2.1.18-6_amd64 added"],"Removed":[]}}')
        self.assertEqual(
            self.rapi.add_uploaded_file("aptly-repo", "test", force_replace=True),
            FileReport(failed_files=[],
                       report={'Added': ['dirmngr_2.1.18-6_amd64 added'],
                               'Removed': [], 'Warnings': []})
        )

    def test_add_package(self, *, rmock: requests_mock.Mocker) -> None:
        rmock.post("http://test/api/repos/aptly-repo/packages",
                   text='{"Name":"aptly-repo","Comment":"","DefaultDistribution":"","DefaultComponent":""}')
        self.assertEqual(
            self.rapi.add_packages_by_key("aptly-repo", "Pamd64 dirmngr 2.1.18-6 4c7412c5f0d7b30a"),
            Repo(name='aptly-repo', comment='', default_distribution='', default_component='')
        )

    def test_delete_package(self, *, rmock: requests_mock.Mocker) -> None:
        rmock.delete(
            "http://test/api/repos/aptly-repo/packages",
            text='{"Name":"aptly-repo","Comment":"","DefaultDistribution":"","DefaultComponent":""}'
        )
        self.assertEqual(
            self.rapi.delete_packages_by_key("aptly-repo", "Pamd64 dirmngr 2.1.18-6 4c7412c5f0d7b30a"),
            Repo(name='aptly-repo', comment='', default_distribution='', default_component=''),
        )

    def test_search_invalid_params(self, *, rmock: requests_mock.Mocker) -> None:
        with self.assertRaises(AptlyAPIException):
            self.rapi.search_packages("aptly-repo", with_deps=True)