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