chore: add current provisioning state before migration

This commit is contained in:
Jesús Pérez 2025-09-22 23:11:41 +01:00
parent a9703b4748
commit 50745b0f22
660 changed files with 88126 additions and 0 deletions

View file

@ -0,0 +1,60 @@
#!/bin/bash
# Info: Script to create first Coder admin user
# Author: Provisioning System
set -e
CODER_USER=${CODER_USER:-admin}
CODER_EMAIL=${CODER_EMAIL:-admin@{{ coder.access_url | replace('http://', '') | replace('https://', '') }}}
CODER_PASSWORD=${CODER_PASSWORD:-$(openssl rand -base64 12)}
echo "Creating first Coder admin user..."
# Wait for Coder server to be ready
timeout=60
while [ $timeout -gt 0 ]; do
if curl -f -s "{{ coder.access_url }}/api/v2/buildinfo" >/dev/null 2>&1; then
echo "Coder server is ready"
break
fi
echo "Waiting for Coder server to start... ($timeout seconds remaining)"
sleep 2
timeout=$((timeout - 2))
done
if [ $timeout -le 0 ]; then
echo "Timeout waiting for Coder server to start"
exit 1
fi
# Create first user via API
RESPONSE=$(curl -s -X POST "{{ coder.access_url }}/api/v2/users/first" \
-H "Content-Type: application/json" \
-d "{
\"username\": \"$CODER_USER\",
\"email\": \"$CODER_EMAIL\",
\"password\": \"$CODER_PASSWORD\",
\"trial\": false
}")
if echo "$RESPONSE" | grep -q '"username"'; then
echo "✅ First admin user created successfully!"
echo "Username: $CODER_USER"
echo "Email: $CODER_EMAIL"
echo "Password: $CODER_PASSWORD"
echo ""
echo "Login at: {{ coder.access_url }}"
# Save credentials to secure file
echo "USERNAME=$CODER_USER" > {{ coder.config_path }}/admin-credentials
echo "EMAIL=$CODER_EMAIL" >> {{ coder.config_path }}/admin-credentials
echo "PASSWORD=$CODER_PASSWORD" >> {{ coder.config_path }}/admin-credentials
chmod 600 {{ coder.config_path }}/admin-credentials
chown {{ coder.run_user.name }}:{{ coder.run_user.group }} {{ coder.config_path }}/admin-credentials
echo "Credentials saved to: {{ coder.config_path }}/admin-credentials"
else
echo "❌ Failed to create first user"
echo "Response: $RESPONSE"
exit 1
fi

View file

@ -0,0 +1,38 @@
[Unit]
Description=Coder Development Environment Platform
Documentation=https://coder.com/docs
After=network-online.target
Wants=network-online.target
{% if coder.database.typ == "postgresql" and coder.database.host == "127.0.0.1" %}
After=postgresql.service
Wants=postgresql.service
{% endif %}
[Service]
Type=simple
User={{ coder.run_user.name }}
Group={{ coder.run_user.group }}
EnvironmentFile={{ coder.config_path }}/coder.env
WorkingDirectory={{ coder.work_path }}
ExecStart={{ coder.run_path }} server
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
RestartSec=10
# Security settings
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths={{ coder.work_path }} {{ coder.config_path }}
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
# Resource limits
LimitNOFILE=65536
{% if coder.oauth.enabled %}
# Additional memory for OAuth operations
MemoryMax=2G
{% endif %}
[Install]
WantedBy=multi-user.target

View file

@ -0,0 +1,67 @@
# Coder Environment Configuration
# Generated by provisioning system
CODER_VERSION={{ coder.version }}
CODER_RUN_USER={{ coder.run_user.name }}
CODER_RUN_GROUP={{ coder.run_user.group }}
CODER_RUN_USER_HOME={{ coder.run_user.home }}
CODER_WORK_PATH={{ coder.work_path }}
CODER_CONFIG_PATH={{ coder.config_path }}
CODER_RUN_PATH={{ coder.run_path }}
# Server Configuration
CODER_ACCESS_URL={{ coder.access_url }}
{% if coder.wildcard_access_url is defined %}
CODER_WILDCARD_ACCESS_URL={{ coder.wildcard_access_url }}
{% endif %}
CODER_HTTP_ADDRESS={{ coder.http_address }}
CODER_LOG_LEVEL={{ coder.log_level }}
CODER_TELEMETRY={{ coder.telemetry_enabled | lower }}
CODER_UPDATE_CHECK={{ coder.update_check_enabled | lower }}
CODER_REDIRECT_TO_ACCESS_URL={{ coder.redirect_to_access_url | lower }}
CODER_SECURE_AUTH_COOKIE={{ coder.secure_auth_cookie | lower }}
CODER_MAX_SESSION_TOKEN_LIFETIME={{ coder.max_session_token_lifetime }}
CODER_DISABLE_PASSWORD_AUTH={{ coder.disable_password_auth | lower }}
{% if coder.proxy_trusted_headers %}
CODER_PROXY_TRUSTED_HEADERS="{{ coder.proxy_trusted_headers | join(',') }}"
{% endif %}
{% if coder.proxy_trusted_origins %}
CODER_PROXY_TRUSTED_ORIGINS="{{ coder.proxy_trusted_origins | join(',') }}"
{% endif %}
# Database Configuration
{% if coder.database.typ == "sqlite" %}
CODER_PG_CONNECTION_URL=sqlite3://{{ coder.database.path }}
{% else %}
CODER_PG_CONNECTION_URL=postgresql://{{ coder.database.username }}:{{ coder.database.password }}@{{ coder.database.host }}:{{ coder.database.port }}/{{ coder.database.database }}?sslmode={{ coder.database.ssl_mode }}
{% endif %}
# TLS Configuration
{% if coder.tls.enabled %}
CODER_TLS_ENABLE=true
CODER_TLS_ADDRESS={{ coder.tls.address }}
CODER_TLS_CERT_FILE={{ coder.tls.cert_file }}
CODER_TLS_KEY_FILE={{ coder.tls.key_file }}
{% else %}
CODER_TLS_ENABLE=false
{% endif %}
# OAuth Configuration
{% if coder.oauth.enabled %}
{% if coder.oauth.provider == "github" %}
CODER_OAUTH2_GITHUB_CLIENT_ID={{ coder.oauth.client_id }}
CODER_OAUTH2_GITHUB_CLIENT_SECRET={{ coder.oauth.client_secret }}
CODER_OAUTH2_GITHUB_ALLOW_SIGNUPS=true
{% elif coder.oauth.provider == "oidc" %}
CODER_OIDC_ISSUER_URL={{ coder.oauth.issuer_url }}
CODER_OIDC_CLIENT_ID={{ coder.oauth.client_id }}
CODER_OIDC_CLIENT_SECRET={{ coder.oauth.client_secret }}
CODER_OIDC_SCOPES="{{ coder.oauth.scopes | join(',') }}"
CODER_OIDC_ALLOW_SIGNUPS=true
{% elif coder.oauth.provider == "google" %}
CODER_OAUTH2_GOOGLE_CLIENT_ID={{ coder.oauth.client_id }}
CODER_OAUTH2_GOOGLE_CLIENT_SECRET={{ coder.oauth.client_secret }}
CODER_OAUTH2_GOOGLE_ALLOW_SIGNUPS=true
{% endif %}
{% endif %}

View file

@ -0,0 +1,197 @@
#!/bin/bash
# Info: Script to install Coder
# Author: Provisioning System
# Release: 1.0
# Date: 2025-07-24
USAGE="install-coder.sh"
[ "$1" == "-h" ] && echo "$USAGE" && exit 1
[ -r "env-coder" ] && . ./env-coder
CODER_VERSION=${CODER_VERSION:-2.23.4}
# Determine architecture
ARCH="$(uname -m)"
case $ARCH in
x86_64) ARCH="amd64" ;;
aarch64) ARCH="arm64" ;;
armv7*) ARCH="armv7" ;;
*) echo "Unsupported architecture: $ARCH" && exit 1 ;;
esac
# Determine OS
OS="$(uname -s | tr '[:upper:]' '[:lower:]')"
case $OS in
linux) OS="linux" ;;
darwin) OS="darwin" ;;
*) echo "Unsupported OS: $OS" && exit 1 ;;
esac
CODER_URL=https://github.com/coder/coder/releases/download
CODER_BINARY=v${CODER_VERSION}/coder_${CODER_VERSION}_${OS}_${ARCH}.tar.gz
CODER_ARCHIVE=coder_${CODER_VERSION}_${OS}_${ARCH}.tar.gz
CODER_RUN_PATH=${CODER_RUN_PATH:-/usr/local/bin/coder}
CODER_SYSTEMCTL_MODE=${CODER_SYSTEMCTL_MODE:-enabled}
CODER_CONFIG_PATH=${CODER_CONFIG_PATH:-/etc/coder}
CODER_WORK_PATH=${CODER_WORK_PATH:-/var/lib/coder}
CODER_RUN_USER=${CODER_RUN_USER:-coder}
CODER_RUN_GROUP=${CODER_RUN_GROUP:-coder}
CODER_RUN_USER_HOME=${CODER_RUN_USER_HOME:-/home/coder}
CODER_ACCESS_URL=${CODER_ACCESS_URL:-http://localhost:7080}
CODER_HTTP_ADDRESS=${CODER_HTTP_ADDRESS:-0.0.0.0:7080}
echo "Installing Coder ${CODER_VERSION}..."
# Install dependencies
echo "Installing dependencies..."
if command -v apt-get >/dev/null 2>&1; then
apt-get update
apt-get install -y curl ca-certificates git
elif command -v yum >/dev/null 2>&1; then
yum update -y
yum install -y curl ca-certificates git
elif command -v dnf >/dev/null 2>&1; then
dnf update -y
dnf install -y curl ca-certificates git
else
echo "Package manager not found. Please install curl, ca-certificates, and git manually."
exit 1
fi
# Create user and group
if ! id "$CODER_RUN_USER" &>/dev/null; then
groupadd -r "$CODER_RUN_GROUP"
useradd -r -g "$CODER_RUN_GROUP" -d "$CODER_RUN_USER_HOME" -s /bin/bash -c "Coder service user" "$CODER_RUN_USER"
fi
# Create directories
mkdir -p "$CODER_CONFIG_PATH"
mkdir -p "$CODER_WORK_PATH"
mkdir -p "$CODER_RUN_USER_HOME"
# Download and install Coder
cd /tmp
echo "Downloading Coder from ${CODER_URL}/${CODER_BINARY}..."
curl -L -o "$CODER_ARCHIVE" "${CODER_URL}/${CODER_BINARY}"
if [ ! -f "$CODER_ARCHIVE" ]; then
echo "Failed to download Coder archive"
exit 1
fi
# Extract and install binary
echo "Extracting Coder..."
tar -xzf "$CODER_ARCHIVE"
if [ ! -f "coder" ]; then
echo "Failed to extract Coder binary"
exit 1
fi
# Install binary
chmod +x coder
mv coder "$(dirname "$CODER_RUN_PATH")/"
# Create environment file
cat > "$CODER_CONFIG_PATH/coder.env" << EOF
CODER_ACCESS_URL=$CODER_ACCESS_URL
CODER_HTTP_ADDRESS=$CODER_HTTP_ADDRESS
CODER_CONFIG_DIR=$CODER_WORK_PATH
EOF
# Load additional environment variables from template if available
if [ -f "env-coder" ]; then
cat env-coder >> "$CODER_CONFIG_PATH/coder.env"
fi
# Set ownership
chown -R "$CODER_RUN_USER:$CODER_RUN_GROUP" "$CODER_WORK_PATH"
chown -R "$CODER_RUN_USER:$CODER_RUN_GROUP" "$CODER_RUN_USER_HOME"
chown -R "$CODER_RUN_USER:$CODER_RUN_GROUP" "$CODER_CONFIG_PATH"
# Create systemd service file
cat > /etc/systemd/system/coder.service << EOF
[Unit]
Description=Coder Development Environment Platform
Documentation=https://coder.com/docs
After=network-online.target
Wants=network-online.target
$(if [ "${CODER_DATABASE_TYPE:-postgresql}" = "postgresql" ] && [ -z "$CODER_PG_CONNECTION_URL" ]; then echo "After=postgresql.service"; echo "Wants=postgresql.service"; fi)
[Service]
Type=simple
User=$CODER_RUN_USER
Group=$CODER_RUN_GROUP
EnvironmentFile=$CODER_CONFIG_PATH/coder.env
WorkingDirectory=$CODER_WORK_PATH
ExecStart=$CODER_RUN_PATH server
ExecReload=/bin/kill -HUP \$MAINPID
Restart=always
RestartSec=10
# Security settings
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=$CODER_WORK_PATH $CODER_CONFIG_PATH
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
# Resource limits
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
# Initialize Coder database and first user if needed
echo "Initializing Coder server..."
sudo -u "$CODER_RUN_USER" bash -c "
export CODER_CONFIG_DIR='$CODER_WORK_PATH'
export CODER_ACCESS_URL='$CODER_ACCESS_URL'
export CODER_HTTP_ADDRESS='$CODER_HTTP_ADDRESS'
cd '$CODER_WORK_PATH'
if [ ! -f '$CODER_WORK_PATH/.initialized' ]; then
timeout 30 '$CODER_RUN_PATH' server --init-only 2>/dev/null || true
touch '$CODER_WORK_PATH/.initialized'
fi
"
# Enable and start service
systemctl daemon-reload
systemctl "$CODER_SYSTEMCTL_MODE" coder.service
if [ "$CODER_SYSTEMCTL_MODE" = "enabled" ]; then
systemctl start coder.service
# Wait a moment for service to start
sleep 5
fi
# Cleanup
cd /
rm -rf /tmp/"$CODER_ARCHIVE" /tmp/coder
echo "Coder installation completed!"
echo "Service: coder.service"
echo "Coder Server available at: $CODER_ACCESS_URL"
echo "Configuration: $CODER_CONFIG_PATH/coder.env"
echo "Data directory: $CODER_WORK_PATH"
# Display service status
if systemctl is-active --quiet coder.service; then
echo "✅ Coder service is running"
echo ""
echo "First time login:"
echo "1. Open $CODER_ACCESS_URL in a browser"
echo "2. Create your first admin user account"
echo "3. Start creating workspaces and templates"
else
echo "⚠️ Coder service status:"
systemctl status coder.service --no-pager -l
fi

101
taskservs/coder/default/prepare Executable file
View file

@ -0,0 +1,101 @@
#!/bin/bash
# Info: Coder preparation script
# Author: Provisioning System
# Release: 1.0
echo "Preparing Coder installation..."
# Load environment variables
[ -r "env-coder" ] && . ./env-coder
# Check if required tools are available
command -v curl >/dev/null 2>&1 || { echo "curl is required but not installed." >&2; exit 1; }
command -v tar >/dev/null 2>&1 || { echo "tar is required but not installed." >&2; exit 1; }
command -v systemctl >/dev/null 2>&1 || { echo "systemctl is required but not installed." >&2; exit 1; }
# Check for Git (recommended for Coder workspaces)
if ! command -v git >/dev/null 2>&1; then
echo "Warning: Git not found. Git is recommended for Coder workspaces."
fi
# Validate configuration
if [ -z "$CODER_VERSION" ]; then
echo "CODER_VERSION must be set" >&2
exit 1
fi
if [ -z "$CODER_ACCESS_URL" ]; then
echo "CODER_ACCESS_URL must be set" >&2
exit 1
fi
# Validate access URL format
if ! echo "$CODER_ACCESS_URL" | grep -qE '^https?://'; then
echo "CODER_ACCESS_URL must be a valid HTTP/HTTPS URL" >&2
exit 1
fi
# Check if access URL is not localhost for production
if echo "$CODER_ACCESS_URL" | grep -q "localhost\|127\.0\.0\.1"; then
echo "Warning: Using localhost in CODER_ACCESS_URL. This should only be used for development."
fi
# Check port availability
CODER_PORT=$(echo "$CODER_HTTP_ADDRESS" | sed 's/.*://')
if command -v netstat >/dev/null 2>&1; then
if netstat -tuln | grep -q ":${CODER_PORT} "; then
echo "Warning: Port ${CODER_PORT} appears to be in use"
fi
elif command -v ss >/dev/null 2>&1; then
if ss -tuln | grep -q ":${CODER_PORT} "; then
echo "Warning: Port ${CODER_PORT} appears to be in use"
fi
fi
# Validate database configuration
if [ -n "$CODER_PG_CONNECTION_URL" ]; then
echo "Using external PostgreSQL database"
# Basic validation of PostgreSQL URL format
if ! echo "$CODER_PG_CONNECTION_URL" | grep -qE '^(postgresql|postgres)://'; then
echo "Invalid PostgreSQL connection URL format" >&2
exit 1
fi
else
echo "Using built-in PostgreSQL database"
fi
# Check TLS configuration if enabled
if [ "${CODER_TLS_ENABLE:-false}" = "true" ]; then
echo "TLS is enabled"
if [ -z "$CODER_TLS_CERT_FILE" ] || [ -z "$CODER_TLS_KEY_FILE" ]; then
echo "TLS enabled but certificate files not specified" >&2
exit 1
fi
if [ ! -f "$CODER_TLS_CERT_FILE" ]; then
echo "Warning: TLS certificate file not found: $CODER_TLS_CERT_FILE"
fi
if [ ! -f "$CODER_TLS_KEY_FILE" ]; then
echo "Warning: TLS key file not found: $CODER_TLS_KEY_FILE"
fi
fi
# Check OAuth configuration if enabled
if [ -n "$CODER_OAUTH2_GITHUB_CLIENT_ID" ] || [ -n "$CODER_OIDC_CLIENT_ID" ] || [ -n "$CODER_OAUTH2_GOOGLE_CLIENT_ID" ]; then
echo "OAuth authentication is configured"
fi
# Check system resources
echo "Checking system resources..."
FREE_MEMORY=$(free -m 2>/dev/null | awk '/^Mem:/{print $7}' || echo "unknown")
if [ "$FREE_MEMORY" != "unknown" ] && [ "$FREE_MEMORY" -lt 2048 ]; then
echo "Warning: Less than 2GB of free memory available. Coder recommends at least 4GB for optimal performance."
fi
CPU_CORES=$(nproc 2>/dev/null || echo "unknown")
if [ "$CPU_CORES" != "unknown" ] && [ "$CPU_CORES" -lt 2 ]; then
echo "Warning: Less than 2 CPU cores available. Coder recommends at least 2 cores for optimal performance."
fi
echo "Preparation completed successfully."

View file

@ -0,0 +1,2 @@
info = "coder"
release = "1.0"

24
taskservs/coder/info.md Normal file
View file

@ -0,0 +1,24 @@
Coder taskserv has been successfully added to the provisioning system! The service includes:
Created files:
- taskservs/coder/kcl/coder.k - KCL schema definitions for Coder configuration
- taskservs/coder/default/provisioning.toml - Service metadata
- taskservs/coder/default/env-coder.j2 - Environment variable template
- taskservs/coder/default/coder.service.j2 - Systemd service template
- taskservs/coder/default/coder-first-user.sh.j2 - First admin user creation script
- taskservs/coder/default/install-coder.sh - Installation script
- taskservs/coder/default/prepare - Preparation script
Features:
- Configurable Coder development environment platform (default port 7080)
- Database support: SQLite (default) and PostgreSQL
- OAuth authentication: GitHub, OIDC, Google
- TLS/SSL support with certificate configuration
- Wildcard domain support for workspace access
- Systemd service integration with security hardening
- User and permission management
- First admin user creation helper
- Resource requirements validation
- Automatic service discovery
The service can now be deployed using: ./core/nulib/provisioning taskserv create coder