From: Christian Brauner Date: Mon, 26 Feb 2018 20:12:17 +0000 (+0100) Subject: tree-wide: rm templates in favor of distrobuilder X-Git-Tag: lxc-3.0.0.beta1~3^2~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=aafb5ea2a849056f9866359996605af0290605bd;p=thirdparty%2Flxc.git tree-wide: rm templates in favor of distrobuilder Signed-off-by: Christian Brauner --- diff --git a/config/templates/Makefile.am b/config/templates/Makefile.am index 6598615b4..3ec580910 100644 --- a/config/templates/Makefile.am +++ b/config/templates/Makefile.am @@ -4,43 +4,8 @@ EXTRA_DIST = common.seccomp 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 diff --git a/config/templates/alpine.common.conf.in b/config/templates/alpine.common.conf.in deleted file mode 100644 index 1c4cf815a..000000000 --- a/config/templates/alpine.common.conf.in +++ /dev/null @@ -1,24 +0,0 @@ -# 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 diff --git a/config/templates/alpine.userns.conf.in b/config/templates/alpine.userns.conf.in deleted file mode 100644 index 4336b448c..000000000 --- a/config/templates/alpine.userns.conf.in +++ /dev/null @@ -1,2 +0,0 @@ -# This derives from the global userns config. -lxc.include = @LXCTEMPLATECONFIG@/userns.conf diff --git a/config/templates/archlinux.common.conf.in b/config/templates/archlinux.common.conf.in deleted file mode 100644 index 81d654883..000000000 --- a/config/templates/archlinux.common.conf.in +++ /dev/null @@ -1,31 +0,0 @@ -# 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 diff --git a/config/templates/archlinux.userns.conf.in b/config/templates/archlinux.userns.conf.in deleted file mode 100644 index 707bb30c0..000000000 --- a/config/templates/archlinux.userns.conf.in +++ /dev/null @@ -1,2 +0,0 @@ -# This derives from the global userns config -lxc.include = @LXCTEMPLATECONFIG@/userns.conf diff --git a/config/templates/centos.common.conf.in b/config/templates/centos.common.conf.in deleted file mode 100644 index 8a72ad003..000000000 --- a/config/templates/centos.common.conf.in +++ /dev/null @@ -1,20 +0,0 @@ -# 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 diff --git a/config/templates/centos.userns.conf.in b/config/templates/centos.userns.conf.in deleted file mode 100644 index 707bb30c0..000000000 --- a/config/templates/centos.userns.conf.in +++ /dev/null @@ -1,2 +0,0 @@ -# This derives from the global userns config -lxc.include = @LXCTEMPLATECONFIG@/userns.conf diff --git a/config/templates/debian.common.conf.in b/config/templates/debian.common.conf.in deleted file mode 100644 index 4e6a6e6a3..000000000 --- a/config/templates/debian.common.conf.in +++ /dev/null @@ -1,28 +0,0 @@ -# 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 diff --git a/config/templates/debian.userns.conf.in b/config/templates/debian.userns.conf.in deleted file mode 100644 index 707bb30c0..000000000 --- a/config/templates/debian.userns.conf.in +++ /dev/null @@ -1,2 +0,0 @@ -# This derives from the global userns config -lxc.include = @LXCTEMPLATECONFIG@/userns.conf diff --git a/config/templates/fedora.common.conf.in b/config/templates/fedora.common.conf.in deleted file mode 100644 index acebe3c7c..000000000 --- a/config/templates/fedora.common.conf.in +++ /dev/null @@ -1,21 +0,0 @@ -# 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 diff --git a/config/templates/fedora.userns.conf.in b/config/templates/fedora.userns.conf.in deleted file mode 100644 index 707bb30c0..000000000 --- a/config/templates/fedora.userns.conf.in +++ /dev/null @@ -1,2 +0,0 @@ -# This derives from the global userns config -lxc.include = @LXCTEMPLATECONFIG@/userns.conf diff --git a/config/templates/gentoo.common.conf.in b/config/templates/gentoo.common.conf.in deleted file mode 100644 index 477a2abfb..000000000 --- a/config/templates/gentoo.common.conf.in +++ /dev/null @@ -1,27 +0,0 @@ -# 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 diff --git a/config/templates/gentoo.moresecure.conf.in b/config/templates/gentoo.moresecure.conf.in deleted file mode 100644 index aa7c625cc..000000000 --- a/config/templates/gentoo.moresecure.conf.in +++ /dev/null @@ -1,45 +0,0 @@ -# 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. diff --git a/config/templates/gentoo.userns.conf.in b/config/templates/gentoo.userns.conf.in deleted file mode 100644 index 707bb30c0..000000000 --- a/config/templates/gentoo.userns.conf.in +++ /dev/null @@ -1,2 +0,0 @@ -# This derives from the global userns config -lxc.include = @LXCTEMPLATECONFIG@/userns.conf diff --git a/config/templates/opensuse.common.conf.in b/config/templates/opensuse.common.conf.in deleted file mode 100644 index b040e95d9..000000000 --- a/config/templates/opensuse.common.conf.in +++ /dev/null @@ -1,22 +0,0 @@ -# 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 diff --git a/config/templates/opensuse.userns.conf.in b/config/templates/opensuse.userns.conf.in deleted file mode 100644 index 707bb30c0..000000000 --- a/config/templates/opensuse.userns.conf.in +++ /dev/null @@ -1,2 +0,0 @@ -# This derives from the global userns config -lxc.include = @LXCTEMPLATECONFIG@/userns.conf diff --git a/config/templates/openwrt.common.conf.in b/config/templates/openwrt.common.conf.in deleted file mode 100644 index 73db6f60b..000000000 --- a/config/templates/openwrt.common.conf.in +++ /dev/null @@ -1,50 +0,0 @@ -# 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 diff --git a/config/templates/oracle.common.conf.in b/config/templates/oracle.common.conf.in deleted file mode 100644 index 8a72ad003..000000000 --- a/config/templates/oracle.common.conf.in +++ /dev/null @@ -1,20 +0,0 @@ -# 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 diff --git a/config/templates/oracle.userns.conf.in b/config/templates/oracle.userns.conf.in deleted file mode 100644 index 707bb30c0..000000000 --- a/config/templates/oracle.userns.conf.in +++ /dev/null @@ -1,2 +0,0 @@ -# This derives from the global userns config -lxc.include = @LXCTEMPLATECONFIG@/userns.conf diff --git a/config/templates/plamo.common.conf.in b/config/templates/plamo.common.conf.in deleted file mode 100644 index 7918b4a37..000000000 --- a/config/templates/plamo.common.conf.in +++ /dev/null @@ -1,9 +0,0 @@ -# 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 diff --git a/config/templates/plamo.userns.conf.in b/config/templates/plamo.userns.conf.in deleted file mode 100644 index 707bb30c0..000000000 --- a/config/templates/plamo.userns.conf.in +++ /dev/null @@ -1,2 +0,0 @@ -# This derives from the global userns config -lxc.include = @LXCTEMPLATECONFIG@/userns.conf diff --git a/config/templates/sabayon.common.conf.in b/config/templates/sabayon.common.conf.in deleted file mode 100644 index ccb4c1236..000000000 --- a/config/templates/sabayon.common.conf.in +++ /dev/null @@ -1,79 +0,0 @@ -# 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/ diff --git a/config/templates/sabayon.userns.conf.in b/config/templates/sabayon.userns.conf.in deleted file mode 100644 index 707bb30c0..000000000 --- a/config/templates/sabayon.userns.conf.in +++ /dev/null @@ -1,2 +0,0 @@ -# This derives from the global userns config -lxc.include = @LXCTEMPLATECONFIG@/userns.conf diff --git a/config/templates/slackware.common.conf.in b/config/templates/slackware.common.conf.in deleted file mode 100644 index 899c52ce3..000000000 --- a/config/templates/slackware.common.conf.in +++ /dev/null @@ -1,46 +0,0 @@ -# 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 diff --git a/config/templates/slackware.userns.conf.in b/config/templates/slackware.userns.conf.in deleted file mode 100644 index 707bb30c0..000000000 --- a/config/templates/slackware.userns.conf.in +++ /dev/null @@ -1,2 +0,0 @@ -# This derives from the global userns config -lxc.include = @LXCTEMPLATECONFIG@/userns.conf diff --git a/config/templates/sparclinux.common.conf.in b/config/templates/sparclinux.common.conf.in deleted file mode 100644 index 8a72ad003..000000000 --- a/config/templates/sparclinux.common.conf.in +++ /dev/null @@ -1,20 +0,0 @@ -# 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 diff --git a/config/templates/sparclinux.userns.conf.in b/config/templates/sparclinux.userns.conf.in deleted file mode 100644 index 707bb30c0..000000000 --- a/config/templates/sparclinux.userns.conf.in +++ /dev/null @@ -1,2 +0,0 @@ -# This derives from the global userns config -lxc.include = @LXCTEMPLATECONFIG@/userns.conf diff --git a/config/templates/ubuntu-cloud.common.conf.in b/config/templates/ubuntu-cloud.common.conf.in deleted file mode 100644 index 4d6772299..000000000 --- a/config/templates/ubuntu-cloud.common.conf.in +++ /dev/null @@ -1,4 +0,0 @@ -# This derives from the main Ubuntu config -lxc.include = @LXCTEMPLATECONFIG@/ubuntu.common.conf - -lxc.hook.clone = @LXCHOOKDIR@/ubuntu-cloud-prep diff --git a/config/templates/ubuntu-cloud.lucid.conf.in b/config/templates/ubuntu-cloud.lucid.conf.in deleted file mode 100644 index 78205e5f2..000000000 --- a/config/templates/ubuntu-cloud.lucid.conf.in +++ /dev/null @@ -1,2 +0,0 @@ -# This derives from the main Ubuntu lucid config -lxc.include = @LXCTEMPLATECONFIG@/ubuntu.lucid.conf diff --git a/config/templates/ubuntu-cloud.userns.conf.in b/config/templates/ubuntu-cloud.userns.conf.in deleted file mode 100644 index e1baca8eb..000000000 --- a/config/templates/ubuntu-cloud.userns.conf.in +++ /dev/null @@ -1,2 +0,0 @@ -# This derives from the main Ubuntu userns config -lxc.include = @LXCTEMPLATECONFIG@/ubuntu.userns.conf diff --git a/config/templates/ubuntu.common.conf.in b/config/templates/ubuntu.common.conf.in deleted file mode 100644 index ff8ef6a8f..000000000 --- a/config/templates/ubuntu.common.conf.in +++ /dev/null @@ -1,35 +0,0 @@ -# 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 diff --git a/config/templates/ubuntu.lucid.conf.in b/config/templates/ubuntu.lucid.conf.in deleted file mode 100644 index b6fe37c97..000000000 --- a/config/templates/ubuntu.lucid.conf.in +++ /dev/null @@ -1,2 +0,0 @@ -# Ubuntu 10.04 LTS doesn't have /dev/lxc/ -lxc.tty.dir = diff --git a/config/templates/ubuntu.userns.conf.in b/config/templates/ubuntu.userns.conf.in deleted file mode 100644 index 0d73464cd..000000000 --- a/config/templates/ubuntu.userns.conf.in +++ /dev/null @@ -1,6 +0,0 @@ -# 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 diff --git a/config/templates/voidlinux.common.conf.in b/config/templates/voidlinux.common.conf.in deleted file mode 100644 index c287b45c5..000000000 --- a/config/templates/voidlinux.common.conf.in +++ /dev/null @@ -1,35 +0,0 @@ -# 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 diff --git a/config/templates/voidlinux.userns.conf.in b/config/templates/voidlinux.userns.conf.in deleted file mode 100644 index f319bc546..000000000 --- a/config/templates/voidlinux.userns.conf.in +++ /dev/null @@ -1,8 +0,0 @@ -# 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 diff --git a/configure.ac b/configure.ac index a4de1f29b..571aa6071 100644 --- a/configure.ac +++ b/configure.ac @@ -666,44 +666,10 @@ AC_CONFIG_FILES([ 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 @@ -832,31 +798,10 @@ AC_CONFIG_FILES([ 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 diff --git a/templates/Makefile.am b/templates/Makefile.am index 63abdf6fb..15df51dff 100644 --- a/templates/Makefile.am +++ b/templates/Makefile.am @@ -1,28 +1,6 @@ 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 diff --git a/templates/lxc-alpine.in b/templates/lxc-alpine.in deleted file mode 100644 index 174c36815..000000000 --- a/templates/lxc-alpine.in +++ /dev/null @@ -1,516 +0,0 @@ -#!/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 - -# 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 diff --git a/templates/lxc-altlinux.in b/templates/lxc-altlinux.in deleted file mode 100644 index d526fa096..000000000 --- a/templates/lxc-altlinux.in +++ /dev/null @@ -1,498 +0,0 @@ -#!/bin/bash - -# -# template script for generating altlinux container for LXC -# - -# -# lxc: linux Container library - -# Authors: -# Alexey Shabalin - -# 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 < ${rootfs_path}/etc/net/ifaces/eth0/options -BOOTPROTO=${BOOTPROTO} -ONBOOT=yes -NM_CONTROLLED=yes -TYPE=eth -EOF - -if [ ${BOOTPROTO} != "dhcp" ]; then - # ip address - cat < ${rootfs_path}/etc/net/ifaces/eth0/ipv4address -${ipv4} -EOF - - cat < ${rootfs_path}/etc/net/ifaces/eth0/ipv4route -${gw} -EOF - - cat < ${rootfs_path}/etc/net/ifaces/eth0/resolv.conf -nameserver ${dns} -EOF - - cat < ${rootfs_path}/etc/net/ifaces/eth0/ipv6address -${ipv6} -EOF - - cat < ${rootfs_path}/etc/net/ifaces/eth0/ipv6route -${gw6} -EOF - -fi - - # set the hostname - cat < ${rootfs_path}/etc/sysconfig/network -NETWORKING=yes -CONFMETHOD=etcnet -HOSTNAME=${UTSNAME} -RESOLV_MODS=yes -EOF - - # set minimal hosts - cat < $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 <> $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 <> $config_path/config -lxc.net.0.ipv4.address = $ipv4 -EOF -fi -if [ ! -z ${gw} ]; then - cat <> $config_path/config -lxc.net.0.ipv4.gateway = $gw -EOF -fi -if [ ! -z ${ipv6} ]; then - cat <> $config_path/config -lxc.net.0.ipv6.address = $ipv6 -EOF -fi -if [ ! -z ${gw6} ]; then - cat <> $config_path/config -lxc.net.0.ipv6.gateway = $gw6 -EOF -fi - cat <> $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 < - [-p|--path=] [-c|--clean] [-R|--release=] - [-4|--ipv4=] [-6|--ipv6=] - [-g|--gw=] [-d|--dns=] - [-P|--profile=] [--rootfs=] - [-a|--apt-conf=] - [-A|--arch=] - [-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" diff --git a/templates/lxc-archlinux.in b/templates/lxc-archlinux.in deleted file mode 100644 index f8d4ba01c..000000000 --- a/templates/lxc-archlinux.in +++ /dev/null @@ -1,334 +0,0 @@ -#!/bin/bash - -# -# template script for generating Arch Linux container for LXC -# - -# -# lxc: linux Container library - -# Authors: -# Alexander Vladimirov -# John Lane - -# 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//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 < [-p|--path=] [-a|--arch=] - [-r|--root_password=] [-P|--packages=] - [-e|--enable_units=unit1,unit2...] [-d|--disable_units=unit1,unit2...] - [-c|--config=] [-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 diff --git a/templates/lxc-centos.in b/templates/lxc-centos.in deleted file mode 100644 index eba5ec8a3..000000000 --- a/templates/lxc-centos.in +++ /dev/null @@ -1,968 +0,0 @@ -#!/bin/bash - -# -# template script for generating CentOS container for LXC - -# -# lxc: linux Container library - -# Authors: -# Daniel Lezcano -# Ramez Hanna -# Fajar A. Nugraha -# Michael H. Warfield - -# 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 < ${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 < ${rootfs_path}/etc/sysconfig/network -NETWORKING=yes -HOSTNAME=${utsname} -EOF - - # set minimal hosts - cat < $rootfs_path/etc/hosts -127.0.0.1 localhost $name -EOF - - # set minimal fstab - cat < $rootfs_path/etc/fstab -/dev/root / rootfs defaults 0 0 -EOF - - # create lxc compatibility init script - if [ "$release" = "6" ]; then - cat < $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 < $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 <${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 < $REPO_FILE -[base] -name=local repository -baseurl="$repo" -EOF - elif [ ${basearch} = 'i386' ] || [ ${basearch} = 'x86_64' ]; then - cat < $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 < $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 <> $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 < - [-p|--path=] [-c|--clean] [-R|--release=] [-a|--arch=] - [-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 diff --git a/templates/lxc-cirros.in b/templates/lxc-cirros.in deleted file mode 100644 index de79dafd8..000000000 --- a/templates/lxc-cirros.in +++ /dev/null @@ -1,343 +0,0 @@ -#!/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 -# -# 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 <&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" <> $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 diff --git a/templates/lxc-debian.in b/templates/lxc-debian.in deleted file mode 100644 index 438847894..000000000 --- a/templates/lxc-debian.in +++ /dev/null @@ -1,824 +0,0 @@ -#!/bin/bash - -# -# lxc: linux Container library - -# Authors: -# Daniel Lezcano - -# 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 < $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 < $rootfs/etc/network/interfaces -auto lo -iface lo inet loopback - -auto eth0 -iface eth0 inet dhcp -EOF - - # set the hostname - cat < $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 <> $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 < [-c|--clean] [-a|--arch=] [-r|--release=] - [--mirror=] [--security-mirror=] - [--package=] - [-I|--interpreter-path=] - [-F | --flush-cache] [-S|--auth-key=] - -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 diff --git a/templates/lxc-fedora-legacy.in b/templates/lxc-fedora-legacy.in deleted file mode 100644 index 3ef341530..000000000 --- a/templates/lxc-fedora-legacy.in +++ /dev/null @@ -1,1495 +0,0 @@ -#!/bin/bash - -# -# template script for generating fedora container for LXC -# - -# -# lxc: linux Container library - -# Authors: -# Daniel Lezcano -# Ramez Hanna -# Michael H. Warfield - -# 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 < ${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 < ${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 < $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 <${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/.*.*//' ) - 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/.*.*//' ) - 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 <> $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 < - [-p|--path=] [-c|--clean] [-R|--release=] - [--fqdn=] [-a|--arch=] - [--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 diff --git a/templates/lxc-fedora.in b/templates/lxc-fedora.in deleted file mode 100644 index 10b90b1e5..000000000 --- a/templates/lxc-fedora.in +++ /dev/null @@ -1,1291 +0,0 @@ -#!/bin/bash - -# -# template script for generating Fedora container for LXC -# - -# -# lxc: linux Container library - -# Authors: -# Daniel Lezcano -# Ramez Hanna -# Michael H. Warfield -# Reto Gantenbein - -# 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 < "${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 <> "${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 < "${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 <> "${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 "${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 </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: diff --git a/templates/lxc-gentoo.in b/templates/lxc-gentoo.in deleted file mode 100644 index 950f17c73..000000000 --- a/templates/lxc-gentoo.in +++ /dev/null @@ -1,833 +0,0 @@ -#!/bin/bash - -# -# LXC template for gentoo -# -# Author: Guillaume Zitta -# -# 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 <] [-v|--variant ] [-P|--private-portage] [--portage-dir ] [-t|--tarball ] - [-F|--flush-cache] [-c|--cache-only] [-u|--user ] [-w|--password ] [--autologin] [-S|--auth-key ] - [-s|--settings ] [-m|--mirror ] [--tty ] - -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 diff --git a/templates/lxc-openmandriva.in b/templates/lxc-openmandriva.in deleted file mode 100644 index 2761cd509..000000000 --- a/templates/lxc-openmandriva.in +++ /dev/null @@ -1,484 +0,0 @@ -#!/bin/bash - -# -# template script for generating openmandriva container for LXC -# - -# -# lxc: linux Container library - -# Authors: -# Alexander Khryukin -# Vokhmin Alexey V - -# 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 < ${rootfs_path}/etc/sysconfig/network-scripts/ifcfg-eth0 -DEVICE=eth0 -ONBOOT=yes -BOOTPROTO=dhcp -NM_CONTROLLED=no -HOSTNAME=${utsname} -EOF - - # set the hostname - cat < ${rootfs_path}/etc/sysconfig/network -NETWORKING=yes -HOSTNAME=${utsname} -EOF - -echo "${utsname}" > ${rootfs_path}/etc/hostname - - # set minimal hosts - cat < $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 <> $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 <> $config_path/config -lxc.net.0.ipv4.address = $ipv4 -EOF -fi -if [ ! -z ${gw} ]; then - cat <> $config_path/config -lxc.net.0.ipv4.gateway = $gw -EOF -fi -if [ ! -z ${ipv6} ]; then - cat <> $config_path/config -lxc.net.0.ipv6.address = $ipv6 -EOF -fi -if [ ! -z ${gw6} ]; then - cat <> $config_path/config -lxc.net.0.ipv6.gateway = $gw6 -EOF -fi - cat <> $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 < - [-p|--path=] [-c|--clean] [-R|--release=] - [-4|--ipv4=] [-6|--ipv6=] - [-g|--gw=] [-d|--dns=] - [-P|--profile=] [--rootfs=] - [-A|--arch=] - [-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" diff --git a/templates/lxc-opensuse.in b/templates/lxc-opensuse.in deleted file mode 100644 index c2480dd60..000000000 --- a/templates/lxc-opensuse.in +++ /dev/null @@ -1,557 +0,0 @@ -#!/bin/bash - -# -# template script for generating OpenSUSE container for LXC -# - -# -# lxc: linux Container library - -# Authors: -# Daniel Lezcano -# Frederic Crozat -# Michael H. Warfield -# Johannes Kastl -# Thomas Lamprecht - -# 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 < $rootfs/etc/sysconfig/network/ifcfg-eth0 -STARTMODE='auto' -BOOTPROTO='dhcp' -EOF - - # create empty fstab - touch $rootfs/etc/fstab - - # set the hostname - cat < $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 <> $rootfs/etc/sysconfig/cron -unset HOSTNAME -EOF - - # set minimal hosts - cat < $rootfs/etc/hosts -127.0.0.1 localhost $hostname -EOF - - # disable yast->bootloader in container - cat < $rootfs/etc/sysconfig/bootloader -LOADER_TYPE=none -LOADER_LOCATION=none -EOF - - # set /dev/console as securetty - cat << EOF >> $rootfs/etc/securetty -console -EOF - - cat <> $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 <> $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 < -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 diff --git a/templates/lxc-oracle.in b/templates/lxc-oracle.in deleted file mode 100644 index afb690210..000000000 --- a/templates/lxc-oracle.in +++ /dev/null @@ -1,972 +0,0 @@ -#!/bin/sh -# -# Template script for generating Oracle Enterprise Linux container for LXC -# based on lxc-fedora, lxc-ubuntu -# -# Copyright © 2011 Wim Coekaerts -# Copyright © 2012 Dwight Engen -# -# Modified for Oracle Linux 5 -# Wim Coekaerts -# -# Modified for Oracle Linux 6,7 combined OL4,5,6 into one template script -# Dwight Engen -# -# 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 < $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 < $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 < $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 <$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 < $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 < $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 <> $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 <> $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 < architecture (ie. i386, x86_64) - -R|--release= release to download for the new container - --rootfs= rootfs path - -r|--rpms= additional rpms to install into container - -u|--url= replace yum repo url (ie. Oracle public-yum mirror) - --baseurl= use package repository (ie. file:///mnt) - arch and release must also be specified - -t|--templatefs= copy/clone rootfs at path instead of downloading - -P|--patch= 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" diff --git a/templates/lxc-plamo.in b/templates/lxc-plamo.in deleted file mode 100644 index ec442ec3a..000000000 --- a/templates/lxc-plamo.in +++ /dev/null @@ -1,384 +0,0 @@ -#!/bin/bash -eu - -# -# template script for generating Plamo Linux container for LXC -# - -# -# lxc: linux Container library - -# Authors: -# KATOH Yasufumi -# TAMUKI Shoichi - -# 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= -n|--name= --rootfs= - [-c|--clean] [-r|--release=] [-a|--arch=] - [-b|--bindhome=] - release: $release - arch: x86 or x86_64: defaults to host arch - bindhome: bind '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 diff --git a/templates/lxc-pld.in b/templates/lxc-pld.in deleted file mode 100644 index b748cb87b..000000000 --- a/templates/lxc-pld.in +++ /dev/null @@ -1,484 +0,0 @@ -#!/bin/sh - -# -# template script for generating PLD Linux container for LXC -# - -# -# lxc: Linux Container library - -# Authors: -# Elan Ruusamäe - -# 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 < $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 <> $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 < $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 < - [-p|--path=] [-c|--clean] [-R|--release=] [--fqdn=] [-A|--arch=] - [-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" diff --git a/templates/lxc-sabayon.in b/templates/lxc-sabayon.in deleted file mode 100644 index 51594c189..000000000 --- a/templates/lxc-sabayon.in +++ /dev/null @@ -1,513 +0,0 @@ -#!/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 - -# 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 < 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 < ${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 diff --git a/templates/lxc-slackware.in b/templates/lxc-slackware.in deleted file mode 100644 index 0c85c5103..000000000 --- a/templates/lxc-slackware.in +++ /dev/null @@ -1,793 +0,0 @@ -#!/bin/bash - -# -# lxc: linux Container library - -# Authors: -# Daniel Lezcano - -# Template for slackware by Matteo Bernardini -# 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 < $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 <$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 - # Modified by: Patrick J. Volkerding, - # -+# minor tweaks for an lxc container -+# by Matteo Bernardini , -+# 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, - # -+# minor tweaks for an lxc container -+# by Matteo Bernardini , -+# 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, - # Heavily modified by Patrick Volkerding - # -+# minor tweaks for an lxc container -+# by Matteo Bernardini : -+# 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 : -+# 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 < $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 < $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 <> $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 < --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 diff --git a/templates/lxc-sparclinux.in b/templates/lxc-sparclinux.in deleted file mode 100644 index e5e686f8e..000000000 --- a/templates/lxc-sparclinux.in +++ /dev/null @@ -1,702 +0,0 @@ -#!/bin/sh -# -# Template script for generating Linux for SPARC for LXC -# based on lxc-fedora, lxc-ubuntu -# -# Copyright © 2011 Wim Coekaerts -# Copyright © 2012 Dwight Engen -# Copyright � 2015 Wim Coekaerts -# -# Modified for Oracle Linux 5 -# Wim Coekaerts -# -# Modified for Oracle Linux 6,7 combined OL4,5,6 into one template script -# Dwight Engen -# -# Modified for Linux for SPARC 1.0 -# Wim Coekaerts -# -# 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 < $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 < $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 < $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 <$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 < $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 < $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 <> $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 <> $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 < architecture (sparc64) - -R|--release= release to download for the new container - --rootfs= rootfs path - -r|--rpms= additional rpms to install into container - -u|--url= replace yum repo url (ie. Oracle public-yum mirror) - --baseurl= use package repository (ie. file:///mnt) - arch and release must also be specified - -t|--templatefs= copy/clone rootfs at path instead of downloading - -P|--patch= 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" diff --git a/templates/lxc-sshd.in b/templates/lxc-sshd.in deleted file mode 100644 index e6f90ad7c..000000000 --- a/templates/lxc-sshd.in +++ /dev/null @@ -1,276 +0,0 @@ -#!/bin/bash - -# -# lxc: linux Container library - -# Authors: -# Daniel Lezcano - -# 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 < $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 < $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 < $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 <> $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 <> $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 <> $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 <> $path/config -lxc.mount.entry = /lib64 lib64 none ro,bind 0 0 -EOF - fi -} - -usage() -{ - cat < [--rootfs=] -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 diff --git a/templates/lxc-ubuntu-cloud.in b/templates/lxc-ubuntu-cloud.in deleted file mode 100644 index 2bf534ab8..000000000 --- a/templates/lxc-ubuntu-cloud.in +++ /dev/null @@ -1,374 +0,0 @@ -#!/bin/bash - -# template script for generating ubuntu container for LXC based on released -# cloud images. -# -# Copyright © 2012 Serge Hallyn -# -# 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 <> $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 < ]: Release name of container, defaults to host -[ --rootfs ]: 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 diff --git a/templates/lxc-ubuntu.in b/templates/lxc-ubuntu.in deleted file mode 100644 index 80a28fd2a..000000000 --- a/templates/lxc-ubuntu.in +++ /dev/null @@ -1,877 +0,0 @@ -#!/bin/bash - -# -# template script for generating ubuntu container for LXC -# -# This script consolidates and extends the existing lxc ubuntu scripts -# - -# Copyright © 2011 Serge Hallyn -# Copyright © 2010 Wilhelm Meier -# Author: Wilhelm Meier -# -# 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 < $rootfs/etc/netplan/10-lxc.yaml -network: - ethernets: - eth0: {dhcp4: true} - version: 2 -EOF - else - cat < $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 < $rootfs/etc/hostname -$hostname -EOF - # set minimal hosts - cat < $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 <> $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 <] [-d|--debug] - [-F | --flush-cache] [-r|--release ] [-v|--variant] [ -S | --auth-key ] - [--rootfs ] [--packages ] [-u|--user ] [--password ] - [--mirror ] [--security-mirror ] -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 's home into the container - The ubuntu user will not be created, and 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 "" diff --git a/templates/lxc-voidlinux.in b/templates/lxc-voidlinux.in deleted file mode 100644 index d74da385a..000000000 --- a/templates/lxc-voidlinux.in +++ /dev/null @@ -1,199 +0,0 @@ -#!/bin/bash - -# -# template script for generating Void Linux container for LXC -# - -# -# lxc: linux Container library - -# Authors: -# Gregor Reitzenstein - -# Based on lxc-archlinux template by: -# Alexander Vladimirov -# John Lane - -# 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 < [-p|--path=] [-a|--arch=] - [-r|--root_password=] [-P|--packages=] [-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