Skip to content

Instantly share code, notes, and snippets.



Last active Sep 12, 2019
What would you like to do?
lxc-arch2: a script to create a copy of my Arch Linux system in LXC for testing
#!/bin/zsh -e
cd ~/tmpfs
mkdir -p .lxc-root .lxc-data/root/etc .lxc-work
sudo GDK_DPI_SCALE=$GDK_DPI_SCALE zsh -e - <<'EOF'
chown 0:0 .lxc-data/root .lxc-data/root/etc
modprobe overlay
mountpoint .lxc-root || mount -t overlay -o lowerdir=/,upperdir=$PWD/.lxc-data/root,workdir=$PWD/.lxc-root overlayfs $PWD/.lxc-root
# .lxc-root/etc/resolv.conf is protected
echo nameserver > .lxc-data/root/etc/resolv.conf
rm -f .lxc-root/etc/fstab
rm -r .lxc-root/var/log/journal
mkdir -p .lxc-root/var/log/journal
chgrp systemd-journal .lxc-root/var/log/journal
setfacl -Rnm g:systemd-journal:rx,d:g:systemd-journal:rx .lxc-root/var/log/journal
setopt null_glob extended_glob
ln -sf /usr/lib/systemd/system/ .lxc-root/etc/systemd/system/
rm -f .lxc-root/etc/systemd/system/*~*/sshd.service
rm -f .lxc-root/etc/systemd/user/
rm -f .lxc-root/etc/systemd/system/
rm -f .lxc-root/usr/lib/systemd/system/
rm -f .lxc-root/usr/lib/systemd/system/*.timer
rm -rf .lxc-root/usr/etc/systemd/system/
rm -rf .lxc-root/usr/lib/systemd/system/
# this makes systemd-tmpfiles-setup.service fail on ro /sys
rm -f .lxc-root/usr/lib/tmpfiles.d/linux-firmware.conf
unsetopt null_glob
ln -sf /usr/lib/systemd/system/rc-local.service .lxc-root/etc/systemd/system/
cat > .lxc-root/etc/rc.local <<'RCLOCAL'
ip address delete dev eth0
ip address add dev eth0
ip route add default via
chmod +x .lxc-root/etc/rc.local
echo lxc-arch2 > .lxc-root/etc/hostname
mkdir -p .lxc-data/root/home/lilydjwg
setfattr -n trusted.overlay.opaque -v y .lxc-data/root/home/lilydjwg
chown lilydjwg: .lxc-root/home/lilydjwg
touch .lxc-root/etc/.updated
if [[ -f .lxc-root/var/lib/pacman.fs ]] && ! mountpoint .lxc-root/var/lib/pacman; then
# make overlayfs make a copy of the file, instead of referencing the original one
# this happens with linux 4.9.6
touch .lxc-root/var/lib/pacman.fs
# XFS refuses to mount a same UUID by default
mount -o loop,nouuid .lxc-root/var/lib/pacman{.fs,}
mkdir -p .lxc-data/root/home/lilydjwg/.config/htop
cp {~,.lxc-data/root/home/lilydjwg}/.config/htop/htoprc
mkdir -p .lxc-data/root/home/lilydjwg/.local/share/applications
cp {~,.lxc-data/root/home/lilydjwg}/.local/share/applications/mimeinfo.cache
alsomount () {
local src=$1
local dest=${2:-$src}
local name=${${src##*/}#.}
if ! mountpoint .lxc-root$src; then
mkdir -p $PWD/.lxc-work/$name $PWD/.lxc-root$dest $PWD/.lxc-data/root$dest $PWD/.lxc-data/$name
mount -t overlay -o lowerdir=$src,upperdir=$PWD/.lxc-data/$name,workdir=$PWD/.lxc-work/$name overlayfs $PWD/.lxc-root$dest
mount --bind $PWD/.lxc-data/$name $PWD/.lxc-data/root$dest
bindmount () {
local p=$1
if ! mountpoint .lxc-root$p; then
mkdir -p .lxc-root$p
mount --bind $p .lxc-root$p
alsomount /home/lilydjwg/.zsh
for r in root home/lilydjwg; do
mkdir -p .lxc-root/$r/.ssh
chmod 700 .lxc-root/$r/.ssh
echo ZSH_PS_HOST=lxc-arch2 >> .lxc-root/$r/.zsh/zshrc.local
cp ~lilydjwg/.ssh/ .lxc-root/$r/.ssh/authorized_keys
cp ~lilydjwg/.zprofile .lxc-root/$r
chown -R ${r##*/}:${r##*/} .lxc-root/$r/.ssh .lxc-root/$r/.zsh/zshrc.local .lxc-root/$r/.zprofile
if [[ $r != root ]]; then
ln -s .zsh/zshrc .lxc-root/$r/.zshrc || true
chown -R ${r##*/}:${r##*/} .lxc-root/$r/.zshrc .lxc-root/$r/{.config,.local}
sed -i '/^root:/s/bash/zsh/' .lxc-root/etc/passwd
cat <<CONFIG >> .lxc-root/home/lilydjwg/.zsh/zshrc.local
export DISPLAY=
export GTK_IM_MODULE=xim QT_IM_MODULE=xim XMODIFIERS=@im=fcitx
alsomount /home/lilydjwg/.vim
alsomount /home/lilydjwg/.cache
chown lilydjwg: .lxc-root/home/lilydjwg/{.vim,.zsh,.cache}
bindmount /var/cache/pacman/pkg
sudo zsh -c "lxc-start -F -n arch2; mount -o remount,rw .lxc-root"
# = arch2
lxc.autodev = 1
lxc.tty.max = 1
lxc.pty.max = 1024
lxc.rootfs.path = /home/lilydjwg/tmpfs/.lxc-root
# this prevents kbd and sound getting reset = proc sys
lxc.cap.drop = mknod sys_module mac_admin mac_override sys_time
#networking = veth = br0 = up = eth0 =
lxc.cgroup.devices.deny = a
lxc.cgroup.devices.allow = c *:* m
lxc.cgroup.devices.allow = b *:* m
lxc.cgroup.devices.allow = c 1:3 rwm
lxc.cgroup.devices.allow = c 1:5 rwm
lxc.cgroup.devices.allow = c 1:7 rwm
lxc.cgroup.devices.allow = c 1:8 rwm
lxc.cgroup.devices.allow = c 1:9 rwm
lxc.cgroup.devices.allow = c 1:9 rwm
lxc.cgroup.devices.allow = c 4:1 rwm
lxc.cgroup.devices.allow = c 5:0 rwm
lxc.cgroup.devices.allow = c 5:1 rwm
lxc.cgroup.devices.allow = c 5:2 rwm
# pts
lxc.cgroup.devices.allow = c 136:* rwm

This comment has been minimized.

Copy link
Owner Author

@lilydjwg lilydjwg commented Mar 14, 2015

See my blog post for more (in Chinese).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment