#!/bin/bash # $HeadURL$ $LastChangedRevision$ # Properties MY_ID=system PARENT_ID= MY_PRIVATE_ATTRIBUTES="uname status debian_url" MY_PUBLIC_ATTRIBUTES="arch release kernel_commandline vm_flag hvm_flag bootmedia engine virttool macaddr pdi dnsclient_flag dnsclient_domain dnsclient_servers serial_console_flag" MY_ATTRIBUTES="$MY_PRIVATE_ATTRIBUTES $MY_PUBLIC_ATTRIBUTES" # Helpers are set explicitly, because order is important. MY_HELPER_IDS="dns repo boot preseed pdi hardware" # My attributes for MY_ATTRIBUTE in ${MY_ATTRIBUTES^^}; do eval "$MY_ATTRIBUTE="; done # Defaults for the questions we ask (should only used here) DFLT_RELEASE=wheezy DFLT_ARCH=amd64 DFLT_VM_FLAG=y DFLT_HVM_FLAG=n DFLT_BOOTMEDIA=net DFLT_ENGINE=kvm DFLT_VIRTTOOL=virt-manager DFLT_PDI=true DFLT_MACADDR= DFLT_DNSCLIENT_FLAG=true DFLT_DNSCLIENT_DOMAIN=$(dnsdomainname) DFLT_DNSCLIENT_SERVERS="192.168.1.2" DFLT_SERIAL_CONSOLE_FLAG=false # Other globals PRESEEDSERVER_IPADDR=$(host $(uname -n) 2> /dev/null | sed 's/.*has address //') # Hooks init_prologue() { inherit SQLITE_CMD DB_FILE # Create extra tables debug 10 "init_prologue: creating extra tables ..." # Why does this table have an allergy to the helper column being called 'helper'? Instead, $SQLITE_CMD $DB_FILE "drop table if exists helpers;" $SQLITE_CMD $DB_FILE "create table helpers ( helper text not null, parent_helper text not null, primary key (helper) );" $SQLITE_CMD $DB_FILE "drop table if exists attributes;" $SQLITE_CMD $DB_FILE "create table attributes ( helper text not null, attribute text not null, public integer check (public == 0 or public == 1), primary key (helper, attribute) );" $SQLITE_CMD $DB_FILE "drop table if exists attribute_values;" $SQLITE_CMD $DB_FILE "create table attribute_values ( helper text not null, attribute text not null, uname text not null, value text not null, primary key (helper, attribute, uname) );" return 0 } init_epilogue() { # This view will help load_local_attributes() and load_inherited_attributes(). # It consists of a deeper and deeper recursion (via helpers) to determine # the attributes that an ancestor table makes public. And then tagged on the # beginning is a rather contorted view of the attributes table to fit into # the same form as the others (which just says that an owner has permission to # view its own attributes (but which helps to provide a *single* interface # for looking this stuff up in). $SQLITE_CMD $DB_FILE "drop view if exists attribute_viewing_permissions;" $SQLITE_CMD $DB_FILE "create view attribute_viewing_permissions as select helper as viewing_helper,helper as owning_helper,attribute from attributes union select h1.helper,attributes.helper,attributes.attribute from helpers as h1,attributes where h1.parent_helper == attributes.helper and attributes.public == 1 union select h1.helper,attributes.helper,attributes.attribute from helpers as h1,helpers as h2,attributes where h1.parent_helper == h2.helper and h2.parent_helper == attributes.helper and attributes.public == 1 union select h1.helper,attributes.helper,attributes.attribute from helpers as h1,helpers as h2,helpers as h3,attributes where h1.parent_helper == h2.helper and h2.parent_helper == h3.helper and h3.parent_helper == attributes.helper and attributes.public == 1 union select h1.helper,attributes.helper,attributes.attribute from helpers as h1,helpers as h2,helpers as h3,helpers as h4,attributes where h1.parent_helper == h2.helper and h2.parent_helper == h3.helper and h3.parent_helper == h4.helper and h4.parent_helper == attributes.helper and attributes.public == 1 union select h1.helper,attributes.helper,attributes.attribute from helpers as h1,helpers as h2,helpers as h3,helpers as h4,helpers as h5,attributes where h1.parent_helper == h2.helper and h2.parent_helper == h3.helper and h3.parent_helper == h4.helper and h4.parent_helper == h5.helper and h5.parent_helper == attributes.helper and attributes.public == 1 union select h1.helper,attributes.helper,attributes.attribute from helpers as h1,helpers as h2,helpers as h3,helpers as h4,helpers as h5,helpers as h6,attributes where h1.parent_helper == h2.helper and h2.parent_helper == h3.helper and h3.parent_helper == h4.helper and h4.parent_helper == h5.helper and h5.parent_helper == h6.helper and h6.parent_helper == attributes.helper and attributes.public == 1 order by viewing_helper,owning_helper,attribute;" return 0 } edit_prologue() { inherit MY_HELPER_IDS DISPLAY_PROGNAME inherit ${MY_ATTRIBUTES^^} debug 10 "edit_prologue: prompting for changes ..." # VM? question --force-ask=true VM_FLAG "VM" "$DFLT_VM_FLAG" "echo \"y or n\"" validate_logical rationalise_logical if $VM_FLAG; then question --force-ask=true VIRTTOOL "virtualisation tool" "$DFLT_VIRTTOOL" "echo \"virsh or virt-manager\"" "validate_string \"^(virsh|virt-manager)\\\$\"" echo question --force-ask=true ENGINE "engine" "$DFLT_ENGINE" "echo \"xen or kvm\"" "validate_string \"^(xen|kvm)\\\$\"" echo else VIRTTOOL=not-used ENGINE=not-used fi if $VM_FLAG; then question --force-ask=true HVM_FLAG "HVM" "$DFLT_HVM_FLAG" "echo \"y or n\"" validate_logical rationalise_logical else HVM_FLAG=not-used fi # Serial console? if $VM_FLAG && ! $HVM_FLAG; then SERIAL_CONSOLE_FLAG=true else question --force-ask=true SERIAL_CONSOLE_FLAG "serial console" "$DFLT_SERIAL_CONSOLE_FLAG" "echo \"y or n\"" validate_logical rationalise_logical fi # Boot media question --force-ask=true BOOTMEDIA "boot media" "$DFLT_BOOTMEDIA" "echo \"net or cd\"" "validate_string \"^(net|cd)\\\$\"" echo # Kernel commandline if [ $BOOTMEDIA = net ]; then debug 10 "edit_prologue: VM_FLAG=$VM_FLAG, HVM_FLAG=$HVM_FLAG, RELEASE=$RELEASE, UNAME=$UNAME, SERIAL_CONSOLE_FLAG=$SERIAL_CONSOLE_FLAG" get_kernel_commandline_net $VM_FLAG $HVM_FLAG $RELEASE $UNAME $SERIAL_CONSOLE_FLAG KERNEL_COMMANDLINE || return $? else get_kernel_commandline_cd $UNAME KERNEL_COMMANDLINE || return $? fi # Arch question --force-ask=true ARCH "arch" "$DFLT_ARCH" "echo \"i386 or amd64\"" "validate_string \"^(i386|amd64)\\\$\"" rationalise_arch # Release question --force-ask=true RELEASE "release" "$DFLT_RELEASE" "echo \"lenny, squeeze or wheezy\"" "validate_string \"^(lenny|squeeze|wheezy)\\\$\"" rationalise_release # MAC address if [ $BOOTMEDIA != net ] && [ "X$MACADDR" = X ]; then MACADDR=not-used elif [ $BOOTMEDIA != net ]; then # Preserve MAC address for next time : elif $VM_FLAG && [ "X$MACADDR" = X ]; then info "inventing a MAC address ..." if [ $ENGINE = xen ]; then printf -v MACADDR "00:16:3e:%02x:%02x:%02x" $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)) else printf -v MACADDR "52:54:00:%02x:%02x:%02x" $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)) fi elif $VM_FLAG; then # Preserve MAC address for next time : else question --force-ask=true MACADDR "MAC address" "$DFLT_MACADDR" "enter MAC address in format xx:xx:xx:xx:xx:xx" validate_macaddr rationalise_macaddr fi # Install PDI? question --force-ask=true PDI "install pdi" "$DFLT_PDI" "echo \"no help available\"" validate_logical rationalise_logical # DNS question --force-ask=true DNSCLIENT_FLAG "DNS client" "$DFLT_DNSCLIENT_FLAG" help_nohelpavailable validate_logical rationalise_logical if $DNSCLIENT_FLAG; then question --force-ask=true DNSCLIENT_DOMAIN "DNS domain" "$DFLT_DNSCLIENT_DOMAIN" help_nohelpavailable validate_dnsdomain echo question --force-ask=true DNSCLIENT_SERVERS "space-separated IP address(es) of DNS server(s)" "$DFLT_DNSCLIENT_MODE" help_nohelpavailable "validate_list validate_ipaddr" echo else DNSCLIENT_DOMAIN=not-used DNSCLIENT_SERVERS=not-used fi return 0 } list_prologue() { : } # Support functions get_kernel_commandline_net() { # local for arguments local VM_FLAG HVM_FLAG RELEASE UNAME SERIAL_CONSOLE_FLAG KERNEL_COMMANDLINE_REF # globals inherit DNSCLIENT_DOMAIN PRESEEDSERVER_IPADDR PRESEEDSERVER_DIR PRESEEDSERVER_DOCROOT # real local local KERNEL_COMMANDLINE_LOCAL [ $# = 6 ] || internal "get_kernel_commandline_net: $#: bad argument count" VM_FLAG=$1 HVM_FLAG=$2 RELEASE=$3 UNAME=$4 SERIAL_CONSOLE_FLAG=$5 KERNEL_COMMANDLINE_REF=$6 # Console if $SERIAL_CONSOLE_FLAG; then KERNEL_COMMANDLINE_LOCAL+="console=ttyS0,115200 " fi # Language KERNEL_COMMANDLINE_LOCAL+="debian-installer/language=en " # Country KERNEL_COMMANDLINE_LOCAL+="debian-installer/country=US " # Locale KERNEL_COMMANDLINE_LOCAL+="debian-installer/locale=en_US.UTF-8 " # Keyboard KERNEL_COMMANDLINE_LOCAL+="keyboard-configuration/xkb-keymap=us " # macaroni has multiple NICS KERNEL_COMMANDLINE_LOCAL+="netcfg/choose_interface=auto " # Host name and domain KERNEL_COMMANDLINE_LOCAL+="netcfg/get_hostname=debian " KERNEL_COMMANDLINE_LOCAL+="netcfg/get_domain=$DNSCLIENT_DOMAIN " # IP configuration # PVs boot quicker and therefore make DHCP requests earlier which causes # STP problems on the bridge. ! $VM_FLAG || $HVM_FLAG || KERNEL_COMMANDLINE_LOCAL+="netcfg/dhcp_timeout=60 " # On wheezy, the installer is the graphical one. Disable that. KERNEL_COMMANDLINE_LOCAL+="DEBIAN_FRONTEND=newt " # The rest KERNEL_COMMANDLINE_LOCAL+="preseed/url=http://$PRESEEDSERVER_IPADDR${PRESEEDSERVER_DIR#$PRESEEDSERVER_DOCROOT}/$UNAME.cfg " eval "$KERNEL_COMMANDLINE_REF=\"$KERNEL_COMMANDLINE_LOCAL\"" return 0 } get_kernel_commandline_cd() { # local for arguments local UNAME KERNEL_COMMANDLINE_REF # globals inherit PRESEEDSERVER_IPADDR PRESEEDSERVER_DIR PRESEEDSERVER_DOCROOT # real local local KERNEL_COMMANDLINE_LOCAL [ $# = 2 ] || internal "get_kernel_commandline_cd: $#: bad argument count" UNAME=$1 KERNEL_COMMANDLINE_REF=$2 # Console if $VM_FLAG and ! $HVM_FLAG; then KERNEL_COMMANDLINE_LOCAL+="console=ttyS0,115200 " fi # The rest KERNEL_COMMANDLINE_LOCAL+="preseed/url=http://$PRESEEDSERVER_IPADDR${PRESEEDSERVER_DIR#$PRESEEDSERVER_DOCROOT}/$UNAME.cfg " eval "$KERNEL_COMMANDLINE_REF=\"$KERNEL_COMMANDLINE_LOCAL\"" return 0 }