diff --git a/install/common/functions b/install/common/functions new file mode 100755 index 0000000..933062a --- /dev/null +++ b/install/common/functions @@ -0,0 +1,370 @@ +#!/bin/bash + +xe_min() +{ + local cmd="$1" + shift + xe "$cmd" --minimal "$@" +} + +function die_with_error { + local err_msg + + err_msg="$1" + + echo "$err_msg" >&2 + exit 1 +} + +function xapi_plugin_location { + for PLUGIN_DIR in "/etc/xapi.d/plugins/" "/usr/lib/xcp/plugins/" "/usr/lib/xapi/plugins" "/usr/lib64/xapi/plugins"; do + if [ -d $PLUGIN_DIR ]; then + echo $PLUGIN_DIR + return 0 + fi + done + return 1 +} + +function create_directory_for_kernels { + if [ -d "/boot/guest" ]; then + echo "INFO: /boot/guest directory already exists, using that" >&2 + else + local local_path + local_path="$(get_local_sr_path)/os-guest-kernels" + mkdir -p $local_path + ln -s $local_path /boot/guest + fi +} + +function create_directory_for_images { + if [ -d "/images" ]; then + echo "INFO: /images directory already exists, using that" >&2 + else + local local_path + local_path="$(get_local_sr_path)/os-images" + mkdir -p $local_path + ln -s $local_path /images + fi +} + +function get_local_sr { + xe pool-list params=default-SR minimal=true +} + +function get_local_sr_path { + pbd_path="/var/run/sr-mount/$(get_local_sr)" + pbd_device_config_path=`xe pbd-list sr-uuid=$(get_local_sr) params=device-config | grep " path: "` + if [ -n "$pbd_device_config_path" ]; then + pbd_uuid=`xe pbd-list sr-uuid=$(get_local_sr) minimal=true` + pbd_path=`xe pbd-param-get uuid=$pbd_uuid param-name=device-config param-key=path || echo ""` + fi + echo $pbd_path +} + +function find_ip_by_name { + local guest_name="$1" + local interface="$2" + + local period=10 + local max_tries=10 + local i=0 + + while true; do + if [ $i -ge $max_tries ]; then + echo "Timeout: ip address for interface $interface of $guest_name" + exit 11 + fi + + ipaddress=$(xe vm-list --minimal \ + name-label=$guest_name \ + params=networks | sed -ne "s,^.*${interface}/ip: \([0-9.]*\).*\$,\1,p") + + if [ -z "$ipaddress" ]; then + sleep $period + i=$((i+1)) + else + echo $ipaddress + break + fi + done +} + +function _vm_uuid { + local vm_name_label + + vm_name_label="$1" + + xe vm-list name-label="$vm_name_label" --minimal +} + +function _create_new_network { + local name_label + name_label=$1 + + xe network-create name-label="$name_label" +} + +function _multiple_networks_with_name { + local name_label + name_label=$1 + + # A comma indicates multiple matches + xe network-list name-label="$name_label" --minimal | grep -q "," +} + +function _network_exists { + local name_label + name_label=$1 + + ! [ -z "$(xe network-list name-label="$name_label" --minimal)" ] +} + +function _bridge_exists { + local bridge + bridge=$1 + + ! [ -z "$(xe network-list bridge="$bridge" --minimal)" ] +} + +function _network_uuid { + local bridge_or_net_name + bridge_or_net_name=$1 + + if _bridge_exists "$bridge_or_net_name"; then + xe network-list bridge="$bridge_or_net_name" --minimal + else + xe network-list name-label="$bridge_or_net_name" --minimal + fi +} + +function add_interface { + local vm_name_label + local bridge_or_network_name + + vm_name_label="$1" + bridge_or_network_name="$2" + device_number="$3" + + local vm + local net + + vm=$(_vm_uuid "$vm_name_label") + net=$(_network_uuid "$bridge_or_network_name") + xe vif-create network-uuid=$net vm-uuid=$vm device=$device_number +} + +function setup_network { + local bridge_or_net_name + bridge_or_net_name=$1 + + if ! _bridge_exists "$bridge_or_net_name"; then + if _network_exists "$bridge_or_net_name"; then + if _multiple_networks_with_name "$bridge_or_net_name"; then + cat >&2 << EOF +ERROR: Multiple networks found matching name-label to "$bridge_or_net_name" +please review your XenServer network configuration / localrc file. +EOF + exit 1 + fi + else + _create_new_network "$bridge_or_net_name" + fi + fi +} + +function bridge_for { + local bridge_or_net_name + bridge_or_net_name=$1 + + if _bridge_exists "$bridge_or_net_name"; then + echo "$bridge_or_net_name" + else + xe network-list name-label="$bridge_or_net_name" params=bridge --minimal + fi +} + +function xenapi_ip_on { + local bridge_or_net_name + bridge_or_net_name=$1 + + ip -4 addr show $(bridge_for "$bridge_or_net_name") |\ + awk '/inet/{split($2, ip, "/"); print ip[1];}' +} + +function xenapi_is_listening_on { + local bridge_or_net_name + bridge_or_net_name=$1 + + ! [ -z $(xenapi_ip_on "$bridge_or_net_name") ] +} + +function parameter_is_specified { + local parameter_name + parameter_name=$1 + + compgen -v | grep "$parameter_name" +} + +function append_kernel_cmdline { + local vm_name_label + local kernel_args + + vm_name_label="$1" + kernel_args="$2" + + local vm + local pv_args + + vm=$(_vm_uuid "$vm_name_label") + pv_args=$(xe vm-param-get param-name=PV-args uuid=$vm) + xe vm-param-set PV-args="$pv_args $kernel_args" uuid=$vm +} + +function destroy_all_vifs_of { + local vm_name_label + + vm_name_label="$1" + + local vm + + vm=$(_vm_uuid "$vm_name_label") + IFS=, + for vif in $(xe vif-list vm-uuid=$vm --minimal); do + xe vif-destroy uuid="$vif" + done + unset IFS +} + +function have_multiple_hosts { + xe host-list --minimal | grep -q "," +} + +function attach_network { + local bridge_or_net_name + + bridge_or_net_name="$1" + + local net + local host + + net=$(_network_uuid "$bridge_or_net_name") + host=$(xe host-list --minimal) + + xe network-attach uuid=$net host-uuid=$host +} + +function set_vm_memory { + local vm_name_label + local memory + + vm_name_label="$1" + memory="$2" + + local vm + + vm=$(_vm_uuid "$vm_name_label") + + xe vm-memory-limits-set \ + static-min=${memory}MiB \ + static-max=${memory}MiB \ + dynamic-min=${memory}MiB \ + dynamic-max=${memory}MiB \ + uuid=$vm +} + +function max_vcpus { + local vm_name_label + + vm_name_label="$1" + + local vm + local host + local cpu_count + + host=$(xe host-list --minimal) + vm=$(_vm_uuid "$vm_name_label") + + cpu_count=$(xe host-param-get \ + param-name=cpu_info \ + uuid=$host | + sed -e 's/^.*cpu_count: \([0-9]*\);.*$/\1/g') + + if [ -z "$cpu_count" ]; then + # get dom0's vcpu count + cpu_count=$(cat /proc/cpuinfo | grep processor | wc -l) + fi + + # Assert cpu_count is not empty + [ -n "$cpu_count" ] + + # Assert ithas a numeric nonzero value + expr "$cpu_count" + 0 + + # 8 VCPUs should be enough for devstack VM; avoid using too + # many VCPUs: + # 1. too many VCPUs may trigger a kernel bug which result VM + # not able to boot: + # https://kernel.googlesource.com/pub/scm/linux/kernel/git/wsa/linux/+/e2e004acc7cbe3c531e752a270a74e95cde3ea48 + # 2. The remaining CPUs can be used for other purpose: + # e.g. boot test VMs. + MAX_VCPUS=8 + if [ $cpu_count -ge $MAX_VCPUS ]; then + cpu_count=$MAX_VCPUS + fi + + xe vm-param-set uuid=$vm VCPUs-max=$cpu_count + xe vm-param-set uuid=$vm VCPUs-at-startup=$cpu_count +} + +function get_domid { + local vm_name_label + + vm_name_label="$1" + + xe vm-list name-label="$vm_name_label" params=dom-id minimal=true +} + +function install_conntrack_tools { + local xs_host + local xs_ver_major + local centos_ver + local conntrack_conf + xs_host=$(xe host-list --minimal) + xs_ver_major=$(xe host-param-get uuid=$xs_host param-name=software-version param-key=product_version_text_short | cut -d'.' -f 1) + if [ $xs_ver_major -gt 6 ]; then + # Only support conntrack-tools in Dom0 with XS7.0 and above + if [ ! -f /usr/sbin/conntrackd ]; then + sed -i s/#baseurl=/baseurl=/g /etc/yum.repos.d/CentOS-Base.repo + centos_ver=$(yum version nogroups |grep Installed | cut -d' ' -f 2 | cut -d'/' -f 1 | cut -d'-' -f 1) + yum install -y --enablerepo=base --releasever=$centos_ver conntrack-tools + # Backup conntrackd.conf after install conntrack-tools, use the one with statistic mode + mv /etc/conntrackd/conntrackd.conf /etc/conntrackd/conntrackd.conf.back + conntrack_conf=$(find /usr/share/doc -name conntrackd.conf |grep stats) + cp $conntrack_conf /etc/conntrackd/conntrackd.conf + fi + service conntrackd restart + fi +} + +# +# Wait for VM to halt +# +function wait_for_VM_to_halt { + #mgmt_ip="$1" + GUEST_VM_NAME="$1" + set +x + echo "Waiting for the VM to halt. Progress in-VM can be checked with XenCenter or xl console:" + domid=$(get_domid "$GUEST_VM_NAME") + echo "ssh root@host \"xl console $domid\"" + while true; do + state=$(xe_min vm-list name-label="$GUEST_VM_NAME" power-state=halted) + if [ -n "$state" ]; then + break + else + echo -n "." + sleep 20 + fi + done + set -x +} diff --git a/install/conf/ubuntupreseed.cfg b/install/conf/ubuntupreseed.cfg new file mode 100644 index 0000000..00bf37b --- /dev/null +++ b/install/conf/ubuntupreseed.cfg @@ -0,0 +1,471 @@ +### Contents of the preconfiguration file (for squeeze) +### Localization +# Preseeding only locale sets language, country and locale. +d-i debian-installer/locale string en_US + +# The values can also be preseeded individually for greater flexibility. +#d-i debian-installer/language string en +#d-i debian-installer/country string NL +#d-i debian-installer/locale string en_GB.UTF-8 +# Optionally specify additional locales to be generated. +#d-i localechooser/supported-locales en_US.UTF-8, nl_NL.UTF-8 + +# Keyboard selection. +# Disable automatic (interactive) keymap detection. +d-i console-setup/ask_detect boolean false +#d-i keyboard-configuration/modelcode string pc105 +d-i keyboard-configuration/layoutcode string us +# To select a variant of the selected layout (if you leave this out, the +# basic form of the layout will be used): +#d-i keyboard-configuration/variantcode string dvorak + +### Network configuration +# Disable network configuration entirely. This is useful for cdrom +# installations on non-networked devices where the network questions, +# warning and long timeouts are a nuisance. +#d-i netcfg/enable boolean false + +# 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 + +# To pick a particular interface instead: +#d-i netcfg/choose_interface select eth1 + +# If you have a slow dhcp server and the installer times out waiting for +# it, this might be useful. +d-i netcfg/dhcp_timeout string 120 + +# If you prefer to configure the network manually, uncomment this line and +# the static network configuration below. +#d-i netcfg/disable_autoconfig boolean true + +# If you want the preconfiguration file to work on systems both with and +# without a dhcp server, uncomment these lines and the static network +# configuration below. +#d-i netcfg/dhcp_failed note +#d-i netcfg/dhcp_options select Configure network manually + +# Static network configuration. +#d-i netcfg/get_nameservers string 192.168.1.1 +#d-i netcfg/get_ipaddress string 192.168.1.42 +#d-i netcfg/get_netmask string 255.255.255.0 +#d-i netcfg/get_gateway string 192.168.1.1 +#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. +d-i netcfg/get_hostname string stack +d-i netcfg/get_domain string stackpass + +# Disable that annoying WEP key dialog. +d-i netcfg/wireless_wep string +# The wacky dhcp hostname that some ISPs use as a password of sorts. +#d-i netcfg/dhcp_hostname string radish + +# If non-free firmware is needed for the network or other hardware, you can +# configure the installer to always try to load it, without prompting. Or +# change to false to disable asking. +#d-i hw-detect/load_firmware boolean true + +### Network console +# Use the following settings if you wish to make use of the network-console +# component for remote installation over SSH. This only makes sense if you +# intend to perform the remainder of the installation manually. +#d-i anna/choose_modules string network-console +#d-i network-console/password password r00tme +#d-i network-console/password-again password r00tme + +### 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 manual +d-i mirror/http/hostname string archive.ubuntu.com +d-i mirror/http/directory string /ubuntu +d-i mirror/http/proxy string + +# Alternatively: by default, the installer uses CC.archive.ubuntu.com where +# CC is the ISO-3166-2 code for the selected country. You can preseed this +# so that it does so without asking. +#d-i mirror/http/mirror select CC.archive.ubuntu.com + +# Suite to install. +#d-i mirror/suite string squeeze +# Suite to use for loading installer components (optional). +#d-i mirror/udeb/suite string squeeze +# Components to use for loading installer components (optional). +#d-i mirror/udeb/components multiselect main, restricted + +### 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/Pacific + +# Controls whether to use NTP to set the clock during the install +d-i clock-setup/ntp boolean true +# NTP server to use. The default is almost always fine here. +d-i clock-setup/ntp-server string 0.us.pool.ntp.org + +### Partitioning +## Partitioning example +# If the system has free space you can choose to only partition that space. +# This is only honoured if partman-auto/method (below) is not set. +# Alternatives: custom, some_device, some_device_crypto, some_device_lvm. +#d-i partman-auto/init_automatically_partition select biggest_free + +# Alternatively, you may specify a disk to partition. If the system has only +# one disk the installer will default to using that, but otherwise the device +# name must be given in traditional, non-devfs format (so e.g. /dev/hda or +# /dev/sda, and not e.g. /dev/discs/disc0/disc). +# For example, to use the first SCSI/SATA hard disk: +#d-i partman-auto/disk string /dev/sda +# In addition, you'll need to specify the method to use. +# The presently available methods are: +# - regular: use the usual partition types for your architecture +# - lvm: use LVM to partition the disk +# - crypto: use LVM within an encrypted partition +d-i partman-auto/method string regular + +# 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-lvm/device_remove_lvm boolean true +# The same applies to pre-existing software RAID array: +d-i partman-md/device_remove_md boolean true +# And the same goes for the confirmation to write the lvm partitions. +d-i partman-lvm/confirm boolean true + +# For LVM partitioning, you can select how much of the volume group to use +# for logical volumes. +#d-i partman-auto-lvm/guided_size string max +#d-i partman-auto-lvm/guided_size string 10GB +#d-i partman-auto-lvm/guided_size string 50% + +# You can choose one of the three predefined partitioning recipes: +# - atomic: all files in one partition +# - home: separate /home partition +# - multi: separate /home, /usr, /var, and /tmp partitions +d-i partman-auto/choose_recipe select atomic + +# Or provide a recipe of your own... +# 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{ } \ +# . + +# If you just want to change the default filesystem from ext3 to something +# else, you can do that without providing a full recipe. +d-i partman/default_filesystem string ext3 + +# The full recipe format is documented in the file partman-auto-recipe.txt +# included in the 'debian-installer' package or available from D-I source +# repository. This also documents how to specify settings such as file +# system labels, volume group names and which physical devices to include +# in a volume group. + +# This makes partman automatically partition without confirmation, provided +# that you told it what to do using one of the methods above. +d-i partman-partitioning/confirm_write_new_label boolean true +d-i partman/choose_partition select finish +d-i partman/confirm boolean true +d-i partman/confirm_nooverwrite boolean true + +## Partitioning using RAID +# The method should be set to "raid". +#d-i partman-auto/method string raid +# Specify the disks to be partitioned. They will all get the same layout, +# so this will only work if the disks are the same size. +#d-i partman-auto/disk string /dev/sda /dev/sdb + +# Next you need to specify the physical partitions that will be used. +#d-i partman-auto/expert_recipe string \ +# multiraid :: \ +# 1000 5000 4000 raid \ +# $primary{ } method{ raid } \ +# . \ +# 64 512 300% raid \ +# method{ raid } \ +# . \ +# 500 10000 1000000000 raid \ +# method{ raid } \ +# . + +# Last you need to specify how the previously defined partitions will be +# used in the RAID setup. Remember to use the correct partition numbers +# for logical partitions. RAID levels 0, 1, 5, 6 and 10 are supported; +# devices are separated using "#". +# Parameters are: +# \ +# + +#d-i partman-auto-raid/recipe string \ +# 1 2 0 ext3 / \ +# /dev/sda1#/dev/sdb1 \ +# . \ +# 1 2 0 swap - \ +# /dev/sda5#/dev/sdb5 \ +# . \ +# 0 2 0 ext3 /home \ +# /dev/sda6#/dev/sdb6 \ +# . + +# For additional information see the file partman-auto-raid-recipe.txt +# included in the 'debian-installer' package or available from D-I source +# repository. + +# This makes partman automatically partition without confirmation. +d-i partman-md/confirm boolean true +d-i partman-partitioning/confirm_write_new_label boolean true +d-i partman/choose_partition select finish +d-i partman/confirm boolean true +d-i partman/confirm_nooverwrite boolean true + +## Controlling how partitions are mounted +# The default is to mount by UUID, but you can also choose "traditional" to +# use traditional device names, or "label" to try filesystem labels before +# falling back to UUIDs. +#d-i partman/mount_style select uuid + +### Base system installation +# Configure APT to not install recommended packages by default. Use of this +# option can result in an incomplete system and should only be used by very +# experienced users. +#d-i base-installer/install-recommends boolean false + +# The kernel image (meta) package to be installed; "none" can be used if no +# kernel is to be installed. +d-i base-installer/kernel/image string linux-virtual + +### Account setup +# Skip creation of a root account (normal user account will be able to +# use sudo). The default is false; preseed this to true if you want to set +# a root password. +d-i passwd/root-login boolean true +# 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 stackpass +d-i passwd/root-password-again password stackpass +# or encrypted using an MD5 hash. +#d-i passwd/root-password-crypted password [MD5 hash] + +# To create a normal user account. +#d-i passwd/user-fullname string Ubuntu User +#d-i passwd/username string ubuntu +# 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] +# Create the first user with the specified UID instead of the default. +#d-i passwd/user-uid string 1010 +# The installer will warn about weak passwords. If you are sure you know +# what you're doing and want to override it, uncomment this. +d-i user-setup/allow-password-weak boolean true + +# The user account will be added to some standard initial groups. To +# override that, use this. +#d-i passwd/user-default-groups string audio cdrom video + +# Set to true if you want to encrypt the first user's home directory. +d-i user-setup/encrypt-home boolean false + +### Apt setup +# You can choose to install restricted and universe software, or to install +# software from the backports repository. +d-i apt-setup/restricted boolean true +d-i apt-setup/universe boolean true +d-i apt-setup/backports boolean true +# Uncomment this if you don't want to use a network mirror. +#d-i apt-setup/use_mirror boolean false +# Select which update services to use; define the mirrors to be used. +# Values shown below are the normal defaults. +#d-i apt-setup/services-select multiselect security +#d-i apt-setup/security_host string security.ubuntu.com +#d-i apt-setup/security_path string /ubuntu + +# Additional repositories, local[0-9] available +#d-i apt-setup/local0/repository string \ +# http://local.server/ubuntu squeeze 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 boolean true + +### Package selection +#tasksel tasksel/first multiselect ubuntu-desktop +#tasksel tasksel/first multiselect lamp-server, print-server +#tasksel tasksel/first multiselect kubuntu-desktop +tasksel tasksel/first multiselect openssh-server + +# Individual additional packages to install +d-i pkgsel/include string cracklib-runtime curl wget ssh openssh-server tcpdump ethtool git sudo python-netaddr coreutils + +# Whether to upgrade packages after debootstrap. +# Allowed values: none, safe-upgrade, full-upgrade +d-i pkgsel/upgrade select safe-upgrade + +# Language pack selection +#d-i pkgsel/language-packs multiselect de, en, zh + +# Policy for applying updates. May be "none" (no automatic updates), +# "unattended-upgrades" (install security updates automatically), or +# "landscape" (manage system with Landscape). +d-i pkgsel/update-policy select unattended-upgrades + +# Some versions of the installer can report back on what software you have +# installed, and what software you use. The default is not to report back, +# but sending reports helps the project determine what software is most +# popular and include it on CDs. +#popularity-contest popularity-contest/participate boolean false + +# By default, the system's locate database will be updated after the +# installer has finished installing most packages. This may take a while, so +# if you don't want it, you can set this to "false" to turn it off. +d-i pkgsel/updatedb boolean false + +### 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 +# To also skip installing lilo, and install no bootloader, uncomment this +# too: +#d-i lilo-installer/skip boolean true + +# With a few exceptions for unusual partitioning setups, GRUB 2 is now the +# default. If you need GRUB Legacy for some particular reason, then +# uncomment this: +d-i grub-installer/grub2_instead_of_grub_legacy boolean false + +# 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) + +# Optional password for grub, either in clear text +#d-i grub-installer/password password r00tme +#d-i grub-installer/password-again password r00tme +# or encrypted using an MD5 hash, see grub-md5-crypt(8). +#d-i grub-installer/password-crypted password [MD5 hash] + +# Use the following option to add additional boot parameters for the +# installed system (if supported by the bootloader installer). +# Note: options passed to the installer will be added automatically. +#d-i debian-installer/add-kernel-opts string nousb + +### Finishing up the installation +# During installations from serial console, the regular virtual consoles +# (VT1-VT6) are normally disabled in /etc/inittab. Uncomment the next +# line to prevent this. +d-i finish-install/keep-consoles boolean true + +# 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 + +# This is how to make the installer shutdown when finished, but not +# reboot into the installed system. +#d-i debian-installer/exit/halt boolean true +# This will power off the machine instead of just halting it. +#d-i debian-installer/exit/poweroff boolean true + +### X configuration +# X can detect the right driver for some cards, but if you're preseeding, +# you override whatever it chooses. Still, vesa will work most places. +#xserver-xorg xserver-xorg/config/device/driver select vesa + +# A caveat with mouse autodetection is that if it fails, X will retry it +# over and over. So if it's preseeded to be done, there is a possibility of +# an infinite loop if the mouse is not autodetected. +#xserver-xorg xserver-xorg/autodetect_mouse boolean true + +# Monitor autodetection is recommended. +xserver-xorg xserver-xorg/autodetect_monitor boolean true +# Uncomment if you have an LCD display. +#xserver-xorg xserver-xorg/config/monitor/lcd boolean true +# X has three configuration paths for the monitor. Here's how to preseed +# the "medium" path, which is always available. The "simple" path may not +# be available, and the "advanced" path asks too many questions. +xserver-xorg xserver-xorg/config/monitor/selection-method \ + select medium +xserver-xorg xserver-xorg/config/monitor/mode-list \ + select 1024x768 @ 60 Hz + +### 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 immediately before the partitioner starts. It may be +# useful to apply dynamic partitioner preseeding that depends on the state +# of the disks (which may not be visible when preseed/early_command runs). +#d-i partman/early_command \ +# string debconf-set partman-auto/disk "$(list-devices disk | head -n1)" +# 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 diff --git a/install/conf/xenrc b/install/conf/xenrc new file mode 100644 index 0000000..c2085b3 --- /dev/null +++ b/install/conf/xenrc @@ -0,0 +1,114 @@ +#!/bin/bash + +# +# XenServer specific defaults for the /tools/xen/ scripts +# Similar to stackrc, you can override these in your localrc +# + +# Name of this guest +GUEST_NAME=${GUEST_NAME:-CleanUbuntuVM} + +# Template cleanup +CLEAN_TEMPLATES=${CLEAN_TEMPLATES:-false} +TNAME="jeos_template_for_ubuntu" +SNAME_TEMPLATE="jeos_snapshot_for_ubuntu" + +# Devstack now contains many components. 4GB ram is not enough to prevent +# swapping and memory fragmentation - the latter of which can cause failures +# such as blkfront failing to plug a VBD and lead to random test fails. +# +# Set to 6GB so an 8GB XenServer VM can have a 1GB Dom0 and leave 1GB for VMs +OSDOMU_MEM_MB=6144 +OSDOMU_VDI_GB=8 + +# Size of image +VDI_MB=${VDI_MB:-5000} + +# Devstack now contains many components. 4GB ram is not enough to prevent +# swapping and memory fragmentation - the latter of which can cause failures +# such as blkfront failing to plug a VBD and lead to random test fails. +# +# Set to 6GB so an 8GB XenServer VM can have a 1GB Dom0 and leave 1GB for VMs +CLEAN_VM_MEM_MB=6144 +CLEAN_VM_VDI_GB=8 + +# VM Password +GUEST_PASSWORD=${GUEST_PASSWORD:-secret} + +# Extracted variables for OpenStack VM network device numbers. +# Make sure they form a continuous sequence starting from 0 +MGT_DEV_NR=0 + +# Host Interface, i.e. the interface on the nova vm you want to expose the +# services on. Usually the device connected to the management network or the +# one connected to the public network is used. +HOST_IP_IFACE=${HOST_IP_IFACE:-"eth${MGT_DEV_NR}"} + +# +# Our nova host's network info +# + +# Management network +MGT_IP=${MGT_IP:-dhcp} +MGT_NETMASK=${MGT_NETMASK:-ignored} + +# Ubuntu install settings +UBUNTU_INST_RELEASE="xenial" +UBUNTU_INST_TEMPLATE_NAME="Ubuntu 16.04 (64-bit) for DevStack" +# For 12.04 use "precise" and update template name +# However, for 12.04, you should be using +# XenServer 6.1 and later or XCP 1.6 or later +# 11.10 is only really supported with XenServer 6.0.2 and later +UBUNTU_INST_ARCH="amd64" +UBUNTU_INST_HTTP_HOSTNAME="archive.ubuntu.com" +UBUNTU_INST_HTTP_DIRECTORY="/ubuntu" +UBUNTU_INST_HTTP_PROXY="" +UBUNTU_INST_LOCALE="en_US" +UBUNTU_INST_KEYBOARD="us" +# network configuration for ubuntu netinstall +UBUNTU_INST_IP="dhcp" +UBUNTU_INST_NAMESERVERS="" +UBUNTU_INST_NETMASK="" +UBUNTU_INST_GATEWAY="" + +# Create a separate xvdb. Tis could be used as a backing device for cinder +# volumes. Specify +# XEN_XVDB_SIZE_GB=10 +# VOLUME_BACKING_DEVICE=/dev/xvdb +# in your localrc to avoid kernel lockups: +# https://bugs.launchpad.net/cinder/+bug/1023755 +# +# Set the size to 0 to avoid creation of additional disk. +XEN_XVDB_SIZE_GB=0 + + + +## +#configuration for openstack +## +STACK_LABEL=DEVSTACK + +## +# configuration for devstack DomU +## + +# Name of DomU +DEV_STACK_DOMU_NAME=${DEV_STACK_DOMU_NAME:-DevStackOSDomU} + +STACK_USER=stack +DOMZERO_USER=domzero + +# Network mapping. Specify bridge names or network names. Network names may +# differ across localised versions of XenServer. If a given bridge/network +# was not found, a new network will be created with the specified name. + +# Get the management network from the XS installation +VM_BRIDGE_OR_NET_NAME="OpenStack VM Network" +PUB_BRIDGE_OR_NET_NAME="OpenStack Public Network" +XEN_INT_BRIDGE_OR_NET_NAME="OpenStack VM Integration Network" + +# Extracted variables for OpenStack VM network device numbers. +# Make sure they form a continuous sequence starting from 0 +MGT_DEV_NR=0 +VM_DEV_NR=1 +PUB_DEV_NR=2 diff --git a/install/create_ubuntu_template.sh b/install/create_ubuntu_template.sh new file mode 100755 index 0000000..7ed6b37 --- /dev/null +++ b/install/create_ubuntu_template.sh @@ -0,0 +1,201 @@ +#!/bin/bash + +# This script must be run on a XenServer or XCP machine +# +# It creates a clean ubuntu VM template +# +# For more details see: README.md + +set -o errexit +set -o nounset +set -o xtrace + +export LC_ALL=C + +# directory settings +THIS_DIR=$(cd $(dirname "$0") && pwd) +SCRIPT_DIR="$THIS_DIR/scripts" +COMM_DIR="$THIS_DIR/common" +CONF_DIR="$THIS_DIR/conf" + +# Include onexit commands +. $SCRIPT_DIR/on_exit.sh + +# xapi functions + +. $COMM_DIR/functions + +# Source params - override xenrc params in your local.conf to suit your taste +source $CONF_DIR/xenrc + +# +# Prepare Dom0 +# including installing XenAPI plugins +# + +cd $THIS_DIR + +# Die if multiple hosts listed +if have_multiple_hosts; then + cat >&2 << EOF +ERROR: multiple hosts found. This might mean that the XenServer is a member +of a pool - Exiting. +EOF + exit 1 +fi + +# +# Configure Networking +# + +MGT_NETWORK=`xe pif-list management=true params=network-uuid minimal=true` +HOST_MGT_BRIDGE_OR_NET_NAME=`xe network-list uuid=$MGT_NETWORK params=bridge minimal=true` + +setup_network "$HOST_MGT_BRIDGE_OR_NET_NAME" + +if ! xenapi_is_listening_on "$HOST_MGT_BRIDGE_OR_NET_NAME"; then + cat >&2 << EOF +ERROR: XenAPI does not have an assigned IP address on the management network. +please review your XenServer network configuration file. +EOF + exit 1 +fi + +HOST_IP=$(xenapi_ip_on "$HOST_MGT_BRIDGE_OR_NET_NAME") + +# Set up ip forwarding, but skip on xcp-xapi +if [ -a /etc/sysconfig/network ]; then + if ! grep -q "FORWARD_IPV4=YES" /etc/sysconfig/network; then + # FIXME: This doesn't work on reboot! + echo "FORWARD_IPV4=YES" >> /etc/sysconfig/network + fi +fi +# Also, enable ip forwarding in rc.local, since the above trick isn't working +if ! grep -q "echo 1 >/proc/sys/net/ipv4/ip_forward" /etc/rc.local; then + echo "echo 1 >/proc/sys/net/ipv4/ip_forward" >> /etc/rc.local +fi +# Enable ip forwarding at runtime as well +echo 1 > /proc/sys/net/ipv4/ip_forward + + +# +# Shutdown previous runs +# + +DO_SHUTDOWN=${DO_SHUTDOWN:-1} +CLEAN_TEMPLATES=${CLEAN_TEMPLATES:-false} +if [ "$DO_SHUTDOWN" = "1" ]; then + # Shutdown all VM's that created previously + clean_templates_arg="" + if $CLEAN_TEMPLATES; then + clean_templates_arg="--remove-templates" + fi + $SCRIPT_DIR/uninstall-os-vpx.sh $clean_templates_arg + + # Destroy any instances that were launched + for uuid in `xe vm-list | grep -1 instance | grep uuid | sed "s/.*\: //g"`; do + echo "Shutting down nova instance $uuid" + xe vm-uninstall uuid=$uuid force=true + done + + # Destroy orphaned vdis + for uuid in `xe vdi-list | grep -1 Glance | grep uuid | sed "s/.*\: //g"`; do + xe vdi-destroy uuid=$uuid + done +fi + + +# +# Create Ubuntu VM template +# and/or create VM from template +# + +templateuuid=$(xe template-list name-label="$TNAME") +if [ -z "$templateuuid" ]; then + # + # Install Ubuntu over network + # + UBUNTU_INST_BRIDGE_OR_NET_NAME=${UBUNTU_INST_BRIDGE_OR_NET_NAME:-"$HOST_MGT_BRIDGE_OR_NET_NAME"} + + # always update the preseed file, incase we have a newer one + PRESEED_URL=${PRESEED_URL:-""} + if [ -z "$PRESEED_URL" ]; then + PRESEED_URL="${HOST_IP}/ubuntupreseed.cfg" + + HTTP_SERVER_LOCATION="/opt/xensource/www" + if [ ! -e $HTTP_SERVER_LOCATION ]; then + HTTP_SERVER_LOCATION="/var/www/html" + mkdir -p $HTTP_SERVER_LOCATION + fi + + # Copy the tools DEB to the XS web server + XS_TOOLS_URL="https://github.com/downloads/citrix-openstack/warehouse/xe-guest-utilities_5.6.100-651_amd64.deb" + ISO_DIR="/opt/xensource/packages/iso" + if [ -e "$ISO_DIR" ]; then + TOOLS_ISO=$(ls -1 $ISO_DIR/*-tools-*.iso | head -1) + TMP_DIR=/tmp/temp.$RANDOM + mkdir -p $TMP_DIR + mount -o loop $TOOLS_ISO $TMP_DIR + # the target deb package maybe *amd64.deb or *all.deb, + # so use *amd64.deb by default. If it doesn't exist, + # then use *all.deb. + DEB_FILE=$(ls $TMP_DIR/Linux/*amd64.deb || ls $TMP_DIR/Linux/*all.deb) + cp $DEB_FILE $HTTP_SERVER_LOCATION + umount $TMP_DIR + rmdir $TMP_DIR + XS_TOOLS_URL=${HOST_IP}/$(basename $DEB_FILE) + fi + + cp -f $CONF_DIR/ubuntupreseed.cfg $HTTP_SERVER_LOCATION + cp -f $SCRIPT_DIR/ubuntu_latecommand.sh $HTTP_SERVER_LOCATION/latecommand.sh + + sed \ + -e "s,\(d-i mirror/http/hostname string\).*,\1 $UBUNTU_INST_HTTP_HOSTNAME,g" \ + -e "s,\(d-i mirror/http/directory string\).*,\1 $UBUNTU_INST_HTTP_DIRECTORY,g" \ + -e "s,\(d-i mirror/http/proxy string\).*,\1 $UBUNTU_INST_HTTP_PROXY,g" \ + -e "s,\(d-i passwd/root-password password\).*,\1 $GUEST_PASSWORD,g" \ + -e "s,\(d-i passwd/root-password-again password\).*,\1 $GUEST_PASSWORD,g" \ + -e "s,\(d-i preseed/late_command string\).*,\1 in-target mkdir -p /tmp; in-target wget --no-proxy ${HOST_IP}/latecommand.sh -O /root/latecommand.sh; in-target bash /root/latecommand.sh,g" \ + -i "${HTTP_SERVER_LOCATION}/ubuntupreseed.cfg" + + sed \ + -e "s,@XS_TOOLS_URL@,$XS_TOOLS_URL,g" \ + -i "${HTTP_SERVER_LOCATION}/latecommand.sh" + fi + + # Update the template + $SCRIPT_DIR/install_ubuntu_template.sh $PRESEED_URL + + # create a new VM from the given template with eth0 attached to the given + # network + $SCRIPT_DIR/install-os-vpx.sh \ + -t "$UBUNTU_INST_TEMPLATE_NAME" \ + -n "$UBUNTU_INST_BRIDGE_OR_NET_NAME" \ + -l "$GUEST_NAME" + + set_vm_memory "$GUEST_NAME" "1024" + + xe vm-start vm="$GUEST_NAME" + + # wait for install to finish + wait_for_VM_to_halt "$GUEST_NAME" + + # set VM to restart after a reboot + vm_uuid=$(xe_min vm-list name-label="$GUEST_NAME") + xe vm-param-set actions-after-reboot=Restart uuid="$vm_uuid" + + # Make template from VM + snuuid=$(xe vm-snapshot vm="$GUEST_NAME" new-name-label="$SNAME_TEMPLATE") + xe snapshot-clone uuid=$snuuid new-name-label="$TNAME" + xe vm-uninstall vm="$GUEST_NAME" force=true +else + echo "the template has already exist" +fi +template_uuid=$(xe_min template-list name-label="$TNAME") +echo "$template_uuid" +exist_val=$(xe template-param-get uuid=$template_uuid param-name=PV-args) +echo "$exist_val" +if [ -n "$exist_val" ]; + then + xe template-param-set uuid=$template_uuid PV-args="" +fi diff --git a/install/scripts/install-os-vpx.sh b/install/scripts/install-os-vpx.sh new file mode 100755 index 0000000..66f7ef4 --- /dev/null +++ b/install/scripts/install-os-vpx.sh @@ -0,0 +1,135 @@ +#!/bin/bash +# +# Copyright (c) 2011 Citrix Systems, Inc. +# Copyright 2011 OpenStack Foundation +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +set -eux + +BRIDGE= +NAME_LABEL= +TEMPLATE_NAME= + +usage() +{ +cat << EOF + + Usage: $0 -t TEMPLATE_NW_INSTALL -l NAME_LABEL [-n BRIDGE] + + Install a VM from a template + + OPTIONS: + + -h Shows this message. + -t template VM template to use + -l name Specifies the name label for the VM. + -n bridge The bridge/network to use for eth0. Defaults to xenbr0 +EOF +} + +get_params() +{ + while getopts "hbn:r:l:t:" OPTION; do + case $OPTION in + h) usage + exit 1 + ;; + n) + BRIDGE=$OPTARG + ;; + l) + NAME_LABEL=$OPTARG + ;; + t) + TEMPLATE_NAME=$OPTARG + ;; + ?) + usage + exit + ;; + esac + done + if [[ -z $BRIDGE ]]; then + BRIDGE=xenbr0 + fi + + if [[ -z $TEMPLATE_NAME ]]; then + echo "Please specify a template name" >&2 + exit 1 + fi + + if [[ -z $NAME_LABEL ]]; then + echo "Please specify a name-label for the new VM" >&2 + exit 1 + fi +} + + +xe_min() +{ + local cmd="$1" + shift + xe "$cmd" --minimal "$@" +} + + +find_network() +{ + result=$(xe_min network-list bridge="$1") + if [ "$result" = "" ]; then + result=$(xe_min network-list name-label="$1") + fi + echo "$result" +} + + +create_vif() +{ + local v="$1" + echo "Installing VM interface on [$BRIDGE]" + local out_network_uuid + out_network_uuid=$(find_network "$BRIDGE") + xe vif-create vm-uuid="$v" network-uuid="$out_network_uuid" device="0" +} + + + +# Make the VM auto-start on server boot. +set_auto_start() +{ + local v="$1" + xe vm-param-set uuid="$v" other-config:auto_poweron=true +} + + +destroy_vifs() +{ + local v="$1" + IFS=, + for vif in $(xe_min vif-list vm-uuid="$v"); do + xe vif-destroy uuid="$vif" + done + unset IFS +} + + +get_params "$@" + +vm_uuid=$(xe_min vm-install template="$TEMPLATE_NAME" new-name-label="$NAME_LABEL") +destroy_vifs "$vm_uuid" +set_auto_start "$vm_uuid" +create_vif "$vm_uuid" +xe vm-param-set actions-after-reboot=Destroy uuid="$vm_uuid" diff --git a/install/scripts/install_ubuntu_template.sh b/install/scripts/install_ubuntu_template.sh new file mode 100755 index 0000000..17bd6ba --- /dev/null +++ b/install/scripts/install_ubuntu_template.sh @@ -0,0 +1,86 @@ +#!/bin/bash +# +# This creates an Ubuntu Server 32bit or 64bit template +# on Xenserver 5.6.x, 6.0.x and 6.1.x +# The template does a net install only +# +# Based on a script by: David Markey +# + +set -o errexit +set -o nounset +set -o xtrace + +# This directory +THIS_DIR=$(cd $(dirname "$0") && pwd) +SCRIPT_DIR="$THIS_DIR/../scripts" +COMM_DIR="$THIS_DIR/../common" +CONF_DIR="$THIS_DIR/../conf" +# For default setings see xenrc +source $CONF_DIR/xenrc + +# Get the params +preseed_url=$1 + +# Delete template or skip template creation as required +previous_template=$(xe template-list name-label="$UBUNTU_INST_TEMPLATE_NAME" \ + params=uuid --minimal) +if [ -n "$previous_template" ]; then + if $CLEAN_TEMPLATES; then + xe template-param-clear param-name=other-config uuid=$previous_template + xe template-uninstall template-uuid=$previous_template force=true + else + echo "Template $UBUNTU_INST_TEMPLATE_NAME already present" + exit 0 + fi +fi + +# Get built-in template +builtin_name="Debian Squeeze 6.0 (32-bit)" +builtin_uuid=$(xe template-list name-label="$builtin_name" --minimal) +if [[ -z $builtin_uuid ]]; then + echo "Can't find the Debian Squeeze 32bit template on your XenServer." + exit 1 +fi + +# Clone built-in template to create new template +new_uuid=$(xe vm-clone uuid=$builtin_uuid \ + new-name-label="$UBUNTU_INST_TEMPLATE_NAME") +disk_size=$(($CLEAN_VM_VDI_GB * 1024 * 1024 * 1024)) + +# Some of these settings can be found in example preseed files +# however these need to be answered before the netinstall +# is ready to fetch the preseed file, and as such must be here +# to get a fully automated install +pvargs="quiet console=hvc0 partman/default_filesystem=ext3 \ +console-setup/ask_detect=false locale=${UBUNTU_INST_LOCALE} \ +keyboard-configuration/layoutcode=${UBUNTU_INST_KEYBOARD} \ +netcfg/choose_interface=eth0 \ +netcfg/get_hostname=os netcfg/get_domain=os auto \ +url=${preseed_url}" + +if [ "$UBUNTU_INST_IP" != "dhcp" ]; then + netcfgargs="netcfg/disable_autoconfig=true \ +netcfg/get_nameservers=${UBUNTU_INST_NAMESERVERS} \ +netcfg/get_ipaddress=${UBUNTU_INST_IP} \ +netcfg/get_netmask=${UBUNTU_INST_NETMASK} \ +netcfg/get_gateway=${UBUNTU_INST_GATEWAY} \ +netcfg/confirm_static=true" + pvargs="${pvargs} ${netcfgargs}" +fi + +xe template-param-set uuid=$new_uuid \ + other-config:install-methods=http \ + other-config:install-repository="http://${UBUNTU_INST_HTTP_HOSTNAME}${UBUNTU_INST_HTTP_DIRECTORY}" \ + PV-args="$pvargs" \ + other-config:debian-release="$UBUNTU_INST_RELEASE" \ + other-config:default_template=true \ + other-config:disks='' \ + other-config:install-arch="$UBUNTU_INST_ARCH" + +if ! [ -z "$UBUNTU_INST_HTTP_PROXY" ]; then + xe template-param-set uuid=$new_uuid \ + other-config:install-proxy="$UBUNTU_INST_HTTP_PROXY" +fi + +echo "Ubuntu template installed uuid:$new_uuid" diff --git a/install/scripts/on_exit.sh b/install/scripts/on_exit.sh new file mode 100755 index 0000000..2846dc4 --- /dev/null +++ b/install/scripts/on_exit.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +set -e +set -o xtrace + +if [ -z "${on_exit_hooks:-}" ]; then + on_exit_hooks=() +fi + +on_exit() +{ + for i in $(seq $((${#on_exit_hooks[*]} - 1)) -1 0); do + eval "${on_exit_hooks[$i]}" + done +} + +add_on_exit() +{ + local n=${#on_exit_hooks[*]} + on_exit_hooks[$n]="$*" + if [[ $n -eq 0 ]]; then + trap on_exit EXIT + fi +} diff --git a/install/scripts/ubuntu_latecommand.sh b/install/scripts/ubuntu_latecommand.sh new file mode 100755 index 0000000..2afbe2c --- /dev/null +++ b/install/scripts/ubuntu_latecommand.sh @@ -0,0 +1,14 @@ +#!/bin/bash +set -eux + +# Need to set barrier=0 to avoid a Xen bug +# https://bugs.launchpad.net/ubuntu/+source/linux/+bug/824089 +sed -i -e 's/errors=/barrier=0,errors=/' /etc/fstab + +# Allow root to login with a password +sed -i -e 's/.*PermitRootLogin.*/PermitRootLogin yes/g' /etc/ssh/sshd_config + +# Install the XenServer tools so IP addresses are reported +wget --no-proxy @XS_TOOLS_URL@ -O /root/tools.deb +dpkg -i /root/tools.deb +rm /root/tools.deb diff --git a/install/scripts/uninstall-os-vpx.sh b/install/scripts/uninstall-os-vpx.sh new file mode 100755 index 0000000..96dad7e --- /dev/null +++ b/install/scripts/uninstall-os-vpx.sh @@ -0,0 +1,88 @@ +#!/bin/bash +# +# Copyright (c) 2011 Citrix Systems, Inc. +# Copyright 2011 OpenStack Foundation +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +set -ex + +# By default, don't remove the templates +REMOVE_TEMPLATES=${REMOVE_TEMPLATES:-"false"} +if [ "$1" = "--remove-templates" ]; then + REMOVE_TEMPLATES=true +fi + +xe_min() +{ + local cmd="$1" + shift + xe "$cmd" --minimal "$@" +} + +destroy_vdi() +{ + local vbd_uuid="$1" + local type + type=$(xe_min vbd-list uuid=$vbd_uuid params=type) + local dev + dev=$(xe_min vbd-list uuid=$vbd_uuid params=userdevice) + local vdi_uuid + vdi_uuid=$(xe_min vbd-list uuid=$vbd_uuid params=vdi-uuid) + + if [ "$type" == 'Disk' ] && [ "$dev" != 'xvda' ] && [ "$dev" != '0' ]; then + xe vdi-destroy uuid=$vdi_uuid + fi +} + +uninstall() +{ + local vm_uuid="$1" + local power_state + power_state=$(xe_min vm-list uuid=$vm_uuid params=power-state) + + if [ "$power_state" != "halted" ]; then + xe vm-shutdown vm=$vm_uuid force=true + fi + + for v in $(xe_min vbd-list vm-uuid=$vm_uuid | sed -e 's/,/ /g'); do + destroy_vdi "$v" + done + + xe vm-uninstall vm=$vm_uuid force=true >/dev/null +} + +uninstall_template() +{ + local vm_uuid="$1" + + for v in $(xe_min vbd-list vm-uuid=$vm_uuid | sed -e 's/,/ /g'); do + destroy_vdi "$v" + done + + xe template-uninstall template-uuid=$vm_uuid force=true >/dev/null +} + +# remove the VMs and their disks +for u in $(xe_min vm-list other-config:os-vpx=true | sed -e 's/,/ /g'); do + uninstall "$u" +done + +# remove the templates +if [ "$REMOVE_TEMPLATES" == "true" ]; then + for u in $(xe_min template-list other-config:os-vpx=true | sed -e 's/,/ /g'); do + uninstall_template "$u" + done +fi