]> git.proxmox.com Git - pve-manager.git/blame - bin/pveupdate
update shipped appliance info index
[pve-manager.git] / bin / pveupdate
CommitLineData
19407634 1#!/usr/bin/perl
aff192e6
DM
2
3use strict;
19407634
DM
4use warnings;
5
aff192e6
DM
6use IO::File;
7use File::Find;
8use File::stat;
9
5366e88e 10use PVE::APLInfo;
4a57db55
FG
11use PVE::CertHelpers;
12use PVE::Certificate;
784a50cc 13use PVE::Cluster::Setup;
5366e88e 14use PVE::Cluster;
3ac3653e 15use PVE::DataCenterConfig;
5366e88e
TL
16use PVE::INotify;
17use PVE::NodeConfig;
4027c59b 18use PVE::RPCEnvironment;
5366e88e 19use PVE::SafeSyslog;
784a50cc 20use PVE::Tools;
5366e88e 21
4a57db55 22use PVE::API2::ACME;
5366e88e
TL
23use PVE::API2::APT;
24use PVE::API2::Subscription;
4027c59b 25
c8969ecb 26initlog ('pveupdate', 'daemon');
aff192e6 27
4027c59b
DM
28die "please run as root\n" if $> != 0;
29
30$ENV{'PATH'} = '/sbin:/bin:/usr/sbin:/usr/bin';
31
32PVE::INotify::inotify_init();
33
34my $rpcenv = PVE::RPCEnvironment->init('cli');
35
36$rpcenv->init_request();
37$rpcenv->set_language($ENV{LANG});
c9355915 38$rpcenv->set_user('root@pam');
4027c59b
DM
39
40my $nodename = PVE::INotify::nodename();
41
42eval { PVE::API2::Subscription->update({ node => $nodename }); };
43if (my $err = $@) {
a88002cf 44 syslog ('err', "update subscription info failed: $err");
4027c59b
DM
45}
46
c9164975
DM
47my $dccfg = PVE::Cluster::cfs_read_file('datacenter.cfg');
48eval { PVE::APLInfo::update($dccfg->{http_proxy}); };
49if (my $err = $@) {
a88002cf
DM
50 syslog ('err', "update appliance info failed - see /var/log/pveam.log for details");
51}
52
d017de1f 53my $info = eval { PVE::API2::Subscription::read_etc_subscription() };
8432c6d3
TL
54
55my $notify_on = $dccfg->{notify}->{'package-updates'} // 'auto';
56my $notify = 0;
57if ($notify_on eq 'auto') {
58 # hosts with subscriptions are likely production system and thus want infos about new packages
59 $notify = ($info && $info->{status} eq 'active') ? 1 : 0;
60} elsif ($notify_on eq 'always') {
61 $notify = 1;
62} elsif ($notify_on eq 'never') {
63 $notify = 0;
64} else {
65 warn "unexpected package-updates notify configuration value '$notify_on'\n";
66}
d916c09d
DM
67eval { PVE::API2::APT->update_database({ node => $nodename, notify => $notify, quiet => 1 }); };
68if (my $err = $@) {
69 syslog ('err', "update apt database failed: $err");
c9164975 70}
aff192e6 71
4a57db55
FG
72eval {
73 my $node_config = PVE::NodeConfig::load_config($nodename);
e7083f9a
FG
74 my $acme_node_config = PVE::NodeConfig::get_acme_conf($node_config);
75 if ($acme_node_config && $acme_node_config->{domains}) {
4a57db55
FG
76 my $cert = PVE::CertHelpers::cert_path_prefix($nodename).".pem";
77 if (-e $cert) {
78 if (PVE::Certificate::check_expiry($cert, time() + 30*24*60*60)) {
79 PVE::API2::ACME->renew_certificate({ node => $nodename });
80 } else {
81 syslog ('info', 'Custom certificate does not expire soon, skipping ACME renewal.');
82 }
83 } else {
84 syslog ('info', 'ACME config found for node, but no custom certificate exists. Skipping ACME renewal until initial certificate has been deployed.');
85 }
86 }
87};
88syslog ('err', "Renewing ACME certificate failed: $@") if $@;
89
784a50cc
DC
90eval {
91 my $certpath = PVE::CertHelpers::default_cert_path_prefix($nodename).".pem";
92 my $capath = "/etc/pve/pve-root-ca.pem";
93
75456ef3
FG
94 my $renew = sub {
95 my ($msg) = @_;
96
784a50cc
DC
97 # get CA info
98 my $cainfo = PVE::Certificate::get_certificate_info($capath);
99
100 # get cert and check issuer and chain metadata
101 my $certinfo = PVE::Certificate::get_certificate_info($certpath);
102 if ($certinfo->{issuer} ne $cainfo->{subject}) {
f5ad0c97 103 die "SSL certificate ($certpath) is not issued by root CA ($capath)!\n";
784a50cc
DC
104 }
105
106 # check if cert is really signed by the ca
f5ad0c97 107 # TODO: replace by low level ssleay interface if version 1.86 is available
784a50cc
DC
108 PVE::Tools::run_command(['/usr/bin/openssl', 'verify', '-CAfile', $capath, $certpath]);
109
75456ef3 110 print "PVE certificate $msg\n";
784a50cc
DC
111 # create new certificate
112 my $ip = PVE::Cluster::remote_node_ip($nodename);
113 PVE::Cluster::Setup::gen_pve_ssl_cert(1, $nodename, $ip);
f5ad0c97 114
784a50cc
DC
115 print "Restarting pveproxy after renewing certificate\n";
116 PVE::Tools::run_command(['systemctl', 'reload-or-restart', 'pveproxy']);
75456ef3
FG
117 };
118
119 if (PVE::Certificate::check_expiry($certpath, time() + 14*24*60*60)) {
120 # expires in next 2 weeks
121 $renew->("expires soon, renewing...");
122 } elsif (!PVE::Certificate::check_expiry($certpath, time() + 2*365*24*60*60)) {
123 # expires in more than 2 years
e33f43a3 124 $renew->("expires in more than 2 years, renewing to reduce certificate life-span for client compatibility...");
784a50cc
DC
125 }
126};
127syslog ('err', "Checking/Renewing SSL certificate failed: $@") if $@;
128
aff192e6
DM
129sub cleanup_tasks {
130
131 my $taskdir = "/var/log/pve/tasks";
132 my $filename = "$taskdir/index.1";
133
134 my $fh = IO::File->new($filename, O_RDONLY);
135 return if !$fh;
136
137 my $endtime = 0;
138 while (defined(my $line = <$fh>)) {
139 if ($line =~ m/^(\S+)(\s([0-9A-Za-z]{8})(\s(\S.*))?)?$/) {
140 $endtime = hex($3);
141 last;
142 }
143 }
144 close($fh);
145
146 return if !$endtime;
147
148 # print "delete task older that $endtime\n" . localtime($endtime) . "\n";
149
150 my $count = 0;
151
152 my $wanted = sub {
153 my $filename = $_;
154
155 return if $filename !~ m/^UPID:/;
156
157 my $st;
158 if (($st = stat($filename)) && ($st->mtime < $endtime)) {
159 unlink($filename);
160 $count++;
161 }
162 };
163
b0a65294 164 foreach my $subdir (qw(0 1 2 3 4 5 6 7 8 9 A B C D E F)) {
aff192e6
DM
165 my $path = "$taskdir/$subdir";
166 find($wanted, $path);
167 }
168
169 if ($count) {
170 syslog('info', "cleanup removed $count task logs");
171 }
172}
173
174cleanup_tasks();
175
176exit (0);