#!/usr/bin/perl -w
#
#  Copyright (C) 2003-2006 Brian Elliott Finley
#  Copyright (C) 2006 Andrea Righi
#
#  $Id: si_mkbootpackage 3760 2006-10-08 15:21:30Z arighi $
#   vi:set filetype=perl:
# 
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
# 
#   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.
# 
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#

use lib "/usr/lib/systemimager/perl";
use strict;
use Carp;
use POSIX;
use File::Copy;
use File::Path;
use File::Basename;
use Getopt::Long;
use vars qw($VERSION);
use SystemImager::Common;
use SystemImager::UseYourOwnKernel;

# set version
$VERSION = "3.7.5";

# set extension to use when backing up config files
my $backup_extension = ".before_systemimager-$VERSION";

# configuration directory
my $systemimagerdir = "/etc/systemimager";

# location of temporary rsyncd.conf file
my $rsyncd_conf_file = "/tmp/rsyncd.conf.$$";

# set path
$ENV{PATH} = "/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin";

# we rely on english text when parsing command output
$ENV{"LANG"} = "C";

my $progname = basename $0;

my $version_info = <<"EOF";
$progname (part of SystemImager) v$VERSION

Copyright (C) 1999-2006 Brian Elliott Finley
Copyright (C) 2006 Andrea Righi

This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
EOF

my $help_info = $version_info . <<"EOF";

Usage: $progname --destination DIR [OPTION]...

Description:
        Takes the kernel specified, and necessary modules from it, and creates
        a new boot package based on said kernel.  The resultant files include
        a matched kernel and initrd.img that can be used as the SystemImager
        autoinstall client software.

Options:
 --version             
    Display version and copyright information.

 --help                
    Display this output.

 --destination DIR
    The destination directory to put the new boot package (kernel and
    initrd.img).

    Required.

  --yes                 
    Answer yes to all yes/no questions.

 --quiet
    Run silently.  Return an exit status of 0 for success or a non-zero
    exit status for failure.

 --my-modules
    Only include the modules that are currently loaded on this machine
    when creating the UYOK (Use Your Own Kernel) initrd.img.

    Without this option, all available modules are included whether or
    not they are currently in use (except for those listed in the
    /etc/systemimager/UYOK.modules_to_exclude file).

    Including all modules allows your UYOK kernel and initrd.img to be
    used with a greater variety of client hardware, but can make the
    resultant initrd.img much larger. 

 --kernel KERNEL
    Do not detect the kernel to use with UYOK, but instead use the
    file specified by the argument KERNEL.
    If --kernel is not specified, the running kernel will be used.

 --modules-dir DIR
    Get kernel modules to use with UYOK from the DIR repository.
    Use this parameter only with --kernel and only if you use UYOK
    feature.

 --image IMAGENAME
    Get kernel and kernel modules automatically from the image specified
    by IMAGENAME to use with UYOK (if executed on image server).
    Use this parameter only if you use UYOK feature.

 --filesystem FILESYSTEM
    Force the use of FILESYSTEM to create the initial ramdisk. Use the
    filesystem name as specified in /proc/filesystems.
    Important: the filesystem must be statically compiled in the kernel
    used to install the clients.

Download, report bugs, and make suggestions at:
http://systemimager.org/

EOF

GetOptions(
    "help"                 => \my $help,
    "quiet"                => \my $quiet,
    "destination=s"        => \my $destination,
    "my-modules"           => \my $my_modules,
    "kernel=s"             => \my $custom_kernel,
    "modules-dir=s"        => \my $modules_dir,
    "image=s"              => \my $image,
    "filesystem=s"         => \my $filesystem,
    "version"              => \my $version,
    "yes"                  => \my $yes
) || die "$help_info";


### BEGIN option validation ###
# show version if requested
if($version) {
    print $version_info;
    exit 0;
}

# give help if requested
if($help) {
    print "$help_info";
    exit 0;
}

# bail if not root
if ($> != 0) {
    print "Must be run as root!\n";
    exit 1;
}

unless($destination) {
    print "FATAL: missing --destination DIR option!\n";
    print qq(Try "$progname --help" for more info.\n);
    exit 1;
}

if(!($custom_kernel) and $modules_dir) {
    print "FATAL:  --modules-dir DIR option must be used in conjunction with --kernel KERNEL!\n";
    print qq(Try "$progname --help" for more info.\n);
    exit 1;
}

if($custom_kernel and !($modules_dir)) {
    print "WARNING: --kernel KERNEL used without --modules-dir DIR option!\n";
    print qq(You can use this option only if KERNEL is a monolithic kernel,\n) .
          qq(or if the needed modules are already present in the initrd\n) .
          qq(template (e.g. the standard BOEL kernel).\n\n);
    unless (($quiet) or ($yes)) {
        print "Continue? (y/[n]): ";
        my $answer = <>;
        unless($answer =~ /y/i) {
            print "Boot package build cancelled.  No files modified.\n";
            exit 1;
        }
    }
}

if($my_modules and $modules_dir) {
    print "FATAL:  --my-modules option conflicts with --modules-dir DIR!\n";
    print qq(Try "$progname --help" for more info.\n);
    exit 1;
}

if($custom_kernel and $image) {
    print "FATAL:  --kernel KERNEL option conflicts with --image IMAGENAME!\n";
    print qq(Try "$progname --help" for more info.\n);
    exit 1;
}

if($my_modules and $image) {
    print "FATAL:  --my-modules option conflicts with --image IMAGENAME!\n";
    print qq(Try "$progname --help" for more info.\n);
    exit 1;
}

# if quiet redirect all to /dev/null
if ($quiet) {
    open(STDERR, '>/dev/null');
    open(STDOUT, '>/dev/null');
}

# Do UYOK stuff.
create_boot_package();

print << "EOF";

Boot kernel and initrd.img (generated by the initrd_template package)
can be found in /etc/systemimager/boot. If PXE-booting, you can copy the
files to /tftpboot or the specified location.

EOF

# Well done.
exit(0);

### BEGIN functions
# SystemImager specific functions

#
# Usage: my $arch = get_arch();
#
sub get_arch {
	my $arch = (uname())[4];
	$arch =~ s/i.86/i386/;
	return $arch;
}

# Usage:
# create_boot_package();
sub create_boot_package {
    my $arch = get_arch();
    my $verbose = 1 unless($quiet);

    SystemImager::UseYourOwnKernel->create_uyok_initrd(
        $arch, $my_modules, $custom_kernel, $modules_dir,
        $image, $filesystem, $destination, $verbose
    );

    return 1;
}

### END functions

# /* vi: set filetype=perl ai et ts=4: */

