2 # vim: set ts=4 sw=4 expandtab
4 # Exit on error and treat unset variables as an error.
8 # LXC template for Sabayon OS, based of Alpine script.
12 # Geaaru <geaaru@gmail.com>
14 # This library is free software; you can redistribute it and/or
15 # modify it under the terms of the GNU Lesser General Public
16 # License as published by the Free Software Foundation; either
17 # version 2.1 of the License, or (at your option) any later version.
19 # This library is distributed in the hope that it will be useful,
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 # Lesser General Public License for more details.
24 # You should have received a copy of the GNU Lesser General Public
25 # License along with this library; if not, write to the Free Software
26 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29 #=========================== Constants ============================#
31 # Make sure the usual locations are in PATH
32 export PATH
=$PATH:/usr
/sbin
:/usr
/bin
:/sbin
:/bin
34 readonly LOCAL_STATE_DIR
='@LOCALSTATEDIR@'
35 readonly LXC_TEMPLATE_CONFIG
='@LXCTEMPLATECONFIG@'
38 # Temporary static MIRROR LIST. I will get list from online path on the near future.
39 readonly MIRRORS_LIST
="
40 http://mirror.it.sabayon.org/
41 http://dl.sabayon.org/
42 ftp://ftp.klid.dk/sabayonlinux/
43 http://ftp.fsn.hu/pub/linux/distributions/sabayon/
44 http://ftp.cc.uoc.gr/mirrors/linux/SabayonLinux/
45 http://ftp.rnl.ist.utl.pt/pub/sabayon/
46 ftp://ftp.nluug.nl/pub/os/Linux/distr/sabayonlinux/
47 http://mirror.internode.on.net/pub/sabayon/
48 http://mirror.yandex.ru/sabayon/
49 http://sabayon.c3sl.ufpr.br/
50 http://mirror.clarkson.edu/sabayon/
51 http://na.mirror.garr.it/mirrors/sabayonlinux/"
53 #======================== Global variables ========================#
55 # Clean variables and set defaults.
69 #======================== Helper Functions ========================#
73 Template specific options can be passed to lxc-create after a '--' like this:
75 lxc-create --name=NAME [lxc-create-options] -- [template-options]
78 -a ARCH, --arch=ARCH The container architecture (e.g. x86_64, armv7); defaults
80 -d, --debug Run this script in a debug mode (set -x and wget w/o -q).
81 -m URL --mirror=URL The Sabayon mirror to use; defaults to random mirror.
82 -u, --unprivileged Tuning of rootfs for unprivileged containers.
83 -r, --release Identify release to use. Default is DAILY.
84 --mapped-gid Group Id to use on unprivileged container
85 (based of value present on file /etc/subgid).
86 --mapped-uid User Id to use on unprivileged container
87 (based of value present on file /etc/subuid)
88 --flush-owner Only for directly creation of unprivileged containers
89 through lxc-create command. Execute fuidshift command.
90 Require --mapped-gid,--mapped-uid and --unprivileged
93 Environment variables:
94 RELEASE Release version of Sabayon. Default is ${RELEASE}.
101 if [ $arch == 'amd64' ] ; then
102 url
=$
(echo $MIRRORS_LIST |
sed -e 's/ /\n/g' |
sort -R --random-source=/dev
/urandom |
head -n 1)
104 if [ $arch == 'armv7l' ] ; then
105 # Currently armv7l tarball is not on sabayon mirrored tree.
106 url
="https://dockerbuilder.sabayon.org/"
110 [ -n "$url" ] && echo "$url"
114 local retval
=$1; shift
125 if [ "$debug" = 'yes' ]; then
128 wget
-T 10 -O - -q $@
134 x86_64 | amd64
) echo 'amd64';;
135 armv7 | armv7l
) echo 'armv7l';;
136 #arm*) echo 'armhf';;
148 mkdir
-p "$LOCAL_STATE_DIR/lock/subsys"
152 echo -n "Obtaining an exclusive lock..."
153 if ! flock
-x 9; then
161 } 9> "$LOCAL_STATE_DIR/lock/subsys/lxc-sabayon-$lock_name"
169 # Example of amd64 tarball url
170 # http://mirror.yandex.ru/sabayon/iso/daily/Sabayon_Linux_DAILY_amd64_tarball.tar.gz
172 if [ $arch == 'amd64' ] ; then
174 if [ $release = 'DAILY' ] ; then
175 url
="${MIRROR_URL}iso/daily/Sabayon_Linux_DAILY_amd64_tarball.tar.gz"
177 url
="${MIRROR_URL}iso/monthly/Sabayon_Linux_${release}_amd64_tarball.tar.gz"
180 # https://dockerbuilder.sabayon.org/Sabayon_Linux_16_armv7l.tar.bz2
181 if [ $arch == 'armv7l' ] ; then
183 # Currently $arch tarball is not on sabayon mirrored tree.
184 url
="${MIRROR_URL}Sabayon_Linux_16_armv7l.tar.bz2"
193 #=========================== Configure ===========================#
195 unprivileged_rootfs
() {
197 pushd ${rootfs}/etc
/systemd
/system
199 # Disable systemd-journald-audit.socket because it seems that doesn't
200 # start correctly on unprivileged container
201 ln -s /dev
/null systemd-journald-audit.socket
203 # Disable systemd-remount-fs.service because on unprivileged container
204 # systemd can't remount filesystem
205 ln -s /dev
/null systemd-remount-fs.service
207 # Remove mount of FUSE Control File system
208 ln -s /dev
/null sys-fs-fuse-connections.mount
210 # Change execution of service systemd-sysctl to avoid errors.
211 mkdir systemd-sysctl.service.d
212 cat <<EOF > systemd-sysctl.service.d/00gentoo.conf
215 ExecStart=/usr/lib/systemd/systemd-sysctl --prefix=/etc/sysctl.d/
218 # Disable mount of hugepages
219 ln -s /dev
/null dev-hugepages.mount
225 # Disable sabayon-anti-fork-bomb limits (already apply to lxc container manager)
226 sed -i -e 's/^*/#*/g' .
/etc
/security
/limits.d
/00-sabayon-anti-fork-bomb.conf ||
return 1
227 sed -i -e 's/^root/#root/g' .
/etc
/security
/limits.d
/00-sabayon-anti-fork-bomb.conf ||
return 1
234 unprivileged_shift_owner
() {
236 # I use /usr/bin/fuidshift from LXD project.
238 einfo
"Executing: fuidshift ${rootfs} u:0:${mapped_uid}:65536 g:0:${mapped_gid}:65536 ..."
240 fuidshift
${rootfs} u:0:${mapped_uid}:65536 g:0:${mapped_gid}:65536 ||
241 die
1 "Error on change owners of ${rootfs} directory"
245 # Fix permission of container directory
251 systemd_container_tuning
() {
253 # To avoid error on start systemd-tmpfiles-setup service
254 # it is needed clean journal directory
255 rm -rf ${rootfs}/var
/log
/journal
/
257 # Remove LVM service. Normally not needed on container system.
258 rm -rf ${rootfs}/etc
/systemd
/system
/sysinit.target.wants
/lvm2-lvmetad.service
260 # Comment unneeded entry on /etc/fstab
261 sed -e 's/\/dev/#\/dev/g' -i ${rootfs}/etc
/fstab
263 # Fix this stupid error until fix is available on sabayon image
264 # /usr/lib/systemd/system-generators/gentoo-local-generator: line 4: cd: /etc/local.d: No such file or directory
265 mkdir
${rootfs}/etc
/local.d
/
267 # Fix TERM variable for container console
268 mkdir container-getty\@
0.service.d
269 cat <<EOF > container-getty\@0.service.d/00gentoo.conf
272 Environment=TERM=linux
278 configure_container
() {
282 local privileged_options
=""
283 local unprivileged_options
=""
285 if [[ $unprivileged && $unprivileged == true
]] ; then
286 if [[ $flush_owner == true
]] ; then
287 unprivileged_options
="
288 lxc.idmap = u 0 ${mapped_uid} 65536
289 lxc.idmap = g 0 ${mapped_gid} 65536
293 unprivileged_options
="
294 $unprivileged_options
296 # Force use of cgroup v1. Currently systemd doesn't support
297 # correctly cgroup v2. See: https://github.com/lxc/lxc/issues/1669
298 # about discussion of default-hierarchy option.
299 lxc.init.cmd = /sbin/init systemd.legacy_systemd_cgroup_controller=yes
301 # Include common configuration.
302 lxc.include = $LXC_TEMPLATE_CONFIG/sabayon.userns.conf
307 ## Allow any mknod (but not reading/writing the node)
308 lxc.cgroup.devices.allow = b *:* m
309 lxc.cgroup.devices.allow = c *:* m
312 lxc.cgroup.devices.allow = c 136:* rwm
314 lxc.cgroup.devices.allow = c 5:0 rwm
316 lxc.cgroup.devices.allow = c 5:1 rwm
318 lxc.cgroup.devices.allow = c 5:2 rwm
320 lxc.cgroup.devices.allow = c 10:229 rwm
325 cat <<-EOF >> "$config"
326 # Specify container architecture.
330 lxc.uts.name = $hostname
332 # Include common configuration.
333 lxc.include = $LXC_TEMPLATE_CONFIG/sabayon.common.conf
335 $unprivileged_options
341 #============================= Main ==============================#
345 # Parse command options.
346 local short_options
="a:dm:n:p:r:hu"
347 local long_options
="arch:,debug,mirror:,name:,path:,release:,rootfs:,mapped-uid:,mapped-gid:,flush-owner,help"
349 options
=$
(getopt
-u -q -a -o "$short_options" -l "$long_options" -- "$@")
351 eval set -- "$options"
353 # Process command options.
354 while [ $# -gt 0 ]; do
405 einfo
"Unknown option: $1"
413 if [ "$(id -u)" != "0" ]; then
414 die
1 "This script must be run as 'root'"
418 [ -n "$name" ] || die
1 'Missing required option --name'
419 [ -n "$path" ] || die
1 'Missing required option --path'
421 if [ -z "$rootfs" ] && [ -f "$path/config" ]; then
422 rootfs
="$(sed -nE 's/^lxc.rootfs\s*=\s*(.*)$/\1/p' "$path/config
")"
424 if [ -z "$rootfs" ]; then
425 rootfs
="$path/rootfs"
428 [ -z "$path" ] && die
1 "'path' parameter is required."
430 arch
=$
(parse_arch
"$arch") \
431 || die
1 "Unsupported architecture: $arch"
433 [[ $unprivileged == true
&& $flush_owner == true
&&-z "$mapped_uid" ]] && \
434 die
1 'Missing required option --mapped-uid with --unprivileged option'
436 [[ $unprivileged == true
&& $flush_owner == true
&& -z "$mapped_gid" ]] && \
437 die
1 'Missing required option --mapped-gid with --unprivileged option'
439 [[ $flush_owner == true
&& $unprivileged == false
]] && \
440 die
1 'flush-owner require --unprivileged option'
449 # Set global variables.
450 RELEASE
="${RELEASE:-"DAILY"}"
451 ARCH
="${ARCH:-`uname -m`}"
452 OS
="${OS:-"sabayon"}"
454 einfo
"Processing command line arguments: $@"
456 # Parse command line options
460 MIRROR_URL
="${mirror_url:-$(random_mirror_url)}"
462 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, flush_owner = $flush_owner"
464 [ "$debug" = 'yes' ] && set -x
466 # Download sabayon tarball
467 tarball
=$
(create_url
)
468 einfo
"Fetching tarball $tarball..."
470 # TODO: use only a compression mode
471 if [ $arch == 'amd64' ] ; then
472 fetch
"${tarball}" |
tar -xpz -C "${rootfs}"
474 if [ $arch == 'armv7l' ] ; then
475 fetch
"${tarball}" |
tar -xpj -C "${rootfs}"
479 einfo
"Tarball ${tarball} Extracted."
481 systemd_container_tuning
483 # Fix container for unprivileged mode.
484 if [[ $unprivileged == true
]] ; then
486 if [[ $flush_owner == true
]] ; then
487 unprivileged_shift_owner
495 einfo
"Prepare creation of sabayon container with params: $@ ($#)"
498 run_exclusively
'main' 10 main
"$@"
499 configure_container
"$path/config" "$name" "$arch"
501 einfo
"Container's rootfs and config have been created"
503 Edit the config file $path/config to check/enable networking setup.
504 The installed system is preconfigured for a loopback and single network
505 interface configured via DHCP.
507 To start the container, run "lxc-start -n $name".
508 The root password is not set; to enter the container run "lxc-attach -n $name".
510 Note: From kenel >= 4.6 for use unprivileged containers it is needed this mount on host:
512 mkdir /sys/fs/cgroup/systemd
513 mount -t cgroup -o none,name=systemd systemd /sys/fs/cgroup/systemd