[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Shipping the mini.iso files with the installer-images package?



So.

On Wed, Dec 13, 2023 at 10:45:36AM +0200, Wouter Verhelst wrote:
> That sounds like a much more reasonable way forward, although I'm not
> keen on extending di-netboot-assistant (it's massive already, and does
> very different things). At any rate, I'll have a look at implementing
> this. Thanks for the suggestion!

This turned out to be fairly simple in the end. First, create a apt.conf
file like so:

Acquire::IndexTargets::deb::SHA256SUMS {
	MetaKey "$(COMPONENT)/installer-$(ARCHITECTURE)/current/images/SHA256SUMS";
	ShortDescription "SHA256SUMS";
	Description "$(RELEASE)/$(COMPONENT) $(ARCHITECTURE) d-i SHA256SUMS (deb)";
};

Next, create a config file like this:

images:
  mini.iso:
    mirror_type: deb
    limit:
      Suite: stable
      Architecture: amd64
    basedir: main/installer-amd64/current/images
    relative_name: ./netboot/gtk/mini.iso
    target_filename: /var/lib/libvirt/images/bookworm-mini.iso
  netboot.iso:
    mirror_type: cd
    basedir: current/amd64/iso-cd
    filename_regex: debian-[0-9.]+-amd64-netinst.iso
    target_filename: /var/lib/libvirt/images/bookworm-netinst.iso

And then once you have that, the following perl script should do the
job.

(config file stored either as /etc/debian-isosync/config.yaml or
passed as the first argument to the script)

---
#!/usr/bin/perl -w

use v5.36;

use Crypt::Digest::SHA256 qw/sha256_file_hex/;
use YAML::XS qw/LoadFile Dump/;
use Dpkg::Control::HashCore;
use LWP::UserAgent;
use File::Temp qw/tempdir/;

my $ua = LWP::UserAgent->new(show_progress => 1);
$ua->env_proxy;

my $cfilename = shift;
if(!defined($cfilename)) {
	$cfilename = "/etc/debian-isosync/config.yaml";
}

my $cfile = LoadFile($cfilename) or die $!;

die "need list of images in config file" unless exists($cfile->{images});
die "images setting in config file is not a hash" unless ref($cfile->{images}) eq "HASH";

sub get_apt_sha256sum {
	my $rv = [];
	my $found;
	open my $indextargets, "-|", "apt-get", "indextargets";
	do {
		my $indexes = Dpkg::Control::HashCore->new;
		$found = $indexes->parse($indextargets, "index targets");
		push @$rv, $indexes if $found;
	} while $found;

	close $indextargets;

	return $rv;
}

sub ensure_file($url, $sha256_expected, $filename) {
	if(-f $filename) {
		my $sha256sum_found = sha256_file_hex($filename);
		if ($sha256sum_found eq $sha256_expected) {
			say "$filename is up-to-date, no update required";
			return;
		}
	} else {
		say "$filename not found, downloading";
	}
	$ua->get($url, ":content_file" => $filename);
}

NAME:
foreach my $name(keys %{$cfile->{images}}) {
	say "checking $name...";
	my $image = $cfile->{images}{$name};
	die "invalid entry $name in config file: missing mirror type" unless exists($image->{mirror_type});
	die "invalid entry $name in config file: missing directory with SHA256SUMS file" unless exists($image->{basedir});
	die "invalid entry $name in config file: missing target filename" unless exists($image->{target_filename});
	next if $image->{disabled};

	if($image->{mirror_type} eq "deb") {
		die "invalid entry $name in config file: missing relative filename" unless exists($image->{relative_name});
		my $indexes = get_apt_sha256sum;
		INDEX:
		foreach my $index(@$indexes) {
			next INDEX unless $index->{ShortDesc} eq "SHA256SUMS";
			if(exists($image->{limit})) {
				foreach my $limit(keys %{$image->{limit}}) {
					next INDEX unless $index->{$limit} eq $image->{limit}{$limit};
				}
			}
			open my $shafile, "<", $index->{Filename};
			my $sha256sum_expected;
			SHASUM:
			while(my $line = <$shafile>) {
				chomp $line;
				my $filename;
				($sha256sum_expected, $filename) = split /\s+/, $line;
				last SHASUM if $filename eq $image->{relative_name};
				$sha256sum_expected = undef;
			}
			next INDEX unless defined($sha256sum_expected);
			ensure_file(join('/', $index->{"Base-URI"}, $image->{basedir}, $image->{relative_name}), $sha256sum_expected, $image->{target_filename});
			last INDEX;
		}
	} elsif($image->{mirror_type} eq "cd") {
		die "invalid entry $name in config file: missing filename regex" unless exists($image->{filename_regex});
		next if $image->{disabled};

		my $dir = tempdir(CLEANUP => 1);
		$ua->get("https://cdimage.debian.org/debian-cd/"; . $image->{basedir} . "/SHA256SUMS", ":content_file" => "$dir/SHA256SUMS");
		$ua->get("https://cdimage.debian.org/debian-cd/"; . $image->{basedir} . "/SHA256SUMS.sign", ":content_file" => "$dir/SHA256SUMS.gpg");
		open my $gpgv, "-|", "gpgv", "--status-fd", "1", "--keyring", "/usr/share/keyrings/debian-role-keys.gpg", "$dir/SHA256SUMS.gpg", "$dir/SHA256SUMS";
		my $found_validsig = 0;
		while(my $line = <$gpgv>) {
			next unless $line =~ /^\[GNUPG:\] VALIDSIG/;
			$found_validsig++;
		}
		die "could not download for $name: no valid SHA256SUMS signature found" unless $found_validsig;
		close $gpgv;
		open my $shafile, "<", "$dir/SHA256SUMS";
		my $sha256sum_expected;
		my $filename;
		SHASUM:
		while(my $line = <$shafile>) {
			chomp $line;
			($sha256sum_expected, $filename) = split /\s+/, $line;
			last SHASUM if $filename =~ $image->{filename_regex};
			$sha256sum_expected = undef;
		}
		die "could not download for $name: file not found in SHA256SUMS" unless defined($sha256sum_expected);
		ensure_file("https://cdimage.debian.org/debian-cd/"; . $image->{basedir} . "/" . $filename, $sha256sum_expected, $image->{target_filename});
	} else {
		die "unknown mirror type " . $image->{mirror_type} . "\n";
	}
}
---

I'm not sure whether this is sufficiently useful to upload to the
archive... thoughts?

-- 
     w@uter.{be,co.za}
wouter@{grep.be,fosdem.org,debian.org}

I will have a Tin-Actinium-Potassium mixture, thanks.


Reply to: