Merge pull request #126 from fgrehm/126-base-boxes-revamp

Clean up base boxes creation scripts
This commit is contained in:
Fabio Rehm 2013-09-20 21:17:35 -07:00
commit bda01dbc4d
20 changed files with 408 additions and 2110 deletions

55
BOXES.md Normal file
View file

@ -0,0 +1,55 @@
# vagrant-lxc base boxes
Although the official documentation says it is only supported for VirtualBox
environments, you can use the [`vagrant package`](http://docs.vagrantup.com/v2/cli/package.html)
command to export a `.box` file from an existing vagrant-lxc container.
There is also a set of [bash scripts](https://github.com/fgrehm/vagrant-lxc/tree/master/boxes)
that you can use to build base boxes as needed. By default it won't include any
provisioning tool and you can pick the ones you want by providing some environment
variables.
For example:
```
git clone https://github.com/fgrehm/vagrant-lxc.git
cd vagrant-lxc/boxes
PUPPET=1 CHEF=1 sudo -E ./build-ubuntu-box.sh precise amd64
```
Will build a Ubuntu Precise x86_64 box with latest Puppet and Chef pre-installed, please refer to the scripts for more information.
## "Anatomy" of a box
If you need to go deeper and build your scripts from scratch or if you are interested
on knowing what makes a base box for vagrant-lxc, here's what's needed:
### Expected `.box` contents
| FILE | DESCRIPTION |
| --- | --- |
| `lxc-template` | Script responsible for creating and setting up the container (used with `lxc-create`), a ["generic script"]() is provided along with project's source. |
| `rootfs.tar.gz` | Compressed container rootfs tarball (need to remeber to pass in `--numeric-owner` when creating it) |
| `lxc.conf` | |
| `metadata.json` | |
### metadata.json
```json
{
"provider": "lxc",
"version": "3",
"built-on": "Sat Sep 21 21:10:00 UTC 2013",
"template-opts": {
"--arch": "amd64",
"--release": "quantal"
}
}
```
| KEY | REQUIRED? | DESCRIPTION |
| --- | --- | --- |
| `provider` | Yes | Required by Vagrant |
| `version` | Yes | Tracks backward incompatibilities |
| `built-on` | No | Date / time when the box was packaged |
| `template-opts` | No | Extra options to be passed to the `lxc-template` script provided with the .box package |

View file

@ -106,13 +106,13 @@ to find out how to work around that specially if you are running an OS with sudo
Please check [the wiki](https://github.com/fgrehm/vagrant-lxc/wiki/Base-boxes)
for a list of [pre built](https://github.com/fgrehm/vagrant-lxc/wiki/Base-boxes#available-boxes)
base boxes and information on [how to build your own](https://github.com/fgrehm/vagrant-lxc/wiki/Base-boxes#building-your-own).
base boxes and have a look at [`BOXES.md`](https://github.com/fgrehm/vagrant-lxc/tree/master/BOXES.md)
for more information on building your own.
## More information
Please refer the [wiki](https://github.com/fgrehm/vagrant-lxc/wiki) for more
information.
Please refer the [wiki](https://github.com/fgrehm/vagrant-lxc/wiki).
## Problems / ideas?
@ -129,6 +129,14 @@ to ask questions, propose new functionality and / or report bugs.
* [vagueant](https://github.com/neerolyte/vagueant) - "vaguely like Vagrant for linux containers (lxc)"
## Donating
Support this project and [others by fgrehm](https://github.com/fgrehm)
via [gittip](https://www.gittip.com/fgrehm/).
[![Support via Gittip](https://rawgithub.com/twolfson/gittip-badge/0.1.0/dist/gittip.png)](https://www.gittip.com/fgrehm/)
## Contributing
1. Fork it

167
boxes/build-debian-box.sh Executable file
View file

@ -0,0 +1,167 @@
#!/bin/bash
# set -x
set -e
# Script used to build Debian base vagrant-lxc containers, currently limited to
# host's arch
#
# USAGE:
# $ cd boxes && sudo ./build-debian-box.sh DEBIAN_RELEASE
#
# To enable Chef or any other configuration management tool pass '1' to the
# corresponding env var:
# $ CHEF=1 sudo -E ./build-debian-box.sh DEBIAN_RELEASE
# $ PUPPET=1 sudo -E ./build-debian-box.sh DEBIAN_RELEASE
# $ SALT=1 sudo -E ./build-debian-box.sh DEBIAN_RELEASE
# $ BABUSHKA=1 sudo -E ./build-debian-box.sh DEBIAN_RELEASE
##################################################################################
# 0 - Initial setup and sanity checks
TODAY=$(date -u +"%Y-%m-%d")
NOW=$(date -u)
RELEASE=${1:-"wheezy"}
ARCH=$(dpkg --print-architecture) # This is what the Debian template will use under the hood
PKG=vagrant-lxc-${RELEASE}-${ARCH}-${TODAY}.box
WORKING_DIR=/tmp/vagrant-lxc-${RELEASE}
VAGRANT_KEY="ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key"
ROOTFS=/var/lib/lxc/${RELEASE}-base/rootfs
# Providing '1' will enable these tools
CHEF=${CHEF:-0}
PUPPET=${PUPPET:-0}
SALT=${SALT:-0}
BABUSHKA=${BABUSHKA:-0}
# Path to files bundled with the box
CWD=`readlink -f .`
LXC_TEMPLATE=${CWD}/common/lxc-template
LXC_CONF=${CWD}/common/lxc.conf
METATADA_JSON=${CWD}/common/metadata.json
# Set up a working dir
mkdir -p $WORKING_DIR
if [ -f "${WORKING_DIR}/${PKG}" ]; then
echo "Found a box on ${WORKING_DIR}/${PKG} already!"
exit 1
fi
##################################################################################
# 1 - Create the base container
if $(lxc-ls | grep -q "${RELEASE}-base"); then
echo "Base container already exists, please remove it with \`lxc-destroy -n ${RELEASE}-base\`!"
exit 1
else
export SUITE=$RELEASE
lxc-create -n ${RELEASE}-base -t debian
fi
######################################
# 2 - Fix some known issues
# Fixes some networking issues
# See https://github.com/fgrehm/vagrant-lxc/issues/91 for more info
sed -i -e "s/\(127.0.0.1\s\+localhost\)/\1\n127.0.1.1\t${RELEASE}-base\n/g" ${ROOTFS}/etc/hosts
# Ensures that `/tmp` does not get cleared on halt
# See https://github.com/fgrehm/vagrant-lxc/issues/68 for more info
chroot $ROOTFS /usr/sbin/update-rc.d -f checkroot-bootclean.sh remove
chroot $ROOTFS /usr/sbin/update-rc.d -f mountall-bootclean.sh remove
chroot $ROOTFS /usr/sbin/update-rc.d -f mountnfs-bootclean.sh remove
# Ensure locales are properly set, based on http://linux.livejournal.com/1880366.html
sed -i "s/^# en_US/en_US/" ${ROOTFS}/etc/locale.gen
chroot $ROOTFS /usr/sbin/locale-gen
chroot $ROOTFS update-locale LANG=en_US.UTF-8
##################################################################################
# 3 - Prepare vagrant user
sudo chroot ${ROOTFS} useradd --create-home -s /bin/bash vagrant
echo -n 'vagrant:vagrant' | chroot ${ROOTFS} chpasswd
##################################################################################
# 4 - Setup SSH access and passwordless sudo
# Configure SSH access
mkdir -p ${ROOTFS}/home/vagrant/.ssh
echo $VAGRANT_KEY > ${ROOTFS}/home/vagrant/.ssh/authorized_keys
chroot ${ROOTFS} chown -R vagrant: /home/vagrant/.ssh
chroot ${ROOTFS} apt-get install sudo -y --force-yes
chroot ${ROOTFS} adduser vagrant sudo
# Enable passwordless sudo for users under the "sudo" group
cp ${ROOTFS}/etc/sudoers{,.orig}
sed -i -e \
's/%sudo\s\+ALL=(ALL\(:ALL\)\?)\s\+ALL/%sudo ALL=NOPASSWD:ALL/g' \
${ROOTFS}/etc/sudoers
##################################################################################
# 5 - Add some goodies and update packages
PACKAGES=(vim curl wget man-db bash-completion ca-certificates)
chroot ${ROOTFS} apt-get install ${PACKAGES[*]} -y --force-yes
chroot ${ROOTFS} apt-get upgrade -y --force-yes
##################################################################################
# 6 - Configuration management tools
if [ $CHEF = 1 ]; then
./common/install-chef $ROOTFS
fi
if [ $PUPPET = 1 ]; then
./common/install-puppet $ROOTFS
fi
if [ $SALT = 1 ]; then
./common/install-salt $ROOTFS
fi
if [ $BABUSHKA = 1 ]; then
./common/install-babushka $ROOTFS
fi
##################################################################################
# 7 - Free up some disk space
rm -rf ${ROOTFS}/tmp/*
chroot ${ROOTFS} apt-get clean
##################################################################################
# 8 - Build box package
# Compress container's rootfs
cd $(dirname $ROOTFS)
tar --numeric-owner -czf /tmp/vagrant-lxc-${RELEASE}/rootfs.tar.gz ./rootfs/*
# Prepare package contents
cd $WORKING_DIR
cp $LXC_TEMPLATE .
cp $LXC_CONF .
cp $METATADA_JSON .
chmod +x lxc-template
sed -i "s/<TODAY>/${NOW}/" metadata.json
# Vagrant box!
tar -czf $PKG ./*
chmod +rw ${WORKING_DIR}/${PKG}
mkdir -p ${CWD}/output
mv ${WORKING_DIR}/${PKG} ${CWD}/output
# Clean up after ourselves
rm -rf ${WORKING_DIR}
echo "The base box was built successfully to ${CWD}/output/${PKG}"

151
boxes/build-ubuntu-box.sh Executable file
View file

@ -0,0 +1,151 @@
#!/bin/bash
# set -x
set -e
# Script used to build Ubuntu base vagrant-lxc containers
#
# USAGE:
# $ cd boxes && sudo ./build-ubuntu-box.sh UBUNTU_RELEASE BOX_ARCH
#
# To enable Chef or any other configuration management tool pass '1' to the
# corresponding env var:
# $ CHEF=1 sudo -E ./build-ubuntu-box.sh UBUNTU_RELEASE BOX_ARCH
# $ PUPPET=1 sudo -E ./build-ubuntu-box.sh UBUNTU_RELEASE BOX_ARCH
# $ SALT=1 sudo -E ./build-ubuntu-box.sh UBUNTU_RELEASE BOX_ARCH
# $ BABUSHKA=1 sudo -E ./build-ubuntu-box.sh UBUNTU_RELEASE BOX_ARCH
##################################################################################
# 0 - Initial setup and sanity checks
TODAY=$(date -u +"%Y-%m-%d")
NOW=$(date -u)
RELEASE=${1:-"raring"}
ARCH=${2:-"amd64"}
PKG=vagrant-lxc-${RELEASE}-${ARCH}-${TODAY}.box
WORKING_DIR=/tmp/vagrant-lxc-${RELEASE}
VAGRANT_KEY="ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key"
ROOTFS=/var/lib/lxc/${RELEASE}-base/rootfs
# Providing '1' will enable these tools
CHEF=${CHEF:-0}
PUPPET=${PUPPET:-0}
SALT=${SALT:-0}
BABUSHKA=${BABUSHKA:-0}
# Path to files bundled with the box
CWD=`readlink -f .`
LXC_TEMPLATE=${CWD}/common/lxc-template
LXC_CONF=${CWD}/common/lxc.conf
METATADA_JSON=${CWD}/common/metadata.json
# Set up a working dir
mkdir -p $WORKING_DIR
if [ -f "${WORKING_DIR}/${PKG}" ]; then
echo "Found a box on ${WORKING_DIR}/${PKG} already!"
exit 1
fi
##################################################################################
# 1 - Create the base container
if $(lxc-ls | grep -q "${RELEASE}-base"); then
echo "Base container already exists, please remove it with \`lxc-destroy -n ${RELEASE}-base\`!"
exit 1
else
lxc-create -n ${RELEASE}-base -t ubuntu -- --release ${RELEASE} --arch ${ARCH}
fi
# Fixes some networking issues
# See https://github.com/fgrehm/vagrant-lxc/issues/91 for more info
echo 'ff02::3 ip6-allhosts' >> ${ROOTFS}/etc/hosts
##################################################################################
# 2 - Prepare vagrant user
mv ${ROOTFS}/home/{ubuntu,vagrant}
chroot ${ROOTFS} usermod -l vagrant -d /home/vagrant ubuntu
chroot ${ROOTFS} groupmod -n vagrant ubuntu
echo -n 'vagrant:vagrant' | chroot ${ROOTFS} chpasswd
##################################################################################
# 3 - Setup SSH access and passwordless sudo
# Configure SSH access
mkdir -p ${ROOTFS}/home/vagrant/.ssh
echo $VAGRANT_KEY > ${ROOTFS}/home/vagrant/.ssh/authorized_keys
chroot ${ROOTFS} chown -R vagrant: /home/vagrant/.ssh
# Enable passwordless sudo for users under the "sudo" group
cp ${ROOTFS}/etc/sudoers{,.orig}
sed -i -e \
's/%sudo\s\+ALL=(ALL\(:ALL\)\?)\s\+ALL/%sudo ALL=NOPASSWD:ALL/g' \
${ROOTFS}/etc/sudoers
##################################################################################
# 4 - Add some goodies and update packages
PACKAGES=(vim curl wget man-db bash-completion)
chroot ${ROOTFS} apt-get install ${PACKAGES[*]} -y --force-yes
chroot ${ROOTFS} apt-get upgrade -y --force-yes
##################################################################################
# 5 - Configuration management tools
if [ $CHEF = 1 ]; then
./common/install-chef $ROOTFS
fi
if [ $PUPPET = 1 ]; then
./common/install-puppet $ROOTFS
fi
if [ $SALT = 1 ]; then
./common/install-salt $ROOTFS
fi
if [ $BABUSHKA = 1 ]; then
./common/install-babushka $ROOTFS
fi
##################################################################################
# 6 - Free up some disk space
rm -rf ${ROOTFS}/tmp/*
chroot ${ROOTFS} apt-get clean
##################################################################################
# 7 - Build box package
# Compress container's rootfs
cd $(dirname $ROOTFS)
tar --numeric-owner -czf /tmp/vagrant-lxc-${RELEASE}/rootfs.tar.gz ./rootfs/*
# Prepare package contents
cd $WORKING_DIR
cp $LXC_TEMPLATE .
cp $LXC_CONF .
cp $METATADA_JSON .
chmod +x lxc-template
sed -i "s/<TODAY>/${NOW}/" metadata.json
# Vagrant box!
tar -czf $PKG ./*
chmod +rw ${WORKING_DIR}/${PKG}
mkdir -p ${CWD}/output
mv ${WORKING_DIR}/${PKG} ${CWD}/output
# Clean up after ourselves
rm -rf ${WORKING_DIR}
lxc-destroy -n ${RELEASE}-base
echo "The base box was built successfully to ${CWD}/output/${PKG}"

View file

@ -1,12 +1,13 @@
#!/bin/bash
cache=`readlink -f .`
rootfs="${cache}/rootfs"
set -e
rootfs=$1
echo "installing babushka"
cat > $rootfs/tmp/install-babushka.sh << EOF
#!/bin/sh
curl -L https://babushka.me/up | sudo bash < /dev/null
curl https://babushka.me/up | sudo bash
EOF
chmod +x $rootfs/tmp/install-babushka.sh

View file

@ -1,7 +1,8 @@
#!/bin/bash
cache=`readlink -f .`
rootfs="${cache}/rootfs"
set -e
rootfs=$1
echo "installing chef"
cat > $rootfs/tmp/install-chef.sh << EOF

View file

@ -1,7 +1,8 @@
#!/bin/bash
cache=`readlink -f .`
rootfs="${cache}/rootfs"
set -e
rootfs=$1
echo "installing puppet"
wget http://apt.puppetlabs.com/puppetlabs-release-stable.deb -O "${rootfs}/tmp/puppetlabs-release-stable.deb"

View file

@ -1,7 +1,8 @@
#!/bin/bash
cache=`readlink -f .`
rootfs="${cache}/rootfs"
set -e
rootfs=$1
echo "installing salt"
chroot $rootfs apt-add-repository -y ppa:saltstack/salt

View file

@ -112,12 +112,8 @@ post_process()
usage()
{
cat <<EOF
$1 -h|--help [-a|--arch] [--trim] [-d|--debug]
[-F | --flush-cache] [-r|--release <release>] [ -S | --auth-key <keyfile>]
release: the ubuntu release (e.g. precise): defaults to host release on ubuntu, otherwise uses latest LTS
trim: make a minimal (faster, but not upgrade-safe) container
$1 -h|--help [-a|--arch] [--trim] [-d|--debug] [--rootfs <rootfs>] [-T|--tarball <rootfs-tarball>
arch: the container architecture (e.g. amd64): defaults to host arch
auth-key: SSH Public key file to inject into container
EOF
return 0
}
@ -162,12 +158,11 @@ while true
do
case "$1" in
-h|--help) usage $0 && exit 0;;
--rootfs) rootfs=$2; shift 2;;
-p|--path) path=$2; shift 2;;
-n|--name) name=$2; shift 2;;
-T|--tarball) tarball=$2; shift 2;;
-r|--release) release=$2; shift 2;;
-a|--arch) arch=$2; shift 2;;
-x|--trim) trim_container=1; shift 1;;
-S|--auth-key) auth_key=$2; shift 2;;
-d|--debug) debug=1; shift 1;;
--) shift 1; break ;;
@ -179,7 +174,6 @@ if [ $debug -eq 1 ]; then
set -x
fi
if [ "$arch" == "i686" ]; then
arch=i386
fi
@ -201,10 +195,13 @@ fi
# detect rootfs
config="$path/config"
if grep -q '^lxc.rootfs' $config 2>/dev/null ; then
rootfs=`grep 'lxc.rootfs =' $config | awk -F= '{ print $2 }'`
else
rootfs=$path/rootfs
# if $rootfs exists here, it was passed in with --rootfs
if [ -z "$rootfs" ]; then
if grep -q '^lxc.rootfs' $config 2>/dev/null ; then
rootfs=`grep 'lxc.rootfs =' $config | awk -F= '{ print $2 }'`
else
rootfs=$path/rootfs
fi
fi
install_ubuntu $rootfs $release $tarball

View file

@ -1,4 +1,5 @@
{
"provider": "lxc",
"version": "3"
"version": "3",
"built-on": "<TODAY>"
}

View file

@ -1,156 +0,0 @@
#!/bin/bash
# This is the code extracted from /usr/share/lxc/templates/lxc-debian
# that comes with Ubuntu 13.04 which is responsible for downloading the
# rootfs files / packages
set -e
suggest_flush()
{
echo <<EOF
Container upgrade failed. The container cache may be out of date,
in which case flushing the case (see -F in the hep output) may help.
EOF
}
cleanup()
{
rm -rf $cache/partial
rm -rf $cache/rootfs
}
write_sourceslist()
{
rootfs=$1
arch=$2
release=$3
MIRROR=${MIRROR:-http://ftp.debian.org/debian}
SECURITY_MIRROR=${SECURITY_MIRROR:-http://security.debian.org/debian-security}
if [ 'sid' == "${release}" -o 'unstable' == "${release}" ]; then
cat <<EOF > ${rootfs}/etc/apt/sources.list
# ${release}
#------------------------------------------------------------------------------
deb ${MIRROR} ${release} main contrib non-free
EOF
else
cat <<EOF > ${rootfs}/etc/apt/sources.list
# ${release}
#------------------------------------------------------------------------------
deb ${MIRROR} ${release} main contrib non-free
# ${release} security
#------------------------------------------------------------------------------
deb ${SECURITY_MIRROR} ${release}/updates main contrib non-free
# ${release} updates
#------------------------------------------------------------------------------
deb ${MIRROR} ${release}-updates main contrib non-free
# ${release} proposed updates
#------------------------------------------------------------------------------
deb ${MIRROR} ${release}-proposed-updates main contrib non-free
EOF
fi
}
download_debian()
{
cache=$1
arch=$2
release=$3
packages=\
sudo,\
ifupdown,\
locales,\
libui-dialog-perl,\
dialog,\
isc-dhcp-client,\
netbase,\
net-tools,\
iproute,\
openssh-server,\
vim,\
jed,\
jed-extra,\
ssh,\
curl,\
wget,\
bash-completion,\
manpages,\
man-db,\
psmisc,\
bind9-host,\
telnet,\
mtr-tiny,\
iputils-ping,\
ca-certificates
if [ ! -z "${ADDITIONAL_PACKAGES}" ]; then
packages=${ADDITIONAL_PACKAGES},${packages}
fi
echo "installing packages: ${packages}"
trap cleanup EXIT SIGHUP SIGINT SIGTERM
# check the mini debian was not already downloaded
partial=${cache}/partial
mkdir -p ${partial}
if [ $? -ne 0 ]; then
echo "Failed to create '${partial}' directory"
return 1
fi
# download a mini debian into a cache
echo "Downloading debian ${release} minimal ..."
debootstrap \
--variant=minbase \
--verbose \
--components=main,contrib,non-free \
--arch=${arch} \
--include=${packages} ${release} ${partial} ${MIRROR}
if [ $? -ne 0 ]; then
echo 'Failed to download the rootfs, aborting.'
return 1
fi
echo 'Installing updates'
write_sourceslist ${partial} ${arch} ${release}
chroot ${partial} apt-get update
if [ $? -ne 0 ]; then
echo 'Failed to update the apt cache'
return 1
fi
lxc-unshare -s MOUNT -- chroot ${partial} \
apt-get dist-upgrade -y || { suggest_flush; false; }
chroot ${partial} apt-get clean
mv ${partial} ${cache}/rootfs
trap EXIT
trap SIGINT
trap SIGTERM
trap SIGHUP
echo 'Download complete'
return 0
}
declare cache=`readlink -f .` \
arch=$1 \
release=$2
if [ -d ${cache}/rootfs ]; then
echo <<EOF
The rootfs cache has been built already, please remove it if you want to update
EOF
exit 1
fi
download_debian ${cache} ${arch} ${release}

View file

@ -1,195 +0,0 @@
#!/bin/bash
# This is a modified version of /usr/share/lxc/templates/lxc-debian
# that comes with Ubuntu 13.04 changed to suit vagrant-lxc needs
set -e
if [ -r /etc/default/lxc ]; then
. /etc/default/lxc
fi
SUITE=${SUITE:-wheezy}
MIRROR=${MIRROR:-http://ftp.debian.org/debian}
configure_debian()
{
rootfs=$1
hostname=$2
release=$2
# squeeze only has /dev/tty and /dev/tty0 by default,
# therefore creating missing device nodes for tty1-4.
for tty in $(seq 1 4); do
if [ ! -e $rootfs/dev/tty$tty ]; then
mknod $rootfs/dev/tty$tty c 4 $tty
fi
done
# configure the inittab
cat <<EOF > $rootfs/etc/inittab
id:3:initdefault:
si::sysinit:/etc/init.d/rcS
l0:0:wait:/etc/init.d/rc 0
l1:1:wait:/etc/init.d/rc 1
l2:2:wait:/etc/init.d/rc 2
l3:3:wait:/etc/init.d/rc 3
l4:4:wait:/etc/init.d/rc 4
l5:5:wait:/etc/init.d/rc 5
l6:6:wait:/etc/init.d/rc 6
# Normally not reached, but fallthrough in case of emergency.
z6:6:respawn:/sbin/sulogin
1:2345:respawn:/sbin/getty 38400 console
#c1:12345:respawn:/sbin/getty 38400 tty1 linux
c2:12345:respawn:/sbin/getty 38400 tty2 linux
c3:12345:respawn:/sbin/getty 38400 tty3 linux
c4:12345:respawn:/sbin/getty 38400 tty4 linux
p6::ctrlaltdel:/sbin/init 6
p0::powerfail:/sbin/init 0
EOF
# disable selinux in debian
mkdir -p $rootfs/selinux
echo 0 > $rootfs/selinux/enforce
# configure the network using the dhcp
cat <<EOF > $rootfs/etc/network/interfaces
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
EOF
# set the hostname
cat <<EOF > $rootfs/etc/hostname
$hostname
EOF
# set minimal hosts
cat <<EOF > $rootfs/etc/hosts
127.0.0.1 localhost
127.0.1.1 $hostname
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
EOF
# set default locale
cat <<EOF > $rootfs/etc/locale.gen
en_US.UTF-8 UTF-8
EOF
echo "default locale set to en_US.UTF-8 UTF-8"
chroot $rootfs locale-gen 'en_US.UTF-8' > /dev/null 2>&1
chroot $rootfs update-locale LANG='en_US.UTF-8'
echo 'update-locale done'
# remove pointless services in a container
chroot $rootfs /usr/sbin/update-rc.d -f checkroot.sh remove
chroot $rootfs /usr/sbin/update-rc.d -f umountfs remove
chroot $rootfs /usr/sbin/update-rc.d -f hwclock.sh remove
chroot $rootfs /usr/sbin/update-rc.d -f hwclockfirst.sh remove
echo "root:vagrant" | chroot $rootfs chpasswd
if ! (grep -q vagrant $rootfs/etc/passwd); then
chroot $rootfs useradd --create-home -s /bin/bash vagrant
echo "vagrant:vagrant" | chroot $rootfs chpasswd
chroot $rootfs adduser vagrant sudo >/dev/null 2>&1 || true
chroot $rootfs cp /etc/sudoers /etc/sudoers.orig >/dev/null 2>&1 || true
chroot $rootfs sed -i -e \
's/%sudo\s\+ALL=(ALL\(:ALL\)\?)\s\+ALL/%sudo ALL=NOPASSWD:ALL/g' \
/etc/sudoers >/dev/null 2>&1 || true
fi
return 0
}
cleanup()
{
rm -rf ${cache}/partial
rm -rf ${cache}/rootfs
}
add_ssh_key()
{
user=$1
if [ -n "$auth_key" -a -f "$auth_key" ]; then
u_path="/home/${user}/.ssh"
root_u_path="$rootfs/$u_path"
mkdir -p $root_u_path
cp $auth_key "$root_u_path/authorized_keys"
chroot $rootfs chown -R ${user}: "$u_path"
echo "Inserted SSH public key from $auth_key into /home/${user}/.ssh/authorized_keys"
fi
}
disable_tmp_cleanup() {
rootfs=$1
chroot $rootfs /usr/sbin/update-rc.d -f checkroot-bootclean.sh remove
chroot $rootfs /usr/sbin/update-rc.d -f mountall-bootclean.sh remove
chroot $rootfs /usr/sbin/update-rc.d -f mountnfs-bootclean.sh remove
}
release=wheezy # Default to the last Debian stable release
arch=$(uname -m)
# Code taken from debootstrap
if [ -x /usr/bin/dpkg ] && /usr/bin/dpkg --print-architecture >/dev/null 2>&1; then
arch=`/usr/bin/dpkg --print-architecture`
elif type udpkg >/dev/null 2>&1 && udpkg --print-architecture >/dev/null 2>&1; then
arch=`/usr/bin/udpkg --print-architecture`
else
arch=$(uname -m)
if [ "$arch" = "i686" ]; then
arch="i386"
elif [ "$arch" = "x86_64" ]; then
arch="amd64"
elif [ "$arch" = "armv7l" ]; then
arch="armel"
fi
fi
if [ "$(id -u)" != "0" ]; then
echo "This script should be run as 'root'"
exit 1
fi
declare cache=`readlink -f .` \
arch=$1 \
release=$2 \
auth_key=$3
# detect rootfs
cache=`readlink -f .`
rootfs="${cache}/rootfs"
configure_debian $rootfs $release
if [ $? -ne 0 ]; then
echo "failed to configure debian $release for a container"
exit 1
fi
add_ssh_key vagrant
# vagrant and / or plugins might mount some shared folders under /tmp by default
# (like puppet manifests) and we need to make sure no shared folder gets its
# contents removed because of it. For more information, please check:
# https://github.com/fgrehm/vagrant-lxc/issues/68
disable_tmp_cleanup $rootfs
echo ""
echo "##"
echo "# The default user is 'vagrant' with password 'vagrant'!"
echo "# Use the 'sudo' command to run tasks as root in the container."
echo "##"
echo ""

View file

@ -1,367 +0,0 @@
#!/bin/bash
# This is a modified version of /usr/share/lxc/templates/lxc-debian
# that comes with Ubuntu 13.04 changed to suit vagrant-lxc needs
set -e
if [ -r /etc/default/lxc ]; then
. /etc/default/lxc
fi
SUITE=${SUITE:-wheezy}
MIRROR=${MIRROR:-http://ftp.debian.org/debian}
configure_debian()
{
rootfs=$1
hostname=$2
release=$2
# squeeze only has /dev/tty and /dev/tty0 by default,
# therefore creating missing device nodes for tty1-4.
for tty in $(seq 1 4); do
if [ ! -e $rootfs/dev/tty$tty ]; then
mknod $rootfs/dev/tty$tty c 4 $tty
fi
done
# configure the inittab
cat <<EOF > $rootfs/etc/inittab
id:3:initdefault:
si::sysinit:/etc/init.d/rcS
l0:0:wait:/etc/init.d/rc 0
l1:1:wait:/etc/init.d/rc 1
l2:2:wait:/etc/init.d/rc 2
l3:3:wait:/etc/init.d/rc 3
l4:4:wait:/etc/init.d/rc 4
l5:5:wait:/etc/init.d/rc 5
l6:6:wait:/etc/init.d/rc 6
# Normally not reached, but fallthrough in case of emergency.
z6:6:respawn:/sbin/sulogin
1:2345:respawn:/sbin/getty 38400 console
#c1:12345:respawn:/sbin/getty 38400 tty1 linux
c2:12345:respawn:/sbin/getty 38400 tty2 linux
c3:12345:respawn:/sbin/getty 38400 tty3 linux
c4:12345:respawn:/sbin/getty 38400 tty4 linux
p6::ctrlaltdel:/sbin/init 6
p0::powerfail:/sbin/init 0
EOF
# disable selinux in debian
mkdir -p $rootfs/selinux
echo 0 > $rootfs/selinux/enforce
# configure the network using the dhcp
cat <<EOF > $rootfs/etc/network/interfaces
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
EOF
# set the hostname
cat <<EOF > $rootfs/etc/hostname
$hostname
EOF
# set minimal hosts
cat <<EOF > $rootfs/etc/hosts
127.0.0.1 localhost
127.0.1.1 $hostname
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
EOF
# set default locale
cat <<EOF > $rootfs/etc/locale.gen
en_US.UTF-8 UTF-8
EOF
echo "default locale set to en_US.UTF-8 UTF-8"
chroot $rootfs locale-gen 'en_US.UTF-8' > /dev/null 2>&1
chroot $rootfs update-locale LANG='en_US.UTF-8'
echo 'update-locale done'
# remove pointless services in a container
chroot $rootfs /usr/sbin/update-rc.d -f checkroot.sh remove
chroot $rootfs /usr/sbin/update-rc.d -f umountfs remove
chroot $rootfs /usr/sbin/update-rc.d -f hwclock.sh remove
chroot $rootfs /usr/sbin/update-rc.d -f hwclockfirst.sh remove
echo "root:vagrant" | chroot $rootfs chpasswd
if ! (grep -q vagrant $rootfs/etc/passwd); then
chroot $rootfs useradd --create-home -s /bin/bash vagrant
echo "vagrant:vagrant" | chroot $rootfs chpasswd
chroot $rootfs adduser vagrant sudo >/dev/null 2>&1 || true
chroot $rootfs cp /etc/sudoers /etc/sudoers.orig >/dev/null 2>&1 || true
chroot $rootfs sed -i -e \
's/%sudo\s\+ALL=(ALL\(:ALL\)\?)\s\+ALL/%sudo ALL=NOPASSWD:ALL/g' \
/etc/sudoers >/dev/null 2>&1 || true
fi
return 0
}
cleanup()
{
rm -rf ${cache}/partial
rm -rf ${cache}/rootfs
}
extract_rootfs()
{
tarball=$1
arch=$2
rootfs=$3
echo "Extracting $tarball ..."
mkdir -p $(dirname $rootfs)
(cd `dirname $rootfs` && tar xfz $tarball)
return 0
}
install_debian()
{
rootfs=$1
release=$2
tarball=$3
mkdir -p /var/lock/subsys/
(
flock -x 200
if [ $? -ne 0 ]; then
echo "Cache repository is busy."
return 1
fi
extract_rootfs $tarball $arch $rootfs
if [ $? -ne 0 ]; then
echo "Failed to copy rootfs"
return 1
fi
return 0
) 200>/var/lock/subsys/lxc
return $?
}
copy_configuration()
{
path=$1
rootfs=$2
name=$3
# if there is exactly one veth network entry, make sure it has an
# associated hwaddr.
nics=`grep -e '^lxc\.network\.type[ \t]*=[ \t]*veth' $path/config | wc -l`
if [ $nics -eq 1 ]; then
grep -q "^lxc.network.hwaddr" $path/config || cat <<EOF >> $path/config
lxc.network.hwaddr = 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//')
EOF
fi
grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config
cat <<EOF >> $path/config
lxc.tty = 4
lxc.pts = 1024
lxc.utsname = ${name}
# When using LXC with apparmor, uncomment the next line to run unconfined:
#lxc.aa_profile = unconfined
lxc.cgroup.devices.deny = a
# Allow any mknod (but not using the node)
lxc.cgroup.devices.allow = c *:* m
lxc.cgroup.devices.allow = b *:* m
# /dev/null and zero
lxc.cgroup.devices.allow = c 1:3 rwm
lxc.cgroup.devices.allow = c 1:5 rwm
# consoles
lxc.cgroup.devices.allow = c 5:1 rwm
lxc.cgroup.devices.allow = c 5:0 rwm
lxc.cgroup.devices.allow = c 4:0 rwm
lxc.cgroup.devices.allow = c 4:1 rwm
# /dev/{,u}random
lxc.cgroup.devices.allow = c 1:9 rwm
lxc.cgroup.devices.allow = c 1:8 rwm
lxc.cgroup.devices.allow = c 136:* rwm
lxc.cgroup.devices.allow = c 5:2 rwm
# rtc
lxc.cgroup.devices.allow = c 254:0 rwm
#fuse
lxc.cgroup.devices.allow = c 10:229 rwm
#tun
lxc.cgroup.devices.allow = c 10:200 rwm
#full
lxc.cgroup.devices.allow = c 1:7 rwm
#hpet
lxc.cgroup.devices.allow = c 10:228 rwm
#kvm
lxc.cgroup.devices.allow = c 10:232 rwm
# mounts point
lxc.mount.entry = proc proc proc nodev,noexec,nosuid 0 0
lxc.mount.entry = sysfs sys sysfs defaults 0 0
EOF
if [ $? -ne 0 ]; then
echo 'failed to add configuration'
return 1
fi
}
add_ssh_key()
{
user=$1
if [ -n "$auth_key" -a -f "$auth_key" ]; then
u_path="/home/${user}/.ssh"
root_u_path="$rootfs/$u_path"
mkdir -p $root_u_path
cp $auth_key "$root_u_path/authorized_keys"
chroot $rootfs chown -R ${user}: "$u_path"
echo "Inserted SSH public key from $auth_key into /home/${user}/.ssh/authorized_keys"
fi
}
disable_tmp_cleanup() {
rootfs=$1
chroot $rootfs /usr/sbin/update-rc.d -f checkroot-bootclean.sh remove
chroot $rootfs /usr/sbin/update-rc.d -f mountall-bootclean.sh remove
chroot $rootfs /usr/sbin/update-rc.d -f mountnfs-bootclean.sh remove
}
usage()
{
cat <<EOF
$1 -h|--help [-a|--arch] [-d|--debug]
[-F | --flush-cache] [-r|--release <release>] [ -S | --auth-key <keyfile>]
release: the debian release (e.g. wheezy): defaults to host release on debian, otherwise uses latest stable
arch: the container architecture (e.g. amd64): defaults to host arch
auth-key: SSH Public key file to inject into container
EOF
return 0
}
options=$(getopt -o a:b:hp:r:xn:Fd:C -l arch:,help,path:,release:,name:,flush-cache,auth-key:,debug:,tarball: -- "$@")
if [ $? -ne 0 ]; then
usage $(basename $0)
exit 1
fi
eval set -- "$options"
release=wheezy # Default to the last Debian stable release
arch=$(uname -m)
# Code taken from debootstrap
if [ -x /usr/bin/dpkg ] && /usr/bin/dpkg --print-architecture >/dev/null 2>&1; then
arch=`/usr/bin/dpkg --print-architecture`
elif type udpkg >/dev/null 2>&1 && udpkg --print-architecture >/dev/null 2>&1; then
arch=`/usr/bin/udpkg --print-architecture`
else
arch=$(uname -m)
if [ "$arch" = "i686" ]; then
arch="i386"
elif [ "$arch" = "x86_64" ]; then
arch="amd64"
elif [ "$arch" = "armv7l" ]; then
arch="armel"
fi
fi
debug=0
hostarch=$arch
while true
do
case "$1" in
-h|--help) usage $0 && exit 0;;
-p|--path) path=$2; shift 2;;
-n|--name) name=$2; shift 2;;
-T|--tarball) tarball=$2; shift 2;;
-r|--release) release=$2; shift 2;;
-S|--auth-key) auth_key=$2; shift 2;;
-a|--arch) arch=$2; shift 2;;
-d|--debug) debug=1; shift 1;;
--) shift 1; break ;;
*) break ;;
esac
done
if [ $debug -eq 1 ]; then
set -x
fi
if [ "$arch" == "i686" ]; then
arch=i386
fi
if [ $hostarch = "i386" -a $arch = "amd64" ]; then
echo "can't create amd64 container on i386"
exit 1
fi
if [ -z "$path" ]; then
echo "'path' parameter is required"
exit 1
fi
if [ "$(id -u)" != "0" ]; then
echo "This script should be run as 'root'"
exit 1
fi
# detect rootfs
config="$path/config"
if grep -q '^lxc.rootfs' $config 2>/dev/null ; then
rootfs=`grep 'lxc.rootfs =' $config | awk -F= '{ print $2 }'`
else
rootfs=$path/rootfs
fi
install_debian $rootfs $release $tarball
if [ $? -ne 0 ]; then
echo "failed to install debian $release"
exit 1
fi
configure_debian $rootfs $release
if [ $? -ne 0 ]; then
echo "failed to configure debian $release for a container"
exit 1
fi
copy_configuration $path $rootfs $name
if [ $? -ne 0 ]; then
echo "failed write configuration file"
exit 1
fi
add_ssh_key vagrant
# vagrant and / or plugins might mount some shared folders under /tmp by default
# (like puppet manifests) and we need to make sure no shared folder gets its
# contents removed because of it. For more information, please check:
# https://github.com/fgrehm/vagrant-lxc/issues/68
disable_tmp_cleanup $rootfs
echo ""
echo "##"
echo "# The default user is 'vagrant' with password 'vagrant'!"
echo "# Use the 'sudo' command to run tasks as root in the container."
echo "##"
echo ""

View file

@ -1,9 +0,0 @@
{
"provider": "lxc",
"version": "2",
"template-opts": {
"--arch": "ARCH",
"--release": "RELEASE"
}
}

View file

@ -1,113 +0,0 @@
#!/bin/bash
# This is the code extracted from /usr/share/lxc/templates/lxc-ubuntu
# that comes with Ubuntu 12.10 which is responsible for downloading the
# rootfs files / packages
set -e
suggest_flush()
{
echo "Container upgrade failed. The container cache may be out of date,"
echo "in which case flushing the case (see -F in the hep output) may help."
}
cleanup()
{
rm -rf $cache/partial
rm -rf $cache/rootfs
}
write_sourceslist()
{
# $1 => path to the rootfs
MIRROR=${MIRROR:-http://archive.ubuntu.com/ubuntu}
SECURITY_MIRROR=${SECURITY_MIRROR:-http://security.ubuntu.com/ubuntu}
cat >> "$1/etc/apt/sources.list" << EOF
deb $MIRROR ${release} main restricted universe multiverse
deb $MIRROR ${release}-updates main restricted universe multiverse
deb $SECURITY_MIRROR ${release}-security main restricted universe multiverse
EOF
}
download_ubuntu()
{
packages=vim,ssh,curl,wget,bash-completion,manpages,man-db,psmisc
# Try to guess a list of langpacks to install
langpacks="language-pack-en"
if which dpkg >/dev/null 2>&1; then
langpacks=`(echo $langpacks &&
dpkg -l | grep -E "^ii language-pack-[a-z]* " |
cut -d ' ' -f3) | sort -u`
fi
packages="$packages,$(echo $langpacks | sed 's/ /,/g')"
echo "installing packages: $packages"
trap cleanup EXIT SIGHUP SIGINT SIGTERM
# check the mini ubuntu was not already downloaded
mkdir -p "$cache/partial"
if [ $? -ne 0 ]; then
echo "Failed to create '$cache/partial' directory"
return 1
fi
# download a mini ubuntu into a cache
echo "Downloading ubuntu $release minimal ..."
if [ -n "$(which qemu-debootstrap)" ]; then
qemu-debootstrap --verbose --components=main,universe --arch=$arch --include=$packages $release $cache/partial $MIRROR
else
debootstrap --verbose --components=main,universe --arch=$arch --include=$packages $release $cache/partial $MIRROR
fi
if [ $? -ne 0 ]; then
echo "Failed to download the rootfs, aborting."
return 1
fi
# Serge isn't sure whether we should avoid doing this when
# $release == `distro-info -d`
echo "Installing updates"
> $cache/partial/etc/apt/sources.list
write_sourceslist $cache/partial/ $arch
chroot "$1/partial" apt-get update
if [ $? -ne 0 ]; then
echo "Failed to update the apt cache"
return 1
fi
cat > "$1/partial"/usr/sbin/policy-rc.d << EOF
#!/bin/sh
exit 101
EOF
chmod +x "$1/partial"/usr/sbin/policy-rc.d
lxc-unshare -s MOUNT -- chroot "$1/partial" apt-get dist-upgrade -y || { suggest_flush; false; }
rm -f "$1/partial"/usr/sbin/policy-rc.d
chroot "$1/partial" apt-get clean
mv "$1/partial" "$1/rootfs"
trap EXIT
trap SIGINT
trap SIGTERM
trap SIGHUP
echo "Download complete"
return 0
}
declare cache=`readlink -f .` \
arch=$1 \
release=$2
if [ -d "${cache}/rootfs" ]; then
echo 'The rootfs cache has been built already, please remove it if you want to update'
exit 1
fi
download_ubuntu $cache $arch $release

View file

@ -1,374 +0,0 @@
#!/bin/bash
# This is a modified version of /usr/share/lxc/templates/lxc-ubuntu
# that comes with Ubuntu 13.04 changed to suit vagrant-lxc needs
#
# template script for generating ubuntu container for LXC
#
# This script consolidates and extends the existing lxc ubuntu scripts
#
# Copyright © 2011 Serge Hallyn <serge.hallyn@canonical.com>
# Copyright © 2010 Wilhelm Meier
# Author: Wilhelm Meier <wilhelm.meier@fh-kl.de>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2, as
# published by the Free Software Foundation.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
set -e
if [ -r /etc/default/lxc ]; then
. /etc/default/lxc
fi
configure_ubuntu()
{
rootfs=$1
release=$2
hostname=$2
# configure the network using the dhcp
cat <<EOF > $rootfs/etc/network/interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
# The loopback network interface
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
EOF
# set the hostname
cat <<EOF > $rootfs/etc/hostname
$hostname
EOF
# set minimal hosts
cat <<EOF > $rootfs/etc/hosts
127.0.0.1 localhost
127.0.1.1 $hostname
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
EOF
if [ ! -f $rootfs/etc/init/container-detect.conf ]; then
# suppress log level output for udev
sed -i "s/=\"err\"/=0/" $rootfs/etc/udev/udev.conf
# remove jobs for consoles 5 and 6 since we only create 4 consoles in
# this template
rm -f $rootfs/etc/init/tty{5,6}.conf
fi
if ! (grep -q vagrant $rootfs/etc/passwd); then
chroot $rootfs useradd --create-home -s /bin/bash vagrant
echo "vagrant:vagrant" | chroot $rootfs chpasswd
fi
# make sure we have the current locale defined in the container
chroot $rootfs locale-gen en_US.UTF-8
chroot $rootfs update-locale LANG=en_US.UTF-8
return 0
}
# finish setting up the user in the container by injecting ssh key and
# adding sudo group membership.
# passed-in user is 'vagrant'
finalize_user()
{
user=$1
sudo_version=$(chroot $rootfs dpkg-query -W -f='${Version}' sudo)
if chroot $rootfs dpkg --compare-versions $sudo_version gt "1.8.3p1-1"; then
groups="sudo"
else
groups="sudo admin"
fi
for group in $groups; do
chroot $rootfs groupadd --system $group >/dev/null 2>&1 || true
chroot $rootfs adduser ${user} $group >/dev/null 2>&1 || true
done
chroot $rootfs cp /etc/sudoers /etc/sudoers.orig >/dev/null 2>&1 || true
chroot $rootfs sed -i -e 's/%sudo\s\+ALL=(ALL:ALL)\s\+ALL/%sudo ALL=NOPASSWD:ALL/g' /etc/sudoers >/dev/null 2>&1 || true
if [ -n "$auth_key" -a -f "$auth_key" ]; then
u_path="/home/${user}/.ssh"
root_u_path="$rootfs/$u_path"
mkdir -p $root_u_path
cp $auth_key "$root_u_path/authorized_keys"
chroot $rootfs chown -R ${user}: "$u_path"
echo "Inserted SSH public key from $auth_key into /home/${user}/.ssh/authorized_keys"
fi
return 0
}
write_sourceslist()
{
# $1 => path to the rootfs
# $2 => architecture we want to add
# $3 => whether to use the multi-arch syntax or not
case $2 in
amd64|i386)
MIRROR=${MIRROR:-http://archive.ubuntu.com/ubuntu}
SECURITY_MIRROR=${SECURITY_MIRROR:-http://security.ubuntu.com/ubuntu}
;;
*)
MIRROR=${MIRROR:-http://ports.ubuntu.com/ubuntu-ports}
SECURITY_MIRROR=${SECURITY_MIRROR:-http://ports.ubuntu.com/ubuntu-ports}
;;
esac
if [ -n "$3" ]; then
cat >> "$1/etc/apt/sources.list" << EOF
deb [arch=$2] $MIRROR ${release} main restricted universe multiverse
deb [arch=$2] $MIRROR ${release}-updates main restricted universe multiverse
deb [arch=$2] $SECURITY_MIRROR ${release}-security main restricted universe multiverse
deb-src [arch=$2] $MIRROR ${release} main restricted universe multiverse
deb-src [arch=$2] $MIRROR ${release}-updates main restricted universe multiverse
deb-src [arch=$2] $SECURITY_MIRROR ${release}-security main restricted universe multiverse
EOF
else
cat >> "$1/etc/apt/sources.list" << EOF
deb $MIRROR ${release} main restricted universe multiverse
deb $MIRROR ${release}-updates main restricted universe multiverse
deb $SECURITY_MIRROR ${release}-security main restricted universe multiverse
deb-src $MIRROR ${release} main restricted universe multiverse
deb-src $MIRROR ${release}-updates main restricted universe multiverse
deb-src $SECURITY_MIRROR ${release}-security main restricted universe multiverse
EOF
fi
}
trim()
{
rootfs=$1
release=$2
# provide the lxc service
cat <<EOF > $rootfs/etc/init/lxc.conf
# fake some events needed for correct startup other services
description "Container Upstart"
start on startup
script
rm -rf /var/run/*.pid
rm -rf /var/run/network/*
/sbin/initctl emit stopped JOB=udevtrigger --no-wait
/sbin/initctl emit started JOB=udev --no-wait
end script
EOF
# fix buggus runlevel with sshd
cat <<EOF > $rootfs/etc/init/ssh.conf
# ssh - OpenBSD Secure Shell server
#
# The OpenSSH server provides secure shell access to the system.
description "OpenSSH server"
start on filesystem
stop on runlevel [!2345]
expect fork
respawn
respawn limit 10 5
umask 022
# replaces SSHD_OOM_ADJUST in /etc/default/ssh
oom never
pre-start script
test -x /usr/sbin/sshd || { stop; exit 0; }
test -e /etc/ssh/sshd_not_to_be_run && { stop; exit 0; }
test -c /dev/null || { stop; exit 0; }
mkdir -p -m0755 /var/run/sshd
end script
# if you used to set SSHD_OPTS in /etc/default/ssh, you can change the
# 'exec' line here instead
exec /usr/sbin/sshd
EOF
cat <<EOF > $rootfs/etc/init/console.conf
# console - getty
#
# This service maintains a console on tty1 from the point the system is
# started until it is shut down again.
start on stopped rc RUNLEVEL=[2345]
stop on runlevel [!2345]
respawn
exec /sbin/getty -8 38400 /dev/console
EOF
cat <<EOF > $rootfs/lib/init/fstab
# /lib/init/fstab: cleared out for bare-bones lxc
EOF
# remove pointless services in a container
chroot $rootfs /usr/sbin/update-rc.d -f ondemand remove
chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls u*.conf); do mv $f $f.orig; done'
chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls tty[2-9].conf); do mv $f $f.orig; done'
chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls plymouth*.conf); do mv $f $f.orig; done'
chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls hwclock*.conf); do mv $f $f.orig; done'
chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls module*.conf); do mv $f $f.orig; done'
# if this isn't lucid, then we need to twiddle the network upstart bits :(
if [ $release != "lucid" ]; then
sed -i 's/^.*emission handled.*$/echo Emitting lo/' $rootfs/etc/network/if-up.d/upstart
fi
}
post_process()
{
rootfs=$1
release=$2
trim_container=$3
if [[ $trim_container -eq 1 ]]; then
trim $rootfs $release
elif [ ! -f $rootfs/etc/init/container-detect.conf ]; then
# Make sure we have a working resolv.conf
cresolvonf="${rootfs}/etc/resolv.conf"
mv $cresolvonf ${cresolvonf}.lxcbak
cat /etc/resolv.conf > ${cresolvonf}
# for lucid, if not trimming, then add the ubuntu-virt
# ppa and install lxcguest
if [ $release = "lucid" ]; then
chroot $rootfs apt-get update
chroot $rootfs apt-get install --force-yes -y python-software-properties
chroot $rootfs add-apt-repository ppa:ubuntu-virt/ppa
fi
chroot $rootfs apt-get update
chroot $rootfs apt-get install --force-yes -y lxcguest
# Restore old resolv.conf
rm -f ${cresolvonf}
mv ${cresolvonf}.lxcbak ${cresolvonf}
fi
# If the container isn't running a native architecture, setup multiarch
if [ -x "$(ls -1 ${rootfs}/usr/bin/qemu-*-static 2>/dev/null)" ]; then
dpkg_version=$(chroot $rootfs dpkg-query -W -f='${Version}' dpkg)
if chroot $rootfs dpkg --compare-versions $dpkg_version ge "1.16.2"; then
chroot $rootfs dpkg --add-architecture ${hostarch}
else
mkdir -p ${rootfs}/etc/dpkg/dpkg.cfg.d
echo "foreign-architecture ${hostarch}" > ${rootfs}/etc/dpkg/dpkg.cfg.d/lxc-multiarch
fi
# Save existing value of MIRROR and SECURITY_MIRROR
DEFAULT_MIRROR=$MIRROR
DEFAULT_SECURITY_MIRROR=$SECURITY_MIRROR
# Write a new sources.list containing both native and multiarch entries
> ${rootfs}/etc/apt/sources.list
write_sourceslist $rootfs $arch "native"
MIRROR=$DEFAULT_MIRROR
SECURITY_MIRROR=$DEFAULT_SECURITY_MIRROR
write_sourceslist $rootfs $hostarch "multiarch"
# Finally update the lists and install upstart using the host architecture
chroot $rootfs apt-get update
chroot $rootfs apt-get install --force-yes -y --no-install-recommends upstart:${hostarch} mountall:${hostarch} iproute:${hostarch} isc-dhcp-client:${hostarch}
fi
# rmdir /dev/shm for containers that have /run/shm
# I'm afraid of doing rm -rf $rootfs/dev/shm, in case it did
# get bind mounted to the host's /run/shm. So try to rmdir
# it, and in case that fails move it out of the way.
if [ ! -L $rootfs/dev/shm ] && [ -d $rootfs/run/shm ] && [ -e $rootfs/dev/shm ]; then
mv $rootfs/dev/shm $rootfs/dev/shm.bak
ln -s /run/shm $rootfs/dev/shm
fi
}
release=precise # Default to the last Ubuntu LTS release for non-Ubuntu systems
if [ -f /etc/lsb-release ]; then
. /etc/lsb-release
if [ "$DISTRIB_ID" = "Ubuntu" ]; then
release=$DISTRIB_CODENAME
fi
fi
arch=$(uname -m)
# Code taken from debootstrap
if [ -x /usr/bin/dpkg ] && /usr/bin/dpkg --print-architecture >/dev/null 2>&1; then
arch=`/usr/bin/dpkg --print-architecture`
elif type udpkg >/dev/null 2>&1 && udpkg --print-architecture >/dev/null 2>&1; then
arch=`/usr/bin/udpkg --print-architecture`
else
arch=$(uname -m)
if [ "$arch" = "i686" ]; then
arch="i386"
elif [ "$arch" = "x86_64" ]; then
arch="amd64"
elif [ "$arch" = "armv7l" ]; then
arch="armel"
fi
fi
if [ "$(id -u)" != "0" ]; then
echo "This script should be run as 'root'"
exit 1
fi
declare cache=`readlink -f .` \
arch=$1 \
release=$2 \
auth_key=$3
# detect rootfs
cache=`readlink -f .`
rootfs="${cache}/rootfs"
configure_ubuntu $rootfs $release
if [ $? -ne 0 ]; then
echo "failed to configure ubuntu $release for a container"
exit 1
fi
post_process $rootfs $release $trim_container
finalize_user vagrant
echo ""
echo "##"
echo "# The default user is 'vagrant' with password 'vagrant'!"
echo "# Use the 'sudo' command to run tasks as root in the container."
echo "##"
echo ""

View file

@ -1,559 +0,0 @@
#!/bin/bash
# This is a modified version of /usr/share/lxc/templates/lxc-ubuntu
# that comes with Ubuntu 13.04 changed to suit vagrant-lxc needs
#
# template script for generating ubuntu container for LXC
#
# This script consolidates and extends the existing lxc ubuntu scripts
#
# Copyright © 2011 Serge Hallyn <serge.hallyn@canonical.com>
# Copyright © 2010 Wilhelm Meier
# Author: Wilhelm Meier <wilhelm.meier@fh-kl.de>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2, as
# published by the Free Software Foundation.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
set -e
if [ -r /etc/default/lxc ]; then
. /etc/default/lxc
fi
configure_ubuntu()
{
rootfs=$1
release=$2
hostname=$2
# configure the network using the dhcp
cat <<EOF > $rootfs/etc/network/interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
# The loopback network interface
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
EOF
# set the hostname
cat <<EOF > $rootfs/etc/hostname
$hostname
EOF
# set minimal hosts
cat <<EOF > $rootfs/etc/hosts
127.0.0.1 localhost
127.0.1.1 $hostname
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
EOF
if [ ! -f $rootfs/etc/init/container-detect.conf ]; then
# suppress log level output for udev
sed -i "s/=\"err\"/=0/" $rootfs/etc/udev/udev.conf
# remove jobs for consoles 5 and 6 since we only create 4 consoles in
# this template
rm -f $rootfs/etc/init/tty{5,6}.conf
fi
if ! (grep -q vagrant $rootfs/etc/passwd); then
chroot $rootfs useradd --create-home -s /bin/bash vagrant
echo "vagrant:vagrant" | chroot $rootfs chpasswd
fi
# make sure we have the current locale defined in the container
chroot $rootfs locale-gen en_US.UTF-8
chroot $rootfs update-locale LANG=en_US.UTF-8
return 0
}
# finish setting up the user in the container by injecting ssh key and
# adding sudo group membership.
# passed-in user is 'vagrant'
finalize_user()
{
user=$1
sudo_version=$(chroot $rootfs dpkg-query -W -f='${Version}' sudo)
if chroot $rootfs dpkg --compare-versions $sudo_version gt "1.8.3p1-1"; then
groups="sudo"
else
groups="sudo admin"
fi
for group in $groups; do
chroot $rootfs groupadd --system $group >/dev/null 2>&1 || true
chroot $rootfs adduser ${user} $group >/dev/null 2>&1 || true
done
chroot $rootfs cp /etc/sudoers /etc/sudoers.orig >/dev/null 2>&1 || true
chroot $rootfs sed -i -e 's/%sudo\s\+ALL=(ALL:ALL)\s\+ALL/%sudo ALL=NOPASSWD:ALL/g' /etc/sudoers >/dev/null 2>&1 || true
if [ -n "$auth_key" -a -f "$auth_key" ]; then
u_path="/home/${user}/.ssh"
root_u_path="$rootfs/$u_path"
mkdir -p $root_u_path
cp $auth_key "$root_u_path/authorized_keys"
chroot $rootfs chown -R ${user}: "$u_path"
echo "Inserted SSH public key from $auth_key into /home/${user}/.ssh/authorized_keys"
fi
return 0
}
write_sourceslist()
{
# $1 => path to the rootfs
# $2 => architecture we want to add
# $3 => whether to use the multi-arch syntax or not
case $2 in
amd64|i386)
MIRROR=${MIRROR:-http://archive.ubuntu.com/ubuntu}
SECURITY_MIRROR=${SECURITY_MIRROR:-http://security.ubuntu.com/ubuntu}
;;
*)
MIRROR=${MIRROR:-http://ports.ubuntu.com/ubuntu-ports}
SECURITY_MIRROR=${SECURITY_MIRROR:-http://ports.ubuntu.com/ubuntu-ports}
;;
esac
if [ -n "$3" ]; then
cat >> "$1/etc/apt/sources.list" << EOF
deb [arch=$2] $MIRROR ${release} main restricted universe multiverse
deb [arch=$2] $MIRROR ${release}-updates main restricted universe multiverse
deb [arch=$2] $SECURITY_MIRROR ${release}-security main restricted universe multiverse
EOF
else
cat >> "$1/etc/apt/sources.list" << EOF
deb $MIRROR ${release} main restricted universe multiverse
deb $MIRROR ${release}-updates main restricted universe multiverse
deb $SECURITY_MIRROR ${release}-security main restricted universe multiverse
EOF
fi
}
extract_rootfs()
{
tarball=$1
arch=$2
rootfs=$3
echo "Extracting $tarball ..."
mkdir -p $(dirname $rootfs)
(cd `dirname $rootfs` && tar xfz $tarball)
return 0
}
install_ubuntu()
{
rootfs=$1
release=$2
tarball=$3
mkdir -p /var/lock/subsys/
(
flock -x 200
if [ $? -ne 0 ]; then
echo "Cache repository is busy."
return 1
fi
extract_rootfs $tarball $arch $rootfs
if [ $? -ne 0 ]; then
echo "Failed to copy rootfs"
return 1
fi
return 0
) 200>/var/lock/subsys/lxc
return $?
}
copy_configuration()
{
path=$1
rootfs=$2
name=$3
arch=$4
if [ $arch = "i386" ]; then
arch="i686"
fi
ttydir=""
if [ -f $rootfs/etc/init/container-detect.conf ]; then
ttydir=" lxc"
fi
# if there is exactly one veth network entry, make sure it has an
# associated hwaddr.
nics=`grep -e '^lxc\.network\.type[ \t]*=[ \t]*veth' $path/config | wc -l`
if [ $nics -eq 1 ]; then
grep -q "^lxc.network.hwaddr" $path/config || sed -i -e "/^lxc\.network\.type[ \t]*=[ \t]*veth/a lxc.network.hwaddr = 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//')" $path/config
fi
grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config
cat <<EOF >> $path/config
lxc.mount = $path/fstab
lxc.pivotdir = lxc_putold
lxc.devttydir =$ttydir
lxc.tty = 4
lxc.pts = 1024
lxc.utsname = $name
lxc.arch = $arch
lxc.cap.drop = sys_module mac_admin mac_override
# When using LXC with apparmor, uncomment the next line to run unconfined:
#lxc.aa_profile = unconfined
lxc.cgroup.devices.deny = a
# Allow any mknod (but not using the node)
lxc.cgroup.devices.allow = c *:* m
lxc.cgroup.devices.allow = b *:* m
# /dev/null and zero
lxc.cgroup.devices.allow = c 1:3 rwm
lxc.cgroup.devices.allow = c 1:5 rwm
# consoles
lxc.cgroup.devices.allow = c 5:1 rwm
lxc.cgroup.devices.allow = c 5:0 rwm
#lxc.cgroup.devices.allow = c 4:0 rwm
#lxc.cgroup.devices.allow = c 4:1 rwm
# /dev/{,u}random
lxc.cgroup.devices.allow = c 1:9 rwm
lxc.cgroup.devices.allow = c 1:8 rwm
lxc.cgroup.devices.allow = c 136:* rwm
lxc.cgroup.devices.allow = c 5:2 rwm
# rtc
lxc.cgroup.devices.allow = c 254:0 rwm
#fuse
lxc.cgroup.devices.allow = c 10:229 rwm
#tun
lxc.cgroup.devices.allow = c 10:200 rwm
#full
lxc.cgroup.devices.allow = c 1:7 rwm
#hpet
lxc.cgroup.devices.allow = c 10:228 rwm
#kvm
lxc.cgroup.devices.allow = c 10:232 rwm
EOF
cat <<EOF > $path/fstab
proc proc proc nodev,noexec,nosuid 0 0
sysfs sys sysfs defaults 0 0
EOF
if [ $? -ne 0 ]; then
echo "Failed to add configuration"
return 1
fi
return 0
}
trim()
{
rootfs=$1
release=$2
# provide the lxc service
cat <<EOF > $rootfs/etc/init/lxc.conf
# fake some events needed for correct startup other services
description "Container Upstart"
start on startup
script
rm -rf /var/run/*.pid
rm -rf /var/run/network/*
/sbin/initctl emit stopped JOB=udevtrigger --no-wait
/sbin/initctl emit started JOB=udev --no-wait
end script
EOF
# fix buggus runlevel with sshd
cat <<EOF > $rootfs/etc/init/ssh.conf
# ssh - OpenBSD Secure Shell server
#
# The OpenSSH server provides secure shell access to the system.
description "OpenSSH server"
start on filesystem
stop on runlevel [!2345]
expect fork
respawn
respawn limit 10 5
umask 022
# replaces SSHD_OOM_ADJUST in /etc/default/ssh
oom never
pre-start script
test -x /usr/sbin/sshd || { stop; exit 0; }
test -e /etc/ssh/sshd_not_to_be_run && { stop; exit 0; }
test -c /dev/null || { stop; exit 0; }
mkdir -p -m0755 /var/run/sshd
end script
# if you used to set SSHD_OPTS in /etc/default/ssh, you can change the
# 'exec' line here instead
exec /usr/sbin/sshd
EOF
cat <<EOF > $rootfs/etc/init/console.conf
# console - getty
#
# This service maintains a console on tty1 from the point the system is
# started until it is shut down again.
start on stopped rc RUNLEVEL=[2345]
stop on runlevel [!2345]
respawn
exec /sbin/getty -8 38400 /dev/console
EOF
cat <<EOF > $rootfs/lib/init/fstab
# /lib/init/fstab: cleared out for bare-bones lxc
EOF
# remove pointless services in a container
chroot $rootfs /usr/sbin/update-rc.d -f ondemand remove
chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls u*.conf); do mv $f $f.orig; done'
chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls tty[2-9].conf); do mv $f $f.orig; done'
chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls plymouth*.conf); do mv $f $f.orig; done'
chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls hwclock*.conf); do mv $f $f.orig; done'
chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls module*.conf); do mv $f $f.orig; done'
# if this isn't lucid, then we need to twiddle the network upstart bits :(
if [ $release != "lucid" ]; then
sed -i 's/^.*emission handled.*$/echo Emitting lo/' $rootfs/etc/network/if-up.d/upstart
fi
}
post_process()
{
rootfs=$1
release=$2
trim_container=$3
if [ $trim_container -eq 1 ]; then
trim $rootfs $release
elif [ ! -f $rootfs/etc/init/container-detect.conf ]; then
# Make sure we have a working resolv.conf
cresolvonf="${rootfs}/etc/resolv.conf"
mv $cresolvonf ${cresolvonf}.lxcbak
cat /etc/resolv.conf > ${cresolvonf}
# for lucid, if not trimming, then add the ubuntu-virt
# ppa and install lxcguest
if [ $release = "lucid" ]; then
chroot $rootfs apt-get update
chroot $rootfs apt-get install --force-yes -y python-software-properties
chroot $rootfs add-apt-repository ppa:ubuntu-virt/ppa
fi
chroot $rootfs apt-get update
chroot $rootfs apt-get install --force-yes -y lxcguest
# Restore old resolv.conf
rm -f ${cresolvonf}
mv ${cresolvonf}.lxcbak ${cresolvonf}
fi
# If the container isn't running a native architecture, setup multiarch
if [ -x "$(ls -1 ${rootfs}/usr/bin/qemu-*-static 2>/dev/null)" ]; then
dpkg_version=$(chroot $rootfs dpkg-query -W -f='${Version}' dpkg)
if chroot $rootfs dpkg --compare-versions $dpkg_version ge "1.16.2"; then
chroot $rootfs dpkg --add-architecture ${hostarch}
else
mkdir -p ${rootfs}/etc/dpkg/dpkg.cfg.d
echo "foreign-architecture ${hostarch}" > ${rootfs}/etc/dpkg/dpkg.cfg.d/lxc-multiarch
fi
# Save existing value of MIRROR and SECURITY_MIRROR
DEFAULT_MIRROR=$MIRROR
DEFAULT_SECURITY_MIRROR=$SECURITY_MIRROR
# Write a new sources.list containing both native and multiarch entries
> ${rootfs}/etc/apt/sources.list
write_sourceslist $rootfs $arch "native"
MIRROR=$DEFAULT_MIRROR
SECURITY_MIRROR=$DEFAULT_SECURITY_MIRROR
write_sourceslist $rootfs $hostarch "multiarch"
# Finally update the lists and install upstart using the host architecture
chroot $rootfs apt-get update
chroot $rootfs apt-get install --force-yes -y --no-install-recommends upstart:${hostarch} mountall:${hostarch} iproute:${hostarch} isc-dhcp-client:${hostarch}
fi
# rmdir /dev/shm for containers that have /run/shm
# I'm afraid of doing rm -rf $rootfs/dev/shm, in case it did
# get bind mounted to the host's /run/shm. So try to rmdir
# it, and in case that fails move it out of the way.
if [ ! -L $rootfs/dev/shm ] && [ -d $rootfs/run/shm ] && [ -e $rootfs/dev/shm ]; then
mv $rootfs/dev/shm $rootfs/dev/shm.bak
ln -s /run/shm $rootfs/dev/shm
fi
}
usage()
{
cat <<EOF
$1 -h|--help [-a|--arch] [--trim] [-d|--debug]
[-F | --flush-cache] [-r|--release <release>] [ -S | --auth-key <keyfile>]
release: the ubuntu release (e.g. precise): defaults to host release on ubuntu, otherwise uses latest LTS
trim: make a minimal (faster, but not upgrade-safe) container
arch: the container architecture (e.g. amd64): defaults to host arch
auth-key: SSH Public key file to inject into container
EOF
return 0
}
options=$(getopt -o a:b:hp:r:xn:FS:d:C -l arch:,help,path:,release:,trim,name:,flush-cache,auth-key:,debug:,tarball: -- "$@")
if [ $? -ne 0 ]; then
usage $(basename $0)
exit 1
fi
eval set -- "$options"
release=precise # Default to the last Ubuntu LTS release for non-Ubuntu systems
if [ -f /etc/lsb-release ]; then
. /etc/lsb-release
if [ "$DISTRIB_ID" = "Ubuntu" ]; then
release=$DISTRIB_CODENAME
fi
fi
arch=$(uname -m)
# Code taken from debootstrap
if [ -x /usr/bin/dpkg ] && /usr/bin/dpkg --print-architecture >/dev/null 2>&1; then
arch=`/usr/bin/dpkg --print-architecture`
elif type udpkg >/dev/null 2>&1 && udpkg --print-architecture >/dev/null 2>&1; then
arch=`/usr/bin/udpkg --print-architecture`
else
arch=$(uname -m)
if [ "$arch" = "i686" ]; then
arch="i386"
elif [ "$arch" = "x86_64" ]; then
arch="amd64"
elif [ "$arch" = "armv7l" ]; then
arch="armel"
fi
fi
debug=0
trim_container=0
hostarch=$arch
while true
do
case "$1" in
-h|--help) usage $0 && exit 0;;
-p|--path) path=$2; shift 2;;
-n|--name) name=$2; shift 2;;
-T|--tarball) tarball=$2; shift 2;;
-r|--release) release=$2; shift 2;;
-a|--arch) arch=$2; shift 2;;
-x|--trim) trim_container=1; shift 1;;
-S|--auth-key) auth_key=$2; shift 2;;
-d|--debug) debug=1; shift 1;;
--) shift 1; break ;;
*) break ;;
esac
done
if [ $debug -eq 1 ]; then
set -x
fi
if [ "$arch" == "i686" ]; then
arch=i386
fi
if [ $hostarch = "i386" -a $arch = "amd64" ]; then
echo "can't create amd64 container on i386"
exit 1
fi
if [ -z "$path" ]; then
echo "'path' parameter is required"
exit 1
fi
if [ "$(id -u)" != "0" ]; then
echo "This script should be run as 'root'"
exit 1
fi
# detect rootfs
config="$path/config"
if grep -q '^lxc.rootfs' $config 2>/dev/null ; then
rootfs=`grep 'lxc.rootfs =' $config | awk -F= '{ print $2 }'`
else
rootfs=$path/rootfs
fi
install_ubuntu $rootfs $release $tarball
if [ $? -ne 0 ]; then
echo "failed to install ubuntu $release"
exit 1
fi
configure_ubuntu $rootfs $release
if [ $? -ne 0 ]; then
echo "failed to configure ubuntu $release for a container"
exit 1
fi
copy_configuration $path $rootfs $name $arch
if [ $? -ne 0 ]; then
echo "failed write configuration file"
exit 1
fi
post_process $rootfs $release $trim_container
finalize_user vagrant
echo ""
echo "##"
echo "# The default user is 'vagrant' with password 'vagrant'!"
echo "# Use the 'sudo' command to run tasks as root in the container."
echo "##"
echo ""

View file

@ -1,9 +0,0 @@
{
"provider": "lxc",
"version": "2",
"template-opts": {
"--arch": "ARCH",
"--release": "RELEASE"
}
}

View file

@ -1,115 +0,0 @@
require 'pathname'
require 'rake/tasklib'
load 'tasks/boxes.v2.rake'
class BuildGenericBoxTaskV3 < BuildGenericBoxTaskV2
def build
require 'vagrant'
check_if_box_has_been_built!
FileUtils.mkdir_p 'boxes/temp' unless File.exist? 'base/temp'
check_for_partially_built_box!
pwd = Dir.pwd
sh 'mkdir -p boxes/temp/'
Dir.chdir 'boxes/temp' do
download
install_cfg_engines
finalize
prepare_package_contents pwd
sh 'sudo rm -rf rootfs'
sh "tar -czf tmp-package.box ./*"
end
sh 'mkdir -p boxes/output'
sh "cp boxes/temp/tmp-package.box boxes/output/#{@file}"
sh "rm -rf boxes/temp"
end
def finalize
auth_key = Vagrant.source_root.join('keys', 'vagrant.pub').expand_path.to_s
run 'finalize', @arch, @release, auth_key
end
def prepare_package_contents(pwd)
run 'cleanup'
sh 'sudo rm -f rootfs.tar.gz'
sh 'sudo tar --numeric-owner -czf rootfs.tar.gz ./rootfs/*'
sh "sudo chown #{ENV['USER']}:#{`id -gn`.strip} rootfs.tar.gz"
sh "cp #{pwd}/boxes/common/lxc-template ."
sh "cp #{pwd}/boxes/common/lxc.conf ."
sh "cp #{pwd}/boxes/common/metadata.json ."
end
end
class BuildDebianBoxTaskV3 < BuildGenericBoxTaskV3
def initialize(name, release, arch, opts = {})
super(name, 'debian', release, arch, opts)
end
end
class BuildUbuntuBoxTaskV3 < BuildGenericBoxTaskV3
def initialize(name, release, arch, opts = {})
super(name, 'ubuntu', release, arch, opts)
end
end
puppet = ENV['PUPPET'] == '1'
babushka = ENV['BABUSHKA'] == '1'
salt = ENV['SALT'] == '1'
namespace :boxes do
namespace :ubuntu do
namespace :build do
desc 'Build an Ubuntu Precise 64 bits box'
BuildUbuntuBoxTaskV3.
new(:precise64,
:precise, 'amd64', puppet: puppet, babushka: babushka, salt: salt)
desc 'Build an Ubuntu Quantal 64 bits box'
BuildUbuntuBoxTaskV3.
new(:quantal64,
:quantal, 'amd64', puppet: puppet, babushka: babushka, salt: salt)
desc 'Build an Ubuntu Raring 64 bits box'
BuildUbuntuBoxTaskV3.
new(:raring64,
:raring, 'amd64', puppet: puppet, babushka: babushka, salt: salt)
desc 'Build an Ubuntu Saucy 64 bits box'
BuildUbuntuBoxTaskV3.
new(:saucy64,
:saucy, 'amd64', puppet: puppet, babushka: babushka, salt: salt)
desc 'Build all Ubuntu boxes'
task :all => %w( precise64 quantal64 raring64 saucy64 )
end
end
namespace :debian do
namespace :build do
desc 'Build an Debian Squeeze 64 bits box'
BuildDebianBoxTaskV3.
new(:squeeze64,
:squeeze, 'amd64', puppet: puppet, babushka: babushka, salt: false)
desc 'Build an Debian Wheezy 64 bits box'
BuildDebianBoxTaskV3.
new(:wheezy64,
:wheezy, 'amd64', puppet: puppet, babushka: babushka, salt: false)
desc 'Build an Debian Sid/unstable 64 bits box'
BuildDebianBoxTaskV3.
new(:sid64,
:sid, 'amd64', puppet: puppet, babushka: babushka, salt: false)
desc 'Build all Debian boxes'
task :all => %w( squeeze64 wheezy64 sid64 )
end
end
desc 'Build all base boxes for release'
task :build_all => %w( ubuntu:build:all debian:build:all )
end

View file

@ -1,188 +0,0 @@
require 'pathname'
require 'rake/tasklib'
class BuildGenericBoxTaskV2 < ::Rake::TaskLib
include ::Rake::DSL
attr_reader :name
def initialize(name, distrib, release, arch, opts = {})
@name = name
@distrib = distrib
@release = release.to_s
@arch = arch.to_s
@install_chef = opts.fetch(:chef, false)
@install_puppet = opts.fetch(:puppet, true)
@install_babushka = opts.fetch(:babushka, true)
@install_salt = opts.fetch(:salt, true)
@file = opts[:file] || default_box_file
@scripts_path = Pathname(Dir.pwd).join('boxes')
desc "Build an #{distrib.upcase} #{release} #{arch} box" unless
::Rake.application.last_comment
task name do
RakeFileUtils.send(:verbose, true) do
build
end
end
end
def default_box_file
require 'time'
"lxc-#{@release}-#{@arch}-#{Date.today}.box"
end
def run(script_name, *args)
unless (script = @scripts_path.join(@distrib, script_name)).readable?
script = @scripts_path.join('common', script_name)
end
if script.readable?
sh "sudo #{script} #{args.join(' ')}"
else
STDERR.puts "cannot execute #{script_name} (not found?)"
exit 1
end
end
def build
check_if_box_has_been_built!
FileUtils.mkdir_p 'boxes/temp' unless File.exist? 'base/temp'
check_for_partially_built_box!
pwd = Dir.pwd
sh 'mkdir -p boxes/temp/'
Dir.chdir 'boxes/temp' do
download
install_cfg_engines
prepare_package_contents pwd
sh 'sudo rm -rf rootfs'
sh "tar -czf tmp-package.box ./*"
end
sh 'mkdir -p boxes/output'
sh "cp boxes/temp/tmp-package.box boxes/output/#{@file}"
sh "rm -rf boxes/temp"
end
def check_if_box_has_been_built!
return unless File.exists?("./boxes/output/#{@file}")
puts 'Box has been built already!'
exit 1
end
def check_for_partially_built_box!
return unless Dir.entries('boxes/temp').size > 2
puts 'There is a partially built box under ' +
File.expand_path('./boxes/temp') +
', please remove it before building a new box'
exit 1
end
def download
run 'download', @arch, @release
end
def install_cfg_engines
[ :puppet, :chef, :babushka, :salt ].each do |cfg_engine|
next unless instance_variable_get :"@install_#{cfg_engine}"
script_name = "install-#{cfg_engine}"
run script_name
end
end
def prepare_package_contents(pwd)
run 'cleanup'
sh 'sudo rm -f rootfs.tar.gz'
sh 'sudo tar --numeric-owner -czf rootfs.tar.gz ./rootfs/*'
sh "sudo chown #{ENV['USER']}:#{`id -gn`.strip} rootfs.tar.gz"
sh "cp #{pwd}/boxes/#{@distrib}/lxc-template ."
compile_metadata(pwd)
end
def compile_metadata(pwd)
metadata = File.read("#{pwd}/boxes/#{@distrib}/metadata.json.template")
metadata.gsub!('ARCH', @arch)
metadata.gsub!('RELEASE', @release)
File.open('metadata.json', 'w') { |f| f.print metadata }
end
end
class BuildDebianBoxTaskV2 < BuildGenericBoxTaskV2
def initialize(name, release, arch, opts = {})
super(name, 'debian', release, arch, opts)
end
end
class BuildUbuntuBoxTaskV2 < BuildGenericBoxTaskV2
def initialize(name, release, arch, opts = {})
super(name, 'ubuntu', release, arch, opts)
end
end
chef = ENV['CHEF'] == '1'
puppet = ENV['PUPPET'] == '1'
babushka = ENV['BABUSHKA'] == '1'
salt = ENV['SALT'] == '1'
namespace :boxes do
namespace :v2 do
namespace :ubuntu do
namespace :build do
desc 'Build an Ubuntu Precise 64 bits box'
BuildUbuntuBoxTaskV2.
new(:precise64,
:precise, 'amd64', chef: chef, puppet: puppet, babushka: babushka, salt: salt)
desc 'Build an Ubuntu Quantal 64 bits box'
BuildUbuntuBoxTaskV2.
new(:quantal64,
:quantal, 'amd64', chef: chef, puppet: puppet, babushka: babushka, salt: salt)
# FIXME: Find out how to install chef on raring
desc 'Build an Ubuntu Raring 64 bits box'
BuildUbuntuBoxTaskV2.
new(:raring64,
:raring, 'amd64', chef: chef, puppet: puppet, babushka: babushka, salt: salt)
desc 'Build an Ubuntu Saucy 64 bits box'
BuildUbuntuBoxTaskV2.
new(:saucy64,
:saucy, 'amd64', chef: chef, puppet: puppet, babushka: babushka, salt: salt)
desc 'Build all Ubuntu boxes'
task :all => %w( precise64 quantal64 raring64 saucy64 )
end
end
# FIXME: Find out how to install chef on debian boxes
namespace :debian do
namespace :build do
desc 'Build an Debian Squeeze 64 bits box'
BuildDebianBoxTaskV2.
new(:squeeze64,
:squeeze, 'amd64', chef: false, puppet: puppet, babushka: babushka, salt: false)
desc 'Build an Debian Wheezy 64 bits box'
BuildDebianBoxTaskV2.
new(:wheezy64,
:wheezy, 'amd64', chef: false, puppet: puppet, babushka: babushka, salt: false)
desc 'Build an Debian Sid/unstable 64 bits box'
BuildDebianBoxTaskV2.
new(:sid64,
:sid, 'amd64', chef: false, puppet: puppet, babushka: babushka, salt: false)
desc 'Build all Debian boxes'
task :all => %w( squeeze64 wheezy64 sid64 )
end
end
desc 'Build all base boxes for release'
task :build_all => %w( ubuntu:build:all debian:build:all )
end
end