Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rebuildibility poc #2623

Closed
wants to merge 36 commits into from
Closed

Rebuildibility poc #2623

wants to merge 36 commits into from

Conversation

jreidinger
Copy link
Member

draft to have a tool to test a various approaches for detecting rebuildability issues.

Still WIP, but feel free to comment approach.

@codecov-commenter
Copy link

codecov-commenter commented Aug 19, 2021

Codecov Report

Merging #2623 (524e70f) into master (b133ea6) will decrease coverage by 0.67%.
The diff coverage is 0.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #2623      +/-   ##
==========================================
- Coverage   25.20%   24.52%   -0.68%     
==========================================
  Files          91       96       +5     
  Lines       15156    15574     +418     
==========================================
  Hits         3820     3820              
- Misses      11336    11754     +418     
Impacted Files Coverage Δ
osclib/dependency.py 0.00% <0.00%> (ø)
osclib/remote_package.py 0.00% <0.00%> (ø)
osclib/remote_project.py 0.00% <0.00%> (ø)
rebuildability_check.py 0.00% <0.00%> (ø)
skippkg-finder.py 0.00% <0.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b133ea6...524e70f. Read the comment docs.

cleaning_regex = re.compile(r'\.[0-9]+$')
for project in linked_projects:
for pkg in project.get_packages(inherited = False):
# TODO: is there better way then regex?
Copy link
Member

Choose a reason for hiding this comment

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

Note that ruby2.5 also matches your regexp but is not maintenance specific, so relying on regexp is basically a no go. /source/SUSE:SLE-15-SP2:Update/zypper.15590/_meta will tell you <releasename>zypper</releasename>.

Copy link
Member Author

Choose a reason for hiding this comment

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

Good catch with that ruby...in general I a bit worry about performance as when I check SLE15-SP4 there was a lot of updates in update channel, but lets not preoptimalize in advance.

return cls.from_xml(osc.core.http_GET(url))
except HTTPError as e:
if e.code == 404:
raise PackageNotFound('Package %s not found' % (package_name))
Copy link
Member

Choose a reason for hiding this comment

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

you need to reraise in else - or you will get very strange results

class RebuildabilityChecker(object):
def __init__(self, project_str):
self.logger = logging.getLogger('RebuildibilityChecker')
self.project = RemoteProject.find(project_str) # apiurl should be read from osc.conf.config['apiurl'], osclib config class looks like has different goal?
Copy link
Member

Choose a reason for hiding this comment

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

that might be just me but could you limit your line length to a value that makes reading the comments possible without scrolling left and right on github page? That would be awesome

Copy link
Member Author

Choose a reason for hiding this comment

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

goal of this comments is mainly discussion about code where we cooperate. It should not be there before we merge it.
But thanks for catch


def copy(self, target_project_name, expand=False):
apiurl = osc.conf.config['apiurl']
osc.core.copy_pac(apiurl, self.project_name, self.name, apiurl, target_project_name, self.name, expand=expand)
Copy link
Member

Choose a reason for hiding this comment

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

note that copy_pac is greatly expensive operating. For such use cases a revisioned _link is much clearly preferred.

Copy link
Member Author

Choose a reason for hiding this comment

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

yeah, I expect it is expensive. I just want to avoid any diff issue. Revisioned _link can be solution as I expect in SLE15 it won't change much. If we want to use it on staging it can be more tricky as staging change more frequently and link can be broken. ( question is how big issue it is as it means that it is removed from staging )

Copy link
Member

Choose a reason for hiding this comment

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

if you plan to rebuild all of SLE15 history against a moving target you want to go back to the drawing board anyway.

rebuild_project = self.project.create_subproject("Rebuild", title, description) # how to handle if it exists? Clean it and use? What if we do not have permission to create subproject?

testing_packages = [package.copy(rebuild_project.name, expand=True) for package in packages]
while not all([p.builds.is_finished for p in testing_packages]): # builds is object for handling building and is_finished means that all builds are finished ( or disabled )
Copy link
Member

Choose a reason for hiding this comment

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

I assume this is supposed to read as pseudo code? Because you don't need to query all packages' build status just to find out that one is not finished (taking that is_finished is going to be an external API call).

Copy link
Member Author

Choose a reason for hiding this comment

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

yeah, we decide to start with pseudo code how the API can look like and adapt it as we implement it. Maybe we can even find some project specific query to find unfinished build.

# write some progress about number of pass, failures, what is waiting, etc. using p.builds query ( ensure it is not memoized )
print("Working like a crazy monk")

# TODO: delete rebuild project or keep it for inspection?
Copy link
Member

Choose a reason for hiding this comment

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

in principle: all succeeded packages are normally uninteresting. The failed ones you might need to show around. Not sure the yast team ever accepted a "it failed, fix it - that's all I have!" :)

But depending on how often you plan to run this, you surely do not want to have a lot of these projects around as they fill up several hundered GB easily. So reusing them can be key.

Copy link
Member Author

Choose a reason for hiding this comment

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

Maybe it can be even parameter specific e.g. for SLE-15-SP4 I expect we want to keep it and just reuse project when we want another rebuild test. For some other usage like maintenance update, different behavior can make sense.

Copy link
Member

Choose a reason for hiding this comment

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

Before you discuss such things, learn how long it takes to create and recompile a single project. So before you start to worry about reports and cleanup, just create one of these beasts

Copy link
Member Author

Choose a reason for hiding this comment

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

yep, that is a goal of this tool, to start playing with it and as side-effect create a bit of high level API that helps with whatever we decided to do.

@@ -23,7 +23,7 @@ def result(self):
description = "Temporary project including expanded copy of parent to verify if everything can be rebuild from scratch"
rebuild_project = self.project.create_subproject("Rebuild", title, description) # how to handle if it exists? Clean it and use? What if we do not have permission to create subproject?

testing_packages = [package.copy(rebuild_project.name, expand=True) for package in packages]
testing_packages = [package.link(rebuild_project.name) for package in packages]
Copy link
Member

Choose a reason for hiding this comment

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

note that only works for truely static targets. In case of update projects, you really want to have a revision to your link. Like osc linkpac --current does

@jreidinger
Copy link
Member Author

OK, so first run finished. It uses code after commit ede0f67
repo is at https://build.suse.de/project/show/home:jreidinger:SP4-rebuild-testing:Rebuild
runtime for creating such repo is

real	231m10.171s
user	11m26.858s
sys	1m36.694s

building of such repo started 23.08. at 22:00

@coolo
Copy link
Member

coolo commented Aug 24, 2021

On the project page, click on the repo name, ignore the disgusting amount of build cyles and look for "Check the rebuild time for x86_64"

@jreidinger
Copy link
Member Author

thanks

@imobachgs
Copy link
Member

What we did in the past: Query /source/?view=info and then compare <filename> with package name

Thanks! I found out exactly that query last night checking the OBS code 😄 because I felt that things were too complicated.

jreidinger and others added 3 commits August 24, 2021 16:15
* Extract the logic to read the packages to a separate class,
  so it is easy to change the overall approach if needed in the future.
@coolo
Copy link
Member

coolo commented Aug 26, 2021

So your branch eventually finished, any idea what to do with the result?

@jreidinger
Copy link
Member Author

@coolo we see it together with a bunch of failures and unresolvable stuff. For multi choice we need to fix the script to copy source Prefer configuration. For rest we need to try to find if it is valid or issue with our approach. And then we probably need to talk with release manages/PMs what to do with it. And meanwhile we are preparing alternative approaches that takes less time ( and probably find less issues as it cover limited set of packages ).

@coolo
Copy link
Member

coolo commented Aug 26, 2021

What prefers do you want to copy? You build against SP3 and all the project configs are inherited. The only thing you would need to copy is if you want to compile sp4 sources against sp3. But in sp4 project configs are no prefers that would fix your issues.

But your project checks if you can rebuild packages against other packages you rebuild, i.e. bootstrap the merged set. I don't think that's what #2581 asks for. And some of the unresolvables and failures might actually inherit from that.

@jreidinger
Copy link
Member Author

@coolo interesting note about bootstrapping, if it is really not goal ( which I am not aware, as I thought that e.g. for embedded stuff it is needed ) then the other two options which script support can be interesting. The first one is just to provide list of packages to try to rebuild ( plan is to provide also possibility to specify file path instead of comma separated list ) or provide package and compute what it can break in build dependencies ( e.g. I test it with yast2-core which cause rebuild of all yast2 packages which is correct ). I hope that the second option with build dependencies can be something that can address #2581

@jreidinger
Copy link
Member Author

BTW usage to get what needs to check rebuild when new glibc is introduced should be python3 rebuildability_check.py --project SUSE:SLE-15-SP4:GA --apiurl https://api.suse.de --packages=glibc --dependencies=standard --dry-run but it now fails for me ( need to debug it on monday ).

@coolo
Copy link
Member

coolo commented Aug 28, 2021

Bootstrap is indeed interesting for embedded but for a fraction of the package. But it's impossible if the package sources aren't rebuildable to begin with - and that's what the issue asks for IMO.

@jreidinger
Copy link
Member Author

OK, I fix issue with getting proper source project name and now even more interesting issue appear. Build info for update project is empty. No clue why. Will ask on monday on build service chat - https://api.suse.de/build/SUSE:SLE-15-SP3:Update/standard/x86_64/_builddepinfo?view=revpkgnames

@coolo
Copy link
Member

coolo commented Aug 30, 2021

@coolo
Copy link
Member

coolo commented Feb 15, 2022

Closing the PR - leaving the branch

@coolo coolo closed this Feb 15, 2022
@coolo coolo deleted the rebuildibility_POC branch November 11, 2022 09:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants