Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2022-04-23 17:47:52 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2022-04-23 17:47:52 +0200
commitf5f70d8015fe0e34be8254b362844ff052cd6b36 (patch)
tree87cd6febef2bbbe8e19561599dba35e613c04993
adapted template to Arch32
-rw-r--r--README.md11
-rwxr-xr-xlxc-archlinux32337
2 files changed, 348 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..fc0d905
--- /dev/null
+++ b/README.md
@@ -0,0 +1,11 @@
+# LXC
+
+Bases on https://github.com/lxc/lxc-templates (version 3.04.)
+
+# usage
+
+Copy `lxc-archlinux32` to `/usr/share/lxc/templates`.
+
+Create an LXC image with:
+`lxc-create -n arch32 -t /usr/share/lxc/templates/lxc-archlinux32 -- -a pentium4`
+(choose one of `pentium4`, `i686` or `i486`)
diff --git a/lxc-archlinux32 b/lxc-archlinux32
new file mode 100755
index 0000000..fb2d41d
--- /dev/null
+++ b/lxc-archlinux32
@@ -0,0 +1,337 @@
+#!/bin/bash -x
+
+#
+# template script for generating Arch Linux container for LXC
+#
+
+#
+# lxc: linux Container library
+
+# Authors:
+# Alexander Vladimirov <alexander.idkfa.vladimirov@gmail.com>
+# John Lane <lxc@jelmail.com>
+
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+# Detect use under userns (unsupported)
+for arg in "$@"; do
+ [ "$arg" = "--" ] && break
+ if [ "$arg" = "--mapped-uid" -o "$arg" = "--mapped-gid" ]; then
+ echo "This template can't be used for unprivileged containers." 1>&2
+ echo "You may want to try the \"download\" template instead." 1>&2
+ exit 1
+ fi
+done
+
+# Make sure the usual locations are in PATH
+export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
+
+# defaults
+arch=$(uname -m)
+default_path="/var/lib/lxc"
+default_locale="en_US.UTF-8"
+pacman_config="/etc/pacman.conf"
+common_config="/usr/share/lxc/config/common.conf"
+shared_config="/usr/share/lxc/config/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
+pacman-key --populate archlinux32
+
+# enable networkd
+systemctl enable systemd-networkd
+systemctl enable systemd-resolved
+ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
+EOF
+ # enable getty on active ttys
+ local nttys=$(cat "${config_path}/config" ${shared_config} ${common_config} | grep "^lxc.tty.max" | head -n1 | cut -d= -f2 | tr -d "[:blank:]")
+ local devttydir=$(cat "${config_path}/config" ${shared_config} ${common_config} | grep "^lxc.tty.dir" | head -n1 | cut -d= -f2 | tr -d "[:blank:]")
+ local devtty=""
+ # bind getty instances to /dev/<devttydir>/tty* if lxc.tty.dir is set
+ [ -n "${devttydir}" ] && devtty="${devttydir}-"
+ if [ ${nttys:-0} -gt 1 ]; then
+ ( cd "${rootfs_path}/etc/systemd/system/getty.target.wants"
+ for i in $(seq 1 $nttys); do ln -sf "../getty@.service" "getty@${devtty}tty${i}.service"; done )
+ fi
+ # update securetty to allow console login if devttydir is set
+ if [ -n "${devttydir}" ]; then
+ for i in $(seq 1 ${nttys:-1}); do
+ echo "${devttydir}/tty${i}" >> "${rootfs_path}/etc/securetty"
+ done
+ fi
+ [ -n "${devttydir}" ] && echo "${devttydir}/console" >> "${rootfs_path}/etc/securetty"
+ # Arch default configuration allows only tty1-6 for login
+ [ ${nttys:-0} -gt 6 ] && echo \
+ "You may want to modify container's /etc/securetty \
+ file to allow root logins on tty7 and higher"
+ return 0
+}
+
+# write container configuration files
+copy_configuration() {
+ mkdir -p "${config_path}"
+ local config="${config_path}/config"
+ echo "lxc.uts.name = ${name}" >> "${config}"
+ grep -q "^lxc.arch" "${config}" 2>/dev/null \
+ || echo "lxc.arch = ${arch}" >> "${config}"
+ grep -q "^lxc.rootfs.path" "${config}" 2>/dev/null \
+ || echo "lxc.rootfs.path = ${rootfs_path}" >> "${config}"
+ [ -e "${shared_config}" ] \
+ && echo "lxc.include = ${shared_config}" >> "${config}"
+ if [ $? -ne 0 ]; then
+ echo "Failed to configure container"
+ return 1
+ fi
+ return 0
+}
+
+# install packages within container chroot
+install_arch() {
+ [ "${arch}" != "$(uname -m)" ] && different_arch=true
+
+ if [ "${different_arch}" = "true" ]; then
+ container_pacman_config=$(mktemp)
+ container_mirrorlist=$(mktemp)
+ sed -e "s:Architecture =.*:Architecture = ${arch}:g" \
+ -e "s:/etc/pacman.d/mirrorlist:${container_mirrorlist}:g" \
+ -e "/\[multilib\]/,+2d" \
+ "${pacman_config}" > "${container_pacman_config}"
+ sed -e "s:\(x86_64\|\$arch\):${arch}:g" \
+ /etc/pacman.d/mirrorlist32 > "${container_mirrorlist}"
+ sed -e
+
+ pacman_config="${container_pacman_config}"
+ fi
+
+ if ! pacstrap -dcGC "${pacman_config}" "${rootfs_path}" \
+ ${base_packages[@]}; then
+ echo "Failed to install container packages"
+ return 1
+ fi
+
+ if [ "${different_arch}" = "true" ]; then
+ sed -i -e "s:Architecture =.*:Architecture = ${arch}:g" \
+ "${rootfs_path}"/etc/pacman.conf
+ cp "${container_mirrorlist}" "${rootfs_path}"/etc/pacman.d/mirrorlist
+ rm "${container_pacman_config}" "${container_mirrorlist}"
+ fi
+
+ [ -d "${rootfs_path}/lib/modules" ] && ldconfig -r "${rootfs_path}"
+ return 0
+}
+
+usage() {
+ cat <<EOF
+usage:
+ ${1} -n|--name=<container_name> [-p|--path=<path>] [-a|--arch=<arch of the container>]
+ [-r|--root_password=<root password>] [-P|--packages=<pkg1,pkg2,...>]
+ [-e|--enable_units=unit1,unit2...] [-d|--disable_units=unit1,unit2...]
+ [-c|--config=<pacman config path>] [-h|--help]
+
+Mandatory args:
+ -n,--name container name, used to as an identifier for that container from now on
+Optional args:
+ -p,--path path to where the container rootfs will be created (${default_path})
+ --rootfs path for actual container rootfs, (${default_path}/rootfs)
+ -P,--packages preinstall additional packages, comma-separated list
+ -e,--enable_units enable systemd services, comma-separated list
+ -d,--disable_units disable systemd services, comma-separated list
+ -c,--config use specified pacman config when installing container packages
+ -a,--arch use specified architecture instead of host's architecture
+ -r,--root_password set container root password
+ -h,--help print this help
+EOF
+ return 0
+}
+
+options=$(getopt -o hp:P:e:d:n:c:a:r: -l help,rootfs:,path:,packages:,enable_units:,disable_units:,name:,config:,arch:,root_password: -- "${@}")
+if [ ${?} -ne 0 ]; then
+ usage $(basename ${0})
+ exit 1
+fi
+eval set -- "${options}"
+
+while true
+do
+ case "${1}" in
+ -h|--help) usage ${0} && exit 0;;
+ -p|--path) path=${2}; shift 2;;
+ -n|--name) name=${2}; shift 2;;
+ --rootfs) rootfs_path=${2}; shift 2;;
+ -P|--packages) additional_packages=${2}; shift 2;;
+ -e|--enable_units) enable_units=${2}; shift 2;;
+ -d|--disable_units) disable_units=${2}; shift 2;;
+ -c|--config) pacman_config=${2}; shift 2;;
+ -a|--arch) arch=${2}; shift 2;;
+ -r|--root_password) root_passwd=${2}; shift 2;;
+ --) shift 1; break ;;
+ *) break ;;
+ esac
+done
+
+if [ -z "${name}" ]; then
+ echo "missing required 'name' parameter"
+ exit 1
+fi
+
+type pacman >/dev/null 2>&1
+if [ ${?} -ne 0 ]; then
+ echo "'pacman' command is missing, refer to wiki.archlinux.org for information about installing pacman"
+ exit 1
+fi
+
+if [ -z "${path}" ]; then
+ path="${default_path}/${name}"
+fi
+
+if [ "${EUID}" != "0" ]; then
+ echo "This script should be run as 'root'"
+ exit 1
+fi
+
+if [ -z "$rootfs_path" ]; then
+ rootfs_path="${path}/rootfs"
+fi
+config_path="${path}"
+
+revert() {
+ echo "Interrupted, cleaning up"
+ lxc-destroy -n "${name}"
+ rm -rf "${path}/${name}"
+ rm -rf "${default_path}/${name}"
+ exit 1
+}
+
+trap revert SIGHUP SIGINT SIGTERM
+
+copy_configuration
+if [ ${?} -ne 0 ]; then
+ echo "failed to write configuration file"
+ rm -rf "${config_path}"
+ exit 1
+fi
+
+if [ ${#additional_packages[@]} -gt 0 ]; then
+ split_string ${additional_packages}
+ base_packages+=(${result[@]})
+fi
+
+mkdir -p "${rootfs_path}"
+install_arch
+if [ ${?} -ne 0 ]; then
+ echo "failed to install Arch Linux"
+ rm -rf "${config_path}" "${path}"
+ exit 1
+fi
+
+configure_arch
+if [ ${?} -ne 0 ]; then
+ echo "failed to configure Arch Linux for a container"
+ rm -rf "${config_path}" "${path}"
+ exit 1
+fi
+
+if [ ${#enable_units[@]} -gt 0 ]; then
+ split_string ${enable_units}
+ for unit in ${result[@]}; do
+ [ "${unit##*.}" = "service" ] || unit="${unit}.service"
+ ln -s "/usr/lib/systemd/system/${unit}" \
+ "${rootfs_path}/etc/systemd/system/multi-user.target.wants/"
+ done
+fi
+
+if [ ${#disable_units[@]} -gt 0 ]; then
+ split_string ${disable_units}
+ for unit in ${result[@]}; do
+ [ "${unit##*.}" = "service" ] || unit="${unit}.service"
+ ln -s /dev/null "${rootfs_path}/etc/systemd/system/${unit}"
+ done
+fi
+
+if [ -n "${root_passwd}" ]; then
+ echo "root:${root_passwd}" | chroot "${rootfs_path}" chpasswd
+fi
+
+cat << EOF
+Arch Linux container ${name} is successfully created! The configuration is
+stored in ${config_path}/config. Please refer to https://wiki.archlinux.org for
+information about configuring Arch Linux.
+EOF