diff --git a/bridge/DEVELOP.md b/bridge/DEVELOP.md new file mode 100644 index 000000000..516ae70dc --- /dev/null +++ b/bridge/DEVELOP.md @@ -0,0 +1,19 @@ +# Developing the bridge + +## Local Devnet + +The following dependencies are required for local development: + +- Go >= 1.14 +- Docker >= 19.03 +- Tilt >= 0.17.0 +- Any of the local Kubernetes clusters supported by Tilt (we recommend minikube or kind). + +See the [Tilt docs](https://docs.tilt.dev/install.html) docs on how to set up your local cluster - +it won't take more than a few minutes to set up! + +This works natively on both Linux and MacOS. + +Then, just run `tilt up`. Whenever you modify a file, the devnet is automatically rebuilt. + +Once you're done, press Ctrl-C. Run `tilt down` to tear down the devnet. diff --git a/bridge/Dockerfile b/bridge/Dockerfile new file mode 100644 index 000000000..7593f846f --- /dev/null +++ b/bridge/Dockerfile @@ -0,0 +1,11 @@ +# syntax=docker/dockerfile:experimental +FROM golang:1.14 + +WORKDIR /app + +ADD . . + +RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg \ + go build -o /guardiand github.com/certusone/wormhole/bridge/cmd/guardiand + +ENTRYPOINT /guardiand diff --git a/bridge/Tiltfile b/bridge/Tiltfile new file mode 100644 index 000000000..9e3c2161e --- /dev/null +++ b/bridge/Tiltfile @@ -0,0 +1,9 @@ +docker_build( + ref = "guardiand-image", + context = ".", + dockerfile = "Dockerfile", +) + +k8s_yaml("k8s/deployment.yaml") + +k8s_resource("guardian") diff --git a/bridge/dev-install.sh b/bridge/dev-install.sh new file mode 100755 index 000000000..988e1b08d --- /dev/null +++ b/bridge/dev-install.sh @@ -0,0 +1,114 @@ +#!/bin/bash +set -euo pipefail +# +# This script downloads and installs development dependencies required for +# bridge development on Linux. +# +# Tested on amd64 with CentOS 8, Debian 10 and Ubuntu 20.04. Likely works on other distros as well. +# +# We use this to set up our CI, but you might find it useful for your own development needs. +# +# This installer pulls in binaries from, and therefore trusts, a number of third-party sources: +# +# - k3s.io by Rancher Labs. +# - Go binary distribution by Google. +# - Tilt binary distribution by Tilt. +# +# Idempotent and safe to run multiple times for upgrades (but restarts your cluster). +# Goes without saying, but this is NOT for production, or anywhere close to it. +# +# If you want to allow other users on the host access to the k3s cluster, look into +# run the installer script with an appropriate K3S_KUBECONFIG_MODE. + +if [[ $EUID -ne 0 ]]; then + echo "This script must be run as root" + exit 1 +fi + +if ! docker info; then + echo "Please install and configure Docker first" + exit 1 +fi + +# On Ubuntu/Debian, switch to iptables-legacy +# https://github.com/rancher/k3s/issues/1114 +if update-alternatives --set iptables /usr/sbin/iptables-legacy; then + systemctl restart docker +fi + +# Ensure that our binaries are not shadowed by the distribution. +export PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/sbin:/bin + +# Install Go binaries. +ARCH=amd64 +GO=1.14.6 + +( + if [[ -d /usr/local/go ]]; then + rm -rf /usr/local/go + fi + + TMP=$(mktemp -d) + + ( + cd "$TMP" + curl -OJ "https://dl.google.com/go/go${GO}.linux-${ARCH}.tar.gz" + tar -C /usr/local -xzf "go${GO}.linux-${ARCH}.tar.gz" + + echo 'PATH=/usr/local/go/bin:$PATH' >/etc/profile.d/local_go.sh + ) + + rm -rf "$TMP" +) + +. /etc/profile.d/local_go.sh + +# Install Tilt (latest stable release by Tilt). Install script looks fine. +curl -fsSL https://raw.githubusercontent.com/tilt-dev/tilt/master/scripts/install.sh | bash + +# Install SELinux policies for k3s on CentOS/Fedora systems (ignored otherwise). +if rpm -q libselinux-utils; then + yum install -y container-selinux selinux-policy-base + ! rpm -i https://rpm.rancher.io/k3s-selinux-0.1.1-rc1.el7.noarch.rpm +fi + +# Install k3s with sane defaults and make it use the local Docker daemon. +curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION="v1.18.6+k3s1" INSTALL_K3S_EXEC="server + --disable-cloud-controller + --kube-scheduler-arg=address=127.0.0.1 + --kube-controller-manager-arg=address=127.0.0.1 + --disable traefik + --docker +" sh -s - + +cat <<'EOF' > /etc/profile.d/k3s.sh +alias kc=kubectl + +source <(kubectl completion bash) +complete -F __start_kubectl kc + +function use-namespace { + kubectl config set-context --current --namespace=$1 +} + +# Required for tilt to find the local cluster +export KUBECONFIG=/etc/rancher/k3s/k3s.yaml +EOF + +. /etc/profile.d/k3s.sh + +# Set default namespace to wormhole to make it easier to reset without deleting the cluster. +kubectl create namespace wormhole +use-namespace wormhole + +# Trick tilt into not pushing images by pretending to be docker-desktop +# FIXME: https://github.com/tilt-dev/tilt/issues/3654 +sed -i 's/ name: default/ name: docker-desktop/g' $KUBECONFIG +sed -i 's/current-context: default/current-context: docker-desktop/g' $KUBECONFIG +sed -i 's/cluster: default/cluster: docker-desktop/g' $KUBECONFIG + +while ! k3s kubectl get all; do + echo "Waiting for k3s..." + systemctl status k3s.service + sleep 5 +done diff --git a/bridge/k8s/deployment.yaml b/bridge/k8s/deployment.yaml new file mode 100644 index 000000000..83ed8e134 --- /dev/null +++ b/bridge/k8s/deployment.yaml @@ -0,0 +1,50 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: guardian + labels: + app: guardian +spec: + ports: + - port: 8999 + name: p2p + protocol: UDP + clusterIP: None + selector: + app: guardian +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: guardian +spec: + selector: + matchLabels: + app: guardian + serviceName: guardian + replicas: 20 + template: + metadata: + labels: + app: guardian + spec: + terminationGracePeriodSeconds: 1 + containers: + - name: guardiand + image: guardiand-image + ports: + - containerPort: 8999 + name: p2p + protocol: UDP + volumeMounts: + - name: guardian-data + mountPath: /data + volumeClaimTemplates: + - metadata: + name: guardian-data + spec: + accessModes: [ "ReadWriteOnce" ] + resources: + requests: + storage: 1Gi