# Multiple Advisories in one repo
## Problem Statement
* Advisories are "supposed to be" invariant
* MANY repos in the RPM ecosystem "adjust" advisories with Wilde Abandonne
* updating text (e.g., description) (Everyone)
* adding References (Everyone)
* adding packages-affected (occasionally Red Hat, others)
* **changing** packages-affected (EPEL)
* advisories have a version-field that:
* is supposed to be updated when the above happens
* it often doesn't
* is supposed to be some comparable-version-string
* it is seen as "random string" In The Wild
* advisories have issue and updated-dates
* they can't be relied on either
* third-party repos "in the wild" can also have multiple advisories with the same id, in the same repo
* pulp_rpm wants there to be one Advisory with a given ID in a given repo-version
* pulp_rpm tries to warn the user when advisory-changes "look bad"
* the heuristics for the above are "best efforts"
* but failure fails the entire sync
### Advisory Parts
* id
* text
* references
* list of BZs/CVEs/etc
* package-list(s)
* packages changed for this advisory
* EPEL changes this ALL THE TIME
* version
* if int or semver, can be compared for "newer"
* highly unreliable
* sometimes None
* sometimes Arbitrary String
* often does not change in the face of updated advisory
* issue_date
* timestamp (or datetime) of when the advisory was released into the repo
* unreliable, sometimes None, sometimes changes
* when present, can be before, same, or **after** update_date
* update_date
* timestamp (or datetime) of when the advisory was *changed*
* unreliable, sometimes None
* digest
* checksum of all of the above, to uniquely-identify advisory-object
### What does "newer" mean (currently)
* version exists and "can be compared" - larger-int/semver wins
* "can be compared" - vers are same, or int, or semver-int-str (e.g., 1.2.3)
* in all other cases, choose first-vers-compared
* usually the vers in previous-repo-version
* IF NO VERSION - update_date exists, can be compared - newer date wins
* "can be compared" == "can be handed to parse_datetime() or datetime.fromtimestamp()"
* if it can't be parsed, same as None
* issued_date CURRENTLY IGNORED
## Current State
* attempt to have one instance of a given advisory-id per repo-version
* handled at finalize_version()
* doesn't know you're in mirror-mode
* finalize_new_version() doesn't know its calling-context
* repo.last_sync_details is only set when you *sync* - so a mirror-sync to create /versions/5/ followed by a copy() to create vresions/6/ leaves /6/ thinking it was a mirror-sync
* overloading last_sync_details to say "resulted from a copy/upload" breaks the use of last_sync_details
* NOT knowing something happened after the "last sync", **also** breaks last_sync_details' purpose
* ~~PROPOSAL: add a "last_operation" to last_sync_details?~~
* sync/copy involves pulp_rpm code and can be modified
* upload/add-or-remove happens in pulpcore, alas
* **Ignore this proposal** - being able to rely on it requires some architectural/workflow changes in pulpcore, needs a lot of thought/care to do correctly
## Proposal
~~* recognize mirror-mode-sync, take Whatever Is Incoming
* knowing "what happened" at finalize_version() is Problematic
* last_sync_details tells us last-sync-policy - but that may **not** be why we're creating a new version "now"~~
* ~~in all not-mirror-sync,~~ continue driving for There Can Be Only One
* dups in incoming - **merge them**
* dups in prev - merge them, compare result to incoming
* Implication:
* copy/modify-content/upload cases **will** result in single advisory that may NOT be the uploaded/copied one(s)
## Possible Scenarios
### ~~Mirror_complete, mirror_content_only~~
* ~~Always take whatever is incoming, no matter what~~
* WE DO NOT DO THIS CURRENTLY!
### ~~additive/copy~~
#### No overlap between incoming and previous IDs, no dups
* No problem!
#### No overlap between incoming and previous IDs, duplicate IDs incoming
* CURRENT: FAIL
* Proposal: **merge**
#### Overlap, one incoming, one previous
* CURRENT: merge
* Proposal: merge
#### Overlap, one incoming, multiple previous
* CURRENT: take incoming and ignore previous one(s)
* Proposal: um. OK?
* Proposal: merge previous, continue to "one incoming, one previous" above
#### Overlap, multiple incoming, multiple previous
* CURRENT: FAIL due to dup-in-incoming
* Proposal: **merge** incoming, continue to "one incoming, multiple previous"