-
-
Save tpokorra/8bc85d2963ddc219ba0a to your computer and use it in GitHub Desktop.
| #!/bin/bash | |
| # | |
| # lxc: linux Container library | |
| # Authors: | |
| # Original Debian: | |
| # Daniel Lezcano <[email protected]> | |
| # Changes for Raspberry Pi by: | |
| # Oliver Heller <[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 | |
| SUITE=${SUITE:-jessie} | |
| MIRROR=${MIRROR:-http://archive.raspbian.org/raspbian} | |
| configure_debian() | |
| { | |
| rootfs=$1 | |
| hostname=$2 | |
| # squeeze only has /dev/tty and /dev/tty0 by default, | |
| # therefore creating missing device nodes for tty1-4. | |
| for tty in $(seq 1 4); do | |
| if [ ! -e $rootfs/dev/tty$tty ]; then | |
| mknod $rootfs/dev/tty$tty c 4 $tty | |
| fi | |
| done | |
| # configure the inittab | |
| cat <<EOF > $rootfs/etc/inittab | |
| id:2:initdefault: | |
| si::sysinit:/etc/init.d/rcS | |
| 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 | |
| 1:2345:respawn:/sbin/getty 38400 console | |
| c1:12345:respawn:/sbin/getty 38400 tty1 linux | |
| c2:12345:respawn:/sbin/getty 38400 tty2 linux | |
| c3:12345:respawn:/sbin/getty 38400 tty3 linux | |
| c4:12345:respawn:/sbin/getty 38400 tty4 linux | |
| EOF | |
| # disable selinux in debian | |
| mkdir -p $rootfs/selinux | |
| echo 0 > $rootfs/selinux/enforce | |
| # configure the network using the dhcp | |
| cat <<EOF > $rootfs/etc/network/interfaces | |
| auto lo | |
| iface lo inet loopback | |
| auto eth0 | |
| iface eth0 inet dhcp | |
| EOF | |
| # set the hostname | |
| cat <<EOF > $rootfs/etc/hostname | |
| $hostname | |
| EOF | |
| # reconfigure some services | |
| LANG="${LANG:-en_US.UTF-8}" | |
| locale="$LANG $(echo $LANG | cut -d. -f2)" | |
| chroot $rootfs echo "locales locales/default_environment_locale select $LANG" | chroot $rootfs sh -c "LANG=C debconf-set-selections" | |
| chroot $rootfs echo "locales locales/default_environment_locale seen true" | chroot $rootfs sh -c "LANG=C debconf-set-selections" | |
| chroot $rootfs echo "locales locales/locales_to_be_generated seen true" | chroot $rootfs sh -c "LANG=C debconf-set-selections" | |
| chroot $rootfs sed -i -e "0,/^[# ]*$locale *$/ s/^[# ]*$locale *$/$locale/" /etc/locale.gen | |
| chroot $rootfs sh -c "LANG=C dpkg-reconfigure locales -f noninteractive" | |
| # remove pointless services in a container | |
| chroot $rootfs /usr/sbin/update-rc.d -f checkroot.sh remove # S | |
| chroot $rootfs /usr/sbin/update-rc.d checkroot.sh stop 09 S . | |
| chroot $rootfs /usr/sbin/update-rc.d -f umountfs remove # 0 6 | |
| chroot $rootfs /usr/sbin/update-rc.d umountfs start 09 0 6 . | |
| chroot $rootfs /usr/sbin/update-rc.d -f umountroot remove # 0 6 | |
| chroot $rootfs /usr/sbin/update-rc.d umountroot start 10 0 6 . | |
| # The following initscripts don't provide an empty start or stop block. | |
| # To prevent them being enabled on upgrades, we leave a start link on | |
| # runlevel 3. | |
| chroot $rootfs /usr/sbin/update-rc.d -f hwclock.sh remove # S 0 6 | |
| chroot $rootfs /usr/sbin/update-rc.d hwclock.sh start 10 3 . | |
| chroot $rootfs /usr/sbin/update-rc.d -f hwclockfirst.sh remove # S | |
| chroot $rootfs /usr/sbin/update-rc.d hwclockfirst start 08 3 . | |
| chroot $rootfs /usr/sbin/update-rc.d -f module-init-tools remove # S | |
| chroot $rootfs /usr/sbin/update-rc.d module-init-tools start 10 3 . | |
| echo "root:root" | chroot $rootfs chpasswd | |
| echo "Root password is 'root', please change !" | |
| return 0 | |
| } | |
| cleanup() | |
| { | |
| rm -rf $cache/partial-$SUITE-$arch | |
| rm -rf $cache/rootfs-$SUITE-$arch | |
| } | |
| download_debian() | |
| { | |
| packages=\ | |
| ifupdown,\ | |
| locales,\ | |
| libui-dialog-perl,\ | |
| dialog,\ | |
| isc-dhcp-client,\ | |
| netbase,\ | |
| net-tools,\ | |
| iproute,\ | |
| openssh-server | |
| cache=$1 | |
| arch=$2 | |
| trap cleanup EXIT SIGHUP SIGINT SIGTERM | |
| # check the mini debian was not already downloaded | |
| mkdir -p "$cache/partial-$SUITE-$arch" | |
| if [ $? -ne 0 ]; then | |
| echo "Failed to create '$cache/partial-$SUITE-$arch' directory" | |
| return 1 | |
| fi | |
| # download a mini debian into a cache | |
| echo "Downloading debian minimal ..." | |
| qemu-debootstrap --verbose --variant=minbase --arch=$arch \ | |
| --include=$packages \ | |
| "$SUITE" "$cache/partial-$SUITE-$arch" $MIRROR | |
| if [ $? -ne 0 ]; then | |
| echo "Failed to download the rootfs, aborting." | |
| return 1 | |
| fi | |
| mv "$1/partial-$SUITE-$arch" "$1/rootfs-$SUITE-$arch" | |
| echo "Download complete." | |
| trap EXIT | |
| trap SIGINT | |
| trap SIGTERM | |
| trap SIGHUP | |
| return 0 | |
| } | |
| copy_debian() | |
| { | |
| cache=$1 | |
| arch=$2 | |
| rootfs=$3 | |
| # make a local copy of the minidebian | |
| echo -n "Copying rootfs to $rootfs..." | |
| mkdir -p $rootfs | |
| rsync -a "$cache/rootfs-$SUITE-$arch"/ $rootfs/ || return 1 | |
| return 0 | |
| } | |
| install_debian() | |
| { | |
| cache="/var/cache/lxc/pi" | |
| rootfs=$1 | |
| mkdir -p /var/lock/subsys/ | |
| ( | |
| flock -x 200 | |
| if [ $? -ne 0 ]; then | |
| echo "Cache repository is busy." | |
| return 1 | |
| fi | |
| arch="armhf" | |
| echo "Checking cache download in $cache/rootfs-$SUITE-$arch ... " | |
| if [ ! -e "$cache/rootfs-$SUITE-$arch" ]; then | |
| download_debian $cache $arch | |
| if [ $? -ne 0 ]; then | |
| echo "Failed to download 'debian base'" | |
| return 1 | |
| fi | |
| fi | |
| copy_debian $cache $arch $rootfs | |
| if [ $? -ne 0 ]; then | |
| echo "Failed to copy rootfs" | |
| return 1 | |
| fi | |
| return 0 | |
| ) 200>/var/lock/subsys/lxc | |
| return $? | |
| } | |
| copy_configuration() | |
| { | |
| path=$1 | |
| rootfs=$2 | |
| name=$3 | |
| cat >> $path/config << EOF | |
| # $path/config | |
| ## Container | |
| lxc.utsname = $name | |
| lxc.rootfs = $rootfs | |
| lxc.tty = 4 | |
| lxc.pts = 1024 | |
| #lxc.console = /var/log/lxc/$name.console | |
| ## Capabilities | |
| lxc.cap.drop = sys_admin | |
| # uncomment the next line to run the container unconfined: | |
| #lxc.aa_profile = unconfined | |
| ## Devices | |
| #lxc.cgroup.devices.allow = a | |
| lxc.cgroup.devices.deny = a | |
| # /dev/null | |
| lxc.cgroup.devices.allow = c 1:3 rwm | |
| # /dev/zero | |
| lxc.cgroup.devices.allow = c 1:5 rwm | |
| # /dev/tty[1-4] 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 | |
| # /dev/rtc | |
| lxc.cgroup.devices.allow = c 254:0 rwm | |
| ## Limits | |
| #lxc.cgroup.cpu.shares = 1024 | |
| #lxc.cgroup.cpuset.cpus = 0 | |
| #lxc.cgroup.memory.limit_in_bytes = 256M | |
| #lxc.cgroup.memory.memsw.limit_in_bytes = 1G | |
| ## Filesystem | |
| lxc.mount.entry = proc proc proc nodev,noexec,nosuid 0 0 | |
| lxc.mount.entry = sysfs sys sysfs defaults,ro 0 0 | |
| #lxc.mount.entry = /srv/$name srv/$name none defaults,bind 0 0 | |
| EOF | |
| if [ $? -ne 0 ]; then | |
| echo "Failed to add configuration" | |
| return 1 | |
| fi | |
| return 0 | |
| } | |
| clean() | |
| { | |
| cache="/var/cache/lxc/pi" | |
| if [ ! -e $cache ]; then | |
| exit 0 | |
| fi | |
| # lock, so we won't purge while someone is creating a repository | |
| ( | |
| flock -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 | |
| $1 -h|--help -p|--rootpath=<path> --clean | |
| EOF | |
| return 0 | |
| } | |
| options=$(getopt -o hp:n:c -l help,path:,rootfs:,name:,clean -- "$@") | |
| 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;; | |
| --rootfs) rootfs=$2; shift 2;; | |
| -n|--name) name=$2; shift 2;; | |
| -c|--clean) clean=$2; shift 2;; | |
| --) shift 1; break ;; | |
| *) break ;; | |
| esac | |
| done | |
| if [ ! -z "$clean" -a -z "$path" ]; then | |
| clean || exit 1 | |
| exit 0 | |
| fi | |
| type qemu-debootstrap | |
| if [ $? -ne 0 ]; then | |
| echo "'qemu-debootstrap' command is missing" | |
| exit 1 | |
| fi | |
| if [ -z "$path" ]; then | |
| echo "'path' parameter is required" | |
| exit 1 | |
| fi | |
| if [ "$(id -u)" != "0" ]; then | |
| echo "This script should be run as 'root'" | |
| exit 1 | |
| fi | |
| #rootfs=$path/rootfs | |
| install_debian $rootfs | |
| if [ $? -ne 0 ]; then | |
| echo "failed to install debian" | |
| exit 1 | |
| fi | |
| configure_debian $rootfs $name | |
| if [ $? -ne 0 ]; then | |
| echo "failed to configure debian for a container" | |
| exit 1 | |
| fi | |
| copy_configuration $path $rootfs $name | |
| if [ $? -ne 0 ]; then | |
| echo "failed write configuration file" | |
| exit 1 | |
| fi | |
| if [ ! -z $clean ]; then | |
| clean || exit 1 | |
| exit 0 | |
| fi |
trying the config file from Debian Jessie:
# Distribution configuration
lxc.include = /usr/share/lxc/config/debian.common.conf
# Container specific configuration
lxc.utsname = raspberry-jessie
lxc.rootfs = /var/lib/lxc/raspberry-jessie/rootfs
# Network configuration
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = lxcbr0
lxc.network.hwaddr = 00:16:3e:bd:05:d2
lxc.network.ipv4=10.0.3.50/24
lxc.network.ipv4.gateway=10.0.3.1
lxc.aa_profile = unconfined
lxc.kmsg = 0
lxc.autodev = 1
lxc.cap.drop = mknod
shows error:
systemd 215 running in system mode. (+PAM +AUDIT +SELINUX +IMA +SYSVINIT +LIBCRYPTSETUP +GCRYPT +ACL +XZ -SECCOMP -APPARMOR)
Detected virtualization 'lxc'.
Detected architecture 'arm'.
Welcome to Raspbian GNU/Linux 8 (jessie)!
Set hostname to <raspberry-jessie>.
Unsupported ioctl: cmd=0x8933
qemu: Unsupported syscall: 355
Failed to allocate manager object: Function not implemented
original script from https://d24m.de/opensource/2013/07/19/raspbian-unter-lxc.html
goes to /usr/share/lxc/templates/lxc-pi
sudo apt-get install qemu-user-static
sudo lxc-create -t pi -n raspberry-container
on Fedora (qemu 2.3.1 in F22, https://apps.fedoraproject.org/packages/qemu):
sudo dnf install qemu
replace qemu-debootstrap with debootstrap in /usr/share/lxc/templates/lxc-pi
lxc-create -t pi -n raspberry-container
I get this error:
W: Failure trying to run: chroot /var/cache/lxc/pi/partial-jessie-armhf mount -t proc proc /proc
W: See /var/cache/lxc/pi/partial-jessie-armhf/debootstrap/debootstrap.log for details
Failed to download the rootfs, aborting.
Failed to download 'debian base'
failed to install debian
lxc-create: lxccontainer.c: create_run_template: 1201 container creation template for raspberry-container failed
lxc-create: lxc_create.c: main: 274 Error creating container raspberry-container
see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=770658, setting Path in lxc-pi before debootstrap call
PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
That does not seem to help.
Running the script directly:
/usr/share/lxc/templates/lxc-pi -p /var/cache/lxc/pi/test
I hope I could still find the debootstrap log file.
or even more directly:
debootstrap --verbose --variant=minbase --arch=armhf --include=ifupdown,locales,libui-dialog-perl,dialog,isc-dhcp-client,netbase,net-tools,iproute,openssh-server jessie /var/cache/lxc/pi/partial-jessie-armhf http://archive.raspbian.org/raspbian
Shows error:
W: Failure trying to run: chroot /var/cache/lxc/pi/partial-jessie-armhf mount -t proc proc /proc
W: See /var/cache/lxc/pi/partial-jessie-armhf/debootstrap/debootstrap.log for details
Detail in debootstrap.log:
chroot: failed to run command 'mount': No such file or directory
This happens when the arch is different. The /bin/mount works on ARM, but not on my 64 bit. So I need qemu-debootstrap, but I cannot find where to get that on Fedora...
see this: https://wiki.ubuntu.com/ARM/RootfsFromScratch/QemuDebootstrap
splitting into two parts:
rootfs=/var/cache/lxc/pi/partial-jessie-armhf
debootstrap --verbose --foreign --variant=minbase --arch=armhf --include=ifupdown,locales,libui-dialog-perl,dialog,isc-dhcp-client,netbase,net-tools,iproute,openssh-server jessie $rootfs http://archive.raspbian.org/raspbian
cp /usr/bin/qemu-arm $rootfs/usr/bin
sudo chroot $rootfs /bin/bash
that also does not work...
see https://wiki.debian.org/QemuUserEmulation and https://lists.fedoraproject.org/pipermail/arm/2014-January/007307.html
see https://copr.fedorainfracloud.org/coprs/bboozzoo/qemu-arm-static/ I have rebuilt that package for my Fedora 22, and installed it. see https://copr.fedorainfracloud.org/coprs/tpokorra/qemu-arm-static/
qemu-binfmt-conf.sh
chroot $rootfs /bin/bash
/debootstrap/debootstrap --second-stage
now works...
For Jessie see debops/ansible-lxc#15
Adding to the end of the config file of the container:
Currently that still does not start for me