package PVE::APLInfo;
use strict;
use IO::File;
use PVE::SafeSyslog;
use PVE::I18N;
use LWP::UserAgent;
use PVE::Config;
use POSIX qw(strftime);
my @channels = (
{'name' => 'proxmox',
'index' => 'http://download.proxmox.com/appliances/aplinfo.dat.gz',
'indexsig' => 'http://download.proxmox.com/appliances/aplinfo.dat.asc',
'keyid' => '5CAC72FE',
'keyserver' => '',
'keyfile' => '/usr/share/doc/pve-manager/support@proxmox.com.pubkey'},
{'name' => 'turnkeylinux',
'index' => 'http://releases.turnkeylinux.org/pve/aplinfo.dat.gz',
'indexsig' => 'http://releases.turnkeylinux.org/pve/aplinfo.dat.asc',
'keyid' => 'A16EB94D',
'keyserver' => 'hkp://keyserver.ubuntu.com',
'keyfile' => ''},
);
my $logfile = "/var/log/pveam.log";
sub logmsg {
my ($logfd, $msg) = @_;
print "debug: $msg\n";
chomp $msg;
my $tstr = strftime ("%b %d %H:%M:%S", localtime);
foreach my $line (split (/\n/, $msg)) {
print $logfd "$tstr $line\n";
}
}
sub url_get {
my ($ua, $url, $file, $logfh) = @_;
my $req = HTTP::Request->new(GET => $url);
logmsg ($logfh, "url_get: $url");
my $res = $ua->request($req, $file);
if ($res->is_success) {
logmsg ($logfh, "url_get: " . $res->status_line);
return 0;
}
logmsg ($logfh, "url_get: " . $res->status_line);
return 1;
}
sub update {
my ($proxy) = @_;
my $size;
if (($size = (-s $logfile) || 0) > (1024*50)) {
system ("mv $logfile $logfile.0");
}
my $logfd = IO::File->new (">>$logfile");
logmsg ($logfd, "channel updates: initiated");
my $tmpapl = "/tmp/pveam.apl.tmp.$$";
system ("rm -f $tmpapl");
eval {
for (my $i=0; $i < scalar (@channels); $i++) {
my $name = $channels[$i]{'name'};
logmsg ($logfd, "$name: starting...");
my $tmp = "/tmp/pveam.$name.tmp.$$";
my $tmpgz = "$tmp.gz";
my $sigfn = "$tmp.asc";
# setup user-agent, proxy. supports ftp and http.
local $ENV{FTP_PASSIVE} = 1;
my $ua = LWP::UserAgent->new;
$ua->agent("PVE/1.0");
if ($proxy) { $ua->proxy(['http'], $proxy);
} else { $ua->env_proxy; }
# pull index and gpg sig
logmsg ($logfd, "$name: getting index signature");
if (url_get ($ua, $channels[$i]{'indexsig'}, $sigfn, $logfd) != 0) {
die "$name: update failed - no signature\n";
}
logmsg ($logfd, "$name: getting index");
if (url_get ($ua, $channels[$i]{'index'}, $tmpgz, $logfd) != 0) {
die "$name: update failed - no data\n";
}
if (system ("zcat -f $tmpgz >$tmp 2>/dev/null") != 0) {
die "$name: update failed: unable to unpack '$tmpgz'\n";
}
# import gpg keys if needed
my $keyid = $channels[$i]{'keyid'};
my $keyfile = $channels[$i]{'keyfile'};
my $keyserver = $channels[$i]{'keyserver'};
if (system ("/usr/bin/gpg --logger-fd=1 --list-keys $keyid 2>&1 >/dev/null") != 0) {
if ( $keyfile ) {
logmsg ($logfd, "$name: importing $keyid from $keyfile");
system ("/usr/bin/gpg --batch --no-tty --status-fd=1 -q " .
"--logger-fd=1 --import $keyfile >>$logfile");
}
if ( $keyserver ) {
logmsg ($logfd, "$name: importing $keyid from $keyserver");
system ("/usr/bin/gpg --keyserver $keyserver --recv-keys " .
"--logger-fd=1 0x$keyid >>$logfile");
}
}
# verify index integrity
logmsg ($logfd, "$name: verifying index integrity");
if (system ("/usr/bin/gpg --logger-fd=1 --verify $sigfn $tmp 2>&1 >>$logfile") != 0) {
die "$name: unable to verify signature\n";
}
# validate index syntax
logmsg ($logfd, "$name: validating index syntax");
eval {
my $fh = IO::File->new ("<$tmp") ||
die "unable to open file '$tmp' - $!\n";
PVE::Config::read_aplinfo ($tmp, $fh, 1);
close ($fh);
};
die "update failed, invalid syntax: $@" if $@;
# append channel index to main tmp appliance list
system ("cat $tmp >> $tmpapl");
logmsg ($logfd, "$name: update complete");
}
logmsg ($logfd, "channel updates: finalizing");
if (system ("mv $tmpapl /var/lib/pve-manager/apl-available 2>/dev/null") != 0) {
die "update failed: unable to store data\n";
}
logmsg ($logfd, "channel updates: complete");
};
my $err = $@;
if ($err) {
logmsg ($logfd, $err);
close ($logfd);
return 0;
}
close ($logfd);
return 1;
}
sub load_data {
my $filename = "/var/lib/pve-manager/apl-available";
if (! -f $filename) {
system ("cp /usr/share/doc/pve-manager/aplinfo.dat /var/lib/pve-manager/apl-available");
}
return PVE::Config::read_file ('aplinfo');
}
sub display_name {
my ($template) = @_;
my $templates = load_data ();
return $template if !$templates;
my $d = $templates->{'all'}->{$template};
$template =~ s/\.tar\.gz$//;
$template =~ s/_i386$//;
return $template if !$d;
return "$d->{package}_$d->{version}";
}
sub pkginfo {
my ($template) = @_;
my $templates = load_data ();
return undef if !$templates;
my $d = $templates->{'all'}->{$template};
return $d;
}
sub webnews {
my ($lang) = @_;
my $templates = load_data ();
my $html = '';
$html .= __("Welcome to the Proxmox Virtual Environment!");
$html .= "
";
$html .= __("For more information please visit our homepage at");
$html .= " www.proxmox.com.";
return $html if !$templates;
# my $d = $templates->{'all'}->{"pve-web-news-$lang"} ||
my $d = $templates->{all}->{'pve-web-news'};
return $html if !$d;
return $d->{description};
}
1;