lxc-plamo.in revision db821c3a4168c9c1072a433340e6009892e26cf2
970N/A#!/bin/bash
970N/A
970N/A#
970N/A# template script for generating Plamo Linux container for LXC
1500N/A#
970N/A
970N/A#
970N/A# lxc: linux Container library
970N/A
970N/A# Authors:
970N/A# KATOH Yasufumi <karma@jazz.email.ne.jp>
970N/A# TAMUKI Shoichi <tamuki@linet.gr.jp>
970N/A
970N/A# This library is free software; you can redistribute it and/or
970N/A# modify it under the terms of the GNU Lesser General Public
970N/A# License as published by the Free Software Foundation; either
970N/A# version 2.1 of the License, or (at your option) any later version.
970N/A
970N/A# This library is distributed in the hope that it will be useful,
970N/A# but WITHOUT ANY WARRANTY; without even the implied warranty of
970N/A# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
970N/A# Lesser General Public License for more details.
970N/A
970N/A# You should have received a copy of the GNU Lesser General Public
970N/A# License along with this library; if not, write to the Free Software
970N/A# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
970N/A
970N/A# ref. https://github.com/Ponce/lxc-slackware/blob/master/lxc-slackware
970N/A# lxc-ubuntu script
970N/A
970N/A[ -r /etc/default/lxc ] && . /etc/default/lxc
970N/A
970N/AMIRRORSRV=${MIRRORSRV:-"ftp.ne.jp"}
970N/AMIRRORPATH=${MIRRORPATH:-"/Linux/distributions/plamolinux"}
970N/ACATEGORY[0]=${CATEGORY:-"00_base"}
970N/APACKAGES[0]=${PACKAGES:-"aaa_base acl at attr bash btrfs_progs bzip2
970N/A coreutils cracklib dcron devs dhcp dialog dosfstools dump e2fsprogs
970N/A ed eject etc extipl file findutils gawk glibc grep groff grub gzip
970N/A hdsetup hibernate_script iproute2 iputils kbd kmod less libcap
970N/A libgcc libtirpc lilo linux_pam logrotate lvm2 man
970N/A mdadm microcode_ctl mlocate ncurses net_tools netkit_combo
970N/A network_configs nvi openbsd_inetd openssh openssl os_prober pciutils
970N/A pm_utils procinfo_ng procps_ng readline reiserfsprogs rsyslog sed
1105N/A shadow sudo sysfsutils syslinux sysvinit tar tcp_wrappers tcsh
970N/A timezone traceroute udev unicon_tools util_linux xz zlib"}
970N/ACATEGORY[1]="01_minimum"
970N/APACKAGES[1]="FDclone autofs bc berkeley_db bsd_games cpio cpufreqd
970N/A cpufrequtils fortune_mod gc gdbm gpm hddtemp hdparm keyutils libelf
970N/A libieee1284 libusb libusb_compat libxml2 libzip linux_howto lm_sensors
970N/A lshw lsof lv man_pages man_pages_ja nilfs_utils nkf pcre perl popt
970N/A psmisc python recode rpm2targz ruby screen sg3_utils sharutils sqlite
970N/A squashfs_lzma sysstat texinfo time tree unzip usbutils utempter which
970N/A yaml zip zsh"
970N/ACATEGORY[2]="01_minimum/alsa.txz"
970N/APACKAGES[2]="alsa_lib alsa_plugins alsa_utils"
970N/ACATEGORY[3]="01_minimum/aspell.txz"
970N/APACKAGES[3]="aspell aspell6_en"
970N/ACATEGORY[4]="01_minimum/devel.txz"
970N/APACKAGES[4]="autoconf automake binutils bison cloog cvs diffutils flex
970N/A g++ gcc gdb gettext gmp indent intltool kernel_headers libc libtool
970N/A m4 make mpc mpfr onig patch pkg_config ppl pth slang strace yasm"
970N/ACATEGORY[5]="01_minimum/gnupg_tls.txz"
970N/APACKAGES[5]="gnupg gnutls gpgme libassuan libgcrypt libgpg_error libksba
970N/A libtasn1"
970N/ACATEGORY[6]="01_minimum/network.txz"
970N/APACKAGES[6]="bind bridge_utils curl cyrus_sasl dnsmasq ethtool fetchmail
970N/A heimdal hostapd iptables iw libidn libiec61883 libnl3 libpcap
970N/A libraw1394 libssh2 mailx metamail ncftp ntrack parprouted postfix
970N/A ppp procmail rsync setserial uml_utilities w3m wget wireless_tools
1130N/A wpa_supplicant"
970N/ACATEGORY[7]="01_minimum/nfs.txz"
970N/APACKAGES[7]="libevent libnfsidmap nfs_utils rpcbind"
970N/ACATEGORY[8]="01_minimum/tcl.txz"
970N/APACKAGES[8]="expect itcl tcl tclx"
970N/A
970N/Adownload_plamo() {
970N/A # check the mini plamo was not already downloaded
970N/A if ! mkdir -p $ptcache ; then
970N/A echo "Failed to create '$ptcache' directory."
970N/A return 1
970N/A fi
970N/A # download a mini plamo into a cache
970N/A echo "Downloading Plamo-$release minimal..."
970N/A echo "open $MIRRORSRV" > /tmp/getpkg
970N/A for i in `seq 0 $((${#CATEGORY[@]} - 1))` ; do
970N/A for p in ${PACKAGES[$i]} ; do
970N/A cat <<- EOF >> /tmp/getpkg
970N/A mget $MIRRORPATH/Plamo-$release/$arch/plamo/${CATEGORY[$i]}/$p-*.t?z
970N/A EOF
970N/A done
970N/A done
970N/A echo "close" >> /tmp/getpkg
970N/A cd $ptcache
970N/A if ! lftp -f /tmp/getpkg ; then
970N/A echo "Failed to download the rootfs, aborting."
970N/A return 1
970N/A fi
970N/A rm -f /tmp/getpkg
1105N/A mv $ptcache $dlcache
1105N/A echo "Download complete."
970N/A return 0
1105N/A}
970N/A
970N/Acopy_plamo() {
970N/A # make a local copy of the mini plamo
970N/A echo "Copying $rtcache to $rootfs..."
970N/A mkdir -p $rootfs
970N/A find $rtcache -mindepth 1 -maxdepth 1 -exec cp -a {} $rootfs \; || return 1
1527N/A return 0
1152N/A}
970N/A
1172N/Ainstall_plamo() {
1172N/A mkdir -p @LOCALSTATEDIR@/lock/subsys
1172N/A (
970N/A if ! flock -n 200 ; then
1105N/A echo "Cache repository is busy."
970N/A return 1
970N/A fi
1105N/A echo "Checking cache download in $dlcache..."
970N/A if [ ! -d $dlcache ] ; then
970N/A if ! download_plamo ; then
1120N/A echo "Failed to download plamo $release base packages."
1120N/A return 1
1120N/A fi
1479N/A fi
1479N/A if [ ! -x /sbin/installpkg ] ; then
1172N/A echo "'installpkg' command is missing."
1172N/A echo "Installing 'installpkg' command into $dlcache/sbin..."
1153N/A ( cd $dlcache ; tar xpJf hdsetup-*.txz ; rm -rf tmp usr var )
970N/A sed -i "/ldconfig/!s@/sbin@$dlcache&@g" $dlcache/sbin/installpkg*
970N/A PATH=$dlcache/sbin:$PATH
1356N/A fi
1356N/A echo "Installing packages to $rtcache..."
1356N/A if [ ! -d $rtcache ] ; then
1356N/A mkdir -p $rtcache
1356N/A for i in `seq 0 $((${#CATEGORY[@]} - 1))` ; do
1356N/A for p in ${PACKAGES[$i]} ; do
1356N/A installpkg -root $rtcache -priority ADD $dlcache/$p-*.t?z
1356N/A done
1356N/A done
1356N/A fi
970N/A echo "Copy $rtcache to $rootfs..."
970N/A if ! copy_plamo ; then
1105N/A echo "Failed to copy rootfs."
1105N/A return 1
1105N/A fi
970N/A return 0
970N/A ) 200> @LOCALSTATEDIR@/lock/subsys/lxc
970N/A}
1479N/A
1479N/Aconfigure_plamo() {
1105N/A # create /dev
970N/A mknod -m 666 $rootfs/dev/zero c 1 5
970N/A chmod 666 $rootfs/dev/random
1479N/A mknod -m 666 $rootfs/dev/urandom c 1 9
1479N/A mkdir -m 755 $rootfs/dev/pts
970N/A chmod 666 $rootfs/dev/tty
970N/A chmod 600 $rootfs/dev/console
970N/A mknod -m 666 $rootfs/dev/tty0 c 4 0
970N/A mknod -m 666 $rootfs/dev/tty1 c 4 1
970N/A mknod -m 666 $rootfs/dev/tty2 c 4 2
970N/A mknod -m 666 $rootfs/dev/tty3 c 4 3
970N/A mknod -m 666 $rootfs/dev/tty4 c 4 4
1316N/A mknod -m 666 $rootfs/dev/full c 1 7
1189N/A mknod -m 600 $rootfs/dev/initctl p
1189N/A mknod -m 666 $rootfs/dev/ptmx c 5 2
1189N/A # suppress log level output for udev
1316N/A sed -i 's/="err"/=0/' $rootfs/etc/udev/udev.conf
1189N/A # /etc/fstab
1316N/A cat <<- "EOF" > $rootfs/etc/fstab
1189N/A none /proc proc defaults 0 0
1189N/A none /sys sysfs defaults 0 0
1189N/A none /dev tmpfs defaults 0 0
970N/A none /tmp tmpfs defaults 0 0
970N/A none /dev/pts devpts gid=5,mode=620 0 0
970N/A none /proc/bus/usb usbfs noauto 0 0
970N/A none /var/lib/nfs/rpc_pipefs rpc_pipefs defaults 0 0
970N/A EOF
1189N/A # /etc/inittab
1189N/A cat <<- "EOF" | patch $rootfs/etc/inittab
970N/A 32,33c32,33
970N/A < # What to do when power fails (shutdown to single user).
970N/A < pf::powerfail:/sbin/shutdown -f +5 "THE POWER IS FAILING"
1132N/A ---
1132N/A > # What to do when power fails (shutdown).
1132N/A > pf::powerfail:/sbin/shutdown -h +0 "THE POWER IS FAILING"
970N/A 47a48
970N/A > 1:1235:respawn:/sbin/agetty 38400 console
970N/A 52,53d52
970N/A < c5:1235:respawn:/sbin/agetty 38400 tty5 linux
970N/A < c6:12345:respawn:/sbin/agetty 38400 tty6 linux
1276N/A EOF
1316N/A # set the hostname
970N/A echo "$name" > $rootfs/etc/HOSTNAME
970N/A # set minimal hosts
1132N/A echo "127.0.0.1 localhost $name" > $rootfs/etc/hosts
1132N/A # configure the network using the dhcp
1132N/A echo "DHCP" > $rootfs/var/run/inet1-scheme
1132N/A # localtime (JST)
1132N/A ln -s ../usr/share/zoneinfo/Asia/Tokyo $rootfs/etc/localtime
970N/A # disable pam_loginuid.so in /etc/pam.d/login (for libvirt's lxc driver)
1132N/A sed -i '/pam_loginuid/s/^/#/' $rootfs/etc/pam.d/login
1132N/A # glibc configure
1132N/A mv $rootfs/etc/ld.so.conf{.new,}
1132N/A chroot $rootfs ldconfig
1132N/A # root password
1147N/A echo "Setting root password to 'root'..."
1147N/A echo "root:root" | chroot $rootfs chpasswd
1147N/A echo "Please change root password!"
1147N/A # /etc/rc.d/rc.S
1132N/A ed - $rootfs/etc/rc.d/rc.S <<- "EOF"
1132N/A 230,261d
1132N/A 156,163d
1132N/A 26,147d
1132N/A 16,22d
1132N/A w
1298N/A EOF
1298N/A # /etc/rc.d/rc.M
1298N/A ed - $rootfs/etc/rc.d/rc.M <<- "EOF"
1298N/A 269,270d
1479N/A 56,82d
1479N/A 31,38d
1479N/A w
1298N/A EOF
1153N/A # /etc/rc.d/rc.inet1.tradnet
1153N/A head -n-93 $rootfs/sbin/netconfig.tradnet > /tmp/netconfig.rconly
1153N/A cat <<- EOF >> /tmp/netconfig.rconly
1153N/A PCMCIA=n
1172N/A RC=$rootfs/etc/rc.d/rc.inet1.tradnet
970N/A IFCONFIG=sbin/ifconfig
970N/A ROUTE=sbin/route
1003N/A INET1SCHEME=var/run/inet1-scheme
1003N/A IPADDR=127.0.0.1
1392N/A NETWORK=127.0.0.0
970N/A DHCPCD=usr/sbin/dhclient
970N/A LOOPBACK=y
1153N/A make_config_file
1172N/A EOF
1172N/A rm -f $rootfs/etc/rc.d/rc.inet1.tradnet
970N/A sh /tmp/netconfig.rconly
1172N/A rm -f /tmp/netconfig.rconly
1154N/A return 0
970N/A}
970N/A
970N/Acopy_configuration() {
970N/A if ! cat <<- EOF >> $path/config ; then
970N/A lxc.utsname = $name
970N/A
970N/A lxc.tty = 4
970N/A lxc.pts = 1024
1105N/A lxc.mount.auto = proc sys cgroup
1105N/A lxc.arch = $arch
970N/A lxc.cap.drop = sys_module mac_admin mac_override sys_time
1105N/A
1105N/A lxc.cgroup.devices.deny = a
1153N/A # /dev/null and zero
1153N/A lxc.cgroup.devices.allow = c 1:3 rwm
970N/A lxc.cgroup.devices.allow = c 1:5 rwm
1153N/A # consoles
1153N/A lxc.cgroup.devices.allow = c 5:0 rwm
1153N/A lxc.cgroup.devices.allow = c 5:1 rwm
1153N/A # /dev/{,u}random
970N/A lxc.cgroup.devices.allow = c 1:8 rwm
1479N/A lxc.cgroup.devices.allow = c 1:9 rwm
1479N/A lxc.cgroup.devices.allow = c 5:2 rwm
1479N/A lxc.cgroup.devices.allow = c 136:* rwm
1479N/A # rtc
1479N/A lxc.cgroup.devices.allow = c 254:0 rm
1479N/A # fuse
1479N/A lxc.cgroup.devices.allow = c 10:229 rwm
1479N/A EOF
970N/A echo "Failed to add configuration."
1261N/A return 1
1261N/A fi
1261N/A return 0
1261N/A}
1261N/A
970N/Apost_process() {
1261N/A # nothing do in Plamo Linux
1261N/A true
1152N/A}
1261N/A
1152N/Ado_bindhome() {
970N/A # bind-mount the user's path into the container's /home
970N/A h=`getent passwd $bindhome | cut -d: -f6`
970N/A mkdir -p $rootfs/$h
970N/A echo "$h $rootfs/$h none bind 0 0" >> $path/fstab
970N/A # copy /etc/passwd, /etc/shadow, and /etc/group entries into container
970N/A if ! pwd=`getent passwd $bindhome` ; then
970N/A echo "Warning: failed to copy password entry for $bindhome."
970N/A else
970N/A echo $pwd >> $rootfs/etc/passwd
970N/A fi
970N/A echo `getent shadow $bindhome` >> $rootfs/etc/shadow
970N/A}
970N/A
970N/Acleanup() {
970N/A [ -d $dlcache -a -d $rtcache ] || return 0
970N/A # lock, so we won't purge while someone is creating a repository
970N/A (
1153N/A if ! flock -n 200 ; then
970N/A echo "Cache repository is busy."
970N/A return 1
970N/A fi
970N/A echo "Purging the download cache..."
970N/A rm -rf --one-file-system $dlcache $rtcache || return 1
970N/A echo "Done."
1152N/A return 0
970N/A ) 200> @LOCALSTATEDIR@/lock/subsys/lxc
970N/A}
970N/A
970N/Ausage() {
970N/A cat <<- EOF
1261N/A $prog [-h|--help] -p|--path=<path> -n|--name=<name> --rootfs=<rootfs>
1261N/A [--clean] [-r|--release=<release>] [-b|--bindhome=<user>]
1261N/A [-a|--arch=<arch>]
1261N/A release: $release
970N/A bindhome: bind <user>'s home into the container
970N/A arch: x86 or x86_64: defaults to host arch
970N/A EOF
970N/A}
970N/A
1046N/Aprog=`basename $0`
1046N/Apath="" ; name="" ; rootfs=""
1046N/Aclean=0
1046N/Arelease=${release:-5.x}
1261N/Abindhome=""
1261N/Aarch=`uname -m | sed 's/i.86/x86/'` ; hostarch=$arch
1261N/Asopts=hp:n:cr:b:a:
1261N/Alopts=help,path:,name:,rootfs:,clean,release:,bindhome:,arch:
1261N/Aif ! options=`getopt -o $sopts -l $lopts -- "$@"` ; then
1261N/A usage
1261N/A exit 1
1261N/Afi
1261N/Aeval set -- "$options"
1261N/Awhile true ; do
1152N/A case "$1" in
1152N/A -h|--help) usage && exit 0 ;;
1261N/A -p|--path) path=$2 ; shift 2 ;;
1152N/A -n|--name) name=$2 ; shift 2 ;;
970N/A --rootfs) rootfs=$2 ; shift 2 ;;
1152N/A -c|--clean) clean=1 ; shift 1 ;;
1152N/A -r|--release) release=$2 ; shift 2 ;;
970N/A -b|--bindhome) bindhome=$2 ; shift 2 ;;
970N/A -a|--arch) arch=$2 ; shift 2 ;;
970N/A --) shift 1 ; break ;;
1261N/A *) break ;;
1261N/A esac
1261N/Adone
970N/Aif [ $clean -eq 1 -a -z "$path" ] ; then
970N/A cleanup || exit 1
970N/A exit 0
970N/Afi
1152N/Aif [ $hostarch == "x86" -a $arch == "x86_64" ] ; then
1152N/A echo "Can't create x86_64 container on x86."
1152N/A exit 1
1152N/Afi
1152N/Aif [ -z "$path" ] ; then
1152N/A echo "'path' parameter is required."
1152N/A exit 1
1153N/Afi
1153N/Aif [ -z "$name" ] ; then
1153N/A echo "'name' parameter is required."
1153N/A exit 1
1153N/Afi
1153N/Aif [ `id -u` -ne 0 ] ; then
1152N/A echo "This script should be run as 'root'."
1153N/A exit 1
1152N/Afi
1152N/Acache=@LOCALSTATEDIR@/cache/lxc
1153N/Aptcache=$cache/partial-${prog##*-}-$release-$arch
1152N/Adlcache=$cache/cache-${prog##*-}-$release-$arch
1152N/Artcache=$cache/rootfs-${prog##*-}-$release-$arch
1152N/Aif [ -z "$rootfs" ] ; then
970N/A if grep -q "^lxc.rootfs" $path/config ; then
1153N/A rootfs=$(awk -F= '/^lxc.rootfs =/{ print $2 }' $path/config)
1153N/A else
1153N/A rootfs=$path/rootfs
1153N/A fi
1153N/Afi
1153N/Aif ! install_plamo ; then
1153N/A echo "Failed to install plamo $release."
1153N/A exit 1
1153N/Afi
1130N/Aif ! configure_plamo ; then
1130N/A echo "Failed to configure plamo $release for a container."
1130N/A exit 1
1130N/Afi
1130N/Aif ! copy_configuration ; then
1130N/A echo "Failed to write configuration file."
1130N/A exit 1
1130N/Afi
1130N/Apost_process
1130N/Aif [ -n "$bindhome" ] ; then
1130N/A do_bindhome
1130N/Afi
1130N/Aif [ $clean -eq 1 ] ; then
1130N/A cleanup || exit 1
1130N/A exit 0
1161N/Afi
1130N/A