1f54307cc6
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
177 lines
4.9 KiB
Perl
Executable File
177 lines
4.9 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use IO::File;
|
|
use File::Find;
|
|
use File::stat;
|
|
|
|
use PVE::APLInfo;
|
|
use PVE::CertHelpers;
|
|
use PVE::Certificate;
|
|
use PVE::Cluster::Setup;
|
|
use PVE::Cluster;
|
|
use PVE::DataCenterConfig;
|
|
use PVE::INotify;
|
|
use PVE::NodeConfig;
|
|
use PVE::RPCEnvironment;
|
|
use PVE::SafeSyslog;
|
|
use PVE::Tools;
|
|
|
|
use PVE::API2::ACME;
|
|
use PVE::API2::APT;
|
|
use PVE::API2::Subscription;
|
|
|
|
initlog ('pveupdate', 'daemon');
|
|
|
|
die "please run as root\n" if $> != 0;
|
|
|
|
$ENV{'PATH'} = '/sbin:/bin:/usr/sbin:/usr/bin';
|
|
|
|
PVE::INotify::inotify_init();
|
|
|
|
my $rpcenv = PVE::RPCEnvironment->init('cli');
|
|
|
|
$rpcenv->init_request();
|
|
$rpcenv->set_language($ENV{LANG});
|
|
$rpcenv->set_user('root@pam');
|
|
|
|
my $nodename = PVE::INotify::nodename();
|
|
|
|
eval { PVE::API2::Subscription->update({ node => $nodename }); };
|
|
if (my $err = $@) {
|
|
syslog ('err', "update subscription info failed: $err");
|
|
}
|
|
|
|
my $dccfg = PVE::Cluster::cfs_read_file('datacenter.cfg');
|
|
eval { PVE::APLInfo::update($dccfg->{http_proxy}); };
|
|
if (my $err = $@) {
|
|
syslog ('err', "update appliance info failed - see /var/log/pveam.log for details");
|
|
}
|
|
|
|
my $info = eval { PVE::API2::Subscription::read_etc_subscription() };
|
|
|
|
my $notify_on = $dccfg->{notify}->{'package-updates'} // 'auto';
|
|
my $notify = 0;
|
|
if ($notify_on eq 'auto') {
|
|
# hosts with subscriptions are likely production system and thus want infos about new packages
|
|
$notify = ($info && $info->{status} eq 'active') ? 1 : 0;
|
|
} elsif ($notify_on eq 'always') {
|
|
$notify = 1;
|
|
} elsif ($notify_on eq 'never') {
|
|
$notify = 0;
|
|
} else {
|
|
warn "unexpected package-updates notify configuration value '$notify_on'\n";
|
|
}
|
|
eval { PVE::API2::APT->update_database({ node => $nodename, notify => $notify, quiet => 1 }); };
|
|
if (my $err = $@) {
|
|
syslog ('err', "update apt database failed: $err");
|
|
}
|
|
|
|
eval {
|
|
my $node_config = PVE::NodeConfig::load_config($nodename);
|
|
my $acme_node_config = PVE::NodeConfig::get_acme_conf($node_config);
|
|
if ($acme_node_config && $acme_node_config->{domains}) {
|
|
my $cert = PVE::CertHelpers::cert_path_prefix($nodename).".pem";
|
|
if (-e $cert) {
|
|
if (PVE::Certificate::check_expiry($cert, time() + 30*24*60*60)) {
|
|
PVE::API2::ACME->renew_certificate({ node => $nodename });
|
|
} else {
|
|
syslog ('info', 'Custom certificate does not expire soon, skipping ACME renewal.');
|
|
}
|
|
} else {
|
|
syslog ('info', 'ACME config found for node, but no custom certificate exists. Skipping ACME renewal until initial certificate has been deployed.');
|
|
}
|
|
}
|
|
};
|
|
syslog ('err', "Renewing ACME certificate failed: $@") if $@;
|
|
|
|
eval {
|
|
my $certpath = PVE::CertHelpers::default_cert_path_prefix($nodename).".pem";
|
|
my $capath = "/etc/pve/pve-root-ca.pem";
|
|
|
|
my $renew = sub {
|
|
my ($msg) = @_;
|
|
|
|
# get CA info
|
|
my $cainfo = PVE::Certificate::get_certificate_info($capath);
|
|
|
|
# get cert and check issuer and chain metadata
|
|
my $certinfo = PVE::Certificate::get_certificate_info($certpath);
|
|
if ($certinfo->{issuer} ne $cainfo->{subject}) {
|
|
die "SSL certificate ($certpath) is not issued by root CA ($capath)!\n";
|
|
}
|
|
|
|
# check if cert is really signed by the ca
|
|
# TODO: replace by low level ssleay interface if version 1.86 is available
|
|
PVE::Tools::run_command(['/usr/bin/openssl', 'verify', '-CAfile', $capath, $certpath]);
|
|
|
|
print "PVE certificate $msg\n";
|
|
# create new certificate
|
|
my $ip = PVE::Cluster::remote_node_ip($nodename);
|
|
PVE::Cluster::Setup::gen_pve_ssl_cert(1, $nodename, $ip);
|
|
|
|
print "Restarting pveproxy after renewing certificate\n";
|
|
PVE::Tools::run_command(['systemctl', 'reload-or-restart', 'pveproxy']);
|
|
};
|
|
|
|
if (PVE::Certificate::check_expiry($certpath, time() + 14*24*60*60)) {
|
|
# expires in next 2 weeks
|
|
$renew->("expires soon, renewing...");
|
|
} elsif (!PVE::Certificate::check_expiry($certpath, time() + 2*365*24*60*60)) {
|
|
# expires in more than 2 years
|
|
$renew->("expires in more than 2 years, renewing to reduce certificate life-span for client compatibility...");
|
|
}
|
|
};
|
|
syslog ('err', "Checking/Renewing SSL certificate failed: $@") if $@;
|
|
|
|
sub cleanup_tasks {
|
|
|
|
my $taskdir = "/var/log/pve/tasks";
|
|
my $filename = "$taskdir/index.1";
|
|
|
|
my $fh = IO::File->new($filename, O_RDONLY);
|
|
return if !$fh;
|
|
|
|
my $endtime = 0;
|
|
while (defined(my $line = <$fh>)) {
|
|
if ($line =~ m/^(\S+)(\s([0-9A-Za-z]{8})(\s(\S.*))?)?$/) {
|
|
$endtime = hex($3);
|
|
last;
|
|
}
|
|
}
|
|
close($fh);
|
|
|
|
return if !$endtime;
|
|
|
|
# print "delete task older that $endtime\n" . localtime($endtime) . "\n";
|
|
|
|
my $count = 0;
|
|
|
|
my $wanted = sub {
|
|
my $filename = $_;
|
|
|
|
return if $filename !~ m/^UPID:/;
|
|
|
|
my $st;
|
|
if (($st = stat($filename)) && ($st->mtime < $endtime)) {
|
|
unlink($filename);
|
|
$count++;
|
|
}
|
|
};
|
|
|
|
foreach my $subdir (qw(0 1 2 3 4 5 6 7 8 9 A B C D E F)) {
|
|
my $path = "$taskdir/$subdir";
|
|
find($wanted, $path);
|
|
}
|
|
|
|
if ($count) {
|
|
syslog('info', "cleanup removed $count task logs");
|
|
}
|
|
}
|
|
|
|
cleanup_tasks();
|
|
|
|
exit (0);
|