New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for suse errata #1088
Conversation
4842ce9
to
1bd728d
Compare
| @@ -1215,7 +1223,7 @@ def update_needed(self, other): | |||
| format. | |||
| """ | |||
| if other.updated == "": | |||
| return False | |||
| return other.version > self.version | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible that there is no version in the erratum so one of the operands (or both) canl be None?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm I had assumed version was required since it was neither marked as optional, nor commented on here: https://github.com/openSUSE/libzypp/blob/master/zypp/parser/yum/schema/updateinfo.rnc#L11
But I guess I shouldn't assume anything when it comes to errata...
| @@ -1226,6 +1234,10 @@ def update_needed(self, other): | |||
| existing_updated_dt = util.errata_format_to_datetime(self_updated_field, | |||
| msg=existing_err_msg) | |||
| new_updated_dt = util.errata_format_to_datetime(other.updated, msg=other_err_msg) | |||
|
|
|||
| if new_updated_dt == existing_updated_dt: | |||
| return other.version > self.version | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same concern as above. Is it possible that operand(s) can have None value?
| @@ -62,7 +66,10 @@ def process_package_element(element): | |||
| for package in collection['packages']: | |||
| if package.get('reboot_suggested') is not None: | |||
| package_info['reboot_suggested'] = True | |||
| break | |||
| if package.get('relogin_suggested') is not None: | |||
| package_info['relogin_suggested'] = True | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is here an assumption that if tag is present in the package description then it always has a True value? Is it intentional? Can tag be present but has a False value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assumed this worked in the same way as reboot_suggested, but it's a good idea to revise this to work with both True and False possible values
| @@ -122,6 +122,12 @@ def add_unit_metadata(self, item, filtered_pkglist): | |||
| if erratum_unit.reboot_suggested: | |||
| self.xml_generator.completeElement('reboot_suggested', {}, 'True') | |||
|
|
|||
| if erratum_unit.relogin_suggested: | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This adds relogin_suggested to the top level of erratum xml. As per SUSE docs, it's only inside of package.
reboot_suggested is added both to the top level and inside the package tag because of how certain versions of yum handles that, iirc. So I suggest to comply with SUSE docs for its tags.
| erratum_collection = get_collection('units_erratum') | ||
|
|
||
| for errata in erratum_collection.find({}): | ||
| erratum_collection.update({'_id': errata['_id']}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For migration to be idempotent, I suggest to update only those which don't have new fields at all.
|
|
||
| erratum_collection = get_collection('units_erratum') | ||
|
|
||
| for errata in erratum_collection.find({}): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the only field you need is _id, I suggest to limit returned fields to that.
It's also usually not a bad idea to set some batch_size to the cursor not being timed out in case of slowness with DB writes.
See example here
|
|
||
| erratum_collection = get_collection('units_erratum') | ||
|
|
||
| for errata in erratum_collection.find({}): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For users it's more clear what's happening when they see the progress of the migration. Consider adding progress like here
dcfec49
to
82e7b94
Compare
| @@ -1226,6 +1242,11 @@ def update_needed(self, other): | |||
| existing_updated_dt = util.errata_format_to_datetime(self_updated_field, | |||
| msg=existing_err_msg) | |||
| new_updated_dt = util.errata_format_to_datetime(other.updated, msg=other_err_msg) | |||
|
|
|||
| # if updated time are equivalent and version exists on both erratum, then check version | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just because it's not easy to keep comments up to date, I suggest to remove this one. The docstring to the method explains logic well and variable names are self-descriptive enough, imo. But it's entirely up to you.
| @@ -10,3 +10,8 @@ New Features | |||
|
|
|||
| * A new pulp-manifest tool that can be used to create PULP_MANIFEST for a | |||
| directory that the user plans to use the iso importer with. | |||
|
|
|||
| * Add support for SUSE Errata format. This includes the addition of two new | |||
| fields on the Erratum mode: `relogin_suggested` and `restart_suggested`. | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/mode/model/
| fields | ||
|
|
||
| Note: SUSE errata lacks the updated field, and rely only on version to determine if it | ||
| needs an update. Redhat errata only increments version when text in the errata changes; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe s/Redhat errata/dnf/yum errata/ ?
or s/Redhat errata/Fedora/RHEL errata/ ?
| @@ -62,13 +64,17 @@ def process_package_element(element): | |||
| for package in collection['packages']: | |||
| if package.get('reboot_suggested') is not None: | |||
| package_info['reboot_suggested'] = True | |||
| break | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is it needed to remove this break and inspect all the packages in a collection for reboot_suggested?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah my bad, this was when I was checking restart_suggested and relogin_suggested in the loop too, I'll put it back
| @@ -173,6 +173,11 @@ def add_unit_metadata(self, item, filtered_pkglist): | |||
|
|
|||
| if package.get('reboot_suggested'): | |||
| self.xml_generator.completeElement('reboot_suggested', {}, 'True') | |||
| if package.get('relogin_suggested'): | |||
| self.xml_generator.completeElement('relogin_suggested', {}, 'True') | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on this, I guess relogin/restart_suggested can be either True or 1 when enabled.
If it's so, then I think we should preserve the original value, if it was 1, let's generate 1 as well.
But I think here it always will be True. Am I missing something?
| total_erratum_units = erratum_collection.count( | ||
| {'relogin_suggested': {'$exists': False}, 'restart_suggested': {'$exists': False}}) | ||
|
|
||
| with utils.MigrationProgressLog('Erratum', total_erratum_units) as migration_log: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure why progress shows N out of N units, when migration_log.progress() is called 2N times. I guess it's a bug in progress tooling.
I get that we need two loops to handle the case when migration was interrupted but I guess then we need 2 separate progress logs as well... and the total number of units can potentially be different in such case.
Maybe something like this:
fields_to_add = ['relogin_suggested', 'restart_suggested']
for field in fields_to_add:
total_erratum_units = erratum_collection.count(
{field: {'$exists': False}})
with utils.MigrationProgressLog('Erratum (%s field)' % field, total_erratum_units) as migration_log:
for errata in erratum_collection.find(
{field: {'$exists': False}})...
...
Thoughts?
| } | ||
|
|
||
| @mock.patch.object(migration, 'get_collection') | ||
| def test_calls_correct_functions(self, mock_get_collection): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you also add tests for re-run cases?
Both fields are already there, so no db update calls
One field is there and it's not changed after migration, just the missing one is added.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@goosemania I think it's hard making a unit test for "One field is there and it's not changed after migration, just the missing one is added." Since I'm setting mock_get_collection.return_value.find.return_value.batch_size.return_value to test. Do you have any suggestions for this?
|
@werwty , one more thing. I tested this PR with the repo mentioned in the redmine issue. And it turned out that in the remote repo there are 23 restart_suggested tags and in repo published by Pulp, only 14.
I didn't check the relogin_suggested tag. Can you take a look at it and figure out where the problem is? |
|
@goosemania When errata is published would you expect pulp to publish only the |
|
@werwty , here, where we create a list of packages in a repo we look at RPMs only. I guess no one thought about SRPMs. Good find! |
daf6a11
to
ac0714d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot, @werwty ! 🎆 🎉 🐙
Metadata sync currently works with query_auth_token. Removing TYPE_ID_ERRATA from QUERY_AUTH_TOKEN_UNSUPPORTED allows pulp to sync updateinfo.xml from SLES, and generate errata content. Add relogin_suggested, restart_suggested to errata model since these fields are available on SUSE metadata. Add migrations to create relogin_suggested and restart_suggested fields to pulp's errata models in database fixes #3377 https://pulp.plan.io/issues/3377
Metadata sync currently works with
query_auth_token. RemovingTYPE_ID_ERRATAfromQUERY_AUTH_TOKEN_UNSUPPORTEDallows pulp to syncupdateinfo.xmlfrom SLES, and generate errata content.Add relogin_suggested, restart_suggested to errata model since these
fields are available on SUSE metadata.
Add migrations to create relogin_suggested and restart_suggested fields
to pulp's errata models in database
fixes #3377
https://pulp.plan.io/issues/3377