Add a template to create a cirros container. One great thing about cirros is that the image you download is 3.5M.
Thanks smoser! Note by default /etc/inittab doesn't have a /dev/console entry, so you don't get a login on the lxc-start console. Adding console::respawn:/sbin/getty 115200 console makes that work, but ctrl-c still gets forwarded to init which then reboots. So I didn't bother adding console as part of the template (yet). Instead I simply lxc-start -d, then lxc-console. Signed-off-by: Scott Moser <scott.mo...@canonical.com> Signed-off-by: Serge Hallyn <serge.hal...@ubuntu.com> --- configure.ac | 1 + templates/Makefile.am | 3 +- templates/lxc-cirros.in | 288 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 291 insertions(+), 1 deletion(-) create mode 100644 templates/lxc-cirros.in diff --git a/configure.ac b/configure.ac index f27fb87..414d71b 100644 --- a/configure.ac +++ b/configure.ac @@ -363,6 +363,7 @@ AC_CONFIG_FILES([ hooks/Makefile templates/Makefile + templates/lxc-cirros templates/lxc-debian templates/lxc-ubuntu templates/lxc-ubuntu-cloud diff --git a/templates/Makefile.am b/templates/Makefile.am index 0c30667..98d6d72 100644 --- a/templates/Makefile.am +++ b/templates/Makefile.am @@ -11,4 +11,5 @@ templates_SCRIPTS = \ lxc-busybox \ lxc-sshd \ lxc-archlinux \ - lxc-alpine + lxc-alpine \ + lxc-cirros diff --git a/templates/lxc-cirros.in b/templates/lxc-cirros.in new file mode 100644 index 0000000..88827db --- /dev/null +++ b/templates/lxc-cirros.in @@ -0,0 +1,288 @@ +#!/bin/bash + +# template script for generating ubuntu container for LXC +# +# This script consolidates and extends the existing lxc ubuntu scripts +# + +# Copyright © 2013 Canonical Ltd. +# Author: Scott Moser <scott.mo...@canonical.com> +# +# 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. +VERBOSITY=0 +TEMP_D="" +DOWNLOAD_URL="http://download.cirros-cloud.net/" +CACHE_D="/var/cache/lxc/cirros" +CACHE_D="@LOCALSTATEDIR@/cache/lxc/cirros" +TMP_FILE="" + +UNAME_M=$(uname -m) +ARCHES=( i386 x86_64 amd64 arm ) +STREAMS=( released devel ) +BUILD="standard" + +DEF_VERSION="released" +case "${UNAME_M}" in + i?86) DEF_ARCH="i386";; + x86_64) DEF_ARCH="x86_64";; + arm*) DEF_ARCH="arm";; + *) DEF_ARCH="i386";; +esac + + +error() { echo "$@" 1>&2; } +errorp() { printf "$@" 1>&2; } +fail() { [ $# -eq 0 ] || error "$@"; exit 1; } +failp() { [ $# -eq 0 ] || errorp "$@"; exit 1; } +inargs() { + local needle="$1" x="" + shift + for x in "$@"; do + [ "$needle" = "$x" ] && return 0 + done + return 1 +} + +Usage() { + cat <<EOF +${0##*/} [options] + + -a | --arch A architecture to use [${ARCHES}] + default: ${DEF_ARCH} + -h | --help this usage + -v | --verbose increase verbosity + -S | --auth-key K insert auth key 'K' + -v | --version V version [${STREAMS[*]}] + default: ${DEF_VERSION} + -u | --userdata U user-data file +EOF +} + +bad_Usage() { Usage 1>&2; [ $# -eq 0 ] || error "$@"; exit 1; } +cleanup() { + [ -z "${TEMP_D}" -o ! -d "${TEMP_D}" ] || rm -Rf "${TEMP_D}" + [ -z "${TEMP_FILE}" ] || rm -Rf "${TEMP_FILE}" +} + +debug() { + local level=${1}; shift; + [ "${level}" -gt "${VERBOSITY}" ] && return + error "${@}" +} +jsondict() { + local k="" v="" ret="{" + for arg in "$@"; do + k="${arg%%=*}" + v="${arg#*=}" + ret="${ret} \"${k}\": \"$v\"," + done + ret="${ret%,} }" + echo "$ret" +} + +copy_configuration() +{ + local path=$1 rootfs=$2 name=$3 arch=$4 release=$5 +cat >> "$path/config" <<EOF +# Template used to create this container: cirros + +lxc.rootfs = $rootfs +#lxc.mount = $path/fstab +lxc.pivotdir = lxc_putold + +lxc.tty = 4 +lxc.pts = 1024 + +lxc.utsname = $name +lxc.arch = $arch +lxc.cap.drop = sys_module mac_admin mac_override sys_time + +# When using LXC with apparmor, uncomment the next line to run unconfined: +#lxc.aa_profile = unconfined +# To support container nesting on an Ubuntu host, uncomment next two lines: +#lxc.aa_profile = lxc-container-default-with-nesting +#lxc.hook.mount = /usr/share/lxc/hooks/mountcgroups + +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 +# /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 +} + +insert_ds() { + local root_d="$1" dstype="$2" authkey="$3" userdata="$4" + local sdir="$root_d/var/lib/cloud/seed/nocloud" + + mkdir -p "$sdir" || + { error "failed to make datasource dir $sdir"; return 1; } + rm -f "$sdir/meta-data" "$sdir/user-data" || + { error "failed to clean old data from $sdir"; return 1; } + + iid="iid-local01" + jsondict "instance-id=$iid" \ + ${authkeys:+"public-keys=${authkeys}"} > "$sdir/meta-data" || + { error "failed to write metadata to $sdir/meta-data"; return 1; } + + [ -z "$userdata" ] || + echo "$userdata" > "$sdir/user-data" || + { error "failed to write user-data to $sdir"; return 1; } +} + +extract_rootfs() { + local tarball="$1" rootfs_d="$2" + mkdir -p "${rootfs_d}" || + { error "failed to make rootfs dir ${rootfs_d}"; return 1; } + + tar -C "${rootfs_d}" -Sxzf "${tarball}" || + { error "failed to populate ${rootfs_d}"; return 1; } + return 0 +} + +download_tarball() { + local arch="$1" ver="$2" cached="$3" baseurl="$4" + local out="" outd="" file="" dlpath="" + file="cirros-$ver-$arch-lxc.tar.gz" + dlpath="$ver/$file" + outd="${cached}/${dlpath%/*}" + if [ -f "$cached/$dlpath" ]; then + _RET="$cached/$dlpath" + return 0 + fi + + mkdir -p "${outd}" || + { error "failed to create ${outd}"; return 1; } + + wget "${baseurl%/}/$dlpath" -O "$cached/${dlpath}.$$" && + mv "$cached/$dlpath.$$" "$cached/$dlpath" || { + rm -f "$cached/$dlpath.$$"; + error "failed to download $dlpath"; + return 1; + } + _RET="$cached/$dlpath" +} + +short_opts="a:n:p:S:huV" +long_opts="arch:,auth-key:,name:,path:,userdata:,verbose,version:" +getopt_out=$(getopt --name "${0##*/}" \ + --options "${short_opts}" --long "${long_opts}" -- "$@") && + eval set -- "${getopt_out}" || + bad_Usage + +arch="${DEF_ARCH}" +version="${DEF_VERSION}" +authkey_f="" +authkeys="" +userdata="" +seed=true +path="" + +while [ $# -ne 0 ]; do + cur=$1; next=$2; + case "$cur" in + -a|--arch) arch="$next"; shift;; + -h|--help) Usage ; exit 0;; + -n|--name) name="$next"; shift;; + -v|--verbose) VERBOSITY=$((${VERBOSITY}+1));; + -S|--auth-key) authkey_f="$next"; shift;; + -p|--path) path=$next; shift;; + -v|--version) version=$next; shift;; + -u|--userdata) userdata="$next"; shift;; + --) shift; break;; + esac + shift; +done + +[ $# -eq 0 ] || bad_Usage "unexpected arguments: $*" +[ -n "$path" ] || fail "'path' parameter is required" + +if [ "$(id -u)" != "0" ]; then + fail "must be run as root" +fi + +case "$arch" in + i?86) arch="i386";; + amd64) arch="x86_65";; +esac + +inargs "$arch" "${ARCHES[@]}" || + fail "bad arch '$arch'. allowed: ${ARCHES[*]}" + +if inargs "$version" "${STREAMS[@]}"; then + out=$(wget -O - -q "${DOWNLOAD_URL%/}/version/$version") || + fail "failed to convert 'version=$version'" + version="$out" +fi + +if [ -n "$authkey_f" ]; then + if [ ! -f "$authkey_f" ]; then + echo "--auth-key=${authkey_f} must reference a file" + exit 1 + fi + authkeys=$(cat "$authkey") +fi + +trap cleanup EXIT + +download_tarball "$arch" "$version" "${CACHE_D}" "${DOWNLOAD_URL}" || fail +tarball="$_RET" + +rootfs_d="$path/rootfs" +extract_rootfs "${tarball}" "${rootfs_d}" || fail + +# oopsie - some cirros tarballs ship random as a blockdev, breaking +# dropbear. +if [ -b ${rootfs_d}/dev/random ]; then + rm -f ${rootfs_d}/dev/random + rm -f ${rootfs_d}/dev/urandom + mknod ${rootfs_d}/dev/random c 1 8 + mknod ${rootfs_d}/dev/urandom c 1 9 + chmod 777 ${rootfs_d}/dev/random ${rootfs_d}/dev/urandom +fi + +if false; then + insert_ds "$path/rootfs" "nocloud" "$authkeys" "$userdata" || + fail "failed to insert userdata to $path/rootfs" +else + # disable ec2, because its annoying + sed -i 's,ec2,,' "$path/rootfs/etc/cirros-init/config" +fi + +copy_configuration "$path" "$path/rootfs" "$name" "$arch" "$release" + + +# vi: ts=4 expandtab -- 1.8.1.2 ------------------------------------------------------------------------------ Learn Graph Databases - Download FREE O'Reilly Book "Graph Databases" is the definitive new guide to graph databases and their applications. This 200-page book is written by three acclaimed leaders in the field. The early access version is available now. Download your free book today! http://p.sf.net/sfu/neotech_d2d_may _______________________________________________ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel