#!/usr/bin/perl 
# -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
# vim: ts=4 sts=4 sw=4:

#ident "$Id: topspin-eth-devices,v 1.1 2015/04/13 08:24:49 gsc Exp $
# Copyright (c) 2014 Bruker BioSpin GmbH"";

use strict;
use warnings;
use English;
use Getopt::Long;
use File::Basename;
use Pod::Usage;
use Sys::Syslog qw(:standard :macros);  # standard functions & macros

sub EditGrubConfig($);
sub ShowHashArray($%);

my $program = basename($0);

####
# Supported options
my $help = 0;
my $man = 0;
my $test = 0;
my $verbose = 0;
my $syslog = 1;

GetOptions(
	   'help|?' => \$help,
	   'man'  => \$man,
	   'verbose+'  => \$verbose,
	   'syslog!'  => \$syslog,
	   'test'  => \$test,
	  ) || pod2usage(2);
pod2usage(1) if $help;
pod2usage(-exitstatus => 0, -verbose => 2) if $man;

###
# Some info about myself
my @Version =  split(' ','$Revision: 1.1 $ ');
my $Version = $Version[1];
my $OS_Version = get_os_version();
print "$program (Version $Version)\nCopyright (c) 2014 Bruker BioSpin GmbH\n\n" if $verbose;
print "OS_Version = $OS_Version\n\n" if $verbose;

###
# default file names
my $netcfg	= '/etc/sysconfig/network-scripts/ifcfg';
my $grubcfg = '/etc/default/grub';
my $sysnet = '/sys/class/net';


openlog('bruker-setup', 'nofatal,pid', 'user') if $syslog;


opendir(DIR,$sysnet)  || die "Can't get directory $sysnet: $!\n";
my @ethdevices = grep(/(eth*)/,readdir(DIR));
rewinddir(DIR);
my @netdevices = grep(/(en*)/,readdir(DIR));
closedir(DIR);

print "Found ether devices:\n\t@ethdevices \n\t@netdevices\n" if $verbose;

my $edstatus = EditGrubConfig($grubcfg) unless (@ethdevices);

push(my @devices, @ethdevices,@netdevices);
foreach my $interface (@devices)
{
    open(my $fh, '<', join('/',$sysnet,$interface,'operstate')) or die $!;
    my $state = <$fh>;
    close($fh);
    chomp($state);

    open($fh, '<', join('/',$sysnet,$interface,'address')) or die $!;
    my $address = <$fh>;
    close($fh);
    chomp($address);

    printf "Interface %s is %s addr = %s\n", $interface,$state,$address if $verbose;

    my $ifcg = $netcfg . '-' . $interface;
    
    if (-f $ifcg)
    {
	print "$ifcg\n" if $verbose;
	open($fh, '<',$ifcg ) or die $!;
	my @config = <$fh>;
	close($fh);
	foreach my $line (@config)
	{
	    my $hwaddr 	= $1 if ($line =~ /^HWADDR=([0-9a-fA-F:]*)/ );

	    print $hwaddr,"\n" if $hwaddr;
	}

#	print "@config\n";
    }
    else
    {
	print "$ifcg missing\n" if $verbose;	
    }
}

closelog  if $syslog;

exit;

###################
##               ##
##  Subroutines  ##
##               ##
###################
sub get_os_version
{
    my $querycmd = 'rpm -qf --queryformat %{Name} /etc/redhat-release';
    my $redhat = `$querycmd`;

    chomp $redhat;
    $querycmd = 'rpm -q --queryformat %{version} ' . $redhat;

    my $redhat_release = `$querycmd`;

    my $rh_release  = (int $redhat_release);
    return $rh_release;
}

sub ShowHashArray($%)
{
    my $head = shift;
    my %hash = @ARG;
    print "$head:\n";
    while (my($key,$val) = each(%hash))
    {
	print " $key => $val\n";
    }
}

sub EditGrubConfig($)
{
    my $grubcfg = shift;
    open(GRUB,"$grubcfg")  || die "$grubcfg: $!\n";
    my @lines = <GRUB>;
    close(GRUB);

    my $netifnames = 0;
    open(GRUB,">$grubcfg")  || die "$grubcfg: $!\n";
    foreach my $line (@lines)
    {
	if ($line =~ /^GRUB_CMDLINE_LINUX="(.*)"/)
	{
	    my $options = $1;
	    unless ($options =~ /net.ifnames=0/)
	    {
		print GRUB "GRUB_CMDLINE_LINUX=\"$options net.ifnames=0\"\n";
		my $msg =  "\nGRUB_CMDLINE_LINUX=\"$options net.ifnames=0\"\n  changed.\n";
		print $msg if $verbose;
		syslog(LOG_INFO, $msg) if $syslog;

		$netifnames = 1;
		next;
	    }
	}
	print GRUB $line;
    }
    close(GRUB);

    my $bioscfg = '/boot/grub2/grub.cfg';
    my $ueficfg = '/boot/efi/EFI/centos/grub.cfg';
    $grubcfg = $bioscfg if (-f $bioscfg);
    $grubcfg = $ueficfg if (-f $ueficfg);

    print "execute grub2-mkconfig:"  if $verbose;
    system("grub2-mkconfig -o $grubcfg") if $netifnames;

    return $netifnames;
}
__END__

=head1 NAME

rename-eth-devices - rename ethernet devices according to topspin requirements

=head1 SYNOPSIS

rename-eth-devices [options]

Options:

     -help            brief help message
     -man             prints the manual page
     -verbose         create verbose output


=head1 OPTIONS

=over 8

=item B<-help>

    Print a brief help message and exits.

=item B<-man>

    Prints the manual page and exits.


=item B<-verbose>

    Print additional debug information

=item B<-save>

    Modifiy /etc/sysconfig/network-scripts/ifcfg-eth* files
    and change MAC addresse of ifcfg-eth1 to the device which
    has 'Hewlett Packard' as Vendors  OUI

=item B<-show>

    Display the Vendors  OUI of the HWADDR in 
    /etc/sysconfig/network-scripts/ifcfg-eth* files
=back


=head1 DESCRIPTION

rename-eth-devices - rename ethernet devices according to topspin requirements
 
This script checks if ethernet device are named eth0, eth2, ... and defines
the kernel option 'net.ifnames=0' to disable the renaming scheme.

=cut

