├── NEWS ├── debian ├── compat ├── example ├── docs ├── links ├── dirs ├── watch ├── control ├── copyright ├── rules └── changelog ├── variants.list ├── ganeti_api_version ├── AUTHORS ├── Berksfile ├── example ├── config │ ├── scripts │ │ └── standard.sh │ ├── kickstart │ │ └── centos-5.5-x86_64-ganeti.cfg │ └── preseed │ │ ├── debian-5.04-x86_64-ganeti.cfg │ │ └── ubuntu-10.04-x86_64-ganeti.cfg └── hooks │ ├── overlays │ ├── ssh │ ├── cloud-init │ ├── zz_ddns │ ├── interfaces │ └── grub ├── test ├── cookbooks │ └── instance-image-devel │ │ ├── recipes │ │ ├── variants.rb │ │ ├── install.rb │ │ └── default.rb │ │ └── metadata.rb └── scripts │ └── cloudinit.sh ├── autogen.sh ├── .gitignore ├── tools ├── make-qemu-img.in ├── mount-disks.in ├── umount-disks.in ├── make-dump.in ├── ganeti-image.in └── make-image.in ├── Vagrantfile ├── devel └── upload ├── configure.ac ├── cloud_init.rb ├── export ├── import ├── Makefile.am ├── defaults ├── rename ├── ChangeLog ├── ganeti-instance-image.spec ├── create ├── .github └── workflows │ └── ci.yml ├── README.markdown ├── common.sh.in └── COPYING /NEWS: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 7 2 | -------------------------------------------------------------------------------- /variants.list: -------------------------------------------------------------------------------- 1 | default 2 | -------------------------------------------------------------------------------- /debian/example: -------------------------------------------------------------------------------- 1 | example/hooks 2 | -------------------------------------------------------------------------------- /ganeti_api_version: -------------------------------------------------------------------------------- 1 | 5 2 | 10 3 | 15 4 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Lance Albertson 2 | -------------------------------------------------------------------------------- /debian/docs: -------------------------------------------------------------------------------- 1 | NEWS 2 | README.markdown 3 | example 4 | -------------------------------------------------------------------------------- /debian/links: -------------------------------------------------------------------------------- 1 | etc/ganeti/instance-image/variants.list usr/share/ganeti/os/image/variants.list 2 | -------------------------------------------------------------------------------- /debian/dirs: -------------------------------------------------------------------------------- 1 | usr/share/ganeti/os/image 2 | usr/share/ganeti/os/image/tools 3 | var/cache/ganeti-instance-image 4 | etc/default 5 | etc/ganeti/instance-image/hooks 6 | 7 | -------------------------------------------------------------------------------- /debian/watch: -------------------------------------------------------------------------------- 1 | # Compulsory line, this is a version 3 file 2 | version=3 3 | 4 | http://code.osuosl.org/attachments/download/3/ ganeti-instance-image-(\d+\.\d+[\d.]*)\.tar(?:\.gz)? 5 | -------------------------------------------------------------------------------- /Berksfile: -------------------------------------------------------------------------------- 1 | source 'https://supermarket.chef.io' 2 | 3 | cookbook 'ganeti', github: 'osuosl-cookbooks/ganeti' 4 | cookbook 'instance-image-devel', path: 'test/cookbooks/instance-image-devel' 5 | -------------------------------------------------------------------------------- /example/config/scripts/standard.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | export LANG="en_US.UTF-8" 3 | 4 | update-alternatives --set editor /usr/bin/vim.basic 5 | update-alternatives --set pager /usr/bin/less 6 | -------------------------------------------------------------------------------- /test/cookbooks/instance-image-devel/recipes/variants.rb: -------------------------------------------------------------------------------- 1 | instance_image_variant 'cirros' do 2 | image_name 'cirros-0.3.5' 3 | image_type 'qcow2' 4 | image_verify 'no' 5 | image_cleanup 'no' 6 | nomount 'yes' 7 | image_url 'http://ftp.osuosl.org/pub/osl/ganeti-images/' 8 | end 9 | -------------------------------------------------------------------------------- /test/scripts/cloudinit.sh: -------------------------------------------------------------------------------- 1 | export INSTANCE_NAME=foo.bar.example.org 2 | export CINIT_USER=foobar 3 | export CINIT_MANAGE_RESOLV_CONF="yes" 4 | export DNS_SERVERS="192.168.1.1 192.168.1.2" 5 | export DNS_SEARCH="example.org example.bak" 6 | export CINIT_DISABLE_ROOT="yes" 7 | export CINIT_SSH_PWAUTH="no" 8 | ./cloud_init.rb 9 | -------------------------------------------------------------------------------- /test/cookbooks/instance-image-devel/metadata.rb: -------------------------------------------------------------------------------- 1 | name 'instance-image-devel' 2 | maintainer 'Oregon State University' 3 | maintainer_email 'chef@osuosl.org' 4 | license 'Apache-2.0' 5 | description 'Installs/Configures instance-image-devel' 6 | version '0.1.0' 7 | depends 'ganeti' 8 | depends 'line' 9 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if test ! -f configure.ac ; then 4 | echo "You must execute this script from the top level directory." 5 | exit 1 6 | fi 7 | 8 | set -e 9 | 10 | rm -rf config.cache autom4te.cache 11 | mkdir -p autotools 12 | 13 | ${ACLOCAL:-aclocal} -I autotools 14 | ${AUTOCONF:-autoconf} 15 | ${AUTOMAKE:-automake} --add-missing 16 | 17 | rm -rf autom4te.cache 18 | -------------------------------------------------------------------------------- /test/cookbooks/instance-image-devel/recipes/install.rb: -------------------------------------------------------------------------------- 1 | execute 'install instance-image' do 2 | cwd '/vagrant' 3 | command <<-EOF 4 | ./autogen.sh 5 | ./configure --prefix=/usr --localstatedir=/var --sysconfdir=/etc \ 6 | --with-os-dir=/srv/ganeti/os 7 | make 8 | make install 9 | EOF 10 | action :run 11 | end 12 | 13 | include_recipe 'ganeti::instance_image' 14 | 15 | delete_resource(:yum_repository, 'ganeti-instance-image') 16 | delete_resource(:apt_repository, 'ganeti-instance-image') 17 | delete_resource(:package, 'ganeti-instance-image') 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # gitignore rules 2 | # autotools results 3 | /Makefile 4 | /Makefile.in 5 | /aclocal.m4 6 | /autom4te.cache 7 | /autotools 8 | /config.log 9 | /config.status 10 | /configure 11 | 12 | # built scripts 13 | /common.sh 14 | tools/ganeti-image 15 | tools/make-dump 16 | tools/make-image 17 | tools/make-qemu-img 18 | tools/mount-disks 19 | tools/umount-disks 20 | 21 | # archives 22 | ganeti-instance-image*.tar.gz 23 | 24 | # vim 25 | *.swp 26 | 27 | # redhat 28 | *.rpm 29 | 30 | # debian 31 | *.dsc 32 | *.deb 33 | *.changes 34 | build-stamp 35 | debian/files 36 | debian/*.log 37 | debian/ganeti-instance-image/ 38 | debian/ganeti-instance-image.substvars 39 | debian/.debhelper/ 40 | 41 | # Vagrant/Chef 42 | Berksfile.lock 43 | .vagrant/ 44 | cookbooks/ 45 | -------------------------------------------------------------------------------- /tools/make-qemu-img.in: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | INSTANCE_NAME="$1" 4 | 5 | if [ -z "$INSTANCE_NAME" ] ; then 6 | echo "Must provide a node name!" 7 | exit 1 8 | fi 9 | 10 | info=($(gnt-instance list -o os,hypervisor,disk.count --no-headers --separator=' ' $INSTANCE_NAME)) 11 | OS_VARIANT="${info[0]/*+/}" 12 | HYPERVISOR="${info[1]}" 13 | DISK_COUNT="${info[2]}" 14 | OS_API_VERSION="15" 15 | 16 | # do stuff 17 | output="$(gnt-instance activate-disks $INSTANCE_NAME)" 18 | CLEANUP+=("gnt-instance deactivate-disks $INSTANCE_NAME") 19 | 20 | DISK_0_PATH="${output/*disk\/0\:/}" 21 | 22 | . @osdir@/@osname@/common.sh 23 | 24 | if [ -n "$2" ] ; then 25 | IMAGE_DIR=$2 26 | fi 27 | 28 | echo "Creating qemu-img image from $INSTANCE_NAME to ${IMAGE_DIR}/${IMAGE_NAME}-${ARCH}.img" 29 | $QEMU_IMG convert -O qcow2 $DISK_0_PATH ${IMAGE_DIR}/${IMAGE_NAME}-${ARCH}.img 30 | -------------------------------------------------------------------------------- /tools/mount-disks.in: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | INSTANCE_NAME="$1" 4 | 5 | if [ -z "$INSTANCE_NAME" ] ; then 6 | echo "Must provide a node name!" 7 | exit 1 8 | fi 9 | 10 | info=($(gnt-instance list -o os,hypervisor,disk.count --no-headers --separator=' ' $INSTANCE_NAME)) 11 | OS_VARIANT="${info[0]/*+/}" 12 | HYPERVISOR="${info[1]}" 13 | DISK_COUNT="${info[2]}" 14 | OS_API_VERSION="15" 15 | 16 | # do stuff 17 | output="$(gnt-instance activate-disks $INSTANCE_NAME)" 18 | 19 | DISK_0_PATH="${output/*disk\/0\:/}" 20 | 21 | . @osdir@/@osname@/common.sh 22 | 23 | filesystem_dev=$(map_disk0 $blockdev) 24 | root_dev=$(map_partition $filesystem_dev root) 25 | boot_dev=$(map_partition $filesystem_dev boot) 26 | 27 | target="/tmp/${INSTANCE_NAME}_root" 28 | mkdir -p $target 29 | 30 | # mount filesystems 31 | mount_disk0 $target 32 | echo "$INSTANCE_NAME is now mounted at $target" 33 | 34 | CLEANUP=( ) 35 | -------------------------------------------------------------------------------- /tools/umount-disks.in: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | INSTANCE_NAME="$1" 5 | 6 | if [ -z "$INSTANCE_NAME" ] ; then 7 | echo "Must provide a node name!" 8 | exit 1 9 | fi 10 | 11 | info=($(gnt-instance list -o os,hypervisor,disk.count --no-headers --separator=' ' $INSTANCE_NAME)) 12 | OS_VARIANT="${info[0]/*+/}" 13 | HYPERVISOR="${info[1]}" 14 | DISK_COUNT="${info[2]}" 15 | OS_API_VERSION="15" 16 | 17 | # do stuff 18 | output="$(gnt-instance activate-disks $INSTANCE_NAME)" 19 | 20 | DISK_0_PATH="${output/*disk\/0\:/}" 21 | filesystem_dev="${DISK_0_PATH/\/dev\//}" 22 | 23 | . @osdir@/@osname@/common.sh 24 | 25 | target="/tmp/${INSTANCE_NAME}_root" 26 | 27 | root_dev=$(map_partition $filesystem_dev root) 28 | boot_dev=$(map_partition $filesystem_dev boot) 29 | 30 | if [ -n "${boot_dev}" ] ; then 31 | umount $target/boot 32 | fi 33 | 34 | umount $target 35 | rmdir $target 36 | $KPARTX -d -p- $DISK_0_PATH 37 | gnt-instance deactivate-disks $INSTANCE_NAME 38 | 39 | CLEANUP=( ) 40 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: ganeti-instance-image 2 | Section: admin 3 | Priority: extra 4 | Maintainer: Lance Albertson 5 | Build-Depends: debhelper (>= 7), autotools-dev, automake, curl, dump, kpartx, qemu-utils, fdisk 6 | Standards-Version: 3.7.3 7 | Homepage: http://code.osuosl.org/projects/ganeti-image 8 | Vcs-Browser: http://git.osuosl.org/?p=ganeti-instance-image.git 9 | Vcs-Git: git://git.osuosl.org/gitolite/ganeti/ganeti-instance-image.git 10 | 11 | Package: ganeti-instance-image 12 | Architecture: all 13 | Depends: ${misc:Depends}, dump, gawk, curl, kpartx, qemu-utils, fdisk 14 | Conflicts: ganeti (<< 1.2.7) 15 | Enhances: ganeti 16 | Description: image based instance OS defintion for ganeti 17 | Ganeti is a virtual server cluster management software tool built on 18 | top of the Xen virtual machine monitor and other Open Source software. 19 | After setting it up it will provide you with an automated environment 20 | to manage highly available virtual machine instances. 21 | . 22 | This package provides an OS definition for ganeti that will allow 23 | installation via OS images 24 | -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | VAGRANTFILE_API_VERSION = '2'.freeze 5 | 6 | Vagrant.require_version '>= 1.7.0' 7 | 8 | Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| 9 | %w( 10 | almalinux-8 11 | almalinux-9 12 | centos-7 13 | debian-10 14 | debian-11 15 | ubuntu-18.04 16 | ubuntu-20.04 17 | ubuntu-22.04 18 | ).each do |os| 19 | config.vm.define os do |node| 20 | node.vm.hostname = 'instance-image.localdomain' 21 | node.vm.box = "bento/#{os}" 22 | node.vm.network :private_network, ip: '192.168.10.11' 23 | node.vm.provider 'virtualbox' do |v| 24 | v.memory = 2048 25 | v.cpus = 2 26 | end 27 | node.vm.provision :chef_solo do |chef| 28 | chef.version = '17' 29 | chef.install = true 30 | chef.cookbooks_path = 'cookbooks' 31 | chef.binary_env = 'CHEF_LICENSE=accept-no-persist' 32 | chef.run_list = %w( 33 | recipe[instance-image-devel] 34 | recipe[instance-image-devel::install] 35 | recipe[instance-image-devel::variants] 36 | recipe[instance-image-devel::instance_add] 37 | ) 38 | end 39 | end 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /tools/make-dump.in: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | INSTANCE_NAME="$1" 4 | 5 | if [ -z "$INSTANCE_NAME" ] ; then 6 | echo "Must provide a node name!" 7 | exit 1 8 | fi 9 | 10 | info=($(gnt-instance list -o os,hypervisor,disk.count --no-headers --separator=' ' $INSTANCE_NAME)) 11 | OS_VARIANT="${info[0]/*+/}" 12 | HYPERVISOR="${info[1]}" 13 | DISK_COUNT="${info[2]}" 14 | OS_API_VERSION="15" 15 | 16 | # do stuff 17 | output="$(gnt-instance activate-disks $INSTANCE_NAME)" 18 | CLEANUP+=("gnt-instance deactivate-disks $INSTANCE_NAME") 19 | 20 | DISK_0_PATH="${output/*disk\/0\:/}" 21 | 22 | . @osdir@/@osname@/common.sh 23 | 24 | if [ -n "$2" ] ; then 25 | IMAGE_DIR=$2 26 | fi 27 | 28 | filesystem_dev=$(map_disk0 $blockdev) 29 | CLEANUP+=("unmap_disk0 $blockdev") 30 | root_dev=$(map_partition $filesystem_dev root) 31 | boot_dev=$(map_partition $filesystem_dev boot) 32 | 33 | if [ -n "$boot_dev" ] ; then 34 | echo "Creating dump from $INSTANCE_NAME for boot at ${IMAGE_DIR}/${IMAGE_NAME}-${ARCH}-boot.dump" 35 | dump -0 -q -z9 -f ${IMAGE_DIR}/${IMAGE_NAME}-${ARCH}-boot.dump $boot_dev 36 | fi 37 | 38 | echo "Creating dump from $INSTANCE_NAME for root at ${IMAGE_DIR}/${IMAGE_NAME}-${ARCH}-root.dump" 39 | dump -0 -q -z9 -f ${IMAGE_DIR}/${IMAGE_NAME}-${ARCH}-root.dump $root_dev 40 | -------------------------------------------------------------------------------- /example/hooks/overlays: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (C) 2010 Oregon State University 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, but 11 | # WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 | # 02110-1301, USA. 19 | # 20 | # Copy files from an overlay directory into an instance. This assumes the same 21 | # filesystem structure as the system. 22 | 23 | set -e 24 | 25 | . common.sh 26 | 27 | debug set -x 28 | 29 | if [ -z "${TARGET}" -o ! -d "${TARGET}" ] ; then 30 | log_error "Missing target directory" 31 | exit 1 32 | fi 33 | 34 | if [ -n "${OVERLAY}" ] ; then 35 | overlay="${OVERLAYS_DIR}/${OVERLAY}" 36 | if [ ! -d "${overlay}" ] ; then 37 | log_error "${overlay} not found" 38 | fi 39 | # copy overlay files into target instance 40 | cp -a ${overlay}/* ${TARGET} 41 | fi 42 | 43 | exit 0 44 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | This package was debianized by: 2 | 3 | Ed Lim on Tue, 13 Jul 2010 18:25:43 +0000. 4 | 5 | It was downloaded from: 6 | http://code.osuosl.org/projects/ganeti-image 7 | 8 | Upstream Author(s): 9 | 10 | Lance Albertson 11 | 12 | Copyright: 13 | 14 | Copyright (C) 2010 Lance Albertson 15 | 16 | License: 17 | 18 | This program is free software; you can redistribute it and/or modify 19 | it under the terms of the GNU General Public License as published by 20 | the Free Software Foundation; either version 2 of the License, or 21 | (at your option) any later version. 22 | 23 | This program is distributed in the hope that it will be useful, but 24 | WITHOUT ANY WARRANTY; without even the implied warranty of 25 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 26 | General Public License for more details. 27 | 28 | You should have received a copy of the GNU General Public License 29 | along with this program; if not, write to the Free Software 30 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 31 | 02110-1301, USA. 32 | 33 | On Debian systems, the complete text of the GNU General 34 | Public License version 2 can be found in `/usr/share/common-licenses/GPL-2'. 35 | 36 | The Debian packaging is: 37 | 38 | Copyright (C) 2010, Ed Lim 39 | 40 | and is licensed under the GPL, see `/usr/share/common-licenses/GPL'. 41 | -------------------------------------------------------------------------------- /example/hooks/ssh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (C) 2010 Oregon State University 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, but 11 | # WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 | # 02110-1301, USA. 19 | # 20 | # Remove all generated keys so that each instance has unique keys for ssh 21 | 22 | set -e 23 | 24 | . common.sh 25 | 26 | debug set -x 27 | 28 | HOST_KEY="/etc/ssh/ssh_host_key" 29 | RSA_KEY="/etc/ssh/ssh_host_rsa_key" 30 | DSA_KEY="/etc/ssh/ssh_host_dsa_key" 31 | 32 | if [ -e ${TARGET}/etc/debian_version ] ; then 33 | echo "Debian/Ubuntu: replace existing ssh keys" 34 | [ -f "${TARGET}/${RSA_KEY}" ] && rm -f ${TARGET}/${RSA_KEY}* && \ 35 | ssh-keygen -t rsa -q -N '' -f ${TARGET}/${RSA_KEY} 36 | [ -f "${TARGET}/${DSA_KEY}" ] && rm -f ${TARGET}/${DSA_KEY}* && \ 37 | ssh-keygen -t dsa -q -N '' -f ${TARGET}/${DSA_KEY} 38 | exit 0 39 | fi 40 | 41 | for key in $HOST_KEY $RSA_KEY $DSA_KEY ; do 42 | if [ -f "${TARGET}/${key}" ] ; then 43 | rm -f ${TARGET}/${key}* 44 | fi 45 | done 46 | 47 | exit 0 48 | -------------------------------------------------------------------------------- /example/hooks/cloud-init: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (C) 2015 Oregon State University 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, but 11 | # WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 | # 02110-1301, USA. 19 | # 20 | # Copy files from an overlay directory into an instance. This assumes the same 21 | # filesystem structure as the system. 22 | 23 | set -e 24 | 25 | . common.sh 26 | 27 | # Ganeti specific NoCloud cloud-init config 28 | cinit_cfg="/etc/cloud/cloud.cfg.d/99_ganeti.cfg" 29 | 30 | debug set -x 31 | 32 | if [ -z "${TARGET}" -o ! -d "${TARGET}" ] ; then 33 | log_error "Missing target directory" 34 | exit 1 35 | fi 36 | 37 | # Need to export these out to the ruby script can read it 38 | export CINIT_USER CINIT_SSH_KEY CINIT_SSH_PWAUTH 39 | export CINIT_MANAGE_RESOLV_CONF CINIT_DISABLE_ROOT 40 | export DNS_SERVERS DNS_SEARCH 41 | 42 | # Write out config as a yaml file 43 | if [ -d ${TARGET}/etc/cloud/cloud.cfg.d ] ; then 44 | ./cloud_init.rb > ${TARGET}/${cinit_cfg} 45 | else 46 | log_error "cloud-init is not installed" 47 | exit 1 48 | fi 49 | 50 | exit 0 51 | -------------------------------------------------------------------------------- /devel/upload: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (C) 2006, 2007 Google Inc. 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, but 11 | # WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 | # 02110-1301, USA. 19 | 20 | # This is a test script to ease development and testing on test clusters. 21 | # It should not be used to update production environments. 22 | 23 | # Usage: upload node-{1,2,3} 24 | 25 | set -e 26 | 27 | hosts= 28 | while [ "$#" -gt 0 ]; do 29 | opt="$1" 30 | case "$opt" in 31 | -h|--help) 32 | echo "Usage: $0 hosts..." 33 | exit 0 34 | ;; 35 | -*) 36 | echo "Unknown option: $opt" >&2 37 | exit 1 38 | ;; 39 | *) 40 | hosts="$hosts $opt" 41 | ;; 42 | esac 43 | shift 44 | done 45 | 46 | set ${hosts} 47 | 48 | TXD=`mktemp -d` 49 | trap 'rm -rf $TXD' EXIT 50 | 51 | # install the os as a real tree 52 | make install DESTDIR="$TXD" 53 | 54 | echo --- 55 | 56 | ( cd "$TXD" && find; ) 57 | 58 | echo --- 59 | 60 | for host; do 61 | echo Uploading code to ${host}... 62 | rsync -v -rlDc ${TXD}/* root@${host}:/ & 63 | done 64 | wait 65 | 66 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # -*- makefile -*- 3 | 4 | # Uncomment this to turn on verbose mode. 5 | #export DH_VERBOSE=1 6 | 7 | 8 | config.status: configure 9 | 10 | configure: 11 | dh_testdir 12 | ./autogen.sh 13 | ./configure $(CROSS) --prefix=/usr --localstatedir=/var --sysconfdir=/etc 14 | 15 | build: build-stamp 16 | 17 | build-stamp: config.status 18 | dh_testdir 19 | 20 | # Add here commands to compile the package. 21 | $(MAKE) 22 | #docbook-to-man debian/ganeti-instance-image.sgml > ganeti-instance-image.1 23 | 24 | touch $@ 25 | 26 | clean: 27 | dh_testdir 28 | dh_testroot 29 | rm -f build-stamp 30 | 31 | # Add here commands to clean up after the build process. 32 | [ ! -f Makefile ] || $(MAKE) distclean 33 | rm -f config.sub config.guess 34 | rm -rf aclocal.m4 autotools configure Makefile.in 35 | 36 | dh_clean 37 | 38 | install: build 39 | dh_testdir 40 | dh_testroot 41 | dh_clean -k 42 | dh_installdirs 43 | 44 | # Add here commands to install the package into debian/ganeti-instance-image. 45 | cp defaults $(CURDIR)/debian/ganeti-instance-image/etc/default/ganeti-instance-image 46 | $(MAKE) DESTDIR=$(CURDIR)/debian/ganeti-instance-image install 47 | 48 | 49 | # Build architecture-independent files here. 50 | binary-indep: build install 51 | # We have nothing to do by default. 52 | 53 | # Build architecture-dependent files here. 54 | binary-arch: build install 55 | dh_testdir 56 | dh_testroot 57 | dh_installchangelogs ChangeLog 58 | dh_installdocs 59 | dh_installexamples 60 | dh_install 61 | # dh_installmenu 62 | # dh_installdebconf 63 | # dh_installlogrotate 64 | # dh_installemacsen 65 | # dh_installpam 66 | # dh_installmime 67 | # dh_python 68 | # dh_installinit 69 | # dh_installcron 70 | # dh_installinfo 71 | dh_installman 72 | dh_link 73 | dh_strip 74 | dh_compress 75 | dh_fixperms 76 | # dh_perl 77 | # dh_makeshlibs 78 | dh_installdeb 79 | dh_shlibdeps 80 | dh_gencontrol 81 | dh_md5sums 82 | dh_builddeb 83 | 84 | binary: binary-indep binary-arch 85 | .PHONY: build clean binary-indep binary-arch binary install 86 | -------------------------------------------------------------------------------- /test/cookbooks/instance-image-devel/recipes/default.rb: -------------------------------------------------------------------------------- 1 | # node.default['ganeti']['version'] = '2.16.2' 2 | node.default['ganeti']['yum']['url'] = 'https://ftp2.osuosl.org/pub/ganeti-rpm/$releasever/$basearch' 3 | node.default['ganeti']['master-node'] = 'instance-image.localdomain' 4 | node.default['ganeti']['instance_image']['variants_list'] = %w(default cirros) 5 | node.default['ganeti']['instance_image']['config_defaults']['image_debug'] = 1 6 | node.default['ganeti']['instance_image']['config_defaults']['swap'] = 'no' 7 | node.default['ganeti']['instance_image']['config_defaults']['cache_dir'] = '' 8 | node.default['ganeti']['cluster'].tap do |c| 9 | c['master-netdev'] = 'eth1' 10 | c['disk-templates'] = %w(plain) 11 | c['nic'] = { 12 | 'mode' => 'routed', 13 | 'link' => '100', 14 | } 15 | c['extra-opts'] = [ 16 | '--vg-name=ganeti', 17 | "-H kvm:kernel_path='',initrd_path=''", 18 | ].join(' ') 19 | c['name'] = 'ganeti.localdomain' 20 | end 21 | 22 | build_essential 'ganeti-instance-image' 23 | 24 | package %w( 25 | automake 26 | curl 27 | dump 28 | kpartx 29 | lvm2 30 | parted 31 | vim 32 | ) 33 | 34 | execute 'create ganeti volume group' do 35 | command <<-EOF 36 | dd if=/dev/zero of=/var/tmp/ganeti_vg bs=1M seek=21480 count=0 37 | vgcreate ganeti $(losetup --show -f /var/tmp/ganeti_vg) 38 | EOF 39 | action :run 40 | not_if 'vgs ganeti' 41 | end 42 | 43 | replace_or_add 'localhost' do 44 | path '/etc/hosts' 45 | pattern /^127.0.0.1.*/ 46 | sensitive false 47 | line '127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4' 48 | end 49 | 50 | delete_lines 'remove 127.0.1.1' do 51 | path '/etc/hosts' 52 | pattern /^127.0.1.1.*/ 53 | sensitive false 54 | end 55 | 56 | append_if_no_line '192.168.10.10' do 57 | path '/etc/hosts' 58 | sensitive false 59 | line '192.168.10.10 ganeti.localdomain' 60 | end 61 | 62 | append_if_no_line 'hostname' do 63 | path '/etc/hosts' 64 | sensitive false 65 | line "#{node['network']['interfaces']['eth1']['addresses'].keys[1]} #{node['fqdn']} #{node['hostname']}" 66 | end 67 | 68 | include_recipe 'ganeti' 69 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | ganeti-instance-image (0.7.3) unstable; urgency=medium 2 | 3 | * Released 0.7.3 4 | * Fixes Include: 5 | - Remove datasource_list from generated cloud-init config (#31) 6 | 7 | -- Lance Albertson Thu, 27 Apr 2023 16:18:02 -0700 8 | 9 | ganeti-instance-image (0.7.2) unstable; urgency=medium 10 | 11 | * Released 0.7.2 12 | * Fixes Include: 13 | - Add /var/cache/ganeti-instance-image directory to package (#29) 14 | - bug fix: can't create instance if swap=no and disk size is < memory (25) 15 | 16 | -- Lance Albertson Thu, 20 Jul 2017 14:51:02 -0700 17 | 18 | ganeti-instance-image (0.7.1) unstable; urgency=medium 19 | 20 | * Released 0.7.1 21 | * Fixes include: 22 | - Properly set variable checks for IMAGE_CLEANUP (#27) 23 | - Vagrant environment fixes (#28) 24 | 25 | -- Lance Albertson Wed, 19 Jul 2017 16:07:45 -0700 26 | 27 | ganeti-instance-image (0.7.0) unstable; urgency=medium 28 | 29 | * Major features added: 30 | * Vagrant+Chef development environment 31 | * Image URL support (imported from GRNET) 32 | * Support for qcow2 images 33 | * Cloud init support 34 | 35 | -- Lance Albertson Fri, 14 Jul 2017 19:21:35 -0700 36 | 37 | ganeti-instance-image (0.6-1) unstable; urgency=high 38 | * Version bump, bug fixes and new features 39 | 40 | -- Lance Albertson Mon, 08 Jul 2013 09:33:34 -0700 41 | 42 | ganeti-instance-image (0.5.1-1) unstable; urgency=high 43 | * Bugfix release 44 | * Ticket #4785 - blkid sometimes didn't return a value 45 | * Ticket #5685 - baselayout-2.x support for gentoo guests 46 | 47 | -- Lance Albertson Fri, 25 May 2011 14:18:35 -0700 48 | 49 | ganeti-instance-image (0.5-1) unstable; urgency=low 50 | * Version bump 51 | 52 | -- Lance Albertson Fri, 1 Apr 2011 10:44:00 -0700 53 | 54 | ganeti-instance-image (0.4-1+gitaf758a63) lenny-backports; urgency=low 55 | 56 | * git revision af758a63c8776e0dc0f310f296cdc181fa31b011. 57 | * fixes for FTBFS 58 | 59 | -- hoonet local system user Mon, 20 Dec 2010 09:34:15 +0100 60 | 61 | ganeti-instance-image (0.4-1) unstable; urgency=low 62 | 63 | * Initial release 64 | 65 | -- Ed Lim Tue, 13 Jul 2010 18:25:43 +0000 66 | 67 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | AC_PREREQ(2.59) 2 | AC_INIT(ganeti-instance-image, 0.7.3, lance@osuosl.org) 3 | 4 | AC_CONFIG_AUX_DIR(autotools) 5 | AC_CONFIG_SRCDIR(configure) 6 | 7 | AM_INIT_AUTOMAKE([1.9 foreign tar-ustar -Wall -Wno-portability]) 8 | 9 | # --with-os-dir=... 10 | AC_ARG_WITH([os-dir], 11 | [AS_HELP_STRING([--with-os-dir=DIR], 12 | [top-level OS directory under which to install] 13 | [ [DATADIR/ganeti/os]] 14 | )], 15 | [os_dir="$withval"], 16 | [os_dir="$datadir/ganeti/os"]) 17 | AC_SUBST(OS_DIR, $os_dir) 18 | 19 | # --with-default-dir=... 20 | AC_ARG_WITH([default-dir], 21 | [AS_HELP_STRING([--with-default-dir=DIR], 22 | [top-level default config directory under which to install] 23 | [ [SYSCONFDIR/default]] 24 | )], 25 | [default_dir="$withval"], 26 | [default_dir="$sysconfdir/default"]) 27 | AC_SUBST(DEFAULT_DIR, $default_dir) 28 | 29 | # Check common programs 30 | AC_PROG_INSTALL 31 | AC_PROG_LN_S 32 | AC_PROG_AWK 33 | AC_PROG_MKDIR_P 34 | 35 | AC_PATH_PROG(DUMP, [dump], [], [$PATH:/usr/sbin:/sbin]) 36 | if test -z "$DUMP" ; then 37 | AC_MSG_ERROR([dump not found in $PATH]) 38 | fi 39 | 40 | AC_PATH_PROG(LOSETUP, [losetup], [], [$PATH:/usr/sbin:/sbin]) 41 | if test -z "$LOSETUP" ; then 42 | AC_MSG_ERROR([losetup not found in $PATH]) 43 | fi 44 | 45 | AC_PATH_PROG(KPARTX, [kpartx], [], [$PATH:/usr/sbin:/sbin]) 46 | if test -z "$KPARTX" ; then 47 | AC_MSG_ERROR([kpartx not found in $PATH]) 48 | fi 49 | 50 | if $KPARTX | grep -q '\-s sync mode'; then 51 | KPARTX="$KPARTX -s" 52 | fi 53 | 54 | AC_PATH_PROG(SFDISK, [sfdisk], [], [$PATH:/usr/sbin:/sbin]) 55 | if test -z "$SFDISK" ; then 56 | AC_MSG_ERROR([sfdisk not found in $PATH]) 57 | fi 58 | 59 | AC_PATH_PROG(PARTED, [parted], [], [$PATH:/usr/sbin:/sbin]) 60 | if test -z "$PARTED" ; then 61 | AC_MSG_WARN([parted not found in $PATH]) 62 | fi 63 | 64 | AC_PATH_PROG(QEMU_IMG, [qemu-img], [], [$PATH:/usr/sbin:/sbin]) 65 | if test -z "$QEMU_IMG" ; then 66 | AC_MSG_ERROR([qemu-img not found in $PATH]) 67 | fi 68 | 69 | AC_PATH_PROG(CURL, [curl], [], [$PATH:/usr/bin:/bin]) 70 | if test -z "$CURL" ; then 71 | AC_MSG_ERROR([curl not found in $PATH]) 72 | fi 73 | 74 | AC_PATH_PROG(SHA1SUM, [sha1sum], [], [$PATH:/usr/bin:/bin]) 75 | if test -z "$SHA1SUM" ; then 76 | AC_MSG_ERROR([sha1sum not found in $PATH]) 77 | fi 78 | 79 | AC_CONFIG_FILES([ 80 | Makefile 81 | ]) 82 | 83 | AC_OUTPUT 84 | -------------------------------------------------------------------------------- /cloud_init.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # Copyright (C) 2015 Oregon State University 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, but 11 | # WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 | # 02110-1301, USA. 19 | 20 | require 'yaml' 21 | 22 | def cloud_init 23 | host = ENV['INSTANCE_NAME'] || '' 24 | user = ENV['CINIT_USER'] 25 | ssh_key = ENV['CINIT_SSH_KEY'] 26 | disable_root = ENV['CINIT_DISABLE_ROOT'] == 'yes' ? 1 : 0 27 | ssh_pwauth = ENV['CINIT_SSH_PWAUTH'] == 'yes' ? 1 : 0 28 | manage_resolv_conf = ENV['CINIT_MANAGE_RESOLV_CONF'] == 'yes' ? true : false 29 | name_servers = ENV['DNS_SERVERS'] 30 | search_domains = ENV['DNS_SEARCH'] 31 | domain = host.split('.').drop(1).join('.') 32 | resolv_conf = nil 33 | 34 | if manage_resolv_conf 35 | manage_conf = true 36 | resolv_conf = { 37 | 'nameservers' => name_servers.split, 38 | 'searchdomains' => search_domains.split, 39 | 'domain' => domain, 40 | 'options' => { 41 | 'rotate' => true, 42 | 'timeout' => 1 43 | } 44 | } 45 | else 46 | manage_conf = false 47 | end 48 | 49 | init_modules = 50 | %w( 51 | migrator 52 | bootcmd 53 | write-files 54 | growpart 55 | resizefs 56 | set_hostname 57 | update_hostname 58 | update_etc_hosts 59 | resolv_conf 60 | rsyslog 61 | users-groups 62 | ssh 63 | ) 64 | 65 | config = { 66 | 'hostname' => host.sub(/\..*$/, ''), 67 | 'fqdn' => host, 68 | 'instance-id' => host, 69 | 'disable_root' => disable_root, 70 | 'ssh_pwauth' => ssh_pwauth, 71 | 'manage-resolv-conf' => manage_conf, 72 | 'manage_resolv_conf' => manage_conf, 73 | 'cloud_init_modules' => init_modules, 74 | 'users' => [ 75 | 'name' => user, 76 | 'primary-group' => user, 77 | 'groups' => %w(wheel adm systemd-journal), 78 | 'sudo' => ['ALL=(ALL) NOPASSWD:ALL'], 79 | 'shell' => '/bin/bash', 80 | 'lock_passwd' => true, 81 | 'ssh-authorized-keys' => [ssh_key] 82 | ], 83 | 'groups' => [user], 84 | 'resolv_conf' => resolv_conf 85 | } 86 | 87 | config.to_yaml 88 | end 89 | 90 | puts cloud_init 91 | -------------------------------------------------------------------------------- /export: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (C) 2010 Oregon State University 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, but 11 | # WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 | # 02110-1301, USA. 19 | 20 | set -e 21 | 22 | . common.sh 23 | 24 | debug set -x 25 | 26 | # If the target device is not a real block device we'll first losetup it. 27 | # This is needed for file disks. 28 | if [ ! -b $blockdev ]; then 29 | ORIGINAL_BLOCKDEV=$blockdev 30 | blockdev=$($LOSETUP -sf $blockdev) 31 | CLEANUP+=("$LOSETUP -d $blockdev") 32 | fi 33 | 34 | if [ ! "${NOMOUNT}" = "yes" ] ; then 35 | filesystem_dev=$(map_disk0 $blockdev) 36 | CLEANUP+=("unmap_disk0 $blockdev") 37 | root_dev=$(map_partition $filesystem_dev root) 38 | boot_dev=$(map_partition $filesystem_dev boot) 39 | fi 40 | 41 | TARGET=`mktemp -d --tmpdir=${EXPORT_DIR}` || exit 1 42 | CLEANUP+=("rmdir $TARGET") 43 | 44 | if [ "${NOMOUNT}" = "yes" ] ; then 45 | # convert block device to qcow2 image to support OS's like Windows. Use 46 | # qcow2 to conserve on space. 47 | $QEMU_IMG convert $blockdev -O qcow2 ${TARGET}/disk.img 48 | CLEANUP+=("rm ${TARGET}/disk.img") 49 | else 50 | vol_type_root="$($VOL_TYPE $root_dev)" 51 | if [ -n "${boot_dev}" ] ; then 52 | vol_type_boot="$($VOL_TYPE $boot_dev)" 53 | fi 54 | 55 | for fs in boot root ; do 56 | # use indirect reference to make the variables dynamic 57 | dev="$(eval "echo \${$(echo ${fs}_dev)"})" 58 | vol_type="$(eval echo \$vol_type_${fs})" 59 | if [ -z "$vol_type" -a -n "${dev}" ] ; then 60 | log_error "Unable to find ${fs} filesystem type at ${dev}" 61 | exit 1 62 | fi 63 | if [ -n "${dev}" ] ; then 64 | if [ "$vol_type" = "ext3" -o "$vol_type" = "ext2" \ 65 | -o "$vol_type" = "ext4" ] ; then 66 | $DUMP -0 -q -z9 -f ${TARGET}/${fs}.dump $dev 67 | CLEANUP+=("rm ${TARGET}/${fs}.dump") 68 | else 69 | log_error "${fs} is not a supported filesystem. Please use ext{2,3,4}" 70 | exit 1 71 | fi 72 | fi 73 | done 74 | fi 75 | 76 | ( cd $TARGET ; tar -cf - . ) 77 | 78 | # execute cleanups 79 | cleanup 80 | trap - EXIT 81 | 82 | exit 0 83 | -------------------------------------------------------------------------------- /example/config/kickstart/centos-5.5-x86_64-ganeti.cfg: -------------------------------------------------------------------------------- 1 | auth --useshadow --enablemd5 2 | # System bootloader configuration 3 | bootloader --location=mbr 4 | # Clear the Master Boot Record 5 | zerombr 6 | # Partition clearing information 7 | clearpart --all --initlabel 8 | # Use text mode install 9 | text 10 | # Firewall configuration 11 | firewall --enable 12 | # Run the Setup Agent on first boot 13 | firstboot --disable 14 | # System keyboard 15 | keyboard us 16 | # System language 17 | lang en_US 18 | # Installation logging level 19 | logging --level=debug 20 | # Use network installation 21 | url --url=http://centos.osuosl.org/5.5/os/x86_64/ 22 | # Add everything repo 23 | repo --name=EPEL --baseurl=http://epel.osuosl.org/5/x86_64/ 24 | repo --name=updates --baseurl=http://centos.osuosl.org/5.5/updates/x86_64/ 25 | # Network information 26 | network --bootproto=dhcp 27 | # Reboot after installation 28 | #reboot 29 | #Root password 30 | rootpw --iscrypted 31 | 32 | # SELinux configuration 33 | selinux --enforcing 34 | # Services 35 | services --enabled=network,denyhosts,acpid 36 | # Do not configure the X Window System 37 | skipx 38 | # System timezone 39 | timezone --utc UTC 40 | # Install OS instead of upgrade 41 | install 42 | # Disk partitioning information 43 | part /boot --fstype="ext3" --size=200 44 | part swap --fstype="swap" --recommended 45 | part / --fstype="ext3" --grow --size=100 46 | 47 | %packages 48 | @base 49 | -aspell 50 | -aspell-en 51 | -bluez-utils 52 | -bluez-gnome 53 | -bluez-hcidump 54 | -bluez-libs 55 | -ccid 56 | -coolkey 57 | -finger 58 | -gpm 59 | -iptstate 60 | -irda-utils 61 | -jwhois 62 | -lftp 63 | -logwatch 64 | -NetworkManager 65 | -pcmciautils 66 | -pinfo 67 | -rdate 68 | -rsh 69 | -telnet 70 | -firstboot-tui 71 | -system-config-network-tui 72 | -nfs-utils 73 | -nfs-utils-lib 74 | -policycoreutils 75 | -zsh 76 | -autofs 77 | -ksh 78 | -mdadm 79 | -smartmontools 80 | -udftools 81 | #-device-mapper-multipath 82 | @system-tools 83 | -ipsec-tools 84 | -nmap 85 | -samba-client 86 | -samba-common 87 | -xdelta 88 | -zisofs-tools 89 | -vnc 90 | -sendmail 91 | postfix 92 | acpid 93 | #syslog-ng 94 | bash-completion 95 | @editors 96 | e2fsprogs 97 | denyhosts 98 | -rdist 99 | 100 | %post --interpreter /bin/bash --log=/root/post-install.log 101 | set -x 102 | # import key 103 | /bin/rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5 104 | # remove several X related apps we don't need 105 | /usr/bin/yum -y remove gnome-mount gtk2 cups cups-libs libX11 \ 106 | libXau libXdmcp atk alsa-lib audiofile portmap ppp avahi 107 | # install & import epel key 108 | /bin/rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/x86_64/epel-release-5-3.noarch.rpm 109 | /bin/rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL 110 | /usr/bin/yum -y clean all 111 | # relabel selinux on boot for new ganeti guests 112 | touch /.autorelabel 113 | %end 114 | -------------------------------------------------------------------------------- /import: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (C) 2010, 2011, 2012 Oregon State University 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, but 11 | # WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 | # 02110-1301, USA. 19 | 20 | set -e 21 | 22 | . common.sh 23 | 24 | debug set -x 25 | 26 | # If the target device is not a real block device we'll first losetup it. 27 | # This is needed for file disks. 28 | if [ ! -b $blockdev ]; then 29 | ORIGINAL_BLOCKDEV=$blockdev 30 | blockdev=$($LOSETUP -sf $blockdev) 31 | CLEANUP+=("$LOSETUP -d $blockdev") 32 | fi 33 | 34 | TARGET=`mktemp -d` || exit 1 35 | CLEANUP+=("rmdir $TARGET") 36 | DUMPDIR=`mktemp -d` || exit 1 37 | CLEANUP+=("rm -rf $DUMPDIR") 38 | 39 | if [ ! "${NOMOUNT}" = "yes" ] ; then 40 | format_disk0 $blockdev 41 | filesystem_dev=$(map_disk0 $blockdev) 42 | CLEANUP+=("unmap_disk0 $blockdev") 43 | root_dev=$(map_partition $filesystem_dev root) 44 | boot_dev=$(map_partition $filesystem_dev boot) 45 | swap_dev=$(map_partition $filesystem_dev swap) 46 | 47 | mkfs_disk0 48 | root_uuid="$($VOL_ID $root_dev)" 49 | [ -n "$boot_dev" ] && boot_uuid="$($VOL_ID $boot_dev)" 50 | [ -n "$swap_dev" ] && swap_uuid="$($VOL_ID $swap_dev)" 51 | 52 | mount_disk0 $TARGET 53 | fi 54 | 55 | # import dumps from tar file 56 | ( cd $DUMPDIR; tar -xf - ) 57 | 58 | if [ "${NOMOUNT}" = "yes" ] ; then 59 | ( $QEMU_IMG convert ${DUMPDIR}/disk.img -O host_device ${blockdev} ) 60 | else 61 | # clean up any previous restore runs 62 | rm -rf /tmp/rst* 63 | ( cd $TARGET ; restore -r -y -f ${DUMPDIR}/root.dump ) 64 | if [ -n "${boot_dev}" ] ; then 65 | ( cd ${TARGET}/boot ; restore -r -y -f ${DUMPDIR}/boot.dump ) 66 | fi 67 | 68 | setup_fstab $TARGET 69 | 70 | if [ "${INSTANCE_HV_serial_console}" = "True" ] ; then 71 | setup_console $TARGET 72 | fi 73 | 74 | rm -f $TARGET/etc/udev/rules.d/z*_persistent-net.rules 75 | 76 | if [ -n "$CUSTOMIZE_DIR" -a -d "$CUSTOMIZE_DIR" -a -x "$CUSTOMIZE_DIR/grub" ] ; then 77 | TARGET=$TARGET 78 | BLOCKDEV=$blockdev 79 | ROOT_DEV=$root_dev 80 | BOOT_DEV=$boot_dev 81 | IMPORT_SCRIPT="1" 82 | export TARGET SUITE BLOCKDEV ROOT_DEV BOOT_DEV IMPORT_SCRIPT 83 | # Install grub since we're not deploying via qemu-img 84 | ${CUSTOMIZE_DIR}/grub 85 | fi 86 | fi 87 | 88 | # execute cleanups 89 | cleanup 90 | trap - EXIT 91 | 92 | exit 0 93 | -------------------------------------------------------------------------------- /example/hooks/zz_ddns: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (C) 2011, 2012 Oregon State University 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, but 11 | # WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 | # 02110-1301, USA. 19 | # 20 | # This is an example script that configures your DHCP clients to set "send 21 | # host-name" so that Dynamic DNS work properly after installation. 22 | 23 | set -e 24 | 25 | . common.sh 26 | 27 | debug set -x 28 | 29 | FQDN="${INSTANCE_NAME}" 30 | SHORT_NAME="$(echo ${INSTANCE_NAME} | cut -d . -f 1)" 31 | RENAME= 32 | 33 | if [ -z "${TARGET}" -o ! -d "${TARGET}" ] ; then 34 | log_error "Missing target directory" 35 | exit 1 36 | fi 37 | 38 | while getopts "r" opt ; do 39 | case $opt in 40 | r) 41 | RENAME=true 42 | ;; 43 | *) 44 | ;; 45 | esac 46 | done 47 | 48 | # Functions 49 | debian_setup() { 50 | local dhclient_conf="" 51 | if [ -f "${TARGET}/etc/dhcp/dhclient.conf" ] ; then 52 | dhclient_conf="${TARGET}/etc/dhcp/dhclient.conf" 53 | elif [ -f "${TARGET}/etc/dhcp3/dhclient.conf" ] ; then 54 | dhclient_conf="${TARGET}/etc/dhcp3/dhclient.conf" 55 | else 56 | log_error "Missing dhclient.conf file" 57 | exit 1 58 | fi 59 | 60 | if [ -n "${FQDN}" ] && [ -z "${RENAME}" ] ; then 61 | echo "send host-name ${SHORT_NAME};" >> ${dhclient_conf} 62 | else 63 | sed -i -e "s/send host-name.*/send host-name ${SHORT_NAME};/" \ 64 | ${dhclient_conf} 65 | fi 66 | } 67 | 68 | redhat_setup() { 69 | if [ ! -f "${TARGET}/etc/sysconfig/network-scripts/ifcfg-eth0" ] ; then 70 | log_error "Missing ifcfg-eth0 file" 71 | exit 1 72 | fi 73 | if [ -n "${FQDN}" ] && [ -z "${RENAME}" ] ; then 74 | echo "DHCP_HOSTNAME=${SHORT_NAME}" >> \ 75 | ${TARGET}/etc/sysconfig/network-scripts/ifcfg-eth0 76 | else 77 | sed -i -e "s/DHCP_HOSTNAME=.*/DHCP_HOSTNAME=${SHORT_NAME}/" \ 78 | ${TARGET}/etc/sysconfig/network-scripts/ifcfg-eth0 79 | fi 80 | } 81 | 82 | gentoo_setup() { 83 | echo "no action needed for ddns" 84 | } 85 | 86 | suse_setup() { 87 | echo "untested for suse" 88 | } 89 | 90 | # Main 91 | get_os_type $TARGET 92 | 93 | if [ "${NIC_COUNT}" -gt 0 -a -n "${OS_TYPE}" ] ; then 94 | ${OS_TYPE}_setup 95 | else 96 | log_error "Unsupported OS_TYPE" 97 | fi 98 | 99 | exit 0 100 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | osname=$(subst ganeti-instance-,,$(PACKAGE)) 2 | 3 | osdir=$(OS_DIR)/$(osname) 4 | customdir=${sysconfdir}/ganeti/instance-image/hooks 5 | configdir=${sysconfdir}/ganeti/instance-image 6 | variantsdir=${sysconfdir}/ganeti/instance-image/variants 7 | networksdir=${sysconfdir}/ganeti/instance-image/networks 8 | overlaysdir=${sysconfdir}/ganeti/instance-image/overlays 9 | toolsdir=$(OS_DIR)/$(osname)/tools 10 | 11 | dist_os_SCRIPTS = ${srcdir}/create ${srcdir}/import ${srcdir}/export \ 12 | ${srcdir}/rename ${srcdir}/cloud_init.rb 13 | dist_os_DATA = ${srcdir}/ganeti_api_version 14 | dist_config_DATA = ${srcdir}/variants.list 15 | os_DATA = common.sh 16 | tools_SCRIPTS = tools/ganeti-image tools/make-image tools/make-dump \ 17 | tools/make-qemu-img tools/mount-disks tools/umount-disks 18 | 19 | dist_custom_DATA = ${srcdir}/example/hooks/* 20 | 21 | dist_doc_DATA = ${srcdir}/COPYING ${srcdir}/NEWS ${srcdir}/README.markdown 22 | 23 | EXTRA_DIST = common.sh.in defaults tools/ganeti-image.in tools/make-image.in \ 24 | tools/make-dump.in tools/make-qemu-img.in tools/mount-disks.in \ 25 | tools/umount-disks.in ganeti-instance-image.spec debian 26 | 27 | edit = sed \ 28 | -e 's|@sysconfdir[@]|$(sysconfdir)|g' \ 29 | -e 's|@localstatedir[@]|$(localstatedir)|g' \ 30 | -e 's|@osdir[@]|$(OS_DIR)|g' \ 31 | -e 's|@osname[@]|$(osname)|g' \ 32 | -e 's|@defaultdir[@]|$(DEFAULT_DIR)|g' \ 33 | -e 's|@AWK[@]|$(AWK)|g' \ 34 | -e 's|@MKDIR_P[@]|$(MKDIR_P)|g' \ 35 | -e 's|@DUMP[@]|$(DUMP)|g' \ 36 | -e 's|@LOSETUP[@]|$(LOSETUP)|g' \ 37 | -e 's|@KPARTX[@]|$(KPARTX)|g' \ 38 | -e 's|@SFDISK[@]|$(SFDISK)|g' \ 39 | -e 's|@PARTED[@]|$(PARTED)|g' \ 40 | -e 's|@QEMU_IMG[@]|$(QEMU_IMG)|g' \ 41 | -e 's|@CURL[@]|$(CURL)|g' \ 42 | -e 's|@SHA1SUM[@]|$(SHA1SUM)|g' 43 | 44 | common.sh: Makefile 45 | rm -f $@ $@.tmp 46 | srcdir=''; \ 47 | test -f ./$@.in || srcdir=$(srcdir)/; \ 48 | $(edit) $${srcdir}$@.in >$@.tmp 49 | mv $@.tmp $@ 50 | 51 | $(tools_SCRIPTS): Makefile 52 | @mkdir_p@ tools 53 | rm -f $@ $@.tmp 54 | srcdir=''; \ 55 | test -f ./$@.in || srcdir=$(srcdir)/; \ 56 | $(edit) $${srcdir}$@.in >$@.tmp 57 | mv $@.tmp $@ 58 | 59 | common.sh: $(srcdir)/common.sh.in 60 | tools/ganeti-image: $(srcdir)/tools/ganeti-image.in 61 | tools/make-dump: $(srcdir)/tools/make-dump.in 62 | tools/make-image: $(srcdir)/tools/make-image.in 63 | tools/make-qemu-img: $(srcdir)/tools/make-qemu-img.in 64 | tools/mount-disks: $(srcdir)/tools/mount-disks.in 65 | tools/umount-disks: $(srcdir)/tools/umount-disks.in 66 | 67 | install-exec-local: 68 | @mkdir_p@ "$(DESTDIR)$(OS_DIR)/$(osname)" 69 | @mkdir_p@ "$(DESTDIR)$(variantsdir)" 70 | @mkdir_p@ "$(DESTDIR)$(networksdir)/subnets" 71 | @mkdir_p@ "$(DESTDIR)$(networksdir)/instances" 72 | @mkdir_p@ "$(DESTDIR)$(overlaysdir)" 73 | @mkdir_p@ "$(DESTDIR)$(localstatedir)/cache/ganeti-instance-image" 74 | touch "$(DESTDIR)$(variantsdir)/default.conf" 75 | ln -fs $(DESTDIR)$(configdir)/variants.list $(DESTDIR)$(OS_DIR)/$(osname)/variants.list 76 | 77 | distclean-local: 78 | rm -rf build-stamp debian/files debian/*.log debian/ganeti-instance-image/ \ 79 | debian/ganeti-instance-image.substvars 80 | 81 | CLEANFILES = $(os_DATA) $(tools_SCRIPTS) 82 | -------------------------------------------------------------------------------- /defaults: -------------------------------------------------------------------------------- 1 | # ganeti-instance-image defaults file 2 | 3 | # CDINSTALL: Only setup disks for a cd based install 4 | # Just setup the disks so that you can boot a machine up on a cd to create a 5 | # new image 6 | # CDINSTALL="no" 7 | 8 | # SWAP: Create a swap partition 9 | # SWAP=yes 10 | 11 | # SWAP_SIZE: Manually set the size of the swap partition (in MB) 12 | # If left empty, it will set the size equal to the memory for the instance. 13 | # Make sure you have enough disk space for the swap partition! 14 | # SWAP_SIZE="" 15 | 16 | # BOOT_SIZE: Set the size of the /boot partition (in MB) 17 | # If left empty, it will use the default setting of 100MB as the size of the 18 | # /boot volume. 19 | # BOOT_SIZE="" 20 | 21 | # FILESYSTEM: Set which filesystem to format the disks as. Currently only 22 | # supports ext3 or ext4. Default is ext3. 23 | # FILESYSTEM="ext3" 24 | 25 | # KERNEL_ARGS: Add additional kernel boot arguments to an instance. This only 26 | # works on instances booting a kernel from inside. 27 | # KERNEL_ARGS="" 28 | 29 | # IMAGE_NAME: Name of the image to use 30 | # Generally you use the name of the image with the version of the OS included. 31 | # Examples include: 32 | # centos-5.4 debian-4.0 fedora-12 33 | # IMAGE_NAME="" 34 | 35 | # IMAGE_TYPE: Either qemu disk images, tarball, or dump based images. 36 | # Use either qemu, raw, qcow2, tarball, dump (default is dump) 37 | # IMAGE_TYPE="dump" 38 | 39 | # IMAGE_DIR: directory location for disk images 40 | # ( default is @localstatedir@/cache/ganeti-instance-image ) 41 | # IMAGE_DIR="" 42 | 43 | # NOMOUNT: Do not try to mount volume (if it is not a linux partition). Accepts 44 | # either 'yes' or 'no'. This option is useful for installing Windows images for 45 | # example. ( default is no ) 46 | # NOMOUNT="" 47 | 48 | # OVERLAY: overlay of files to be copied to the instance after OS installation. 49 | # This is useful for situations where you want to copy instance specific 50 | # configs such as resolv.conf. 51 | # OVERLAY="" 52 | 53 | # EXPORT_DIR: directory used when exporting an instance 54 | # (default is: /tmp) 55 | # EXPORT_DIR="/tmp" 56 | 57 | # ARCH: Define the ARCH of the image to use 58 | # Use either x86 or x86_64 59 | # ARCH="" 60 | 61 | # CUSTOMIZE_DIR: a directory containing scripts to customize the installation. 62 | # The scripts are executed using run-parts 63 | # By default /etc/ganeti/instance-image/hooks 64 | # CUSTOMIZE_DIR="/etc/ganeti/instance-image/hooks" 65 | 66 | # IMAGE_DEBUG: turn on debugging output for the scripts 67 | # IMAGE_DEBUG=0 68 | 69 | # IMAGE_URL: a remote (HTTP) location for the images. 70 | # A checksum (in SHA1 form) file with an appended .sig extention is required 71 | # to be present there for checking the image intergrity. 72 | # If not set, it falls back to IMAGE_DIR. 73 | # IMAGE_URL="" 74 | 75 | # CACHE_DIR: directory where the downloaded images will be saved 76 | # ( default is @localstatedir@/cache/ganeti-instance-image ) 77 | # CACHE_DIR="" 78 | 79 | # IMAGE_VERIFY: Check the image signature 80 | # if set to yes then a file .sig must be on the IMAGE_URL 81 | # and contain the sha1sum value of the image 82 | # IMAGE_VERIFY="yes" 83 | 84 | # IMG_CLEANUP: whether to remove the downloaded image after the installation 85 | # finishes. If set to no manual cleanup of images is needed. 86 | # IMAGE_CLEANUP="no" 87 | -------------------------------------------------------------------------------- /rename: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (C) 2010, 2011, 2012 Oregon State University 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, but 11 | # WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 | # 02110-1301, USA. 19 | 20 | set -e 21 | 22 | . common.sh 23 | 24 | debug set -x 25 | 26 | if [ "${NOMOUNT}" = "yes" ] ; then 27 | # do nothing if NOMOUNT is enabled 28 | exit 0 29 | fi 30 | 31 | TARGET=`mktemp -d` || exit 1 32 | CLEANUP+=("rmdir $TARGET") 33 | 34 | # If the target device is not a real block device we'll first losetup it. 35 | # This is needed for file disks. 36 | if [ ! -b $blockdev ]; then 37 | ORIGINAL_BLOCKDEV=$blockdev 38 | blockdev=$($LOSETUP -sf $blockdev) 39 | CLEANUP+=("$LOSETUP -d $blockdev") 40 | fi 41 | 42 | filesystem_dev=$(map_disk0 $blockdev) 43 | CLEANUP+=("unmap_disk0 $blockdev") 44 | root_dev=$(map_partition $filesystem_dev root) 45 | boot_dev=$(map_partition $filesystem_dev boot) 46 | 47 | mount_disk0 $TARGET 48 | get_os_type $TARGET 49 | 50 | case "${OS_TYPE}" in 51 | debian) 52 | HNAME="${TARGET}/etc/hostname" 53 | OLD_HNAME="$(cat $HNAME)" 54 | ;; 55 | redhat) 56 | HNAME="${TARGET}/etc/sysconfig/network" 57 | OLD_HNAME="$(grep HOSTNAME ${HNAME} | \ 58 | sed -e 's/HOSTNAME=//' | \ 59 | sed -e s/\"//g)" 60 | ;; 61 | gentoo) 62 | HNAME="${TARGET}/etc/conf.d/hostname" 63 | # baselayout-2.x support 64 | if [ -d ${TARGET}/usr/share/openrc ] ; then 65 | OLD_HNAME="$(grep hostname ${HNAME} | \ 66 | sed -e 's/hostname=//' | \ 67 | sed -e s/\"//g)" 68 | else 69 | OLD_HNAME="$(grep HOSTNAME ${HNAME} | \ 70 | sed -e 's/HOSTNAME=//' | \ 71 | sed -e s/\"//g)" 72 | fi 73 | ;; 74 | suse) 75 | HNAME="${TARGET}/etc/HOSTNAME" 76 | OLD_HNAME="$(cat $HNAME)" 77 | ;; 78 | esac 79 | 80 | if [ "$OLD_HNAME" = "$old_name" \ 81 | -o "${OLD_HNAME}.$(echo $old_name | cut -d . -f 2,3)" \ 82 | = "$old_name" ] ; then 83 | case "${OS_TYPE}" in 84 | debian|suse) 85 | echo $instance > $HNAME 86 | ;; 87 | redhat) 88 | sed -ie "s/HOSTNAME=${OLD_HNAME}/HOSTNAME=${instance}/" $HNAME 89 | ;; 90 | gentoo) 91 | if [ -d ${TARGET}/usr/share/openrc ] ; then 92 | sed -ie "s/hostname.*/hostname=\"${instance}\"/" $HNAME 93 | else 94 | sed -ie "s/HOSTNAME.*/HOSTNAME=\"${instance}\"/" $HNAME 95 | fi 96 | ;; 97 | esac 98 | 99 | if [ -x ${CUSTOMIZE_DIR}/zz_ddns ] ; then 100 | TARGET=$TARGET 101 | export TARGET 102 | ${CUSTOMIZE_DIR}/zz_ddns -r 103 | fi 104 | else 105 | log_error "Cannot rename from $old_name to $instance:" 106 | log_error "Instance has a different hostname ($OLD_HNAME)" 107 | exit 1 108 | fi 109 | 110 | # execute cleanups 111 | cleanup 112 | trap - EXIT 113 | 114 | exit 0 115 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | 2023-04-27 Lance Albertson 2 | * Released 0.7.3 3 | * Fixes Include: 4 | - Remove datasource_list from generated cloud-init config (#31) 5 | 2017-07-20 Lance Albertson 6 | * Released 0.7.2 7 | * Fixes Include: 8 | - Add /var/cache/ganeti-instance-image directory to package (#29) 9 | - bug fix: can't create instance if swap=no and disk size is < memory (25) 10 | 11 | 2017-07-19 Lance Albertson 12 | * Released 0.7.1 13 | * Fixes include: 14 | - Properly set variable checks for IMAGE_CLEANUP (#27) 15 | - Vagrant environment fixes (#28) 16 | 17 | 2017-07-14 Lance Albertson 18 | * Released 0.7.0 19 | 20 | 2015-06-02 Lance Albertson 21 | * Released 0.7-beta1 22 | * Major features added: 23 | * Vagrant+Chef development environment 24 | * Image URL support (imported from GRNET) 25 | * Support for qcow2 images 26 | * Cloud init support 27 | 28 | 2013-07-08 Lance Albertson 29 | * Released 0.6 30 | * Major features added: 31 | * Complete refactor of image creation scripts (ganeti-image) 32 | * Configurable boot directory size 33 | * Add optional support for parted instead of sfdisk 34 | * Ticket bug/feature fixes: 35 | * #3873 - Fix renaming for DDNS 36 | * #4143 - make-dump looks for common.sh in a wrong place 37 | * #5907 - Add gawk as debian dependency 38 | * #5955 - Updates for ganeti-instance-image.spec 39 | * #5967 - Restore leaving files in /tmp causes creation/import to fail 40 | * #7095 - Autotools building system does not work correctly 41 | * #7101 - The presence of `lsb_release' is not detected properly in 42 | common.sh 43 | * #7113 - Race conditions in restore's usage 44 | * #7515 - Add centos serial console support for redhat, too 45 | * #7815 - partitioning when KERNEL_PATH should set bootable flag 46 | * #8673 - Exporting to /tmp fails if the image is larger than the free 47 | space 48 | * #9231 - Make size of /boot configurable 49 | * #10473 - Package signing key not available 50 | * #10509 - Find grub/grub-setup paths correctly 51 | * #10923 - Fix resolv.conf for Ubuntu 12.04 52 | * #11871 - Fix mkfs.xfs 53 | * #11973 - Add parted support 54 | * #12435 - Add warning if swap size is larger than system disk size 55 | * #12441 - Bug in instance-image, overlay code 56 | 57 | 2011-05-25 Lance Albertson 58 | * Bugfix release 59 | * Ticket #4785 - blkid sometimes didn't return a value 60 | * Ticket #5685 - baselayout-2.x support for gentoo guests 61 | 62 | 2011-03-25 Lance Albertson 63 | * Released 0.5 64 | * Moved hooks directory to match upstream 65 | * Fixed rename 66 | * Fixed Debian/Redhat package files 67 | * CDINSTALL no set to "no" by default 68 | * Fixed hostname setting 69 | * New hook for dyanmic DNS 70 | 71 | 2010-05-07 Lance Albertson 72 | * Released 0.4 73 | * Add partial grub2 support 74 | * Switch default image type to dump 75 | * Added feature to add optional kernel parameters 76 | 77 | 2010-04-12 Lance Albertson 78 | * Released 0.3.1 (bugfix) 79 | * Fix logic for exports so that it works properly now 80 | * Run sync prior to umounting to avoid nasty hanging ext4 bug 81 | 82 | 2010-04-02 Lance Albertson 83 | * Released 0.3 84 | * Added feature to set static IPs for instances (see README) 85 | * Moved variants.list to $sysconfigdir/instance-image/variants.list and 86 | created a symlink to the old location. See issue 92 on the Ganeti issue 87 | tracker for more background information. 88 | 89 | 2010-03-30 Lance Albertson 90 | * Released 0.2 91 | * Added feature to set which filesystem to use (ext3 or ext4) 92 | * Added feature to manually set the size of the swap partition 93 | 94 | 2010-03-11 Lance Albertson 95 | * Initial release of 0.1 96 | -------------------------------------------------------------------------------- /tools/ganeti-image.in: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (C) 2012 Oregon State University 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, but 11 | # WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 | # 02110-1301, USA. 19 | 20 | set -e 21 | 22 | [ $GANETI_DEBUG ] && set -x 23 | IMAGE_DIR= 24 | INSTANCE_NAME= 25 | IMAGE_NAME= 26 | ARCH= 27 | HOSTNAME="$(hostname)" 28 | 29 | run_help() { 30 | echo "Usage: $0 [-d PATH] [-n NAME] [-a ARCH] -t TYPE -i INSTANCE" 31 | echo 32 | echo "Create an image of a ganeti instance using either a tarball, dump, or qemu image.." 33 | echo 34 | echo "-t TYPE Type of image, either: tarball, dump, or qemu-img" 35 | echo "-d PATH Path of where to put the image" 36 | echo "-i INSTANCE Name of the instance" 37 | echo "-n NAME Name of the image" 38 | echo "-a ARCH Architecture of the image" 39 | echo 40 | echo "This utility must be used on the master node. All optional args will" 41 | echo "have defaults if you do not set them." 42 | exit 0 43 | } 44 | 45 | while getopts "hd:i:a:n:t:" opt ; do 46 | case $opt in 47 | t) 48 | TYPE="$OPTARG" 49 | ;; 50 | d) 51 | IMAGE_DIR="-m $OPTARG" 52 | ;; 53 | i) 54 | INSTANCE_NAME="$OPTARG" 55 | ;; 56 | n) 57 | IMAGE_NAME="-n $OPTARG" 58 | ;; 59 | a) 60 | ARCH="-a $OPTARG" 61 | ;; 62 | h) 63 | run_help 64 | ;; 65 | *) 66 | ;; 67 | esac 68 | done 69 | 70 | #[ -z "$IMAGE_DIR" ] && echo "Error: Image path not set" && exit 1 71 | [ -z "$INSTANCE_NAME" ] && echo "Error: Instance name not set" && exit 1 72 | [ -z "$TYPE" ] && echo "Error: Image type not set" && exit 1 73 | 74 | incorrect_type=1 75 | for i in tarball dump qemu-img ; do 76 | if [ "$i" == $TYPE ] ; then 77 | incorrect_type=0 78 | fi 79 | done 80 | 81 | [ "$incorrect_type" == "1" ] && echo "Error: Incorrect type set" && exit 1 82 | 83 | # Am I master? 84 | if [ "$(gnt-cluster getmaster)" != "${HOSTNAME}" ] ; then 85 | echo "ERROR: Command must be run from master node" 86 | exit 1 87 | fi 88 | 89 | # Gather some information 90 | info=($(gnt-instance list -o os,hypervisor,disk.count,hv/kernel_path --no-headers --separator=' ' $INSTANCE_NAME)) 91 | OS_VARIANT="${info[0]/*+/}" 92 | HYPERVISOR="${info[1]}" 93 | DISK_COUNT="${info[2]}" 94 | INSTANCE_HV_kernel_path="${info[3]}" 95 | OS_API_VERSION="15" 96 | 97 | # Activate disks and capture output 98 | ad_output=($(gnt-instance activate-disks $INSTANCE_NAME | sed -e 's/\:/ /g')) 99 | 100 | # Get node/disk path 101 | NODE="${ad_output[0]}" 102 | DISK_0_PATH="${ad_output[2]}" 103 | 104 | export OS_VARIANT HYPERVISOR DISK_COUNT OS_API_VERSION DISK_0_PATH \ 105 | INSTANCE_HV_kernel_path 106 | 107 | echo "Creating image with type $TYPE from $INSTANCE_NAME in ${IMAGE_DIR} from node $NODE" 108 | 109 | if [ "$NODE" == "$HOSTNAME" ] ; then 110 | @osdir@/@osname@/tools/make-image -i $INSTANCE_NAME \ 111 | $IMAGE_DIR $IMAGE_NAME $ARCH -t $TYPE 112 | else 113 | ssh $NODE @osdir@/@osname@/tools/make-image \ 114 | -i $INSTANCE_NAME $IMAGE_DIR $IMAGE_NAME $ARCH -t $TYPE 115 | fi 116 | 117 | gnt-instance deactivate-disks $INSTANCE_NAME 118 | -------------------------------------------------------------------------------- /ganeti-instance-image.spec: -------------------------------------------------------------------------------- 1 | %define instancename image 2 | Name: ganeti-instance-image 3 | Version: 0.7.3 4 | Release: 1%{?dist} 5 | Summary: Guest OS definition for Ganeti based on Linux-based images 6 | 7 | Group: System Environment/Daemons 8 | License: GPLv2 9 | URL: http://code.osuosl.org/projects/ganeti-image 10 | Source0: http://ftp.osuosl.org/pub/osl/ganeti-instance-image/%{name}-%{version}.tar.gz 11 | BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) 12 | BuildRequires: qemu-img, dump, tar, kpartx, curl 13 | Requires: qemu-img, dump, tar, kpartx, curl, ganeti 14 | BuildArch: noarch 15 | 16 | %description 17 | This is a guest OS definition for Ganeti (http://code.google.com/p/ganeti). It 18 | will install a Linux-based image using either a tarball, filesystem dump, or a 19 | qemu-img disk image file. This definition also allows for manual creation of an 20 | instance by simply setting only the disks up and allowing you to boot via the 21 | install cd manually. The goal of this instance is to allow fast and flexible 22 | installation of instances without the need for external tools such as 23 | debootstrap. 24 | 25 | 26 | %prep 27 | %setup -q 28 | 29 | 30 | %build 31 | %configure \ 32 | --prefix=%{_prefix} \ 33 | --sysconfdir=%{_sysconfdir} \ 34 | --localstatedir=%{_localstatedir} 35 | make %{?_smp_mflags} 36 | 37 | 38 | %install 39 | rm -rf $RPM_BUILD_ROOT 40 | make install DESTDIR=$RPM_BUILD_ROOT 41 | 42 | # Next part covered by %doc in %files 43 | rm -rf $RPM_BUILD_ROOT/%{_datadir}/doc/%{name} 44 | 45 | # Workaround issue #92 http://code.google.com/p/ganeti/issues/detail?id=92 46 | # The install scripts create a symlink using the fully qualified path 47 | # that includes the build root path. 48 | pushd $RPM_BUILD_ROOT%{_datadir}/ganeti/os/%{instancename} 49 | rm -f variants.list 50 | ln -s ../../../../..%{_sysconfdir}/ganeti/instance-%{instancename}/variants.list variants.list 51 | popd 52 | 53 | 54 | %clean 55 | rm -rf $RPM_BUILD_ROOT 56 | 57 | 58 | %files 59 | %defattr(-,root,root,-) 60 | %doc COPYING README.markdown NEWS example/hooks/* 61 | %config(noreplace) %{_sysconfdir}/ganeti/instance-%{instancename}/variants/default.conf 62 | %config(noreplace) %{_sysconfdir}/ganeti/instance-%{instancename}/variants.list 63 | %config(noreplace) %{_sysconfdir}/ganeti/instance-%{instancename}/hooks/* 64 | %{_datadir}/ganeti/os/%{instancename}/* 65 | %{_localstatedir}/cache/ganeti-instance-image 66 | 67 | %changelog 68 | * Thu Apr 27 2032 Lance Albertson 69 | - Released 0.7.3 70 | - Fixes Include: 71 | - Remove datasource_list from generated cloud-init config (#31) 72 | 73 | * Thu Jul 20 2017 Lance Albertson 74 | - Released 0.7.2 75 | - Fixes Include: 76 | - Add /var/cache/ganeti-instance-image directory to package (#29) 77 | - bug fix: can't create instance if swap=no and disk size is < memory (25) 78 | 79 | * Wed Jul 19 2017 Lance Albertson 80 | - Released 0.7.1 81 | - Fixes include: 82 | - Properly set variable checks for IMAGE_CLEANUP (#27) 83 | - Vagrant environment fixes (#28) 84 | 85 | * Fri Jul 14 2017 Lance Albertson 86 | - Version bump to 0.7.0 87 | 88 | * Tue Jun 02 2015 Lance Albertson 89 | - Version bump to 0.7beta1 90 | - Vagrant+Chef development environment 91 | - Image URL support (imported from GRNET) 92 | - Support for qcow2 images 93 | - Cloud init support 94 | 95 | * Mon Jul 08 2013 Lance Albertson 96 | - Version bump to 0.6 97 | 98 | * Thu May 26 2011 Stephen Fromm 99 | - Fix dependencies and Source0 URL. 100 | - Default to %datadir for os-dir. Eliminates the arch problem with %libdir 101 | 102 | * Wed May 25 2011 Lance Albertson 103 | - Bugfix release 104 | - Ticket #4785 - blkid sometimes didn't return a value 105 | - Ticket #5685 - baselayout-2.x support for gentoo guests 106 | 107 | * Fri Apr 1 2011 Lance Albertson 108 | - Version bump to 0.5 109 | 110 | * Tue Nov 9 2010 Stephen Fromm 111 | - Fix handling of variants.list in /usr/lib/ganeti/os/ 112 | 113 | * Thu Nov 4 2010 Stephen Fromm 114 | - Initial package for version 0.4 115 | -------------------------------------------------------------------------------- /tools/make-image.in: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (C) 2012 Oregon State University 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, but 11 | # WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 | # 02110-1301, USA. 19 | 20 | set -e 21 | 22 | [ $GANETI_DEBUG ] && set -x 23 | IMAGE_DIR2= 24 | INSTANCE_NAME= 25 | IMAGE_NAME2= 26 | ARCH2= 27 | 28 | run_help() { 29 | echo "Usage: $0 -n NAME -m IMAGE_DIR -a ARCH -i INSTANCE_NAME -t TYPE" 30 | echo 31 | echo "Create an image tarball of a ganeti instance." 32 | echo 33 | echo "-t TYPE Image type, either: tarball, dump, or qemu-img" 34 | echo "-m IMAGE_DIR Path of where to put the tarball" 35 | echo "-i INSTANCE_NAME Name of the instance" 36 | echo "-n IMAGE_NAME Name of the tarball image" 37 | echo "-a ARCH Architecture of the image" 38 | echo 39 | echo "This is a helper utility for the ganeti-image script" 40 | exit 0 41 | } 42 | 43 | while getopts ":hi:a:n:m:t:" opt ; do 44 | case $opt in 45 | t) 46 | TYPE="$OPTARG" 47 | ;; 48 | m) 49 | IMAGE_DIR2="$OPTARG" 50 | ;; 51 | i) 52 | INSTANCE_NAME="$OPTARG" 53 | ;; 54 | n) 55 | IMAGE_NAME2="$OPTARG" 56 | ;; 57 | a) 58 | ARCH2="$OPTARG" 59 | ;; 60 | h) 61 | run_help 62 | ;; 63 | *) 64 | ;; 65 | esac 66 | done 67 | 68 | . @osdir@/@osname@/common.sh 69 | 70 | # Set overrides 71 | [ -n "$IMAGE_DIR2" ] && IMAGE_DIR=$IMAGE_DIR2 72 | [ -n "$IMAGE_NAME2" ] && IMAGE_NAME=$IMAGE_NAME2 73 | [ -n "$ARCH2" ] && ARCH=$ARCH2 74 | 75 | # Sanity checks 76 | [ -z "$IMAGE_DIR" ] && echo "Error: IMAGE_DIR not set" && exit 1 77 | [ -z "$TYPE" ] && echo "Error: Image type not set" && exit 1 78 | [ -z "$INSTANCE_NAME" ] && echo "Error: INSTANCE_NAME not set" && exit 1 79 | [ -z "$INSTANCE_HV_kernel_path" ] && \ 80 | echo "Error: INSTANCE_HV_kernel_path not set" && exit 1 81 | [ -z "$IMAGE_NAME" ] && echo "Error: IMAGE_NAME not set" && exit 1 82 | [ -z "$ARCH" ] && echo "Error: ARCH not set" && exit 1 83 | [ -z "$OS_VARIANT" ] && echo "Error: OS_VARIANT not set" && exit 1 84 | [ -z "$HYPERVISOR" ] && echo "Error: HYPERVISOR not set" && exit 1 85 | [ -z "$DISK_COUNT" ] && echo "Error: DISK_COUNT not set" && exit 1 86 | [ -z "$OS_API_VERSION" ] && echo "Error: OS_API_VERSION not set" && exit 1 87 | [ -z "$DISK_0_PATH" ] && echo "Error: DISK_0_PATH not set" && exit 1 88 | [ ! -d $IMAGE_DIR ] && echo "Error: $IMAGE_DIR not found" && exit 1 89 | 90 | # Setup partitions w/ kpartx 91 | filesystem_dev=$(map_disk0 $blockdev) 92 | CLEANUP+=("unmap_disk0 $blockdev") 93 | root_dev=$(map_partition $filesystem_dev root) 94 | boot_dev=$(map_partition $filesystem_dev boot) 95 | 96 | case $TYPE in 97 | tarball) 98 | # Make temp dir for mounting 99 | TARGET=`mktemp -d` || exit 1 100 | CLEANUP+=("rmdir $TARGET") 101 | 102 | # Mount filesystems 103 | mount_disk0 $TARGET 104 | 105 | OLDPWD=$PWD 106 | cd $TARGET 107 | 108 | echo "Creating tarball from $INSTANCE_NAME to ${IMAGE_DIR}/${IMAGE_NAME}-${ARCH}.tar.gz" 109 | if [ -x /usr/bin/pigz ] ; then 110 | tar -I /usr/bin/pigz --numeric-owner -cpf ${IMAGE_DIR}/${IMAGE_NAME}-${ARCH}.tar.gz . 111 | else 112 | tar --numeric-owner -zcpf ${IMAGE_DIR}/${IMAGE_NAME}-${ARCH}.tar.gz . 113 | fi 114 | ;; 115 | dump) 116 | if [ -n "$boot_dev" ] ; then 117 | echo "Creating dump from $INSTANCE_NAME for boot at ${IMAGE_DIR}/${IMAGE_NAME}-${ARCH}-boot.dump" 118 | $DUMP -0 -q -z9 -f ${IMAGE_DIR}/${IMAGE_NAME}-${ARCH}-boot.dump $boot_dev 2> /dev/null 119 | fi 120 | 121 | echo "Creating dump from $INSTANCE_NAME for root at ${IMAGE_DIR}/${IMAGE_NAME}-${ARCH}-root.dump" 122 | $DUMP -0 -q -z9 -f ${IMAGE_DIR}/${IMAGE_NAME}-${ARCH}-root.dump $root_dev 123 | ;; 124 | qemu-img) 125 | echo "Creating qemu-img image from $INSTANCE_NAME to ${IMAGE_DIR}/${IMAGE_NAME}-${ARCH}.img" 126 | $QEMU_IMG convert -O qcow2 $DISK_0_PATH ${IMAGE_DIR}/${IMAGE_NAME}-${ARCH}.img 127 | ;; 128 | *) 129 | echo "Command $TYPE not supported!" 130 | ;; 131 | esac 132 | 133 | cd $OLDPWD 134 | -------------------------------------------------------------------------------- /example/hooks/interfaces: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (C) 2010 Oregon State University 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, but 11 | # WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 | # 02110-1301, USA. 19 | # 20 | # This is an example script that configures your network settings after 21 | # installation. By default it sets it up to use dhcp. 22 | 23 | set -e 24 | 25 | . common.sh 26 | 27 | debug set -x 28 | 29 | FQDN="${INSTANCE_NAME}" 30 | SHORT_NAME="$(echo ${INSTANCE_NAME} | cut -d . -f 1)" 31 | STATIC="" 32 | 33 | if [ -z "${TARGET}" -o ! -d "${TARGET}" ] ; then 34 | log_error "Missing target directory" 35 | exit 1 36 | fi 37 | 38 | if [ -z "${NIC_COUNT}" ] ; then 39 | log_error "Missing NIC_COUNT" 40 | exit 1 41 | fi 42 | 43 | if [ -f "${NETWORKS_DIR}/instances/${FQDN}" ] ; then 44 | STATIC="yes" 45 | source ${NETWORKS_DIR}/instances/${FQDN} 46 | if [ -f "${NETWORKS_DIR}/subnets/${SUBNET}" ] ; then 47 | source ${NETWORKS_DIR}/subnets/${SUBNET} 48 | else 49 | echo "No subnet file for subnet ${SUBNET}!" 50 | exit 1 51 | fi 52 | fi 53 | 54 | resolvconf() { 55 | nl=$'\n' 56 | if [ -n "${DNS_SERVERS}" ] && [ -n "${DNS_SEARCH}" ] && [ -n "${DNS_DOMAIN}" ]; then 57 | for server in $DNS_SERVERS ; do 58 | nameservers="nameserver ${server}${nl}${nameservers}" 59 | done 60 | 61 | cat > ${TARGET}/etc/resolv.conf << EOF 62 | ${nameservers} 63 | domain ${DNS_DOMAIN} 64 | search ${DNS_SEARCH} 65 | EOF 66 | fi 67 | } 68 | 69 | # Functions 70 | debian_setup() { 71 | if [ ! -d "${TARGET}/etc/network" ] ; then 72 | log_error "Missing target network directory" 73 | exit 1 74 | fi 75 | 76 | if [ -z "${STATIC}" ] ; then 77 | cat > ${TARGET}/etc/network/interfaces << EOF 78 | # This file describes the network interfaces available on your system 79 | # and how to activate them. For more information, see interfaces(5). 80 | 81 | auto lo 82 | iface lo inet loopback 83 | 84 | auto eth0 85 | iface eth0 inet dhcp 86 | 87 | EOF 88 | else 89 | cat > ${TARGET}/etc/network/interfaces << EOF 90 | # This file describes the network interfaces available on your system 91 | # and how to activate them. For more information, see interfaces(5). 92 | 93 | auto lo 94 | iface lo inet loopback 95 | 96 | auto eth0 97 | iface eth0 inet static 98 | address ${ADDRESS} 99 | netmask ${NETMASK} 100 | gateway ${GATEWAY} 101 | EOF 102 | if [ -n "${DNS_SERVERS}" ] && [ -n "${DNS_SEARCH}" ] && [ -n "${DNS_DOMAIN}" ]; then 103 | cat >> ${TARGET}/etc/network/interfaces << EOF 104 | dns-nameservers ${DNS_SERVERS} 105 | dns-domain ${DNS_DOMAIN} 106 | dns-search ${DNS_SEARCH} 107 | 108 | EOF 109 | fi 110 | fi 111 | 112 | if [ -n "${FQDN}" ] ; then 113 | echo "${SHORT_NAME}" > ${TARGET}/etc/hostname 114 | fi 115 | } 116 | 117 | redhat_setup() { 118 | if [ ! -d "${TARGET}/etc/sysconfig/network-scripts" ] ; then 119 | log_error "Missing target network directory" 120 | exit 1 121 | fi 122 | if [ -z "${STATIC}" ] ; then 123 | cat > ${TARGET}/etc/sysconfig/network-scripts/ifcfg-eth0 << EOF 124 | DEVICE=eth0 125 | BOOTPROTO=dhcp 126 | ONBOOT=yes 127 | EOF 128 | else 129 | cat > ${TARGET}/etc/sysconfig/network-scripts/ifcfg-eth0 << EOF 130 | DEVICE=eth0 131 | BOOTPROTO=static 132 | IPADDR=${ADDRESS} 133 | NETMASK=${NETMASK} 134 | ONBOOT=yes 135 | EOF 136 | fi 137 | 138 | if [ -n "${FQDN}" ] ; then 139 | cat > ${TARGET}/etc/sysconfig/network << EOF 140 | NETWORKING=yes 141 | HOSTNAME=${FQDN} 142 | GATEWAY=${GATEWAY} 143 | EOF 144 | else 145 | cat > ${TARGET}/etc/sysconfig/network << EOF 146 | NETWORKING=yes 147 | GATEWAY=${GATEWAY} 148 | EOF 149 | fi 150 | 151 | resolvconf 152 | } 153 | 154 | gentoo_setup() { 155 | if [ ! -f "${TARGET}/etc/conf.d/net" ] ; then 156 | log_error "Missing target network file" 157 | exit 1 158 | fi 159 | if [ -z "${STATIC}" ] ; then 160 | cat > ${TARGET}/etc/conf.d/net << EOF 161 | config_eth0=( "dhcp" ) 162 | EOF 163 | else 164 | cat > ${TARGET}/etc/conf.d/net << EOF 165 | config_eth0=( "${ADDRESS} netmask ${NETMASK}" ) 166 | routes_eth0=( "default gw ${GATEWAY}" ) 167 | EOF 168 | fi 169 | 170 | resolvconf 171 | 172 | chroot ${TARGET} ln -sf /etc/init.d/net.lo /etc/init.d/net.eth0 173 | chroot ${TARGET} rc-update add net.eth0 default 174 | 175 | if [ -n "${FQDN}" ] ; then 176 | # baselayout-2.x 177 | if [ -d "${TARGET}/usr/share/openrc/" ] ; then 178 | cat > ${TARGET}/etc/conf.d/hostname << EOF 179 | hostname="${SHORT_NAME}" 180 | EOF 181 | else 182 | cat > ${TARGET}/etc/conf.d/hostname << EOF 183 | HOSTNAME="${SHORT_NAME}" 184 | EOF 185 | fi 186 | fi 187 | } 188 | 189 | suse_setup() { 190 | if [ ! -d ${TARGET}/etc/sysconfig/network ] ; then 191 | log_error "Missing target network directory" 192 | exit 1 193 | fi 194 | cat > ${TARGET}/etc/sysconfig/network/ifcfg-eth0 << EOF 195 | BOOTPROTO='dhcp4' 196 | STARTMODE='auto' 197 | NAME='Ethernet Card 0' 198 | EOF 199 | if [ -n "${FQDN}" ] ; then 200 | echo "${FQDN}" > ${TARGET}/etc/HOSTNAME 201 | fi 202 | 203 | resolvconf 204 | } 205 | 206 | # Main 207 | get_os_type $TARGET 208 | 209 | if [ "${NIC_COUNT}" -gt 0 -a -n "${OS_TYPE}" ] ; then 210 | ${OS_TYPE}_setup 211 | else 212 | log_error "Unsupported OS_TYPE" 213 | fi 214 | 215 | 216 | exit 0 217 | -------------------------------------------------------------------------------- /create: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (C) 2010, 2011, 2012 Oregon State University 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, but 11 | # WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 | # 02110-1301, USA. 19 | 20 | set -e 21 | 22 | . common.sh 23 | 24 | debug set -x 25 | 26 | case "$IMAGE_TYPE" in 27 | tarball) 28 | IMG_EXT=".tar.gz" 29 | ;; 30 | qemu) 31 | IMG_EXT=".img" 32 | ;; 33 | raw) 34 | IMG_EXT=".raw" 35 | ;; 36 | qcow2) 37 | IMG_EXT=".qcow2" 38 | ;; 39 | dump) 40 | IMG_EXT="-root.dump" 41 | ;; 42 | esac 43 | 44 | if [ ! -z "$IMAGE_URL" ] ; then 45 | cd ${CACHE_DIR} 46 | if [ ! -e ${CACHE_DIR}/${IMAGE_NAME}-${ARCH}${IMG_EXT} ]; then 47 | $CURL -O "${IMAGE_URL}/${IMAGE_NAME}-${ARCH}${IMG_EXT}" 2>/dev/null\ 48 | || (log_error "Failed to find the image on ${IMAGE_URL}"; exit 1) 49 | fi 50 | if [ "$IMAGE_VERIFY" = "yes" ]; then 51 | $CURL -O "${IMAGE_URL}/${IMAGE_NAME}-${ARCH}${IMG_EXT}.sig" 2>/dev/null\ 52 | || (log_error "Failed to find the checksum file"; exit 1) 53 | $SHA1SUM -c "${IMAGE_NAME}-${ARCH}${IMG_EXT}.sig" >/dev/null \ 54 | || (log_error "Image doesn't match checksum!"; exit 1) 55 | CLEANUP+=("rm ${CACHE_DIR}/${IMAGE_NAME}-${ARCH}${IMG_EXT}.sig") 56 | fi 57 | if [ "$IMAGE_CLEANUP" = "yes" ]; then 58 | CLEANUP+=("rm ${CACHE_DIR}/${IMAGE_NAME}-${ARCH}${IMG_EXT}") 59 | fi 60 | IMAGE_FILE="${CACHE_DIR}/${IMAGE_NAME}-${ARCH}${IMG_EXT}" 61 | cd $OLDPWD 62 | else 63 | IMAGE_FILE="${IMAGE_DIR}/${IMAGE_NAME}-${ARCH}${IMG_EXT}" 64 | fi 65 | 66 | if [ "$IMAGE_TYPE" = "dump" ] ; then 67 | # Workaround for restore's non-unique /tmp/rstdir* and /tmp/rstmode* 68 | export TMPDIR=$(mktemp -d /tmp/${INSTANCE_NAME}_XXXXXXXX) 69 | CLEANUP+=("rmdir --ignore-fail-on-non-empty $TMPDIR") 70 | fi 71 | 72 | if [ "$CDINSTALL" = "no" ] ; then 73 | # If the target device is not a real block device we'll first losetup it. 74 | # This is needed for file disks. 75 | if [ ! -b $blockdev ]; then 76 | ORIGINAL_BLOCKDEV=$blockdev 77 | blockdev=$($LOSETUP -sf $blockdev) 78 | CLEANUP+=("$LOSETUP -d $blockdev") 79 | fi 80 | 81 | DISK_SIZE="$(expr `blockdev --getsize64 $blockdev` / 1048576)" 82 | 83 | if [ "${SWAP}" = "yes" ] ; then 84 | if [ -z "$SWAP_SIZE" ] ; then 85 | log_error "SWAP_SIZE not set however SWAP is enabled" 86 | exit 1 87 | elif [ "${SWAP_SIZE}" -gt "${DISK_SIZE}" ] ; then 88 | log_error "SWAP_SIZE larger than system disk size: " 89 | log_error " ${SWAP_SIZE}MB swap > ${DISK_SIZE}MB system disk" 90 | exit 1 91 | fi 92 | fi 93 | 94 | if [ ! -f "$IMAGE_FILE" ] ; then 95 | log_error "Can't find image file: $IMAGE_FILE" 96 | exit 1 97 | fi 98 | 99 | case "$IMAGE_TYPE" in 100 | tarball|dump) 101 | # If the image is tarball based, then we need to manually create the 102 | # volumes, filesystems, etc 103 | # Create 3 partitions, /boot, swap, & / 104 | format_disk0 $blockdev 105 | ;; 106 | qemu|raw|qcow2) 107 | # need a recent version of qemu for this 108 | ${QEMU_IMG} convert ${IMAGE_FILE} -O host_device ${blockdev} > /dev/null 109 | ;; 110 | esac 111 | 112 | # deploying something like a windows image, skip the rest 113 | if [ "${NOMOUNT}" = "yes" ] ; then 114 | cleanup 115 | exit 0 116 | fi 117 | 118 | filesystem_dev=$(map_disk0 $blockdev) 119 | CLEANUP+=("unmap_disk0 $blockdev") 120 | root_dev=$(map_partition $filesystem_dev root) 121 | boot_dev=$(map_partition $filesystem_dev boot) 122 | swap_dev=$(map_partition $filesystem_dev swap) 123 | 124 | if [ "${IMAGE_TYPE}" = "tarball" -o "${IMAGE_TYPE}" = "dump" ] ; then 125 | mkfs_disk0 126 | root_uuid="$($VOL_ID $root_dev)" 127 | [ -n "$boot_dev" ] && sleep 1 && boot_uuid="$($VOL_ID $boot_dev)" 128 | [ -n "$swap_dev" ] && sleep 1 && swap_uuid="$($VOL_ID $swap_dev)" 129 | fi 130 | 131 | TARGET=`mktemp -d` || exit 1 132 | CLEANUP+=("rmdir $TARGET") 133 | 134 | # mount filesystems 135 | mount_disk0 $TARGET 136 | 137 | if [ "${IMAGE_TYPE}" = "tarball" ] ; then 138 | # unpack image 139 | tar pzxf $IMAGE_FILE -C $TARGET 140 | elif [ "${IMAGE_TYPE}" = "dump" ] ; then 141 | root_dump="${IMAGE_FILE}" 142 | ( cd ${TARGET}; restore -r -y -f ${root_dump} > /dev/null ) 143 | 144 | if [ -n "${boot_dev}" ] ; then 145 | boot_dump="${IMAGE_FILE/root.dump/boot.dump}" 146 | if [ ! -f "$boot_dump" ] ; then 147 | log_error "Can't find image file: $boot_dump" 148 | exit 1 149 | fi 150 | ( cd ${TARGET}/boot; restore -r -y -f ${boot_dump} > /dev/null ) 151 | fi 152 | fi 153 | 154 | if [ "${IMAGE_TYPE}" = "tarball" -o "${IMAGE_TYPE}" = "dump" ] ; then 155 | setup_fstab $TARGET 156 | fi 157 | 158 | if [ "${INSTANCE_HV_serial_console}" = "True" ] ; then 159 | setup_console $TARGET 160 | fi 161 | 162 | RUN_PARTS=`which run-parts` 163 | 164 | if [ -n "$RUN_PARTS" -a -n "$CUSTOMIZE_DIR" -a -d "$CUSTOMIZE_DIR" ]; then 165 | TARGET=$TARGET 166 | BLOCKDEV=$blockdev 167 | ROOT_DEV=$root_dev 168 | BOOT_DEV=$boot_dev 169 | export TARGET SUITE BLOCKDEV ROOT_DEV BOOT_DEV IMAGE_TYPE 170 | $RUN_PARTS $CUSTOMIZE_DIR 171 | fi 172 | fi 173 | 174 | # execute cleanups 175 | cleanup 176 | trap - EXIT 177 | 178 | exit 0 179 | -------------------------------------------------------------------------------- /example/hooks/grub: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (C) 2010, 2011, 2012 Oregon State University 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, but 11 | # WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 | # 02110-1301, USA. 19 | # 20 | # This is an example script that configures, grub after installation. This 21 | # script assumes that grub has been installed onto the image already and a 22 | # working grub.conf exists. This is only enabled if using the tarball image 23 | # type. 24 | 25 | set -e 26 | 27 | . common.sh 28 | 29 | debug set -x 30 | 31 | CLEANUP=( ) 32 | 33 | trap cleanup EXIT 34 | 35 | if [ -z "${TARGET}" -o ! -d "${TARGET}" ] ; then 36 | log_error "Missing target directory" 37 | exit 1 38 | fi 39 | 40 | # Set disk based on type of hypervisor 41 | disk="" 42 | if [ "${HYPERVISOR}" = "kvm" ] ; then 43 | disk="vda" 44 | else 45 | disk="xda" 46 | fi 47 | 48 | boot_dir="${TARGET}/boot/grub" 49 | 50 | setup_disk_devs() { 51 | root_part="${ROOT_DEV/*-/}" 52 | boot_part="${BOOT_DEV/*-/}" 53 | 54 | mknod ${TARGET}/dev/${disk} b $(stat -L -c "0x%t 0x%T" $BLOCKDEV) 55 | CLEANUP+=("rm -f ${TARGET}/dev/$disk") 56 | 57 | mknod ${TARGET}/dev/${disk}${root_part} b $(stat -L -c "0x%t 0x%T" $ROOT_DEV) 58 | CLEANUP+=("rm -f ${TARGET}/dev/${disk}${root_part}") 59 | 60 | if [ -n "$BOOT_DEV" ] ; then 61 | mknod ${TARGET}/dev/${disk}${boot_part} b $(stat -L -c "0x%t 0x%T" $BOOT_DEV) 62 | CLEANUP+=("rm -f ${TARGET}/dev/${disk}${boot_part}") 63 | fi 64 | 65 | # setup minimal proc environment for grub2 66 | $MKDIR_P ${TARGET}/proc/ 67 | cat > ${TARGET}/proc/mounts < ${TARGET}/proc/devices < ${TARGET}/proc/misc << EOF 80 | 60 device-mapper 81 | EOF 82 | CLEANUP+=("rm -r ${TARGET}/proc/misc") 83 | } 84 | 85 | add_devicemap() { 86 | cat > "${TARGET}/boot/grub/device.map" < /dev/null < /dev/null 140 | fi 141 | fi 142 | 143 | # setup serial console 144 | if [ "${INSTANCE_HV_serial_console}" = "True" ] ; then 145 | if [ ! -e ${TARGET}/dev/${disk} ] ; then 146 | setup_disk_devs 147 | fi 148 | if [ -e "${boot_dir}/menu.lst" ] ; then 149 | # grub 0.x 150 | sed --follow-symlinks -ie 's/^default.*/default 0\n\nserial --unit=0\nterminal --timeout=3 console serial/' \ 151 | ${boot_dir}/menu.lst 152 | sed --follow-symlinks -ie 's/\(.*kernel.*\)/\1 console=ttyS0,115200n8/g' \ 153 | ${boot_dir}/menu.lst 154 | elif [ -e "${boot_dir}/grub.cfg" -a -e "${TARGET}/etc/default/grub" ] ; then 155 | # grub 2.x 156 | add_devicemap 157 | sed -ie 's/.*GRUB_TERMINAL.*/GRUB_TERMINAL=serial/' ${TARGET}/etc/default/grub 158 | sed -ie 's/.*GRUB_CMDLINE_LINUX=\"\(.*\)\"/GRUB_CMDLINE_LINUX=\"\1 console=ttyS0,115200n8\"/' \ 159 | ${TARGET}/etc/default/grub 160 | echo "GRUB_SERIAL_COMMAND=\"serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1\"" \ 161 | >> ${TARGET}/etc/default/grub 162 | else 163 | echo "No grub bootloader found, skipping..." 164 | fi 165 | fi 166 | 167 | # execute cleanups 168 | cleanup 169 | trap - EXIT 170 | 171 | exit 0 172 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: ci 3 | 4 | "on": 5 | pull_request: 6 | push: 7 | branches: 8 | - master 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Check out code 15 | uses: actions/checkout@v4 16 | - name: Install dependencies 17 | run: | 18 | sudo apt-get update 19 | sudo apt-get -y install build-essential autoconf dump kpartx fdisk \ 20 | qemu-utils 21 | - name: Build 22 | run: | 23 | ./autogen.sh 24 | ./configure 25 | make 26 | sudo make install 27 | - name: Verify installation 28 | run: | 29 | test -d /usr/local/share/ganeti/os/image 30 | test -f /usr/local/share/ganeti/os/image/create 31 | test -f /usr/local/share/ganeti/os/image/import 32 | test -f /usr/local/share/ganeti/os/image/export 33 | 34 | # Call package build workflows 35 | rpm-build: 36 | runs-on: ubuntu-latest 37 | strategy: 38 | matrix: 39 | include: 40 | - os: 'almalinux:8' 41 | name: 'almalinux-8' 42 | - os: 'almalinux:9' 43 | name: 'almalinux-9' 44 | container: 45 | image: ${{ matrix.os }} 46 | 47 | steps: 48 | - name: Check out code 49 | uses: actions/checkout@v4 50 | 51 | - name: Install build dependencies 52 | run: | 53 | dnf install -y --allowerasing curl 54 | dnf install -y epel-release 55 | dnf install -y rpm-build rpmdevtools git autoconf automake make 56 | dnf builddep -y ganeti-instance-image.spec 57 | 58 | - name: Set up RPM build environment 59 | run: | 60 | rpmdev-setuptree 61 | 62 | - name: Generate configure script 63 | run: | 64 | ./autogen.sh 65 | 66 | - name: Configure build 67 | run: | 68 | ./configure 69 | 70 | - name: Create source tarball 71 | run: | 72 | make dist 73 | cp ganeti-instance-image-*.tar.gz ~/rpmbuild/SOURCES/ 74 | 75 | - name: Build RPM package 76 | run: | 77 | rpmbuild -ba ganeti-instance-image.spec 78 | 79 | - name: Check built packages 80 | run: | 81 | ls -la ~/rpmbuild/RPMS/noarch/ 82 | ls -la ~/rpmbuild/SRPMS/ 83 | 84 | - name: Upload RPM artifacts 85 | uses: actions/upload-artifact@v4 86 | with: 87 | name: rpm-packages-${{ matrix.name }} 88 | path: | 89 | ~/rpmbuild/RPMS/noarch/*.rpm 90 | ~/rpmbuild/SRPMS/*.rpm 91 | retention-days: 30 92 | 93 | debian-build: 94 | runs-on: ubuntu-latest 95 | strategy: 96 | matrix: 97 | include: 98 | - os: 'debian:12' 99 | name: 'debian-12' 100 | - os: 'debian:13' 101 | name: 'debian-13' 102 | - os: 'ubuntu:22.04' 103 | name: 'ubuntu-22-04' 104 | - os: 'ubuntu:24.04' 105 | name: 'ubuntu-24-04' 106 | container: 107 | image: ${{ matrix.os }} 108 | 109 | steps: 110 | - name: Check out code 111 | uses: actions/checkout@v4 112 | 113 | - name: Install build dependencies 114 | run: | 115 | apt-get update 116 | apt-get install -y build-essential devscripts debhelper \ 117 | autotools-dev automake git 118 | # Install all build dependencies from debian/control 119 | apt-get build-dep -y . 120 | 121 | - name: Generate configure script 122 | run: | 123 | ./autogen.sh 124 | 125 | - name: Configure build 126 | run: | 127 | ./configure 128 | 129 | - name: Build Debian package 130 | run: | 131 | debuild -us -uc -b 132 | 133 | - name: Check built packages 134 | run: | 135 | ls -la ../*.deb 136 | ls -la ../*.changes 137 | 138 | - name: Move built packages to workspace 139 | run: | 140 | mv -v ../*.deb . 141 | mv -v ../*.changes . 142 | 143 | - name: Upload Debian artifacts 144 | uses: actions/upload-artifact@v4 145 | with: 146 | name: debian-packages-${{ matrix.name }} 147 | path: | 148 | *.deb 149 | *.changes 150 | retention-days: 30 151 | 152 | package-test: 153 | needs: 154 | - rpm-build 155 | - debian-build 156 | strategy: 157 | matrix: 158 | include: 159 | - os: 'almalinux:8' 160 | name: 'almalinux-8' 161 | artifact: 'rpm-packages-almalinux-8' 162 | - os: 'almalinux:9' 163 | name: 'almalinux-9' 164 | artifact: 'rpm-packages-almalinux-9' 165 | - os: 'debian:12' 166 | name: 'debian-12' 167 | artifact: 'debian-packages-debian-12' 168 | - os: 'debian:13' 169 | name: 'debian-13' 170 | artifact: 'debian-packages-debian-13' 171 | - os: 'ubuntu:22.04' 172 | name: 'ubuntu-22-04' 173 | artifact: 'debian-packages-ubuntu-22-04' 174 | - os: 'ubuntu:24.04' 175 | name: 'ubuntu-24-04' 176 | artifact: 'debian-packages-ubuntu-24-04' 177 | runs-on: ubuntu-latest 178 | container: 179 | image: ${{ matrix.os }} 180 | steps: 181 | - name: Download package artifact 182 | uses: actions/download-artifact@v4 183 | with: 184 | name: ${{ matrix.artifact }} 185 | path: . 186 | - name: Install gdebi (Debian/Ubuntu only) 187 | if: startsWith(matrix.os, 'debian') || startsWith(matrix.os, 'ubuntu') 188 | run: apt-get update && apt-get install -y gdebi-core 189 | - name: Add Ganeti repo (EL only) 190 | shell: bash 191 | if: contains(matrix.os, 'almalinux') 192 | run: | 193 | cat < /etc/yum.repos.d/ganeti.repo 194 | [ganeti] 195 | name=Integ Ganeti Packages $releasever - \$basearch 196 | baseurl=https://ftp2.osuosl.org/pub/ganeti-rpm/\$releasever/\$basearch/ 197 | enabled=1 198 | gpgcheck=1 199 | gpgkey=https://ftp2.osuosl.org/pub/ganeti-rpm/RPM-GPG-KEY-integ-ganeti 200 | EOF 201 | rpm --import https://ftp2.osuosl.org/pub/ganeti-rpm/RPM-GPG-KEY-integ-ganeti 202 | - name: Install package 203 | shell: bash 204 | run: | 205 | case "${{ matrix.os }}" in 206 | debian*) 207 | gdebi -n ./*.deb 208 | ;; 209 | ubuntu*) 210 | gdebi -n ./*.deb 211 | ;; 212 | almalinux*) 213 | dnf install -y epel-release 214 | dnf install -y RPMS/noarch/*.rpm 215 | ;; 216 | esac 217 | - name: Verify installation 218 | run: 'test -d /usr/share/ganeti/os/image' 219 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | # ganeti-instance-image 2 | 3 | This is a guest OS definition for [Ganeti](http://code.google.com/p/ganeti). It 4 | will install a Linux-based image using either a tarball, filesystem dump, or a 5 | qemu-img disk image file. This definition also allows for manual creation of an 6 | instance by simply setting only the disks up and allowing you to boot via the 7 | install cd manually. The goal of this instance is to allow fast and flexible 8 | installation of instances without the need for external tools such as 9 | debootstrap. 10 | 11 | ## Installation 12 | 13 | In order to install this package from source, you need to determine what options 14 | ganeti itself has been configured with. If ganeti was built directly from 15 | source, then the only place it looks for OS definitions is `/srv/ganeti/os`, 16 | and you need to install the OS under it: 17 | 18 | ./configure --prefix=/usr --localstatedir=/var \ 19 | --sysconfdir=/etc \ 20 | --with-os-dir=/srv/ganeti/os 21 | make && make install 22 | 23 | If ganeti was installed from a package, its default OS path should already 24 | include /usr/share/ganeti/os, so you can just run: 25 | 26 | ./configure -prefix=/usr --localstatedir=/var \ 27 | --sysconfdir=/etc 28 | make && make install 29 | 30 | Note that you need to repeat this procedure on all nodes of the cluster. 31 | 32 | The actual path that ganeti has been installed with can be determined by looking 33 | for a file named `_autoconf.py` under a ganeti directory in the python modules 34 | tree (e.g. `/usr/lib/python2.4/site-packages/ganeti/_autoconf.py`). In this 35 | file, a variable named `OS_SEARCH_PATH` will list all the directories in 36 | which ganeti will look for OS definitions. 37 | 38 | ## Configuration of instance creation 39 | 40 | The kind of instance created can be customized via a settings file. This file 41 | may or may not be installed by default, as the instance creation will work 42 | without it. The creation scripts will look for it in 43 | `$sysconfdir/default/ganeti-instance-image`, so if you have run configure with 44 | the parameter `--sysconfdir=/etc`, the final filename will be 45 | `/etc/default/ganeti-instance-image`. 46 | 47 | The following settings will be examined in this file: 48 | 49 | * `CDINSTALL`: If 'yes' only setup disks for a cd based install or manual 50 | installation via other means. It will not deploy any images or 51 | create any partitions. (default: no) 52 | * `SWAP`: Create a swap partition (tarball only) (default: yes) 53 | * `SWAP_SIZE`: Manually set the default swap partition size in MB (default: size 54 | of instance memory) 55 | * `FILESYSTEM`: Set which filesystem to format the disks as. Currently only 56 | supports ext3 or ext4. (default: ext3) 57 | * `FDISK`: Select either "parted" or "sfdisk" as the fdisk program to use 58 | when creating partitions. (default: sfdisk) 59 | * `KERNEL_ARGS`: Add additional kernel boot parameters to an instance. This 60 | currently only works on booting a kernel from inside. 61 | * `IMAGE_NAME`: Name for the image to use. Generally they will have names similar 62 | to: centos-5.4, debian-5.0, etc. The naming is free form 63 | depending on what you name the file itself. 64 | * `IMAGE_TYPE`: Create instance by either using a gzipped tarball, file system 65 | dump, or an image created by qemu-img. Accepts either 'tarball', 66 | 'dump', or 'qemu'. (default: dump). 67 | * `IMAGE_DIR`: Override default location for images. 68 | (default: `$localstatedir/cache/ganeti-instance-image`) 69 | * `NOMOUNT`: Do not try to mount volume (typically used if it is not a linux 70 | partition). Accepts either 'yes' or 'no'. This option is useful 71 | for installing Windows images for example. (default: no) 72 | * `OVERLAY`: Overlay of files to be copied to the instance after OS 73 | installation. This is useful for situations where you want to 74 | copy instance specific configs such as resolv.conf. 75 | * `ARCH`: Define the architecture of the image to use. Accepts either 'x86' 76 | or 'x86_64'. 77 | * `CUSTOMIZE_DIR`: A directory containing customization script for the instance. 78 | (by default $sysconfdir/ganeti/instance-image/hooks) See 79 | "Customization of the instance" below. 80 | * `IMAGE_DEBUG`: Enable verbose output for instance scripts. Enable by either 81 | using "1" or "yes" (default: no ) 82 | 83 | Note that the settings file is important on the node that the instance is 84 | installed on, not the cluster master. This is indeed not a very good model of 85 | using this OS but currently the OS interface in ganeti is limiting. 86 | 87 | ## Creation of Deployment Images 88 | 89 | There are three types that are supported for deploying images. 90 | 91 | * tarball 92 | * dump 93 | * qemu image 94 | 95 | ### Tarball 96 | 97 | Tarball based images are quite simply a tarball of a working system. An good 98 | example use case for this is deploying a Gentoo instance using a stage4 tarball. 99 | The only requirement is that the tarball is gzipped instead of bzip2 for speed. 100 | If you wish use a kernel inside of the VM instead of externally, make sure that 101 | a working kernel, grub config are install in the tarball. Enable the 'grub' 102 | custom script to install the grub boot image during installation. 103 | 104 | ### Qemu Images 105 | 106 | NOTE: qemu images will create a partition of the exact same size as it was 107 | originally created with. So if you create a 4GB image and created a new instance 108 | of 10G it will create a partition that is only 4GB and leave the rest as "free". 109 | 110 | To create a new qemu based disk image, you will need to able the `CDINSTALL` 111 | option and install the VM using the distro's provided installation medium. It is 112 | not recommended to build images on systems outside of ganeti (such as libvirt) 113 | as we have encountered issues with systems segfaulting. 114 | 115 | Once the instance has been created, boot the instance and point it to the 116 | install medium: 117 | 118 | gnt-instance start -H cdrom_image_path=path/to/iso/ubuntu-9.10.iso, \ 119 | boot_order=cdrom instance-name 120 | 121 | Once the base image has been installed, ensure you have the acpid package 122 | installed so that ganeti can shutdown the VM properly. Once you are happy with 123 | your base image, shutdown the VM, activate the disks, and create the disk 124 | image using qemu-img. Its recommended you use qcow2 with compression to reduce 125 | the amount of disk space used: 126 | 127 | # activate disks 128 | gnt-instance activate-disks instance-name 129 | # create image 130 | qemu-img convert -c -f host_device /dev/drbd1 \ 131 | -O qcow2 $IMAGE_DIR/ubuntu-9.10-x86_64.img 132 | 133 | Note: Older versions of qemu-img may not support the `host_device` format so 134 | use `raw` instead which should work in theory. 135 | 136 | ### Dump 137 | 138 | The last, and most efficient type of disk image is creating filesystem dumps 139 | using the dump command. The advantage with using dumps is that its much faster 140 | to deploy using it, and it also has built-in compression. The disadvantage is 141 | that you need to install grub manually which might be an issue on some operating 142 | systems. We currently fully support grub 1 and have partial support with grub2. 143 | After the new instance has booted, you will need to run `update-grub` and reboot 144 | the VM to get the new settings. We currently cannot run `update-grub` during the 145 | install because of an upstream grub2 issue. 146 | 147 | You will need to create images for both the boot and root partition (if you 148 | include a boot partition). 149 | 150 | Create a base image for an instance just like its described in Qemu Images. Make 151 | sure the instance is shutdown and then issue the following commands (assuming 152 | the activated disk is drbd1):: 153 | 154 | dump -0 -q -z9 -f ${IMAGE_DIR}/${IMAGE_NAME}-${ARCH}-boot.dump \ 155 | /dev/mapper/drbdq-1 156 | 157 | dump -0 -q -z9 -f ${IMAGE_DIR}/${IMAGE_NAME}-${ARCH}-root.dump \ 158 | /dev/mapper/drbdq-3 159 | 160 | ### Partition Layout 161 | 162 | Currently the partition layout is locked into a specific way in order to make it 163 | work more elegantly with ganeti. We might change this to be more flexible in the 164 | future, however you *must* use the following layout otherwise ganeti will not 165 | install the VM correctly. Currently the following partition layout is assumed: 166 | 167 | With swap: 168 | /dev/$disk1 /boot 169 | /dev/$disk2 swap 170 | /dev/$disk3 / 171 | 172 | Without swap: 173 | /dev/$disk1 /boot 174 | /dev/$disk2 / 175 | 176 | NOTE: If you have `kernel_path` set, /boot will not be created and all partition 177 | numbers will go up by one. For example: 178 | 179 | With swap: 180 | /dev/$disk1 swap 181 | /dev/$disk2 / 182 | 183 | Without swap: 184 | /dev/$disk1 / 185 | 186 | ### Image Naming 187 | 188 | The naming convention that is used is the following: 189 | 190 | * tarball: `$IMAGE_NAME-$ARCH.tar.gz` 191 | * dump: `$IMAGE_NAME-$ARCH-boot.dump` `$IMAGE_NAME-$ARCH-root.dump` 192 | * qemu-img: `$IMAGE_NAME-$ARCH.img` 193 | 194 | ### Useful Scripts 195 | 196 | There are a set of useful scripts located in /usr/share/ganeti/os/image/tools 197 | that you are welcome to use. These scripts are all intended to be run on the 198 | master node:: 199 | 200 | mount-disks $instance_name 201 | umount-disks $instance_name 202 | 203 | This will mount or umount an instance to `/tmp/${instance_name}_root` 204 | 205 | A utility script named `ganeti-image` will enable you to quickly create an image 206 | of the operating system from the master node. It will execute a script on the 207 | remote host if the instance resides on a remote host. Below is the help output. 208 | 209 | ganeti-image [-d PATH] [-n NAME] [-a ARCH] -t TYPE -i INSTANCE 210 | 211 | Create an image of a ganeti instance using either a tarball, dump, or qemu 212 | image.. 213 | 214 | -t TYPE Type of image, either: tarball, dump, or qemu-img 215 | -d PATH Path of where to put the image 216 | -i INSTANCE Name of the instance 217 | -n NAME Name of the image 218 | -a ARCH Architecture of the image 219 | 220 | This utility must be used on the master node. All optional args will 221 | have defaults if you do not set them. 222 | 223 | The previous image scripts are now deprecated and will be removed in a future 224 | release. 225 | 226 | ## Customization of the instance 227 | 228 | If run-parts is in the os create script, and the `CUSTOMIZE_DIR` (by default 229 | $sysconfdir/ganeti/instance-image/hooks, /etc/ganeti/instance-image/hooks if you 230 | configured the os with --sysconfdir=/etc) directory exists any executable whose 231 | name matches the run-parts execution rules (quoting run-parts(8): the names must 232 | consist entirely of upper and lower case letters, digits, underscores, and 233 | hyphens) is executed to allow further personalization of the installation. The 234 | following environment variables are passed, in addition to the ones ganeti 235 | passes to the OS scripts: 236 | 237 | TARGET: directory in which the filesystem is mounted 238 | BLOCKDEV: ganeti block device 239 | ROOT_DEV: device in which the root (/) filesystem resides (the one mounted 240 | in TARGET) 241 | BOOT_DEV: device in which the boot (/boot) filesystem resides 242 | IMAGE_TYPE: type of image being used (tarball, qemu, dump) 243 | 244 | The scripts in `CUSTOMIZE_DIR` can exit with an error code to signal an error in 245 | the instance creation, should they fail. 246 | 247 | The scripts in `CUSTOMIZE_DIR` should not start any long-term processes or 248 | daemons using this directory, otherwise the installation will fail because it 249 | won't be able to umount the filesystem from the directory, and hand the instance 250 | back to Ganeti. 251 | 252 | ### Included Custom Scripts 253 | 254 | This OS definition includes three optional customization scripts that are 255 | disabled by default. They are not required but are useful. 256 | 257 | ### Grub 258 | 259 | When enabled, this can setup three things: 260 | 261 | - Install grub into the MBR 262 | - Setup serial access to grub 263 | - Add optional kernel boot parameters 264 | 265 | In general, the MBR will only be installed if you're not using a qemu image 266 | type, or the `kernel_path` parameter is empty or initiating an import. There is 267 | currently partial support for install a grub2 MBR (which Ubuntu Karmic and newer 268 | requires). 269 | 270 | If `serial_console` is `True` then this script will try to enable serial support 271 | for grub. 272 | 273 | ### Interfaces 274 | 275 | When enabled, it would try to setup networking for eth0 and enable DHCP. It 276 | assumes you already have a DHCP client installed on the guest OS. This currently 277 | supports the following operating systems: 278 | 279 | - Redhat (CentOS/Fedora) 280 | - Debian/Ubuntu 281 | - Gentoo 282 | - OpenSUSE 283 | 284 | If you need to set a static ip for instances, you can do that by creating 285 | several files in a manner described below. 286 | 287 | Subnets: 288 | 289 | Create a file in `/etc/ganeti/instance-image/networks/subnets` that has a useful 290 | name such as `vlan42`. This file will describe subnet routing information such 291 | as the netmask, gateway, and dns. The following is an example: 292 | 293 | NETMASK="255.255.255.0" 294 | GATEWAY="192.168.1.1" 295 | DNS_DOMAIN="example.org" 296 | DNS_SEARCH="example.org example.net" 297 | DNS_SERVERS="8.8.8.8 4.4.4.4" 298 | 299 | Instance: 300 | 301 | Create a file in `/etc/ganeti/instance-image/networks/instances` and name it the 302 | FQDN of the instance. The file will describe the IP address for the instance and 303 | which subnet it resides on. For example, we could create a file named 304 | `myinstance.osuosl.org` and have the following in it: 305 | 306 | ADDRESS=192.168.1.100 307 | SUBNET=vlan42 308 | 309 | ### SSH 310 | 311 | When enabled, it will clear out any generated ssh keys that the image may have 312 | so that each instance have *unique* host keys. Currently its disabled for 313 | Debian/Ubuntu since the keys won't be regenerated via the init script. We plan 314 | to fix this manually at some point in the future. 315 | 316 | ### Overlays 317 | 318 | When enabled it will copy a directory of files recursively into the instance. 319 | This is quite useful for site specific configurations such as resolv.conf. 320 | Create a directory in `/etc/ganeit/instance-image/overlays/` and copy files as 321 | needed into it. Treat the directory as the root of the filesystem. Set `OVERLAY` 322 | for the variant as the name of the directory. This directory needs to exist on 323 | all nodes in order to work. 324 | 325 | vi: set tw=80 ft=markdown : 326 | -------------------------------------------------------------------------------- /example/config/preseed/debian-5.04-x86_64-ganeti.cfg: -------------------------------------------------------------------------------- 1 | #### Contents of the preconfiguration file (for lenny) 2 | ### Localization 3 | # Locale sets language and country. 4 | d-i debian-installer/locale string en_US.UTF-8 5 | 6 | # Keyboard selection. 7 | #d-i console-tools/archs select at 8 | d-i console-keymaps-at/keymap select us 9 | # Example for a different keyboard architecture 10 | #d-i console-keymaps-usb/keymap select mac-usb-us 11 | 12 | ### Network configuration 13 | # netcfg will choose an interface that has link if possible. This makes it 14 | # skip displaying a list if there is more than one interface. 15 | d-i netcfg/choose_interface select auto 16 | 17 | # To pick a particular interface instead: 18 | #d-i netcfg/choose_interface select eth1 19 | 20 | # If you have a slow dhcp server and the installer times out waiting for 21 | # it, this might be useful. 22 | #d-i netcfg/dhcp_timeout string 60 23 | 24 | # If you prefer to configure the network manually, uncomment this line and 25 | # the static network configuration below. 26 | #d-i netcfg/disable_dhcp boolean true 27 | 28 | # If you want the preconfiguration file to work on systems both with and 29 | # without a dhcp server, uncomment these lines and the static network 30 | # configuration below. 31 | #d-i netcfg/dhcp_failed note 32 | #d-i netcfg/dhcp_options select Configure network manually 33 | 34 | # Static network configuration. 35 | #d-i netcfg/get_nameservers string 192.168.1.1 36 | #d-i netcfg/get_ipaddress string 192.168.1.42 37 | #d-i netcfg/get_netmask string 255.255.255.0 38 | #d-i netcfg/get_gateway string 192.168.1.1 39 | #d-i netcfg/confirm_static boolean true 40 | 41 | # Any hostname and domain names assigned from dhcp take precedence over 42 | # values set here. However, setting the values still prevents the questions 43 | # from being shown, even if values come from dhcp. 44 | d-i netcfg/get_hostname string gimager 45 | d-i netcfg/get_domain string example.com 46 | 47 | # Disable that annoying WEP key dialog. 48 | d-i netcfg/wireless_wep string 49 | # The wacky dhcp hostname that some ISPs use as a password of sorts. 50 | #d-i netcfg/dhcp_hostname string radish 51 | 52 | # If non-free firmware is needed for the network or other hardware, you can 53 | # configure the installer to always try to load it, without prompting. Or 54 | # change to false to disable asking. 55 | #d-i hw-detect/load_firmware boolean true 56 | 57 | ### Network console 58 | # Use the following settings if you wish to make use of the network-console 59 | # component for remote installation over SSH. This only makes sense if you 60 | # intend to perform the remainder of the installation manually. 61 | #d-i anna/choose_modules string network-console 62 | #d-i network-console/password password r00tme 63 | #d-i network-console/password-again password r00tme 64 | 65 | ### Mirror settings 66 | # If you select ftp, the mirror/country string does not need to be set. 67 | #d-i mirror/protocol string ftp 68 | d-i mirror/country string manual 69 | d-i mirror/http/hostname string debian.osuosl.org 70 | d-i mirror/http/directory string /debian 71 | d-i mirror/http/proxy string 72 | 73 | # Suite to install. 74 | #d-i mirror/suite string testing 75 | # Suite to use for loading installer components (optional). 76 | #d-i mirror/udeb/suite string testing 77 | 78 | ### Clock and time zone setup 79 | # Controls whether or not the hardware clock is set to UTC. 80 | d-i clock-setup/utc boolean true 81 | 82 | # You may set this to any valid setting for $TZ; see the contents of 83 | # /usr/share/zoneinfo/ for valid values. 84 | d-i time/zone string UTC 85 | 86 | # Controls whether to use NTP to set the clock during the install 87 | d-i clock-setup/ntp boolean true 88 | # NTP server to use. The default is almost always fine here. 89 | d-i clock-setup/ntp-server string pool.ntp.org 90 | 91 | ### Partitioning 92 | # If the system has free space you can choose to only partition that space. 93 | #d-i partman-auto/init_automatically_partition select biggest_free 94 | 95 | # Alternatively, you can specify a disk to partition. The device name must 96 | # be given in traditional non-devfs format. 97 | # Note: A disk must be specified, unless the system has only one disk. 98 | # For example, to use the first SCSI/SATA hard disk: 99 | d-i partman-auto/disk string /dev/vda 100 | # In addition, you'll need to specify the method to use. 101 | # The presently available methods are: "regular", "lvm" and "crypto" 102 | d-i partman-auto/method string regular 103 | 104 | # If one of the disks that are going to be automatically partitioned 105 | # contains an old LVM configuration, the user will normally receive a 106 | # warning. This can be preseeded away... 107 | d-i partman-lvm/device_remove_lvm boolean true 108 | # The same applies to pre-existing software RAID array: 109 | d-i partman-md/device_remove_md boolean true 110 | # And the same goes for the confirmation to write the lvm partitions. 111 | d-i partman-lvm/confirm boolean true 112 | 113 | # You can choose one of the three predefined partitioning recipes: 114 | # - atomic: all files in one partition 115 | # - home: separate /home partition 116 | # - multi: separate /home, /usr, /var, and /tmp partitions 117 | #d-i partman-auto/choose_recipe select boot-root 118 | 119 | # Or provide a recipe of your own... 120 | # The recipe format is documented in the file devel/partman-auto-recipe.txt. 121 | # If you have a way to get a recipe file into the d-i environment, you can 122 | # just point at it. 123 | #d-i partman-auto/expert_recipe_file string /hd-media/recipe 124 | 125 | # If not, you can put an entire recipe into the preconfiguration file in one 126 | # (logical) line. This example creates a small /boot partition, suitable 127 | # swap, and uses the rest of the space for the root partition: 128 | #d-i partman-auto/expert_recipe string \ 129 | # boot-root :: \ 130 | d-i partman-auto/expert_recipe string boot-root :: \ 131 | 200 210 220 ext3 \ 132 | $primary{ } $bootable{ } \ 133 | method{ format } format{ } \ 134 | use_filesystem{ } filesystem{ ext3 } \ 135 | mountpoint{ /boot } \ 136 | . \ 137 | 64 512 1024 linux-swap \ 138 | $primary{ } \ 139 | method{ swap } format{ } \ 140 | . \ 141 | 2500 3000 -1 ext3 \ 142 | $primary{ } \ 143 | method{ format } format{ } \ 144 | use_filesystem{ } filesystem{ ext3 } \ 145 | mountpoint{ / } \ 146 | . \ 147 | 148 | # This makes partman automatically partition without confirmation, provided 149 | # that you told it what to do using one of the methods above. 150 | d-i partman/confirm_write_new_label boolean true 151 | d-i partman/choose_partition select finish 152 | d-i partman/confirm boolean true 153 | 154 | ### Base system installation 155 | # Select the initramfs generator used to generate the initrd for 2.6 kernels. 156 | #d-i base-installer/kernel/linux/initramfs-generators string yaird 157 | 158 | # The kernel image (meta) package to be installed; "none" can be used if no 159 | # kernel is to be installed. 160 | d-i base-installer/kernel/image string linux-image-amd64 161 | 162 | ### Account setup 163 | # Skip creation of a root account (normal user account will be able to 164 | # use sudo). 165 | #d-i passwd/root-login boolean false 166 | # Alternatively, to skip creation of a normal user account. 167 | d-i passwd/make-user boolean true 168 | 169 | # Root password, either in clear text 170 | #d-i passwd/root-password password changeme 171 | #d-i passwd/root-password-again password changeme 172 | # or encrypted using an MD5 hash. 173 | #d-i passwd/root-password-crypted password changeme 174 | 175 | # To create a normal user account. 176 | #d-i passwd/user-fullname string John Doe 177 | #d-i passwd/username string jdoe 178 | # Normal user's password, either in clear text 179 | #d-i passwd/user-password password insecure 180 | #d-i passwd/user-password-again password insecure 181 | # or encrypted using an MD5 hash. 182 | #d-i passwd/user-password-crypted password changeme 183 | # Create the first user with the specified UID instead of the default. 184 | #d-i passwd/user-uid string 1010 185 | 186 | # The user account will be added to some standard initial groups. To 187 | # override that, use this. 188 | #d-i passwd/user-default-groups string audio cdrom video 189 | 190 | ### Apt setup 191 | # You can choose to install non-free and contrib software. 192 | d-i apt-setup/non-free boolean true 193 | d-i apt-setup/contrib boolean true 194 | # Uncomment this if you don't want to use a network mirror. 195 | #d-i apt-setup/use_mirror boolean false 196 | # Select which update services to use; define the mirrors to be used. 197 | # Values shown below are the normal defaults. 198 | #d-i apt-setup/services-select multiselect security, volatile 199 | #d-i apt-setup/security_host string security.debian.org 200 | #d-i apt-setup/volatile_host string volatile.debian.org 201 | 202 | # Additional repositories, local[0-9] available 203 | #d-i apt-setup/local0/repository string \ 204 | # http://local.server/debian stable main 205 | #d-i apt-setup/local0/comment string local server 206 | # Enable deb-src lines 207 | #d-i apt-setup/local0/source boolean true 208 | # URL to the public key of the local repository; you must provide a key or 209 | # apt will complain about the unauthenticated repository and so the 210 | # sources.list line will be left commented out 211 | #d-i apt-setup/local0/key string http://local.server/key 212 | 213 | # By default the installer requires that repositories be authenticated 214 | # using a known gpg key. This setting can be used to disable that 215 | # authentication. Warning: Insecure, not recommended. 216 | #d-i debian-installer/allow_unauthenticated string true 217 | 218 | ### Package selection 219 | tasksel tasksel/first multiselect Standard system 220 | # If the desktop task is selected, install the kde and xfce desktops 221 | # instead of the default gnome desktop. 222 | #tasksel tasksel/desktop multiselect kde, xfce 223 | 224 | # Individual additional packages to install 225 | d-i pkgsel/include string openssh-server denyhosts rsync vim sudo 226 | # Whether to upgrade packages after debootstrap. 227 | # Allowed values: none, safe-upgrade, full-upgrade 228 | d-i pkgsel/upgrade select safe-upgrade 229 | 230 | # Some versions of the installer can report back on what software you have 231 | # installed, and what software you use. The default is not to report back, 232 | # but sending reports helps the project determine what software is most 233 | # popular and include it on CDs. 234 | popularity-contest popularity-contest/participate boolean false 235 | 236 | ### Boot loader installation 237 | # Grub is the default boot loader (for x86). If you want lilo installed 238 | # instead, uncomment this: 239 | #d-i grub-installer/skip boolean true 240 | # To also skip installing lilo, and install no bootloader, uncomment this 241 | # too: 242 | #d-i lilo-installer/skip boolean true 243 | 244 | # This is fairly safe to set, it makes grub install automatically to the MBR 245 | # if no other operating system is detected on the machine. 246 | d-i grub-installer/only_debian boolean true 247 | 248 | # This one makes grub-installer install to the MBR if it also finds some other 249 | # OS, which is less safe as it might not be able to boot that other OS. 250 | d-i grub-installer/with_other_os boolean true 251 | 252 | # Alternatively, if you want to install to a location other than the mbr, 253 | # uncomment and edit these lines: 254 | #d-i grub-installer/only_debian boolean false 255 | #d-i grub-installer/with_other_os boolean false 256 | #d-i grub-installer/bootdev string (hd0,0) 257 | # To install grub to multiple disks: 258 | #d-i grub-installer/bootdev string (hd0,0) (hd1,0) (hd2,0) 259 | 260 | # Optional password for grub, either in clear text 261 | #d-i grub-installer/password password r00tme 262 | #d-i grub-installer/password-again password r00tme 263 | # or encrypted using an MD5 hash, see grub-md5-crypt(8). 264 | #d-i grub-installer/password-crypted password [MD5 hash] 265 | 266 | ### Finishing up the installation 267 | # During installations from serial console, the regular virtual consoles 268 | # (VT1-VT6) are normally disabled in /etc/inittab. Uncomment the next 269 | # line to prevent this. 270 | #d-i finish-install/keep-consoles boolean true 271 | 272 | # Avoid that last message about the install being complete. 273 | d-i finish-install/reboot_in_progress note 274 | 275 | # This will prevent the installer from ejecting the CD during the reboot, 276 | # which is useful in some situations. 277 | #d-i cdrom-detect/eject boolean false 278 | 279 | # This is how to make the installer shutdown when finished, but not 280 | # reboot into the installed system. 281 | d-i debian-installer/exit/halt boolean true 282 | # This will power off the machine instead of just halting it. 283 | #d-i debian-installer/exit/poweroff boolean true 284 | 285 | ## postfix preseeding 286 | # General type of configuration? Default:Internet Site 287 | # Choices: No configuration, Internet Site, Internet with smarthost, 288 | # Satellite system, Local only 289 | #postfix postfix/main_mailer_type select Internet with smarthost 290 | # Where should mail for root go, Default:if not set, will spool locally 291 | #postfix postfix/root_address string foo@bar.com 292 | # SMTP relay host? (blank for none) Default:(none) 293 | #postfix postfix/relayhost string smtp.example.com 294 | # Force synchronous updates on mail queue? Default:false 295 | #postfix postfix/chattr boolean true 296 | # Local networks? Default:"127.0.0.0/8" 297 | # blank uses the postfix default (which is based on the connected subnets) 298 | #postfix postfix/mynetworks string 299 | # Use procmail for local delivery? Defaults to true if /usr/bin/procmail exists 300 | #postfix postfix/procmail boolean false 301 | # Mailbox size limit Default:0 (unlimited), upstream default is 51200000 302 | postfix postfix/mailbox_limit string 51200000 303 | # Local address extension character? Default:+ 304 | #postfix postfix/recipient_delim string - 305 | # Internet protocols to use? Default is based on checking if 306 | # /proc/sys/net/ipv{4,6} exist 307 | # Choices: all, ipv6, ipv4 308 | postfix postfix/protocols select ipv4 309 | 310 | ### Preseeding other packages 311 | # Depending on what software you choose to install, or if things go wrong 312 | # during the installation process, it's possible that other questions may 313 | # be asked. You can preseed those too, of course. To get a list of every 314 | # possible question that could be asked during an install, do an 315 | # installation, and then run these commands: 316 | # debconf-get-selections --installer > file 317 | # debconf-get-selections >> file 318 | 319 | 320 | #### Advanced options 321 | ### Running custom commands during the installation 322 | # d-i preseeding is inherently not secure. Nothing in the installer checks 323 | # for attempts at buffer overflows or other exploits of the values of a 324 | # preconfiguration file like this one. Only use preconfiguration files from 325 | # trusted locations! To drive that home, and because it's generally useful, 326 | # here's a way to run any shell command you'd like inside the installer, 327 | # automatically. 328 | 329 | # This first command is run as early as possible, just after 330 | # preseeding is read. 331 | #d-i preseed/early_command string anna-install some-udeb 332 | 333 | # This command is run just before the install finishes, but when there is 334 | # still a usable /target directory. You can chroot to /target and use it 335 | # directly, or use the apt-install and in-target commands to easily install 336 | # packages and run commands in the target system. 337 | #d-i preseed/late_command string apt-install zsh; in-target chsh -s /bin/zsh 338 | d-i preseed/late_command string \ 339 | wget http://packages.example.com/preseed/scripts/standard.sh ; \ 340 | chmod +x standard.sh ; \ 341 | mv standard.sh /target/ ; \ 342 | chroot /target /standard.sh ; \ 343 | in-target aptitude -y clean ; \ 344 | rm /target/standard.sh ; 345 | -------------------------------------------------------------------------------- /common.sh.in: -------------------------------------------------------------------------------- 1 | # 2 | 3 | # Copyright (C) 2007, 2008, 2009 Google Inc. 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, but 11 | # WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 | # 02110-1301, USA. 19 | 20 | AWK="@AWK@" 21 | DUMP="@DUMP@" 22 | LOSETUP="@LOSETUP@" 23 | KPARTX="@KPARTX@" 24 | SFDISK="@SFDISK@" 25 | PARTED="@PARTED@" 26 | QEMU_IMG="@QEMU_IMG@" 27 | MKDIR_P="@MKDIR_P@" 28 | INSTANCE_MEM= 29 | CURL="@CURL@" 30 | SHA1SUM="@SHA1SUM@" 31 | 32 | CLEANUP=( ) 33 | 34 | log_error() { 35 | echo "$@" >&2 36 | } 37 | 38 | debug() { 39 | [ "$IMAGE_DEBUG" == "1" -o "$IMAGE_DEBUG" == "yes" ] && $@ || : 40 | } 41 | 42 | get_api5_arguments() { 43 | GETOPT_RESULT=$* 44 | # Note the quotes around `$TEMP': they are essential! 45 | eval set -- "$GETOPT_RESULT" 46 | while true; do 47 | case "$1" in 48 | -i|-n) instance=$2; shift 2;; 49 | 50 | -o) old_name=$2; shift 2;; 51 | 52 | -b) blockdev=$2; shift 2;; 53 | 54 | -s) swapdev=$2; shift 2;; 55 | 56 | --) shift; break;; 57 | 58 | *) log_error "Internal error!" >&2; exit 1;; 59 | esac 60 | done 61 | if [ -z "$instance" -o -z "$blockdev" ]; then 62 | log_error "Missing OS API Argument (-i, -n, or -b)" 63 | exit 1 64 | fi 65 | if [ "$SCRIPT_NAME" != "export" -a -z "$swapdev" ]; then 66 | log_error "Missing OS API Argument -s (swapdev)" 67 | exit 1 68 | fi 69 | if [ "$SCRIPT_NAME" = "rename" -a -z "$old_name" ]; then 70 | log_error "Missing OS API Argument -o (old_name)" 71 | exit 1 72 | fi 73 | } 74 | 75 | get_api10_arguments() { 76 | if [ -z "$INSTANCE_NAME" -o -z "$HYPERVISOR" -o -z "$DISK_COUNT" ]; then 77 | log_error "Missing OS API Variable:" 78 | log_error "(INSTANCE_NAME HYPERVISOR or DISK_COUNT)" 79 | exit 1 80 | fi 81 | instance=$INSTANCE_NAME 82 | if [ $DISK_COUNT -lt 1 -o -z "$DISK_0_PATH" ]; then 83 | log_error "At least one disk is needed" 84 | exit 1 85 | fi 86 | if [ "$SCRIPT_NAME" = "export" ]; then 87 | if [ -z "$EXPORT_DEVICE" ]; then 88 | log_error "Missing OS API Variable EXPORT_DEVICE" 89 | fi 90 | blockdev=$EXPORT_DEVICE 91 | elif [ "$SCRIPT_NAME" = "import" ]; then 92 | if [ -z "$IMPORT_DEVICE" ]; then 93 | log_error "Missing OS API Variable IMPORT_DEVICE" 94 | fi 95 | blockdev=$IMPORT_DEVICE 96 | else 97 | blockdev=$DISK_0_PATH 98 | fi 99 | if [ "$SCRIPT_NAME" = "rename" -a -z "$OLD_INSTANCE_NAME" ]; then 100 | log_error "Missing OS API Variable OLD_INSTANCE_NAME" 101 | fi 102 | old_name=$OLD_INSTANCE_NAME 103 | } 104 | 105 | get_os_type() { 106 | target=$1 107 | if [ -z "${target}" ] ; then 108 | log_error "target is not set in get_os_type" 109 | exit 1 110 | fi 111 | if [ -e ${target}/etc/redhat-release ] ; then 112 | OS_TYPE="redhat" 113 | elif [ -e ${target}/etc/debian_version ] ; then 114 | OS_TYPE="debian" 115 | elif [ -e ${target}/etc/gentoo-release ] ; then 116 | OS_TYPE="gentoo" 117 | elif [ -e ${target}/etc/SuSE-release ] ; then 118 | OS_TYPE="suse" 119 | fi 120 | } 121 | 122 | get_os() { 123 | target=$1 124 | if [ -z "${target}" ] ; then 125 | log_error "target is not set in get_os" 126 | exit 1 127 | fi 128 | lsb="/usr/bin/lsb_release" 129 | if [ -e ${target}/$lsb ] ; then 130 | OPERATING_SYSTEM="$(chroot ${target} ${lsb} -i -s | tr "[:upper:]" "[:lower:]")" 131 | elif [ -e ${target}/etc/debian_version ] ; then 132 | OPERATING_SYSTEM="debian" 133 | elif [ -e ${target}/etc/gentoo-release ] ; then 134 | OPERATING_SYSTEM="gentoo" 135 | elif [ -e ${target}/etc/fedora-release ] ; then 136 | OPERATING_SYSTEM="fedora" 137 | elif [ -e ${target}/etc/redhat-release ] ; then 138 | if [ -n "$(grep -i centos ${target}/etc/redhat-release)" ] ; then 139 | OPERATING_SYSTEM="centos" 140 | else 141 | OPERATING_SYSTEM="redhat" 142 | fi 143 | fi 144 | } 145 | 146 | get_os_release() { 147 | target=$1 148 | if [ -z "${target}" ] ; then 149 | log_error "target is not set in get_os_release" 150 | exit 1 151 | fi 152 | lsb="/usr/bin/lsb_release" 153 | if [ -e ${target}/lsb ] ; then 154 | OS_RELEASE="$(chroot ${target} ${lsb} -r -s | tr "[:upper:]" "[:lower:]")" 155 | elif [ -e ${target}/etc/debian_version ] ; then 156 | OS_RELEASE="$(cat ${target}/etc/debian_version)" 157 | elif [ -e ${target}/etc/fedora-release ] ; then 158 | OS_RELEASE="$(cat ${target}/etc/fedora-release | awk '{print $3}')" 159 | elif [ -e ${$target}/etc/redhat-release ] ; then 160 | OS_RELEASE="$(cat ${target}/etc/redhat-release | awk '{print $3}')" 161 | fi 162 | } 163 | 164 | format_disk0() { 165 | if [ "${FDISK}" = "parted" ]; then 166 | format_disk0_parted "$1" 167 | elif [ "${FDISK}" = "sfdisk" ]; then 168 | format_disk0_sfdisk "$1" 169 | fi 170 | } 171 | 172 | format_disk0_sfdisk() { 173 | local sfdisk_cmd="$SFDISK -uM -H 255 -S 63 --quiet --Linux --DOS $1" 174 | if [ "${SWAP}" = "yes" -a -z "${KERNEL_PATH}" ] ; then 175 | # Create three partitions: 176 | # 1 - $BOOT_SIZE /boot, bootable 177 | # 2 - Size of Memory, swap 178 | # 3 - Rest 179 | $sfdisk_cmd > /dev/null < /dev/null < /dev/null < /dev/null < /dev/null 255 | # Format /boot 256 | if [ -n "${boot_dev}" ] ; then 257 | $mkfs $mkfs_opts -L /boot $boot_dev > /dev/null 258 | fi 259 | # Format swap 260 | if [ -n "${swap_dev}" ] ; then 261 | # Format swap 262 | mkswap -f $swap_dev > /dev/null 263 | fi 264 | # During reinstalls, ext4 needs a little time after a mkfs so add it here 265 | # and also run a sync to be sure. 266 | sync 267 | sleep 2 268 | } 269 | 270 | mount_disk0() { 271 | local target=$1 272 | mount $root_dev $target 273 | CLEANUP+=("umount $target") 274 | if [ -n "${boot_dev}" ] ; then 275 | $MKDIR_P $target/boot 276 | mount $boot_dev $target/boot 277 | CLEANUP+=("umount $target/boot") 278 | fi 279 | # sync the file systems before unmounting to ensure everything is flushed 280 | # out 281 | CLEANUP+=("sync") 282 | } 283 | 284 | map_disk0() { 285 | blockdev="$1" 286 | filesystem_dev_base=`$KPARTX -l -p- $blockdev | \ 287 | grep -m 1 -- "-1.*$blockdev" | \ 288 | $AWK '{print $1}'` 289 | if [ -z "$filesystem_dev_base" ]; then 290 | log_error "Cannot interpret kpartx output and get partition mapping" 291 | exit 1 292 | fi 293 | $KPARTX -a -p- $blockdev > /dev/null 294 | filesystem_dev="/dev/mapper/${filesystem_dev_base/%-1/}" 295 | if [ ! -b "/dev/mapper/$filesystem_dev_base" ]; then 296 | log_error "Can't find kpartx mapped partition: /dev/mapper/$filesystem_dev_base" 297 | exit 1 298 | fi 299 | echo "$filesystem_dev" 300 | } 301 | 302 | map_partition() { 303 | filesystem_dev="$1" 304 | partition="$2" 305 | if [ "${SWAP}" = "yes" -a -z "${KERNEL_PATH}" ] ; then 306 | boot_dev="${filesystem_dev}-1" 307 | swap_dev="${filesystem_dev}-2" 308 | root_dev="${filesystem_dev}-3" 309 | elif [ "${SWAP}" = "no" -a -z "${KERNEL_PATH}" ] ; then 310 | boot_dev="${filesystem_dev}-1" 311 | root_dev="${filesystem_dev}-2" 312 | elif [ "${SWAP}" = "yes" -a -n "${KERNEL_PATH}" ] ; then 313 | swap_dev="${filesystem_dev}-1" 314 | root_dev="${filesystem_dev}-2" 315 | elif [ "${SWAP}" = "no" -a -n "${KERNEL_PATH}" ] ; then 316 | root_dev="${filesystem_dev}-1" 317 | fi 318 | echo "$(eval "echo \${$(echo ${partition}_dev)"})" 319 | } 320 | 321 | unmap_disk0() { 322 | $KPARTX -d -p- $1 323 | } 324 | 325 | setup_fstab() { 326 | local target=$1 fs=${FILESYSTEM} 327 | get_os_type $target 328 | cat > $target/etc/fstab < 332 | UUID=$root_uuid / $fs defaults 0 1 333 | proc /proc proc defaults 0 0 334 | EOF 335 | 336 | if [ -n "$boot_dev" -a -n "$boot_uuid" ] ; then 337 | cat >> $target/etc/fstab <> $target/etc/fstab <> $target/etc/fstab <> $target/etc/fstab < ${target}/etc/event.d/ttyS0 374 | return 375 | fi 376 | # upstart in karmic and newer 377 | if [ -e ${target}/etc/init/tty1.conf ] ; then 378 | cat ${target}/etc/init/tty1.conf | \ 379 | sed -re 's/^exec.*/exec \/sbin\/getty -L 115200 ttyS0 vt102/' \ 380 | > ${target}/etc/init/ttyS0.conf 381 | sed -ie 's/tty1/ttyS0/g' ${target}/etc/init/ttyS0.conf 382 | return 383 | fi 384 | get_os $target 385 | case $OPERATING_SYSTEM in 386 | gentoo) 387 | sed -i -e 's/.*ttyS0.*/s0:12345:respawn:\/sbin\/agetty 115200 ttyS0 vt100/' \ 388 | ${target}/etc/inittab 389 | ;; 390 | centos|redhat) 391 | echo "s0:12345:respawn:/sbin/agetty 115200 ttyS0 vt100" >> \ 392 | ${target}/etc/inittab 393 | ;; 394 | debian|ubuntu) 395 | sed -i -e 's/.*T0.*/T0:23:respawn:\/sbin\/getty -L ttyS0 115200 vt100/' \ 396 | ${target}/etc/inittab 397 | ;; 398 | *) 399 | echo "No support for your OS in instance-image, skipping..." 400 | ;; 401 | esac 402 | } 403 | 404 | cleanup() { 405 | if [ ${#CLEANUP[*]} -gt 0 ]; then 406 | LAST_ELEMENT=$((${#CLEANUP[*]}-1)) 407 | REVERSE_INDEXES=$(seq ${LAST_ELEMENT} -1 0) 408 | for i in $REVERSE_INDEXES; do 409 | ${CLEANUP[$i]} 410 | done 411 | fi 412 | } 413 | 414 | trap cleanup EXIT 415 | 416 | DEFAULT_FILE="@defaultdir@/ganeti-instance-image" 417 | if [ -f "$DEFAULT_FILE" ]; then 418 | . "$DEFAULT_FILE" 419 | fi 420 | 421 | # Variable name change from 2.5 to 2.6 422 | if [ -n "$INSTANCE_BE_memory" ] ; then 423 | INSTANCE_MEM="$INSTANCE_BE_memory" 424 | else 425 | INSTANCE_MEM="$INSTANCE_BE_maxmem" 426 | fi 427 | 428 | : ${CDINSTALL:="no"} 429 | : ${SWAP:="yes"} 430 | : ${SWAP_SIZE:="${INSTANCE_MEM}"} 431 | : ${BOOT_SIZE:="100"} 432 | : ${FILESYSTEM:="ext3"} 433 | : ${KERNEL_ARGS=""} 434 | : ${OVERLAY=""} 435 | : ${IMAGE_NAME:=""} 436 | : ${IMAGE_TYPE:="dump"} 437 | : ${NOMOUNT:="no"} 438 | : ${ARCH:=""} 439 | : ${CUSTOMIZE_DIR:="@sysconfdir@/ganeti/instance-image/hooks"} 440 | : ${VARIANTS_DIR:="@sysconfdir@/ganeti/instance-image/variants"} 441 | : ${NETWORKS_DIR:="@sysconfdir@/ganeti/instance-image/networks"} 442 | : ${OVERLAYS_DIR:="@sysconfdir@/ganeti/instance-image/overlays"} 443 | : ${EXPORT_DIR:="/tmp"} 444 | : ${IMAGE_DIR:="@localstatedir@/cache/ganeti-instance-image"} 445 | : ${IMAGE_DEBUG:="no"} 446 | : ${FDISK:="sfdisk"} 447 | : ${CACHE_DIR:="@localstatedir@/cache/ganeti-instance-image"} 448 | : ${IMAGE_URL:=""} 449 | : ${IMAGE_VERIFY:="yes"} 450 | : ${IMAGE_CLEANUP:="no"} 451 | 452 | SCRIPT_NAME=$(basename $0) 453 | KERNEL_PATH="$INSTANCE_HV_kernel_path" 454 | 455 | if [ -f /sbin/blkid -a -x /sbin/blkid ]; then 456 | VOL_ID="/sbin/blkid -c /dev/null -o value -s UUID" 457 | VOL_TYPE="/sbin/blkid -c /dev/null -o value -s TYPE" 458 | else 459 | for dir in /lib/udev /sbin; do 460 | if [ -f $dir/vol_id -a -x $dir/vol_id ]; then 461 | VOL_ID="$dir/vol_id -u" 462 | VOL_TYPE="$dir/vol_id -t" 463 | fi 464 | done 465 | fi 466 | 467 | if [ -z "$VOL_ID" ]; then 468 | log_error "vol_id or blkid not found, please install udev or util-linux" 469 | exit 1 470 | fi 471 | 472 | 473 | if [ -z "$OS_API_VERSION" -o "$OS_API_VERSION" = "5" ]; then 474 | OS_API_VERSION=5 475 | GETOPT_RESULT=`getopt -o o:n:i:b:s: -n '$0' -- "$@"` 476 | if [ $? != 0 ] ; then log_error "Terminating..."; exit 1 ; fi 477 | get_api5_arguments $GETOPT_RESULT 478 | elif [ "$OS_API_VERSION" = "10" -o "$OS_API_VERSION" = "15" ]; then 479 | get_api10_arguments 480 | else 481 | log_error "Unknown OS API VERSION $OS_API_VERSION" 482 | exit 1 483 | fi 484 | 485 | if [ -n "$OS_VARIANT" ]; then 486 | if [ ! -d "$VARIANTS_DIR" ]; then 487 | log_error "OS Variants directory $VARIANTS_DIR doesn't exist" 488 | exit 1 489 | fi 490 | VARIANT_CONFIG="$VARIANTS_DIR/$OS_VARIANT.conf" 491 | if [ -f "$VARIANT_CONFIG" ]; then 492 | . "$VARIANT_CONFIG" 493 | else 494 | if grep -qxF "$OS_VARIANT" variants.list; then 495 | log_error "ERROR: instance-image configuration error" 496 | log_error " Published variant $OS_VARIANT is missing its config file" 497 | log_error " Please create $VARIANT_CONFIG or unpublish the variant" 498 | log_error " (by removing $OS_VARIANT from variants.list)" 499 | else 500 | log_error "Unofficial variant $OS_VARIANT is unsupported" 501 | log_error "Most probably this is a user error, forcing a wrong name" 502 | log_error "To support this variant please create file $VARIANT_CONFIG" 503 | fi 504 | exit 1 505 | fi 506 | fi 507 | 508 | -------------------------------------------------------------------------------- /example/config/preseed/ubuntu-10.04-x86_64-ganeti.cfg: -------------------------------------------------------------------------------- 1 | #### Contents of the preconfiguration file (for &releasename;) 2 | ### Localization 3 | # Locale sets language and country. 4 | d-i debian-installer/locale string en_US.UTF-8 5 | 6 | # Keyboard selection. 7 | # Disable automatic (interactive) keymap detection. 8 | d-i console-setup/ask_detect boolean false 9 | #d-i console-setup/modelcode string pc105 10 | d-i console-setup/layoutcode string us 11 | # To select a variant of the selected layout (if you leave this out, the 12 | # basic form of the layout will be used): 13 | #d-i console-setup/variantcode string dvorak 14 | 15 | # Origin of the keyboard: 16 | d-i console-setup/layout select USA 17 | # Keyboard layout: 18 | d-i console-setup/variant select USA 19 | 20 | # Download language support? 21 | d-i pkgsel/install-language-support boolean false 22 | pkgsel pkgsel/install-language-support boolean false 23 | 24 | 25 | ### Network configuration 26 | # netcfg will choose an interface that has link if possible. This makes it 27 | # skip displaying a list if there is more than one interface. 28 | d-i netcfg/choose_interface select auto 29 | 30 | # To pick a particular interface instead: 31 | #d-i netcfg/choose_interface select eth1 32 | 33 | # If you have a slow dhcp server and the installer times out waiting for 34 | # it, this might be useful. 35 | #d-i netcfg/dhcp_timeout string 60 36 | 37 | # If you prefer to configure the network manually, uncomment this line and 38 | # the static network configuration below. 39 | #d-i netcfg/disable_dhcp boolean true 40 | 41 | # If you want the preconfiguration file to work on systems both with and 42 | # without a dhcp server, uncomment these lines and the static network 43 | # configuration below. 44 | #d-i netcfg/dhcp_failed note 45 | #d-i netcfg/dhcp_options select Configure network manually 46 | 47 | # Static network configuration. 48 | #d-i netcfg/get_nameservers string 192.168.1.1 49 | #d-i netcfg/get_ipaddress string 192.168.1.42 50 | #d-i netcfg/get_netmask string 255.255.255.0 51 | #d-i netcfg/get_gateway string 192.168.1.1 52 | #d-i netcfg/confirm_static boolean true 53 | 54 | # Any hostname and domain names assigned from dhcp take precedence over 55 | # values set here. However, setting the values still prevents the questions 56 | # from being shown, even if values come from dhcp. 57 | d-i netcfg/get_hostname string gimager 58 | d-i netcfg/get_domain string example.com 59 | 60 | # Disable that annoying WEP key dialog. 61 | d-i netcfg/wireless_wep string 62 | # The wacky dhcp hostname that some ISPs use as a password of sorts. 63 | #d-i netcfg/dhcp_hostname string radish 64 | 65 | # If non-free firmware is needed for the network or other hardware, you can 66 | # configure the installer to always try to load it, without prompting. Or 67 | # change to false to disable asking. 68 | #d-i hw-detect/load_firmware boolean true 69 | 70 | ### Mirror settings 71 | # If you select ftp, the mirror/country string does not need to be set. 72 | #d-i mirror/protocol string ftp 73 | d-i mirror/country string manual 74 | d-i mirror/http/hostname string ubuntu.osuosl.org 75 | d-i mirror/http/directory string /ubuntu 76 | d-i mirror/http/proxy string 77 | 78 | # Alternatively: by default, the installer uses CC.archive.ubuntu.com where 79 | # CC is the ISO-3166-2 code for the selected country. You can preseed this 80 | # so that it does so without asking. 81 | d-i mirror/http/mirror select ubuntu.osuosl.org 82 | 83 | # Suite to install. 84 | #d-i mirror/suite string &releasename; 85 | # Suite to use for loading installer components (optional). 86 | #d-i mirror/udeb/suite string &releasename; 87 | # Components to use for loading installer components (optional). 88 | #d-i mirror/udeb/components multiselect main, restricted 89 | 90 | ### Clock and time zone setup 91 | # Controls whether or not the hardware clock is set to UTC. 92 | d-i clock-setup/utc boolean true 93 | 94 | # You may set this to any valid setting for $TZ; see the contents of 95 | # /usr/share/zoneinfo/ for valid values. 96 | d-i time/zone string UTC 97 | 98 | # Controls whether to use NTP to set the clock during the install 99 | d-i clock-setup/ntp boolean true 100 | # NTP server to use. The default is almost always fine here. 101 | d-i clock-setup/ntp-server string pool.ntp.org 102 | 103 | ### Partitioning 104 | # If the system has free space you can choose to only partition that space. 105 | # Alternatives: custom, some_device, some_device_crypto, some_device_lvm. 106 | #d-i partman-auto/init_automatically_partition select biggest_free 107 | 108 | # Alternatively, you can specify a disk to partition. The device name must 109 | # be given in traditional non-devfs format. 110 | # Note: A disk must be specified, unless the system has only one disk. 111 | # For example, to use the first SCSI/SATA hard disk: 112 | #d-i partman-auto/disk string /dev/sda 113 | # In addition, you'll need to specify the method to use. 114 | # The presently available methods are: "regular", "lvm" and "crypto" 115 | d-i partman-auto/method string regular 116 | 117 | # If one of the disks that are going to be automatically partitioned 118 | # contains an old LVM configuration, the user will normally receive a 119 | # warning. This can be preseeded away... 120 | d-i partman-lvm/device_remove_lvm boolean true 121 | # The same applies to pre-existing software RAID array: 122 | d-i partman-md/device_remove_md boolean true 123 | # And the same goes for the confirmation to write the lvm partitions. 124 | d-i partman-lvm/confirm boolean true 125 | 126 | # For LVM partitioning, you can select how much of the volume group to use 127 | # for logical volumes. 128 | #d-i partman-auto-lvm/guided_size string max 129 | #d-i partman-auto-lvm/guided_size string 10GB 130 | #d-i partman-auto-lvm/guided_size string 50% 131 | 132 | # You can choose one of the three predefined partitioning recipes: 133 | # - atomic: all files in one partition 134 | # - home: separate /home partition 135 | # - multi: separate /home, /usr, /var, and /tmp partitions 136 | d-i partman-auto/choose_recipe select atomic 137 | 138 | # Or provide a recipe of your own... 139 | # The recipe format is documented in the file devel/partman-auto-recipe.txt. 140 | # If you have a way to get a recipe file into the d-i environment, you can 141 | # just point at it. 142 | #d-i partman-auto/expert_recipe_file string /hd-media/recipe 143 | 144 | # If not, you can put an entire recipe into the preconfiguration file in one 145 | # (logical) line. This example creates a small /boot partition, suitable 146 | # swap, and uses the rest of the space for the root partition: 147 | d-i partman-auto/expert_recipe string boot-root :: \ 148 | 200 210 220 ext4 \ 149 | $primary{ } $bootable{ } \ 150 | method{ format } format{ } \ 151 | use_filesystem{ } filesystem{ ext4 } \ 152 | mountpoint{ /boot } \ 153 | . \ 154 | 64 512 1024 linux-swap \ 155 | $primary{ } \ 156 | method{ swap } format{ } \ 157 | . \ 158 | 2500 3000 -1 ext4 \ 159 | $primary{ } \ 160 | method{ format } format{ } \ 161 | use_filesystem{ } filesystem{ ext4 } \ 162 | mountpoint{ / } \ 163 | . \ 164 | 165 | # If you just want to change the default filesystem from ext3 to something 166 | # else, you can do that without providing a full recipe. 167 | #d-i partman/default_filesystem string ext4 168 | 169 | # This makes partman automatically partition without confirmation, provided 170 | # that you told it what to do using one of the methods above. 171 | d-i partman/confirm_write_new_label boolean true 172 | d-i partman/choose_partition select finish 173 | d-i partman/confirm boolean true 174 | d-i partman/confirm_nooverwrite boolean true 175 | 176 | ### Controlling how partitions are mounted 177 | # The default is to mount by UUID, but you can also choose "traditional" to 178 | # use traditional device names, or "label" to try filesystem labels before 179 | # falling back to UUIDs. 180 | #d-i partman/mount_style select uuid 181 | 182 | ### Base system installation 183 | # The kernel image (meta) package to be installed; "none" can be used if no 184 | # kernel is to be installed. 185 | d-i base-installer/kernel/image string linux-virtual 186 | 187 | ### Account setup 188 | # Skip creation of a root account (normal user account will be able to 189 | # use sudo). The default is false; preseed this to true if you want to set 190 | # a root password. 191 | d-i passwd/root-login boolean true 192 | # Alternatively, to skip creation of a normal user account. 193 | d-i passwd/make-user boolean true 194 | 195 | # Root password, either in clear text 196 | #d-i passwd/root-password password r00tme 197 | #d-i passwd/root-password-again password r00tme 198 | # or encrypted using an MD5 hash. 199 | #d-i passwd/root-password-crypted password changeme 200 | 201 | # To create a normal user account. 202 | #d-i passwd/user-fullname string John Doe 203 | #d-i passwd/username string jdoe 204 | # Normal user's password, either in clear text 205 | #d-i passwd/user-password password insecure 206 | #d-i passwd/user-password-again password insecure 207 | # or encrypted using an MD5 hash. 208 | #d-i passwd/user-password-crypted password changeme 209 | # Create the first user with the specified UID instead of the default. 210 | #d-i passwd/user-uid string 1010 211 | # The installer will warn about weak passwords. If you are sure you know 212 | # what you're doing and want to override it, uncomment this. 213 | #d-i user-setup/allow-password-weak boolean true 214 | 215 | # The user account will be added to some standard initial groups. To 216 | # override that, use this. 217 | #d-i passwd/user-default-groups string audio cdrom video 218 | 219 | # Set to true if you want to encrypt the first user's home directory. 220 | d-i user-setup/encrypt-home boolean false 221 | 222 | ### Apt setup 223 | # You can choose to install restricted and universe software, or to install 224 | # software from the backports repository. 225 | d-i apt-setup/restricted boolean true 226 | d-i apt-setup/universe boolean true 227 | #d-i apt-setup/backports boolean true 228 | # Uncomment this if you don't want to use a network mirror. 229 | #d-i apt-setup/use_mirror boolean false 230 | # Select which update services to use; define the mirrors to be used. 231 | # Values shown below are the normal defaults. 232 | #d-i apt-setup/services-select multiselect security 233 | #d-i apt-setup/security_host string security.ubuntu.com 234 | #d-i apt-setup/security_path string /ubuntu 235 | 236 | # Additional repositories, local[0-9] available 237 | #d-i apt-setup/local0/repository string \ 238 | # http://local.server/ubuntu &releasename; main 239 | #d-i apt-setup/local0/comment string local server 240 | # Enable deb-src lines 241 | #d-i apt-setup/local0/source boolean true 242 | # URL to the public key of the local repository; you must provide a key or 243 | # apt will complain about the unauthenticated repository and so the 244 | # sources.list line will be left commented out 245 | #d-i apt-setup/local0/key string http://local.server/key 246 | 247 | # By default the installer requires that repositories be authenticated 248 | # using a known gpg key. This setting can be used to disable that 249 | # authentication. Warning: Insecure, not recommended. 250 | #d-i debian-installer/allow_unauthenticated string true 251 | 252 | ### Package selection 253 | tasksel tasksel/first multiselect 254 | #tasksel tasksel/first multiselect lamp-server, print-server 255 | #tasksel tasksel/first multiselect kubuntu-desktop 256 | tasksel tasksel/force-tasks string server 257 | 258 | # Individual additional packages to install 259 | d-i pkgsel/include string openssh-server denyhosts rsync vim sudo acpid 260 | # Whether to upgrade packages after debootstrap. 261 | # Allowed values: none, safe-upgrade, full-upgrade 262 | d-i pkgsel/upgrade select safe-upgrade 263 | 264 | # landscape-sysinfo configuration: 265 | # Choices: Do not display sysinfo on login, Cache sysinfo in /etc/motd, Run sysinfo on every login 266 | landscape-common landscape-common/sysinfo select Do not display sysinfo on login 267 | 268 | # Language pack selection 269 | #d-i pkgsel/language-packs multiselect de, en, zh 270 | 271 | # Policy for applying updates. May be "none" (no automatic updates), 272 | # "unattended-upgrades" (install security updates automatically), or 273 | # "landscape" (manage system with Landscape). 274 | d-i pkgsel/update-policy select none 275 | 276 | # Some versions of the installer can report back on what software you have 277 | # installed, and what software you use. The default is not to report back, 278 | # but sending reports helps the project determine what software is most 279 | # popular and include it on CDs. 280 | #popularity-contest popularity-contest/participate boolean false 281 | 282 | # By default, the system's locate database will be updated after the 283 | # installer has finished installing most packages. This may take a while, so 284 | # if you don't want it, you can set this to "false" to turn it off. 285 | #d-i pkgsel/updatedb boolean true 286 | 287 | ### Boot loader installation 288 | # Grub is the default boot loader (for x86). If you want lilo installed 289 | # instead, uncomment this: 290 | #d-i grub-installer/skip boolean true 291 | # To also skip installing lilo, and install no bootloader, uncomment this 292 | # too: 293 | #d-i lilo-installer/skip boolean true 294 | 295 | # This is fairly safe to set, it makes grub install automatically to the MBR 296 | # if no other operating system is detected on the machine. 297 | d-i grub-installer/only_debian boolean true 298 | 299 | # This one makes grub-installer install to the MBR if it also finds some other 300 | # OS, which is less safe as it might not be able to boot that other OS. 301 | d-i grub-installer/with_other_os boolean true 302 | 303 | # Alternatively, if you want to install to a location other than the mbr, 304 | # uncomment and edit these lines: 305 | #d-i grub-installer/only_debian boolean false 306 | #d-i grub-installer/with_other_os boolean false 307 | #d-i grub-installer/bootdev string (hd0,0) 308 | # To install grub to multiple disks: 309 | #d-i grub-installer/bootdev string (hd0,0) (hd1,0) (hd2,0) 310 | 311 | # Optional password for grub, either in clear text 312 | #d-i grub-installer/password password r00tme 313 | #d-i grub-installer/password-again password r00tme 314 | # or encrypted using an MD5 hash, see grub-md5-crypt(8). 315 | #d-i grub-installer/password-crypted password [MD5 hash] 316 | 317 | ### Finishing up the installation 318 | # During installations from serial console, the regular virtual consoles 319 | # (VT1-VT6) are normally disabled in /etc/inittab. Uncomment the next 320 | # line to prevent this. 321 | #d-i finish-install/keep-consoles boolean true 322 | 323 | # Avoid that last message about the install being complete. 324 | d-i finish-install/reboot_in_progress note 325 | 326 | # This will prevent the installer from ejecting the CD during the reboot, 327 | # which is useful in some situations. 328 | #d-i cdrom-detect/eject boolean false 329 | 330 | # This is how to make the installer shutdown when finished, but not 331 | # reboot into the installed system. 332 | #d-i debian-installer/exit/halt boolean true 333 | # This will power off the machine instead of just halting it. 334 | d-i debian-installer/exit/poweroff boolean true 335 | 336 | ### X configuration 337 | # X can detect the right driver for some cards, but if you're preseeding, 338 | # you override whatever it chooses. Still, vesa will work most places. 339 | #xserver-xorg xserver-xorg/config/device/driver select vesa 340 | 341 | # A caveat with mouse autodetection is that if it fails, X will retry it 342 | # over and over. So if it's preseeded to be done, there is a possibility of 343 | # an infinite loop if the mouse is not autodetected. 344 | #xserver-xorg xserver-xorg/autodetect_mouse boolean true 345 | 346 | # Monitor autodetection is recommended. 347 | xserver-xorg xserver-xorg/autodetect_monitor boolean true 348 | # Uncomment if you have an LCD display. 349 | #xserver-xorg xserver-xorg/config/monitor/lcd boolean true 350 | # X has three configuration paths for the monitor. Here's how to preseed 351 | # the "medium" path, which is always available. The "simple" path may not 352 | # be available, and the "advanced" path asks too many questions. 353 | xserver-xorg xserver-xorg/config/monitor/selection-method \ 354 | select medium 355 | xserver-xorg xserver-xorg/config/monitor/mode-list \ 356 | select 1024x768 @ 60 Hz 357 | 358 | ### Preseeding other packages 359 | # Depending on what software you choose to install, or if things go wrong 360 | # during the installation process, it's possible that other questions may 361 | # be asked. You can preseed those too, of course. To get a list of every 362 | # possible question that could be asked during an install, do an 363 | # installation, and then run these commands: 364 | # debconf-get-selections --installer > file 365 | # debconf-get-selections >> file 366 | 367 | 368 | #### Advanced options 369 | ### Running custom commands during the installation 370 | # d-i preseeding is inherently not secure. Nothing in the installer checks 371 | # for attempts at buffer overflows or other exploits of the values of a 372 | # preconfiguration file like this one. Only use preconfiguration files from 373 | # trusted locations! To drive that home, and because it's generally useful, 374 | # here's a way to run any shell command you'd like inside the installer, 375 | # automatically. 376 | 377 | # This first command is run as early as possible, just after 378 | # preseeding is read. 379 | #d-i preseed/early_command string anna-install some-udeb 380 | 381 | # This command is run immediately before the partitioner starts. It may be 382 | # useful to apply dynamic partitioner preseeding that depends on the state 383 | # of the disks (which may not be visible when preseed/early_command runs). 384 | #d-i partman/early_command string debconf-set partman-auto/disk "$(list-devices disk | head -n1)" 385 | 386 | # This command is run just before the install finishes, but when there is 387 | # still a usable /target directory. You can chroot to /target and use it 388 | # directly, or use the apt-install and in-target commands to easily install 389 | # packages and run commands in the target system. 390 | #d-i preseed/late_command string apt-install zsh; in-target chsh -s /bin/zsh 391 | d-i preseed/late_command string \ 392 | wget http://packages.example.com/preseed/scripts/standard.sh ; \ 393 | chmod +x standard.sh ; \ 394 | mv standard.sh /target/ ; \ 395 | in-target aptitude -y full-upgrade ; \ 396 | chroot /target /standard.sh ; \ 397 | in-target aptitude -y purge landscape-common ; \ 398 | in-target aptitude -y clean ; \ 399 | rm /target/standard.sh ; 400 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Library General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License 307 | along with this program; if not, write to the Free Software 308 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 309 | 310 | 311 | Also add information on how to contact you by electronic and paper mail. 312 | 313 | If the program is interactive, make it output a short notice like this 314 | when it starts in an interactive mode: 315 | 316 | Gnomovision version 69, Copyright (C) year name of author 317 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 318 | This is free software, and you are welcome to redistribute it 319 | under certain conditions; type `show c' for details. 320 | 321 | The hypothetical commands `show w' and `show c' should show the appropriate 322 | parts of the General Public License. Of course, the commands you use may 323 | be called something other than `show w' and `show c'; they could even be 324 | mouse-clicks or menu items--whatever suits your program. 325 | 326 | You should also get your employer (if you work as a programmer) or your 327 | school, if any, to sign a "copyright disclaimer" for the program, if 328 | necessary. Here is a sample; alter the names: 329 | 330 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 331 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 332 | 333 | , 1 April 1989 334 | Ty Coon, President of Vice 335 | 336 | This General Public License does not permit incorporating your program into 337 | proprietary programs. If your program is a subroutine library, you may 338 | consider it more useful to permit linking proprietary applications with the 339 | library. If this is what you want to do, use the GNU Library General 340 | Public License instead of this License. 341 | --------------------------------------------------------------------------------