Skip to content

Instantly share code, notes, and snippets.

@wobblybobz
Created October 13, 2016 12:38
Show Gist options
  • Save wobblybobz/5a22835222621f073370f40024399879 to your computer and use it in GitHub Desktop.
Save wobblybobz/5a22835222621f073370f40024399879 to your computer and use it in GitHub Desktop.
[Unit]
Description=Flynn layer 0
After=libvirt-bin.service networking.service
[Service]
ExecStart=/usr/local/bin/flynn-host daemon
Restart=on-failure
RestartSec=20
[Install]
WantedBy=multi-user.target
#!/bin/bash
#
# A script to install Flynn from a TUF repository.
FLYNN_HOST_CHECKSUM="${FLYNN_HOST_CHECKSUM:="70630744fa000b1c1f4a3913374d613baa5cd806a5b3e1d3033074ac975525681582b8afe622b75ac1f0baddb1994d1e5d72cd27b2912333ae8b91ed8d27ef33"}"
usage() {
cat <<USAGE >&2
usage: $0 [options]
A script to install Flynn on Ubuntu 14.04.
See https://flynn.io/docs/installation/manual for further information.
OPTIONS:
-h, --help Show this message
-v, --version VERSION Install explicit VERSION (e.g. v20160512.0)
-c, --channel CHANNEL Fetch updates from CHANNEL (either "stable" or "nightly") [default: stable]
--clean Install from a clean state (implies --remove) [DANGER: this will remove all associated data]
--remove Remove existing Flynn installation [DANGER: this will remove all associated data]
--yes Automatic yes to prompts
-r, --repo URL The TUF repository to download files from [default: https://dl.flynn.io]
VARIABLES:
FLYNN_UPDATE_CHANNEL The release channel to fetch updates from (either "nightly" or "stable") [default: stable]
FLYNN_VERSION An explicit version to install (e.g. v20151104.1)
USAGE
}
main() {
if ! is_root; then
fail "this script must be executed as the root user"
fi
if ! is_ubuntu_xenial; then
fail "this script is only compatible with Ubuntu 16.04 LTS, Xenial Xerus"
fi
check_installed "curl" "sha512sum"
local install=true
local remove=false
local assume_yes=false
local channel="${FLYNN_UPDATE_CHANNEL:-"stable"}"
local repo_url
export DEBIAN_FRONTEND=noninteractive
while true; do
case "$1" in
-v | --version)
if [[ -z "$2" ]]; then
fail "--version requires an argument"
fi
export FLYNN_VERSION="$2"
shift 2
;;
-c | --channel)
if [[ -z "$2" ]]; then
fail "--channel requires an argument"
fi
channel="$2"
shift 2
;;
--clean)
remove=true
shift
;;
--remove)
remove=true
install=false
shift
;;
--yes)
assume_yes=true
shift
;;
-h | --help)
usage
exit 1
;;
-r | --repo)
if [[ -z "$2" ]]; then
fail "--repo requires an argument"
fi
repo_url="$2"
shift 2
;;
*)
break
;;
esac
done
if [[ $# -ne 0 ]]; then
usage
exit 1
fi
if $remove; then
do_remove $assume_yes
fi
if [[ -e "/usr/local/bin/flynn-host" ]]; then
fail "Flynn is already installed. Run 'flynn-host update' to update to a more recent version, or use --clean to remove the existing Flynn install first"
fi
if ! $install; then
exit
fi
repo_url="${repo_url:="https://dl.flynn.io"}"
run apt-get update
# install linux-headers explicitly before ubuntu-zfs to avoid skipping
# building kernel modules due to absent kernel headers.
info "installing linux-headers"
run apt-get install -y "linux-headers-$(uname -r)"
local packages=(
"aufs-tools"
"iptables"
"zfsutils-linux"
)
if ! modprobe aufs &>/dev/null; then
packages+=(
"linux-image-extra-$(uname -r)"
)
fi
info "installing runtime dependencies"
run apt-get install --yes ${packages[@]}
info "loading zfs kernel module"
run modprobe zfs
info "downloading flynn-host binary to tmp dir"
local tmp="$(mktemp --directory)"
trap "rm -rf ${tmp}" EXIT
cd "${tmp}"
if ! curl -fsSL -o "${tmp}/flynn-host.gz" "${repo_url}/tuf/targets/${FLYNN_HOST_CHECKSUM}.flynn-host.gz"; then
fail "failed to download flynn-host binary from ${repo_url}"
fi
info "verifying flynn-host binary checksum"
if ! echo "${FLYNN_HOST_CHECKSUM} *flynn-host.gz" | sha512sum --check --status; then
fail "failed to verify flynn-host binary checksum!"
fi
run gunzip "flynn-host.gz"
run chmod +x "flynn-host"
info "setting release update channel to \"${channel}\""
mkdir -p "/etc/flynn"
echo "${channel}" > "/etc/flynn/channel.txt"
info "downloading Flynn components"
mkdir -p "/etc/flynn"
run ./flynn-host download \
--repository "${repo_url}/tuf" \
--tuf-db "/etc/flynn/tuf.db" \
--config-dir "/etc/flynn" \
--bin-dir "/usr/local/bin"
# install libvirt dependencies for versions before v20160711.0.
#
# NOTE: Uses a negative assertion so we only skip installing if we know the
# installed Flynn version is definitely greater than or equal to
# v20160711.0.
local version="$(/usr/local/bin/flynn-host version)"
if ! [[ "${version:1:8}" -ge "20160711" ]]; then
info "installing extra runtime dependencies"
run apt-get install --yes "libvirt-bin"
info "setting libvirt defaults"
if grep -q "^libvirt_uris=" /etc/default/libvirt-bin; then
sed "s|^libvirt_uris=.*|libvirt_uris='qemu:///system'|" -i /etc/default/libvirt-bin
else
echo "libvirt_uris='qemu:///system'" >> /etc/default/libvirt-bin
fi
fi
info "installing systemd job"
cp /etc/flynn/flynn-host.service /lib/systemd/system/flynn-host.service
systemctl enable flynn-host.service
info "installation complete!"
}
is_root() {
[[ $(id -u) -eq 0 ]]
}
is_ubuntu_xenial() {
grep "Ubuntu 16.04" "/etc/os-release" &>/dev/null
}
do_remove() {
local assume_yes=$1
warn "*** WARNING ***"
warn "About to stop Flynn and remove all existing data"
if ! $assume_yes; then
warn "Are you sure this is what you want?"
echo -n "(yes/no): "
while read answer; do
case "${answer}" in
yes) assume_yes=true; break ;;
no) break ;;
*) echo -n "Please type 'yes' or 'no': " ;;
esac
done
if ! $assume_yes; then
exit
fi
fi
info "stopping flynn-host daemon"
local status="$(systemctl is-active flynn-host)"
if [[ "${status:0:6}" = "active" ]]; then
run systemctl stop flynn-host
fi
info "killing old containers"
sudo start-stop-daemon \
--stop \
--oknodo \
--retry 5 \
--name ".containerinit"
info "destroying ZFS volumes"
for path in $(grep zfs /proc/mounts | cut -d ' ' -f2); do
run sudo umount "${path}"
done
if which flynn-host &>/dev/null; then
run flynn-host destroy-volumes --include-data
fi
if zpool list | grep -q "flynn-default"; then
run zpool destroy flynn-default
fi
info "removing Flynn files and directories"
run rm -rf /usr/local/bin/flynn* /var/lib/flynn /etc/flynn
info "Flynn successfully removed"
}
check_installed() {
local missing=()
for bin in $@; do
if ! which "${bin}" &>/dev/null; then
missing+=("${bin}")
fi
done
if [[ ${#missing[@]} -gt 0 ]]; then
fail "this script requires: ${missing[@]}"
fi
}
run() {
local cmd=$@
info "running \"${cmd}\""
$cmd
local status=$?
if [[ $status -ne 0 ]]; then
fail "failed to run \"${cmd}\", exit status ${status}"
fi
}
timestamp() {
date "+%H:%M:%S.%3N"
}
info() {
local msg=$1
echo -e "\e[1;32m===> $(timestamp) ${msg}\e[0m"
}
warn() {
local msg=$1
echo -e "\e[1;33m===> $(timestamp) ${msg}\e[0m"
}
fail() {
local msg=$1
echo -e "\e[1;31m===> $(timestamp) ERROR: ${msg}\e[0m"
exit 1
}
main $@
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment