| Dean Troyer | 65cf608 | 2011-09-16 12:22:21 -0500 | [diff] [blame] | 1 | #!/bin/bash | 
|  | 2 | # make_image.sh - Create Ubuntu images in various formats | 
|  | 3 | # | 
| Dean Troyer | 57794d4 | 2011-09-16 17:22:23 -0500 | [diff] [blame] | 4 | # Supported formats: qcow (kvm), vmdk (vmserver), vdi (vbox), vhd (vpc), raw | 
| Dean Troyer | 65cf608 | 2011-09-16 12:22:21 -0500 | [diff] [blame] | 5 | # | 
|  | 6 | # Requires sudo to root | 
|  | 7 |  | 
|  | 8 | ROOTSIZE=${ROOTSIZE:-8192} | 
|  | 9 | SWAPSIZE=${SWAPSIZE:-1024} | 
| Dean Troyer | a41f9c7 | 2011-09-29 16:35:43 -0500 | [diff] [blame] | 10 | MIN_PKGS=${MIN_PKGS:-"apt-utils gpgv openssh-server"} | 
| Dean Troyer | 65cf608 | 2011-09-16 12:22:21 -0500 | [diff] [blame] | 11 |  | 
|  | 12 | usage() { | 
| Dean Troyer | a41f9c7 | 2011-09-29 16:35:43 -0500 | [diff] [blame] | 13 | echo "Usage: $0 - Create Ubuntu images" | 
| Dean Troyer | 65cf608 | 2011-09-16 12:22:21 -0500 | [diff] [blame] | 14 | echo "" | 
| Dean Troyer | a41f9c7 | 2011-09-29 16:35:43 -0500 | [diff] [blame] | 15 | echo "$0 [-m] [-r rootsize] [-s swapsize] release format" | 
|  | 16 | echo "$0 -C [-m] release chrootdir" | 
|  | 17 | echo "$0 -I [-r rootsize] [-s swapsize] chrootdir format" | 
|  | 18 | echo "" | 
|  | 19 | echo "-C        - Create the initial chroot dir" | 
|  | 20 | echo "-I        - Create the final image from a chroot" | 
|  | 21 | echo "-m        - minimal installation" | 
|  | 22 | echo "-r size   - root fs size in MB" | 
|  | 23 | echo "-s size   - swap fs size in MB" | 
|  | 24 | echo "release   - Ubuntu release: jaunty - oneric" | 
|  | 25 | echo "format    - image format: qcow2, vmdk, vdi, vhd, xen, raw, fs" | 
| Dean Troyer | 65cf608 | 2011-09-16 12:22:21 -0500 | [diff] [blame] | 26 | exit 1 | 
|  | 27 | } | 
|  | 28 |  | 
| Dean Troyer | a41f9c7 | 2011-09-29 16:35:43 -0500 | [diff] [blame] | 29 | while getopts CIhmr:s: c; do | 
| Dean Troyer | 65cf608 | 2011-09-16 12:22:21 -0500 | [diff] [blame] | 30 | case $c in | 
| Dean Troyer | a41f9c7 | 2011-09-29 16:35:43 -0500 | [diff] [blame] | 31 | C)  CHROOTONLY=1 | 
|  | 32 | ;; | 
|  | 33 | I)  IMAGEONLY=1 | 
|  | 34 | ;; | 
| Dean Troyer | 4dd420e | 2011-09-16 16:16:34 -0500 | [diff] [blame] | 35 | h)  usage | 
|  | 36 | ;; | 
| Dean Troyer | a41f9c7 | 2011-09-29 16:35:43 -0500 | [diff] [blame] | 37 | m)  MINIMAL=1 | 
| Dean Troyer | 4dd420e | 2011-09-16 16:16:34 -0500 | [diff] [blame] | 38 | ;; | 
|  | 39 | r)  ROOTSIZE=$OPTARG | 
|  | 40 | ;; | 
|  | 41 | s)  SWAPSIZE=$OPTARG | 
|  | 42 | ;; | 
| Dean Troyer | 65cf608 | 2011-09-16 12:22:21 -0500 | [diff] [blame] | 43 | esac | 
|  | 44 | done | 
|  | 45 | shift `expr $OPTIND - 1` | 
|  | 46 |  | 
| Dean Troyer | a4b5877 | 2011-09-29 21:30:27 -0500 | [diff] [blame] | 47 | if [ ! "$#" -eq "2" -o -n "$CHROOTONLY" -a -n "$IMAGEONLY" ]; then | 
| Dean Troyer | a41f9c7 | 2011-09-29 16:35:43 -0500 | [diff] [blame] | 48 | usage | 
|  | 49 | fi | 
|  | 50 |  | 
|  | 51 | # Default args | 
| Dean Troyer | 65cf608 | 2011-09-16 12:22:21 -0500 | [diff] [blame] | 52 | RELEASE=$1 | 
|  | 53 | FORMAT=$2 | 
| Dean Troyer | a41f9c7 | 2011-09-29 16:35:43 -0500 | [diff] [blame] | 54 | CHROOTDIR="" | 
|  | 55 |  | 
|  | 56 | if [ -n "$CHROOTONLY" ]; then | 
|  | 57 | RELEASE=$1 | 
|  | 58 | CHROOTDIR=$2 | 
|  | 59 | FORMAT="pass" | 
|  | 60 | fi | 
|  | 61 |  | 
|  | 62 | if [ -n "$IMAGEONLY" ]; then | 
|  | 63 | CHROOTDIR=$1 | 
|  | 64 | FORMAT=$2 | 
|  | 65 | RELEASE="pass" | 
|  | 66 | fi | 
| Dean Troyer | 65cf608 | 2011-09-16 12:22:21 -0500 | [diff] [blame] | 67 |  | 
| Dean Troyer | ecc5a90 | 2011-10-25 15:49:47 -0500 | [diff] [blame] | 68 | # Make sure that we have the proper version of ubuntu | 
|  | 69 | UBUNTU_VERSION=`cat /etc/lsb-release | grep CODENAME | sed 's/.*=//g'` | 
|  | 70 | if [ "$UBUNTU_VERSION" = "natty" -a "$RELEASE" = "oneiric" ]; then | 
|  | 71 | echo "natty installs can't build oneiric images" | 
|  | 72 | exit 1 | 
|  | 73 | fi | 
|  | 74 |  | 
| Dean Troyer | 4dd420e | 2011-09-16 16:16:34 -0500 | [diff] [blame] | 75 | case $FORMAT in | 
|  | 76 | kvm|qcow2)  FORMAT=qcow2 | 
| Dean Troyer | 57794d4 | 2011-09-16 17:22:23 -0500 | [diff] [blame] | 77 | QFORMAT=qcow2 | 
|  | 78 | HYPER=kvm | 
| Dean Troyer | 4dd420e | 2011-09-16 16:16:34 -0500 | [diff] [blame] | 79 | ;; | 
|  | 80 | vmserver|vmdk) | 
|  | 81 | FORMAT=vmdk | 
| Dean Troyer | 57794d4 | 2011-09-16 17:22:23 -0500 | [diff] [blame] | 82 | QFORMAT=vmdk | 
|  | 83 | HYPER=vmserver | 
| Dean Troyer | 4dd420e | 2011-09-16 16:16:34 -0500 | [diff] [blame] | 84 | ;; | 
| Dean Troyer | 57794d4 | 2011-09-16 17:22:23 -0500 | [diff] [blame] | 85 | vbox|vdi)   FORMAT=vdi | 
|  | 86 | QFORMAT=vdi | 
|  | 87 | HYPER=kvm | 
| Dean Troyer | 4dd420e | 2011-09-16 16:16:34 -0500 | [diff] [blame] | 88 | ;; | 
| Dean Troyer | 57794d4 | 2011-09-16 17:22:23 -0500 | [diff] [blame] | 89 | vhd|vpc)    FORMAT=vhd | 
|  | 90 | QFORMAT=vpc | 
|  | 91 | HYPER=kvm | 
| Dean Troyer | 4dd420e | 2011-09-16 16:16:34 -0500 | [diff] [blame] | 92 | ;; | 
|  | 93 | xen)        FORMAT=raw | 
| Dean Troyer | 57794d4 | 2011-09-16 17:22:23 -0500 | [diff] [blame] | 94 | QFORMAT=raw | 
|  | 95 | HYPER=xen | 
|  | 96 | ;; | 
|  | 97 | raw)        FORMAT=raw | 
|  | 98 | QFORMAT=raw | 
|  | 99 | HYPER=kvm | 
| Dean Troyer | 4dd420e | 2011-09-16 16:16:34 -0500 | [diff] [blame] | 100 | ;; | 
| Dean Troyer | a41f9c7 | 2011-09-29 16:35:43 -0500 | [diff] [blame] | 101 | pass)       ;; | 
| Dean Troyer | 4dd420e | 2011-09-16 16:16:34 -0500 | [diff] [blame] | 102 | *)          echo "Unknown format: $FORMAT" | 
|  | 103 | usage | 
| Dean Troyer | 65cf608 | 2011-09-16 12:22:21 -0500 | [diff] [blame] | 104 | esac | 
|  | 105 |  | 
| Dean Troyer | 4dd420e | 2011-09-16 16:16:34 -0500 | [diff] [blame] | 106 | case $RELEASE in | 
| Dean Troyer | fcfa9c3 | 2011-10-24 16:18:52 -0500 | [diff] [blame] | 107 | oneiric)    ;; | 
| Dean Troyer | 4dd420e | 2011-09-16 16:16:34 -0500 | [diff] [blame] | 108 | natty)      ;; | 
|  | 109 | maverick)   ;; | 
|  | 110 | lucid)      ;; | 
|  | 111 | karmic)     ;; | 
|  | 112 | jaunty)     ;; | 
| Dean Troyer | a41f9c7 | 2011-09-29 16:35:43 -0500 | [diff] [blame] | 113 | pass)       ;; | 
| Dean Troyer | 4dd420e | 2011-09-16 16:16:34 -0500 | [diff] [blame] | 114 | *)          echo "Unknown release: $RELEASE" | 
|  | 115 | usage | 
|  | 116 | ;; | 
| Dean Troyer | 65cf608 | 2011-09-16 12:22:21 -0500 | [diff] [blame] | 117 | esac | 
|  | 118 |  | 
|  | 119 | # Install stuff if necessary | 
|  | 120 | if [ -z `which vmbuilder` ]; then | 
| Anthony Young | fa4b5eb | 2011-10-19 11:27:02 -0700 | [diff] [blame] | 121 | sudo apt-get install -y ubuntu-vm-builder | 
| Dean Troyer | 65cf608 | 2011-09-16 12:22:21 -0500 | [diff] [blame] | 122 | fi | 
|  | 123 |  | 
| Dean Troyer | a41f9c7 | 2011-09-29 16:35:43 -0500 | [diff] [blame] | 124 | if [ -n "$CHROOTONLY" ]; then | 
|  | 125 | # Build a chroot directory | 
|  | 126 | HYPER=kvm | 
|  | 127 | if [ "$MINIMAL" = 1 ]; then | 
|  | 128 | ARGS="--variant=minbase" | 
|  | 129 | for i in $MIN_PKGS; do | 
|  | 130 | ARGS="$ARGS --addpkg=$i" | 
|  | 131 | done | 
|  | 132 | fi | 
|  | 133 | sudo vmbuilder $HYPER ubuntu $ARGS \ | 
|  | 134 | --suite $RELEASE \ | 
|  | 135 | --only-chroot \ | 
|  | 136 | --chroot-dir=$CHROOTDIR \ | 
|  | 137 | --overwrite \ | 
|  | 138 | --addpkg=$MIN_PKGS \ | 
|  | 139 |  | 
|  | 140 | sudo cp -p files/sources.list $CHROOTDIR/etc/apt/sources.list | 
| Jesse Andrews | 97c8474 | 2011-10-31 11:45:17 -0700 | [diff] [blame] | 141 | sed -e "s,%DIST%,$RELEASE,g" -i $CHROOTDIR/etc/apt/sources.list | 
| Dean Troyer | a41f9c7 | 2011-09-29 16:35:43 -0500 | [diff] [blame] | 142 | sudo chroot $CHROOTDIR apt-get update | 
|  | 143 |  | 
|  | 144 | exit 0 | 
|  | 145 | fi | 
|  | 146 |  | 
| Dean Troyer | 65cf608 | 2011-09-16 12:22:21 -0500 | [diff] [blame] | 147 | # Build the image | 
| Dean Troyer | a41f9c7 | 2011-09-29 16:35:43 -0500 | [diff] [blame] | 148 | TMPDIR=tmp | 
| Dean Troyer | 57794d4 | 2011-09-16 17:22:23 -0500 | [diff] [blame] | 149 | TMPDISK=`mktemp imgXXXXXXXX` | 
|  | 150 | SIZE=$[$ROOTSIZE+$SWAPSIZE+1] | 
| Dean Troyer | a41f9c7 | 2011-09-29 16:35:43 -0500 | [diff] [blame] | 151 | dd if=/dev/null of=$TMPDISK bs=1M seek=$SIZE count=1 | 
|  | 152 |  | 
|  | 153 | if [ -n "$IMAGEONLY" ]; then | 
|  | 154 | # Build image from chroot | 
|  | 155 | sudo vmbuilder $HYPER ubuntu $ARGS \ | 
| Dean Troyer | c0a6739 | 2011-10-03 16:31:36 -0500 | [diff] [blame] | 156 | --existing-chroot=$CHROOTDIR \ | 
| Dean Troyer | a41f9c7 | 2011-09-29 16:35:43 -0500 | [diff] [blame] | 157 | --overwrite \ | 
|  | 158 | --rootsize=$ROOTSIZE \ | 
|  | 159 | --swapsize=$SWAPSIZE \ | 
|  | 160 | --tmpfs - \ | 
|  | 161 | --raw=$TMPDISK \ | 
|  | 162 |  | 
|  | 163 | else | 
|  | 164 | # Do the whole shebang in one pass | 
|  | 165 | ARGS="--variant=minbase" | 
|  | 166 | for i in $MIN_PKGS; do | 
|  | 167 | ARGS="$ARGS --addpkg=$i" | 
|  | 168 | done | 
|  | 169 | sudo vmbuilder $HYPER ubuntu $ARGS \ | 
|  | 170 | --suite $RELEASE \ | 
|  | 171 | --overwrite \ | 
|  | 172 | --rootsize=$ROOTSIZE \ | 
|  | 173 | --swapsize=$SWAPSIZE \ | 
|  | 174 | --tmpfs - \ | 
|  | 175 | --raw=$TMPDISK \ | 
|  | 176 |  | 
|  | 177 | fi | 
| Dean Troyer | 65cf608 | 2011-09-16 12:22:21 -0500 | [diff] [blame] | 178 |  | 
| Dean Troyer | 57794d4 | 2011-09-16 17:22:23 -0500 | [diff] [blame] | 179 | if [ "$FORMAT" = "raw" ]; then | 
| Dean Troyer | 65cf608 | 2011-09-16 12:22:21 -0500 | [diff] [blame] | 180 | # Get image | 
| Dean Troyer | 57794d4 | 2011-09-16 17:22:23 -0500 | [diff] [blame] | 181 | mv $TMPDISK $RELEASE.$FORMAT | 
| Dean Troyer | 65cf608 | 2011-09-16 12:22:21 -0500 | [diff] [blame] | 182 | else | 
|  | 183 | # Convert image | 
| Dean Troyer | 57794d4 | 2011-09-16 17:22:23 -0500 | [diff] [blame] | 184 | qemu-img convert -O $QFORMAT $TMPDISK $RELEASE.$FORMAT | 
|  | 185 | rm $TMPDISK | 
| Dean Troyer | 65cf608 | 2011-09-16 12:22:21 -0500 | [diff] [blame] | 186 | fi | 
| Dean Troyer | 57794d4 | 2011-09-16 17:22:23 -0500 | [diff] [blame] | 187 | rm -rf ubuntu-$HYPER |