#!/s/std/bin/perl

# A script to generate new UUIDs for RHEL 6 partitions
# Most useful for VMs generated from templates

use strict;
use warnings;

use Data::Dumper;

# only run this script as root
if ($<) {
  print STDERR "ERROR: Only root can reset UUIDs.\n";
  exit 1;
}

# This is only for RHEL 6
my @sys_commands = ('/usr/afsws/bin/sys', '/usr/bin/sys');
my $sys = '';
foreach (@sys_commands) {
  $sys = `$_` || '';
  chomp $sys;
  last if $sys;
}

if ($sys eq 'amd64_rhel6') {
  print "Setting UUIDs on 64-bit RHEL 6 machine...\n";
} else {
  print STDERR "Invalid sysname $sys. Cannot reset UUIDs.\n";
}

my $INFO = '/sbin/blkid';
my $UUIDGEN = '/usr/bin/uuidgen';
my $TUNE2FS = '/sbin/tune2fs';
my $SED = '/bin/sed';
my $SWAPON = '/sbin/swapon';
my $SWAPOFF = '/sbin/swapoff';
my $MKSWAP = '/sbin/mkswap';

my $ROOT = '/dev/sda2';

my @partitions = qw(/dev/sda1 /dev/sda2 /dev/sda3 /dev/sda5 /dev/sda6 /dev/sda7); # partitions to modify
my %uuids = (); # new and old UUIDs for partitions

# Get UUIDs
foreach my $part (@partitions) {
  chomp(my $blk_id = `$INFO $part`);
  $blk_id =~ m!^$part: UUID="([0-9a-f\-]+)" TYPE="(.+)" $!;
  my $old_uuid = $1;
  my $type = $2;
  die "No old UUID found for $part\n" unless defined $old_uuid;

  chomp(my $new_uuid = `$UUIDGEN`);
  die "No new UUID generated for $part\n" unless defined $new_uuid;

  $uuids{$part} = { old => $old_uuid, new => $new_uuid, type => $type };
}

#print Dumper(%uuids);
#exit;

# Set UUIDs in fstab
foreach my $part (@partitions) {
  if ($uuids{$part}{type} eq 'ext4') {
    system $TUNE2FS, $part, "-U", $uuids{$part}{new};
  } elsif ($uuids{$part}{type} eq 'swap') {
    system $SWAPOFF, $part;
    system $MKSWAP, "-U", $uuids{$part}{new}, $part;
    system $SWAPON, $part;
  }
  system $SED, "-i", "s/$uuids{$part}{old}/$uuids{$part}{new}/", '/etc/fstab';
}

# Special-case: set root UUID in grub.conf
system $SED, "-i", "s/$uuids{$ROOT}{old}/$uuids{$ROOT}{new}/", '/boot/grub/grub.conf';
