Skip to content

Instantly share code, notes, and snippets.

@toonn
Last active March 28, 2017 09:34
Show Gist options
  • Save toonn/811ecf5dc87e9817e2832458ea002089 to your computer and use it in GitHub Desktop.
Save toonn/811ecf5dc87e9817e2832458ea002089 to your computer and use it in GitHub Desktop.
Running Nylas sync-engine in a systemd-nspawn Ubuntu container on Arch Linux (based on https://github.com/nylas/sync-engine/wiki/Running-under-systemd-nspawn)
# Install required utilities
pacman -S debootstrap
pacaur -S gnupg1 ubuntu-keyring
# Create a btrfs subvolume to house the container's base system
btrfs subvolume create UbuntuXenial
# Set up the Ubuntu system tree
# According to the man page --arch should be specified on systems without dpkg
debootstrap --arch=amd64 xenial UbuntuXenial/
# Change the hostname, resolv.conf and apt sources.list
echo UbuntuXenial > UbuntuXenial/etc/hostname
# Running a local nameserver so ::1 is fine, change appropriately
#!!! can't get local nameserver to work with the container
echo "nameserver 10.0.0.1" > UbuntuXenial/etc/resolvconf/resolv.conf.d/base #/etc/resolv.conf is overridden by resolvconf
cp sources.list UbuntuXenial/etc/apt/sources.list
# Need to install dbus in each container or in the base container
# if you want to use machinectl to get a shell or login to the container
# Snapshot the base system so it can be used to create containers in the future
btrfs subvolume snapshot UbuntuXenial/ NylasSyncEngine
# Change the hostname for the snapshot
echo NylasSyncEngine > NylasSyncEngine/etc/hostname
# Add an entry to hosts
echo "127.0.1.1 NylasSyncEngine.localdomain NylasSyncEngine" >> NylasSyncEngine/etc/hosts
# Clone sync-engine
git clone https://github.com/nylas/sync-engine.git UbuntuXenial/sync-engine
# Patch sync-engine/setup.sh
cp setup.sh NylasSyncEngine/sync-engine/setup.sh
# Spawn a shell on the container
systemd-nspawn -D NylasSyncEngine/
# Update repos
apt-get update
# Sync-engine can't be run as root so create a user and root password for sudo
passwd
useradd nylas
su nylas
# Run setup.sh, needed sudo, even as root because the script uses $SUDO_UID
cd /sync-engine
sudo ./setup.sh
#!!! Monitor whether COW on MySQL database is a problem
# Additional needed steps (from memory)
# Exit the container
exit
exit
# Start container with virtual ethernet
systemd-nspawn -M NylasSyncEngine -n
# On host
# configure the veth host-side
ip a add 10.0.0.1/24 broadcast 10.0.0.255 dev ve-NylasSyncEn
ip link set dev ve-NylasSyncEn up
# enable ip forwarding and set up iptables for nat (wlp3s0 is my internet connected interface)
sysctl net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o wlp3s0 -j MASQUERADE
iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i ve-NylasSyncEn -o wlp3s0 -j ACCEPT
# Configure pdnsd to listen on all interfaces
# /etc/pdnsd.conf -> server_ip = any;
#!!! DNS still doesn't work from inside the container, no idea why to be honest
# On NylasSyncEngine container
# nohup's may not be necessary if you're not doing this interactively
# As root
# configure the veth container-side
ip a add 10.0.0.2/24 broadcast 10.0.0.255 dev host0
ip link set dev host0 up
ip route add default via 10.0.0.1 dev host0 #set up default gateway
# start the necessary services
nohup service mysql start &
service redis_6379 start
su nylas
# As user nylas
sudo dpkg-reconfigure --frontend noninteractive tzdata # Can't get this to stick
nohup inbox-start &
inbox-api
# Now install and start Nylas Mail on the host and point it to 10.0.0.2:5555
# Nylas Mail seems to be trying to sync but no mails, contacts, calendars, etc. have been synced yet.
# Couple notes, got networking working on another container.
# nameserver gateway -> resolv.conf
# enable systemd-networkd on both host and container.
#!/bin/bash
set -e
prod=false
while getopts "p" opt; do
case $opt in
p)
prod=true
;;
esac
done
color() {
printf '\033[%sm%s\033[m\n' "$@"
# usage color "31;5" "string"
# 0 default
# 5 blink, 1 strong, 4 underlined
# fg: 31 red, 32 green, 33 yellow, 34 blue, 35 purple, 36 cyan, 37 white
# bg: 40 black, 41 red, 44 blue, 45 purple
}
color '36;1' "
_ _ _
| \ | |_ _| | __ _ ___
| \| | | | | |/ _' / __|
| |\ | |_| | | (_| \__ \\
|_| \_|\__, |_|\__,_|___/
|___/
This script installs dependencies for the Nylas Sync Engine.
For more details, visit:
https://www.github.com/nylas/sync-engine
"
if ! [ -e ./setup.py ] || ! [ -e ./setup.sh ] ; then
color '31;1' "Error: setup.sh should be run from the sync-engine repo" >&2
exit 1
fi
color '35;1' 'Updating packages...'
if command -v mysql >/dev/null 2>&1
then
echo "MySQL Exists. Not adding upstream mysql package";
else
echo "Adding MySQL APT Repo";
#Trust MySQL APT Repo
echo "deb http://repo.mysql.com/apt/ubuntu/ xenial mysql-5.7" > /etc/apt/sources.list.d/mysql.list;
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 5072E1F5;
fi
# Don't fail builds if apt-get update fails (eg due to ksplice being down)
set +e
apt-get -qq update
set -e
apt-get -qq -y install python-software-properties
{ \
echo "mysql-community-server mysql-community-server/data-dir select ''"; \
echo "mysql-community-server mysql-community-server/root-pass password root"; \
echo "mysql-community-server mysql-community-server/re-root-pass password root"; \
echo "mysql-community-server mysql-community-server/remove-test-db select false"; \
echo "mysql-server mysql-server/root_password password root";
echo "mysql-server mysql-server/root_password_again password root";
} | sudo debconf-set-selections
color '35;1' 'Installing dependencies from apt-get...'
apt-get -y install git \
mercurial \
wget \
supervisor \
mysql-server \
mysql-client \
python \
python-dev \
python-pip \
python-setuptools \
build-essential \
libmysqlclient-dev \
gcc \
g++ \
libxml2-dev \
libxslt-dev \
lib32z1-dev \
libffi-dev \
libssl-dev \
pkg-config \
python-lxml \
tmux \
curl \
tnef \
stow \
lua5.2 \
liblua5.2-dev \
# Switch to a temporary directory to install dependencies, since the source
# directory might be mounted from a VM host with weird permissions.
src_dir=$(pwd)
temp_dir=`mktemp -d`
cd "$temp_dir"
# Workaround for "error: sodium.h: No such file or directory" bug
# https://github.com/pyca/pynacl/issues/79
libsodium_ver=1.0.0
color '35;1' 'Ensuring libsodium version...'
if ! pkg-config --atleast-version="${libsodium_ver}" libsodium; then
# Ubuntu precise doesn't have a libsodium-dev package, so we build it
# ourselves and install it to /usr/local (using GNU stow so that we can
# uninstall it later).
# Uninstall old version
if pkg-config --exists libsodium; then
libsodium_oldver=`pkg-config --modversion libsodium`
color '35;1' " > Uninstalling libsodium-${libsodium_oldver}..."
stow -d /usr/local/stow -D "libsodium-${libsodium_oldver}"
ldconfig
if pkg-config --exists libsodium; then
color '31;1' " > Unable to uninstall libsodium-${libsodium_oldver}"
exit 1
fi
fi
color '35;1' " > Downloading and installing libsodium-${libsodium_ver}..."
curl -L -O https://github.com/jedisct1/libsodium/releases/download/${libsodium_ver}/libsodium-${libsodium_ver}.tar.gz
echo 'ced1fe3d2066953fea94f307a92f8ae41bf0643739a44309cbe43aa881dbc9a5 *libsodium-1.0.0.tar.gz' | sha256sum -c || exit 1
tar -xzf libsodium-${libsodium_ver}.tar.gz
cd libsodium-${libsodium_ver}
./configure --prefix=/usr/local/stow/libsodium-${libsodium_ver}
make -j4
rm -rf /usr/local/stow/libsodium-${libsodium_ver}
mkdir -p /usr/local/stow/libsodium-${libsodium_ver}
make install
stow -d /usr/local/stow -R libsodium-${libsodium_ver}
ldconfig
cd ..
rm -rf libsodium-${libsodium_ver} libsodium-${libsodium_ver}.tar.gz
if pkg-config --exists libsodium; then
color '34;1' " > libsodium-${libsodium_ver} installed."
else
color '31;1' " > Unable to install libsodium-${libsodium_ver}"
exit 1
fi
fi
if ! ${prod}; then
color "35;1" "Ensuring redis version..."
redis_version=2.8.17
if ! [ -e /usr/local/stow/redis-${redis_version} ]; then
color "35;1" "Downloading and installing redis-${redis_version}..."
curl -L -O --progress-bar http://download.redis.io/releases/redis-${redis_version}.tar.gz
echo "913479f9d2a283bfaadd1444e17e7bab560e5d1e *redis-${redis_version}.tar.gz" | sha1sum -c --quiet || exit 1
tar -xf redis-${redis_version}.tar.gz
cd redis-${redis_version}
make -j2 || exit 1
rm -rf /usr/local/stow/redis-${redis_version}
make PREFIX=/usr/local/stow/redis-${redis_version} install
stow -d /usr/local/stow/ -R redis-${redis_version}
cd utils
echo -e -n "\n\n\n\n\n\n" | ./install_server.sh
rm -f /tmp/6379.conf
cd ../..
rm -rf redis-${redis_version} redis-${redis_version}.tar.gz
# modify redis conf so that redis is only accessible localy
sed -i '/^#.*bind 127/s/^#//' /etc/redis/6379.conf
fi
color '34;1' 'redis-'${redis_version}' installed.'
fi
color '35;1' 'Ensuring setuptools and pip versions...'
# Need up-to-date pyparsing or upgrading pip will break pip
# https://github.com/pypa/packaging/issues/94
pip install 'pyparsing==2.2.0'
# If python-setuptools is actually the old 'distribute' fork of setuptools,
# then the first 'pip install setuptools' will be a no-op.
pip install 'pip==9.0.1' 'setuptools==34.3.1'
hash pip # /usr/bin/pip might now be /usr/local/bin/pip
pip install 'pip==9.0.1' 'setuptools==34.3.1'
# Doing pip upgrade setuptools leaves behind this problematic symlink
rm -rf /usr/lib/python2.7/dist-packages/setuptools.egg-info
# Install tox for running tests
pip install 'tox'
# Now that the new version of pip and our other non-pip dependencies are
# installed, we can switch back to the source directory.
cd "$src_dir"
color '35;1' 'Removing .pyc files...' # they might be stale
find . -name \*.pyc -delete
color '35;1' 'Installing dependencies from pip...'
SODIUM_INSTALL=system pip install -r requirements.txt
pip install -e .
color '35;1' 'Finished installing dependencies.'
mkdir -p /etc/inboxapp
chown $SUDO_UID:$SUDO_GID /etc/inboxapp
color '35;1' 'Copying default development configuration to /etc/inboxapp'
src=./etc/config-dev.json
dest=/etc/inboxapp/config.json
if [ ! -f $dest ]; then
install -m0644 -o$SUDO_UID $src $dest
elif [ $src -nt $dest ]; then
set +e
diff_result=$(diff -q $src $dest)
different=$?
set -e
if [ $different -ne 0 ]; then
echo "Error: sync engine config is newer and merging of configs not (yet) supported."
echo "Diffs:"
echo "src: $src dest: $dest"
diff $dest $src
exit 1
fi
fi
# make sure that users upgrading from a previous release get file permissions
# right
chmod 0644 $dest
chown $SUDO_UID:$SUDO_GID $dest
color '35;1' 'Copying default secrets configuration to /etc/inboxapp'
src=./etc/secrets-dev.yml
dest=/etc/inboxapp/secrets.yml
if [ ! -f $dest ]; then
install -m0600 -o$SUDO_UID $src $dest
elif [ $src -nt $dest ]; then
set +e
diff_result=$(diff -q $src $dest)
different=$?
set -e
if [ $different -ne 0 ]; then
echo "Error: sync engine secrets config is newer and merging of configs not (yet) supported."
echo "Diffs:"
echo "src: $src dest: $dest"
diff $dest $src
exit 1
fi
fi
# make sure that users upgrading from a previous release get file permissions
# right
chmod 0600 $dest
chown $SUDO_UID:$SUDO_GID $dest
if ! $prod; then
# Mysql config
color '35;1' 'Copying default mysql configuration to /etc/mysql/conf.d'
src=./etc/my.cnf
dest=/etc/mysql/conf.d/inboxapp.cnf
if [ ! -f $dest ]; then
install -m0644 $src $dest
elif [ $src -nt $dest ]; then
set +e
diff_result=$(diff -q $src $dest)
different=$?
set -e
if [ $different -ne 0 ]; then
echo "Error: sync engine config is newer and merging of configs not (yet) supported."
echo "Diffs:"
echo "src: $src dest: $dest"
diff $dest $src
exit 1
fi
fi
mkdir -p /var/run/mysqld
mysqld_safe &
sleep 10
env NYLAS_ENV=dev PYTHONPATH=/sync-engine:$PYTHONPATH bin/create-db
env NYLAS_ENV=dev PYTHONPATH=/sync-engine:$PYTHONPATH bin/create-test-db
fi
if [[ $(mysql --version) != *"5.6"* ]]
then
echo "WARNING: We've detected that you are not using mysql 5.6. Please upgrade.";
fi
color '35;1' 'Cleaning up...'
apt-get -y autoremove
mkdir -p /var/lib/inboxapp/parts
chown -R $SUDO_UID:$SUDO_GID /var/lib/inboxapp
mkdir -p /var/log/inboxapp
chown $SUDO_UID:$SUDO_GID /var/log/inboxapp
mkdir -p /etc/inboxapp
cp etc/config-dev.json /etc/inboxapp/config.json
cp etc/secrets-dev.yml /etc/inboxapp/secrets.yml
chown $SUDO_UID:$SUDO_GID /etc/inboxapp
git config branch.master.rebase true
# Set proper timezone
echo 'UTC' | sudo tee /etc/timezone
color '35;1' 'Done!.'
#------------------------------------------------------------------------------#
# OFFICIAL UBUNTU REPOS #
#------------------------------------------------------------------------------#
###### Ubuntu Main Repos
deb http://be.archive.ubuntu.com/ubuntu/ xenial main restricted universe multiverse
###### Ubuntu Update Repos
deb http://be.archive.ubuntu.com/ubuntu/ xenial-security main restricted universe multiverse
deb http://be.archive.ubuntu.com/ubuntu/ xenial-updates main restricted universe multiverse
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment