-
Notifications
You must be signed in to change notification settings - Fork 197
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
Make the repo sanity checks much more strict #2373
Conversation
32df816
to
a580b7b
Compare
a580b7b
to
6415dc2
Compare
6415dc2
to
cc0e0d1
Compare
cc0e0d1
to
552c938
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.
We should document the new dependencies on hawkey and libcomps in the release notes and requirements.txt.
bodhi/server/util.py
Outdated
import libravatar | ||
import librepo | ||
import markdown | ||
import requests | ||
import rpm | ||
import shutil |
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 PEP-8, this import should be included with the first group of imports, since it's part of the Python stdlib.
""" | ||
Inject a file into the repodata with the help of createrepo_c. | ||
|
||
Args: |
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.
Let's also document the comp_type
argument here.
bodhi/server/util.py
Outdated
""" | ||
Generate package metadata for a given directory. | ||
|
||
If the metadata doesn't exist, then create it. | ||
|
||
Args: | ||
path (basestring): The directory to generate metadata for. | ||
""" | ||
updateinfo (basestring or None or False): The updateinfo to insert instead of example. | ||
No updateinfo is inserted if False is passed. |
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.
It would be good to document the subtle difference between None
and False
here. Also, technically False
isn't a type - the ()'s should document types that are accepted, so we should probably put bool
there instead of False
. It would also be good to document that passing True
causes undefined behavior.
bodhi/server/util.py
Outdated
comps (basestring or None): The comps to insert instead of example. | ||
""" | ||
compsfile = '''<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE comps PUBLIC "-//Red Hat, Inc.//DTD Comps info//EN" "comps.dtd"> |
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 betting the answer is no... but is there a URL to this dtd? Do we have a copy of it anywhere to reference?
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.
Yes, but not an official one that the libraries will probably accept: https://github.com/rpm-software-management/libcomps/blob/master/libcomps/tests/comps.dtd
if not comps: | ||
comps = os.path.join(path, 'comps.xml') | ||
with open(comps, 'w') as f: | ||
f.write(compsfile) |
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 this for unit tests? If so, I would prefer we use mock to insert it rather than include this in the production code.
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.
The entire function mkmetadatadir
is only ever used in the tests.....
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, in that case can we move it into the tests folder somewhere? Perhaps bodhi/tests/server/test_util.py
?
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.
We talked about this on IRC - for now let's just leave it here and I'll move it in another PR separately.
@@ -264,7 +335,7 @@ def sanity_check_repodata(myurl): | |||
Args: | |||
myurl (basestring): A path to a repodata directory. | |||
Raises: | |||
bodhi.server.exceptions.RepodataException: If the repodata is not valid or does not exist. | |||
Exception: If the repodata is not valid or does not exist. |
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.
It looks like the code still raises RepodataException
- should we change this doc back?
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.
Well, I've seen all kinds of methods of hawkey and librepo fail due to... weird reasons unrelated to the actual repodata in the other functions.
686e1ca
to
ef83dc2
Compare
devel/ci/rawhide-packages
Outdated
python3-pyramid-fas-openid | ||
python3-pyramid-fas-openid \ | ||
python2-hawkey \ | ||
python2-libcomps |
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 have a feeling the Python 3 versions of these packages are getting pulled in via requirements.txt
instead of via RPM packages. We should probably add those to devel/bodhi/devel/ci/rpm-packages
.
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.
They are in the base system as they're used by DNF...
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 cool
ef83dc2
to
377d1dc
Compare
requirements.txt
Outdated
@@ -24,6 +24,8 @@ pyramid_mako | |||
pyramid_tm | |||
python-bugzilla | |||
python-fedora | |||
python-hawkey |
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.
It looks like hawkey is not available under PyPI (or at least, not under this name). This is OK, as there are other Bodhi dependencies that are also not on PyPI (like Koji), but it does cause the pip container to fail to build:
pip Collecting python-hawkey (from -r /bodhi/requirements.txt (line 27))
pip �[91m Could not find a version that satisfies the requirement python-hawkey (from -r /bodhi/requirements.txt (line 27)) (from versions: )
pip �[0m�[91mNo matching distribution found for python-hawkey (from -r /bodhi/requirements.txt (line 27))
To fix this, you can add it to devel/ci/pip-packages
so that it gets installed via RPM for that container.
377d1dc
to
f02d13f
Compare
requirements.txt
Outdated
@@ -24,6 +24,8 @@ pyramid_mako | |||
pyramid_tm | |||
python-bugzilla | |||
python-fedora | |||
python-hawkey |
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.
There is something called hawkey, but it has no description so I have no idea if it's the same one:
https://pypi.org/project/hawkey/
Anyways, CI is still failing due to hawkey:
pip Collecting python-hawkey (from -r /bodhi/requirements.txt (line 27))
pip �[91m Could not find a version that satisfies the requirement python-hawkey (from -r /bodhi/requirements.txt (line 27)) (from versions: )
pip �[0m�[91mNo matching distribution found for python-hawkey (from -r /bodhi/requirements.txt (line 27))
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 going to just drop hawkey from requirements.txt and document it in the release notes. Then we can get this PR moving along.
I might be able to fix this next week if you don't have time to get to it. |
f02d13f
to
585f130
Compare
Hmm, the rawhide container is busted due to GPG sigs :/ |
hk_repo.repomd_fn = repo_info['repomd'] | ||
hk_repo.updateinfo_fn = repo_info['updateinfo'] | ||
except KeyError: | ||
raise RepodataException('Required part not in repomd.xml') |
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 manually ran the CI tests on my laptop, and they failed due to missing coverage on this exception handler.
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 have a test to address this now. I'll push it up shortly:
diff --git a/bodhi/tests/server/test_util.py b/bodhi/tests/server/test_util.py
index 206ec88f..d916816b 100644
--- a/bodhi/tests/server/test_util.py
+++ b/bodhi/tests/server/test_util.py
@@ -16,6 +16,7 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+from xml.etree import ElementTree
import json
import os
import shutil
@@ -577,6 +578,24 @@ class TestSanityCheckRepodata(unittest.TestCase):
self.assertEqual(str(exc.exception), 'Comps file empty')
+ def test_repomd_missing_updateinfo(self):
+ """If the updateinfo data tag is missing in repomd.xml, an Exception should be raised."""
+ util.mkmetadatadir(self.tempdir)
+ repomd_path = os.path.join(self.tempdir, 'repodata', 'repomd.xml')
+ repomd = ElementTree.parse(repomd_path)
+ ElementTree.register_namespace('', 'http://linux.duke.edu/metadata/repo')
+ root = repomd.getroot()
+ # Find the <data type="updateinfo"> tag and delete it
+ for data in root.findall('{http://linux.duke.edu/metadata/repo}data'):
+ if data.attrib['type'] == 'updateinfo':
+ root.remove(data)
+ repomd.write(repomd_path, encoding='UTF-8', xml_declaration=True)
+
+ with self.assertRaises(util.RepodataException) as exc:
+ util.sanity_check_repodata(self.tempdir)
+
+ self.assertEqual(str(exc.exception), 'Required part not in repomd.xml')
+
class TestType2Icon(unittest.TestCase):
"""Test the type2icon() function."""
Also, in order to get the tests to run, I applied this patch:
I will push that up to your branch now. |
585f130
to
41aa2ed
Compare
This makes us use librepo/hawkey to verify that a repo can be correctly read and used by DNF, which should prevent us from accepting a repo if DNF will then crash on using it. Note: per the hawkey docs, it's obsoleted, and one is supposed to use libhif, but the libhif (redirected to libdnf) repo says it is being "reworked and is unstable". From my tests, it seems that hawkey calls libdnf underwater, so I think that this is reasonable to do for now. Signed-off-by: Patrick Uiterwijk <[email protected]>
41aa2ed
to
c3f09e5
Compare
This patch is planned to be included in the upcoming 3.10.0 release: #2556. |
This patch has been deployed to Fedora's staging Bodhi instance: |
This makes us use librepo/hawkey to verify that a repo can be correctly read and used
by DNF, which should prevent us from accepting a repo if DNF will then crash on using
it.
Note: per the hawkey docs, it's obsoleted, and one is supposed to use libhif,
but the libhif (redirected to libdnf) repo says it is being "reworked and is unstable".
From my tests, it seems that hawkey calls libdnf underwater, so I think that this
is reasonable to do for now.
Signed-off-by: Patrick Uiterwijk [email protected]