Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
lxc-arch2: a script to create a copy of my Arch Linux system in systemd-nspawn 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 192.168.57.1 > .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/multi-user.target .lxc-root/etc/systemd/system/default.target
rm -f .lxc-root/etc/systemd/system/multi-user.target.wants/*~*/sshd.service
rm -f .lxc-root/etc/systemd/user/default.target.wants/xdg-user-dirs-update.service
rm -f .lxc-root/etc/systemd/system/default.target.wants/shutdown-diagnose.service
rm -f .lxc-root/usr/lib/systemd/system/shutdown.target.wants/alsa-store.service
rm -f .lxc-root/usr/lib/systemd/system/multi-user.target.wants/*.timer
rm -rf .lxc-root/usr/etc/systemd/system/network-online.target.wants
rm -rf .lxc-root/usr/lib/systemd/system/timers.target.wants
# 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/multi-user.target.wants/rc-local.service
cat > .lxc-root/etc/rc.local <<'RCLOCAL'
#!/bin/sh
ip address add 192.168.57.3/24 dev host0
ip link set host0 up
ip route add default via 192.168.57.1
RCLOCAL
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,}
fi
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
fi
}
bindmount () {
local p=$1
if ! mountpoint .lxc-root$p; then
mkdir -p .lxc-root$p
mount --bind $p .lxc-root$p
fi
}
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/id_ed25519.pub .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}
fi
done
sed -i '/^root:/s/bash/zsh/' .lxc-root/etc/passwd
cat <<CONFIG >> .lxc-root/home/lilydjwg/.zsh/zshrc.local
export DISPLAY=192.168.57.1:0
export GTK_IM_MODULE=xim QT_IM_MODULE=xim XMODIFIERS=@im=fcitx
export GDK_DPI_SCALE=$GDK_DPI_SCALE
CONFIG
alsomount /home/lilydjwg/.vim
alsomount /home/lilydjwg/.cache
chown lilydjwg: .lxc-root/home/lilydjwg/{.vim,.zsh,.cache}
bindmount /var/cache/pacman/pkg
EOF
# using systemd-nspawn:
sudo zsh -c "systemd-nspawn --network-bridge=br0 --boot -D .lxc-root; mount -o remount,rw .lxc-root"
# old way: use lxc. Remember to update network interface: host0 -> eth0.
# sudo zsh -c "lxc-start -F -n arch2; mount -o remount,rw .lxc-root"
#
lxc.uts.name = 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
lxc.mount.auto = proc sys
lxc.cap.drop = mknod sys_module mac_admin mac_override sys_time
#networking
lxc.net.0.type = veth
lxc.net.0.link = br0
lxc.net.0.flags = up
lxc.net.0.name = eth0
lxc.net.0.ipv4.address = 192.168.57.3
#cgroups
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
@lilydjwg

This comment has been minimized.

Copy link
Owner Author

@lilydjwg lilydjwg commented Mar 14, 2015

See my blog post for more (in Chinese).

It used to use lxc but now I run it with systemd-nspawn with a little modification.

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