#  -*- mode: python; -*-
#============================================================================
# Example Python setup script for Debian guest installation.
#============================================================================
#
# Standard options are configured as normal. Only a subset are included below.
# See /usr/share/doc/xen-utils-common/examples for full examples.
#
# After standard options are configure use
#    xm create debian.cfg install=true"
# to start the Debian Installer.
#
# In the installation case the following additional variables exist:
#
# COMMON OPTIONS
# install-method: "cdrom" or "network"
# install-arch: which architecture to install. e.g. i386 or amd64
# install-installer: URL or path to the Debian Installer bits. By
#   default for a network install these are located under
#   install-mirror. For a CDROM install the default is a fixed path on
#   the CD.
# install-kernel, install-ramdisk: URL/path to the installer kernel and
#   ramdisk to use, by default these are located via install-installer.
# install-extra: extra command line arguments
#
# CDROM SPECIFIC OPTIONS
# install-media: Path to the Debian install media (i.e. an ISO)
# install-cdrom-device: Name of the CD-ROM device within the guest.
#
# NETWORK SPECIFIC OPTIONS
# install-suite: which Debian version to install. e.g. lenny, squeeze or sid
# install-mirror: which Debian mirror to use
#   e.g. http://ftp.uk.debian.org/debian
#============================================================================


#----------------------------------------------------------------------------
# Standard variables

# Initial memory allocation (in megabytes) for the new domain.
memory = 256

# A name for your domain. All domains must have different names.
name = "ExampleDomain"

# 128-bit UUID for the domain.  The default behavior is to generate a new UUID
# on each call to 'xm create'.
#uuid = "06ed00fe-1162-4fc4-b5d8-11993ee4a8b9"

# List of which CPUS this domain is allowed to use, default Xen picks
#cpus = ""         # leave to Xen to pick
#cpus = "0"        # all vcpus run on CPU0
#cpus = "0-3,5,^1" # run on cpus 0,2,3,5

# Number of Virtual CPUS to use, default is 1
#vcpus = 1

#----------------------------------------------------------------------------
# Define network interfaces.

# By default, no network interfaces are configured.  You may have one created
# with sensible defaults using an empty vif clause:
#
# vif = ['']
#
# or optionally override backend, bridge, ip, mac, script, type, or vifname:
#
# vif = ['mac=00:16:3e:00:00:11, bridge=xenbr0']
#
# or more than one interface may be configured:
#
# vif = ['', 'bridge=xenbr1']

vif = ['']

#----------------------------------------------------------------------------
# Define the disk devices you want the domain to have access to, and
# what you want them accessible as.
# Each disk entry is of the form phy:UNAME,DEV,MODE
# where UNAME is the device, DEV is the device name the domain will see,
# and MODE is r for read-only, w for read-write.
#
# NB: Only xvd devices are supported by the kernel in Debian Lenny and later.

disk = ['file:/path/to/disk.img,xvda,w']

#============================================================================
# Debian Installer specific variables

def check_bool(name, value):
    value = str(value).lower()
    if value in ('t', 'tr', 'tru', 'true'):
        return True
    return False

global var_check_with_default
def var_check_with_default(default, var, val):
    if val:
        return val
    return default

xm_vars.var('install', use='Install Debian, default: false', check=check_bool)
xm_vars.var("install-method",
            use='Installation method to use "cdrom" or "network" (default: network)',
            check=lambda var, val: var_check_with_default('network', var, val))

# install-method == "network"
xm_vars.var("install-mirror",
            use='Debian mirror to install from (default: http://ftp.debian.org/debian)',
            check=lambda var, val: var_check_with_default('http://ftp.debian.org/debian', var, val))
xm_vars.var("install-suite",
            use='Debian suite to install (default: unstable)',
            check=lambda var, val: var_check_with_default('unstable', var, val))

# install-method == "cdrom"
xm_vars.var("install-media",
            use='Installation media to use (default: None)',
            check=lambda var, val: var_check_with_default(None, var, val))
xm_vars.var("install-cdrom-device",
            use='Installation media to use (default: xvdd)',
            check=lambda var, val: var_check_with_default('xvdd', var, val))

# Common options
xm_vars.var("install-arch",
            use='Debian mirror to install from (default: hurd-i386)',
            check=lambda var, val: var_check_with_default('hurd-i386', var, val))
xm_vars.var("install-extra",
            use='Extra command line options (default: None)',
            check=lambda var, val: var_check_with_default(None, var, val))
xm_vars.var("install-installer",
            use='Debian installer to use (default: network uses install-mirror; cdrom uses /install.ARCH)',
            check=lambda var, val: var_check_with_default(None, var, val))
xm_vars.var("install-kernel",
            use='Debian installer kernel to use (default: uses install-installer)',
            check=lambda var, val: var_check_with_default(None, var, val))
xm_vars.var("install-ramdisk",
            use='Debian installer ramdisk to use (default: uses install-installer)',
            check=lambda var, val: var_check_with_default(None, var, val))

xm_vars.check()

if not xm_vars.env.get('install'):
    bootloader="pygrub"
elif xm_vars.env['install-method'] == "network":
    import os.path
    print "Install Mirror: %s" % xm_vars.env['install-mirror']
    print "Install Suite: %s" % xm_vars.env['install-suite']
    if xm_vars.env['install-installer']:
        installer = xm_vars.env['install-installer']
    else:
        installer = xm_vars.env['install-mirror']+"/dists/"+xm_vars.env['install-suite'] + \
                    "/main/installer-"+xm_vars.env['install-arch']+"/current/images"
    print "Installer: %s" % installer

    print
    print "WARNING: Installer kernel and ramdisk are not authenticated."
    print

    if xm_vars.env.get('install-kernel'):
        kernelurl = xm_vars.env['install-kernel']
    else:
        kernelurl = installer + "/netboot/xen/gnumach"

    if xm_vars.env.get('install-ramdisk'):
        ramdiskurl = xm_vars.env['install-ramdisk']
    else:
        ramdiskurl = installer + "/netboot/xen/modules"

    import urllib
    class MyUrlOpener(urllib.FancyURLopener):
        def http_error_default(self, req, fp, code, msg, hdrs):
            raise IOError("%s %s" % (code, msg))
    urlopener = MyUrlOpener()

    try:
        print "Fetching %s" % kernelurl
        kernel, _ = urlopener.retrieve(kernelurl)
        print "Fetching %s" % ramdiskurl
        ramdisk, _ = urlopener.retrieve(ramdiskurl)
    except IOError, _:
        raise

elif xm_vars.env['install-method'] == "cdrom":
    arch_path = { 'i386': "/install.386",
                  'amd64': "/install.amd" }

    if xm_vars.env['install-media']:
        print "Install Media: %s" % xm_vars.env['install-media']
    else:
        raise OptionError("No installation media given.")

    if xm_vars.env['install-installer']:
        installer = xm_vars.env['install-installer']
    else:
        installer = arch_path[xm_vars.env['install-arch']]

    print "Installer: %s" % installer

    if xm_vars.env.get('install-kernel'):
        kernelpath = xm_vars.env['install-kernel']
    else:
        kernelpath = installer + "/xen/gnumach"

    if xm_vars.env.get('install-ramdisk'):
        ramdiskpath = xm_vars.env['install-ramdisk']
    else:
        ramdiskpath = installer + "/xen/modules"

    disk.insert(0, 'file:%s,%s:cdrom,r' % (xm_vars.env['install-media'],
                                           xm_vars.env['install-cdrom-device']))

    bootloader="pygrub"
    bootargs="--kernel=%s --ramdisk=%s" % (kernelpath, ramdiskpath)
    print "From CD"
else:
    print "WARNING: Unknown install-method: %s." % xm_vars.env['install-method']

if xm_vars.env.get('install'):
    # Figure out command line
    if xm_vars.env['install-extra']:
        extras=[xm_vars.env['install-extra']]
    else:
        extras=[]

    # Reboot will just restart the installer since this file is not
    # reparsed, so halt and restart that way.
    extras.append("-H")

    extras.append("root=gunzip:device:rd0")
    # TODO: actually inherit
    extras.append("TERM=ansi")

    extra = str.join(" ", extras)
    print "command line is \"%s\"" % extra
