mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-07-24 17:35:40 +00:00
Add LXC template script of Sabayon OS
Signed-off-by: Geaaru <geaaru@gmail.com>
This commit is contained in:
parent
9eed569a22
commit
11f88f10cd
@ -897,6 +897,7 @@ AC_CONFIG_FILES([
|
||||
templates/lxc-ubuntu-cloud
|
||||
templates/lxc-sparclinux
|
||||
templates/lxc-voidlinux
|
||||
templates/lxc-sabayon
|
||||
|
||||
src/Makefile
|
||||
src/lxc/Makefile
|
||||
|
@ -21,4 +21,5 @@ templates_SCRIPTS = \
|
||||
lxc-ubuntu \
|
||||
lxc-ubuntu-cloud \
|
||||
lxc-sparclinux \
|
||||
lxc-voidlinux
|
||||
lxc-voidlinux \
|
||||
lxc-sabayon
|
||||
|
502
templates/lxc-sabayon.in
Normal file
502
templates/lxc-sabayon.in
Normal file
@ -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@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
|
Loading…
Reference in New Issue
Block a user