diff --git a/utils/centos6-vagrant-lxc/lxc-template b/utils/centos6-vagrant-lxc/lxc-template index ac8a112..202d068 100755 --- a/utils/centos6-vagrant-lxc/lxc-template +++ b/utils/centos6-vagrant-lxc/lxc-template @@ -1,171 +1,226 @@ #!/bin/bash -# This is a modified version of /usr/share/lxc/templates/lxc-download -# that comes with ubuntu-lxc 1.0.0 stable from ppa changed to suit vagrant-lxc needs +# This is a modified version of /usr/share/lxc/templates/lxc-ubuntu +# that comes with Ubuntu 13.04 changed to suit vagrant-lxc needs + # -# Copyright © 2014 Stéphane Graber -# Copyright © 2014 Fábio Rehm +# template script for generating ubuntu container for LXC +# +# This script consolidates and extends the existing lxc ubuntu scripts +# + +# Copyright © 2011 Serge Hallyn +# Copyright © 2010 Wilhelm Meier +# Author: Wilhelm Meier +# +# 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. # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. - -# This library 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 -# Lesser General Public License for more details. - -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 -# USA - -set -eu - -LXC_HOOK_DIR="/usr/share/lxc/hooks" -LXC_TEMPLATE_CONFIG="/usr/share/lxc/config" - -LXC_MAPPED_GID= -LXC_MAPPED_UID= -LXC_NAME= -LXC_PATH= -LXC_ROOTFS= -LXC_TARBALL= -LXC_CONFIG= - -usage() { - cat < ]: The full path of the rootfs tarball +set -e -Optional arguments: -[ --config ]: Configuration file to be used when building the container -[ -h | --help ]: This help message +if [ -r /etc/default/lxc ]; then + . /etc/default/lxc +fi + +extract_rootfs() +{ + tarball=$1 + arch=$2 + rootfs=$3 + + echo "Extracting $tarball ..." + mkdir -p $rootfs + (cd $rootfs && tar xfz $tarball --strip-components=2) + 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 + + grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config + + # 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 + + if [ $? -ne 0 ]; then + echo "Failed to add configuration" + return 1 + fi -LXC internal arguments (do not pass manually!): -[ --name ]: The container name -[ --path ]: The path to the container -[ --rootfs ]: The path to the container's rootfs -[ --mapped-uid ]: A uid map (user namespaces) -[ --mapped-gid ]: A gid map (user namespaces) -EOF return 0 } -options=$(getopt -o h -l auth-key:,tarball:,config:,help:,name:,path:,rootfs:,mapped-uid:,mapped-gid: -- "$@")SS +post_process() +{ + rootfs=$1 + + # 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 <] [-T|--tarball +arch: the container architecture (e.g. amd64): defaults to host arch +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:,rootfs: -- "$@") 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;; - --config) LXC_CONFIG=$2; shift 2;; - --tarball) LXC_TARBALL=$2; shift 2;; - --name) LXC_NAME=$2; shift 2;; - --path) LXC_PATH=$2; shift 2;; - --rootfs) LXC_ROOTFS=$2; shift 2;; - --mapped-uid) LXC_MAPPED_UID=$2; shift 2;; - --mapped-gid) LXC_MAPPED_GID=$2; shift 2;; - *) break;; + -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;; + -a|--arch) arch=$2; shift 2;; + -S|--auth-key) auth_key=$2; shift 2;; + -d|--debug) debug=1; shift 1;; + --) shift 1; break ;; + *) break ;; esac done -if [ -z "${LXC_NAME}" ]; then - echo "'name' parameter is required" - exit 1 +if [ $debug -eq 1 ]; then + set -x +fi + +if [ "$arch" == "i686" ]; then + arch=i386 fi -if [ -z "${LXC_TARBALL}" ]; then - echo "'tarball' parameter is required" +if [ $hostarch = "i386" -a $arch = "amd64" ]; then + echo "can't create amd64 container on i386" exit 1 fi -if [ -z "${LXC_PATH}" ]; then +if [ -z "$path" ]; then echo "'path' parameter is required" exit 1 fi -if [ -z "${LXC_CONFIG}" ]; then - echo "'config' parameter is required" +if [ "$(id -u)" != "0" ]; then + echo "This script should be run as 'root'" exit 1 fi -# if $LXC_ROOTFS exists here, it was passed in with --rootfs -if [ -z "${LXC_ROOTFS}" ]; then - config=${LXC_PATH}/config +# detect rootfs +config="$path/config" +# if $rootfs exists here, it was passed in with --rootfs +if [ -z "$rootfs" ]; then if grep -q '^lxc.rootfs' $config 2>/dev/null ; then - LXC_ROOTFS=`grep 'lxc.rootfs =' $config | awk -F= '{ print $2 }'` + rootfs=`grep 'lxc.rootfs =' $config | awk -F= '{ print $2 }'` else - LXC_ROOTFS=$LXC_PATH/rootfs - echo "lxc.rootfs = ${LXC_ROOTFS}" >> $config + rootfs=$path/rootfs fi fi -# Unpack the rootfs -echo "Unpacking the rootfs" - -mkdir -p /var/lock/subsys -( - flock -x 200 - if [ $? -ne 0 ]; then - echo "Cache repository is busy." - exit 1 - fi - - mkdir -p ${LXC_ROOTFS} - (cd ${LXC_ROOTFS} && tar xfz ${LXC_TARBALL} --strip-components=2) - if [ $? -ne 0 ]; then - echo "Failed to extract rootfs" - exit 1 - fi - -) 200>/var/lock/subsys/lxc - -mkdir -p ${LXC_ROOTFS}/dev/pts/ - -## Extract all the network config entries -sed -i -e "/lxc.network/{w ${LXC_PATH}/config-network" -e "d}" \ - ${LXC_PATH}/config - -## Extract any other config entry -sed -i -e "/lxc./{w ${LXC_PATH}/config-auto" -e "d}" ${LXC_PATH}/config - -## Add the container-specific config -echo "" >> ${LXC_PATH}/config -echo "##############################################" >> ${LXC_PATH}/config -echo "# Container specific configuration (automatically set)" >> ${LXC_PATH}/config -if [ -e "${LXC_PATH}/config-auto" ]; then - cat ${LXC_PATH}/config-auto >> ${LXC_PATH}/config - rm ${LXC_PATH}/config-auto -fi -echo "lxc.utsname = ${LXC_NAME}" >> ${LXC_PATH}/config - -## Re-add the previously removed network config -if [ -e "${LXC_PATH}/config-network" ]; then - echo "" >> ${LXC_PATH}/config - echo "##############################################" >> ${LXC_PATH}/config - echo "# Network configuration (automatically set)" >> ${LXC_PATH}/config - cat ${LXC_PATH}/config-network >> ${LXC_PATH}/config - rm ${LXC_PATH}/config-network +install_ubuntu $rootfs $release $tarball +if [ $? -ne 0 ]; then + echo "failed to install ubuntu $release" + exit 1 fi -## Append the defaults -echo "" >> ${LXC_PATH}/config -echo "##############################################" >> ${LXC_PATH}/config -echo "# vagrant-lxc base box specific configuration" >> ${LXC_PATH}/config -cat ${LXC_CONFIG} >> ${LXC_PATH}/config +copy_configuration $path $rootfs $name $arch +if [ $? -ne 0 ]; then + echo "failed write configuration file" + exit 1 +fi -# Empty section for lxc.customize calls from vagrantfile -echo "" >> ${LXC_PATH}/config -echo "##############################################" >> ${LXC_PATH}/config -echo "# vagrant-lxc container specific configuration" >> ${LXC_PATH}/config +post_process $rootfs $release $trim_container -exit 0 +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 "" -- libgit2 0.21.2