Skip to content
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

Merged
merged 1 commit into from Mar 12, 2018
Merged

Add support for suse errata #1088

merged 1 commit into from Mar 12, 2018

Conversation

werwty
Copy link
Contributor

@werwty werwty commented Feb 27, 2018

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

@werwty werwty force-pushed the suse branch 5 times, most recently from 4842ce9 to 1bd728d Compare March 7, 2018 19:13
@werwty werwty changed the title Allow errata to be synced with query_auth_token. Add support for suse errata Mar 8, 2018
@@ -1215,7 +1223,7 @@ def update_needed(self, other):
format.
"""
if other.updated == "":
return False
return other.version > self.version
Copy link
Member

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?

Copy link
Contributor Author

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
Copy link
Member

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
Copy link
Member

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?

Copy link
Contributor Author

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:
Copy link
Member

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']},
Copy link
Member

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({}):
Copy link
Member

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({}):
Copy link
Member

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

@werwty werwty force-pushed the suse branch 9 times, most recently from dcfec49 to 82e7b94 Compare March 8, 2018 21:52
@@ -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
Copy link
Member

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`.
Copy link
Member

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;
Copy link
Member

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
Copy link
Member

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?

Copy link
Contributor Author

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')
Copy link
Member

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:
Copy link
Member

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):
Copy link
Member

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.

Copy link
Contributor Author

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?

@goosemania
Copy link
Member

goosemania commented Mar 12, 2018

@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.
It can be for 2 reasons I think:

  1. Not all packages which contain restart_suggested are present in the repository and thus Pulp excludes them from the list of packages in errata. This case is fine and we can ignore the difference.
  2. Pulp generates incorrect errata with regards to restart_suggested tag.

I didn't check the relogin_suggested tag.

Can you take a look at it and figure out where the problem is?

@werwty
Copy link
Contributor Author

werwty commented Mar 12, 2018

@goosemania When errata is published would you expect pulp to publish only the arch="x86_64" packages? As far as I can see Pulp is not publishing the arch="src" packages from the SUSE errata

@goosemania
Copy link
Member

@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!

@werwty werwty force-pushed the suse branch 2 times, most recently from daf6a11 to ac0714d Compare March 12, 2018 19:35
Copy link
Member

@goosemania goosemania left a 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants