[PATCH 1/1] scripts: create kernel configuration upgrade script
Elliott Mitchell
ehem+openwrt at m5p.com
Tue Feb 6 17:16:41 PST 2024
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.
Signed-off-by: Elliott Mitchell <ehem+openwrt at m5p.com>
---
scripts/kernel_upgrade.pl | 191 ++++++++++++++++++++++++++++++++++++++
1 file changed, 191 insertions(+)
create mode 100755 scripts/kernel_upgrade.pl
diff --git a/scripts/kernel_upgrade.pl b/scripts/kernel_upgrade.pl
new file mode 100755
index 0000000000..6cebaec201
--- /dev/null
+++ b/scripts/kernel_upgrade.pl
@@ -0,0 +1,191 @@
+#!/usr/bin/env perl
+#
+# Copyright (C) 2024 Elliott Mitchell <ehem+openwrt at m5p.com>
+#
+# This is free software, licensed under the GNU General Public License v3.
+# See /LICENSE for more information.
+#
+
+use warnings;
+use strict;
+
+use feature 'state';
+
+die("wrong number of arguments") if(@ARGV!=2);
+
+my $start;
+
+my ($from, $to)=@ARGV;
+
+sub load()
+{
+ my $ret=[];
+
+ open(my $fd, '-|', 'git rev-parse HEAD');
+ $start=<$fd>;
+ chop($start);
+
+ local $/="\0";
+ open($fd, '-| :raw :bytes', "git ls-tree -trz --full-name --name-only HEAD -- target/linux")||die("failed to read git tree");
+
+ while(<$fd>) {
+ chop($_);
+ push(@$ret, substr($_, 0, -length($from))) if(substr($_, -length($from)) eq $from);
+ }
+
+ @$ret=sort({length($b)-length($a)} @$ret);
+
+ return $ret;
+}
+
+my $gitpid;
+my $gitfds=[undef, undef];
+
+sub startgit()
+{
+ my $child=[];
+ (pipe($child->[0], $gitfds->[0])&&pipe($gitfds->[1], $child->[1])) ||
+die("pipe() failed");
+ binmode($gitfds->[0]);
+ binmode($gitfds->[1]);
+
+ $gitpid=fork();
+ if($gitpid) {
+ close($child->[0]);
+ close($child->[1]);
+ $gitfds->[0]->autoflush(1);
+ } elsif($gitpid==0) {
+ close($gitfds->[0]);
+ close($gitfds->[1]);
+
+ open(STDIN, '<&', $child->[0]);
+ close($child->[0]);
+
+ open(STDOUT, '>&', $child->[1]);
+ close($child->[1]);
+
+ exec('git', 'fast-import', '--done');
+ die('exec() of git failed');
+ } else {
+ die('fork() failed');
+ }
+}
+
+sub gitsend
+{
+ return print({$gitfds->[0]} @_);
+}
+
+sub gitrecv()
+{
+ return $_=readline(${$gitfds}[1]);
+}
+
+sub gitls($$)
+{
+ my ($commit, $name)=@_;
+ local $/="\n";
+ gitsend("ls $commit $name\n");
+ gitrecv();
+
+ die('git ls failed') unless(/^([0-8]+)\s+[a-z]+\s+([0-9a-z]+)\s+.+$/);
+
+ return [$1, $2];
+}
+
+sub gitcommit($$$$)
+{
+ my ($dest, $message, $mark, $branch)=@_;
+ local $/="\n";
+ local $|=1;
+ state $author=undef;
+ unless($author) {
+ $author=['', ''];
+ open(my $user, '-|', 'git', 'config', '--get', 'user.name');
+ while(<$user>) {
+ chomp;
+ $author->[0].=$_;
+ }
+ $author->[0]=[split(/,/, [getpwuid($<)]->[6])]->[0] unless($author->[0]);
+
+ open(my $email, '-|', 'git', 'config', '--get', 'user.email');
+ while(<$email>) {
+ chomp;
+ $author->[1].=$_;
+ }
+ $author->[1]='anonymous at example.com' unless($author->[1]);
+
+ $author=$author->[0].' <'.$author->[1].'>';
+ }
+ gitsend("commit $branch\n");
+ gitsend("mark $mark\n");
+ gitsend("committer $author ".time()." +0000\n");
+
+ $_=length($message);
+ gitsend("data $_\n");
+ gitsend($message);
+ gitsend("from $dest\n");
+}
+
+sub gitdone()
+{
+ local $/="\n";
+ gitsend("done\n");
+ close($gitfds->[0]);
+ $gitfds->[0]=undef;
+ 0 while(waitpid($gitpid, 0) != $gitpid);
+ print(STDERR "WARNING: git returned error exit status\n") if($?);
+ close($gitfds->[1]);
+ $gitfds->[1]=undef;
+}
+
+my $list=load();
+
+die("no files matching \"$from\" found") unless(@$list);
+
+startgit();
+
+
+gitcommit($start, <<"__TMP__", ':1', 'tmp');
+kernel: add configs and patches for $to
+
+Copy the configuration and patches from $from to $to.
+
+This is a special tool-generated commit.
+__TMP__
+
+foreach my $name (@$list) {
+ my $new=gitls($start, "$name$from");
+ gitsend("M $new->[0] $new->[1] $name$to\n");
+ gitsend("D $name$from\n");
+}
+gitsend("\n");
+
+
+gitcommit(':1', <<"__TMP__", ':2', "end");
+kernel: finish update from $from to $to
+
+Merge the add commit into HEAD to create all files with full history.
+
+This is a special tool-generated commit.
+__TMP__
+
+gitsend("merge $start\n");
+
+foreach my $name (@$list) {
+ my $new=gitls($start, "$name$from");
+ gitsend("M $new->[0] $new->[1] $name$from\n");
+}
+gitsend("\n");
+
+
+gitsend("get-mark :2\n");
+my $result=gitrecv();
+
+gitdone();
+
+print("Result is commit $result\n");
+
+exec('git', 'merge', '--ff-only', $result);
+
+exit(0);
--
(\___(\___(\______ --=> 8-) EHM <=-- ______/)___/)___/)
\BS ( | ehem+sigmsg at m5p.com PGP 87145445 | ) /
\_CS\ | _____ -O #include <stddisclaimer.h> O- _____ | / _/
8A19\___\_|_/58D2 7E3D DDF4 7BA6 <-PGP-> 41D1 B375 37D0 8714\_|_/___/5445
More information about the openwrt-devel
mailing list