SUBDIRS = common.conf.d
-templatesconfig_DATA = \
- alpine.common.conf \
- alpine.userns.conf \
- archlinux.common.conf \
- archlinux.userns.conf \
- centos.common.conf \
- centos.userns.conf \
- common.conf \
- common.seccomp \
- debian.common.conf \
- debian.userns.conf \
- fedora.common.conf \
- fedora.userns.conf \
- gentoo.common.conf \
- gentoo.moresecure.conf \
- gentoo.userns.conf \
- nesting.conf \
- oci.common.conf \
- opensuse.common.conf \
- opensuse.userns.conf \
- oracle.common.conf \
- oracle.userns.conf \
- plamo.common.conf \
- plamo.userns.conf \
- slackware.common.conf \
- slackware.userns.conf \
- ubuntu-cloud.common.conf \
- ubuntu-cloud.lucid.conf \
- ubuntu-cloud.userns.conf \
- ubuntu.common.conf \
- ubuntu.lucid.conf \
- ubuntu.userns.conf \
- openwrt.common.conf \
- sparclinux.common.conf \
- sparclinux.userns.conf \
- voidlinux.common.conf \
- voidlinux.userns.conf \
- sabayon.common.conf \
- sabayon.userns.conf \
- userns.conf
+templatesconfig_DATA = common.conf \
+ common.seccomp \
+ nesting.conf \
+ oci.common.conf \
+ userns.conf
+++ /dev/null
-# This derives from the global common config.
-lxc.include = @LXCTEMPLATECONFIG@/common.conf
-
-# Doesn't support consoles in /dev/lxc/.
-lxc.tty.dir =
-
-# Drop another (potentially) harmful capabilities.
-lxc.cap.drop = audit_write
-lxc.cap.drop = ipc_owner
-lxc.cap.drop = mknod
-lxc.cap.drop = setpcap
-lxc.cap.drop = sys_nice
-lxc.cap.drop = sys_pacct
-lxc.cap.drop = sys_rawio
-lxc.cap.drop = sys_resource
-lxc.cap.drop = sys_tty_config
-lxc.cap.drop = syslog
-lxc.cap.drop = wake_alarm
-
-# Mount /run as tmpfs.
-lxc.mount.entry=run run tmpfs rw,nodev,relatime,mode=755 0 0
-
-# Mount /dev/shm as tmpfs; needed for building python and possibly other packages.
-lxc.mount.entry=shm dev/shm tmpfs rw,nodev,noexec,nosuid,relatime,mode=1777,create=dir 0 0
+++ /dev/null
-# This derives from the global userns config.
-lxc.include = @LXCTEMPLATECONFIG@/userns.conf
+++ /dev/null
-# This derives from the global common config
-lxc.include = @LXCTEMPLATECONFIG@/common.conf
-
-# Allow for 6 tty devices by default
-lxc.tty.max = 6
-
-# Set the halt/stop signals
-lxc.signal.halt=SIGRTMIN+4
-
-# Uncomment to disable creating tty devices subdirectory in /dev
-# lxc.tty.dir =
-
-# Capabilities
-# Uncomment these if you don't run anything that needs the capability, and
-# would like the container to run with less privilege.
-#
-# 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_admin
-# lxc.cap.drop = net_raw # breaks dhcp/ping
-# lxc.cap.drop = setgid # breaks login (initgroups/setgroups)
-# lxc.cap.drop = dac_read_search # breaks login (pam unix_chkpwd)
-# lxc.cap.drop = setuid # breaks sshd,nfs statd
-# lxc.cap.drop = audit_control # breaks sshd (set_loginuid failed)
-# lxc.cap.drop = audit_write
-# lxc.cap.drop = setpcap # big big login delays in Fedora 20 systemd
-#
-lxc.cap.drop = setfcap sys_nice sys_pacct sys_rawio
+++ /dev/null
-# This derives from the global userns config
-lxc.include = @LXCTEMPLATECONFIG@/userns.conf
+++ /dev/null
-# This derives from the global common config
-lxc.include = @LXCTEMPLATECONFIG@/common.conf
-
-# Capabilities
-# Uncomment these if you don't run anything that needs the capability, and
-# would like the container to run with less privilege.
-#
-# 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_admin
-# lxc.cap.drop = net_raw # breaks dhcp/ping
-# lxc.cap.drop = setgid # breaks login (initgroups/setgroups)
-# lxc.cap.drop = dac_read_search # breaks login (pam unix_chkpwd)
-# lxc.cap.drop = setuid # breaks sshd,nfs statd
-# lxc.cap.drop = audit_control # breaks sshd (set_loginuid failed)
-# lxc.cap.drop = audit_write
-lxc.cap.drop = sys_nice sys_pacct sys_rawio
+++ /dev/null
-# This derives from the global userns config
-lxc.include = @LXCTEMPLATECONFIG@/userns.conf
+++ /dev/null
-# This derives from the global common config
-lxc.include = @LXCTEMPLATECONFIG@/common.conf
-
-# Doesn't support consoles in /dev/lxc/
-lxc.tty.dir =
-
-# When using LXC with apparmor, the container will be confined by default.
-# If you wish for it to instead run unconfined, copy the following line
-# (uncommented) to the container's configuration file.
-#lxc.apparmor.profile = unconfined
-
-# If you wish to allow mounting block filesystems, then use the following
-# line instead, and make sure to grant access to the block device and/or loop
-# devices below in lxc.cgroup.devices.allow.
-#lxc.apparmor.profile = lxc-container-default-with-mounting
-
-# Extra cgroup device access
-## rtc
-lxc.cgroup.devices.allow = c 254:0 rm
-## tun
-lxc.cgroup.devices.allow = c 10:200 rwm
-## hpet
-lxc.cgroup.devices.allow = c 10:228 rwm
-## kvm
-lxc.cgroup.devices.allow = c 10:232 rwm
-## To use loop devices, copy the following line to the container's
-## configuration file (uncommented).
-#lxc.cgroup.devices.allow = b 7:* rwm
+++ /dev/null
-# This derives from the global userns config
-lxc.include = @LXCTEMPLATECONFIG@/userns.conf
+++ /dev/null
-# This derives from the global common config
-lxc.include = @LXCTEMPLATECONFIG@/common.conf
-
-# Capabilities
-# Uncomment these if you don't run anything that needs the capability, and
-# would like the container to run with less privilege.
-#
-# 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_admin
-# lxc.cap.drop = net_raw # breaks dhcp/ping
-# lxc.cap.drop = setgid # breaks login (initgroups/setgroups)
-# lxc.cap.drop = dac_read_search # breaks login (pam unix_chkpwd)
-# lxc.cap.drop = setuid # breaks sshd,nfs statd
-# lxc.cap.drop = audit_control # breaks sshd (set_loginuid failed)
-# lxc.cap.drop = audit_write
-# lxc.cap.drop = setpcap # big big login delays in Fedora 20 systemd
-lxc.cap.drop = setfcap sys_nice sys_pacct sys_rawio
+++ /dev/null
-# This derives from the global userns config
-lxc.include = @LXCTEMPLATECONFIG@/userns.conf
+++ /dev/null
-# This derives from the global common config
-lxc.include = @LXCTEMPLATECONFIG@/common.conf
-
-# Gentoo common default configuration
-# This is the most feature-full container configuration
-# But security is not the goal.
-# Looking for more security, see gentoo.moresecure.conf
-
-# Doesn't support consoles in /dev/lxc/
-lxc.tty.dir =
-
-# Extra cgroup device access
-## rtc
-lxc.cgroup.devices.allow = c 254:0 rm
-## tun
-lxc.cgroup.devices.allow = c 10:200 rwm
-## hpet
-lxc.cgroup.devices.allow = c 10:228 rwm
-## kvm
-lxc.cgroup.devices.allow = c 10:232 rwm
-## To use loop devices, copy the following line to the container's
-## configuration file (uncommented).
-#lxc.cgroup.devices.allow = b 7:* rwm
-
-# /dev/shm needs to be mounted as tmpfs. It's needed by python (bug #496328)
-# and possibly other packages.
-lxc.mount.entry = none dev/shm tmpfs rw,nosuid,nodev,create=dir
+++ /dev/null
-# This derives from the global common config
-lxc.include = @LXCTEMPLATECONFIG@/common.conf
-
-# Gentoo security oriented default configuration
-# This is a more security oriented container configuration
-# "More" because this is far from fully secure
-# Looking for more working features and you trust your
-# Container user ? see gentoo.common.conf
-
-# do not mount sysfs, see http://blog.bofh.it/debian/id_413
-lxc.mount.entry=mqueue dev/mqueue mqueue rw,nodev,noexec,nosuid,create=dir 0 0
-lxc.mount.entry=shm dev/shm tmpfs rw,nosuid,nodev,noexec,relatime,create=dir 0 0
-lxc.mount.entry=run run tmpfs rw,nosuid,nodev,relatime,mode=755 0 0
-
-# Capabilities
-# Uncomment these if you don't run anything that needs the capability, and
-# would like the container to run with less privilege.
-#
-# 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_admin # breaks systemd
-# lxc.cap.drop = net_raw # breaks dhcp/ping
-# lxc.cap.drop = setgid # breaks login (initgroups/setgroups)
-# lxc.cap.drop = dac_read_search # breaks login (pam unix_chkpwd)
-# lxc.cap.drop = setuid # breaks sshd,nfs statd
-# lxc.cap.drop = audit_control # breaks sshd (set_loginuid failed)
-# lxc.cap.drop = audit_write
-# lxc.cap.drop = setpcap # breaks journald
-# lxc.cap.drop = sys_resource # breaks systemd
-# lxc.cap.drop = sys_boot # breaks sysvinit
-lxc.cap.drop = audit_control audit_write dac_read_search fsetid ipc_owner linux_immutable mknod setfcap setpcap sys_admin sys_nice sys_pacct sys_ptrace sys_rawio sys_resource sys_tty_config syslog
-
-# WARNING: the security vulnerability reported for 'cap_net_admin' at
-# http://mainisusuallyafunction.blogspot.com/2012/11/attacking-hardened-linux-systems-with.html
-# via JIT spraying (the BPF JIT module disabled on most systems was used
-# in the example, but others are suggested vulnerable) meant that users
-# with root in a container, that capability and kernel module may escape
-# the container. ALWAYS be extremely careful granting any process root
-# within a container, use a minimal configuration at all levels -
-# including the kernel - and multiple layers of security on any system
-# where security is a priority. note that not only LXC but PAX (and
-# others?) were vulnerable to this issue.
+++ /dev/null
-# This derives from the global userns config
-lxc.include = @LXCTEMPLATECONFIG@/userns.conf
+++ /dev/null
-# This derives from the global common config
-lxc.include = @LXCTEMPLATECONFIG@/common.conf
-
-# Capabilities
-# Uncomment these if you don't run anything that needs the capability, and
-# would like the container to run with less privilege.
-#
-# 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_admin
-# lxc.cap.drop = net_raw # breaks dhcp/ping
-# lxc.cap.drop = setgid # breaks login (initgroups/setgroups)
-# lxc.cap.drop = dac_read_search # breaks login (pam unix_chkpwd)
-# lxc.cap.drop = setuid # breaks sshd,nfs statd
-# lxc.cap.drop = audit_control # breaks sshd (set_loginuid failed)
-# lxc.cap.drop = audit_write
-# lxc.cap.drop = setpcap # big big login delays in Fedora 20 systemd
-# lxc.cap.drop = setfcap
-lxc.cap.drop = sys_nice sys_pacct sys_rawio
+++ /dev/null
-# This derives from the global userns config
-lxc.include = @LXCTEMPLATECONFIG@/userns.conf
+++ /dev/null
-# Default console settings
-lxc.tty.dir = lxc
-lxc.tty.max = 4
-lxc.pty.max = 1024
-
-# Default capabilities
-lxc.cap.drop = mac_admin
-lxc.cap.drop = mac_override
-lxc.cap.drop = sys_admin
-lxc.cap.drop = sys_module
-lxc.cap.drop = sys_nice
-lxc.cap.drop = sys_pacct
-lxc.cap.drop = sys_ptrace
-lxc.cap.drop = sys_rawio
-lxc.cap.drop = sys_resource
-lxc.cap.drop = sys_time
-lxc.cap.drop = sys_tty_config
-lxc.cap.drop = syslog
-lxc.cap.drop = wake_alarm
-
-# Default cgroups - all denied except those whitelisted
-lxc.cgroup.devices.deny = a
-## /dev/null and zero
-lxc.cgroup.devices.allow = c 1:3 rwm
-lxc.cgroup.devices.allow = c 1:5 rwm
-## consoles
-lxc.cgroup.devices.allow = c 5:0 rwm
-lxc.cgroup.devices.allow = c 5:1 rwm
-## /dev/{,u}random
-lxc.cgroup.devices.allow = c 1:8 rwm
-lxc.cgroup.devices.allow = c 1:9 rwm
-## /dev/pts/*
-lxc.cgroup.devices.allow = c 5:2 rwm
-lxc.cgroup.devices.allow = c 136:* rwm
-## rtc
-lxc.cgroup.devices.allow = c 254:0 rm
-## tun
-lxc.cgroup.devices.allow = c 10:200 rwm
-## dev/tty0
-lxc.cgroup.devices.allow = c 4:0 rwm
-## dev/tty1
-lxc.cgroup.devices.allow = c 4:1 rwm
-
-## To use loop devices, copy the following line to the container's
-## configuration file (uncommented).
-#lxc.cgroup.devices.allow = b 7:* rwm
-
-# Blacklist some syscalls which are not safe in privileged
-# containers
-lxc.seccomp.profile = /usr/share/lxc/config/common.seccomp
+++ /dev/null
-# This derives from the global common config
-lxc.include = @LXCTEMPLATECONFIG@/common.conf
-
-# Capabilities
-# Uncomment these if you don't run anything that needs the capability, and
-# would like the container to run with less privilege.
-#
-# 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_admin
-# lxc.cap.drop = net_raw # breaks dhcp/ping
-# lxc.cap.drop = setgid # breaks login (initgroups/setgroups)
-# lxc.cap.drop = dac_read_search # breaks login (pam unix_chkpwd)
-# lxc.cap.drop = setuid # breaks sshd,nfs statd
-# lxc.cap.drop = audit_control # breaks sshd (set_loginuid failed)
-# lxc.cap.drop = audit_write
-lxc.cap.drop = sys_nice sys_pacct sys_rawio
+++ /dev/null
-# This derives from the global userns config
-lxc.include = @LXCTEMPLATECONFIG@/userns.conf
+++ /dev/null
-# This derives from the global common config
-lxc.include = @LXCTEMPLATECONFIG@/common.conf
-
-# Doesn't support consoles in /dev/lxc/
-lxc.tty.dir =
-
-# Extra cgroup device access
-## rtc
-lxc.cgroup.devices.allow = c 254:0 rm
+++ /dev/null
-# This derives from the global userns config
-lxc.include = @LXCTEMPLATECONFIG@/userns.conf
+++ /dev/null
-# Default configuration for Sabayon containers
-
-# Setup the default mounts
-lxc.mount.auto = cgroup:mixed proc:mixed sys:mixed
-
-# Allow for 1024 pseudo terminals
-lxc.pty.max = 1024
-
-# Setup 1 tty devices for lxc-console command
-lxc.tty.max = 1
-
-# Needed for systemd distro
-lxc.autodev = 1
-
-# Doesn't support consoles in /dev/lxc/
-lxc.tty.dir =
-
-# CGroup whitelist
-lxc.cgroup.devices.deny = a
-
-## Allow any mknod (but not reading/writing the node)
-#lxc.cgroup.devices.allow = c *:* m
-#lxc.cgroup.devices.allow = b *:* m
-
-## Allow specific devices
-### /dev/null
-lxc.cgroup.devices.allow = c 1:3 rwm
-### /dev/zero
-lxc.cgroup.devices.allow = c 1:5 rwm
-### /dev/full
-lxc.cgroup.devices.allow = c 1:7 rwm
-### /dev/random
-lxc.cgroup.devices.allow = c 1:8 rwm
-### /dev/urandom
-lxc.cgroup.devices.allow = c 1:9 rwm
-### /dev/pts/*
-#lxc.cgroup.devices.allow = c 136:* rwm
-### /dev/tty
-#lxc.cgroup.devices.allow = c 5:0 rwm
-### /dev/console
-#lxc.cgroup.devices.allow = c 5:1 rwm
-### /dev/ptmx
-#lxc.cgroup.devices.allow = c 5:2 rwm
-### fuse
-#lxc.cgroup.devices.allow = c 10:229 rwm
-## To use loop devices, copy the following line to the container's
-## configuration file (uncommented).
-#lxc.cgroup.devices.allow = b 7:* rwm
-## rtc
-#lxc.cgroup.devices.allow = c 254:0 rm
-## tun
-#lxc.cgroup.devices.allow = c 10:200 rwm
-## hpet
-#lxc.cgroup.devices.allow = c 10:228 rwm
-## kvm
-#lxc.cgroup.devices.allow = c 10:232 rwm
-## /dev/mem
-#lxc.cgroup.devices.allow = c 1:1 rwm
-
-# 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
-
-
-# /dev/shm needs to be mounted as tmpfs. It's needed by python (bug #496328)
-# and possibly other packages.
-lxc.mount.entry = none dev/shm tmpfs rw,nosuid,nodev,create=dir
-
-# Blacklist some syscalls which are not safe in privileged
-# containers
-lxc.seccomp.profile = @LXCTEMPLATECONFIG@/common.seccomp
-
-# Customize lxc options through common directory
-lxc.include = @LXCTEMPLATECONFIG@/common.conf.d/
+++ /dev/null
-# This derives from the global userns config
-lxc.include = @LXCTEMPLATECONFIG@/userns.conf
+++ /dev/null
-# This derives from the global common config
-lxc.include = @LXCTEMPLATECONFIG@/common.conf
-
-# Doesn't support consoles in /dev/lxc/
-lxc.tty.dir =
-
-# Extra cgroup device access
-## rtc
-lxc.cgroup.devices.allow = c 254:0 rm
-## tun
-lxc.cgroup.devices.allow = c 10:200 rwm
-## hpet
-lxc.cgroup.devices.allow = c 10:228 rwm
-## kvm
-lxc.cgroup.devices.allow = c 10:232 rwm
-## To use loop devices, copy the following line to the container's
-## configuration file (uncommented).
-#lxc.cgroup.devices.allow = b 7:* rwm
-
-# mount /dev/shm as tmpfs
-lxc.mount.entry = none dev/shm tmpfs rw,nosuid,nodev,create=dir
-
-# Capabilities
-# Uncomment these if you don't run anything that needs the capability, and
-# would like the container to run with less privilege.
-# Note that some are already dropped in common.conf.
-#
-# 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).
-#
-# Some of these don't apply in Slackware but are here for future reference.
-#
-# lxc.cap.drop = sys_admin # breaks systemd
-# lxc.cap.drop = net_raw # breaks dhcp/ping
-# lxc.cap.drop = setgid # breaks login (initgroups/setgroups)
-# lxc.cap.drop = dac_read_search # breaks login (pam unix_chkpwd)
-# lxc.cap.drop = setuid # breaks sshd,nfs statd
-# lxc.cap.drop = audit_control # breaks sshd (set_loginuid failed)
-# lxc.cap.drop = audit_write
-# lxc.cap.drop = setpcap # breaks journald
-# lxc.cap.drop = sys_resource # breaks systemd
-#
-lxc.cap.drop = mknod setfcap setpcap
+++ /dev/null
-# This derives from the global userns config
-lxc.include = @LXCTEMPLATECONFIG@/userns.conf
+++ /dev/null
-# This derives from the global common config
-lxc.include = @LXCTEMPLATECONFIG@/common.conf
-
-# Capabilities
-# Uncomment these if you don't run anything that needs the capability, and
-# would like the container to run with less privilege.
-#
-# 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_admin
-# lxc.cap.drop = net_raw # breaks dhcp/ping
-# lxc.cap.drop = setgid # breaks login (initgroups/setgroups)
-# lxc.cap.drop = dac_read_search # breaks login (pam unix_chkpwd)
-# lxc.cap.drop = setuid # breaks sshd,nfs statd
-# lxc.cap.drop = audit_control # breaks sshd (set_loginuid failed)
-# lxc.cap.drop = audit_write
-lxc.cap.drop = sys_nice sys_pacct sys_rawio
+++ /dev/null
-# This derives from the global userns config
-lxc.include = @LXCTEMPLATECONFIG@/userns.conf
+++ /dev/null
-# This derives from the main Ubuntu config
-lxc.include = @LXCTEMPLATECONFIG@/ubuntu.common.conf
-
-lxc.hook.clone = @LXCHOOKDIR@/ubuntu-cloud-prep
+++ /dev/null
-# This derives from the main Ubuntu lucid config
-lxc.include = @LXCTEMPLATECONFIG@/ubuntu.lucid.conf
+++ /dev/null
-# This derives from the main Ubuntu userns config
-lxc.include = @LXCTEMPLATECONFIG@/ubuntu.userns.conf
+++ /dev/null
-# This derives from the global common config
-lxc.include = @LXCTEMPLATECONFIG@/common.conf
-
-# Default mount entries
-lxc.mount.entry = /sys/kernel/debug sys/kernel/debug none bind,optional 0 0
-lxc.mount.entry = /sys/kernel/security sys/kernel/security none bind,optional 0 0
-lxc.mount.entry = /sys/fs/pstore sys/fs/pstore none bind,optional 0 0
-lxc.mount.entry = mqueue dev/mqueue mqueue rw,relatime,create=dir,optional 0 0
-
-# When using LXC with apparmor, the container will be confined by default.
-# If you wish for it to instead run unconfined, copy the following line
-# (uncommented) to the container's configuration file.
-#lxc.apparmor.profile = unconfined
-
-# Uncomment the following line to autodetect squid-deb-proxy configuration on the
-# host and forward it to the guest at start time.
-#lxc.hook.pre-start = /usr/share/lxc/hooks/squid-deb-proxy-client
-
-# If you wish to allow mounting block filesystems, then use the following
-# line instead, and make sure to grant access to the block device and/or loop
-# devices below in lxc.cgroup.devices.allow.
-#lxc.apparmor.profile = lxc-container-default-with-mounting
-
-# Extra cgroup device access
-## rtc
-lxc.cgroup.devices.allow = c 254:0 rm
-## tun
-lxc.cgroup.devices.allow = c 10:200 rwm
-## hpet
-lxc.cgroup.devices.allow = c 10:228 rwm
-## kvm
-lxc.cgroup.devices.allow = c 10:232 rwm
-## To use loop devices, copy the following line to the container's
-## configuration file (uncommented).
-#lxc.cgroup.devices.allow = b 7:* rwm
+++ /dev/null
-# Ubuntu 10.04 LTS doesn't have /dev/lxc/
-lxc.tty.dir =
+++ /dev/null
-# This derives from the global userns config
-lxc.include = @LXCTEMPLATECONFIG@/userns.conf
-
-# Extra fstab entries as mountall can't mount those by itself
-lxc.mount.entry = /sys/firmware/efi/efivars sys/firmware/efi/efivars none bind,optional 0 0
-lxc.mount.entry = /proc/sys/fs/binfmt_misc proc/sys/fs/binfmt_misc none bind,optional 0 0
+++ /dev/null
-# This derives from the global common config
-lxc.include = @LXCTEMPLATECONFIG@/common.conf
-
-# Allow for 6 tty devices by default
-lxc.tty.max = 6
-
-# Set $VIRTUALIZATION so runit doesn't try to mount filesystems or start udevd
-lxc.environment=VIRTUALIZATION=lxc
-
-# Set the halt/stop signals
-lxc.signal.halt=SIGCONT
-
-
-# Uncomment to disable creating tty devices subdirectory in /dev
-# lxc.tty.dir =
-
-# Capabilities
-# Uncomment these if you don't run anything that needs the capability, and
-# would like the container to run with less privilege.
-#
-# 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_admin
-# lxc.cap.drop = net_raw # breaks dhcp/ping
-# lxc.cap.drop = setgid # breaks login (initgroups/setgroups)
-# lxc.cap.drop = dac_read_search # breaks login (pam unix_chkpwd)
-# lxc.cap.drop = setuid # breaks sshd,nfs statd
-# lxc.cap.drop = audit_control # breaks sshd (set_loginuid failed)
-# lxc.cap.drop = audit_write
-# lxc.cap.drop = setpcap # big big login delays in Fedora 20 systemd
-#
-lxc.cap.drop = setfcap sys_nice sys_pacct sys_rawio
+++ /dev/null
-# This derives from the global userns config
-lxc.include = @LXCTEMPLATECONFIG@/userns.conf
-
-# Set $VIRTUALIZATION so runit doesn't try to mount filesystems or start udevd
-lxc.environment=VIRTUALIZATION=lxc
-
-# Set the halt/stop signals
-lxc.signal.halt=SIGCONT
config/init/upstart/Makefile
config/etc/Makefile
config/templates/Makefile
- config/templates/alpine.common.conf
- config/templates/alpine.userns.conf
- config/templates/archlinux.common.conf
- config/templates/archlinux.userns.conf
- config/templates/centos.common.conf
- config/templates/centos.userns.conf
config/templates/common.conf
config/templates/common.conf.d/Makefile
- config/templates/debian.common.conf
- config/templates/debian.userns.conf
- config/templates/fedora.common.conf
- config/templates/fedora.userns.conf
- config/templates/gentoo.common.conf
- config/templates/gentoo.moresecure.conf
- config/templates/gentoo.userns.conf
config/templates/nesting.conf
config/templates/oci.common.conf
- config/templates/opensuse.common.conf
- config/templates/opensuse.userns.conf
- config/templates/oracle.common.conf
- config/templates/oracle.userns.conf
- config/templates/plamo.common.conf
- config/templates/plamo.userns.conf
- config/templates/slackware.common.conf
- config/templates/slackware.userns.conf
- config/templates/ubuntu-cloud.common.conf
- config/templates/ubuntu-cloud.lucid.conf
- config/templates/ubuntu-cloud.userns.conf
- config/templates/ubuntu.common.conf
- config/templates/ubuntu.lucid.conf
- config/templates/ubuntu.userns.conf
- config/templates/openwrt.common.conf
- config/templates/sparclinux.common.conf
- config/templates/sparclinux.userns.conf
- config/templates/voidlinux.common.conf
- config/templates/voidlinux.userns.conf
- config/templates/sabayon.common.conf
- config/templates/sabayon.userns.conf
config/templates/userns.conf
config/yum/Makefile
config/sysconfig/Makefile
hooks/dhclient
templates/Makefile
- templates/lxc-alpine
- templates/lxc-altlinux
- templates/lxc-archlinux
templates/lxc-busybox
- templates/lxc-centos
- templates/lxc-cirros
- templates/lxc-debian
templates/lxc-download
- templates/lxc-fedora
- templates/lxc-fedora-legacy
- templates/lxc-gentoo
templates/lxc-local
templates/lxc-oci
- templates/lxc-openmandriva
- templates/lxc-opensuse
- templates/lxc-oracle
- templates/lxc-plamo
- templates/lxc-pld
- templates/lxc-slackware
- templates/lxc-sshd
- templates/lxc-ubuntu
- templates/lxc-ubuntu-cloud
- templates/lxc-sparclinux
- templates/lxc-voidlinux
- templates/lxc-sabayon
src/Makefile
src/lxc/Makefile
templatesdir=@LXCTEMPLATEDIR@
-templates_SCRIPTS = \
- lxc-alpine \
- lxc-altlinux \
- lxc-archlinux \
- lxc-busybox \
- lxc-centos \
- lxc-cirros \
- lxc-debian \
- lxc-download \
- lxc-fedora \
- lxc-fedora-legacy \
- lxc-gentoo \
- lxc-local \
- lxc-oci \
- lxc-openmandriva \
- lxc-opensuse \
- lxc-oracle \
- lxc-plamo \
- lxc-pld \
- lxc-slackware \
- lxc-sshd \
- lxc-ubuntu \
- lxc-ubuntu-cloud \
- lxc-sparclinux \
- lxc-voidlinux \
- lxc-sabayon
+templates_SCRIPTS = lxc-busybox \
+ lxc-download \
+ lxc-local \
+ lxc-oci
+++ /dev/null
-#!/bin/sh
-# vim: set ts=4:
-
-# Exit on error and treat unset variables as an error.
-set -eu
-
-#
-# LXC template for Alpine Linux 3+
-#
-
-# Note: Do not replace tabs with spaces, it would break heredocs!
-
-# Authors:
-# Jakub Jirutka <jakub@jirutka.cz>
-
-# 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@'
-readonly LXC_CACHE_DIR="${LXC_CACHE_PATH:-"$LOCAL_STATE_DIR/cache/lxc"}/alpine"
-
-# SHA256 checksums of GPG keys for APK.
-readonly APK_KEYS_SHA256="\
-9c102bcc376af1498d549b77bdbfa815ae86faa1d2d82f040e616b18ef2df2d4 alpine-devel@lists.alpinelinux.org-4a6a0840.rsa.pub
-2adcf7ce224f476330b5360ca5edb92fd0bf91c92d83292ed028d7c4e26333ab alpine-devel@lists.alpinelinux.org-4d07755e.rsa.pub
-ebf31683b56410ecc4c00acd9f6e2839e237a3b62b5ae7ef686705c7ba0396a9 alpine-devel@lists.alpinelinux.org-5243ef4b.rsa.pub
-1bb2a846c0ea4ca9d0e7862f970863857fc33c32f5506098c636a62a726a847b alpine-devel@lists.alpinelinux.org-524d27bb.rsa.pub
-12f899e55a7691225603d6fb3324940fc51cd7f133e7ead788663c2b7eecb00c alpine-devel@lists.alpinelinux.org-5261cecb.rsa.pub
-73867d92083f2f8ab899a26ccda7ef63dfaa0032a938620eda605558958a8041 alpine-devel@lists.alpinelinux.org-58199dcc.rsa.pub
-9a4cd858d9710963848e6d5f555325dc199d1c952b01cf6e64da2c15deedbd97 alpine-devel@lists.alpinelinux.org-58cbb476.rsa.pub
-780b3ed41786772cbc7b68136546fa3f897f28a23b30c72dde6225319c44cfff alpine-devel@lists.alpinelinux.org-58e4f17d.rsa.pub"
-
-readonly APK_KEYS_URI='http://alpinelinux.org/keys'
-readonly DEFAULT_MIRROR_URL='http://dl-cdn.alpinelinux.org/alpine'
-
-: ${APK_KEYS_DIR:=/etc/apk/keys}
-if ! ls "$APK_KEYS_DIR"/alpine* >/dev/null 2>&1; then
- APK_KEYS_DIR="$LXC_CACHE_DIR/bootstrap/keys"
-fi
-readonly APK_KEYS_DIR
-
-: ${APK:=$(command -v apk || true)}
-if [ ! -x "$APK" ]; then
- APK="$LXC_CACHE_DIR/bootstrap/sbin/apk.static"
-fi
-readonly APK
-
-
-#======================== 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] [PKG...]
-
- PKG Additional APK package(s) to install into the container.
-
- Template options:
- -a ARCH, --arch=ARCH The container architecture (e.g. x86, x86_64); defaults
- to the host arch.
- -d, --debug Run this script in a debug mode (set -x and wget w/o -q).
- -F, --flush-cache Remove cached files before build.
- -m URL --mirror=URL The Alpine mirror to use; defaults to $DEFAULT_MIRROR_URL.
- -r VER, --release=VER The Alpine release branch to install; default is the
- latest stable.
-
- Environment variables:
- APK The apk-tools binary to use when building rootfs. If not set
- or not executable and apk is not on PATH, then the script
- will download the latest apk-tools-static.
- APK_KEYS_DIR Path to directory with GPG keys for APK. If not set and
- /etc/apk/keys does not contain alpine keys, then the script
- will download the keys from ${APK_KEYS_URI}.
- LXC_CACHE_PATH Path to the cache directory where to store bootstrap files
- and APK packages.
- EOF
-}
-
-die() {
- local retval=$1; shift
-
- printf 'ERROR: %s\n' "$@" 1>&2
- exit $retval
-}
-
-einfo() {
- printf "\n==> $1\n"
-}
-
-fetch() {
- if [ "$DEBUG" = 'yes' ]; then
- wget -T 10 -O - $@
- else
- wget -T 10 -O - -q $@
- fi
-}
-
-latest_release_branch() {
- local arch="$1"
- local branch=$(fetch "$MIRROR_URL/latest-stable/releases/$arch/latest-releases.yaml" \
- | sed -En 's/^[ \t]*branch: (.*)$/\1/p' \
- | head -n 1)
- [ -n "$branch" ] && echo "$branch"
-}
-
-parse_arch() {
- case "$1" in
- x86 | i[3-6]86) echo 'x86';;
- x86_64 | amd64) echo 'x86_64';;
- aarch64 | arm64) echo 'aarch64';;
- armv7) echo 'armv7';;
- arm*) echo 'armhf';;
- ppc64le) echo 'ppc64le';;
- *) return 1;;
- esac
-}
-
-run_exclusively() {
- local lock_name="$1"
- local timeout=$2
- shift 2
-
- 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'
-
- "$@"; retval=$?
- } 9> "$LOCAL_STATE_DIR/lock/subsys/lxc-alpine-$lock_name"
-
- return $retval
-}
-
-
-#============================ Bootstrap ===========================#
-
-bootstrap() {
- if [ "$FLUSH_CACHE" = 'yes' ] && [ -d "$LXC_CACHE_DIR/bootstrap" ]; then
- einfo 'Cleaning cached bootstrap files'
- rm -Rf "$LXC_CACHE_DIR/bootstrap"
- fi
-
- einfo 'Fetching and/or verifying APK keys'
- fetch_apk_keys "$APK_KEYS_DIR"
-
- if [ ! -x "$APK" ]; then
- einfo 'Fetching apk-tools static binary'
-
- local host_arch=$(parse_arch $(uname -m))
- fetch_apk_static "$LXC_CACHE_DIR/bootstrap" "$host_arch"
- fi
-}
-
-fetch_apk_keys() {
- local dest="$1"
- local line keyname
-
- mkdir -p "$dest"
- cd "$dest"
-
- echo "$APK_KEYS_SHA256" | while read -r line; do
- keyname="${line##* }"
- if [ ! -s "$keyname" ]; then
- fetch "$APK_KEYS_URI/$keyname" > "$keyname"
- fi
- echo "$line" | sha256sum -c -
- done || exit 2
-
- cd - >/dev/null
-}
-
-fetch_apk_static() {
- local dest="$1"
- local arch="$2"
- local pkg_name='apk-tools-static'
-
- mkdir -p "$dest"
-
- local pkg_ver=$(fetch "$MIRROR_URL/latest-stable/main/$arch/APKINDEX.tar.gz" \
- | tar -xzO APKINDEX \
- | sed -n "/P:${pkg_name}/,/^$/ s/V:\(.*\)$/\1/p")
-
- [ -n "$pkg_ver" ] || die 2 "Cannot find a version of $pkg_name in APKINDEX"
-
- fetch "$MIRROR_URL/latest-stable/main/$arch/${pkg_name}-${pkg_ver}.apk" \
- | tar -xz -C "$dest" sbin/ # --extract --gzip --directory
-
- [ -s "$dest/sbin/apk.static" ] || die 2 'apk.static not found'
-
- local keyname=$(echo "$dest"/sbin/apk.static.*.pub | sed 's/.*\.SIGN\.RSA\.//')
- openssl dgst -sha1 \
- -verify "$APK_KEYS_DIR/$keyname" \
- -signature "$dest/sbin/apk.static.SIGN.RSA.$keyname" \
- "$dest/sbin/apk.static" \
- || die 2 'Signature verification for apk.static failed'
-
- # Note: apk doesn't return 0 for --version
- local out="$("$dest"/sbin/apk.static --version)"
- echo "$out"
-
- [ "${out%% *}" = 'apk-tools' ] || die 3 'apk.static --version failed'
-}
-
-
-#============================ Install ============================#
-
-install() {
- local dest="$1"
- local arch="$2"
- local branch="$3"
- local extra_packages="$4"
- local apk_cache="$LXC_CACHE_DIR/apk/$arch"
-
- if [ "$FLUSH_CACHE" = 'yes' ] && [ -d "$apk_cache" ]; then
- einfo "Cleaning cached APK packages for $arch"
- rm -Rf "$apk_cache"
- fi
- mkdir -p "$apk_cache"
-
- einfo "Installing Alpine Linux in $dest"
- cd "$dest"
-
- mkdir -p etc/apk
- ln -s "$apk_cache" etc/apk/cache
-
- local repo; for repo in main community; do
- echo "$MIRROR_URL/$branch/$repo" >> etc/apk/repositories
- done
-
- install_packages "$arch" "alpine-base $extra_packages"
- make_dev_nodes
- setup_inittab
- setup_hosts
- setup_network
- setup_services
-
- chroot . /bin/true \
- || die 3 'Failed to execute /bin/true in chroot, the builded rootfs is broken!'
-
- rm etc/apk/cache
- cd - >/dev/null
-}
-
-install_packages() {
- local arch="$1"
- local packages="$2"
-
- $APK --arch="$arch" --root=. --keys-dir="$APK_KEYS_DIR" \
- --update-cache --initdb add $packages
-}
-
-make_dev_nodes() {
- mkdir -p -m 755 dev/pts
- mkdir -p -m 1777 dev/shm
-
- mknod -m 666 dev/zero c 1 5
- mknod -m 666 dev/full c 1 7
- mknod -m 666 dev/random c 1 8
- mknod -m 666 dev/urandom c 1 9
-
- local i; for i in $(seq 0 4); do
- mknod -m 620 dev/tty$i c 4 $i
- chown 0:5 dev/tty$i # root:tty
- done
-
- mknod -m 666 dev/tty c 5 0
- chown 0:5 dev/tty # root:tty
- mknod -m 620 dev/console c 5 1
- mknod -m 666 dev/ptmx c 5 2
- chown 0:5 dev/ptmx # root:tty
-}
-
-setup_inittab() {
- # Remove unwanted ttys.
- sed -i '/^tty[5-9]\:\:.*$/d' etc/inittab
-
- cat <<-EOF >> etc/inittab
- # Main LXC console console
- ::respawn:/sbin/getty 38400 console
- EOF
-}
-
-setup_hosts() {
- # This runscript injects localhost entries with the current hostname
- # into /etc/hosts.
- cat <<'EOF' > etc/init.d/hosts
-#!/sbin/openrc-run
-
-start() {
- local start_tag='# begin generated'
- local end_tag='# end generated'
-
- local content=$(
- cat <<-EOF
- $start_tag by /etc/init.d/hosts
- 127.0.0.1 $(hostname).local $(hostname) localhost
- ::1 $(hostname).local $(hostname) localhost
- $end_tag
- EOF
- )
-
- if grep -q "^${start_tag}" /etc/hosts; then
- # escape \n, busybox sed doesn't like them
- content=${content//$'\n'/\\$'\n'}
-
- sed -ni "/^${start_tag}/ {
- a\\${content}
- # read and discard next line and repeat until $end_tag or EOF
- :a; n; /^${end_tag}/!ba; n
- }; p" /etc/hosts
- else
- printf "$content" >> /etc/hosts
- fi
-}
-EOF
- chmod +x etc/init.d/hosts
-
- # Wipe it, will be generated by the above runscript.
- echo -n > etc/hosts
-}
-
-setup_network() {
- # Note: loopback is automatically started by LXC.
- cat <<-EOF > etc/network/interfaces
- auto eth0
- iface eth0 inet dhcp
- hostname \$(hostname)
- EOF
-}
-
-setup_services() {
- local svc_name
-
- # Specify the LXC subsystem.
- sed -i 's/^#*rc_sys=.*/rc_sys="lxc"/' etc/rc.conf
-
- # boot runlevel
- for svc_name in bootmisc hosts syslog; do
- ln -s /etc/init.d/$svc_name etc/runlevels/boot/$svc_name
- done
-
- # default runlevel
- for svc_name in networking cron crond; do
- # issue 1164: alpine renamed cron to crond
- # Use the one that exists.
- if [ -e etc/init.d/$svc_name ]; then
- ln -s /etc/init.d/$svc_name etc/runlevels/default/$svc_name
- fi
- done
-}
-
-
-#=========================== Configure ===========================#
-
-configure_container() {
- local config="$1"
- local hostname="$2"
- local arch="$3"
-
- cat <<-EOF >> "$config"
-
- # Specify container architecture.
- lxc.arch = $arch
-
- # Set hostname.
- lxc.uts.name = $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_admin
-
- # Comment this out if you have to debug processes by tracing.
- lxc.cap.drop = sys_ptrace
-
- # Include common configuration.
- lxc.include = $LXC_TEMPLATE_CONFIG/alpine.common.conf
- EOF
-}
-
-
-#============================= Main ==============================#
-
-if [ "$(id -u)" != "0" ]; then
- die 1 "This script must be run as 'root'"
-fi
-
-# Parse command options.
-options=$(getopt -o a:dFm:n:p:r:h -l arch:,debug,flush-cache,mirror:,name:,\
-path:,release:,rootfs:,help,mapped-uid:,mapped-gid: -- "$@")
-eval set -- "$options"
-
-# Clean variables and set defaults.
-arch="$(uname -m)"
-debug='no'
-flush_cache='no'
-mirror_url=
-name=
-path=
-release=
-rootfs=
-
-# Process command options.
-while [ $# -gt 0 ]; do
- case $1 in
- -a | --arch)
- arch=$2; shift 2
- ;;
- -d | --debug)
- debug='yes'; shift 1
- ;;
- -F | --flush-cache)
- flush_cache='yes'; shift 1
- ;;
- -m | --mirror)
- mirror_url=$2; shift 2
- ;;
- -n | --name)
- name=$2; shift 2
- ;;
- -p | --path)
- path=$2; shift 2
- ;;
- -r | --release)
- release=$2; shift 2
- ;;
- --rootfs)
- rootfs=$2; shift 2
- ;;
- -h | --help)
- usage; exit 0
- ;;
- --)
- shift; break
- ;;
- --mapped-[ug]id)
- die 1 "This template can't be used for unprivileged containers." \
- 'You may want to try the "download" template instead.'
- ;;
- *)
- echo "Unknown option: $1" 1>&2
- usage; exit 1
- ;;
- esac
-done
-
-extra_packages="$@"
-
-[ "$debug" = 'yes' ] && set -x
-
-# Set global variables.
-readonly DEBUG="$debug"
-readonly FLUSH_CACHE="$flush_cache"
-readonly MIRROR_URL="${mirror_url:-$DEFAULT_MIRROR_URL}"
-
-# 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.path\s*=\s*(.*)$/\1/p' "$path/config")"
-fi
-if [ -z "$rootfs" ]; then
- rootfs="$path/rootfs"
-fi
-
-arch=$(parse_arch "$arch") \
- || die 1 "Unsupported architecture: $arch"
-
-if [ -z "$release" ]; then
- release=$(latest_release_branch "$arch") \
- || die 2 'Failed to resolve Alpine last release branch'
-fi
-
-# Here we go!
-run_exclusively 'bootstrap' 10 bootstrap
-run_exclusively "$arch" 30 install "$rootfs" "$arch" "$release" "$extra_packages"
-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".
-EOF
+++ /dev/null
-#!/bin/bash
-
-#
-# template script for generating altlinux container for LXC
-#
-
-#
-# lxc: linux Container library
-
-# Authors:
-# Alexey Shabalin <shaba@altlinux.org>
-
-# 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
-
-# Detect use under userns (unsupported)
-for arg in "$@"; do
- [ "$arg" = "--" ] && break
- if [ "$arg" = "--mapped-uid" -o "$arg" = "--mapped-gid" ]; then
- echo "This template can't be used for unprivileged containers." 1>&2
- echo "You may want to try the \"download\" template instead." 1>&2
- exit 1
- fi
-done
-
-# Make sure the usual locations are in PATH
-export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
-
-#Configurations
-arch=$(uname -m)
-cache_base=@LOCALSTATEDIR@/cache/lxc/altlinux/$arch
-default_path=@LXCPATH@
-default_profile=default
-profile_dir=/etc/lxc/profiles
-lxc_network_type=veth
-lxc_network_link=virbr0
-
-# is this altlinux?
-[ -f /etc/altlinux-release ] && is_altlinux=true
-
-configure_altlinux()
-{
-
- # disable selinux in altlinux
- mkdir -p $rootfs_path/selinux
- echo 0 > $rootfs_path/selinux/enforce
-
- mkdir -p ${rootfs_path}/etc/net/ifaces/eth0
- cat <<EOF > ${rootfs_path}/etc/net/ifaces/eth0/options
-BOOTPROTO=${BOOTPROTO}
-ONBOOT=yes
-NM_CONTROLLED=yes
-TYPE=eth
-EOF
-
-if [ ${BOOTPROTO} != "dhcp" ]; then
- # ip address
- cat <<EOF > ${rootfs_path}/etc/net/ifaces/eth0/ipv4address
-${ipv4}
-EOF
-
- cat <<EOF > ${rootfs_path}/etc/net/ifaces/eth0/ipv4route
-${gw}
-EOF
-
- cat <<EOF > ${rootfs_path}/etc/net/ifaces/eth0/resolv.conf
-nameserver ${dns}
-EOF
-
- cat <<EOF > ${rootfs_path}/etc/net/ifaces/eth0/ipv6address
-${ipv6}
-EOF
-
- cat <<EOF > ${rootfs_path}/etc/net/ifaces/eth0/ipv6route
-${gw6}
-EOF
-
-fi
-
- # set the hostname
- cat <<EOF > ${rootfs_path}/etc/sysconfig/network
-NETWORKING=yes
-CONFMETHOD=etcnet
-HOSTNAME=${UTSNAME}
-RESOLV_MODS=yes
-EOF
-
- # set minimal hosts
- cat <<EOF > $rootfs_path/etc/hosts
-127.0.0.1 localhost.localdomain localhost $name
-EOF
- # Allow to login at virsh console. loginuid.so doen't work in the absence of auditd.
-# sed -i 's/^.*loginuid.so.*$/\#&/' ${rootfs_path}/etc/pam.d/common-login
-
- # Allow root to login at virsh console
- echo "pts/0" >> ${rootfs_path}/etc/securetty
- echo "console" >> ${rootfs_path}/etc/securetty
-
- # Enable services
- for service in network syslogd random NetworkManager
- do
- chroot ${rootfs_path} chkconfig $service --list &>/dev/null && chroot ${rootfs_path} chkconfig $service on || true
- # For systemd
- chroot ${rootfs_path} systemctl -q enable $service &>/dev/null|| true
- done
- # Disable services
- for service in rawdevices fbsetfont
- do
- chroot ${rootfs_path} chkconfig $service --list &>/dev/null && chroot ${rootfs_path} chkconfig $service off || true
- chroot ${rootfs_path} systemctl -q disable $service &>/dev/null || true
- done
-
- subst 's/^\([3-9]\+:[0-9]\+:respawn:\/sbin\/mingetty.*\)/#\1/' ${rootfs_path}/etc/inittab
- echo "c1:2345:respawn:/sbin/mingetty --noclear console" >> ${rootfs_path}/etc/inittab
-
- [ -f "${rootfs_path}/etc/syslog.conf" ] && \
- subst 's,\/dev\/tty12,/var/log/syslog/console,' ${rootfs_path}/etc/syslog.conf
-
- dev_path="${rootfs_path}/dev"
- rm -rf ${dev_path}
- mkdir -p ${dev_path}
- mknod -m 666 ${dev_path}/null c 1 3
- mknod -m 666 ${dev_path}/zero c 1 5
- mknod -m 644 ${dev_path}/random c 1 8
- mknod -m 644 ${dev_path}/urandom c 1 9
- mkdir -m 755 ${dev_path}/pts
- mkdir -m 1777 ${dev_path}/shm
- mknod -m 666 ${dev_path}/tty c 5 0
- chown root:tty ${dev_path}/tty
- mknod -m 600 ${dev_path}/tty0 c 4 0
- mknod -m 600 ${dev_path}/tty1 c 4 1
- mknod -m 600 ${dev_path}/tty2 c 4 2
- mknod -m 600 ${dev_path}/tty3 c 4 3
- mknod -m 600 ${dev_path}/tty4 c 4 4
- mknod -m 600 ${dev_path}/console c 5 1
- mknod -m 666 ${dev_path}/full c 1 7
- mknod -m 600 ${dev_path}/initctl p
- mknod -m 666 ${dev_path}/ptmx c 5 2
- chown root:tty ${dev_path}/ptmx
- ln -s /proc/self/fd ${dev_path}/fd
- ln -s /proc/kcore ${dev_path}/core
- mkdir -m 755 ${dev_path}/mapper
- mknod -m 600 ${dev_path}/mapper/control c 10 236
- mkdir -m 755 ${dev_path}/net
- mknod -m 666 ${dev_path}/net/tun c 10 200
-
- if [ -n "${root_password}" ]; then
- echo "setting root passwd to $root_password"
- echo "root:$root_password" | chroot $rootfs_path chpasswd
- fi
-
- return 0
-}
-
-download_altlinux()
-{
-
- if [ -z "$aptconfver" ]; then
- case "$release" in
- sisyphus)
- aptconfver=apt-conf-sisyphus ;;
- *)
- aptconfver=apt-conf-branch ;;
- esac
- fi
-
- # check the mini altlinux was not already downloaded
- INSTALL_ROOT=$cache/partial
- mkdir -p $INSTALL_ROOT
- if [ $? -ne 0 ]; then
- echo "Failed to create '$INSTALL_ROOT' directory"
- return 1
- fi
-
- # download a mini altlinux into a cache
- echo "Downloading altlinux minimal ..."
- APT_GET="apt-get -o RPM::RootDir=$INSTALL_ROOT -y"
- PKG_LIST="$(grep -hs '^[^#]' "$profile_dir/$profile")"
- # if no configuration file $profile -- fall back to default list of packages
- [ -z "$PKG_LIST" ] && PKG_LIST="interactivesystem apt $aptconfver etcnet-full openssh-server systemd-sysvinit systemd-units systemd NetworkManager-daemon"
-
- mkdir -p $INSTALL_ROOT/var/lib/rpm
- rpm --root $INSTALL_ROOT --initdb
-
- # some scripts want to have /dev/null at least
- dev_path="$INSTALL_ROOT/dev"
- if [ ! -c "${dev_path}/null" ]; then
- mkdir -p "${dev_path}"
- mknod -m 666 "${dev_path}/null" c 1 3
- fi
-
- $APT_GET install $PKG_LIST
-
- if [ $? -ne 0 ]; then
- echo "Failed to download the rootfs, aborting."
- return 1
- fi
-
- mv "$INSTALL_ROOT" "$cache/rootfs"
- echo "Download complete."
-
- return 0
-}
-
-copy_altlinux()
-{
-
- # make a local copy of the minialtlinux
- echo -n "Copying rootfs to $rootfs_path ..."
- #cp -a $cache/rootfs-$arch $rootfs_path || return 1
- # i prefer rsync (no reason really)
- mkdir -p $rootfs_path
- rsync -SHaAX $cache/rootfs/ $rootfs_path/
- return 0
-}
-
-update_altlinux()
-{
- chroot $cache/rootfs apt-get update
- chroot $cache/rootfs apt-get -y dist-upgrade
-}
-
-install_altlinux()
-{
- mkdir -p @LOCALSTATEDIR@/lock/subsys/
- (
- flock -x 9
- if [ $? -ne 0 ]; then
- echo "Cache repository is busy."
- return 1
- fi
-
- echo "Checking cache download in $cache/rootfs ... "
- if [ ! -e "$cache/rootfs" ]; then
- download_altlinux
- if [ $? -ne 0 ]; then
- echo "Failed to download 'altlinux base'"
- return 1
- fi
- else
- echo "Cache found. Updating..."
- update_altlinux
- if [ $? -ne 0 ]; then
- echo "Failed to update 'altlinux base', continuing with last known good cache"
- else
- echo "Update finished"
- fi
- fi
-
- echo "Copy $cache/rootfs to $rootfs_path ... "
- copy_altlinux
- if [ $? -ne 0 ]; then
- echo "Failed to copy rootfs"
- return 1
- fi
- return 0
- ) 9>@LOCALSTATEDIR@/lock/subsys/lxc-altlinux
-
- return $?
-}
-
-copy_configuration()
-{
-
- mkdir -p $config_path
- grep -q "^lxc.rootfs.path" $config_path/config 2>/dev/null || echo "lxc.rootfs.path = $rootfs_path" >> $config_path/config
- cat <<EOF >> $config_path/config
-lxc.uts.name = $name
-lxc.tty.max = 4
-lxc.pty.max = 1024
-lxc.cap.drop = sys_module mac_admin mac_override sys_time
-
-# When using LXC with apparmor, uncomment the next line to run unconfined:
-#lxc.apparmor.profile = unconfined
-
-#networking
-#lxc.net.0.type = $lxc_network_type
-#lxc.net.0.flags = up
-#lxc.net.0.link = $lxc_network_link
-#lxc.net.0.name = veth0
-#lxc.net.0.mtu = 1500
-EOF
-if [ ! -z ${ipv4} ]; then
- cat <<EOF >> $config_path/config
-lxc.net.0.ipv4.address = $ipv4
-EOF
-fi
-if [ ! -z ${gw} ]; then
- cat <<EOF >> $config_path/config
-lxc.net.0.ipv4.gateway = $gw
-EOF
-fi
-if [ ! -z ${ipv6} ]; then
- cat <<EOF >> $config_path/config
-lxc.net.0.ipv6.address = $ipv6
-EOF
-fi
-if [ ! -z ${gw6} ]; then
- cat <<EOF >> $config_path/config
-lxc.net.0.ipv6.gateway = $gw6
-EOF
-fi
- cat <<EOF >> $config_path/config
-#cgroups
-lxc.cgroup.devices.deny = a
-# /dev/null and zero
-lxc.cgroup.devices.allow = c 1:3 rwm
-lxc.cgroup.devices.allow = c 1:5 rwm
-# 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
-# rtc
-lxc.cgroup.devices.allow = c 10:135 rwm
-
-lxc.mount.auto = cgroup:mixed proc:mixed sys:mixed
-EOF
-
- if [ $? -ne 0 ]; then
- echo "Failed to add configuration"
- return 1
- fi
-
- return 0
-}
-
-clean()
-{
-
- if [ ! -e $cache ]; then
- exit 0
- fi
-
- # lock, so we won't purge while someone is creating a repository
- (
- flock -x 9
- if [ $? != 0 ]; then
- echo "Cache repository is busy."
- exit 1
- fi
-
- echo -n "Purging the download cache for ALTLinux-$release..."
- rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1
- exit 0
- ) 9>@LOCALSTATEDIR@/lock/subsys/lxc-altlinux
-}
-
-usage()
-{
- cat <<EOF
-usage:
- $1 -n|--name=<container_name>
- [-p|--path=<path>] [-c|--clean] [-R|--release=<ALTLinux_release>]
- [-4|--ipv4=<ipv4 address>] [-6|--ipv6=<ipv6 address>]
- [-g|--gw=<gw address>] [-d|--dns=<dns address>]
- [-P|--profile=<name of the profile>] [--rootfs=<path>]
- [-a|--apt-conf=<apt-conf>]
- [-A|--arch=<arch of the container>]
- [-h|--help]
-Mandatory args:
- -n,--name container name, used to as an identifier for that container from now on
-Optional args:
- -p,--path path to where the container rootfs will be created, defaults to @LXCPATH@. The container config will go under @LXCPATH@ in that case
- -c,--clean clean the cache
- -R,--release ALTLinux release for the new container. if the host is ALTLinux, then it will defaultto the host's release.
- -4,--ipv4 specify the ipv4 address to assign to the virtualized interface, eg. 192.168.1.123/24
- -6,--ipv6 specify the ipv6 address to assign to the virtualized interface, eg. 2003:db8:1:0:214:1234:fe0b:3596/64
- -g,--gw specify the default gw, eg. 192.168.1.1
- -G,--gw6 specify the default gw, eg. 2003:db8:1:0:214:1234:fe0b:3596
- -d,--dns specify the DNS server, eg. 192.168.1.2
- -a,--apt-conf specify preferred 'apt-conf' package, eg. 'apt-conf-branch'
- -P,--profile Profile name is the file name in /etc/lxc/profiles contained packages name for install to cache.
- -A,--arch NOT USED YET. Define what arch the container will be [i686,x86_64]
- ---rootfs rootfs path
- -h,--help print this help
-EOF
- return 0
-}
-
-options=$(getopt -o hp:n:P:cR:4:6:g:d:a: -l help,rootfs:,path:,name:,profile:,clean,release:,ipv4:,ipv6:,gw:,dns:,apt-conf: -- "$@")
-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_path=$2; shift 2;;
- -n|--name) name=$2; shift 2;;
- -P|--profile) profile=$2; shift 2;;
- -c|--clean) clean=1; shift 1;;
- -R|--release) release=$2; shift 2;;
- -4|--ipv4) ipv4=$2; shift 2;;
- -6|--ipv6) ipv6=$2; shift 2;;
- -g|--gw) gw=$2; shift 2;;
- -d|--dns) dns=$2; shift 2;;
- -a|--apt-conf) aptconfver=$2; shift 2;;
- --) shift 1; break ;;
- *) break ;;
- esac
-done
-
-if [ ! -z "$clean" -a -z "$path" ]; then
- clean || exit 1
- exit 0
-fi
-
-type apt-get >/dev/null 2>&1
-if [ $? -ne 0 ]; then
- echo "'apt-get' command is missing"
- exit 1
-fi
-
-if [ -z "$path" ]; then
- path=$default_path
-fi
-
-if [ -z "$profile" ]; then
- profile=$default_profile
-fi
-
-if [ -z "$release" ]; then
- if [ "$is_altlinux" ]; then
- release=$(cat /etc/altlinux-release |awk '/^ALT/ {print $3}')
- else
- echo "This is not a ALTLinux host and release missing, use -R|--release to specify release"
- exit 1
- fi
-fi
-
-if [ -z "$ipv4" -a -z "$ipv6" ]; then
- BOOTPROTO="dhcp"
-else
- BOOTPROTO="static"
-fi
-
-if [ "$(id -u)" != "0" ]; then
- echo "This script should be run as 'root'"
- exit 1
-fi
-
-# check for 'lxc.rootfs.path' passed in through default config by lxc-create
-if [ -z "$rootfs_path" ]; then
- if grep -q '^lxc.rootfs.path' $path/config 2>/dev/null ; then
- rootfs_path=$(awk -F= '/^lxc.rootfs.path =/{ print $2 }' $path/config)
- else
- rootfs_path=$path/rootfs
- fi
-fi
-
-config_path=$default_path/$name
-cache=$cache_base/$release/$profile
-
-install_altlinux
-if [ $? -ne 0 ]; then
- echo "failed to install altlinux"
- exit 1
-fi
-
-configure_altlinux
-if [ $? -ne 0 ]; then
- echo "failed to configure altlinux for a container"
- exit 1
-fi
-
-copy_configuration
-if [ $? -ne 0 ]; then
- echo "failed write configuration file"
- exit 1
-fi
-
-if [ ! -z "$clean" ]; then
- clean || exit 1
- exit 0
-fi
-echo "container rootfs and config created"
-echo "network configured as $lxc_network_type in the $lxc_network_link"
+++ /dev/null
-#!/bin/bash
-
-#
-# template script for generating Arch Linux container for LXC
-#
-
-#
-# lxc: linux Container library
-
-# Authors:
-# Alexander Vladimirov <alexander.idkfa.vladimirov@gmail.com>
-# John Lane <lxc@jelmail.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
-
-# Detect use under userns (unsupported)
-for arg in "$@"; do
- [ "$arg" = "--" ] && break
- if [ "$arg" = "--mapped-uid" -o "$arg" = "--mapped-gid" ]; then
- echo "This template can't be used for unprivileged containers." 1>&2
- echo "You may want to try the \"download\" template instead." 1>&2
- exit 1
- fi
-done
-
-# Make sure the usual locations are in PATH
-export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
-
-# defaults
-arch=$(uname -m)
-default_path="@LXCPATH@"
-default_locale="en_US.UTF-8"
-pacman_config="/etc/pacman.conf"
-common_config="@LXCTEMPLATECONFIG@/common.conf"
-shared_config="@LXCTEMPLATECONFIG@/archlinux.common.conf"
-
-# by default, install 'base' except the kernel
-pkg_blacklist="linux"
-base_packages=()
-for pkg in $(pacman -Sqg base); do
- [ "${pkg_blacklist#*$pkg}" = "$pkg_blacklist" ] && base_packages+=($pkg)
-done
-declare -a additional_packages
-
-# split comma-separated string into an array
-# ${1} - string to split
-# ${2} - separator (default is ",")
-# ${result} - result value on success
-split_string() {
- local ifs=${IFS}
- IFS="${2:-,}"
- read -a result < <(echo "${1}")
- IFS=${ifs}
- return 0
-}
-
-[ -f /etc/arch-release ] && is_arch=true
-
-# Arch-specific preconfiguration for container
-configure_arch() {
- # on ArchLinux, read defaults from host systemd configuration
- if [ "${is_arch}" ]; then
- cp -p /etc/locale.conf /etc/locale.gen "${rootfs_path}/etc/"
- else
- echo "LANG=${default_locale}" > "${rootfs_path}/etc/locale.conf"
- if [ -e "${rootfs_path}/etc/locale.gen" ]; then
- sed -i 's@^#\(en_US\.UTF-8\)@\1@' "${rootfs_path}/etc/locale.gen"
- if [ ! "${default_locale}" = "en_US.UTF-8" ]; then
- echo "${default_locale} ${default_locale##*.}" >> \
- "${rootfs_path}/etc/locale.gen"
- fi
- fi
- fi
-
- # hostname and nameservers
- echo "${name}" > "${rootfs_path}/etc/hostname"
-
- # network configuration
- cat > "${rootfs_path}/etc/systemd/network/eth0.network" << EOF
-[Match]
-Name=eth0
-
-[Network]
-DHCP=ipv4
-EOF
-
- # chroot and configure system
- arch-chroot "${rootfs_path}" /bin/bash -s << EOF
-mkdir /run/lock
-locale-gen
-# set default boot target
-ln -s /lib/systemd/system/multi-user.target /etc/systemd/system/default.target
-# override getty@.service for container ttys
-sed -e 's/^ConditionPathExists=/# ConditionPathExists=/' \
- -e 's/After=dev-%i.device/After=/' \
- < /lib/systemd/system/getty\@.service \
- > /etc/systemd/system/getty\@.service
-# fix systemd-sysctl service
-sed -e 's/^ConditionPathIsReadWrite=\/proc\/sys\/$/ConditionPathIsReadWrite=\/proc\/sys\/net\//' \
- -e 's/^ExecStart=\/usr\/lib\/systemd\/systemd-sysctl$/ExecStart=\/usr\/lib\/systemd\/systemd-sysctl --prefix net/' \
- -i /usr/lib/systemd/system/systemd-sysctl.service
-# initialize pacman keyring
-pacman-key --init
-pacman-key --populate archlinux
-
-# enable networkd
-systemctl enable systemd-networkd
-systemctl enable systemd-resolved
-ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
-EOF
- # enable getty on active ttys
- local nttys=$(cat "${config_path}/config" ${shared_config} ${common_config} | grep "^lxc.tty.max" | head -n1 | cut -d= -f2 | tr -d "[:blank:]")
- local devttydir=$(cat "${config_path}/config" ${shared_config} ${common_config} | grep "^lxc.tty.dir" | head -n1 | cut -d= -f2 | tr -d "[:blank:]")
- local devtty=""
- # bind getty instances to /dev/<devttydir>/tty* if lxc.tty.dir is set
- [ -n "${devttydir}" ] && devtty="${devttydir}-"
- if [ ${nttys:-0} -gt 1 ]; then
- ( cd "${rootfs_path}/etc/systemd/system/getty.target.wants"
- for i in $(seq 1 $nttys); do ln -sf "../getty@.service" "getty@${devtty}tty${i}.service"; done )
- fi
- # update securetty to allow console login if devttydir is set
- if [ -n "${devttydir}" ]; then
- for i in $(seq 1 ${nttys:-1}); do
- echo "${devttydir}/tty${i}" >> "${rootfs_path}/etc/securetty"
- done
- fi
- [ -n "${devttydir}" ] && echo "${devttydir}/console" >> "${rootfs_path}/etc/securetty"
- # Arch default configuration allows only tty1-6 for login
- [ ${nttys:-0} -gt 6 ] && echo \
- "You may want to modify container's /etc/securetty \
- file to allow root logins on tty7 and higher"
- return 0
-}
-
-# write container configuration files
-copy_configuration() {
- mkdir -p "${config_path}"
- local config="${config_path}/config"
- echo "lxc.uts.name = ${name}" >> "${config}"
- grep -q "^lxc.arch" "${config}" 2>/dev/null \
- || echo "lxc.arch = ${arch}" >> "${config}"
- grep -q "^lxc.rootfs.path" "${config}" 2>/dev/null \
- || echo "lxc.rootfs.path = ${rootfs_path}" >> "${config}"
- [ -e "${shared_config}" ] \
- && echo "lxc.include = ${shared_config}" >> "${config}"
- if [ $? -ne 0 ]; then
- echo "Failed to configure container"
- return 1
- fi
- return 0
-}
-
-# install packages within container chroot
-install_arch() {
- [ "${arch}" != "$(uname -m)" ] && different_arch=true
-
- if [ "${different_arch}" = "true" ]; then
- container_pacman_config=$(mktemp)
- container_mirrorlist=$(mktemp)
- sed -e "s:Architecture =.*:Architecture = ${arch}:g" \
- -e "s:/etc/pacman.d/mirrorlist:${container_mirrorlist}:g" \
- "${pacman_config}" > "${container_pacman_config}"
- sed -e "s:\(x86_64\|\$arch\):${arch}:g" \
- /etc/pacman.d/mirrorlist > "${container_mirrorlist}"
-
- pacman_config="${container_pacman_config}"
- fi
-
- if ! pacstrap -dcGC "${pacman_config}" "${rootfs_path}" \
- ${base_packages[@]}; then
- echo "Failed to install container packages"
- return 1
- fi
-
- if [ "${different_arch}" = "true" ]; then
- sed -i -e "s:Architecture =.*:Architecture = ${arch}:g" \
- "${rootfs_path}"/etc/pacman.conf
- cp "${container_mirrorlist}" "${rootfs_path}"/etc/pacman.d/mirrorlist
- rm "${container_pacman_config}" "${container_mirrorlist}"
- fi
-
- [ -d "${rootfs_path}/lib/modules" ] && ldconfig -r "${rootfs_path}"
- return 0
-}
-
-usage() {
- cat <<EOF
-usage:
- ${1} -n|--name=<container_name> [-p|--path=<path>] [-a|--arch=<arch of the container>]
- [-r|--root_password=<root password>] [-P|--packages=<pkg1,pkg2,...>]
- [-e|--enable_units=unit1,unit2...] [-d|--disable_units=unit1,unit2...]
- [-c|--config=<pacman config path>] [-h|--help]
-
-Mandatory args:
- -n,--name container name, used to as an identifier for that container from now on
-Optional args:
- -p,--path path to where the container rootfs will be created (${default_path})
- --rootfs path for actual container rootfs, (${default_path}/rootfs)
- -P,--packages preinstall additional packages, comma-separated list
- -e,--enable_units enable systemd services, comma-separated list
- -d,--disable_units disable systemd services, comma-separated list
- -c,--config use specified pacman config when installing container packages
- -a,--arch use specified architecture instead of host's architecture
- -r,--root_password set container root password
- -h,--help print this help
-EOF
- return 0
-}
-
-options=$(getopt -o hp:P:e:d:n:c:a:r: -l help,rootfs:,path:,packages:,enable_units:,disable_units:,name:,config:,arch:,root_password: -- "${@}")
-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;;
- -n|--name) name=${2}; shift 2;;
- --rootfs) rootfs_path=${2}; shift 2;;
- -P|--packages) additional_packages=${2}; shift 2;;
- -e|--enable_units) enable_units=${2}; shift 2;;
- -d|--disable_units) disable_units=${2}; shift 2;;
- -c|--config) pacman_config=${2}; shift 2;;
- -a|--arch) arch=${2}; shift 2;;
- -r|--root_password) root_passwd=${2}; shift 2;;
- --) shift 1; break ;;
- *) break ;;
- esac
-done
-
-if [ -z "${name}" ]; then
- echo "missing required 'name' parameter"
- exit 1
-fi
-
-type pacman >/dev/null 2>&1
-if [ ${?} -ne 0 ]; then
- echo "'pacman' command is missing, refer to wiki.archlinux.org for information about installing pacman"
- exit 1
-fi
-
-if [ -z "${path}" ]; then
- path="${default_path}/${name}"
-fi
-
-if [ "${EUID}" != "0" ]; then
- echo "This script should be run as 'root'"
- exit 1
-fi
-
-if [ -z "$rootfs_path" ]; then
- rootfs_path="${path}/rootfs"
-fi
-config_path="${path}"
-
-revert() {
- echo "Interrupted, cleaning up"
- lxc-destroy -n "${name}"
- rm -rf "${path}/${name}"
- rm -rf "${default_path}/${name}"
- exit 1
-}
-
-trap revert SIGHUP SIGINT SIGTERM
-
-copy_configuration
-if [ ${?} -ne 0 ]; then
- echo "failed to write configuration file"
- rm -rf "${config_path}"
- exit 1
-fi
-
-if [ ${#additional_packages[@]} -gt 0 ]; then
- split_string ${additional_packages}
- base_packages+=(${result[@]})
-fi
-
-mkdir -p "${rootfs_path}"
-install_arch
-if [ ${?} -ne 0 ]; then
- echo "failed to install Arch Linux"
- rm -rf "${config_path}" "${path}"
- exit 1
-fi
-
-configure_arch
-if [ ${?} -ne 0 ]; then
- echo "failed to configure Arch Linux for a container"
- rm -rf "${config_path}" "${path}"
- exit 1
-fi
-
-if [ ${#enable_units[@]} -gt 0 ]; then
- split_string ${enable_units}
- for unit in ${result[@]}; do
- [ "${unit##*.}" = "service" ] || unit="${unit}.service"
- ln -s "/usr/lib/systemd/system/${unit}" \
- "${rootfs_path}/etc/systemd/system/multi-user.target.wants/"
- done
-fi
-
-if [ ${#disable_units[@]} -gt 0 ]; then
- split_string ${disable_units}
- for unit in ${result[@]}; do
- [ "${unit##*.}" = "service" ] || unit="${unit}.service"
- ln -s /dev/null "${rootfs_path}/etc/systemd/system/${unit}"
- done
-fi
-
-if [ -n "${root_passwd}" ]; then
- echo "root:${root_passwd}" | chroot "${rootfs_path}" chpasswd
-fi
-
-cat << EOF
-Arch Linux container ${name} is successfully created! The configuration is
-stored in ${config_path}/config. Please refer to https://wiki.archlinux.org for
-information about configuring Arch Linux.
-EOF
+++ /dev/null
-#!/bin/bash
-
-#
-# template script for generating CentOS container for LXC
-
-#
-# lxc: linux Container library
-
-# Authors:
-# Daniel Lezcano <daniel.lezcano@free.fr>
-# Ramez Hanna <rhanna@informatiq.org>
-# Fajar A. Nugraha <github@fajar.net>
-# Michael H. Warfield <mhw@WittsEnd.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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-#Configurations
-default_path=@LXCPATH@
-
-# Some combinations of the tuning knobs below do not exactly make sense.
-# but that's ok.
-#
-# If the "root_password" is non-blank, use it, else set a default.
-# This can be passed to the script as an environment variable and is
-# set by a shell conditional assignment. Looks weird but it is what it is.
-#
-# If the root password contains a ding ($) then try to expand it.
-# That will pick up things like ${name} and ${RANDOM}.
-# If the root password contains more than 3 consecutive X's, pass it as
-# a template to mktemp and take the result.
-#
-# If root_display_password = yes, display the temporary root password at exit.
-# If root_store_password = yes, store it in the configuration directory
-# If root_prompt_password = yes, invoke "passwd" to force the user to change
-# the root password after the container is created.
-# If root_expire_password = yes, you will be prompted to change the root
-# password at the first login.
-#
-# These are conditional assignments... The can be overridden from the
-# preexisting environment variables...
-#
-# Make sure this is in single quotes to defer expansion to later!
-# :{root_password='Root-${name}-${RANDOM}'}
-: ${root_password='Root-${name}-XXXXXX'}
-
-# Now, it doesn't make much sense to display, store, and force change
-# together. But, we gotta test, right???
-: ${root_display_password='no'}
-: ${root_store_password='yes'}
-# Prompting for something interactive has potential for mayhem
-# with users running under the API... Don't default to "yes"
-: ${root_prompt_password='no'}
-
-# Expire root password? Default to yes, but can be overridden from
-# the environment variable
-: ${root_expire_password='yes'}
-
-# These are only going into comments in the resulting config...
-lxc_network_type=veth
-lxc_network_link=lxcbr0
-
-# is this CentOS?
-# Alow for weird remixes like the Raspberry Pi
-#
-# Use the Mitre standard CPE identifier for the release ID if possible...
-# This may be in /etc/os-release or /etc/system-release-cpe. We
-# should be able to use EITHER. Give preference to /etc/os-release for now.
-
-# Detect use under userns (unsupported)
-for arg in "$@"; do
- [ "$arg" = "--" ] && break
- if [ "$arg" = "--mapped-uid" -o "$arg" = "--mapped-gid" ]; then
- echo "This template can't be used for unprivileged containers." 1>&2
- echo "You may want to try the \"download\" template instead." 1>&2
- exit 1
- fi
-done
-
-# Make sure the usual locations are in PATH
-export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
-
-if [ -e /etc/os-release ]
-then
-# This is a shell friendly configuration file. We can just source it.
-# What we're looking for in here is the ID, VERSION_ID and the CPE_NAME
- . /etc/os-release
- echo "Host CPE ID from /etc/os-release: ${CPE_NAME}"
-fi
-
-if [ "${CPE_NAME}" = "" -a -e /etc/system-release-cpe ]
-then
- CPE_NAME=$(head -n1 /etc/system-release-cpe)
- CPE_URI=$(expr ${CPE_NAME} : '\([^:]*:[^:]*\)')
- if [ "${CPE_URI}" != "cpe:/o" ]
- then
- CPE_NAME=
- else
- # Probably a better way to do this but sill remain posix
- # compatible but this works, shrug...
- # Must be nice and not introduce convenient bashisms here.
- #
- # According to the official registration at Mitre and NIST,
- # this should have been something like this for CentOS:
- # cpe:/o:centos:centos:6
- # or this:
- # cpe:/o:centos:centos:6.5
- #
- ID=$(expr ${CPE_NAME} : '[^:]*:[^:]*:[^:]*:\([^:]*\)')
- # The "enterprise_linux" is a bone toss back to RHEL.
- # Since CentOS and RHEL are so tightly coupled, we'll
- # take the RHEL version if we're running on it and do the
- # equivalent version for CentOS.
- if [ ${ID} = "linux" -o ${ID} = "enterprise_linux" ]
- then
- # Instead we got this: cpe:/o:centos:linux:6
- ID=$(expr ${CPE_NAME} : '[^:]*:[^:]*:\([^:]*\)')
- fi
-
- VERSION_ID=$(expr ${CPE_NAME} : '[^:]*:[^:]*:[^:]*:[^:]*:\([^:]*\)')
- echo "Host CPE ID from /etc/system-release-cpe: ${CPE_NAME}"
- fi
-fi
-
-if [ "${CPE_NAME}" != "" -a "${ID}" = "centos" -a "${VERSION_ID}" != "" ]
-then
- centos_host_ver=${VERSION_ID}
- is_centos=true
-elif [ "${CPE_NAME}" != "" -a "${ID}" = "redhat" -o "${ID}" = "rhel" -a "${VERSION_ID}" != "" ]
-then
- # RHEL 7+ /etc/os-release ID = 'rhel', which doesn't enter this elif without the added OR statement
- redhat_host_ver=${VERSION_ID}
- is_redhat=true
-elif [ -e /etc/centos-release ]
-then
- # Only if all other methods fail, try to parse the redhat-release file.
- centos_host_ver=$( sed -e '/^CentOS /!d' -e 's/CentOS.*\srelease\s*\([0-9][0-9.]*\)\s.*/\1/' < /etc/centos-release )
- if [ "$centos_host_ver" != "" ]
- then
- is_centos=true
- fi
-fi
-
-force_mknod()
-{
- # delete a device node if exists, and create a new one
- rm -f $2 && mknod -m $1 $2 $3 $4 $5
-}
-
-configure_centos()
-{
-
- # disable selinux in CentOS
- mkdir -p $rootfs_path/selinux
- echo 0 > $rootfs_path/selinux/enforce
-
- # Also kill it in the /etc/selinux/config file if it's there...
- if [ -f $rootfs_path/etc/selinux/config ]
- then
- sed -i '/^SELINUX=/s/.*/SELINUX=disabled/' $rootfs_path/etc/selinux/config
- fi
-
- # Nice catch from Dwight Engen in the Oracle template.
- # Wantonly plagerized here with much appreciation.
- if [ -f $rootfs_path/usr/sbin/selinuxenabled ]; then
- mv $rootfs_path/usr/sbin/selinuxenabled $rootfs_path/usr/sbin/selinuxenabled.lxcorig
- ln -s /bin/false $rootfs_path/usr/sbin/selinuxenabled
- fi
-
- # This is a known problem and documented in RedHat bugzilla as relating
- # to a problem with auditing enabled. This prevents an error in
- # the container "Cannot make/remove an entry for the specified session"
- sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs_path}/etc/pam.d/login
- sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs_path}/etc/pam.d/sshd
-
- if [ -f ${rootfs_path}/etc/pam.d/crond ]
- then
- sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs_path}/etc/pam.d/crond
- fi
-
- # In addition to disabling pam_loginuid in the above config files
- # we'll also disable it by linking it to pam_permit to catch any
- # we missed or any that get installed after the container is built.
- #
- # Catch either or both 32 and 64 bit archs.
- if [ -f ${rootfs_path}/lib/security/pam_loginuid.so ]
- then
- ( cd ${rootfs_path}/lib/security/
- mv pam_loginuid.so pam_loginuid.so.disabled
- ln -s pam_permit.so pam_loginuid.so
- )
- fi
-
- if [ -f ${rootfs_path}/lib64/security/pam_loginuid.so ]
- then
- ( cd ${rootfs_path}/lib64/security/
- mv pam_loginuid.so pam_loginuid.so.disabled
- ln -s pam_permit.so pam_loginuid.so
- )
- fi
-
- # Set default localtime to the host localtime if not set...
- if [ -e /etc/localtime -a ! -e ${rootfs_path}/etc/localtime ]
- then
- # if /etc/localtime is a symlink, this should preserve it.
- cp -a /etc/localtime ${rootfs_path}/etc/localtime
- fi
-
- # Deal with some dain bramage in the /etc/init.d/halt script.
- # Trim it and make it our own and link it in before the default
- # halt script so we can intercept it. This also preventions package
- # updates from interferring with our interferring with it.
- #
- # There's generally not much in the halt script that useful but what's
- # in there from resetting the hardware clock down is generally very bad.
- # So we just eliminate the whole bottom half of that script in making
- # ourselves a copy. That way a major update to the init scripts won't
- # trash what we've set up.
- if [ -f ${rootfs_path}/etc/init.d/halt ]
- then
- sed -e '/hwclock/,$d' \
- < ${rootfs_path}/etc/init.d/halt \
- > ${rootfs_path}/etc/init.d/lxc-halt
-
- echo '$command -f' >> ${rootfs_path}/etc/init.d/lxc-halt
- chmod 755 ${rootfs_path}/etc/init.d/lxc-halt
-
- # Link them into the rc directories...
- (
- cd ${rootfs_path}/etc/rc.d/rc0.d
- ln -s ../init.d/lxc-halt S00lxc-halt
- cd ${rootfs_path}/etc/rc.d/rc6.d
- ln -s ../init.d/lxc-halt S00lxc-reboot
- )
- fi
-
- # configure the network using the dhcp
- cat <<EOF > ${rootfs_path}/etc/sysconfig/network-scripts/ifcfg-eth0
-DEVICE=eth0
-BOOTPROTO=dhcp
-ONBOOT=yes
-HOSTNAME=${utsname}
-NM_CONTROLLED=no
-TYPE=Ethernet
-MTU=${MTU}
-DHCP_HOSTNAME=\`hostname\`
-EOF
-
- # set the hostname
- cat <<EOF > ${rootfs_path}/etc/sysconfig/network
-NETWORKING=yes
-HOSTNAME=${utsname}
-EOF
-
- # set minimal hosts
- cat <<EOF > $rootfs_path/etc/hosts
-127.0.0.1 localhost $name
-EOF
-
- # set minimal fstab
- cat <<EOF > $rootfs_path/etc/fstab
-/dev/root / rootfs defaults 0 0
-EOF
-
- # create lxc compatibility init script
- if [ "$release" = "6" ]; then
- cat <<EOF > $rootfs_path/etc/init/lxc-sysinit.conf
-start on startup
-env container
-
-pre-start script
- if [ "x\$container" != "xlxc" -a "x\$container" != "xlibvirt" ]; then
- stop;
- fi
-
- rm -f /var/lock/subsys/*
- rm -f /var/run/*.pid
- [ -e /etc/mtab ] || ln -s /proc/mounts /etc/mtab
- mkdir -p /dev/shm
- mount -t tmpfs -o nosuid,nodev tmpfs /dev/shm
-
- initctl start tty TTY=console
- telinit 3
- exit 0
-end script
-EOF
- elif [ "$release" = "5" ]; then
- cat <<EOF > $rootfs_path/etc/rc.d/lxc.sysinit
-#! /bin/bash
-rm -f /etc/mtab /var/run/*.{pid,lock} /var/lock/subsys/*
-rm -rf {/,/var}/tmp/*
-echo "/dev/root / rootfs defaults 0 0" > /etc/mtab
-exit 0
-EOF
- chmod 755 $rootfs_path/etc/rc.d/lxc.sysinit
- sed -i 's|si::sysinit:/etc/rc.d/rc.sysinit|si::bootwait:/etc/rc.d/lxc.sysinit|' $rootfs_path/etc/inittab
- # prevent mingetty from calling vhangup(2) since it fails with userns.
- # Same issue as oracle template: prevent mingetty from calling vhangup(2)
- # commit 2e83f7201c5d402478b9849f0a85c62d5b9f1589.
- sed -i 's|^1:|co:2345:respawn:/sbin/mingetty --nohangup console\n1:|' $rootfs_path/etc/inittab
- sed -i 's|^\([56]:\)|#\1|' $rootfs_path/etc/inittab
- fi
-
- dev_path="${rootfs_path}/dev"
- rm -rf $dev_path
- mkdir -p $dev_path
- mknod -m 666 ${dev_path}/null c 1 3
- mknod -m 666 ${dev_path}/zero c 1 5
- mknod -m 666 ${dev_path}/random c 1 8
- mknod -m 666 ${dev_path}/urandom c 1 9
- mkdir -m 755 ${dev_path}/pts
- mkdir -m 1777 ${dev_path}/shm
- mknod -m 666 ${dev_path}/tty c 5 0
- mknod -m 666 ${dev_path}/tty0 c 4 0
- mknod -m 666 ${dev_path}/tty1 c 4 1
- mknod -m 666 ${dev_path}/tty2 c 4 2
- mknod -m 666 ${dev_path}/tty3 c 4 3
- mknod -m 666 ${dev_path}/tty4 c 4 4
- mknod -m 600 ${dev_path}/console c 5 1
- mknod -m 666 ${dev_path}/full c 1 7
- mknod -m 600 ${dev_path}/initctl p
- mknod -m 666 ${dev_path}/ptmx c 5 2
-
- # setup console and tty[1-4] for login. note that /dev/console and
- # /dev/tty[1-4] will be symlinks to the ptys /dev/lxc/console and
- # /dev/lxc/tty[1-4] so that package updates can overwrite the symlinks.
- # lxc will maintain these links and bind mount ptys over /dev/lxc/*
- # since lxc.tty.dir is specified in the config.
-
- # allow root login on console, tty[1-4], and pts/0 for libvirt
- echo "# LXC (Linux Containers)" >>${rootfs_path}/etc/securetty
- echo "lxc/console" >>${rootfs_path}/etc/securetty
- echo "lxc/tty1" >>${rootfs_path}/etc/securetty
- echo "lxc/tty2" >>${rootfs_path}/etc/securetty
- echo "lxc/tty3" >>${rootfs_path}/etc/securetty
- echo "lxc/tty4" >>${rootfs_path}/etc/securetty
- echo "# For libvirt/Virtual Machine Monitor" >>${rootfs_path}/etc/securetty
- echo "pts/0" >>${rootfs_path}/etc/securetty
-
- # prevent mingetty from calling vhangup(2) since it fails with userns.
- # Same issue as oracle template: prevent mingetty from calling vhangup(2)
- # commit 2e83f7201c5d402478b9849f0a85c62d5b9f1589.
- test -f $rootfs_path/etc/init/tty.conf && sed -i 's|mingetty|mingetty --nohangup|' $rootfs_path/etc/init/tty.conf
-
- if [ ${root_display_password} = "yes" ]
- then
- echo "Setting root password to '$root_password'"
- fi
- if [ ${root_store_password} = "yes" ]
- then
- touch ${config_path}/tmp_root_pass
- chmod 600 ${config_path}/tmp_root_pass
- echo ${root_password} > ${config_path}/tmp_root_pass
- echo "Storing root password in '${config_path}/tmp_root_pass'"
- fi
-
- echo "root:$root_password" | chroot $rootfs_path chpasswd
-
- if [ ${root_expire_password} = "yes" ]
- then
- # Also set this password as expired to force the user to change it!
- chroot $rootfs_path passwd -e root
- fi
-
- # This will need to be enhanced for CentOS 7 when systemd
- # comes into play... /\/\|=mhw=|\/\/
-
- return 0
-}
-
-configure_centos_init()
-{
- test -f ${rootfs_path}/etc/rc.sysinit && sed -i 's|.sbin.start_udev||' ${rootfs_path}/etc/rc.sysinit
- test -f ${rootfs_path}/etc/rc.d/rc.sysinit && sed -i 's|.sbin.start_udev||' ${rootfs_path}/etc/rc.d/rc.sysinit
- if [ "$release" = "6" ]; then
- chroot ${rootfs_path} chkconfig udev-post off
- fi
- chroot ${rootfs_path} chkconfig network on
-
- if [ "$release" = "7" ]; then
- # don't wait for the timeout
- chroot ${rootfs_path} chkconfig systemd-remount-fs off
- fi
-
- if [ -d ${rootfs_path}/etc/init ]
- then
- # This is to make upstart honor SIGPWR
- cat <<EOF >${rootfs_path}/etc/init/power-status-changed.conf
-# power-status-changed - shutdown on SIGPWR
-#
-start on power-status-changed
-
-exec /sbin/shutdown -h now "SIGPWR received"
-EOF
- fi
-}
-
-download_centos()
-{
-
- # check the mini CentOS was not already downloaded
- INSTALL_ROOT=$cache/partial
- mkdir -p $INSTALL_ROOT
- if [ $? -ne 0 ]; then
- echo "Failed to create '$INSTALL_ROOT' directory"
- return 1
- fi
-
- # download a mini CentOS into a cache
- echo "Downloading CentOS minimal ..."
- YUM0="yum --installroot $INSTALL_ROOT -y --nogpgcheck"
-
- if yum -h | grep -q 'releasever=RELEASEVER'; then
- YUM="$YUM0 --releasever=$release"
- else
- YUM="$YUM0"
- fi
- PKG_LIST="yum initscripts passwd rsyslog vim-minimal openssh-server openssh-clients dhclient chkconfig rootfiles policycoreutils cronie"
-
- # use temporary repository definition
- # always prefer the repo given by the user
- # if no repo given, use mirrorlist.centos.org for i386 and x86_64
- # and http://mirror.centos.org/altarch/ otherwise
- REPO_FILE=$INSTALL_ROOT/etc/yum.repos.d/lxc-centos-temp.repo
- mkdir -p $(dirname $REPO_FILE)
- if [ -n "$repo" ]; then
- cat <<EOF > $REPO_FILE
-[base]
-name=local repository
-baseurl="$repo"
-EOF
- elif [ ${basearch} = 'i386' ] || [ ${basearch} = 'x86_64' ]; then
- cat <<EOF > $REPO_FILE
-[base]
-name=CentOS-$release - Base
-mirrorlist=http://mirrorlist.centos.org/?release=$release&arch=$basearch&repo=os
-
-[updates]
-name=CentOS-$release - Updates
-mirrorlist=http://mirrorlist.centos.org/?release=$release&arch=$basearch&repo=updates
-EOF
- else
- cat <<EOF > $REPO_FILE
-[base]
-name=CentOS-$release - Base
-baseurl=http://mirror.centos.org/altarch/7/os/$basearch/
-
-[updates]
-name=CentOS-$release - Updates
-baseurl=http://mirror.centos.org/altarch/7/updates/$basearch/
-EOF
- fi
-
- # create minimal device nodes, needed for "yum install" and "yum update" process
- mkdir -p $INSTALL_ROOT/dev
- force_mknod 666 $INSTALL_ROOT/dev/null c 1 3
- force_mknod 666 $INSTALL_ROOT/dev/urandom c 1 9
-
- # create /run directory, just in case it is missing (e.g. RHEL7)
- mkdir -p $INSTALL_ROOT/run
-
- $YUM install $PKG_LIST
-
- # create symlink for /var/run -> ../run
- if [ "$release" = "7" ]; then
- mv $INSTALL_ROOT/var/run/* $INSTALL_ROOT/run/
- rmdir $INSTALL_ROOT/var/run
- ln -sf ../run $INSTALL_ROOT/var/run
- fi
-
- if [ $? -ne 0 ]; then
- echo "Failed to download the rootfs, aborting."
- return 1
- fi
-
- # use same nameservers as hosts, needed for "yum update later"
- cp /etc/resolv.conf $INSTALL_ROOT/etc/
-
- # check whether rpmdb is under $HOME
- if [ ! -e $INSTALL_ROOT/var/lib/rpm/Packages -a -e $INSTALL_ROOT/$HOME/.rpmdb/Packages ]; then
- echo "Fixing rpmdb location ..."
- mv $INSTALL_ROOT/$HOME/.rpmdb/[A-Z]* $INSTALL_ROOT/var/lib/rpm/
- rm -rf $INSTALL_ROOT/$HOME/.rpmdb
- chroot $INSTALL_ROOT rpm --rebuilddb 2>/dev/null
- fi
-
- # check whether rpmdb version is correct
- chroot $INSTALL_ROOT rpm --quiet -q yum 2>/dev/null
- ret=$?
-
- # if "rpm -q" doesn't work due to rpmdb version difference,
- # then we need to redo the process using the newly-installed yum
- if [ $ret -gt 0 ]; then
- echo "Reinstalling packages ..."
- mv $REPO_FILE $REPO_FILE.tmp
- mkdir $INSTALL_ROOT/etc/yum.repos.disabled
- mv $INSTALL_ROOT/etc/yum.repos.d/*.repo $INSTALL_ROOT/etc/yum.repos.disabled/
- mv $REPO_FILE.tmp $REPO_FILE
- mkdir -p $INSTALL_ROOT/$INSTALL_ROOT/etc
- cp /etc/resolv.conf $INSTALL_ROOT/$INSTALL_ROOT/etc/
- mkdir -p $INSTALL_ROOT/$INSTALL_ROOT/dev
- mknod -m 666 $INSTALL_ROOT/$INSTALL_ROOT/dev/null c 1 3
- mknod -m 666 $INSTALL_ROOT/$INSTALL_ROOT/dev/urandom c 1 9
- mkdir -p $INSTALL_ROOT/$INSTALL_ROOT/var/cache/yum
- cp -al $INSTALL_ROOT/var/cache/yum/* $INSTALL_ROOT/$INSTALL_ROOT/var/cache/yum/
- chroot $INSTALL_ROOT $YUM0 install $PKG_LIST
- if [ $? -ne 0 ]; then
- echo "Failed to download the rootfs, aborting."
- return 1
- fi
- mv $INSTALL_ROOT/$INSTALL_ROOT $INSTALL_ROOT.tmp
- rm -rf $INSTALL_ROOT
- mv $INSTALL_ROOT.tmp $INSTALL_ROOT
- fi
-
- rm -f $REPO_FILE
- rm -rf $INSTALL_ROOT/var/cache/yum/*
-
- mv "$INSTALL_ROOT" "$cache/rootfs"
- echo "Download complete."
-
- return 0
-}
-
-copy_centos()
-{
-
- # make a local copy of the mini CentOS
- echo -n "Copying rootfs to $rootfs_path ..."
- #cp -a $cache/rootfs-$arch $rootfs_path || return 1
- # i prefer rsync (no reason really)
- mkdir -p $rootfs_path
- rsync -SHaAX $cache/rootfs/ $rootfs_path/
- echo
- return 0
-}
-
-update_centos()
-{
- YUM="chroot $cache/rootfs yum -y --nogpgcheck"
- $YUM update
- if [ $? -ne 0 ]; then
- return 1
- fi
- $YUM clean packages
-}
-
-install_centos()
-{
- mkdir -p /var/lock/subsys/
- (
- flock -x 9
- if [ $? -ne 0 ]; then
- echo "Cache repository is busy."
- return 1
- fi
-
- echo "Checking cache download in $cache/rootfs ... "
- if [ ! -e "$cache/rootfs" ]; then
- download_centos
- if [ $? -ne 0 ]; then
- echo "Failed to download 'CentOS base'"
- return 1
- fi
- else
- echo "Cache found. Updating..."
- update_centos
- if [ $? -ne 0 ]; then
- echo "Failed to update 'CentOS base', continuing with last known good cache"
- else
- echo "Update finished"
- fi
- fi
-
- echo "Copy $cache/rootfs to $rootfs_path ... "
- copy_centos
- if [ $? -ne 0 ]; then
- echo "Failed to copy rootfs"
- return 1
- fi
-
- return 0
-
- ) 9>/var/lock/subsys/lxc-centos
-
- return $?
-}
-
-create_hwaddr()
-{
- openssl rand -hex 5 | sed -e 's/\(..\)/:\1/g; s/^/fe/'
-}
-
-copy_configuration()
-{
- mkdir -p $config_path
-
- grep -q "^lxc.rootfs.path" $config_path/config 2>/dev/null || echo "
-lxc.rootfs.path = $rootfs_path
-" >> $config_path/config
-
- # The following code is to create static MAC addresses for each
- # interface in the container. This code will work for multiple
- # interfaces in the default config.
- mv $config_path/config $config_path/config.def
- while read LINE
- do
- # This should catch variable expansions from the default config...
- if expr "${LINE}" : '.*\$' > /dev/null 2>&1
- then
- LINE=$(eval "echo \"${LINE}\"")
- fi
-
- # There is a tab and a space in the regex bracket below!
- # Seems that \s doesn't work in brackets.
- KEY=$(expr "${LINE}" : '\s*\([^ ]*\)\s*=')
-
- if [[ "${KEY}" != "lxc.net.0.hwaddr" ]]
- then
- echo ${LINE} >> $config_path/config
-
- if [[ "${KEY}" == "lxc.net.0.link" ]]
- then
- echo "lxc.net.0.hwaddr = $(create_hwaddr)" >> $config_path/config
- fi
- fi
- done < $config_path/config.def
-
- rm -f $config_path/config.def
-
- if [ -e "@LXCTEMPLATECONFIG@/centos.common.conf" ]; then
- echo "
-# Include common configuration
-lxc.include = @LXCTEMPLATECONFIG@/centos.common.conf
-" >> $config_path/config
- fi
-
- # Append things which require expansion here...
- cat <<EOF >> $config_path/config
-lxc.arch = $arch
-lxc.uts.name = $utsname
-
-# When using LXC with apparmor, uncomment the next line to run unconfined:
-#lxc.apparmor.profile = unconfined
-
-# example simple networking setup, uncomment to enable
-#lxc.net.0.type = $lxc_network_type
-#lxc.net.0.flags = up
-#lxc.net.0.link = $lxc_network_link
-#lxc.net.0.name = eth0
-# Additional example for veth network type
-# static MAC address,
-#lxc.net.0.hwaddr = 00:16:3e:77:52:20
-# persistent veth device name on host side
-# Note: This may potentially collide with other containers of same name!
-#lxc.net.0.veth.pair = v-$name-e0
-
-EOF
-
- if [ $? -ne 0 ]; then
- echo "Failed to add configuration"
- return 1
- fi
-
- return 0
-}
-
-clean()
-{
-
- if [ ! -e $cache ]; then
- exit 0
- fi
-
- # lock, so we won't purge while someone is creating a repository
- (
- flock -x 9
- if [ $? != 0 ]; then
- echo "Cache repository is busy."
- exit 1
- fi
-
- echo -n "Purging the download cache for CentOS-$release..."
- rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1
- exit 0
-
- ) 9>@LOCALSTATEDIR@/lock/subsys/lxc-centos
-}
-
-usage()
-{
- cat <<EOF
-usage:
- $1 -n|--name=<container_name>
- [-p|--path=<path>] [-c|--clean] [-R|--release=<CentOS_release>] [-a|--arch=<arch of the container>]
- [-h|--help]
-Mandatory args:
- -n,--name container name, used to as an identifier for that container from now on
-Optional args:
- -p,--path path to where the container rootfs will be created, defaults to /var/lib/lxc/name.
- -c,--clean clean the cache
- -R,--release CentOS release for the new container. If the host is CentOS, then it will default to the host's release.
- --fqdn fully qualified domain name (FQDN) for DNS and system naming
- --repo repository to use (url)
- -a,--arch Define what arch the container will be [i686,x86_64]
- -h,--help print this help
-EOF
- return 0
-}
-
-options=$(getopt -o a:hp:n:cR: -l help,path:,rootfs:,name:,clean,release:,repo:,arch:,fqdn: -- "$@")
-if [ $? -ne 0 ]; then
- usage $(basename $0)
- exit 1
-fi
-
-arch=$(uname -m)
-eval set -- "$options"
-while true
-do
- case "$1" in
- -h|--help) usage $0 && exit 0;;
- -p|--path) path=$2; shift 2;;
- --rootfs) rootfs_path=$2; shift 2;;
- -n|--name) name=$2; shift 2;;
- -c|--clean) clean=1; shift 1;;
- -R|--release) release=$2; shift 2;;
- --repo) repo="$2"; shift 2;;
- -a|--arch) newarch=$2; shift 2;;
- --fqdn) utsname=$2; shift 2;;
- --) shift 1; break ;;
- *) break ;;
- esac
-done
-
-if [ ! -z "$clean" -a -z "$path" ]; then
- clean || exit 1
- exit 0
-fi
-
-basearch=${arch}
-# Map a few architectures to their generic CentOS repository archs.
-# The two ARM archs are a bit of a guesstimate for the v5 and v6
-# archs. V6 should have hardware floating point (Rasberry Pi).
-# The "arm" arch is safer (no hardware floating point). So
-# there may be cases where we "get it wrong" for some v6 other
-# than RPi.
-case "$arch" in
-i686) basearch=i386 ;;
-armv3l|armv4l|armv5l) basearch=arm ;;
-armv6l|armv7l|armv8l) basearch=armhfp ;;
-*) ;;
-esac
-
-# Somebody wants to specify an arch. This is very limited case.
-# i386/i586/i686 on i386/x86_64
-# - or -
-# x86_64 on x86_64
-if [ "${newarch}" != "" -a "${newarch}" != "${arch}" ]
-then
- case "${newarch}" in
- i386|i586|i686)
- if [ "${basearch}" = "i386" -o "${basearch}" = "x86_64" ]
- then
- # Make the arch a generic x86 32 bit...
- arch=${newarch}
- basearch=i386
- else
- basearch=bad
- fi
- ;;
- *)
- basearch=bad
- ;;
- esac
-
- if [ "${basearch}" = "bad" ]
- then
- echo "You cannot build a ${newarch} CentOS container on a ${arch} host. Sorry!"
- exit 1
- fi
-fi
-
-# Allow the cache base to be set by environment variable
-cache_base=${LXC_CACHE_PATH:-"@LOCALSTATEDIR@/cache/lxc"}/centos/$basearch
-
-# Let's do something better for the initial root password.
-# It's not perfect but it will defeat common scanning brute force
-# attacks in the case where ssh is exposed. It will also be set to
-# expired, forcing the user to change it at first login.
-if [ "${root_password}" = "" ]
-then
- root_password=Root-${name}-${RANDOM}
-else
- # If it's got a ding in it, try and expand it!
- if [ $(expr "${root_password}" : '.*$.') != 0 ]
- then
- root_password=$(eval echo "${root_password}")
- fi
-
- # If it has more than 3 consecutive X's in it, feed it
- # through mktemp as a template.
- if [ $(expr "${root_password}" : '.*XXXX') != 0 ]
- then
- root_password=$(mktemp -u ${root_password})
- fi
-fi
-
-if [ -z "${utsname}" ]; then
- utsname=${name}
-fi
-
-# This follows a standard "resolver" convention that an FQDN must have
-# at least two dots or it is considered a local relative host name.
-# If it doesn't, append the dns domain name of the host system.
-#
-# This changes one significant behavior when running
-# "lxc_create -n Container_Name" without using the
-# --fqdn option.
-#
-# Old behavior:
-# utsname and hostname = Container_Name
-# New behavior:
-# utsname and hostname = Container_Name.Domain_Name
-
-if [ $(expr "$utsname" : '.*\..*\.') = 0 ]; then
- if [[ "$(dnsdomainname)" != "" && "$(dnsdomainname)" != "localdomain" ]]; then
- utsname=${utsname}.$(dnsdomainname)
- fi
-fi
-
-type yum >/dev/null 2>&1
-if [ $? -ne 0 ]; then
- echo "'yum' command is missing"
- exit 1
-fi
-
-if [ -z "$path" ]; then
- path=$default_path/$name
-fi
-
-if [ -z "$release" ]; then
- if [ "$is_centos" -a "$centos_host_ver" ]; then
- release=$centos_host_ver
- elif [ "$is_redhat" -a "$redhat_host_ver" ]; then
- # This is needed to clean out bullshit like 6workstation and 6server.
- release=$(expr $redhat_host_ver : '\([0-9.]*\)')
- else
- echo "This is not a CentOS or Red Hat host and release is missing, defaulting to 7, use -R|--release to specify release"
- release=7
- fi
-fi
-
-if [ "$(id -u)" != "0" ]; then
- echo "This script should be run as 'root'"
- exit 1
-fi
-
-if [ -z "$rootfs_path" ]; then
- rootfs_path=$path/rootfs
- # check for 'lxc.rootfs.path' passed in through default config by lxc-create
- if grep -q '^lxc.rootfs.path' $path/config 2>/dev/null ; then
- rootfs_path=$(sed -e '/^lxc.rootfs.path\s*=/!d' -e 's/\s*#.*//' \
- -e 's/^lxc.rootfs.path\s*=\s*//' -e q $path/config)
- fi
-fi
-config_path=$path
-cache=$cache_base/$release
-
-revert()
-{
- echo "Interrupted, so cleaning up"
- lxc-destroy -n $name
- # maybe was interrupted before copy config
- rm -rf $path
- echo "exiting..."
- exit 1
-}
-
-trap revert SIGHUP SIGINT SIGTERM
-
-copy_configuration
-if [ $? -ne 0 ]; then
- echo "failed write configuration file"
- exit 1
-fi
-
-install_centos
-if [ $? -ne 0 ]; then
- echo "failed to install CentOS"
- exit 1
-fi
-
-configure_centos
-if [ $? -ne 0 ]; then
- echo "failed to configure CentOS for a container"
- exit 1
-fi
-
-configure_centos_init
-
-if [ ! -z "$clean" ]; then
- clean || exit 1
- exit 0
-fi
-echo "
-Container rootfs and config have been created.
-Edit the config file to check/enable networking setup.
-"
-
-if [ ${root_display_password} = "yes" ]
-then
- echo "The temporary password for root is: '$root_password'
-
-You may want to note that password down before starting the container.
-"
-fi
-
-if [ ${root_store_password} = "yes" ]
-then
- echo "The temporary root password is stored in:
-
- '${config_path}/tmp_root_pass'
-"
-fi
-
-if [ ${root_prompt_password} = "yes" ]
-then
- echo "Invoking the passwd command in the container to set the root password.
-
- chroot ${rootfs_path} passwd
-"
- chroot ${rootfs_path} passwd
-else
- if [ ${root_expire_password} = "yes" ]
- then
- if ( mountpoint -q -- "${rootfs_path}" )
- then
- echo "To reset the root password, you can do:
-
- lxc-start -n ${name}
- lxc-attach -n ${name} -- passwd
- lxc-stop -n ${name}
-"
- else
- echo "
-The root password is set up as "expired" and will require it to be changed
-at first login, which you should do as soon as possible. If you lose the
-root password or wish to change it without starting the container, you
-can change it from the host by running the following command (which will
-also reset the expired flag):
-
- chroot ${rootfs_path} passwd
-"
- fi
- fi
-fi
+++ /dev/null
-#!/bin/bash
-
-# template script for generating ubuntu container for LXC
-#
-# This script consolidates and extends the existing lxc ubuntu scripts
-#
-
-# Copyright © 2013 Canonical Ltd.
-# Author: Scott Moser <scott.moser@canonical.com>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2, as
-# published by the Free Software Foundation.
-
-# This program 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 General Public License for more details.
-
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-# Detect use under userns (unsupported)
-# Make sure the usual locations are in PATH
-export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
-
-VERBOSITY=0
-DOWNLOAD_URL="http://download.cirros-cloud.net/"
-
-UNAME_M=$(uname -m)
-ARCHES=( i386 x86_64 amd64 arm )
-STREAMS=( released devel )
-SOURCES=( nocloud none )
-BUILD="standard"
-LXC_TEMPLATE_CONFIG="@LXCTEMPLATECONFIG@"
-
-LXC_MAPPED_GID=
-LXC_MAPPED_UID=
-
-DEF_VERSION="released"
-DEF_SOURCE="nocloud"
-case "${UNAME_M}" in
- i?86) DEF_ARCH="i386";;
- x86_64) DEF_ARCH="x86_64";;
- arm*) DEF_ARCH="arm";;
- *) DEF_ARCH="i386";;
-esac
-
-am_in_userns() {
- [ -e /proc/self/uid_map ] || { echo no; return; }
- [ "$(wc -l /proc/self/uid_map | awk '{ print $1 }')" -eq 1 ] || { echo yes; return; }
- line=$(awk '{ print $1 " " $2 " " $3 }' /proc/self/uid_map)
- [ "$line" = "0 0 4294967295" ] && { echo no; return; }
- echo yes
-}
-
-in_userns=0
-[ $(am_in_userns) = "yes" ] && in_userns=1
-
-# Allow the cache base to be set by environment variable
-if [ $(id -u) -eq 0 ]; then
- CACHE_D=${LXC_CACHE_PATH:-"@LOCALSTATEDIR@/cache/lxc/cirros"}
-else
- CACHE_D=${LXC_CACHE_PATH:-"$HOME/.cache/lxc/cirros"}
-fi
-
-error() { echo "$@" 1>&2; }
-inargs() {
- local needle="$1" x=""
- shift
- for x in "$@"; do
- [ "$needle" = "$x" ] && return 0
- done
- return 1
-}
-
-Usage() {
- cat <<EOF
-${0##*/} [options]
-
- -a | --arch A architecture to use [${ARCHES[*]}]
- default: ${DEF_ARCH}
- -h | --help this usage
- -v | --verbose increase verbosity
- -S | --auth-key K insert auth key 'K'
- -v | --version V version [${STREAMS[*]}]
- default: ${DEF_VERSION}
- -u | --userdata U user-data file
- --tarball T read from tarball 'T' rather than downloading
- or using cache.
- --source S insert userdata/metadata via source S
- [${SOURCES[*]}]
-EOF
-}
-
-bad_Usage() { Usage 1>&2; [ $# -eq 0 ] || error "$@"; return 1; }
-
-debug() {
- local level=${1}; shift;
- [ "${level}" -gt "${VERBOSITY}" ] && return
- error "${@}"
-}
-jsondict() {
- local k="" v="" ret="{"
- for arg in "$@"; do
- k="${arg%%=*}"
- v="${arg#*=}"
- ret="${ret} \"${k}\": \"$v\","
- done
- ret="${ret%,} }"
- echo "$ret"
-}
-
-copy_configuration()
-{
- local path=$1 rootfs=$2 name=$3 arch=$4 release=$5
-cat >> "$path/config" <<EOF
-# Template used to create this container: cirros
-
-lxc.rootfs.path = $rootfs
-
-lxc.tty.max = 4
-lxc.pty.max = 1024
-
-lxc.uts.name = $name
-lxc.arch = $arch
-lxc.cap.drop = sys_module mac_admin mac_override sys_time
-
-# When using LXC with apparmor, uncomment the next line to run unconfined:
-#lxc.apparmor.profile = unconfined
-lxc.mount.auto = cgroup:mixed proc:mixed sys:mixed
-
-lxc.cgroup.devices.deny = a
-# Allow any mknod (but not using the node)
-lxc.cgroup.devices.allow = c *:* m
-lxc.cgroup.devices.allow = b *:* m
-# /dev/null and zero
-lxc.cgroup.devices.allow = c 1:3 rwm
-lxc.cgroup.devices.allow = c 1:5 rwm
-# consoles
-lxc.cgroup.devices.allow = c 5:1 rwm
-lxc.cgroup.devices.allow = c 5:0 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
-# rtc
-lxc.cgroup.devices.allow = c 254:0 rwm
-# fuse
-lxc.cgroup.devices.allow = c 10:229 rwm
-# tun
-lxc.cgroup.devices.allow = c 10:200 rwm
-# full
-lxc.cgroup.devices.allow = c 1:7 rwm
-# hpet
-lxc.cgroup.devices.allow = c 10:228 rwm
-# kvm
-lxc.cgroup.devices.allow = c 10:232 rwm
-EOF
-
- if [ $in_userns -eq 1 ] && [ -e "${LXC_TEMPLATE_CONFIG}/ubuntu-cloud.userns.conf" ]; then
- echo "lxc.include = ${LXC_TEMPLATE_CONFIG}/ubuntu.userns.conf" >> $path/config
- fi
-
-}
-
-insert_ds_nocloud() {
- local root_d="$1" authkey="$2" udfile="$3"
- local sdir="$root_d/var/lib/cloud/seed/nocloud"
-
- mkdir -p "$sdir" ||
- { error "failed to make datasource dir $sdir"; return 1; }
- rm -f "$sdir/meta-data" "$sdir/user-data" ||
- { error "failed to clean old data from $sdir"; return 1; }
-
- iid="iid-local01"
- jsondict "instance-id=$iid" \
- ${authkeys:+"public-keys=${authkeys}"} > "$sdir/meta-data" ||
- { error "failed to write metadata to $sdir/meta-data"; return 1; }
-
- if [ -n "$udfile" ]; then
- cat "$udfile" > "$sdir/user-data" ||
- { error "failed to write user-data to $sdir"; return 1; }
- else
- rm -f "$sdir/user-data"
- fi
-}
-
-insert_ds() {
- local dstype="$1" root_d="$2" authkey="$3" udfile="$4"
- case "$dstype" in
- nocloud) insert_ds_nocloud "$root_d" "$authkey" "$udfile"
- esac
-}
-
-extract_rootfs() {
- local tarball="$1" rootfs_d="$2"
- mkdir -p "${rootfs_d}" ||
- { error "failed to make rootfs dir ${rootfs_d}"; return 1; }
-
- if [ $in_userns -eq 1 ]; then
- tar -C "${rootfs_d}" --anchored --exclude="dev/*" -Sxzf "${tarball}" ||
- { error "failed to populate ${rootfs_d}"; return 1; }
- else
- tar -C "${rootfs_d}" -Sxzf "${tarball}" ||
- { error "failed to populate ${rootfs_d}"; return 1; }
- fi
- return 0
-}
-
-download_tarball() {
- local arch="$1" ver="$2" cached="$3" baseurl="$4"
- local out="" outd="" file="" dlpath=""
- file="cirros-$ver-$arch-lxc.tar.gz"
- dlpath="$ver/$file"
- outd="${cached}/${dlpath%/*}"
- if [ -f "$cached/$dlpath" ]; then
- _RET="$cached/$dlpath"
- return 0
- fi
-
- mkdir -p "${outd}" ||
- { error "failed to create ${outd}"; return 1; }
-
- debug 1 "downloading ${baseurl%/}/$dlpath" to "${cached}/$dlpath"
- wget "${baseurl%/}/$dlpath" -O "$cached/${dlpath}.$$" &&
- mv "$cached/$dlpath.$$" "$cached/$dlpath" || {
- rm -f "$cached/$dlpath.$$";
- error "failed to download $dlpath";
- return 1;
- }
- _RET="$cached/$dlpath"
-}
-
-create_main() {
- local short_opts="a:hn:p:S:uvV"
- local long_opts="arch:,auth-key:,name:,path:,tarball:,userdata:,verbose,version:,rootfs:,mapped-uid:,mapped-gid:"
- local getopt_out=""
- getopt_out=$(getopt --name "${0##*/}" \
- --options "${short_opts}" --long "${long_opts}" -- "$@") &&
- eval set -- "${getopt_out}" ||
- { bad_Usage; return; }
-
- local arch="${DEF_ARCH}" dsource="${DEF_SOURCE}" version="${DEF_VERSION}"
- local authkey_f="" authkeys="" userdata_f="" path="" tarball=""
- local cur="" next=""
- local rootfs_d=""
-
- while [ $# -ne 0 ]; do
- cur=$1; next=$2;
- case "$cur" in
- -a|--arch) arch="$next"; shift;;
- -h|--help) Usage ; return 0;;
- -n|--name) name="$next"; shift;;
- -v|--verbose) VERBOSITY=$((${VERBOSITY}+1));;
- -S|--auth-key) authkey_f="$next"; shift;;
- -p|--path) path=$next; shift;;
- -v|--version) version=$next; shift;;
- -u|--userdata) userdata_f="$next"; shift;;
- --tarball) tarball="$next"; shift;;
- --source) dsource="$next"; shift;;
- --rootfs) rootfs_d="$next"; shift;;
- --mapped-uid) LXC_MAPPED_UID=$next; shift;;
- --mapped-gid) LXC_MAPPED_GID=$next; shift;;
- --) shift; break;;
- esac
- shift;
- done
-
- [ -n "$rootfs_d" ] || rootfs_d="$path/rootfs"
- [ $# -eq 0 ] || { bad_Usage "unexpected arguments: $*"; return; }
- [ -n "$path" ] || { error "'path' parameter is required"; return 1; }
-
- if [ "$(id -u)" != "0" ]; then
- { error "must be run as root"; return 1; }
- fi
-
- case "$arch" in
- i?86) arch="i386";;
- amd64) arch="x86_64";;
- esac
-
- inargs "$arch" "${ARCHES[@]}" ||
- { error "bad arch '$arch'. allowed: ${ARCHES[*]}"; return 1; }
-
- inargs "$dsource" "${SOURCES[@]}" ||
- { error "bad source '$dsource'. allowed: ${SOURCES[*]}"; return 1; }
-
- if [ "$dsource" = "none" ] && [ -n "$userdata_f" -o -n "$authkey_f" ]; then
- error "userdata and authkey are incompatible with --source=none";
- return 1;
- fi
-
- if [ -n "$authkey_f" ]; then
- if [ ! -f "$authkey_f" ]; then
- error "--auth-key=${authkey_f} must reference a file"
- return 1
- fi
- authkeys=$(cat "$authkey_f") ||
- { error "failed to read ${authkey_f}"; return 1; }
- fi
-
- if [ -n "$userdata_f" -a ! -f "${userdata_f}" ]; then
- error "${userdata_f}: --userdata arg not a file"
- return 1
- fi
-
- if [ -z "$tarball" ]; then
- if inargs "$version" "${STREAMS[@]}"; then
- out=$(wget -O - -q "${DOWNLOAD_URL%/}/version/$version") ||
- { error "failed to convert 'version=$version'"; return 1; }
- version="$out"
- fi
- download_tarball "$arch" "$version" "${CACHE_D}" "${DOWNLOAD_URL}" ||
- return
- tarball="$_RET"
- fi
-
- extract_rootfs "${tarball}" "${rootfs_d}" || return
-
- if [ "$version" = "0.3.2~pre1" ]; then
- debug 1 "fixing console for lxc and '$version'"
- sed -i 's,^\(#console.* 115200 \)# /dev/console,\1 console,g' \
- "$rootfs_d/etc/inittab" ||
- { error "failed to fix console entry for $version"; return 1; }
- fi
-
- if [ "$dsource" != "none" ]; then
- insert_ds "$dsource" "$path/rootfs" "$authkeys" "$userdata_f" || {
- error "failed to insert userdata to $path/rootfs"
- return 1
- }
- fi
-
- copy_configuration "$path" "$path/rootfs" "$name" "$arch" "$release"
- return
-}
-
-create_main "$@"
-
-# vi: ts=4 expandtab
+++ /dev/null
-#!/bin/bash
-
-#
-# lxc: linux Container library
-
-# Authors:
-# Daniel Lezcano <daniel.lezcano@free.fr>
-
-# 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
-
-# Detect use under userns (unsupported)
-for arg in "$@"; do
- [ "$arg" = "--" ] && break
- if [ "$arg" = "--mapped-uid" -o "$arg" = "--mapped-gid" ]; then
- echo "This template can't be used for unprivileged containers." 1>&2
- echo "You may want to try the \"download\" template instead." 1>&2
- exit 1
- fi
-done
-
-# Make sure the usual locations are in PATH
-export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
-export GREP_OPTIONS=""
-
-MIRROR=${MIRROR:-http://deb.debian.org/debian}
-SECURITY_MIRROR=${SECURITY_MIRROR:-http://security.debian.org/}
-LOCALSTATEDIR="@LOCALSTATEDIR@"
-LXC_TEMPLATE_CONFIG="@LXCTEMPLATECONFIG@"
-# Allows the lxc-cache directory to be set by environment variable
-LXC_CACHE_PATH=${LXC_CACHE_PATH:-"$LOCALSTATEDIR/cache/lxc"}
-
-find_interpreter()
-{
- given_interpreter=$(basename "$1")
-
- if [ ! -d /proc/sys/fs/binfmt_misc/ ] ; then
- return 1
- fi
- for file in /proc/sys/fs/binfmt_misc/* ; do
- if [ "$file" = "/proc/sys/fs/binfmt_misc/register" -o \
- "$file" = "/proc/sys/fs/binfmt_misc/status" ] ; then
- continue
- fi
- interpreter_path=$(sed -n "/^interpreter/s/interpreter \([^[:space:]]*\)/\1/p" "$file")
- interpreter=$(basename "$interpreter_path")
-
- if [ "$given_interpreter" = "$interpreter" ] ; then
- echo "$interpreter_path"
- return 0
- fi
- done
- return 1
-}
-
-configure_debian()
-{
- rootfs=$1
- hostname=$2
- num_tty=$3
-
- # squeeze only has /dev/tty and /dev/tty0 by default,
- # therefore creating missing device nodes for tty1-4.
- for tty in $(seq 1 "$num_tty"); 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:3: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
-$(for tty in $(seq 1 "$num_tty"); do echo "c${tty}:12345:respawn:/sbin/getty 38400 tty${tty} linux" ; done;)
-p6::ctrlaltdel:/sbin/init 6
-p0::powerfail:/sbin/init 0
-EOF
-
- # symlink mtab
- [ -e "$rootfs/etc/mtab" ] && rm "$rootfs/etc/mtab"
- ln -s /proc/self/mounts "$rootfs/etc/mtab"
-
- # 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
-
- # but first reconfigure locales - so we get no noisy perl-warnings
- if [ -z "$LANG" ] || echo $LANG | grep -E -q "^C(\..+)*$"; then
- cat >> "$rootfs/etc/locale.gen" << EOF
-en_US.UTF-8 UTF-8
-EOF
- chroot "$rootfs" locale-gen en_US.UTF-8 UTF-8
- chroot "$rootfs" update-locale LANG=en_US.UTF-8
- else
- encoding=$(echo "$LANG" | cut -d. -f2)
- chroot "$rootfs" sed -e "s/^# \(${LANG} ${encoding}\)/\1/" \
- -i /etc/locale.gen 2> /dev/null
- cat >> "$rootfs/etc/locale.gen" << EOF
-$LANG $encoding
-EOF
- chroot "$rootfs" locale-gen "$LANG" "$encoding"
- chroot "$rootfs" update-locale LANG="$LANG"
- fi
-
- # remove pointless services in a container
- chroot "$rootfs" /usr/sbin/update-rc.d -f checkroot.sh disable
- chroot "$rootfs" /usr/sbin/update-rc.d -f umountfs disable
- chroot "$rootfs" /usr/sbin/update-rc.d -f hwclock.sh disable
- chroot "$rootfs" /usr/sbin/update-rc.d -f hwclockfirst.sh disable
-
- # generate new SSH keys
- if [ -x "$rootfs/var/lib/dpkg/info/openssh-server.postinst" ]; then
- cat > "$rootfs/usr/sbin/policy-rc.d" << EOF
-#!/bin/sh
-exit 101
-EOF
- chmod +x "$rootfs/usr/sbin/policy-rc.d"
-
- if [ -f "$rootfs/etc/init/ssh.conf" ]; then
- mv "$rootfs/etc/init/ssh.conf" "$rootfs/etc/init/ssh.conf.disabled"
- fi
-
- rm -f "$rootfs/etc/ssh/"ssh_host_*key*
-
- DPKG_MAINTSCRIPT_PACKAGE=openssh DPKG_MAINTSCRIPT_NAME=postinst chroot "$rootfs" /var/lib/dpkg/info/openssh-server.postinst configure
- sed -i "s/root@$(hostname)/root@$hostname/g" "$rootfs/etc/ssh/"ssh_host_*.pub
-
- if [ -f "$rootfs/etc/init/ssh.conf.disabled" ]; then
- mv "$rootfs/etc/init/ssh.conf.disabled" "$rootfs/etc/init/ssh.conf"
- fi
-
- rm -f "$rootfs/usr/sbin/policy-rc.d"
- fi
-
- # set initial timezone as on host
- if [ -f /etc/timezone ]; then
- cat /etc/timezone > "$rootfs/etc/timezone"
- chroot "$rootfs" dpkg-reconfigure -f noninteractive tzdata
- elif [ -f /etc/sysconfig/clock ]; then
- . /etc/sysconfig/clock
- echo "$ZONE" > "$rootfs/etc/timezone"
- chroot "$rootfs" dpkg-reconfigure -f noninteractive tzdata
- else
- echo "Timezone in container is not configured. Adjust it manually."
- fi
-
- if [ -n "$authkey" ]; then
- local ssh_dir_path="${rootfs}/root/.ssh"
- mkdir -p "$ssh_dir_path"
- cp "$authkey" "${ssh_dir_path}/authorized_keys"
- chmod 700 "$ssh_dir_path"
- echo "Inserted SSH public key from '$authkey' into /root/.ssh/authorized_keys"
- fi
-
- return 0
-}
-
-write_sourceslist()
-{
- local rootfs="$1"; shift
- local release="$1"; shift
- local arch="$1"; shift
-
- local prefix="deb"
- if [ -n "${arch}" ]; then
- prefix="deb [arch=${arch}]"
- fi
-
- if [ "$mainonly" = 1 ]; then
- non_main=''
- else
- non_main=' contrib non-free'
- fi
-
- cat >> "${rootfs}/etc/apt/sources.list" << EOF
-${prefix} $MIRROR ${release} main${non_main}
-EOF
-
- if [ "$release" != "unstable" -a "$release" != "sid" ]; then
- cat >> "${rootfs}/etc/apt/sources.list" << EOF
-${prefix} $SECURITY_MIRROR ${release}/updates main${non_main}
-EOF
- fi
-}
-
-install_packages()
-{
- local rootfs="$1"; shift
- local packages="$*"
-
- chroot "${rootfs}" apt-get update
- if [ -n "${packages}" ]; then
- chroot "${rootfs}" apt-get install --force-yes -y --no-install-recommends ${packages}
- fi
-}
-
-configure_debian_systemd()
-{
- path=$1
- rootfs=$2
- config=$3
- num_tty=$4
-
- # just in case systemd is not installed
- mkdir -p "${rootfs}/lib/systemd/system"
- mkdir -p "${rootfs}/etc/systemd/system/getty.target.wants"
-
- # Fix getty-static-service as debootstrap does not install dbus
- if [ -e "$rootfs//lib/systemd/system/getty-static.service" ] ; then
- local tty_services
- tty_services=$(for i in $(seq 2 "$num_tty"); do echo -n "getty@tty${i}.service "; done; )
- sed 's/ getty@tty.*/'" $tty_services "'/g' \
- "$rootfs/lib/systemd/system/getty-static.service" | \
- sed 's/\(tty2-tty\)[5-9]/\1'"${num_tty}"'/g' > "$rootfs/etc/systemd/system/getty-static.service"
- fi
-
- # This function has been copied and adapted from lxc-fedora
- rm -f "${rootfs}/etc/systemd/system/default.target"
- chroot "${rootfs}" ln -s /dev/null /etc/systemd/system/udev.service
- chroot "${rootfs}" ln -s /dev/null /etc/systemd/system/systemd-udevd.service
- chroot "${rootfs}" ln -s /lib/systemd/system/multi-user.target /etc/systemd/system/default.target
- # Setup getty service on the ttys we are going to allow in the
- # default config. Number should match lxc.tty.max
- ( cd "${rootfs}/etc/systemd/system/getty.target.wants"
- for i in $(seq 1 "$num_tty") ; do ln -sf ../getty\@.service getty@tty"${i}".service; done )
-
- # Since we use static-getty.target; we need to mask container-getty@.service generated by
- # container-getty-generator, so we don't get multiple instances of agetty running.
- # See https://github.com/lxc/lxc/issues/520 and https://github.com/lxc/lxc/issues/484
- ( cd "${rootfs}/etc/systemd/system/getty.target.wants"
- for i in $(seq 0 "$num_tty"); do ln -sf /dev/null container-getty\@"${i}".service; done )
-
- return 0
-}
-
-# Check if given path is in a btrfs partition
-is_btrfs()
-{
- [ -e "$1" -a "$(stat -f -c '%T' "$1")" = "btrfs" ]
-}
-
-# Check if given path is the root of a btrfs subvolume
-is_btrfs_subvolume()
-{
- [ -d "$1" -a "$(stat -f -c '%T' "$1")" = "btrfs" -a "$(stat -c '%i' "$1")" -eq 256 ]
-}
-
-try_mksubvolume()
-{
- path=$1
- [ -d "$path" ] && return 0
- mkdir -p "$(dirname "$path")"
- if which btrfs >/dev/null 2>&1 && is_btrfs "$(dirname "$path")"; then
- btrfs subvolume create "$path"
- else
- mkdir -p "$path"
- fi
-}
-
-try_rmsubvolume()
-{
- path=$1
- [ -d "$path" ] || return 0
- if which btrfs >/dev/null 2>&1 && is_btrfs_subvolume "$path"; then
- btrfs subvolume delete "$path"
- else
- rm -rf "$path"
- fi
-}
-
-cleanup()
-{
- try_rmsubvolume "$cache/partial-$release-$arch"
- try_rmsubvolume "$cache/rootfs-$release-$arch"
-}
-
-download_debian()
-{
- case "$release" in
- wheezy)
- init=sysvinit
- iproute=iproute
- ;;
- *)
- init=init
- iproute=iproute2
- ;;
- esac
- packages=\
-$init,\
-ifupdown,\
-locales,\
-dialog,\
-isc-dhcp-client,\
-netbase,\
-net-tools,\
-$iproute,\
-openssh-server
-
- cache=$1
- arch=$2
- release=$3
- interpreter="$4"
- interpreter_path="$5"
-
- trap cleanup EXIT SIGHUP SIGINT SIGTERM
-
- # Create the cache
- mkdir -p "$cache"
-
- # If debian-archive-keyring isn't installed, fetch GPG keys directly
- releasekeyring=/usr/share/keyrings/debian-archive-keyring.gpg
- if [ ! -f $releasekeyring ]; then
- releasekeyring="$cache/archive-key.gpg"
- case $release in
- "wheezy")
- gpgkeyname="archive-key-7.0"
- ;;
- *)
- gpgkeyname="archive-key-8"
- ;;
- esac
- wget https://ftp-master.debian.org/keys/${gpgkeyname}.asc -O - --quiet \
- | gpg --import --no-default-keyring --keyring="${releasekeyring}"
- fi
- # check the mini debian was not already downloaded
- try_mksubvolume "$cache/partial-$release-$arch"
- if [ $? -ne 0 ]; then
- echo "Failed to create '$cache/partial-$release-$arch' directory"
- return 1
- fi
-
- # download a mini debian into a cache
- echo "Downloading debian minimal ..."
- if [ "$interpreter" = "" ] ; then
- debootstrap --verbose --variant=minbase --arch="$arch" \
- --include=$packages --keyring="${releasekeyring}" \
- "$release" "$cache/partial-$release-$arch" "$MIRROR"
- if [ $? -ne 0 ]; then
- echo "Failed to download the rootfs, aborting."
- return 1
- fi
- else
- debootstrap --foreign --verbose --variant=minbase --arch="$arch" \
- --include=$packages --keyring="${releasekeyring}" \
- "$release" "$cache/partial-$release-$arch" "$MIRROR"
- if [ $? -ne 0 ]; then
- echo "Failed to download the rootfs, aborting."
- return 1
- fi
- mkdir -p "$(basename "$cache/partial-$release-$arch/$interpreter_path")"
- cp "$interpreter" "$cache/partial-$release-$arch/$interpreter_path"
- if [ $? -ne 0 ]; then
- echo "failed to copy $interpreter to $cache/partial-$release-$arch/$interpreter_path"
- return 1
- fi
- chroot "$cache/partial-$release-$arch" debootstrap/debootstrap --second-stage
- if [ $? -ne 0 ]; then
- echo "failed to update the rootfs, aborting"
- return 1
- fi
- fi
-
- mv "$1/partial-$release-$arch" "$1/rootfs-$release-$arch"
- echo "Download complete."
- trap EXIT
- trap SIGINT
- trap SIGTERM
- trap SIGHUP
-
- return 0
-}
-
-copy_debian()
-{
- cache=$1
- arch=$2
- rootfs=$3
- release=$4
-
- # make a local copy of the minidebian
- echo -n "Copying rootfs to $rootfs..."
- try_mksubvolume "$rootfs"
- if which btrfs >/dev/null 2>&1 && \
- is_btrfs_subvolume "$cache/rootfs-$release-$arch" && \
- is_btrfs_subvolume "$rootfs"; then
- realrootfs="$(dirname "$config")"/rootfs
- [ "$rootfs" = "$realrootfs" ] || umount "$rootfs" || return 1
- btrfs subvolume delete "$realrootfs" || return 1
- btrfs subvolume snapshot "$cache/rootfs-$release-$arch" "$realrootfs" || return 1
- [ "$rootfs" = "$realrootfs" ] || mount --bind "$realrootfs" "$rootfs" || return 1
- else
- rsync -SHaAX "$cache/rootfs-$release-$arch"/ $rootfs/ || return 1
- fi
- return 0
-}
-
-install_debian()
-{
- rootfs=$1
- release=$2
- arch=$3
- cache="$4/debian"
- interpreter="$5"
- interpreter_path="$6"
- flushcache=$7
- mkdir -p $LOCALSTATEDIR/lock/subsys/
- (
- flock -x 9
- if [ $? -ne 0 ]; then
- echo "Cache repository is busy."
- return 1
- fi
-
- if [ "$flushcache" -eq 1 ]; then
- echo "Flushing cache..."
- cleanup
- fi
-
- echo "Checking cache download in $cache/rootfs-$release-$arch ... "
- if [ ! -e "$cache/rootfs-$release-$arch" ]; then
- download_debian "$cache" "$arch" "$release" "$interpreter" "$interpreter_path"
- if [ $? -ne 0 ]; then
- echo "Failed to download 'debian base'"
- return 1
- fi
- fi
-
- copy_debian "$cache" "$arch" "$rootfs" "$release"
- if [ $? -ne 0 ]; then
- echo "Failed to copy rootfs"
- return 1
- fi
-
- return 0
-
- ) 9>$LOCALSTATEDIR/lock/subsys/lxc-debian
-
- return $?
-}
-
-copy_configuration()
-{
- path=$1
- rootfs=$2
- hostname=$3
- arch=$4
- num_tty=$5
-
- # Generate the configuration file
- # if there is exactly one veth network entry, make sure it has an
- # associated hwaddr.
- nics=$(grep -ce '^lxc\.net\.0\.type[ \t]*=[ \t]*veth' "$path/config")
- if [ "$nics" -eq 1 ]; then
- grep -q "^lxc.net.0.hwaddr" "$path/config" || sed -i -e "/^lxc\.net\.0\.type[ \t]*=[ \t]*veth/a lxc.net.0.hwaddr = 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//')" "$path/config"
- fi
-
- ## Add all the includes
- echo "" >> "$path/config"
- echo "# Common configuration" >> "$path/config"
- if [ -e "${LXC_TEMPLATE_CONFIG}/debian.common.conf" ]; then
- echo "lxc.include = ${LXC_TEMPLATE_CONFIG}/debian.common.conf" >> "$path/config"
- fi
- if [ -e "${LXC_TEMPLATE_CONFIG}/debian.${release}.conf" ]; then
- echo "lxc.include = ${LXC_TEMPLATE_CONFIG}/debian.${release}.conf" >> "$path/config"
- fi
-
- ## Add the container-specific config
- echo "" >> "$path/config"
- echo "# Container specific configuration" >> "$path/config"
- grep -q "^lxc.rootfs.path" "$path/config" 2> /dev/null || echo "lxc.rootfs.path = $rootfs" >> "$path/config"
-
- cat <<EOF >> $path/config
-lxc.tty.max = $num_tty
-lxc.uts.name = $hostname
-lxc.arch = $arch
-lxc.pty.max = 1024
-EOF
-
- if [ $? -ne 0 ]; then
- echo "Failed to add configuration"
- return 1
- fi
-
- return 0
-}
-
-post_process()
-{
- local rootfs="$1"; shift
- local release="$1"; shift
- local arch="$1"; shift
- local hostarch="$1"; shift
- local interpreter="$1"; shift
- local packages="$*"
-
- # Disable service startup
- cat > "${rootfs}/usr/sbin/policy-rc.d" << EOF
-#!/bin/sh
-exit 101
-EOF
- chmod +x "${rootfs}/usr/sbin/policy-rc.d"
-
- # If the container isn't running a native architecture, setup multiarch
- if [ "$interpreter" = "" -a "${arch}" != "${hostarch}" ]; then
- # Test if dpkg supports multiarch
- if ! chroot "$rootfs" dpkg --print-foreign-architectures 2>&1; then
- chroot "$rootfs" dpkg --add-architecture "${hostarch}"
- fi
- fi
-
- # Write a new sources.list containing both native and multiarch entries
- > "${rootfs}/etc/apt/sources.list"
- if [ "$interpreter" != "" -a "${arch}" = "${hostarch}" ]; then
- write_sourceslist "${rootfs}" "${release}" "${arch}"
- else
- write_sourceslist "${rootfs}" "${release}"
- fi
-
- # Install Packages in container
- if [ -n "${packages}" ]; then
- local pack_list
- pack_list="${packages//,/ }"
- echo "Installing packages: ${pack_list}"
- install_packages "${rootfs}" "${pack_list}"
- fi
-
- # Re-enable service startup
- rm "${rootfs}/usr/sbin/policy-rc.d"
-
- # end
-}
-
-clean()
-{
- cache=${LXC_CACHE_PATH:-"$LOCALSTATEDIR/cache/lxc/debian"}
-
- if [ ! -e "$cache" ]; then
- exit 0
- fi
-
- # lock, so we won't purge while someone is creating a repository
- (
- flock -x 9
- 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
-
- ) 9>$LOCALSTATEDIR/lock/subsys/lxc-debian
-}
-
-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]
-
-Usage: $1 -h|--help -p|--path=<path> [-c|--clean] [-a|--arch=<arch>] [-r|--release=<release>]
- [--mirror=<mirror>] [--security-mirror=<security mirror>]
- [--package=<package_name1,package_name2,...>]
- [-I|--interpreter-path=<interpreter path>]
- [-F | --flush-cache] [-S|--auth-key=<keyfile>]
-
-Options :
-
- -h, --help print this help text
- -p, --path=PATH directory where config and rootfs of this VM will be kept
- -S, --auth-key=KEYFILE SSH public key to inject into the container as the root user.
- -a, --arch=ARCH The container architecture. Can be one of: i686, x86_64,
- amd64, armhf, armel, powerpc. Defaults to host arch.
- -r, --release=RELEASE Debian release. Can be one of: wheezy, jessie, stretch, buster, sid.
- Defaults to current stable.
- --mirror=MIRROR Debian mirror to use during installation. Overrides the MIRROR
- environment variable (see below).
- --security-mirror=SECURITY_MIRROR
- Debian mirror to use for security updates. Overrides the
- SECURITY_MIRROR environment variable (see below).
- --packages=PACKAGE_NAME1,PACKAGE_NAME2,...
- List of additional packages to install. Comma separated, without space.
- -c, --clean only clean up the cache and terminate
- --enable-non-free include also Debian's contrib and non-free repositories.
- -I|--interpreter-path=INTERPRETER-PATH
- Path of the binfmt interpreter to copy to the rootfs
- -F | --flush-cache Flush the debian release cache
-
-Environment variables:
-
- MIRROR The Debian package mirror to use. See also the --mirror switch above.
- Defaults to '$MIRROR'
- SECURITY_MIRROR The Debian package security mirror to use. See also the --security-mirror switch above.
- Defaults to '$SECURITY_MIRROR'
-
-EOF
- return 0
-}
-
-options=$(getopt -o hp:n:a:r:cI:FS: -l arch:,auth-key:,clean,help,enable-non-free,mirror:,name:,packages:,path:,release:,rootfs:,security-mirror:,interpreter-path:,flush-cache -- "$@")
-if [ $? -ne 0 ]; then
- usage "$(basename "$0")"
- exit 1
-fi
-eval set -- "$options"
-
-littleendian=$(lscpu | grep '^Byte Order' | grep -q Little && echo yes)
-
-arch=$(uname -m)
-if [ "$arch" = "i686" ]; then
- arch="i386"
-elif [ "$arch" = "x86_64" ]; then
- arch="amd64"
-elif [ "$arch" = "armv7l" ]; then
- arch="armhf"
-elif [ "$arch" = "aarch64" ]; then
- arch="arm64"
-elif [ "$arch" = "ppc" ]; then
- arch="powerpc"
-elif [ "$arch" = "ppc64le" ]; then
- arch="ppc64el"
-elif [ "$arch" = "mips" -a "$littleendian" = "yes" ]; then
- arch="mipsel"
-elif [ "$arch" = "mips64" -a "$littleendian" = "yes" ]; then
- arch="mips64el"
-fi
-hostarch=$arch
-mainonly=1
-flushcache=0
-
-while true
-do
- case "$1" in
- -h|--help) usage "$0" && exit 1;;
- --) shift 1; break ;;
-
- -a|--arch) arch=$2; shift 2;;
- -S|--auth-key) authkey=$2; shift 2;;
- -I|--interpreter-path)
- interpreter="$2"; shift 2;;
- -c|--clean) clean=1; shift 1;;
- --enable-non-free) mainonly=0; shift 1;;
- --mirror) MIRROR=$2; shift 2;;
- -n|--name) name=$2; shift 2;;
- --packages) packages=$2; shift 2;;
- -p|--path) path=$2; shift 2;;
- -r|--release) release=$2; shift 2;;
- --rootfs) rootfs=$2; shift 2;;
- --security-mirror) SECURITY_MIRROR=$2; shift 2;;
- -F|--flush-cache) flushcache=1; shift 1;;
- *) break ;;
- esac
-done
-
-if [ ! -z "$clean" -a -z "$path" ]; then
- clean || exit 1
- exit 0
-fi
-
-if [ "$arch" = "i686" ]; then
- arch=i386
-fi
-
-if [ "$arch" = "x86_64" ]; then
- arch=amd64
-fi
-
-if [ "$interpreter" = "" ] ; then
- if [ $hostarch = "i386" -a $arch = "amd64" ]; then
- echo "can't create $arch container on $hostarch"
- exit 1
- fi
-
- if [ $hostarch = "armhf" -o $hostarch = "armel" ] && \
- [ $arch != "armhf" -a $arch != "armel" ]; then
- echo "can't create $arch container on $hostarch"
- exit 1
- fi
-
- if [ $hostarch = "powerpc" -a $arch != "powerpc" ]; then
- echo "can't create $arch container on $hostarch"
- exit 1
- fi
-
- if [ $hostarch = "mips" -a $arch != "mips" ] || \
- [ $hostarch = "mipsel" -a $arch != "mipsel" ] || \
- [ $hostarch = "mips64" -a $arch != "mips" -a $arch != "mips64" ] || \
- [ $hostarch = "mips64el" -a $arch != "mipsel" -a $arch != "mips64el" ]; then
- echo "can't create $arch container on $hostarch"
- exit 1
- fi
-else
- if ! file -b "${interpreter}" |grep -q "statically linked" ; then
- echo "'${interpreter}' must be statically linked" 1>&2
- exit 1
- fi
- interpreter_path=$(find_interpreter "$interpreter")
- if [ $? -ne 0 ] ; then
- echo "no binfmt interpreter using $(basename "$interpreter")" 1>&2
- exit 1
- fi
-fi
-
-type debootstrap
-if [ $? -ne 0 ]; then
- echo "'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
-
-if [ -n "$authkey" ]; then
- if [ ! -f "$authkey" ]; then
- echo "SSH keyfile '$authkey' not found"
- exit 1
- fi
- # This is mostly to prevent accidental uage of the private key instead
- # of the public key.
- if [ "${authkey: -4}" != ".pub" ]; then
- echo "SSH keyfile '$authkey' does not end with '.pub'"
- exit 1
- fi
-fi
-
-release=${release:-stable}
-permanent_releases=('stable' 'testing' 'sid' 'unstable')
-if [[ ! "${permanent_releases[*]}" =~ (^|[^[:alpha:]])$release([^[:alpha:]]|$) ]]; then
- if ! wget "${MIRROR}/dists/${release}/Release" -O /dev/null 2> /dev/null; then
- echo "Invalid release ${release} (not found in mirror)"
- exit 1
- fi
-fi
-
-# detect rootfs
-config="$path/config"
-if [ -z "$rootfs" ]; then
- if grep -q '^lxc.rootfs.path' "$config" 2> /dev/null ; then
- rootfs=$(awk -F= '/^lxc.rootfs.path[ \t]+=/{ print $2 }' "$config")
- else
- rootfs=$path/rootfs
- fi
-fi
-
-# determine the number of ttys - default is 4
-if grep -q '^lxc.tty.max' "$config" 2> /dev/null ; then
- num_tty=$(awk -F= '/^lxc.tty.max[ \t]+=/{ print $2 }' "$config")
-else
- num_tty=4
-fi
-
-install_debian "$rootfs" "$release" "$arch" "$LXC_CACHE_PATH" "$interpreter" "$interpreter_path" "$flushcache"
-if [ $? -ne 0 ]; then
- echo "failed to install debian"
- exit 1
-fi
-
-configure_debian "$rootfs" "$name" $num_tty
-if [ $? -ne 0 ]; then
- echo "failed to configure debian for a container"
- exit 1
-fi
-
-copy_configuration "$path" "$rootfs" "$name" $arch $num_tty
-if [ $? -ne 0 ]; then
- echo "failed write configuration file"
- exit 1
-fi
-
-configure_debian_systemd "$path" "$rootfs" "$config" $num_tty
-
-post_process "${rootfs}" "${release}" ${arch} ${hostarch} "${interpreter}" "${packages}"
-
-if [ ! -z "$clean" ]; then
- clean || exit 1
- exit 0
-fi
+++ /dev/null
-#!/bin/bash
-
-#
-# template script for generating fedora container for LXC
-#
-
-#
-# lxc: linux Container library
-
-# Authors:
-# Daniel Lezcano <daniel.lezcano@free.fr>
-# Ramez Hanna <rhanna@informatiq.org>
-# Michael H. Warfield <mhw@WittsEnd.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
-
-#Configurations
-default_path=@LXCPATH@
-
-# Some combinations of the tuning knobs below do not exactly make sense.
-# but that's ok.
-#
-# If the "root_password" is non-blank, use it, else set a default.
-# This can be passed to the script as an environment variable and is
-# set by a shell conditional assignment. Looks weird but it is what it is.
-#
-# If the root password contains a ding ($) then try to expand it.
-# That will pick up things like ${name} and ${RANDOM}.
-# If the root password contains more than 3 consecutive X's, pass it as
-# a template to mktemp and take the result.
-#
-# If root_display_password = yes, display the temporary root password at exit.
-# If root_store_password = yes, store it in the configuration directory
-# If root_prompt_password = yes, invoke "passwd" to force the user to change
-# the root password after the container is created.
-# If root_expire_password = yes, you will be prompted to change the root
-# password at the first login.
-#
-# These are conditional assignments... The can be overridden from the
-# preexisting environment variables...
-#
-# Make sure this is in single quotes to defer expansion to later!
-# :{root_password='Root-${name}-${RANDOM}'}
-: ${root_password='Root-${name}-XXXXXX'}
-
-# Now, it doesn't make much sense to display, store, and force change
-# together. But, we gotta test, right???
-: ${root_display_password='no'}
-: ${root_store_password='yes'}
-# Prompting for something interactive has potential for mayhem
-# with users running under the API... Don't default to "yes"
-: ${root_prompt_password='no'}
-
-# Expire root password? Default to yes, but can be overridden from
-# the environment variable
-: ${root_expire_password='yes'}
-
-# These are only going into comments in the resulting config...
-lxc_network_type=veth
-lxc_network_link=lxcbr0
-
-# is this fedora?
-# Alow for weird remixes like the Raspberry Pi
-#
-# Use the Mitre standard CPE identifier for the release ID if possible...
-# This may be in /etc/os-release or /etc/system-release-cpe. We
-# should be able to use EITHER. Give preference to /etc/os-release for now.
-
-# Detect use under userns (unsupported)
-for arg in "$@"; do
- [ "$arg" = "--" ] && break
- if [ "$arg" = "--mapped-uid" -o "$arg" = "--mapped-gid" ]; then
- echo "This template can't be used for unprivileged containers." 1>&2
- echo "You may want to try the \"download\" template instead." 1>&2
- exit 1
- fi
-done
-
-# Make sure the usual locations are in PATH
-export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
-
-if [ -e /etc/os-release ]
-then
-# This is a shell friendly configuration file. We can just source it.
-# What we're looking for in here is the ID, VERSION_ID and the CPE_NAME
- . /etc/os-release
- echo "Host CPE ID from /etc/os-release: ${CPE_NAME}"
-fi
-
-if [ "${CPE_NAME}" = "" -a -e /etc/system-release-cpe ]
-then
- CPE_NAME=$(head -n1 /etc/system-release-cpe)
- CPE_URI=$(expr ${CPE_NAME} : '\([^:]*:[^:]*\)')
- if [ "${CPE_URI}" != "cpe:/o" ]
- then
- CPE_NAME=
- else
- echo "Host CPE ID from /etc/system-release-cpe: ${CPE_NAME}"
- # Probably a better way to do this but sill remain posix
- # compatible but this works, shrug...
- # Must be nice and not introduce convenient bashisms here.
- ID=$(expr ${CPE_NAME} : '[^:]*:[^:]*:[^:]*:\([^:]*\)')
- VERSION_ID=$(expr ${CPE_NAME} : '[^:]*:[^:]*:[^:]*:[^:]*:\([^:]*\)')
- fi
-fi
-
-if [ "${CPE_NAME}" != "" -a "${ID}" = "fedora" -a "${VERSION_ID}" != "" ]
-then
- fedora_host_ver=${VERSION_ID}
- is_fedora=true
-elif [ -e /etc/redhat-release ]
-then
- # Only if all other methods fail, try to parse the redhat-release file.
- fedora_host_ver=$( sed -e '/^Fedora /!d' -e 's/Fedora.*\srelease\s*\([0-9][0-9]*\)\s.*/\1/' < /etc/redhat-release )
- if [ "$fedora_host_ver" != "" ]
- then
- is_fedora=true
- fi
-fi
-
-configure_fedora()
-{
-
- # disable selinux in fedora
- mkdir -p $rootfs_path/selinux
- echo 0 > $rootfs_path/selinux/enforce
-
- # Also kill it in the /etc/selinux/config file if it's there...
- if [[ -f $rootfs_path/etc/selinux/config ]]
- then
- sed -i '/^SELINUX=/s/.*/SELINUX=disabled/' $rootfs_path/etc/selinux/config
- fi
-
- # Nice catch from Dwight Engen in the Oracle template.
- # Wantonly plagerized here with much appreciation.
- if [ -f $rootfs_path/usr/sbin/selinuxenabled ]; then
- mv $rootfs_path/usr/sbin/selinuxenabled $rootfs_path/usr/sbin/selinuxenabled.lxcorig
- ln -s /bin/false $rootfs_path/usr/sbin/selinuxenabled
- fi
-
- # This is a known problem and documented in RedHat bugzilla as relating
- # to a problem with auditing enabled. This prevents an error in
- # the container "Cannot make/remove an entry for the specified session"
- sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs_path}/etc/pam.d/login
- sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs_path}/etc/pam.d/sshd
-
- if [ -f ${rootfs_path}/etc/pam.d/crond ]
- then
- sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs_path}/etc/pam.d/crond
- fi
-
- # In addition to disabling pam_loginuid in the above config files
- # we'll also disable it by linking it to pam_permit to catch any
- # we missed or any that get installed after the container is built.
- #
- # Catch either or both 32 and 64 bit archs.
- if [ -f ${rootfs_path}/lib/security/pam_loginuid.so ]
- then
- ( cd ${rootfs_path}/lib/security/
- mv pam_loginuid.so pam_loginuid.so.disabled
- ln -s pam_permit.so pam_loginuid.so
- )
- fi
-
- if [ -f ${rootfs_path}/lib64/security/pam_loginuid.so ]
- then
- ( cd ${rootfs_path}/lib64/security/
- mv pam_loginuid.so pam_loginuid.so.disabled
- ln -s pam_permit.so pam_loginuid.so
- )
- fi
-
- # Set default localtime to the host localtime if not set...
- if [ -e /etc/localtime -a ! -e ${rootfs_path}/etc/localtime ]
- then
- # if /etc/localtime is a symlink, this should preserve it.
- cp -a /etc/localtime ${rootfs_path}/etc/localtime
- fi
-
- # Deal with some dain bramage in the /etc/init.d/halt script.
- # Trim it and make it our own and link it in before the default
- # halt script so we can intercept it. This also preventions package
- # updates from interferring with our interferring with it.
- #
- # There's generally not much in the halt script that useful but what's
- # in there from resetting the hardware clock down is generally very bad.
- # So we just eliminate the whole bottom half of that script in making
- # ourselves a copy. That way a major update to the init scripts won't
- # trash what we've set up.
- #
- # This is mostly for legacy distros since any modern systemd Fedora
- # release will not have this script so we won't try to intercept it.
- if [ -f ${rootfs_path}/etc/init.d/halt ]
- then
- sed -e '/hwclock/,$d' \
- < ${rootfs_path}/etc/init.d/halt \
- > ${rootfs_path}/etc/init.d/lxc-halt
-
- echo '$command -f' >> ${rootfs_path}/etc/init.d/lxc-halt
- chmod 755 ${rootfs_path}/etc/init.d/lxc-halt
-
- # Link them into the rc directories...
- (
- cd ${rootfs_path}/etc/rc.d/rc0.d
- ln -s ../init.d/lxc-halt S00lxc-halt
- cd ${rootfs_path}/etc/rc.d/rc6.d
- ln -s ../init.d/lxc-halt S00lxc-reboot
- )
- fi
-
- # configure the network using the dhcp
- cat <<EOF > ${rootfs_path}/etc/sysconfig/network-scripts/ifcfg-eth0
-DEVICE=eth0
-BOOTPROTO=dhcp
-ONBOOT=yes
-HOSTNAME=${utsname}
-DHCP_HOSTNAME=\`hostname\`
-NM_CONTROLLED=no
-TYPE=Ethernet
-MTU=${MTU}
-EOF
-
- # set the hostname
- cat <<EOF > ${rootfs_path}/etc/sysconfig/network
-NETWORKING=yes
-HOSTNAME=${utsname}
-EOF
-
- # set hostname on systemd Fedora systems
- if [ $release -gt 14 ]; then
- echo "${utsname}" > ${rootfs_path}/etc/hostname
- fi
-
- # set minimal hosts
- cat <<EOF > $rootfs_path/etc/hosts
-127.0.0.1 localhost.localdomain localhost $utsname
-::1 localhost6.localdomain6 localhost6
-EOF
-
- # These mknod's really don't make any sense with modern releases of
- # Fedora with systemd, devtmpfs, and autodev enabled. They are left
- # here for legacy reasons and older releases with upstart and sysv init.
- dev_path="${rootfs_path}/dev"
- rm -rf $dev_path
- mkdir -p $dev_path
- mknod -m 666 ${dev_path}/null c 1 3
- mknod -m 666 ${dev_path}/zero c 1 5
- mknod -m 666 ${dev_path}/random c 1 8
- mknod -m 666 ${dev_path}/urandom c 1 9
- mkdir -m 755 ${dev_path}/pts
- mkdir -m 1777 ${dev_path}/shm
- mknod -m 666 ${dev_path}/tty c 5 0
- mknod -m 666 ${dev_path}/tty0 c 4 0
- mknod -m 666 ${dev_path}/tty1 c 4 1
- mknod -m 666 ${dev_path}/tty2 c 4 2
- mknod -m 666 ${dev_path}/tty3 c 4 3
- mknod -m 666 ${dev_path}/tty4 c 4 4
- mknod -m 600 ${dev_path}/console c 5 1
- mknod -m 666 ${dev_path}/full c 1 7
- mknod -m 600 ${dev_path}/initctl p
- mknod -m 666 ${dev_path}/ptmx c 5 2
-
- # setup console and tty[1-4] for login. note that /dev/console and
- # /dev/tty[1-4] will be symlinks to the ptys /dev/lxc/console and
- # /dev/lxc/tty[1-4] so that package updates can overwrite the symlinks.
- # lxc will maintain these links and bind mount ptys over /dev/lxc/*
- # since lxc.tty.dir is specified in the config.
-
- # allow root login on console, tty[1-4], and pts/0 for libvirt
- echo "# LXC (Linux Containers)" >>${rootfs_path}/etc/securetty
- echo "lxc/console" >>${rootfs_path}/etc/securetty
- echo "lxc/tty1" >>${rootfs_path}/etc/securetty
- echo "lxc/tty2" >>${rootfs_path}/etc/securetty
- echo "lxc/tty3" >>${rootfs_path}/etc/securetty
- echo "lxc/tty4" >>${rootfs_path}/etc/securetty
- echo "# For libvirt/Virtual Machine Monitor" >>${rootfs_path}/etc/securetty
- echo "pts/0" >>${rootfs_path}/etc/securetty
-
- if [ ${root_display_password} = "yes" ]
- then
- echo "Setting root password to '$root_password'"
- fi
- if [ ${root_store_password} = "yes" ]
- then
- touch ${config_path}/tmp_root_pass
- chmod 600 ${config_path}/tmp_root_pass
- echo ${root_password} > ${config_path}/tmp_root_pass
- echo "Storing root password in '${config_path}/tmp_root_pass'"
- fi
-
- echo "root:$root_password" | chroot $rootfs_path chpasswd
-
- if [ ${root_expire_password} = "yes" ]
- then
- # Also set this password as expired to force the user to change it!
- chroot $rootfs_path passwd -e root
- fi
-
- # specifying this in the initial packages doesn't always work.
- # Even though it should have...
- echo "installing fedora-release package"
- mount -o bind /dev ${rootfs_path}/dev
- mount -t proc proc ${rootfs_path}/proc
- # Always make sure /etc/resolv.conf is up to date in the target!
- cp /etc/resolv.conf ${rootfs_path}/etc/
- # Rebuild the rpm database based on the target rpm version...
- rm -f ${rootfs_path}/var/lib/rpm/__db*
- chroot ${rootfs_path} rpm --rebuilddb
- chroot ${rootfs_path} yum -y install fedora-release
-
- if [[ ! -e ${rootfs_path}/sbin/NetworkManager ]]
- then
- # NetworkManager has not been installed. Use the
- # legacy chkconfig command to enable the network startup
- # scripts in the container.
- chroot ${rootfs_path} chkconfig network on
- fi
-
- umount ${rootfs_path}/proc
- umount ${rootfs_path}/dev
-
- # silence some needless startup errors
- touch ${rootfs_path}/etc/fstab
-
- # give us a console on /dev/console
- sed -i 's/ACTIVE_CONSOLES=.*$/ACTIVE_CONSOLES="\/dev\/console \/dev\/tty[1-4]"/' \
- ${rootfs_path}/etc/sysconfig/init
-
- return 0
-}
-
-configure_fedora_init()
-{
- sed -i 's|.sbin.start_udev||' ${rootfs_path}/etc/rc.sysinit
- sed -i 's|.sbin.start_udev||' ${rootfs_path}/etc/rc.d/rc.sysinit
- # don't mount devpts, for pete's sake
- sed -i 's/^.*dev.pts.*$/#\0/' ${rootfs_path}/etc/rc.sysinit
- sed -i 's/^.*dev.pts.*$/#\0/' ${rootfs_path}/etc/rc.d/rc.sysinit
- chroot ${rootfs_path} chkconfig udev-post off
- chroot ${rootfs_path} chkconfig network on
-
- if [ -d ${rootfs_path}/etc/init ]
- then
- # This is to make upstart honor SIGPWR. Should do no harm
- # on systemd systems and some systems may have both.
- cat <<EOF >${rootfs_path}/etc/init/power-status-changed.conf
-# power-status-changed - shutdown on SIGPWR
-#
-start on power-status-changed
-
-exec /sbin/shutdown -h now "SIGPWR received"
-EOF
- fi
-}
-
-configure_fedora_systemd()
-{
- rm -f ${rootfs_path}/etc/systemd/system/default.target
- touch ${rootfs_path}/etc/fstab
- chroot ${rootfs_path} ln -s /dev/null /etc/systemd/system/udev.service
- chroot ${rootfs_path} ln -s /lib/systemd/system/multi-user.target /etc/systemd/system/default.target
- # Make systemd honor SIGPWR
- chroot ${rootfs_path} ln -s /usr/lib/systemd/system/halt.target /etc/systemd/system/sigpwr.target
-
- # if desired, prevent systemd from over-mounting /tmp with tmpfs
- if [ $masktmp -eq 1 ]; then
- chroot ${rootfs_path} ln -s /dev/null /etc/systemd/system/tmp.mount
- fi
-
- #dependency on a device unit fails it specially that we disabled udev
- # sed -i 's/After=dev-%i.device/After=/' ${rootfs_path}/lib/systemd/system/getty\@.service
- #
- # Actually, the After=dev-%i.device line does not appear in the
- # Fedora 17 or Fedora 18 systemd getty\@.service file. It may be left
- # over from an earlier version and it's not doing any harm. We do need
- # to disable the "ConditionalPathExists=/dev/tty0" line or no gettys are
- # started on the ttys in the container. Lets do it in an override copy of
- # the service so it can still pass rpm verifies and not be automatically
- # updated by a new systemd version. -- mhw /\/\|=mhw=|\/\/
-
- sed -e 's/^ConditionPathExists=/# ConditionPathExists=/' \
- -e 's/After=dev-%i.device/After=/' \
- < ${rootfs_path}/lib/systemd/system/getty\@.service \
- > ${rootfs_path}/etc/systemd/system/getty\@.service
- # Setup getty service on the 4 ttys we are going to allow in the
- # default config. Number should match lxc.tty
- ( cd ${rootfs_path}/etc/systemd/system/getty.target.wants
- for i in 1 2 3 4 ; do ln -sf ../getty\@.service getty@tty${i}.service; done )
-}
-
-### BEGIN Bootstrap Environment Code... Michael H. Warfield /\/\|=mhw=|\/\/
-
-# Ok... Heads up. If you're reading these comments, you're either a
-# template owner or someone wondering how the hell I did this (or, worse,
-# someone in the future trying to maintain it). This code is slightly
-# "evil coding bastard" code with one significant hack / dirty trick
-# that you would probably miss just reading the code below. I'll mark
-# it out with comments.
-#
-# Because of what this code does, it deserves a lot of comments so people
-# can understand WHY I did it this way...
-#
-# Ultimate Objective - Build a Fedora container on a host system which does
-# not have a (complete compatible) version of rpm and/or yum. That basically
-# means damn near any distro other than Fedora and Ubuntu (which has rpm and
-# yum available). Only requirements for this function are rsync and
-# squashfs available to the kernel. If you don't have those, why are you
-# even attempting to build containers?
-#
-# Challenge for this function - Bootstrap a Fedora install bootstrap
-# run time environment which has all the pieces to run rpm and yum and
-# from which we can build targets containers even where the host system
-# has no support for rpm, yum, or fedora.
-#
-# Steps:
-# Stage 0 - Download a Fedora LiveOS squashfs core (netinst core).
-# Stage 1 - Extract filesystem from Stage 0 and update to full rpm & yum
-# Stage 2 - Use Stage 1 to build a rootfs with python, rpm, and yum.
-#
-# Stage 2 becomes our bootstrap file system which can be cached
-# and then used to build other arbitrary vesions of Fedora of a
-# given architecture. Note that this only has to run once for
-# Fedora on a given architecture since rpm and yum can build other
-# versions. We'll arbitrarily pick Fedora 20 to build this. This
-# will need to change as time goes on.
-
-# Programmers Note... A future fall back may be to download the netinst
-# iso image instead of the LiveOS squasfs image and work from that.
-# That may be more general but will introduce another substep
-# (mounting the iso) to the stage0 setup.
-
-# This system is designed to be as autonomous as possible so all whitelists
-# and controls are self-contained.
-
-# Initial testing - Whitelist nobody. Build for everybody...
-# Initial deployment - Whitelist Fedora.
-# Long term - Whitelist Fedora, Debian, Ubuntu, CentOs, Scientific, and NST.
-
-# List of distros which do not (should not) need a bootstrap (but we will test
-# for rpm and yum none the less... OS SHOULD be taken from CPE values but
-# Debian / Ubuntu doesn't support CPE yet.
-
-# BOOTSTRAP_WHITE_LIST=""
-BOOTSTRAP_WHITE_LIST="fedora"
-# BOOTSTRAP_WHITE_LIST="fedora debian ubuntu centos scientific sl nst"
-
-BOOTSTRAP=0
-BOOTSTRAP_DIR=
-BOOTSTRAP_CHROOT=
-
-fedora_get_bootstrap()
-{
- echo "Bootstrap Environment testing..."
-
- WHITE_LISTED=1
-
- # We need rpm. No rpm - not possible to white list...
- if ! which rpm > /dev/null 2>&1
- then
- WHITE_LISTED=0
- fi
-
- # We need yum No yum - not possible to white list...
- if ! which yum > /dev/null 2>&1
- then
- WHITE_LISTED=0
- fi
-
- if [[ ${WHITE_LISTED} != 0 ]]
- then
- for OS in ${BOOTSTRAP_WHITE_LIST}
- do
- if [[ ${ID} = ${OS} ]]
- then
- echo "
-OS ${ID} is whitelisted. Installation Bootstrap Environment not required.
-"
- return 0;
- fi
- done
- fi
-
- echo "
-Fedora Installation Bootstrap Build..."
-
- if ! which rsync > /dev/null 2>&1
- then
- echo "
-Unable to locate rsync. Cravely bailing out before even attempting to build
-an Installation Bootstrap Please install rsync and then rerun this process.
-"
-
- return 255
- fi
-
- [[ -d ${cache_base} ]] || mkdir -p ${cache_base}
-
- cd ${cache_base}
-
- # We know we don't have a cache directory of this version or we
- # would have never reached this code to begin with. But we may
- # have another Fedora cache directory from which we could run...
- # We'll give a preference for close matches preferring higher over
- # lower - which makes for really ugly code...
-
- # Is this a "bashism" that will need cleaning up????
- BOOTSTRAP_LIST="$(( $release + 1 ))/rootfs $(( $release - 1 ))/rootfs \
-$(( $release + 2 ))/rootfs $(( $release - 2 ))/rootfs \
-$(( $release + 3 ))/rootfs $(( $release - 3 ))/rootfs \
-bootstrap"
-
- for bootstrap in ${BOOTSTRAP_LIST}
- do
- if [[ -d ${bootstrap} ]]
- then
- echo "
-Existing Bootstrap found. Testing..."
-
- mount -o bind /dev ${bootstrap}/dev
- mount -t proc proc ${bootstrap}/proc
- # Always make sure /etc/resolv.conf is up to date in the target!
- cp /etc/resolv.conf ${bootstrap}/etc/
- rm -f ${bootstrap}/var/lib/rpm/__db*
- chroot ${bootstrap} rpm --rebuilddb
- chroot ${bootstrap} yum -y update
- RC=$?
- umount ${bootstrap}/proc
- umount ${bootstrap}/dev
-
- if [[ 0 == ${RC} ]]
- then
- BOOTSTRAP=1
- BOOTSTRAP_DIR="${cache_base}/${bootstrap}"
- BOOTSTRAP_CHROOT="chroot ${BOOTSTRAP_DIR} "
- BOOTSTRAP_INSTALL_ROOT=/run/install
-
- echo "
-Functional Installation Bootstrap exists and appears to be completed.
-Will use existing Bootstrap: ${BOOTSTRAP_DIR}
-"
- return 0
- fi
- echo "
-Installation Bootstrap in ${BOOTSTRAP_DIR} exists
-but appears to be non-functional. Skipping... It should be removed.
-"
- fi
- done
-
- TMP_BOOTSTRAP_DIR=$( mktemp -d --tmpdir=${cache_base} bootstrap_XXXXXX )
-
- cd ${TMP_BOOTSTRAP_DIR}
-
- mkdir squashfs stage0 stage1 bootstrap
-
-### Stage 0 setup.
-# Download the LiveOS squashfs image
-# mount image to "squashfs"
-# mount contained LiveOS to stage0
-
-# We're going to use the archives.fedoraproject.org mirror for the initial stages...
-# 1 - It's generally up to date and complete
-# 2 - It's has high bandwidth access
-# 3 - It supports rsync and wildcarding (and we need both)
-# 4 - Not all the mirrors carry the LiveOS images
-
- if [[ ! -f ../LiveOS/squashfs.img ]]
- then
- echo "
-Downloading stage 0 LiveOS squashfs file system from archives.fedoraproject.org...
-Have a beer or a cup of coffee. This will take a bit (~300MB).
-"
- sleep 3 # let him read it...
-
- # Right now, we are using Fedora 20 for the inial bootstrap.
- # We could make this the "current" Fedora rev (F > 15).
-
- rsync -av ${mirrorurl}/fedora/linux/releases/20/Fedora/$basearch/os/LiveOS .
-
- if [[ 0 == $? ]]
- then
- echo "Download of squashfs image complete."
- mv LiveOS ..
- else
- echo "
-Download of squashfs image failed.
-"
- return 255
- fi
- else
- echo "Using cached stage 0 LiveOS squashfs file system."
- fi
-
- mount -o loop ../LiveOS/squashfs.img squashfs
-
- if [[ $? != 0 ]]
- then
- echo "
-Mount of LiveOS squashfs image failed! You mush have squashfs support
-available to mount image. Unable to continue. Correct and retry
-process later! LiveOS image not removed. Process may be rerun
-without penalty of downloading LiveOS again. If LiveOS is corrupt,
-remove ${cache_base}/LiveOS before rerunning to redownload.
-"
- return 255
- fi
-
- mount -o loop squashfs/LiveOS/rootfs.img stage0
-
- if [[ $? != 0 ]]
- then
- echo "
-Mount of LiveOS stage0 rootfs image failed! LiveOS download may be corrupt.
-Remove ${cache_base}/LiveOS to force a new download or
-troubleshoot cached image and then rerun process.
-"
- return 255
- fi
-
-
-### Stage 1 setup.
-# Copy stage0 (which is ro) to stage1 area (rw) for modification.
-# Unmount stage0 mounts - we're done with stage 0 at this point.
-# Download our rpm and yum rpm packages.
-# Force install of rpm and yum into stage1 image (dirty hack!)
-
- echo "Stage 0 complete, building Stage 1 image...
-This will take a couple of minutes. Patience..."
-
- echo "Creating Stage 1 r/w copy of r/o Stage 0 squashfs image from LiveOS."
-
- rsync -aAHS stage0/. stage1/
-
- umount stage0
- umount squashfs
-
- cd stage1
-
- # Setup stage1 image with pieces to run installs...
-
-
- mount -o bind /dev dev
- mount -t proc proc proc
- # Always make sure /etc/resolv.conf is up to date in the target!
- cp /etc/resolv.conf etc/
-
- mkdir run/install
-
- echo "Updating Stage 1 image with full rpm and yum packages"
-
- # Retrieve our 2 rpm packages we need to force down the throat
- # of this LiveOS image we're camped out on. This is the beginning
- # of the butt ugly hack. Look close or you may missing it...
-
- rsync -av ${mirrorurl}/fedora/linux/releases/20/Fedora/$basearch/os/Packages/r/rpm-[0-9]* \
- ${mirrorurl}/fedora/linux/releases/20/Fedora/$basearch/os/Packages/y/yum-[0-9]* .
-
- # And here it is...
- # The --nodeps is STUPID but F15 had a bogus dependency on RawHide?!?!
- chroot . rpm -ivh --nodeps rpm-* yum-*
- # Did you catch it?
-
- # The LiveOS image contains rpm (but not rpmdb) and yum (but not
- # yummain.py - What the hell good does yum do with no
- # yummain.py?!?! - Sigh...). It contains all the supporting
- # pieces but the rpm database has not be initialized and it
- # doesn't know all the dependences (seem to) have been met.
- # So we do a "--nodeps" rpm install in the chrooted environment
- # to force the installation of the full rpm and yum packages.
- #
- # For the purists - Yes, I know the rpm database is wildly out
- # of whack now. That's why this is a butt ugly hack / dirty trick.
- # But, this is just the stage1 image that we are going to discard as
- # soon as the stage2 image is built, so we don't care. All we care
- # is that the stage2 image ends up with all the pieces it need to
- # run yum and rpm and that the stage2 rpm database is coherent.
- #
- # NOW we can really go to work!
-
-### Stage 2 setup.
-# Download our Fedora Release rpm packages.
-# Install fedora-release into bootstrap to initialize fs and databases.
-# Install rpm, and yum into bootstrap image using yum
-
- echo "Stage 1 creation complete. Building stage 2 Installation Bootstrap"
-
- mount -o bind ../bootstrap run/install
- rsync -av ${mirrorurl}/fedora/linux/releases/20/Fedora/$basearch/os/Packages/f/fedora-release-20* .
-
- # The --nodeps is STUPID but F15 had a bogus dependency on RawHide?!?!
- chroot . rpm --root /run/install --nodeps -ivh fedora-release-*
-
- # yum will take $basearch from host, so force the arch we want
- sed -i "s|\$basearch|$basearch|" ./run/install/etc/yum.repos.d/*
-
- chroot . yum -y --nogpgcheck --installroot /run/install install python rpm yum
-
- umount run/install
- umount proc
- umount dev
-
-# That's it! We should now have a viable installation BOOTSTRAP in
-# bootstrap We'll do a yum update in that to verify and then
-# move it to the cache location before cleaning up.
-
- cd ../bootstrap
- mount -o bind /dev dev
- mount -t proc proc proc
- # Always make sure /etc/resolv.conf is up to date in the target!
- cp /etc/resolv.conf etc/
-
- # yum will take $basearch from host, so force the arch we want
- sed -i "s|\$basearch|$basearch|" ./etc/yum.repos.d/*
-
- chroot . yum -y update
-
- RC=$?
-
- umount proc
- umount dev
-
- cd ..
-
- if [[ ${RC} != 0 ]]
- then
- echo "
-Build of Installation Bootstrap failed. Temp directory
-not removed so it can be investigated.
-"
- return 255
- fi
-
- # We know have a working run time environment in rootfs...
- mv bootstrap ..
- cd ..
- rm -rf ${TMP_BOOTSTRAP_DIR}
-
- echo "
-Build of Installation Bootstrap complete! We now return you to your
-normally scheduled template creation.
-"
-
- BOOTSTRAP=1
- BOOTSTRAP_DIR="${cache_base}/bootstrap"
- BOOTSTRAP_CHROOT="chroot ${BOOTSTRAP_DIR} "
- BOOTSTRAP_INSTALL_ROOT=/run/install
-
- return 0
-}
-
-
-fedora_bootstrap_mounts()
-{
- if [[ ${BOOTSTRAP} -ne 1 ]]
- then
- return 0
- fi
-
- BOOTSTRAP_CHROOT="chroot ${BOOTSTRAP_DIR} "
-
- echo "Mounting Bootstrap mount points"
-
- [[ -d ${BOOTSTRAP_DIR}/run/install ]] || mkdir -p ${BOOTSTRAP_DIR}/run/install
-
- mount -o bind ${INSTALL_ROOT} ${BOOTSTRAP_DIR}/run/install
- mount -o bind /dev ${BOOTSTRAP_DIR}/dev
- mount -t proc proc ${BOOTSTRAP_DIR}/proc
- # Always make sure /etc/resolv.conf is up to date in the target!
- cp /etc/resolv.conf ${BOOTSTRAP_DIR}/etc/
-}
-
-fedora_bootstrap_umounts()
-{
- if [[ ${BOOTSTRAP} -ne 1 ]]
- then
- return 0
- fi
-
- umount ${BOOTSTRAP_DIR}/proc
- umount ${BOOTSTRAP_DIR}/dev
- umount ${BOOTSTRAP_DIR}/run/install
-}
-
-
-# This is the code to create the initial roofs for Fedora. It may
-# require a run time environment by calling the routines above...
-
-download_fedora()
-{
-
- # check the mini fedora was not already downloaded
- INSTALL_ROOT=$cache/partial
- mkdir -p $INSTALL_ROOT
- if [ $? -ne 0 ]; then
- echo "Failed to create '$INSTALL_ROOT' directory"
- return 1
- fi
-
- # download a mini fedora into a cache
- echo "Downloading fedora minimal ..."
-
- # These will get changed if it's decided that we need a
- # boostrap environment (can not build natively). These
- # are the defaults for the non-boostrap (native) mode.
-
- BOOTSTRAP_INSTALL_ROOT=${INSTALL_ROOT}
- BOOTSTRAP_CHROOT=
- BOOTSTRAP_DIR=
-
- PKG_LIST="yum initscripts passwd rsyslog vim-minimal openssh-server openssh-clients dhclient chkconfig rootfiles policycoreutils fedora-release"
- MIRRORLIST_URL="http://mirrors.fedoraproject.org/mirrorlist?repo=fedora-$release&arch=$basearch"
-
- if [[ ${release} -lt 17 ]]
- then
- # The reflects the move of db_dump and db_load from db4_utils to
- # libdb_utils in Fedora 17 and above and it's inclusion as a dep...
- # Prior to Fedora 11, we need to explicitly include it!
- PKG_LIST="${PKG_LIST} db4-utils"
- fi
-
- if [[ ${release} -ge 21 ]]
- then
- # Since Fedora 21, a separate fedora-repos package is needed.
- # Before, the information was conained in fedora-release.
- PKG_LIST="${PKG_LIST} fedora-repos"
- fi
-
- DOWNLOAD_OK=no
-
- # We're splitting the old loop into two loops plus a directory retrival.
- # First loop... Try and retrive a mirror list with retries and a slight
- # delay between attempts...
- for trynumber in 1 2 3 4; do
- [ $trynumber != 1 ] && echo "Trying again..."
- # This code is mildly "brittle" in that it assumes a certain
- # page format and parsing HTML. I've done worse. :-P
- MIRROR_URLS=$(curl -s -S -f "$MIRRORLIST_URL" | sed -e '/^http:/!d' -e '2,6!d')
- if [ $? -eq 0 ] && [ -n "$MIRROR_URLS" ]
- then
- break
- fi
-
- echo "Failed to get a mirror on try $trynumber"
- sleep 3
- done
-
- # This will fall through if we didn't get any URLS above
- for MIRROR_URL in ${MIRROR_URLS}
- do
- if [ "$release" -gt "16" ]; then
- RELEASE_URL="$MIRROR_URL/Packages/f"
- else
- RELEASE_URL="$MIRROR_URL/Packages/"
- fi
-
- echo "Fetching release rpm name from $RELEASE_URL..."
- # This code is mildly "brittle" in that it assumes a certain directory
- # page format and parsing HTML. I've done worse. :-P
- RELEASE_RPM=$(curl -L -f "$RELEASE_URL" | sed -e "/fedora-release-${release}-/!d" -e 's/.*<a href=\"//' -e 's/\">.*//' )
- if [ $? -ne 0 -o "${RELEASE_RPM}" = "" ]; then
- echo "Failed to identify fedora release rpm."
- continue
- fi
-
- echo "Fetching fedora release rpm from ${RELEASE_URL}/${RELEASE_RPM}......"
- curl -L -f "${RELEASE_URL}/${RELEASE_RPM}" > ${INSTALL_ROOT}/${RELEASE_RPM}
- if [ $? -ne 0 ]; then
- echo "Failed to download fedora release rpm ${RELEASE_RPM}."
- continue
- fi
-
- # F21 and newer need fedora-repos in addition to fedora-release.
- if [ "$release" -ge "21" ]; then
- echo "Fetching repos rpm name from $RELEASE_URL..."
- REPOS_RPM=$(curl -L -f "$RELEASE_URL" | sed -e "/fedora-repos-${release}-/!d" -e 's/.*<a href=\"//' -e 's/\">.*//' )
- if [ $? -ne 0 -o "${REPOS_RPM}" = "" ]; then
- echo "Failed to identify fedora repos rpm."
- continue
- fi
-
- echo "Fetching fedora repos rpm from ${RELEASE_URL}/${REPOS_RPM}..."
- curl -L -f "${RELEASE_URL}/${REPOS_RPM}" > ${INSTALL_ROOT}/${REPOS_RPM}
- if [ $? -ne 0 ]; then
- echo "Failed to download fedora repos rpm ${RELEASE_RPM}."
- continue
- fi
- fi
-
-
- DOWNLOAD_OK=yes
- break
- done
-
- if [ $DOWNLOAD_OK != yes ]; then
- echo "Aborting"
- return 1
- fi
-
- mkdir -p ${INSTALL_ROOT}/var/lib/rpm
-
- if ! fedora_get_bootstrap
- then
- echo "Fedora Bootstrap setup failed"
- return 1
- fi
-
- fedora_bootstrap_mounts
-
- ${BOOTSTRAP_CHROOT}rpm --root ${BOOTSTRAP_INSTALL_ROOT} --initdb
-
- # The --nodeps is STUPID but F15 had a bogus dependency on RawHide?!?!
- ${BOOTSTRAP_CHROOT}rpm --root ${BOOTSTRAP_INSTALL_ROOT} --nodeps -ivh ${BOOTSTRAP_INSTALL_ROOT}/${RELEASE_RPM}
-
- # F21 and newer need fedora-repos in addition to fedora-release...
- # Note that fedora-release and fedora-system have a mutual dependency.
- # So installing the reops package after the release package we can
- # spare one --nodeps.
- if [ "$release" -ge "21" ]; then
- ${BOOTSTRAP_CHROOT}rpm --root ${BOOTSTRAP_INSTALL_ROOT} -ivh ${BOOTSTRAP_INSTALL_ROOT}/${REPOS_RPM}
- fi
-
- # yum will take $basearch from host, so force the arch we want
- sed -i "s|\$basearch|$basearch|" ${BOOTSTRAP_DIR}/${BOOTSTRAP_INSTALL_ROOT}/etc/yum.repos.d/*
-
- ${BOOTSTRAP_CHROOT}yum --installroot ${BOOTSTRAP_INSTALL_ROOT} -y --nogpgcheck install ${PKG_LIST}
-
- RC=$?
-
- if [[ ${BOOTSTRAP} -eq 1 ]]
- then
- # Here we have a bit of a sticky problem. We MIGHT have just installed
- # this template cache using versions of yum and rpm in the bootstrap
- # chroot that use a different database version than the target version.
- # That can be a very big problem. Solution is to rebuild the rpmdatabase
- # with the target database now that we are done building the cache. In the
- # vast majority of cases, this is a do-not-care with no harm done if we
- # didn't do it. But it catches several corner cases with older unsupported
- # releases and it really doesn't cost us a lot of time for a one shot
- # install that will never be done again for this rev.
- #
- # Thanks and appreciation to Dwight Engen and the Oracle template for the
- # database rewrite hint!
-
- echo "Fixing up rpm databases"
-
- # Change to our target install directory (if we're not already
- # there) just to simplify some of the logic to follow...
- cd ${INSTALL_ROOT}
-
- rm -f var/lib/rpm/__db*
- # Programmers Note (warning):
- #
- # Pay careful attention to the following commands! It
- # crosses TWO chroot boundaries linked by a bind mount!
- # In the bootstrap case, that's the bind mount of ${INSTALL_ROOT}
- # to the ${BOOTSTRAP_CHROOT}/run/install directory! This is
- # a deliberate hack across that bind mount to do a database
- # translation between two environments, neither of which may
- # be the host environment! It's ugly and hard to follow but,
- # if you don't understand it, don't mess with it! The pipe
- # is in host space between the two chrooted environments!
- # This is also why we cd'ed into the INSTALL_ROOT directory
- # in advance of this loop, so everything is relative to the
- # current working directory and congruent with the same working
- # space in both chrooted environments. The output into the new
- # db is also done in INSTALL_ROOT space but works in either host
- # space or INSTALL_ROOT space for the mv, so we don't care. It's
- # just not obvious what's happening in the db_dump and db_load
- # commands...
- #
- for db in var/lib/rpm/* ; do
- ${BOOTSTRAP_CHROOT} db_dump ${BOOTSTRAP_INSTALL_ROOT}/$db | chroot . db_load $db.new
- mv $db.new $db
- done
- # finish up by rebuilding the database...
- # This should be redundant but we do it for completeness and
- # any corner cases I may have missed...
- mount -t proc proc proc
- mount -o bind /dev dev
- chroot . rpm --rebuilddb
- umount dev
- umount proc
- fi
-
- fedora_bootstrap_umounts
-
- if [ ${RC} -ne 0 ]; then
- echo "Failed to download the rootfs, aborting."
- return 1
- fi
-
- mv "$INSTALL_ROOT" "$cache/rootfs"
- echo "Download complete."
-
- return 0
-}
-
-copy_fedora()
-{
-
- # make a local copy of the minifedora
- echo -n "Copying rootfs to $rootfs_path ..."
- #cp -a $cache/rootfs-$basearch $rootfs_path || return 1
- # i prefer rsync (no reason really)
- mkdir -p $rootfs_path
- rsync -SHaAX $cache/rootfs/ $rootfs_path/
- echo
- return 0
-}
-
-update_fedora()
-{
- mount -o bind /dev ${cache}/rootfs/dev
- mount -t proc proc ${cache}/rootfs/proc
- # Always make sure /etc/resolv.conf is up to date in the target!
- cp /etc/resolv.conf ${cache}/rootfs/etc/
- chroot ${cache}/rootfs yum -y update
- umount ${cache}/rootfs/proc
- umount ${cache}/rootfs/dev
-}
-
-install_fedora()
-{
- mkdir -p @LOCALSTATEDIR@/lock/subsys/
- (
- flock -x 9
- if [ $? -ne 0 ]; then
- echo "Cache repository is busy."
- return 1
- fi
-
- echo "Checking cache download in $cache/rootfs ... "
- if [ ! -e "$cache/rootfs" ]; then
- download_fedora
- if [ $? -ne 0 ]; then
- echo "Failed to download 'fedora base'"
- return 1
- fi
- else
- echo "Cache found. Updating..."
- update_fedora
- if [ $? -ne 0 ]; then
- echo "Failed to update 'fedora base', continuing with last known good cache"
- else
- echo "Update finished"
- fi
- fi
-
- echo "Copy $cache/rootfs to $rootfs_path ... "
- copy_fedora
- if [ $? -ne 0 ]; then
- echo "Failed to copy rootfs"
- return 1
- fi
-
- return 0
- ) 9>@LOCALSTATEDIR@/lock/subsys/lxc-fedora
-
- return $?
-}
-
-# Generate a random hardware (MAC) address composed of FE followed by
-# 5 random bytes...
-create_hwaddr()
-{
- openssl rand -hex 5 | sed -e 's/\(..\)/:\1/g; s/^/fe/'
-}
-
-copy_configuration()
-{
- mkdir -p $config_path
-
- grep -q "^lxc.rootfs.path" $config_path/config 2>/dev/null || echo "
-lxc.rootfs.path = $rootfs_path
-" >> $config_path/config
-
- # The following code is to create static MAC addresses for each
- # interface in the container. This code will work for multiple
- # interfaces in the default config. It will also strip any
- # hwaddr stanzas out of the default config since we can not share
- # MAC addresses between containers.
- mv $config_path/config $config_path/config.def
- while read LINE
- do
- # This should catch variable expansions from the default config...
- if expr "${LINE}" : '.*\$' > /dev/null 2>&1
- then
- LINE=$(eval "echo \"${LINE}\"")
- fi
-
- # There is a tab and a space in the regex bracket below!
- # Seems that \s doesn't work in brackets.
- KEY=$(expr "${LINE}" : '\s*\([^ ]*\)\s*=')
-
- if [[ "${KEY}" != "lxc.net.0.hwaddr" ]]
- then
- echo "${LINE}" >> $config_path/config
-
- if [[ "${KEY}" == "lxc.net.0.link" ]]
- then
- echo "lxc.net.0.hwaddr = $(create_hwaddr)" >> $config_path/config
- fi
- fi
- done < $config_path/config.def
-
- rm -f $config_path/config.def
-
- if [ -e "@LXCTEMPLATECONFIG@/fedora.common.conf" ]; then
- echo "
-# Include common configuration
-lxc.include = @LXCTEMPLATECONFIG@/fedora.common.conf
-" >> $config_path/config
- fi
-
- # Append things which require expansion here...
- cat <<EOF >> $config_path/config
-lxc.arch = $arch
-lxc.uts.name = $utsname
-
-# When using LXC with apparmor, uncomment the next line to run unconfined:
-#lxc.apparmor.profile = unconfined
-
-# example simple networking setup, uncomment to enable
-#lxc.net.0.type = $lxc_network_type
-#lxc.net.0.flags = up
-#lxc.net.0.link = $lxc_network_link
-#lxc.net.0.name = eth0
-# Additional example for veth network type
-# static MAC address,
-#lxc.net.0.hwaddr = 00:16:3e:77:52:20
-# persistent veth device name on host side
-# Note: This may potentially collide with other containers of same name!
-#lxc.net.0.veth.pair = v-$name-e0
-
-EOF
-
- if [ $? -ne 0 ]; then
- echo "Failed to add configuration"
- return 1
- fi
-
- return 0
-}
-
-clean()
-{
-
- if [ ! -e $cache ]; then
- exit 0
- fi
-
- # lock, so we won't purge while someone is creating a repository
- (
- flock -x 9
- if [ $? != 0 ]; then
- echo "Cache repository is busy."
- exit 1
- fi
-
- echo -n "Purging the download cache for Fedora-$release..."
- rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1
- exit 0
- ) 9>@LOCALSTATEDIR@/lock/subsys/lxc-fedora
-}
-
-usage()
-{
- cat <<EOF
-usage:
- $1 -n|--name=<container_name>
- [-p|--path=<path>] [-c|--clean] [-R|--release=<Fedora_release>]
- [--fqdn=<network name of container>] [-a|--arch=<arch of the container>]
- [--mask-tmp]
- [-h|--help]
-Mandatory args:
- -n,--name container name, used to as an identifier for that container
-Optional args:
- -p,--path path to where the container will be created,
- defaults to @LXCPATH@.
- --rootfs path for actual rootfs.
- -c,--clean clean the cache
- -R,--release Fedora release for the new container.
- Defaults to host's release if the host is Fedora.
- --fqdn fully qualified domain name (FQDN) for DNS and system naming
- -a,--arch Define what arch the container will be [i686,x86_64]
- --mask-tmp Prevent systemd from over-mounting /tmp with tmpfs.
- -h,--help print this help
-EOF
- return 0
-}
-
-options=$(getopt -o a:hp:n:cR: -l help,path:,rootfs:,name:,clean,release:,arch:,fqdn:,mask-tmp -- "$@")
-if [ $? -ne 0 ]; then
- usage $(basename $0)
- exit 1
-fi
-
-arch=$(uname -m)
-masktmp=0
-
-eval set -- "$options"
-while true
-do
- case "$1" in
- -h|--help) usage $0 && exit 0;;
- -p|--path) path=$2; shift 2;;
- --rootfs) rootfs_path=$2; shift 2;;
- -n|--name) name=$2; shift 2;;
- -c|--clean) clean=1; shift 1;;
- -R|--release) release=$2; shift 2;;
- -a|--arch) newarch=$2; shift 2;;
- --fqdn) utsname=$2; shift 2;;
- --mask-tmp) masktmp=1; shift 1;;
- --) shift 1; break ;;
- *) break ;;
- esac
-done
-
-if [ ! -z "$clean" -a -z "$path" ]; then
- clean || exit 1
- exit 0
-fi
-
-basearch=${arch}
-# Map a few architectures to their generic Fedora repository archs.
-# The two ARM archs are a bit of a guesstimate for the v5 and v6
-# archs. V6 should have hardware floating point (Rasberry Pi).
-# The "arm" arch is safer (no hardware floating point). So
-# there may be cases where we "get it wrong" for some v6 other
-# than RPi.
-case "$arch" in
-i686) basearch=i386 ;;
-armv3l|armv4l|armv5l) basearch=arm ;;
-armv6l|armv7l|armv8l) basearch=armhfp ;;
-*) ;;
-esac
-
-mirrorurl="archives.fedoraproject.org::fedora-archive"
-case "$basearch" in
-ppc64|s390x) mirrorurl="archives.fedoraproject.org::fedora-secondary" ;;
-*) ;;
-esac
-
-# Somebody wants to specify an arch. This is very limited case.
-# i386/i586/i686 on i386/x86_64
-# - or -
-# x86_64 on x86_64
-if [ "${newarch}" != "" -a "${newarch}" != "${arch}" ]
-then
- case "${newarch}" in
- i386|i586|i686)
- if [ "${basearch}" = "i386" -o "${basearch}" = "x86_64" ]
- then
- # Make the arch a generic x86 32 bit...
- arch=${newarch}
- basearch=i386
- else
- basearch=bad
- fi
- ;;
- *)
- basearch=bad
- ;;
- esac
-
- if [ "${basearch}" = "bad" ]
- then
- echo "You cannot build a ${newarch} Fedora container on a ${arch} host. Sorry!"
- exit 1
- fi
-fi
-
-# Allow the cache base to be set by environment variable
-cache_base=${LXC_CACHE_PATH:-"@LOCALSTATEDIR@/cache/lxc"}/fedora/$basearch
-
-# Let's do something better for the initial root password.
-# It's not perfect but it will defeat common scanning brute force
-# attacks in the case where ssh is exposed. It will also be set to
-# expired, forcing the user to change it at first login.
-if [ "${root_password}" = "" ]
-then
- root_password=Root-${name}-${RANDOM}
-else
- # If it's got a ding in it, try and expand it!
- if [ $(expr "${root_password}" : '.*$.') != 0 ]
- then
- root_password=$(eval echo "${root_password}")
- fi
-
- # If it has more than 3 consecutive X's in it, feed it
- # through mktemp as a template.
- if [ $(expr "${root_password}" : '.*XXXX') != 0 ]
- then
- root_password=$(mktemp -u ${root_password})
- fi
-fi
-
-if [ -z "${utsname}" ]; then
- utsname=${name}
-fi
-
-# This follows a standard "resolver" convention that an FQDN must have
-# at least two dots or it is considered a local relative host name.
-# If it doesn't, append the dns domain name of the host system.
-#
-# This changes one significant behavior when running
-# "lxc_create -n Container_Name" without using the
-# --fqdn option.
-#
-# Old behavior:
-# utsname and hostname = Container_Name
-# New behavior:
-# utsname and hostname = Container_Name.Domain_Name
-
-if [ $(expr "$utsname" : '.*\..*\.') = 0 ]; then
- if [[ "$(dnsdomainname)" != "" && "$(dnsdomainname)" != "localdomain" ]]; then
- utsname=${utsname}.$(dnsdomainname)
- fi
-fi
-
-needed_pkgs=""
-
-type curl >/dev/null 2>&1
-if [ $? -ne 0 ]; then
- needed_pkgs="curl $needed_pkgs"
-fi
-type openssl >/dev/null 2>&1
-if [ $? -ne 0 ]; then
- needed_pkgs="openssl $needed_pkgs"
-fi
-
-if [ -n "$needed_pkgs" ]; then
- echo "Missing commands: $needed_pkgs"
- echo "Please install these using \"sudo yum install $needed_pkgs\""
- exit 1
-fi
-
-if [ -z "$path" ]; then
- path=$default_path/$name
-fi
-
-if [ -z "$release" ]; then
- if [ "$is_fedora" -a "$fedora_host_ver" ]; then
- release=$fedora_host_ver
- else
- echo "This is not a fedora host and release missing, defaulting to 22 use -R|--release to specify release"
- release=22
- fi
-fi
-
-if [ "$(id -u)" != "0" ]; then
- echo "This script should be run as 'root'"
- exit 1
-fi
-
-if [ -z "$rootfs_path" ]; then
- rootfs_path=$path/rootfs
- # check for 'lxc.rootfs.path' passed in through default config by lxc-create
- if grep -q '^lxc.rootfs.path' $path/config 2>/dev/null ; then
- rootfs_path=$(sed -e '/^lxc.rootfs.path\s*=/!d' -e 's/\s*#.*//' \
- -e 's/^lxc.rootfs.path\s*=\s*//' -e q $path/config)
- fi
-fi
-config_path=$path
-cache=$cache_base/$release
-
-revert()
-{
- echo "Interrupted, so cleaning up"
- lxc-destroy -n $name
- # maybe was interrupted before copy config
- rm -rf $path
- echo "exiting..."
- exit 1
-}
-
-trap revert SIGHUP SIGINT SIGTERM
-
-copy_configuration
-if [ $? -ne 0 ]; then
- echo "failed write configuration file"
- exit 1
-fi
-
-install_fedora
-if [ $? -ne 0 ]; then
- echo "failed to install fedora"
- exit 1
-fi
-
-configure_fedora
-if [ $? -ne 0 ]; then
- echo "failed to configure fedora for a container"
- exit 1
-fi
-
-# If the systemd configuration directory exists - set it up for what we need.
-if [ -d ${rootfs_path}/etc/systemd/system ]
-then
- configure_fedora_systemd
-fi
-
-# This configuration (rc.sysinit) is not inconsistent with the systemd stuff
-# above and may actually coexist on some upgraded systems. Let's just make
-# sure that, if it exists, we update this file, even if it's not used...
-if [ -f ${rootfs_path}/etc/rc.sysinit ]
-then
- configure_fedora_init
-fi
-
-if [ ! -z "$clean" ]; then
- clean || exit 1
- exit 0
-fi
-echo "
-Container rootfs and config have been created.
-Edit the config file to check/enable networking setup.
-"
-
-if [[ -d ${cache_base}/bootstrap ]]
-then
- echo "You have successfully built a Fedora container and cache. This cache may
-be used to create future containers of various revisions. The directory
-${cache_base}/bootstrap contains a bootstrap
-which may no longer needed and can be removed.
-"
-fi
-
-if [[ -e ${cache_base}/LiveOS ]]
-then
- echo "A LiveOS directory exists at ${cache_base}/LiveOS.
-This is only used in the creation of the bootstrap run-time-environment
-and may be removed.
-"
-fi
-
-if [ ${root_display_password} = "yes" ]
-then
- echo "The temporary password for root is: '$root_password'
-
-You may want to note that password down before starting the container.
-"
-fi
-
-if [ ${root_store_password} = "yes" ]
-then
- echo "The temporary root password is stored in:
-
- '${config_path}/tmp_root_pass'
-"
-fi
-
-if [ ${root_prompt_password} = "yes" ]
-then
- echo "Invoking the passwd command in the container to set the root password.
-
- chroot ${rootfs_path} passwd
-"
- chroot ${rootfs_path} passwd
-else
- if [ ${root_expire_password} = "yes" ]
- then
- if ( mountpoint -q -- "${rootfs_path}" )
- then
- echo "To reset the root password, you can do:
-
- lxc-start -n ${name}
- lxc-attach -n ${name} -- passwd
- lxc-stop -n ${name}
-"
- else
- echo "
-The root password is set up as "expired" and will require it to be changed
-at first login, which you should do as soon as possible. If you lose the
-root password or wish to change it without starting the container, you
-can change it from the host by running the following command (which will
-also reset the expired flag):
-
- chroot ${rootfs_path} passwd
-"
- fi
- fi
-fi
+++ /dev/null
-#!/bin/bash
-
-#
-# template script for generating Fedora container for LXC
-#
-
-#
-# lxc: linux Container library
-
-# Authors:
-# Daniel Lezcano <daniel.lezcano@free.fr>
-# Ramez Hanna <rhanna@informatiq.org>
-# Michael H. Warfield <mhw@WittsEnd.com>
-# Reto Gantenbein <reto.gantenbein@linuxmonk.ch>
-
-# 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
-
-# configurations
-FEDORA_RELEASE_MIN=24
-FEDORA_RELEASE_DEFAULT=${FEDORA_RELEASE_DEFAULT:-25}
-FEDORA_RSYNC_URL="${FEDORA_RSYNC_URL:-archives.fedoraproject.org::fedora-enchilada}"
-MIRRORLIST_URL=${MIRRORLIST_URL:-https://mirrors.fedoraproject.org/mirrorlist}
-
-local_state_dir="@LOCALSTATEDIR@"
-lxc_path="@LXCPATH@"
-lxc_template_config="@LXCTEMPLATECONFIG@"
-lxc_default_conf="@LXC_DEFAULT_CONFIG@"
-
-# allows the cache directory to be set by environment variable
-LXC_CACHE_PATH="${LXC_CACHE_PATH:-"${local_state_dir}/cache/lxc"}"
-
-# these are only going into comments in the resulting config...
-lxc_network_type=veth
-lxc_network_link=lxcbr0
-
-# Some combinations of the tuning knobs below do not exactly make sense.
-# but that's ok.
-#
-# If the "root_password" is non-blank, use it, else set a default.
-# This can be passed to the script as an environment variable and is
-# set by a shell conditional assignment. Looks weird but it is what it is.
-#
-# If the root password contains a ding ($) then try to expand it.
-# That will pick up things like ${name} and ${RANDOM}.
-# If the root password contains more than 3 consecutive X's, pass it as
-# a template to mktemp and take the result.
-#
-# If root_display_password = yes, display the temporary root password at exit.
-# If root_store_password = yes, store it in the configuration directory
-# If root_prompt_password = yes, invoke "passwd" to force the user to change
-# the root password after the container is created.
-# If root_expire_password = yes, you will be prompted to change the root
-# password at the first login.
-#
-# These are conditional assignments... The can be overridden from the
-# preexisting environment variables...
-#
-# Make sure this is in single quotes to defer expansion to later!
-# :{root_password='Root-${name}-${RANDOM}'}
-: "${root_password='Root-${name}-XXXXXX'}"
-
-# Now, it doesn't make much sense to display, store, and force change
-# together. But, we gotta test, right???
-: "${root_display_password='no'}"
-: "${root_store_password='yes'}"
-# Prompting for something interactive has potential for mayhem
-# with users running under the API... Don't default to "yes"
-: "${root_prompt_password='no'}"
-
-# Expire root password? Default to yes, but can be overridden from
-# the environment variable
-: "${root_expire_password='yes'}"
-
-# detect use under userns (unsupported)
-for arg in "$@"; do
- [ "${arg}" = "--" ] && break
- if [ "${arg}" = "--mapped-uid" ] || [ "${arg}" = "--mapped-gid" ]
- then
- echo "This template can't be used for unprivileged containers." 1>&2
- echo "You may want to try the \"download\" template instead." 1>&2
- exit 1
- fi
-done
-
-# make sure the usual locations are in PATH
-export PATH=${PATH}:/usr/sbin:/usr/bin:/sbin:/bin
-
-# dnf package manager arguments
-dnf_args=( --assumeyes --best --allowerasing --disablerepo=* --enablerepo=fedora --enablerepo=updates )
-
-# This function is going to setup a minimal host-arch native Fedora bootstrap
-# environment which will be used to create new containers on non-Fedora hosts.
-#
-bootstrap_fedora()
-{
- local cache="${1}"
-
- local bootstrap="${cache}/bootstrap"
- if [ -d "${bootstrap}" ]
- then
- echo "Existing Fedora bootstrap environment found. Testing ..."
- if chroot_update_fedora "${bootstrap}"
- then
- CHROOT_DIR="${bootstrap}"
- CHROOT_CMD="chroot ${CHROOT_DIR} "
-
- echo "Bootstrap environment appears to be functional."
- return 0
- else
- echo "Error: Bootstrap environment detected in ${bootstrap}"
- echo "but appears to be non-functional. Please remove and restart."
- return 1
- fi
- fi
-
- echo "Setting up new Fedora ${FEDORA_RELEASE_DEFAULT} (${basearch}) bootstrap environment."
-
- [[ -d "${cache}" ]] || mkdir -p "${cache}"
-
- tmp_bootstrap_dir=$( mktemp -d --tmpdir="${cache}" bootstrap_XXXXXX )
- pushd "${tmp_bootstrap_dir}" >/dev/null
-
- mkdir squashfs liveos bootstrap
-
- # download the LiveOS squashfs image
- if [ ! -f "${cache}/install.img" ]
- then
- local os_path="linux/releases/${FEDORA_RELEASE_DEFAULT}/Everything/${basearch}/os"
- local image_path="images/install.img"
- local ret=1
-
- if [ -n "${rsync}" ]
- then
- echo "Syncing LiveOS squashfs image from ${FEDORA_RSYNC_URL} ... "
- rsync --archive --info=progress "${FEDORA_RSYNC_URL}/${os_path}/${image_path}" .
- ret=$?
- else
- if [ -z "${mirror}" ]
- then
- get_mirrors "${FEDORA_RELEASE_DEFAULT}" "${basearch}" || return $?
- else
- local mirror_url="${mirror}/${os_path}"
- fi
- for url in ${mirror:-${mirror_urls}}
- do
- echo "Downloading LiveOS squashfs image from ${url} ... "
- curl --silent --show-error --fail --remote-name "${url}/${image_path}"
- ret=$?
- if [ ${ret} -ne 0 ]
- then
- continue
- else
- break
- fi
- done
- fi
-
- if [ "${ret}" != 0 ] || [ ! -s install.img ]
- then
- echo "Error: Download of squashfs image failed."
- return 1
- fi
- mv install.img "${cache}/"
- else
- echo "Using cached LiveOS squashfs image."
- fi
-
- echo "Mounting LiveOS squashfs file system."
- if ! mount -o loop -t squashfs "${cache}/install.img" squashfs/
- then
- echo "
-Error: Mount of LiveOS squashfs image failed
---------------------------------------------
-You must have squashfs support available to mount image. LiveOS image is now
-cached. Process may be rerun without penalty of downloading LiveOS again. If
-LiveOS is corrupt, remove ${cache}/install.img
-"
- return 1
- fi
-
- # mount contained LiveOS
- if ! mount -o loop squashfs/LiveOS/rootfs.img liveos
- then
- echo "
-Error: Mount of LiveOS stage0 rootfs image failed
--------------------------------------------------
-LiveOS download may be corrupt. Remove ${cache}/LiveOS
-to force a new download.
-"
- return 1
- fi
-
- echo "Copying LiveOS content to bootstrap environment ... "
- if ! rsync --archive --acls --hard-links --sparse liveos/. bootstrap/
- then
- echo "Error: Build of bootstrap environment failed."
- echo "Keeping directory ${tmp_bootstrap_dir} for your investigation."
- exit 1
- fi
-
- # unmount liveos mounts - we're done with liveos at this point
- umount liveos
- umount squashfs
-
- # customize bootstrap rootfs
- pushd bootstrap >/dev/null
-
- # setup repositories in bootstrap chroot
- CHROOT_DIR="$(pwd)"
- CHROOT_CMD="chroot ${CHROOT_DIR} "
- INSTALL_ROOT="/"
- if ! setup_repositories "${cache}" "${basearch}" "${FEDORA_RELEASE_DEFAULT}" "${mirror}"
- then
- echo "Error: Failed to configure repositories in ${CHROOT_DIR}${INSTALL_ROOT}"
- exit 1
- fi
- if [ -n "${mirror}" ]
- then
- set_dnf_mirror_url ./etc/yum.repos.d/fedora*.repo
- fi
-
- # make sure /etc/resolv.conf is up to date in the chroot
- cp /etc/resolv.conf ./etc/
-
- # verify bootstrap chroot by running a dnf update
- chroot_update_fedora "$(pwd)"
- ret=$?
-
- popd >/dev/null
-
- if [ "${ret}" != 0 ]
- then
- echo "Error: Build of bootstrap environment failed."
- echo "Keeping directory ${tmp_bootstrap_dir} for your investigation."
- return 1
- fi
-
- mv bootstrap "${cache}"
-
- popd >/dev/null
- rm -rf "${tmp_bootstrap_dir}"
-
- CHROOT_DIR="${bootstrap}"
- CHROOT_CMD="chroot ${CHROOT_DIR} "
-
- echo "Fedora bootstrap environment successfully created."
- return 0
-}
-
-chroot_mounts()
-{
- test -n "${1}" && local chroot="${1}" || return 1
-
- mount -t proc proc "${chroot}/proc" &&
- mount -o bind /dev "${chroot}/dev"
-}
-
-chroot_umounts()
-{
- test -n "${1}" && local chroot="${1}" || return 1
-
- umount "${chroot}/proc" &&
- umount "${chroot}/dev"
-}
-
-clean_cache()
-{
- local cache="${1}"
-
- test ! -e "${cache}" && return 0
-
- # lock, so we won't purge while someone is creating a repository
- (
- if ! flock -x 9
- then
- echo "Error: Cache repository is busy."
- exit 1
- fi
-
- echo -n "Purging the Fedora bootstrap and download cache ... "
- rm --preserve-root --one-file-system -rf "${cache}" && echo "Done." || exit 1
-
- exit 0
-
- ) 9>"${local_state_dir}/lock/subsys/lxc-fedora"
-
- return $?
-}
-
-# Customize container rootfs
-#
-configure_fedora()
-{
- local rootfs="${1}"
- local release="${2}"
- local utsname="${3}"
-
- # disable selinux
- mkdir -p "${rootfs}/selinux"
- echo 0 > "${rootfs}/selinux/enforce"
-
- # also kill it in the /etc/selinux/config file if it's there...
- if [ -f "${rootfs}/etc/selinux/config" ]
- then
- sed -i '/^SELINUX=/s/.*/SELINUX=disabled/' "${rootfs}/etc/selinux/config"
- fi
-
- # nice catch from Dwight Engen in the Oracle template.
- # wantonly plagerized here with much appreciation.
- if [ -f "${rootfs}/usr/sbin/selinuxenabled" ]
- then
- rm -f "${rootfs}/usr/sbin/selinuxenabled"
- ln -s /bin/false "${rootfs}/usr/sbin/selinuxenabled"
- fi
-
- # set hostname
- echo "${utsname}" > "${rootfs}/etc/hostname"
-
- # set default localtime to the host localtime if not set...
- if [ -e /etc/localtime ] && [ ! -e "${rootfs}/etc/localtime" ]
- then
- # if /etc/localtime is a symlink, this should preserve it.
- cp -a /etc/localtime "${rootfs}/etc/localtime"
- fi
-
- # set minimal hosts
- cat <<EOF > "${rootfs}/etc/hosts"
-127.0.0.1 localhost.localdomain localhost ${utsname}
-::1 localhost6.localdomain6 localhost6
-EOF
-
- # setup console and tty[1-4] for login. note that /dev/console and
- # /dev/tty[1-4] will be symlinks to the ptys /dev/lxc/console and
- # /dev/lxc/tty[1-4] so that package updates can overwrite the symlinks.
- # lxc will maintain these links and bind mount ptys over /dev/lxc/*
- # since lxc.tty.dir is specified in the config.
-
- # allow root login on console, tty[1-4], and pts/0 for libvirt
- cat <<EOF >> "${rootfs}/etc/securetty"
-# LXC (Linux Containers)
-lxc/console
-lxc/tty1
-lxc/tty2
-lxc/tty3
-lxc/tty4
-# For libvirt/Virtual Machine Monitor
-pts/0
-EOF
-
- if [ "${root_display_password}" = yes ]
- then
- echo "Setting root password to '$root_password'"
- fi
- if [ "${root_store_password}" = yes ]
- then
- touch "${path}/tmp_root_pass"
- chmod 600 "${path}/tmp_root_pass"
- echo "${root_password}" > "${path}/tmp_root_pass"
- echo "Storing root password in '${path}/tmp_root_pass'"
- fi
-
- echo "root:$root_password" | chroot "${rootfs}" chpasswd
-
- if [ "${root_expire_password}" = yes ]
- then
- # also set this password as expired to force the user to change it!
- chroot "${rootfs}" passwd -e root
- fi
-
- chroot_mounts "${rootfs}"
-
- # always make sure /etc/resolv.conf is up to date in the target!
- cp /etc/resolv.conf "${rootfs}/etc/"
-
- # rebuild the rpm database based on the target rpm version...
- rm -f "${rootfs}"/var/lib/rpm/__db*
- chroot "${rootfs}" rpm --rebuilddb
-
- chroot_umounts "${rootfs}"
-
- # default systemd target
- chroot "${rootfs}" ln -s /lib/systemd/system/multi-user.target \
- /etc/systemd/system/default.target
-
- # enable networking via systemd-networkd
- test -d "${rootfs}/etc/systemd/network" || mkdir "${rootfs}/etc/systemd/network"
- cat <<EOF > "${rootfs}/etc/systemd/network/eth0.network"
-[Match]
-Name=eth0
-
-[Network]
-DHCP=both
-EOF
- mkdir -p "${rootfs}/etc/systemd/system/socket.target.wants"
- chroot "${rootfs}" ln -s /usr/lib/systemd/system/systemd-networkd.socket \
- /etc/systemd/system/socket.target.wants/systemd-networkd.socket
- chroot "${rootfs}" ln -s /usr/lib/systemd/system/systemd-networkd.service \
- /etc/systemd/system/multi-user.target.wants/systemd-networkd.service
- mkdir -p "${rootfs}/etc/systemd/system/network-online.target.wants"
- chroot "${rootfs}" ln -s /usr/lib/systemd/system/systemd-networkd-wait-online.service \
- /etc/systemd/system/network-online.target.wants/systemd-networkd-wait-online.service
-
- # disable traditional network init
- chroot "${rootfs}" chkconfig network off
-
- # enable systemd-resolved
- rm -f "${rootfs}/etc/resolv.conf"
- chroot "${rootfs}" ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf
- chroot "${rootfs}" ln -s /usr/lib/systemd/system/systemd-resolved.service \
- /etc/systemd/system/multi-user.target.wants/systemd-resolved.service
-
- # if desired, prevent systemd from over-mounting /tmp with tmpfs
- if [ "${masktmp}" -eq 1 ]
- then
- chroot "${rootfs}" ln -s /dev/null /etc/systemd/system/tmp.mount
- fi
-
- return 0
-}
-
-copy_configuration()
-{
- local rootfs="${1}"
- local config="${2}"
- local utsname="${3}"
-
- # include configuration from default.conf if available
- grep -q "^lxc." "${lxc_default_conf}" > "${config}" 2>/dev/null
-
- grep -q "^lxc.rootfs.path" "${config}" 2>/dev/null || echo "
-lxc.rootfs.path = ${rootfs}
-" >> "${config}"
-
- # The following code is to create static MAC addresses for each
- # interface in the container. This code will work for multiple
- # interfaces in the default config. It will also strip any
- # hwaddr stanzas out of the default config since we can not share
- # MAC addresses between containers.
- mv "${config}" "${config}.orig"
-
- local line key
- while read -r line
- do
- # This should catch variable expansions from the default config...
- if expr "${line}" : '.*\$' > /dev/null 2>&1
- then
- line=$(eval "echo \"${line}\"")
- fi
-
- # There is a tab and a space in the regex bracket below!
- # Seems that \s doesn't work in brackets.
- key=$(expr "${line}" : '\s*\([^ ]*\)\s*=')
-
- if [ "${key}" != "lxc.net.0.hwaddr" ]
- then
- echo "${line}" >> "${config}"
-
- if [ "${key}" == "lxc.net.0.link" ]
- then
- echo "lxc.net.0.hwaddr = $(create_hwaddr)" >> "${config}"
- fi
- fi
- done < "${config}.orig"
- rm -f "${config}.orig"
-
- if [ -e "${lxc_template_config}/fedora.common.conf" ]
- then
- echo "
-# Include common configuration
-lxc.include = ${lxc_template_config}/fedora.common.conf
-" >> "${config}"
- fi
-
- cat <<EOF >> "${path}/config"
-# Container specific configuration
-lxc.arch = ${basearch}
-lxc.uts.name = ${utsname}
-
-# When using LXC with apparmor, uncomment the next line to run unconfined:
-#lxc.apparmor.profile = unconfined
-
-# example simple networking setup, uncomment to enable
-#lxc.net.0.type = ${lxc_network_type}
-#lxc.net.0.flags = up
-#lxc.net.0.link = ${lxc_network_link}
-#lxc.net.0.name = eth0
-# Additional example for veth network type
-# static MAC address,
-#lxc.net.0.hwaddr = $(create_hwaddr)
-# persistent veth device name on host side
-# Note: This may potentially collide with other containers of same name!
-#lxc.net.0.veth.pair = v-${name}-e0
-EOF
-
- if [ $? -ne 0 ]
- then
- echo "Failed to add configuration"
- return 1
- fi
-
- return 0
-}
-
-copy_fedora()
-{
- local cache="${1}"
- local rootfs="${2}"
- echo -n "Copying ${cache} to ${rootfs} ... "
-
- mkdir -p "${rootfs}" &&
- rsync --archive --hard-links --sparse --acls --xattrs "${cache}/" "${rootfs}/" &&
- echo || return 1
-
- return 0
-}
-
-# Generate a random hardware (MAC) address composed of FE followed by
-# 5 random bytes...
-#
-create_hwaddr()
-{
- openssl rand -hex 5 | sed -e 's/\(..\)/:\1/g; s/^/fe/'
-}
-
-# Make sure a fully functional rootfs of the requested release and architecture
-# will be setup in the given cache directory. If this is a Fedora host the
-# commands will run natively otherwise in a minimal Fedora bootstrap chroot.
-#
-download_fedora()
-{
- local cache_rootfs="${1}"
- local setup_rootfs="${cache_rootfs%%/rootfs}/partial"
-
- # suppress errors due to unknown locales
- LC_ALL=C
- LANG=en_US
-
- echo "Downloading ${basearch} rootfs for Fedora ${release} ..."
-
- # The following variables are going to be overwritten if the rootfs setup
- # is run in a separate boostrap environment (can not build natively).
- # These are the defaults for the non-boostrap (native) mode.
- CHROOT_DIR=
- CHROOT_CMD=
- INSTALL_ROOT=${setup_rootfs}
-
- if [ ! "${is_fedora}" ] || [ "${fedora_host_ver}" -lt "${FEDORA_VERSION_MINIMAL}" ]
- then
- # if this is not a supported Fedora host, use minimal bootstrap chroot
- echo "Non-Fedora host detected. Checking for bootstrap environment ... "
- if ! bootstrap_fedora "${cache}"
- then
- echo "Error: Fedora Bootstrap setup failed"
- return 1
- fi
- echo "Using bootstrap environment at ${CHROOT_DIR}"
- fi
-
- if ! mkdir -p "${setup_rootfs}"
- then
- echo "Error: Failed to create '${setup_rootfs}' directory."
- return 1
- fi
-
- trap revert_rootfs SIGHUP SIGINT SIGTERM
-
- mkdir -p "${setup_rootfs}/var/lib/rpm"
-
- # if the setup is going to be run in a chroot, mount the related file systems
- if [ -n "${CHROOT_DIR}" ]
- then
- chroot_mounts "${CHROOT_DIR}"
-
- # make sure rootfs is available in bootstrap chroot
- INSTALL_ROOT="/run/install"
- test -d "${CHROOT_DIR}${INSTALL_ROOT}" || mkdir -p "${CHROOT_DIR}${INSTALL_ROOT}"
- mount -o bind "${setup_rootfs}" "${CHROOT_DIR}${INSTALL_ROOT}"
- fi
-
- if ! setup_repositories "${cache}" "${basearch}" "${release}" "${mirror}"
- then
- echo "Error: Failed to configure repositories in ${CHROOT_DIR}${INSTALL_ROOT}"
- revert_rootfs >/dev/null
- return 1
- fi
-
- # Unforunately <dnf-2.0 doesn't respect the repository configuration of the
- # installroot but use the one from the host. This obviously doesn't work
- # with a custom mirror or target architecture. Therefore a temporary dnf.conf
- # is created and passed to the chroot command.
- cat "${CHROOT_DIR}${INSTALL_ROOT}"/etc/yum.repos.d/{fedora,fedora-updates}.repo > "${CHROOT_DIR}${INSTALL_ROOT}/dnf.conf"
- if [ -n "${mirror}" ]
- then
- set_dnf_mirror_url "${CHROOT_DIR}${INSTALL_ROOT}/dnf.conf"
- fi
-
- # install minimal container file system
- local pkg_list="dnf initscripts passwd vim-minimal openssh-server openssh-clients dhclient rootfiles policycoreutils fedora-release fedora-repos"
- if ! ${CHROOT_CMD}dnf --installroot "${INSTALL_ROOT}" \
- --config="${INSTALL_ROOT}/dnf.conf" \
- --releasever "${release}" \
- ${dnf_args[@]} \
- install ${pkg_list}
- then
- echo "Error: Failed to setup the rootfs in ${CHROOT_DIR}${INSTALL_ROOT}."
- revert_rootfs >/dev/null
- return 1
- fi
-
- unmount_installroot
-
- # from now on we'll work in the new rootfs
- chroot_mounts "${setup_rootfs}"
-
- # It might happen, that the dnf used above will write an incompatible
- # RPM database for the version running in the rootfs. Rebuild it.
- echo "Fixing up RPM databases"
- rm -f "${setup_rootfs}"/var/lib/rpm/__db*
- chroot "${setup_rootfs}" rpm --rebuilddb
-
- # Restrict locale for installed packages to en_US to shrink image size
- # following: https://pagure.io/fedora-kickstarts/blob/master/f/fedora-cloud-base.ks
- echo "Cleanup locales and language files ..."
- find "${setup_rootfs}/usr/share/locale" -mindepth 1 -maxdepth 1 -type d \
- -not -name "${LANG}" -exec rm -rf {} +
-
- chroot "${setup_rootfs}" localedef --list-archive | grep -v ^"${LANG}" | xargs \
- chroot "${setup_rootfs}" localedef --delete-from-archive
-
- mv -f "${setup_rootfs}/usr/lib/locale/locale-archive" \
- "${setup_rootfs}/usr/lib/locale/locale-archive.tmpl"
- chroot "${setup_rootfs}" build-locale-archive
-
- echo "%_install_langs C:en:${LANG}:${LANG}.UTF-8" > "${setup_rootfs}/etc/rpm/macros.image-language-conf"
-
- chroot_umounts "${setup_rootfs}"
-
- # reset traps
- trap SIGHUP
- trap SIGINT
- trap SIGTERM
-
- # use generated rootfs as future cache
- mv "${setup_rootfs}" "${cache_rootfs}"
-
- echo "Download of Fedora rootfs complete."
- return 0
-}
-
-# Query the Fedora mirrorlist for several HTTPS mirrors
-#
-get_mirrors()
-{
- local release="${1}"
- local mirror_arch="${2}"
-
- for trynumber in 1 2 3 4
- do
- [ "${trynumber}" != 1 ] && echo -n "Trying again ... "
-
- # choose some mirrors by parsing directory index
- mirror_urls=$(curl --silent --show-error --fail "${MIRRORLIST_URL}?repo=fedora-${release}&arch=${mirror_arch}" | sed '/^https:/!d' | sed '2,6!d')
-
- # shellcheck disable=SC2181
- if [ $? -eq 0 ] && [ -n "${mirror_urls}" ]
- then
- break
- fi
-
- echo "Warning: Failed to get a mirror on try ${trynumber}."
- sleep 3
- done
-
- if [ -z "${mirror_urls}" ]
- then
- echo "Error: Failed to retrieve Fedora mirror URL. Please use '-m MIRROR' option."
- return 1
- fi
-
- return 0
-}
-
-# Install a functional Fedora rootfs into the container root
-#
-install_fedora()
-{
- local rootfs="${1}"
- local cache="${2}"
- local cache_rootfs="${cache}/${release}-${basearch}/rootfs"
-
- mkdir -p "${local_state_dir}/lock/subsys/"
- (
- if ! flock -x 9
- then
- echo "Error: Cache repository is busy."
- return 1
- fi
-
- echo "Checking cache download in ${cache_rootfs} ... "
- if [ ! -e "${cache_rootfs}" ]
- then
- if ! download_fedora "${cache_rootfs}"
- then
- echo "Error: Failed to download Fedora ${release} (${basearch})"
- return 1
- fi
- else
- echo "Cache found at ${cache_rootfs}. Updating ..."
- if ! chroot_update_fedora "${cache_rootfs}"
- then
- echo "Failed to update cached rootfs, continuing with previously cached version."
- else
- echo "Fedora update finished."
- fi
- fi
-
- trap revert_container SIGHUP SIGINT SIGTERM
-
- if ! copy_fedora "${cache_rootfs}" "${rootfs}"
- then
- echo "Error: Failed to copy rootfs"
- return 1
- fi
-
- chroot_mounts "${rootfs}"
-
- # install additional user provided packages
- if [ -n "${packages}" ]
- then
- # always make sure /etc/resolv.conf is up to date in the target!
- cp /etc/resolv.conf "${rootfs}/etc/"
-
- echo "Installing user requested RPMs: ${packages}"
- if ! chroot "${rootfs}" dnf install ${dnf_args[@]} $(tr ',' ' ' <<< "${packages}")
- then
- echo "Error: Installation of user provided packages failed."
- echo "Cleaning up ... "
- sleep 3 # wait for all file handles to properly close
- chroot_umounts "${setup_rootfs}"
- return 1
- fi
- fi
-
- # cleanup dnf cache in new container
- chroot "${rootfs}" dnf clean all
-
- sleep 3 # wait for all file handles to properly close
- chroot_umounts "${rootfs}"
-
- return 0
- ) 9>"${local_state_dir}/lock/subsys/lxc-fedora"
-
- return $?
-}
-
-# Cleanup partial container
-#
-revert_container()
-{
- echo "Interrupted, so cleaning up ..."
- lxc-destroy -n "${name}" 2>/dev/null
- # maybe was interrupted before copy config, try to prevent some mistakes
- if [ -d "${path}" ] &&
- [ "${path}" != "/" ] && [ "${path}" != "/tmp" ] && [ "${path}" != "/bin" ]
- then
- rm -rf "${path}"
- fi
- echo "Exiting ..."
- exit 1
-}
-
-# Cleanup partial rootfs cache
-#
-revert_rootfs()
-{
- echo "Interrupted, so cleaning up ..."
- unmount_installroot
- rm -rf "${setup_rootfs}"
- echo "Exiting ..."
- exit 1
-}
-
-# Set dnf repository mirror in given repo files
-#
-set_dnf_mirror_url()
-{
- sed -i -e 's/^\(metalink=.*\)$/#\1/g' "${@}"
- sed -i -e '/baseurl/ s|^#||g' "${@}"
- sed -i -e "/baseurl/ s|http://download.fedoraproject.org/pub/fedora|${mirror}|g" "${@}"
-}
-
-# Setup dnf repository configuration. It can be run in a chroot by specifying
-# $CHROOT_DIR (chroot directory) and $CHROOT_CMD (chroot command) and/or
-# with an alternative RPM install root defined in $INSTALL_ROOT.
-#
-setup_repositories()
-{
- local cache="${1}"
- local target_arch="${2}"
- local release="${3}"
- local mirror="${4}"
-
- # download repository packages if not found in cache
- pushd "${cache}" >/dev/null
- if [ -z "$(ls -1 ./fedora-release-${release}*.noarch.rpm 2>/dev/null)" ] ||
- [ -z "$(ls -1 ./fedora-repos-${release}*.noarch.rpm 2>/dev/null)" ]
- then
- # if no mirror given, get an appropriate mirror from the mirror list
- if [ -z "${mirror}" ]
- then
- get_mirrors "${release}" "${target_arch}" || return $?
- else
- # construct release-specific mirror url
- mirror="${mirror}/linux/releases/${release}/Everything/${target_arch}/os"
- fi
-
- for mirror_url in ${mirror:-${mirror_urls}}
- do
- local release_url="${mirror_url}/Packages/f"
-
- for pkg in fedora-release-${release} fedora-repos-${release}
- do
- test -n "$(ls -1 ./${pkg}*.noarch.rpm 2>/dev/null)" && continue
-
- # query package name by parsing directory index
- echo "Requesting '${pkg}' package version from ${release_url}."
- pkg_name=$(curl --silent --show-error --fail "${release_url}/" | sed -n -e "/${pkg}/ s/.*href=\"\(${pkg}-.*\.noarch\.rpm\)\">.*/\1/p" | tail -1)
-
- # shellcheck disable=SC2181
- if [ $? -ne 0 ] || [ -z "${pkg_name}" ]
- then
- echo "Error: Failed to get '${pkg}' version from ${release_url}/."
- continue
- fi
-
- echo "Downloading '${release_url}/${pkg_name} ... "
- if ! curl --silent --show-error --fail --remote-name "${release_url}/${pkg_name}"
- then
- echo "Error: Package download failed."
- continue
- fi
- done
-
- # if we have both packages continue
- if [ -z "$(ls -1 ./fedora-release-${release}*.noarch.rpm 2>/dev/null)" ] ||
- [ -z "$(ls -1 ./fedora-repos-${release}*.noarch.rpm 2>/dev/null)" ]
- then
- break
- fi
- done
- fi
-
- # copy packages to chroot file system
- if [ -n "${CHROOT_DIR}" ]
- then
- cp ./fedora-release-${release}*.noarch.rpm "${CHROOT_DIR}" &&
- cp ./fedora-repos-${release}*.noarch.rpm "${CHROOT_DIR}"
- else
- local pkgdir="${cache}"
- fi
-
- # use '--nodeps' to work around 'fedora-release-24-*' bash dependency
- ${CHROOT_CMD}rpm --root "${INSTALL_ROOT}" -ivh --nodeps "${pkgdir}"/{fedora-release-${release}*.noarch.rpm,fedora-repos-${release}*.noarch.rpm}
- local ret=$?
-
- # dnf will take $basearch from host, so force the arch we want
- sed -i "s|\$basearch|${target_arch}|" ${CHROOT_DIR}${INSTALL_ROOT}/etc/yum.repos.d/*
-
- popd >/dev/null
-
- if [ "${ret}" -ne 0 ]
- then
- echo "Failed to setup repositories in ${CHROOT_DIR}${INSTALL_ROOT}"
- exit 1
- fi
-
- # cleanup installed packages
- if [ -n "${CHROOT_DIR}" ]
- then
- # shellcheck disable=SC2086
- rm -f "${CHROOT_DIR}"/{fedora-release-${release}*.noarch.rpm,fedora-repos-${release}*.noarch.rpm}
- fi
-
- return 0
-}
-
-# Run dnf update in the given chroot directory.
-#
-chroot_update_fedora()
-{
- local chroot="${1}"
- chroot_mounts "${chroot}"
-
- # always make sure /etc/resolv.conf is up to date in the target!
- cp /etc/resolv.conf "${chroot}/etc/"
-
- chroot "${chroot}" dnf -y update
- local ret=$?
-
- sleep 3 # wait for all file handles to properly close
-
- chroot_umounts "${chroot}"
-
- return ${ret}
-}
-
-# Unmount installroot after bootstrapping or on error.
-#
-unmount_installroot() {
- if [ -n "${CHROOT_DIR}" ]
- then
- sleep 3 # wait for all file handles to properly close
- chroot_umounts "${CHROOT_DIR}" 2>/dev/null
- umount "${CHROOT_DIR}${INSTALL_ROOT}" 2>/dev/null
- fi
-}
-
-usage()
-{
- cat <<EOF
-LXC Container configuration for Fedora images.
-
-Template specific options can be passed to lxc-create after a '--' like this:
-
- lxc-create --name=NAME -t fedora [OPTION..] -- [TEMPLATE_OPTION..]
-
-Template options:
-
- -a, --arch Define what arch the container will be [i386,x86_64]
- -c, --clean Clean bootstrap and download cache
- -d, --debug Run with 'set -x' to debug errors
- --fqdn Fully qualified domain name (FQDN)
- -h, --help Print this help text
- --mask-tmp Prevent systemd from over-mounting /tmp with tmpfs.
- -M, --mirror=MIRROR Fedora mirror to use during installation.
- -p, --path=PATH Path to where the container will be created,
- defaults to ${lxc_path}.
- -P, --packages=PKGS Comma-separated list of additional RPM packages to
- install into the container.
- -R, --release=RELEASE Fedora release number of the container, defaults
- to host's release if the host is Fedora.
- --rootfs=ROOTFS Path for the actual container root file system
- --rsync Use rsync instead of HTTPS to download bootstrap
- image (insecure).
-
-Environment variables:
-
- LXC_CACHE_PATH Cache directory for image bootstrap. Defaults to
- '${LXC_CACHE_PATH}'
-
- MIRRORLIST_URL List of Fedora mirrors queried if no custom mirror is
- given. Defaults to '${MIRRORLIST_URL}'
-
- FEDORA_RSYNC_URL Fedora rsync URL to use for bootstrap with '--rsync'.
- Defaults to '${FEDORA_RSYNC_URL}'
-
- FEDORA_RELEASE_DEFAULT Set default Fedora release if not detected from the
- host. Is set to '${FEDORA_RELEASE_DEFAULT}'
-
-EOF
- return 0
-}
-
-options=$(getopt -o a:hp:n:cR:dP:M: -l help,path:,rootfs:,name:,clean,release:,arch:,debug,fqdn:,mask-tmp,mirror:,packages:,rsync -- "$@")
-# shellcheck disable=SC2181
-if [ $? -ne 0 ]; then
- usage
- exit 1
-fi
-
-arch=$(uname -m)
-debug=0
-masktmp=0
-
-eval set -- "$options"
-while true
-do
- case "${1}" in
- -h|--help) usage; exit 0 ;;
- -n|--name) name="${2}"; shift 2 ;;
- -p|--path) path="${2}"; shift 2 ;;
- --rootfs) rootfs="${2}"; shift 2 ;;
- -a|--arch) newarch="${2}"; shift 2 ;;
- -c|--clean) clean=1; shift 1 ;;
- -d|--debug) debug=1; shift 1 ;;
- --fqdn) utsname="${2}"; shift 2 ;;
- --mask-tmp) masktmp=1; shift 1 ;;
- -M|--mirror) mirror="${2}"; shift 2 ;;
- -P|--packages) packages="${2}"; shift 2 ;;
- -R|--release) release="${2}"; shift 2 ;;
- --rsync) rsync=1; shift 1 ;;
- --) shift 1; break ;;
- *) break ;;
- esac
-done
-
-if [ "${debug}" -eq 1 ]
-then
- set -x
-fi
-
-# change to a safe directory
-cd || exit $?
-
-# Is this Fedora?
-# Allow for weird remixes like the Raspberry Pi
-#
-# Use the Mitre standard CPE identifier for the release ID if possible...
-# This may be in /etc/os-release or /etc/system-release-cpe. We
-# should be able to use EITHER. Give preference to /etc/os-release for now.
-
-if [ -e /etc/os-release ]
-then
-# This is a shell friendly configuration file. We can just source it.
-# What we're looking for in here is the ID, VERSION_ID and the CPE_NAME
- . /etc/os-release
-fi
-
-if [ "${CPE_NAME}" = "" ] && [ -e /etc/system-release-cpe ]
-then
- CPE_NAME=$(head -n1 /etc/system-release-cpe)
- CPE_URI=$(expr "${CPE_NAME}" : '\([^:]*:[^:]*\)')
- if [ "${CPE_URI}" != "cpe:/o" ]
- then
- CPE_NAME=
- else
- echo "Host CPE ID from /etc/system-release-cpe: ${CPE_NAME}"
- # Probably a better way to do this but sill remain posix
- # compatible but this works, shrug...
- # Must be nice and not introduce convenient bashisms here.
- ID=$(expr ${CPE_NAME} : '[^:]*:[^:]*:[^:]*:\([^:]*\)')
- VERSION_ID=$(expr ${CPE_NAME} : '[^:]*:[^:]*:[^:]*:[^:]*:\([^:]*\)')
- fi
-fi
-
-if [ "${ID}" = "fedora" ] && [ -n "${CPE_NAME}" ] && [ -n "${VERSION_ID}" ]
-then
- fedora_host_ver=${VERSION_ID}
- is_fedora=true
-fi
-
-# Map a few architectures to their generic Fedora repository archs.
-# The two ARM archs are a bit of a guesstimate for the v5 and v6
-# archs. V6 should have hardware floating point (Rasberry Pi).
-# The "arm" arch is safer (no hardware floating point). So
-# there may be cases where we "get it wrong" for some v6 other
-# than RPi.
-basearch=${arch}
-case "${arch}" in
- i686) basearch=i386 ;;
- armv3l|armv4l|armv5l) basearch=arm ;;
- armv6l|armv7l|armv8l) basearch=armhfp ;;
- *) ;;
-esac
-
-case "${basearch}" in
- ppc64|s390x) FEDORA_RSYNC_URL="archives.fedoraproject.org::fedora-secondary" ;;
- *) ;;
-esac
-
-# Somebody wants to specify an arch. This is very limited case.
-# i386/i586/i686 on i386/x86_64
-# - or -
-# x86_64 on x86_64
-if [ "${newarch}" != "" ] && [ "${newarch}" != "${arch}" ]
-then
- case "${newarch}" in
- i386|i586|i686)
- if [ "${basearch}" = "i386" ] || [ "${basearch}" = "x86_64" ]
- then
- # Make the arch a generic x86 32 bit...
- basearch=i386
- else
- basearch=bad
- fi
- ;;
- *)
- basearch=bad
- ;;
- esac
-
- if [ "${basearch}" = "bad" ]
- then
- echo "Error: You cannot build a ${newarch} Fedora container on a ${arch} host. Sorry!"
- exit 1
- fi
-fi
-
-# Let's do something better for the initial root password.
-# It's not perfect but it will defeat common scanning brute force
-# attacks in the case where ssh is exposed. It will also be set to
-# expired, forcing the user to change it at first login.
-if [ "${root_password}" = "" ]
-then
- root_password=Root-${name}-${RANDOM}
-else
- # If it's got a ding in it, try and expand it!
- if [ "$(expr "${root_password}" : '.*$.')" != 0 ]
- then
- root_password=$(eval echo "${root_password}")
- fi
-
- # If it has more than 3 consecutive X's in it, feed it
- # through mktemp as a template.
- if [ "$(expr "${root_password}" : '.*XXXX')" != 0 ]
- then
- root_password=$(mktemp -u "${root_password}")
- fi
-fi
-
-if [ -z "${utsname}" ]; then
- utsname=${name}
-fi
-
-# This follows a standard "resolver" convention that an FQDN must have
-# at least two dots or it is considered a local relative host name.
-# If it doesn't, append the dns domain name of the host system.
-#
-# This changes one significant behavior when running
-# "lxc_create -n Container_Name" without using the
-# --fqdn option.
-#
-# Old behavior:
-# utsname and hostname = Container_Name
-# New behavior:
-# utsname and hostname = Container_Name.Domain_Name
-
-if [ "$(expr "${utsname}" : '.*\..*\.')" = 0 ]
-then
- if [ -n "$(dnsdomainname)" ] && [ "$(dnsdomainname)" != "localdomain" ]
- then
- utsname="${utsname}.$(dnsdomainname)"
- fi
-fi
-
-# check if the pre-requisite binaries are available
-prerequisite_pkgs=( curl openssl rsync )
-needed_pkgs=""
-for pkg in "${prerequisite_pkgs[@]}"
-do
- if ! type "${pkg}" >/dev/null 2>&1
- then
- needed_pkgs="${pkg} ${needed_pkgs}"
- fi
-done
-if [ -n "${needed_pkgs}" ]
-then
- echo "Error: Missing command(s): ${needed_pkgs}"
- exit 1
-fi
-
-if [ "$(id -u)" != "0" ]
-then
- echo "This script should be run as 'root'"
- exit 1
-fi
-
-# cleanup cache if requested
-cache="${LXC_CACHE_PATH}/fedora"
-if [ -n "${clean}" ]
-then
- clean_cache "${cache}" || exit 1
- exit 0
-fi
-
-# set container directory
-if [ -z "${path}" ]
-then
- path="${lxc_path}/${name}"
-fi
-
-# set container rootfs and configuration path
-config="${path}/config"
-if [ -z "${rootfs}" ]
-then
- # check for 'lxc.rootfs.path' passed in through default config by lxc-create
- if grep -q '^lxc.rootfs.path' "${config}" 2>/dev/null
- then
- rootfs=$(awk -F= '/^lxc.rootfs.path =/{ print $2 }' "${config}")
- else
- rootfs="${path}/rootfs"
- fi
-fi
-
-# set release if not given
-if [ -z "${release}" ]
-then
- if [ "${is_fedora}" ] && [ -n "${fedora_host_ver}" ]
- then
- echo "Detected Fedora ${fedora_host_ver} host. Set release to ${fedora_host_ver}."
- release="${fedora_host_ver}"
- else
- echo "This is not a Fedora host or release is missing, defaulting release to ${FEDORA_RELEASE_DEFAULT}."
- release="${FEDORA_RELEASE_DEFAULT}"
- fi
-fi
-if [ "${release}" -lt "${FEDORA_RELEASE_MIN}" ]
-then
- echo "Error: Fedora release ${release} is not supported. Set -R at least to ${FEDORA_RELEASE_MIN}."
- exit 1
-fi
-
-# bootstrap rootfs and copy to container file system
-if ! install_fedora "${rootfs}" "${cache}"
-then
- echo "Error: Failed to create Fedora container"
- exit 1
-fi
-
-# customize container file system
-if ! configure_fedora "${rootfs}" "${release}" "${utsname}"
-then
- echo "Error: Failed to configure Fedora container"
- exit 1
-fi
-
-# create container configuration (will be overwritten by newer lxc-create)
-if ! copy_configuration "${rootfs}" "${config}" "${utsname}"
-then
- echo "Error: Failed write container configuration file"
- exit 1
-fi
-
-if [ -n "${clean}" ]; then
- clean || exit 1
- exit 0
-fi
-
-echo "Successfully created container '${name}'"
-
-if [ "${root_display_password}" = "yes" ]
-then
- echo "The temporary password for root is: '$root_password'
-
-You may want to note that password down before starting the container.
-"
-fi
-
-if [ "${root_store_password}" = "yes" ]
-then
- echo "The temporary root password is stored in:
-
- '${config}/tmp_root_pass'
-"
-fi
-
-if [ "${root_prompt_password}" = "yes" ]
-then
- echo "Invoking the passwd command in the container to set the root password.
-
- chroot ${rootfs} passwd
-"
- chroot "${rootfs}" passwd
-else
- if [ "${root_expire_password}" = "yes" ]
- then
- if ( mountpoint -q -- "${rootfs}" )
- then
- echo "To reset the root password, you can do:
-
- lxc-start -n ${name}
- lxc-attach -n ${name} -- passwd
- lxc-stop -n ${name}
-"
- else
- echo "
-The root password is set up as expired and will require it to be changed
-at first login, which you should do as soon as possible. If you lose the
-root password or wish to change it without starting the container, you
-can change it from the host by running the following command (which will
-also reset the expired flag):
-
- chroot ${rootfs} passwd
-"
- fi
- fi
-fi
-
-# vim: set ts=4 sw=4 expandtab:
+++ /dev/null
-#!/bin/bash
-
-#
-# LXC template for gentoo
-#
-# Author: Guillaume Zitta <lxc@zitta.fr>
-#
-# Widely inspired from lxc-gentoo script at https://github.com/globalcitizen/lxc-gentoo
-#
-# this version is reworked with :
-# - out of the lxc-create compat
-# - vanilla gentoo config
-# - ready to use cache
-#
-
-# Detect use under userns (unsupported)
-for arg in "$@"; do
- [ "$arg" = "--" ] && break
- if [ "$arg" = "--mapped-uid" -o "$arg" = "--mapped-gid" ]; then
- echo "This template can't be used for unprivileged containers." 1>&2
- echo "You may want to try the \"download\" template instead." 1>&2
- exit 1
- fi
-done
-
-# Make sure the usual locations are in PATH
-export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
-
-# Ensure strict root's umask doesen't render the VM unusable
-umask 022
-
-LXC_TEMPLATE_CONFIG="@LXCTEMPLATECONFIG@"
-
-################################################################################
-# Various helper functions
-################################################################################
-
-# param: $1: the name of the lock
-# param: $2: the timeout for the lock
-# The rest contain the command to execute and its parameters
-execute_exclusively()
-{
- mkdir -p @LOCALSTATEDIR@/lock/subsys/
-
- local lock_name="$1"
- local timeout="$2"
- shift 2
-
- {
- printf "Attempting to obtain an exclusive lock (timeout: %s sec) named \"%s\"...\n" "${timeout}" "$lock_name"
-
- flock -x -w "${timeout}" 50
-
- if [[ $? -ne 0 ]]; then
- printf " => unable to obtain lock, aborting.\n"
- return 2
- else
- printf " => done.\n"
- fi
-
- printf " => Executing \"%s\"\n" "$*"
- "$@"
- retval=$?
- } 50> "@LOCALSTATEDIR@/lock/subsys/lxc-gentoo-${lock_name}"
- return $retval
-}
-
-# a die function is always a good idea
-die()
-{
- printf "\n[the last exit code leading to this death was: %s ]\n" "$?"
- local retval="$1"
- shift 1
- printf "$@"
- exit "$retval"
-}
-
-# gentoo arch/variant detection
-set_default_arch()
-{
- printf "### set_default_arch: default arch/variant autodetect...\n"
- arch=$(uname -m)
- if [[ $arch =~ i.86 ]]; then
- arch="x86"
- variant="x86"
- elif [[ $arch == "x86_64" ]]; then
- arch="amd64"
- variant="amd64"
- elif [[ $arch =~ arm.* ]]; then
- arch="arm"
- variant="armv7a"
- else
- #who knows, it may work...
- printf " => warn: unexpected arch:${arch} let me knows if it works :)\n"
- variant="${arch}"
- fi
- printf " => Got: arch=%s variant=%s\n" "${arch}" "${variant}"
-}
-
-store_user_message()
-{
- user_message="${user_message}=> $@\n"
-}
-
-################################################################################
-# CACHE Preparation
-################################################################################
-# during setup cachedir is $cacheroot/partial-$arch-$variant
-# at the end, it will be $cacheroot/rootfs-$arch-$variant
-
-cache_setup(){
- partialfs="${cacheroot}/partial-${arch}-${variant}"
-
- #if cache exists and flush not needed, return
- [[ -d "${cachefs}" && -z "${flush_cache}" ]] && return 0
-
- printf "###### cache_setup(): doing cache preparation\n"
- local retval=1
-
- #clean from failed previous run
- rm -rf "${partialfs}"
- mkdir -p "${partialfs}"
-
- #let's go
- cache_precheck && \
- cache_stage3 && \
- cache_portage && \
- cache_inittab && \
- cache_net && \
- cache_dev && \
- cache_openrc && \
- cache_locale && \
- rm -rf "${cachefs}" && \
- mv "${partialfs}" "${cachefs}" && \
- printf "###### cache_setup: Cache should be ready\n"
-
- return $?
-}
-
-cache_precheck()
-{
- printf "### cache_precheck(): doing some pre-start checks ...\n"
- # never hurts to have a fail-safe.
- [[ -n "${cacheroot//\/}" ]] \
- || die 8 "\$cacheroot (%s) IS EMPTY OR MADE OF ONLY DIRECTORY SEPARATORS, THIS IS *VERY* BAD!\n" "${cacheroot}"
-}
-
-#get latest stage3 tarball
-cache_stage3()
-{
- printf "### cache_stage3(): stage3 cache deployment...\n"
-
- if [ -z "${tarball}" ]; then
- #variables init
- local stage3_baseurl="${mirror}/releases/${arch}/autobuilds"
-
- # get latest-stage3....txt file for subpath
- local stage3_pointer="${stage3_baseurl}/latest-stage3-${variant}.txt"
-
- printf "Determining path to latest Gentoo %s (%s) stage3 archive...\n" "${arch}" "${variant}"
- printf " => downloading and processing %s\n" "${stage3_pointer}"
-
- local stage3_latest_tarball=$(wget -q -O - "${stage3_pointer}" | tail -n1 | cut -d' ' -f1) \
- || die 6 "Error: unable to fetch\n"
-
- printf " => Got: %s\n" "${stage3_latest_tarball}"
-
- printf "Downloading/untarring the actual stage3 tarball...\n"
-
- compressor="j"
- if echo ${stage3_latest_tarball} | grep ".xz$"; then
- compressor="J"
- fi
-
- wget -O - "${stage3_baseurl}/${stage3_latest_tarball}" \
- | tar -x${compressor}pf - --numeric-owner -C "${partialfs}" \
- || die 6 "Error: unable to fetch or untar\n"
- printf " => extracted to: %s\n" "${partialfs}"
- else
- printf "Extracting the stage3 tarball...\n"
- tar -xpf "${tarball}" --numeric-owner -C "${partialfs}" \
- || die 6 "unable to untar ${tarball} to ${partialfs}"
- fi
-
- #check if it chroots
- printf "chroot test..."
- chroot ${partialfs} /bin/true || die 1 "Error: chroot %s /bin/true, failed" "${partialfs}"
- printf " OK\n"
- printf " => stage3 cache extracted in : %s\n" "${partialfs}"
- return 0
-}
-
-cache_portage()
-{
- printf "### cache_portage: caching portage tree tarball...\n"
- [[ -z "${flush_cache}" && -f "${portage_cache}" ]] && return 0
-
- rm -f ${portage_cache}
-
- printf "Downloading Gentoo portage (software build database) snapshot...\n"
- execute_exclusively portage 60 wget -O "${portage_cache}" "${mirror}/snapshots/portage-latest.tar.bz2" \
- || die 6 "Error: unable to fetch\n"
- printf " => done.\n"
-}
-
-# custom inittab
-cache_inittab()
-{
- printf "### cache_inittab: tuning inittab...\n"
-
- INITTAB="${partialfs}/etc/inittab"
-
- [[ -w "$INITTAB" ]] || die 1 "Error: $INITTAB is not writeable"
-
- # create console
- echo "# Lxc main console" >> "$INITTAB"
- echo "1:12345:respawn:/sbin/agetty -a root --noclear 115200 console linux" >> "$INITTAB"
-
- # finally we add a pf line to enable clean shutdown on SIGPWR (issue 60)
- echo "# clean container shutdown on SIGPWR" >> "$INITTAB"
- echo "pf:12345:powerwait:/sbin/halt" >> "$INITTAB"
-
- # we also blank out /etc/issue here in order to prevent delays spawning login
- # caused by attempts to determine domainname on disconnected containers
- sed -i 's/[\][Oo]//g' "${partialfs}/etc/issue"
-}
-
-cache_net()
-{
- printf "### cache_net: doing some useful net tuning...\n"
- # useful for chroot
- # /etc/resolv.conf
- grep -i 'search ' /etc/resolv.conf > "${partialfs}/etc/resolv.conf"
- grep -i 'nameserver ' /etc/resolv.conf >> "${partialfs}/etc/resolv.conf"
-
- # fix boot-time interface config wipe under aggressive cap drop
- # (openrc 0.9.8.4 ~sep 2012 - https://bugs.gentoo.org/show_bug.cgi?id=436266)
- # initial warkaround was: sed -i -e 's/^#rc_nostop=""/rc_nostop="net.eth0 net.lo"/' "${partialfs}/etc/rc.conf"
- # but this one does not depends on interfaces names
- echo 'rc_keyword="-stop"' >> "${partialfs}/etc/conf.d/net"
-}
-
-cache_dev()
-{
- printf "### cache_dev(): /dev tuning...\n"
-
- #Wait for https://bugs.gentoo.org/show_bug.cgi?id=496054
- mkdir "${partialfs}/dev/pts"
- mkdir "${partialfs}/dev/shm"
- mkdir "${partialfs}/dev/mqueue"
-
- mkdir -m 755 "${partialfs}/dev/net"
- mknod -m 666 "${partialfs}/dev/net/tun" c 10 200
-
- return 0
-}
-
-# fix openrc system
-cache_openrc()
-{
- printf "### cache_openrc(): doing openrc tuning\n"
-
- #Wait for https://bugs.gentoo.org/show_bug.cgi?id=496054
- chroot "${partialfs}" sed s/-lxc//g -i "/etc/init.d/devfs"
-
- return 0
-}
-
-cache_locale()
-{
- printf "### cache_locale(): initiating minimale locale en_US.UTF-8 \n"
-
- echo "en_US.UTF-8 UTF-8" >> "${partialfs}/etc/locale.gen"
- chroot "${partialfs}" locale-gen
-
- return 0
-}
-
-################################################################################
-# CONTAINER Preparation
-################################################################################
-
-container_setup() {
- printf "##### container_setup(): starting container setup\n"
-
- #in most cases lxc-create should have provided a copy of default lxc.conf
- #let's tag where template starts, or just create the files
- echo '### lxc-gentoo template stuff starts here' >> "$path/config"
-
- #Determine rootfs
- #If backingstore was specified, lxc.rootfs.path should be present or --rootfs did the rootfs var creation
- if [ -z "${rootfs}" ]; then
- rootfs=`awk -F= '$1 ~ /^lxc.rootfs.path/ { print $2 }' "$path/config" 2>/dev/null`
- if [ -z "${rootfs}" ]; then
- #OK it's default
- rootfs="${path}/rootfs"
- fi
- fi
- store_user_message "rootfs of container is : ${rootfs}"
- store_user_message "config of container is : ${path}/config"
-
- container_precheck && \
- container_rootfs && \
- container_consoles && \
- container_tz && \
- container_portage && \
- container_net && \
- container_hostname && \
- container_auth && \
- container_sshd && \
- container_conf
- if [ $? -ne 0 ]; then
- die 1 "container_setup(): one step didn't complete, sorry\n"
- fi
-
- printf "###### container_setup(): container should be ready to start!\n"
- printf "\n\n"
- printf "You could now use you container with: lxc-start -n %s\n" "${name}"
- printf "little things you should know about your container:\n"
- printf "${user_message}"
- return 0
-}
-
-container_precheck()
-{
- printf "### container_precheck(): doing some pre-start checks ...\n"
- # never hurts to have a fail-safe.
- [[ -n "${name//\/}" ]] \
- || die 8 "\$name (%s) IS EMPTY OR MADE OF ONLY DIRECTORY SEPARATORS, THIS IS *VERY* BAD!\n" "${name}"
-
- [[ -n "${rootfs//\/}" ]] \
- || die 8 "\$rootfs (%s) IS EMPTY OR MADE OF ONLY DIRECTORY SEPARATORS, THIS IS *VERY* BAD!\n" "${rootfs}"
-
- [[ -n "${cachefs//\/}" ]] \
- || die 8 "\$cachefs (%s) IS EMPTY OR MADE OF ONLY DIRECTORY SEPARATORS, THIS IS *VERY* BAD!\n" "${cachefs}"
-
- # check if the rootfs already exists
- [[ -d "${rootfs}/etc" ]] && die 18 "Error: \$rootfs (%s) already exists!" "${rootfs}"
-
- # check cache
- [[ ! -d "${cachefs}/etc" ]] && die 1 "Error: \$cachefs (%s) not found!" "${cachefs}"
-
- return 0
-}
-
-container_rootfs()
-{
- printf "#### container_rootfs(): copying rootfs %s from cache %s ...\n" "${rootfs}" "${cachefs}"
- tar -c -f - --numeric-owner -C "${cachefs}" . \
- | tar -x -p -f - --numeric-owner -C "${rootfs}" \
- || die 1 "Error: cache copy to rootfs failed"
-
- printf "chroot test..."
- chroot "${rootfs}" /bin/true || die 1 "Error: 'chroot %s /bin/true' failed"
- printf " OK\n"
-
- printf " => done\n"
- return 0
-}
-
-container_consoles() {
- printf "#### container_consoles(): setting container consoles ...\n"
-
- # disable unwanted ttys
- if [[ ${tty} < 6 ]]; then
- local mindis=$(( ${tty} + 1 ))
- sed -i "s/^c[${mindis}-6]/#&/" "${rootfs}/etc/inittab"
- fi
- printf " => main console + ${tty} ttys\n"
-
- if [[ -z "${autologin}" ]]; then
- sed 's/agetty -a root/agetty/' -i "${rootfs}/etc/inittab"
- elif [[ "${user}" != "root" ]]; then
- sed "s/agetty -a root/agetty -a ${user}/" -i "${rootfs}/etc/inittab"
- printf " => Autologin on main console for %s enabled\n" "${user}"
- [[ -z "${forced_password}" ]] && unset password
- store_user_message "${user} has autologin on main console"
- else
- printf " => Autologin on main console for root enabled\n"
- [[ -z "${forced_password}" ]] && unset password
- store_user_message "${user} has autologin on main console"
- fi
- printf " => done\n"
-}
-
-container_tz()
-{
- printf "#### container_tz(): setting container timezone ...\n"
-
- #let's try to copy it from host
- if [ -L "/etc/localtime" ]; then
- #host has a symlink
- #let see if we can reproduct symlink
- target=$(readlink /etc/localtime)
- if [[ "$target" != "" ]]; then
- if [ -f "${rootfs}/${target}" ]; then
- #same target exists in container
- chroot "${rootfs}" ln -sf "${target}" "/etc/localtime"
- printf " => host symlink reproducted in container : %s\n" "${target}"
- store_user_message "timezone copyed from host"
- return 0
- fi
- fi
- fi
-
- if [ -e /etc/localtime ]; then
- # duplicate host timezone
- cat /etc/localtime > "${rootfs}/etc/localtime"
- printf " => host localtime copyed to container\n"
- store_user_message "timezone was staticly copyed from host"
- else
- # otherwise set up UTC
- chroot "${rootfs}" ln -sf /usr/share/zoneinfo/UTC /etc/localtime
- printf " => fallback: fixed to UTC\n"
- store_user_message "timezone was fixed to UTC"
- fi
-}
-
-
-container_portage()
-{
- printf "#### container_portage(): setting container portage... \n"
-
- #default entry for conf
- portage_mount="#container set with private portage tree, no mount here"
-
- printf "Warnings are normal here, don't worry\n"
- #container repos detection
- if chroot ${rootfs} portageq get_repo_path / gentoo > /dev/null ; then
- portage_container="$(chroot ${rootfs} portageq get_repo_path / gentoo)"
- else
- die 1 "Failed to figure out container portage tree location with portageq get_repo_path / gentoo\n"
- fi
-
- if [[ -n "${private_portage}" ]]; then
- container_private_portage
- return 0
- fi
-
- if [ -z "${portage_dir}" ]; then
- #gentoo host detection
- printf "trying to guess portage_dir from host...\n"
- portage_dir="$(portageq get_repo_path / gentoo 2>/dev/null)"
- if [ ! -d "${portage_dir}/profiles" ]; then
- printf " => host portage detection failed (not gentoo host), fallback to private portage tree\n"
- container_private_portage
- return 0
- fi
- else
- if [ ! -d "${portage_dir}/profiles" ]; then
- die 1 "specified portage_dir (%s) does not contains profiles, is it a portage tree ?\n" "${portage_dir}"
- fi
- fi
-
- printf "trying to guess portage distfiles dir from host ...\n"
- portage_distfiles_dir="$(portageq distdir 2>/dev/null)"
- if [ ! -d "${portage_distfiles_dir}" ]; then
- portage_distfiles_dir="${portage_dir}/distfiles"
- fi
-
- # if we are here, we have shared portage_dir
- #ensure dir exists
- chroot "${rootfs}" mkdir ${portage_container}
- portage_mount="#container set with shared portage
-lxc.mount.entry=${portage_dir} ${portage_container/\//} none ro,bind 0 0
-lxc.mount.entry=${portage_distfiles_dir} ${portage_container/\//}/distfiles none rw,bind 0 0
-#If you use eix, you should uncomment this
-#lxc.mount.entry=/var/cache/eix var/cache/eix none ro,bind 0 0"
- store_user_message "container has a shared portage from host's ${portage_dir} to ${portage_container/\//}"
- #Let's propose binary packages
- cat <<- EOF >> "${rootfs}/etc/portage/make.conf"
-# enable this to store built binary packages
-#FEATURES="\$FEATURES buildpkg"
-
-# enable this to use built binary packages
-#EMERGE_DEFAULT_OPTS="\${EMERGE_DEFAULT_OPTS} --usepkg"
-
-# enable and *tune* this kind of entry to slot binaries, specialy if you use multiples archs and variants
-#PKGDIR="\${PKGDIR}/amd64
-#or PKGDIR="\${PKGDIR}/hardened"
-EOF
- printf " => portage stuff done, see /etc/portage/make.conf for additional tricks\n"
-
-}
-
-container_private_portage()
-{
- #called from container_portage() do not call directly from container_setup
- printf "# untaring private portage to %s from %s ... \n" "${rootfs}/${portage_container}" "${portage_cache}"
- mkdir -p "${rootfs}/${portage_container}"
- execute_exclusively portage 60 \
- tar -xp --strip-components 1 -C "${rootfs}/${portage_container}" \
- -f "${portage_cache}" --numeric-owner \
- || die 2 "Error: unable to extract the portage tree.\n"
- store_user_message "container has its own portage tree at ${portage_container}"
- printf "=> done\n"
-}
-
-#helper func for container_genconf_net()
-nic_write()
-{
- #display with gentoo's confd.net format
- echo "config_${nic_name}=\"${nic_conf}\""
- #add to managed list
- [[ "${nic_conf}" == "dhcp" ]] && nic_managed="${nic_managed} ${nic_name}"
- [[ "${nic_conf}" == "null" ]] && nic_unmanaged="${nic_unmanaged} ${nic_name}"
- [[ -z "${nic_hwaddr}" && ${nic_type} == "veth" ]] && nic_wo_hwaddr="${nic_wo_hwaddr} ${nic_name}"
- nic_writed=1
-}
-
-#Analyse lxc.conf and print conf.d/net content
-container_conf_net()
-{
- local file=${1}
- [[ -z "${nic_last}" ]] && nic_last=-1
- [[ -z "${nic_named}" ]] && nic_named=0
- OLDIFS=$IFS
- IFS="
-"
- #let's do some drity bash things to parse lxc network conf
- for line in $( sed -r "s/[ ]*=[ ]*/_real_ugly_sep_42_/" "${file}" ); do
- key=$(echo "${line}" | sed 's/_real_ugly_sep_42_.*$//')
- value=$(echo "${line}" | sed 's/^.*_real_ugly_sep_42_//')
-
- #new nic !
- if [[ "${key}" == "lxc.net.0.type" ]]; then
- #we don't know what to do with it.
- [[ "${value}" == "empty" ]] && continue
-
- #write conf from previous loops
- [[ "${nic_writed}" == "0" ]] && nic_write
-
- #init defaults
- let nic_last=nic_last+1
-
- nic_writed=0
- #if 1 named between 2 not named: last is eth1
- #=> Number is ID munis number of named NIC before
- nic_name="eth$(( ${nic_last} - ${nic_named} ))"
- nic_conf="dhcp"
- nic_type="${value}"
- fi
-
- if [[ "${key}" == "lxc.net.0.hwaddr" ]]; then
- nic_hwaddr=1
- fi
-
- if [[ "${key}" =~ ^lxc.net.0.ipv(4|6) ]]; then
- #tell openrc to not manage this NIC as LXC set there address
- nic_conf="null"
- fi
- if [[ "${key}" =~ ^lxc.net.0.name ]]; then
- nic_name="${value}"
- let nic_named=nic_named+1
- fi
- if [[ "${key}" == "lxc.include" ]]; then
- #recursive into include
- container_conf_net "${value}"
- fi
- done
- #write conf from previous loops
- [[ "${nic_writed}" == "0" ]] && nic_write
- IFS=$OLDIFS
-}
-
-container_net()
-{
- printf "container_net(): setting container network conf... \n"
-
- #Analyse network configuration in config
- container_conf_net "$path/config" >> "${rootfs}/etc/conf.d/net"
-
- # found how much nic finally have
- nic_count=$(( ${nic_last} + 1 ))
-
- # unless openrc manage a nic, we now have to force openrc to automatic
- # provision of the 'net' dep. If we do not, network dependent services
- # will fail to load
- if [[ -z "${nic_managed}" ]]; then
- #tell openrc that lxc already did the work
- echo 'rc_provide="net"' >> "${rootfs}/etc/rc.conf"
- fi
-
- #No NIC ?
- if [[ ${nic_count} == 0 ]]; then
- #If no Nic, no need to continue
- bridge=$(brctl show | awk 'NR==2 {print $1}')
- if [[ "${bridge}" != "" ]]; then
- store_user_message "No network interface for this container
-It's a pitty, you have bridge, ${bridge}.
-If it is for Lxc, use it next time by adding this to your default.conf :
-lxc.net.0.type = veth
-lxc.net.0.link = ${bridge}
-lxc.net.0.flags = up
-lxc.net.0.hwaddr = fe:xx:xx:xx:xx:xx"
- return 0
- else
- store_user_message "No network interface for this container"
- return 0
- fi
- fi
-
- #For each openrc managed nic, activate
- sys_nic_index=1
- for nic in ${nic_managed}
- do
- chroot "${rootfs}" ln -s net.lo "/etc/init.d/net.${nic}"
- chroot "${rootfs}" rc-update add net.${nic} default
- #fake sysfs for openrc, in case settings does not provide it
- mkdir -p "${rootfs}/sys/class/net/${nic}"
- echo ${sys_nic_index} > "${rootfs}/sys/class/net/${nic}/ifindex"
- echo up > "${rootfs}/sys/class/net/${nic}/operstate"
- let sys_nic_index=sys_nic_index+1
- done
-
- #Warn about dynamic hwaddr
- if [[ -n "${nic_wo_hwaddr}" ]]; then
- store_user_message "Warning, these veth NIC don't have fixed hwaddr :
-${nic_wo_hwaddr}
-
-see http://lists.linuxcontainers.org/pipermail/lxc-devel/2013-December/006736.html
-and man lxc.conf"
- fi
-
- printf " => network conf done.\n"
-}
-
-# custom hostname
-container_hostname()
-{
- printf "#### container_hostname(): setting hostname... \n"
- printf "hostname=\"%s\"\n" "${name}" > "${rootfs}/etc/conf.d/hostname"
- printf " => done.\n"
-}
-
-container_auth()
-{
- printf "#### container_auth(): setting authentification... \n"
- if [[ "${user}" != "root" ]]; then
- printf " non root user requested, creating... \n"
- chroot "${rootfs}" useradd --create-home -s /bin/bash "${user}" || die 1 "failed to create user ${user}"
- printf " => user %s created\n" "${user}"
- fi
- store_user_message "Connection user is ${user}"
- #Home of user
- auth_home=$(chroot "${rootfs}" getent passwd "${user}" | cut -d : -f 6)
- if [[ -r "${auth_key}" ]]; then
- printf " deploying auth_key %s for user %s ...\n" "${auth_key}" "${user}"
- mkdir -p "${rootfs}/${auth_home}/.ssh"
- cat "${auth_key}" >> "${rootfs}/${auth_home}/.ssh/authorized_keys"
- chroot "${rootfs}" chown "${user}:" "${auth_home}/.ssh/authorized_keys"
- printf " => inserted public key in %s/.ssh/authorized_keys\n" "${auth_home}"
- [[ -z "${forced_password}" ]] && unset password
- store_user_message "${user} has the ssh key you gave us"
- fi
-
- if [[ -n "${password}" ]]; then
- printf " setting password for %s ...\n" "${user}"
- echo "${user}:${password}" | chroot "${rootfs}" chpasswd || die 1 "failed to change password"
- printf " => done. if you didn't specify , default is 'toor'\n"
- if [[ -n "${forced_password}" ]]; then
- store_user_message "${user} has the password you give for him"
- fi
- fi
-
- printf " => done.\n"
-}
-
-container_sshd() {
- printf "#### container_sshd(): enabling sshd... \n"
-
- chroot "${rootfs}" rc-update add sshd || die 1 "failed to enable sshd\n"
-
- printf " => done.\n"
-}
-
-################################################################################
-# lxc configuration files
-################################################################################
-
-container_conf()
-{
- printf "container_configuration(): making lxc configuration file... \n"
-
- #at this point if there
- conf_file="${path}/config"
-
- # if there is exactly one veth network entry, make sure it has an
- # associated hwaddr.
- nics=`grep -e '^lxc\.net\.0\.type[ \t]*=[ \t]*veth' ${conf_file} | wc -l`
- if [ $nics -eq 1 ]; then
- grep -q "^lxc.net.0.hwaddr" ${conf_file} || sed -i -e "/^lxc\.net\.0\.type[ \t]*=[ \t]*veth/a lxc.net.0.hwaddr = 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//')" ${conf_file}
- fi
-
- if grep -q "^lxc.rootfs.path" "${conf_file}" ; then
- #lxc-create already provided one
- conf_rootfs_line=""
- else
- conf_rootfs_line="lxc.rootfs.path = $(readlink -f "${rootfs}")"
- fi
- if [[ "${arch}" == "x86" || "${arch}" == "amd64" ]]; then
- local conf_arch_line="lxc.arch = ${arch}"
- else
- local conf_arch_line="# lxc.arch = ${arch}"
- fi
-
- cat <<- EOF >> "${conf_file}"
-# sets container architecture
-# If desired architecture != amd64 or x86, then we leave it unset as
-# LXC does not oficially support anything other than x86 or amd64.
-${conf_arch_line}
-
-# set the hostname
-lxc.uts.name = ${name}
-lxc.tty.max = ${tty}
-
-${conf_rootfs_line}
-${portage_mount}
-${conf_sysfs}
-${conf_mounts}
-
-lxc.include = ${LXC_TEMPLATE_CONFIG}/gentoo.${settings}.conf
-EOF
- printf " => done.\n"
-}
-
-usage()
-{
- cat <<EOF
-$1 -h|--help [-a|--arch <arch>] [-v|--variant <variant>] [-P|--private-portage] [--portage-dir <protagedir>] [-t|--tarball <stage3file>]
- [-F|--flush-cache] [-c|--cache-only] [-u|--user <username>] [-w|--password <password>] [--autologin] [-S|--auth-key <keyfile>]
- [-s|--settings <name>] [-m|--mirror <gentoomirror>] [--tty <number>]
-
-arch: the container architecture (e.g. amd64): defaults to host arch (currently: '${arch}')
- If you choose one that needs emulation
- tested: amd64, x86
- You could try any other gentoo arch, why not...
-
-variant: gentoo's Architecture variant as of dec 2013 : (currently: '${variant}')
- for amd64 arch: amd64 (default), amd64-hardened+nomultilib, amd64-hardened, amd64-nomultilib, x32
- for x86 arch: i686 (default), i486, i686-hardened
- for arm arch: armv7a (default), armv7a_hardfp, armv6j, armv6j_hardfp, armv5tel, armv4tl
-
-private-portage: by default, /usr/portage is mount-binded with host one if exists (currently: '${private_portage}')
- this force container to have his own copy
-
-portage-dir: portage dir used for shared portage
- by default the host on if any (currently: '${portage_dir}')
-
-tarball: force usage of local stage3 archive (currently: '${arch}')
- If empty, latest will be downloaded
-
-flush-cache: do like there is no previous cache
-
-cache-only: just ensure cache is present
- if cache exists and "flush-cache" not specified, does nothing
-
-user: user used in auth oriented options (currently: '${user}')
-
-password: password for user (currently: '${password}')
- if default, usage of auth-key will disable password setting
-
-autologin: enable autologin for user (currently: '${autologin}')
- This unset default password setting
-
-auth-key: SSH Public key file to inject into container for user (currently: '${auth_key}')
- This unset default password setting
-
-settings: choose common configuration (currently: '${settings}')
- see ${LXC_TEMPLATE_CONFIG}/gentoo.*.conf
- Available settings:
- $(ls -1 ${LXC_TEMPLATE_CONFIG}/gentoo.*.conf | xargs basename -a -s .conf | sed 's/^gentoo.//')
-
-mirror: gentoo mirror for download (currently: '${mirror}')
-
-tty: number of tty (6 max) (currently: '${tty}')
-EOF
- exit 0
-}
-
-#some overridable defaults
-set_default_arch
-
-mirror="http://distfiles.gentoo.org"
-user="root"
-tty=1
-settings="common"
-options=$(getopt -o hp:n:a:FcPv:t:S:u:w:s:m: -l help,rootfs:,path:,name:,arch:,flush-cache,cache-only,private-portage,variant:,portage-dir:,tarball:,auth-key:,user:,autologin,password:,settings:,mirror:,tty: -- "$@")
-
-eval set -- "$options"
-
-while true
-do
- case "$1" in
- -h|--help) usage $0 && exit 0;;
- --rootfs) rootfs=$2; shift 2;;
- -p|--path) path=$2; shift 2;;
- -n|--name) name=$2; shift 2;;
- -a|--arch) arch=$2; shift 2;;
- -F|--flush-cache) flush_cache=1; shift 1;;
- -c|--cache-only) cache_only=1; shift 1;;
- -P|--private-portage) private_portage=1; shift 1;;
- -v|--variant) variant=$2; shift 2;;
- --portage-dir) portage_dir=$2; shift 2;;
- -t|--tarball) tarball=$2; shift 2;;
- -S|--auth-key) auth_key=$2; shift 2;;
- -u|--user) user=$2; shift 2;;
- -w|--password) forced_password=1; password=$2; shift 2;;
- -s|--settings) settings=$2; shift 2;;
- -m|--mirror) mirror=$2; shift 2;;
- --container-cache) containercache=$2; shift 2;;
- --tty) [[ $2 -lt 6 ]] && tty=$2; shift 2;;
- --autologin) autologin=1; shift 1;;
- --) shift 1; break ;;
- *) break ;;
- esac
-done
-
-# Allow the cache path to be set by environment variable
-cacheroot="${LXC_CACHE_PATH:-"@LOCALSTATEDIR@/cache/lxc"}/gentoo"
-portage_cache="${cacheroot}/portage.tbz"
-cachefs="${cacheroot}/rootfs-${arch}-${variant}"
-
-alias wget="wget --timeout=8 --read-timeout=15 -c -t10 -nd"
-
-do_all() {
- cache_setup
- if [ -z "${cache_only}" ]; then
- container_setup
- fi
-}
-
-execute_exclusively "cache-${arch}-${variant}" 60 do_all
+++ /dev/null
-#!/bin/bash
-
-#
-# template script for generating openmandriva container for LXC
-#
-
-#
-# lxc: linux Container library
-
-# Authors:
-# Alexander Khryukin <alexander@mezon.ru>
-# Vokhmin Alexey V <avokhmin@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
-#
-
-# Detect use under userns (unsupported)
-for arg in "$@"; do
- [ "$arg" = "--" ] && break
- if [ "$arg" = "--mapped-uid" -o "$arg" = "--mapped-gid" ]; then
- echo "This template can't be used for unprivileged containers." 1>&2
- echo "You may want to try the \"download\" template instead." 1>&2
- exit 1
- fi
-done
-
-# Make sure the usual locations are in PATH
-export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
-
-#Configurations
-#distro=cooker
-hostarch=$(uname -m)
-# Allow the cache base to be set by environment variable
-cache_base="${LXC_CACHE_PATH:-@LOCALSTATEDIR@/cache/lxc/openmandriva/$arch}"
-default_path=@LXCPATH@
-default_profile=default
-lxc_network_type=veth
-lxc_network_link=br0
-
-# is this openmandriva?
-[ -f /etc/mandriva-release ] && is_openmandriva=true
-
-configure_openmandriva()
-{
-mkdir -p ${rootfs_path}/etc/sysconfig/network-scripts/
-
- # configure the network using the dhcp
- cat <<EOF > ${rootfs_path}/etc/sysconfig/network-scripts/ifcfg-eth0
-DEVICE=eth0
-ONBOOT=yes
-BOOTPROTO=dhcp
-NM_CONTROLLED=no
-HOSTNAME=${utsname}
-EOF
-
- # set the hostname
- cat <<EOF > ${rootfs_path}/etc/sysconfig/network
-NETWORKING=yes
-HOSTNAME=${utsname}
-EOF
-
-echo "${utsname}" > ${rootfs_path}/etc/hostname
-
- # set minimal hosts
- cat <<EOF > $rootfs_path/etc/hosts
-127.0.0.1 localhost.localdomain localhost $utsname
-::1 localhost6.localdomain6 localhost6
-EOF
-}
-
-populate_dev()
-{
- echo -n "Create devices in /dev/"
- dev_path="${rootfs_path}/dev"
- rm -rf $dev_path
- mkdir -p $dev_path
- mknod -m 666 ${dev_path}/null c 1 3
- mknod -m 666 ${dev_path}/zero c 1 5
- mknod -m 666 ${dev_path}/random c 1 8
- mknod -m 666 ${dev_path}/urandom c 1 9
- mkdir -m 755 ${dev_path}/pts
- mkdir -m 1777 ${dev_path}/shm
- mknod -m 666 ${dev_path}/tty c 5 0
- mknod -m 666 ${dev_path}/tty0 c 4 0
- mknod -m 666 ${dev_path}/tty1 c 4 1
- mknod -m 666 ${dev_path}/tty2 c 4 2
- mknod -m 666 ${dev_path}/tty3 c 4 3
- mknod -m 666 ${dev_path}/tty4 c 4 4
- mknod -m 600 ${dev_path}/console c 5 1
- mknod -m 666 ${dev_path}/full c 1 7
- mknod -m 600 ${dev_path}/initctl p
- mknod -m 666 ${dev_path}/ptmx c 5 2
- mkdir -m 755 ${dev_path}/net
- mknod -m 666 ${dev_path}/net/tun c 10 200
-
-}
-
-set_guest_root_password()
-{
- [ -z "$root_password" ] && return # pass is empty, abort
-
- echo " - setting guest root password.."
- echo "root passwd is: $root_password"
- echo "root:$root_password" | chroot "$rootfs_path" chpasswd
- echo "done."
-}
-
-create_chroot_openmandriva()
-{
- # check the mini openmandriva was not already downloaded
- INSTALL_ROOT=$cache/cache
- mkdir -p $INSTALL_ROOT
- if [ $? -ne 0 ]; then
- echo "Failed to create '$INSTALL_ROOT' directory"
- return 1
- fi
- # package list to install
- PKG_LIST="basesystem-minimal locales locales-en initscripts urpmi cronie dhcp-client kbd"
- # download a mini openmandriva into a cache
- echo "Downloading openmandriva minimal ..."
- URPMI="/usr/sbin/urpmi.addmedia --urpmi-root $INSTALL_ROOT main http://abf.rosalinux.ru/downloads/$release/repository/$arch/main/release"
- echo $URPMI
- URPMI_BASE="/usr/sbin/urpmi --no-suggests --no-verify-rpm --ignorearch --root $INSTALL_ROOT --urpmi-root $INSTALL_ROOT --auto $PKG_LIST"
- $URPMI
- $URPMI_BASE
- # We're splitting the old loop into two loops plus a directory retrival.
- # First loop... Try and retrive a mirror list with retries and a slight
- # delay between attempts...
- if [ $? -ne 0 ]; then
- echo "Failed to download the rootfs, aborting."
- return 1
- fi
-
- mv "$INSTALL_ROOT" "$cache/rootfs"
- echo "Download complete."
-
- return 0
-
-}
-
-copy_openmandriva()
-{
-
- echo -n "Copying rootfs to $rootfs_path ..."
- mkdir -p $rootfs_path
- rsync -SHaAX $cache/rootfs/ $rootfs_path/
- return 0
-}
-
-update_openmandriva()
-{
- echo "automated update in progress..."
- urpmi --root $cache/rootfs --urpmi-root $cache/rootfs --auto --auto-update --ignorearch
-}
-
-configure_openmandriva_systemd()
-{
- chroot ${rootfs_path} ln -s /dev/null /etc/systemd/system/proc-sys-fs-binfmt_misc.automount
- chroot ${rootfs_path} ln -s /dev/null /etc/systemd/system/systemd-udevd.service
- chroot ${rootfs_path} ln -s /dev/null /etc/systemd/system/systemd-udevd-control.socket
- chroot ${rootfs_path} ln -s /dev/null /etc/systemd/system/systemd-udevd-kernel.socket
- # remove numlock service
- # KDGKBLED: Inappropriate ioctl for device
- rm -f ${rootfs_path}/etc/systemd/system/getty@.service.d/enable-numlock.conf
-
- unlink ${rootfs_path}/etc/systemd/system/default.target
- chroot ${rootfs_path} ln -s /lib/systemd/system/multi-user.target /etc/systemd/system/default.target
- sed -i 's!ConditionPathExists=/dev/tty0!ConditionPathExists=|/dev/tty0\nConditionVirtualization=|lxc!' \
- ${rootfs_path}/lib/systemd/system/getty\@.service
-}
-
-
-install_openmandriva()
-{
- mkdir -p @LOCALSTATEDIR@/lock/subsys/
- (
- flock -x 9
- if [ $? -ne 0 ]; then
- echo "Cache repository is busy."
- return 1
- fi
-
- echo "Checking cache download in $cache/rootfs ... "
- if [ ! -e "$cache/rootfs" ]; then
- echo $cache/rootfs
- create_chroot_openmandriva
- if [ $? -ne 0 ]; then
- echo "Failed to download 'openmandriva basesystem-minimal'"
- return 1
- fi
- else
- echo "Cache found. Updating..."
- update_openmandriva
- if [ $? -ne 0 ]; then
- echo "Failed to update 'openmandriva base', continuing with last known good cache"
- else
- echo "Update finished"
- fi
- fi
-
- echo "Copy $cache/rootfs to $rootfs_path ... "
- copy_openmandriva
- if [ $? -ne 0 ]; then
- echo "Failed to copy rootfs"
- return 1
- fi
- return 0
- ) 9>@LOCALSTATEDIR@/lock/subsys/lxc-openmandriva
-
- return $?
-}
-
-copy_configuration()
-{
-
- mkdir -p $config_path
- grep -q "^lxc.rootfs.path" $config_path/config 2>/dev/null || echo "lxc.rootfs.path = $rootfs_path" >> $config_path/config
- cat <<EOF >> $config_path/config
-lxc.uts.name = $name
-lxc.tty.max = 4
-lxc.pty.max = 1024
-lxc.cap.drop = sys_module mac_admin mac_override sys_time
-lxc.mount.auto = cgroup:mixed proc:mixed sys:mixed
-
-# When using LXC with apparmor, uncomment the next line to run unconfined:
-#lxc.apparmor.profile = unconfined
-
-#networking
-lxc.net.0.type = $lxc_network_type
-lxc.net.0.flags = up
-lxc.net.0.link = $lxc_network_link
-lxc.net.0.name = eth0
-lxc.net.0.mtu = 1500
-EOF
-if [ ! -z ${ipv4} ]; then
- cat <<EOF >> $config_path/config
-lxc.net.0.ipv4.address = $ipv4
-EOF
-fi
-if [ ! -z ${gw} ]; then
- cat <<EOF >> $config_path/config
-lxc.net.0.ipv4.gateway = $gw
-EOF
-fi
-if [ ! -z ${ipv6} ]; then
- cat <<EOF >> $config_path/config
-lxc.net.0.ipv6.address = $ipv6
-EOF
-fi
-if [ ! -z ${gw6} ]; then
- cat <<EOF >> $config_path/config
-lxc.net.0.ipv6.gateway = $gw6
-EOF
-fi
- cat <<EOF >> $config_path/config
-#cgroups
-lxc.cgroup.devices.deny = a
-# /dev/null and zero
-lxc.cgroup.devices.allow = c 1:3 rwm
-lxc.cgroup.devices.allow = c 1:5 rwm
-# 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
-# rtc
-lxc.cgroup.devices.allow = c 10:135 rwm
-EOF
-
- if [ $? -ne 0 ]; then
- echo "Failed to add configuration"
- return 1
- fi
-
- return 0
-}
-
-clean()
-{
-
- if [ ! -e $cache ]; then
- exit 0
- fi
-
- # lock, so we won't purge while someone is creating a repository
- (
- flock -x 9
- if [ $? != 0 ]; then
- echo "Cache repository is busy."
- exit 1
- fi
-
- echo -n "Purging the download cache for OpenMandriva-$release..."
- rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1
- exit 0
- ) 9>@LOCALSTATEDIR@/lock/subsys/lxc-openmandriva
-}
-
-usage()
-{
- cat <<EOF
-usage:
- $1 -n|--name=<container_name>
- [-p|--path=<path>] [-c|--clean] [-R|--release=<openmandriva2013.0/rosa2012.1/cooker/ release>]
- [-4|--ipv4=<ipv4 address>] [-6|--ipv6=<ipv6 address>]
- [-g|--gw=<gw address>] [-d|--dns=<dns address>]
- [-P|--profile=<name of the profile>] [--rootfs=<path>]
- [-A|--arch=<arch of the container>]
- [-h|--help]
-Mandatory args:
- -n,--name container name, used to as an identifier for that container from now on
-Optional args:
- -p,--path path to where the container rootfs will be created, defaults to @LXCPATH@. The container config will go under @LXCPATH@ in that case
- -c,--clean clean the cache
- -R,--release openmandriva2013.0/cooker/rosa2012.1 release for the new container. if the host is OpenMandriva, then it will default to the host's release.
- -4,--ipv4 specify the ipv4 address to assign to the virtualized interface, eg. 192.168.1.123/24
- -6,--ipv6 specify the ipv6 address to assign to the virtualized interface, eg. 2003:db8:1:0:214:1234:fe0b:3596/64
- -g,--gw specify the default gw, eg. 192.168.1.1
- -G,--gw6 specify the default gw, eg. 2003:db8:1:0:214:1234:fe0b:3596
- -d,--dns specify the DNS server, eg. 192.168.1.2
- -P,--profile Profile name is the file name in /etc/lxc/profiles contained packages name for install to cache.
- -A,--arch Define what arch the container will be [i586,x86_64,armv7l,armv7hl]
- ---rootfs rootfs path
- -h,--help print this help
-EOF
- return 0
-}
-
-options=$(getopt -o hp:n:P:cR:4:6:g:d:A -l help,rootfs:,path:,name:,profile:,clean:,release:,ipv4:,ipv6:,gw:,dns:,arch: -- "$@")
-if [ $? -ne 0 ]; then
- usage $(basename $0)
- exit 1
-fi
-eval set -- "$options"
-
-release=${release:-"cooker"}
-if [ -f /etc/lsb-release ]; then
- . /etc/lsb-release
- if [ "$DISTRIB_ID" = "OpenMandrivaLinux" ]; then
- release=openmandriva2013.0
- elif [ "$DISTRIB_ID" = "RosaDesktop.Fresh" ]; then
- release=rosa2012.1
- else
- echo "This is not an OpenMandriva or ROSA release"
- exit 1
- fi
-fi
-
-while true
-do
- case "$1" in
- -h|--help) usage $0 && exit 0;;
- -p|--path) path=$2; shift 2;;
- --rootfs) rootfs_path=$2; shift 2;;
- -n|--name) name=$2; shift 2;;
- -P|--profile) profile=$2; shift 2;;
- -c|--clean) clean=1; shift 1;;
- -R|--release) release=$2; shift 2;;
- -A|--arch) arch=$2; shift 2;;
- -4|--ipv4) ipv4=$2; shift 2;;
- -6|--ipv6) ipv6=$2; shift 2;;
- -g|--gw) gw=$2; shift 2;;
- -d|--dns) dns=$2; shift 2;;
- --) shift 1; break ;;
- *) break ;;
- esac
-done
-
-arch=${arch:-$hostarch}
-
-if [ ! -z "$clean" -a -z "$path" ]; then
- clean || exit 1
- exit 0
-fi
-
-if [ -z "${utsname}" ]; then
- utsname=${name}
-fi
-
-type urpmi >/dev/null 2>&1
-if [ $? -ne 0 ]; then
- echo "'urpmi' command is missing"
- exit 1
-fi
-
-if [ -z "$path" ]; then
- path=$default_path
-fi
-
-if [ -z "$profile" ]; then
- profile=$default_profile
-fi
-
-if [ $hostarch = "i586" -a $arch = "x86_64" ]; then
- echo "can't create x86_64 container on i586"
- exit 1
-fi
-
-if [ -z "$ipv4" -a -z "$ipv6" ]; then
- BOOTPROTO="dhcp"
-else
- BOOTPROTO="static"
-fi
-
-if [ "$(id -u)" != "0" ]; then
- echo "This script should be run as 'root'"
- exit 1
-fi
-
-# check for 'lxc.rootfs.path' passed in through default config by lxc-create
-if [ -z "$rootfs_path" ]; then
- if grep -q '^lxc.rootfs.path' $path/config 2>/dev/null ; then
- rootfs_path=$(awk -F= '/^lxc.rootfs.path =/{ print $2 }' $path/config)
- else
- rootfs_path=$path/$name/rootfs
- fi
-fi
-
-config_path=$default_path/$name
-cache=$cache_base/$release/$arch/$profile
-
-if [ ! -f $config_path/config ]; then
- echo "A container with that name exists, chose a different name"
- exit 1
-fi
-
-install_openmandriva
-if [ $? -ne 0 ]; then
- echo "failed to install openmandriva"
- exit 1
-fi
-
-configure_openmandriva
-if [ $? -ne 0 ]; then
- echo "failed to configure openmandriva for a container"
- exit 1
-fi
-
-# If the systemd configuration directory exists - set it up for what we need.
-if [ -d ${rootfs_path}/etc/systemd/system ]
-then
- configure_openmandriva_systemd
-fi
-
-populate_dev
-if [ $? -ne 0 ]; then
- echo "failed to populated /dev/ devices"
- exit 1
-fi
-
-set_guest_root_password
-if [ $? -ne 0 ]; then
- echo "failed to configure password for chroot"
- exit 1
-fi
-
-copy_configuration
-if [ $? -ne 0 ]; then
- echo "failed write configuration file"
- exit 1
-fi
-
-if [ ! -z "$clean" ]; then
- clean || exit 1
- exit 0
-fi
-echo "container rootfs and config created"
+++ /dev/null
-#!/bin/bash
-
-#
-# template script for generating OpenSUSE container for LXC
-#
-
-#
-# lxc: linux Container library
-
-# Authors:
-# Daniel Lezcano <daniel.lezcano@free.fr>
-# Frederic Crozat <fcrozat@suse.com>
-# Michael H. Warfield <mhw@WittsEnd.com>
-# Johannes Kastl <mail@ojkastl.de>
-# Thomas Lamprecht <t.lamprecht@proxmox.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
-
-# Detect use under userns (unsupported)
-for arg in "$@"; do
- [ "$arg" = "--" ] && break
- if [ "$arg" = "--mapped-uid" -o "$arg" = "--mapped-gid" ]; then
- echo "This template can't be used for unprivileged containers." 1>&2
- echo "You may want to try the \"download\" template instead." 1>&2
- exit 1
- fi
-done
-
-# Make sure the usual locations are in PATH
-export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
-
-if [ -x /usr/bin/obs-build ]; then
- BUILD=/usr/bin/obs-build
- export BUILD_DIR=/usr/lib/obs-build
-else
- BUILD=/usr/bin/build
- export BUILD_DIR=/usr/lib/build
-fi
-
-configure_opensuse()
-{
- rootfs=$1
- hostname=$2
-
- # set first network adapter as dhcp. This is the most common config.
- cat <<EOF > $rootfs/etc/sysconfig/network/ifcfg-eth0
-STARTMODE='auto'
-BOOTPROTO='dhcp'
-EOF
-
- # create empty fstab
- touch $rootfs/etc/fstab
-
- # set the hostname
- cat <<EOF > $rootfs/etc/HOSTNAME
-$hostname
-EOF
- # ensure /etc/hostname is available too
- ln -s -f HOSTNAME $rootfs/etc/hostname
-
- # do not use hostname from HOSTNAME variable
- cat <<EOF >> $rootfs/etc/sysconfig/cron
-unset HOSTNAME
-EOF
-
- # set minimal hosts
- cat <<EOF > $rootfs/etc/hosts
-127.0.0.1 localhost $hostname
-EOF
-
- # disable yast->bootloader in container
- cat <<EOF > $rootfs/etc/sysconfig/bootloader
-LOADER_TYPE=none
-LOADER_LOCATION=none
-EOF
-
- # set /dev/console as securetty
- cat << EOF >> $rootfs/etc/securetty
-console
-EOF
-
- cat <<EOF >> $rootfs/etc/sysconfig/boot
-# disable root fsck
-ROOTFS_FSCK="0"
-ROOTFS_BLKDEV="/dev/null"
-EOF
-
-
- # remove pointless services in a container
- ln -s /dev/null $rootfs/etc/systemd/system/proc-sys-fs-binfmt_misc.automount
- ln -s /dev/null $rootfs/etc/systemd/system/console-shell.service
- ln -s /dev/null $rootfs/etc/systemd/system/systemd-vconsole-setup.service
- # enable getty and console services
- sed -e 's/ConditionPathExists=.*//' $rootfs/usr/lib/systemd/system/getty@.service > $rootfs/etc/systemd/system/getty@.service
- ln -s getty@.service $rootfs/etc/systemd/system/getty@tty1.service
- mkdir -p $rootfs/etc/systemd/system/getty.target.wants/
- ln -s ../getty@.service $rootfs/etc/systemd/system/getty.target.wants/getty@console.service
- ln -s -f ../getty@.service $rootfs/etc/systemd/system/getty.target.wants/getty@tty1.service
- ln -s ../getty@.service $rootfs/etc/systemd/system/getty.target.wants/getty@tty2.service
- ln -s ../getty@.service $rootfs/etc/systemd/system/getty.target.wants/getty@tty3.service
- ln -s ../getty@.service $rootfs/etc/systemd/system/getty.target.wants/getty@tty4.service
-
- touch $rootfs/etc/sysconfig/kernel
-
- echo "Please change root-password !"
-
- return 0
-}
-
-download_opensuse()
-{
- cache=$1
- arch=$2
-
- if [ ! -x ${BUILD} ]; then
- echo "Could not create openSUSE template :"
- echo "you need to install \"build\" package"
- return 1
- fi
-
- # check the mini opensuse was not already downloaded
- mkdir -p "$cache/partial-$arch"
-
- if [ $? -ne 0 ]; then
- echo "Failed to create '$cache/partial-$arch' directory"
- return 1
- fi
-
- # download a mini opensuse into a cache
- echo "Downloading opensuse minimal ..."
- mkdir -p "$cache/partial-$arch-packages"
-
- oss_repo_url="http://download.opensuse.org/distribution/$DISTRO/repo/oss/"
- if [[ $DISTRO == "tumbleweed" ]]; then
- oss_repo_url="http://download.opensuse.org/$DISTRO/repo/oss/"
- fi
- zypper --quiet --root $cache/partial-$arch-packages --non-interactive ar "$oss_repo_url" repo-oss || return 1
-
- update_repo_url="http://download.opensuse.org/update/$DISTRO/repo/oss"
- # Leap update repos were rearranged
- if [[ $DISTRO == "leap/4"* ]]; then
- update_repo_url="http://download.opensuse.org/update/$DISTRO/oss/"
- fi
- # tumbleweed has no update repo
- if [[ $DISTRO != "tumbleweed" ]]; then
- zypper --quiet --root $cache/partial-$arch-packages --non-interactive ar "$update_repo_url" update || return 1
- fi
-
- zypper --quiet --root $cache/partial-$arch-packages --non-interactive --gpg-auto-import-keys update || return 1
- zypper --root $cache/partial-$arch-packages --non-interactive in --auto-agree-with-licenses --download-only zypper lxc patterns-openSUSE-base bash iputils sed tar rsyslog || return 1
-
- cat > $cache/partial-$arch-packages/opensuse.conf << EOF
-Preinstall: aaa_base bash coreutils diffutils
-Preinstall: filesystem fillup glibc grep insserv-compat perl-base
-Preinstall: libbz2-1 pam
-Preinstall: permissions rpm sed tar libz1 libselinux1
-Preinstall: liblzma5 libcap2 libacl1 libattr1
-Preinstall: libpopt0 libelf1
-Preinstall: libpcre1
-
-RunScripts: aaa_base
-
-Support: zypper
-Support: patterns-openSUSE-base
-Support: lxc
-Support: ncurses-utils
-Support: iputils
-Support: udev
-Support: netcfg
-Support: hwinfo insserv-compat module-init-tools openSUSE-release openssh
-Support: pwdutils sysconfig
-
-Ignore: rpm:suse-build-key,build-key
-Ignore: systemd:systemd-presets-branding
-EOF
-
- if [ $DISTRO = "13.2" ]
- then
- echo "Support: python3-base" >> $cache/partial-$arch-packages/opensuse.conf
- fi
-
- if [[ $DISTRO == "tumbleweed" ]]; then
- echo "Preinstall: liblua5_3 libncurses6 libreadline7" >> $cache/partial-$arch-packages/opensuse.conf
- else
- echo "Preinstall: liblua5_1 libncurses5 libreadline6" >> $cache/partial-$arch-packages/opensuse.conf
- echo "Support: rpcbind" >> $cache/partial-$arch-packages/opensuse.conf
- fi
-
- # dhcpcd is not in the default repos since Leap 42.1, neither in tumbleweed
- if [[ $DISTRO != "leap/4"* ]] && [[ $DISTRO != "tumbleweed" ]]; then
- echo "Support: dhcpcd" >> $cache/partial-$arch-packages/opensuse.conf
- fi
-
- # Leap and tumbleweed doesn't seem to have iproute2 utils installed
- if [[ $DISTRO == "leap/4"* ]] || [[ $DISTRO == "tumbleweed" ]]; then
- echo "Support: net-tools iproute2" >> $cache/partial-$arch-packages/opensuse.conf
- fi
-
- if [ "$arch" = "i686" ]; then
- mkdir -p $cache/partial-$arch-packages/var/cache/zypp/packages/repo-oss/suse/i686/
- for i in "$cache/partial-$arch-packages/var/cache/zypp/packages/repo-oss/suse/i586/*" ; do
- ln -s $i $cache/partial-$arch-packages/var/cache/zypp/packages/repo-oss/suse/i686/
- done
- mkdir -p $cache/partial-$arch-packages/var/cache/zypp/packages/update/i686
- for i in "$cache/partial-$arch-packages/var/cache/zypp/packages/update/i586/*" ; do
- ln -s $i $cache/partial-$arch-packages/var/cache/zypp/packages/update/i686/
- done
- fi
-
- # openSUSE 13.2 has no noarch directory in update
- [ -d $cache/partial-$arch-packages/var/cache/zypp/packages/update/noarch ] || mkdir -p $cache/partial-$arch-packages/var/cache/zypp/packages/update/noarch
-
- repos=("--repository" "$cache/partial-$arch-packages/var/cache/zypp/packages/repo-oss/suse/$arch" "--repository" "$cache/partial-$arch-packages/var/cache/zypp/packages/repo-oss/suse/noarch")
- if [[ $DISTRO != "tumbleweed" ]]; then # tumbleweed has no update repo
- repos+=("--repository" "$cache/partial-$arch-packages/var/cache/zypp/packages/update/$arch" "--repository" "$cache/partial-$arch-packages/var/cache/zypp/packages/update/noarch")
- fi
-
- CLEAN_BUILD=1 BUILD_ARCH="$arch" BUILD_ROOT="$cache/partial-$arch" BUILD_DIST="$cache/partial-$arch-packages/opensuse.conf" PATH="$PATH:$BUILD_DIR" $BUILD_DIR/init_buildsystem --clean --configdir $BUILD_DIR/configs --cachedir $cache/partial-$arch-cache ${repos[*]} || return 1
-
- chroot $cache/partial-$arch /usr/bin/zypper --quiet --non-interactive ar "$oss_repo_url" repo-oss || return 1
- if [[ $DISTRO != "tumbleweed" ]]; then
- chroot $cache/partial-$arch /usr/bin/zypper --quiet --non-interactive ar "$update_repo_url" update || return 1
- fi
-
-# really clean the image
- rm -fr $cache/partial-$arch/{.build,.guessed_dist,.srcfiles*,installed-pkg}
- rm -fr $cache/partial-$arch/dev
-# make sure we have a minimal /dev
- mkdir -p "$cache/partial-$arch/dev"
- mknod -m 666 $cache/partial-$arch/dev/null c 1 3
- mknod -m 666 $cache/partial-$arch/dev/zero c 1 5
-# create mtab symlink
- rm -f $cache/partial-$arch/etc/mtab
- ln -sf /proc/self/mounts $cache/partial-$arch/etc/mtab
-
-# ensure /var/run and /run are symlinked
- rm -fr $cache/partial-$arch/var/run
- ln -s -f ../run $cache/partial-$arch/var/run
- if [ $? -ne 0 ]; then
- echo "Failed to download the rootfs, aborting."
- return 1
- fi
-
- rm -fr "$cache/partial-$arch-packages"
- mv "$1/partial-$arch" "$1/rootfs-$arch"
- echo "Download complete."
-
- return 0
-}
-
-copy_opensuse()
-{
- cache=$1
- arch=$2
- rootfs=$3
-
- # make a local copy of the mini opensuse
- echo "Copying rootfs to $rootfs ..."
- mkdir -p $rootfs
- rsync -SHaAX $cache/rootfs-$arch/ $rootfs/ || return 1
- return 0
-}
-
-install_opensuse()
-{
- # Allow the cache base to be set by environment variable
- cache="${LXC_CACHE_PATH:-@LOCALSTATEDIR@/cache/lxc/opensuse/$DISTRO}"
- rootfs=$1
- mkdir -p @LOCALSTATEDIR@/lock/subsys/
- (
- flock -x 9
- if [ $? -ne 0 ]; then
- echo "Cache repository is busy."
- return 1
- fi
-
- echo "Checking cache download in $cache/rootfs-$arch ... "
- if [ ! -e "$cache/rootfs-$arch" ]; then
- download_opensuse $cache $arch
- if [ $? -ne 0 ]; then
- echo "Failed to download 'opensuse base'"
- return 1
- fi
- fi
-
- echo "Copy $cache/rootfs-$arch to $rootfs ... "
- copy_opensuse $cache $arch $rootfs
- if [ $? -ne 0 ]; then
- echo "Failed to copy rootfs"
- return 1
- fi
-
- return 0
- ) 9>@LOCALSTATEDIR@/lock/subsys/lxc-opensuse
-
- return $?
-}
-
-# Generate a random hardware (MAC) address composed of FE followed by
-# 5 random bytes...
-create_hwaddr()
-{
- openssl rand -hex 5 | sed -e 's/\(..\)/:\1/g; s/^/fe/'
-}
-
-copy_configuration()
-{
- path=$1
- rootfs=$2
- name=$3
-
- grep -q "^lxc.rootfs.path" $path/config 2>/dev/null || echo "
-lxc.rootfs.path = $rootfs_path
-" >> $path/config
-
- # The following code is to create static MAC addresses for each
- # interface in the container. This code will work for multiple
- # interfaces in the default config. It will also strip any
- # hwaddr stanzas out of the default config since we can not share
- # MAC addresses between containers.
- #
- # This code is largely mimiced from the Fedora Template.
- mv $path/config $path/config.def
- while read LINE
- do
- # This should catch variable expansions from the default config...
- if expr "${LINE}" : '.*\$' > /dev/null 2>&1
- then
- LINE=$(eval "echo \"${LINE}\"")
- fi
-
- # There is a tab and a space in the regex bracket below!
- # Seems that \s doesn't work in brackets.
- KEY=$(expr "${LINE}" : '\s*\([^ ]*\)\s*=')
-
- if [[ "${KEY}" != "lxc.net.0.hwaddr" ]]
- then
- echo "${LINE}" >> $path/config
-
- if [[ "${KEY}" == "lxc.net.0.link" ]]
- then
- echo "lxc.net.0.hwaddr = $(create_hwaddr)" >> $path/config
- fi
- fi
- done < $path/config.def
-
- rm -f $path/config.def
-
- if [ -e "@LXCTEMPLATECONFIG@/opensuse.common.conf" ]; then
- echo "
-# Include common configuration
-lxc.include = @LXCTEMPLATECONFIG@/opensuse.common.conf
-" >> $path/config
- fi
-
- # Append things which require expansion here...
- cat <<EOF >> $path/config
-lxc.arch = $arch
-lxc.uts.name = $name
-
-lxc.mount.auto = cgroup:mixed proc:mixed sys:mixed
-
-# When using LXC with apparmor, uncomment the next line to run unconfined:
-lxc.apparmor.profile = unconfined
-
-# example simple networking setup, uncomment to enable
-#lxc.net.0.type = $lxc_network_type
-#lxc.net.0.flags = up
-#lxc.net.0.link = $lxc_network_link
-#lxc.net.0.name = eth0
-# Additional example for veth network type
-# static MAC address,
-#lxc.net.0.hwaddr = 00:16:3e:77:52:20
-# persistent veth device name on host side
-# Note: This may potentially collide with other containers of same name!
-#lxc.net.0.veth.pair = v-$name-e0
-
-EOF
-
- if [ $? -ne 0 ]; then
- echo "Failed to add configuration"
- return 1
- fi
-
- return 0
-}
-
-clean()
-{
- cache="${LXC_CACHE_PATH:-@LOCALSTATEDIR@/cache/lxc/opensuse}"
-
- if [ ! -e $cache ]; then
- exit 0
- fi
-
- # lock, so we won't purge while someone is creating a repository
- (
- flock -x 9
- 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
- ) 9>@LOCALSTATEDIR@/lock/subsys/lxc-opensuse
-}
-
-usage()
-{
- cat <<EOF
-$1 -h|--help -p|--path=<path> -r|--release nn.n --clean
-Please give the release as 13.1, 13.2 etc.
-If no release is given, openSUSE Leap 42.2 is installed.
-EOF
- return 0
-}
-
-# Make arch a global. This may become configurable?
-arch=$(uname -m)
-
-options=$(getopt -o hp:n:r:c -l help,rootfs:,path:,name:,release:,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;;
- -r|--release) DISTRO=$2; shift 2;;
- -c|--clean) clean=1; shift 1;;
- --) shift 1; break ;;
- *) break ;;
- esac
-done
-
-if [ ! -z "$clean" -a -z "$path" ]; then
- clean || exit 1
- exit 0
-fi
-
-type zypper > /dev/null
-if [ $? -ne 0 ]; then
- echo "'zypper' command is missing"
- exit 1
-fi
-
-if [ -z "$path" ]; then
- echo "'path' parameter is required"
- exit 1
-fi
-
-if grep -q Harlequin /etc/os-release || grep -q Tumbleweed /etc/os-release ; then
- BVER=`rpm -q --qf '%{version}\n' build`
- if [ $? -ne 0 -o "$BVER" -lt "20141120" ]; then
- echo "Building openSUSE containers with your version of the build package is broken. Please install the update to version 20141120 or newer."
- exit 1
- fi
-fi
-
-if [ -z "$DISTRO" ]; then
- echo ""
- echo "No release selected, using openSUSE Leap 42.2"
- DISTRO="leap/42.2"
-else
- echo ""
- case "$DISTRO" in
- 13.1)
- echo "Selected openSUSE 13.1"
- ;;
-
- 13.2)
- echo "Selected openSUSE 13.2"
- ;;
-
- 42.1|leap/42.1|leap)
- echo "Selected openSUSE Leap 42.1"
- DISTRO="leap/42.1"
- ;;
-
- 42.2|leap/42.2|422)
- echo "Selected openSUSE Leap 42.2"
- DISTRO="leap/42.2"
- ;;
- 42.3|leap/42.3|423)
- echo "Selected openSUSE Leap 42.3"
- DISTRO="leap/42.3"
- ;;
- tumbleweed|factory)
- echo "Selected openSUSE Leap Tumbleweed"
- DISTRO="tumbleweed"
- ;;
-
- *)
- echo "You have chosen an invalid release, quitting..."
- exit 1
- ;;
- esac
-fi
-
-
-if [ "$(id -u)" != "0" ]; then
- echo "This script should be run as 'root'"
- exit 1
-fi
-
-# detect rootfs
-config="$path/config"
-if [ -z "$rootfs" ]; then
- if grep -q '^lxc.rootfs.path' $config 2>/dev/null ; then
- rootfs=$(awk -F= '/^lxc.rootfs.path =/{ print $2 }' $config)
- else
- rootfs=$path/rootfs
- fi
-fi
-
-install_opensuse $rootfs
-if [ $? -ne 0 ]; then
- echo "failed to install opensuse"
- exit 1
-fi
-
-configure_opensuse $rootfs $name
-if [ $? -ne 0 ]; then
- echo "failed to configure opensuse 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
+++ /dev/null
-#!/bin/sh
-#
-# Template script for generating Oracle Enterprise Linux container for LXC
-# based on lxc-fedora, lxc-ubuntu
-#
-# Copyright © 2011 Wim Coekaerts <wim.coekaerts@oracle.com>
-# Copyright © 2012 Dwight Engen <dwight.engen@oracle.com>
-#
-# Modified for Oracle Linux 5
-# Wim Coekaerts <wim.coekaerts@oracle.com>
-#
-# Modified for Oracle Linux 6,7 combined OL4,5,6 into one template script
-# Dwight Engen <dwight.engen@oracle.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
-#
-
-# Detect use under userns (unsupported)
-for arg in "$@"; do
- [ "$arg" = "--" ] && break
- if [ "$arg" = "--mapped-uid" -o "$arg" = "--mapped-gid" ]; then
- echo "This template can't be used for unprivileged containers." 1>&2
- echo "You may want to try the \"download\" template instead." 1>&2
- exit 1
- fi
-done
-
-# Make sure the usual locations are in PATH
-export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
-
-die()
-{
- echo "failed: $1"
- exit 1
-}
-
-is_btrfs_subvolume()
-{
- if which btrfs >/dev/null 2>&1 && \
- btrfs subvolume list "$1" >/dev/null 2>&1; then
- return 0
- fi
- return 1
-}
-
-can_chcon()
-{
- if which chcon >/dev/null 2>&1; then
- selinuxenabled >/dev/null 2>&1
- return $?
- fi
- return 1
-}
-
-# fix up the container_rootfs
-container_rootfs_patch()
-{
- echo "Patching container rootfs $container_rootfs for Oracle Linux $container_release_major.$container_release_minor"
-
- # copy ourself into the container to be used to --patch the rootfs when
- # yum update on certain packages is done. we do this here instead of in
- # container_rootfs_configure() in case the patching done in this function
- # is updated in the future, we can inject the updated version of ourself
- # into older containers.
- if [ $container_rootfs != "/" ]; then
- cp -f `readlink -f $0` $container_rootfs/usr/bin/lxc-patch
- if [ $container_release_major -lt "6" ]; then
- mkdir -p $container_rootfs/usr/lib/yum-plugins
- cp @DATADIR@/lxc/lxc-patch.py $container_rootfs/usr/lib/yum-plugins
- fi
- if [ $container_release_major -ge "6" ]; then
- mkdir -p $container_rootfs/usr/share/yum-plugins
- cp @DATADIR@/lxc/lxc-patch.py $container_rootfs/usr/share/yum-plugins
- fi
- mkdir -p $container_rootfs/etc/yum/pluginconf.d
- cat <<EOF > $container_rootfs/etc/yum/pluginconf.d/lxc-patch.conf
-[main]
-enabled=1
-packages=dbus,initscripts,iptables,openssh-server,setup,selinux-policy,readahead,udev,util-linux,util-linux-ng
-EOF
- fi
-
- if [ $container_release_major = "4" ]; then
- # yum plugin type of TYPE_INTERFACE works in all releases but gives a
- # deprecation warning on major > 4, so we default to TYPE_INTERACTIVE
- # and fix it up here
- sed -i 's|TYPE_INTERACTIVE|TYPE_INTERFACE|' $container_rootfs/usr/lib/yum-plugins/lxc-patch.py
- if [ -f $container_rootfs/etc/yum.repos.d/ULN-Base.repo ]; then
- mv $container_rootfs/etc/yum.repos.d/ULN-Base.repo \
- $container_rootfs/etc/yum.repos.d/ULN-Base.repo.lxc-disabled
- fi
- echo "plugins = 1" >>$container_rootfs/etc/yum.conf
- fi
-
- # "disable" selinux in the guest. The policy in the container isn't
- # likely to match the hosts (unless host == guest exactly) and the
- # kernel can only be enforcing one policy.
- #
- # The OL 5 init honors /etc/selinux/config, but note that
- # this doesnt actually disable it if it's enabled in the host, since
- # libselinux::is_selinux_enabled() in the guest will check
- # /proc/filesystems and see selinuxfs, thus reporting that it is on
- # (ie. check the output of sestatus in the guest). We also replace
- # /usr/sbin/selinuxenabled with a symlink to /bin/false so that init
- # scripts (ie. mcstransd) that call that think selinux is disabled.
- mkdir -p $container_rootfs/selinux
- echo 0 > $container_rootfs/selinux/enforce
- if [ -e $container_rootfs/etc/selinux/config ]; then
- sed -i 's|SELINUX=enforcing|SELINUX=disabled|' $container_rootfs/etc/selinux/config
- else
- mkdir -p $container_rootfs/etc/selinux
- echo "SELINUX=disabled" >$container_rootfs/etc/selinux/config
- fi
- sed -i 's|session[ \t]*required[ \t]*pam_selinux.so[ \t]*close|#session required pam_selinux.so close|' $container_rootfs/etc/pam.d/login
- sed -i 's|session[ \t]*required[ \t]*pam_selinux.so[ \t]*open|#session required pam_selinux.so open|' $container_rootfs/etc/pam.d/login
- sed -i 's|session[ \t]*required[ \t]*pam_selinux.so[ \t]*close|#session required pam_selinux.so close|' $container_rootfs/etc/pam.d/sshd
- sed -i 's|session[ \t]*required[ \t]*pam_selinux.so[ \t]*open|#session required pam_selinux.so open|' $container_rootfs/etc/pam.d/sshd
-
- # setting /proc/$$/loginuid doesn't work under user namespace, which
- # prevents logins from working
- sed -i 's|session[ \t]*required[ \t]*pam_loginuid.so|#session required pam_loginuid.so|' $container_rootfs/etc/pam.d/sshd
- sed -i 's|session[ \t]*required[ \t]*pam_loginuid.so|#session required pam_loginuid.so|' $container_rootfs/etc/pam.d/login
-
- if [ -f $container_rootfs/usr/sbin/selinuxenabled ]; then
- mv $container_rootfs/usr/sbin/selinuxenabled $container_rootfs/usr/sbin/selinuxenabled.lxcorig
- ln -s /bin/false $container_rootfs/usr/sbin/selinuxenabled
- fi
-
- # ensure /dev/ptmx refers to the newinstance devpts of the container, or
- # pty's will get crossed up with the hosts (https://lkml.org/lkml/2012/1/23/512)
- rm -f $container_rootfs/dev/ptmx
- ln -s pts/ptmx $container_rootfs/dev/ptmx
-
- # OL7 has systemd, no rc.sysinit
- if [ $container_release_major = "7" ]; then
- # with newer systemd (OL7.2), getty service include container-getty.service
- # let that be the one who manage the getty service instead
- if [ ! -f $container_rootfs/usr/lib/systemd/system/container-getty@.service ]; then
- # from mhw in the fedora template: We do need to disable the
- # "ConditionalPathExists=/dev/tty0" line or no gettys are started on
- # the ttys in the container. Lets do it in an override copy of the
- # service so it can still pass rpm verifies and not be automatically
- # updated by a new systemd version.
- sed -e 's/^ConditionPathExists=/#LXC ConditionPathExists=/' \
- < $container_rootfs/usr/lib/systemd/system/getty\@.service \
- > $container_rootfs/etc/systemd/system/getty\@.service
- # Setup getty service on the 4 ttys we are going to allow in the
- # default config. Number should match lxc.tty
- ( cd $container_rootfs/etc/systemd/system/getty.target.wants
- for i in 1 2 3 4 ; do ln -sf ../getty\@.service getty@tty${i}.service; done )
- # We only want to spawn a getty on /dev/console in lxc, libvirt-lxc
- # symlinks /dev/console to /dev/tty1
- sed -i '/Before=getty.target/a ConditionVirtualization=lxc' $container_rootfs/usr/lib/systemd/system/console-getty.service
- fi
-
- # disable some systemd services, set default boot, sigpwr target
- rm -f $container_rootfs/usr/lib/systemd/system/sysinit.target.wants/kmod-static-nodes.service
- chroot $container_rootfs systemctl -q disable graphical.target
- chroot $container_rootfs systemctl -q enable multi-user.target
-
- # systemd in userns won't be able to set /proc/self/oom_score_adj which
- # prevents the dbus service from starting
- sed -i 's|^OOMScoreAdjust|#LXC OOMScoreAdjust|' $container_rootfs/usr/lib/systemd/system/dbus.service
- return
- fi
-
- # silence error in checking for selinux
- sed -i 's|cat /proc/self/attr/current|cat /proc/self/attr/current 2>/dev/null|' $container_rootfs/etc/rc.sysinit
- sed -i 's|cat /proc/self/attr/current|cat /proc/self/attr/current 2>/dev/null|' $container_rootfs/etc/rc.d/rc.sysinit
-
- # on ol4 pam_limits prevents logins when using user namespaces
- if [ $container_release_major = "4" ]; then
- sed -i 's|session[ \t]*required[ \t]*/lib/security/\$ISA/pam_limits.so|#session required /lib/security/$ISA/pam_limits.so|' $container_rootfs/etc/pam.d/system-auth
- fi
-
- # avoid error in ol5 attempting to copy non-existent resolv.conf
- if [ $container_release_major = "5" ]; then
- sed -i 's|resolv.conf.predhclient|resolv.conf.predhclient 2>/dev/null|' $container_rootfs/sbin/dhclient-script
- fi
-
- # disable interactive ovmd asking questions
- if [ -f $container_rootfs/etc/sysconfig/ovmd ]; then
- sed -i 's|INITIAL_CONFIG=yes|INITIAL_CONFIG=no|' $container_rootfs/etc/sysconfig/ovmd
- fi
-
- # disable disabling of ipv4 forwarding and defrag on shutdown since
- # we mount /proc/sys ro
- if [ $container_release_major = "5" ]; then
- sed -i 's|-f /proc/sys/net/ipv4/ip_forward|-w /proc/sys/net/ipv4/ip_forward|' $container_rootfs/etc/rc.d/init.d/network
- sed -i 's|-f /proc/sys/net/ipv4/ip_always_defrag|-w /proc/sys/net/ipv4/ip_always_defrag|' $container_rootfs/etc/rc.d/init.d/network
- fi
-
- # disable ipv6 on ol6
- rm -f $container_rootfs/etc/sysconfig/network-scripts/init.ipv6-global
-
- # remove module stuff for iptables it just shows errors that are not
- # relevant in a container
- if [ -f "$container_rootfs/etc/sysconfig/iptables-config" ]; then
- sed -i 's|IPTABLES_MODULES=".*|IPTABLES_MODULES=""|' $container_rootfs/etc/sysconfig/iptables-config
- sed -i 's|IPTABLES_MODULES_UNLOAD=".*|IPTABLES_MODULES_UNLOAD="no"|' $container_rootfs/etc/sysconfig/iptables-config
- fi
-
- # disable readahead in the container
- if [ $container_release_major = "6" -a -e $container_rootfs/etc/sysconfig/readahead ]; then
- rm -f $container_rootfs/etc/init/readahead-collector.conf
- rm -f $container_rootfs/etc/init/readahead-disable-services.conf
- sed -i 's|READAHEAD="yes"|READAHEAD="no"|' $container_rootfs/etc/sysconfig/readahead
- fi
-
- if [ $container_release_major = "4" ]; then
- # enable fastboot always
- sed -i 's|\[ -f /fastboot \]|/bin/true|' $container_rootfs/etc/rc.sysinit
- sed -i 's|\[ -f /fastboot \]|/bin/true|' $container_rootfs/etc/rc.d/rc.sysinit
-
- # dont attempt to set kernel parameters
- sed -i 's|action $"Configuring kernel parameters|# LXC action $"Configuring kernel parameters|' $container_rootfs/etc/rc.sysinit
- sed -i 's|action $"Configuring kernel parameters|# LXC action $"Configuring kernel parameters|' $container_rootfs/etc/rc.d/rc.sysinit
- sed -i 's|action $"Setting network parameters|# LXC action $"Setting network parameters|' $container_rootfs/etc/init.d/network 2>/dev/null
- sed -i 's|action $"Setting network parameters|# LXC action $"Setting network parameters|' $container_rootfs/etc/init.d/NetworkManager 2>/dev/null
- fi
-
- # no need to attempt to mount /
- sed -i 's|mount -f /$|# LXC mount -f /|' $container_rootfs/etc/rc.sysinit
- sed -i 's|mount -f /$|# LXC mount -f /|' $container_rootfs/etc/rc.d/rc.sysinit
- sed -i 's|action \$"Remounting root filesystem|/bin/true # LXC action $"Remounting root filesystem|' $container_rootfs/etc/rc.sysinit
- sed -i 's|action \$"Remounting root filesystem|/bin/true # LXC action $"Remounting root filesystem|' $container_rootfs/etc/rc.d/rc.sysinit
-
- # disable udev in the container
- if [ $container_release_major = "4" ]; then
- sed -i 's|\[ -x /sbin/start_udev \]|# LXC no udev|' $container_rootfs/etc/rc.sysinit
- sed -i 's|\[ -x /sbin/start_udev \]|# LXC no udev|' $container_rootfs/etc/rc.d/rc.sysinit
- else
- sed -i 's|.sbin.start_udev||' $container_rootfs/etc/rc.sysinit
- sed -i 's|.sbin.start_udev||' $container_rootfs/etc/rc.d/rc.sysinit
- fi
-
- # disable nash raidautorun in the container since no /dev/md*
- if [ $container_release_major = "4" -o $container_release_major = "5" ]; then
- sed -i 's|echo "raidautorun /dev/md0"|echo ""|' $container_rootfs/etc/rc.sysinit
- sed -i 's|echo "raidautorun /dev/md0"|echo ""|' $container_rootfs/etc/rc.d/rc.sysinit
- fi
-
- # prevent rc.sysinit from attempting to loadkeys
- if [ \( $container_release_major = "4" -o $container_release_major = "5" \) -a -e $container_rootfs/etc/sysconfig/keyboard ]; then
- rm $container_rootfs/etc/sysconfig/keyboard
- fi
-
- # dont use the hwclock, it messes up the host's time
- if [ $container_release_major = "4" ]; then
- sed -i 's|runcmd $"Syncing hardware clock|# LXC no hwclock runcmd $"Syncing hardware clock|' $container_rootfs/etc/rc.d/init.d/halt
- else
- sed -i 's|\[ -x /sbin/hwclock|\[ 0 -eq 1|' $container_rootfs/etc/rc.d/init.d/halt
- fi
- sed -i 's|^\[ -x /sbin/hwclock|\[ 0 -eq 1|' $container_rootfs/etc/rc.sysinit
- sed -i 's|^\[ -x /sbin/hwclock|\[ 0 -eq 1|' $container_rootfs/etc/rc.d/rc.sysinit
- sed -i 's|^/sbin/hwclock|# LXC /sbin/nohwclock|' $container_rootfs/etc/rc.sysinit
- sed -i 's|^/sbin/hwclock|# LXC /sbin/nohwclock|' $container_rootfs/etc/rc.d/rc.sysinit
-
- # dont start lvm
- if [ $container_release_major -lt "6" -a -f $container_rootfs/sbin/lvm.static ]; then
- mv $container_rootfs/sbin/lvm.static $container_rootfs/sbin/lvm.static.lxc-disabled
- fi
- if [ $container_release_major = "6" ]; then
- touch $container_rootfs/.nolvm
- fi
-
- # fix assumptions that plymouth is available
- sed -i 's|\[ "$PROMPT" != no \] && plymouth|[ "$PROMPT" != no ] \&\& [ -n "$PLYMOUTH" ] \&\& plymouth|' $container_rootfs/etc/rc.sysinit
- sed -i 's|\[ "$PROMPT" != no \] && plymouth|[ "$PROMPT" != no ] \&\& [ -n "$PLYMOUTH" ] \&\& plymouth|' $container_rootfs/etc/rc.d/rc.sysinit
- rm -f $container_rootfs/etc/init/plymouth-shutdown.conf
- rm -f $container_rootfs/etc/init/quit-plymouth.conf
- rm -f $container_rootfs/etc/init/splash-manager.conf
-
- # dont try to unmount /dev/lxc devices
- sed -i 's|&& $1 !~ /^\\/dev\\/ram/|\&\& $2 !~ /^\\/dev\\/lxc/ \&\& $1 !~ /^\\/dev\\/ram/|' $container_rootfs/etc/init.d/halt
-
- # don't try to unmount swap
- sed -i 's|\[ -f /proc/swaps \]|# LXC [ -f /proc/swaps ]|' $container_rootfs/etc/init.d/halt
-
- # sem_open(3) checks that /dev/shm is SHMFS_SUPER_MAGIC, so make sure to
- # mount /dev/shm (normally done by dracut initrd) as tmpfs
- if [ $container_release_major = "4" -o $container_release_major = "5" ]; then
- grep -q "mount -t tmpfs tmpfs /dev/shm" $container_rootfs/etc/rc.sysinit
- if [ $? -eq 1 ]; then
- echo "mkdir -p /dev/shm && mount -t tmpfs tmpfs /dev/shm" >>$container_rootfs/etc/rc.sysinit
- echo "mkdir -p /dev/shm && mount -t tmpfs tmpfs /dev/shm" >>$container_rootfs/etc/rc.d/rc.sysinit
- fi
- fi
- if [ $container_release_major = "6" ]; then
- sed -i 's|mount -n -o remount /dev/shm >/dev/null 2>&1$|mkdir -p /dev/shm \&\& mount -t tmpfs tmpfs /dev/shm # LXC|' $container_rootfs/etc/rc.sysinit
- sed -i 's|mount -n -o remount /dev/shm >/dev/null 2>&1$|mkdir -p /dev/shm \&\& mount -t tmpfs tmpfs /dev/shm # LXC|' $container_rootfs/etc/rc.d/rc.sysinit
- fi
-
- # there might be other services that are useless but the below set is a good start
- # some of these might not exist in the image, so we silence chkconfig complaining
- # about the service file not being found
- for service in \
- acpid apmd auditd autofs cpuspeed dund gpm haldaemon hidd \
- ip6tables irqbalance iscsi iscsid isdn kdump kudzu \
- lm_sensors lvm2-monitor mdmonitor microcode_ctl \
- ntpd pcmcia postfix sendmail udev-post xfs ;
- do
- chroot $container_rootfs chkconfig 2>/dev/null $service off
- done
-
- for service in rsyslog ;
- do
- chroot $container_rootfs chkconfig 2>/dev/null $service on
- done
-}
-
-container_rootfs_configure()
-{
- container_rootfs_patch
- echo "Configuring container for Oracle Linux $container_release_major.$container_release_minor"
-
- # configure the network to use dhcp. we set DHCP_HOSTNAME so the guest
- # will report its name and be resolv'able by the hosts dnsmasq
- cat <<EOF > $container_rootfs/etc/sysconfig/network-scripts/ifcfg-eth0
-DEVICE=eth0
-BOOTPROTO=dhcp
-ONBOOT=yes
-HOSTNAME=$name
-DHCP_HOSTNAME=\`hostname\`
-NM_CONTROLLED=no
-TYPE=Ethernet
-EOF
-
- # set the hostname
- if [ $container_release_major -ge "7" ]; then
- # systemd honors /etc/hostname
- echo "$name" >$container_rootfs/etc/hostname
- fi
- cat <<EOF > $container_rootfs/etc/sysconfig/network
-NETWORKING=yes
-NETWORKING_IPV6=no
-HOSTNAME=$name
-EOF
-
- # set minimal hosts
- echo "127.0.0.1 localhost $name" > $container_rootfs/etc/hosts
-
- # this file has to exist for libvirt/Virtual machine monitor to boot the container
- touch $container_rootfs/etc/mtab
-
- # setup console and tty[1-4] for login. note that /dev/console and
- # /dev/tty[1-4] will be symlinks to the ptys /dev/lxc/console and
- # /dev/lxc/tty[1-4] so that package updates can overwrite the symlinks.
- # lxc will maintain these links and bind mount ptys over /dev/lxc/*
- # since lxc.tty.dir is specified in the config.
-
- # allow root login on console, tty[1-4], and pts/0 for libvirt
- echo "# LXC (Linux Containers)" >>$container_rootfs/etc/securetty
- echo "lxc/console" >>$container_rootfs/etc/securetty
- for i in 1 2 3 4; do
- echo "lxc/tty$i" >>$container_rootfs/etc/securetty
- done
- echo "# For libvirt/Virtual Machine Monitor" >>$container_rootfs/etc/securetty
- for i in 0 1 2 3 4; do
- echo "pts/$i" >>$container_rootfs/etc/securetty
- done
-
- # prevent mingetty from calling vhangup(2) since it fails with userns
- if [ -f $container_rootfs/etc/init/tty.conf ]; then
- sed -i 's|mingetty|mingetty --nohangup|' $container_rootfs/etc/init/tty.conf
- fi
-
- # create maygetty which only spawns a getty on the console when running
- # under lxc, not libvirt-lxc which symlinks /dev/console to the same pty
- # as /dev/tty1
- cat <<EOF >$container_rootfs/sbin/maygetty
-#!/bin/sh
-if [ "\$container" = "lxc" ]; then
- exec /sbin/mingetty \$@
-fi
-exec sleep infinity
-EOF
- chmod 755 $container_rootfs/sbin/maygetty
-
- # start a getty on /dev/console, /dev/tty[1-4]
- if [ $container_release_major = "4" -o $container_release_major = "5" ]; then
- sed -i 's|mingetty|mingetty --nohangup|' $container_rootfs/etc/inittab
- sed -i '/1:2345:respawn/i cns:2345:respawn:/sbin/maygetty --nohangup --noclear console' $container_rootfs/etc/inittab
- sed -i '/5:2345:respawn/d' $container_rootfs/etc/inittab
- sed -i '/6:2345:respawn/d' $container_rootfs/etc/inittab
- fi
-
- if [ $container_release_major = "6" ]; then
- cat <<EOF > $container_rootfs/etc/init/console.conf
-# console - getty
-#
-# This service maintains a getty on the console from the point the system is
-# started until it is shut down again.
-
-start on stopped rc RUNLEVEL=[2345]
-stop on runlevel [!2345]
-env container
-
-respawn
-exec /sbin/maygetty --nohangup --noclear /dev/console
-EOF
- fi
-
- # lxc-shutdown sends SIGPWR to init, OL4 and OL5 have SysVInit, just
- # make it do shutdown now instead of delaying 2 minutes. OL6 uses
- # upstart, so we create an upstart job to handle SIGPWR to shut down
- # cleanly. We use "init 0" instead of shutdown -h now to avoid SELinux
- # permission denied when upstart's shutdown tries to connect to the
- # /com/ubuntu/upstart socket.
- if [ $container_release_major = "4" -o $container_release_major = "5" ]; then
- sed -i 's|pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; |pf::powerfail:/sbin/shutdown -f -h now "|' $container_rootfs/etc/inittab
- elif [ $container_release_major = "6" ]; then
- cat <<EOF > $container_rootfs/etc/init/power-status-changed.conf
-# power-status-changed - used to cleanly shut down the container
-#
-# This task is run whenever init receives SIGPWR
-# Used to shut down the machine.
-
-start on power-status-changed
-
-exec init 0
-EOF
- fi
-
- # start with a clean /var/log/messages
- rm -f $container_rootfs/var/log/messages
-
- # set initial timezone as on host
- if [ -f /etc/sysconfig/clock ]; then
- . /etc/sysconfig/clock
- if [ $container_release_major = "5" -o $container_release_major = "6" ]; then
- echo ZONE=$ZONE > $container_rootfs/etc/sysconfig/clock
- chroot $container_rootfs tzdata-update
- else
- ZONE="${ZONE// /_}"
- chroot $container_rootfs ln -sf ../usr/share/zoneinfo/$ZONE /etc/localtime
- fi
- else
- ZONE=`readlink /etc/localtime | sed -s "s/\.\.\/usr\/share\/zoneinfo\///g"`
- if [ "$ZONE" ]; then
- if [ $container_release_major = "5" -o $container_release_major = "6" ]; then
- echo ZONE=$ZONE > $container_rootfs/etc/sysconfig/clock
- chroot $container_rootfs tzdata-update
- else
- # if /etc/localtime is a symlink, this should preserve it.
- cp -a /etc/localtime $container_rootfs/etc/localtime
- fi
- else
- echo "Timezone in container is not configured. Adjust it manually."
- fi
- fi
-
- # add oracle user
- chroot $container_rootfs useradd -m -s /bin/bash oracle
- printf "Added container user:\033[1moracle\033[0m\n"
- printf "Added container user:\033[1mroot\033[0m\n"
-}
-
-# create the container's lxc config file
-container_config_create()
-{
- echo "Create configuration file $cfg_dir/config"
- mkdir -p $cfg_dir || die "unable to create config dir $cfg_dir"
-
- echo "# Common configuration" >> $cfg_dir/config
- if [ -e "@LXCTEMPLATECONFIG@/oracle.common.conf" ]; then
- echo "lxc.include = @LXCTEMPLATECONFIG@/oracle.common.conf" >> $cfg_dir/config
- fi
-
- cat <<EOF >> $cfg_dir/config || die "unable to create $cfg_dir/config"
-# Container configuration for Oracle Linux $container_release_major.$container_release_minor
-lxc.arch = $arch
-lxc.uts.name = $name
-EOF
- grep -q "^lxc.rootfs.path" $cfg_dir/config 2>/dev/null || echo "lxc.rootfs.path = $container_rootfs" >> $cfg_dir/config
-
- if [ $container_release_major != "4" ]; then
- echo "lxc.cap.drop = sys_resource" >>$cfg_dir/config
- fi
-
- # systemd services like logind and journald need these
- if [ $container_release_major != "7" ]; then
- echo "lxc.cap.drop = setfcap setpcap" >>$cfg_dir/config
- fi
-
- echo "# Networking" >>$cfg_dir/config
- # see if the default network settings were already specified
- lxc_network_type=`grep '^lxc.net.0.type' $cfg_dir/config | awk -F'[= \t]+' '{ print $2 }'`
- if [ -z "$lxc_network_type" ]; then
- echo "lxc.net.0.type = veth" >>$cfg_dir/config
- lxc_network_type=veth
- fi
-
- lxc_network_link=`grep '^lxc.net.0.link' $cfg_dir/config | awk -F'[= \t]+' '{ print $2 }'`
- if [ -z "$lxc_network_link" ]; then
- echo "lxc.net.0.link = lxcbr0" >>$cfg_dir/config
- lxc_network_link=lxcbr0
- fi
-
- lxc_network_hwaddr=`grep '^lxc.net.0.hwaddr' $cfg_dir/config | awk -F'[= \t]+' '{ print $2 }'`
- if [ -z "$lxc_network_hwaddr" ]; then
- # generate a hwaddr for the container
- # see http://sourceforge.net/tracker/?func=detail&aid=3411497&group_id=163076&atid=826303
- local hwaddr="00:16:3e:`dd if=/dev/urandom bs=8 count=1 2>/dev/null |od -t x8 | \
- head -n1 | awk '{print $2}' | cut -c1-6 | \
- sed 's/\(..\)/\1:/g; s/.$//'`"
- echo "lxc.net.0.hwaddr = $hwaddr" >>$cfg_dir/config
- fi
-
- lxc_network_flags=`grep '^lxc.net.0.flags' $cfg_dir/config | awk -F'[= \t]+' '{ print $2 }'`
- if [ -z "$lxc_network_flags" ]; then
- echo "lxc.net.0.flags = up" >>$cfg_dir/config
- fi
-
- cat <<EOF >> $cfg_dir/config || die "unable to create $cfg_dir/config"
-lxc.net.0.name = eth0
-lxc.net.0.mtu = 1500
-EOF
-}
-
-container_rootfs_clone()
-{
- if is_btrfs_subvolume $template_rootfs; then
- # lxc-create already made $container_rootfs a btrfs subvolume, but
- # in this case we want to snapshot the original subvolume so we we
- # have to delete the one that lxc-create made
- btrfs subvolume delete $container_rootfs
- btrfs subvolume snapshot $template_rootfs $container_rootfs || die "btrfs clone template"
- else
- echo "Copying rootfs ..."
- cp -axT $template_rootfs $container_rootfs || die "copy template"
- fi
-}
-
-container_rootfs_repo_create()
-{
- echo "# LXC generated .repo file" >$1
- echo "[$2]" >>$1
- echo "name=Oracle Linux $container_release_major.$container_release_minor ($basearch)" >>$1
- echo "baseurl=$3/" >>$1
- echo "enabled=1" >>$1
- echo "skip_if_unavailable=1" >>$1
-
- if [ "$4" != "" ]; then
- echo "gpgkey=$yum_url/RPM-GPG-KEY-oracle-ol$container_release_major" >>$1
- echo "gpgcheck=1" >>$1
- else
- echo "gpgcheck=0" >>$1
- fi
-}
-
-container_rootfs_dev_create()
-{
- # create required devices. note that /dev/console will be created by lxc
- # or libvirt itself to be a symlink to the right pty.
- # take care to not nuke /dev in case $container_rootfs isn't set
- dev_path="$container_rootfs/dev"
- if [ $container_rootfs != "/" -a -d $dev_path ]; then
- rm -rf $dev_path
- fi
- mkdir -p $dev_path
- if can_chcon; then
- # ensure symlinks created in /dev have the right context
- chcon -t device_t $dev_path
- fi
- mknod -m 666 $dev_path/null c 1 3
- mknod -m 666 $dev_path/zero c 1 5
- mknod -m 666 $dev_path/random c 1 8
- mknod -m 666 $dev_path/urandom c 1 9
- mkdir -m 755 $dev_path/pts
- mkdir -m 1777 $dev_path/shm
- mknod -m 666 $dev_path/tty c 5 0
- mknod -m 666 $dev_path/tty1 c 4 1
- mknod -m 666 $dev_path/tty2 c 4 2
- mknod -m 666 $dev_path/tty3 c 4 3
- mknod -m 666 $dev_path/tty4 c 4 4
- mknod -m 666 $dev_path/full c 1 7
- mknod -m 600 $dev_path/initctl p
-
- # set selinux labels same as host
- if can_chcon; then
- for node in null zero random urandom pts shm \
- tty tty0 tty1 tty2 tty3 tty4 full ;
- do
- chcon --reference /dev/$node $dev_path/$node 2>/dev/null
- done
- fi
-}
-
-container_rootfs_create()
-{
- if can_chcon; then
- chcon --reference / $container_rootfs 2>/dev/null
- fi
-
- cmds="rpm wget yum"
- if [ $container_release_major -lt "6" ]; then
- if [ $host_distribution = "Ubuntu" -o $host_distribution = "Debian" ]; then
- db_dump_cmd="db5.1_dump"
- fi
- if [ $host_distribution = "OracleServer" -o \
- $host_distribution = "Fedora" ]; then
- db_dump_cmd="db_dump"
- fi
-
- cmds="$cmds $db_dump_cmd file"
- fi
- for cmd in $cmds; do
- which $cmd >/dev/null 2>&1
- if [ $? -ne 0 ]; then
- die "The $cmd command is required, please install it"
- fi
- done
-
- mkdir -p @LOCALSTATEDIR@/lock/subsys
- (
- flock -x 9
- if [ $? -ne 0 ]; then
- die "The template is busy."
- fi
-
- echo "Yum installing release $container_release_major.$container_release_minor for $basearch"
-
- if [ -n "$repourl" ]; then
- yum_url=$repourl
- else
- yum_url=http://public-yum.oracle.com
- fi
- if [ $container_release_major = "4" -o $container_release_major = "5" ]; then
- latest_L="el"
- latest_U="EL"
- else
- latest_L="ol"
- latest_U="OL"
- fi
-
- if [ -n "$baseurl" ]; then
- # create .repo pointing at baseurl
- repo="lxc-install"
- mkdir -p $container_rootfs/etc/yum.repos.d
- container_rootfs_repo_create \
- $container_rootfs/etc/yum.repos.d/lxc-install.repo $repo $baseurl
- else
- # get public-yum repo file
- if [ $container_release_major = "4" ]; then
- repofile=public-yum-el4.repo
- elif [ $container_release_major = "5" ]; then
- repofile=public-yum-el5.repo
- elif [ $container_release_major = "6" ]; then
- repofile=public-yum-ol6.repo
- elif [ $container_release_major = "7" ]; then
- repofile=public-yum-ol7.repo
- else
- die "Unsupported release $container_release_major"
- fi
-
- mkdir -p $container_rootfs/etc/yum.repos.d
- wget -q $yum_url/$repofile -O $container_rootfs/etc/yum.repos.d/$repofile
- if [ $? -ne 0 ]; then
- die "Unable to download repo file $yum_url/$repofile, release unavailable"
- fi
-
- # yum will take $basearch from host, so force the arch we want
- sed -i "s|\$basearch|$basearch|" $container_rootfs/etc/yum.repos.d/$repofile
-
- # replace url if they specified one
- if [ -n "$repourl" ]; then
- sed -i "s|baseurl=http://public-yum.oracle.com/repo|baseurl=$repourl/repo|" $container_rootfs/etc/yum.repos.d/$repofile
- sed -i "s|gpgkey=http://public-yum.oracle.com|gpgkey=$repourl|" $container_rootfs/etc/yum.repos.d/$repofile
- fi
-
- # disable all repos, then enable the repo for the version we are installing.
- if [ $container_release_minor = "latest" ]; then
- repo=$latest_L""$container_release_major"_"$container_release_minor
- elif [ $container_release_major = "7" ]; then
- repo="ol"$container_release_major"_u"$container_release_minor"_base"
- elif [ $container_release_major = "6" ]; then
- if [ $container_release_minor = "0" ]; then
- repo="ol"$container_release_major"_ga_base"
- else
- repo="ol"$container_release_major"_u"$container_release_minor"_base"
- fi
- elif [ $container_release_major = "5" ]; then
- if [ $container_release_minor = "0" ]; then
- repo="el"$container_release_major"_ga_base"
- elif [ $container_release_minor -lt "6" ]; then
- repo="el"$container_release_major"_u"$container_release_minor"_base"
- else
- repo="ol"$container_release_major"_u"$container_release_minor"_base"
- fi
- elif [ $container_release_major = "4" -a $container_release_minor -gt "5" ]; then
- repo="el"$container_release_major"_u"$container_release_minor"_base"
- else
- die "Unsupported release $container_release_major.$container_release_minor"
- fi
- sed -i "s|enabled=1|enabled=0|" $container_rootfs/etc/yum.repos.d/$repofile
- sed -i "/\[$repo\]/,/\[/ s/enabled=0/enabled=1/" $container_rootfs/etc/yum.repos.d/$repofile
- fi
-
- container_rootfs_dev_create
-
- # don't put devpts,proc, nor sysfs in here, it will already be mounted for us by lxc/libvirt
- echo "" >$container_rootfs/etc/fstab
-
- # create rpm db, download and yum install minimal packages
- mkdir -p $container_rootfs/var/lib/rpm
- rpm --root $container_rootfs --initdb
- yum_args="--installroot $container_rootfs --disablerepo=* --enablerepo=$repo -y --nogpgcheck"
- min_pkgs="yum initscripts passwd rsyslog vim-minimal openssh-server openssh-clients dhclient chkconfig rootfiles policycoreutils oraclelinux-release"
- if [ $container_release_major -lt "6" ]; then
- min_pkgs="$min_pkgs db4-utils"
- fi
-
- # we unshare the mount namespace because yum installing the ol4
- # packages causes $rootfs/proc to be mounted on
- lxc-unshare -s MOUNT yum -- $yum_args install $min_pkgs $user_pkgs
- if [ $? -ne 0 ]; then
- die "Failed to download and install the rootfs, aborting."
- fi
-
- # rsyslog and pam depend on coreutils for some common commands in
- # their POSTIN scriptlets, but coreutils wasn't installed yet. now
- # that coreutils is installed, reinstall the packages so their POSTIN
- # runs right. similarly, libutempter depends on libselinux.so.1 when
- # it runs /usr/sbin/groupadd, so reinstall it too
- redo_pkgs=""
- if [ $container_release_major = "5" ]; then
- if [ $container_release_minor = "latest" ]; then
- redo_pkgs="pam rsyslog libutempter"
- elif [ $container_release_minor -lt 2 ]; then
- redo_pkgs="pam"
- elif [ $container_release_minor -lt 6 ]; then
- redo_pkgs="pam rsyslog"
- elif [ $container_release_minor -gt 5 ]; then
- redo_pkgs="pam rsyslog libutempter"
- fi
- fi
- # shadow utils fails on ol4 and ol6.1
- if [ $container_release_major = "4" -o \
- $container_release_major = "6" -a $container_release_minor = "1" ]; then
- redo_pkgs="shadow-utils"
- fi
- if [ x"$redo_pkgs" != x ]; then
- rpm --root $container_rootfs --nodeps -e $redo_pkgs
- lxc-unshare -s MOUNT yum -- $yum_args install $redo_pkgs
- if [ $? -ne 0 ]; then
- die "Unable to reinstall packages"
- fi
- fi
-
- # if installing from a baseurl, create a .repo that the container
- # can use to update to _latest from http://public-yum.oracle.com
- if [ -n "$baseurl" ]; then
- container_rootfs_repo_create \
- "$container_rootfs/etc/yum.repos.d/public-yum-"$latestL""$container_release_major".repo" \
- $latest_L""$container_release_major"_latest" \
- $yum_url"/repo/OracleLinux/"$latest_U""$container_release_major"/latest/$basearch" gpg
- fi
-
- # these distributions put the rpm database in a place the guest is
- # not expecting it, so move it
- if [ $host_distribution = "Ubuntu" -o $host_distribution = "Debian" ]; then
- mv $container_rootfs/$HOME/.rpmdb/* $container_rootfs/var/lib/rpm
- fi
-
- # if the native rpm created the db with Hash version 9, we need to
- # downgrade it to Hash version 8 for use with OL5.x
- db_version=`file $container_rootfs/var/lib/rpm/Packages | \
- grep -o 'version [0-9]*' |awk '{print $2}'`
- if [ $container_release_major -lt "6" -a $db_version != "8" ]; then
- echo "Fixing (downgrading) rpm database from version $db_version"
- rm -f $container_rootfs/var/lib/rpm/__db*
- for db in $container_rootfs/var/lib/rpm/* ; do
- $db_dump_cmd $db |chroot $container_rootfs db_load /var/lib/rpm/`basename $db`.new
- mv $db.new $db
- done
- fi
-
- # the host rpm may not be the same as the guest, rebuild the db with
- # the guest rpm version
- echo "Rebuilding rpm database"
- rm -f $container_rootfs/var/lib/rpm/__db*
- chroot $container_rootfs rpm --rebuilddb >/dev/null 2>&1
-
- ) 9>@LOCALSTATEDIR@/lock/subsys/lxc-oracle-$name
- if [ $? -ne 0 ]; then
- exit 1
- fi
-}
-
-container_release_get()
-{
- if [ -f $1/etc/oracle-release ]; then
- container_release_version=`cat $1/etc/oracle-release |awk '/^Oracle/ {print $5}'`
- container_release_major=`echo $container_release_version |awk -F '.' '{print $1}'`
- container_release_minor=`echo $container_release_version |awk -F '.' '{print $2}'`
- elif grep -q "Enterprise Linux AS" $1/etc/redhat-release; then
- container_release_major=`cat $1/etc/redhat-release |awk '{print $7}'`
- container_release_minor=`cat $1/etc/redhat-release |awk '{print $10}' |tr -d ")"`
- container_release_version="$container_release_major.$container_release_minor"
- elif grep -q "Enterprise Linux Server" $1/etc/redhat-release; then
- container_release_version=`cat $1/etc/redhat-release |awk '{print $7}'`
- container_release_major=`echo $container_release_version |awk -F '.' '{print $1}'`
- container_release_minor=`echo $container_release_version |awk -F '.' '{print $2}'`
- else
- echo "Unable to determine container release version"
- exit 1
- fi
-}
-
-usage()
-{
- cat <<EOF
- -a|--arch=<arch> architecture (ie. i386, x86_64)
- -R|--release=<release> release to download for the new container
- --rootfs=<path> rootfs path
- -r|--rpms=<rpm name> additional rpms to install into container
- -u|--url=<url> replace yum repo url (ie. Oracle public-yum mirror)
- --baseurl=<url> use package repository (ie. file:///mnt)
- arch and release must also be specified
- -t|--templatefs=<path> copy/clone rootfs at path instead of downloading
- -P|--patch=<path> only patch the rootfs at path for use as a container
- -h|--help
-
-Release is of the format "major.minor", for example "5.8", "6.3", or "6.latest"
-This template supports Oracle Linux releases 4.6 - 7.0
-EOF
- return 0
-}
-
-options=$(getopt -o hp:n:a:R:r:u:t: -l help,rootfs:,path:,name:,arch:,release:,rpms:,url:,templatefs:,patch:,baseurl: -- "$@")
-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) cfg_dir=$2; shift 2;;
- --rootfs) container_rootfs=$2; shift 2;;
- -n|--name) name=$2; shift 2;;
- -a|--arch) arch=$2; shift 2;;
- -R|--release) container_release_version=$2; shift 2;;
- -r|--rpms) user_pkgs=$2; shift 2;;
- -u|--url) repourl=$2; shift 2;;
- -t|--templatefs) template_rootfs=$2; shift 2;;
- --patch) patch_rootfs=$2; shift 2;;
- --baseurl) baseurl=$2; shift 2;;
- --) shift 1; break ;;
- *) break ;;
- esac
-done
-
-# make sure mandatory args are given and valid
-if [ "$(id -u)" != "0" ]; then
- echo "This script should be run as 'root'"
- exit 1
-fi
-
-if [ -n "$baseurl" ]; then
- if [ "$arch" = "" -o "$container_release_version" = "" ]; then
- echo "The --arch and --release must be specified when using --baseurl"
- usage
- exit 1
- fi
-fi
-
-if [ "$arch" = "" ]; then
- arch=$(uname -m)
-fi
-
-if [ -n "$patch_rootfs" ]; then
- container_rootfs="$patch_rootfs"
- container_release_get $container_rootfs
- container_rootfs_patch
- exit 0
-fi
-
-if [ -z $name ]; then
- echo "Container name must be given"
- usage
- exit 1
-fi
-
-if [ -z $cfg_dir ]; then
- echo "Configuration directory must be given, check lxc-create"
- usage
- exit 1
-fi
-
-basearch=$arch
-if [ "$arch" = "i686" ]; then
- basearch="i386"
-fi
-
-if [ "$arch" != "i386" -a "$arch" != "x86_64" ]; then
- echo "Bad architecture given, check lxc-create"
- usage
- exit 1
-fi
-
-if which lsb_release >/dev/null 2>&1; then
- host_distribution=`lsb_release --id |awk '{print $3}'`
- host_release_version=`lsb_release --release |awk '{print $2}'`
- host_release_major=`echo $host_release_version |awk -F '.' '{print $1}'`
- host_release_minor=`echo $host_release_version |awk -F '.' '{print $2}'`
-else
- if [ -f /etc/fedora-release ]; then
- host_distribution="Fedora"
- host_release_version=`cat /etc/fedora-release |awk '{print $3}'`
- host_release_major=$host_release_version
- host_release_minor=0
- elif [ -f /etc/oracle-release ]; then
- host_distribution="OracleServer"
- host_release_version=`cat /etc/oracle-release |awk '{print $5}'`
- host_release_major=`echo $host_release_version |awk -F '.' '{print $1}'`
- host_release_minor=`echo $host_release_version |awk -F '.' '{print $2}'`
- else
- echo "Unable to determine host distribution, ensure lsb_release is installed"
- exit 1
- fi
-fi
-echo "Host is $host_distribution $host_release_version"
-
-if [ -z "$container_rootfs" ]; then
- container_rootfs="$cfg_dir/rootfs"
-fi
-
-if [ -n "$template_rootfs" ]; then
- container_release_get $template_rootfs
-else
- if [ -z "$container_release_version" ]; then
- if [ $host_distribution = "OracleServer" ]; then
- container_release_version=$host_release_version
- else
- echo "No release specified with -R, defaulting to 6.5"
- container_release_version="6.5"
- fi
- fi
- container_release_major=`echo $container_release_version |awk -F '.' '{print $1}'`
- container_release_minor=`echo $container_release_version |awk -F '.' '{print $2}'`
-fi
-
-container_config_create
-if [ -n "$template_rootfs" ]; then
- container_rootfs_clone
-else
- container_rootfs_create
-fi
-
-container_release_get $container_rootfs
-
-container_rootfs_configure
-
-echo "Container : $container_rootfs"
-echo "Config : $cfg_dir/config"
-echo "Network : eth0 ($lxc_network_type) on $lxc_network_link"
+++ /dev/null
-#!/bin/bash -eu
-
-#
-# template script for generating Plamo Linux container for LXC
-#
-
-#
-# lxc: linux Container library
-
-# Authors:
-# KATOH Yasufumi <karma@jazz.email.ne.jp>
-# TAMUKI Shoichi <tamuki@linet.gr.jp>
-
-# 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
-
-# ref. https://github.com/Ponce/lxc-slackware/blob/master/lxc-slackware
-# lxc-ubuntu script
-
-# Detect use under userns (unsupported)
-for arg in "$@"; do
- [ "$arg" = "--" ] && break
- if [ "$arg" = "--mapped-uid" -o "$arg" = "--mapped-gid" ]; then
- echo "This template can't be used for unprivileged containers." 1>&2
- echo "You may want to try the \"download\" template instead." 1>&2
- exit 1
- fi
-done
-
-# Make sure the usual locations are in PATH
-export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
-
-[ -r /etc/default/lxc ] && . /etc/default/lxc
-
-DLSCHEME=${DLSCHEME:-"http"}
-MIRRORSRV=${MIRRORSRV:-"repository.plamolinux.org"}
-MIRRORPATH=${MIRRORPATH:-"/pub/linux/Plamo"}
-CATEGORIES=${CATEGORIES-"00_base 01_minimum"}
-EXTRACTGRS=${EXTRACTGRS-""}
-IGNOREPKGS=${IGNOREPKGS-"grub kernel lilo linux_firmware microcode_ctl
- cpufreqd cpufrequtils gpm ntp kmod"}
-ADDONPKGS=${ADDONPKGS-"`echo contrib/Hamradio/{morse,qrq}`"}
-
-download_plamo() {
- # check the mini plamo was not already downloaded
- if ! mkdir -p $ptcache ; then
- echo "Failed to create '$ptcache' directory."
- return 1
- fi
- # download a mini plamo into a cache
- echo "Downloading Plamo-$release minimal..."
- cd $ptcache
- case $DLSCHEME in http) depth=2 ;; ftp) depth=3 ;; esac
- rej=${IGNOREPKGS%% *} ; [ -n "$rej" ] && rej="$rej-*"
- if [ `echo $IGNOREPKGS | wc -w` -gt 1 ] ; then
- for p in ${IGNOREPKGS#* } ; do rej="$rej,$p-*" ; done
- fi
- for i in $CATEGORIES ; do
- wget -nv -e robots=off -r -l $depth -nd -A .tgz,.txz -R "$rej" \
- -I $MIRRORPATH/Plamo-$release/$arch/plamo/$i \
- -X $MIRRORPATH/Plamo-$release/$arch/plamo/$i/old \
- $DLSCHEME://$MIRRORSRV$MIRRORPATH/Plamo-$release/$arch/plamo/$i
- if [ $? -ne 0 ] ; then
- echo "Failed to download the rootfs, aborting."
- return 1
- fi
- done
- for i in $EXTRACTGRS ; do
- wget -nv -e robots=off -r -l $depth -nd -A .tgz,.txz -R "$rej" \
- -I $MIRRORPATH/Plamo-$release/$arch/contrib/$i \
- -X $MIRRORPATH/Plamo-$release/$arch/contrib/$i/old \
- $DLSCHEME://$MIRRORSRV$MIRRORPATH/Plamo-$release/$arch/contrib/$i
- if [ $? -ne 0 ] ; then
- echo "Failed to download the rootfs, aborting."
- return 1
- fi
- done
- for p in $ADDONPKGS ; do
- wget -nv -e robots=off -r -l $depth -nd -A "`basename $p`-*" \
- -I $MIRRORPATH/Plamo-$release/$arch/`dirname $p` \
- -X $MIRRORPATH/Plamo-$release/$arch/`dirname $p`/old \
- $DLSCHEME://$MIRRORSRV$MIRRORPATH/Plamo-$release/$arch/`dirname $p`
- if [ $? -ne 0 ] ; then
- echo "Failed to download the rootfs, aborting."
- return 1
- fi
- done
- mv $ptcache $dlcache
- echo "Download complete."
- return 0
-}
-
-copy_plamo() {
- # make a local copy of the mini plamo
- echo "Copying $rtcache to $rootfs..."
- mkdir -p $rootfs
- find $rtcache -mindepth 1 -maxdepth 1 -exec cp -a {} $rootfs \; || return 1
- return 0
-}
-
-install_plamo() {
- mkdir -p @LOCALSTATEDIR@/lock/subsys
- (
- if ! flock -n 9 ; then
- echo "Cache repository is busy."
- return 1
- fi
- echo "Checking cache download in $dlcache..."
- if [ ! -d $dlcache ] ; then
- if ! download_plamo ; then
- echo "Failed to download plamo $release base packages."
- return 1
- fi
- fi
- # install "installpkg" command temporarily with static linked tar
- # command into the lxc cache directory to keep the original uid/
- # gid of files/directories.
- echo "Installing 'installpkg' command into $dlcache/sbin..."
- ( cd $dlcache ; tar xpJf hdsetup-*.txz ; rm -rf tmp usr var )
- sed -i "/ldconfig/!s@/sbin@$dlcache&@g" $dlcache/sbin/installpkg*
- PATH=$dlcache/sbin:$PATH
- echo "Installing packages to $rtcache..."
- if [ ! -d $rtcache ] ; then
- mkdir -p $rtcache
- for p in `ls -cr $dlcache/*.t?z` ; do
- installpkg -root $rtcache -priority ADD $p
- done
- fi
- echo "Copy $rtcache to $rootfs..."
- if ! copy_plamo ; then
- echo "Failed to copy rootfs."
- return 1
- fi
- return 0
- ) 9> @LOCALSTATEDIR@/lock/subsys/lxc-plamo
-}
-
-configure_plamo() {
- # suppress log level output for udev
- sed -i 's/="err"/=0/' $rootfs/etc/udev/udev.conf
- # /etc/fstab
- cat <<- "EOF" > $rootfs/etc/fstab
- none /proc proc defaults 0 0
- none /sys sysfs defaults 0 0
- none /dev tmpfs defaults 0 0
- none /tmp tmpfs defaults 0 0
- none /dev/pts devpts gid=5,mode=620 0 0
- none /proc/bus/usb usbfs noauto 0 0
- none /var/lib/nfs/rpc_pipefs rpc_pipefs defaults 0 0
- EOF
- # /etc/inittab
- cat <<- "EOF" | patch $rootfs/etc/inittab
- 32,33c32,33
- < # What to do when power fails (shutdown to single user).
- < pf::powerfail:/sbin/shutdown -f +5 "THE POWER IS FAILING"
- ---
- > # What to do when power fails (shutdown).
- > pf::powerfail:/sbin/shutdown -h +0 "THE POWER IS FAILING"
- 47a48
- > 1:1235:respawn:/sbin/agetty 38400 console
- 52,53d52
- < c5:1235:respawn:/sbin/agetty 38400 tty5 linux
- < c6:12345:respawn:/sbin/agetty 38400 tty6 linux
- EOF
- # set the hostname
- echo "$name" > $rootfs/etc/HOSTNAME
- # set minimal hosts
- echo "127.0.0.1 localhost $name" > $rootfs/etc/hosts
- # configure the network using the dhcp
- echo "DHCP" > $rootfs/var/run/inet1-scheme
- # localtime (JST)
- ln -s ../usr/share/zoneinfo/Asia/Tokyo $rootfs/etc/localtime
- # disable pam_loginuid.so in /etc/pam.d/login (for libvirt's lxc driver)
- sed -i '/pam_loginuid/s/^/#/' $rootfs/etc/pam.d/login
- # glibc configure
- mv $rootfs/etc/ld.so.conf{.new,}
- chroot $rootfs ldconfig
-
- # delete unnecessary process from rc.S
- ed - $rootfs/etc/rc.d/rc.S <<- "EOF"
- /^mount -w -n -t proc/;/^mkdir \/dev\/shm/-1d
- /^mknod \/dev\/null/;/^# Clean \/etc\/mtab/-2d
- /^# copy the rules/;/^# Set the hostname/-1d
- /^# Check the integrity/;/^# Clean up temporary/-1d
- w
- EOF
-
- # delete unnecessary process from rc.M
- ed - $rootfs/etc/rc.d/rc.M <<- "EOF"
- /^# Screen blanks/;/^# Initialize ip6tables/-1d
- /^# Initialize sysctl/;/^echo "Starting services/-1d
- /^sync/;/^# All done/-1d
- w
- EOF
-
- # delete unnecessary process from rc.6
- ed - $rootfs/etc/rc.d/rc.6 <<- "EOF"
- /^# Save system time/;/^# Unmount any remote filesystems/-1d
- /^# Turn off swap/;/^# See if this is a powerfail situation/-1d
- w
- EOF
-
- # /etc/rc.d/rc.inet1.tradnet
- head -n-93 $rootfs/sbin/netconfig.tradnet > /tmp/netconfig.rconly
- cat <<- EOF >> /tmp/netconfig.rconly
- PCMCIA=n
- RC=$rootfs/etc/rc.d/rc.inet1.tradnet
- IFCONFIG=sbin/ifconfig
- ROUTE=sbin/route
- INET1SCHEME=var/run/inet1-scheme
- IPADDR=127.0.0.1
- NETWORK=127.0.0.0
- DHCPCD=usr/sbin/dhclient
- LOOPBACK=y
- make_config_file
- EOF
- rm -f $rootfs/etc/rc.d/rc.inet1.tradnet
- sh /tmp/netconfig.rconly
- rm -f /tmp/netconfig.rconly
- sed -i '/cmdline/s/if/& false \&\&/' $rootfs/etc/rc.d/rc.inet1.tradnet
- # /etc/rc.d/rc.inet2
- sed -i '/rpc.mountd/s/^/#/' $rootfs/etc/rc.d/rc.inet2
- sed -i '/modprobe/s/^/#/' $rootfs/etc/rc.d/rc.inet2
- # configure to start only the minimum of service
- chmod 644 $rootfs/etc/rc.d/init.d/saslauthd
- chmod 644 $rootfs/etc/rc.d/init.d/open-iscsi
- rm -f $rootfs/etc/rc.d/init.d/postfix
- rm -f $rootfs/var/log/initpkg/shadow
- return 0
-}
-
-copy_configuration() {
- ret=0
- cat <<- EOF >> $path/config || let ret++
- lxc.uts.name = $name
- lxc.arch = $arch
- EOF
- if [ -f "@LXCTEMPLATECONFIG@/plamo.common.conf" ] ; then
- cat <<- "EOF" >> $path/config || let ret++
-
- lxc.include = @LXCTEMPLATECONFIG@/plamo.common.conf
- EOF
- fi
- if [ $ret -ne 0 ] ; then
- echo "Failed to add configuration."
- return 1
- fi
- return 0
-}
-
-post_process() {
- # nothing do in Plamo Linux
- true
-}
-
-do_bindhome() {
- # bind-mount the user's path into the container's /home
- h=`getent passwd $bindhome | cut -d: -f6`
- mkdir -p $rootfs/$h
- echo "lxc.mount.entry = $h $rootfs/$h none bind 0 0" >> $path/config
- # copy /etc/passwd, /etc/shadow, and /etc/group entries into container
- if ! pwd=`getent passwd $bindhome` ; then
- echo "Warning: failed to copy password entry for $bindhome."
- else
- echo $pwd >> $rootfs/etc/passwd
- fi
- echo `getent shadow $bindhome` >> $rootfs/etc/shadow
-}
-
-cleanup() {
- [ -d $dlcache -a -d $rtcache ] || return 0
- # lock, so we won't purge while someone is creating a repository
- (
- if ! flock -n 9 ; then
- echo "Cache repository is busy."
- return 1
- fi
- echo "Purging the download cache..."
- rm -rf --one-file-system $dlcache $rtcache || return 1
- echo "Done."
- return 0
- ) 9> @LOCALSTATEDIR@/lock/subsys/lxc-plamo
-}
-
-usage() {
- cat <<- EOF
- $prog [-h|--help] -p|--path=<path> -n|--name=<name> --rootfs=<rootfs>
- [-c|--clean] [-r|--release=<release>] [-a|--arch=<arch>]
- [-b|--bindhome=<user>]
- release: $release
- arch: x86 or x86_64: defaults to host arch
- bindhome: bind <user>'s home into the container
- EOF
-}
-
-prog=`basename $0`
-path="" ; name="" ; rootfs=""
-clean=0
-release=${release:-6.x}
-arch=`uname -m | sed 's/i.86/x86/'` ; hostarch=$arch
-bindhome=""
-sopts=hp:n:cr:a:b:
-lopts=help,path:,name:,rootfs:,clean,release:,arch:,bindhome:
-if ! options=`getopt -o $sopts -l $lopts -- "$@"` ; then
- usage
- exit 1
-fi
-eval set -- "$options"
-while true ; do
- case "$1" in
- -h|--help) usage && exit 0 ;;
- -p|--path) path=$2 ; shift 2 ;;
- -n|--name) name=$2 ; shift 2 ;;
- --rootfs) rootfs=$2 ; shift 2 ;;
- -c|--clean) clean=1 ; shift 1 ;;
- -r|--release) release=$2 ; shift 2 ;;
- -a|--arch) arch=$2 ; shift 2 ;;
- -b|--bindhome) bindhome=$2 ; shift 2 ;;
- --) shift 1 ; break ;;
- *) break ;;
- esac
-done
-if [ $clean -eq 1 -a -z "$path" ] ; then
- cleanup || exit 1
- exit 0
-fi
-if [ $hostarch == "x86" -a $arch == "x86_64" ] ; then
- echo "Can't create x86_64 container on x86."
- exit 1
-fi
-if [ -z "$path" ] ; then
- echo "'path' parameter is required."
- exit 1
-fi
-if [ -z "$name" ] ; then
- echo "'name' parameter is required."
- exit 1
-fi
-if [ `id -u` -ne 0 ] ; then
- echo "This script should be run as 'root'."
- exit 1
-fi
-cache="${LXC_CACHE_PATH:-@LOCALSTATEDIR@/cache/lxc}"
-ptcache=$cache/partial-${prog##*-}-$release-$arch
-dlcache=$cache/cache-${prog##*-}-$release-$arch
-rtcache=$cache/rootfs-${prog##*-}-$release-$arch
-if [ -z "$rootfs" ] ; then
- if grep -q "^lxc.rootfs.path" $path/config ; then
- rootfs=`awk -F= '/^lxc.rootfs.path =/{ print $2 }' $path/config`
- else
- rootfs=$path/rootfs
- fi
-fi
-if ! install_plamo ; then
- echo "Failed to install plamo $release."
- exit 1
-fi
-if ! configure_plamo ; then
- echo "Failed to configure plamo $release for a container."
- exit 1
-fi
-if ! copy_configuration ; then
- echo "Failed to write configuration file."
- exit 1
-fi
-post_process
-if [ -n "$bindhome" ] ; then
- do_bindhome
-fi
-if [ $clean -eq 1 ] ; then
- cleanup || exit 1
- exit 0
-fi
+++ /dev/null
-#!/bin/sh
-
-#
-# template script for generating PLD Linux container for LXC
-#
-
-#
-# lxc: Linux Container library
-
-# Authors:
-# Elan Ruusamäe <glen@pld-linux.org>
-
-# 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
-
-# Detect use under userns (unsupported)
-for arg in "$@"; do
- [ "$arg" = "--" ] && break
- if [ "$arg" = "--mapped-uid" -o "$arg" = "--mapped-gid" ]; then
- echo "This template can't be used for unprivileged containers." 1>&2
- echo "You may want to try the \"download\" template instead." 1>&2
- exit 1
- fi
-done
-
-# Configuration
-arch=$(uname -m)
-cache_base=@LOCALSTATEDIR@/cache/lxc/pld/$arch
-default_path=@LXCPATH@
-
-if [ -e /etc/os-release ]; then
- # This is a shell friendly configuration file. We can just source it.
- # What we're looking for in here is the ID, VERSION_ID and the CPE_NAME
- . /etc/os-release
- echo "Host CPE ID from /etc/os-release: ${CPE_NAME}"
-fi
-
-if [ "${CPE_NAME}" != "" -a "${ID}" = "pld" -a "${VERSION_ID}" != "" ]; then
- pld_host_ver=${VERSION_ID}
- is_pld=true
-elif [ -e /etc/pld-release ]; then
- # Only if all other methods fail, try to parse the pld-release file.
- pld_host_ver=$(sed -e '/PLD /!d' -e 's/^\([0-9.]*\)\sPLD.*/\1/' < /etc/pld-release)
- if [ "$pld_host_ver" != "" ]; then
- is_pld=true
- fi
-fi
-
-# Map a few architectures to their generic PLD Linux repository archs.
-case "$pld_host_ver:$arch" in
-3.0:i586) arch=i486 ;;
-esac
-
-configure_pld()
-{
-
- # disable selinux
- mkdir -p $rootfs_path/selinux
- echo 0 > $rootfs_path/selinux/enforce
-
- # configure the network using the dhcp
- sed -i -e "s/^HOSTNAME=.*/HOSTNAME=${utsname}/" ${rootfs_path}/etc/sysconfig/network
-
- # set hostname on systemd
- if [ $release = "3.0" ]; then
- echo "${utsname}" > ${rootfs_path}/etc/hostname
- fi
-
- # set minimal hosts
- test -e $rootfs_path/etc/hosts || \
- cat <<EOF > $rootfs_path/etc/hosts
-127.0.0.1 localhost.localdomain localhost $utsname
-::1 localhost6.localdomain6 localhost6
-EOF
-
- dev_path="${rootfs_path}/dev"
- rm -rf $dev_path
- mkdir -p $dev_path
- mknod -m 666 ${dev_path}/null c 1 3
- mknod -m 666 ${dev_path}/zero c 1 5
- mknod -m 666 ${dev_path}/random c 1 8
- mknod -m 666 ${dev_path}/urandom c 1 9
- mkdir -m 755 ${dev_path}/pts
- mkdir -m 1777 ${dev_path}/shm
- mknod -m 666 ${dev_path}/tty c 5 0
- mknod -m 666 ${dev_path}/tty0 c 4 0
- mknod -m 666 ${dev_path}/tty1 c 4 1
- mknod -m 666 ${dev_path}/tty2 c 4 2
- mknod -m 666 ${dev_path}/tty3 c 4 3
- mknod -m 666 ${dev_path}/tty4 c 4 4
- mknod -m 600 ${dev_path}/console c 5 1
- mknod -m 666 ${dev_path}/full c 1 7
- mknod -m 600 ${dev_path}/initctl p
- mknod -m 666 ${dev_path}/ptmx c 5 2
-
- if [ -n "${root_password}" ]; then
- echo "setting root passwd to $root_password"
- echo "root:$root_password" | chroot $rootfs_path chpasswd
- fi
-
- return 0
-}
-
-configure_pld_init()
-{
- # default powerfail action waits 2 minutes. for lxc we want it immediately
- sed -i -e '/^pf::powerfail:/ s,/sbin/shutdown.*,/sbin/halt,' ${rootfs_path}/etc/inittab
-}
-
-configure_pld_systemd()
-{
- unlink ${rootfs_path}/etc/systemd/system/default.target
- chroot ${rootfs_path} ln -s /dev/null /etc/systemd/system/udev.service
- chroot ${rootfs_path} ln -s /lib/systemd/system/multi-user.target /etc/systemd/system/default.target
-
- # Actually, the After=dev-%i.device line does not appear in the
- # Fedora 17 or Fedora 18 systemd getty@.service file. It may be left
- # over from an earlier version and it's not doing any harm. We do need
- # to disable the "ConditionalPathExists=/dev/tty0" line or no gettys are
- # started on the ttys in the container. Lets do it in an override copy of
- # the service so it can still pass rpm verifies and not be automatically
- # updated by a new systemd version. -- mhw /\/\|=mhw=|\/\/
-
- sed -e 's/^ConditionPathExists=/# ConditionPathExists=/' \
- -e 's/After=dev-%i.device/After=/' \
- < ${rootfs_path}/lib/systemd/system/getty@.service \
- > ${rootfs_path}/etc/systemd/system/getty@.service
-
- # Setup getty service on the 4 ttys we are going to allow in the
- # default config. Number should match lxc.tty.max
- for i in 1 2 3 4; do
- ln -sf ../getty@.service ${rootfs_path}/etc/systemd/system/getty.target.wants/getty@tty${i}.service
- done
-}
-
-download_pld()
-{
-
- # check the mini pld was not already downloaded
- INSTALL_ROOT=$cache/partial
- mkdir -p $INSTALL_ROOT
- if [ $? -ne 0 ]; then
- echo "Failed to create '$INSTALL_ROOT' directory"
- return 1
- fi
-
- # download a mini pld into a cache
- echo "Downloading PLD Linux minimal ..."
- POLDEK="poldek --root $INSTALL_ROOT --noask --nohold --noignore"
- PKG_LIST="basesystem filesystem pld-release rpm poldek vserver-packages rc-scripts pwdutils mingetty"
-
- mkdir -p $INSTALL_ROOT@LOCALSTATEDIR@/lib/rpm
- rpm --root $INSTALL_ROOT --initdb
- $POLDEK -u $PKG_LIST
-
- if [ $? -ne 0 ]; then
- echo "Failed to download the rootfs, aborting."
- return 1
- fi
-
- mv "$INSTALL_ROOT" "$cache/rootfs"
- echo "Download complete."
-
- return 0
-}
-
-copy_pld()
-{
-
- # make a local copy of the minipld
- echo -n "Copying rootfs to $rootfs_path ..."
- cp -a $cache/rootfs/* $rootfs_path || return 1
- return 0
-}
-
-update_pld()
-{
- POLDEK="poldek --root $cache/rootfs --noask"
- $POLDEK --upgrade-dist
-}
-
-install_pld()
-{
- mkdir -p @LOCALSTATEDIR@/lock/subsys/
- (
- flock -x 9
- if [ $? -ne 0 ]; then
- echo "Cache repository is busy."
- return 1
- fi
-
- echo "Checking cache download in $cache/rootfs ... "
- if [ ! -e "$cache/rootfs" ]; then
- download_pld
- if [ $? -ne 0 ]; then
- echo "Failed to download 'pld base'"
- return 1
- fi
- else
- echo "Cache found. Updating..."
- update_pld
- if [ $? -ne 0 ]; then
- echo "Failed to update 'pld base', continuing with last known good cache"
- else
- echo "Update finished"
- fi
- fi
-
- echo "Copy $cache/rootfs to $rootfs_path ... "
- copy_pld
- if [ $? -ne 0 ]; then
- echo "Failed to copy rootfs"
- return 1
- fi
-
- return 0
- ) 9>@LOCALSTATEDIR@/lock/subsys/lxc-pld
-
- return $?
-}
-
-copy_configuration()
-{
-
- mkdir -p $config_path
- grep -q "^lxc.rootfs.path" $config_path/config 2>/dev/null || echo "lxc.rootfs.path = $rootfs_path" >> $config_path/config
- cat <<EOF >> $config_path/config
-# Most of below settings should be taken as defaults from
-# lxc.include = /usr/share/lxc/config/common.conf
-lxc.uts.name = $utsname
-lxc.tty.max = 4
-lxc.pty.max = 1024
-# Consider if below line is right for systemd container
-lxc.mount.fstab = $config_path/fstab
-lxc.cap.drop = sys_module mac_admin mac_override sys_time
-
-lxc.autodev = $auto_dev
-
-# When using LXC with apparmor, uncomment the next line to run unconfined:
-#lxc.apparmor.profile = unconfined
-
-## Devices
-# Allow all devices
-#lxc.cgroup.devices.allow = a
-# Deny all devices
-lxc.cgroup.devices.deny = a
-# Allow to mknod all devices (but not using them)
-lxc.cgroup.devices.allow = c *:* m
-lxc.cgroup.devices.allow = b *:* m
-
-# /dev/null and zero
-lxc.cgroup.devices.allow = c 1:3 rwm
-lxc.cgroup.devices.allow = c 1:5 rwm
-# 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
-# rtc
-lxc.cgroup.devices.allow = c 254:0 rm
-EOF
-
- cat <<EOF > $config_path/fstab
-proc proc proc nodev,noexec,nosuid 0 0
-sysfs sys sysfs defaults 0 0
-EOF
- if [ $? -ne 0 ]; then
- echo "Failed to add configuration"
- return 1
- fi
-
- return 0
-}
-
-clean()
-{
-
- if [ ! -e $cache ]; then
- exit 0
- fi
-
- # lock, so we won't purge while someone is creating a repository
- (
- flock -x 9
- if [ $? != 0 ]; then
- echo "Cache repository is busy."
- exit 1
- fi
-
- echo -n "Purging the download cache for PLD Linux $release..."
- rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1
- exit 0
- ) 9>@LOCALSTATEDIR@/lock/subsys/lxc-pld
-}
-
-usage()
-{
- cat <<EOF
-usage:
- $1 -n|--name=<container_name>
- [-p|--path=<path>] [-c|--clean] [-R|--release=<PLD Release>] [--fqdn=<network name of container>] [-A|--arch=<arch of the container>]
- [-h|--help]
-Mandatory args:
- -n,--name container name, used to as an identifier for that container from now on
-Optional args:
- -p,--path path to where the container will be created, defaults to @LXCPATH@. The container config will go under @LXCPATH@ in that case
- --rootfs path for actual rootfs.
- -c,--clean clean the cache
- -R,--release PLD Linux release for the new container. if the host is PLD Linux, then it will default to the host's release.
- --fqdn fully qualified domain name (FQDN) for DNS and system naming
- -A,--arch NOT USED YET. Define what arch the container will be [i686,x86_64]
- -h,--help print this help
-EOF
- return 0
-}
-
-options=$(getopt -o hp:n:cR: -l help,path:,rootfs:,name:,clean,release:,fqdn: -- "$@")
-if [ $? -ne 0 ]; then
- usage $(basename $0)
- exit 1
-fi
-eval set -- "$options"
-
-while :; 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;;
- -R|--release) release=$2; shift 2;;
- --fqdn) utsname=$2; shift 2;;
- --) shift 1; break ;;
- *) break ;;
- esac
-done
-
-if [ ! -z "$clean" -a -z "$path" ]; then
- clean || exit 1
- exit 0
-fi
-
-if [ -z "${utsname}" ]; then
- utsname=${name}
-fi
-
-# This follows a standard "resolver" convention that an FQDN must have
-# at least two dots or it is considered a local relative host name.
-# If it doesn't, append the dns domain name of the host system.
-#
-# This changes one significant behavior when running
-# "lxc_create -n Container_Name" without using the
-# --fqdn option.
-#
-# Old behavior:
-# utsname and hostname = Container_Name
-# New behavior:
-# utsname and hostname = Container_Name.Domain_Name
-
-if [ $(expr "$utsname" : '.*\..*\.') = 0 ]; then
- if [ -n "$(dnsdomainname)" ]; then
- utsname=${utsname}.$(dnsdomainname)
- fi
-fi
-
-needed_pkgs=""
-type poldek >/dev/null 2>&1
-if [ $? -ne 0 ]; then
- needed_pkgs="poldek $needed_pkgs"
-fi
-
-#type curl >/dev/null 2>&1
-#if [ $? -ne 0 ]; then
-# needed_pkgs="curl $needed_pkgs"
-#fi
-
-if [ -n "$needed_pkgs" ]; then
- echo "Missing commands: $needed_pkgs"
- echo "Please install these using \"sudo poldek -u $needed_pkgs\""
- exit 1
-fi
-
-if [ -z "$path" ]; then
- path=$default_path/$name
-fi
-
-if [ -z "$release" ]; then
- if [ "$is_pld" -a "$pld_host_ver" ]; then
- release=$pld_host_ver
- else
- echo "This is not a PLD Linux host and release missing, defaulting to 3.0. use -R|--release to specify release"
- release=3.0
- fi
-fi
-
-# pld th have systemd. We need autodev enabled to keep systemd from causing problems.
-if [ $release = 3.0 ]; then
- auto_dev="0"
-else
- auto_dev="0"
-fi
-
-if [ "$(id -u)" != "0" ]; then
- echo "This script should be run as 'root'"
- exit 1
-fi
-
-if [ -z "$rootfs" ]; then
- rootfs_path=$path/rootfs
- # check for 'lxc.rootfs.path' passed in through default config by lxc-create
- # TODO: should be lxc.rootfs.mount used instead?
- if grep -q '^lxc.rootfs.path' $path/config 2>/dev/null ; then
- rootfs_path=$(awk -F= '/^lxc.rootfs.path =/{ print $2 }' $path/config)
- fi
-else
- rootfs_path=$rootfs
-fi
-config_path=$default_path/$name
-cache=$cache_base/$release
-
-revert()
-{
- echo "Interrupted, so cleaning up"
- lxc-destroy -n $name
- # maybe was interrupted before copy config
- rm -rf $path
- rm -rf $default_path/$name
- echo "exiting..."
- exit 1
-}
-
-trap revert SIGHUP SIGINT SIGTERM
-
-copy_configuration
-if [ $? -ne 0 ]; then
- echo "Failed write configuration file"
- exit 1
-fi
-
-install_pld
-if [ $? -ne 0 ]; then
- echo "Failed to install PLD Linux"
- exit 1
-fi
-
-configure_pld
-if [ $? -ne 0 ]; then
- echo "Failed to configure PLD Linux for a container"
- exit 1
-fi
-
-# If the systemd configuration directory exists - set it up for what we need.
-if [ -d ${rootfs_path}/etc/systemd/system ]; then
- configure_pld_systemd
-fi
-
-# This configuration (rc.sysinit) is not inconsistent with the systemd stuff
-# above and may actually coexist on some upgraded systems. Let's just make
-# sure that, if it exists, we update this file, even if it's not used...
-if [ -f ${rootfs_path}/etc/rc.sysinit ]; then
- configure_pld_init
-fi
-
-if [ ! -z $clean ]; then
- clean || exit 1
- exit 0
-fi
-echo "container rootfs and config created"
+++ /dev/null
-#!/bin/bash
-# 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/
-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://mirror.internode.on.net/pub/sabayon/
-http://mirror.yandex.ru/sabayon/
-http://sabayon.c3sl.ufpr.br/
-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=
-flush_owner=false
-
-#======================== 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.
- -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)
- --flush-owner Only for directly creation of unprivileged containers
- through lxc-create command. Execute fuidshift command.
- Require --mapped-gid,--mapped-uid and --unprivileged
- options.
-
-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
-
- 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
-
- # Comment unneeded entry on /etc/fstab
- sed -e 's/\/dev/#\/dev/g' -i ${rootfs}/etc/fstab
-
- # Fix this stupid error until fix is available on sabayon image
- # /usr/lib/systemd/system-generators/gentoo-local-generator: line 4: cd: /etc/local.d: No such file or directory
- mkdir ${rootfs}/etc/local.d/
-
- mkdir ${rootfs}/etc/systemd/system/NetworkManager.service.d/
- cat <<EOF > ${rootfs}/etc/systemd/system/NetworkManager.service.d/override.conf
-[Service]
-ExecStartPre=-/bin/ip -4 link set dev eth0 down
-EOF
- chmod 644 ${rootfs}/etc/systemd/system/NetworkManager.service.d/override.conf
-
- return 0
-}
-
-configure_container() {
- local config="$1"
- local hostname="$2"
- local arch="$3"
- local privileged_options=""
- local unprivileged_options=""
-
- if [[ $unprivileged && $unprivileged == true ]] ; then
- if [[ $flush_owner == true ]] ; then
- unprivileged_options="
-lxc.idmap = u 0 ${mapped_uid} 65536
-lxc.idmap = g 0 ${mapped_gid} 65536
-"
- fi
-
- unprivileged_options="
-$unprivileged_options
-
-# Force use of cgroup v1. Currently systemd doesn't support
-# correctly cgroup v2. See: https://github.com/lxc/lxc/issues/1669
-# about discussion of default-hierarchy option.
-lxc.init.cmd = /sbin/init systemd.legacy_systemd_cgroup_controller=yes
-
-# Include common configuration.
-lxc.include = $LXC_TEMPLATE_CONFIG/sabayon.userns.conf
-"
-
- else
- privileged_options="
-## Allow any mknod (but not reading/writing the node)
-lxc.cgroup.devices.allow = b *:* m
-lxc.cgroup.devices.allow = c *:* m
-
-### /dev/pts/*
-lxc.cgroup.devices.allow = c 136:* rwm
-### /dev/tty
-lxc.cgroup.devices.allow = c 5:0 rwm
-### /dev/console
-lxc.cgroup.devices.allow = c 5:1 rwm
-### /dev/ptmx
-lxc.cgroup.devices.allow = c 5:2 rwm
-### fuse
-lxc.cgroup.devices.allow = c 10:229 rwm
-
-"
- fi
-
- cat <<-EOF >> "$config"
-# Specify container architecture.
-lxc.arch = $arch
-
-# Set hostname.
-lxc.uts.name = $hostname
-
-# Include common configuration.
-lxc.include = $LXC_TEMPLATE_CONFIG/sabayon.common.conf
-
-$unprivileged_options
-$privileged_options
-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:,flush-owner,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
- ;;
- --flush-owner)
- flush_owner=true
- ;;
- --)
- 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 == true && $flush_owner == true &&-z "$mapped_uid" ]] && \
- die 1 'Missing required option --mapped-uid with --unprivileged option'
-
- [[ $unprivileged == true && $flush_owner == true && -z "$mapped_gid" ]] && \
- die 1 'Missing required option --mapped-gid with --unprivileged option'
-
- [[ $flush_owner == true && $unprivileged == false ]] && \
- die 1 'flush-owner require --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, flush_owner = $flush_owner"
-
- [ "$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 == true ]] ; then
- unprivileged_rootfs
- if [[ $flush_owner == true ]] ; then
- unprivileged_shift_owner
- fi
- 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
+++ /dev/null
-#!/bin/bash
-
-#
-# lxc: linux Container library
-
-# Authors:
-# Daniel Lezcano <daniel.lezcano@free.fr>
-
-# Template for slackware by Matteo Bernardini <ponce@slackbuilds.org>
-# some parts are taken from the debian one (used as model)
-
-# 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
-
-# Detect use under userns (unsupported)
-for arg in "$@"; do
- [ "$arg" = "--" ] && break
- if [ "$arg" = "--mapped-uid" -o "$arg" = "--mapped-gid" ]; then
- echo "This template can't be used for unprivileged containers." 1>&2
- echo "You may want to try the \"download\" template instead." 1>&2
- exit 1
- fi
-done
-
-# Add some directories to PATH in case we create containers with sudo
-export PATH=/sbin:/usr/sbin:$PATH
-
-cache=${cache:-/var/cache/lxc/slackware}
-
-# Use the primary Slackware site by default, but please consider changing
-# this to a closer mirror site.
-MIRROR=${MIRROR:-http://ftp.slackware.com/pub/slackware}
-
-if [ -z "$arch" ]; then
-case "$( uname -m )" in
- i?86) arch=i486 ;;
- arm*) arch=arm ;;
- *) arch=$( uname -m ) ;;
-esac
-fi
-
-LXC_TEMPLATE_CONFIG="@LXCTEMPLATECONFIG@"
-
-configure_slackware()
-{
-rootfs=$1
-hostname=$2
-
-echo "Configuring..." ; echo
-
-# The next part contains excerpts taken from SeTconfig (written by
-# Patrick Volkerding) from the slackware setup disk.
-# But before pasting them just set a variable to use them as they are
-T_PX=$rootfs
-
-( cd $T_PX ; chmod 755 ./ )
-( cd $T_PX ; chmod 755 ./var )
-if [ -d $T_PX/usr/src/linux ]; then
- chmod 755 $T_PX/usr/src/linux
-fi
-if [ ! -d $T_PX/proc ]; then
- mkdir $T_PX/proc
- chown root.root $T_PX/proc
-fi
-if [ ! -d $T_PX/sys ]; then
- mkdir $T_PX/sys
- chown root.root $T_PX/sys
-fi
-chmod 1777 $T_PX/tmp
-if [ ! -d $T_PX/var/spool/mail ]; then
- mkdir -p $T_PX/var/spool/mail
- chmod 755 $T_PX/var/spool
- chown root.mail $T_PX/var/spool/mail
- chmod 1777 $T_PX/var/spool/mail
-fi
-
-echo "#!/bin/sh" > $T_PX/etc/rc.d/rc.keymap
-echo "# Load the keyboard map. More maps are in /usr/share/kbd/keymaps." \
- >> $T_PX/etc/rc.d/rc.keymap
-echo "if [ -x /usr/bin/loadkeys ]; then" >> $T_PX/etc/rc.d/rc.keymap
-echo " /usr/bin/loadkeys us" >> $T_PX/etc/rc.d/rc.keymap
-echo "fi" >> $T_PX/etc/rc.d/rc.keymap
-chmod 755 $T_PX/etc/rc.d/rc.keymap
-
-# Network configuration is left to the user, that have to edit
-# /etc/rc.d/rc.inet1.conf and /etc/resolv.conf of the container
-# just set the hostname
-cat <<EOF > $rootfs/etc/HOSTNAME
-$hostname.example.net
-EOF
-cp $rootfs/etc/HOSTNAME $rootfs/etc/hostname
-
-# make needed devices, from Chris Willing's MAKEDEV.sh
-# http://www.vislab.uq.edu.au/howto/lxc/MAKEDEV.sh
-DEV=$rootfs/dev
-mkdir -p ${DEV}
-mknod -m 666 ${DEV}/null c 1 3
-mknod -m 666 ${DEV}/zero c 1 5
-mknod -m 666 ${DEV}/random c 1 8
-mknod -m 666 ${DEV}/urandom c 1 9
-mkdir -m 755 ${DEV}/pts
-mkdir -m 1777 ${DEV}/shm
-mknod -m 666 ${DEV}/tty c 5 0
-mknod -m 600 ${DEV}/console c 5 1
-mknod -m 666 ${DEV}/tty0 c 4 0
-mknod -m 666 ${DEV}/tty1 c 4 1
-mknod -m 666 ${DEV}/tty2 c 4 2
-mknod -m 666 ${DEV}/tty3 c 4 3
-mknod -m 666 ${DEV}/tty4 c 4 4
-mknod -m 666 ${DEV}/tty5 c 4 5
-mknod -m 666 ${DEV}/full c 1 7
-mknod -m 600 ${DEV}/initctl p
-mknod -m 660 ${DEV}/loop0 b 7 0
-mknod -m 660 ${DEV}/loop1 b 7 1
-ln -s pts/ptmx ${DEV}/ptmx
-ln -s /proc/self/fd ${DEV}/fd
-
-echo "Adding an etc/fstab"
-cat >$rootfs/etc/fstab <<EOF
-none /run tmpfs defaults,mode=0755 0 0
-EOF
-
-# simplify rc.6 and rc.S, http://www.vislab.uq.edu.au/howto/lxc/create_container.html
-# and some other small fixes for a clean boot
-cat >$rootfs/tmp/rcs.patch <<'EOF'
---- ./etc/rc.orig/rc.6 2012-08-15 01:03:12.000000000 +0200
-+++ ./etc/rc.d/rc.6 2013-02-17 10:26:30.888839354 +0100
-@@ -9,6 +9,12 @@
- # Author: Miquel van Smoorenburg <miquels@drinkel.nl.mugnet.org>
- # Modified by: Patrick J. Volkerding, <volkerdi@slackware.com>
- #
-+# minor tweaks for an lxc container
-+# by Matteo Bernardini <ponce@slackbuilds.org>,
-+# based also on Chris Willing's modifications
-+# http://www.vislab.uq.edu.au/howto/lxc/rc.6
-+# a check for a container variable is made to jump sections
-+container="lxc"
-
- # Set the path.
- PATH=/sbin:/etc:/bin:/usr/bin
-@@ -37,6 +43,9 @@
- ;;
- esac
-
-+# lxc container check
-+if [ ! $container = "lxc" ]; then
-+
- # Save the system time to the hardware clock using hwclock --systohc.
- if [ -x /sbin/hwclock ]; then
- # Check for a broken motherboard RTC clock (where ioports for rtc are
-@@ -53,6 +62,8 @@
- fi
- fi
-
-+fi # end container check
-+
- # Run any local shutdown scripts:
- if [ -x /etc/rc.d/rc.local_shutdown ]; then
- /etc/rc.d/rc.local_shutdown stop
-@@ -148,6 +159,9 @@
- sleep 2
- fi
-
-+# lxc container check
-+if [ ! $container = "lxc" ]; then
-+
- # Shut down PCMCIA devices:
- if [ -x /etc/rc.d/rc.pcmcia ]; then
- . /etc/rc.d/rc.pcmcia stop
-@@ -155,11 +169,16 @@
- /bin/sleep 5
- fi
-
-+fi # end container check
-+
- # Turn off process accounting:
- if [ -x /sbin/accton -a -r /var/log/pacct ]; then
- /sbin/accton off
- fi
-
-+# lxc container check
-+if [ ! $container = "lxc" ]; then
-+
- # Terminate acpid before syslog:
- if [ -x /etc/rc.d/rc.acpid -a -r /var/run/acpid.pid ]; then # quit
- . /etc/rc.d/rc.acpid stop
-@@ -170,6 +189,8 @@
- sh /etc/rc.d/rc.udev force-stop
- fi
-
-+fi # end container check
-+
- # Kill all remaining processes.
- if [ ! "$1" = "fast" ]; then
- echo "Sending all processes the SIGTERM signal."
-@@ -179,6 +200,9 @@
- /sbin/killall5 -9
- fi
-
-+# lxc container check
-+if [ ! $container = "lxc" ]; then
-+
- # Try to turn off quota.
- if /bin/grep -q quota /etc/fstab ; then
- if [ -x /sbin/quotaoff ]; then
-@@ -187,6 +211,8 @@
- fi
- fi
-
-+fi # end container check
-+
- # Carry a random seed between reboots.
- echo "Saving random seed from /dev/urandom in /etc/random-seed."
- # Use the pool size from /proc, or 512 bytes:
-@@ -205,6 +231,9 @@
- rm -f /var/lock/subsys/*
- fi
-
-+# lxc container check
-+if [ ! $container = "lxc" ]; then
-+
- # Turn off swap:
- echo "Turning off swap."
- /sbin/swapoff -a
-@@ -216,6 +245,8 @@
- echo "Remounting root filesystem read-only."
- /bin/mount -v -n -o remount,ro /
-
-+fi # end container check
-+
- # This never hurts:
- /bin/sync
-
-@@ -240,12 +271,17 @@
- done
- fi
-
-+# lxc container check
-+if [ ! $container = "lxc" ]; then
-+
- # Deactivate LVM volume groups:
- if [ -r /etc/lvmtab -o -d /etc/lvm/backup ]; then
- echo "Deactivating LVM volume groups:"
- /sbin/vgchange -an --ignorelockingfailure
- fi
-
-+fi # end container check
-+
- # This never hurts again (especially since root-on-LVM always fails
- # to deactivate the / logical volume... but at least it was
- # remounted as read-only first)
-@@ -258,6 +294,9 @@
- # This is to ensure all processes have completed on SMP machines:
- wait
-
-+# lxc container check
-+if [ ! $container = "lxc" ]; then
-+
- if [ -x /sbin/genpowerd ]; then
- # See if this is a powerfail situation:
- if /bin/egrep -q "FAIL|SCRAM" /etc/upsstatus 2> /dev/null ; then
-@@ -274,6 +313,13 @@
- fi
- fi
-
-+else
-+
-+# confirm successful shutdown of the container
-+echo ; echo "* container stopped. *" ; echo
-+
-+fi # end container check
-+
- # Now halt (poweroff with APM or ACPI enabled kernels) or reboot.
- if [ "$command" = "reboot" ]; then
- echo "Rebooting."
---- ./etc/rc.orig/rc.S 2012-09-13 21:38:34.000000000 +0200
-+++ ./etc/rc.d/rc.S 2013-02-17 09:39:41.579799641 +0100
-@@ -4,9 +4,18 @@
- #
- # Mostly written by: Patrick J. Volkerding, <volkerdi@slackware.com>
- #
-+# minor tweaks for an lxc container
-+# by Matteo Bernardini <ponce@slackbuilds.org>,
-+# based also on Chris Willing's modifications
-+# http://www.vislab.uq.edu.au/howto/lxc/rc.S
-+# a check for a container variable is made to jump sections
-+container="lxc"
-
- PATH=/sbin:/usr/sbin:/bin:/usr/bin
-
-+# lxc container check
-+if [ ! $container = "lxc" ]; then
-+
- # Try to mount /proc:
- /sbin/mount -v proc /proc -n -t proc 2> /dev/null
-
-@@ -254,10 +263,27 @@
- read junk;
- fi # Done checking root filesystem
-
-+else
-+ # We really don't want to start udev in the container
-+ if [ -f /etc/rc.d/rc.udev ]; then
-+ chmod -x /etc/rc.d/rc.udev
-+ fi
-+ # Alsa won't work
-+ if [ -f /etc/rc.d/rc.alsa ]; then
-+ chmod -x /etc/rc.d/rc.alsa
-+ fi
-+ # This too
-+ if [ -f /etc/rc.d/rc.loop ]; then
-+ chmod -x /etc/rc.d/rc.loop
-+ fi
-+fi # end container check
-
- # Any /etc/mtab that exists here is old, so we start with a new one:
- /bin/rm -f /etc/mtab{,~,.tmp} && /bin/touch /etc/mtab
-
-+# lxc container check
-+if [ ! $container = "lxc" ]; then
-+
- # Add entry for / to /etc/mtab:
- /sbin/mount -f -w /
-
-@@ -337,6 +363,8 @@
- # mounted read-write.
- /sbin/swapon -a 2> /dev/null
-
-+fi # end container check
-+
- # Clean up some temporary files:
- rm -f /var/run/* /var/run/*/* /var/run/*/*/* /etc/nologin \
- /etc/dhcpc/*.pid /etc/forcefsck /etc/fastboot \
-@@ -364,7 +392,7 @@
- # if the first line of that file begins with the word 'Linux'.
- # You are free to modify the rest of the file as you see fit.
- if [ -x /bin/sed ]; then
-- /bin/sed -i "{1s/^Linux.*/$(/bin/uname -sr)\./}" /etc/motd
-+ /bin/sed -i "{1s/^Linux.*/$(/bin/uname -sr) lxc container\./}" /etc/motd
- fi
-
- # If there are SystemV init scripts for this runlevel, run them.
-@@ -372,6 +400,9 @@
- . /etc/rc.d/rc.sysvinit
- fi
-
-+# lxc container check
-+if [ ! $container = "lxc" ]; then
-+
- # Run serial port setup script:
- # CAREFUL! This can make some systems hang if the rc.serial script isn't
- # set up correctly. If this happens, you may have to edit the file from a
-@@ -380,6 +411,8 @@
- sh /etc/rc.d/rc.serial start
- fi
-
-+fi # end container check
-+
- # Carry an entropy pool between reboots to improve randomness.
- if [ -f /etc/random-seed ]; then
- echo "Using /etc/random-seed to initialize /dev/urandom."
---- ./etc/rc.orig/rc.M 2012-09-25 19:47:07.000000000 +0200
-+++ ./etc/rc.d/rc.M 2013-02-17 09:39:41.579799641 +0100
-@@ -10,6 +10,10 @@
- # Author: Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
- # Heavily modified by Patrick Volkerding <volkerdi@slackware.com>
- #
-+# minor tweaks for an lxc container
-+# by Matteo Bernardini <ponce@slackbuilds.org>:
-+# a check for a container variable is made to jump sections
-+container="lxc"
-
- # Tell the viewers what's going to happen.
- echo "Going multiuser..."
-@@ -20,6 +24,9 @@
- /sbin/ldconfig &
- fi
-
-+# lxc container check
-+if [ ! $container = "lxc" ]; then
-+
- # Screen blanks after 15 minutes idle time, and powers down in one hour
- # if the kernel supports APM or ACPI power management:
- /bin/setterm -blank 15 -powersave powerdown -powerdown 60
-@@ -33,6 +40,8 @@
- /bin/hostname darkstar
- fi
-
-+fi # end container check
-+
- # Set the permissions on /var/log/dmesg according to whether the kernel
- # permits non-root users to access kernel dmesg information:
- if [ -r /proc/sys/kernel/dmesg_restrict ]; then
-@@ -135,6 +144,9 @@
- chmod 755 / 2> /dev/null
- chmod 1777 /tmp /var/tmp
-
-+# lxc container check
-+if [ ! $container = "lxc" ]; then
-+
- # Start APM or ACPI daemon.
- # If APM is enabled in the kernel, start apmd:
- if [ -e /proc/apm ]; then
-@@ -146,6 +158,8 @@
- . /etc/rc.d/rc.acpid start
- fi
-
-+fi # end container check
-+
- # Update any existing icon cache files:
- if find /usr/share/icons 2> /dev/null | grep -q icon-theme.cache ; then
- for theme_dir in /usr/share/icons/* ; do
---- ./etc/rc.orig/rc.inet1 2012-08-05 19:13:27.000000000 +0200
-+++ ./etc/rc.d/rc.inet1 2013-02-17 09:39:41.579799641 +0100
-@@ -3,6 +3,11 @@
- # This script is used to bring up the various network interfaces.
- #
- # @(#)/etc/rc.d/rc.inet1 10.2 Sun Jul 24 12:45:56 PDT 2005 (pjv)
-+#
-+# minor tweaks for an lxc container
-+# by Matteo Bernardini <ponce@slackbuilds.org>:
-+# a check for a container variable is made to jump sections
-+container="lxc"
-
- ############################
- # READ NETWORK CONFIG FILE #
-@@ -105,6 +110,10 @@
- [ "${IFNAME[$i]}" = "${1}" ] && break
- i=$(($i+1))
- done
-+
-+ # lxc container check
-+ if [ ! $container = "lxc" ]; then
-+
- # If the interface is a bridge, then create it first:
- [ -n "${BRNICS[$i]}" ] && br_open $i
- # If the interface isn't in the kernel yet (but there's an alias for it in
-@@ -115,6 +124,9 @@
- /sbin/modprobe ${1}
- fi
- fi
-+
-+ fi # end container check
-+
- if grep `echo ${1}: | cut -f 1 -d :`: /proc/net/dev 1> /dev/null ; then # interface exists
- if ! /sbin/ifconfig | grep -w "${1}" 1>/dev/null || \
- ! /sbin/ifconfig ${1} | grep -w inet 1> /dev/null ; then # interface not up or not configured
-EOF
-( cd $rootfs ; patch -p1 < tmp/rcs.patch ; rm tmp/rcs.patch )
-
-# restart rc.inet1 to have routing for the loop device
-echo "/etc/rc.d/rc.inet1 restart" >> $rootfs/etc/rc.d/rc.local
-
-# reduce the number of local consoles: two should be enough
-sed -i '/^c3\|^c4\|^c5\|^c6/s/^/# /' $rootfs/etc/inittab
-
-# better not use this in a container
-sed -i 's/.*genpowerfail.*//' $rootfs/etc/inittab
-
-# add a message to rc.local that confirms successful container startup
-echo "echo ; echo \"* container $name started. *\" ; echo" >> $rootfs/etc/rc.d/rc.local
-
-# borrow the time configuration from the local machine
-cp -a /etc/localtime $rootfs/etc/localtime
-
-return 0
-}
-
-copy_slackware()
-{
-rootfs=$1
-
-# make a local copy of the installed filesystem
-echo -n "Copying rootfs to $rootfs..."
-mkdir -p $rootfs
-cp -a $cache/rootfs-$release-$arch/* $rootfs/ || exit 1
-
-# fix fstab with the actual path
-sed -i "s|$cache/rootfs-$release-$arch|$rootfs|" $rootfs/etc/fstab
-
-return 0
-}
-
-install_slackware()
-{
-rootfs=$1
-mkdir -p /var/lock/subsys/
-(
-flock -n -x 9
-if [ $? -ne 0 ]; then
- echo "Cache repository is busy."
- return 1
-fi
-
-if [ "$arch" == "x86_64" ]; then
- PKGMAIN=slackware64
-elif [ "$arch" == "arm" ]; then
- PKGMAIN=slackwarearm
-else
- PKGMAIN=slackware
-fi
-
-export CONF=$cache/slackpkg-conf
-export ROOT=$cache/rootfs-$release-$arch
-
-mkdir -p $cache/cache-$release-$arch $cache/rootfs-$release-$arch \
- $cache/slackpkg-$release-$arch $CONF/templates
-
-echo "$MIRROR/$PKGMAIN-$release/" > $CONF/mirrors
-touch $CONF/blacklist
-
-cat <<EOF > $CONF/slackpkg.conf
-# v2.8
-ARCH=$arch
-TEMP=$cache/cache-$release-$arch
-WORKDIR=$cache/slackpkg-$release-$arch
-DELALL=off
-CHECKMD5=on
-CHECKGPG=on
-CHECKSIZE=off
-PRIORITY=( patches %PKGMAIN extra pasture testing )
-POSTINST=on
-ONLY_NEW_DOTNEW=off
-ONOFF=on
-DOWNLOAD_ALL=on
-DIALOG=off
-BATCH=on
-DEFAULT_ANSWER=y
-USE_INCLUDES=on
-SPINNING=off
-EOF
-
-# thanks to Vincent Batts for this list of packages
-# (that I modified a little :P)
-# http://connie.slackware.com/~vbatts/minimal/
-cat <<EOF > $CONF/templates/minimal-lxc.template
-aaa_base
-aaa_elflibs
-aaa_terminfo
-bash
-bin
-bzip2
-coreutils
-dhcpcd
-dialog
-diffutils
-e2fsprogs
-elvis
-etc
-findutils
-gawk
-glibc-solibs
-gnupg
-grep
-gzip
-hostname
-iputils
-libunistring
-logrotate
-mpfr
-net-tools
-network-scripts
-ncurses
-openssh
-openssl-solibs
-pkgtools
-procps-ng
-sed
-shadow
-sharutils
-slackpkg
-sysklogd
-sysvinit
-sysvinit-functions
-sysvinit-scripts
-tar
-udev
-util-linux
-wget
-which
-xz
-EOF
-
-TEMPLATE=${TEMPLATE:-minimal-lxc}
-if [ ! "$TEMPLATE" = "minimal-lxc" ]; then
- if [ -f /etc/slackpkg/templates/$TEMPLATE.template ]; then
- cat /etc/slackpkg/templates/$TEMPLATE.template \
- > $CONF/templates/$TEMPLATE.template
- else
- TEMPLATE="minimal-lxc"
- fi
-fi
-
-# clean previous installs
-rm -fR $ROOT/*
-
-slackpkg -default_answer=n update
-slackpkg install-template $TEMPLATE
-
-# add a slackpkg default mirror
-echo "$MIRROR/$PKGMAIN-$release/" >> $ROOT/etc/slackpkg/mirrors
-
-# blacklist the devs package (we have to use our premade devices).
-# do the same with the kernel packages (we use the host's one),
-# but leave available headers and sources
-echo "devs" >> $ROOT/etc/slackpkg/blacklist
-sed -i \
- -e "s|^#kernel-|kernel-|" \
- -e "s|^kernel-headers|#kernel-headers|" \
- -e "s|^kernel-source|#kernel-source|" \
- $ROOT/etc/slackpkg/blacklist
-
-# force klog to use the system call interface to the kernel message
-# buffers - needed for unprivileged containers
-sed -i 's|3\ \-x|3 -x -s|' $ROOT/etc/rc.d/rc.syslog || true
-
-return 0
-
-) 9>/var/lock/subsys/lxc
-
-return $?
-}
-
-copy_configuration()
-{
-path=$1
-rootfs=$2
-name=$3
-
-cat <<EOF >> $path/config
-
-lxc.uts.name = $name
-lxc.arch = $arch
-
-lxc.mount.fstab = $rootfs/etc/fstab
-
-lxc.include = ${LXC_TEMPLATE_CONFIG}/slackware.common.conf
-EOF
-
-if [ $? -ne 0 ]; then
- echo "Failed to add configuration."
- return 1
-fi
-
-return 0
-}
-
-clean()
-{
-if [ ! -e $cache ]; then
- exit 0
-fi
-
-# lock, so we won't purge while someone is creating a repository
-(
-flock -n -x 9
-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
-
-) 9>/var/lock/subsys/lxc
-}
-
-usage()
-{
-cat <<EOF
-$1 -h|--help -p|--path=<path> --clean
-EOF
-return 0
-}
-
-options=$(getopt -o hp:n:a:r:c -l help,rootfs:,path:,name:,arch:,release:,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;;
- -a|--arch) arch=$2; shift 2;;
- -r|--release) release=$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 installpkg
-if [ $? -ne 0 ]; then
- echo "'installpkg' command is missing."
- exit 1
-fi
-
-type slackpkg
-if [ $? -ne 0 ]; then
- echo "'slackpkg' 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
-
-# If no release version was specified, use current
-release=${release:-current}
-
-if [ -z "$name" ]; then
- # no name given? set a default one
- name=slackwarecontainer
-fi
-
-# detect rootfs
-config="$path/config"
-if [ -z "$rootfs" ]; then
- if grep -q '^lxc.rootfs.path' $config 2>/dev/null ; then
- rootfs=$(awk -F= '/^lxc.rootfs.path =/{ print $2 }' $config)
- else
- rootfs=$path/rootfs
- fi
-fi
-
-echo
-
-set -e
-
-install_slackware $rootfs
-if [ $? -ne 0 ]; then
- echo "Failed to install slackware."
- exit 1
-fi
-
-echo
-
-configure_slackware $cache/rootfs-$release-$arch $name
-if [ $? -ne 0 ]; then
- echo "Failed to configure slackware for a container."
- exit 1
-fi
-
-echo
-
-rootfs=$path/rootfs
-copy_slackware $rootfs
-if [ $? -ne 0 ]; then
- echo "Failed to copy rootfs."
- exit 1
-fi
-
-echo
-
-copy_configuration $path $rootfs $name
-if [ $? -ne 0 ]; then
- echo "Failed to write configuration file."
- exit 1
-fi
-
-if [ ! -z $clean ]; then
- clean || exit 1
- exit 0
-fi
+++ /dev/null
-#!/bin/sh
-#
-# Template script for generating Linux for SPARC for LXC
-# based on lxc-fedora, lxc-ubuntu
-#
-# Copyright © 2011 Wim Coekaerts <wim.coekaerts@oracle.com>
-# Copyright © 2012 Dwight Engen <dwight.engen@oracle.com>
-# Copyright � 2015 Wim Coekaerts <wim.coekaerts@oracle.com>
-#
-# Modified for Oracle Linux 5
-# Wim Coekaerts <wim.coekaerts@oracle.com>
-#
-# Modified for Oracle Linux 6,7 combined OL4,5,6 into one template script
-# Dwight Engen <dwight.engen@oracle.com>
-#
-# Modified for Linux for SPARC 1.0
-# Wim Coekaerts <wim.coekaerts@oracle.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
-#
-
-# Detect use under userns (unsupported)
-for arg in "$@"; do
- [ "$arg" = "--" ] && break
- if [ "$arg" = "--mapped-uid" -o "$arg" = "--mapped-gid" ]; then
- echo "This template can't be used for unprivileged containers." 1>&2
- echo "You may want to try the \"download\" template instead." 1>&2
- exit 1
- fi
-done
-
-# Make sure the usual locations are in PATH
-export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
-
-die()
-{
- echo "failed: $1"
- exit 1
-}
-
-is_btrfs_subvolume()
-{
- if which btrfs >/dev/null 2>&1 && \
- btrfs subvolume list "$1" >/dev/null 2>&1; then
- return 0
- fi
- return 1
-}
-
-can_chcon()
-{
- if which chcon >/dev/null 2>&1; then
- selinuxenabled >/dev/null 2>&1
- return $?
- fi
- return 1
-}
-
-# fix up the container_rootfs
-container_rootfs_patch()
-{
- echo "Patching container rootfs $container_rootfs for Linux for SPARC $container_release_major.$container_release_minor"
-
- # copy ourself into the container to be used to --patch the rootfs when
- # yum update on certain packages is done. we do this here instead of in
- # container_rootfs_configure() in case the patching done in this function
- # is updated in the future, we can inject the updated version of ourself
- # into older containers.
- if [ $container_rootfs != "/" ]; then
- cp -f `readlink -f $0` $container_rootfs/usr/bin/lxc-patch
- mkdir -p $container_rootfs/usr/share/yum-plugins
- cp @DATADIR@/lxc/lxc-patch.py $container_rootfs/usr/share/yum-plugins
- mkdir -p $container_rootfs/etc/yum/pluginconf.d
- cat <<EOF > $container_rootfs/etc/yum/pluginconf.d/lxc-patch.conf
-[main]
-enabled=1
-packages=dbus,initscripts,iptables,openssh-server,setup,selinux-policy,readahead,udev,util-linux,util-linux-ng
-EOF
- fi
-
- # "disable" selinux in the guest. The policy in the container isn't
- # likely to match the hosts (unless host == guest exactly) and the
- # kernel can only be enforcing one policy.
- #
- mkdir -p $container_rootfs/selinux
- echo 0 > $container_rootfs/selinux/enforce
- if [ -e $container_rootfs/etc/selinux/config ]; then
- sed -i 's|SELINUX=enforcing|SELINUX=disabled|' $container_rootfs/etc/selinux/config
- else
- mkdir -p $container_rootfs/etc/selinux
- echo "SELINUX=disabled" >$container_rootfs/etc/selinux/config
- fi
- sed -i 's|session[ \t]*required[ \t]*pam_selinux.so[ \t]*close|#session required pam_selinux.so close|' $container_rootfs/etc/pam.d/login
- sed -i 's|session[ \t]*required[ \t]*pam_selinux.so[ \t]*open|#session required pam_selinux.so open|' $container_rootfs/etc/pam.d/login
- sed -i 's|session[ \t]*required[ \t]*pam_selinux.so[ \t]*close|#session required pam_selinux.so close|' $container_rootfs/etc/pam.d/sshd
- sed -i 's|session[ \t]*required[ \t]*pam_selinux.so[ \t]*open|#session required pam_selinux.so open|' $container_rootfs/etc/pam.d/sshd
-
- # setting /proc/$$/loginuid doesn't work under user namespace, which
- # prevents logins from working
- sed -i 's|session[ \t]*required[ \t]*pam_loginuid.so|#session required pam_loginuid.so|' $container_rootfs/etc/pam.d/sshd
- sed -i 's|session[ \t]*required[ \t]*pam_loginuid.so|#session required pam_loginuid.so|' $container_rootfs/etc/pam.d/login
-
- if [ -f $container_rootfs/usr/sbin/selinuxenabled ]; then
- mv $container_rootfs/usr/sbin/selinuxenabled $container_rootfs/usr/sbin/selinuxenabled.lxcorig
- ln -s /bin/false $container_rootfs/usr/sbin/selinuxenabled
- fi
-
- # ensure /dev/ptmx refers to the newinstance devpts of the container, or
- # pty's will get crossed up with the hosts (https://lkml.org/lkml/2012/1/23/512)
- rm -f $container_rootfs/dev/ptmx
- ln -s pts/ptmx $container_rootfs/dev/ptmx
-
- # silence error in checking for selinux
- sed -i 's|cat /proc/self/attr/current|cat /proc/self/attr/current 2>/dev/null|' $container_rootfs/etc/rc.sysinit
- sed -i 's|cat /proc/self/attr/current|cat /proc/self/attr/current 2>/dev/null|' $container_rootfs/etc/rc.d/rc.sysinit
-
- # disable ipv6
- rm -f $container_rootfs/etc/sysconfig/network-scripts/init.ipv6-global
-
- # remove module stuff for iptables it just shows errors that are not
- # relevant in a container
- if [ -f "$container_rootfs/etc/sysconfig/iptables-config" ]; then
- sed -i 's|IPTABLES_MODULES=".*|IPTABLES_MODULES=""|' $container_rootfs/etc/sysconfig/iptables-config
- sed -i 's|IPTABLES_MODULES_UNLOAD=".*|IPTABLES_MODULES_UNLOAD="no"|' $container_rootfs/etc/sysconfig/iptables-config
- fi
-
- # disable readahead in the container
- if [ $container_release_major = "1" -a -e $container_rootfs/etc/sysconfig/readahead ]; then
- rm -f $container_rootfs/etc/init/readahead-collector.conf
- rm -f $container_rootfs/etc/init/readahead-disable-services.conf
- sed -i 's|READAHEAD="yes"|READAHEAD="no"|' $container_rootfs/etc/sysconfig/readahead
- fi
-
-
- # no need to attempt to mount /
- sed -i 's|mount -f /$|# LXC mount -f /|' $container_rootfs/etc/rc.sysinit
- sed -i 's|mount -f /$|# LXC mount -f /|' $container_rootfs/etc/rc.d/rc.sysinit
- sed -i 's|action \$"Remounting root filesystem|/bin/true # LXC action $"Remounting root filesystem|' $container_rootfs/etc/rc.sysinit
- sed -i 's|action \$"Remounting root filesystem|/bin/true # LXC action $"Remounting root filesystem|' $container_rootfs/etc/rc.d/rc.sysinit
-
- # disable udev in the container
- sed -i 's|.sbin.start_udev||' $container_rootfs/etc/rc.sysinit
- sed -i 's|.sbin.start_udev||' $container_rootfs/etc/rc.d/rc.sysinit
-
- sed -i 's|\[ -x /sbin/hwclock|\[ 0 -eq 1|' $container_rootfs/etc/rc.d/init.d/halt
- sed -i 's|^\[ -x /sbin/hwclock|\[ 0 -eq 1|' $container_rootfs/etc/rc.sysinit
- sed -i 's|^\[ -x /sbin/hwclock|\[ 0 -eq 1|' $container_rootfs/etc/rc.d/rc.sysinit
- sed -i 's|^/sbin/hwclock|# LXC /sbin/nohwclock|' $container_rootfs/etc/rc.sysinit
- sed -i 's|^/sbin/hwclock|# LXC /sbin/nohwclock|' $container_rootfs/etc/rc.d/rc.sysinit
-
- touch $container_rootfs/.nolvm
-
- # fix assumptions that plymouth is available
- sed -i 's|\[ "$PROMPT" != no \] && plymouth|[ "$PROMPT" != no ] \&\& [ -n "$PLYMOUTH" ] \&\& plymouth|' $container_rootfs/etc/rc.sysinit
- sed -i 's|\[ "$PROMPT" != no \] && plymouth|[ "$PROMPT" != no ] \&\& [ -n "$PLYMOUTH" ] \&\& plymouth|' $container_rootfs/etc/rc.d/rc.sysinit
- rm -f $container_rootfs/etc/init/plymouth-shutdown.conf
- rm -f $container_rootfs/etc/init/quit-plymouth.conf
- rm -f $container_rootfs/etc/init/splash-manager.conf
-
- # dont try to unmount /dev/lxc devices
- sed -i 's|&& $1 !~ /^\\/dev\\/ram/|\&\& $2 !~ /^\\/dev\\/lxc/ \&\& $1 !~ /^\\/dev\\/ram/|' $container_rootfs/etc/init.d/halt
-
- # don't try to unmount swap
- sed -i 's|\[ -f /proc/swaps \]|# LXC [ -f /proc/swaps ]|' $container_rootfs/etc/init.d/halt
-
- sed -i 's|mount -n -o remount /dev/shm >/dev/null 2>&1$|mkdir -p /dev/shm \&\& mount -t tmpfs tmpfs /dev/shm # LXC|' $container_rootfs/etc/rc.sysinit
- sed -i 's|mount -n -o remount /dev/shm >/dev/null 2>&1$|mkdir -p /dev/shm \&\& mount -t tmpfs tmpfs /dev/shm # LXC|' $container_rootfs/etc/rc.d/rc.sysinit
-
- # there might be other services that are useless but the below set is a good start
- # some of these might not exist in the image, so we silence chkconfig complaining
- # about the service file not being found
- for service in \
- acpid apmd auditd autofs cpuspeed dund gpm haldaemon hidd \
- ip6tables irqbalance iscsi iscsid isdn kdump kudzu \
- lm_sensors lvm2-monitor mdmonitor microcode_ctl \
- ntpd pcmcia postfix sendmail udev-post xfs ;
- do
- chroot $container_rootfs chkconfig 2>/dev/null $service off
- done
-
- for service in rsyslog ;
- do
- chroot $container_rootfs chkconfig 2>/dev/null $service on
- done
-}
-
-container_rootfs_configure()
-{
- container_rootfs_patch
- echo "Configuring container for Linux for SPARC $container_release_major.$container_release_minor"
-
- # configure the network to use dhcp. we set DHCP_HOSTNAME so the guest
- # will report its name and be resolv'able by the hosts dnsmasq
- cat <<EOF > $container_rootfs/etc/sysconfig/network-scripts/ifcfg-eth0
-DEVICE=eth0
-BOOTPROTO=dhcp
-ONBOOT=yes
-HOSTNAME=$name
-DHCP_HOSTNAME=\`hostname\`
-NM_CONTROLLED=no
-TYPE=Ethernet
-EOF
-
- cat <<EOF > $container_rootfs/etc/sysconfig/network
-NETWORKING=yes
-NETWORKING_IPV6=no
-HOSTNAME=$name
-EOF
-
- # set minimal hosts
- echo "127.0.0.1 localhost $name" > $container_rootfs/etc/hosts
-
- # this file has to exist for libvirt/Virtual machine monitor to boot the container
- touch $container_rootfs/etc/mtab
-
- # setup console and tty[1-4] for login. note that /dev/console and
- # /dev/tty[1-4] will be symlinks to the ptys /dev/lxc/console and
- # /dev/lxc/tty[1-4] so that package updates can overwrite the symlinks.
- # lxc will maintain these links and bind mount ptys over /dev/lxc/*
- # since lxc.tty.dir is specified in the config.
-
- # allow root login on console, tty[1-4], and pts/0 for libvirt
- echo "# LXC (Linux Containers)" >>$container_rootfs/etc/securetty
- echo "lxc/console" >>$container_rootfs/etc/securetty
- for i in 1 2 3 4; do
- echo "lxc/tty$i" >>$container_rootfs/etc/securetty
- done
- echo "# For libvirt/Virtual Machine Monitor" >>$container_rootfs/etc/securetty
- for i in 0 1 2 3 4; do
- echo "pts/$i" >>$container_rootfs/etc/securetty
- done
-
- # prevent mingetty from calling vhangup(2) since it fails with userns
- if [ -f $container_rootfs/etc/init/tty.conf ]; then
- sed -i 's|mingetty|mingetty --nohangup|' $container_rootfs/etc/init/tty.conf
- fi
-
- # create maygetty which only spawns a getty on the console when running
- # under lxc, not libvirt-lxc which symlinks /dev/console to the same pty
- # as /dev/tty1
- cat <<EOF >$container_rootfs/sbin/maygetty
-#!/bin/sh
-if [ "\$container" = "lxc" ]; then
- exec /sbin/mingetty \$@
-fi
-exec sleep infinity
-EOF
- chmod 755 $container_rootfs/sbin/maygetty
-
- cat <<EOF > $container_rootfs/etc/init/console.conf
-# console - getty
-#
-# This service maintains a getty on the console from the point the system is
-# started until it is shut down again.
-
-start on stopped rc RUNLEVEL=[2345]
-stop on runlevel [!2345]
-env container
-
-respawn
-exec /sbin/maygetty --nohangup --noclear /dev/console
-EOF
-
- cat <<EOF > $container_rootfs/etc/init/power-status-changed.conf
-# power-status-changed - used to cleanly shut down the container
-#
-# This task is run whenever init receives SIGPWR
-# Used to shut down the machine.
-
-start on power-status-changed
-
-exec init 0
-EOF
-
- # start with a clean /var/log/messages
- rm -f $container_rootfs/var/log/messages
-
- # set initial timezone as on host
- if [ -f /etc/sysconfig/clock ]; then
- . /etc/sysconfig/clock
- echo ZONE=$ZONE > $container_rootfs/etc/sysconfig/clock
- chroot $container_rootfs tzdata-update
- else
- echo "Timezone in container is not configured. Adjust it manually."
- fi
-
- # add oracle user
- chroot $container_rootfs useradd -m -s /bin/bash oracle
- printf "Added container user:\033[1moracle\033[0m\n"
- printf "Added container user:\033[1mroot\033[0m\n"
-}
-
-# create the container's lxc config file
-container_config_create()
-{
- echo "Create configuration file $cfg_dir/config"
- mkdir -p $cfg_dir || die "unable to create config dir $cfg_dir"
-
- echo "# Common configuration" >> $cfg_dir/config
- if [ -e "@LXCTEMPLATECONFIG@/sparclinux.common.conf" ]; then
- echo "lxc.include = @LXCTEMPLATECONFIG@/sparclinux.common.conf" >> $cfg_dir/config
- fi
-
- cat <<EOF >> $cfg_dir/config || die "unable to create $cfg_dir/config"
-# Container configuration for Linux for SPARC $container_release_major.$container_release_minor
-lxc.arch = $arch
-lxc.uts.name = $name
-EOF
- grep -q "^lxc.rootfs.path" $cfg_dir/config 2>/dev/null || echo "lxc.rootfs.path = $container_rootfs" >> $cfg_dir/config
-
- echo "lxc.cap.drop = sys_resource" >>$cfg_dir/config
-
- echo "lxc.cap.drop = setfcap setpcap" >>$cfg_dir/config
-
- echo "# Networking" >>$cfg_dir/config
- # see if the default network settings were already specified
- lxc_network_type=`grep '^lxc.net.0.type' $cfg_dir/config | awk -F'[= \t]+' '{ print $2 }'`
- if [ -z "$lxc_network_type" ]; then
- echo "lxc.net.0.type = veth" >>$cfg_dir/config
- lxc_network_type=veth
- fi
-
- lxc_network_link=`grep '^lxc.net.0.link' $cfg_dir/config | awk -F'[= \t]+' '{ print $2 }'`
- if [ -z "$lxc_network_link" ]; then
- echo "lxc.net.0.link = lxcbr0" >>$cfg_dir/config
- lxc_network_link=lxcbr0
- fi
-
- lxc_network_hwaddr=`grep '^lxc.net.0.hwaddr' $cfg_dir/config | awk -F'[= \t]+' '{ print $2 }'`
- if [ -z "$lxc_network_hwaddr" ]; then
- # generate a hwaddr for the container
- # see http://sourceforge.net/tracker/?func=detail&aid=3411497&group_id=163076&atid=826303
- local hwaddr="00:16:3e:`dd if=/dev/urandom bs=8 count=1 2>/dev/null |od -t x8 | \
- head -n1 | awk '{print $2}' | cut -c1-6 | \
- sed 's/\(..\)/\1:/g; s/.$//'`"
- echo "lxc.net.0.hwaddr = $hwaddr" >>$cfg_dir/config
- fi
-
- lxc_network_flags=`grep '^lxc.net.0.flags' $cfg_dir/config | awk -F'[= \t]+' '{ print $2 }'`
- if [ -z "$lxc_network_flags" ]; then
- echo "lxc.net.0.flags = up" >>$cfg_dir/config
- fi
-
- cat <<EOF >> $cfg_dir/config || die "unable to create $cfg_dir/config"
-lxc.net.0.name = eth0
-lxc.net.0.mtu = 1500
-EOF
-}
-
-container_rootfs_clone()
-{
- if is_btrfs_subvolume $template_rootfs; then
- # lxc-create already made $container_rootfs a btrfs subvolume, but
- # in this case we want to snapshot the original subvolume so we we
- # have to delete the one that lxc-create made
- btrfs subvolume delete $container_rootfs
- btrfs subvolume snapshot $template_rootfs $container_rootfs || die "btrfs clone template"
- else
- echo "Copying rootfs ..."
- cp -axT $template_rootfs $container_rootfs || die "copy template"
- fi
-}
-
-container_rootfs_repo_create()
-{
- echo "# LXC generated .repo file" >$1
- echo "[$2]" >>$1
- echo "name=Linux for SPARC $container_release_major.$container_release_minor ($basearch)" >>$1
- echo "baseurl=$3/" >>$1
- echo "enabled=1" >>$1
- echo "skip_if_unavailable=1" >>$1
-
- if [ "$4" != "" ]; then
- echo "gpgkey=$yum_url/RPM-GPG-KEY-oracle-ol$container_release_major" >>$1
- echo "gpgcheck=1" >>$1
- else
- echo "gpgcheck=0" >>$1
- fi
-}
-
-container_rootfs_dev_create()
-{
- # create required devices. note that /dev/console will be created by lxc
- # or libvirt itself to be a symlink to the right pty.
- # take care to not nuke /dev in case $container_rootfs isn't set
- dev_path="$container_rootfs/dev"
- if [ $container_rootfs != "/" -a -d $dev_path ]; then
- rm -rf $dev_path
- fi
- mkdir -p $dev_path
- if can_chcon; then
- # ensure symlinks created in /dev have the right context
- chcon -t device_t $dev_path
- fi
- mknod -m 666 $dev_path/null c 1 3
- mknod -m 666 $dev_path/zero c 1 5
- mknod -m 666 $dev_path/random c 1 8
- mknod -m 666 $dev_path/urandom c 1 9
- mkdir -m 755 $dev_path/pts
- mkdir -m 1777 $dev_path/shm
- mknod -m 666 $dev_path/tty c 5 0
- mknod -m 666 $dev_path/tty1 c 4 1
- mknod -m 666 $dev_path/tty2 c 4 2
- mknod -m 666 $dev_path/tty3 c 4 3
- mknod -m 666 $dev_path/tty4 c 4 4
- mknod -m 666 $dev_path/full c 1 7
- mknod -m 600 $dev_path/initctl p
-
- # set selinux labels same as host
- if can_chcon; then
- for node in null zero random urandom pts shm \
- tty tty0 tty1 tty2 tty3 tty4 full ;
- do
- chcon --reference /dev/$node $dev_path/$node 2>/dev/null
- done
- fi
-}
-
-container_rootfs_create()
-{
- if can_chcon; then
- chcon --reference / $container_rootfs 2>/dev/null
- fi
-
- cmds="rpm wget yum"
- for cmd in $cmds; do
- which $cmd >/dev/null 2>&1
- if [ $? -ne 0 ]; then
- die "The $cmd command is required, please install it"
- fi
- done
-
- mkdir -p @LOCALSTATEDIR@/lock/subsys
- (
- flock -x 9
- if [ $? -ne 0 ]; then
- die "The template is busy."
- fi
-
- echo "Yum installing release $container_release_major.$container_release_minor for $basearch"
-
- if [ -n "$repourl" ]; then
- yum_url=$repourl
- else
- yum_url=http://yum.oracle.com
- fi
-
- if [ -n "$baseurl" ]; then
- # create .repo pointing at baseurl
- repo="lxc-install"
- mkdir -p $container_rootfs/etc/yum.repos.d
- container_rootfs_repo_create \
- $container_rootfs/etc/yum.repos.d/lxc-install.repo $repo $baseurl
- else
- # get public-yum repo file
- if [ $container_release_major = "1" ]; then
- repofile=yum-linux-sparc64.repo
- else
- die "Unsupported release $container_release_major"
- fi
-
- mkdir -p $container_rootfs/etc/yum.repos.d
- wget -q $yum_url/$repofile -O $container_rootfs/etc/yum.repos.d/$repofile
- if [ $? -ne 0 ]; then
- die "Unable to download repo file $yum_url/$repofile, release unavailable"
- fi
-
- # yum will take $basearch from host, so force the arch we want
- sed -i "s|\$basearch|$basearch|" $container_rootfs/etc/yum.repos.d/$repofile
-
- # replace url if they specified one
- if [ -n "$repourl" ]; then
- sed -i "s|baseurl=http://yum.oracle.com/|baseurl=$repourl/repo|" $container_rootfs/etc/yum.repos.d/$repofile
- sed -i "s|gpgkey=http://yum.oracle.com|gpgkey=$repourl|" $container_rootfs/etc/yum.repos.d/$repofile
-
- fi
-
- # disable all repos, then enable the repo for the version we are installing.
- if [ $container_release_minor = "latest" ]; then
- repo="lfs"_$container_release_minor
- else
- die "Unsupported release $container_release_major.$container_release_minor"
- fi
- sed -i "s|enabled=1|enabled=0|" $container_rootfs/etc/yum.repos.d/$repofile
- sed -i "/\[$repo\]/,/\[/ s/enabled=0/enabled=1/" $container_rootfs/etc/yum.repos.d/$repofile
- fi
-
- container_rootfs_dev_create
-
- # don't put devpts,proc, nor sysfs in here, it will already be mounted for us by lxc/libvirt
- echo "" >$container_rootfs/etc/fstab
-
- # create rpm db, download and yum install minimal packages
- mkdir -p $container_rootfs/var/lib/rpm
- rpm --root $container_rootfs --initdb
- yum_args="--installroot $container_rootfs --disablerepo=* --enablerepo=$repo -y --nogpgcheck"
- min_pkgs="yum initscripts passwd rsyslog vim-minimal openssh-server openssh-clients dhclient chkconfig rootfiles policycoreutils sparclinux-release"
-
- # we unshare the mount namespace because yum installing the ol4
- # packages causes $rootfs/proc to be mounted on
- lxc-unshare -s MOUNT yum -- $yum_args install $min_pkgs $user_pkgs
- if [ $? -ne 0 ]; then
- die "Failed to download and install the rootfs, aborting."
- fi
-
- # rsyslog and pam depend on coreutils for some common commands in
- # their POSTIN scriptlets, but coreutils wasn't installed yet. now
- # that coreutils is installed, reinstall the packages so their POSTIN
- # runs right. similarly, libutempter depends on libselinux.so.1 when
- # it runs /usr/sbin/groupadd, so reinstall it too
- redo_pkgs=""
- if [ x"$redo_pkgs" != x ]; then
- rpm --root $container_rootfs --nodeps -e $redo_pkgs
- lxc-unshare -s MOUNT yum -- $yum_args install $redo_pkgs
- if [ $? -ne 0 ]; then
- die "Unable to reinstall packages"
- fi
- fi
-
- # these distributions put the rpm database in a place the guest is
- # not expecting it, so move it
- if [ $host_distribution = "Ubuntu" -o $host_distribution = "Debian" ]; then
- mv $container_rootfs/$HOME/.rpmdb/* $container_rootfs/var/lib/rpm
- fi
-
- # if the native rpm created the db with Hash version 9, we need to
- # downgrade it to Hash version 8 for use with OL5.x
- db_version=`file $container_rootfs/var/lib/rpm/Packages | \
- grep -o 'version [0-9]*' |awk '{print $2}'`
-
- # the host rpm may not be the same as the guest, rebuild the db with
- # the guest rpm version
- echo "Rebuilding rpm database"
- rm -f $container_rootfs/var/lib/rpm/__db*
- chroot $container_rootfs rpm --rebuilddb >/dev/null 2>&1
-
- ) 9>@LOCALSTATEDIR@/lock/subsys/lxc-sparclinux-$name
- if [ $? -ne 0 ]; then
- exit 1
- fi
-}
-
-container_release_get()
-{
- if [ -f $1/etc/sparclinux-release ]; then
- container_release_version=`cat $1/etc/sparclinux-release |awk '/^Linux/ {print $5}'`
- container_release_major=`echo $container_release_version |awk -F '.' '{print $1}'`
- container_release_minor=`echo $container_release_version |awk -F '.' '{print $2}'`
- else
- echo "Unable to determine container release version"
- exit 1
- fi
-}
-
-usage()
-{
- cat <<EOF
- -a|--arch=<arch> architecture (sparc64)
- -R|--release=<release> release to download for the new container
- --rootfs=<path> rootfs path
- -r|--rpms=<rpm name> additional rpms to install into container
- -u|--url=<url> replace yum repo url (ie. Oracle public-yum mirror)
- --baseurl=<url> use package repository (ie. file:///mnt)
- arch and release must also be specified
- -t|--templatefs=<path> copy/clone rootfs at path instead of downloading
- -P|--patch=<path> only patch the rootfs at path for use as a container
- -h|--help
-
-Release is of the format "major.minor", for example "1.0" or "1.latest"
-This template supports Linux for SPARC release 1.0
-EOF
- return 0
-}
-
-options=$(getopt -o hp:n:a:R:r:u:t: -l help,rootfs:,path:,name:,arch:,release:,rpms:,url:,templatefs:,patch:,baseurl: -- "$@")
-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) cfg_dir=$2; shift 2;;
- --rootfs) container_rootfs=$2; shift 2;;
- -n|--name) name=$2; shift 2;;
- -a|--arch) arch=$2; shift 2;;
- -R|--release) container_release_version=$2; shift 2;;
- -r|--rpms) user_pkgs=$2; shift 2;;
- -u|--url) repourl=$2; shift 2;;
- -t|--templatefs) template_rootfs=$2; shift 2;;
- --patch) patch_rootfs=$2; shift 2;;
- --baseurl) baseurl=$2; shift 2;;
- --) shift 1; break ;;
- *) break ;;
- esac
-done
-
-# make sure mandatory args are given and valid
-if [ "$(id -u)" != "0" ]; then
- echo "This script should be run as 'root'"
- exit 1
-fi
-
-if [ -n "$baseurl" ]; then
- if [ "$arch" = "" -o "$container_release_version" = "" ]; then
- echo "The --arch and --release must be specified when using --baseurl"
- usage
- exit 1
- fi
-fi
-
-if [ "$arch" = "" ]; then
- arch=$(uname -m)
-fi
-
-if [ -n "$patch_rootfs" ]; then
- container_rootfs="$patch_rootfs"
- container_release_get $container_rootfs
- container_rootfs_patch
- exit 0
-fi
-
-if [ -z $name ]; then
- echo "Container name must be given"
- usage
- exit 1
-fi
-
-if [ -z $cfg_dir ]; then
- echo "Configuration directory must be given, check lxc-create"
- usage
- exit 1
-fi
-
-basearch=$arch
-
-if [ "$arch" != "sparc64" ]; then
- echo "Bad architecture given, check lxc-create"
- usage
- exit 1
-fi
-
-if [ -f /etc/sparclinux-release ]; then
- host_distribution="SPARCLinux"
- host_release_version=`cat /etc/sparclinux-release |awk '{print $5}'`
- host_release_major=`echo $host_release_version |awk -F '.' '{print $1}'`
- host_release_minor=`echo $host_release_version |awk -F '.' '{print $2}'`
-else
- echo "Unable to determine host distribution"
- exit 1
-fi
-
-echo "Host is $host_distribution $host_release_version"
-
-if [ -z "$container_rootfs" ]; then
- container_rootfs="$cfg_dir/rootfs"
-fi
-
-if [ -n "$template_rootfs" ]; then
- container_release_get $template_rootfs
-else
- if [ -z "$container_release_version" ]; then
- if [ $host_distribution = "SPARCLinux" ]; then
- container_release_version=$host_release_version
- else
- echo "No release specified with -R, defaulting to 1.latest"
- container_release_version="1.latest"
- fi
- fi
- container_release_major=`echo $container_release_version |awk -F '.' '{print $1}'`
- container_release_minor=`echo $container_release_version |awk -F '.' '{print $2}'`
-fi
-
-container_config_create
-if [ -n "$template_rootfs" ]; then
- container_rootfs_clone
-else
- container_rootfs_create
-fi
-
-container_release_get $container_rootfs
-
-container_rootfs_configure
-
-echo "Container : $container_rootfs"
-echo "Config : $cfg_dir/config"
-echo "Network : eth0 ($lxc_network_type) on $lxc_network_link"
+++ /dev/null
-#!/bin/bash
-
-#
-# lxc: linux Container library
-
-# Authors:
-# Daniel Lezcano <daniel.lezcano@free.fr>
-
-# 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
-
-# Detect use under userns (unsupported)
-for arg in "$@"; do
- [ "$arg" = "--" ] && break
- if [ "$arg" = "--mapped-uid" -o "$arg" = "--mapped-gid" ]; then
- echo "This template can't be used for unprivileged containers." 1>&2
- echo "You may want to try the \"download\" template instead." 1>&2
- exit 1
- fi
-done
-
-# Make sure the usual locations are in PATH
-export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
-
-install_sshd()
-{
- rootfs=$1
-
- tree="\
-$rootfs/var/empty/sshd \
-$rootfs/var/lib/empty/sshd \
-$rootfs/etc/init.d \
-$rootfs/etc/rc.d \
-$rootfs/etc/ssh \
-$rootfs/etc/sysconfig/network-scripts \
-$rootfs/dev/shm \
-$rootfs/run/sshd \
-$rootfs/proc \
-$rootfs/sys \
-$rootfs/bin \
-$rootfs/sbin \
-$rootfs/usr \
-$rootfs/tmp \
-$rootfs/home \
-$rootfs/root \
-$rootfs/lib \
-$rootfs/lib64"
-
- mkdir -p $tree
- if [ $? -ne 0 ]; then
- return 1
- fi
-
- ln -s /run $rootfs/var/run
- if [ $? -ne 0 ]; then
- return 1
- fi
-
- return 0
-}
-
-configure_sshd()
-{
- rootfs=$1
-
- cat <<EOF > $rootfs/etc/passwd
-root:x:0:0:root:/root:/bin/bash
-sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
-EOF
-
- cat <<EOF > $rootfs/etc/group
-root:x:0:root
-sshd:x:74:
-EOF
-
-ssh-keygen -t rsa -N "" -f $rootfs/etc/ssh/ssh_host_rsa_key
-ssh-keygen -t dsa -N "" -f $rootfs/etc/ssh/ssh_host_dsa_key
-
- # by default setup root password with no password
- cat <<EOF > $rootfs/etc/ssh/sshd_config
-Port 22
-Protocol 2
-HostKey /etc/ssh/ssh_host_rsa_key
-HostKey /etc/ssh/ssh_host_dsa_key
-UsePrivilegeSeparation yes
-SyslogFacility AUTH
-LogLevel INFO
-LoginGraceTime 120
-PermitRootLogin yes
-StrictModes yes
-PubkeyAuthentication yes
-IgnoreRhosts yes
-HostbasedAuthentication no
-PermitEmptyPasswords yes
-ChallengeResponseAuthentication no
-EOF
-
- if [ -n "$auth_key" -a -f "$auth_key" ]; then
- u_path="/root/.ssh"
- root_u_path="$rootfs/$u_path"
- mkdir -p $root_u_path
- cp $auth_key "$root_u_path/authorized_keys"
- chown -R 0:0 "$rootfs/$u_path"
- chmod 700 "$rootfs/$u_path"
- echo "Inserted SSH public key from $auth_key into $rootfs/$u_path"
- fi
-
- return 0
-}
-
-copy_configuration()
-{
- path=$1
- rootfs=$2
- name=$3
-
- init_path=$(realpath --relative-to=/ $(readlink -f /sbin/init))
-
- grep -q "^lxc.rootfs.path" $path/config 2>/dev/null || echo "lxc.rootfs.path = $rootfs" >> $path/config
-cat <<EOF >> $path/config
-lxc.uts.name = $name
-lxc.pty.max = 1024
-lxc.cap.drop = sys_module mac_admin mac_override sys_time
-
-# When using LXC with apparmor, uncomment the next line to run unconfined:
-#lxc.apparmor.profile = unconfined
-
-lxc.mount.entry = /dev dev none ro,bind 0 0
-lxc.mount.entry = /lib lib none ro,bind 0 0
-lxc.mount.entry = /bin bin none ro,bind 0 0
-lxc.mount.entry = /usr usr none ro,bind 0 0
-lxc.mount.entry = /sbin sbin none ro,bind 0 0
-lxc.mount.entry = tmpfs run/sshd tmpfs mode=0644 0 0
-lxc.mount.entry = @LXCTEMPLATEDIR@/lxc-sshd $init_path none ro,bind 0 0
-lxc.mount.entry = /etc/init.d etc/init.d none ro,bind 0 0
-
-lxc.mount.auto = cgroup:mixed proc:mixed sys:mixed
-EOF
-
- # Oracle Linux and Fedora need the following two bind mounted
- if [ -d /etc/sysconfig/network-scripts ]; then
- cat <<EOF >> $path/config
-lxc.mount.entry = /etc/sysconfig/network-scripts etc/sysconfig/network-scripts none ro,bind 0 0
-EOF
- fi
-
- if [ -d /etc/rc.d ]; then
- cat <<EOF >> $path/config
-lxc.mount.entry = /etc/rc.d etc/rc.d none ro,bind 0 0
-EOF
- fi
-
- # if no .ipv4 section in config, then have the container run dhcp
- grep -q "^lxc.net.0.ipv4.address" $path/config || touch $rootfs/run-dhcp
-
- if [ "$(uname -m)" = "x86_64" ]; then
- cat <<EOF >> $path/config
-lxc.mount.entry = /lib64 lib64 none ro,bind 0 0
-EOF
- fi
-}
-
-usage()
-{
- cat <<EOF
-$1 -h|--help -p|--path=<path> [--rootfs=<path>]
-EOF
- return 0
-}
-
-check_for_cmd()
-{
- cmd_path=`type $1`
- if [ $? -ne 0 ]; then
- echo "The command '$1' $cmd_path is not accessible on the system"
- exit 1
- fi
- # we use cut instead of awk because awk is alternatives symlink on ubuntu
- # and /etc/alternatives isn't bind mounted
- cmd_path=`echo $cmd_path |cut -d ' ' -f 3`
-}
-
-options=$(getopt -o hp:n:S: -l help,rootfs:,path:,name:,auth-key: -- "$@")
-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;;
- -S|--auth-key) auth_key=$2; shift 2;;
- --) shift 1; break ;;
- *) break ;;
- esac
-done
-
-if [ "$(id -u)" != "0" ]; then
- echo "This script should be run as 'root'"
- exit 1
-fi
-
-if [ $0 = "/sbin/init" ]; then
-
- PATH="$PATH:/bin:/sbin:/usr/sbin"
- check_for_cmd @SBINDIR@/init.lxc
- check_for_cmd sshd
- sshd_path=$cmd_path
-
- # run dhcp?
- if [ -f /run-dhcp ]; then
- check_for_cmd dhclient
- check_for_cmd ifconfig
- touch /etc/fstab
- rm -f /dhclient.conf
- cat > /dhclient.conf << EOF
-send host-name = gethostname();
-EOF
- ifconfig eth0 up
- dhclient eth0 -cf /dhclient.conf
- echo "Container IP address:"
- ifconfig eth0 |grep inet
- fi
-
- exec @SBINDIR@/init.lxc -- $sshd_path
- exit 1
-fi
-
-if [ -z "$path" ]; then
- echo "'path' parameter is required"
- exit 1
-fi
-
-# detect rootfs
-config="$path/config"
-if [ -z "$rootfs" ]; then
- if grep -q '^lxc.rootfs.path' $config 2>/dev/null ; then
- rootfs=$(awk -F= '/^lxc.rootfs.path =/{ print $2 }' $config)
- else
- rootfs=$path/rootfs
- fi
-fi
-
-install_sshd $rootfs
-if [ $? -ne 0 ]; then
- echo "failed to install sshd's rootfs"
- exit 1
-fi
-
-configure_sshd $rootfs
-if [ $? -ne 0 ]; then
- echo "failed to configure sshd template"
- exit 1
-fi
-
-copy_configuration $path $rootfs $name
-if [ $? -ne 0 ]; then
- echo "failed to write configuration file"
- exit 1
-fi
+++ /dev/null
-#!/bin/bash
-
-# template script for generating ubuntu container for LXC based on released
-# cloud images.
-#
-# Copyright © 2012 Serge Hallyn <serge.hallyn@canonical.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
-
-set -e
-
-STATE_DIR="@LOCALSTATEDIR@"
-HOOK_DIR="@LXCHOOKDIR@"
-CLONE_HOOK_FN="$HOOK_DIR/ubuntu-cloud-prep"
-LXC_TEMPLATE_CONFIG="@LXCTEMPLATECONFIG@"
-KNOWN_RELEASES="precise trusty xenial yakkety zesty"
-skip_arch_check=${UCTEMPLATE_SKIP_ARCH_CHECK:-0}
-
-# Make sure the usual locations are in PATH
-export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
-
-if [ -r /etc/default/lxc ]; then
- . /etc/default/lxc
-fi
-
-am_in_userns() {
- [ -e /proc/self/uid_map ] || { echo no; return; }
- [ "$(wc -l /proc/self/uid_map | awk '{ print $1 }')" -eq 1 ] || { echo yes; return; }
- line=$(awk '{ print $1 " " $2 " " $3 }' /proc/self/uid_map)
- [ "$line" = "0 0 4294967295" ] && { echo no; return; }
- echo yes
-}
-
-in_userns=0
-[ $(am_in_userns) = "yes" ] && in_userns=1
-
-copy_configuration()
-{
- path=$1
- rootfs=$2
- name=$3
- arch=$4
- release=$5
-
- if [ $arch = "i386" ]; then
- arch="i686"
- fi
-
- # if there is exactly one veth network entry, make sure it has an
- # associated hwaddr.
- nics=`grep -e '^lxc\.net\.0\.type[ \t]*=[ \t]*veth' $path/config | wc -l`
- if [ $nics -eq 1 ]; then
- grep -q "^lxc.net.0.hwaddr" $path/config || sed -i -e "/^lxc\.net\.0\.type[ \t]*=[ \t]*veth/a lxc.net.0.hwaddr = 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//')" $path/config
- fi
-
- # Generate the configuration file
- ## Relocate all the network config entries
- sed -i -e "/lxc.net.0/{w ${path}/config-network" -e "d}" $path/config
-
- ## Relocate any other config entries
- sed -i -e "/lxc./{w ${path}/config-auto" -e "d}" $path/config
-
- ## Add all the includes
- echo "" >> $path/config
- echo "# Common configuration" >> $path/config
- if [ -e "${LXC_TEMPLATE_CONFIG}/ubuntu-cloud.common.conf" ]; then
- echo "lxc.include = ${LXC_TEMPLATE_CONFIG}/ubuntu-cloud.common.conf" >> $path/config
- fi
- if [ -e "${LXC_TEMPLATE_CONFIG}/ubuntu-cloud.${release}.conf" ]; then
- echo "lxc.include = ${LXC_TEMPLATE_CONFIG}/ubuntu-cloud.${release}.conf" >> $path/config
- fi
- if [ $in_userns -eq 1 ] && [ -e "${LXC_TEMPLATE_CONFIG}/ubuntu-cloud.userns.conf" ]; then
- echo "lxc.include = ${LXC_TEMPLATE_CONFIG}/ubuntu-cloud.userns.conf" >> $path/config
- fi
-
- ## Add the container-specific config
- echo "" >> $path/config
- echo "# Container specific configuration" >> $path/config
- [ -e "$path/config-auto" ] && cat $path/config-auto >> $path/config && rm $path/config-auto
- grep -q "^lxc.rootfs.path" $path/config 2>/dev/null || echo "lxc.rootfs.path = $rootfs" >> $path/config
- cat <<EOF >> $path/config
-lxc.uts.name = $name
-lxc.arch = $arch
-EOF
-
- ## Re-add the previously removed network config
- echo "" >> $path/config
- echo "# Network configuration" >> $path/config
- cat $path/config-network >> $path/config
- rm $path/config-network
-
- # Set initial timezone as on host
- if [ -f /etc/timezone ]; then
- cat /etc/timezone > $rootfs/etc/timezone
- chroot $rootfs dpkg-reconfigure -f noninteractive tzdata
- elif [ -f /etc/sysconfig/clock ]; then
- . /etc/sysconfig/clock
- echo $ZONE > $rootfs/etc/timezone
- chroot $rootfs dpkg-reconfigure -f noninteractive tzdata
- else
- echo "Timezone in container is not configured. Adjust it manually."
- fi
-
- # rmdir /dev/shm for containers that have /run/shm
- # I'm afraid of doing rm -rf $rootfs/dev/shm, in case it did
- # get bind mounted to the host's /run/shm. So try to rmdir
- # it, and in case that fails move it out of the way.
- # NOTE: This can only be removed once 12.04 goes out of support
- if [ ! -L $rootfs/dev/shm ] && [ -e $rootfs/dev/shm ]; then
- rmdir $rootfs/dev/shm 2>/dev/null || mv $rootfs/dev/shm $rootfs/dev/shm.bak
- ln -s /run/shm $rootfs/dev/shm
- fi
-
- return 0
-}
-
-usage()
-{
- cat <<EOF
-LXC Container configuration for Ubuntu Cloud images.
-
-Generic Options
-[ -r | --release <release> ]: Release name of container, defaults to host
-[ --rootfs <path> ]: Path in which rootfs will be placed
-[ -a | --arch ]: Architecture of container, defaults to host architecture
-[ -T | --tarball ]: Location of tarball
-[ -d | --debug ]: Run with 'set -x' to debug errors
-[ -s | --stream]: Use specified stream rather than 'tryreleased'
-
-Additionally, clone hooks can be passed through (ie, --userdata). For those,
-see:
- $CLONE_HOOK_FN --help
-EOF
- return 0
-}
-
-options=$(getopt -o a:hp:r:n:Fi:CLS:T:ds:u: -l arch:,help,rootfs:,path:,release:,name:,flush-cache,hostid:,auth-key:,cloud,no_locales,tarball:,debug,stream:,userdata:,vendordata:,mapped-uid:,mapped-gid: -- "$@")
-if [ $? -ne 0 ]; then
- usage $(basename $0)
- exit 1
-fi
-eval set -- "$options"
-
-mapped_uid=-1
-mapped_gid=-1
-# default release is trusty, or the systems release if recognized
-release=trusty
-if [ -f /etc/lsb-release ]; then
- . /etc/lsb-release
- rels=$(ubuntu-distro-info --supported 2>/dev/null) ||
- rels="$KNOWN_RELEASES"
- for r in $rels; do
- [ "$DISTRIB_CODENAME" = "$r" ] && release="$r"
- done
-fi
-
-# Code taken from debootstrap
-if [ -x /usr/bin/dpkg ] && /usr/bin/dpkg --print-architecture >/dev/null 2>&1; then
- arch=`/usr/bin/dpkg --print-architecture`
-elif type udpkg >/dev/null 2>&1 && udpkg --print-architecture >/dev/null 2>&1; then
- arch=`/usr/bin/udpkg --print-architecture`
-else
- arch=$(uname -m)
- if [ "$arch" = "i686" ]; then
- arch="i386"
- elif [ "$arch" = "x86_64" ]; then
- arch="amd64"
- elif [ "$arch" = "armv7l" ]; then
- # note: arm images don't exist before oneiric; are called armhf in
- # trusty and later; and are not supported by the query, so we don't actually
- # support them yet (see check later on). When Query2 is available,
- # we'll use that to enable arm images.
- arch="armhf"
- elif [ "$arch" = "aarch64" ]; then
- arch="arm64"
- elif [ "$arch" = "ppc64le" ]; then
- arch="ppc64el"
- fi
-fi
-
-debug=0
-hostarch=$arch
-cloud=0
-locales=1
-flushcache=0
-stream="tryreleased"
-cloneargs=()
-while true
-do
- case "$1" in
- -h|--help) usage $0 && exit 1;;
- -p|--path) path=$2; shift 2;;
- -n|--name) name=$2; shift 2;;
- -F|--flush-cache) flushcache=1; shift 1;;
- -r|--release) release=$2; shift 2;;
- -a|--arch) arch=$2; shift 2;;
- -T|--tarball) tarball=$2; shift 2;;
- -d|--debug) debug=1; shift 1;;
- -s|--stream) stream=$2; shift 2;;
- --rootfs) rootfs=$2; shift 2;;
- -L|--no?locales) cloneargs[${#cloneargs[@]}]="--no-locales"; shift 1;;
- -i|--hostid) cloneargs[${#cloneargs[@]}]="--hostid=$2"; shift 2;;
- -u|--userdata) cloneargs[${#cloneargs[@]}]="--userdata=$2"; shift 2;;
- -V|--vendordata) cloneargs[${#cloneargs[@]}]="--vendordata=$2"; shift 2;;
- -C|--cloud) cloneargs[${#cloneargs[@]}]="--cloud"; shift 1;;
- -S|--auth-key) cloneargs[${#cloneargs[@]}]="--auth-key=$2"; shift 2;;
- --mapped-uid) mapped_uid=$2; shift 2;;
- --mapped-gid) mapped_gid=$2; shift 2;;
- --) shift 1; break ;;
- *) break ;;
- esac
-done
-
-cloneargs=( "--name=$name" "${cloneargs[@]}" )
-
-if [ $debug -eq 1 ]; then
- set -x
-fi
-
-if [ "$arch" = "i686" ]; then
- arch=i386
-fi
-
-if [ "$skip_arch_check" = "0" ]; then
- case "$hostarch:$arch" in
- $arch:$arch) : ;; # the host == container
- amd64:i386) :;; # supported "cross"
- arm64:arm*) :;; # supported "cross"
- armel:armhf) :;; # supported "cross"
- armhf:armel) :;; # supported "cross"
- *) echo "cannot create '$arch' container on hostarch '$hostarch'";
- exit 1;;
- esac
-fi
-
-if [ "$stream" != "daily" -a "$stream" != "released" -a "$stream" != "tryreleased" ]; then
- echo "Only 'daily' and 'released' and 'tryreleased' streams are supported"
- 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
-
-# detect rootfs
-config="$path/config"
-if [ -z "$rootfs" ]; then
- if grep -q '^lxc.rootfs.path' $config 2>/dev/null ; then
- rootfs=$(awk -F= '/^lxc.rootfs.path =/{ print $2 }' $config)
- else
- rootfs=$path/rootfs
- fi
-fi
-
-type ubuntu-cloudimg-query
-type wget
-
-# determine the url, tarball, and directory names
-# download if needed
-# Allow the cache base to be set by environment variable
-cache=${LXC_CACHE_PATH:-"$STATE_DIR/cache/lxc"}/cloud-$release
-if [ $in_userns -eq 1 ]; then
- STATE_DIR="$HOME/.cache/lxc"
- cache=${LXC_CACHE_PATH:-"$STATE_DIR"}/cloud-$release
-fi
-
-mkdir -p $cache
-
-if [ "$stream" = "tryreleased" ]; then
- stream=released
- ubuntu-cloudimg-query $release $stream $arch 1>/dev/null 2>/dev/null || stream=daily
-fi
-
-if [ -n "$tarball" ]; then
- url2="$tarball"
-else
- if ! url1=`ubuntu-cloudimg-query $release $stream $arch --format "%{url}\n"`; then
- echo "There is no download available for release=$release, stream=$stream, arch=$arch"
- [ "$stream" = "daily" ] || echo "You may try with '--stream=daily'"
- exit 1
- fi
- if [ "$release" = "precise" ] || [ "$release" = "trusty" ]; then
- url2=`echo $url1 | sed -e 's/.tar.gz/-root\0/' -e 's/.tar.gz/.tar.xz/'`
- else
- url2=`echo $url1 | sed -e 's/.tar.gz/.squashfs/'`
- fi
-fi
-
-filename=`basename $url2`
-
-wgetcleanup()
-{
- rm -f $filename
-}
-
-do_extract_rootfs() {
-
- cd $cache
- if [ $flushcache -eq 1 ]; then
- echo "Clearing the cached images"
- rm -f $filename
- fi
-
- trap wgetcleanup EXIT SIGHUP SIGINT SIGTERM
- if [ ! -f $filename ]; then
- wget $url2
- fi
- trap EXIT
- trap SIGHUP
- trap SIGINT
- trap SIGTERM
-
- echo "Extracting container rootfs"
- mkdir -p $rootfs
- cd $rootfs
- if [ "${filename##*.}" = "squashfs" ]; then
- unsquashfs -n -f -d "$rootfs" "$cache/$filename"
- else
- if [ $in_userns -eq 1 ]; then
- tar --anchored --exclude="dev/*" --numeric-owner -xpf "$cache/$filename"
- mkdir -p $rootfs/dev/pts/
- else
- tar --numeric-owner -xpf "$cache/$filename"
- fi
- fi
-}
-
-if [ -n "$tarball" ]; then
- do_extract_rootfs
-else
- mkdir -p "$STATE_DIR/lock/subsys/"
- (
- flock -x 9
- do_extract_rootfs
- ) 9>"$STATE_DIR/lock/subsys/lxc-ubuntu-cloud"
-fi
-
-copy_configuration $path $rootfs $name $arch $release
-
-"$CLONE_HOOK_FN" "${cloneargs[@]}" "$rootfs"
-
-if [ $mapped_uid -ne -1 ]; then
- chown $mapped_uid $path/config
- chown -R $mapped_uid $STATE_DIR
- chown -R $mapped_uid $cache
-fi
-if [ $mapped_gid -ne -1 ]; then
- chgrp $mapped_gid $path/config
- chgrp -R $mapped_gid $STATE_DIR
- chgrp -R $mapped_gid $cache
-fi
-
-echo "Container $name created."
-exit 0
-
-# vi: ts=4 expandtab
+++ /dev/null
-#!/bin/bash
-
-#
-# template script for generating ubuntu container for LXC
-#
-# This script consolidates and extends the existing lxc ubuntu scripts
-#
-
-# Copyright © 2011 Serge Hallyn <serge.hallyn@canonical.com>
-# Copyright © 2010 Wilhelm Meier
-# Author: Wilhelm Meier <wilhelm.meier@fh-kl.de>
-#
-# 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
-
-# Detect use under userns (unsupported)
-for arg in "$@"; do
- [ "$arg" = "--" ] && break
- if [ "$arg" = "--mapped-uid" -o "$arg" = "--mapped-gid" ]; then
- echo "This template can't be used for unprivileged containers." 1>&2
- echo "You may want to try the \"download\" template instead." 1>&2
- exit 1
- fi
-done
-
-# Make sure the usual locations are in PATH
-export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
-
-set -e
-
-LOCALSTATEDIR="@LOCALSTATEDIR@"
-LXC_TEMPLATE_CONFIG="@LXCTEMPLATECONFIG@"
-# Allows the lxc-cache directory to be set by environment variable
-LXC_CACHE_PATH=${LXC_CACHE_PATH:-"$LOCALSTATEDIR/cache/lxc"}
-
-if [ -r /etc/default/lxc ]; then
- . /etc/default/lxc
-fi
-
-# Check if given path is in a btrfs partition
-is_btrfs()
-{
- [ -e $1 -a $(stat -f -c '%T' $1) = "btrfs" ]
-}
-
-# Check if given path is the root of a btrfs subvolume
-is_btrfs_subvolume()
-{
- [ -d $1 -a $(stat -f -c '%T' $1) = "btrfs" -a $(stat -c '%i' $1) -eq 256 ]
-}
-
-try_mksubvolume()
-{
- path=$1
- [ -d $path ] && return 0
- mkdir -p $(dirname $path)
- if which btrfs >/dev/null 2>&1 && is_btrfs $(dirname $path); then
- btrfs subvolume create $path
- else
- mkdir -p $path
- fi
-}
-
-try_rmsubvolume()
-{
- path=$1
- [ -d $path ] || return 0
- if which btrfs >/dev/null 2>&1 && is_btrfs_subvolume $path; then
- btrfs subvolume delete $path
- else
- rm -rf $path
- fi
-}
-
-configure_ubuntu()
-{
- rootfs=$1
- hostname=$2
- release=$3
- user=$4
- password=$5
-
- # configure the network using the dhcp
- if chroot $rootfs which netplan >/dev/null 2>&1; then
- cat <<EOF > $rootfs/etc/netplan/10-lxc.yaml
-network:
- ethernets:
- eth0: {dhcp4: true}
- version: 2
-EOF
- else
- cat <<EOF > $rootfs/etc/network/interfaces
-# This file describes the network interfaces available on your system
-# and how to activate them. For more information, see interfaces(5).
-
-# The loopback network interface
-auto lo
-iface lo inet loopback
-
-auto eth0
-iface eth0 inet dhcp
-EOF
- fi
-
- # set the hostname
- cat <<EOF > $rootfs/etc/hostname
-$hostname
-EOF
- # set minimal hosts
- cat <<EOF > $rootfs/etc/hosts
-127.0.0.1 localhost
-127.0.1.1 $hostname
-
-# The following lines are desirable for IPv6 capable hosts
-::1 ip6-localhost ip6-loopback
-fe00::0 ip6-localnet
-ff00::0 ip6-mcastprefix
-ff02::1 ip6-allnodes
-ff02::2 ip6-allrouters
-EOF
-
- if [ ! -f $rootfs/etc/init/container-detect.conf ]; then
- # suppress log level output for udev
- sed -i "s/=\"err\"/=0/" $rootfs/etc/udev/udev.conf
-
- # remove jobs for consoles 5 and 6 since we only create 4 consoles in
- # this template
- rm -f $rootfs/etc/init/tty{5,6}.conf
- fi
-
- if [ -z "$bindhome" ]; then
- chroot $rootfs useradd --create-home -s /bin/bash $user
- echo "$user:$password" | chroot $rootfs chpasswd
- fi
-
- # make sure we have the current locale defined in the container
- if [ -z "$LANG" ] || echo $LANG | grep -E -q "^C(\..+)*$"; then
- chroot $rootfs locale-gen en_US.UTF-8 || true
- chroot $rootfs update-locale LANG=en_US.UTF-8 || true
- else
- chroot $rootfs locale-gen $LANG || true
- chroot $rootfs update-locale LANG=$LANG || true
- fi
-
- # generate new SSH keys
- if [ -x $rootfs/var/lib/dpkg/info/openssh-server.postinst ]; then
- cat > $rootfs/usr/sbin/policy-rc.d << EOF
-#!/bin/sh
-exit 101
-EOF
- chmod +x $rootfs/usr/sbin/policy-rc.d
-
- if [ -f "$rootfs/etc/init/ssh.conf" ]; then
- mv "$rootfs/etc/init/ssh.conf" "$rootfs/etc/init/ssh.conf.disabled"
- fi
-
- rm -f $rootfs/etc/ssh/ssh_host_*key*
-
- DPKG_MAINTSCRIPT_PACKAGE=openssh DPKG_MAINTSCRIPT_NAME=postinst chroot $rootfs /var/lib/dpkg/info/openssh-server.postinst configure
-
- sed -i "s/root@$(hostname)/root@$hostname/g" $rootfs/etc/ssh/ssh_host_*.pub
-
- if [ -f "$rootfs/etc/init/ssh.conf.disabled" ]; then
- mv "$rootfs/etc/init/ssh.conf.disabled" "$rootfs/etc/init/ssh.conf"
- fi
-
- rm -f $rootfs/usr/sbin/policy-rc.d
- fi
-
- return 0
-}
-
-# finish setting up the user in the container by injecting ssh key and
-# adding sudo group membership.
-# passed-in user is either 'ubuntu' or the user to bind in from host.
-finalize_user()
-{
- user=$1
-
- sudo_version=$(chroot $rootfs dpkg-query -W -f='${Version}' sudo)
-
- if chroot $rootfs dpkg --compare-versions $sudo_version gt "1.8.3p1-1"; then
- groups="sudo"
- else
- groups="sudo admin"
- fi
-
- for group in $groups; do
- chroot $rootfs groupadd --system $group >/dev/null 2>&1 || true
- chroot $rootfs adduser ${user} $group >/dev/null 2>&1 || true
- done
-
- if [ -n "$auth_key" -a -f "$auth_key" ]; then
- u_path="/home/${user}/.ssh"
- root_u_path="$rootfs/$u_path"
- mkdir -p $root_u_path
- cp $auth_key "$root_u_path/authorized_keys"
- chroot $rootfs chown -R ${user}: "$u_path"
-
- echo "Inserted SSH public key from $auth_key into /home/${user}/.ssh/authorized_keys"
- fi
- return 0
-}
-
-# A function to try and autodetect squid-deb-proxy servers on the local network
-# if either the squid-deb-proxy-client package is installed on the host or
-# a parent container set the 50squid-deb-proxy-client file.
-squid_deb_proxy_autodetect()
-{
- local apt_discover=/usr/share/squid-deb-proxy-client/apt-avahi-discover
- local proxy_file=/etc/apt/apt.conf.d/50squid-deb-proxy-client
- squid_proxy_line= # That's a global :/
-
- # Maybe the host is aware of a squid-deb-proxy?
- if [ -f $apt_discover ]; then
- echo -n "Discovering squid-deb-proxy..."
- squid_proxy_line=$($apt_discover)
- if [ -n "$squid_proxy_line" ]; then
- echo "found squid-deb-proxy: $squid_proxy_line"
- else
- echo "no squid-deb-proxy found"
- fi
- fi
-
- # Are we in a nested container, and the parent already knows of a proxy?
- if [ -f $proxy_file ]; then
- # Extract the squid URL from the file (whatever is between "")
- squid_proxy_line=`cat $proxy_file | sed "s/.*\"\(.*\)\".*/\1/"`
- fi
-}
-
-#
-# Choose proxies for container
-# http_proxy will be used by debootstrap on the host.
-# APT_PROXY will be used to set /etc/apt/apt.conf.d/70proxy in the container.
-#
-choose_container_proxy()
-{
- local rootfs=$1
- local arch=$2
-
- if [ -z "$HTTP_PROXY" ]; then
- HTTP_PROXY="none"
- fi
- case "$HTTP_PROXY" in
- none)
- squid_deb_proxy_autodetect
- if [ -n "$squid_proxy_line" ]; then
- APT_PROXY=$squid_proxy_line
- export http_proxy=$squid_proxy_line
- else
- APT_PROXY=
- fi
- ;;
- apt)
- RES=`apt-config shell APT_PROXY Acquire::http::Proxy`
- eval $RES
- [ -z "$APT_PROXY" ] || export http_proxy=$APT_PROXY
- ;;
- *)
- APT_PROXY=$HTTP_PROXY
- export http_proxy=$HTTP_PROXY
- ;;
- esac
-}
-
-write_sourceslist()
-{
- # $1 => path to the partial cache or the rootfs
- # $2 => architecture we want to add
- # $3 => whether to use the multi-arch syntax or not
-
- if [ -n "$APT_PROXY" ]; then
- mkdir -p $1/etc/apt/apt.conf.d
- cat > $1/etc/apt/apt.conf.d/70proxy << EOF
-Acquire::http::Proxy "$APT_PROXY" ;
-EOF
- fi
-
- case $2 in
- amd64|i386)
- MIRROR=${MIRROR:-http://archive.ubuntu.com/ubuntu}
- SECURITY_MIRROR=${SECURITY_MIRROR:-http://security.ubuntu.com/ubuntu}
- ;;
- *)
- MIRROR=${MIRROR:-http://ports.ubuntu.com/ubuntu-ports}
- SECURITY_MIRROR=${SECURITY_MIRROR:-http://ports.ubuntu.com/ubuntu-ports}
- ;;
- esac
- if [ -n "$3" ]; then
- cat >> "$1/etc/apt/sources.list" << EOF
-deb [arch=$2] $MIRROR ${release} main restricted universe multiverse
-deb [arch=$2] $MIRROR ${release}-updates main restricted universe multiverse
-deb [arch=$2] $SECURITY_MIRROR ${release}-security main restricted universe multiverse
-EOF
- else
- cat >> "$1/etc/apt/sources.list" << EOF
-deb $MIRROR ${release} main restricted universe multiverse
-deb $MIRROR ${release}-updates main restricted universe multiverse
-deb $SECURITY_MIRROR ${release}-security main restricted universe multiverse
-EOF
- fi
-}
-
-install_packages()
-{
- local rootfs="$1"
- shift
- local packages="$*"
- if [ -z $update ]
- then
- chroot $rootfs apt-get update
- update=true
- fi
- if [ -n "${packages}" ]
- then
- chroot $rootfs apt-get install --force-yes -y --no-install-recommends ${packages}
- fi
-}
-
-cleanup()
-{
- try_rmsubvolume $cache/partial-$arch
- try_rmsubvolume $cache/rootfs-$arch
-}
-
-suggest_flush()
-{
- echo "Container upgrade failed. The container cache may be out of date,"
- echo "in which case flushing the cache (see -F in the help output) may help."
-}
-
-download_ubuntu()
-{
- cache=$1
- arch=$2
- release=$3
-
- case $2 in
- amd64|i386)
- MIRROR=${MIRROR:-http://archive.ubuntu.com/ubuntu}
- SECURITY_MIRROR=${SECURITY_MIRROR:-http://security.ubuntu.com/ubuntu}
- ;;
- *)
- MIRROR=${MIRROR:-http://ports.ubuntu.com/ubuntu-ports}
- SECURITY_MIRROR=${SECURITY_MIRROR:-http://ports.ubuntu.com/ubuntu-ports}
- ;;
- esac
-
- packages_template=${packages_template:-"apt-transport-https,ssh,vim"}
- debootstrap_parameters=
-
- # Try to guess a list of langpacks to install
- langpacks="language-pack-en"
-
- if which dpkg >/dev/null 2>&1; then
- langpacks=`(echo $langpacks &&
- dpkg -l | grep -E "^ii language-pack-[a-z]* " |
- cut -d ' ' -f3) | sort -u`
- fi
- packages_template="${packages_template},$(echo $langpacks | sed 's/ /,/g')"
-
- if [ -n "$variant" ]; then
- debootstrap_parameters="$debootstrap_parameters --variant=$variant"
- fi
- if [ "$variant" = 'minbase' ]; then
- packages_template="${packages_template},sudo"
- # Newer releases use netplan, EOL releases not supported
- case $release in
- trusty|xenial|zesty)
- packages_template="${packages_template},ifupdown,isc-dhcp-client"
- ;;
- esac
- fi
-
- echo "Installing packages in template: ${packages_template}"
-
- trap cleanup EXIT SIGHUP SIGINT SIGTERM
- # check the mini ubuntu was not already downloaded
- try_mksubvolume "$cache/partial-$arch"
- if [ $? -ne 0 ]; then
- echo "Failed to create '$cache/partial-$arch' directory"
- return 1
- fi
-
- choose_container_proxy $cache/partial-$arch/ $arch
- # download a mini ubuntu into a cache
- echo "Downloading ubuntu $release minimal ..."
- if [ -n "$(which qemu-debootstrap)" ]; then
- qemu-debootstrap --verbose $debootstrap_parameters --components=main,universe --arch=$arch --include=${packages_template} $release $cache/partial-$arch $MIRROR
- else
- debootstrap --verbose $debootstrap_parameters --components=main,universe --arch=$arch --include=${packages_template} $release $cache/partial-$arch $MIRROR
- fi
-
- if [ $? -ne 0 ]; then
- echo "Failed to download the rootfs, aborting."
- return 1
- fi
-
- # Serge isn't sure whether we should avoid doing this when
- # $release == `distro-info -d`
- echo "Installing updates"
- > $cache/partial-$arch/etc/apt/sources.list
- write_sourceslist $cache/partial-$arch/ $arch
-
- chroot "$1/partial-${arch}" apt-get update
- if [ $? -ne 0 ]; then
- echo "Failed to update the apt cache"
- return 1
- fi
- cat > "$1/partial-${arch}"/usr/sbin/policy-rc.d << EOF
-#!/bin/sh
-exit 101
-EOF
- chmod +x "$1/partial-${arch}"/usr/sbin/policy-rc.d
-
- (
- cat << EOF
- mount -t proc proc "${1}/partial-${arch}/proc"
- chroot "${1}/partial-${arch}" apt-get dist-upgrade -y
-EOF
- ) | lxc-unshare -s MOUNT -- sh -eu || (suggest_flush; false)
-
- rm -f "$1/partial-${arch}"/usr/sbin/policy-rc.d
-
- chroot "$1/partial-${arch}" apt-get clean
-
- mv "$1/partial-$arch" "$1/rootfs-$arch"
- trap EXIT
- trap SIGINT
- trap SIGTERM
- trap SIGHUP
- echo "Download complete"
- return 0
-}
-
-copy_ubuntu()
-{
- cache=$1
- arch=$2
- rootfs=$3
-
- # make a local copy of the miniubuntu
- echo "Copying rootfs to $rootfs ..."
- try_mksubvolume $rootfs
- if which btrfs >/dev/null 2>&1 && is_btrfs_subvolume $cache/rootfs-$arch && is_btrfs_subvolume $rootfs; then
- realrootfs=$(dirname $config)/rootfs
- [ "$rootfs" = "$realrootfs" ] || umount $rootfs || return 1
- btrfs subvolume delete $realrootfs || return 1
- btrfs subvolume snapshot $cache/rootfs-$arch $realrootfs || return 1
- [ "$rootfs" = "$realrootfs" ] || mount --bind $realrootfs $rootfs || return 1
- else
- rsync -SHaAX $cache/rootfs-$arch/ $rootfs/ || return 1
- fi
- return 0
-}
-
-install_ubuntu()
-{
- rootfs=$1
- release=$2
- flushcache=$3
- cache="$4/$release"
- mkdir -p $LOCALSTATEDIR/lock/subsys/
-
- (
- flock -x 9
- if [ $? -ne 0 ]; then
- echo "Cache repository is busy."
- return 1
- fi
-
-
- if [ $flushcache -eq 1 ]; then
- echo "Flushing cache..."
- try_rmsubvolume $cache/partial-$arch
- try_rmsubvolume $cache/rootfs-$arch
- fi
-
- echo "Checking cache download in $cache/rootfs-$arch ... "
- if [ ! -e "$cache/rootfs-$arch" ]; then
- download_ubuntu $cache $arch $release
- if [ $? -ne 0 ]; then
- echo "Failed to download 'ubuntu $release base'"
- return 1
- fi
- fi
-
- echo "Copy $cache/rootfs-$arch to $rootfs ... "
- copy_ubuntu $cache $arch $rootfs
- if [ $? -ne 0 ]; then
- echo "Failed to copy rootfs"
- return 1
- fi
-
- return 0
-
- ) 9>$LOCALSTATEDIR/lock/subsys/lxc-ubuntu$release
-
- return $?
-}
-
-copy_configuration()
-{
- path=$1
- rootfs=$2
- name=$3
- arch=$4
- release=$5
-
- if [ $arch = "i386" ]; then
- arch="i686"
- fi
-
- # if there is exactly one veth network entry, make sure it has an
- # associated hwaddr.
- nics=`grep -e '^lxc\.net\.0\.type[ \t]*=[ \t]*veth' $path/config | wc -l`
- if [ $nics -eq 1 ]; then
- grep -q "^lxc.net.0.hwaddr" $path/config || sed -i -e "/^lxc\.net\.0\.type[ \t]*=[ \t]*veth/a lxc.net.0.hwaddr = 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//')" $path/config
- fi
-
- # Generate the configuration file
- ## Relocate all the network config entries
- sed -i -e "/lxc.net.0/{w ${path}/config-network" -e "d}" $path/config
-
- ## Relocate any other config entries
- sed -i -e "/lxc./{w ${path}/config-auto" -e "d}" $path/config
-
- ## Add all the includes
- echo "" >> $path/config
- echo "# Common configuration" >> $path/config
- if [ -e "${LXC_TEMPLATE_CONFIG}/ubuntu.common.conf" ]; then
- echo "lxc.include = ${LXC_TEMPLATE_CONFIG}/ubuntu.common.conf" >> $path/config
- fi
- if [ -e "${LXC_TEMPLATE_CONFIG}/ubuntu.${release}.conf" ]; then
- echo "lxc.include = ${LXC_TEMPLATE_CONFIG}/ubuntu.${release}.conf" >> $path/config
- fi
-
- ## Add the container-specific config
- echo "" >> $path/config
- echo "# Container specific configuration" >> $path/config
- [ -e "$path/config-auto" ] && cat $path/config-auto >> $path/config && rm $path/config-auto
- grep -q "^lxc.rootfs.path" $path/config 2>/dev/null || echo "lxc.rootfs.path = $rootfs" >> $path/config
- cat <<EOF >> $path/config
-lxc.uts.name = $name
-lxc.arch = $arch
-EOF
-
- ## Re-add the previously removed network config
- echo "" >> $path/config
- echo "# Network configuration" >> $path/config
- cat $path/config-network >> $path/config
- rm $path/config-network
-
- if [ $? -ne 0 ]; then
- echo "Failed to add configuration"
- return 1
- fi
-
- return 0
-}
-
-post_process()
-{
- rootfs=$1
- release=$2
- packages=$3
-
- # Disable service startup
- cat > $rootfs/usr/sbin/policy-rc.d << EOF
-#!/bin/sh
-exit 101
-EOF
- chmod +x $rootfs/usr/sbin/policy-rc.d
-
- # If the container isn't running a native architecture, setup multiarch
- if [ -x "$(ls -1 ${rootfs}/usr/bin/qemu-*-static 2>/dev/null)" ]; then
- dpkg_version=$(chroot $rootfs dpkg-query -W -f='${Version}' dpkg)
- if chroot $rootfs dpkg --compare-versions $dpkg_version ge "1.16.2"; then
- chroot $rootfs dpkg --add-architecture ${hostarch}
- else
- mkdir -p ${rootfs}/etc/dpkg/dpkg.cfg.d
- echo "foreign-architecture ${hostarch}" > ${rootfs}/etc/dpkg/dpkg.cfg.d/lxc-multiarch
- fi
-
- # Save existing value of MIRROR and SECURITY_MIRROR
- DEFAULT_MIRROR=$MIRROR
- DEFAULT_SECURITY_MIRROR=$SECURITY_MIRROR
-
- # Write a new sources.list containing both native and multiarch entries
- > ${rootfs}/etc/apt/sources.list
- write_sourceslist $rootfs $arch "native"
-
- MIRROR=$DEFAULT_MIRROR
- SECURITY_MIRROR=$DEFAULT_SECURITY_MIRROR
- write_sourceslist $rootfs $hostarch "multiarch"
-
- # Finally update the lists and install upstart using the host architecture
- HOST_PACKAGES="upstart:${hostarch} mountall:${hostarch} isc-dhcp-client:${hostarch}"
- chroot $rootfs apt-get update
- if chroot $rootfs dpkg -l iproute2 | grep -q ^ii; then
- HOST_PACKAGES="$HOST_PACKAGES iproute2:${hostarch}"
- else
- HOST_PACKAGES="$HOST_PACKAGES iproute:${hostarch}"
- fi
- install_packages $rootfs $HOST_PACKAGES
- fi
-
- # Install Packages in container
- if [ -n "$packages" ]
- then
- local packages="`echo $packages | sed 's/,/ /g'`"
- echo "Installing packages: ${packages}"
- install_packages $rootfs $packages
- fi
-
- # Set initial timezone as on host
- if [ -f /etc/timezone ]; then
- cat /etc/timezone > $rootfs/etc/timezone
- chroot $rootfs dpkg-reconfigure -f noninteractive tzdata
- elif [ -f /etc/sysconfig/clock ]; then
- . /etc/sysconfig/clock
- echo $ZONE > $rootfs/etc/timezone
- chroot $rootfs dpkg-reconfigure -f noninteractive tzdata
- else
- echo "Timezone in container is not configured. Adjust it manually."
- fi
-
- # rmdir /dev/shm for containers that have /run/shm
- # I'm afraid of doing rm -rf $rootfs/dev/shm, in case it did
- # get bind mounted to the host's /run/shm. So try to rmdir
- # it, and in case that fails move it out of the way.
- # NOTE: This can only be removed once 12.04 goes out of support
- if [ ! -L $rootfs/dev/shm ] && [ -e $rootfs/dev/shm ]; then
- rmdir $rootfs/dev/shm 2>/dev/null || mv $rootfs/dev/shm $rootfs/dev/shm.bak
- ln -s /run/shm $rootfs/dev/shm
- fi
-
- # Re-enable service startup
- rm $rootfs/usr/sbin/policy-rc.d
-}
-
-do_bindhome()
-{
- rootfs=$1
- user=$2
-
- # copy /etc/passwd, /etc/shadow, and /etc/group entries into container
- pwd=`getent passwd $user` || { echo "Failed to copy password entry for $user"; false; }
- echo $pwd >> $rootfs/etc/passwd
-
- # make sure user's shell exists in the container
- shell=`echo $pwd | cut -d: -f 7`
- if [ ! -x $rootfs/$shell ]; then
- echo "shell $shell for user $user was not found in the container."
- pkg=`dpkg -S $(readlink -m $shell) | cut -d ':' -f1`
- echo "Installing $pkg"
- install_packages $rootfs $pkg
- fi
-
- shad=`getent shadow $user`
- echo "$shad" >> $rootfs/etc/shadow
-
- # bind-mount the user's path into the container's /home
- h=`getent passwd $user | cut -d: -f 6`
- mkdir -p $rootfs/$h
-
- # use relative path in container
- h2=${h#/}
- while [ ${h2:0:1} = "/" ]; do
- h2=${h2#/}
- done
- echo "lxc.mount.entry = $h $h2 none bind 0 0" >> $path/config
-
- # Make sure the group exists in container
- grp=`echo $pwd | cut -d: -f 4` # group number for $user
- grpe=`getent group $grp` || return 0 # if host doesn't define grp, ignore in container
- chroot $rootfs getent group "$grpe" || echo "$grpe" >> $rootfs/etc/group
-}
-
-usage()
-{
- cat <<EOF
-$1 -h|--help [-a|--arch] [-b|--bindhome <user>] [-d|--debug]
- [-F | --flush-cache] [-r|--release <release>] [-v|--variant] [ -S | --auth-key <keyfile>]
- [--rootfs <rootfs>] [--packages <packages>] [-u|--user <user>] [--password <password>]
- [--mirror <url>] [--security-mirror <url>]
-release: the ubuntu release (e.g. xenial): defaults to host release on ubuntu, otherwise uses latest LTS
-variant: debootstrap variant to use (see debootstrap(8))
-bindhome: bind <user>'s home into the container
- The ubuntu user will not be created, and <user> will have
- sudo access.
-arch: the container architecture (e.g. amd64): defaults to host arch
-auth-key: SSH Public key file to inject into container
-packages: list of packages to add comma separated
-mirror,security-mirror: mirror for download and /etc/apt/sources.list
-EOF
- return 0
-}
-
-options=$(getopt -o a:b:hp:r:v:n:FS:du: -l arch:,bindhome:,help,path:,release:,variant:,name:,flush-cache,auth-key:,debug,rootfs:,packages:,user:,password:,mirror:,security-mirror: -- "$@")
-if [ $? -ne 0 ]; then
- usage $(basename $0)
- exit 1
-fi
-eval set -- "$options"
-
-release=xenial # Default to the last Ubuntu LTS release for non-Ubuntu systems
-if [ -f /etc/lsb-release ]; then
- . /etc/lsb-release
- if [ "$DISTRIB_ID" = "Ubuntu" ]; then
- release=$DISTRIB_CODENAME
- fi
-fi
-
-bindhome=
-
-# Code taken from debootstrap
-if [ -x /usr/bin/dpkg ] && /usr/bin/dpkg --print-architecture >/dev/null 2>&1; then
- arch=`/usr/bin/dpkg --print-architecture`
-elif which udpkg >/dev/null 2>&1 && udpkg --print-architecture >/dev/null 2>&1; then
- arch=`/usr/bin/udpkg --print-architecture`
-else
- arch=$(uname -m)
- if [ "$arch" = "i686" ]; then
- arch="i386"
- elif [ "$arch" = "x86_64" ]; then
- arch="amd64"
- elif [ "$arch" = "armv7l" ]; then
- arch="armhf"
- elif [ "$arch" = "aarch64" ]; then
- arch="arm64"
- elif [ "$arch" = "ppc64le" ]; then
- arch="ppc64el"
- fi
-fi
-
-debug=0
-hostarch=$arch
-flushcache=0
-packages=""
-user="ubuntu"
-password="ubuntu"
-
-while true
-do
- case "$1" in
- -h|--help) usage $0 && exit 0;;
- --rootfs) rootfs=$2; shift 2;;
- -p|--path) path=$2; shift 2;;
- -n|--name) name=$2; shift 2;;
- -u|--user) user=$2; shift 2;;
- --password) password=$2; shift 2;;
- -F|--flush-cache) flushcache=1; shift 1;;
- -r|--release) release=$2; shift 2;;
- -v|--variant) variant=$2; shift 2;;
- --packages) packages=$2; shift 2;;
- -b|--bindhome) bindhome=$2; shift 2;;
- -a|--arch) arch=$2; shift 2;;
- -S|--auth-key) auth_key=$2; shift 2;;
- -d|--debug) debug=1; shift 1;;
- --mirror) MIRROR=$2; shift 2;;
- --security-mirror) SECURITY_MIRROR=$2; shift 2;;
- --) shift 1; break ;;
- *) break ;;
- esac
-done
-
-if [ $debug -eq 1 ]; then
- set -x
-fi
-
-if [ -n "$bindhome" ]; then
- pwd=`getent passwd $bindhome`
- if [ $? -ne 0 ]; then
- echo "Error: no password entry found for $bindhome"
- exit 1
- fi
-fi
-
-
-if [ "$arch" = "i686" ]; then
- arch=i386
-fi
-
-if [ $hostarch = "i386" -a $arch = "amd64" ]; then
- echo "can't create $arch container on $hostarch"
- exit 1
-fi
-
-if [ $hostarch = "armhf" -o $hostarch = "armel" -o $hostarch = "arm64" ] && \
- [ $arch != "armhf" -a $arch != "armel" -a $arch != "arm64" ]; then
- echo "can't create $arch container on $hostarch"
- exit 1
-fi
-
-if [ $arch = "arm64" ] && [ $hostarch != "arm64" ]; then
- echo "can't create $arch container on $hostarch"
- exit 1
-fi
-
-if [ $hostarch = "powerpc" -a $arch != "powerpc" ]; then
- echo "can't create $arch container on $hostarch"
- exit 1
-fi
-
-which debootstrap >/dev/null 2>&1 || { echo "'debootstrap' command is missing" >&2; false; }
-
-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
-
-# detect rootfs
-config="$path/config"
-# if $rootfs exists here, it was passed in with --rootfs
-if [ -z "$rootfs" ]; then
- if grep -q '^lxc.rootfs.path' $config 2>/dev/null ; then
- rootfs=$(awk -F= '/^lxc.rootfs.path =/{ print $2 }' $config)
- else
- rootfs=$path/rootfs
- fi
-fi
-
-install_ubuntu $rootfs $release $flushcache $LXC_CACHE_PATH
-if [ $? -ne 0 ]; then
- echo "failed to install ubuntu $release"
- exit 1
-fi
-
-configure_ubuntu $rootfs $name $release $user $password
-if [ $? -ne 0 ]; then
- echo "failed to configure ubuntu $release for a container"
- exit 1
-fi
-
-copy_configuration $path $rootfs $name $arch $release
-if [ $? -ne 0 ]; then
- echo "failed write configuration file"
- exit 1
-fi
-
-post_process $rootfs $release $trim_container $packages
-
-if [ -n "$bindhome" ]; then
- do_bindhome $rootfs $bindhome
- finalize_user $bindhome
-else
- finalize_user $user
-fi
-
-echo ""
-echo "##"
-if [ -n "$bindhome" ]; then
- echo "# Log in as user $bindhome"
-else
- echo "# The default user is '$user' with password '$password'!"
- echo "# Use the 'sudo' command to run tasks as root in the container."
-fi
-echo "##"
-echo ""
+++ /dev/null
-#!/bin/bash
-
-#
-# template script for generating Void Linux container for LXC
-#
-
-#
-# lxc: linux Container library
-
-# Authors:
-# Gregor Reitzenstein <dean4devil@paranoidlabs.org>
-
-# Based on lxc-archlinux template by:
-# Alexander Vladimirov <alexander.idkfa.vladimirov@gmail.com>
-# John Lane <lxc@jelmail.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
-
-# Utility functions
-
-# Check if array $2 contains item $1
-containsElement() {
- local e
- for e in "${@:2}"; do [[ "$1" == "$e" ]] && return 0; done
- return 1
-}
-
-# split comma-separated string into an array
-# ${1} - string to split
-# ${2} - separator (default is ",")
-# ${result} - result value on success
-split_string() {
- local ifs=${IFS}
- IFS="${2:-,}"
- read -ra result < <(echo "${1}")
- IFS=${ifs}
- return 0
-}
-
-# Make sure the usual locations are in PATH
-export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
-
-# defaults
-default_path="/var/lib/lxc"
-default_path="@LXCPATH@"
-shared_config="@LXCTEMPLATECONFIG@/voidlinux.common.conf"
-userns_config="@LXCTEMPLATECONFIG@/voidlinux.userns.conf"
-
-pkg_blacklist=("linux>=0" "e2fsprogs>=0" "btrfs-progs>=0" "xfsprogs>=0" "f2fs-tools>=0" "dosfstools>=0")
-base_packages=()
-for pkg in $(xbps-query -Mv --repository="http://repo2.voidlinux.eu/current/" -x base-system); do
- containsElement "$pkg" "${pkg_blacklist[@]}" || base_packages+=($pkg)
-done
-declare -a additional_packages
-
-copy_configuration() {
- mkdir -p "${config_path}"
- local config="${config_path}/config"
- echo "lxc.uts.name = ${name}" >> "${config}"
- grep -q "^lxc.rootfs.path" "${config}" 2>/dev/null \
- || echo "lxc.rootfs.path = ${rootfs_path}" >> "${config}"
-
- # Detect if were in a UserNS and include the right config
- if [ -z "${LXC_MAPPED_GID+x}" ] || [ -z "${LXC_MAPPED_UID+x}" ]; then
- echo "lxc.include = ${userns_config}" >> "${config}"
- else
- echo "lxc.include = ${shared_config}" >> "${config}"
- fi
-
- if [ $? -ne 0 ]; then
- echo "Failed to configure container"
- return 1
- fi
- return 0
-}
-
-install_void() {
- if ! yes | xbps-install -Sy -R http://repo2.voidlinux.eu/current -r "${rootfs_path}" "${base_packages[@]}"
- then
- echo "Failed to install container packages"
- return 1
- fi
-}
-
-usage() {
- cat <<EOF
-usage:
- ${1} -n|--name=<container_name> [-p|--path=<path>] [-a|--arch=<arch of the container>]
- [-r|--root_password=<root password>] [-P|--packages=<pkg1,pkg2,...>] [-h|--help]
-
-Mandatory args:
- -n,--name container name, used to as an identifier for that container from now on
-Optional args:
- -p,--path path to where the container rootfs will be created (${default_path})
- --rootfs path for actual container rootfs, (${default_path}/rootfs)
- -P,--packages preinstall additional packages, comma-separated list
- -c,--config use specified pacman config when installing container packages
- -a,--arch use specified architecture instead of host's architecture
- -r,--root_password set container root password
- -h,--help print this help
-EOF
- return 0
-}
-
-options=$(getopt -o hp:P:n:c:r: -l help,rootfs:,path:,packages:,name:,config:,root_password:,mapped-uid:,mapped-gid: -- "${@}")
-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;;
- -n|--name) name=${2}; shift 2;;
- -c|--config) config_path=${2}; shift 2;;
- --rootfs) rootfs_path=${2}; shift 2;;
- -P|--packages) additional_packages=${2}; shift 2;;
- -r|--root_password) root_passwd=${2}; shift 2;;
- --mapped-uid) LXC_MAPPED_UID=$2; shift 2;;
- --mapped-gid) LXC_MAPPED_GID=$2; shift 2;;
- --) shift 1; break ;;
- *) break ;;
- esac
-done
-
-if [ -z "${name}" ]; then
- echo "missing required 'name' parameter"
- exit 1
-fi
-
-type xbps-install >/dev/null 2>&1
-if [ ${?} -ne 0 ]; then
- echo "'xbps-install' command is missing."
-fi
-type xbps-query >/dev/null 2>&1
-if [ ${?} -ne 0 ]; then
- echo "'xbps-query' command is missing."
-fi
-
-if [ -z "${rootfs_path}" ]; then
- rootfs_path="${path}/rootfs"
-fi
-config_path="${path}"
-
-revert() {
- echo "Interrupted, cleaning up"
- lxc-destroy -n "${name}"
- rm -rf "${path:?}/${name}"
- rm -rf "${default_path:?}/${name}"
- exit 1
-}
-trap revert SIGHUP SIGINT SIGTERM
-
-copy_configuration
-if [ $? -ne 0 ]; then
- echo "Failed to write configuration file"
- rm -rf "${config_path}"
- exit 1
-fi
-
-if [ ${#additional_packages[@]} -gt 0 ]; then
- split_string "${additional_packages}"
- base_packages+=(${result[@]})
-fi
-
-mkdir -p "${rootfs_path}"
-install_void
-if [ ${?} -ne 0 ]; then
- echo "Failed to install Void Linux"
- rm -rf "${config_path}" "${path}"
- exit 1
-fi
-
-
-
-if [ -n "${root_passwd}" ]; then
- echo "root:${root_passwd}" | chroot "${rootfs_path}" chpasswd
-fi
-
-cat << EOF
-Void Linux Container ${name} has been successfully created. The configuration is
-stored in ${config_path}/config. Please refer to https://wiki.voidlinux.eu for
-information regarding Void Linux.
-EOF