a system for building guest images on demand (partially implemented)
authorGreg Price <price@mit.edu>
Tue, 16 Oct 2007 08:11:46 +0000 (04:11 -0400)
committerGreg Price <price@mit.edu>
Tue, 16 Oct 2007 08:11:46 +0000 (04:11 -0400)
The plan, roughly, is
 1. we download an upstream install CD iso, mount it, copy out the contents;
 2. when a user wants a VM, the script makes a copy, applies a small static
    patch (mostly a preseed file for the installer), adds a few vm-dependent
    variables to the preseed, maybe makes some other changes here,
    then makes an iso from that;
 3. we boot a vm from the new iso, with the empty volume as /dev/hda,
    and let the installer run.

This checkin implements 2 and 3, when run in an appropriate testing
environment, but I haven't adapted it to the real environment yet.
Step 2 turns out to be surprisingly fast; much less than a second.
Step 3, unfortunately, is looking like 20 minutes, maybe 10 if we
work at tightening it.  We'll want to mitigate that somehow.

Code in the 'partial' directory is meant to be moved elsewhere
as it gets integrated.

svn path=/trunk/packages/sipb-xen-guest-installer/sipb-xen-guest-installer/; revision=201

debian/changelog [new file with mode: 0644]
debian/compat [new file with mode: 0644]
debian/control [new file with mode: 0644]
debian/control.in [new file with mode: 0644]
debian/copyright [new file with mode: 0644]
debian/rules [new file with mode: 0755]
debian/sipb-xen-guest-installer.install [new file with mode: 0644]
partial/cdrom.patch [new file with mode: 0644]
partial/iso.url [new file with mode: 0644]
partial/preseed.cfg [new file with mode: 0644]
partial/sipb-xen-make-iso.py [new file with mode: 0755]

diff --git a/debian/changelog b/debian/changelog
new file mode 100644 (file)
index 0000000..5b9025a
--- /dev/null
@@ -0,0 +1,5 @@
+sipb-xen-guest-installer (1.0) unstable; urgency=low
+  * Initial release.
+ -- Greg Price <price@mega-man.mit.edu>  Tue, 16 Oct 2007 03:01:08 -0400
diff --git a/debian/compat b/debian/compat
new file mode 100644 (file)
index 0000000..b8626c4
--- /dev/null
@@ -0,0 +1 @@
diff --git a/debian/control b/debian/control
new file mode 100644 (file)
index 0000000..0df6d21
--- /dev/null
@@ -0,0 +1,12 @@
+Source: sipb-xen-remctl-auto
+Section: net
+Priority: extra
+Maintainer: SIPB Xen Project <sipb-xen@mit.edu>
+Build-Depends: cdbs (>= 0.4.23-1.1), debhelper (>= 4.1.0)
+Standards-Version: 3.7.2
+Package: sipb-xen-remctl-auto
+Architecture: all
+Depends: ${misc:Depends}, remctl-server
+Description: Installs the SIPB Xen automatic remctl management system
+ This is our automatic remctl configuration management system.
diff --git a/debian/control.in b/debian/control.in
new file mode 100644 (file)
index 0000000..9e02b50
--- /dev/null
@@ -0,0 +1,12 @@
+Source: sipb-xen-guest-installer
+Section: net
+Priority: extra
+Maintainer: SIPB Xen Project <sipb-xen@mit.edu>
+Build-Depends: @cdbs@
+Standards-Version: 3.7.2
+Package: sipb-xen-guest-installer
+Architecture: all
+Depends: ${misc:Depends}
+Description: SIPB Xen automatic guest-image installer system
+ This is our automatic guest-image installer system.
diff --git a/debian/copyright b/debian/copyright
new file mode 100644 (file)
index 0000000..7bddd1a
--- /dev/null
@@ -0,0 +1,3 @@
+This package was created for internal use of the SIPB Xen Project of
+the MIT Student Information Processing Board.  Ask tabbott@mit.edu if
+you have questions about redistribution.
diff --git a/debian/rules b/debian/rules
new file mode 100755 (executable)
index 0000000..6bf6850
--- /dev/null
@@ -0,0 +1,4 @@
+#!/usr/bin/make -f
+include /usr/share/cdbs/1/rules/debhelper.mk
diff --git a/debian/sipb-xen-guest-installer.install b/debian/sipb-xen-guest-installer.install
new file mode 100644 (file)
index 0000000..9da31b3
--- /dev/null
@@ -0,0 +1 @@
+files/* .
diff --git a/partial/cdrom.patch b/partial/cdrom.patch
new file mode 100644 (file)
index 0000000..a741347
--- /dev/null
@@ -0,0 +1,16 @@
+diff -Nur cdrom.old/isolinux/isolinux.cfg cdrom/isolinux/isolinux.cfg
+--- cdrom.old/isolinux/isolinux.cfg 2007-08-20 16:16:20.000000000 -0400
++++ cdrom/isolinux/isolinux.cfg 2007-10-16 01:04:37.000000000 -0400
+@@ -12,7 +12,11 @@
+ F9 f9.txt
+ F0 f10.txt
+-DEFAULT install
++DEFAULT sipb-xen-install
++LABEL sipb-xen-install
++       kernel /install.amd/vmlinuz
++       append auto=true preseed/file=/cdrom/preseed.cfg priority=critical vga=normal fb=false initrd=/install.amd/initrd.gz --
+ LABEL install
+        kernel /install.amd/vmlinuz
diff --git a/partial/iso.url b/partial/iso.url
new file mode 100644 (file)
index 0000000..dc01ddf
--- /dev/null
@@ -0,0 +1 @@
diff --git a/partial/preseed.cfg b/partial/preseed.cfg
new file mode 100644 (file)
index 0000000..ee13a7f
--- /dev/null
@@ -0,0 +1,237 @@
+#### Contents of the preconfiguration file
+d-i debian-installer/locale string en_US
+d-i console-keymaps-at/keymap select us
+### Network configuration
+# netcfg will choose an interface that has link if possible. This makes it
+# skip displaying a list if there is more than one interface.
+d-i netcfg/choose_interface select auto
+#d-i netcfg/dhcp_timeout string 1
+d-i netcfg/use_dhcp boolean false
+# If you prefer to configure the network manually, uncomment this line and
+# the static network configuration below.
+d-i netcfg/disable_dhcp boolean true
+# Static network configuration.
+d-i netcfg/get_nameservers string
+# at bottom  #d-i netcfg/get_ipaddress string fillme
+d-i netcfg/get_netmask string
+d-i netcfg/get_gateway string
+d-i netcfg/confirm_static boolean true
+# Any hostname and domain names assigned from dhcp take precedence over
+# values set here. However, setting the values still prevents the questions
+# from being shown, even if values come from dhcp.
+# at bottom  #d-i netcfg/get_hostname string fillme
+d-i netcfg/get_domain string mit.edu
+# Disable that annoying WEP key dialog.
+d-i netcfg/wireless_wep string
+### Mirror settings
+# If you select ftp, the mirror/country string does not need to be set.
+#d-i mirror/protocol string ftp
+d-i mirror/country string enter information manually
+d-i mirror/http/hostname string debian.lcs.mit.edu
+d-i mirror/http/directory string /debian
+d-i mirror/http/proxy string
+# Suite to install.
+#d-i mirror/suite string testing
+# Suite to use for loading installer components (optional).
+#d-i mirror/udeb/suite string testing
+### Partitioning
+# If the system has free space you can choose to only partition that space.
+# Note: this must be preseeded with a localized (translated) value.
+#d-i partman-auto/init_automatically_partition \
+#      select Guided - use the largest continuous free space
+# Alternatively, you can specify a disk to partition. The device name
+# can be given in either devfs or traditional non-devfs format.
+# For example, to use the first disk:
+d-i partman-auto/disk string /dev/discs/disc0/disc
+# In addition, you'll need to specify the method to use.
+# The presently available methods are: "regular", "lvm" and "crypto"
+d-i partman-auto/method string lvm
+# If one of the disks that are going to be automatically partitioned
+# contains an old LVM configuration, the user will normally receive a
+# warning. This can be preseeded away...
+d-i partman-auto/purge_lvm_from_device boolean true
+# And the same goes for the confirmation to write the lvm partitions.
+d-i partman-lvm/confirm boolean true
+# You can choose from any of the predefined partitioning recipes.
+# Note: this must be preseeded with a localized (translated) value.
+d-i partman-auto/choose_recipe \
+       select All files in one partition (recommended for new users)
+#d-i partman-auto/choose_recipe \
+#       select Separate /home partition
+#d-i partman-auto/choose_recipe \
+#       select Separate /home, /usr, /var, and /tmp partitions
+# Or provide a recipe of your own...
+# The recipe format is documented in the file devel/partman-auto-recipe.txt.
+# If you have a way to get a recipe file into the d-i environment, you can
+# just point at it.
+#d-i partman-auto/expert_recipe_file string /hd-media/recipe
+# If not, you can put an entire recipe into the preconfiguration file in one
+# (logical) line. This example creates a small /boot partition, suitable
+# swap, and uses the rest of the space for the root partition:
+#d-i partman-auto/expert_recipe string                         \
+#      boot-root ::                                            \
+#              40 50 100 ext3                                  \
+#                      $primary{ } $bootable{ }                \
+#                      method{ format } format{ }              \
+#                      use_filesystem{ } filesystem{ ext3 }    \
+#                      mountpoint{ /boot }                     \
+#              .                                               \
+#              500 10000 1000000000 ext3                       \
+#                      method{ format } format{ }              \
+#                      use_filesystem{ } filesystem{ ext3 }    \
+#                      mountpoint{ / }                         \
+#              .                                               \
+#              64 512 300% linux-swap                          \
+#                      method{ swap } format{ }                \
+#              .
+# This makes partman automatically partition without confirmation.
+d-i partman/confirm_write_new_label boolean true
+d-i partman/choose_partition \
+       select Finish partitioning and write changes to disk
+d-i partman/confirm boolean true
+### Clock and time zone setup
+# Controls whether or not the hardware clock is set to UTC.
+d-i clock-setup/utc boolean true
+# You may set this to any valid setting for $TZ; see the contents of
+# /usr/share/zoneinfo/ for valid values.
+d-i time/zone string US/Eastern
+### Apt setup
+# You can choose to install non-free and contrib software.
+#d-i apt-setup/non-free boolean true
+#d-i apt-setup/contrib boolean true
+# Uncomment this if you don't want to use a network mirror.
+#d-i apt-setup/use_mirror boolean false
+# Uncomment this to avoid adding security sources, or
+# add a hostname to use a different server than security.debian.org.
+#d-i apt-setup/security_host string
+# Additional repositories, local[0-9] available
+#d-i apt-setup/local0/repository string \
+#       deb http://local.server/debian stable main
+#d-i apt-setup/local0/comment string local server
+# Enable deb-src lines
+#d-i apt-setup/local0/source boolean true
+# URL to the public key of the local repository; you must provide a key or
+# apt will complain about the unauthenticated repository and so the
+# sources.list line will be left commented out
+#d-i apt-setup/local0/key string http://local.server/key
+# By default the installer requires that repositories be authenticated
+# using a known gpg key. This setting can be used to disable that
+# authentication. Warning: Insecure, not recommended.
+#d-i debian-installer/allow_unauthenticated string true
+### Account setup
+# Skip creation of a root account (normal user account will be able to
+# use sudo).
+#d-i passwd/root-login boolean false
+# Alternatively, to skip creation of a normal user account.
+d-i passwd/make-user boolean false
+# Root password, either in clear text
+#d-i passwd/root-password password r00tme
+#d-i passwd/root-password-again password r00tme
+# or encrypted using an MD5 hash.
+# at bottom  #d-i passwd/root-password-crypted password [MD5 hash]
+# To create a normal user account.
+#d-i passwd/user-fullname string Debian User
+#d-i passwd/username string debian
+# Normal user's password, either in clear text
+#d-i passwd/user-password password insecure
+#d-i passwd/user-password-again password insecure
+# or encrypted using an MD5 hash.
+#d-i passwd/user-password-crypted password [MD5 hash]
+### Base system installation
+# Select the initramfs generator used to generate the initrd for 2.6 kernels.
+#d-i base-installer/kernel/linux/initramfs-generators string yaird
+### Boot loader installation
+# Grub is the default boot loader (for x86). If you want lilo installed
+# instead, uncomment this:
+#d-i grub-installer/skip boolean true
+# This is fairly safe to set, it makes grub install automatically to the MBR
+# if no other operating system is detected on the machine.
+d-i grub-installer/only_debian boolean true
+# This one makes grub-installer install to the MBR if it also finds some other
+# OS, which is less safe as it might not be able to boot that other OS.
+d-i grub-installer/with_other_os boolean true
+# Alternatively, if you want to install to a location other than the mbr,
+# uncomment and edit these lines:
+#d-i grub-installer/only_debian boolean false
+#d-i grub-installer/with_other_os boolean false
+#d-i grub-installer/bootdev  string (hd0,0)
+# To install grub to multiple disks:
+#d-i grub-installer/bootdev  string (hd0,0) (hd1,0) (hd2,0)
+### Package selection
+tasksel tasksel/first multiselect standard
+# Individual additional packages to install
+#d-i pkgsel/include string openssh-server build-essential
+### Finishing up the first stage install
+# Avoid that last message about the install being complete.
+d-i finish-install/reboot_in_progress note
+# This will prevent the installer from ejecting the CD during the reboot,
+# which is useful in some situations.
+#d-i cdrom-detect/eject boolean false
+### Preseeding other packages
+# Depending on what software you choose to install, or if things go wrong
+# during the installation process, it's possible that other questions may
+# be asked. You can preseed those too, of course. To get a list of every
+# possible question that could be asked during an install, do an
+# installation, and then run these commands:
+#   debconf-get-selections --installer > file
+#   debconf-get-selections >> file
+#### Advanced options
+### Running custom commands during the installation
+# d-i preseeding is inherently not secure. Nothing in the installer checks
+# for attempts at buffer overflows or other exploits of the values of a
+# preconfiguration file like this one. Only use preconfiguration files from
+# trusted locations! To drive that home, and because it's generally useful,
+# here's a way to run any shell command you'd like inside the installer,
+# automatically.
+# This first command is run as early as possible, just after
+# preseeding is read.
+#d-i preseed/early_command string anna-install some-udeb
+# This command is run just before the install finishes, but when there is
+# still a usable /target directory. You can chroot to /target and use it
+# directly, or use the apt-install and in-target commands to easily install
+# packages and run commands in the target system.
+#d-i preseed/late_command string apt-install zsh; in-target chsh -s /bin/zsh
+# sipb-xen: automatically filled-in values get appended here. 
+# at bottom  #d-i netcfg/get_ipaddress string fillme
+# at bottom  #d-i netcfg/get_hostname string fillme
+# at bottom  #d-i passwd/root-password-crypted password [MD5 hash]
diff --git a/partial/sipb-xen-make-iso.py b/partial/sipb-xen-make-iso.py
new file mode 100755 (executable)
index 0000000..5eadd32
--- /dev/null
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+import sys
+import os
+from subprocess import call
+def make_debian_cd(basetree, guest_ip, guest_hostname, passhash, output_iso):
+  old_preseed = file(os.path.join(basetree, 'preseed.cfg'))
+  cdtree = os.path.join(basetree, 'cdrom')
+  new_preseed = file(os.path.join(cdtree, 'preseed.cfg'), 'w')
+  new_preseed.write(old_preseed.read())
+  new_preseed.write('d-i netcfg/get_ipaddress string '+guest_ip+'\n')
+  new_preseed.write('d-i netcfg/get_hostname string '+guest_hostname+'\n')
+  new_preseed.write('d-i passwd/root-password-crypted password '+passhash+'\n')
+  new_preseed.close()
+  call('''mkisofs -r -V "SIPB-Xen_Custom_Install_CD" -cache-inodes -J -l
+           -b isolinux/isolinux.bin -c isolinux/boot.cat
+           -no-emul-boot -boot-load-size 4 -boot-info-table'''.split()
+       + ['-o', output_iso, cdtree])
+if __name__ == '__main__':
+  make_debian_cd(*sys.argv[1:])