app
service-kicad
Public Made by Adomby adom
Shared headless KiCad 10: DRC, ERC, SVG/Gerber/STEP export, Altium library conversion, symbol/footprint/3D-model lookup. Every Adom tool shells to this CLI instead of calling the HTTP API directly.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
#!/usr/bin/env bash
# service-kicad deploy — V9 FALLBACK channel.
#
# Run ONCE on a fresh default-light container. Most users want
# `deploy.sh` (the default v10 channel); this script exists only for
# callers that need to pin to KiCad 9 (file-format compat, etc.).
# The v9 PPA overwrites the v10 `kicad` package, so a host can be on
# exactly one channel at a time.
set -euo pipefail
REPO_DIR="$HOME/service-kicad"
echo "==> service-kicad deploy starting (v9 fallback channel)"
echo "==> repo dir: $REPO_DIR"
# 1. System deps — KiCad 9 + libraries. No aci-* deps; this container
# is tool-agnostic and consumed by symbol-creator, footprint-creator,
# library-creator, adom-chipfit, adom-tsci, adom-circuit, etc.
echo "==> installing apt packages (KiCad 9 + libraries + cron)"
sudo apt-get update
sudo apt-get install -y \
software-properties-common curl build-essential pkg-config git jq cron
sudo add-apt-repository -y ppa:kicad/kicad-9.0-releases
sudo apt-get update
sudo apt-get install -y kicad kicad-symbols kicad-footprints kicad-packages3d
# The Ubuntu apt-package mirrors of KiCad libraries lag upstream by ~years
# (24.04 ships the ~2020 snapshot — e.g., SOIC-8W_5.3x5.3mm_P1.27mm,
# committed upstream 2020-09-29, was missing from the apt copy as of
# 2026-04-26 dogfood). Overlay the upstream github repos so users get
# the latest parts. service-kicad's KICAD_*_DIR env vars point at these
# clones; a weekly `git pull` cron keeps them fresh.
LIB_BASE=/opt
for repo in kicad-footprints kicad-symbols kicad-packages3D; do
dir="$LIB_BASE/${repo,,}-upstream" # lowercase
if [ ! -d "$dir/.git" ]; then
echo "==> cloning upstream $repo → $dir"
sudo git clone --depth 1 "https://github.com/KiCad/$repo.git" "$dir"
else
echo "==> upstream $repo already at $dir; refreshing"
sudo git -C "$dir" pull --quiet --ff-only || true
fi
done
# Persist KICAD_*_DIR for service-kicad-api (read at startup).
sudo tee /etc/default/service-kicad >/dev/null <<'EOF'
KICAD_FOOTPRINTS_DIR=/opt/kicad-footprints-upstream
KICAD_SYMBOLS_DIR=/opt/kicad-symbols-upstream
KICAD_PACKAGES3D_DIR=/opt/kicad-packages3d-upstream
EOF
# Weekly refresh — Mondays @ 04:00 UTC.
sudo tee /etc/cron.d/kicad-lib-pull >/dev/null <<'EOF'
0 4 * * 1 root for d in /opt/kicad-footprints-upstream /opt/kicad-symbols-upstream /opt/kicad-packages3d-upstream; do git -C "$d" pull --quiet --ff-only 2>&1 | logger -t kicad-lib-pull; done
EOF
sudo chmod 0644 /etc/cron.d/kicad-lib-pull
# default-light has sshd as PID 1 (no systemd) — cron has to be
# launched manually and kept alive by the user.
if ! pgrep -x cron >/dev/null; then
echo "==> starting cron daemon"
sudo /usr/sbin/cron
fi
# 2. Rust toolchain
echo "==> installing rustup"
if ! command -v rustup &>/dev/null; then
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable
source "$HOME/.cargo/env"
fi
# 3. Clone + build the service API
if [ ! -d "$REPO_DIR" ]; then
echo "==> cloning service-kicad"
git clone https://github.com/adom-inc/service-kicad.git "$REPO_DIR"
fi
cd "$REPO_DIR"
git pull --rebase origin main
echo "==> building service-kicad-api (http server) and service-kicad (cli)"
cargo build --release --bin service-kicad-api --bin service-kicad
sudo install "$REPO_DIR/target/release/service-kicad-api" /usr/local/bin/service-kicad-api
sudo install "$REPO_DIR/target/release/service-kicad" /usr/local/bin/service-kicad
# 4. Install watchdog cron
echo "==> installing watchdog cron"
mkdir -p "$HOME/.cache"
CRON_LINE="*/2 * * * * $REPO_DIR/watchdog.sh >> $HOME/.cache/service-kicad-watchdog.log 2>&1"
# crontab -l exits 1 when there's no existing crontab; the subshell
# must not abort under `set -e`, so disable pipefail around this block.
set +e
( crontab -l 2>/dev/null | grep -v "service-kicad/watchdog.sh" ; echo "$CRON_LINE" ) | crontab -
cron_exit=$?
set -e
[ $cron_exit -ne 0 ] && { echo "crontab install failed (exit $cron_exit)"; exit $cron_exit; }
# 5. First launch + health check
echo "==> starting service-kicad-api"
sudo touch /var/log/service-kicad.log && sudo chown "$USER" /var/log/service-kicad.log
pkill -x service-kicad-api || true
# Source /etc/default/service-kicad for KICAD_*_DIR env vars before launch.
set -a; [ -f /etc/default/service-kicad ] && . /etc/default/service-kicad; set +a
nohup /usr/local/bin/service-kicad-api >> /var/log/service-kicad.log 2>&1 &
sleep 3
if curl -sf http://127.0.0.1:8780/health | jq -e '.ok' > /dev/null; then
echo "==> service-kicad is healthy ✓"
curl -sf http://127.0.0.1:8780/health | jq
else
echo "==> service-kicad health check FAILED" >&2
exit 1
fi
echo "==> deploy complete"