mirror of
https://github.com/getnora-io/nora.git
synced 2026-04-12 12:40:31 +00:00
feat: nora mirror CLI + systemd + install script
nora mirror: - Pre-fetch dependencies through NORA proxy cache - npm: --lockfile (v1/v2/v3) and --packages with --all-versions - pip: requirements.txt parser - cargo: Cargo.lock parser - maven: dependency:list output parser - Concurrent downloads (--concurrency, default 8) - Progress bar with indicatif - Health check before start dist/: - nora.service — systemd unit with security hardening - nora.env.example — environment configuration template - install.sh — automated install (binary + user + systemd + config) Tested: 103 tests pass, 0 clippy warnings, cargo audit clean. Smoke: mirrored 70 npm packages from real lockfile in 5.4s.
This commit is contained in:
111
dist/install.sh
vendored
Executable file
111
dist/install.sh
vendored
Executable file
@@ -0,0 +1,111 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# NORA Artifact Registry — install script
|
||||
# Usage: curl -fsSL https://getnora.io/install.sh | bash
|
||||
|
||||
VERSION="${NORA_VERSION:-latest}"
|
||||
ARCH=$(uname -m)
|
||||
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
|
||||
INSTALL_DIR="/usr/local/bin"
|
||||
CONFIG_DIR="/etc/nora"
|
||||
DATA_DIR="/var/lib/nora"
|
||||
LOG_DIR="/var/log/nora"
|
||||
|
||||
case "$ARCH" in
|
||||
x86_64|amd64) ARCH="x86_64" ;;
|
||||
aarch64|arm64) ARCH="aarch64" ;;
|
||||
*) echo "Unsupported architecture: $ARCH"; exit 1 ;;
|
||||
esac
|
||||
|
||||
echo "Installing NORA ($OS/$ARCH)..."
|
||||
|
||||
# Download binary
|
||||
if [ "$VERSION" = "latest" ]; then
|
||||
DOWNLOAD_URL="https://github.com/getnora-io/nora/releases/latest/download/nora-${OS}-${ARCH}"
|
||||
else
|
||||
DOWNLOAD_URL="https://github.com/getnora-io/nora/releases/download/${VERSION}/nora-${OS}-${ARCH}"
|
||||
fi
|
||||
|
||||
echo "Downloading from $DOWNLOAD_URL..."
|
||||
if command -v curl &>/dev/null; then
|
||||
curl -fsSL -o /tmp/nora "$DOWNLOAD_URL"
|
||||
elif command -v wget &>/dev/null; then
|
||||
wget -qO /tmp/nora "$DOWNLOAD_URL"
|
||||
else
|
||||
echo "Error: curl or wget required"; exit 1
|
||||
fi
|
||||
|
||||
chmod +x /tmp/nora
|
||||
sudo mv /tmp/nora "$INSTALL_DIR/nora"
|
||||
|
||||
# Create system user
|
||||
if ! id nora &>/dev/null; then
|
||||
sudo useradd --system --shell /usr/sbin/nologin --home-dir "$DATA_DIR" --create-home nora
|
||||
echo "Created system user: nora"
|
||||
fi
|
||||
|
||||
# Create directories
|
||||
sudo mkdir -p "$CONFIG_DIR" "$DATA_DIR" "$LOG_DIR"
|
||||
sudo chown nora:nora "$DATA_DIR" "$LOG_DIR"
|
||||
|
||||
# Install default config if not exists
|
||||
if [ ! -f "$CONFIG_DIR/nora.env" ]; then
|
||||
cat > /tmp/nora.env << 'ENVEOF'
|
||||
NORA_HOST=0.0.0.0
|
||||
NORA_PORT=4000
|
||||
NORA_STORAGE_PATH=/var/lib/nora
|
||||
ENVEOF
|
||||
sudo mv /tmp/nora.env "$CONFIG_DIR/nora.env"
|
||||
sudo chmod 600 "$CONFIG_DIR/nora.env"
|
||||
sudo chown nora:nora "$CONFIG_DIR/nora.env"
|
||||
echo "Created default config: $CONFIG_DIR/nora.env"
|
||||
fi
|
||||
|
||||
# Install systemd service
|
||||
if [ -d /etc/systemd/system ]; then
|
||||
cat > /tmp/nora.service << 'SVCEOF'
|
||||
[Unit]
|
||||
Description=NORA Artifact Registry
|
||||
Documentation=https://getnora.dev
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=nora
|
||||
Group=nora
|
||||
ExecStart=/usr/local/bin/nora serve
|
||||
WorkingDirectory=/etc/nora
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
LimitNOFILE=65535
|
||||
NoNewPrivileges=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
ReadWritePaths=/var/lib/nora /var/log/nora
|
||||
PrivateTmp=true
|
||||
EnvironmentFile=-/etc/nora/nora.env
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
SVCEOF
|
||||
sudo mv /tmp/nora.service /etc/systemd/system/nora.service
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable nora
|
||||
echo "Installed systemd service: nora"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "NORA installed successfully!"
|
||||
echo ""
|
||||
echo " Binary: $INSTALL_DIR/nora"
|
||||
echo " Config: $CONFIG_DIR/nora.env"
|
||||
echo " Data: $DATA_DIR"
|
||||
echo " Version: $(nora --version 2>/dev/null || echo 'unknown')"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo " 1. Edit $CONFIG_DIR/nora.env"
|
||||
echo " 2. sudo systemctl start nora"
|
||||
echo " 3. curl http://localhost:4000/health"
|
||||
echo ""
|
||||
31
dist/nora.env.example
vendored
Normal file
31
dist/nora.env.example
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
# NORA configuration — environment variables
|
||||
# Copy to /etc/nora/nora.env and adjust
|
||||
|
||||
# Server
|
||||
NORA_HOST=0.0.0.0
|
||||
NORA_PORT=4000
|
||||
# NORA_PUBLIC_URL=https://registry.example.com
|
||||
|
||||
# Storage
|
||||
NORA_STORAGE_PATH=/var/lib/nora
|
||||
# NORA_STORAGE_MODE=s3
|
||||
# NORA_STORAGE_S3_URL=http://minio:9000
|
||||
# NORA_STORAGE_BUCKET=registry
|
||||
|
||||
# Auth (optional)
|
||||
# NORA_AUTH_ENABLED=true
|
||||
# NORA_AUTH_HTPASSWD_FILE=/etc/nora/users.htpasswd
|
||||
|
||||
# Rate limiting
|
||||
# NORA_RATE_LIMIT_ENABLED=true
|
||||
|
||||
# npm proxy
|
||||
# NORA_NPM_PROXY=https://registry.npmjs.org
|
||||
# NORA_NPM_METADATA_TTL=300
|
||||
# NORA_NPM_PROXY_AUTH=user:pass
|
||||
|
||||
# PyPI proxy
|
||||
# NORA_PYPI_PROXY=https://pypi.org/simple/
|
||||
|
||||
# Docker upstreams
|
||||
# NORA_DOCKER_UPSTREAMS=https://registry-1.docker.io
|
||||
28
dist/nora.service
vendored
Normal file
28
dist/nora.service
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
[Unit]
|
||||
Description=NORA Artifact Registry
|
||||
Documentation=https://getnora.dev
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=nora
|
||||
Group=nora
|
||||
ExecStart=/usr/local/bin/nora serve
|
||||
WorkingDirectory=/etc/nora
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
LimitNOFILE=65535
|
||||
|
||||
# Security hardening
|
||||
NoNewPrivileges=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
ReadWritePaths=/var/lib/nora /var/log/nora
|
||||
PrivateTmp=true
|
||||
|
||||
# Environment
|
||||
EnvironmentFile=-/etc/nora/nora.env
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Reference in New Issue
Block a user