lxc-busybox.in revision e62fa3f9cea8c97fbfa3a3c8e6acc00c420c8363
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano#!/bin/bash
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano#
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano# lxc: linux Container library
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano# Authors:
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano# Daniel Lezcano <daniel.lezcano@free.fr>
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano# This library is free software; you can redistribute it and/or
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano# modify it under the terms of the GNU Lesser General Public
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano# License as published by the Free Software Foundation; either
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano# version 2.1 of the License, or (at your option) any later version.
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano# This library is distributed in the hope that it will be useful,
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano# but WITHOUT ANY WARRANTY; without even the implied warranty of
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano# Lesser General Public License for more details.
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano# You should have received a copy of the GNU Lesser General Public
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano# License along with this library; if not, write to the Free Software
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanoinstall_busybox()
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano{
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano rootfs=$1
99e4008cad9e959b683c6f48411fcf15a92be3b5Michel Normand name=$2
99e4008cad9e959b683c6f48411fcf15a92be3b5Michel Normand res=0
10fba81b9d0221b8e47aa1e0b43236413b7d28dfMichel Normand tree="\
99e4008cad9e959b683c6f48411fcf15a92be3b5Michel Normand$rootfs/selinux \
99e4008cad9e959b683c6f48411fcf15a92be3b5Michel Normand$rootfs/dev \
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano$rootfs/home \
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano$rootfs/root \
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano$rootfs/etc \
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano$rootfs/etc/init.d \
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano$rootfs/bin \
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano$rootfs/sbin \
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano$rootfs/proc \
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano$rootfs/mnt \
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano$rootfs/tmp \
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano$rootfs/var/log \
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano$rootfs/usr/share/udhcpc \
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano$rootfs/dev/pts \
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano$rootfs/dev/shm \
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano$rootfs/lib \
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano$rootfs/usr/lib \
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano$rootfs/lib64 \
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano$rootfs/usr/lib64"
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano mkdir -p $tree || return 1
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano chmod 755 $tree || return 1
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano pushd $rootfs/dev > /dev/null || return 1
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano # minimal devices needed for busybox
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano mknod tty c 5 0 || res=1
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano mknod console c 5 1 || res=1
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano chmod 666 tty console || res=1
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano mknod tty0 c 4 0 || res=1
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano mknod tty1 c 4 0 || res=1
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano mknod tty5 c 4 0 || res=1
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano chmod 666 tty0 || res=1
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano mknod ram0 b 1 0 || res=1
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano chmod 600 ram0 || res=1
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano mknod null c 1 3 || res=1
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano chmod 666 null || res=1
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano popd > /dev/null
10fba81b9d0221b8e47aa1e0b43236413b7d28dfMichel Normand
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano # root user defined
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano cat <<EOF >> $rootfs/etc/passwd
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanoroot:x:0:0:root:/root:/bin/sh
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanoEOF
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano cat <<EOF >> $rootfs/etc/group
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanoroot:x:0:root
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanoEOF
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano # mount everything
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano cat <<EOF >> $rootfs/etc/init.d/rcS
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano#!/bin/sh
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano/bin/syslogd
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano/bin/mount -a
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano/bin/udhcpc
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanoEOF
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano # executable
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano chmod 744 $rootfs/etc/init.d/rcS || return 1
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano # mount points
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano cat <<EOF >> $rootfs/etc/fstab
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanoproc /proc proc defaults 0 0
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanoshm /dev/shm tmpfs defaults 0 0
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanoEOF
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano # writable and readable for other
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano chmod 644 $rootfs/etc/fstab || return 1
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano # launch rcS first then make a console available
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano # and propose a shell on the tty, the last one is
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano # not needed
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano cat <<EOF >> $rootfs/etc/inittab
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano::sysinit:/etc/init.d/rcS
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanotty1::respawn:/bin/getty -L tty1 115200 vt100
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanoconsole::askfirst:/bin/sh
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanoEOF
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano # writable and readable for other
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano chmod 644 $rootfs/etc/inittab || return 1
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano cat <<EOF >> $rootfs/usr/share/udhcpc/default.script
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano#!/bin/sh
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanocase "\$1" in
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano deconfig)
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano ip addr flush dev \$interface
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano ;;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano renew|bound)
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano # flush all the routes
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano if [ -n "\$router" ]; then
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano ip route del default 2> /dev/null
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano fi
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano # check broadcast
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano if [ -n "\$broadcast" ]; then
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano broadcast="broadcast \$broadcast"
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano fi
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano # add a new ip address
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano ip addr add \$ip/\$mask \$broadcast dev \$interface
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano if [ -n "\$router" ]; then
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano ip route add default via \$router dev \$interface
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano fi
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano [ -n "\$domain" ] && echo search \$domain > /etc/resolv.conf
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano for i in \$dns ; do
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano echo nameserver \$i >> /etc/resolv.conf
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano done
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano ;;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanoesac
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanoexit 0
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanoEOF
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
99e4008cad9e959b683c6f48411fcf15a92be3b5Michel Normand chmod 744 $rootfs/usr/share/udhcpc/default.script
99e4008cad9e959b683c6f48411fcf15a92be3b5Michel Normand
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano return $res
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano}
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanoconfigure_busybox()
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano{
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano rootfs=$1
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano functions="\
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano [ [[ addgroup adduser adjtimex ar arp arping ash awk basename \
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano brctl bunzip2 bzcat bzip2 cal cat catv chattr chgrp chmod \
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano chown chpasswd chpst chroot chrt chvt cksum clear cmp comm \
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano cp cpio crond crontab cryptpw cut date dc dd deallocvt \
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano delgroup deluser df dhcprelay diff dirname dmesg dnsd dos2unix \
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano du dumpkmap dumpleases echo ed egrep eject env envdir envuidgid \
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano ether-wake expand expr fakeidentd false fbset fdformat fdisk \
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano fetchmail fgrep find findfs fold free freeramdisk fsck \
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano fsck.minix ftpget ftpput fuser getopt getty grep gunzip gzip \
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano halt hdparm head hexdump hostid hostname httpd hwclock id \
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano ifconfig ifdown ifenslave ifup inetd init insmod install ip \
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano ipaddr ipcalc ipcrm ipcs iplink iproute iprule iptunnel \
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano kbd_mode kill killall killall5 klogd last length less linux32 \
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano linux64 linuxrc ln loadfont loadkmap logger login logname \
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano logread losetup lpd lpq lpr ls lsattr lsmod lzmacat makedevs \
md5sum mdev mesg microcom mkdir mkfifo mkfs.minix mknod mkswap \
mktemp modprobe more mount mountpoint msh mt mv nameif nc \
netstat nice nmeter nohup nslookup od openvt passwd patch \
pgrep pidof ping ping6 pipe_progress pivot_root pkill poweroff \
printenv printf ps pscan pwd raidautorun rdate readahead \
readlink readprofile realpath reboot renice reset resize rm \
rmdir rmmod route rpm rpm2cpio run-parts runlevel runsv \
runsvdir rx script sed sendmail seq setarch setconsole \
setkeycodes setlogcons setsid setuidgid sh sha1sum slattach \
sleep softlimit sort split start-stop-daemon stat strings \
stty su sulogin sum sv svlogd swapoff swapon switch_root \
sync sysctl syslogd tac tail tar taskset tcpsvd tee telnet \
telnetd test tftp tftpd time top touch tr traceroute \
true tty ttysize udhcpc udhcpd udpsvd umount uname uncompress \
unexpand uniq unix2dos unlzma unzip uptime usleep uudecode \
uuencode vconfig vi vlock watch watchdog wc wget which \
who whoami xargs yes zcat zcip"
type busybox >/dev/null
if [ $? -ne 0 ]; then
echo "busybox executable is not accessible"
return 1
fi
file $(which busybox) | grep -q "statically linked"
if [ $? -ne 0 ]; then
echo "warning : busybox is not statically linked."
echo "warning : The template script may not correctly"
echo "warning : setup the container environment."
fi
# copy busybox in the rootfs
cp $(which busybox) $rootfs/bin
if [ $? -ne 0 ]; then
echo "failed to copy busybox in the rootfs"
return 1
fi
# do hardlink to busybox for the different commands
for i in $functions; do ln $rootfs/bin/busybox $rootfs/bin/$i; done
# relink /sbin/init
ln $rootfs/bin/busybox $rootfs/sbin/init
# passwd exec must be setuid
chmod +s $rootfs/bin/passwd
touch $rootfs/etc/shadow
chroot $rootfs /bin/passwd -d root
echo "No password for 'root', please change !"
return 0
}
copy_configuration()
{
path=$1
rootfs=$2
name=$3
grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config
cat <<EOF >> $path/config
lxc.utsname = $name
lxc.tty = 1
lxc.pts = 1
# When using LXC with apparmor, uncomment the next line to run unconfined:
#lxc.aa_profile = unconfined
EOF
if [ -d "$rootfs/lib" ]; then
cat <<EOF >> $path/config
lxc.mount.entry=/lib $rootfs/lib none ro,bind 0 0
lxc.mount.entry=/usr/lib $rootfs/usr/lib none ro,bind 0 0
EOF
fi
libdirs="\
lib \
usr/lib \
lib64 \
usr/lib64"
for dir in $libdirs; do
if [ -d "/$dir" ] && [ -d "$rootfs/$dir" ]; then
echo "lxc.mount.entry=/$dir $dir none ro,bind 0 0" >> $path/config
fi
done
}
usage()
{
cat <<EOF
$1 -h|--help -p|--path=<path>
EOF
return 0
}
options=$(getopt -o hp:n: -l help,path:,name: -- "$@")
if [ $? -ne 0 ]; then
usage $(basename $0)
exit 1
fi
eval set -- "$options"
while true
do
case "$1" in
-h|--help) usage $0 && exit 0;;
-p|--path) path=$2; shift 2;;
-n|--name) name=$2; shift 2;;
--) shift 1; break ;;
*) break ;;
esac
done
if [ "$(id -u)" != "0" ]; then
echo "This script should be run as 'root'"
exit 1
fi
if [ -z "$path" ]; then
echo "'path' parameter is required"
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_busybox $rootfs $name
if [ $? -ne 0 ]; then
echo "failed to install busybox's rootfs"
exit 1
fi
configure_busybox $rootfs
if [ $? -ne 0 ]; then
echo "failed to configure busybox template"
exit 1
fi
copy_configuration $path $rootfs $name
if [ $? -ne 0 ]; then
echo "failed to write configuration file"
exit 1
fi