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

scripts: create kernel configuration upgrade script #14907

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

ehem
Copy link
Contributor

@ehem ehem commented Mar 16, 2024

Since GitHub has effectively displaced the mailing list, a different implementation already got in. This script though has some major advantages.

First, it is rather more robust. The one presently in the tree failed with the first thing I tried. There are several brittle spots which have a high probability of failing in the future.

Second, this does not touch the working tree at all. It generates the two appropriate commits, but then lets the person running decide whether they want a new branch versus bringing into their current branch.

Third, this gets everything in one pass. No need to run it 44 times for each and every device (worse, having one maintainer not know there is a script and manually copy files). This is extremely helpful for rebasing commits modifying the default values in generic.

Fourth, this has cleaner copyright. While not impossible for two people to come up with the same wording, having the exact same goof seems rather less likely.

Fifth, rather better messages. scripts/kernel_bump.sh yields an unhelpful mysterious error. This script emits its usage message. The formatting of the second commit message by the other script isn't very good.

Sixth, this is inherently much faster. Since it has no need to touch the working tree, it never has the two intermediate commit nor final commit unpacked on the filesystem (in fact this script only has one intermediate).

Okay, so Perl is no longer such common knowledge. Until there is a policy of getting rid of Perl, it was an appropriate tool for this script. Python may be better longer-term (and converting to Python seems a likely future enhancement), but Perl was simpler short-term due to better string handling.

The other trick is this is using git fast-import. This is a lesser known portion of Git. Fully two-thirds of the lines in this script are interfacing with git fast-import. Unless you know the tool this is going to seem puzzling. I suggest playing with git fast-export --no-data if you want to learn more.

I would suggest running:

scripts/update_kernel.pl -6.1 -6.6
git merge --ff-only <sha1 provided>
scripts/update_kernel.pl -5.15 -6.6
git merge --ff-only <sha1 provided>

If this goes in.

@github-actions github-actions bot added the build/scripts/tools pull request/issues for build, scripts and tools related changes label Mar 16, 2024
@ehem
Copy link
Contributor Author

ehem commented Mar 16, 2024

On second thought, might be best for a maintainer to quickly grab the script out of the commit and run:

scripts/update_kernel.pl -6.1 -6.6
git merge --ff-only <sha1 provided>
scripts/update_kernel.pl -5.15 -6.6
git merge --ff-only <sha1 provided>

(or at least the first two lines, looks like several device update pull requests exist and at least some are not using the history-preserving scripts).

@ehem
Copy link
Contributor Author

ehem commented Mar 16, 2024

Quick check, 3 were using the other script, 3 were doing manual copy. While the ratio may improve in the future, that is a Bad Sign.

Problem is it will take years before enough history is preserved to be really valuable, but then it takes a single miss to destroy that history. In light of this, doing everything in one pass really does seem the right way to do it.

@namiltd
Copy link
Contributor

namiltd commented Mar 16, 2024

Take a look at this: #14713
Looks like someone beat you to it ;)

@hauke
Copy link
Member

hauke commented Mar 16, 2024

Please provide an example so that I can have a look at the result of this script.

@ehem
Copy link
Contributor Author

ehem commented Mar 16, 2024

Take a look at this: #14713 Looks like someone beat you to it ;)

Not really so (notice the date on this).

Please provide an example so that I can have a look at the result of this script.

Okay, since it is the example given, here. Beware, due to the structure of the merges, GitHub shows them backwards if you look at the commits online (easier to understand the blame data or log).

@ehem
Copy link
Contributor Author

ehem commented Mar 16, 2024

I should ask since it came to mind when examining #14713. How are devices currently without 6.1 configurations expected to be handled? Will they be required to skip 6.1 and immediately go to 6.6?

It would be possible to modify the script to take multiple source and/or destination versions. Something like scripts/kernel_upgrade.pl -s -5.15 -s -6.1 -d -6.1 -d -6.6 this would be handled by copying from -6.1 if it existed, but falling back to -5.15; and copying this to both -6.1 (if it doesn't exist) and -6.6.

This would be useful if the present situation is likely to occur again. This would synthesize 2 copy commits and 1 merge commit, instead of 2 copies and 2 merges (may look better in logs depending on PoV). Simply requires a degenerate octopus merge instead of 2 standard merges.

@hauke
Copy link
Member

hauke commented Mar 16, 2024

NACK, I do not like it

Using two times -C will make git blame to detect the moves:

git blame -C -C  target/linux/malta/config-6.1

After the first commit the tree is broken, git bisect will break with such commits which make the build break.
It takes some time to port each target we can not do it all in one shot. Doing such change for all targets will not work.

@ehem
Copy link
Contributor Author

ehem commented Mar 16, 2024

NACK, I do not like it

Using two times -C will make git blame to detect the moves:

git blame -C -C  target/linux/malta/config-6.1

Exactly the same as "--find-copies-harder" with the well documented problem. This is orders of magnitude slower than git blame without the option. This is the difference between a tool you can use on a regular basis to investigate minor oddities (thus avoiding breakage due to understanding a problem), versus one you take a coffee break while waiting for it to complete.

After the first commit the tree is broken, git bisect will break with such commits which make the build break. It takes some time to port each target we can not do it all in one shot. Doing such change for all targets will not work.

git bisect says on the label it is expected to find broken checkouts. The documentation suggests strategies for dealing with this because it is expected. If you can't deal with that then git bisect is not the tool for you!

There is a consensus having a few commits where git bisect fails, but git blame is fast is a good trade off.

There is an unresolved question of whether it is better to do this individually for each board, versus all boards at once. This is presenting the all boards at once strategy. Ends up being a question of whether it is worthwhile to have first-step copied kernel configs around for a long time while it is decided whether to drop a board versus updates being sluggish.

This approach has the advantage of there is a single bisect broken commit for each update, rather than >40 spread all over the place. This also makes it far easier to handle changing the fallback settings in generic, since you can update everything at once instead of having to continuously monitor for new board updates (this is truly a nightmare).

@ehem
Copy link
Contributor Author

ehem commented Mar 19, 2024

I'll be rebasing in a few hours, when I'll squash the third in. I've also got something others may like better for doing single device updates.

@ehem ehem force-pushed the script branch 2 times, most recently from 8e6a89d to 498ed9c Compare March 19, 2024 23:56
@ehem
Copy link
Contributor Author

ehem commented Mar 20, 2024

@hauke if you're truly that much against the idea, you'll need to revert 3561015. Otherwise most others think git blame being properly functional is kind of important.

@ehem
Copy link
Contributor Author

ehem commented Mar 23, 2024

An interesting issue was pointed out elsewhere, so update to take care of situation.

The second patch was adjusted for better efficiency.

@stintel
Copy link
Member

stintel commented Mar 24, 2024

OpenWrt is licensed GPL-2.0-only. Please use the same license if you expect the script to be accepted in this repo.

And if we're deliberately going to be breaking git bisect, please provide a git bisect script that is able to automatically skip these commits. Bisecting OpenWrt is painful enough already. If you don't know what I'm talking about, I suggest you give it a try yourself.

@ehem
Copy link
Contributor Author

ehem commented Mar 25, 2024

OpenWrt is licensed GPL-2.0-only. Please use the same license if you expect the script to be accepted in this repo.

That is certainly a topic for negotiation. Unless there is genuine hope this will be accepted you're not offering much in negotiation.

And if we're deliberately going to be breaking git bisect, please provide a git bisect script that is able to automatically skip these commits. Bisecting OpenWrt is painful enough already. If you don't know what I'm talking about, I suggest you give it a try yourself.

I haven't used git bisect with OpenWRT, but I can readily believe it is painful. Hard-coded URLs have an unpleasant tendency to expire if the upstream source moves. Several solutions come to mind:

  1. git submodule so many projects are using git, perhaps requiring git might now be acceptable. I haven't played with this, but there is a legion of "don't use this" reports.
  2. git subtree similar to git submodule, but with some differences. A similar tool with some advantages.
  3. Use FreeBSD's strategy. Create a directory for mirrored git trees. Merge all the tools into a subdirectory of the OpenWRT repository (from reading this may be similar to what git subtree does).
  4. Start mirroring all upstream tarballs.

There is the major issue of OpenWRT's build system being slow. Too much .NOTPARALLEL when now most developer machines are likely to have >12 processors. The FreeBSD project is worried about having too much single-threaded building, yet it still manages to average use of 10 of 24 processors during its build.

So yes, I can readily believe bisecting being painful. I don't know which reasons are your main concerns though. This doesn't break git bisect, it does generate a single unbuildable commit though. Yet even without this broken commits happen and you have to be able to cope with those during bisect sessions.

Perhaps you're proposing a change to the intermediate commit message to ensure it is more obvious not to try building it when git bisect shows you the single-line commit message? Perhaps standardize on unbuildable commits should start with "DONTBUILD", "DONOTBUILD", or "NONBUILD"? (this needs to be coordinated with #14913)

@ehem
Copy link
Contributor Author

ehem commented Apr 2, 2024

And if we're deliberately going to be breaking git bisect, please provide a git bisect script that is able to automatically skip these commits. Bisecting OpenWrt is painful enough already. If you don't know what I'm talking about, I suggest you give it a try yourself.

Uhm, I was kind of asking questions in order to figure out a best approach. Would be valuable to get a response...

@hauke and @stintel I regret to inform you the avalanche has already started, it is too late even for boulders to vote. Notice, 16edee9, e28492c and 25abc8f. I believe #14907 can do a better job with this (generate a single non-buildable commit per update, rather than one for every device), but without direct commit ability there is only so much I can do.

Guess I should concede git fast-import is riskier in some ways. It is readily able to synthesize arbitrary commits which command-line git won't allow. Yet in the hands of someone knowledgeable it is a powerful tool.

Create a script for automating kernel version changes.  This
generates a pair of commits which cause history to remain attached to
all versioned configuration files.

Crucially this makes `git blame` work without needing
--find-copies-harder, which is too slow for routine use.  This also
updates *everything*, which greatly simplifies rebasing patches
which effect multiple devices.

Credit to Christian Marangi who knew of the technique:
<https://lists.openwrt.org/pipermail/openwrt-devel/2023-October/041672.html>

Signed-off-by: Elliott Mitchell <ehem+openwrt@m5p.com>
@ehem ehem closed this Apr 3, 2024
@ehem ehem deleted the script branch April 3, 2024 22:26
@ehem
Copy link
Contributor Author

ehem commented Apr 3, 2024

Gah, screwing up commands dealing with remote repositories in a different way this time.

Slowly waking up the Perl writing skills. Adjusting some argument orders to better match with how things need to be done in Perl.

@ehem
Copy link
Contributor Author

ehem commented Apr 3, 2024

Okay, seems to be a 2 step process to reopen.

@ehem
Copy link
Contributor Author

ehem commented Apr 3, 2024

Okay, bit of a delay in GitHub processing things. Now to deal with the bug which showed up right when I pushed this. Hrmm. (have a suboptimal workaround, but I would like to do better).

…ript

This matches the way this has been handled in the past.  This could
also help devices which were skipped due to abandoned plans to drop.

Signed-off-by: Elliott Mitchell <ehem+openwrt@m5p.com>
@ehem
Copy link
Contributor Author

ehem commented Apr 3, 2024

Unless another device update has happened in the meantime (quite likely), I would suggest doing:

scripts/kernel_upgrade.pl -5.15 -6.1 at91 bcm47xx lantiq octeontx oxnas pistachio qoriq realtek tegra zynq
git merge --ff-only <given sha1>
scripts/kernel_upgrade.pl -6.1 -6.6
git merge --ff-only <given sha1>

When bringing this in. Point being to update everything which hasn't been updated. I'm distinctly unsure of this since I'm wondering whether it might be better for bcm47xx and the other devices still on 5.15 to simply skip 6.1.

Return part of the original design.  Issue is at some future time,
it could be possible for a versioned file to be created inside a
versioned directory.  Presently there are no cases of
"dir-<version>/file-<version>", but it seems best to be prepared for
this.

Alas, this points out `git fast-import` isn't really a proper binary
protocol.  There really needs to be a -0 option to allow arbitrary
filenames.

Signed-off-by: Elliott Mitchell <ehem+openwrt@m5p.com>
@@ -288,7 +288,7 @@ ()

foreach my $name (@$list) {
next if($git->ls($start, "$name$to"));
my $new=$git->ls($start, "$name$from");
my $new=$git->ls('', "\"$name$from\"");
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Then when looking some more, realize the quotes should instead be added in GitImporter->ls().

@ehem
Copy link
Contributor Author

ehem commented Apr 7, 2024

I've had that lurking for some time. I had noticed it was an issue, problem was I needed to reread the documentation several times to figure out why that hadn't been working.

I don't believe it actually matters right now, but I could see this being desired in the future.

if(index($_, $from, length($_)-length($from))>0);
}

@$ret=sort({length($b)-length($a)} @$ret);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Then go looking at things and @$ret=reverse(@$ret); should work here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
build/scripts/tools pull request/issues for build, scripts and tools related changes needs reviewer
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants