diff --git a/Build.pm b/Build.pm index 3f49dd8f1..f07a92f3f 100644 --- a/Build.pm +++ b/Build.pm @@ -1354,6 +1354,7 @@ sub query { return Build::Kiwi::queryiso($handle, %opts) if $do_kiwi && $binname =~ /\.iso$/; return Build::Arch::query($handle, %opts) if $do_arch && $binname =~ /\.pkg\.tar(?:\.gz|\.xz|\.zst)?$/; return Build::Arch::query($handle, %opts) if $do_arch && $binname =~ /\.arch$/; + return Build::Mkosi::queryiso($handle, %opts) if $do_mkosi && $binname =~ /\.(raw|tar|cpio|qcow2)(?:\.gz|\.xz|\.zstd)?$/; return undef; } @@ -1379,6 +1380,7 @@ sub queryhdrmd5 { my ($binname) = @_; return Build::Rpm::queryhdrmd5(@_) if $do_rpm && $binname =~ /\.d?rpm$/; return Build::Deb::queryhdrmd5(@_) if $do_deb && $binname =~ /\.deb$/; + return Build::Mkosi::queryhdrmd5(@_) if $do_mkosi && $binname =~ /\.(raw|tar|cpio|qcow2)(?:\.gz|\.xz|\.zstd)?$/; return Build::Kiwi::queryhdrmd5(@_) if $do_kiwi && $binname =~ /\.iso$/; return Build::Kiwi::queryhdrmd5(@_) if $do_kiwi && $binname =~ /\.raw$/; return Build::Kiwi::queryhdrmd5(@_) if $do_kiwi && $binname =~ /\.raw.install$/; diff --git a/Build/Mkosi.pm b/Build/Mkosi.pm index 8a9dd9c26..15b373ad6 100644 --- a/Build/Mkosi.pm +++ b/Build/Mkosi.pm @@ -67,6 +67,9 @@ sub parse { if (length $cfg->val('Content', 'BuildPackages')) { push(@packages, split /\s+/, $cfg->val('Content', 'BuildPackages')); } + if (length $cfg->val('Partitions', 'BaseImage')) { + push(@packages, $cfg->val('Partitions', 'BaseImage')); + } $ret->{'name'} = $fn; $ret->{'deps'} = \@packages; @@ -74,4 +77,65 @@ sub parse { return $ret; } +sub queryiso { + my ($file, %opts) = @_; + my $json_fh; + my $md5 = Digest::MD5->new; + + open(my $fh, '<', $file) or die("Error opening $file: $!\n"); + $md5->addfile($fh); + close($fh); + # If we also have split verity artifacts, the manifest file is the same as the main image, + # so remove the suffixes to find it + $file =~ s/(\.root|\.usr)//g; + $file = $file . ".manifest.gz"; + + eval { require JSON; }; + *JSON::decode_json = sub {die("JSON::decode_json is not available\n")} unless defined &JSON::decode_json; + + eval { require IO::Uncompress::Gunzip; }; + *IO::Uncompress::Gunzip::new = sub {die("IO::Uncompress::Gunzip is not available\n")} unless defined &IO::Uncompress::Gunzip::new; + + my $json_text = do { + open($json_fh, "<", $file) or die("Error opening $file: $!\n"); + $json_fh = IO::Uncompress::Gunzip->new($json_fh) or die("Error opening $file: $IO::Uncompress::Gunzip::GunzipError\n"); + local $/; + <$json_fh> + }; + + my $metadata = JSON::decode_json($json_text); + close $json_fh; + + if (!$metadata || !$metadata->{'config'}) { + return {}; + } + + my $distribution = $metadata->{'config'}->{'distribution'}; + my $release = $metadata->{'config'}->{'release'}; + my $architecture = $metadata->{'config'}->{'architecture'}; + my $name = $metadata->{'config'}->{'name'}; + my $version = $metadata->{'config'}->{'version'}; + my @provides = ("$distribution:$release"); + + return { + 'provides' => \@provides, + 'version' => $version, + 'arch' => $architecture, + 'name' => $name, + 'source' => $name, + 'hdrmd5' => $md5->hexdigest(), + }; +} + +sub queryhdrmd5 { + my ($bin) = @_; + + open(my $fh, '<', $bin) or croak("could not open $bin"); + my $md5 = Digest::MD5->new; + $md5->addfile($fh); + close($fh); + + return $md5->hexdigest(); +} + 1; diff --git a/PBuild/BuildResult.pm b/PBuild/BuildResult.pm index 79e1666ea..c67f6a813 100644 --- a/PBuild/BuildResult.pm +++ b/PBuild/BuildResult.pm @@ -126,6 +126,13 @@ sub integrate_build_result { my $obsbinlnk = PBuild::Container::containerinfo2obsbinlnk($1, $2, $p->{'pkg'}); PBuild::Util::store("$dst/$prefix.obsbinlnk", undef, $obsbinlnk) if $obsbinlnk; } + if ($file =~ /(.*)\.manifest(?:\.(?:gz|bz2|xz|zst|zstd))?$/) { + # create an obsbinlnk file from the mkosi manifest + my $prefix = $1; + die unless $result->{$file} =~ /^(.*)\/([^\/]+)$/; + my $obsbinlnk = PBuild::Container::manifest2obsbinlnk($1, $2, $prefix, $p->{'pkg'}); + PBuild::Util::store("$dst/$prefix.obsbinlnk", undef, $obsbinlnk) if $obsbinlnk; + } PBuild::Util::cp($result->{$file}, "$dst/$file"); } # create new bininfo diff --git a/PBuild/Container.pm b/PBuild/Container.pm index e63cf61d0..e21968903 100644 --- a/PBuild/Container.pm +++ b/PBuild/Container.pm @@ -28,8 +28,66 @@ use PBuild::Verify; eval { require JSON::XS }; *JSON::XS::decode_json = sub {die("JSON::XS is not available\n")} unless defined &JSON::XS::decode_json; +eval { require IO::Uncompress::Gunzip; }; +*IO::Uncompress::Gunzip::new = sub {die("IO::Uncompress::Gunzip is not available\n")} unless defined &IO::Uncompress::Gunzip::new; + use strict; +sub manifest2obsbinlnk { + my ($dir, $file, $prefix, $packid) = @_; + my $json_fh; + my $md5 = Digest::MD5->new; + my $image; + my $json_text = do { + unless (open($json_fh, "<", "$dir/$file")) { + warn("Error opening $dir/$file: $!\n"); + return {}; + } + if ($file =~ /\.gz$/) { + $json_fh = IO::Uncompress::Gunzip->new($json_fh) or die("Error opening $dir/$file: $IO::Uncompress::Gunzip::GunzipError\n"); + } + local $/; + <$json_fh> + }; + + my $metadata = JSON::XS::decode_json($json_text); + if (!$metadata || !$metadata->{'config'}) { + return {}; + } + + foreach my $ext ("", ".gz", ".xz", ".zst", ".zstd") { + if (-e "$dir/$prefix$ext") { + open(my $fh, '<', "$dir/$prefix$ext") or die("Error opening $dir/$prefix$ext: $!\n"); + $md5->addfile($fh); + close($fh); + $image = $prefix . $ext; + last; + } + } + if (!$image) { + return {}; + } + + my $distribution = $metadata->{'config'}->{'distribution'}; + my $release = $metadata->{'config'}->{'release'}; + my $architecture = $metadata->{'config'}->{'architecture'}; + my $name = $metadata->{'config'}->{'name'}; + my $version = $metadata->{'config'}->{'version'}; + # Note: release here is not the RPM release, but the distribution release (eg: Debian 10) + my @provides = ("$distribution:$release", "$name = $version", "$packid = $version"); + + return { + 'provides' => \@provides, + 'source' => $packid, + 'name' => $name, + 'version' => $version, + 'release' => '0', + 'arch' => $architecture, + 'hdrmd5' => $md5->hexdigest(), + 'lnk' => $image, + }; +} + sub containerinfo2nevra { my ($d) = @_; my $lnk = {}; diff --git a/build-vm-qemu b/build-vm-qemu index 7d85a06d4..9a999de48 100644 --- a/build-vm-qemu +++ b/build-vm-qemu @@ -88,6 +88,7 @@ vm_startup_qemu() { x86_64) qemu_bin="/usr/bin/qemu-system-x86_64" qemu_cpu="-cpu qemu64" + qemu_device=virtio-blk # Use defaults and fallbacks for other values ;; # @@ -213,7 +214,7 @@ vm_kill_qemu() { vm_fixup_qemu() { vm_fixup_kvm case $BUILD_HOST_ARCH in - armv6l|armv7l|armv8l|aarch32|aarch64|aarch64_ilp32|ppc|ppcle|ppc64|ppc64le|riscv64|s390|s390x) + armv6l|armv7l|armv8l|aarch32|aarch64|aarch64_ilp32|ppc|ppcle|ppc64|ppc64le|riscv64|s390|s390x|x86_64) VM_ROOTDEV=/dev/disk/by-id/virtio-0 VM_SWAPDEV=/dev/disk/by-id/virtio-1 ;;