[lxc-devel] [lxc/master] Add LXC template script of Sabayon OS

geaaru on Github lxc-bot at linuxcontainers.org
Sat Jan 28 22:02:07 UTC 2017


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 391 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20170128/9e2a1578/attachment.bin>
-------------- next part --------------
From b1c6ef82e671528409dea2989eac23146538d83e Mon Sep 17 00:00:00 2001
From: Geaaru <geaaru at gmail.com>
Date: Sat, 28 Jan 2017 22:55:25 +0100
Subject: [PATCH] Add LXC template script of Sabayon OS

---
 templates/Makefile.am    |   3 +-
 templates/lxc-sabayon.in | 502 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 504 insertions(+), 1 deletion(-)
 create mode 100644 templates/lxc-sabayon.in

diff --git a/templates/Makefile.am b/templates/Makefile.am
index c6c5ea5..6d889c4 100644
--- a/templates/Makefile.am
+++ b/templates/Makefile.am
@@ -21,4 +21,5 @@ templates_SCRIPTS = \
 	lxc-ubuntu \
 	lxc-ubuntu-cloud \
 	lxc-sparclinux \
-	lxc-voidlinux
+	lxc-voidlinux \
+	lxc-sabayon
diff --git a/templates/lxc-sabayon.in b/templates/lxc-sabayon.in
new file mode 100644
index 0000000..4c9adbc
--- /dev/null
+++ b/templates/lxc-sabayon.in
@@ -0,0 +1,502 @@
+#!/bin/sh
+# vim: set ts=4 sw=4 expandtab
+
+# Exit on error and treat unset variables as an error.
+set -eu
+
+#
+# LXC template for Sabayon OS, based of Alpine script.
+#
+
+# Authors:
+# Geaaru <geaaru at gmail.com>
+
+# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+#===========================  Constants  ============================#
+
+# Make sure the usual locations are in PATH
+export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
+
+readonly LOCAL_STATE_DIR='@LOCALSTATEDIR@'
+readonly LXC_TEMPLATE_CONFIG='@LXCTEMPLATECONFIG@'
+
+
+# Temporary static MIRROR LIST. I will get list from online path on the near future.
+readonly MIRRORS_LIST="
+http://mirror.it.sabayon.org/
+http://dl.sabayon.org/
+http://ftp.kddilabs.jp/Linux/packages/sabayonlinux/
+ftp://ftp.klid.dk/sabayonlinux/
+http://ftp.fsn.hu/pub/linux/distributions/sabayon/
+http://ftp.cc.uoc.gr/mirrors/linux/SabayonLinux/
+http://ftp.rnl.ist.utl.pt/pub/sabayon/
+ftp://ftp.nluug.nl/pub/os/Linux/distr/sabayonlinux/
+http://ftp.surfnet.nl/pub/os/Linux/distr/sabayonlinux/
+http://mirror.internode.on.net/pub/sabayon/
+http://mirror.yandex.ru/sabayon/
+http://sabayon.c3sl.ufpr.br/
+http://mirror.umd.edu/sabayonlinux/
+http://mirror.clarkson.edu/sabayon/
+http://na.mirror.garr.it/mirrors/sabayonlinux/"
+
+#========================  Global variables  ========================#
+
+# Clean variables and set defaults.
+arch="$(uname -m)"
+debug='no'
+flush_cache='no'
+mirror_url=
+name=
+path=
+release="DAILY"
+rootfs=
+unprivileged=false
+mapped_uid=
+mapped_gid=
+
+#========================  Helper Functions  ========================#
+
+usage() {
+    cat <<-EOF
+Template specific options can be passed to lxc-create after a '--' like this:
+
+    lxc-create --name=NAME [lxc-create-options] -- [template-options]
+
+Template options:
+    -a ARCH, --arch=ARCH   The container architecture (e.g. x86_64, armv7); defaults
+                           to the host arch.
+    -d, --debug            Run this script in a debug mode (set -x and wget w/o -q).
+    -m URL --mirror=URL    The Sabayon mirror to use; defaults to random mirror.
+    -u, --unprivileged     Tuning of rootfs for unprivileged containers.
+                           Are needed --mapped-gid and --mapped-uid options.
+    -r, --release          Identify release to use. Default is DAILY.
+    --mapped-gid           Group Id to use on unprivileged container
+                           (based of value present on file /etc/subgid).
+    --mapped-uid           User Id to use on unprivileged container
+                           (based of value present on file /etc/subuid)
+
+Environment variables:
+    RELEASE                Release version of Sabayon. Default is ${RELEASE}.
+EOF
+}
+
+random_mirror_url() {
+    local url=""
+
+    if [ $arch == 'amd64' ] ; then
+        url=$(echo $MIRRORS_LIST | sed -e 's/ /\n/g' |  sort -R --random-source=/dev/urandom | head -n 1)
+    else
+        if [ $arch == 'armv7l' ] ; then
+            # Currently armv7l tarball is not on sabayon mirrored tree.
+            url="https://dockerbuilder.sabayon.org/"
+        fi
+    fi
+
+    [ -n "$url" ] && echo "$url"
+}
+
+die() {
+    local retval=$1; shift
+
+    echo -e "==> $@\n"
+    exit $retval
+}
+
+einfo() {
+    echo -e "==> $@\n"
+}
+
+fetch() {
+    if [ "$debug" = 'yes' ]; then
+        wget -T 10 -O - $@
+    else
+        wget -T 10 -O - -q $@
+    fi
+}
+
+parse_arch() {
+    case "$1" in
+        x86_64 | amd64) echo 'amd64';;
+        armv7 | armv7l) echo 'armv7l';;
+        #arm*) echo 'armhf';;
+        *) return 1;;
+    esac
+}
+
+run_exclusively() {
+
+    local lock_name="$1"
+    local timeout=$2
+    local method=$3
+    shift 3
+
+    mkdir -p "$LOCAL_STATE_DIR/lock/subsys"
+
+    local retval
+    {
+        echo -n "Obtaining an exclusive lock..."
+        if ! flock -x 9; then
+            echo ' failed.'
+            return 1
+        fi
+        echo ' done'
+
+        ${method} $@
+        retval=$?
+    } 9> "$LOCAL_STATE_DIR/lock/subsys/lxc-sabayon-$lock_name"
+
+    return $retval
+}
+
+create_url () {
+
+    local url=""
+    # Example of amd64 tarball url
+    # http://mirror.yandex.ru/sabayon/iso/daily/Sabayon_Linux_DAILY_amd64_tarball.tar.gz
+
+    if [ $arch == 'amd64' ] ; then
+
+        if [ $release = 'DAILY' ] ; then
+            url="${MIRROR_URL}iso/daily/Sabayon_Linux_DAILY_amd64_tarball.tar.gz"
+        else
+            url="${MIRROR_URL}iso/monthly/Sabayon_Linux_${release}_amd64_tarball.tar.gz"
+        fi
+    else
+        # https://dockerbuilder.sabayon.org/Sabayon_Linux_16_armv7l.tar.bz2
+        if [ $arch == 'armv7l' ] ; then
+
+            # Currently $arch tarball is not on sabayon mirrored tree.
+            url="${MIRROR_URL}Sabayon_Linux_16_armv7l.tar.bz2"
+
+        fi
+    fi
+
+    echo $url
+}
+
+
+#===========================  Configure  ===========================#
+
+unprivileged_rootfs() {
+
+   pushd ${rootfs}/etc/systemd/system
+
+   # Disable systemd-journald-audit.socket because it seems that doesn't
+   # start correctly on unprivileged container
+   ln -s /dev/null systemd-journald-audit.socket
+
+   # Disable systemd-remount-fs.service because on unprivileged container
+   # systemd can't remount filesystem
+   ln -s /dev/null systemd-remount-fs.service
+
+   # Remove mount of FUSE Control File system
+   ln -s /dev/null sys-fs-fuse-connections.mount
+
+   # Change execution of service systemd-sysctl to avoid errors.
+   mkdir systemd-sysctl.service.d
+   cat <<EOF > systemd-sysctl.service.d/00gentoo.conf
+[Service]
+ExecStart=
+ExecStart=/usr/lib/systemd/systemd-sysctl  --prefix=/etc/sysctl.d/
+EOF
+
+   # Disable mount of hugepages
+   ln -s /dev/null dev-hugepages.mount
+
+   # Fix TERM variable for container console
+   mkdir container-getty\@0.service.d
+   cat <<EOF > container-getty\@0.service.d/00gentoo.conf
+[Service]
+Environment=TERM=
+Environment=TERM=linux
+EOF
+
+
+   popd
+
+   pushd ${rootfs}
+
+   # Disable sabayon-anti-fork-bomb limits (already apply to lxc container manager)
+   sed -i -e 's/^*/#*/g'   ./etc/security/limits.d/00-sabayon-anti-fork-bomb.conf || return 1
+   sed -i -e 's/^root/#root/g'   ./etc/security/limits.d/00-sabayon-anti-fork-bomb.conf || return 1
+
+   popd
+
+   return 0
+}
+
+unprivileged_shift_owner () {
+
+    # I use /usr/bin/fuidshift from LXD project.
+
+    einfo "Executing: fuidshift ${rootfs} u:0:${mapped_uid}:65536 g:0:${mapped_gid}:65536 ..."
+
+    fuidshift ${rootfs} u:0:${mapped_uid}:65536 g:0:${mapped_gid}:65536 ||
+        die 1 "Error on change owners of ${rootfs} directory"
+
+    einfo "Done."
+
+    # Fix permission of container directory
+    chmod a+rx ${path}
+
+    return 0
+}
+
+systemd_container_tuning () {
+
+    # To avoid error on start systemd-tmpfiles-setup service
+    # it is needed clean journal directory
+    rm -rf ${rootfs}/var/log/journal/
+
+    # Remove LVM service. Normally not needed on container system.
+    rm -rf ${rootfs}/etc/systemd/system/sysinit.target.wants/lvm2-lvmetad.service
+
+    return 0
+}
+
+configure_container() {
+    local config="$1"
+    local hostname="$2"
+    local arch="$3"
+    local privileged_options=""
+    local unprivileged_options=""
+
+    if [[ $unprivileged && $unprivileged == true ]] ; then
+        unprivileged_options="
+lxc.mount.auto = proc:mixed sys:mixed cgroup:mixed
+
+# Enable tty console for lxc-console command
+lxc.tty = 1
+
+lxc.id_map = u 0 ${mapped_uid} 65536
+lxc.id_map = g 0 ${mapped_gid} 65536
+"
+
+    else
+        privileged_options="
+lxc.mount.auto = proc:mixed sys:mixed cgroup:mixed
+lxc.cgroup.devices.deny = a
+lxc.cgroup.devices.allow = b *:* m
+lxc.cgroup.devices.allow = c *:* m
+lxc.cgroup.devices.allow = c 136:* rwm
+lxc.cgroup.devices.allow = c 1:3 rwm
+lxc.cgroup.devices.allow = c 1:5 rwm
+lxc.cgroup.devices.allow = c 1:7 rwm
+lxc.cgroup.devices.allow = c 1:8 rwm
+lxc.cgroup.devices.allow = c 1:9 rwm
+lxc.cgroup.devices.allow = c 5:0 rwm
+lxc.cgroup.devices.allow = c 5:1 rwm
+lxc.cgroup.devices.allow = c 5:2 rwm
+lxc.cgroup.devices.allow = c 10:229 rwm
+"
+    fi
+
+    cat <<-EOF >> "$config"
+# Specify container architecture.
+lxc.arch = $arch
+
+# Set hostname.
+lxc.utsname = $hostname
+
+# If something doesn't work, try to comment this out.
+# Dropping sys_admin disables container root from doing a lot of things
+# that could be bad like re-mounting lxc fstab entries rw for example,
+# but also disables some useful things like being able to nfs mount, and
+# things that are already namespaced with ns_capable() kernel checks, like
+# hostname(1).
+lxc.cap.drop = sys_time sys_module sys_rawio mac_admin mac_override
+#lxc.cap.drop = sys_admin
+
+lxc.autodev = 1
+lxc.pts = 1024
+
+$unprivileged_options
+$privileged_options
+
+# Customize lxc options through common directory
+lxc.include = /usr/share/lxc/config/common.conf.d/
+
+EOF
+}
+
+
+#=============================  Main  ==============================#
+
+parse_cmdline() {
+
+    # Parse command options.
+    local short_options="a:dm:n:p:r:hu"
+    local long_options="arch:,debug,mirror:,name:,path:,release:,rootfs:,mapped-uid:,mapped-gid:,help"
+
+    options=$(getopt -u -q -a -o "$short_options" -l "$long_options" -- "$@")
+
+    eval set -- "$options"
+
+    # Process command options.
+    while [ $# -gt 0 ]; do
+        case $1 in
+            -a | --arch)
+                arch=$2
+                shift
+                ;;
+            -d | --debug)
+                debug='yes'
+                ;;
+            -m | --mirror)
+                mirror_url=$2
+                shift
+                ;;
+            -n | --name)
+                name=$2
+                shift
+                ;;
+            -p | --path)
+                path=$2
+                shift
+                ;;
+            -r | --release)
+                release=$2
+                shift
+                ;;
+            --rootfs)
+                rootfs=$2
+                shift
+                ;;
+            -u | --unprivileged)
+                unprivileged=true
+                ;;
+            -h | --help)
+                usage
+                exit 1
+                ;;
+            --mapped-uid)
+                mapped_uid=$2
+                shift
+                ;;
+            --mapped-gid)
+                mapped_gid=$2
+                shift
+                ;;
+            --)
+                break
+                ;;
+            *)
+                einfo "Unknown option: $1"
+                usage
+                exit 1
+                ;;
+        esac
+        shift
+    done
+
+    if [ "$(id -u)" != "0" ]; then
+        die 1 "This script must be run as 'root'"
+    fi
+
+    # Validate options.
+    [ -n "$name" ] || die 1 'Missing required option --name'
+    [ -n "$path" ] || die 1 'Missing required option --path'
+
+    if [ -z "$rootfs" ] && [ -f "$path/config" ]; then
+        rootfs="$(sed -nE 's/^lxc.rootfs\s*=\s*(.*)$/\1/p' "$path/config")"
+    fi
+    if [ -z "$rootfs" ]; then
+        rootfs="$path/rootfs"
+    fi
+
+    [ -z "$path" ] && die 1 "'path' parameter is required."
+
+    arch=$(parse_arch "$arch") \
+        || die 1 "Unsupported architecture: $arch"
+
+    [[ $unprivileged && $unprivileged == true && -z "$mapped_uid" ]] && \
+        die 1 'Missing required option --mapped-uid with --unprivileged option'
+
+    [[ $unprivileged && $unprivileged == true && -z "$mapped_gid" ]] && \
+        die 1 'Missing required option --mapped-gid with --unprivileged option'
+
+    return 0
+}
+
+main () {
+
+    local tarball=""
+
+    # Set global variables.
+    RELEASE="${RELEASE:-"DAILY"}"
+    ARCH="${ARCH:-`uname -m`}"
+    OS="${OS:-"sabayon"}"
+
+    einfo "Processing command line arguments: $@"
+
+    # Parse command line options
+    parse_cmdline "$@"
+
+    DEBUG="$debug"
+    MIRROR_URL="${mirror_url:-$(random_mirror_url)}"
+
+    einfo "Use arch = $arch, mirror_url = $MIRROR_URL, path = $path, name = $name, release = $release, unprivileged = $unprivileged, rootfs = $rootfs, mapped_uid = $mapped_uid, mapped_gid = $mapped_gid"
+
+    [ "$debug" = 'yes' ] && set -x
+
+    # Download sabayon tarball
+    tarball=$(create_url)
+    einfo "Fetching tarball $tarball..."
+
+    # TODO: use only a compression mode
+    if [ $arch == 'amd64' ] ; then
+        fetch "${tarball}" | tar -xpz -C "${rootfs}"
+    else
+        if [ $arch == 'armv7l' ] ; then
+            fetch "${tarball}" | tar -xpj -C "${rootfs}"
+        fi
+    fi
+
+    einfo "Tarball ${tarball} Extracted."
+
+    systemd_container_tuning
+
+    # Fix container for unprivileged mode.
+    if [[ $unprivileged && $unprivileged == true ]] ; then
+        unprivileged_rootfs
+        unprivileged_shift_owner
+    fi
+
+    return 0
+}
+
+
+einfo "Prepare creation of sabayon container with params: $@ ($#)"
+
+# Here we go!
+run_exclusively 'main' 10 main "$@"
+configure_container "$path/config" "$name" "$arch"
+
+einfo "Container's rootfs and config have been created"
+cat <<-EOF
+    Edit the config file $path/config to check/enable networking setup.
+    The installed system is preconfigured for a loopback and single network
+    interface configured via DHCP.
+
+    To start the container, run "lxc-start -n $name".
+    The root password is not set; to enter the container run "lxc-attach -n $name".
+
+    Note: From kenel >= 4.6 for use unprivileged containers it is needed this mount on host:
+
+    mkdir /sys/fs/cgroup/systemd
+    mount -t cgroup -o none,name=systemd systemd /sys/fs/cgroup/systemd
+EOF


More information about the lxc-devel mailing list