def populated_repo(controller): units = [ RpmUnit(name="bash", version="4.0", release="1", arch="x86_64"), RpmUnit(content_type_id="srpm", name="bash", version="4.0", release="1", arch="src"), RpmUnit( name="glibc", version="5.0", release="1", arch="x86_64", sourcerpm="glibc-5.0-1.el5_11.1.src.rpm", ), ModulemdUnit(name="module1", stream="s1", version=1234, context="a1b2", arch="x86_64"), ModulemdUnit(name="module2", stream="s2", version=1234, context="a1b2", arch="x86_64"), ErratumUnit(id="RHBA-1234:56", summary="The best advisory"), ] repo = YumRepository(id="repo1") controller.insert_repository(repo) controller.insert_units(repo, units) return controller.client.get_repository(repo.id).result()
def unit_for_item(item, old_unit): assert isinstance(item, ErratumPushItem) return ErratumUnit( # Fields which are plainly copied id=item.name, status=item.status, updated=item.updated, issued=item.issued, description=item.description, pushcount=item.pushcount, reboot_suggested=item.reboot_suggested, from_=item.from_, rights=item.rights, title=item.title, severity=item.severity, release=item.release, type=item.type, solution=item.solution, summary=item.summary, content_types=item.content_types, # This field needs to be bumped if there is an existing unit, # else Pulp will discard changes. version=unit_erratum_version(item, old_unit), # These types need some conversions applied. references=unit_erratum_references(item), pkglist=unit_erratum_pkglist(item), )
def test_erratum_publishes_all_repos(): item = PulpErratumPushItem( # We're being asked to push an advisory to a few repos... pushsource_item=ErratumPushItem(name="RHSA-1234:56", dest=["new1", "new2", "existing1"]), pulp_state=State.PARTIAL, pulp_unit=ErratumUnit( id="abc123", # ...and the advisory already exists in some Pulp, repos, maybe with # some overlap repository_memberships=[ "all-rpm-content", "all-rpm-content-ff", "existing1", "existing2", ], ), ) # Then when we calculate the repos which should be published for this item, # it should always include both the new repo(s) we're pushing to and also the # existing repos, as any mutation of the erratum requires metadata to be # republished for all of them. # all-rpm-content is an exception given that those repos don't get published. assert item.publish_pulp_repos == [ "existing1", "existing2", "new1", "new2" ]
def test_upload_overwrite_noop(): """repo.upload_erratum() doesn't overwrite erratum unit if version is unmodified.""" controller = FakeController() controller.insert_repository(YumRepository(id="repo1")) controller.insert_repository(YumRepository(id="repo2")) client = controller.client repo1 = client.get_repository("repo1").result() repo2 = client.get_repository("repo2").result() to_upload1 = ErratumUnit(id="RHBA-1234:56", summary="test advisory", version="3") to_upload2 = ErratumUnit( id="RHBA-1234:56", summary="updated test advisory", description="changed it, but no effect due to same version", version="3", ) # Upload the advisory to two different repos. assert repo1.upload_erratum(to_upload1).result() assert repo2.upload_erratum(to_upload2).result() # Now let's check the outcome in each repo (and entire system). units_repo1 = sorted(repo1.search_content(), key=repr) units_repo2 = sorted(repo2.search_content(), key=repr) units_all = sorted(client.search_content(), key=repr) # What we expect to see is that we only have one advisory (as only # a single id was used), that advisory is present in two repos, and # the advisory content is equal to the first upload because version # was not bumped for the second upload. assert units_repo1 == [ ErratumUnit( unit_id="e3e70682-c209-4cac-629f-6fbed82c07cd", id="RHBA-1234:56", summary="test advisory", version="3", repository_memberships=["repo1", "repo2"], ) ] assert units_repo2 == units_repo1 assert units_all == units_repo1
def test_can_upload_units(): """repo.upload_erratum() succeeds with fake client and populates units.""" controller = FakeController() controller.insert_repository(YumRepository(id="repo1")) client = controller.client repo1 = client.get_repository("repo1").result() to_upload = ErratumUnit( id="RHBA-1234:56", summary="test advisory", # Add some existing memberships in an attempt to screw it up... # (they should not affect the upload) repository_memberships=["repo2", "repo3"], ) upload_f = repo1.upload_erratum(to_upload) # Upload should complete successfully. tasks = upload_f.result() # At least one task. assert tasks # Every task should have succeeded. for t in tasks: assert t.succeeded # If I now search for content in that repo, or content across all repos... units_in_repo = list(repo1.search_content()) units_all = list(client.search_content()) # They should be equal assert units_all == units_in_repo # And they should be this assert units_in_repo == [ ErratumUnit( unit_id="e3e70682-c209-4cac-629f-6fbed82c07cd", id="RHBA-1234:56", summary="test advisory", repository_memberships=["repo1"], ) ]
def test_search_erratum_by_type(populated_repo): """search_content for erratum returns matching content""" crit = Criteria.with_field("content_type_id", "erratum") units = list(populated_repo.search_content(crit)) assert units == [ ErratumUnit( unit_id="85776e9a-dd84-f39e-7154-5a137a1d5006", id="RHBA-1234:56", summary="The best advisory", repository_memberships=["repo1"], ) ]
def _setup_controller(controller): # add repo repo = YumRepository( id="repo", eng_product_id=101, distributors=[], relative_url="content/unit/1/client", mutable_urls=["mutable1", "mutable2"], ) nochannel_repo = YumRepository( id="all-rpm-content", eng_product_id=100, distributors=[], relative_url="content/unit/1/all-rpm", mutable_urls=["mutable1", "mutable2"], ) # add unit erratum = ErratumUnit( id="RHSA-1234:56", version="2", content_types=["rpm", "module"], references=[ ErratumReference( title="title", href="https://example.com/test-advisory", type="self", id="self-id", ), ErratumReference( title="CVE-123", href="https://example.com/test-cve", type="cve", id="CVE-123", ), ], pkglist=[], repository_memberships=["repo", "all-rpm-content"], ) controller.insert_repository(repo) controller.insert_repository(nochannel_repo) controller.insert_units(repo, [erratum]) controller.insert_units(nochannel_repo, [erratum])
def test_erratum_validates_references(): """It is not possible to pass incorrect types into an erratum reference list.""" # Validation of references within the list is tested explicitly because deep # validation is uncommon across the model. We don't explicitly test it for every # field though. unit = ErratumUnit(id="RHBA-1234:56") ref = ErratumReference(href="https://example.com") # It starts out with absent references. assert unit.references is None # We can add an empty list OK... assert evolve(unit, references=[]).references == [] # We can add a list with references OK... assert evolve(unit, references=[ref]).references == [ref] # But we cannot add a list with other stuff with pytest.raises(TypeError): evolve(unit, references=[ref, {"href": "abc123"}])
def test_delete_advisory(command_tester, fake_collector, monkeypatch): """Deletion of packages and modules in advisories from provided repos succeeds""" repo1 = YumRepository(id="some-yumrepo", relative_url="some/publish/url", mutable_urls=["repomd.xml"]) repo2 = YumRepository( id="some-other-repo", relative_url="other/publish/url", mutable_urls=["repomd.xml"], ) pkglist = [ ErratumPackageCollection( name="colection-0", packages=None, short="", module=ErratumModule(name="mymod", stream="s1", version="123", context="a1c2", arch="s390x"), ), ErratumPackageCollection( name="collection-1", packages=[ ErratumPackage( name="bash", version="1.23", release="1.test8", arch="x86_64", filename="bash-1.23-1.test8_x86_64.rpm", sha256sum="a" * 64, md5sum="b" * 32, ), ErratumPackage( name="dash", version="1.23", release="1.test8", arch="x86_64", filename="dash-1.23-1.test8_x86_64.rpm", sha256sum="a" * 64, md5sum="b" * 32, ), ], short="", module=None, ), ] files1 = [ RpmUnit( name="bash", version="1.23", release="1.test8", arch="x86_64", filename="bash-1.23-1.test8_x86_64.rpm", sha256sum="a" * 64, md5sum="b" * 32, signing_key="aabbcc", unit_id="files1_rpm1", ), RpmUnit( name="dash", version="1.23", release="1.test8", arch="x86_64", filename="dash-1.23-1.test8_x86_64.rpm", sha256sum="a" * 64, md5sum="b" * 32, signing_key="aabbcc", unit_id="files1_rpm2", ), RpmUnit( name="crash", version="1.23", release="1.test8", arch="x86_64", filename= "crash-1.23-1.test8.module+el8.0.0+3049+59fd2bba.x86_64.rpm", sha256sum="a" * 64, md5sum="b" * 32, signing_key="aabbcc", unit_id="files1_rpm3", ), ModulemdUnit( name="mymod", stream="s1", version=123, context="a1c2", arch="s390x", artifacts=[ "crash-0:1.23-1.test8.module+el8.0.0+3049+59fd2bba.x86_64" ], unit_id="files1_mod1", ), ErratumUnit( unit_id="e3e70682-c209-4cac-629f-6fbed82c07cd", id="RHSA-1111:22", summary="Dummy erratum", content_type_id="erratum", repository_memberships=["some-yumrepo"], pkglist=pkglist, ), ] files2 = [ ErratumUnit( unit_id="x4e73262-e239-44ac-629f-6fbed82c07cd", id="RHBA-1001:22", summary="Other erratum", content_type_id="erratum", repository_memberships=["some-other-repo"], pkglist=[], ), ] with FakeDeleteAdvisory() as task_instance: task_instance.pulp_client_controller.insert_repository(repo1) task_instance.pulp_client_controller.insert_repository(repo2) task_instance.pulp_client_controller.insert_units(repo1, files1) task_instance.pulp_client_controller.insert_units(repo2, files2) # Let's try setting the cache flush root via env. monkeypatch.setenv("FASTPURGE_ROOT_URL", "https://cdn.example2.com/") # It should run with expected output. command_tester.test( task_instance.main, [ "test-delete", "--pulp-url", "https://pulp.example.com/", "--fastpurge-host", "fakehost-xxx.example.net", "--fastpurge-client-secret", "abcdef", "--fastpurge-client-token", "efg", "--fastpurge-access-token", "tok", "--repo", "some-yumrepo,other-yumrepo", "--advisory", "RHSA-1111:22", "--advisory", "RHBA-1001:22", ], ) assert sorted(fake_collector.items, key=lambda pi: pi["filename"]) == [ { "origin": "pulp", "src": None, "dest": "some-yumrepo", "signing_key": None, "filename": "bash-1.23-1.test8.x86_64.rpm", "state": "DELETED", "build": None, "checksums": { "sha256": "a" * 64 }, }, { "origin": "pulp", "src": None, "dest": "some-yumrepo", "signing_key": None, "filename": "crash-1.23-1.test8.x86_64.rpm", "state": "DELETED", "build": None, "checksums": { "sha256": "a" * 64 }, }, { "origin": "pulp", "src": None, "dest": "some-yumrepo", "signing_key": None, "filename": "dash-1.23-1.test8.x86_64.rpm", "state": "DELETED", "build": None, "checksums": { "sha256": "a" * 64 }, }, { "origin": "pulp", "src": None, "dest": "some-yumrepo", "signing_key": None, "filename": "mymod:s1:123:a1c2:s390x", "state": "DELETED", "build": None, "checksums": None, }, ] # verify whether the rpms and modules were deleted from the repo on Pulp client = task_instance.pulp_client # effectively only some-yumrepo(repo1) was modified repos = list( client.search_repository( Criteria.with_id("some-yumrepo")).result()) assert len(repos) == 1 repo = repos[0] # list the removed unit's unit_id # RPMs from the erratum package list unit_ids = ["files1_rpm1", "files1_rpm2"] # module from the erratum package list unit_ids.append("files1_mod1") # package in the above module unit_ids.append("files1_rpm3") criteria = Criteria.with_field("unit_id", Matcher.in_(unit_ids)) # deleted files are not in the repo files = list(repo.search_content(criteria).result()) assert len(files) == 0 # same files exist on Pulp as orphans files_search = list(client.search_content(criteria).result()) assert len(files_search) == 4
def test_update_push(fake_controller, data_path, fake_push, fake_state_path, command_tester, monkeypatch): """Test a more complex push where items already exist in Pulp in a variety of different states. """ # For this test we'll force an abnormally small queue size. # This will verify that nothing breaks in edge cases such as the queue size # being smaller than the batch size. monkeypatch.setattr(context, "QUEUE_SIZE", 2) # Sanity check that the Pulp server is, initially, empty. client = fake_controller.client assert list(client.search_content()) == [] all_rpm_content = client.get_repository("all-rpm-content").result() iso_dest1 = client.get_repository("iso-dest1").result() dest1 = client.get_repository("dest1").result() # Make this RPM exist, but not in all the desired repos. existing_rpm = RpmUnit( cdn_published=datetime.datetime(2021, 12, 14, 9, 59), arch="src", filename="test-srpm01-1.0-1.src.rpm", md5sum="ba9257ced24f77f4d777e399e67924f5", name="test-srpm01", version="1.0", release="1", provides=[], requires=[ RpmDependency( epoch="0", version="4.6.0", release="1", flags="LE", name="rpmlib(FileDigests)", ), RpmDependency( epoch="0", version="3.0.4", release="1", flags="LE", name="rpmlib(CompressedFileNames)", ), ], sha1sum="d9629c034fed3a2f47870fc6fdc78a30c5556e1d", sha256sum= "54cc4713fe704dfc7a4fd5b398f834ceb6a692f53b0c6aefaf89d88417b4c51d", unit_id="existing-rpm-id1", ) fake_controller.insert_units(all_rpm_content, [existing_rpm]) # Make this file exist, but with an outdated description. existing_file = FileUnit( cdn_path= "/content/origin/files/sha256/db/db68c8a70f8383de71c107dca5fcfe53b1132186d1a6681d9ee3f4eea724fabb/some-iso", cdn_published=datetime.datetime(2021, 12, 14, 9, 59), description="A wrong description", path="some-iso", sha256sum= "db68c8a70f8383de71c107dca5fcfe53b1132186d1a6681d9ee3f4eea724fabb", size=46, unit_id="existing-file-id1", ) fake_controller.insert_units(iso_dest1, [existing_file]) # Make this file exist, but in no repos at all, making it an orphan orphan_file = FileUnit( cdn_path= "/content/origin/files/sha256/d8/d8301c5f72f16455dbc300f3d1bef8972424255caad103cc6c7ba7dc92d90ca8/test.txt", cdn_published=datetime.datetime(2021, 12, 14, 9, 59), path="test.txt", sha256sum= "d8301c5f72f16455dbc300f3d1bef8972424255caad103cc6c7ba7dc92d90ca8", size=33, unit_id="orphan-file-id1", ) fake_controller.insert_units(None, [orphan_file]) # Make this erratum exist, but with most fields missing existing_erratum = ErratumUnit( id="RHSA-2020:0509", unit_id="existing-erratum-id1", # make this have a non-integral version right now so usual bumping # does not work version="oops-not-integer", ) fake_controller.insert_units(dest1, [existing_erratum]) # Set it up to find content from our staging dir, which contains a mixture # of just about every content type stagedir = os.path.join(data_path, "staged-mixed") compare_extra = { "pulp.yaml": { "filename": fake_state_path, "normalize": hide_unit_ids, } } args = [ "", "--source", "staged:%s" % stagedir, "--allow-unsigned", "--pulp-url", "https://pulp.example.com/", ] run = functools.partial(entry_point, cls=lambda: fake_push) # It should be able to run without crashing. command_tester.test( run, args, compare_plaintext=False, compare_jsonl=False, # This will ensure the Pulp state matches the baseline. compare_extra=compare_extra, ) # Pulp state is covered by compare_extra, but let's also explicitly compare # the changes we expect on those existing units... updated_rpm = list( client.search_content( Criteria.with_field("unit_id", existing_rpm.unit_id))) assert len(updated_rpm) == 1 updated_rpm = updated_rpm[0] updated_file = list( client.search_content( Criteria.with_field("unit_id", existing_file.unit_id))) assert len(updated_file) == 1 updated_file = updated_file[0] updated_orphan_file = list( client.search_content( Criteria.with_field("unit_id", orphan_file.unit_id))) assert len(updated_orphan_file) == 1 updated_orphan_file = updated_orphan_file[0] updated_erratum = list( client.search_content( Criteria.with_field("unit_id", existing_erratum.unit_id))) assert len(updated_erratum) == 1 updated_erratum = updated_erratum[0] # RPM after push should be as it was before except that dest1 was added into # repository_memberships. assert updated_rpm == attr.evolve( existing_rpm, repository_memberships=["all-rpm-content", "dest1"]) # File after push should be as it was before except that description was updated # to the desired value. assert updated_file == attr.evolve(updated_file, description="My wonderful ISO") # Orphaned file after push should be as it was before except no longer an orphan. assert updated_orphan_file == attr.evolve( orphan_file, repository_memberships=["iso-dest1", "iso-dest2"], ) # Erratum after push should be updated. The full update will not be tested here # as it's extremely verbose, we'll just sample some fields. But, critically, # the 'version' field (which was not an integer in pulp) should have been # simply overwritten with the input rather than bumped. assert updated_erratum.title == "Important: sudo security update" assert updated_erratum.pkglist assert updated_erratum.version == "3"
def u(version=None): return ErratumUnit(id="whatever", version=version)
def test_upload_overwrite(): """repo.upload_erratum() can overwrite fields of an existing advisory.""" controller = FakeController() controller.insert_repository(YumRepository(id="repo1")) controller.insert_repository(YumRepository(id="repo2")) client = controller.client repo1 = client.get_repository("repo1").result() repo2 = client.get_repository("repo2").result() to_upload1 = ErratumUnit(id="RHBA-1234:56", summary="test advisory", version="1") to_upload2 = ErratumUnit( id="RHBA-1234:56", summary="updated test advisory", description="I've altered the deal", version="2", ) to_upload3 = ErratumUnit(id="RHBA-1234:57", summary="a different advisory") # Upload all three of the above advisories. # Uploads 1 and 2 are for the same advisory (though we use # different repos to see what happens). assert repo1.upload_erratum(to_upload1).result() assert repo2.upload_erratum(to_upload2).result() assert repo2.upload_erratum(to_upload3).result() # Now let's check the outcome in each repo (and entire system). units_repo1 = sorted(repo1.search_content(), key=repr) units_repo2 = sorted(repo2.search_content(), key=repr) units_all = sorted(client.search_content(), key=repr) # What we expect to see is that the three uploads resulted in only # two errata, with the fields on the first advisory set to the values # after the most recent upload of it, and the second advisory equal to # the single upload for that advisory. Also, the first advisory is # now present in two repos. assert units_repo1 == [ ErratumUnit( unit_id="e3e70682-c209-4cac-629f-6fbed82c07cd", id="RHBA-1234:56", summary="updated test advisory", description="I've altered the deal", version="2", repository_memberships=["repo1", "repo2"], ) ] assert units_repo2 == [ ErratumUnit( unit_id="e3e70682-c209-4cac-629f-6fbed82c07cd", id="RHBA-1234:56", summary="updated test advisory", description="I've altered the deal", version="2", repository_memberships=["repo1", "repo2"], ), ErratumUnit( unit_id="e6f4590b-9a16-4106-cf6a-659eb4862b21", id="RHBA-1234:57", summary="a different advisory", repository_memberships=["repo2"], ), ] assert units_repo2 == units_all
def make_erratum_unit(self, metadata): md = metadata.copy() md["_id"] = self.next_unit_id() md["_content_type_id"] = "erratum" return ErratumUnit.from_data(md)
def test_can_load_erratum(data_path): """ErratumUnit loads correctly from a complex sample Pulp response.""" # This JSON was taken from a real Pulp search, though it was slightly trimmed # to reduce the size of the test data (e.g. cutting out modules for some arches, # cutting down the repo and package lists). with open(os.path.join(data_path, "sample-erratum.json"), "rt") as f: data = json.load(f) # It should parse correctly loaded = Unit.from_data(data) # It should be equal to the following... # Note, in order to make the test more manageable in case of failure, we verify # some of the more complicated nested fields first, then omit them from the # later comparison of the overall unit. This way the pytest output is more amenable # to copy-pasting values back into the test if behavior changes. assert loaded.references == [ ErratumReference( href="https://access.redhat.com/errata/RHSA-2019:0975", id="RHSA-2019:0975", title="RHSA-2019:0975", type="self", ), ErratumReference( href="https://bugzilla.redhat.com/show_bug.cgi?id=1664908", id="1664908", title= "CVE-2019-5736 runc: Execution of malicious containers allows for container escape and access to host filesystem", type="bugzilla", ), ErratumReference( href="https://bugzilla.redhat.com/show_bug.cgi?id=1695689", id="1695689", title= "[stream rhel8] don't allow a container to connect to random services", type="bugzilla", ), ErratumReference( href="https://www.redhat.com/security/data/cve/CVE-2019-5736.html", id="CVE-2019-5736", title="CVE-2019-5736", type="cve", ), ErratumReference( href= "https://access.redhat.com/security/updates/classification/#important", id="classification", title="important", type="other", ), ] assert loaded.pkglist == [ ErratumPackageCollection( name="collection-0", packages=[ ErratumPackage( arch="x86_64", filename= "slirp4netns-debuginfo-0.1-2.dev.gitc4e1bc5.module+el8.0.0+2958+4e823551.x86_64.rpm", epoch="0", name="slirp4netns-debuginfo", version="0.1", release="2.dev.gitc4e1bc5.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="917ceef4aba550095d6ce5ab72b20e2e", sha1sum=None, sha256sum= "c4de28590622f59415de3a8b9fcb427cfd34637c4a7e6accd29d3f39d7699e6d", ), ErratumPackage( arch="x86_64", filename= "slirp4netns-debugsource-0.1-2.dev.gitc4e1bc5.module+el8.0.0+2958+4e823551.x86_64.rpm", epoch="0", name="slirp4netns-debugsource", version="0.1", release="2.dev.gitc4e1bc5.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="9519596175f7eb90439f4f60db38e97d", sha1sum=None, sha256sum= "d0f48388b6ba9d62d2350cd4216755f2517aaa3934663e2fc192b2f40c615e49", ), ErratumPackage( arch="x86_64", filename= "slirp4netns-0.1-2.dev.gitc4e1bc5.module+el8.0.0+2958+4e823551.x86_64.rpm", epoch="0", name="slirp4netns", version="0.1", release="2.dev.gitc4e1bc5.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="af0d6447dc9f81d2718e70f103070bc0", sha1sum=None, sha256sum= "e7a6c321ae08e6050c39d5a0c94d6e765c1a9d4d2b030f219bf6d916619b29f1", ), ErratumPackage( arch="SRPMS", filename= "slirp4netns-0.1-2.dev.gitc4e1bc5.module+el8.0.0+2958+4e823551.src.rpm", epoch="0", name="slirp4netns", version="0.1", release="2.dev.gitc4e1bc5.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="c863064c1edd9f5d78208e873692c9dd", sha1sum=None, sha256sum= "be2d49e797db6395e819335ea8debe2639d562a621c730604b38139961d9d05b", ), ErratumPackage( arch="x86_64", filename= "skopeo-debugsource-0.1.32-3.git1715c90.module+el8.0.0+2958+4e823551.x86_64.rpm", epoch="1", name="skopeo-debugsource", version="0.1.32", release="3.git1715c90.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="6ee19888b7b3f900063331c75f9c4ab6", sha1sum=None, sha256sum= "71a82a595c93c9aef8c316fd87937e0334af51e2fc2996970ce39285daf03053", ), ErratumPackage( arch="x86_64", filename= "skopeo-0.1.32-3.git1715c90.module+el8.0.0+2958+4e823551.x86_64.rpm", epoch="1", name="skopeo", version="0.1.32", release="3.git1715c90.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="b6ae238c20daf85543d25daa292f83a7", sha1sum=None, sha256sum= "59070bd8647cdb34f434ef1a5593ff727ab87a0df105417de0bf16a2b5232512", ), ErratumPackage( arch="x86_64", filename= "runc-debugsource-1.0.0-55.rc5.dev.git2abd837.module+el8.0.0+3049+59fd2bba.x86_64.rpm", epoch="0", name="runc-debugsource", version="1.0.0", release= "55.rc5.dev.git2abd837.module+el8.0.0+3049+59fd2bba", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="eedf3c1be375ebbe727471f4c9a225d9", sha1sum=None, sha256sum= "f408bd733935a79274bb810bd1cff00bca93fcfa410315b1e4f071ae177774e6", ), ], short="", module=ErratumModule( name="container-tools", stream="rhel8", version="8000020190416221845", context="2ffa3d27", arch="x86_64", ), ), ErratumPackageCollection( name="collection-3", packages=[ ErratumPackage( arch="SRPMS", filename= "slirp4netns-0.1-2.dev.gitc4e1bc5.module+el8.0.0+2958+4e823551.src.rpm", epoch="0", name="slirp4netns", version="0.1", release="2.dev.gitc4e1bc5.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="c863064c1edd9f5d78208e873692c9dd", sha1sum="f3d9ae4aeea6946a8668445395ba10b7399523a0", sha256sum= "be2d49e797db6395e819335ea8debe2639d562a621c730604b38139961d9d05b", ), ErratumPackage( arch="s390x", filename= "skopeo-debugsource-0.1.32-3.git1715c90.module+el8.0.0+2958+4e823551.s390x.rpm", epoch="1", name="skopeo-debugsource", version="0.1.32", release="3.git1715c90.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="76161e93a42383b4b6b1f42482f3dd4d", sha1sum=None, sha256sum= "aea7d37b68d252d5e57d6db50b5c26188412d6464e0b81a5a6deae431ea55bee", ), ErratumPackage( arch="s390x", filename= "skopeo-debuginfo-0.1.32-3.git1715c90.module+el8.0.0+2958+4e823551.s390x.rpm", epoch="1", name="skopeo-debuginfo", version="0.1.32", release="3.git1715c90.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="8004f3a05e5eac46c76a2e805be3809e", sha1sum=None, sha256sum= "dda994b3f186ed3ce6a9d7c48402a0bab7757eb020b72991c9dd35e615b5e4eb", ), ErratumPackage( arch="s390x", filename= "runc-debugsource-1.0.0-55.rc5.dev.git2abd837.module+el8.0.0+3049+59fd2bba.s390x.rpm", epoch="0", name="runc-debugsource", version="1.0.0", release= "55.rc5.dev.git2abd837.module+el8.0.0+3049+59fd2bba", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="6b171a203c7bf91b8f0b78f453fcef9c", sha1sum=None, sha256sum= "845de746c15d5bf7e29f5a13011066c968c1dfb05cd554b0450a2d25a7e4e3bc", ), ErratumPackage( arch="SRPMS", filename= "runc-1.0.0-55.rc5.dev.git2abd837.module+el8.0.0+3049+59fd2bba.src.rpm", epoch="0", name="runc", version="1.0.0", release= "55.rc5.dev.git2abd837.module+el8.0.0+3049+59fd2bba", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="364ba52d0e1eb8fbe899c3424520eb56", sha1sum=None, sha256sum= "3a40f68a0b93dd2ac3cddf5b1d58ef77372942777fc798ff413453d6fa0253f7", ), ErratumPackage( arch="s390x", filename= "slirp4netns-debuginfo-0.1-2.dev.gitc4e1bc5.module+el8.0.0+2958+4e823551.s390x.rpm", epoch="0", name="slirp4netns-debuginfo", version="0.1", release="2.dev.gitc4e1bc5.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="797254858bba898ace72128df8d8ec3e", sha1sum=None, sha256sum= "e169df356459146ceaa745297d8df49a3b15cc9e648b418869ca9e35020f3cac", ), ErratumPackage( arch="s390x", filename= "runc-1.0.0-55.rc5.dev.git2abd837.module+el8.0.0+3049+59fd2bba.s390x.rpm", epoch="0", name="runc", version="1.0.0", release= "55.rc5.dev.git2abd837.module+el8.0.0+3049+59fd2bba", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="25e8c8cd2ed9e0a0a02dc5aef09889a8", sha1sum=None, sha256sum= "46bb4965c22bca3aadc383503a5e84d2879b19217830ee0d04f029aa0bf92f07", ), ErratumPackage( arch="s390x", filename= "runc-debuginfo-1.0.0-55.rc5.dev.git2abd837.module+el8.0.0+3049+59fd2bba.s390x.rpm", epoch="0", name="runc-debuginfo", version="1.0.0", release= "55.rc5.dev.git2abd837.module+el8.0.0+3049+59fd2bba", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="326c37fb3566e45dc014968e5374fa87", sha1sum=None, sha256sum= "5db29f35f2f40cfada2231146a8f6d1e3f430722c0f8d43a2638259ff2627e3f", ), ErratumPackage( arch="noarch", filename= "podman-docker-1.0.0-2.git921f98f.module+el8.0.0+2958+4e823551.noarch.rpm", epoch="0", name="podman-docker", version="1.0.0", release="2.git921f98f.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="ad952f9efc5f29afec5fb9530deb28b6", sha1sum=None, sha256sum= "40d3190ed329073ed3454bb726a7452b1b3ba8cd87b7d78183e42e899d187a1d", ), ErratumPackage( arch="s390x", filename= "podman-debugsource-1.0.0-2.git921f98f.module+el8.0.0+2958+4e823551.s390x.rpm", epoch="0", name="podman-debugsource", version="1.0.0", release="2.git921f98f.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="30b56bf9f2be62a4eb2f04cb6b6fd21a", sha1sum=None, sha256sum= "052278774a5459fea098ca1307756adf8f3039cac64aff3b8968ceb765618b09", ), ErratumPackage( arch="s390x", filename= "podman-debuginfo-1.0.0-2.git921f98f.module+el8.0.0+2958+4e823551.s390x.rpm", epoch="0", name="podman-debuginfo", version="1.0.0", release="2.git921f98f.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="1597e5db5b8b4019b3025c986286091e", sha1sum=None, sha256sum= "af7a7ba25f770cdd7710d4fc9fbf03b9c42e48b8ec1012592a8c9dd4f67d8fa6", ), ErratumPackage( arch="SRPMS", filename= "skopeo-0.1.32-3.git1715c90.module+el8.0.0+2958+4e823551.src.rpm", epoch="1", name="skopeo", version="0.1.32", release="3.git1715c90.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="3400331ed99d0400067f9aed159e1e0d", sha1sum=None, sha256sum= "21dc81a5e23fee5345680ff6862536ae7390a0e9e91dba6fc667e1e60dde57d9", ), ErratumPackage( arch="SRPMS", filename= "podman-1.0.0-2.git921f98f.module+el8.0.0+2958+4e823551.src.rpm", epoch="0", name="podman", version="1.0.0", release="2.git921f98f.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="c3da563d95ae856854e0db46bd92d98b", sha1sum=None, sha256sum= "39757bdfbe409896cff75635e3afe6aea21b25c09aab0789961d6168e8c8bff6", ), ErratumPackage( arch="SRPMS", filename= "containernetworking-plugins-0.7.4-3.git9ebe139.module+el8.0.0+2958+4e823551.src.rpm", epoch="0", name="containernetworking-plugins", version="0.7.4", release="3.git9ebe139.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="fdb5afbae0ad44795776d843f2defd76", sha1sum=None, sha256sum= "44e465a362abb8357f2019057162d02226a510abc78c15c65a88d72c67dd53b5", ), ErratumPackage( arch="s390x", filename= "containernetworking-plugins-0.7.4-3.git9ebe139.module+el8.0.0+2958+4e823551.s390x.rpm", epoch="0", name="containernetworking-plugins", version="0.7.4", release="3.git9ebe139.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="cc9e5527550ebf573ad36c5092c19ffc", sha1sum=None, sha256sum= "b212c36df71a20689079592f27a9d03870a623a11f51a9761f7973e659939f81", ), ErratumPackage( arch="s390x", filename= "containernetworking-plugins-debugsource-0.7.4-3.git9ebe139.module+el8.0.0+2958+4e823551.s390x.rpm", epoch="0", name="containernetworking-plugins-debugsource", version="0.7.4", release="3.git9ebe139.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="85a20df93f2b529ad239e00492b67cd7", sha1sum=None, sha256sum= "3a0b84d25293ede8957c38dae236947cd508415a7f0b892ad205d8cdb37f35e1", ), ErratumPackage( arch="SRPMS", filename= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", epoch="2", name="container-selinux", version="2.94", release="1.git1e99f1d.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="e4265aa655362fdf6cc0265a29dc3792", sha1sum=None, sha256sum= "e014ffe8047a36c08ddfdaa4f96a09d954cef60c17c2c79a6dc0d72d4ba5770e", ), ErratumPackage( arch="s390x", filename= "skopeo-0.1.32-3.git1715c90.module+el8.0.0+2958+4e823551.s390x.rpm", epoch="1", name="skopeo", version="0.1.32", release="3.git1715c90.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="d382120e5fdaaa24e405fbb5ee670451", sha1sum=None, sha256sum= "501765be7912c9d08ab5c5f5752ecf73569536457cd3ee2ce0643f70d3991cde", ), ErratumPackage( arch="s390x", filename= "podman-1.0.0-2.git921f98f.module+el8.0.0+2958+4e823551.s390x.rpm", epoch="0", name="podman", version="1.0.0", release="2.git921f98f.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="69ce75e8b3f2a2271cd8f17b6b1db4b7", sha1sum=None, sha256sum= "893044e6293c97fd33e55d57058505b012d5aada5ebfc25cc00aa6950160cd84", ), ErratumPackage( arch="s390x", filename= "buildah-1.5-3.gite94b4f9.module+el8.0.0+2958+4e823551.s390x.rpm", epoch="0", name="buildah", version="1.5", release="3.gite94b4f9.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="d63e2bc9c179ea8135b9fc7ce8f4e326", sha1sum=None, sha256sum= "044fd3ab6a4231843c704998b61eb161839ae0c203ed2b0a9cbe0259f35bc65b", ), ErratumPackage( arch="s390x", filename= "slirp4netns-debugsource-0.1-2.dev.gitc4e1bc5.module+el8.0.0+2958+4e823551.s390x.rpm", epoch="0", name="slirp4netns-debugsource", version="0.1", release="2.dev.gitc4e1bc5.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="c2e8d125a5e2c65fef41cca893048400", sha1sum=None, sha256sum= "a85891d07733c3e7b765229358d2cec33331731649265a105a7b742e5b0accfa", ), ErratumPackage( arch="SRPMS", filename= "fuse-overlayfs-0.3-2.module+el8.0.0+2958+4e823551.src.rpm", epoch="0", name="fuse-overlayfs", version="0.3", release="2.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="b09d3edcc9350a269b6c4c4c277d270a", sha1sum=None, sha256sum= "88c203351d6aae3f5a02ea46fc221be18d28e3c3f2c5ebd17bada049bdb9e4d8", ), ErratumPackage( arch="noarch", filename= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.noarch.rpm", epoch="2", name="container-selinux", version="2.94", release="1.git1e99f1d.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="f7d31e5f099bcdadf419239db840baa8", sha1sum=None, sha256sum= "8a3a4eb8c3ee529e3b103ece6200517ff6834d24dab1d202e392347efedc254e", ), ErratumPackage( arch="s390x", filename= "containernetworking-plugins-debuginfo-0.7.4-3.git9ebe139.module+el8.0.0+2958+4e823551.s390x.rpm", epoch="0", name="containernetworking-plugins-debuginfo", version="0.7.4", release="3.git9ebe139.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="da26f260ae089792ec07a876f4dbf2bb", sha1sum=None, sha256sum= "e78ffa580ea6daad1fd16c15aa3483f2d85f0c15d6ba23c4a372daaa4382e31f", ), ErratumPackage( arch="SRPMS", filename= "buildah-1.5-3.gite94b4f9.module+el8.0.0+2958+4e823551.src.rpm", epoch="0", name="buildah", version="1.5", release="3.gite94b4f9.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="d2366a6349f28506bfd4fb0525b533d7", sha1sum=None, sha256sum= "55756e48575e8cf7eab5021c8ecd788e66741287a6da6d4dc18ed005e22e3093", ), ErratumPackage( arch="s390x", filename= "buildah-debuginfo-1.5-3.gite94b4f9.module+el8.0.0+2958+4e823551.s390x.rpm", epoch="0", name="buildah-debuginfo", version="1.5", release="3.gite94b4f9.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="4c8460d1f71c6d574aeca973ad2e0d89", sha1sum=None, sha256sum= "65c626e0d15440fb56e8e0489da3f1ccf1442f3ba6ebf3338eefdf7ee98cea89", ), ErratumPackage( arch="s390x", filename= "slirp4netns-0.1-2.dev.gitc4e1bc5.module+el8.0.0+2958+4e823551.s390x.rpm", epoch="0", name="slirp4netns", version="0.1", release="2.dev.gitc4e1bc5.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="41cec16504692c5bc462b7d5f8737087", sha1sum=None, sha256sum= "0e9580680295adeba3bc9f033176492f881adb98cbe919b921b9ec9a74f80181", ), ErratumPackage( arch="s390x", filename= "fuse-overlayfs-debuginfo-0.3-2.module+el8.0.0+2958+4e823551.s390x.rpm", epoch="0", name="fuse-overlayfs-debuginfo", version="0.3", release="2.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="51c4b466077a37084d7fedfdda3f57ff", sha1sum=None, sha256sum= "fddcdcf52fec789deb0d68d871cc3e9960ec4f1f0930c3275f188b5a968d93d1", ), ErratumPackage( arch="s390x", filename= "fuse-overlayfs-debugsource-0.3-2.module+el8.0.0+2958+4e823551.s390x.rpm", epoch="0", name="fuse-overlayfs-debugsource", version="0.3", release="2.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="ba7f2bac9de2bdf232187b9c543c47fc", sha1sum=None, sha256sum= "c7b0b7de23a900d05fe4052614e68226b00f1252b505898e14da3382002c26ef", ), ErratumPackage( arch="s390x", filename= "oci-systemd-hook-0.1.15-2.git2d0b8a3.module+el8.0.0+2958+4e823551.s390x.rpm", epoch="1", name="oci-systemd-hook", version="0.1.15", release="2.git2d0b8a3.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="122fc1079f4a05e0b2dee5e60dea3e54", sha1sum=None, sha256sum= "593595e3005ea32cf2ca84c93e1cba832461b2854b003046f3bd59f2e331819b", ), ErratumPackage( arch="s390x", filename= "fuse-overlayfs-0.3-2.module+el8.0.0+2958+4e823551.s390x.rpm", epoch="0", name="fuse-overlayfs", version="0.3", release="2.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="5eeec013645c903124089ceae13e6710", sha1sum=None, sha256sum= "28211a39e8bbdaf8792fc4485699696e67f62a0c4a40fc22a9ac1b7399f8edf7", ), ErratumPackage( arch="SRPMS", filename= "oci-systemd-hook-0.1.15-2.git2d0b8a3.module+el8.0.0+2958+4e823551.src.rpm", epoch="1", name="oci-systemd-hook", version="0.1.15", release="2.git2d0b8a3.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="a338cf74fe10bce021bbd5d8ba335657", sha1sum=None, sha256sum= "e7c95270d345a04b03d9f2351aca6f2f298764a89bf2039b27de71adc1362f8c", ), ErratumPackage( arch="SRPMS", filename= "oci-umount-2.3.4-2.git87f9237.module+el8.0.0+2958+4e823551.src.rpm", epoch="2", name="oci-umount", version="2.3.4", release="2.git87f9237.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="aa746cb0a01066d7fa670ca420833cf0", sha1sum=None, sha256sum= "eeb07a3822a3a4e4f78dd94e0e34a3b227d7d17d87ea04267439eb27c2265b33", ), ErratumPackage( arch="s390x", filename= "oci-systemd-hook-debuginfo-0.1.15-2.git2d0b8a3.module+el8.0.0+2958+4e823551.s390x.rpm", epoch="1", name="oci-systemd-hook-debuginfo", version="0.1.15", release="2.git2d0b8a3.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="a55e75853de831fec4462adf79257a03", sha1sum=None, sha256sum= "e01939fdfa24a707ed422262bb19a68e5e22995afd0f669be06c33202e00847a", ), ErratumPackage( arch="s390x", filename= "oci-systemd-hook-debugsource-0.1.15-2.git2d0b8a3.module+el8.0.0+2958+4e823551.s390x.rpm", epoch="1", name="oci-systemd-hook-debugsource", version="0.1.15", release="2.git2d0b8a3.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="9b29f218aac3861685faff8c69bb03ac", sha1sum=None, sha256sum= "c55dfc5af5c4a715f69b95a3772a4ede50db2d78c88cc9ca00b271d9f8b0c4a4", ), ErratumPackage( arch="s390x", filename= "oci-umount-debuginfo-2.3.4-2.git87f9237.module+el8.0.0+2958+4e823551.s390x.rpm", epoch="2", name="oci-umount-debuginfo", version="2.3.4", release="2.git87f9237.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="1f891c443aa35396dd57ae1185f98f9c", sha1sum=None, sha256sum= "344385d9c0cfdca4ddf16876936e36abad91c1cd7b99d3cb86e2fc5f858cb56f", ), ErratumPackage( arch="s390x", filename= "oci-umount-2.3.4-2.git87f9237.module+el8.0.0+2958+4e823551.s390x.rpm", epoch="2", name="oci-umount", version="2.3.4", release="2.git87f9237.module+el8.0.0+2958+4e823551", src= "container-selinux-2.94-1.git1e99f1d.module+el8.0.0+2958+4e823551.src.rpm", reboot_suggested=None, md5sum="eba982381b3a54d0ae7c14230f29fd69", sha1sum=None, sha256sum= "872610d40f5f50030ef6188d26178ae7b0dc8eedab72e285c8b513f8df145a2b", ), ], short="", module=ErratumModule( name="container-tools", stream="rhel8", version="8000020190416221845", context="2ffa3d27", arch="s390x", ), ), ] loaded = attr.evolve(loaded, pkglist=[], references=[]) assert loaded == ErratumUnit( unit_id="d003313d-2272-4ba3-8ea9-820269284dc2", id="RHSA-2019:0975", version="1", status="final", updated="2019-05-07 03:39:02 UTC", issued="2019-05-07 03:39:11 UTC", description= "The container-tools module contains tools for working with containers, notably podman, buildah, skopeo, and runc.\n\nSecurity Fix(es):\n\n* A flaw was found in the way runc handled system file descriptors when running containers. A malicious container could use this flaw to overwrite contents of the runc binary and consequently run arbitrary commands on the container host system. (CVE-2019-5736)\n\nFor more details about the security issue(s), including the impact, a CVSS score, acknowledgments, and other related information, refer to the CVE page(s) listed in the References section.\n\nBug Fix(es):\n\n* [stream rhel8] rebase container-selinux to 2.94 (BZ#1693675)\n\n* [stream rhel8] unable to mount disk at `/var/lib/containers` via `systemd` unit when `container-selinux` policy installed (BZ#1695669)\n\n* [stream rhel8] don't allow a container to connect to random services (BZ#1695689)", pushcount="8", reboot_suggested=False, from_="*****@*****.**", rights="Copyright 2019 Red Hat Inc", title="Important: container-tools:rhel8 security and bug fix update", severity="Important", release="0", type="security", solution= "For details on how to apply this update, which includes the changes described in this advisory, refer to:\n\nhttps://access.redhat.com/articles/11258", summary= "An update for the container-tools:rhel8 module is now available for Red Hat Enterprise Linux 8.\n\nRed Hat Product Security has rated this update as having a security impact of Important. A Common Vulnerability Scoring System (CVSS) base score, which gives a detailed severity rating, is available for each vulnerability from the CVE link(s) in the References section.", content_types=["module"], references=[], pkglist=[], content_type_id="erratum", repository_memberships=[ "all-rpm-content", "rhel-8-for-aarch64-appstream-source-rpms__8_DOT_0", "rhel-8-for-aarch64-appstream-source-rpms__8_DOT_1", "rhel-8-for-aarch64-appstream-source-rpms__8_DOT_2", "rhel-8-for-aarch64-appstream-source-rpms__8_DOT_3", "rhel-8-for-ppc64le-appstream-rpms__8_DOT_0", "rhel-8-for-ppc64le-appstream-rpms__8_DOT_1", "rhel-8-for-ppc64le-appstream-rpms__8_DOT_2", "rhel-8-for-ppc64le-appstream-rpms__8_DOT_3", "rhel-8-for-s390x-appstream-rpms__8", "rhel-8-for-s390x-appstream-rpms__8_DOT_1", "rhel-8-for-s390x-appstream-rpms__8_DOT_2", "rhel-8-for-x86_64-appstream-rpms__8", ], )
def test_upload_erratum(client, requests_mocker): """An ErratumUnit can be uploaded to a repository using the client.""" repo_id = "repo1" repo = YumRepository(id=repo_id) repo.__dict__["_client"] = client unit = ErratumUnit( id="RHBA-1234:56", summary="A great advisory", version="1", status="final", updated="some updated time", issued="some issued time", description="testing upload", pushcount="507", from_="*****@*****.**", reboot_suggested=False, rights="copyright bob", content_types=["rpm", "module"], references=[ ErratumReference( title="a link", href="https://example.com/test-advisory", type="self", id="self-id", ) ], pkglist=[], ) # Set up the requests it'll do: # # It will request an upload requests_mocker.post( "https://pulp.example.com/pulp/api/v2/content/uploads/", json={"upload_id": "my-upload-123"}, ) # It'll do an import against that upload requests_mocker.post( "https://pulp.example.com/pulp/api/v2/repositories/repo1/actions/import_upload/", json={ "spawned_tasks": [{ "task_id": "task123" }, { "task_id": "task234" }] }, ) # It'll search for status of the import tasks requests_mocker.post( "https://pulp.example.com/pulp/api/v2/tasks/search/", json=[ { "task_id": "task123", "state": "finished" }, { "task_id": "task234", "state": "finished" }, ], ) # It'll clean up the upload requests_mocker.delete( "https://pulp.example.com/pulp/api/v2/content/uploads/my-upload-123/") # Mocker setup is complete. # It should start the upload OK upload_f = repo.upload_erratum(unit) # I can await the result tasks = upload_f.result() # There should be the two tasks returned from the API assert sorted([t.id for t in tasks]) == ["task123", "task234"] # Each task should be successful for t in tasks: assert t.completed assert t.succeeded # What did the client actually try to import? import_request = requests_mocker.request_history[1] assert import_request.json() == { "upload_id": "my-upload-123", "unit_type_id": "erratum", "unit_key": { "id": "RHBA-1234:56" }, "unit_metadata": { # This should contain an accurate serialization of all fields # into the form required by Pulp. "id": "RHBA-1234:56", "version": "1", "status": "final", "updated": "some updated time", "issued": "some issued time", "description": "testing upload", "pushcount": "507", "reboot_suggested": False, "from": "*****@*****.**", "rights": "copyright bob", "summary": "A great advisory", "pulp_user_metadata": { "content_types": ["rpm", "module"] }, "references": [{ "href": "https://example.com/test-advisory", "id": "self-id", "title": "a link", "type": "self", }], "pkglist": [], # Note also that fields not explicitly set will be serialized # as None (see doc string on upload_erratum). "title": None, "severity": None, "release": None, "type": None, "solution": None, }, }
def test_copy_content_all(controller): """copy_content with no criteria copies all units from a repo""" src = YumRepository(id="src-repo") dest = YumRepository(id="dest-repo") other = YumRepository(id="other-repo") controller.insert_repository(src) controller.insert_repository(dest) controller.insert_repository(other) # Set up that both 'src' and 'other' contain some units. # The units in 'other' are there to ensure that copying only # happens from the given source repo and not other repos unexpectedly. src_units = [ ErratumUnit(id="RHSA-1111:22", summary="Fixes bad things"), ModulemdUnit( name="module1", stream="s1", version=1234, context="a1b2", arch="x86_64", repository_memberships=["repoA", "repoB"], ), RpmUnit( name="bash", version="4.0", release="1", arch="x86_64", # Note: the next two fields aren't part of the unit key on RPM units. # We put these here specifically to verify they'll be filtered out # on the copy response (as a real Pulp server does). filename="bash-4.0-1.x86_64.rpm", signing_key="a1b2c3", ), ] controller.insert_units(src, src_units) controller.insert_units( other, [ RpmUnit( name="glibc", version="5.0", release="1", arch="x86_64", sourcerpm="glibc-5.0-1.el5_11.1.src.rpm", ) ], ) client = controller.client # Repos are initially detached, re-fetch them via client src = client.get_repository(src.id).result() dest = client.get_repository(dest.id).result() # It should succeed copy_tasks = list(client.copy_content(src, dest)) # Gather all units apparently copied units = sum([t.units for t in copy_tasks], []) # It should copy just the units we expect, from src. # Note that these are incomplete views of the units, as (just like real pulp) # the fake will only return fields present in the unit_key after a copy. assert sorted(units, key=repr) == [ ErratumUnit(id="RHSA-1111:22"), ModulemdUnit(name="module1", stream="s1", version=1234, context="a1b2", arch="x86_64"), RpmUnit(name="bash", version="4.0", release="1", arch="x86_64", epoch="0"), ] # The copy should also impact subsequent content searches. dest_units = list(dest.search_content()) # The units we get from the search are not *precisely* the same as src_units, # because repository_memberships has been updated. assert sorted(dest_units, key=repr) == [ ErratumUnit( unit_id="e3e70682-c209-4cac-629f-6fbed82c07cd", id="RHSA-1111:22", summary="Fixes bad things", content_type_id="erratum", repository_memberships=["src-repo", "dest-repo"], ), ModulemdUnit( unit_id="82e2e662-f728-b4fa-4248-5e3a0a5d2f34", name="module1", stream="s1", version=1234, context="a1b2", arch="x86_64", content_type_id="modulemd", repository_memberships=["src-repo", "dest-repo", "repoA", "repoB"], ), RpmUnit( unit_id="d4713d60-c8a7-0639-eb11-67b367a9c378", name="bash", version="4.0", release="1", arch="x86_64", epoch="0", signing_key="a1b2c3", filename="bash-4.0-1.x86_64.rpm", content_type_id="rpm", repository_memberships=["src-repo", "dest-repo"], ), ]
def test_delete_advisory_no_repos_provided(command_tester, fake_collector, monkeypatch): """Deletion of packages succeeds in all the repos when the same advisory is present in multiple repos and repos are not provided in the request""" repo1 = YumRepository(id="some-yumrepo", relative_url="some/publish/url", mutable_urls=["repomd.xml"]) repo2 = YumRepository( id="other-yumrepo", relative_url="other/publish/url", mutable_urls=["repomd.xml"], ) pkglist = [ ErratumPackageCollection( name="collection-1", packages=[ ErratumPackage( name="bash", version="1.23", release="1.test8", arch="x86_64", filename="bash-1.23-1.test8_x86_64.rpm", sha256sum="a" * 64, md5sum="b" * 32, ), ErratumPackage( name="dash", version="1.23", release="1.test8", arch="x86_64", filename="dash-1.23-1.test8_x86_64.rpm", sha256sum="a" * 64, md5sum="b" * 32, ), ], short="", module=None, ), ] files = [ RpmUnit( name="bash", version="1.23", release="1.test8", arch="x86_64", filename="bash-1.23-1.test8_x86_64.rpm", sha256sum="a" * 64, md5sum="b" * 32, signing_key="aabbcc", unit_id="files1_rpm1", ), RpmUnit( name="dash", version="1.23", release="1.test8", arch="x86_64", filename="dash-1.23-1.test8_x86_64.rpm", sha256sum="a" * 64, md5sum="b" * 32, signing_key="aabbcc", unit_id="files1_rpm2", ), RpmUnit( name="crash", version="1.23", release="1.test8", arch="x86_64", filename= "crash-1.23-1.test8.module+el8.0.0+3049+59fd2bba.x86_64.rpm", sha256sum="a" * 64, md5sum="b" * 32, signing_key="aabbcc", unit_id="files1_rpm3", ), ErratumUnit( unit_id="x4e73262-e239-44ac-629f-6fbed82c07cd", id="RHBA-1001:22", summary="Other erratum", content_type_id="erratum", repository_memberships=["some-yumrepo", "other-yumrepo"], pkglist=pkglist, ), ] with FakeDeleteAdvisory() as task_instance: task_instance.pulp_client_controller.insert_repository(repo1) task_instance.pulp_client_controller.insert_repository(repo2) task_instance.pulp_client_controller.insert_units(repo1, files) task_instance.pulp_client_controller.insert_units(repo2, files) # Let's try setting the cache flush root via env. monkeypatch.setenv("FASTPURGE_ROOT_URL", "https://cdn.example2.com/") # It should run with expected output. command_tester.test( task_instance.main, [ "test-delete", "--pulp-url", "https://pulp.example.com/", "--fastpurge-host", "fakehost-xxx.example.net", "--fastpurge-client-secret", "abcdef", "--fastpurge-client-token", "efg", "--fastpurge-access-token", "tok", "--advisory", "RHBA-1001:22", ], ) assert sorted(fake_collector.items, key=lambda pi: (pi["filename"], pi["dest"])) == [ { "build": None, "checksums": { "sha256": "a" * 64 }, "dest": "other-yumrepo", "filename": "bash-1.23-1.test8.x86_64.rpm", "origin": "pulp", "signing_key": None, "src": None, "state": "DELETED", }, { "build": None, "checksums": { "sha256": "a" * 64 }, "dest": "some-yumrepo", "filename": "bash-1.23-1.test8.x86_64.rpm", "origin": "pulp", "signing_key": None, "src": None, "state": "DELETED", }, { "build": None, "checksums": { "sha256": "a" * 64 }, "dest": "other-yumrepo", "filename": "dash-1.23-1.test8.x86_64.rpm", "origin": "pulp", "signing_key": None, "src": None, "state": "DELETED", }, { "build": None, "checksums": { "sha256": "a" * 64 }, "dest": "some-yumrepo", "filename": "dash-1.23-1.test8.x86_64.rpm", "origin": "pulp", "signing_key": None, "src": None, "state": "DELETED", }, ] # verify whether the rpms were deleted from the repo on Pulp client = task_instance.pulp_client # get all the repos repos = list( client.search_repository( Criteria.with_id("some-yumrepo")).result()) assert len(repos) == 1 repo1 = repos[0] repos = list( client.search_repository( Criteria.with_id("other-yumrepo")).result()) assert len(repos) == 1 repo2 = repos[0] # list the removed unit's unit_id # RPMs from the erratum package list unit_ids = ["files1_rpm1", "files1_rpm2"] criteria = Criteria.with_field("unit_id", Matcher.in_(unit_ids)) # deleted packages from the advisory are not in both the repos files = list(repo1.search_content(criteria).result()) assert len(files) == 0 files = list(repo2.search_content(criteria).result()) assert len(files) == 0 # same files exist on Pulp as orphans files_search = list(client.search_content(criteria).result()) assert len(files_search) == 2