Skip to content

Instantly share code, notes, and snippets.

@bobfeldbauer
Created June 28, 2012 02:52
Show Gist options
  • Save bobfeldbauer/3008518 to your computer and use it in GitHub Desktop.
Save bobfeldbauer/3008518 to your computer and use it in GitHub Desktop.
Setup Linux container on debian
#!/bin/bash
#
# lxc: linux Container library
# Authors:
# Daniel Lezcano <[email protected]>
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
path="/var/lib/lxc"
configure_debian()
{
# disable selinux in debian
mkdir -p "$rootfs/selinux"
echo 0 > "$rootfs/selinux/enforce"
# configure the network
cat <<EOF > $rootfs/etc/network/interfaces
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
address 10.0.0.$num
netmask 255.255.255.0
gateway 10.0.0.1
EOF
# set the hostname
cat <<EOF > "$rootfs/etc/hostname"
$name
EOF
# configure resolver
cat <<EOF > "$rootfs/etc/resolv.conf"
nameserver 8.8.8.8
EOF
# remove pointless services in a container
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
# Remove udev
chroot "$rootfs" /usr/bin/apt-get -y --purge remove udev
# Create tty device nodes
for num in $(seq 0 4); do
if [ ! -e "$rootfs/dev/tty$num" ]; then
mknod "$rootfs/dev/tty$num" c 4 $num
chmod 600 "$rootfs/dev/tty$num"
chown root:tty "$rootfs/dev/tty$num"
fi
done
echo "root:root" | chroot "$rootfs" chpasswd
echo "Root password is 'root', please change !"
return 0
}
download_debian()
{
packages="locales,less,vim,psmisc"
# check the mini debian was not already downloaded
mkdir -p "$cache/partial-$dist"
if [ $? -ne 0 ]; then
echo "Failed to create '$cache/partial-$dist' directory"
return 1
fi
# download a mini debian into a cache
echo "Downloading debian minimal ..."
debootstrap --verbose --include "$packages" \
"$dist" "$cache/partial-$dist" http://ftp.us.debian.org/debian
if [ $? -ne 0 ]; then
echo "Failed to download the rootfs, aborting."
return 1
fi
mv "$cache/partial-$dist" "$cache/rootfs-$dist"
echo "Download complete."
return 0
}
copy_debian()
{
# make a local copy of the minidebian
echo -n "Copying rootfs to $rootfs..."
mkdir -p "$(dirname "$rootfs")"
cp -a "$cache/rootfs-$dist" "$rootfs" || return 1
return 0
}
install_debian()
{
cache="/var/cache/lxc/debian"
mkdir -p /var/lock/subsys/
(
flock -n -x 200
if [ $? -ne 0 ]; then
echo "Cache repository is busy."
return 1
fi
echo "Checking cache download in $cache/rootfs-$dist ... "
if [ ! -e "$cache/rootfs-$dist" ]; then
download_debian
if [ $? -ne 0 ]; then
echo "Failed to download 'debian base'"
return 1
fi
fi
copy_debian
if [ $? -ne 0 ]; then
echo "Failed to copy rootfs"
return 1
fi
return 0
) 200>/var/lock/subsys/lxc
return $?
}
copy_configuration()
{
cat <<EOF > "$rootfs/etc/hosts"
# 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
127.0.0.1 localhost.localdomain localhost
# Auto-generated hostname. Please do not remove this comment.
10.0.0.$num $name
EOF
cat <<EOF > "$rootfs/etc/inittab"
# /etc/inittab: init(8) configuration.
# $Id: inittab,v 1.91 2002/01/25 13:35:21 miquels Exp $
# The default runlevel.
id:2:initdefault:
# Boot-time system configuration/initialization script.
# This is run first except when booting in emergency (-b) mode.
si::sysinit:/etc/init.d/rcS
# What to do in single-user mode.
~:S:wait:/sbin/sulogin
# /etc/init.d executes the S and K scripts upon change
# of runlevel.
#
# Runlevel 0 is halt.
# Runlevel 1 is single-user.
# Runlevels 2-5 are multi-user.
# Runlevel 6 is reboot.
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
# What to do when CTRL-ALT-DEL is pressed.
ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
# The "id" field MUST be the same as the last
# characters of the device (after "tty").
#
# Format:
# <id>:<runlevels>:<action>:<process>
#
# Note that on most Debian systems tty7 is used by the X Window System,
# so if you want to add more getty's go ahead but skip tty7 if you run X.
#
1:2345:respawn:/sbin/getty 38400 tty1
2:23:respawn:/sbin/getty 38400 tty2
3:23:respawn:/sbin/getty 38400 tty3
4:23:respawn:/sbin/getty 38400 tty4
EOF
cat <<EOF > "$path/$name/config"
lxc.tty = 4
lxc.pts = 1024
lxc.rootfs = $rootfs
lxc.cgroup.devices.deny = a
# /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
# mounts point
lxc.mount.entry=proc $rootfs/proc proc nodev,noexec,nosuid 0 0
lxc.mount.entry=devpts $rootfs/dev/pts devpts defaults 0 0
lxc.mount.entry=sysfs $rootfs/sys sysfs defaults 0 0
# network
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
lxc.network.veth.pair = veth_$name
# tun/tap
lxc.cgroup.devices.allow = c 10:200 rwm
EOF
if [ $? -ne 0 ]; then
echo "Failed to add configuration"
return 1
fi
return 0
}
clean()
{
cache="/var/cache/lxc/debian"
if [ ! -e $cache ]; then
exit 0
fi
# lock, so we won't purge while someone is creating a repository
(
flock -n -x 200
if [ $? != 0 ]; then
echo "Cache repository is busy."
exit 1
fi
echo -n "Purging the download cache..."
rm --preserve-root --one-file-system -rf "$cache" && echo "Done." || exit 1
exit 0
) 200>/var/lock/subsys/lxc
}
usage()
{
cat <<EOF
Usage: $1 dist container-name container-number
EOF
return 0
}
if [ $# -ne 3 ]; then
usage $(basename $0)
exit 1
fi
dist="$1"
name="$2"
num="$3"
type debootstrap
if [ $? -ne 0 ]; then
echo "'debootstrap' command is missing"
exit 1
fi
if [ "$(id -u)" != "0" ]; then
echo "This script should be run as 'root'"
exit 1
fi
rootfs="$path/$name/rootfs"
install_debian
if [ $? -ne 0 ]; then
echo "failed to install debian"
exit 1
fi
configure_debian
if [ $? -ne 0 ]; then
echo "failed to configure debian for a container"
exit 1
fi
copy_configuration
if [ $? -ne 0 ]; then
echo "failed write configuration file"
exit 1
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment