From 3b1055c843d7137a879de1d29abb402746706d34 Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Sun, 9 Mar 2014 03:49:06 -0300 Subject: [PATCH] New base box template --- boxes/common/lxc-template | 301 ++++++++++++++------------------------ 1 file changed, 113 insertions(+), 188 deletions(-) diff --git a/boxes/common/lxc-template b/boxes/common/lxc-template index 202d068..a9318d1 100755 --- a/boxes/common/lxc-template +++ b/boxes/common/lxc-template @@ -1,226 +1,151 @@ #!/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 - +# 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 # -# template script for generating ubuntu container for LXC -# -# This script consolidates and extends the existing lxc ubuntu scripts +# Copyright © 2014 Stéphane Graber +# Copyright © 2014 Fábio Rehm # +# 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. -# 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 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. -# 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 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 -# 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 -eu -set -e +LXC_HOOK_DIR="/usr/share/lxc/hooks" +LXC_TEMPLATE_CONFIG="/usr/share/lxc/config" -if [ -r /etc/default/lxc ]; then - . /etc/default/lxc -fi +LXC_MAPPED_GID= +LXC_MAPPED_UID= +LXC_NAME= +LXC_PATH= +LXC_ROOTFS= +LXC_TARBALL= +LXC_CONFIG= -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 - - return 0 -} - -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() -{ +usage() { cat <] [-T|--tarball -arch: the container architecture (e.g. amd64): defaults to host arch +vagrant-lxc default template + +Required arguments: +[ --tarball ]: The full path of the rootfs tarball + +Optional arguments: +[ --config ]: Configuration file to be used when building the container +[ -h | --help ]: This help message + +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 a:b:hp:r:xn:FS:d:C -l arch:,help,path:,release:,trim,name:,flush-cache,auth-key:,debug:,tarball:,rootfs: -- "$@") +options=$(getopt -o h -l tarball:,config:,help:,name:,path:,rootfs:,mapped-uid:,mapped-gid: -- "$@")SS + 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;; - --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 ;; + -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;; 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" +if [ -z "${LXC_NAME}" ]; then + echo "'name' parameter is required" exit 1 fi -if [ -z "$path" ]; then +if [ -z "${LXC_TARBALL}" ]; then + echo "'tarball' parameter is required" + exit 1 +fi + +if [ -z "${LXC_ROOTFS}" ]; then + echo "'rootfs' parameter is required" + exit 1 +fi + +if [ -z "${LXC_CONFIG}" ]; then + echo "'config' parameter is required" + exit 1 +fi + +if [ -z "${LXC_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 +# Unpack the rootfs +echo "Unpacking the rootfs" + +mkdir -p ${LXC_ROOTFS} +(cd ${LXC_ROOTFS} && tar xfz ${LXC_TARBALL} --strip-components=2) + +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 fi -# 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 - rootfs=`grep 'lxc.rootfs =' $config | awk -F= '{ print $2 }'` - else - rootfs=$path/rootfs - fi -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 -install_ubuntu $rootfs $release $tarball -if [ $? -ne 0 ]; then - echo "failed to install ubuntu $release" - 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 -copy_configuration $path $rootfs $name $arch -if [ $? -ne 0 ]; then - echo "failed write configuration file" - exit 1 -fi - -post_process $rootfs $release $trim_container - -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 "" +exit 0