#!/usr/bin/perl -w # # Module: show_version # # **** License **** # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # This code was originally developed by Vyatta, Inc. # Portions created by Vyatta are Copyright (C) 2005, 2006, 2007 Vyatta, Inc. # All Rights Reserved. # # Author: Rick Balocca # Date: 2007 # Description: # # **** End License **** # use strict; use warnings; # # Global hash of debians in the base install and now. # my $rHoH_base_debs; my $rHoH_now_debs; my $base = '/opt/vyatta/etc'; my $versionfile = "$base/version"; my $buildfile = "$base/build.txt"; my $debsfile = "$base/deb-versions.txt"; sub echo_file { my ($file) = @_; my @lines = (); if (!(-e $file)) { return @lines; } open(my $FH, '<', $file) or die "Unable to open [$file]\n"; @lines=<$FH>; close($FH); return @lines; } # This follows the chain from /boot/grub/menu.cfg which # boots /boot/vmlinuz to find the version of kernel running sub get_image_type { my $kernel = readlink('/boot/vmlinuz'); my $version; unless (defined($kernel)) { warn "Can not read link /boot/vmlinuz: $!\n"; return; } unless ($kernel =~ /^vmlinuz-.*-([^-]*)-vyatta(.*)$/) { warn "Unknown kernel version: $kernel\n"; return; } if ($1 eq '586') { $version = "Intel 32bit"; } elsif ($1 eq "amd64") { $version = "Intel 64bit"; } else { $version = $1; } if ($2 eq '-virt') { $version .= " Virtual" } return $version; } # # convert the "dpkg -l" output have same format as deb-versions.txt # sub get_pkg_version { my @lines = @_; my @new_lines = (); foreach my $line (@lines) { if ($line =~ /^[D\|\+]/) { next; # skip header } my ($status, $pkg, $version) = split(/[ \t\n]+/, $line, 4); if ($status =~ /^i/) { push(@new_lines, "$pkg $version"); } } return @new_lines; } sub read_pkg_file { my @pkgs_list = @_; my %HoH = (); my ($name, $version); foreach my $line (@pkgs_list) { ($name, $version) = split(/[ \t\n]+/, $line, 3); $HoH{$name}{'version'} = $version; } return \%HoH; } sub show_added { for my $name (sort keys %$rHoH_now_debs) { if (!$rHoH_base_debs->{$name}) { printf("Aii %-25s %-25s\n", $name, $rHoH_now_debs->{$name}->{'version'}); } } } sub show_deleted { for my $name (sort keys %$rHoH_base_debs) { if (!$rHoH_now_debs->{$name}) { printf("X %-25s %-25s\n", $name, $rHoH_base_debs->{$name}->{'version'}); } } } sub show_upgraded_downgraded { my ($up_down) = @_; my ($symbol, $op, $ver_base, $ver_now, $cmd); if ($up_down eq "upgraded") { $symbol = "U"; $op = "lt"; } else { $symbol = "D"; $op = "gt"; } for my $name (sort keys %$rHoH_base_debs) { if ($rHoH_now_debs->{$name}) { $ver_base = $rHoH_base_debs->{$name}{'version'}; $ver_now = $rHoH_now_debs->{$name}{'version'}; if ($ver_base ne $ver_now) { $cmd = "dpkg --compare-versions \"$ver_base\" $op \"$ver_now\""; if (!system($cmd)) { printf("%sii %-25s %-20s (baseline: %s)\n", $symbol, $name, $ver_now, $ver_base); } } } } } sub show_upgraded { show_upgraded_downgraded("upgraded"); } sub show_downgraded { show_upgraded_downgraded("downgraded"); } sub show_all { show_added(); show_deleted(); show_upgraded(); show_downgraded(); } my %options = ( "added" => \&show_added, "deleted", => \&show_deleted, "upgraded" => \&show_upgraded, "downgraded" => \&show_downgraded, "all" => \&show_all, ); # # main # print(&echo_file($versionfile)); print(&echo_file($buildfile)); my $type = get_image_type(); if ($type) { print "System type: $type\n"; } my $booted = `egrep -e '^(union|overlay|au)fs.*/filesystem\.squashfs' /proc/mounts`; if (defined($booted) && $booted ne "") { $booted="livecd"; } else { my $image_boot = `egrep -e '^(union|overlay)fs / (union|overlay)fs.*\.squashfs' /proc/mounts`; if ($image_boot ne "") { $booted="image"; } else { $booted="disk"; } } print "Boot via: $booted\n"; my $hv = `/opt/vyatta/sbin/hypervisor_vendor`; if (defined($hv) && $hv ne "") { chomp $hv; print "Hypervisor: $hv\n"; } my $plat_model = `sudo /usr/sbin/dmidecode -s system-product-name`; chomp $plat_model; my $plat_sn = `sudo /usr/sbin/dmidecode -s system-serial-number`; chomp $plat_sn; my $plat_uuid = `sudo /usr/sbin/dmidecode -s system-uuid`; chomp $plat_uuid; if (defined $plat_model && $plat_model ne "" && $plat_model ne " ") { print "HW model: $plat_model\n" } if (defined $plat_sn && $plat_sn ne "" && $plat_sn ne " ") { print "HW S/N: $plat_sn\n" } if (defined $plat_uuid && $plat_uuid ne "" && $plat_uuid ne " ") { print "HW UUID: $plat_uuid\n" } my $uptime = `uptime`; if (defined $uptime && $uptime ne "") { print "Uptime: $uptime\n"; } if (!(-e $debsfile)) { exit 0; } print "\n"; $rHoH_base_debs = read_pkg_file(&echo_file($debsfile)); $rHoH_now_debs = read_pkg_file(get_pkg_version(`dpkg -l 2> /dev/null`)); if ($#ARGV == 0) { if ($options{$ARGV[0]}) { $options{$ARGV[0]}->(); } else { print "Usage: showversion [added|deleted|upgraded|downgraded|all]\n"; exit 1; } }