一、pve-enterprise.list,文件路径/etc/apt/sources.list.d/pve-enterprise.list:
deb https://enterprise.proxmox.com/debian/pve bookworm pve-enterprise
二、sources.list,文件路径/etc/apt/sources.list:
deb http://ftp.debian.org/debian bookworm main contrib deb http://ftp.debian.org/debian bookworm-updates main contrib # security updates deb http://security.debian.org bookworm-security main contrib
三、ceph.list,文件路径/etc/apt/sources.list.d/ceph.list:
deb https://enterprise.proxmox.com/debian/ceph-quincy bookworm enterprise
五、APLInfo.pm,文件路径为/usr/share/perl5/PVE/APLInfo.pm:
package PVE::APLInfo;
use strict;
use warnings;
use IO::File;
use LWP::UserAgent;
use POSIX qw(strftime);
use PVE::SafeSyslog;
use PVE::Storage;
use PVE::Tools qw(run_command);
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|.*/([^/]+$PVE::Storage::vztmpl_extension_re)$|$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, $aplinfo, $logfd) = @_;
my $aplsrcurl = "$aplinfo->{url}/$aplinfo->{file}.gz";
my $aplsigurl = "$aplinfo->{url}/$aplinfo->{file}.asc";
my $host = $aplinfo->{host};
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 { 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";
my $logfunc = sub { logmsg($logfd, "signature verification: $_[0]"); };
eval {
run_command($cmd, outfunc => $logfunc, errfunc => $logfunc);
};
die "unable to verify signature - $@\n" if $@;
# test syntax
eval { read_aplinfo($tmp, {}, $aplinfo->{url}, 1) };
die "update failed: $@" if $@;
rename($tmp, "$aplinfodir/$host") or
die "update failed: unable to store data: $!\n";
logmsg($logfd, "update successful");
};
my $err = $@;
unlink $tmp;
unlink $tmpgz;
unlink $sigfn;
die $err if $err;
}
sub get_apl_sources {
my $sources = [
{
host => "download.proxmox.com",
url => "http://download.proxmox.com/images",
file => 'aplinfo-pve-8.dat',
},
{
host => "releases.turnkeylinux.org",
url => "https://releases.turnkeylinux.org/pve",
file => 'aplinfo.dat',
},
];
return $sources;
}
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 $sources = get_apl_sources();
mkdir $aplinfodir;
my @dlerr = ();
foreach my $info (@$sources) {
eval {
download_aplinfo($ua, $info, $logfd);
};
if (my $err = $@) {
logmsg ($logfd, $err);
push @dlerr, $info->{url};
}
}
close($logfd);
return 0 if scalar(@dlerr);
return 1;
}
sub load_data {
my $sources = get_apl_sources();
my $list = {};
foreach my $info (@$sources) {
eval {
my $host = $info->{host};
read_aplinfo("$aplinfodir/$host", $list, $info->{url});
};
warn $@ if $@;
}
return $list;
}
1;
原创文章,作者:开心电脑网,如若转载,请注明出处。