mirror of
https://git.proxmox.com/git/pve-manager
synced 2025-06-13 07:35:40 +00:00

Wit commit a74ba607d4
we switched over
to using the dpkg-dev provided helpers to set package version,
architecture and such in the buildsystem.
But unlike other repositories we used the version also for giving it
back over the API through the during build generated PVE::pvecfg
module, which wasn't fully updated to the new style.
This patch does that, and also cleans up semantics a bit, the
following two changed:
release is now the Debian release, instead of the "package release"
(i.e., the -X part of a full package version).
version is now simply the full (pve-manager) version, e.g., 6.0-1 or
the currently for testing used 6.0-0+1
This allows to do everything we used this information for even in a
slightly easier way (no string concat needed anymore), and fits also
with the terminology we often used in our public channels (mailing
lists, forum, website)
Remove some cruft as we touch things.
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
280 lines
6.0 KiB
Perl
280 lines
6.0 KiB
Perl
package PVE::APLInfo;
|
|
|
|
use strict;
|
|
use warnings;
|
|
use IO::File;
|
|
use PVE::SafeSyslog;
|
|
use PVE::Tools;
|
|
use LWP::UserAgent;
|
|
use POSIX qw(strftime);
|
|
use PVE::pvecfg;
|
|
|
|
my $logfile = "/var/log/pveam.log";
|
|
my $aplinfodir = "/var/lib/pve-manager/apl-info";
|
|
|
|
sub logmsg {
|
|
my ($logfd, $msg) = @_;
|
|
|
|
chomp $msg;
|
|
|
|
my $tstr = strftime ("%F %H:%M:%S", localtime);
|
|
|
|
foreach my $line (split (/\n/, $msg)) {
|
|
print $logfd "$tstr $line\n";
|
|
}
|
|
}
|
|
|
|
sub read_aplinfo_from_fh {
|
|
my ($fh, $list, $source, $update) = @_;
|
|
|
|
local $/ = "";
|
|
|
|
while (my $rec = <$fh>) {
|
|
chomp $rec;
|
|
|
|
my $res = {};
|
|
|
|
while ($rec) {
|
|
|
|
if ($rec =~ s/^Description:\s*([^\n]*)(\n\s+.*)*$//si) {
|
|
$res->{headline} = $1;
|
|
my $long = $2 || '';
|
|
$long =~ s/\n\s+/ /g;
|
|
$long =~ s/^\s+//g;
|
|
$long =~ s/\s+$//g;
|
|
$res->{description} = $long;
|
|
} elsif ($rec =~ s/^Version:\s*(.*\S)\s*\n//i) {
|
|
my $version = $1;
|
|
if ($version =~ m/^(\d[a-zA-Z0-9\.\+\-\:\~]*)(-(\d+))?$/) {
|
|
$res->{version} = $version;
|
|
} else {
|
|
my $msg = "unable to parse appliance record: version = '$version'\n";
|
|
$update ? die $msg : warn $msg;
|
|
}
|
|
} elsif ($rec =~ s/^Type:\s*(.*\S)\s*\n//i) {
|
|
my $type = $1;
|
|
if ($type =~ m/^(openvz|lxc)$/) {
|
|
$res->{type} = $type;
|
|
} else {
|
|
my $msg = "unable to parse appliance record: unknown type '$type'\n";
|
|
$update ? die $msg : warn $msg;
|
|
}
|
|
} elsif ($rec =~ s/^([^:]+):\s*(.*\S)\s*\n//) {
|
|
$res->{lc $1} = $2;
|
|
} else {
|
|
my $msg = "unable to parse appliance record: $rec\n";
|
|
$update ? die $msg : warn $msg;
|
|
$res = {};
|
|
last;
|
|
}
|
|
}
|
|
|
|
if ($res->{'package'} eq 'pve-web-news' && $res->{description}) {
|
|
$list->{'all'}->{$res->{'package'}} = $res;
|
|
next;
|
|
}
|
|
|
|
$res->{section} = 'unknown' if !$res->{section};
|
|
|
|
if ($res->{'package'} && $res->{type} && $res->{os} && $res->{version} &&
|
|
$res->{infopage}) {
|
|
my $template;
|
|
if ($res->{location}) {
|
|
$template = $res->{location};
|
|
$template =~ s|.*/([^/]+.tar.[gx]z)$|$1|;
|
|
if ($res->{location} !~ m|^([a-zA-Z]+)\://|) {
|
|
# relative localtion (no http:// prefix)
|
|
$res->{location} = "$source/$res->{location}";
|
|
}
|
|
} else {
|
|
my $arch = $res->{architecture} || 'i386';
|
|
$template = "$res->{os}-$res->{package}_$res->{version}_$arch.tar.gz";
|
|
$template =~ s/$res->{os}-$res->{os}-/$res->{os}-/;
|
|
$res->{location} = "$source/$res->{section}/$template";
|
|
}
|
|
$res->{source} = $source;
|
|
$res->{template} = $template;
|
|
$list->{$res->{section}}->{$template} = $res;
|
|
$list->{'all'}->{$template} = $res;
|
|
} else {
|
|
my $msg = "found incomplete appliance records\n";
|
|
$update ? die $msg : warn $msg;
|
|
}
|
|
}
|
|
}
|
|
|
|
sub read_aplinfo {
|
|
my ($filename, $list, $source, $update) = @_;
|
|
|
|
my $fh = IO::File->new("<$filename") ||
|
|
die "unable to open file '$filename' - $!\n";
|
|
|
|
eval { read_aplinfo_from_fh($fh, $list, $source, $update); };
|
|
my $err = $@;
|
|
|
|
close($fh);
|
|
|
|
die $err if $err;
|
|
|
|
return $list;
|
|
}
|
|
|
|
sub url_get {
|
|
my ($ua, $url, $file, $logfh) = @_;
|
|
|
|
my $req = HTTP::Request->new(GET => $url);
|
|
|
|
logmsg ($logfh, "start download $url");
|
|
my $res = $ua->request($req, $file);
|
|
|
|
if ($res->is_success) {
|
|
logmsg ($logfh, "download finished: " . $res->status_line);
|
|
return 0;
|
|
}
|
|
|
|
logmsg ($logfh, "download failed: " . $res->status_line);
|
|
|
|
return 1;
|
|
}
|
|
|
|
sub download_aplinfo {
|
|
my ($ua, $aplurl, $host, $logfd) = @_;
|
|
|
|
my $aplsrcurl = "$aplurl/aplinfo.dat.gz";
|
|
my $aplsigurl = "$aplurl/aplinfo.dat.asc";
|
|
|
|
my $tmp = "$aplinfodir/pveam-${host}.tmp.$$";
|
|
my $tmpgz = "$tmp.gz";
|
|
my $sigfn = "$tmp.asc";
|
|
|
|
eval {
|
|
|
|
if (url_get($ua, $aplsigurl, $sigfn, $logfd) != 0) {
|
|
die "update failed - no signature file '$sigfn'\n";
|
|
}
|
|
|
|
if (url_get($ua, $aplsrcurl, $tmpgz, $logfd) != 0) {
|
|
die "update failed - no data file '$aplsrcurl'\n";
|
|
}
|
|
|
|
eval {
|
|
PVE::Tools::run_command(["gunzip", "-f", $tmpgz]);
|
|
};
|
|
die "update failed: unable to unpack '$tmpgz'\n" if $@;
|
|
|
|
|
|
|
|
# verify signature
|
|
my $trustedkeyring = "/usr/share/doc/pve-manager/trustedkeys.gpg";
|
|
my $cmd = "/usr/bin/gpgv -q --keyring $trustedkeyring $sigfn $tmp";
|
|
|
|
eval {
|
|
my $logfunc = sub {
|
|
my $line = shift;
|
|
logmsg($logfd, "signature verification: $line");
|
|
};
|
|
|
|
PVE::Tools::run_command($cmd,
|
|
outfunc => $logfunc,
|
|
errfunc => $logfunc);
|
|
};
|
|
die "unable to verify signature - $@\n" if $@;
|
|
|
|
# test syntax
|
|
eval {
|
|
read_aplinfo($tmp, {}, $aplurl, 1);
|
|
};
|
|
die "update failed: $@" if $@;
|
|
|
|
if (!rename($tmp, "$aplinfodir/$host")) {
|
|
die "update failed: unable to store data\n";
|
|
}
|
|
|
|
logmsg($logfd, "update sucessful");
|
|
};
|
|
|
|
my $err = $@;
|
|
|
|
unlink $tmp;
|
|
unlink $tmpgz;
|
|
unlink $sigfn;
|
|
|
|
die $err if $err;
|
|
}
|
|
|
|
sub get_apl_sources {
|
|
|
|
my $urls = [];
|
|
push @$urls, "http://download.proxmox.com/images";
|
|
push @$urls, "https://releases.turnkeylinux.org/pve";
|
|
|
|
return $urls;
|
|
}
|
|
|
|
sub update {
|
|
my ($proxy) = @_;
|
|
|
|
my $size;
|
|
if (($size = (-s $logfile) || 0) > (1024*50)) {
|
|
rename($logfile, "$logfile.0");
|
|
}
|
|
my $logfd = IO::File->new (">>$logfile");
|
|
logmsg($logfd, "starting update");
|
|
|
|
my $ua = LWP::UserAgent->new;
|
|
my $release = PVE::pvecfg::release();
|
|
$ua->agent("PVE/$release");
|
|
|
|
if ($proxy) {
|
|
$ua->proxy(['http', 'https'], $proxy);
|
|
} else {
|
|
$ua->env_proxy;
|
|
}
|
|
|
|
my $urls = get_apl_sources();
|
|
|
|
mkdir $aplinfodir;
|
|
|
|
my @dlerr = ();
|
|
foreach my $aplurl (@$urls) {
|
|
eval {
|
|
my $uri = URI->new($aplurl);
|
|
my $host = $uri->host();
|
|
download_aplinfo($ua, $aplurl, $host, $logfd);
|
|
};
|
|
if (my $err = $@) {
|
|
logmsg ($logfd, $err);
|
|
push @dlerr, $aplurl;
|
|
}
|
|
}
|
|
|
|
close($logfd);
|
|
|
|
return 0 if scalar(@dlerr);
|
|
|
|
return 1;
|
|
}
|
|
|
|
sub load_data {
|
|
|
|
my $urls = get_apl_sources();
|
|
|
|
my $list = {};
|
|
|
|
foreach my $aplurl (@$urls) {
|
|
|
|
eval {
|
|
|
|
my $uri = URI->new($aplurl);
|
|
my $host = $uri->host();
|
|
read_aplinfo("$aplinfodir/$host", $list, $aplurl);
|
|
};
|
|
warn $@ if $@;
|
|
}
|
|
|
|
return $list;
|
|
}
|
|
|
|
1;
|
|
|