hub/setup-edenfs.shblame
View source
99f1a2e1#!/bin/bash
99f1a2e2# Sets up EdenFS on the hub server.
99f1a2e3# EdenFS runs on the HOST (not in Docker) because it needs FUSE access.
99f1a2e4#
99f1a2e5# Prerequisites:
99f1a2e6# - grove/edenfs:latest Docker image must be built
99f1a2e7# - Mononoke SLAPI must be running (grove.host:8443)
99f1a2e8# - TLS client certs at /data/grove/tls/
99f1a2e9#
99f1a2e10# What this does:
99f1a2e11# 1. Extracts edenfs + edenfs_privhelper binaries from Docker image
99f1a2e12# 2. Creates EdenFS config pointing at Mononoke SLAPI
99f1a2e13# 3. Creates a backing repo (metadata-only sl clone)
99f1a2e14# 4. Installs a systemd service for the edenfs daemon
99f1a2e15# 5. Creates an EdenFS mount at /mnt/sapling
99f1a2e16#
99f1a2e17# Usage: sudo bash setup-edenfs.sh
99f1a2e18
99f1a2e19set -euo pipefail
99f1a2e20
99f1a2e21EDEN_DIR="/data/eden"
99f1a2e22EDEN_CONFIG_DIR="/etc/eden"
99f1a2e23EDEN_BIN_DIR="/usr/local/bin"
99f1a2e24MOUNT_POINT="/mnt/sapling"
99f1a2e25BACKING_REPO="/data/eden/backing/sapling"
99f1a2e26TLS_DIR="/data/grove/tls"
99f1a2e27SLAPI_URL="https://localhost:8443"
99f1a2e28REPO_NAME="sapling"
99f1a2e29
99f1a2e30# ── Extract binaries from Docker image ────────────────────────────
99f1a2e31
99f1a2e32echo "Extracting EdenFS binaries from Docker image..."
99f1a2e33CONTAINER_ID=$(docker create grove/edenfs:latest)
99f1a2e34docker cp "$CONTAINER_ID:/usr/local/bin/edenfs" "$EDEN_BIN_DIR/edenfs" || true
99f1a2e35docker cp "$CONTAINER_ID:/usr/local/bin/edenfs_privhelper" "$EDEN_BIN_DIR/edenfs_privhelper" || true
99f1a2e36docker cp "$CONTAINER_ID:/usr/local/bin/edenfsctl" "$EDEN_BIN_DIR/edenfsctl" || true
99f1a2e37docker rm "$CONTAINER_ID"
99f1a2e38
99f1a2e39chmod +x "$EDEN_BIN_DIR/edenfs" "$EDEN_BIN_DIR/edenfs_privhelper" "$EDEN_BIN_DIR/edenfsctl" 2>/dev/null || true
99f1a2e40
99f1a2e41echo "Extracted binaries:"
99f1a2e42ls -la "$EDEN_BIN_DIR/edenfs" "$EDEN_BIN_DIR/edenfs_privhelper" "$EDEN_BIN_DIR/edenfsctl" 2>/dev/null || echo "(some binaries not found — build may have produced different names)"
99f1a2e43
99f1a2e44# ── Create directories ────────────────────────────────────────────
99f1a2e45
99f1a2e46mkdir -p "$EDEN_DIR"
99f1a2e47mkdir -p "$EDEN_CONFIG_DIR"
99f1a2e48mkdir -p "$MOUNT_POINT"
99f1a2e49mkdir -p "$BACKING_REPO"
99f1a2e50
99f1a2e51# ── Create EdenFS system config ───────────────────────────────────
99f1a2e52
99f1a2e53cat > "$EDEN_CONFIG_DIR/edenfs.toml" <<TOML
99f1a2e54[core]
99f1a2e55edenDirectory = "$EDEN_DIR"
99f1a2e56
99f1a2e57[clone]
99f1a2e58default-revision = "main"
99f1a2e59TOML
99f1a2e60
99f1a2e61# ── Create backing repo config ────────────────────────────────────
99f1a2e62# EdenFS needs a Sapling backing repo with edenapi config pointing
99f1a2e63# at Mononoke. This is like a metadata-only clone — EdenFS fetches
99f1a2e64# actual file contents lazily via SLAPI.
99f1a2e65
99f1a2e66mkdir -p "$BACKING_REPO/.sl"
99f1a2e67
99f1a2e68cat > "$BACKING_REPO/.sl/config" <<TOML
99f1a2e69[remotefilelog]
99f1a2e70reponame = $REPO_NAME
99f1a2e71
99f1a2e72[edenapi]
99f1a2e73url = $SLAPI_URL
99f1a2e74
99f1a2e75[auth]
99f1a2e76grove.cert = $TLS_DIR/client.crt
99f1a2e77grove.key = $TLS_DIR/client.key
99f1a2e78grove.cacerts = $TLS_DIR/ca.crt
99f1a2e79grove.prefix = *
99f1a2e80
99f1a2e81[remotenames]
99f1a2e82selectivepulldefault = main
99f1a2e83
99f1a2e84[push]
99f1a2e85edenapi = true
99f1a2e86TOML
99f1a2e87
99f1a2e88# ── Install systemd service ───────────────────────────────────────
99f1a2e89
99f1a2e90cat > /etc/systemd/system/edenfs.service <<SERVICE
99f1a2e91[Unit]
99f1a2e92Description=EdenFS Virtual Filesystem Daemon
99f1a2e93After=network.target docker.service
99f1a2e94Wants=network.target
99f1a2e95
99f1a2e96[Service]
99f1a2e97Type=simple
99f1a2e98ExecStart=$EDEN_BIN_DIR/edenfs \
99f1a2e99 --edenDir $EDEN_DIR \
99f1a2e100 --etcEdenDir $EDEN_CONFIG_DIR \
99f1a2e101 --configPath $EDEN_CONFIG_DIR/edenfs.toml \
99f1a2e102 --foreground
99f1a2e103Restart=on-failure
99f1a2e104RestartSec=5
99f1a2e105
99f1a2e106# FUSE requires these capabilities
99f1a2e107AmbientCapabilities=CAP_SYS_ADMIN
99f1a2e108NoNewPrivileges=false
99f1a2e109
99f1a2e110[Install]
99f1a2e111WantedBy=multi-user.target
99f1a2e112SERVICE
99f1a2e113
99f1a2e114systemctl daemon-reload
99f1a2e115
99f1a2e116echo ""
99f1a2e117echo "=== EdenFS Setup Complete ==="
99f1a2e118echo ""
99f1a2e119echo "Next steps:"
99f1a2e120echo " 1. Start the daemon: systemctl start edenfs"
99f1a2e121echo " 2. Check status: systemctl status edenfs"
99f1a2e122echo " 3. Mount the sapling repo:"
99f1a2e123echo " edenfsctl clone $BACKING_REPO $MOUNT_POINT"
99f1a2e124echo " 4. Verify the mount: ls $MOUNT_POINT"
99f1a2e125echo " 5. Enable on boot: systemctl enable edenfs"
99f1a2e126echo ""
99f1a2e127echo "The sapling repo will be lazily mounted at $MOUNT_POINT"
99f1a2e128echo "Files are fetched on-demand from Mononoke SLAPI ($SLAPI_URL)"