Skip to content
This repository has been archived by the owner on Oct 13, 2023. It is now read-only.

[ART-4558] Use repoquery to detect non-latest rpms #764

Merged
merged 1 commit into from
May 19, 2023

Conversation

vfreex
Copy link
Contributor

@vfreex vfreex commented Apr 28, 2023

Currently we detect outdated rpms in images and RHCOS by comparing the NVRs of the installed rpms to the NVRs of the rpms in our rhaos-x.y-rhel-z-candidate Brew tag.

The current approach has 2 issues. See ART-4558 and ART-3965.

With this new approach, repoquery command will be used to query available RPMs in the configured build repos instead of the candidate Brew tag. This will provide more accurate detection and also be able to detect rpms that are not in rhaos repos (e.g. RHEL repos).

Note this PR only covers the gen-payload change. A change for scan-sources will be another PR.

@openshift-bot
Copy link

Build #1

GLOB sdist-make: /mnt/workspace/jenkins/working/art-tools_doozer_PR-764/setup.py
py38 create: /mnt/workspace/jenkins/working/art-tools_doozer_PR-764/.tox/py38
py38 installdeps: -rrequirements-dev.txt, -rrequirements.txt
py38 inst: /mnt/workspace/jenkins/working/art-tools_doozer_PR-764/.tox/.tmp/package/1/rh-doozer-2.0.15.dev318+gc2bc6ec.zip
py38 installed: aiofiles==23.1.0,aiohttp==3.8.4,aiosignal==1.3.1,astroid==2.15.4,async-timeout==4.0.2,attrs==23.1.0,autopep8==2.0.2,bashlex==0.18,bcrypt==4.0.1,cachetools==5.3.0,certifi==2022.12.7,cffi==1.15.1,chardet==5.1.0,charset-normalizer==3.1.0,click==8.1.3,colorama==0.4.6,coverage==7.2.4,cryptography==40.0.2,decorator==5.1.1,defusedxml==0.7.1,Deprecated==1.2.13,dill==0.3.6,distlib==0.3.6,dockerfile-parse==2.0.0,exceptiongroup==1.1.1,fastcore==1.5.29,filelock==3.12.0,flake8==6.0.0,flexmock==0.11.3,frozenlist==1.3.3,future==0.18.3,ghapi==1.0.3,gssapi==1.8.2,idna==3.4,iniconfig==2.0.0,isort==5.12.0,jira==3.4.1,koji==1.32.1,krb5==0.5.0,lazy-object-proxy==1.9.0,mccabe==0.7.0,multidict==6.0.4,mysql-connector-python==8.0.33,oauthlib==3.2.2,openshift-client==1.0.18,packaging==23.1,paramiko==3.1.0,platformdirs==3.5.0,pluggy==1.0.0,protobuf==3.20.3,pycodestyle==2.10.0,pycparser==2.21,pyflakes==3.0.1,pygit2==1.10.1,PyGithub==1.58.1,PyJWT==2.6.0,pylint==2.17.3,PyNaCl==1.5.0,pyproject-api==1.5.1,pyspnego==0.8.0,pytest==7.3.1,python-dateutil==2.8.2,PyYAML==6.0,requests==2.29.0,requests-gssapi==1.2.3,requests-kerberos==0.14.0,requests-oauthlib==1.3.1,requests-toolbelt==0.10.1,rh-doozer @ file:///mnt/workspace/jenkins/working/art-tools_doozer_PR-764/.tox/.tmp/package/1/rh-doozer-2.0.15.dev318%2Bgc2bc6ec.zip,semver==3.0.0,setuptools-scm==7.1.0,six==1.16.0,tenacity==8.2.2,tomli==2.0.1,tomlkit==0.11.8,tox==4.5.1,typing==3.7.4.3,typing-extensions==4.5.0,urllib3==1.26.15,virtualenv==20.23.0,wrapt==1.15.0,yarl==1.9.2
py38 run-test-pre: PYTHONHASHSEED='1092728384'
py38 run-test: commands[0] | coverage run --branch --source doozerlib -m unittest discover -t . -s tests/
............................................................................................................................................s.s....................................s.s...s.s.s..s.s.s.............................................................................
----------------------------------------------------------------------
Ran 264 tests in 2.537s

OK (skipped=10)
py38 run-test: commands[1] | flake8
py38 run-test: commands[2] | coverage report
Name                                          Stmts   Miss Branch BrPart  Cover
-------------------------------------------------------------------------------
doozerlib/__init__.py                            12      7      2      1    43%
doozerlib/_version.py                             2      2      0      0     0%
doozerlib/assembly.py                           164     26     91     11    80%
doozerlib/assembly_inspector.py                 216    156    124      9    24%
doozerlib/assertion.py                           13      0      6      0   100%
doozerlib/brew.py                               366    206    152      4    40%
doozerlib/build_status_detector.py               85     10     54      3    86%
doozerlib/cli/__init__.py                       122     64     28      0    39%
doozerlib/cli/__main__.py                      1133   1133    452      0     0%
doozerlib/cli/cli_opts.py                        20      3      8      0    89%
doozerlib/cli/config_plashet.py                 535    535    246      0     0%
doozerlib/cli/detect_embargo.py                 167     35     70      8    75%
doozerlib/cli/get_nightlies.py                  230     59    127      3    71%
doozerlib/cli/images_health.py                   82     30     26      2    59%
doozerlib/cli/images_streams.py                 687    687    296      0     0%
doozerlib/cli/inspect_stream.py                  66     66     28      0     0%
doozerlib/cli/release_calc_upgrade_tests.py      24     24      6      0     0%
doozerlib/cli/release_gen_assembly.py           277    146    118      3    42%
doozerlib/cli/release_gen_payload.py            703    260    300     20    58%
doozerlib/cli/rpms_build.py                     165     59     58      8    57%
doozerlib/cli/scan_sources.py                   182    141    100      2    17%
doozerlib/comment_on_pr.py                       46      0      8      0   100%
doozerlib/config.py                              97     97     44      0     0%
doozerlib/constants.py                           11      0      0      0   100%
doozerlib/coverity.py                           255    225     82      0     9%
doozerlib/dblib.py                              263    160     68      4    35%
doozerlib/distgit.py                           1552    999    748     40    33%
doozerlib/dotconfig.py                           54     43     31      0    13%
doozerlib/exceptions.py                           2      0      0      0   100%
doozerlib/exectools.py                          197    105     76     10    43%
doozerlib/gitdata.py                            171    137     76      0    14%
doozerlib/image.py                              530    355    230      6    27%
doozerlib/logutil.py                              9      0      2      1    91%
doozerlib/metadata.py                           432    151    184     30    61%
doozerlib/model.py                              113     21     36      2    82%
doozerlib/olm/__init__.py                         0      0      0      0   100%
doozerlib/olm/bundle.py                         315    230     72      0    22%
doozerlib/osbs2_builder.py                      119     30     44     19    67%
doozerlib/plashet.py                            134      9     90     15    89%
doozerlib/pushd.py                               22      0      2      0   100%
doozerlib/release_schedule.py                    28     17      8      0    31%
doozerlib/repos.py                              243    132    121     17    41%
doozerlib/rhcos.py                              231     55     84     12    71%
doozerlib/rpm_builder.py                        225     28    119     31    82%
doozerlib/rpm_utils.py                          134     33     90     11    74%
doozerlib/rpmcfg.py                             151     61     64      8    55%
doozerlib/runtime.py                            950    692    376      8    21%
doozerlib/source_modifications.py               116     33     26      4    68%
doozerlib/state.py                               23     12      8      0    35%
doozerlib/util.py                               452    217    180     13    48%
-------------------------------------------------------------------------------
TOTAL                                         12126   7491   5161    305    35%
___________________________________ summary ____________________________________
  py38: commands succeeded
  congratulations :)

@vfreex vfreex requested a review from joepvd April 28, 2023 13:09
@openshift-bot
Copy link

Build #2

GLOB sdist-make: /mnt/workspace/jenkins/working/art-tools_doozer_PR-764/setup.py
py38 recreate: /mnt/workspace/jenkins/working/art-tools_doozer_PR-764/.tox/py38
py38 installdeps: -rrequirements-dev.txt, -rrequirements.txt
py38 inst: /mnt/workspace/jenkins/working/art-tools_doozer_PR-764/.tox/.tmp/package/1/rh-doozer-2.0.15.dev319+gcea8fe1.zip
py38 installed: aiofiles==23.1.0,aiohttp==3.8.4,aiosignal==1.3.1,astroid==2.15.4,async-timeout==4.0.2,attrs==23.1.0,autopep8==2.0.2,bashlex==0.18,bcrypt==4.0.1,cachetools==5.3.0,certifi==2022.12.7,cffi==1.15.1,chardet==5.1.0,charset-normalizer==3.1.0,click==8.1.3,colorama==0.4.6,coverage==7.2.4,cryptography==40.0.2,decorator==5.1.1,defusedxml==0.7.1,Deprecated==1.2.13,dill==0.3.6,distlib==0.3.6,dockerfile-parse==2.0.0,exceptiongroup==1.1.1,fastcore==1.5.29,filelock==3.12.0,flake8==6.0.0,flexmock==0.11.3,frozenlist==1.3.3,future==0.18.3,ghapi==1.0.3,gssapi==1.8.2,idna==3.4,iniconfig==2.0.0,isort==5.12.0,jira==3.4.1,koji==1.32.1,krb5==0.5.0,lazy-object-proxy==1.9.0,mccabe==0.7.0,multidict==6.0.4,mysql-connector-python==8.0.33,oauthlib==3.2.2,openshift-client==1.0.18,packaging==23.1,paramiko==3.1.0,platformdirs==3.5.0,pluggy==1.0.0,protobuf==3.20.3,pycodestyle==2.10.0,pycparser==2.21,pyflakes==3.0.1,pygit2==1.10.1,PyGithub==1.58.1,PyJWT==2.6.0,pylint==2.17.3,PyNaCl==1.5.0,pyproject-api==1.5.1,pyspnego==0.8.0,pytest==7.3.1,python-dateutil==2.8.2,PyYAML==6.0,requests==2.29.0,requests-gssapi==1.2.3,requests-kerberos==0.14.0,requests-oauthlib==1.3.1,requests-toolbelt==0.10.1,rh-doozer @ file:///mnt/workspace/jenkins/working/art-tools_doozer_PR-764/.tox/.tmp/package/1/rh-doozer-2.0.15.dev319%2Bgcea8fe1.zip,semver==3.0.0,setuptools-scm==7.1.0,six==1.16.0,tenacity==8.2.2,tomli==2.0.1,tomlkit==0.11.8,tox==4.5.1,typing==3.7.4.3,typing-extensions==4.5.0,urllib3==1.26.15,virtualenv==20.23.0,wrapt==1.15.0,yarl==1.9.2
py38 run-test-pre: PYTHONHASHSEED='3620572957'
py38 run-test: commands[0] | coverage run --branch --source doozerlib -m unittest discover -t . -s tests/
............................................................................................................................................s.s....................................s.s...s.s.s..s.s.s.............................................................................
----------------------------------------------------------------------
Ran 264 tests in 2.277s

OK (skipped=10)
py38 run-test: commands[1] | flake8
py38 run-test: commands[2] | coverage report
Name                                          Stmts   Miss Branch BrPart  Cover
-------------------------------------------------------------------------------
doozerlib/__init__.py                            12      7      2      1    43%
doozerlib/_version.py                             2      2      0      0     0%
doozerlib/assembly.py                           164     26     91     11    80%
doozerlib/assembly_inspector.py                 216    156    124      9    24%
doozerlib/assertion.py                           13      0      6      0   100%
doozerlib/brew.py                               366    206    152      4    40%
doozerlib/build_status_detector.py               85     10     54      3    86%
doozerlib/cli/__init__.py                       122     64     28      0    39%
doozerlib/cli/__main__.py                      1136   1136    454      0     0%
doozerlib/cli/cli_opts.py                        20      3      8      0    89%
doozerlib/cli/config_plashet.py                 535    535    246      0     0%
doozerlib/cli/detect_embargo.py                 167     35     70      8    75%
doozerlib/cli/get_nightlies.py                  230     59    127      3    71%
doozerlib/cli/images_health.py                   82     30     26      2    59%
doozerlib/cli/images_streams.py                 687    687    296      0     0%
doozerlib/cli/inspect_stream.py                  66     66     28      0     0%
doozerlib/cli/release_calc_upgrade_tests.py      24     24      6      0     0%
doozerlib/cli/release_gen_assembly.py           277    146    118      3    42%
doozerlib/cli/release_gen_payload.py            703    260    300     20    58%
doozerlib/cli/rpms_build.py                     165     59     58      8    57%
doozerlib/cli/scan_sources.py                   182    141    100      2    17%
doozerlib/comment_on_pr.py                       46      0      8      0   100%
doozerlib/config.py                              97     97     44      0     0%
doozerlib/constants.py                           11      0      0      0   100%
doozerlib/coverity.py                           255    225     82      0     9%
doozerlib/dblib.py                              263    160     68      4    35%
doozerlib/distgit.py                           1552    999    748     40    33%
doozerlib/dotconfig.py                           54     43     31      0    13%
doozerlib/exceptions.py                           2      0      0      0   100%
doozerlib/exectools.py                          197    105     76     10    43%
doozerlib/gitdata.py                            171    137     76      0    14%
doozerlib/image.py                              530    355    230      6    27%
doozerlib/logutil.py                              9      0      2      1    91%
doozerlib/metadata.py                           432    151    184     30    61%
doozerlib/model.py                              113     21     36      2    82%
doozerlib/olm/__init__.py                         0      0      0      0   100%
doozerlib/olm/bundle.py                         315    230     72      0    22%
doozerlib/osbs2_builder.py                      119     30     44     19    67%
doozerlib/plashet.py                            134      9     90     15    89%
doozerlib/pushd.py                               22      0      2      0   100%
doozerlib/release_schedule.py                    28     17      8      0    31%
doozerlib/repos.py                              243    132    121     17    41%
doozerlib/rhcos.py                              231     55     84     12    71%
doozerlib/rpm_builder.py                        225     28    119     31    82%
doozerlib/rpm_utils.py                          134     33     90     11    74%
doozerlib/rpmcfg.py                             151     61     64      8    55%
doozerlib/runtime.py                            950    692    376      8    21%
doozerlib/source_modifications.py               116     33     26      4    68%
doozerlib/state.py                               23     12      8      0    35%
doozerlib/util.py                               452    217    180     13    48%
-------------------------------------------------------------------------------
TOTAL                                         12129   7494   5163    305    35%
___________________________________ summary ____________________________________
  py38: commands succeeded
  congratulations :)

@openshift-bot
Copy link

Build #3

GLOB sdist-make: /mnt/workspace/jenkins/working/art-tools_doozer_PR-764/setup.py
py38 recreate: /mnt/workspace/jenkins/working/art-tools_doozer_PR-764/.tox/py38
py38 installdeps: -rrequirements-dev.txt, -rrequirements.txt
py38 inst: /mnt/workspace/jenkins/working/art-tools_doozer_PR-764/.tox/.tmp/package/1/rh-doozer-2.0.15.dev320+g45134f8.zip
py38 installed: aiofiles==23.1.0,aiohttp==3.8.4,aiosignal==1.3.1,astroid==2.15.4,async-timeout==4.0.2,attrs==23.1.0,autopep8==2.0.2,bashlex==0.18,bcrypt==4.0.1,cachetools==5.3.0,certifi==2022.12.7,cffi==1.15.1,chardet==5.1.0,charset-normalizer==3.1.0,click==8.1.3,colorama==0.4.6,coverage==7.2.4,cryptography==40.0.2,decorator==5.1.1,defusedxml==0.7.1,Deprecated==1.2.13,dill==0.3.6,distlib==0.3.6,dockerfile-parse==2.0.0,exceptiongroup==1.1.1,fastcore==1.5.29,filelock==3.12.0,flake8==6.0.0,flexmock==0.11.3,frozenlist==1.3.3,future==0.18.3,ghapi==1.0.3,gssapi==1.8.2,idna==3.4,iniconfig==2.0.0,isort==5.12.0,jira==3.4.1,koji==1.32.1,krb5==0.5.0,lazy-object-proxy==1.9.0,mccabe==0.7.0,multidict==6.0.4,mysql-connector-python==8.0.33,oauthlib==3.2.2,openshift-client==1.0.18,packaging==23.1,paramiko==3.1.0,platformdirs==3.5.0,pluggy==1.0.0,protobuf==3.20.3,pycodestyle==2.10.0,pycparser==2.21,pyflakes==3.0.1,pygit2==1.10.1,PyGithub==1.58.1,PyJWT==2.6.0,pylint==2.17.3,PyNaCl==1.5.0,pyproject-api==1.5.1,pyspnego==0.8.0,pytest==7.3.1,python-dateutil==2.8.2,PyYAML==6.0,requests==2.29.0,requests-gssapi==1.2.3,requests-kerberos==0.14.0,requests-oauthlib==1.3.1,requests-toolbelt==0.10.1,rh-doozer @ file:///mnt/workspace/jenkins/working/art-tools_doozer_PR-764/.tox/.tmp/package/1/rh-doozer-2.0.15.dev320%2Bg45134f8.zip,semver==3.0.0,setuptools-scm==7.1.0,six==1.16.0,tenacity==8.2.2,tomli==2.0.1,tomlkit==0.11.8,tox==4.5.1,typing==3.7.4.3,typing-extensions==4.5.0,urllib3==1.26.15,virtualenv==20.23.0,wrapt==1.15.0,yarl==1.9.2
py38 run-test-pre: PYTHONHASHSEED='1803824676'
py38 run-test: commands[0] | coverage run --branch --source doozerlib -m unittest discover -t . -s tests/
............................................................................................................................................s.s....................................s.s...s.s.s..s.s.s.............................................................................
----------------------------------------------------------------------
Ran 264 tests in 2.526s

OK (skipped=10)
py38 run-test: commands[1] | flake8
py38 run-test: commands[2] | coverage report
Name                                          Stmts   Miss Branch BrPart  Cover
-------------------------------------------------------------------------------
doozerlib/__init__.py                            12      7      2      1    43%
doozerlib/_version.py                             2      2      0      0     0%
doozerlib/assembly.py                           164     26     91     11    80%
doozerlib/assembly_inspector.py                 216    156    124      9    24%
doozerlib/assertion.py                           13      0      6      0   100%
doozerlib/brew.py                               366    206    152      4    40%
doozerlib/build_status_detector.py               85     10     54      3    86%
doozerlib/cli/__init__.py                       122     64     28      0    39%
doozerlib/cli/__main__.py                      1136   1136    454      0     0%
doozerlib/cli/cli_opts.py                        20      3      8      0    89%
doozerlib/cli/config_plashet.py                 535    535    246      0     0%
doozerlib/cli/detect_embargo.py                 167     35     70      8    75%
doozerlib/cli/get_nightlies.py                  230     59    127      3    71%
doozerlib/cli/images_health.py                   82     30     26      2    59%
doozerlib/cli/images_streams.py                 687    687    296      0     0%
doozerlib/cli/inspect_stream.py                  66     66     28      0     0%
doozerlib/cli/release_calc_upgrade_tests.py      24     24      6      0     0%
doozerlib/cli/release_gen_assembly.py           277    146    118      3    42%
doozerlib/cli/release_gen_payload.py            703    260    300     20    58%
doozerlib/cli/rpms_build.py                     165     59     58      8    57%
doozerlib/cli/scan_sources.py                   182    141    100      2    17%
doozerlib/comment_on_pr.py                       46      0      8      0   100%
doozerlib/config.py                              97     97     44      0     0%
doozerlib/constants.py                           11      0      0      0   100%
doozerlib/coverity.py                           255    225     82      0     9%
doozerlib/dblib.py                              263    160     68      4    35%
doozerlib/distgit.py                           1552    999    748     40    33%
doozerlib/dotconfig.py                           54     43     31      0    13%
doozerlib/exceptions.py                           2      0      0      0   100%
doozerlib/exectools.py                          197    105     76     10    43%
doozerlib/gitdata.py                            171    137     76      0    14%
doozerlib/image.py                              530    355    230      6    27%
doozerlib/logutil.py                              9      0      2      1    91%
doozerlib/metadata.py                           432    151    184     30    61%
doozerlib/model.py                              113     21     36      2    82%
doozerlib/olm/__init__.py                         0      0      0      0   100%
doozerlib/olm/bundle.py                         315    230     72      0    22%
doozerlib/osbs2_builder.py                      119     30     44     19    67%
doozerlib/plashet.py                            134      9     90     15    89%
doozerlib/pushd.py                               22      0      2      0   100%
doozerlib/release_schedule.py                    28     17      8      0    31%
doozerlib/repos.py                              243    132    121     17    41%
doozerlib/rhcos.py                              231     55     84     12    71%
doozerlib/rpm_builder.py                        225     28    119     31    82%
doozerlib/rpm_utils.py                          134     33     90     11    74%
doozerlib/rpmcfg.py                             151     61     64      8    55%
doozerlib/runtime.py                            950    692    376      8    21%
doozerlib/source_modifications.py               116     33     26      4    68%
doozerlib/state.py                               23     12      8      0    35%
doozerlib/util.py                               452    217    180     13    48%
-------------------------------------------------------------------------------
TOTAL                                         12129   7494   5163    305    35%
___________________________________ summary ____________________________________
  py38: commands succeeded
  congratulations :)

@openshift-bot
Copy link

Build #4

GLOB sdist-make: /mnt/workspace/jenkins/working/art-tools_doozer_PR-764/setup.py
py38 recreate: /mnt/workspace/jenkins/working/art-tools_doozer_PR-764/.tox/py38
py38 installdeps: -rrequirements-dev.txt, -rrequirements.txt
py38 inst: /mnt/workspace/jenkins/working/art-tools_doozer_PR-764/.tox/.tmp/package/1/rh-doozer-2.0.15.dev321+g2ab93d0.zip
py38 installed: aiofiles==23.1.0,aiohttp==3.8.4,aiosignal==1.3.1,astroid==2.15.4,async-timeout==4.0.2,attrs==23.1.0,autopep8==2.0.2,bashlex==0.18,bcrypt==4.0.1,cachetools==5.3.0,certifi==2022.12.7,cffi==1.15.1,chardet==5.1.0,charset-normalizer==3.1.0,click==8.1.3,colorama==0.4.6,coverage==7.2.5,cryptography==40.0.2,decorator==5.1.1,defusedxml==0.7.1,Deprecated==1.2.13,dill==0.3.6,distlib==0.3.6,dockerfile-parse==2.0.0,exceptiongroup==1.1.1,fastcore==1.5.29,filelock==3.12.0,flake8==6.0.0,flexmock==0.11.3,frozenlist==1.3.3,future==0.18.3,ghapi==1.0.3,gssapi==1.8.2,idna==3.4,iniconfig==2.0.0,isort==5.12.0,jira==3.4.1,koji==1.32.1,krb5==0.5.0,lazy-object-proxy==1.9.0,mccabe==0.7.0,multidict==6.0.4,mysql-connector-python==8.0.33,oauthlib==3.2.2,openshift-client==1.0.18,packaging==23.1,paramiko==3.1.0,platformdirs==3.5.0,pluggy==1.0.0,protobuf==3.20.3,pycodestyle==2.10.0,pycparser==2.21,pyflakes==3.0.1,pygit2==1.10.1,PyGithub==1.58.1,PyJWT==2.6.0,pylint==2.17.3,PyNaCl==1.5.0,pyproject-api==1.5.1,pyspnego==0.9.0,pytest==7.3.1,python-dateutil==2.8.2,PyYAML==6.0,requests==2.29.0,requests-gssapi==1.2.3,requests-kerberos==0.14.0,requests-oauthlib==1.3.1,requests-toolbelt==1.0.0,rh-doozer @ file:///mnt/workspace/jenkins/working/art-tools_doozer_PR-764/.tox/.tmp/package/1/rh-doozer-2.0.15.dev321%2Bg2ab93d0.zip,semver==3.0.0,setuptools-scm==7.1.0,six==1.16.0,tenacity==8.2.2,tomli==2.0.1,tomlkit==0.11.8,tox==4.5.1,typing==3.7.4.3,typing-extensions==4.5.0,urllib3==1.26.15,virtualenv==20.23.0,wrapt==1.15.0,yarl==1.9.2
py38 run-test-pre: PYTHONHASHSEED='313267147'
py38 run-test: commands[0] | coverage run --branch --source doozerlib -m unittest discover -t . -s tests/
............................................................................................................................................s.s....................................s.s...s.s.s..s.s.s.............................................................................
----------------------------------------------------------------------
Ran 264 tests in 2.003s

OK (skipped=10)
py38 run-test: commands[1] | flake8
py38 run-test: commands[2] | coverage report
Name                                          Stmts   Miss Branch BrPart  Cover
-------------------------------------------------------------------------------
doozerlib/__init__.py                            12      7      2      1    43%
doozerlib/_version.py                             2      2      0      0     0%
doozerlib/assembly.py                           164     26     91     11    80%
doozerlib/assembly_inspector.py                 216    156    124      9    24%
doozerlib/assertion.py                           13      0      6      0   100%
doozerlib/brew.py                               366    206    152      4    40%
doozerlib/build_status_detector.py               85     10     54      3    86%
doozerlib/cli/__init__.py                       122     64     28      0    39%
doozerlib/cli/__main__.py                      1136   1136    454      0     0%
doozerlib/cli/cli_opts.py                        20      3      8      0    89%
doozerlib/cli/config_plashet.py                 535    535    246      0     0%
doozerlib/cli/detect_embargo.py                 167     35     70      8    75%
doozerlib/cli/get_nightlies.py                  230     59    127      3    71%
doozerlib/cli/images_health.py                   82     30     26      2    59%
doozerlib/cli/images_streams.py                 687    687    296      0     0%
doozerlib/cli/inspect_stream.py                  66     66     28      0     0%
doozerlib/cli/release_calc_upgrade_tests.py      24     24      6      0     0%
doozerlib/cli/release_gen_assembly.py           277    146    118      3    42%
doozerlib/cli/release_gen_payload.py            703    260    300     20    58%
doozerlib/cli/rpms_build.py                     165     59     58      8    57%
doozerlib/cli/scan_sources.py                   182    141    100      2    17%
doozerlib/comment_on_pr.py                       46      0      8      0   100%
doozerlib/config.py                              97     97     44      0     0%
doozerlib/constants.py                           11      0      0      0   100%
doozerlib/coverity.py                           255    225     82      0     9%
doozerlib/dblib.py                              263    160     68      4    35%
doozerlib/distgit.py                           1552    999    748     40    33%
doozerlib/dotconfig.py                           54     43     31      0    13%
doozerlib/exceptions.py                           2      0      0      0   100%
doozerlib/exectools.py                          197    105     76     10    43%
doozerlib/gitdata.py                            171    137     76      0    14%
doozerlib/image.py                              530    355    230      6    27%
doozerlib/logutil.py                              9      0      2      1    91%
doozerlib/metadata.py                           432    151    184     30    61%
doozerlib/model.py                              113     21     36      2    82%
doozerlib/olm/__init__.py                         0      0      0      0   100%
doozerlib/olm/bundle.py                         315    230     72      0    22%
doozerlib/osbs2_builder.py                      119     30     44     19    67%
doozerlib/plashet.py                            134      9     90     15    89%
doozerlib/pushd.py                               22      0      2      0   100%
doozerlib/release_schedule.py                    28     17      8      0    31%
doozerlib/repos.py                              243    132    121     17    41%
doozerlib/rhcos.py                              231     55     84     12    71%
doozerlib/rpm_builder.py                        225     28    119     31    82%
doozerlib/rpm_utils.py                          134     33     90     11    74%
doozerlib/rpmcfg.py                             151     61     64      8    55%
doozerlib/runtime.py                            950    692    376      8    21%
doozerlib/source_modifications.py               116     33     26      4    68%
doozerlib/state.py                               23     12      8      0    35%
doozerlib/util.py                               452    217    180     13    48%
-------------------------------------------------------------------------------
TOTAL                                         12129   7494   5163    305    35%
___________________________________ summary ____________________________________
  py38: commands succeeded
  congratulations :)

@vfreex
Copy link
Contributor Author

vfreex commented May 8, 2023

Added unit tests.

@openshift-bot
Copy link

Build #5

GLOB sdist-make: /mnt/workspace/jenkins/working/art-tools_doozer_PR-764/setup.py
py38 recreate: /mnt/workspace/jenkins/working/art-tools_doozer_PR-764/.tox/py38
py38 installdeps: -rrequirements-dev.txt, -rrequirements.txt
py38 inst: /mnt/workspace/jenkins/working/art-tools_doozer_PR-764/.tox/.tmp/package/1/rh-doozer-2.0.15.dev321+g7657a88.zip
py38 installed: aiofiles==23.1.0,aiohttp==3.8.4,aiosignal==1.3.1,astroid==2.15.4,async-timeout==4.0.2,attrs==23.1.0,autopep8==2.0.2,bashlex==0.18,bcrypt==4.0.1,cachetools==5.3.0,certifi==2023.5.7,cffi==1.15.1,chardet==5.1.0,charset-normalizer==3.1.0,click==8.1.3,colorama==0.4.6,coverage==7.2.5,cryptography==40.0.2,decorator==5.1.1,defusedxml==0.7.1,Deprecated==1.2.13,dill==0.3.6,distlib==0.3.6,dockerfile-parse==2.0.0,exceptiongroup==1.1.1,fastcore==1.5.29,filelock==3.12.0,flake8==6.0.0,flexmock==0.11.3,frozenlist==1.3.3,future==0.18.3,ghapi==1.0.3,gssapi==1.8.2,idna==3.4,iniconfig==2.0.0,isort==5.12.0,jira==3.4.1,koji==1.32.1,krb5==0.5.0,lazy-object-proxy==1.9.0,mccabe==0.7.0,multidict==6.0.4,mysql-connector-python==8.0.33,oauthlib==3.2.2,openshift-client==1.0.18,packaging==23.1,paramiko==3.1.0,platformdirs==3.5.0,pluggy==1.0.0,protobuf==3.20.3,pycodestyle==2.10.0,pycparser==2.21,pyflakes==3.0.1,pygit2==1.10.1,PyGithub==1.58.1,PyJWT==2.6.0,pylint==2.17.4,PyNaCl==1.5.0,pyproject-api==1.5.1,pyspnego==0.9.0,pytest==7.3.1,python-dateutil==2.8.2,PyYAML==6.0,requests==2.30.0,requests-gssapi==1.2.3,requests-kerberos==0.14.0,requests-oauthlib==1.3.1,requests-toolbelt==1.0.0,rh-doozer @ file:///mnt/workspace/jenkins/working/art-tools_doozer_PR-764/.tox/.tmp/package/1/rh-doozer-2.0.15.dev321%2Bg7657a88.zip,semver==3.0.0,setuptools-scm==7.1.0,six==1.16.0,tenacity==8.2.2,tomli==2.0.1,tomlkit==0.11.8,tox==4.5.1,typing==3.7.4.3,typing-extensions==4.5.0,urllib3==2.0.2,virtualenv==20.23.0,wrapt==1.15.0,yarl==1.9.2
py38 run-test-pre: PYTHONHASHSEED='4271094572'
py38 run-test: commands[0] | coverage run --branch --source doozerlib -m unittest discover -t . -s tests/
............................................................................................................................................s.s....................................s.s...s.s..s..s.s.s.................................................................................
----------------------------------------------------------------------
Ran 269 tests in 2.035s

OK (skipped=10)
py38 run-test: commands[1] | flake8
py38 run-test: commands[2] | coverage report
Name                                          Stmts   Miss Branch BrPart  Cover
-------------------------------------------------------------------------------
doozerlib/__init__.py                            12      7      2      1    43%
doozerlib/_version.py                             2      2      0      0     0%
doozerlib/assembly.py                           164     26     91     11    80%
doozerlib/assembly_inspector.py                 216    156    124      9    24%
doozerlib/assertion.py                           13      0      6      0   100%
doozerlib/brew.py                               366    206    152      4    40%
doozerlib/build_status_detector.py               85     10     54      3    86%
doozerlib/cli/__init__.py                       122     64     28      0    39%
doozerlib/cli/__main__.py                      1136   1136    454      0     0%
doozerlib/cli/cli_opts.py                        20      3      8      0    89%
doozerlib/cli/config_plashet.py                 535    535    246      0     0%
doozerlib/cli/detect_embargo.py                 167     35     70      8    75%
doozerlib/cli/get_nightlies.py                  230     59    127      3    71%
doozerlib/cli/images_health.py                   82     30     26      2    59%
doozerlib/cli/images_streams.py                 687    687    296      0     0%
doozerlib/cli/inspect_stream.py                  66     66     28      0     0%
doozerlib/cli/release_calc_upgrade_tests.py      24     24      6      0     0%
doozerlib/cli/release_gen_assembly.py           277    146    118      3    42%
doozerlib/cli/release_gen_payload.py            703    260    300     20    58%
doozerlib/cli/rpms_build.py                     165     59     58      8    57%
doozerlib/cli/scan_sources.py                   182    141    100      2    17%
doozerlib/comment_on_pr.py                       46      0      8      0   100%
doozerlib/config.py                              97     97     44      0     0%
doozerlib/constants.py                           11      0      0      0   100%
doozerlib/coverity.py                           255    225     82      0     9%
doozerlib/dblib.py                              263    160     68      4    35%
doozerlib/distgit.py                           1552    999    748     40    33%
doozerlib/dotconfig.py                           54     43     31      0    13%
doozerlib/exceptions.py                           2      0      0      0   100%
doozerlib/exectools.py                          197    105     76     10    43%
doozerlib/gitdata.py                            171    137     76      0    14%
doozerlib/image.py                              530    329    232     10    33%
doozerlib/logutil.py                              9      0      2      1    91%
doozerlib/metadata.py                           432    151    184     30    61%
doozerlib/model.py                              113     21     36      2    82%
doozerlib/olm/__init__.py                         0      0      0      0   100%
doozerlib/olm/bundle.py                         315    230     72      0    22%
doozerlib/osbs2_builder.py                      119     30     44     19    67%
doozerlib/plashet.py                            134      9     90     15    89%
doozerlib/pushd.py                               22      0      2      0   100%
doozerlib/release_schedule.py                    28     17      8      0    31%
doozerlib/repos.py                              243     92    121     17    55%
doozerlib/rhcos.py                              231     31     84     14    84%
doozerlib/rpm_builder.py                        225     28    119     31    82%
doozerlib/rpm_utils.py                          134     23     90     14    81%
doozerlib/rpmcfg.py                             151     61     64      8    55%
doozerlib/runtime.py                            950    692    376      8    21%
doozerlib/source_modifications.py               116     33     26      4    68%
doozerlib/state.py                               23     12      8      0    35%
doozerlib/util.py                               452    217    180     13    48%
-------------------------------------------------------------------------------
TOTAL                                         12129   7394   5165    314    36%
___________________________________ summary ____________________________________
  py38: commands succeeded
  congratulations :)

@openshift-bot
Copy link

Build #6

GLOB sdist-make: /mnt/workspace/jenkins/working/art-tools_doozer_PR-764/setup.py
py38 recreate: /mnt/workspace/jenkins/working/art-tools_doozer_PR-764/.tox/py38
py38 installdeps: -rrequirements-dev.txt, -rrequirements.txt
py38 inst: /mnt/workspace/jenkins/working/art-tools_doozer_PR-764/.tox/.tmp/package/1/rh-doozer-2.0.15.dev322+gfae6f11.zip
py38 installed: aiofiles==23.1.0,aiohttp==3.8.4,aiosignal==1.3.1,astroid==2.15.4,async-timeout==4.0.2,attrs==23.1.0,autopep8==2.0.2,bashlex==0.18,bcrypt==4.0.1,cachetools==5.3.0,certifi==2023.5.7,cffi==1.15.1,chardet==5.1.0,charset-normalizer==3.1.0,click==8.1.3,colorama==0.4.6,coverage==7.2.5,cryptography==40.0.2,decorator==5.1.1,defusedxml==0.7.1,Deprecated==1.2.13,dill==0.3.6,distlib==0.3.6,dockerfile-parse==2.0.0,exceptiongroup==1.1.1,fastcore==1.5.29,filelock==3.12.0,flake8==6.0.0,flexmock==0.11.3,frozenlist==1.3.3,future==0.18.3,ghapi==1.0.3,gssapi==1.8.2,idna==3.4,iniconfig==2.0.0,isort==5.12.0,jira==3.4.1,koji==1.32.1,krb5==0.5.0,lazy-object-proxy==1.9.0,mccabe==0.7.0,multidict==6.0.4,mysql-connector-python==8.0.33,oauthlib==3.2.2,openshift-client==1.0.18,packaging==23.1,paramiko==3.1.0,platformdirs==3.5.0,pluggy==1.0.0,protobuf==3.20.3,pycodestyle==2.10.0,pycparser==2.21,pyflakes==3.0.1,pygit2==1.10.1,PyGithub==1.58.1,PyJWT==2.6.0,pylint==2.17.4,PyNaCl==1.5.0,pyproject-api==1.5.1,pyspnego==0.9.0,pytest==7.3.1,python-dateutil==2.8.2,PyYAML==6.0,requests==2.30.0,requests-gssapi==1.2.3,requests-kerberos==0.14.0,requests-oauthlib==1.3.1,requests-toolbelt==1.0.0,rh-doozer @ file:///mnt/workspace/jenkins/working/art-tools_doozer_PR-764/.tox/.tmp/package/1/rh-doozer-2.0.15.dev322%2Bgfae6f11.zip,semver==3.0.0,setuptools-scm==7.1.0,six==1.16.0,tenacity==8.2.2,tomli==2.0.1,tomlkit==0.11.8,tox==4.5.1,typing==3.7.4.3,typing-extensions==4.5.0,urllib3==2.0.2,virtualenv==20.23.0,wrapt==1.15.0,yarl==1.9.2
py38 run-test-pre: PYTHONHASHSEED='1077398860'
py38 run-test: commands[0] | coverage run --branch --source doozerlib -m unittest discover -t . -s tests/
............................................................................................................................................s.s....................................s.s...s.s..s..s.s.s..................................................................................
----------------------------------------------------------------------
Ran 270 tests in 2.106s

OK (skipped=10)
py38 run-test: commands[1] | flake8
py38 run-test: commands[2] | coverage report
Name                                          Stmts   Miss Branch BrPart  Cover
-------------------------------------------------------------------------------
doozerlib/__init__.py                            12      7      2      1    43%
doozerlib/_version.py                             2      2      0      0     0%
doozerlib/assembly.py                           164     26     91     11    80%
doozerlib/assembly_inspector.py                 216    156    124      9    24%
doozerlib/assertion.py                           13      0      6      0   100%
doozerlib/brew.py                               366    206    152      4    40%
doozerlib/build_status_detector.py               85     10     54      3    86%
doozerlib/cli/__init__.py                       122     64     28      0    39%
doozerlib/cli/__main__.py                      1136   1136    454      0     0%
doozerlib/cli/cli_opts.py                        20      3      8      0    89%
doozerlib/cli/config_plashet.py                 535    535    246      0     0%
doozerlib/cli/detect_embargo.py                 167     35     70      8    75%
doozerlib/cli/get_nightlies.py                  230     59    127      3    71%
doozerlib/cli/images_health.py                   82     30     26      2    59%
doozerlib/cli/images_streams.py                 687    687    296      0     0%
doozerlib/cli/inspect_stream.py                  66     66     28      0     0%
doozerlib/cli/release_calc_upgrade_tests.py      24     24      6      0     0%
doozerlib/cli/release_gen_assembly.py           277    146    118      3    42%
doozerlib/cli/release_gen_payload.py            703    260    300     20    58%
doozerlib/cli/rpms_build.py                     165     59     58      8    57%
doozerlib/cli/scan_sources.py                   182    141    100      2    17%
doozerlib/comment_on_pr.py                       46      0      8      0   100%
doozerlib/config.py                              97     97     44      0     0%
doozerlib/constants.py                           11      0      0      0   100%
doozerlib/coverity.py                           255    225     82      0     9%
doozerlib/dblib.py                              263    160     68      4    35%
doozerlib/distgit.py                           1552    999    748     40    33%
doozerlib/dotconfig.py                           54     43     31      0    13%
doozerlib/exceptions.py                           2      0      0      0   100%
doozerlib/exectools.py                          197    105     76     10    43%
doozerlib/gitdata.py                            171    137     76      0    14%
doozerlib/image.py                              530    329    232     10    33%
doozerlib/logutil.py                              9      0      2      1    91%
doozerlib/metadata.py                           432    151    184     30    61%
doozerlib/model.py                              113     21     36      2    82%
doozerlib/olm/__init__.py                         0      0      0      0   100%
doozerlib/olm/bundle.py                         315    230     72      0    22%
doozerlib/osbs2_builder.py                      119     30     44     19    67%
doozerlib/plashet.py                            134      9     90     15    89%
doozerlib/pushd.py                               22      0      2      0   100%
doozerlib/release_schedule.py                    28     17      8      0    31%
doozerlib/repos.py                              243     92    121     17    55%
doozerlib/rhcos.py                              235     25     90     14    87%
doozerlib/rpm_builder.py                        225     28    119     31    82%
doozerlib/rpm_utils.py                          134     23     90     14    81%
doozerlib/rpmcfg.py                             151     61     64      8    55%
doozerlib/runtime.py                            950    692    376      8    21%
doozerlib/source_modifications.py               116     33     26      4    68%
doozerlib/state.py                               23     12      8      0    35%
doozerlib/util.py                               452    217    180     13    48%
-------------------------------------------------------------------------------
TOTAL                                         12133   7388   5171    314    36%
___________________________________ summary ____________________________________
  py38: commands succeeded
  congratulations :)

Copy link
Contributor

@joepvd joepvd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm

Left two comments that might need addressing.

Think it is a welcome change to get informed about non-current entries in rhcos builds that are from other repositories than our own. Even if this is an area that will see some movement 🔜

OUTDATED_RPMS_IN_STREAM_BUILD will only create an complaint in the log, and an annotation on the imageStream. The extended complaints will not interfere with release work.

"""
Associate relevant assembly issues with an RHCOS PayloadEntry.
Use assembly inspector to detect assembly issues like RPMs installed in
the PayloadEntry that are not what the assembly specifies.
"""

# record issues found in assembly list and per payload entry
self.assembly_issues.extend(assembly_inspector.check_rhcos_issues(payload_entry.rhcos_build))
rhcos_build = cast(RHCOSBuildInspector, payload_entry.rhcos_build)
self.assembly_issues.extend(assembly_inspector.check_rhcos_issues(rhcos_build))
payload_entry.issues.extend(ai for ai in self.assembly_issues if ai.component == "rhcos")

if self.runtime.assembly_type is AssemblyTypes.STREAM:
# For stream alone, we want to enforce that the very latest RPMs are installed.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not your change, but this comment is misleading. We're not enforcing this, we're emitting a warning. In before times, doozer would allow OUTDATED_RPMS_IN_STREAM_BUILD in code. Now we have a permits in stream to say we want this to not be a blocker.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

enforce -> verify

if cached_result is not None: # cache hit
return cached_result

# Cache miss. Will actually query the repo.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Think the cache miss also should be inside the lock. Otherwise, there could be multiple queries running at the same time.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Putting repoquery inside of the lock will prevent from multiple queries over different repos. There is a possibility to run multiple queries over the same repo, I think it is acceptable for now. Though there could still be a room to optimize this by using, such as, more fine grained locks, but I'd like to see how much time this will take in production.

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 added some comments here.

@openshift-bot
Copy link

Build #7

GLOB sdist-make: /mnt/workspace/jenkins/working/art-tools_doozer_PR-764/setup.py
py38 recreate: /mnt/workspace/jenkins/working/art-tools_doozer_PR-764/.tox/py38
py38 installdeps: -rrequirements-dev.txt, -rrequirements.txt
py38 inst: /mnt/workspace/jenkins/working/art-tools_doozer_PR-764/.tox/.tmp/package/1/rh-doozer-2.0.15.dev324+gf6c442e.zip
py38 installed: aiofiles==23.1.0,aiohttp==3.8.4,aiosignal==1.3.1,astroid==2.15.5,async-timeout==4.0.2,attrs==23.1.0,autopep8==2.0.2,bashlex==0.18,bcrypt==4.0.1,cachetools==5.3.0,certifi==2023.5.7,cffi==1.15.1,chardet==5.1.0,charset-normalizer==3.1.0,click==8.1.3,colorama==0.4.6,coverage==7.2.5,cryptography==40.0.2,decorator==5.1.1,defusedxml==0.7.1,Deprecated==1.2.13,dill==0.3.6,distlib==0.3.6,dockerfile-parse==2.0.0,exceptiongroup==1.1.1,fastcore==1.5.29,filelock==3.12.0,flake8==6.0.0,flexmock==0.11.3,frozenlist==1.3.3,future==0.18.3,ghapi==1.0.3,gssapi==1.8.2,idna==3.4,iniconfig==2.0.0,isort==5.12.0,jira==3.4.1,koji==1.32.1,krb5==0.5.0,lazy-object-proxy==1.9.0,mccabe==0.7.0,multidict==6.0.4,mysql-connector-python==8.0.33,oauthlib==3.2.2,openshift-client==1.0.18,packaging==23.1,paramiko==3.1.0,platformdirs==3.5.1,pluggy==1.0.0,protobuf==3.20.3,pycodestyle==2.10.0,pycparser==2.21,pyflakes==3.0.1,pygit2==1.10.1,PyGithub==1.58.2,PyJWT==2.7.0,pylint==2.17.4,PyNaCl==1.5.0,pyproject-api==1.5.1,pyspnego==0.9.0,pytest==7.3.1,python-dateutil==2.8.2,PyYAML==6.0,requests==2.30.0,requests-gssapi==1.2.3,requests-kerberos==0.14.0,requests-oauthlib==1.3.1,requests-toolbelt==1.0.0,rh-doozer @ file:///mnt/workspace/jenkins/working/art-tools_doozer_PR-764/.tox/.tmp/package/1/rh-doozer-2.0.15.dev324%2Bgf6c442e.zip,semver==3.0.0,setuptools-scm==7.1.0,six==1.16.0,tenacity==8.2.2,tomli==2.0.1,tomlkit==0.11.8,tox==4.5.1,typing==3.7.4.3,typing-extensions==4.5.0,urllib3==2.0.2,virtualenv==20.23.0,wrapt==1.15.0,yarl==1.9.2
py38 run-test-pre: PYTHONHASHSEED='2002029585'
py38 run-test: commands[0] | coverage run --branch --source doozerlib -m unittest discover -t . -s tests/
............................................................................................................................................s.s....................................s.s...s.s..s..s.s.s..................................................................................
----------------------------------------------------------------------
Ran 270 tests in 2.213s

OK (skipped=10)
py38 run-test: commands[1] | flake8
py38 run-test: commands[2] | coverage report
Name                                          Stmts   Miss Branch BrPart  Cover
-------------------------------------------------------------------------------
doozerlib/__init__.py                            12      7      2      1    43%
doozerlib/_version.py                             2      2      0      0     0%
doozerlib/assembly.py                           164     26     91     11    80%
doozerlib/assembly_inspector.py                 216    156    124      9    24%
doozerlib/assertion.py                           13      0      6      0   100%
doozerlib/brew.py                               366    206    152      4    40%
doozerlib/build_status_detector.py               85     10     54      3    86%
doozerlib/cli/__init__.py                       122     64     28      0    39%
doozerlib/cli/__main__.py                      1136   1136    454      0     0%
doozerlib/cli/cli_opts.py                        20      3      8      0    89%
doozerlib/cli/config_plashet.py                 535    535    246      0     0%
doozerlib/cli/detect_embargo.py                 167     35     70      8    75%
doozerlib/cli/get_nightlies.py                  230     59    127      3    71%
doozerlib/cli/images_health.py                   82     30     26      2    59%
doozerlib/cli/images_streams.py                 687    687    296      0     0%
doozerlib/cli/inspect_stream.py                  66     66     28      0     0%
doozerlib/cli/release_calc_upgrade_tests.py      24     24      6      0     0%
doozerlib/cli/release_gen_assembly.py           277    146    118      3    42%
doozerlib/cli/release_gen_payload.py            703    260    300     20    58%
doozerlib/cli/rpms_build.py                     165     59     58      8    57%
doozerlib/cli/scan_sources.py                   182    141    100      2    17%
doozerlib/comment_on_pr.py                       46      0      8      0   100%
doozerlib/config.py                              97     97     44      0     0%
doozerlib/constants.py                           11      0      0      0   100%
doozerlib/coverity.py                           255    225     82      0     9%
doozerlib/dblib.py                              263    160     68      4    35%
doozerlib/distgit.py                           1446    895    684     40    36%
doozerlib/dotconfig.py                           54     43     31      0    13%
doozerlib/exceptions.py                           2      0      0      0   100%
doozerlib/exectools.py                          197    105     76     10    43%
doozerlib/gitdata.py                            171    137     76      0    14%
doozerlib/image.py                              530    329    232     10    33%
doozerlib/logutil.py                              9      0      2      1    91%
doozerlib/metadata.py                           432    151    184     30    61%
doozerlib/model.py                              113     21     36      2    82%
doozerlib/olm/__init__.py                         0      0      0      0   100%
doozerlib/olm/bundle.py                         315    230     72      0    22%
doozerlib/osbs2_builder.py                      119     30     44     19    67%
doozerlib/plashet.py                            134      9     90     15    89%
doozerlib/pushd.py                               22      0      2      0   100%
doozerlib/release_schedule.py                    28     17      8      0    31%
doozerlib/repos.py                              243     92    121     17    55%
doozerlib/rhcos.py                              235     25     90     14    87%
doozerlib/rpm_builder.py                        225     28    119     31    82%
doozerlib/rpm_utils.py                          134     23     90     14    81%
doozerlib/rpmcfg.py                             151     61     64      8    55%
doozerlib/runtime.py                            950    692    376      8    21%
doozerlib/source_modifications.py               116     33     26      4    68%
doozerlib/state.py                               23     12      8      0    35%
doozerlib/util.py                               452    217    180     13    48%
-------------------------------------------------------------------------------
TOTAL                                         12027   7284   5107    314    36%
___________________________________ summary ____________________________________
  py38: commands succeeded
  congratulations :)

@openshift-bot
Copy link

Build #8

GLOB sdist-make: /mnt/workspace/jenkins/working/art-tools_doozer_PR-764/setup.py
py38 recreate: /mnt/workspace/jenkins/working/art-tools_doozer_PR-764/.tox/py38
py38 installdeps: -rrequirements-dev.txt, -rrequirements.txt
py38 inst: /mnt/workspace/jenkins/working/art-tools_doozer_PR-764/.tox/.tmp/package/1/rh-doozer-2.0.15.dev326+g9e9309b.zip
py38 installed: aiofiles==23.1.0,aiohttp==3.8.4,aiosignal==1.3.1,astroid==2.15.5,async-timeout==4.0.2,attrs==23.1.0,autopep8==2.0.2,bashlex==0.18,bcrypt==4.0.1,cachetools==5.3.0,certifi==2023.5.7,cffi==1.15.1,chardet==5.1.0,charset-normalizer==3.1.0,click==8.1.3,colorama==0.4.6,coverage==7.2.5,cryptography==40.0.2,decorator==5.1.1,defusedxml==0.7.1,Deprecated==1.2.13,dill==0.3.6,distlib==0.3.6,dockerfile-parse==2.0.0,exceptiongroup==1.1.1,fastcore==1.5.29,filelock==3.12.0,flake8==6.0.0,flexmock==0.11.3,frozenlist==1.3.3,future==0.18.3,ghapi==1.0.3,gssapi==1.8.2,idna==3.4,iniconfig==2.0.0,isort==5.12.0,jira==3.4.1,koji==1.32.1,krb5==0.5.0,lazy-object-proxy==1.9.0,mccabe==0.7.0,multidict==6.0.4,mysql-connector-python==8.0.33,oauthlib==3.2.2,openshift-client==1.0.18,packaging==23.1,paramiko==3.1.0,platformdirs==3.5.1,pluggy==1.0.0,protobuf==3.20.3,pycodestyle==2.10.0,pycparser==2.21,pyflakes==3.0.1,pygit2==1.10.1,PyGithub==1.58.2,PyJWT==2.7.0,pylint==2.17.4,PyNaCl==1.5.0,pyproject-api==1.5.1,pyspnego==0.9.0,pytest==7.3.1,python-dateutil==2.8.2,PyYAML==6.0,requests==2.30.0,requests-gssapi==1.2.3,requests-kerberos==0.14.0,requests-oauthlib==1.3.1,requests-toolbelt==1.0.0,rh-doozer @ file:///mnt/workspace/jenkins/working/art-tools_doozer_PR-764/.tox/.tmp/package/1/rh-doozer-2.0.15.dev326%2Bg9e9309b.zip,semver==3.0.0,setuptools-scm==7.1.0,six==1.16.0,tenacity==8.2.2,tomli==2.0.1,tomlkit==0.11.8,tox==4.5.1,typing==3.7.4.3,typing-extensions==4.5.0,urllib3==2.0.2,virtualenv==20.23.0,wrapt==1.15.0,yarl==1.9.2
py38 run-test-pre: PYTHONHASHSEED='4294757111'
py38 run-test: commands[0] | coverage run --branch --source doozerlib -m unittest discover -t . -s tests/
............................................................................................................................................s.s....................................s.s...s.s..s..s.s.s..................................................................................
----------------------------------------------------------------------
Ran 270 tests in 2.093s

OK (skipped=10)
py38 run-test: commands[1] | flake8
py38 run-test: commands[2] | coverage report
Name                                          Stmts   Miss Branch BrPart  Cover
-------------------------------------------------------------------------------
doozerlib/__init__.py                            12      7      2      1    43%
doozerlib/_version.py                             2      2      0      0     0%
doozerlib/assembly.py                           164     26     91     11    80%
doozerlib/assembly_inspector.py                 216    156    124      9    24%
doozerlib/assertion.py                           13      0      6      0   100%
doozerlib/brew.py                               366    206    152      4    40%
doozerlib/build_status_detector.py               85     10     54      3    86%
doozerlib/cli/__init__.py                       122     64     28      0    39%
doozerlib/cli/__main__.py                      1136   1136    454      0     0%
doozerlib/cli/cli_opts.py                        20      3      8      0    89%
doozerlib/cli/config_plashet.py                 535    535    246      0     0%
doozerlib/cli/detect_embargo.py                 167     35     70      8    75%
doozerlib/cli/get_nightlies.py                  230     59    127      3    71%
doozerlib/cli/images_health.py                   82     30     26      2    59%
doozerlib/cli/images_streams.py                 687    687    296      0     0%
doozerlib/cli/inspect_stream.py                  66     66     28      0     0%
doozerlib/cli/release_calc_upgrade_tests.py      24     24      6      0     0%
doozerlib/cli/release_gen_assembly.py           277    146    118      3    42%
doozerlib/cli/release_gen_payload.py            703    260    300     20    58%
doozerlib/cli/rpms_build.py                     165     59     58      8    57%
doozerlib/cli/scan_sources.py                   182    141    100      2    17%
doozerlib/comment_on_pr.py                       46      0      8      0   100%
doozerlib/config.py                              97     97     44      0     0%
doozerlib/constants.py                           11      0      0      0   100%
doozerlib/coverity.py                           255    225     82      0     9%
doozerlib/dblib.py                              263    160     68      4    35%
doozerlib/distgit.py                           1449    898    686     40    36%
doozerlib/dotconfig.py                           54     43     31      0    13%
doozerlib/exceptions.py                           2      0      0      0   100%
doozerlib/exectools.py                          197    105     76     10    43%
doozerlib/gitdata.py                            171    137     76      0    14%
doozerlib/image.py                              530    329    232     10    33%
doozerlib/logutil.py                              9      0      2      1    91%
doozerlib/metadata.py                           432    151    184     30    61%
doozerlib/model.py                              113     21     36      2    82%
doozerlib/olm/__init__.py                         0      0      0      0   100%
doozerlib/olm/bundle.py                         315    230     72      0    22%
doozerlib/osbs2_builder.py                      119     30     44     19    67%
doozerlib/plashet.py                            134      9     90     15    89%
doozerlib/pushd.py                               22      0      2      0   100%
doozerlib/release_schedule.py                    28     17      8      0    31%
doozerlib/repos.py                              243     92    121     17    55%
doozerlib/rhcos.py                              235     25     90     14    87%
doozerlib/rpm_builder.py                        225     28    119     31    82%
doozerlib/rpm_utils.py                          134     23     90     14    81%
doozerlib/rpmcfg.py                             151     61     64      8    55%
doozerlib/runtime.py                            950    692    376      8    21%
doozerlib/source_modifications.py               116     33     26      4    68%
doozerlib/state.py                               23     12      8      0    35%
doozerlib/util.py                               452    217    180     13    48%
-------------------------------------------------------------------------------
TOTAL                                         12030   7287   5109    314    36%
___________________________________ summary ____________________________________
  py38: commands succeeded
  congratulations :)

@openshift-bot
Copy link

Build #9

GLOB sdist-make: /mnt/workspace/jenkins/working/art-tools_doozer_PR-764/setup.py
py38 recreate: /mnt/workspace/jenkins/working/art-tools_doozer_PR-764/.tox/py38
py38 installdeps: -rrequirements-dev.txt, -rrequirements.txt
py38 inst: /mnt/workspace/jenkins/working/art-tools_doozer_PR-764/.tox/.tmp/package/1/rh-doozer-2.0.15.dev326+g7778a9b.zip
py38 installed: aiofiles==23.1.0,aiohttp==3.8.4,aiosignal==1.3.1,astroid==2.15.5,async-timeout==4.0.2,attrs==23.1.0,autopep8==2.0.2,bashlex==0.18,bcrypt==4.0.1,cachetools==5.3.0,certifi==2023.5.7,cffi==1.15.1,chardet==5.1.0,charset-normalizer==3.1.0,click==8.1.3,colorama==0.4.6,coverage==7.2.5,cryptography==40.0.2,decorator==5.1.1,defusedxml==0.7.1,Deprecated==1.2.13,dill==0.3.6,distlib==0.3.6,dockerfile-parse==2.0.0,exceptiongroup==1.1.1,fastcore==1.5.29,filelock==3.12.0,flake8==6.0.0,flexmock==0.11.3,frozenlist==1.3.3,future==0.18.3,ghapi==1.0.3,gssapi==1.8.2,idna==3.4,iniconfig==2.0.0,isort==5.12.0,jira==3.4.1,koji==1.32.1,krb5==0.5.0,lazy-object-proxy==1.9.0,mccabe==0.7.0,multidict==6.0.4,mysql-connector-python==8.0.33,oauthlib==3.2.2,openshift-client==1.0.18,packaging==23.1,paramiko==3.1.0,platformdirs==3.5.1,pluggy==1.0.0,protobuf==3.20.3,pycodestyle==2.10.0,pycparser==2.21,pyflakes==3.0.1,pygit2==1.10.1,PyGithub==1.58.2,PyJWT==2.7.0,pylint==2.17.4,PyNaCl==1.5.0,pyproject-api==1.5.1,pyspnego==0.9.0,pytest==7.3.1,python-dateutil==2.8.2,PyYAML==6.0,requests==2.30.0,requests-gssapi==1.2.3,requests-kerberos==0.14.0,requests-oauthlib==1.3.1,requests-toolbelt==1.0.0,rh-doozer @ file:///mnt/workspace/jenkins/working/art-tools_doozer_PR-764/.tox/.tmp/package/1/rh-doozer-2.0.15.dev326%2Bg7778a9b.zip,semver==3.0.0,setuptools-scm==7.1.0,six==1.16.0,tenacity==8.2.2,tomli==2.0.1,tomlkit==0.11.8,tox==4.5.1,typing==3.7.4.3,typing-extensions==4.5.0,urllib3==2.0.2,virtualenv==20.23.0,wrapt==1.15.0,yarl==1.9.2
py38 run-test-pre: PYTHONHASHSEED='107538016'
py38 run-test: commands[0] | coverage run --branch --source doozerlib -m unittest discover -t . -s tests/
..................................E..E........................................................................................................s.s....................................s.s...s.s..s..s.s.s........................................F..........................................
======================================================================
ERROR: test_detect_non_latest_rpms (tests.cli.test_gen_payload.TestGenPayloadCli)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib64/python3.8/unittest/async_case.py", line 65, in _callTestMethod
    self._callMaybeAsync(method)
  File "/usr/lib64/python3.8/unittest/async_case.py", line 88, in _callMaybeAsync
    return self._asyncioTestLoop.run_until_complete(fut)
  File "/usr/lib64/python3.8/asyncio/base_events.py", line 616, in run_until_complete
    return future.result()
  File "/usr/lib64/python3.8/unittest/async_case.py", line 102, in _asyncioLoopRunner
    ret = await awaitable
  File "/mnt/workspace/jenkins/working/art-tools_doozer_PR-764/tests/cli/test_gen_payload.py", line 191, in test_detect_non_latest_rpms
    await gpcli.detect_non_latest_rpms(ai)
  File "/mnt/workspace/jenkins/working/art-tools_doozer_PR-764/doozerlib/cli/release_gen_payload.py", line 488, in detect_non_latest_rpms
    for installed_nvr, newest_nvr, repo in non_latest_rpms:
ValueError: not enough values to unpack (expected 3, got 2)

======================================================================
ERROR: test_detect_rhcos_issues (tests.cli.test_gen_payload.TestGenPayloadCli)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib64/python3.8/unittest/async_case.py", line 65, in _callTestMethod
    self._callMaybeAsync(method)
  File "/usr/lib64/python3.8/unittest/async_case.py", line 88, in _callMaybeAsync
    return self._asyncioTestLoop.run_until_complete(fut)
  File "/usr/lib64/python3.8/asyncio/base_events.py", line 616, in run_until_complete
    return future.result()
  File "/usr/lib64/python3.8/unittest/async_case.py", line 102, in _asyncioLoopRunner
    ret = await awaitable
  File "/mnt/workspace/jenkins/working/art-tools_doozer_PR-764/tests/cli/test_gen_payload.py", line 254, in test_detect_rhcos_issues
    await gpcli.detect_rhcos_issues(rhcos_entry, ai)
  File "/mnt/workspace/jenkins/working/art-tools_doozer_PR-764/doozerlib/cli/release_gen_payload.py", line 605, in detect_rhcos_issues
    for installed_nvr, newest_nvr, repo in await rhcos_build.find_non_latest_rpms():
ValueError: not enough values to unpack (expected 3, got 2)

======================================================================
FAIL: test_find_non_latest_rpms (tests.test_rhcos.TestRhcos)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib64/python3.8/unittest/async_case.py", line 65, in _callTestMethod
    self._callMaybeAsync(method)
  File "/usr/lib64/python3.8/unittest/async_case.py", line 88, in _callMaybeAsync
    return self._asyncioTestLoop.run_until_complete(fut)
  File "/usr/lib64/python3.8/asyncio/base_events.py", line 616, in run_until_complete
    return future.result()
  File "/usr/lib64/python3.8/unittest/async_case.py", line 102, in _asyncioLoopRunner
    ret = await awaitable
  File "/usr/lib64/python3.8/unittest/mock.py", line 1342, in patched
    return await func(*newargs, **newkeywargs)
  File "/mnt/workspace/jenkins/working/art-tools_doozer_PR-764/tests/test_rhcos.py", line 268, in test_find_non_latest_rpms
    self.assertEqual(actual, [('bar-1.0.0-1.el9', 'bar-1.1.0-1.el9')])
AssertionError: Lists differ: [('bar-1.0.0-1.el9', 'bar-1.1.0-1.el9', 'rhel-8-baseos-rpms')] != [('bar-1.0.0-1.el9', 'bar-1.1.0-1.el9')]

First differing element 0:
('bar-1.0.0-1.el9', 'bar-1.1.0-1.el9', 'rhel-8-baseos-rpms')
('bar-1.0.0-1.el9', 'bar-1.1.0-1.el9')

- [('bar-1.0.0-1.el9', 'bar-1.1.0-1.el9', 'rhel-8-baseos-rpms')]
?                                       ----------------------

+ [('bar-1.0.0-1.el9', 'bar-1.1.0-1.el9')]

----------------------------------------------------------------------
Ran 270 tests in 2.087s

FAILED (failures=1, errors=2, skipped=10)
ERROR: InvocationError for command /mnt/workspace/jenkins/working/art-tools_doozer_PR-764/.tox/py38/bin/coverage run --branch --source doozerlib -m unittest discover -t . -s tests/ (exited with code 1)
___________________________________ summary ____________________________________
ERROR:   py38: commands failed

Currently we detect outdated rpms in images and RHCOS by
comparing the NVRs of the installed rpms to the NVRs of the rpms in our
`rhaos-x.y-rhel-z-candidate` Brew tag.

The current approach has 2 issues. See ART-4558 and ART-3965.

With this new approach, `repoquery` command will be used to query
available RPMs in the configured build repos instead of the candidate
Brew tag. This will provide more accurate detection and also be able to
detect rpms that are not in rhaos repos (e.g. RHEL repos).

Note this PR only covers the `gen-payload` change. A change for
`scan-sources` will be another PR.
@openshift-bot
Copy link

Build #10

GLOB sdist-make: /mnt/workspace/jenkins/working/art-tools_doozer_PR-764/setup.py
py38 recreate: /mnt/workspace/jenkins/working/art-tools_doozer_PR-764/.tox/py38
py38 installdeps: -rrequirements-dev.txt, -rrequirements.txt
py38 inst: /mnt/workspace/jenkins/working/art-tools_doozer_PR-764/.tox/.tmp/package/1/rh-doozer-2.0.15.dev326+ge973d89.zip
py38 installed: aiofiles==23.1.0,aiohttp==3.8.4,aiosignal==1.3.1,astroid==2.15.5,async-timeout==4.0.2,attrs==23.1.0,autopep8==2.0.2,bashlex==0.18,bcrypt==4.0.1,cachetools==5.3.0,certifi==2023.5.7,cffi==1.15.1,chardet==5.1.0,charset-normalizer==3.1.0,click==8.1.3,colorama==0.4.6,coverage==7.2.5,cryptography==40.0.2,decorator==5.1.1,defusedxml==0.7.1,Deprecated==1.2.13,dill==0.3.6,distlib==0.3.6,dockerfile-parse==2.0.0,exceptiongroup==1.1.1,fastcore==1.5.29,filelock==3.12.0,flake8==6.0.0,flexmock==0.11.3,frozenlist==1.3.3,future==0.18.3,ghapi==1.0.3,gssapi==1.8.2,idna==3.4,iniconfig==2.0.0,isort==5.12.0,jira==3.4.1,koji==1.32.1,krb5==0.5.0,lazy-object-proxy==1.9.0,mccabe==0.7.0,multidict==6.0.4,mysql-connector-python==8.0.33,oauthlib==3.2.2,openshift-client==1.0.18,packaging==23.1,paramiko==3.1.0,platformdirs==3.5.1,pluggy==1.0.0,protobuf==3.20.3,pycodestyle==2.10.0,pycparser==2.21,pyflakes==3.0.1,pygit2==1.10.1,PyGithub==1.58.2,PyJWT==2.7.0,pylint==2.17.4,PyNaCl==1.5.0,pyproject-api==1.5.1,pyspnego==0.9.0,pytest==7.3.1,python-dateutil==2.8.2,PyYAML==6.0,requests==2.30.0,requests-gssapi==1.2.3,requests-kerberos==0.14.0,requests-oauthlib==1.3.1,requests-toolbelt==1.0.0,rh-doozer @ file:///mnt/workspace/jenkins/working/art-tools_doozer_PR-764/.tox/.tmp/package/1/rh-doozer-2.0.15.dev326%2Bge973d89.zip,semver==3.0.0,setuptools-scm==7.1.0,six==1.16.0,tenacity==8.2.2,tomli==2.0.1,tomlkit==0.11.8,tox==4.5.1,typing==3.7.4.3,typing-extensions==4.5.0,urllib3==2.0.2,virtualenv==20.23.0,wrapt==1.15.0,yarl==1.9.2
py38 run-test-pre: PYTHONHASHSEED='900337570'
py38 run-test: commands[0] | coverage run --branch --source doozerlib -m unittest discover -t . -s tests/
............................................................................................................................................s.s....................................s.s...s.s..s..s.s.s..................................................................................
----------------------------------------------------------------------
Ran 270 tests in 2.128s

OK (skipped=10)
py38 run-test: commands[1] | flake8
py38 run-test: commands[2] | coverage report
Name                                          Stmts   Miss Branch BrPart  Cover
-------------------------------------------------------------------------------
doozerlib/__init__.py                            12      7      2      1    43%
doozerlib/_version.py                             2      2      0      0     0%
doozerlib/assembly.py                           164     26     91     11    80%
doozerlib/assembly_inspector.py                 216    156    124      9    24%
doozerlib/assertion.py                           13      0      6      0   100%
doozerlib/brew.py                               366    206    152      4    40%
doozerlib/build_status_detector.py               85     10     54      3    86%
doozerlib/cli/__init__.py                       122     64     28      0    39%
doozerlib/cli/__main__.py                      1136   1136    454      0     0%
doozerlib/cli/cli_opts.py                        20      3      8      0    89%
doozerlib/cli/config_plashet.py                 535    535    246      0     0%
doozerlib/cli/detect_embargo.py                 167     35     70      8    75%
doozerlib/cli/get_nightlies.py                  230     59    127      3    71%
doozerlib/cli/images_health.py                   82     30     26      2    59%
doozerlib/cli/images_streams.py                 687    687    296      0     0%
doozerlib/cli/inspect_stream.py                  66     66     28      0     0%
doozerlib/cli/release_calc_upgrade_tests.py      24     24      6      0     0%
doozerlib/cli/release_gen_assembly.py           277    146    118      3    42%
doozerlib/cli/release_gen_payload.py            703    260    300     20    58%
doozerlib/cli/rpms_build.py                     165     59     58      8    57%
doozerlib/cli/scan_sources.py                   182    141    100      2    17%
doozerlib/comment_on_pr.py                       46      0      8      0   100%
doozerlib/config.py                              97     97     44      0     0%
doozerlib/constants.py                           11      0      0      0   100%
doozerlib/coverity.py                           255    225     82      0     9%
doozerlib/dblib.py                              263    160     68      4    35%
doozerlib/distgit.py                           1449    898    686     40    36%
doozerlib/dotconfig.py                           54     43     31      0    13%
doozerlib/exceptions.py                           2      0      0      0   100%
doozerlib/exectools.py                          197    105     76     10    43%
doozerlib/gitdata.py                            171    137     76      0    14%
doozerlib/image.py                              532    329    232     10    33%
doozerlib/logutil.py                              9      0      2      1    91%
doozerlib/metadata.py                           432    151    184     30    61%
doozerlib/model.py                              113     21     36      2    82%
doozerlib/olm/__init__.py                         0      0      0      0   100%
doozerlib/olm/bundle.py                         315    230     72      0    22%
doozerlib/osbs2_builder.py                      119     30     44     19    67%
doozerlib/plashet.py                            134      9     90     15    89%
doozerlib/pushd.py                               22      0      2      0   100%
doozerlib/release_schedule.py                    28     17      8      0    31%
doozerlib/repos.py                              243     92    121     17    55%
doozerlib/rhcos.py                              237     25     90     14    87%
doozerlib/rpm_builder.py                        225     28    119     31    82%
doozerlib/rpm_utils.py                          134     23     90     14    81%
doozerlib/rpmcfg.py                             151     61     64      8    55%
doozerlib/runtime.py                            950    692    376      8    21%
doozerlib/source_modifications.py               116     33     26      4    68%
doozerlib/state.py                               23     12      8      0    35%
doozerlib/util.py                               452    217    180     13    48%
-------------------------------------------------------------------------------
TOTAL                                         12034   7287   5109    314    36%
___________________________________ summary ____________________________________
  py38: commands succeeded
  congratulations :)

@vfreex vfreex merged commit 15a672d into openshift-eng:master May 19, 2023
2 checks passed
vfreex added a commit to vfreex/doozer that referenced this pull request Jun 20, 2023
In openshift-eng#764, the idea of using
repoquery to detect outdated rpms has been proved.
This PR will adopt the same approach in `scan_sources`.
vfreex added a commit to vfreex/doozer that referenced this pull request Jun 20, 2023
In openshift-eng#764, the idea of using
repoquery to detect outdated rpms has been proved in `gen-payload`.
This PR will adopt the same approach in `scan_sources`.
vfreex added a commit to vfreex/doozer that referenced this pull request Jun 20, 2023
In openshift-eng#764, the idea of using
repoquery to detect outdated rpms has been proved in `gen-payload`.
This PR will adopt the same approach in `scan_sources`.
vfreex added a commit to vfreex/doozer that referenced this pull request Jul 11, 2023
In openshift-eng#764, the idea of using
repoquery to detect outdated rpms has been proved in `gen-payload`.

This PR will adopt a similar approach in `scan_sources`, get rid of
`repoquery` command and also add rpm modularity awareness.
vfreex added a commit to vfreex/doozer that referenced this pull request Jul 12, 2023
Currently we use a tag based approach to detect rpm changes in stream builds.
It considers a package X is outdated if a newer version Y is tagged into any of X's tags.
This approach has some limitations. Especially, it can't detect rpm changes after RHEL version moves or the image moves to a different repo (see https://issues.redhat.com/browse/ART-3965 for a real problem).

I will give you an example to show how it fails to detect a change:
- Image A enables a RHEL 8.4 repo.
- Package `foo-1.0.0-1.el8_3.x86_64.rpm` is installed in image A. It has `rhel-8.3.0-z` tag in Brew.
- A newer version `foo-1.1.0-1.el8_4.x86_64.rpm` is released and has `rhel-8.4.0-z` tag.
- Doozer doesn't think `foo-1.0.0-1.el8_3.x86_64.rpm` is outdated because the newer version `foo-1.1.0-1.el8_4.x86_64.rpm` doesn't have `rhel-8.3.0-z` tag.

To address this limitation, a new approach is proposed to actually query the content of all enabled repos
and compare the installed versions with the latest versions in repos. I will call it "content based" approach.

This content based approach has been proved in `gen-payload` command (invoked in `build-sync` job) with the merge of openshift-eng#764. If you look at [the logs of build-sync build](https://saml.buildvm.hosts.prod.psi.bos.redhat.com:8888/job/aos-cd-builds/job/build%252Fbuild-sync/34458/consoleFull), you will see it shows you which images contain outdated rpms. It contains entries like:

```yaml
- code: OUTDATED_RPMS_IN_STREAM_BUILD
  msg: Found outdated RPM (perl-Pod-Perldoc-3.28-396.el8) installed in openshift-enterprise-builder-container-v4.14.0-202307111728.p0.gfe78ee6.assembly.stream (x86_64) when perl-Pod-Perldoc-3.28.01-443.module+el8.6.0+13324+628a2397 was available in repo rhel-8-appstream-rpms
```

However, the above example is actually a false positive. It is because package `perl-Pod-Perldoc-3.28-396.el8` comes from
a modular repo but our code is not module-aware. A modular rpm repo provides multiple upgrade paths. We should only consider a newer version is upgradable if it belongs to the same stream. For more information about modules, see https://docs.fedoraproject.org/en-US/modularity/. That is a major reason why this new approach is adopted to `scan-sources`, otherwise it would constantly trigger unnecessary rebuilds!

This PR not only updates `scan-sources` to use the new approach, but only adds module-awareness to eliminate false positives.
The new algorithm (probably oversimplified):

1. For an image build, get all modular rpms in enabled repos.
2. For each installed rpm, check if the rpm is contained by a module.
3. If yes, we will consider that module stream is "enabled" for this image.
4. For each enabled module stream, find the module with the largest version.
5. Collect all modular rpms from those modules as collection M.
6. Collect all non-modular rpms with the latest version as collection N. If the package name of a non-modular rpm is already included in the modular rpms collection, exclude it.
7. For each installed rpm, check if it is a modular rpm or not. If it is modular, check if it is older than the one in collection M. Otherwise, check if it is older than the one in collection N.
8. If it is older, we consider is it an outdated rpm.

Note:
1. There is no Brew API or any other cheap way to precisely determine which module streams are enabled during an image build.
The method used in the above algorithm is actually *guess*. It is not perfect, but my tests conclude it is good enough for our use cases (probably because we don't use a lot of modular rpms in our images).
2. Some images use pins in their Dockerfiles. We should exempt them from scan-sources. The exemption can be defined in ocp-build-data image metadata. e.g.

```yaml
scan_sources:
  exempted_packages:
  - openvswitch3.1
  - python3-openvswitch3.1
```
vfreex added a commit to vfreex/doozer that referenced this pull request Jul 12, 2023
Currently we use a tag based approach to detect rpm changes in stream builds.
It considers a package X is outdated if a newer version Y is tagged into any of X's tags.
This approach has some limitations. Especially, it can't detect rpm changes after RHEL version moves or the image moves to a different repo (see https://issues.redhat.com/browse/ART-3965 for a real problem).

I will give you an example to show how it fails to detect a change:
- Image A enables a RHEL 8.4 repo.
- Package `foo-1.0.0-1.el8_3.x86_64.rpm` is installed in image A. It has `rhel-8.3.0-z` tag in Brew.
- A newer version `foo-1.1.0-1.el8_4.x86_64.rpm` is released and has `rhel-8.4.0-z` tag.
- Doozer doesn't think `foo-1.0.0-1.el8_3.x86_64.rpm` is outdated because the newer version `foo-1.1.0-1.el8_4.x86_64.rpm` doesn't have `rhel-8.3.0-z` tag.

To address this limitation, a new approach is proposed to actually query the content of all enabled repos
and compare the installed versions with the latest versions in repos. I will call it "content based" approach.

This content based approach has been proved in `gen-payload` command (invoked in `build-sync` job) with the merge of openshift-eng#764. If you look at [the logs of build-sync build](https://saml.buildvm.hosts.prod.psi.bos.redhat.com:8888/job/aos-cd-builds/job/build%252Fbuild-sync/34458/consoleFull), you will see it shows you which images contain outdated rpms. It contains entries like:

```yaml
- code: OUTDATED_RPMS_IN_STREAM_BUILD
  msg: Found outdated RPM (perl-Pod-Perldoc-3.28-396.el8) installed in openshift-enterprise-builder-container-v4.14.0-202307111728.p0.gfe78ee6.assembly.stream (x86_64) when perl-Pod-Perldoc-3.28.01-443.module+el8.6.0+13324+628a2397 was available in repo rhel-8-appstream-rpms
```

However, the above example is actually a false positive. It is because package `perl-Pod-Perldoc-3.28-396.el8` comes from
a modular repo but our code is not module-aware. A modular rpm repo provides multiple upgrade paths. We should only consider a newer version is upgradable if it belongs to the same stream. For more information about modules, see https://docs.fedoraproject.org/en-US/modularity/. That is a major reason why this new approach is adopted to `scan-sources`, otherwise it would constantly trigger unnecessary rebuilds!

This PR not only updates `scan-sources` to use the new approach, but only adds module-awareness to eliminate false positives.
The new algorithm (probably oversimplified):

1. For an image build, get all modular rpms in enabled repos.
2. For each installed rpm, check if the rpm is contained by a module.
3. If yes, we will consider that module stream is "enabled" for this image.
4. For each enabled module stream, find the module with the largest version.
5. Collect all modular rpms from those modules as collection M.
6. Collect all non-modular rpms with the latest version as collection N. If the package name of a non-modular rpm is already included in the modular rpms collection, exclude it.
7. For each installed rpm, check if it is a modular rpm or not. If it is modular, check if it is older than the one in collection M. Otherwise, check if it is older than the one in collection N.
8. If it is older, we consider is it an outdated rpm.

Note:
1. There is no Brew API or any other cheap way to precisely determine which module streams are enabled during an image build.
The method used in the above algorithm is actually *guess*. It is not perfect, but my tests conclude it is good enough for our use cases (probably because we don't use a lot of modular rpms in our images).
2. Some images use pins in their Dockerfiles. We should exempt them from scan-sources. The exemption can be defined in ocp-build-data image metadata. e.g.

```yaml
scan_sources:
  exempted_packages:
  - openvswitch3.1
  - python3-openvswitch3.1
```
vfreex added a commit to vfreex/doozer that referenced this pull request Jul 12, 2023
Currently we use a tag based approach to detect rpm changes in stream builds.
It considers a package X is outdated if a newer version Y is tagged into any of X's tags.
This approach has some limitations. Especially, it can't detect rpm changes after RHEL version moves or the image moves to a different repo (see https://issues.redhat.com/browse/ART-3965 for a real problem).

I will give you an example to show how it fails to detect a change:
- Image A enables a RHEL 8.4 repo.
- Package `foo-1.0.0-1.el8_3.x86_64.rpm` is installed in image A. It has `rhel-8.3.0-z` tag in Brew.
- A newer version `foo-1.1.0-1.el8_4.x86_64.rpm` is released and has `rhel-8.4.0-z` tag.
- Doozer doesn't think `foo-1.0.0-1.el8_3.x86_64.rpm` is outdated because the newer version `foo-1.1.0-1.el8_4.x86_64.rpm` doesn't have `rhel-8.3.0-z` tag.

To address this limitation, a new approach is proposed to actually query the content of all enabled repos
and compare the installed versions with the latest versions in repos. I will call it "content based" approach.

This content based approach has been proved in `gen-payload` command (invoked in `build-sync` job) with the merge of openshift-eng#764. If you look at [the logs of build-sync build](https://saml.buildvm.hosts.prod.psi.bos.redhat.com:8888/job/aos-cd-builds/job/build%252Fbuild-sync/34458/consoleFull), you will see it shows you which images contain outdated rpms. It contains entries like:

```yaml
- code: OUTDATED_RPMS_IN_STREAM_BUILD
  msg: Found outdated RPM (perl-Pod-Perldoc-3.28-396.el8) installed in openshift-enterprise-builder-container-v4.14.0-202307111728.p0.gfe78ee6.assembly.stream (x86_64) when perl-Pod-Perldoc-3.28.01-443.module+el8.6.0+13324+628a2397 was available in repo rhel-8-appstream-rpms
```

However, the above example is actually a false positive. It is because package `perl-Pod-Perldoc-3.28-396.el8` comes from
a modular repo but our code is not module-aware. A modular rpm repo provides multiple upgrade paths. We should only consider a newer version is upgradable if it belongs to the same stream. For more information about modules, see https://docs.fedoraproject.org/en-US/modularity/. That is a major reason why this new approach is adopted to `scan-sources`, otherwise it would constantly trigger unnecessary rebuilds!

This PR not only updates `scan-sources` to use the new approach, but only adds module-awareness to eliminate false positives.
The new algorithm (probably oversimplified):

1. For an image build, get all modular rpms in enabled repos.
2. For each installed rpm, check if the rpm is contained by a module.
3. If yes, we will consider that module stream is "enabled" for this image.
4. For each enabled module stream, find the module with the largest version.
5. Collect all modular rpms from those modules as collection M.
6. Collect all non-modular rpms with the latest version as collection N. If the package name of a non-modular rpm is already included in the modular rpms collection, exclude it.
7. For each installed rpm, check if it is a modular rpm or not. If it is modular, check if it is older than the one in collection M. Otherwise, check if it is older than the one in collection N.
8. If it is older, we consider is it an outdated rpm.

Note:
1. There is no Brew API or any other cheap way to precisely determine which module streams are enabled during an image build.
The method used in the above algorithm is actually *guess*. It is not perfect, but my tests conclude it is good enough for our use cases (probably because we don't use a lot of modular rpms in our images).
2. Some images use pins in their Dockerfiles. We should exempt them from scan-sources. The exemption can be defined in ocp-build-data image metadata. e.g.

```yaml
scan_sources:
  exempted_packages:
  - openvswitch3.1
  - python3-openvswitch3.1
```
vfreex added a commit to vfreex/doozer that referenced this pull request Jul 12, 2023
Currently we use a tag based approach to detect rpm changes in stream builds.
It considers a package X is outdated if a newer version Y is tagged into any of X's tags.
This approach has some limitations. Especially, it can't detect rpm changes after RHEL version moves or the image moves to a different repo (see https://issues.redhat.com/browse/ART-3965 for a real problem).

I will give you an example to show how it fails to detect a change:
- Image A enables a RHEL 8.4 repo.
- Package `foo-1.0.0-1.el8_3.x86_64.rpm` is installed in image A. It has `rhel-8.3.0-z` tag in Brew.
- A newer version `foo-1.1.0-1.el8_4.x86_64.rpm` is released and has `rhel-8.4.0-z` tag.
- Doozer doesn't think `foo-1.0.0-1.el8_3.x86_64.rpm` is outdated because the newer version `foo-1.1.0-1.el8_4.x86_64.rpm` doesn't have `rhel-8.3.0-z` tag.

To address this limitation, a new approach is proposed to actually query the content of all enabled repos
and compare the installed versions with the latest versions in repos. I will call it "content based" approach.

This content based approach has been proved in `gen-payload` command (invoked in `build-sync` job) with the merge of openshift-eng#764. If you look at [the logs of build-sync build](https://saml.buildvm.hosts.prod.psi.bos.redhat.com:8888/job/aos-cd-builds/job/build%252Fbuild-sync/34458/consoleFull), you will see it shows you which images contain outdated rpms. It contains entries like:

```yaml
- code: OUTDATED_RPMS_IN_STREAM_BUILD
  msg: Found outdated RPM (perl-Pod-Perldoc-3.28-396.el8) installed in openshift-enterprise-builder-container-v4.14.0-202307111728.p0.gfe78ee6.assembly.stream (x86_64) when perl-Pod-Perldoc-3.28.01-443.module+el8.6.0+13324+628a2397 was available in repo rhel-8-appstream-rpms
```

However, the above example is actually a false positive. It is because package `perl-Pod-Perldoc-3.28-396.el8` comes from
a modular repo but our code is not module-aware. A modular rpm repo provides multiple upgrade paths. We should only consider a newer version is upgradable if it belongs to the same stream. For more information about modules, see https://docs.fedoraproject.org/en-US/modularity/. That is a major reason why this new approach is adopted to `scan-sources`, otherwise it would constantly trigger unnecessary rebuilds!

This PR not only updates `scan-sources` to use the new approach, but only adds module-awareness to eliminate false positives.
The new algorithm (probably oversimplified):

1. For an image build, get all modular rpms in enabled repos.
2. For each installed rpm, check if the rpm is contained by a module.
3. If yes, we will consider that module stream is "enabled" for this image.
4. For each enabled module stream, find the module with the largest version.
5. Collect all modular rpms from those modules as collection M.
6. Collect all non-modular rpms with the latest version as collection N. If the package name of a non-modular rpm is already included in the modular rpms collection, exclude it.
7. For each installed rpm, check if it is a modular rpm or not. If it is modular, check if it is older than the one in collection M. Otherwise, check if it is older than the one in collection N.
8. If it is older, we consider is it an outdated rpm.

Note:
1. There is no Brew API or any other cheap way to precisely determine which module streams are enabled during an image build.
The method used in the above algorithm is actually *guess*. It is not perfect, but my tests conclude it is good enough for our use cases (probably because we don't use a lot of modular rpms in our images).
2. Some images use pins in their Dockerfiles. We should exempt them from scan-sources. The exemption can be defined in ocp-build-data image metadata. e.g.

```yaml
scan_sources:
  exempted_packages:
  - openvswitch3.1
  - python3-openvswitch3.1
```
vfreex added a commit to vfreex/doozer that referenced this pull request Jul 14, 2023
Currently we use a tag based approach to detect rpm changes in stream builds.
It considers a package X is outdated if a newer version Y is tagged into any of X's tags.
This approach has some limitations. Especially, it can't detect rpm changes after RHEL version moves or the image moves to a different repo (see https://issues.redhat.com/browse/ART-3965 for a real problem).

I will give you an example to show how it fails to detect a change:
- Image A enables a RHEL 8.4 repo.
- Package `foo-1.0.0-1.el8_3.x86_64.rpm` is installed in image A. It has `rhel-8.3.0-z` tag in Brew.
- A newer version `foo-1.1.0-1.el8_4.x86_64.rpm` is released and has `rhel-8.4.0-z` tag.
- Doozer doesn't think `foo-1.0.0-1.el8_3.x86_64.rpm` is outdated because the newer version `foo-1.1.0-1.el8_4.x86_64.rpm` doesn't have `rhel-8.3.0-z` tag.

To address this limitation, a new approach is proposed to actually query the content of all enabled repos
and compare the installed versions with the latest versions in repos. I will call it "content based" approach.

This content based approach has been proved in `gen-payload` command (invoked in `build-sync` job) with the merge of openshift-eng#764. If you look at [the logs of build-sync build](https://saml.buildvm.hosts.prod.psi.bos.redhat.com:8888/job/aos-cd-builds/job/build%252Fbuild-sync/34458/consoleFull), you will see it shows you which images contain outdated rpms. It contains entries like:

```yaml
- code: OUTDATED_RPMS_IN_STREAM_BUILD
  msg: Found outdated RPM (perl-Pod-Perldoc-3.28-396.el8) installed in openshift-enterprise-builder-container-v4.14.0-202307111728.p0.gfe78ee6.assembly.stream (x86_64) when perl-Pod-Perldoc-3.28.01-443.module+el8.6.0+13324+628a2397 was available in repo rhel-8-appstream-rpms
```

However, the above example is actually a false positive. It is because package `perl-Pod-Perldoc-3.28-396.el8` comes from
a modular repo but our code is not module-aware. A modular rpm repo provides multiple upgrade paths. We should only consider a newer version is upgradable if it belongs to the same stream. For more information about modules, see https://docs.fedoraproject.org/en-US/modularity/. That is a major reason why this new approach is adopted to `scan-sources`, otherwise it would constantly trigger unnecessary rebuilds!

This PR not only updates `scan-sources` to use the new approach, but only adds module-awareness to eliminate false positives.
The new algorithm (probably oversimplified):

1. For an image build, get all modular rpms in enabled repos.
2. For each installed rpm, check if the rpm is contained by a module.
3. If yes, we will consider that module stream is "enabled" for this image.
4. For each enabled module stream, find the module with the largest version.
5. Collect all modular rpms from those modules as collection M.
6. Collect all non-modular rpms with the latest version as collection N. If the package name of a non-modular rpm is already included in the modular rpms collection, exclude it.
7. For each installed rpm, check if it is a modular rpm or not. If it is modular, check if it is older than the one in collection M. Otherwise, check if it is older than the one in collection N.
8. If it is older, we consider is it an outdated rpm.

Note:
1. There is no Brew API or any other cheap way to precisely determine which module streams are enabled during an image build.
The method used in the above algorithm is actually *guess*. It is not perfect, but my tests conclude it is good enough for our use cases (probably because we don't use a lot of modular rpms in our images).
2. Some images use pins in their Dockerfiles. We should exempt them from scan-sources. The exemption can be defined in ocp-build-data image metadata. e.g.

```yaml
scan_sources:
  exempted_packages:
  - openvswitch3.1
  - python3-openvswitch3.1
```
github-actions bot pushed a commit to ashwindasr/art-tools that referenced this pull request Jul 21, 2023
Currently we use a tag based approach to detect rpm changes in stream builds.
It considers a package X is outdated if a newer version Y is tagged into any of X's tags.
This approach has some limitations. Especially, it can't detect rpm changes after RHEL version moves or the image moves to a different repo (see https://issues.redhat.com/browse/ART-3965 for a real problem).

I will give you an example to show how it fails to detect a change:
- Image A enables a RHEL 8.4 repo.
- Package `foo-1.0.0-1.el8_3.x86_64.rpm` is installed in image A. It has `rhel-8.3.0-z` tag in Brew.
- A newer version `foo-1.1.0-1.el8_4.x86_64.rpm` is released and has `rhel-8.4.0-z` tag.
- Doozer doesn't think `foo-1.0.0-1.el8_3.x86_64.rpm` is outdated because the newer version `foo-1.1.0-1.el8_4.x86_64.rpm` doesn't have `rhel-8.3.0-z` tag.

To address this limitation, a new approach is proposed to actually query the content of all enabled repos
and compare the installed versions with the latest versions in repos. I will call it "content based" approach.

This content based approach has been proved in `gen-payload` command (invoked in `build-sync` job) with the merge of openshift-eng/doozer#764. If you look at [the logs of build-sync build](https://saml.buildvm.hosts.prod.psi.bos.redhat.com:8888/job/aos-cd-builds/job/build%252Fbuild-sync/34458/consoleFull), you will see it shows you which images contain outdated rpms. It contains entries like:

```yaml
- code: OUTDATED_RPMS_IN_STREAM_BUILD
  msg: Found outdated RPM (perl-Pod-Perldoc-3.28-396.el8) installed in openshift-enterprise-builder-container-v4.14.0-202307111728.p0.gfe78ee6.assembly.stream (x86_64) when perl-Pod-Perldoc-3.28.01-443.module+el8.6.0+13324+628a2397 was available in repo rhel-8-appstream-rpms
```

However, the above example is actually a false positive. It is because package `perl-Pod-Perldoc-3.28-396.el8` comes from
a modular repo but our code is not module-aware. A modular rpm repo provides multiple upgrade paths. We should only consider a newer version is upgradable if it belongs to the same stream. For more information about modules, see https://docs.fedoraproject.org/en-US/modularity/. That is a major reason why this new approach is adopted to `scan-sources`, otherwise it would constantly trigger unnecessary rebuilds!

This PR not only updates `scan-sources` to use the new approach, but only adds module-awareness to eliminate false positives.
The new algorithm (probably oversimplified):

1. For an image build, get all modular rpms in enabled repos.
2. For each installed rpm, check if the rpm is contained by a module.
3. If yes, we will consider that module stream is "enabled" for this image.
4. For each enabled module stream, find the module with the largest version.
5. Collect all modular rpms from those modules as collection M.
6. Collect all non-modular rpms with the latest version as collection N. If the package name of a non-modular rpm is already included in the modular rpms collection, exclude it.
7. For each installed rpm, check if it is a modular rpm or not. If it is modular, check if it is older than the one in collection M. Otherwise, check if it is older than the one in collection N.
8. If it is older, we consider is it an outdated rpm.

Note:
1. There is no Brew API or any other cheap way to precisely determine which module streams are enabled during an image build.
The method used in the above algorithm is actually *guess*. It is not perfect, but my tests conclude it is good enough for our use cases (probably because we don't use a lot of modular rpms in our images).
2. Some images use pins in their Dockerfiles. We should exempt them from scan-sources. The exemption can be defined in ocp-build-data image metadata. e.g.

```yaml
scan_sources:
  exempted_packages:
  - openvswitch3.1
  - python3-openvswitch3.1
```
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants