Create a gist now

Instantly share code, notes, and snippets.

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/etc .lxc-data/home/lilydjwg/{.vim,.cache} .lxc-work
sudo GDK_DPI_SCALE=$GDK_DPI_SCALE zsh -e - <<'EOF'
modprobe overlay
mountpoint .lxc-root || mount -t overlay -o lowerdir=/,upperdir=$PWD/.lxc-data,workdir=$PWD/.lxc-root overlayfs $PWD/.lxc-root
# .lxc-root/etc/resolv.conf is protected
echo nameserver 192.168.57.1 > .lxc-data/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
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/*
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
# 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
route add -net default gw 192.168.57.1
route add -net 192.168.0.0/16 eth0
route del -net 192.0.0.0/8
RCLOCAL
chmod +x .lxc-root/etc/rc.local
mkdir -p .lxc-data/home/lilydjwg
setfattr -n trusted.overlay.opaque -v y .lxc-data/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/home/lilydjwg/.config/htop
cp {~,.lxc-data/home/lilydjwg}/.config/htop/htoprc
mkdir -p .lxc-data/home/lilydjwg/.local/share/applications
cp {~,.lxc-data/home/lilydjwg}/.local/share/applications/mimeapps.list
for r in root home/lilydjwg; do
mkdir -p .lxc-root/$r/.ssh .lxc-root/$r/.zsh
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/.zshrc ~lilydjwg/.zprofile .lxc-root/$r
chown -R ${r##*/}:${r##*/} .lxc-root/$r/.ssh .lxc-root/$r/.zsh .lxc-root/$r/.zprofile .lxc-root/$r/.zshrc .lxc-root/$r/{.config,.local}
done
sed -i '/^root:/s/bash/zsh/' .lxc-root/etc/passwd
cat <<CONFIG > .lxc-root/home/lilydjwg/.zsh/zshrc.local
ZSH_PS_HOST=lxc-arch2
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
bindmount () {
local p=$1
local name=${${p##*/}#.}
if ! mountpoint .lxc-root$p; then
mkdir -p $PWD/.lxc-work/$name
mount -t overlay -o lowerdir=$p,upperdir=$PWD/.lxc-data$p,workdir=$PWD/.lxc-work/$name overlayfs $PWD/.lxc-root$p
fi
}
bindmount /home/lilydjwg/.vim
bindmount /home/lilydjwg/.cache
EOF
[[ -f .lxc-root/home/lilydjwg/.vim/vimrc ]] || (
cd .lxc-root/home/lilydjwg
git clone /home/lilydjwg/.vim
cd .vim
git remote set-url origin git://192.168.57.1/.vim
)
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
Owner

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