3
# apt-dater - terminal-based remote package update manager
6
# Andre Ellguth <ellguth@ibh.de>
7
# Thomas Liske <liske@ibh.de>
10
# 2008-2012 (C) IBH IT-Service GmbH [http://www.ibh.de/apt-dater/]
13
# This program is free software; you can redistribute it and/or modify
14
# it under the terms of the GNU General Public License as published by
15
# the Free Software Foundation; either version 2 of the License, or
16
# (at your option) any later version.
18
# This program is distributed in the hope that it will be useful,
19
# but WITHOUT ANY WARRANTY; without even the implied warranty of
20
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
# GNU General Public License for more details.
23
# You should have received a copy of the GNU General Public License
24
# along with this package; if not, write to the Free Software
25
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28
use AptPkg::Config '$_config';
29
use AptPkg::System '$_system';
35
my $CFGFILE = '/etc/apt-dater-host.conf';
36
my $DPKGTOOL = 'aptitude';
37
my $APTUPGRADE = 'dist-upgrade';
41
my $FORBID_REFRESH = 0;
42
my $FORBID_UPGRADE = 0;
43
my $FORBID_INSTALL = 0;
44
my $UUIDFILE = '/etc/apt-dater-host.uuid';
53
eval `cat "$CFGFILE"` ;
56
print "ADPROTO: $ADPROTO\n";
57
print "ADPERR: Invalid config $CFGFILE: $@\n";
62
$GETROOT = '' if($> == 0);
64
die "Don't call this script directly!\n" unless (defined($CMD));
65
if($CMD eq 'sshkey') {
66
die "Sorry, no shell access allowed!\n"
67
unless(defined($ENV{'SSH_ORIGINAL_COMMAND'}));
69
@ARGV = split(' ', $ENV{'SSH_ORIGINAL_COMMAND'});
74
die "Invalid command '$CMD'!\n" unless ($CMD=~/^(refresh|status|upgrade|install|kernel)$/);
76
if ($CMD eq 'refresh') {
77
print "ADPROTO: $ADPROTO\n";
78
if ($FORBID_REFRESH) {
79
print STDERR "\n\n** Sorry, apt-dater based refreshs on this host are disabled! **\n\n"
87
elsif ($CMD eq 'status') {
88
print "ADPROTO: $ADPROTO\n";
92
elsif ($CMD eq 'upgrade') {
93
if ($FORBID_UPGRADE) {
94
print STDERR "\n\n** Sorry, apt-dater based upgrades on this host are disabled! **\n\n";
101
elsif ($CMD eq 'install') {
102
if ($FORBID_INSTALL) {
103
print STDERR "\n\n** Sorry, apt-dater based installations on this host are disabled! **\n\n";
110
elsif ($CMD eq 'kernel') {
111
print "ADPROTO: $ADPROTO\n";
115
die "Internal error!\n";
120
if(system("$GETROOT $DPKGTOOL update")) {
121
print "\nADPERR: Failed to execute '$GETROOT $DPKGTOOL update' ($?).\n";
127
return imv_get(IMV_PROB_DEFAULT);
134
chomp($kernel = `uname -s`);
135
chomp($machine = `uname -m`);
136
return "$kernel|$machine";
140
# initialise the global config object with the default values and
141
# setup the $_system object
143
$_system = $_config->system;
145
# supress cache building messages
146
$_config->{quiet} = 2;
149
my $cache = AptPkg::Cache->new;
151
# retrieve lsb informations
152
unless (open(HLSB, "lsb_release -a 2> /dev/null |")) {
153
print "\nADPERR: Failed to execute 'lsb_release -a' ($!).\n";
160
$lsb{$1}=$2 if (/^(Distributor ID|Release|Codename):\s+(\S.*)$/);
164
print "\nADPERR: Error executing 'lsb_release -a' ($?).\n";
167
print "LSBREL: $lsb{'Distributor ID'}|$lsb{'Release'}|$lsb{'Codename'}\n";
169
# retrieve virtualization informations
170
print "VIRT: ".&get_virt."\n";
172
# retrieve uname informations
173
print "UNAME: ".&get_uname."\n";
175
# calculate forbid mask
177
$mask |= 1 if ($FORBID_REFRESH);
178
$mask |= 2 if ($FORBID_UPGRADE);
179
$mask |= 4 if ($FORBID_INSTALL);
180
print "FORBID: $mask\n";
182
# add installation UUID if available
183
if(-r $UUIDFILE && -s $UUIDFILE) {
184
print "UUID: ", `head -n 1 "$UUIDFILE"`;
187
# add cluster name if available
188
foreach my $CLUSTER (@CLUSTERS) {
189
print "CLUSTER: $CLUSTER\n";
192
# get packages which might be upgraded
197
my $_GETROOT = $GETROOT;
199
if($DPKGTOOL eq "apt-get") {
200
$DPKGARGS = "--quiet --simulate --fix-broken --allow-unauthenticated";
202
elsif($DPKGTOOL eq "aptitude") {
203
$DPKGARGS = "--verbose --assume-yes --quiet --simulate -f --allow-untrusted";
207
# unkown DPKG frontend - fallback to apt-get
208
$DPKGTOOL = "apt-get";
209
$DPKGARGS = "--quiet --simulate --fix-broken --allow-unauthenticated";
212
unless(open(HAPT, "$_GETROOT $DPKGTOOL $DPKGARGS dist-upgrade |")) {
213
print "\nADPERR: Failed to execute '$_GETROOT $DPKGTOOL $DPKGARGS dist-upgrade' ($!).\n";
220
$pos=1 if (/^The following packages have been kept back/);
221
$pos=2 if (/^The following packages will be upgraded:/);
230
while(/^\s*(\S+)(\s(.+))?$/) {
241
$updates{$1} = $2 if (/^Inst (\S+) \[.+\] \((\S+) /);
245
print "\nADPERR: Error executing '$GETROOT $DPKGTOOL $DPKGARGS dist-upgrade' ($?).\n";
249
# get version of installed packages
252
unless(open(HDPKG, "dpkg-query --show --showformat='\${Package} \${Version} \${Status}\\n' |")) {
253
print "\nADPERR: Failed to execute \"dpkg-query --show --showformat='\${Package} \${Version} \${Status}\\n'\" ($!).\n";
259
next unless (/^(\S+) (\S+) (\S+) (\S+) (\S+)$/);
260
$installed{$1} = $2 ;
265
elsif($updates{$1}) {
269
$status{$1} = substr($3, 0, 1);
271
if ($status{$1} eq 'i') {
272
my $p = $cache->{$1};
274
unless ($5 eq 'installed') {
275
$status{$1} = "b=$5";
278
if (my $available = $p->{VersionList}) {
280
for my $v (@$available) {
281
for my $f (map $_->{File}, @{$v->{FileList}}) {
282
$extra = 0 unless ($f->{FileName} eq '/var/lib/dpkg/status');
285
$status{$1} = 'x' if($extra);
293
print "\nADPERR: Error executing \"dpkg-query --show --showformat='\${Package} \${Version} \${Status}\\n'\" ($?).\n";
297
foreach my $pkg (keys %installed) {
298
print "STATUS: $pkg|$installed{$pkg}|$status{$pkg}";
299
if (exists($updates{$pkg})) {
300
print "=$updates{$pkg}" ;
308
my $UpgradeCmd = "$GETROOT $DPKGTOOL ";
310
$UpgradeCmd .= '--assume-yes ' if($ASSUMEYES);
312
if($DPKGTOOL eq 'aptitude'){
313
$UpgradeCmd .= '-o Aptitude::Delete-Unused=false ';
315
$UpgradeCmd .= $APTUPGRADE;
322
system($GETROOT, $DPKGTOOL, 'install', @_);
325
system($DPKGTOOL, 'install', @_);
330
my $infostr = 'KERNELINFO:';
331
my $verfile = '/proc/version';
332
my $version = `uname -r`;
335
unless(-r $verfile) {
336
print "$infostr 9 $version\n";
340
unless(`cat /proc/version` =~ /^\S+ \S+ \S+ \(Debian ([^\)]+)\)/) {
341
print "$infostr 2 $version\n";
347
unless(open(HDPKG, "dpkg-query -W -f='\${Version} \${Status;20} \${Maintainer} \${Provides}\n' 'linux-image*'|grep 'install ok installed Debian Kernel Team'|grep linux-image|")) {
348
print "$infostr 9 $version\n";
352
next unless (/^(\S+)\s/);
354
$reboot=1 unless (system("dpkg", "--compare-versions", $vers, "lt", $1) >> 8);
358
print "$infostr $reboot $version\n";
362
return unless $CLEANUP;
364
system("$GETROOT $DPKGTOOL clean");