chore: add current provisioning state before migration
This commit is contained in:
parent
a9703b4748
commit
50745b0f22
660 changed files with 88126 additions and 0 deletions
1
taskservs/cilium/default/env-cilium.j2
Normal file
1
taskservs/cilium/default/env-cilium.j2
Normal file
|
|
@ -0,0 +1 @@
|
|||
CILIUM_CLI_VERSION="{{taskserv.version}}"
|
||||
56
taskservs/cilium/default/install-cilium.sh
Executable file
56
taskservs/cilium/default/install-cilium.sh
Executable file
|
|
@ -0,0 +1,56 @@
|
|||
#!/bin/bash
|
||||
# Info: Script to install/create/delete/update cilium from file settings
|
||||
# Author: JesusPerezLorenzo
|
||||
# Release: 1.0
|
||||
# Date: 12-11-2024
|
||||
|
||||
USAGE="install.sh install | update | remvoe"
|
||||
[ "$1" == "-h" ] && echo "$USAGE" && exit 1
|
||||
|
||||
OS=$(uname | tr '[:upper:]' '[:lower:]')
|
||||
ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')"
|
||||
|
||||
CILIUM_CLI_VERSION=${CILIUM_CLI_VERSION:-$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/master/stable.txt)}
|
||||
CILIUM_URL="https://github.com/cilium/cilium-cli/releases/download"
|
||||
|
||||
_cilium_init() {
|
||||
local curr_version
|
||||
curr_version=$(cilium version 2>/dev/null | grep cli | awk '{ print $2 }')
|
||||
if [ "$curr_version" != "${CILIUM_CLI_VERSION}" ] ; then
|
||||
curl -sL --remote-name-all "$CILIUM_URL/${CILIUM_CLI_VERSION}/cilium-${OS}-${ARCH}.tar.gz"{,.sha256sum}
|
||||
# sha256sum --check cilium-${OS}-${ARCH}.tar.gz.sha256sum
|
||||
sudo tar xzfC "cilium-${OS}-${ARCH}.tar.gz" /usr/local/bin
|
||||
rm cilium-"${OS}"-"${ARCH}".tar.gz{,.sha256sum}
|
||||
fi
|
||||
}
|
||||
_cilium_delete() {
|
||||
sudo cilium uninstall
|
||||
}
|
||||
_cilium_install() {
|
||||
[ "$K8S_MODE" == "image" ] && return 0
|
||||
local status
|
||||
status=$(cilium status 2>/dev/null | grep Operator | awk '{print $4}')
|
||||
[[ "$status" == *OK* ]] && return 0
|
||||
#if ! sudo /usr/local/bin/cilium install --cluster-name $CLUSTER_NAME ; then
|
||||
if ! /usr/local/bin/cilium install &>/dev/null; then
|
||||
echo "Error installing cilium $?"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
_cilium_update() {
|
||||
sudo cilium update
|
||||
}
|
||||
|
||||
if [ "$TSKSRVC" == "remove" ] ; then
|
||||
_cilium_delete
|
||||
exit
|
||||
fi
|
||||
[ "$TSKSRVC" == "update" ] && _cilium_update && exit 0
|
||||
if ! _cilium_init ; then
|
||||
echo "error cilium init"
|
||||
exit 1
|
||||
fi
|
||||
if ! _cilium_install ; then
|
||||
echo "error cilium install"
|
||||
exit 1
|
||||
fi
|
||||
2
taskservs/cilium/default/provisioning.toml
Normal file
2
taskservs/cilium/default/provisioning.toml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
info = "clium"
|
||||
release = "1.0"
|
||||
60
taskservs/coder/default/coder-first-user.sh.j2
Normal file
60
taskservs/coder/default/coder-first-user.sh.j2
Normal 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
|
||||
38
taskservs/coder/default/coder.service.j2
Normal file
38
taskservs/coder/default/coder.service.j2
Normal 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
|
||||
67
taskservs/coder/default/env-coder.j2
Normal file
67
taskservs/coder/default/env-coder.j2
Normal 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 %}
|
||||
197
taskservs/coder/default/install-coder.sh
Executable file
197
taskservs/coder/default/install-coder.sh
Executable 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
101
taskservs/coder/default/prepare
Executable 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."
|
||||
2
taskservs/coder/default/provisioning.toml
Normal file
2
taskservs/coder/default/provisioning.toml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
info = "coder"
|
||||
release = "1.0"
|
||||
24
taskservs/coder/info.md
Normal file
24
taskservs/coder/info.md
Normal 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
|
||||
254
taskservs/containerd/default/_config.toml
Normal file
254
taskservs/containerd/default/_config.toml
Normal file
|
|
@ -0,0 +1,254 @@
|
|||
# Use config version 2 to enable new configuration fields.
|
||||
# Config file is parsed as version 1 by default.
|
||||
# Version 2 uses long plugin names, i.e. "io.containerd.grpc.v1.cri" vs "cri".
|
||||
version = 2
|
||||
|
||||
# The 'plugins."io.containerd.grpc.v1.cri"' table contains all of the server options.
|
||||
[plugins."io.containerd.grpc.v1.cri"]
|
||||
|
||||
# disable_tcp_service disables serving CRI on the TCP server.
|
||||
# Note that a TCP server is enabled for containerd if TCPAddress is set in section [grpc].
|
||||
disable_tcp_service = true
|
||||
|
||||
# stream_server_address is the ip address streaming server is listening on.
|
||||
stream_server_address = "127.0.0.1"
|
||||
|
||||
# stream_server_port is the port streaming server is listening on.
|
||||
stream_server_port = "0"
|
||||
|
||||
# stream_idle_timeout is the maximum time a streaming connection can be
|
||||
# idle before the connection is automatically closed.
|
||||
# The string is in the golang duration format, see:
|
||||
# https://golang.org/pkg/time/#ParseDuration
|
||||
stream_idle_timeout = "4h"
|
||||
|
||||
# enable_selinux indicates to enable the selinux support.
|
||||
enable_selinux = false
|
||||
|
||||
# selinux_category_range allows the upper bound on the category range to be set.
|
||||
# if not specified or set to 0, defaults to 1024 from the selinux package.
|
||||
selinux_category_range = 1024
|
||||
|
||||
# sandbox_image is the image used by sandbox container.
|
||||
sandbox_image = "k8s.gcr.io/pause:3.2"
|
||||
|
||||
# stats_collect_period is the period (in seconds) of snapshots stats collection.
|
||||
stats_collect_period = 10
|
||||
|
||||
# enable_tls_streaming enables the TLS streaming support.
|
||||
# It generates a self-sign certificate unless the following x509_key_pair_streaming are both set.
|
||||
enable_tls_streaming = false
|
||||
|
||||
# tolerate_missing_hugetlb_controller if set to false will error out on create/update
|
||||
# container requests with huge page limits if the cgroup controller for hugepages is not present.
|
||||
# This helps with supporting Kubernetes <=1.18 out of the box. (default is `true`)
|
||||
tolerate_missing_hugetlb_controller = true
|
||||
|
||||
# ignore_image_defined_volumes ignores volumes defined by the image. Useful for better resource
|
||||
# isolation, security and early detection of issues in the mount configuration when using
|
||||
# ReadOnlyRootFilesystem since containers won't silently mount a temporary volume.
|
||||
ignore_image_defined_volumes = false
|
||||
|
||||
# 'plugins."io.containerd.grpc.v1.cri".x509_key_pair_streaming' contains a x509 valid key pair to stream with tls.
|
||||
[plugins."io.containerd.grpc.v1.cri".x509_key_pair_streaming]
|
||||
# tls_cert_file is the filepath to the certificate paired with the "tls_key_file"
|
||||
tls_cert_file = ""
|
||||
|
||||
# tls_key_file is the filepath to the private key paired with the "tls_cert_file"
|
||||
tls_key_file = ""
|
||||
|
||||
# max_container_log_line_size is the maximum log line size in bytes for a container.
|
||||
# Log line longer than the limit will be split into multiple lines. -1 means no
|
||||
# limit.
|
||||
max_container_log_line_size = 16384
|
||||
|
||||
# disable_cgroup indicates to disable the cgroup support.
|
||||
# This is useful when the daemon does not have permission to access cgroup.
|
||||
disable_cgroup = false
|
||||
|
||||
# disable_apparmor indicates to disable the apparmor support.
|
||||
# This is useful when the daemon does not have permission to access apparmor.
|
||||
disable_apparmor = false
|
||||
|
||||
# restrict_oom_score_adj indicates to limit the lower bound of OOMScoreAdj to
|
||||
# the containerd's current OOMScoreAdj.
|
||||
# This is useful when the containerd does not have permission to decrease OOMScoreAdj.
|
||||
restrict_oom_score_adj = false
|
||||
|
||||
# max_concurrent_downloads restricts the number of concurrent downloads for each image.
|
||||
max_concurrent_downloads = 3
|
||||
|
||||
# disable_proc_mount disables Kubernetes ProcMount support. This MUST be set to `true`
|
||||
# when using containerd with Kubernetes <=1.11.
|
||||
disable_proc_mount = false
|
||||
|
||||
# unsetSeccompProfile is the profile containerd/cri will use if the provided seccomp profile is
|
||||
# unset (`""`) for a container (default is `unconfined`)
|
||||
unset_seccomp_profile = ""
|
||||
|
||||
# 'plugins."io.containerd.grpc.v1.cri".containerd' contains config related to containerd
|
||||
[plugins."io.containerd.grpc.v1.cri".containerd]
|
||||
|
||||
# snapshotter is the snapshotter used by containerd.
|
||||
snapshotter = "overlayfs"
|
||||
|
||||
# no_pivot disables pivot-root (linux only), required when running a container in a RamDisk with runc.
|
||||
# This only works for runtime type "io.containerd.runtime.v1.linux".
|
||||
no_pivot = false
|
||||
|
||||
# disable_snapshot_annotations disables to pass additional annotations (image
|
||||
# related information) to snapshotters. These annotations are required by
|
||||
# stargz snapshotter (https://github.com/containerd/stargz-snapshotter)
|
||||
disable_snapshot_annotations = false
|
||||
|
||||
# discard_unpacked_layers allows GC to remove layers from the content store after
|
||||
# successfully unpacking these layers to the snapshotter.
|
||||
discard_unpacked_layers = false
|
||||
|
||||
# default_runtime_name is the default runtime name to use.
|
||||
default_runtime_name = "runc"
|
||||
|
||||
# 'plugins."io.containerd.grpc.v1.cri".containerd.default_runtime' is the runtime to use in containerd.
|
||||
# DEPRECATED: use `default_runtime_name` and `plugins."io.containerd.grpc.v1.cri".runtimes` instead.
|
||||
# Remove in containerd 1.4.
|
||||
[plugins."io.containerd.grpc.v1.cri".containerd.default_runtime]
|
||||
|
||||
# 'plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime' is a runtime to run untrusted workloads on it.
|
||||
# DEPRECATED: use `untrusted` runtime in `plugins."io.containerd.grpc.v1.cri".runtimes` instead.
|
||||
# Remove in containerd 1.4.
|
||||
[plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime]
|
||||
|
||||
# 'plugins."io.containerd.grpc.v1.cri".containerd.runtimes' is a map from CRI RuntimeHandler strings, which specify types
|
||||
# of runtime configurations, to the matching configurations.
|
||||
# In this example, 'runc' is the RuntimeHandler string to match.
|
||||
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
|
||||
# runtime_type is the runtime type to use in containerd.
|
||||
# The default value is "io.containerd.runc.v2" since containerd 1.4.
|
||||
# The default value was "io.containerd.runc.v1" in containerd 1.3, "io.containerd.runtime.v1.linux" in prior releases.
|
||||
runtime_type = "io.containerd.runc.v2"
|
||||
|
||||
# pod_annotations is a list of pod annotations passed to both pod
|
||||
# sandbox as well as container OCI annotations. Pod_annotations also
|
||||
# supports golang path match pattern - https://golang.org/pkg/path/#Match.
|
||||
# e.g. ["runc.com.*"], ["*.runc.com"], ["runc.com/*"].
|
||||
#
|
||||
# For the naming convention of annotation keys, please reference:
|
||||
# * Kubernetes: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/#syntax-and-character-set
|
||||
# * OCI: https://github.com/opencontainers/image-spec/blob/master/annotations.md
|
||||
pod_annotations = []
|
||||
|
||||
# container_annotations is a list of container annotations passed through to the OCI config of the containers.
|
||||
# Container annotations in CRI are usually generated by other Kubernetes node components (i.e., not users).
|
||||
# Currently, only device plugins populate the annotations.
|
||||
container_annotations = []
|
||||
|
||||
# privileged_without_host_devices allows overloading the default behaviour of passing host
|
||||
# devices through to privileged containers. This is useful when using a runtime where it does
|
||||
# not make sense to pass host devices to the container when privileged. Defaults to false -
|
||||
# i.e pass host devices through to privileged containers.
|
||||
privileged_without_host_devices = false
|
||||
|
||||
# base_runtime_spec is a file path to a JSON file with the OCI spec that will be used as the base spec that all
|
||||
# container's are created from.
|
||||
# Use containerd's `ctr oci spec > /etc/containerd/cri-base.json` to output initial spec file.
|
||||
# Spec files are loaded at launch, so containerd daemon must be restared on any changes to refresh default specs.
|
||||
# Still running containers and restarted containers will still be using the original spec from which that container was created.
|
||||
base_runtime_spec = ""
|
||||
|
||||
# 'plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options' is options specific to
|
||||
# "io.containerd.runc.v1" and "io.containerd.runc.v2". Its corresponding options type is:
|
||||
# https://github.com/containerd/containerd/blob/v1.3.2/runtime/v2/runc/options/oci.pb.go#L26 .
|
||||
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
|
||||
# NoPivotRoot disables pivot root when creating a container.
|
||||
NoPivotRoot = false
|
||||
|
||||
# NoNewKeyring disables new keyring for the container.
|
||||
NoNewKeyring = false
|
||||
|
||||
# ShimCgroup places the shim in a cgroup.
|
||||
ShimCgroup = ""
|
||||
|
||||
# IoUid sets the I/O's pipes uid.
|
||||
IoUid = 0
|
||||
|
||||
# IoGid sets the I/O's pipes gid.
|
||||
IoGid = 0
|
||||
|
||||
# BinaryName is the binary name of the runc binary.
|
||||
BinaryName = ""
|
||||
|
||||
# Root is the runc root directory.
|
||||
Root = ""
|
||||
|
||||
# CriuPath is the criu binary path.
|
||||
CriuPath = ""
|
||||
|
||||
# SystemdCgroup enables systemd cgroups.
|
||||
SystemdCgroup = false
|
||||
|
||||
# CriuImagePath is the criu image path
|
||||
CriuImagePath = ""
|
||||
|
||||
# CriuWorkPath is the criu work path.
|
||||
CriuWorkPath = ""
|
||||
|
||||
# 'plugins."io.containerd.grpc.v1.cri".cni' contains config related to cni
|
||||
[plugins."io.containerd.grpc.v1.cri".cni]
|
||||
# bin_dir is the directory in which the binaries for the plugin is kept.
|
||||
bin_dir = "/opt/cni/bin"
|
||||
|
||||
# conf_dir is the directory in which the admin places a CNI conf.
|
||||
conf_dir = "/etc/cni/net.d"
|
||||
|
||||
# max_conf_num specifies the maximum number of CNI plugin config files to
|
||||
# load from the CNI config directory. By default, only 1 CNI plugin config
|
||||
# file will be loaded. If you want to load multiple CNI plugin config files
|
||||
# set max_conf_num to the number desired. Setting max_config_num to 0 is
|
||||
# interpreted as no limit is desired and will result in all CNI plugin
|
||||
# config files being loaded from the CNI config directory.
|
||||
max_conf_num = 1
|
||||
|
||||
# conf_template is the file path of golang template used to generate
|
||||
# cni config.
|
||||
# If this is set, containerd will generate a cni config file from the
|
||||
# template. Otherwise, containerd will wait for the system admin or cni
|
||||
# daemon to drop the config file into the conf_dir.
|
||||
# This is a temporary backward-compatible solution for kubenet users
|
||||
# who don't have a cni daemonset in production yet.
|
||||
# This will be deprecated when kubenet is deprecated.
|
||||
# See the "CNI Config Template" section for more details.
|
||||
conf_template = ""
|
||||
|
||||
# 'plugins."io.containerd.grpc.v1.cri".registry' contains config related to the registry
|
||||
[plugins."io.containerd.grpc.v1.cri".registry]
|
||||
|
||||
# 'plugins."io.containerd.grpc.v1.cri.registry.headers sets the http request headers to send for all registry requests
|
||||
[plugins."io.containerd.grpc.v1.cri".registry.headers]
|
||||
Foo = ["bar"]
|
||||
|
||||
# 'plugins."io.containerd.grpc.v1.cri".registry.mirrors' are namespace to mirror mapping for all namespaces.
|
||||
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
|
||||
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
|
||||
endpoint = ["https://registry-1.docker.io", ]
|
||||
|
||||
# 'plugins."io.containerd.grpc.v1.cri".image_decryption' contains config related
|
||||
# to handling decryption of encrypted container images.
|
||||
[plugins."io.containerd.grpc.v1.cri".image_decryption]
|
||||
# key_model defines the name of the key model used for how the cri obtains
|
||||
# keys used for decryption of encrypted container images.
|
||||
# The [decryption document](https://github.com/containerd/cri/blob/master/docs/decryption.md)
|
||||
# contains additional information about the key models available.
|
||||
#
|
||||
# Set of available string options: {"", "node"}
|
||||
# Omission of this field defaults to the empty string "", which indicates no key model,
|
||||
# disabling image decryption.
|
||||
#
|
||||
# In order to use the decryption feature, additional configurations must be made.
|
||||
# The [decryption document](https://github.com/containerd/cri/blob/master/docs/decryption.md)
|
||||
# provides information of how to set up stream processors and the containerd imgcrypt decoder
|
||||
# with the appropriate key models.
|
||||
#
|
||||
# Additional information:
|
||||
# * Stream processors: https://github.com/containerd/containerd/blob/master/docs/stream_processors.md
|
||||
# * Containerd imgcrypt: https://github.com/containerd/imgcrypt
|
||||
key_model = "node"
|
||||
42
taskservs/containerd/default/containerd.service
Normal file
42
taskservs/containerd/default/containerd.service
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
# Copyright The containerd Authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
[Unit]
|
||||
Description=containerd container runtime
|
||||
Documentation=https://containerd.io
|
||||
After=network.target local-fs.target
|
||||
|
||||
[Service]
|
||||
#uncomment to enable the experimental sbservice (sandboxed) version of containerd/cri integration
|
||||
#Environment="ENABLE_CRI_SANDBOXES=sandboxed"
|
||||
ExecStartPre=-/sbin/modprobe overlay
|
||||
ExecStart=/usr/local/bin/containerd
|
||||
|
||||
Type=notify
|
||||
Delegate=yes
|
||||
KillMode=process
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
# Having non-zero Limit*s causes performance problems due to accounting overhead
|
||||
# in the kernel. We recommend using cgroups to do container-local accounting.
|
||||
LimitNPROC=infinity
|
||||
LimitCORE=infinity
|
||||
LimitNOFILE=infinity
|
||||
# Comment TasksMax if your systemd version does not supports it.
|
||||
# Only systemd 226 and above support this version.
|
||||
TasksMax=infinity
|
||||
OOMScoreAdjust=-999
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
3
taskservs/containerd/default/crictl.yaml
Normal file
3
taskservs/containerd/default/crictl.yaml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
runtime-endpoint: "unix:///run/containerd/containerd.sock"
|
||||
timeout: 0
|
||||
debug: false
|
||||
5
taskservs/containerd/default/env-containerd.j2
Normal file
5
taskservs/containerd/default/env-containerd.j2
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{%- if taskserv.name == "kubernetes" %}
|
||||
CONTAINERD_VERSION="{{taskserv.version}}"
|
||||
CRICTL_VERSION="{{taskserv.crictl_version}}"
|
||||
CRI_SOCKET="unix:///var/run/containerd/containerd.sock"
|
||||
{%- endif %}
|
||||
147
taskservs/containerd/default/install-containerd.sh
Executable file
147
taskservs/containerd/default/install-containerd.sh
Executable file
|
|
@ -0,0 +1,147 @@
|
|||
#!/bin/bash
|
||||
# Info: Script to install/create/delete/update containerd from file settings
|
||||
# Author: JesusPerezLorenzo
|
||||
# Release: 1.0
|
||||
# Date: 12-10-2024
|
||||
|
||||
USAGE="install-containerd.sh install | update | remvoe"
|
||||
[ "$1" == "-h" ] && echo "$USAGE" && exit 1
|
||||
|
||||
ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')"
|
||||
OS="$(uname | tr '[:upper:]' '[:lower:]')"
|
||||
|
||||
[ -r "env-containerd" ] && . ./env-containerd
|
||||
|
||||
CONTAINERD_VERSION="${CONTAINERD_VERSION:-1.7.18}"
|
||||
CONTAINERD_URL=https://github.com/containerd/containerd/releases/download/v$CONTAINERD_VERSION/containerd-$CONTAINERD_VERSION-$OS-$ARCH.tar.gz
|
||||
|
||||
CRICTL_VERSION="${CRICTL_VERSION:-1.28.0}"
|
||||
CRICTL_URL="https://github.com/kubernetes-sigs/cri-tools/releases/download/"
|
||||
|
||||
CONTAINERD_SYSTEMCTL_MODE=enabled
|
||||
|
||||
CMD_TSKSRVC=${1:-install}
|
||||
|
||||
export LC_CTYPE=C.UTF-8
|
||||
export LANG=C.UTF-8
|
||||
|
||||
ORG=$(pwd)
|
||||
|
||||
_clean_others() {
|
||||
[ -d "/etc/cni" ] && sudo rm -r /etc/cni
|
||||
[ -d "/var/lib/containers" ] && sudo rm -r /var/lib/containers
|
||||
sudo rm -f /etc/systemd/system/podman* 2>/dev/null
|
||||
}
|
||||
_init() {
|
||||
[ -z "$CONTAINERD_VERSION" ] && exit 1 # || [ -z "$CONTAINERD_ARCH" ] || [ -z "$CONTAINERD_URL" ] || [ -z "$CONTAINERD_FILE" ] && exit 1
|
||||
local curr_vers
|
||||
local has_containerd
|
||||
has_containerd=$(type containerd 2>/dev/null)
|
||||
if [ -n "$has_containerd" ] ; then
|
||||
curr_vers=$(containerd --version | awk '{print $3}' | sed 's/v//g')
|
||||
else
|
||||
_clean_others
|
||||
fi
|
||||
if [ "$curr_vers" != "$CONTAINERD_VERSION" ] ; then
|
||||
if ! curl -fsSL "$CONTAINERD_URL" -o /tmp/containerd.tar.gz ; then
|
||||
echo "error downloading containerd "
|
||||
return 1
|
||||
fi
|
||||
tar xzf /tmp/containerd.tar.gz
|
||||
if [ -r "bin/containerd" ] ; then
|
||||
cd bin || exit 1
|
||||
[ -n "$has_containerd" ] && sudo timeout -k 10 20 systemctl stop containerd
|
||||
sudo cp * /usr/local/bin
|
||||
cd "$ORG" || exit 1
|
||||
else
|
||||
echo "error installing containerd"
|
||||
ret=1
|
||||
fi
|
||||
rm -fr cri-o
|
||||
rm -f /tmp/containerd_installer.sh
|
||||
[ "$ret" == 1 ] && return 1
|
||||
fi
|
||||
curr_vers=$(crictl --version | awk '{print $3}' | sed 's/v//g')
|
||||
if [ "$curr_vers" != "$CRICTL_VERSION" ] ; then
|
||||
if ! curl -fsSL "${CRICTL_URL}/v${CRICTL_VERSION}/crictl-v${CRICTL_VERSION}-${OS}-${ARCH}.tar.gz" -o /tmp/crictl.tar.gz ; then
|
||||
echo "error downloading crictl installer"
|
||||
return 1
|
||||
fi
|
||||
tar xzf /tmp/crictl.tar.gz
|
||||
if [ -r "crictl" ] ; then
|
||||
chmod +x crictl
|
||||
sudo mv crictl /usr/local/bin
|
||||
fi
|
||||
rm -f /tmp/crictl.tar.gz
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
_config_containerd() {
|
||||
[ ! -d "/etc/containerd" ] && mkdir -p /etc/containerd
|
||||
if [ -r "config.toml" ] && [ ! -r "/etc/containerd/config.toml" ] ; then
|
||||
sudo cp config.toml /etc/containerd/config.toml
|
||||
elif [ ! -r "/etc/containerd/config.toml" ] ; then
|
||||
sudo containerd config default | sudo tee /etc/containerd/config.toml >/dev/null
|
||||
fi
|
||||
local youki_path=$(type -p youki 2>/dev/null)
|
||||
if [ -n "$youki_path" ] && [ -x "$youki_path" ] ; then
|
||||
local has_youki=$(grep youki /etc/containerd/config.toml)
|
||||
if [ -z "$has_youki" ] ; then
|
||||
echo '[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.youki]' >> /etc/containerd/config.toml
|
||||
echo ' runtime_type = "io.containerd.runc.v2"' >> /etc/containerd/config.toml
|
||||
echo ' [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.youki.options]' >> /etc/containerd/config.toml
|
||||
echo ' BinaryName = "'$youki_path'"' >> /etc/containerd/config.toml
|
||||
sed -i 's,SystemdCgroup = true,,' /etc/containerd/config.toml
|
||||
fi
|
||||
fi
|
||||
if [ -r "crictl.yaml" ] && [ ! -r "/etc/containerd-crictl.yaml" ] ; then
|
||||
sudo cp crictl.yaml /etc/containerd-crictl.yaml
|
||||
sudo cp crictl.yaml /etc/crictl.yaml
|
||||
fi
|
||||
if [ -r "containerd.service" ] && [ ! -r "/lib/systemd/containerd.service" ] ; then
|
||||
sudo cp containerd.service /lib/systemd/system
|
||||
[ ! -L "/etc/systemd/system/containerd.service" ] && sudo ln -s /lib/systemd/system/containerd.service /etc/systemd/system
|
||||
sudo timeout -k 10 20 systemctl daemon-reload
|
||||
fi
|
||||
TARGET=/etc/modules-load.d/containerd.conf
|
||||
ITEMS="overlay br_netfilter"
|
||||
for it in $ITEMS
|
||||
do
|
||||
has_item=$(sudo grep ^"$it" $TARGET 2>/dev/null)
|
||||
[ -z "$has_item" ] && echo "$it" | sudo tee -a /etc/modules-load.d/containerd.conf
|
||||
done
|
||||
_start_containerd
|
||||
}
|
||||
|
||||
_remove_containerd() {
|
||||
sudo timeout -k 10 20 systemctl stop containerd
|
||||
sudo timeout -k 10 20 systemctl disable containerd
|
||||
}
|
||||
|
||||
_start_containerd() {
|
||||
if [ "$CONTAINERD_SYSTEMCTL_MODE" == "enabled" ] ; then
|
||||
sudo timeout -k 10 20 systemctl enable containerd
|
||||
else
|
||||
sudo timeout -k 10 20 systemctl disable containerd
|
||||
fi
|
||||
sudo timeout -k 10 20 systemctl start containerd
|
||||
}
|
||||
|
||||
_restart_containerd() {
|
||||
sudo timeout -k 10 20 systemctl restart containerd
|
||||
}
|
||||
[ "$CMD_TSKSRVC" == "remove" ] && _remove_containerd && exit 0
|
||||
if ! _init ; then
|
||||
echo "error containerd install"
|
||||
exit 1
|
||||
fi
|
||||
[ "$CMD_TSKSRVC" == "update" ] && _restart_containerd && exit 0
|
||||
if ! _config_containerd ; then
|
||||
echo "error containerd config"
|
||||
exit 1
|
||||
fi
|
||||
if ! _start_containerd ; then
|
||||
echo "error containerd start"
|
||||
exit 1
|
||||
fi
|
||||
2
taskservs/containerd/default/provisioning.toml
Normal file
2
taskservs/containerd/default/provisioning.toml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
info = "containerd"
|
||||
release = "1.0"
|
||||
29
taskservs/coredns/default/Corefile.j2
Normal file
29
taskservs/coredns/default/Corefile.j2
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
{% for entry in taskserv.entries -%}
|
||||
{{entry.domain}}:{{entry.port}} {
|
||||
{% if entry.file and entry.file != "" -%}
|
||||
file {{entry.file}}
|
||||
{% endif -%}
|
||||
{% if entry.forward and entry.forward.source != "" -%}
|
||||
{%- if entry.forward.forward_ip -%}
|
||||
{% set forward_ip=entry.forward.forward_ip %}
|
||||
{%- elif server.primary_dns -%}
|
||||
{% set forward_ip=server.primary_dns ~ " " ~ server.secondary_dns %}
|
||||
{%- else -%}
|
||||
{% set forward_ip="" %}
|
||||
{%- endif -%}
|
||||
{%- if forward_ip -%}
|
||||
forward {{entry.forward.source}} {{forward_ip}} {
|
||||
}
|
||||
{% endif -%}
|
||||
{% endif -%}
|
||||
{% if entry.use_log or entry.use_log == "true" -%}
|
||||
log
|
||||
{% endif -%}
|
||||
{% if entry.use_errors or entry.use_errors == "true" -%}
|
||||
errors
|
||||
{% endif -%}
|
||||
{% if entry.use_cache or entry.use_cache == "true" -%}
|
||||
cache
|
||||
{% endif -%}
|
||||
}
|
||||
{% endfor -%}
|
||||
20
taskservs/coredns/default/coredns.service.j2
Normal file
20
taskservs/coredns/default/coredns.service.j2
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
[Unit]
|
||||
Description=CoreDNS DNS server
|
||||
Documentation=https://coredns.io
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
PermissionsStartOnly=true
|
||||
LimitNOFILE=1048576
|
||||
LimitNPROC=512
|
||||
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
|
||||
AmbientCapabilities=CAP_NET_BIND_SERVICE
|
||||
NoNewPrivileges=true
|
||||
User=coredns
|
||||
WorkingDirectory=~
|
||||
ExecStart=/usr/local/bin/coredns -conf={{taskserv.etc_corefile}}
|
||||
ExecReload=/bin/kill -SIGUSR1 $MAINPID
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
62
taskservs/coredns/default/dns.tpl
Normal file
62
taskservs/coredns/default/dns.tpl
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
{% if taskserv.entries[DOMAIN_POS].domain == "$defaults" -%}
|
||||
{% set dns_domain=defaults.main_domain %}
|
||||
{%- elif taskserv.entries[DOMAIN_POS].domain == "$server" %}
|
||||
{%- if server.main_domain == "$defaults"or server.main_domain == ""-%}
|
||||
{% set dns_domain=defaults.main_domain %}
|
||||
{%- else -%}
|
||||
{% set dns_domain=server.main_domain %}
|
||||
{%- endif %}
|
||||
{%- else -%}
|
||||
{% set dns_domain=taskserv.entries[DOMAIN_POS].domain %}
|
||||
{%- endif %}
|
||||
$ORIGIN {{dns_domain}}.
|
||||
@ 3600 IN SOA sns.dns.icann.org. noc.dns.icann.org. (
|
||||
2017042745 ; serial
|
||||
7200 ; refresh (2 hours)
|
||||
3600 ; retry (1 hour)
|
||||
1209600 ; expire (2 weeks)
|
||||
3600 ; minimum (1 hour)
|
||||
)
|
||||
3600 IN NS a.iana-servers.net.
|
||||
3600 IN NS b.iana-servers.net.
|
||||
;
|
||||
{% if taskserv.entries[DOMAIN_POS] %}
|
||||
{%- for record in taskserv.entries[DOMAIN_POS].records %}
|
||||
{%- if defs.servers[record.server_pos] and defs.servers[record.server_pos].hostname -%}
|
||||
{% set hostname = defs.servers[record.server_pos].hostname %}
|
||||
{%- else -%}
|
||||
{% set hostname = "" %}
|
||||
{%- endif -%}
|
||||
{%- if record.source == "$hostname" -%}
|
||||
{% set source = hostname %}
|
||||
{%- else -%}
|
||||
{% set source = record.source %}
|
||||
{%- endif -%}
|
||||
{%- if record.target_ip == "$network_private_ip" and defs.servers[record.server_pos] and defs.servers[record.server_pos].network_private_ip -%}
|
||||
{% set target = defs.servers[record.server_pos].network_private_ip %}
|
||||
{%- elif record.target_ip == "$network_public_ip" and defs.servers[record.server_pos].ip_addresses.pub -%}
|
||||
{% set target = defs.servers[record.server_pos].ip_addresses.pub %}
|
||||
{%- else -%}
|
||||
{% set target = record.target_ip %}
|
||||
{%- endif -%}
|
||||
{% if hostname != "" -%}
|
||||
; {{hostname}}
|
||||
{%- endif %}
|
||||
{% if record.rectype == "A" and source and target -%}
|
||||
{{ source }}.{{dns_domain}}. {{record.ttl}} IN A {{target}}
|
||||
{% elif record.rectype == "CNAME" and source and record.value -%}
|
||||
{{ source }}.{{dns_domain}}. {{record.ttl}} IN CNAME {{record.value}}
|
||||
{% endif -%}
|
||||
{%- if hostname != "" and taskserv.entries[DOMAIN_POS].etcd_cluster_name and taskserv.entries[DOMAIN_POS].etcd_cluster_name != "" -%}
|
||||
{%- for taskserv in defs.servers[record.server_pos].taskservs -%}
|
||||
{%- if taskserv.name != "etcd" -%}{% continue %}{%- endif -%}
|
||||
{{ taskserv.entries[DOMAIN_POS].etcd_cluster_name }}.{{dns_domain}}. {{record.ttl}} IN A {{target}} ; {{ hostname }}
|
||||
{% break %}
|
||||
{%- endfor -%}
|
||||
_etcd-server-ssl._tcp.{{dns_domain}}. {{record.etcd_dns_ttl}} IN SRV 0 0 {{record.etcd_peer_port}} {{hostname}}.{{dns_domain}}.
|
||||
_etcd-server._tcp.{{dns_domain}}. {{record.etcd_dns_ttl}} IN SRV 0 0 {{record.etcd_peer_port}} {{hostname}}.{{dns_domain}}.
|
||||
_etcd-client-ssl._tcp.{{dns_domain}}. {{record.etcd_dns_ttl}} IN SRV 0 0 {{record.etcd_cli_port}} {{hostname}}.{{dns_domain}}.
|
||||
_etcd-client._tcp.{{dns_domain}}. {{record.etcd_dns_ttl}} IN SRV 0 0 {{record.etcd_cli_port}} {{hostname}}.{{dns_domain}}.
|
||||
{% endif %}
|
||||
{%- endfor -%}
|
||||
{% endif %}
|
||||
31
taskservs/coredns/default/env-coredns.j2
Normal file
31
taskservs/coredns/default/env-coredns.j2
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
COREDNS_VERSION="{{taskserv.version}}"
|
||||
COREDNS_NAME="{{taskserv.name}}"
|
||||
COREDNS_FILE="{{taskserv.etc_corefile}}"
|
||||
|
||||
NAMESERVERS="{%- for item in taskserv.nameservers -%}
|
||||
{%- if item.ns_ip is starting_with("$servers") -%}
|
||||
{% set arr_ns = item.ns_ip | split(pat=".") %}
|
||||
{% set pos = arr_ns[1] %}
|
||||
{% set ip = arr_ns[2] %}
|
||||
{%- if servers[pos] and ip == "$network_private_ip" and servers[pos].network_private_ip -%}
|
||||
{{servers[pos].network_private_ip}}
|
||||
{%- elif servers[pos] and ip == "$network_public_ip" and settings[pos] and settings[pos].ip_addresses.pub -%}
|
||||
{{settings[pos].ip_addresses.pub}}
|
||||
{%- endif -%}
|
||||
{%- else -%}
|
||||
{{item.ns_ip}}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
"
|
||||
{% if server.main_domain == "$defaults" or server.main_domain == "" %}
|
||||
MAIN_DOMAIN_NAME={{server.main_domain}}
|
||||
{%- else %}
|
||||
MAIN_DOMAIN_NAME={{server.main_domain}}
|
||||
{%- endif %}
|
||||
{% if taskserv.domains_search == "$defaults" %}
|
||||
DOMAINS_SEARCH={{server.domains_search}}
|
||||
{%- elif taskserv.domains_search == "$server" %}
|
||||
DOMAINS_SEARCH={{server.domains_search}}
|
||||
{%- else %}
|
||||
DOMAINS_SEARCH={{taskserv.domains_search}}
|
||||
{%- endif %}
|
||||
106
taskservs/coredns/default/install-coredns.sh
Executable file
106
taskservs/coredns/default/install-coredns.sh
Executable file
|
|
@ -0,0 +1,106 @@
|
|||
#!/bin/bash
|
||||
# Info: Script to install/create/delete/update coredns from file settings
|
||||
# Author: JesusPerezLorenzo
|
||||
# Release: 1.0
|
||||
# Date: 12-11-2024
|
||||
|
||||
USAGE="install-coredns.sh install | update | remvoe"
|
||||
[ "$1" == "-h" ] && echo "$USAGE" && exit 1
|
||||
|
||||
[ -r "env-coredns" ] && . ./env-coredns
|
||||
|
||||
OS=$(uname | tr '[:upper:]' '[:lower:]')
|
||||
ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')"
|
||||
CMD_TSKSRVC=${1:-install}
|
||||
|
||||
HOSTNAME=$(hostname)
|
||||
export LC_CTYPE=C.UTF-8
|
||||
export LANG=C.UTF-8
|
||||
|
||||
[ ! -d "/etc/coredns" ] && sudo mkdir /etc/coredns
|
||||
ROOT=$(dirname "$0")
|
||||
|
||||
_init() {
|
||||
[ -z "$COREDNS_VERSION" ] || [ -z "$ARCH" ] && exit 1
|
||||
local has_coredns
|
||||
local curr_vers
|
||||
has_coredns=$(type -P coredns)
|
||||
[ -n "$has_coredns" ] && curr_vers=$(coredns -version 2>/dev/null | grep CoreDNS | cut -f2 -d"-" | sed 's/ //g')
|
||||
[ "$curr_vers" == "$COREDNS_VERSION" ] && return
|
||||
[ -n "$has_coredns" ] && sudo timeout -k 10 20 systemctl stop coredns
|
||||
[ ! -d "tmp" ] && mkdir tmp
|
||||
rm -f "tmp/coredns_${COREDNS_VERSION}_${OS}_${ARCH}.tgz"
|
||||
if ! curl -fsSL https://github.com/coredns/coredns/releases/download/v${COREDNS_VERSION}/coredns_${COREDNS_VERSION}_${OS}_${ARCH}.tgz -o "tmp/coredns_${COREDNS_VERSION}_${OS}_${ARCH}.tgz" ; then
|
||||
echo "Error downloading coredns_${COREDNS_VERSION}_${OS}_${ARCH}.tgz"
|
||||
exit 1
|
||||
fi
|
||||
if ! tar xzf "tmp/coredns_${COREDNS_VERSION}_${OS}_${ARCH}.tgz" -C tmp ; then
|
||||
echo "Error extracting coredns_${COREDNS_VERSION}-${ARCH}.tar.gz"
|
||||
exit 1
|
||||
fi
|
||||
rm -f "tmp/coredns_${COREDNS_VERSION}_${OS}_${ARCH}.tgz"
|
||||
[ ! -r "tmp/coredns" ] && echo "Error extracting coredns" && exit 1
|
||||
chmod +x tmp/coredns
|
||||
sudo mv tmp/coredns /usr/local/bin
|
||||
rm -r "tmp"
|
||||
}
|
||||
_config_coredns() {
|
||||
[ ! -d "/etc/coredns" ] && sudo mkdir /etc/coredns
|
||||
|
||||
has_user=$(sudo grep coredns /etc/passwd)
|
||||
[ -z "$has_user" ] && sudo useradd -d /var/lib/coredns -m coredns
|
||||
|
||||
# [ ! -d "/etc/ssl/coredns" ] && sudo mkdir -p /etc/ssl/coredns
|
||||
sudo cp "$ROOT"/Corefile /etc/coredns 2>/dev/null
|
||||
sudo cp "$ROOT"/resources/* /etc/coredns 2>/dev/null
|
||||
sudo rm -f /etc/coredns/*.j2
|
||||
sudo chown -R coredns:coredns /etc/coredns
|
||||
|
||||
if [ ! -L "/etc/systemd/system/coredns.service" ] ; then
|
||||
sudo cp coredns.service /lib/systemd/system/coredns.service
|
||||
sudo timeout -k 10 20 systemctl daemon-reload >/dev/null 2>&1
|
||||
#[ ! -L "/etc/systemd/system/coredns.service" ] && sudo ln -s /lib/systemd/system/coredns.service /etc/systemd/system
|
||||
fi
|
||||
sudo timeout -k 10 20 systemctl enable --now coredns >/dev/null 2>&1
|
||||
sudo timeout -k 10 20 systemctl restart coredns >/dev/null 2>&1
|
||||
}
|
||||
_stop_resolved() {
|
||||
sudo timeout -k 10 20 systemctl stop coredns >/dev/null 2>&1
|
||||
sudo timeout -k 10 20 systemctl disable coredns >/dev/null 2>&1
|
||||
}
|
||||
_remove_coredns() {
|
||||
sudo timeout -k 10 20 systemctl stop coredns >/dev/null 2>&1
|
||||
sudo timeout -k 10 20 systemctl disable coredns >/dev/null 2>&1
|
||||
}
|
||||
_start_coredns() {
|
||||
sudo timeout -k 10 20 systemctl enable coredns >/dev/null 2>&1
|
||||
sudo timeout -k 10 20 systemctl start coredns >/dev/null 2>&1
|
||||
}
|
||||
_restart_coredns() {
|
||||
sudo timeout -k 10 20 systemctl restart coredns >/dev/null 2>&1
|
||||
}
|
||||
if [ "$CMD_TSKSRVC" == "config" ] ; then
|
||||
_config_coredns
|
||||
exit
|
||||
fi
|
||||
if [ "$CMD_TSKSRVC" == "remove" ] ; then
|
||||
_remove_coredns
|
||||
exit
|
||||
fi
|
||||
if ! _init ; then
|
||||
echo "error coredns init"
|
||||
exit 1
|
||||
fi
|
||||
if ! _config_coredns ; then
|
||||
echo "error coredns config"
|
||||
exit 1
|
||||
fi
|
||||
[ "$CMD_TSKSRVC" == "update" ] && _restart_coredns && exit 0
|
||||
if ! _stop_resolved ; then
|
||||
echo "error coredns stop"
|
||||
exit 1
|
||||
fi
|
||||
if ! _start_coredns ; then
|
||||
echo "error coredns start"
|
||||
exit 1
|
||||
fi
|
||||
56
taskservs/coredns/default/prepare
Executable file
56
taskservs/coredns/default/prepare
Executable file
|
|
@ -0,0 +1,56 @@
|
|||
#!/usr/bin/env nu
|
||||
# Info: Prepare for coredns installation
|
||||
# Author: JesusPerezLorenzo
|
||||
# Release: 1.0.2
|
||||
# Date: 26-02-2024
|
||||
|
||||
use lib_provisioning/cmd/env.nu *
|
||||
use lib_provisioning/cmd/lib.nu *
|
||||
|
||||
use lib_provisioning/utils/ui.nu *
|
||||
|
||||
print $"(_ansi green_bold)CoreDNS(_ansi reset) with ($env.PROVISIONING_VARS) "
|
||||
|
||||
let run_root = $env.PROVISIONING_WK_ENV_PATH
|
||||
|
||||
if $env.PROVISIONING_RESOURCES == null {
|
||||
print $"🛑 PROVISIONING_RESOURCES not found"
|
||||
exit 1
|
||||
}
|
||||
|
||||
#let resources_path = ($env.PROVISIONING_SETTINGS_SRC_PATH | path join "resources")
|
||||
let resources_path = ($run_root | path join "resources")
|
||||
|
||||
if not ($resources_path | path exists) { ^mkdir -p $resources_path }
|
||||
|
||||
if not ($resources_path | path exists) {
|
||||
print $"🛑 Path ($resources_path | path dirname) not found"
|
||||
exit 1
|
||||
}
|
||||
|
||||
let dns_tpl = ($run_root | path join "dns.tpl")
|
||||
if not ($dns_tpl | path exists) {
|
||||
print $"🛑 dns.tpl not found in ($run_root)"
|
||||
exit 1
|
||||
}
|
||||
|
||||
let defs = load_defs
|
||||
|
||||
$defs.taskserv.entries | enumerate | each {|it|
|
||||
let filename = ($it.item | get -i file | default "")
|
||||
let domain = ($it.item | get -i domain | default "")
|
||||
if $filename != "" and $domain != "" {
|
||||
let resources_filename_path = ($resources_path | path join $"($filename | path basename).j2")
|
||||
cp $dns_tpl $resources_filename_path
|
||||
if not ($resources_filename_path | path exists) {
|
||||
print $"🛑 Path ($resources_filename_path) not found for ($it.index)"
|
||||
exit 1
|
||||
}
|
||||
(open -r $resources_filename_path | str replace --all "DOMAIN_NAME" $domain | str replace --all "DOMAIN_POS" $"($it.index)"
|
||||
| save --force $resources_filename_path )
|
||||
#^sed -i $"\"s/DOMAIN_NAME/($domain)/g\"" $resources_filename_path
|
||||
#^sed -i $"\"s/DOMAIN_POS/($it.index)/g\"" $resources_filename_path
|
||||
# Clean up and compact lines
|
||||
#^sed -i -e '/\S/!d' $resources_filename_path #2>/dev/null
|
||||
}
|
||||
}
|
||||
3
taskservs/crio/default/crictl.yaml
Normal file
3
taskservs/crio/default/crictl.yaml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
runtime-endpoint: "unix:///var/run/crio/crio.sock"
|
||||
timeout: 0
|
||||
debug: false
|
||||
34
taskservs/crio/default/crio.conf.j2
Normal file
34
taskservs/crio/default/crio.conf.j2
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[crio.image]
|
||||
signature_policy = "/etc/crio/policy.json"
|
||||
|
||||
[crio.runtime]
|
||||
{% if taskserv.default_runtime -%}
|
||||
default_runtime = "{{taskserv.default_runtime}}"
|
||||
{% else -%}
|
||||
default_runtime = "crun"
|
||||
{% endif -%}
|
||||
|
||||
{% if taskserv.runtimes is containing("crun") -%}
|
||||
[crio.runtime.runtimes.crun]
|
||||
runtime_path = "/usr/local/bin/crio-crun"
|
||||
monitor_path = "/usr/local/bin/crio-conmon"
|
||||
allowed_annotations = [
|
||||
"io.containers.trace-syscall",
|
||||
]
|
||||
{% endif -%}
|
||||
|
||||
{% if taskserv.runtimes is containing("runc") -%}
|
||||
[crio.runtime.runtimes.runc]
|
||||
runtime_path = "/usr/local/bin/crio-runc"
|
||||
monitor_path = "/usr/local/bin/crio-conmon"
|
||||
{% endif -%}
|
||||
|
||||
{% if taskserv.runtimes is containing("youki") -%}
|
||||
[crio.runtime.runtimes.youki]
|
||||
runtime_path = "/usr/local/bin/youki"
|
||||
monitor_path = "/usr/local/bin/crio-conmon"
|
||||
runtime_type ="oci"
|
||||
runtime_root = "/run/youki"
|
||||
cgroup_manager = "cgroupfs"
|
||||
conmon_cgroup = "pod"
|
||||
{% endif -%}
|
||||
2
taskservs/crio/default/env-crio.j2
Normal file
2
taskservs/crio/default/env-crio.j2
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
CRIO_VERSION="{{taskserv.version}}"
|
||||
CRI_SOCKET="unix:///var/run/crio/crio.sock"
|
||||
140
taskservs/crio/default/install-crio.sh
Executable file
140
taskservs/crio/default/install-crio.sh
Executable file
|
|
@ -0,0 +1,140 @@
|
|||
#!/bin/bash
|
||||
# Info: Script to install/create/delete/update crio from file settings
|
||||
# Author: JesusPerezLorenzo
|
||||
# Release: 1.0
|
||||
# Date: 12-10-2024
|
||||
|
||||
USAGE="install-crio.sh install | update | remvoe"
|
||||
[ "$1" == "-h" ] && echo "$USAGE" && exit 1
|
||||
|
||||
ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')"
|
||||
OS="$(uname | tr '[:upper:]' '[:lower:]')"
|
||||
|
||||
[ -r "env-crio" ] && . ./env-crio
|
||||
|
||||
CRIO_VERSION="${CRIO_VERSION:-1.28.1}"
|
||||
#CRIO_URL=https://raw.githubusercontent.com/cri-o/cri-o/master/scripts/get
|
||||
CRIO_URL=https://storage.googleapis.com/cri-o/artifacts/cri-o.${ARCH}.v$CRIO_VERSION.tar.gz
|
||||
|
||||
CRICTL_VERSION="${CRICTL_VERSION:-1.28.0}"
|
||||
CRICTL_URL="https://github.com/kubernetes-sigs/cri-tools/releases/download/"
|
||||
|
||||
CRIO_SYSTEMCTL_MODE=enabled
|
||||
|
||||
CMD_TSKSRVC=${1:-install}
|
||||
|
||||
export LC_CTYPE=C.UTF-8
|
||||
export LANG=C.UTF-8
|
||||
|
||||
ORG=$(pwd)
|
||||
|
||||
_clean_others() {
|
||||
[ -d "/etc/cni" ] && sudo rm -r /etc/cni
|
||||
[ -d "/var/lib/containers" ] && sudo rm -r /var/lib/containers
|
||||
sudo rm -f /etc/systemd/system/podman* 2>/dev/null
|
||||
}
|
||||
_init() {
|
||||
[ -z "$CRIO_VERSION" ] && exit 1 # || [ -z "$CRIO_ARCH" ] || [ -z "$CRIO_URL" ] || [ -z "$CRIO_FILE" ] && exit 1
|
||||
local curr_vers
|
||||
local has_crio
|
||||
has_crio=$(type crio 2>/dev/null)
|
||||
if [ -n "$has_crio" ] ; then
|
||||
curr_vers=$(crio --version | grep "^Version" | awk '{print $2}')
|
||||
else
|
||||
_clean_others
|
||||
fi
|
||||
if [ "$curr_vers" != "$CRIO_VERSION" ] ; then
|
||||
if ! curl -fsSL "$CRIO_URL" -o /tmp/crio.tar.gz ; then
|
||||
echo "error downloading crio "
|
||||
return 1
|
||||
fi
|
||||
tar xzf /tmp/crio.tar.gz
|
||||
if [ -r "cri-o/install" ] ; then
|
||||
cd cri-o || exit 1
|
||||
[ -n "$has_crio" ] && sudo timeout -k 10 20 systemctl stop crio
|
||||
sudo bash ./install
|
||||
cd "$ORG" || exit 1
|
||||
else
|
||||
echo "error installing crio"
|
||||
ret=1
|
||||
fi
|
||||
rm -fr cri-o
|
||||
rm -f /tmp/crio_installer.sh
|
||||
[ "$ret" == 1 ] && return 1
|
||||
fi
|
||||
curr_vers=$(crictl --version | awk '{print $3}' | sed 's/v//g')
|
||||
if [ "$curr_vers" != "$CRICTL_VERSION" ] ; then
|
||||
if ! curl -fsSL "${CRICTL_URL}/v${CRICTL_VERSION}/crictl-v${CRICTL_VERSION}-${OS}-${ARCH}.tar.gz" -o /tmp/crictl.tar.gz ; then
|
||||
echo "error downloading crictl installer"
|
||||
return 1
|
||||
fi
|
||||
tar xzf /tmp/crictl.tar.gz
|
||||
if [ -r "crictl" ] ; then
|
||||
chmod +x crictl
|
||||
sudo mv crictl /usr/local/bin
|
||||
fi
|
||||
rm -f /tmp/crictl.tar.gz
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
_config_crio() {
|
||||
[ ! -d "/etc/crio" ] && mkdir -p /etc/crio
|
||||
if [ -r "crio_config.toml" ] && [ ! -r "/etc/crio/config.toml" ] ; then
|
||||
sudo cp crio_config.toml /etc/crio/config.toml
|
||||
fi
|
||||
if [ -r "crio.conf" ] && [ -d "/etc/crio/crio.conf.d" ] ; then
|
||||
sudo cp crio.conf /etc/crio/crio.conf.d/10-crio.conf
|
||||
fi
|
||||
[ -r "crio" ] && mkdir -p /etc/crio
|
||||
if [ -r "crictl.yaml" ] && [ ! -r "/etc/crio-crictl.yaml" ] ; then
|
||||
sudo cp crictl.yaml /etc/crio-crictl.yaml
|
||||
sudo cp crictl.yaml /etc/crictl.yaml
|
||||
fi
|
||||
|
||||
if [ -r "crio.service" ] && [ ! -r "/lib/systemd/crio.service" ] ; then
|
||||
sudo cp crio.service /lib/systemd/system
|
||||
[ ! -L "/etc/systemd/system/crio.service" ] && sudo ln -s /lib/systemd/system/crio.service /etc/systemd/system
|
||||
sudo timeout -k 10 20 systemctl daemon-reload
|
||||
fi
|
||||
TARGET=/etc/modules-load.d/crio.conf
|
||||
ITEMS="overlay br_netfilter"
|
||||
for it in $ITEMS
|
||||
do
|
||||
has_item=$(sudo grep ^"$it" $TARGET 2>/dev/null)
|
||||
[ -z "$has_item" ] && echo "$it" | sudo tee -a /etc/modules-load.d/crio.conf
|
||||
done
|
||||
_start_crio
|
||||
}
|
||||
|
||||
_remove_crio() {
|
||||
sudo timeout -k 10 20 systemctl stop crio
|
||||
sudo timeout -k 10 20 systemctl disable crio
|
||||
}
|
||||
|
||||
_start_crio() {
|
||||
if [ "$CRIO_SYSTEMCTL_MODE" == "enabled" ] ; then
|
||||
sudo timeout -k 10 20 systemctl enable crio
|
||||
else
|
||||
sudo timeout -k 10 20 systemctl disable crio
|
||||
fi
|
||||
sudo timeout -k 10 20 systemctl start crio
|
||||
}
|
||||
|
||||
_restart_crio() {
|
||||
sudo timeout -k 10 20 systemctl restart crio
|
||||
}
|
||||
[ "$CMD_TSKSRVC" == "remove" ] && _remove_crio && exit 0
|
||||
if ! _init ; then
|
||||
echo "error crio install"
|
||||
exit 1
|
||||
fi
|
||||
[ "$CMD_TSKSRVC" == "update" ] && _restart_crio && exit 0
|
||||
if ! _config_crio ; then
|
||||
echo "error crio config"
|
||||
exit 1
|
||||
fi
|
||||
if ! _start_crio ; then
|
||||
echo "error crio start"
|
||||
exit 1
|
||||
fi
|
||||
2
taskservs/crio/default/provisioning.toml
Normal file
2
taskservs/crio/default/provisioning.toml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
info = "crio"
|
||||
release = "1.0"
|
||||
2
taskservs/crun/default/env-crun.j2
Normal file
2
taskservs/crun/default/env-crun.j2
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
CRUN_VERSION="{{taskserv.version}}"
|
||||
#CRI_SOCKET="unix:///var/run/crun/crun.sock"
|
||||
110
taskservs/crun/default/install-crun.sh
Executable file
110
taskservs/crun/default/install-crun.sh
Executable file
|
|
@ -0,0 +1,110 @@
|
|||
#!/bin/bash
|
||||
# Info: Script to install/create/delete/update crun from file settings
|
||||
# Author: JesusPerezLorenzo
|
||||
# Release: 1.0
|
||||
# Date: 12-10-2024
|
||||
|
||||
USAGE="install-crun.sh install | update | remvoe"
|
||||
[ "$1" == "-h" ] && echo "$USAGE" && exit 1
|
||||
|
||||
ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')"
|
||||
OS="$(uname | tr '[:upper:]' '[:lower:]')"
|
||||
|
||||
[ -r "env-crun" ] && . ./env-crun
|
||||
|
||||
CRUN_VERSION="${CRUN_VERSION:-1.5}"
|
||||
CRUN_URL=https://github.com/containers/crun/releases/download/$CRUN_VERSION/crun-$CRUN_VERSION-$OS-$ARCH
|
||||
|
||||
CMD_TSKSRVC=${1:-install}
|
||||
|
||||
export LC_CTYPE=C.UTF-8
|
||||
export LANG=C.UTF-8
|
||||
|
||||
ORG=$(pwd)
|
||||
|
||||
_init() {
|
||||
[ -z "$CRUN_VERSION" ] && exit 1 # || [ -z "$CRUN_ARCH" ] || [ -z "$CRUN_URL" ] || [ -z "$CRUN_FILE" ] && exit 1
|
||||
local curr_vers
|
||||
local has_crun
|
||||
has_crun=$(type crun 2>/dev/null)
|
||||
if [ -n "$has_crun" ] ; then
|
||||
curr_vers=$(crun --version | grep "^Version" | awk '{print $2}')
|
||||
fi
|
||||
if [ "$curr_vers" != "$CRUN_VERSION" ] ; then
|
||||
if ! curl -fsSL "$CRUN_URL" -o crun ; then
|
||||
echo "error downloading crun "
|
||||
return 1
|
||||
fi
|
||||
if [ -r "crun" ] ; then
|
||||
chmod +x crun
|
||||
sudo mv crun /usr/local/bin
|
||||
else
|
||||
echo "error installing crun"
|
||||
ret=1
|
||||
fi
|
||||
rm -f crun
|
||||
[ "$ret" == 1 ] && return 1
|
||||
[ -r "/usr/bin/crun" ] && mv /usr/bin/crun /usr/bin/_crun
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
_config_crun() {
|
||||
return 0
|
||||
[ ! -d "/etc/crun" ] && mkdir -p /etc/crun
|
||||
if [ -r "crun_config.toml" ] && [ ! -r "/etc/crun/config.toml" ] ; then
|
||||
sudo cp crun_config.toml /etc/crun/config.toml
|
||||
fi
|
||||
if [ -r "crictl.yaml" ] && [ ! -r "/etc/crun-crictl.yaml" ] ; then
|
||||
sudo cp crictl.yaml /etc/crun-crictl.yaml
|
||||
fi
|
||||
#if [ -r "crictl.yaml" ] && [ ! -r "/etc/crictl.yaml" ] ; then
|
||||
# sudo cp crictl.yaml /etc/crictl.yaml
|
||||
#fi
|
||||
|
||||
if [ -r "crun.service" ] && [ ! -r "/lib/systemd/crun.service" ] ; then
|
||||
sudo cp crun.service /lib/systemd/system
|
||||
[ ! -L "/etc/systemd/system/crun.service" ] && sudo ln -s /lib/systemd/system/crun.service /etc/systemd/system
|
||||
sudo timeout -k 10 20 systemctl daemon-reload
|
||||
fi
|
||||
TARGET=/etc/modules-load.d/crun.conf
|
||||
ITEMS="overlay br_netfilter"
|
||||
for it in $ITEMS
|
||||
do
|
||||
has_item=$(sudo grep ^"$it" $TARGET 2>/dev/null)
|
||||
[ -z "$has_item" ] && echo "$it" | sudo tee -a /etc/modules-load.d/crun.conf
|
||||
done
|
||||
_start_crun
|
||||
}
|
||||
|
||||
_remove_crun() {
|
||||
sudo timeout -k 10 20 systemctl stop crun
|
||||
sudo timeout -k 10 20 systemctl disable crun
|
||||
}
|
||||
|
||||
_start_crun() {
|
||||
if [ "$CRUN_SYSTEMCTL_MODE" == "enabled" ] ; then
|
||||
sudo timeout -k 10 20 systemctl enable crun
|
||||
else
|
||||
sudo timeout -k 10 20 systemctl disable crun
|
||||
fi
|
||||
sudo timeout -k 10 20 systemctl start crun
|
||||
}
|
||||
|
||||
_restart_crun() {
|
||||
sudo timeout -k 10 20 systemctl restart crun
|
||||
}
|
||||
[ "$CMD_TSKSRVC" == "remove" ] && _remove_crun && exit 0
|
||||
if ! _init ; then
|
||||
echo "error crun install"
|
||||
exit 1
|
||||
fi
|
||||
[ "$CMD_TSKSRVC" == "update" ] && _restart_crun && exit 0
|
||||
if ! _config_crun ; then
|
||||
echo "error crun config"
|
||||
exit 1
|
||||
fi
|
||||
#if ! _start_crun ; then
|
||||
# echo "error crun start"
|
||||
# exit 1
|
||||
#fi
|
||||
2
taskservs/crun/default/provisioning.toml
Normal file
2
taskservs/crun/default/provisioning.toml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
info = "crun"
|
||||
release = "1.0"
|
||||
63
taskservs/desktop/default/desktop-apps.conf.j2
Normal file
63
taskservs/desktop/default/desktop-apps.conf.j2
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
# Desktop Applications Configuration
|
||||
# Generated for {{ desktop.name }} - {{ desktop.desktop_env.type | upper }} Desktop
|
||||
|
||||
[applications]
|
||||
# Editor Applications
|
||||
{% for editor in desktop.applications.editors %}
|
||||
{{ editor }}_enabled = true
|
||||
{% endfor %}
|
||||
|
||||
# Browser Applications
|
||||
{% for browser in desktop.applications.browsers %}
|
||||
{{ browser }}_enabled = true
|
||||
{% endfor %}
|
||||
|
||||
# Terminal Applications
|
||||
{% for terminal in desktop.applications.terminals %}
|
||||
{{ terminal }}_enabled = true
|
||||
{% endfor %}
|
||||
|
||||
# Development Tools
|
||||
{% for dev_tool in desktop.applications.development %}
|
||||
{{ dev_tool | replace('-', '_') }}_enabled = true
|
||||
{% endfor %}
|
||||
|
||||
# Media Applications
|
||||
{% for media_app in desktop.applications.media %}
|
||||
{{ media_app }}_enabled = true
|
||||
{% endfor %}
|
||||
|
||||
# Office Applications
|
||||
{% for office_app in desktop.applications.office %}
|
||||
{{ office_app }}_enabled = true
|
||||
{% endfor %}
|
||||
|
||||
# Utility Applications
|
||||
{% for utility in desktop.applications.utilities %}
|
||||
{{ utility }}_enabled = true
|
||||
{% endfor %}
|
||||
|
||||
[desktop_environment]
|
||||
type = "{{ desktop.desktop_env.type }}"
|
||||
display_manager = "{{ desktop.desktop_env.display_manager }}"
|
||||
resolution = "{{ desktop.desktop_env.resolution }}"
|
||||
{% if desktop.desktop_env.theme %}
|
||||
theme = "{{ desktop.desktop_env.theme }}"
|
||||
{% endif %}
|
||||
|
||||
[user_settings]
|
||||
username = "{{ desktop.run_user.name }}"
|
||||
home_directory = "{{ desktop.run_user.home }}"
|
||||
shell = "{{ desktop.run_user.shell }}"
|
||||
auto_login = {{ desktop.auto_login | lower }}
|
||||
|
||||
[vnc_settings]
|
||||
enabled = {{ desktop.vnc.enabled | lower }}
|
||||
port = {{ desktop.vnc.port }}
|
||||
geometry = "{{ desktop.vnc.geometry }}"
|
||||
depth = {{ desktop.vnc.depth }}
|
||||
|
||||
[graphics]
|
||||
driver = "{{ desktop.graphics.driver }}"
|
||||
acceleration = {{ desktop.graphics.acceleration | lower }}
|
||||
compositing = {{ desktop.graphics.compositing | lower }}
|
||||
53
taskservs/desktop/default/env-desktop.j2
Normal file
53
taskservs/desktop/default/env-desktop.j2
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
# Desktop Environment Variables
|
||||
DESKTOP_USER={{ desktop.run_user.name }}
|
||||
DESKTOP_HOME={{ desktop.run_user.home }}
|
||||
DESKTOP_TYPE={{ desktop.desktop_env.type }}
|
||||
DISPLAY_MANAGER={{ desktop.desktop_env.display_manager }}
|
||||
DESKTOP_RESOLUTION={{ desktop.desktop_env.resolution }}
|
||||
|
||||
# VNC Configuration
|
||||
VNC_ENABLED={{ desktop.vnc.enabled | lower }}
|
||||
VNC_PORT={{ desktop.vnc.port }}
|
||||
VNC_GEOMETRY={{ desktop.vnc.geometry }}
|
||||
VNC_DEPTH={{ desktop.vnc.depth }}
|
||||
{% if desktop.vnc.password %}VNC_PASSWORD={{ desktop.vnc.password }}{% endif %}
|
||||
|
||||
# Graphics Configuration
|
||||
GRAPHICS_DRIVER={{ desktop.graphics.driver }}
|
||||
GRAPHICS_ACCELERATION={{ desktop.graphics.acceleration | lower }}
|
||||
GRAPHICS_COMPOSITING={{ desktop.graphics.compositing | lower }}
|
||||
|
||||
# Applications Lists
|
||||
EDITORS="{{ desktop.applications.editors | join(' ') }}"
|
||||
BROWSERS="{{ desktop.applications.browsers | join(' ') }}"
|
||||
TERMINALS="{{ desktop.applications.terminals | join(' ') }}"
|
||||
DEVELOPMENT="{{ desktop.applications.development | join(' ') }}"
|
||||
MEDIA="{{ desktop.applications.media | join(' ') }}"
|
||||
OFFICE="{{ desktop.applications.office | join(' ') }}"
|
||||
UTILITIES="{{ desktop.applications.utilities | join(' ') }}"
|
||||
|
||||
# RustDesk Configuration
|
||||
RUSTDESK_ENABLED={{ desktop.rustdesk.enabled | lower }}
|
||||
RUSTDESK_PORT={{ desktop.rustdesk.port }}
|
||||
RUSTDESK_HBBR_PORT={{ desktop.rustdesk.hbbr_port }}
|
||||
{% if desktop.rustdesk.custom_server %}RUSTDESK_CUSTOM_SERVER={{ desktop.rustdesk.custom_server }}{% endif %}
|
||||
{% if desktop.rustdesk.password %}RUSTDESK_PASSWORD={{ desktop.rustdesk.password }}{% endif %}
|
||||
{% if desktop.rustdesk.permanent_password %}RUSTDESK_PERMANENT_PASSWORD={{ desktop.rustdesk.permanent_password }}{% endif %}
|
||||
RUSTDESK_ALLOW_GUEST={{ desktop.rustdesk.allow_guest | upper }}
|
||||
RUSTDESK_AUTO_START={{ desktop.rustdesk.auto_start | lower }}
|
||||
|
||||
# SSH Configuration
|
||||
SSH_ENABLED={{ desktop.ssh.enabled | lower }}
|
||||
SSH_PORT={{ desktop.ssh.port }}
|
||||
SSH_PASSWORD_AUTH={{ desktop.ssh.password_auth | lower }}
|
||||
SSH_KEY_AUTH={{ desktop.ssh.key_auth | lower }}
|
||||
SSH_ROOT_LOGIN={{ desktop.ssh.root_login }}
|
||||
SSH_MAX_AUTH_TRIES={{ desktop.ssh.max_auth_tries }}
|
||||
SSH_CLIENT_ALIVE_INTERVAL={{ desktop.ssh.client_alive_interval }}
|
||||
SSH_CLIENT_ALIVE_COUNT_MAX={{ desktop.ssh.client_alive_count_max }}
|
||||
{% if desktop.ssh.allowed_users %}SSH_ALLOWED_USERS="{{ desktop.ssh.allowed_users | join(' ') }}"{% endif %}
|
||||
{% if desktop.ssh.denied_users %}SSH_DENIED_USERS="{{ desktop.ssh.denied_users | join(' ') }}"{% endif %}
|
||||
|
||||
# System Configuration
|
||||
AUTO_LOGIN={{ desktop.auto_login | lower }}
|
||||
{% if desktop.startup_script %}STARTUP_SCRIPT={{ desktop.startup_script }}{% endif %}
|
||||
363
taskservs/desktop/default/install-desktop.sh
Executable file
363
taskservs/desktop/default/install-desktop.sh
Executable file
|
|
@ -0,0 +1,363 @@
|
|||
#!/usr/bin/env bash
|
||||
# Desktop Environment Installation Script
|
||||
# Installs minimal desktop environment with essential applications
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Load environment variables
|
||||
source /tmp/env-desktop
|
||||
|
||||
log() {
|
||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1"
|
||||
}
|
||||
|
||||
error() {
|
||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: $1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Detect OS
|
||||
detect_os() {
|
||||
if [[ -f /etc/os-release ]]; then
|
||||
. /etc/os-release
|
||||
OS=$ID
|
||||
VERSION=$VERSION_ID
|
||||
else
|
||||
error "Cannot detect OS"
|
||||
fi
|
||||
log "Detected OS: $OS $VERSION"
|
||||
}
|
||||
|
||||
# Update system packages
|
||||
update_system() {
|
||||
log "Updating system packages..."
|
||||
case $OS in
|
||||
ubuntu|debian)
|
||||
apt-get update -y
|
||||
apt-get upgrade -y
|
||||
;;
|
||||
centos|rhel|fedora)
|
||||
if command -v dnf >/dev/null 2>&1; then
|
||||
dnf update -y
|
||||
else
|
||||
yum update -y
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
error "Unsupported OS: $OS"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Install desktop environment
|
||||
install_desktop_environment() {
|
||||
log "Installing $DESKTOP_TYPE desktop environment..."
|
||||
|
||||
case $OS in
|
||||
ubuntu|debian)
|
||||
case $DESKTOP_TYPE in
|
||||
xfce)
|
||||
apt-get install -y xfce4 xfce4-goodies
|
||||
if [[ "$DISPLAY_MANAGER" == "lightdm" ]]; then
|
||||
apt-get install -y lightdm lightdm-gtk-greeter
|
||||
fi
|
||||
;;
|
||||
gnome)
|
||||
apt-get install -y ubuntu-desktop-minimal
|
||||
;;
|
||||
kde)
|
||||
apt-get install -y kde-plasma-desktop
|
||||
;;
|
||||
lxde)
|
||||
apt-get install -y lxde
|
||||
;;
|
||||
mate)
|
||||
apt-get install -y ubuntu-mate-desktop
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
centos|rhel|fedora)
|
||||
case $DESKTOP_TYPE in
|
||||
xfce)
|
||||
if command -v dnf >/dev/null 2>&1; then
|
||||
dnf groupinstall -y "Xfce Desktop"
|
||||
else
|
||||
yum groupinstall -y "Xfce Desktop"
|
||||
fi
|
||||
;;
|
||||
gnome)
|
||||
if command -v dnf >/dev/null 2>&1; then
|
||||
dnf groupinstall -y "GNOME Desktop Environment"
|
||||
else
|
||||
yum groupinstall -y "GNOME Desktop Environment"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Install VNC server
|
||||
install_vnc_server() {
|
||||
if [[ "$VNC_ENABLED" == "true" ]]; then
|
||||
log "Installing VNC server..."
|
||||
|
||||
case $OS in
|
||||
ubuntu|debian)
|
||||
apt-get install -y tightvncserver
|
||||
;;
|
||||
centos|rhel|fedora)
|
||||
if command -v dnf >/dev/null 2>&1; then
|
||||
dnf install -y tigervnc-server
|
||||
else
|
||||
yum install -y tigervnc-server
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# Configure VNC for desktop user
|
||||
setup_vnc_user
|
||||
fi
|
||||
}
|
||||
|
||||
# Setup VNC for desktop user
|
||||
setup_vnc_user() {
|
||||
log "Setting up VNC for user $DESKTOP_USER..."
|
||||
|
||||
# Create user if not exists
|
||||
if ! id "$DESKTOP_USER" &>/dev/null; then
|
||||
useradd -m -s /bin/bash "$DESKTOP_USER"
|
||||
log "Created user $DESKTOP_USER"
|
||||
fi
|
||||
|
||||
# Setup VNC directory
|
||||
sudo -u "$DESKTOP_USER" mkdir -p "$DESKTOP_HOME/.vnc"
|
||||
|
||||
# Create VNC startup script
|
||||
cat > "$DESKTOP_HOME/.vnc/xstartup" << EOF
|
||||
#!/bin/bash
|
||||
xrdb \$HOME/.Xresources
|
||||
startxfce4 &
|
||||
EOF
|
||||
|
||||
chmod +x "$DESKTOP_HOME/.vnc/xstartup"
|
||||
chown "$DESKTOP_USER:$DESKTOP_USER" "$DESKTOP_HOME/.vnc/xstartup"
|
||||
|
||||
# Set VNC password if provided
|
||||
if [[ -n "${VNC_PASSWORD:-}" ]]; then
|
||||
echo "$VNC_PASSWORD" | sudo -u "$DESKTOP_USER" vncpasswd -f > "$DESKTOP_HOME/.vnc/passwd"
|
||||
chmod 600 "$DESKTOP_HOME/.vnc/passwd"
|
||||
chown "$DESKTOP_USER:$DESKTOP_USER" "$DESKTOP_HOME/.vnc/passwd"
|
||||
fi
|
||||
|
||||
# Create VNC service
|
||||
create_vnc_service
|
||||
}
|
||||
|
||||
# Create VNC systemd service
|
||||
create_vnc_service() {
|
||||
log "Creating VNC systemd service..."
|
||||
|
||||
cat > "/etc/systemd/system/vncserver@.service" << EOF
|
||||
[Unit]
|
||||
Description=Start TightVNC server at startup
|
||||
After=syslog.target network.target
|
||||
|
||||
[Service]
|
||||
Type=forking
|
||||
User=$DESKTOP_USER
|
||||
Group=$DESKTOP_USER
|
||||
WorkingDirectory=$DESKTOP_HOME
|
||||
|
||||
PIDFile=$DESKTOP_HOME/.vnc/%H:%i.pid
|
||||
ExecStartPre=-/usr/bin/vncserver -kill :%i > /dev/null 2>&1
|
||||
ExecStart=/usr/bin/vncserver -depth $VNC_DEPTH -geometry $VNC_GEOMETRY :%i
|
||||
ExecStop=/usr/bin/vncserver -kill :%i
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable "vncserver@1.service"
|
||||
log "VNC service created and enabled"
|
||||
}
|
||||
|
||||
# Install applications
|
||||
install_applications() {
|
||||
log "Installing applications..."
|
||||
|
||||
case $OS in
|
||||
ubuntu|debian)
|
||||
# Install packages
|
||||
local packages=""
|
||||
|
||||
# Editors
|
||||
for editor in $EDITORS; do
|
||||
case $editor in
|
||||
zed)
|
||||
# Install Zed editor
|
||||
install_zed_editor
|
||||
;;
|
||||
*)
|
||||
packages="$packages $editor"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Add other application categories
|
||||
packages="$packages $BROWSERS $TERMINALS $DEVELOPMENT $MEDIA $OFFICE $UTILITIES"
|
||||
|
||||
if [[ -n "$packages" ]]; then
|
||||
apt-get install -y $packages
|
||||
fi
|
||||
;;
|
||||
centos|rhel|fedora)
|
||||
local packages="$BROWSERS $TERMINALS $DEVELOPMENT $MEDIA $OFFICE $UTILITIES"
|
||||
|
||||
# Install Zed if in editors list
|
||||
if echo "$EDITORS" | grep -q "zed"; then
|
||||
install_zed_editor
|
||||
fi
|
||||
|
||||
# Remove zed from package list and add other editors
|
||||
local filtered_editors=$(echo "$EDITORS" | sed 's/zed//g')
|
||||
packages="$packages $filtered_editors"
|
||||
|
||||
if command -v dnf >/dev/null 2>&1; then
|
||||
dnf install -y $packages
|
||||
else
|
||||
yum install -y $packages
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Install Zed editor
|
||||
install_zed_editor() {
|
||||
log "Installing Zed editor..."
|
||||
|
||||
# Download and install Zed
|
||||
case $(uname -m) in
|
||||
x86_64)
|
||||
curl -f https://zed.dev/install.sh | sh
|
||||
;;
|
||||
*)
|
||||
log "Zed editor not available for $(uname -m) architecture, skipping..."
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Configure graphics
|
||||
configure_graphics() {
|
||||
log "Configuring graphics driver: $GRAPHICS_DRIVER"
|
||||
|
||||
case $OS in
|
||||
ubuntu|debian)
|
||||
case $GRAPHICS_DRIVER in
|
||||
nvidia)
|
||||
apt-get install -y nvidia-driver-470
|
||||
;;
|
||||
amd)
|
||||
apt-get install -y mesa-vulkan-drivers xserver-xorg-video-amdgpu
|
||||
;;
|
||||
intel)
|
||||
apt-get install -y mesa-vulkan-drivers xserver-xorg-video-intel
|
||||
;;
|
||||
nouveau)
|
||||
apt-get install -y xserver-xorg-video-nouveau
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Setup auto-login if enabled
|
||||
setup_auto_login() {
|
||||
if [[ "$AUTO_LOGIN" == "true" ]]; then
|
||||
log "Setting up auto-login for $DESKTOP_USER..."
|
||||
|
||||
case $DISPLAY_MANAGER in
|
||||
lightdm)
|
||||
sed -i "s/#autologin-user=/autologin-user=$DESKTOP_USER/" /etc/lightdm/lightdm.conf
|
||||
sed -i "s/#autologin-user-timeout=0/autologin-user-timeout=0/" /etc/lightdm/lightdm.conf
|
||||
;;
|
||||
gdm)
|
||||
cat > "/etc/gdm3/custom.conf" << EOF
|
||||
[daemon]
|
||||
AutomaticLoginEnable=true
|
||||
AutomaticLogin=$DESKTOP_USER
|
||||
EOF
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
}
|
||||
|
||||
# Run remote access setup scripts
|
||||
setup_remote_access() {
|
||||
log "Setting up remote access services..."
|
||||
|
||||
# Run SSH setup if enabled
|
||||
if [[ "${SSH_ENABLED:-true}" == "true" ]]; then
|
||||
log "Running SSH setup..."
|
||||
bash /tmp/ssh-setup.sh
|
||||
fi
|
||||
|
||||
# Run RustDesk setup if enabled
|
||||
if [[ "${RUSTDESK_ENABLED:-true}" == "true" ]]; then
|
||||
log "Running RustDesk setup..."
|
||||
bash /tmp/rustdesk-setup.sh
|
||||
fi
|
||||
|
||||
# Run Zed setup
|
||||
log "Running Zed editor setup..."
|
||||
bash /tmp/zed-setup.sh
|
||||
}
|
||||
|
||||
# Display connection summary
|
||||
display_connection_summary() {
|
||||
log ""
|
||||
log "=== Desktop Environment Setup Complete ==="
|
||||
log ""
|
||||
log "Remote Access Options:"
|
||||
|
||||
if [[ "${VNC_ENABLED:-true}" == "true" ]]; then
|
||||
log " VNC Server: Port $VNC_PORT"
|
||||
log " Start with: systemctl start vncserver@1.service"
|
||||
fi
|
||||
|
||||
if [[ "${RUSTDESK_ENABLED:-true}" == "true" ]]; then
|
||||
log " RustDesk: Ports $RUSTDESK_PORT (main), $RUSTDESK_HBBR_PORT (hbbr)"
|
||||
log " Get ID: sudo -u $DESKTOP_USER rustdesk --get-id"
|
||||
fi
|
||||
|
||||
if [[ "${SSH_ENABLED:-true}" == "true" ]]; then
|
||||
log " SSH Server: Port $SSH_PORT"
|
||||
log " Connect: ssh $DESKTOP_USER@<server-ip> -p $SSH_PORT"
|
||||
fi
|
||||
|
||||
log ""
|
||||
log "Desktop Environment: $DESKTOP_TYPE"
|
||||
log "Desktop User: $DESKTOP_USER"
|
||||
log "Applications installed: Zed editor and standard desktop apps"
|
||||
}
|
||||
|
||||
# Main installation function
|
||||
main() {
|
||||
log "Starting desktop environment installation..."
|
||||
|
||||
detect_os
|
||||
update_system
|
||||
install_desktop_environment
|
||||
install_vnc_server
|
||||
install_applications
|
||||
configure_graphics
|
||||
setup_auto_login
|
||||
setup_remote_access
|
||||
|
||||
display_connection_summary
|
||||
log "Desktop environment installation completed successfully!"
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
131
taskservs/desktop/default/prepare
Executable file
131
taskservs/desktop/default/prepare
Executable file
|
|
@ -0,0 +1,131 @@
|
|||
#!/usr/bin/env bash
|
||||
# Desktop taskserv preparation script
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
log() {
|
||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] PREPARE: $1"
|
||||
}
|
||||
|
||||
# Create desktop user home directory structure
|
||||
prepare_user_directories() {
|
||||
local desktop_user="${DESKTOP_USER:-desktop}"
|
||||
local desktop_home="${DESKTOP_HOME:-/home/$desktop_user}"
|
||||
|
||||
log "Preparing directories for user $desktop_user"
|
||||
|
||||
# Create standard user directories
|
||||
mkdir -p "$desktop_home"/{Desktop,Documents,Downloads,Pictures,Videos,Music}
|
||||
mkdir -p "$desktop_home"/.config
|
||||
mkdir -p "$desktop_home"/.local/{bin,share}
|
||||
|
||||
# Set proper ownership if user exists
|
||||
if id "$desktop_user" &>/dev/null; then
|
||||
chown -R "$desktop_user:$desktop_user" "$desktop_home"
|
||||
fi
|
||||
}
|
||||
|
||||
# Download application assets
|
||||
download_assets() {
|
||||
log "Downloading application assets..."
|
||||
|
||||
# Create assets directory
|
||||
mkdir -p /tmp/desktop-assets
|
||||
|
||||
# Download Zed editor GPG key for verification
|
||||
if command -v curl >/dev/null 2>&1; then
|
||||
curl -fsSL https://zed.dev/install.sh > /tmp/desktop-assets/zed-install.sh
|
||||
chmod +x /tmp/desktop-assets/zed-install.sh
|
||||
fi
|
||||
}
|
||||
|
||||
# Prepare configuration templates
|
||||
prepare_configs() {
|
||||
log "Preparing configuration templates..."
|
||||
|
||||
# Create XFCE configuration template
|
||||
mkdir -p /tmp/desktop-configs/xfce4
|
||||
|
||||
cat > /tmp/desktop-configs/xfce4/desktop.xml << 'EOF'
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<channel name="xfce4-desktop" version="1.0">
|
||||
<property name="backdrop" type="empty">
|
||||
<property name="screen0" type="empty">
|
||||
<property name="monitor0" type="empty">
|
||||
<property name="workspace0" type="empty">
|
||||
<property name="color-style" type="int" value="0"/>
|
||||
<property name="image-style" type="int" value="5"/>
|
||||
<property name="last-image" type="string" value="/usr/share/pixmaps/xfce-blue.jpg"/>
|
||||
</property>
|
||||
</property>
|
||||
</property>
|
||||
</property>
|
||||
</channel>
|
||||
EOF
|
||||
|
||||
# Create application menu template
|
||||
cat > /tmp/desktop-configs/applications.menu << 'EOF'
|
||||
<!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/menu-spec/menu-1.0.dtd">
|
||||
<Menu>
|
||||
<Name>Applications</Name>
|
||||
<Directory>X-GNOME-Menu-Applications.directory</Directory>
|
||||
|
||||
<Menu>
|
||||
<Name>Development</Name>
|
||||
<Directory>Development.directory</Directory>
|
||||
<Include>
|
||||
<Category>Development</Category>
|
||||
</Include>
|
||||
</Menu>
|
||||
|
||||
<Menu>
|
||||
<Name>Graphics</Name>
|
||||
<Directory>Graphics.directory</Directory>
|
||||
<Include>
|
||||
<Category>Graphics</Category>
|
||||
</Include>
|
||||
</Menu>
|
||||
|
||||
<Menu>
|
||||
<Name>Internet</Name>
|
||||
<Directory>Network.directory</Directory>
|
||||
<Include>
|
||||
<Category>Network</Category>
|
||||
</Include>
|
||||
</Menu>
|
||||
|
||||
<Menu>
|
||||
<Name>Office</Name>
|
||||
<Directory>Office.directory</Directory>
|
||||
<Include>
|
||||
<Category>Office</Category>
|
||||
</Include>
|
||||
</Menu>
|
||||
|
||||
<Menu>
|
||||
<Name>System</Name>
|
||||
<Directory>System-Tools.directory</Directory>
|
||||
<Include>
|
||||
<Category>System</Category>
|
||||
</Include>
|
||||
</Menu>
|
||||
</Menu>
|
||||
EOF
|
||||
}
|
||||
|
||||
# Main preparation function
|
||||
main() {
|
||||
log "Starting desktop taskserv preparation..."
|
||||
|
||||
prepare_user_directories
|
||||
download_assets
|
||||
prepare_configs
|
||||
|
||||
log "Desktop taskserv preparation completed!"
|
||||
}
|
||||
|
||||
# Run main function if script is executed directly
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
main "$@"
|
||||
fi
|
||||
2
taskservs/desktop/default/provisioning.toml
Normal file
2
taskservs/desktop/default/provisioning.toml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
info = "desktop"
|
||||
release = "1.0"
|
||||
281
taskservs/desktop/default/rustdesk-setup.sh
Executable file
281
taskservs/desktop/default/rustdesk-setup.sh
Executable file
|
|
@ -0,0 +1,281 @@
|
|||
#!/usr/bin/env bash
|
||||
# RustDesk Remote Desktop Setup Script
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Load environment variables
|
||||
source /tmp/env-desktop
|
||||
|
||||
log() {
|
||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] RUSTDESK: $1"
|
||||
}
|
||||
|
||||
error() {
|
||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] RUSTDESK ERROR: $1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Detect OS and architecture
|
||||
detect_system() {
|
||||
if [[ -f /etc/os-release ]]; then
|
||||
. /etc/os-release
|
||||
OS=$ID
|
||||
VERSION=$VERSION_ID
|
||||
else
|
||||
error "Cannot detect OS"
|
||||
fi
|
||||
|
||||
ARCH=$(uname -m)
|
||||
case $ARCH in
|
||||
x86_64)
|
||||
RUSTDESK_ARCH="x86_64"
|
||||
;;
|
||||
aarch64|arm64)
|
||||
RUSTDESK_ARCH="aarch64"
|
||||
;;
|
||||
*)
|
||||
error "Unsupported architecture: $ARCH"
|
||||
;;
|
||||
esac
|
||||
|
||||
log "Detected system: $OS $VERSION ($RUSTDESK_ARCH)"
|
||||
}
|
||||
|
||||
# Download and install RustDesk
|
||||
install_rustdesk() {
|
||||
log "Installing RustDesk for $OS..."
|
||||
|
||||
local temp_dir="/tmp/rustdesk-install"
|
||||
mkdir -p "$temp_dir"
|
||||
cd "$temp_dir"
|
||||
|
||||
case $OS in
|
||||
ubuntu|debian)
|
||||
# Download RustDesk .deb package
|
||||
local rustdesk_url="https://github.com/rustdesk/rustdesk/releases/latest/download/rustdesk-${RUSTDESK_ARCH}.deb"
|
||||
log "Downloading RustDesk from $rustdesk_url"
|
||||
|
||||
curl -fsSL -o rustdesk.deb "$rustdesk_url" || error "Failed to download RustDesk"
|
||||
|
||||
# Install dependencies
|
||||
apt-get update
|
||||
apt-get install -y libgtk-3-0 libxcb-randr0 libxdo3 libxfixes3 libasound2-dev libsystemd0
|
||||
|
||||
# Install RustDesk
|
||||
dpkg -i rustdesk.deb || apt-get install -f -y
|
||||
;;
|
||||
|
||||
centos|rhel|fedora)
|
||||
# Download RustDesk .rpm package
|
||||
local rustdesk_url="https://github.com/rustdesk/rustdesk/releases/latest/download/rustdesk-${RUSTDESK_ARCH}.rpm"
|
||||
log "Downloading RustDesk from $rustdesk_url"
|
||||
|
||||
curl -fsSL -o rustdesk.rpm "$rustdesk_url" || error "Failed to download RustDesk"
|
||||
|
||||
# Install dependencies
|
||||
if command -v dnf >/dev/null 2>&1; then
|
||||
dnf install -y gtk3 libxcb libXfixes alsa-lib systemd
|
||||
dnf install -y rustdesk.rpm
|
||||
else
|
||||
yum install -y gtk3 libxcb libXfixes alsa-lib systemd
|
||||
yum localinstall -y rustdesk.rpm
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
error "Unsupported OS for RustDesk installation: $OS"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Clean up
|
||||
cd /
|
||||
rm -rf "$temp_dir"
|
||||
|
||||
log "RustDesk installation completed"
|
||||
}
|
||||
|
||||
# Configure RustDesk
|
||||
configure_rustdesk() {
|
||||
local desktop_user="${DESKTOP_USER:-desktop}"
|
||||
local desktop_home="${DESKTOP_HOME:-/home/$desktop_user}"
|
||||
|
||||
log "Configuring RustDesk for user $desktop_user"
|
||||
|
||||
# Create RustDesk config directory
|
||||
sudo -u "$desktop_user" mkdir -p "$desktop_home/.config/rustdesk"
|
||||
|
||||
# Create RustDesk configuration
|
||||
local config_file="$desktop_home/.config/rustdesk/RustDesk2.toml"
|
||||
|
||||
cat > "$config_file" << EOF
|
||||
[options]
|
||||
custom-rendezvous-server = "${RUSTDESK_CUSTOM_SERVER:-}"
|
||||
relay-server = "${RUSTDESK_CUSTOM_SERVER:-}"
|
||||
api-server = "${RUSTDESK_CUSTOM_SERVER:-}"
|
||||
key = ""
|
||||
auto-disconnect-timeout = "10"
|
||||
keep-screen-on = "Y"
|
||||
wake-on-lan = "Y"
|
||||
allow-guest-access = "${RUSTDESK_ALLOW_GUEST:-N}"
|
||||
|
||||
[ui]
|
||||
hide-cm = ""
|
||||
hide-connection-management = ""
|
||||
hide-network-setting = ""
|
||||
hide-password-setting = ""
|
||||
hide-about-link = ""
|
||||
hide-software-update = ""
|
||||
|
||||
[network]
|
||||
rendezvous-server = "${RUSTDESK_CUSTOM_SERVER:-}"
|
||||
nat-type = ""
|
||||
serial = ""
|
||||
|
||||
[security]
|
||||
access-mode = "custom"
|
||||
EOF
|
||||
|
||||
# Set custom server if provided
|
||||
if [[ -n "${RUSTDESK_CUSTOM_SERVER:-}" ]]; then
|
||||
log "Using custom RustDesk server: $RUSTDESK_CUSTOM_SERVER"
|
||||
fi
|
||||
|
||||
# Set permanent password if provided
|
||||
if [[ -n "${RUSTDESK_PERMANENT_PASSWORD:-}" ]]; then
|
||||
log "Setting permanent password for RustDesk"
|
||||
# Note: RustDesk permanent password is set via GUI or command line
|
||||
# This is a placeholder for the configuration
|
||||
echo "permanent_password = \"$RUSTDESK_PERMANENT_PASSWORD\"" >> "$config_file"
|
||||
fi
|
||||
|
||||
chown -R "$desktop_user:$desktop_user" "$desktop_home/.config/rustdesk"
|
||||
|
||||
log "RustDesk configuration created"
|
||||
}
|
||||
|
||||
# Create RustDesk systemd service
|
||||
create_rustdesk_service() {
|
||||
local desktop_user="${DESKTOP_USER:-desktop}"
|
||||
|
||||
log "Creating RustDesk systemd service for user $desktop_user"
|
||||
|
||||
# Create systemd user service
|
||||
local service_dir="/home/$desktop_user/.config/systemd/user"
|
||||
mkdir -p "$service_dir"
|
||||
|
||||
cat > "$service_dir/rustdesk.service" << EOF
|
||||
[Unit]
|
||||
Description=RustDesk Remote Desktop
|
||||
After=graphical-session.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/bin/rustdesk --service
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
Environment=DISPLAY=:0
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
EOF
|
||||
|
||||
chown -R "$desktop_user:$desktop_user" "/home/$desktop_user/.config/systemd"
|
||||
|
||||
# Enable user service
|
||||
sudo -u "$desktop_user" systemctl --user daemon-reload
|
||||
|
||||
if [[ "${RUSTDESK_AUTO_START:-true}" == "true" ]]; then
|
||||
sudo -u "$desktop_user" systemctl --user enable rustdesk.service
|
||||
log "RustDesk service enabled for auto-start"
|
||||
fi
|
||||
|
||||
log "RustDesk systemd service created"
|
||||
}
|
||||
|
||||
# Setup RustDesk desktop shortcut
|
||||
create_desktop_shortcut() {
|
||||
local desktop_user="${DESKTOP_USER:-desktop}"
|
||||
local desktop_home="${DESKTOP_HOME:-/home/$desktop_user}"
|
||||
|
||||
log "Creating RustDesk desktop shortcut"
|
||||
|
||||
cat > "$desktop_home/Desktop/rustdesk.desktop" << 'EOF'
|
||||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Type=Application
|
||||
Name=RustDesk
|
||||
Comment=Remote Desktop Software
|
||||
Exec=rustdesk
|
||||
Icon=rustdesk
|
||||
Terminal=false
|
||||
StartupNotify=true
|
||||
Categories=Network;RemoteAccess;
|
||||
Keywords=remote;desktop;vnc;connection;
|
||||
EOF
|
||||
|
||||
chmod +x "$desktop_home/Desktop/rustdesk.desktop"
|
||||
chown "$desktop_user:$desktop_user" "$desktop_home/Desktop/rustdesk.desktop"
|
||||
|
||||
log "RustDesk desktop shortcut created"
|
||||
}
|
||||
|
||||
# Setup firewall rules for RustDesk
|
||||
setup_firewall() {
|
||||
log "Setting up firewall rules for RustDesk"
|
||||
|
||||
local rustdesk_port="${RUSTDESK_PORT:-21116}"
|
||||
local rustdesk_hbbr_port="${RUSTDESK_HBBR_PORT:-21117}"
|
||||
|
||||
# Try different firewall tools
|
||||
if command -v ufw >/dev/null 2>&1; then
|
||||
ufw allow "$rustdesk_port/tcp" comment "RustDesk"
|
||||
ufw allow "$rustdesk_port/udp" comment "RustDesk"
|
||||
ufw allow "$rustdesk_hbbr_port/tcp" comment "RustDesk hbbr"
|
||||
log "UFW rules added for RustDesk ports $rustdesk_port and $rustdesk_hbbr_port"
|
||||
elif command -v firewall-cmd >/dev/null 2>&1; then
|
||||
firewall-cmd --permanent --add-port="$rustdesk_port/tcp"
|
||||
firewall-cmd --permanent --add-port="$rustdesk_port/udp"
|
||||
firewall-cmd --permanent --add-port="$rustdesk_hbbr_port/tcp"
|
||||
firewall-cmd --reload
|
||||
log "FirewallD rules added for RustDesk ports $rustdesk_port and $rustdesk_hbbr_port"
|
||||
else
|
||||
log "WARNING: No supported firewall tool found. Manual firewall configuration may be needed."
|
||||
fi
|
||||
}
|
||||
|
||||
# Get RustDesk ID and password
|
||||
get_rustdesk_info() {
|
||||
log "RustDesk installation completed!"
|
||||
log "To get your RustDesk ID and password, run:"
|
||||
log " sudo -u $DESKTOP_USER rustdesk --get-id"
|
||||
log " sudo -u $DESKTOP_USER rustdesk --password"
|
||||
log ""
|
||||
log "RustDesk will be available on ports:"
|
||||
log " Main port: ${RUSTDESK_PORT:-21116}"
|
||||
log " hbbr port: ${RUSTDESK_HBBR_PORT:-21117}"
|
||||
}
|
||||
|
||||
# Main installation function
|
||||
main() {
|
||||
if [[ "${RUSTDESK_ENABLED:-true}" != "true" ]]; then
|
||||
log "RustDesk is disabled, skipping installation"
|
||||
return 0
|
||||
fi
|
||||
|
||||
log "Starting RustDesk installation and configuration..."
|
||||
|
||||
detect_system
|
||||
install_rustdesk
|
||||
configure_rustdesk
|
||||
create_rustdesk_service
|
||||
create_desktop_shortcut
|
||||
setup_firewall
|
||||
get_rustdesk_info
|
||||
|
||||
log "RustDesk setup completed successfully!"
|
||||
}
|
||||
|
||||
# Run main function if script is executed directly
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
main "$@"
|
||||
fi
|
||||
344
taskservs/desktop/default/ssh-setup.sh
Executable file
344
taskservs/desktop/default/ssh-setup.sh
Executable file
|
|
@ -0,0 +1,344 @@
|
|||
#!/usr/bin/env bash
|
||||
# SSH Server Setup and Hardening Script
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Load environment variables
|
||||
source /tmp/env-desktop
|
||||
|
||||
log() {
|
||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] SSH: $1"
|
||||
}
|
||||
|
||||
error() {
|
||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] SSH ERROR: $1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Detect OS
|
||||
detect_os() {
|
||||
if [[ -f /etc/os-release ]]; then
|
||||
. /etc/os-release
|
||||
OS=$ID
|
||||
VERSION=$VERSION_ID
|
||||
else
|
||||
error "Cannot detect OS"
|
||||
fi
|
||||
log "Detected OS: $OS $VERSION"
|
||||
}
|
||||
|
||||
# Install SSH server
|
||||
install_ssh_server() {
|
||||
log "Installing SSH server..."
|
||||
|
||||
case $OS in
|
||||
ubuntu|debian)
|
||||
apt-get update
|
||||
apt-get install -y openssh-server openssh-client
|
||||
;;
|
||||
centos|rhel|fedora)
|
||||
if command -v dnf >/dev/null 2>&1; then
|
||||
dnf install -y openssh-server openssh-clients
|
||||
else
|
||||
yum install -y openssh-server openssh-clients
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
error "Unsupported OS for SSH installation: $OS"
|
||||
;;
|
||||
esac
|
||||
|
||||
log "SSH server installed"
|
||||
}
|
||||
|
||||
# Configure SSH server
|
||||
configure_ssh_server() {
|
||||
log "Configuring SSH server..."
|
||||
|
||||
local ssh_port="${SSH_PORT:-22}"
|
||||
local password_auth="${SSH_PASSWORD_AUTH:-yes}"
|
||||
local key_auth="${SSH_KEY_AUTH:-yes}"
|
||||
local root_login="${SSH_ROOT_LOGIN:-prohibit-password}"
|
||||
local max_auth_tries="${SSH_MAX_AUTH_TRIES:-3}"
|
||||
local client_alive_interval="${SSH_CLIENT_ALIVE_INTERVAL:-300}"
|
||||
local client_alive_count_max="${SSH_CLIENT_ALIVE_COUNT_MAX:-2}"
|
||||
|
||||
# Backup original config
|
||||
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backup.$(date +%Y%m%d_%H%M%S)
|
||||
|
||||
# Create new SSH configuration
|
||||
cat > /etc/ssh/sshd_config << EOF
|
||||
# SSH Configuration for Desktop Environment
|
||||
# Generated by provisioning system
|
||||
|
||||
# Connection settings
|
||||
Port $ssh_port
|
||||
AddressFamily any
|
||||
ListenAddress 0.0.0.0
|
||||
ListenAddress ::
|
||||
|
||||
# Host keys
|
||||
HostKey /etc/ssh/ssh_host_rsa_key
|
||||
HostKey /etc/ssh/ssh_host_ecdsa_key
|
||||
HostKey /etc/ssh/ssh_host_ed25519_key
|
||||
|
||||
# Ciphers and keying
|
||||
RekeyLimit default none
|
||||
|
||||
# Logging
|
||||
SyslogFacility AUTH
|
||||
LogLevel INFO
|
||||
|
||||
# Authentication
|
||||
LoginGraceTime 2m
|
||||
PermitRootLogin $root_login
|
||||
StrictModes yes
|
||||
MaxAuthTries $max_auth_tries
|
||||
MaxSessions 10
|
||||
|
||||
PubkeyAuthentication $key_auth
|
||||
AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2
|
||||
|
||||
# Password authentication
|
||||
PasswordAuthentication $password_auth
|
||||
PermitEmptyPasswords no
|
||||
ChallengeResponseAuthentication no
|
||||
|
||||
# Kerberos and GSSAPI (disabled for security)
|
||||
KerberosAuthentication no
|
||||
GSSAPIAuthentication no
|
||||
|
||||
# Connection timeouts
|
||||
ClientAliveInterval $client_alive_interval
|
||||
ClientAliveCountMax $client_alive_count_max
|
||||
TCPKeepAlive yes
|
||||
|
||||
# Compression
|
||||
Compression delayed
|
||||
|
||||
# Environment
|
||||
AcceptEnv LANG LC_*
|
||||
AcceptEnv XMODIFIERS
|
||||
|
||||
# X11 forwarding (enabled for desktop environment)
|
||||
X11Forwarding yes
|
||||
X11DisplayOffset 10
|
||||
X11UseLocalhost yes
|
||||
|
||||
# Agent forwarding (be careful with security)
|
||||
AllowAgentForwarding yes
|
||||
|
||||
# TCP forwarding
|
||||
AllowTcpForwarding yes
|
||||
GatewayPorts no
|
||||
|
||||
# Tunnel device forwarding
|
||||
PermitTunnel no
|
||||
|
||||
# chroot directory
|
||||
ChrootDirectory none
|
||||
|
||||
# Banner
|
||||
Banner none
|
||||
|
||||
# Subsystem
|
||||
Subsystem sftp /usr/lib/openssh/sftp-server
|
||||
|
||||
# User/Group restrictions
|
||||
EOF
|
||||
|
||||
# Add user restrictions if specified
|
||||
if [[ -n "${SSH_ALLOWED_USERS:-}" ]]; then
|
||||
echo "AllowUsers $SSH_ALLOWED_USERS" >> /etc/ssh/sshd_config
|
||||
log "SSH access restricted to users: $SSH_ALLOWED_USERS"
|
||||
fi
|
||||
|
||||
if [[ -n "${SSH_DENIED_USERS:-}" ]]; then
|
||||
echo "DenyUsers $SSH_DENIED_USERS" >> /etc/ssh/sshd_config
|
||||
log "SSH access denied for users: $SSH_DENIED_USERS"
|
||||
fi
|
||||
|
||||
# Fix sftp-server path for different distributions
|
||||
case $OS in
|
||||
ubuntu|debian)
|
||||
sed -i 's|/usr/lib/openssh/sftp-server|/usr/lib/openssh/sftp-server|' /etc/ssh/sshd_config
|
||||
;;
|
||||
centos|rhel|fedora)
|
||||
sed -i 's|/usr/lib/openssh/sftp-server|/usr/libexec/openssh/sftp-server|' /etc/ssh/sshd_config
|
||||
;;
|
||||
esac
|
||||
|
||||
# Test SSH configuration
|
||||
sshd -t || error "SSH configuration is invalid"
|
||||
|
||||
log "SSH server configured"
|
||||
}
|
||||
|
||||
# Setup SSH keys for desktop user
|
||||
setup_ssh_keys() {
|
||||
local desktop_user="${DESKTOP_USER:-desktop}"
|
||||
local desktop_home="${DESKTOP_HOME:-/home/$desktop_user}"
|
||||
|
||||
log "Setting up SSH keys for user $desktop_user"
|
||||
|
||||
# Create user if not exists
|
||||
if ! id "$desktop_user" &>/dev/null; then
|
||||
useradd -m -s /bin/bash "$desktop_user"
|
||||
log "Created user $desktop_user"
|
||||
fi
|
||||
|
||||
# Create .ssh directory
|
||||
sudo -u "$desktop_user" mkdir -p "$desktop_home/.ssh"
|
||||
chmod 700 "$desktop_home/.ssh"
|
||||
|
||||
# Generate SSH key pair if not exists
|
||||
if [[ ! -f "$desktop_home/.ssh/id_rsa" ]]; then
|
||||
log "Generating SSH key pair for $desktop_user"
|
||||
sudo -u "$desktop_user" ssh-keygen -t rsa -b 4096 -f "$desktop_home/.ssh/id_rsa" -N "" -C "$desktop_user@$(hostname)"
|
||||
log "SSH key pair generated"
|
||||
fi
|
||||
|
||||
# Create authorized_keys file
|
||||
sudo -u "$desktop_user" touch "$desktop_home/.ssh/authorized_keys"
|
||||
chmod 600 "$desktop_home/.ssh/authorized_keys"
|
||||
|
||||
# Set proper ownership
|
||||
chown -R "$desktop_user:$desktop_user" "$desktop_home/.ssh"
|
||||
|
||||
log "SSH keys setup completed for $desktop_user"
|
||||
}
|
||||
|
||||
# Setup fail2ban for SSH protection
|
||||
setup_fail2ban() {
|
||||
log "Setting up fail2ban for SSH protection..."
|
||||
|
||||
case $OS in
|
||||
ubuntu|debian)
|
||||
apt-get install -y fail2ban
|
||||
;;
|
||||
centos|rhel|fedora)
|
||||
if command -v dnf >/dev/null 2>&1; then
|
||||
dnf install -y fail2ban
|
||||
else
|
||||
yum install -y fail2ban
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# Create fail2ban configuration for SSH
|
||||
cat > /etc/fail2ban/jail.local << EOF
|
||||
[DEFAULT]
|
||||
# Ban time in seconds (10 minutes)
|
||||
bantime = 600
|
||||
|
||||
# Find time window (10 minutes)
|
||||
findtime = 600
|
||||
|
||||
# Max retry attempts
|
||||
maxretry = 3
|
||||
|
||||
[sshd]
|
||||
enabled = true
|
||||
port = ${SSH_PORT:-22}
|
||||
filter = sshd
|
||||
logpath = /var/log/auth.log
|
||||
maxretry = ${SSH_MAX_AUTH_TRIES:-3}
|
||||
bantime = 3600
|
||||
EOF
|
||||
|
||||
# Start and enable fail2ban
|
||||
systemctl enable fail2ban
|
||||
systemctl start fail2ban
|
||||
|
||||
log "fail2ban configured and started"
|
||||
}
|
||||
|
||||
# Setup firewall rules for SSH
|
||||
setup_firewall() {
|
||||
log "Setting up firewall rules for SSH"
|
||||
|
||||
local ssh_port="${SSH_PORT:-22}"
|
||||
|
||||
# Try different firewall tools
|
||||
if command -v ufw >/dev/null 2>&1; then
|
||||
ufw allow "$ssh_port/tcp" comment "SSH"
|
||||
log "UFW rule added for SSH port $ssh_port"
|
||||
elif command -v firewall-cmd >/dev/null 2>&1; then
|
||||
if [[ "$ssh_port" != "22" ]]; then
|
||||
firewall-cmd --permanent --add-port="$ssh_port/tcp"
|
||||
else
|
||||
firewall-cmd --permanent --add-service=ssh
|
||||
fi
|
||||
firewall-cmd --reload
|
||||
log "FirewallD rule added for SSH port $ssh_port"
|
||||
else
|
||||
log "WARNING: No supported firewall tool found. Manual firewall configuration may be needed."
|
||||
fi
|
||||
}
|
||||
|
||||
# Start and enable SSH service
|
||||
start_ssh_service() {
|
||||
log "Starting SSH service..."
|
||||
|
||||
# Enable and start SSH service
|
||||
systemctl enable ssh sshd 2>/dev/null || systemctl enable sshd
|
||||
systemctl restart ssh sshd 2>/dev/null || systemctl restart sshd
|
||||
|
||||
# Check service status
|
||||
if systemctl is-active --quiet ssh || systemctl is-active --quiet sshd; then
|
||||
log "SSH service is running"
|
||||
else
|
||||
error "Failed to start SSH service"
|
||||
fi
|
||||
|
||||
log "SSH service started and enabled"
|
||||
}
|
||||
|
||||
# Display connection information
|
||||
display_connection_info() {
|
||||
local desktop_user="${DESKTOP_USER:-desktop}"
|
||||
local ssh_port="${SSH_PORT:-22}"
|
||||
local server_ip=$(ip route get 1.1.1.1 | grep -oP 'src \K\S+' 2>/dev/null || echo "$(hostname -I | awk '{print $1}')")
|
||||
|
||||
log "SSH setup completed!"
|
||||
log ""
|
||||
log "SSH Connection Information:"
|
||||
log " Server IP: $server_ip"
|
||||
log " SSH Port: $ssh_port"
|
||||
log " Desktop User: $desktop_user"
|
||||
log ""
|
||||
log "Connect via SSH:"
|
||||
log " ssh $desktop_user@$server_ip -p $ssh_port"
|
||||
log ""
|
||||
log "Public key location (for key-based auth):"
|
||||
log " /home/$desktop_user/.ssh/id_rsa.pub"
|
||||
log ""
|
||||
log "To copy your public key to another machine:"
|
||||
log " ssh-copy-id -i /home/$desktop_user/.ssh/id_rsa.pub user@remote-host"
|
||||
}
|
||||
|
||||
# Main installation function
|
||||
main() {
|
||||
if [[ "${SSH_ENABLED:-true}" != "true" ]]; then
|
||||
log "SSH is disabled, skipping installation"
|
||||
return 0
|
||||
fi
|
||||
|
||||
log "Starting SSH server installation and configuration..."
|
||||
|
||||
detect_os
|
||||
install_ssh_server
|
||||
configure_ssh_server
|
||||
setup_ssh_keys
|
||||
setup_fail2ban
|
||||
setup_firewall
|
||||
start_ssh_service
|
||||
display_connection_info
|
||||
|
||||
log "SSH setup completed successfully!"
|
||||
}
|
||||
|
||||
# Run main function if script is executed directly
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
main "$@"
|
||||
fi
|
||||
182
taskservs/desktop/default/zed-setup.sh
Executable file
182
taskservs/desktop/default/zed-setup.sh
Executable file
|
|
@ -0,0 +1,182 @@
|
|||
#!/usr/bin/env bash
|
||||
# Zed Editor Setup Script for Desktop Environment
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
log() {
|
||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ZED: $1"
|
||||
}
|
||||
|
||||
error() {
|
||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ZED ERROR: $1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Install Zed editor
|
||||
install_zed() {
|
||||
local desktop_user="${DESKTOP_USER:-desktop}"
|
||||
|
||||
log "Installing Zed editor for user $desktop_user"
|
||||
|
||||
# Check architecture
|
||||
local arch=$(uname -m)
|
||||
case $arch in
|
||||
x86_64)
|
||||
log "Installing Zed for x86_64 architecture"
|
||||
;;
|
||||
aarch64|arm64)
|
||||
log "Installing Zed for ARM64 architecture"
|
||||
;;
|
||||
*)
|
||||
log "WARNING: Zed may not be available for $arch architecture"
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
||||
# Download and install Zed
|
||||
if command -v curl >/dev/null 2>&1; then
|
||||
# Install system-wide
|
||||
curl -f https://zed.dev/install.sh | sh
|
||||
|
||||
# Also install for the desktop user
|
||||
sudo -u "$desktop_user" bash -c 'curl -f https://zed.dev/install.sh | sh'
|
||||
else
|
||||
error "curl not found - required for Zed installation"
|
||||
fi
|
||||
}
|
||||
|
||||
# Configure Zed for desktop user
|
||||
configure_zed() {
|
||||
local desktop_user="${DESKTOP_USER:-desktop}"
|
||||
local desktop_home="${DESKTOP_HOME:-/home/$desktop_user}"
|
||||
|
||||
log "Configuring Zed editor for $desktop_user"
|
||||
|
||||
# Create Zed config directory
|
||||
sudo -u "$desktop_user" mkdir -p "$desktop_home/.config/zed"
|
||||
|
||||
# Create basic Zed configuration
|
||||
cat > "$desktop_home/.config/zed/settings.json" << 'EOF'
|
||||
{
|
||||
"assistant": {
|
||||
"default_model": {
|
||||
"provider": "zed.dev",
|
||||
"model": "claude-3-5-sonnet-20241022"
|
||||
},
|
||||
"version": "2"
|
||||
},
|
||||
"vim_mode": false,
|
||||
"ui_font_size": 16,
|
||||
"buffer_font_size": 14,
|
||||
"theme": {
|
||||
"mode": "system",
|
||||
"light": "One Light",
|
||||
"dark": "One Dark"
|
||||
},
|
||||
"project_panel": {
|
||||
"dock": "left"
|
||||
},
|
||||
"outline_panel": {
|
||||
"dock": "right"
|
||||
},
|
||||
"collaboration_panel": {
|
||||
"dock": "left"
|
||||
},
|
||||
"chat_panel": {
|
||||
"dock": "right"
|
||||
},
|
||||
"notification_panel": {
|
||||
"dock": "right"
|
||||
},
|
||||
"terminal": {
|
||||
"dock": "bottom"
|
||||
},
|
||||
"git": {
|
||||
"git_gutter": "tracked_files",
|
||||
"inline_blame": {
|
||||
"enabled": true
|
||||
}
|
||||
},
|
||||
"lsp": {
|
||||
"rust-analyzer": {
|
||||
"binary": {
|
||||
"path_lookup": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"languages": {
|
||||
"Python": {
|
||||
"format_on_save": "on",
|
||||
"formatter": "auto"
|
||||
},
|
||||
"JavaScript": {
|
||||
"format_on_save": "on"
|
||||
},
|
||||
"TypeScript": {
|
||||
"format_on_save": "on"
|
||||
},
|
||||
"Rust": {
|
||||
"format_on_save": "on"
|
||||
},
|
||||
"Go": {
|
||||
"format_on_save": "on"
|
||||
}
|
||||
},
|
||||
"auto_update": true,
|
||||
"telemetry": {
|
||||
"diagnostics": false,
|
||||
"metrics": false
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
# Set proper ownership
|
||||
chown -R "$desktop_user:$desktop_user" "$desktop_home/.config/zed"
|
||||
|
||||
log "Zed configuration created"
|
||||
}
|
||||
|
||||
# Create desktop shortcut for Zed
|
||||
create_desktop_shortcut() {
|
||||
local desktop_user="${DESKTOP_USER:-desktop}"
|
||||
local desktop_home="${DESKTOP_HOME:-/home/$desktop_user}"
|
||||
|
||||
log "Creating desktop shortcut for Zed"
|
||||
|
||||
# Create desktop shortcut
|
||||
cat > "$desktop_home/Desktop/zed.desktop" << 'EOF'
|
||||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Type=Application
|
||||
Name=Zed
|
||||
Comment=A high-performance, multiplayer code editor
|
||||
Exec=zed %F
|
||||
Icon=zed
|
||||
Terminal=false
|
||||
MimeType=text/plain;text/x-chdr;text/x-csrc;text/x-c++hdr;text/x-c++src;text/x-java;text/x-dsrc;text/x-pascal;text/x-perl;text/x-python;application/x-php;application/x-httpd-php3;application/x-httpd-php4;application/x-httpd-php5;application/x-ruby;text/x-tcl;text/x-tex;application/x-sh;text/x-chdr;text/x-csrc;text/css;text/html;text/xml;text/javascript;application/javascript;application/json;text/x-markdown;text/x-rust;text/x-go;
|
||||
StartupNotify=true
|
||||
Categories=Development;TextEditor;
|
||||
Keywords=editor;development;programming;
|
||||
EOF
|
||||
|
||||
chmod +x "$desktop_home/Desktop/zed.desktop"
|
||||
chown "$desktop_user:$desktop_user" "$desktop_home/Desktop/zed.desktop"
|
||||
|
||||
log "Desktop shortcut created"
|
||||
}
|
||||
|
||||
# Main function
|
||||
main() {
|
||||
log "Starting Zed editor setup..."
|
||||
|
||||
install_zed
|
||||
configure_zed
|
||||
create_desktop_shortcut
|
||||
|
||||
log "Zed editor setup completed!"
|
||||
}
|
||||
|
||||
# Run main function if script is executed directly
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
main "$@"
|
||||
fi
|
||||
109
taskservs/desktop/info.md
Normal file
109
taskservs/desktop/info.md
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
Perfect! I've successfully created a complete desktop taskserv for your provisioning system. Here's what has been implemented:
|
||||
|
||||
Desktop TaskServ Created
|
||||
|
||||
Location: /Users/Akasha/repo-cnz/src/provisioning/taskservs/desktop/
|
||||
|
||||
Key Features:
|
||||
|
||||
- Multiple Desktop Environments: XFCE (default), GNOME, KDE, LXDE, MATE
|
||||
- VNC Remote Access: Configured with systemd service management
|
||||
- Zed Editor Integration: Pre-configured with development settings
|
||||
- Essential Applications: Browsers, terminals, development tools, media, office
|
||||
- Multi-OS Support: Ubuntu/Debian, CentOS/RHEL/Fedora
|
||||
- Graphics Configuration: Intel, NVIDIA, AMD driver support
|
||||
|
||||
Files Created:
|
||||
|
||||
- kcl/desktop.k - KCL schema definitions
|
||||
- default/provisioning.toml - Task service metadata
|
||||
- default/env-desktop.j2 - Environment variables template
|
||||
- default/install-desktop.sh - Main installation script
|
||||
- default/prepare - Pre-installation setup
|
||||
- default/zed-setup.sh - Zed editor configuration
|
||||
- default/desktop-apps.conf.j2 - Applications configuration
|
||||
- info.md - Complete documentation
|
||||
|
||||
Usage:
|
||||
|
||||
./core/nulib/provisioning taskserv create desktop --infra <infrastructure-name>
|
||||
|
||||
The desktop taskserv provides a full GUI environment with VNC access on port 5901, includes Zed editor with development
|
||||
configurations, and supports minimal resource requirements starting from 2GB RAM.
|
||||
|
||||
Perfect! I've successfully added RustDesk and SSH remote access support to the desktop taskserv. Here's what has been implemented:
|
||||
|
||||
Enhanced Remote Access Features Added
|
||||
|
||||
🎯 RustDesk Integration
|
||||
|
||||
- Modern remote desktop with excellent performance and built-in encryption
|
||||
- Cross-platform support - works on Windows, macOS, Linux, Android, iOS
|
||||
- Direct P2P connections or custom server support
|
||||
- Automatic service management with systemd
|
||||
- Configurable ports (21116 main, 21117 hbbr)
|
||||
- Permanent password support for unattended access
|
||||
|
||||
🔐 SSH Server with Hardening
|
||||
|
||||
- OpenSSH server with security-focused configuration
|
||||
- Fail2ban protection against brute force attacks
|
||||
- Key-based and password authentication options
|
||||
- User access controls with allow/deny lists
|
||||
- X11 forwarding enabled for GUI applications over SSH
|
||||
- Automatic firewall configuration
|
||||
|
||||
📋 Updated Configuration Options
|
||||
|
||||
Basic Example:
|
||||
desktop: DesktopServer = {
|
||||
rustdesk: {
|
||||
enabled: true
|
||||
port: 21116
|
||||
hbbr_port: 21117
|
||||
}
|
||||
ssh: {
|
||||
enabled: true
|
||||
port: 22
|
||||
password_auth: true
|
||||
key_auth: true
|
||||
}
|
||||
}
|
||||
|
||||
Advanced Example:
|
||||
desktop: DesktopServer = {
|
||||
rustdesk: {
|
||||
enabled: true
|
||||
custom_server: "rustdesk.mycompany.com"
|
||||
permanent_password: "secure_permanent_pass"
|
||||
allow_guest: false
|
||||
}
|
||||
ssh: {
|
||||
enabled: true
|
||||
port: 2222
|
||||
root_login: "no"
|
||||
max_auth_tries: 3
|
||||
allowed_users: ["developer", "admin"]
|
||||
}
|
||||
}
|
||||
|
||||
🚀 Usage Examples
|
||||
|
||||
RustDesk Connection:
|
||||
1. Get ID: sudo -u desktop rustdesk --get-id
|
||||
2. Get password: sudo -u desktop rustdesk --password
|
||||
3. Use RustDesk client to connect
|
||||
|
||||
SSH Connection:
|
||||
# Basic connection
|
||||
ssh desktop@server-ip -p 22
|
||||
|
||||
# With X11 forwarding for GUI apps
|
||||
ssh -X desktop@server-ip -p 22
|
||||
|
||||
# Create secure VNC tunnel
|
||||
ssh -L 5901:localhost:5901 desktop@server-ip
|
||||
|
||||
The desktop taskserv now provides three remote access methods (VNC, RustDesk, SSH) with comprehensive security features, automatic
|
||||
configuration, and detailed documentation for troubleshooting.
|
||||
|
||||
70
taskservs/desktop/test_config.nu
Normal file
70
taskservs/desktop/test_config.nu
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
#!/usr/bin/env nu
|
||||
# Test script to validate desktop taskserv configuration
|
||||
|
||||
def test_desktop_config [] {
|
||||
print "Testing desktop taskserv configuration..."
|
||||
|
||||
# Check if required files exist
|
||||
let required_files = [
|
||||
"default/provisioning.toml",
|
||||
"default/env-desktop.j2",
|
||||
"default/install-desktop.sh",
|
||||
"default/prepare",
|
||||
"kcl/desktop.k",
|
||||
"info.md"
|
||||
]
|
||||
|
||||
mut missing_files = []
|
||||
|
||||
for file in $required_files {
|
||||
if not ($file | path exists) {
|
||||
$missing_files = ($missing_files | append $file)
|
||||
}
|
||||
}
|
||||
|
||||
if ($missing_files | length) > 0 {
|
||||
print $"ERROR: Missing required files: ($missing_files)"
|
||||
return false
|
||||
}
|
||||
|
||||
# Check if install script is executable
|
||||
let install_script = "default/install-desktop.sh"
|
||||
if not ($install_script | path exists) {
|
||||
print $"ERROR: Install script not found: ($install_script)"
|
||||
return false
|
||||
}
|
||||
|
||||
# Validate provisioning.toml format
|
||||
let toml_content = (open "default/provisioning.toml")
|
||||
if ($toml_content.info == "desktop") and ($toml_content.release == "1.0") {
|
||||
print "✓ provisioning.toml is valid"
|
||||
} else {
|
||||
print "ERROR: provisioning.toml format is invalid"
|
||||
return false
|
||||
}
|
||||
|
||||
# Check KCL file syntax (basic)
|
||||
let kcl_content = (open "kcl/desktop.k")
|
||||
if ($kcl_content | str contains "schema DesktopServer") {
|
||||
print "✓ KCL schema file is valid"
|
||||
} else {
|
||||
print "ERROR: KCL schema file is invalid"
|
||||
return false
|
||||
}
|
||||
|
||||
print "✓ All desktop taskserv configuration files are present and valid"
|
||||
print ""
|
||||
print "Desktop taskserv features:"
|
||||
print "- Minimal desktop environments (XFCE, GNOME, KDE, LXDE, MATE)"
|
||||
print "- VNC remote access support"
|
||||
print "- Zed editor integration with configuration"
|
||||
print "- Essential development and productivity applications"
|
||||
print "- Multi-OS support (Ubuntu/Debian, CentOS/RHEL/Fedora)"
|
||||
print "- Graphics driver configuration"
|
||||
print "- Auto-login capability"
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
# Run the test
|
||||
test_desktop_config
|
||||
50
taskservs/etcd/default/backup.sh.j2
Executable file
50
taskservs/etcd/default/backup.sh.j2
Executable file
|
|
@ -0,0 +1,50 @@
|
|||
#!/bin/bash
|
||||
{# LIST="
|
||||
/etc/etcd
|
||||
/etc/ssl/etcd
|
||||
{{data_dir}}
|
||||
"
|
||||
#}
|
||||
{# KLOUDS_ETC_PATH=${KLOUDS_ETC_PATH:-{{klouds_etc_path | default(value="/etc/klouds")}}}
|
||||
KLOUDS_LIB_PATH=${KLOUDS_LIB_PATH:-{{klouds_lib_path | default(value="/var/lib/klouds")}}}
|
||||
KLOUDS_SAVE_PATH=${KLOUDS_SAVE_PATH:-{{klouds_save_path | default(value="/var/lib/klouds/save")}}}
|
||||
|
||||
[ -r "$KLOUDS_ETC_PATH/backup_env" ] && . "$KLOUDS_ETC_PATH/backup_env"
|
||||
#}
|
||||
|
||||
_etcd_cmd() {
|
||||
sudo etcdctl \
|
||||
--endpoints {{taskserv.etcd_protocol}}://{{taskserv.peer_ip}}:{{taskserv.peer_port}} \
|
||||
{% if taskserv.ssl_mode != "" -%}
|
||||
--cacert /etc/ssl/etcd/ca.crt \
|
||||
--cert /etc/ssl/etcd/{{taskserv.cluster_name}}.crt \
|
||||
--key /etc/ssl/etcd/{{taskserv.cluster_name}}.key \
|
||||
{%- endif %}
|
||||
$*
|
||||
}
|
||||
|
||||
_make_snapshot() {
|
||||
[ -z "$1" ] && echo "No path to create etcd snapshot" && exit 1
|
||||
_etcd_cmd snapshot save "$1"
|
||||
}
|
||||
|
||||
_verify_snapshot() {
|
||||
[ -z "$1" ] && echo "No path to verify etcd snapshot" && exit 1
|
||||
[ -r "$1" ] && echo "No path fount to verify etcd snapshot" && exit 1
|
||||
_etcd_cmd --write-out=table snapshot status "$1"
|
||||
}
|
||||
|
||||
_service_backup_verify() {
|
||||
_verify_snapshot $1
|
||||
return 0
|
||||
}
|
||||
_service_backup() {
|
||||
_make_snapshot $1
|
||||
return 0
|
||||
}
|
||||
_service_restore() {
|
||||
return 0
|
||||
}
|
||||
{# local has_run="$(type -t _run_init)"
|
||||
[ -n "$has_run" ] && _run_init
|
||||
#}
|
||||
3
taskservs/etcd/default/cert-show.sh
Executable file
3
taskservs/etcd/default/cert-show.sh
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/bash
|
||||
[ -z "$1" ] || [ ! -r "$1" ] && echo "Cert file $1 not found" && exit 1
|
||||
openssl x509 -in "$1" -text -noout
|
||||
75
taskservs/etcd/default/env-etcd.j2
Normal file
75
taskservs/etcd/default/env-etcd.j2
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
PROV_PATH={{taskserv.prov_path}}
|
||||
USE_LOCALHOST={{taskserv.use_localhost}}
|
||||
|
||||
{% if taskserv.domain_name == "$defaults" or taskserv.domain_name == "" -%}
|
||||
DOMAIN_NAME={{server.main_domain}}
|
||||
{%- elif taskserv.domain_name == "$server" -%}
|
||||
{%- if server.main_domain == "$default" -%}
|
||||
DOMAIN_NAME={{server.main_domain}}
|
||||
{%- else %}
|
||||
DOMAIN_NAME={{server.main_domain}}
|
||||
{%- endif %}
|
||||
{%- else %}
|
||||
DOMAIN_NAME={{taskserv.domain_name}}
|
||||
{%- endif %}
|
||||
|
||||
DISCOVERY_SRV={{taskserv.discovery_srv}}
|
||||
USE_DNS={{taskserv.use_dns}}
|
||||
ETCD_VERSION="v{{taskserv.version}}"
|
||||
{% if taskserv.name == "$hostname" %}
|
||||
ETCD_NAME="{{server.hostname}}"
|
||||
{%- else %}
|
||||
ETCD_NAME="{{taskserv.name}}"
|
||||
{%- endif %}
|
||||
ETCD_CN="{{taskserv.cn}}"
|
||||
ETCD_C="{{taskserv.c}}"
|
||||
ETCD_PROTOCOL="{{taskserv.etcd_protocol}}"
|
||||
ETCD_PORT="{{taskserv.peer_port}}"
|
||||
SSL_MODE="{{taskserv.ssl_mode}}"
|
||||
SIGNATURE="{{taskserv.ssl_sign}}"
|
||||
CA_SIGNATURE="{{taskserv.ca_sign}}"
|
||||
SSL_CURVE="{{taskserv.ssl_curve}}"
|
||||
SIGN_LONG="{{taskserv.long_sign}}"
|
||||
SIGN_CIPHER="{{taskserv.cipher}}"
|
||||
SIGN_DAYS="{{taskserv.sign_days}}"
|
||||
CA_SIGN_DAYS="{{taskserv.ca_sign_days}}"
|
||||
SIGN_SHA="{{taskserv.sign_sha}}"
|
||||
SOURCE_URL="{{taskserv.source_url}}"
|
||||
{% if taskserv.peer_ip == "$network_private_ip" %}
|
||||
ETCD_LISTEN_PEER_URLS="{{taskserv.etcd_protocol}}://{{server.network_private_ip}}:{{taskserv.peer_port}}"
|
||||
ETCD_INITIAL_ADVERTISE_PEER_URLS="{{taskserv.etcd_protocol}}://{{server.network_private_ip}}:{{taskserv.peer_port}}"
|
||||
{% elif taskserv.peer_ip == "$network_public_ip" and server.ip_addresses.pub -%}
|
||||
ETCD_LISTEN_PEER_URLS="{{taskserv.etcd_protocol}}://{{server.ip_addresses.pub}}:{{taskserv.peer_port}}"
|
||||
ETCD_INITIAL_ADVERTISE_PEER_URLS="{{taskserv.etcd_protocol}}://{{server.ip_addresses.pub}}:{{taskserv.peer_port}}"
|
||||
{%- else %}
|
||||
ETCD_LISTEN_PEER_URLS="{{taskserv.etcd_protocol}}://{{taskserv.peer_ip}}:{{taskserv.peer_port}}"
|
||||
ETCD_INITIAL_ADVERTISE_PEER_URLS="{{taskserv.etcd_protocol}}://{{taskserv.peer_ip}}:{{taskserv.peer_port}}"
|
||||
{%- endif %}
|
||||
{% if taskserv.cli_ip == "$network_private_ip" %}
|
||||
ETCD_LISTEN_CLIENT_URLS="{{taskserv.etcd_protocol}}://{{server.network_private_ip}}:{{taskserv.cli_port}}"
|
||||
ETCD_ADVERTISE_CLIENT_URLS="{{taskserv.etcd_protocol}}://{{server.network_private_ip}}:{{taskserv.cli_port}}"
|
||||
{% elif taskserv.cli_ip == "$network_public_ip" and server.ip_addresses.pub -%}
|
||||
ETCD_LISTEN_CLIENT_URLS="{{taskserv.etcd_protocol}}://{{server.ip_addresses.pub}}:{{taskserv.cli_port}}"
|
||||
ETCD_ADVERTISE_CLIENT_URLS="{{taskserv.etcd_protocol}}://{{server.ip_addresses.pub}}:{{taskserv.cli_port}}"
|
||||
{%- else %}
|
||||
ETCD_LISTEN_CLIENT_URLS="{{taskserv.etcd_protocol}}://{{taskserv.cli_ip}}:{{taskserv.cli_port}}"
|
||||
ETCD_ADVERTISE_CLIENT_URLS="{{taskserv.etcd_protocol}}://{{taskserv.cli_ip}}:{{taskserv.cli_port}}"
|
||||
{%- endif %}
|
||||
ETCD_INITIAL_CLUSTER_TOKEN="{{taskserv.token}}"
|
||||
ETCD_INITIAL_CLUSTER="{{taskserv.cluster_list}}"
|
||||
ETCD_TRUSTED_CA_FILE="{{taskserv.certs_path}}/ca.crt"
|
||||
ETCD_CERT_FILE="{{taskserv.certs_path}}/{{taskserv.cluster_name}}.crt"
|
||||
ETCD_KEY_FILE="{{taskserv.certs_path}}/{{taskserv.cluster_name}}.key"
|
||||
ETCD_PEER_CLIENT_CERT_AUTH=true
|
||||
ETCD_PEER_TRUSTED_CA_FILE="{{taskserv.certs_path}}/ca.crt"
|
||||
ETCD_PEER_KEY_FILE="{{taskserv.certs_path}}/{{taskserv.name}}.key"
|
||||
ETCD_PEER_CERT_FILE="{{taskserv.certs_path}}/{{taskserv.name}}.crt"
|
||||
ETCD_DATA="{{taskserv.data_dir}}"
|
||||
ETCD_CLUSTER_LIST="{{taskserv.cluster_list}}"
|
||||
{% if taskserv.use_localhost and taskserv.use_localhost == "true" %}
|
||||
USE_LOCALHOST="{{taskserv.use_localhost}}"
|
||||
{%- endif %}
|
||||
PROVISION_PATH="{{taskserv.prov_path}}"
|
||||
CLUSTER_NAME="{{taskserv.cluster_name}}"
|
||||
SOURCE_NAME="{{taskserv.cluster_name}}.{{taskserv.domain_name}}"
|
||||
|
||||
28
taskservs/etcd/default/etcd.service.j2
Normal file
28
taskservs/etcd/default/etcd.service.j2
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
[Unit]
|
||||
Description=etcd - highly-available key value store
|
||||
Documentation=https://etcd.io
|
||||
Documentation=man:etcd
|
||||
After=network.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Environment=DAEMON_ARGS=""
|
||||
Environment=ETCD_CONFIG_FILE={{taskserv.conf_path}}
|
||||
#Environment=ETCD_NAME=%H
|
||||
Environment=ETCD_DATA_DIR={{taskserv.data_dir}}
|
||||
#EnvironmentFile=-/etc/default/%p
|
||||
#EnvironmentFile=-/etc/etcd/env
|
||||
Type=notify
|
||||
User=etcd
|
||||
PermissionsStartOnly=true
|
||||
#ExecStart=/bin/sh -c "GOMAXPROCS=$(nproc) /usr/local/bin/etcd $DAEMON_ARGS"
|
||||
ExecStart=/usr/local/bin/etcd $DAEMON_ARGS
|
||||
#Restart=on-abnormal
|
||||
Restart=always
|
||||
RestartSec=10s
|
||||
#LimitNOFILE=65536
|
||||
LimitNOFILE=4000
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Alias=etcd.service
|
||||
217
taskservs/etcd/default/etcd.yaml.j2
Normal file
217
taskservs/etcd/default/etcd.yaml.j2
Normal file
|
|
@ -0,0 +1,217 @@
|
|||
# This is the configuration file for the etcd server.
|
||||
|
||||
# Human-readable name for this member.
|
||||
{% if taskserv.etcd_name == "$hostname" %}
|
||||
name: '{{server.hostname}}'
|
||||
{%- else %}
|
||||
name: '{{taskserv.etcd_name}}'
|
||||
{%- endif %}
|
||||
|
||||
# Path to the data directory.
|
||||
data-dir: {{taskserv.data_dir}}
|
||||
#/var/lib/etcd
|
||||
|
||||
# Path to the dedicated wal directory.
|
||||
wal-dir:
|
||||
|
||||
# Number of committed transactions to trigger a snapshot to disk.
|
||||
snapshot-count: 10000
|
||||
|
||||
# Time (in milliseconds) of a heartbeat interval.
|
||||
heartbeat-interval: 100
|
||||
|
||||
# Time (in milliseconds) for an election to timeout.
|
||||
election-timeout: 1000
|
||||
|
||||
# Raise alarms when backend size exceeds the given quota. 0 means use the
|
||||
# default quota.
|
||||
quota-backend-bytes: 0
|
||||
|
||||
{% set str_peer_port = "" ~ taskserv.peer_port %}
|
||||
{% set str_cli_port = "" ~ taskserv.cli_port %}
|
||||
# List of comma separated URLs to listen on for peer traffic.
|
||||
listen-peer-urls: "{%- if taskserv.listen_peers is containing("$network_private_ip") -%}
|
||||
{{taskserv.etcd_protocol}}://{{ taskserv.listen_peers | replace(from="$servers:$network_private_ip",to=server.network_private_ip) | replace(from="$peer_port", to=str_peer_port)}}
|
||||
{%- elif taskserv.listen_peers is containing("$network_public_ip") -%}
|
||||
{{taskserv.etcd_protocol}}://{{ taskserv.listen_peers | replace(from="$servers:$network_public_ip",to=server.ip_addresses.pub) | replace(from="$peer_port", to=str_peer_port)}}
|
||||
{%- else -%}
|
||||
{{taskserv.etcd_protocol}}://{{ taskserv.listen_peers | replace(from="$servers",to=server.hostname) | replace(from="$peer_port", to=str_peer_port)}}
|
||||
{%- endif %}"
|
||||
|
||||
# List of comma separated URLs to listen on for client traffic.
|
||||
|
||||
listen-client-urls: "{%- if taskserv.listen_clients is containing("$network_private_ip") -%}
|
||||
{{taskserv.etcd_protocol}}://{{ taskserv.listen_clients | replace(from="$servers:$network_private_ip",to=server.network_private_ip) | replace(from="$cli_port", to=str_cli_port)}}
|
||||
{%- elif taskserv.listen_clients is containing("$network_public_ip") -%}
|
||||
{{taskserv.etcd_protocol}}://{{ taskserv.listen_clients | replace(from="$servers:$network_public_ip",to=server.ip_addresses.pub) | replace(from="$cli_port", to=str_cli_port)}}
|
||||
{%- else -%}
|
||||
{{taskserv.etcd_protocol}}://{{ taskserv.listen_clients | replace(from="$servers",to=server.hostname) | replace(from="$cli_port", to=str_cli_port)}}
|
||||
{%- endif %}"
|
||||
|
||||
# Maximum number of snapshot files to retain (0 is unlimited).
|
||||
max-snapshots: 5
|
||||
|
||||
# Maximum number of wal files to retain (0 is unlimited).
|
||||
max-wals: 5
|
||||
|
||||
# Comma-separated white list of origins for CORS (cross-origin resource sharing).
|
||||
cors:
|
||||
|
||||
# List of this member's peer URLs to advertise to the rest of the cluster.
|
||||
# The URLs needed to be a comma-separated list.
|
||||
|
||||
initial-advertise-peer-urls: "{%- if taskserv.adv_listen_peers is containing("$network_private_ip") -%}
|
||||
{{taskserv.etcd_protocol}}://{{ taskserv.adv_listen_peers | replace(from="$servers:$network_private_ip",to=server.network_private_ip) | replace(from="$peer_port", to=str_peer_port)}}
|
||||
{%- elif taskserv.adv_listen_peers is containing("$network_public_ip") -%}
|
||||
{{taskserv.etcd_protocol}}://{{ taskserv.adv_listen_peers | replace(from="$servers:$network_public_ip",to=server.ip_addresses.pub) | replace(from="$peer_port", to=str_peer_port)}}
|
||||
{%- else -%}
|
||||
{{taskserv.etcd_protocol}}://{{ taskserv.adv_listen_peers | replace(from="$servers",to=server.hostname) | replace(from="$peer_port", to=str_peer_port)}}
|
||||
{%- endif %}"
|
||||
|
||||
# List of this member's client URLs to advertise to the public.
|
||||
# The URLs needed to be a comma-separated list.
|
||||
advertise-client-urls: "{%- if taskserv.adv_listen_clients is containing("$network_private_ip") -%}
|
||||
{{taskserv.etcd_protocol}}://{{ taskserv.adv_listen_clients | replace(from="$servers:$network_private_ip",to=server.network_private_ip) | replace(from="$cli_port", to=str_cli_port)}}
|
||||
{%- elif taskserv.adv_listen_clients is containing("$network_public_ip") -%}
|
||||
{{taskserv.etcd_protocol}}://{{ taskserv.adv_listen_clients | replace(from="$servers:$network_public_ip",to=settings[loop.index0].ip_addresses.pub) | replace(from="$cli_port", to=str_cli_port)}}
|
||||
{%- else -%}
|
||||
{{taskserv.etcd_protocol}}://{{ taskserv.adv_listen_clients | replace(from="$servers",to=server.hostname) | replace(from="$cli_port", to=str_cli_port)}}
|
||||
{%- endif %}"
|
||||
|
||||
# Discovery URL used to bootstrap the cluster.
|
||||
discovery: {{discovery_url | default(value="")}}
|
||||
|
||||
# Valid values include 'exit', 'proxy'
|
||||
discovery-fallback: 'proxy'
|
||||
|
||||
# HTTP proxy to use for traffic to discovery service.
|
||||
discovery-proxy:
|
||||
|
||||
# DNS domain used to bootstrap initial cluster.
|
||||
discovery-srv: {{taskserv.discovery_srv | default(value="")}}
|
||||
|
||||
# Initial cluster configuration for bootstrapping.
|
||||
initial-cluster: "{%- if taskserv.initial_peers is starting_with("$servers") -%}
|
||||
{%- for srv in defs.servers %}
|
||||
{%- set srv_index = loop.index -%}
|
||||
{%- for task in srv.taskservs -%}
|
||||
{%- if task.name != "etcd" -%}{% continue %}{% endif %}
|
||||
{%- if srv_index > 1 -%},{%- endif -%}
|
||||
{%- if taskserv.initial_peers is containing("$network_private_ip") -%}
|
||||
{{ srv.hostname }}={{taskserv.etcd_protocol}}://{{ taskserv.initial_peers | replace(from="$servers:$network_private_ip",to=srv.network_private_ip) | replace(from="$peer_port", to=str_peer_port)}}
|
||||
{%- elif task.initial_peers is containing("$network_public_ip") -%}
|
||||
{{ srv.hostname }}={{taskserv.etcd_protocol}}://{{ taskserv.initial_peers | replace(from="$servers:$network_public_ip",to=settings[loop.index0].ip_addresses.pub) | replace(from="$peer_port", to=str_peer_port)}}
|
||||
{%- else -%}
|
||||
{%- set full_hostname = srv.hostname ~ "." ~ taskserv.domain_name -%}
|
||||
{{ srv.hostname }}={{taskserv.etcd_protocol}}://{{ taskserv.initial_peers | replace(from="$servers",to=full_hostname) | replace(from="$peer_port", to=str_peer_port)}}
|
||||
{%- endif -%}
|
||||
{% break %}
|
||||
{%- endfor -%}
|
||||
{%- endfor -%}
|
||||
{%- else -%}
|
||||
{{taskserv.cluster_list}}
|
||||
{%- endif -%}"
|
||||
{# {%- endif %} #}
|
||||
|
||||
# Initial cluster token for the etcd cluster during bootstrap.
|
||||
initial-cluster-token: 'etcd-{{taskserv.cluster_name}}-cluster'
|
||||
|
||||
# Initial cluster state ('new' or 'existing').
|
||||
#initial-cluster-state: {% if pos.server == 0 %} 'new' {% else %} 'existing'{% endif %}
|
||||
initial-cluster-state: new
|
||||
|
||||
# Reject reconfiguration requests that would cause quorum loss.
|
||||
strict-reconfig-check: false
|
||||
|
||||
# Enable runtime profiling data via HTTP server
|
||||
enable-pprof: true
|
||||
|
||||
# Valid values include 'on', 'readonly', 'off'
|
||||
proxy: 'off'
|
||||
|
||||
# Time (in milliseconds) an endpoint will be held in a failed state.
|
||||
proxy-failure-wait: 5000
|
||||
|
||||
# Time (in milliseconds) of the endpoints refresh interval.
|
||||
proxy-refresh-interval: 30000
|
||||
|
||||
# Time (in milliseconds) for a dial to timeout.
|
||||
proxy-dial-timeout: 1000
|
||||
|
||||
# Time (in milliseconds) for a write to timeout.
|
||||
proxy-write-timeout: 5000
|
||||
|
||||
# Time (in milliseconds) for a read to timeout.
|
||||
proxy-read-timeout: 0
|
||||
|
||||
{% if taskserv.ssl_mode != "" -%}
|
||||
client-transport-security:
|
||||
# Path to the client server TLS cert file.
|
||||
cert-file: {{taskserv.certs_path}}/{{taskserv.cluster_name}}.crt
|
||||
|
||||
# Path to the client server TLS key file.
|
||||
key-file: {{taskserv.certs_path}}/{{taskserv.cluster_name}}.key
|
||||
|
||||
# Enable client cert authentication.
|
||||
client-cert-auth: false
|
||||
|
||||
# Path to the client server TLS trusted CA cert file.
|
||||
trusted-ca-file: {{taskserv.certs_path}}/ca.crt
|
||||
|
||||
# Client TLS using generated certificates
|
||||
auto-tls: false
|
||||
|
||||
peer-transport-security:
|
||||
{% if taskserv.hostname == "$hostname" %}
|
||||
# Path to the peer server TLS cert file.
|
||||
cert-file: {{taskserv.certs_path}}/{{server.hostname}}.crt
|
||||
# Path to the peer server TLS key file.
|
||||
key-file: {{taskserv.certs_path}}/{{server.hostname}}.key
|
||||
{%- else %}
|
||||
name: '{{taskserv.hostname}}'
|
||||
# Path to the peer server TLS cert file.
|
||||
cert-file: {{taskserv.certs_path}}/{{hostname}}.crt
|
||||
# Path to the peer server TLS key file.
|
||||
key-file: {{taskserv.certs_path}}/{{hostname}}.key
|
||||
{%- endif %}
|
||||
|
||||
# Enable peer client cert authentication.
|
||||
client-cert-auth: false
|
||||
|
||||
# Path to the peer server TLS trusted CA cert file.
|
||||
trusted-ca-file: {{taskserv.certs_path}}/ca.crt
|
||||
|
||||
# Peer TLS using generated certificates.
|
||||
auto-tls: false
|
||||
|
||||
# Allowed CN for inter peer authentication.
|
||||
allowed-cn:
|
||||
|
||||
# Allowed TLS hostname for inter peer authentication.
|
||||
allowed-hostname:
|
||||
|
||||
# The validity period of the self-signed certificate, the unit is year.
|
||||
self-signed-cert-validity: 1
|
||||
|
||||
{%- endif %}
|
||||
|
||||
# Enable debug-level logging for etcd.
|
||||
debug: false
|
||||
|
||||
logger: zap
|
||||
|
||||
# Specify 'stdout' or 'stderr' to skip journald logging even when running under systemd.
|
||||
log-outputs: ['{{taskserv.log_out| default(value="stdout")}}']
|
||||
log-level: '{{taskserv.log_level | default(value="warn")}}'
|
||||
|
||||
# Force to create a new one member cluster.
|
||||
force-new-cluster: false
|
||||
|
||||
auto-compaction-mode: periodic
|
||||
auto-compaction-retention: "1"
|
||||
|
||||
# Limit etcd to a specific set of tls cipher suites
|
||||
cipher-suites: [
|
||||
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
|
||||
]
|
||||
28
taskservs/etcd/default/etcdctl.sh.j2
Normal file
28
taskservs/etcd/default/etcdctl.sh.j2
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#!/bin/bash
|
||||
[ -z "$1" ] && echo "No arguments for etcdctl " && exit 1
|
||||
{% set str_cli_port = "" ~ taskserv.cli_port %}
|
||||
etcdctl \
|
||||
--endpoints {% if taskserv.adv_listen_clients is starting_with("$servers") -%}
|
||||
{%- for srv in defs.servers %}
|
||||
{%- set srv_index = loop.index -%}
|
||||
{%- for task in srv.taskservs -%}
|
||||
{%- if task.name != "etcd" -%}{% continue %}{% endif %}
|
||||
{%- if srv_index > 1 -%},{%- endif -%}
|
||||
{%- if taskserv.adv_listen_clients is containing("$network_private_ip") -%}
|
||||
{{taskserv.etcd_protocol}}://{{ taskserv.adv_listen_clients | replace(from="$servers:$network_private_ip",to=srv.network_private_ip) | replace(from="$cli_port", to=str_cli_port)}}
|
||||
{%- elif taskserv.adv_listen_clients is containing("$network_public_ip") -%}
|
||||
{{taskserv.etcd_protocol}}://{{ taskserv.adv_listen_clients | replace(from="$servers:$network_public_ip",to=settings[loop.index0].ip_addresses.pub) | replace(from="$cli_port", to=str_cli_port)}}
|
||||
{%- else -%}
|
||||
{{taskserv.etcd_protocol}}://{{ taskserv.adv_listen_clients | replace(from="$servers",to=srv.hostname) | replace(from="$cli_port", to=str_cli_port)}}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{%- endfor -%}
|
||||
{%- else -%}
|
||||
{{taskserv.adv_listen_clients}}
|
||||
{%- endif %} \
|
||||
{% if taskserv.ssl_mode != "" -%}
|
||||
--cacert /etc/ssl/etcd/ca.crt \
|
||||
--cert /etc/ssl/etcd/{{taskserv.cluster_name}}.crt \
|
||||
--key /etc/ssl/etcd/{{taskserv.cluster_name}}.key \
|
||||
{%- endif %}
|
||||
$*
|
||||
149
taskservs/etcd/default/install-etcd.sh
Executable file
149
taskservs/etcd/default/install-etcd.sh
Executable file
|
|
@ -0,0 +1,149 @@
|
|||
#!/bin/bash
|
||||
# Info: Script to install/create/delete/update etcd from file settings
|
||||
# Author: JesusPerezLorenzo
|
||||
# Release: 1.0
|
||||
# Date: 12-11-2024
|
||||
|
||||
USAGE="install-etcd.sh install | update | remvoe"
|
||||
[ "$1" == "-h" ] && echo "$USAGE" && exit 1
|
||||
|
||||
[ -r "env-etcd" ] && . ./env-etcd
|
||||
|
||||
ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')"
|
||||
CMD_TSK=${1:-install}
|
||||
|
||||
#[ -z "$ETCD_VERSION" ] && echo "No ETCD_VERSION found " && exit
|
||||
HOSTNAME=$(hostname)
|
||||
export LC_CTYPE=C.UTF-8
|
||||
export LANG=C.UTF-8
|
||||
|
||||
[ ! -d "/etc/etcd" ] && sudo mkdir /etc/etcd
|
||||
|
||||
_init() {
|
||||
[ -z "$ETCD_VERSION" ] || [ -z "$ARCH" ] && exit 1
|
||||
local curr_vers
|
||||
local has_etcd
|
||||
has_etcd=$(type etcd 2>/dev/null)
|
||||
[ -n "$has_etcd" ] && curr_vers="v"$(etcd -version 2>/dev/null | grep etcd | cut -f2 -d":" | sed 's/ //g')
|
||||
[ "$curr_vers" == "$ETCD_VERSION" ] && return
|
||||
# choose either URL
|
||||
GOOGLE_URL=https://storage.googleapis.com/etcd
|
||||
GITHUB_URL=https://github.com/etcd-io/etcd/releases/download
|
||||
case "$SOURCE_URL" in
|
||||
google) DOWNLOAD_URL=${GOOGLE_URL} ;;
|
||||
github) DOWNLOAD_URL=${GITHUB_URL} ;;
|
||||
esac
|
||||
rm -f "/tmp/etcd-${ETCD_VERSION}-${ARCH}.tar.gz"
|
||||
[ -d "/tmp/etcd-download" ] && rm -rf /tmp/etcd-download
|
||||
mkdir -p /tmp/etcd-download
|
||||
|
||||
if ! curl -fsSL "${DOWNLOAD_URL}/${ETCD_VERSION}/etcd-${ETCD_VERSION}-linux-${ARCH}.tar.gz" -o "/tmp/etcd-${ETCD_VERSION}-${ARCH}.tar.gz" ; then
|
||||
echo "Error downloading etcd-${ETCD_VERSION}-${ARCH}.tar.gz"
|
||||
exit 1
|
||||
fi
|
||||
if ! tar xzf "/tmp/etcd-${ETCD_VERSION}-${ARCH}.tar.gz" -C /tmp/etcd-download --strip-components=1 ; then
|
||||
echo "Error extracting etcd-${ETCD_VERSION}-${ARCH}.tar.gz"
|
||||
exit 1
|
||||
fi
|
||||
rm -f "/tmp/etcd-${ETCD_VERSION}-${ARCH}.tar.gz"
|
||||
|
||||
chmod +x /tmp/etcd-download/etcd
|
||||
chmod +x /tmp/etcd-download/etcdctl
|
||||
|
||||
sudo mv /tmp/etcd-download/etcd /usr/local/bin
|
||||
sudo mv /tmp/etcd-download/etcdctl /usr/local/bin
|
||||
sudo mv /tmp/etcd-download/etcdutl /usr/local/bin
|
||||
sudo mv /tmp/etcd-download /etc/etcd/"${ETCD_VERSION}"
|
||||
|
||||
# start a local etcd server
|
||||
# /tmp/etcd-download/etcd
|
||||
# write,read to etcd
|
||||
# /tmp/etcd-download/etcdctl --endpoints=localhost:2379 put foo bar
|
||||
# /tmp/etcd-download/etcdctl --endpoints=localhost:2379 get foo
|
||||
}
|
||||
_config_etcd() {
|
||||
[ ! -d "/etc/etcd" ] && sudo mkdir /etc/etcd
|
||||
|
||||
has_user=$(sudo grep etcd /etc/passwd)
|
||||
[ -z "$has_user" ] && sudo useradd -d /home/etcd -m etcd
|
||||
|
||||
[ ! -d "/etc/ssl/etcd" ] && sudo mkdir -p /etc/ssl/etcd
|
||||
sudo cp certs/* /etc/ssl/etcd
|
||||
sudo chown -R etcd:etcd /etc/ssl/etcd
|
||||
|
||||
[ ! -d "${ETCD_DATA}" ] && sudo mkdir -p "${ETCD_DATA}"
|
||||
sudo chown -R etcd:etcd "${ETCD_DATA}"
|
||||
sudo chmod 700 "${ETCD_DATA}"
|
||||
|
||||
#[ -r "etcd-sysusers.conf" ] && sudo cp etcd-sysusers.conf /usr/lib/sysusers.d
|
||||
#[ -r "etcd-tmpfile.conf" ] && sudo cp etcd-tmpfiles.conf /usr/lib/tmpfiles.d
|
||||
|
||||
sudo cp etcdctl.sh /etc/etcd/etcdctl.sh
|
||||
sed 's/, / /g' < etcdctl.sh | sudo tee /etc/etcd/etcdctl.sh &>/dev/null
|
||||
sudo chmod +x /etc/etcd/etcdctl.sh
|
||||
|
||||
sudo cp cert-show.sh /etc/etcd/cert-show.sh
|
||||
# sudo cp setup.sh /etc/etcd/etcd_setup.sh
|
||||
|
||||
sudo cp env-etcd /etc/etcd/env
|
||||
# [ ! -r "/etc/etcd/config.yaml" ] &&
|
||||
sed 's/,"/"/g' < etcd.yaml | sudo tee /etc/etcd/config.yaml &>/dev/null
|
||||
|
||||
sudo cp etcd.service /lib/systemd/system/etcd.service
|
||||
#[ ! -L "/etc/systemd/system/etcd.service" ] && sudo ln -s /lib/systemd/system/etcd.service /etc/systemd/system
|
||||
sudo timeout -k 10 20 systemctl daemon-reload >/dev/null 2>&1
|
||||
|
||||
sudo timeout -k 10 20 systemctl enable --now etcd >/dev/null 2>&1
|
||||
# sudo timeout -k 10 20 systemctl restart etcd >/dev/null 2>&1
|
||||
|
||||
# This command sets the cluster to existing for the next start
|
||||
#sudo sed -i s"/initial-cluster-state: 'new'/initial-cluster-state: 'existing'/"g /etc/etcd/config.yaml
|
||||
#sudo sed -i s"/ETCD_INITIAL_CLUSTER_STATE=\"new\"/ETCD_INITIAL_CLUSTER_STATE=\"existing\"/"g /etc/etcd/env
|
||||
|
||||
}
|
||||
_stop_resolved() {
|
||||
sudo timeout -k 10 20 systemctl stop etcd >/dev/null 2>&1
|
||||
sudo timeout -k 10 20 systemctl disable etcd >/dev/null 2>&1
|
||||
}
|
||||
_remove_etcd() {
|
||||
sudo timeout -k 10 20 systemctl stop etcd >/dev/null 2>&1
|
||||
sudo timeout -k 10 20 systemctl disable etcd >/dev/null 2>&1
|
||||
}
|
||||
_start_etcd() {
|
||||
sudo timeout -k 10 20 systemctl enable etcd >/dev/null 2>&1
|
||||
sudo timeout -k 10 20 systemctl start etcd >/dev/null 2>&1
|
||||
}
|
||||
_restart_etcd() {
|
||||
sudo timeout -k 10 20 systemctl restart etcd >/dev/null 2>&1
|
||||
}
|
||||
if [ "$CMD_TSK" == "install" ] ; then
|
||||
if ! _init ; then
|
||||
echo "error etcd init"
|
||||
exit 1
|
||||
fi
|
||||
# _make_certs
|
||||
_config_etcd
|
||||
exit 0
|
||||
fi
|
||||
if [ "$CMD_TSK" == "config" ] ; then
|
||||
if ! _config_etcd ; then
|
||||
echo "error etcd config"
|
||||
exit 1
|
||||
fi
|
||||
exit
|
||||
fi
|
||||
if [ "$CMD_TSK" == "remove" ] ; then
|
||||
_remove_etcd
|
||||
exit
|
||||
fi
|
||||
if [ "$CMD_TSK" == "update" ] ; then
|
||||
_restart_etcd && exit 0
|
||||
fi
|
||||
if ! _stop_resolved ; then
|
||||
echo "error etcd stop"
|
||||
exit 1
|
||||
fi
|
||||
if ! _start_etcd ; then
|
||||
echo "error etcd start"
|
||||
exit 1
|
||||
fi
|
||||
33
taskservs/etcd/default/openssl.conf.tpl
Normal file
33
taskservs/etcd/default/openssl.conf.tpl
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
[req]
|
||||
default_bits = 4096
|
||||
distinguished_name = req_distinguished_name
|
||||
req_extensions = v3_req
|
||||
prompt = no
|
||||
|
||||
[req_distinguished_name]
|
||||
|
||||
[v3_req]
|
||||
basicConstraints = CA:FALSE
|
||||
keyUsage = digitalSignature, keyEncipherment, dataEncipherment
|
||||
extendedKeyUsage = serverAuth, clientAuth
|
||||
subjectAltName = @alt_names
|
||||
|
||||
[ ssl_client ]
|
||||
basicConstraints = CA:FALSE
|
||||
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
||||
extendedKeyUsage = clientAuth, serverAuth
|
||||
authorityKeyIdentifier=keyid,issuer
|
||||
subjectAltName = @alt_names
|
||||
|
||||
[ ssl_peer ]
|
||||
basicConstraints = CA:FALSE
|
||||
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
||||
extendedKeyUsage = clientAuth, serverAuth
|
||||
authorityKeyIdentifier=keyid,issuer
|
||||
subjectAltName = @alt_names
|
||||
|
||||
[ v3_ca ]
|
||||
basicConstraints = CA:TRUE
|
||||
keyUsage = keyCertSign,cRLSign
|
||||
|
||||
[alt_names]
|
||||
463
taskservs/etcd/default/prepare
Executable file
463
taskservs/etcd/default/prepare
Executable file
|
|
@ -0,0 +1,463 @@
|
|||
#!/usr/bin/env nu
|
||||
# Info: Prepare for etcd installation
|
||||
# Author: JesusPerezLorenzo
|
||||
# Release: 1.0.2
|
||||
# Date: 26-02-2024
|
||||
|
||||
use lib_provisioning/cmd/env.nu *
|
||||
use lib_provisioning/cmd/lib.nu *
|
||||
use lib_provisioning/utils/ui.nu *
|
||||
use lib_provisioning/utils/files.nu find_file
|
||||
use lib_provisioning/sops *
|
||||
|
||||
def get_domain_name [
|
||||
defs: record
|
||||
source: string
|
||||
] {
|
||||
match $source {
|
||||
"$defaults" => $defs.server.main_domain,
|
||||
_ => $source
|
||||
}
|
||||
}
|
||||
def openssl_ecc_cert [
|
||||
defs: record
|
||||
src: string
|
||||
run_root: string
|
||||
cluster_name: string
|
||||
hostname: string
|
||||
signature: string
|
||||
long_sign: int
|
||||
] {
|
||||
let etcd_cn = ( $defs.taskserv.cn | default "")
|
||||
let ca_signature = ($defs.taskserv.ca_sign | default "")
|
||||
let ssl_curve = ($defs.taskserv.ssl_curve | default "")
|
||||
let sign_sha = ($defs.taskserv.sign_sha | default "")
|
||||
let sign_cipher = ($defs.taskserv.cipher | default "")
|
||||
let sign_days = ($defs.taskserv.sign_days | default "")
|
||||
|
||||
let on_error = { |msg: string|
|
||||
print $"🛑 (_ansi red)Error(_ansi reset) (_ansi yellow)ECC(_ansi reset): ($msg)"
|
||||
rm -f ($src | path join "pass")
|
||||
}
|
||||
^openssl ecparam -genkey -name $ssl_curve -out ($src | path join $"($cluster_name).key") | ignore
|
||||
let res = (^openssl req -new $"-SHA($sign_sha)" -key ($src | path join $"($cluster_name).key") -nodes
|
||||
-out ($src | path join $"($cluster_name).csr")
|
||||
-subj $"/CN=($etcd_cn)" -config ($src | path join "openssl.conf") -extensions ssl_peer
|
||||
| complete )
|
||||
if $res.exit_code != 0 {
|
||||
do $on_error $"openssl csr error ($res.stdout)"
|
||||
exit 1
|
||||
}
|
||||
let res = (^openssl x509 -req $"-SHA($sign_sha)" -in ($src | path join $"($cluster_name).csr")
|
||||
-CA ($src | path join "ca.crt") -CAkey ($src | path join "ca.key")
|
||||
-CAcreateserial -out ($src | path join $"($cluster_name).crt") -days $sign_days
|
||||
-extensions ssl_peer -extfile ($src | path join "openssl.conf")
|
||||
| complete )
|
||||
if $res.exit_code != 0 {
|
||||
do $on_error $"openssl x509 req error ($res.exit_code)($res.stdout)"
|
||||
exit 1
|
||||
}
|
||||
^openssl ecparam -genkey -name $ssl_curve -out ($src | path join $"($hostname).key") | ignore
|
||||
let res = (^openssl req -noenc -new $"-SHA($sign_sha)" -key ($src | path join $"($hostname).key")
|
||||
-nodes -out ($src | path join $"($hostname).csr")
|
||||
-subj $"/CN=($etcd_cn)" -config ($src | path join "openssl.conf") -extensions ssl_peer | complete )
|
||||
if res.exit_code != 0 and not ($src | path join $"($hostname).csr" | path exists) {
|
||||
do $on_error $"🛑 openssl req csr error ($res.exit_code) ($res.stdout)"
|
||||
exit 1
|
||||
}
|
||||
let res = (^openssl x509 -req -noenc $"-SHA($sign_sha)" -in ($src | path join $"($hostname).csr")
|
||||
-CA ($src | path join "ca.crt") -CAkey ($src | path join "ca.key")
|
||||
-CAcreateserial -out ($src | path join $"($hostname).crt") -days $sign_days
|
||||
-extensions ssl_peer -extfile ($src | path join "openssl.conf")
|
||||
| complete )
|
||||
if res.exit_code != 0 and not ($src | path join $"($hostname).crt" | path exists) {
|
||||
do $on_error $"🛑 openssl x509 req error ($res.stdout)"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
def openssl_rsa_cert [
|
||||
defs: record
|
||||
src: string
|
||||
run_root: string
|
||||
cluster_name: string
|
||||
hostname: string
|
||||
signature: string
|
||||
long_sign: int
|
||||
] {
|
||||
let etcd_cn = ( $defs.taskserv.cn | default "")
|
||||
let sign_cipher = ($defs.taskserv.cipher | default "")
|
||||
let sign_days = ($defs.taskserv.sign_days | default "")
|
||||
|
||||
let on_error = { |msg: string|
|
||||
print $"🛑 (_ansi red)Error(_ansi reset) (_ansi yellow)RSA(_ansi reset): ($msg)"
|
||||
rm -f ($src | path join "pass")
|
||||
}
|
||||
if not ($src | path join "pass" | path exists) { $defs.taskserv.sign_pass | save -f ($src | path join "pass") }
|
||||
^openssl genrsa -passout $"file:($src | path join "pass")" $sign_cipher -out ($src | path join $"($cluster_name)_p.key") $long_sign
|
||||
^openssl rsa -in "$src/$cluster_name"_p.key -out ($src | path join $"($cluster_name).key")
|
||||
if not ($src | path join "openssl.conf" | path exists) {
|
||||
do $on_error $"openssl.con not found in ($src |path join "openssl.conf")"
|
||||
exit 1
|
||||
}
|
||||
let res = (^openssl req -newkey rsa:($long_sign) -passout $"file:($src | path join "pass")" -key ($src | path join $"($cluster_name).key")
|
||||
-out ($src | path join $"($cluster_name).csr")
|
||||
-subj $"/CN=($etcd_cn)" -config ($src | path join "openssl.conf") -extensions ssl_client
|
||||
| complete)
|
||||
if $res.exit_code != 0 {
|
||||
do $on_error $"openssl req error ($res.exit_code) ($res.stdout)"
|
||||
exit 1
|
||||
}
|
||||
print $"openssl gemrsa error ($res.exit_code) ($res.stdout)"
|
||||
(^openssl x509 -req -in ($src | path join $"($cluster_name).csr") -CA ($src | path join "ca.crt")
|
||||
-CAkey ($src | path join "ca.key") -out ($src | path join $"($cluster_name).crt") -days $sign_days
|
||||
-extensions ssl_client -extfile ($src | path join "openssl.conf")
|
||||
)
|
||||
let res = (^openssl genrsa -passout $"file:($src | path join "pass")" $sign_cipher
|
||||
-out ($src | path join $"($hostname)_p.key") $long_sign
|
||||
| complete)
|
||||
if $res.exit_code != 0 {
|
||||
do $on_error $"openssl genrsa error ($res.exit_code) ($res.stdout)"
|
||||
exit 1
|
||||
}
|
||||
^openssl rsa -in ($src | path join $"($hostname)_p.key") -out ($src | path join $"($hostname).key")
|
||||
if not ($src | path join "openssl.conf" | path exists) {
|
||||
print $"openssl.con not found in ($src | path join "openssl.conf") "
|
||||
rm -f ($src | path join "pass")
|
||||
exit 1
|
||||
}
|
||||
let res = (^openssl req -newkey rsa:$long_sign -passout $"file:($src | path join "pass")"
|
||||
-key ($src | path join $"($hostname).key") -out ($src | path join $"($hostname).csr")
|
||||
-subj $"/CN=($etcd_cn)" -config ($src | path join "openssl.conf") -extensions ssl_peer
|
||||
| complete)
|
||||
if $res.exit_code == 0 {
|
||||
do $on_error $"openssl req key error ($res.exit_code) ($res.stdout)"
|
||||
exit 1
|
||||
}
|
||||
let res = (^openssl x509 -req -in ($src | path join $"($hostname).csr") -CA ($src | path join "ca.crt") -CAkey ($src | path join "ca.key")
|
||||
-out ($src | path join $"($hostname).crt") -days $sign_days
|
||||
-extensions ssl_peer -extfile ($src | path join "openssl.conf")
|
||||
| complete)
|
||||
if $res.exit_code != 0 {
|
||||
do $on_error $"openssl x509 req cst error ($res.exit_code) ($res.stdout)"
|
||||
exit 1
|
||||
}
|
||||
rm -f ($src | path join "pass")
|
||||
}
|
||||
|
||||
def openssl_mode [
|
||||
defs: record
|
||||
src: string
|
||||
run_root: string
|
||||
cluster_name: string
|
||||
hostname: string
|
||||
signature: string
|
||||
long_sign: int
|
||||
] {
|
||||
let etcd_cn = ( $defs.taskserv.cn | default "")
|
||||
let ca_signature = ($defs.taskserv.ca_sign | default "")
|
||||
let ssl_curve = ($defs.taskserv.ssl_curve | default "")
|
||||
let sign_sha = ($defs.taskserv.sign_sha | default "")
|
||||
let sign_cipher = ($defs.taskserv.cipher | default "")
|
||||
let sign_days = ($defs.taskserv.sign_days | default "")
|
||||
let ca_sign_days = ($defs.taskserv.ca_sign_days | default "")
|
||||
|
||||
mut openssl = (^bash -c "type -P openssl")
|
||||
if $openssl == "" {
|
||||
^sudo apt install openssl -y
|
||||
$openssl = (^bash -c "type -P openssl")
|
||||
}
|
||||
if openssl == "" { print $"openssl not installed " ; exit 1 }
|
||||
if not ($src | path join "openssl.conf" | path exists) and ($run_root | path join "openssl.conf.tpl" | path exists) {
|
||||
cp ($run_root | path join "openssl.conf.tpl") ($src | path join "openssl.conf")
|
||||
if ($src | path join "openssl_conf_alt_names" | path exists ) {
|
||||
open ($src | path join "openssl_conf_alt_names") -r | save -a ($src | path join "openssl.conf")
|
||||
}
|
||||
}
|
||||
print $"CA signature: ($ca_signature)"
|
||||
if not ($src | path join "ca.key" | path exists) {
|
||||
sops_cmd "decrypt" ($src | path join "ca.key") ($src | path join "ca.key") --error_exit
|
||||
#sudo mv "$src/ca.key.$$" "$src/ca.key"
|
||||
}
|
||||
if $ca_signature == "ECC" {
|
||||
if not ($src | path join "ca.key" | path exists) and not ($src| path join "ca.crt" | path exists) {
|
||||
^openssl ecparam -genkey -name $ssl_curve -out ($src | path join "ca.key")
|
||||
let res = (^openssl req -x509 -extensions v3_ca -config ($src | path join "openssl.conf") -new $"-SHA($sign_sha)"
|
||||
-nodes -key ($src | path join "ca.key") -days $ca_sign_days
|
||||
-out ($src | path join "ca.crt") -subj $"/CN=($etcd_cn)"
|
||||
| complete )
|
||||
if $res.exit_code != 0 {
|
||||
print $"🛑 openssl key ($ca_signature) error ($res.stdout)"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
} else if not ($src | path join "ca.key" | path exists) and not ($src |path join "ca.crt" | path exists) {
|
||||
$defs.taskserv.sign_pass | save -f ($src | path join "pass")
|
||||
^openssl genrsa -passout $"file:($src | path join "pass")" $sign_cipher -out ($src | path join "ca_p.key") $long_sign
|
||||
^openssl rsa -in ($src |path join "ca_p.key") -out ($src | path join "ca.key")
|
||||
let res = (^openssl req -x509 -extensions v3_ca -config ($src | path join "openssl.conf") -newkey rsa:($long_sign)
|
||||
-nodes -key ($src | path join "ca.key") -days $sign_days -out ($src | path join "ca.crt") -subj $"CN=($etcd_cn)"
|
||||
| complete )
|
||||
if $res.exit_code != 0 {
|
||||
print $"🛑 openssl ca ($ca_signature) error ($res.stdout)"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
print $"Certs signature: ($signature)"
|
||||
if not ($src | path join $"($cluster_name).crt" | path exists) or not ($src | path join $"($cluster_name).key" | path exists) {
|
||||
match $signature {
|
||||
"ECC" => {
|
||||
(openssl_ecc_cert $defs $src $run_root $cluster_name $hostname $signature $long_sign)
|
||||
},
|
||||
_ => {
|
||||
(openssl_rsa_cert $defs $src $run_root $cluster_name $hostname $signature $long_sign)
|
||||
},
|
||||
}
|
||||
}
|
||||
copy_certs $defs $src $run_root $cluster_name $signature
|
||||
}
|
||||
def cfssl_mode [
|
||||
defs: record
|
||||
src: string
|
||||
run_root: string
|
||||
cluster_name: string
|
||||
hostname: string
|
||||
signature: string
|
||||
long_sign: int
|
||||
] {
|
||||
let domain_name = (get_domain_name $defs ($defs.taskserv.domain_name | default ""))
|
||||
let source_name = $"($cluster_name | default "").($domain_name)"
|
||||
let ORG = $env.PWD
|
||||
let etcd_c = ($defs.taskserv.c | default "")
|
||||
|
||||
mut CFSSL = (^bash -c "type -P cfssl")
|
||||
if "$CFSSL" == "" {
|
||||
let cfssl_install_bin = ($env.PROVISIONING | path join "core"| path join "bin" | path join "cfssl-install.sh")
|
||||
if ($cfssl_install_bin | path exists) { ^$cfssl_install_bin }
|
||||
$CFSSL = (^bash -c "type -P cfssl")
|
||||
}
|
||||
if "$CFSSL" == "" { print $"cfssl not installed " ; exit 1 }
|
||||
let CFSSLJSON = (^bash -c "type -P cfssljson")
|
||||
let csr_json_file = ($src | path join "csr.json")
|
||||
if not ($csr_json_file) {
|
||||
"{" | tee { save -f $csr_json_file } | ignore
|
||||
$"\"hosts\": [" | tee { save -a $csr_json_file } | ignore
|
||||
for server in $defs.defs.servers {
|
||||
let ip = ($server.network_private_ip | default "")
|
||||
if $ip == "" { continue }
|
||||
$"\"($server.hostname)\",\"($server.hostname).($domain_name)\",\"($ip)\"," | tee { save -a $csr_json_file } | ignore
|
||||
}
|
||||
if $source_name != "" and $source_name != $"($cluster_name).($domain_name)" {
|
||||
print $"\"($source_name)\","| tee { save -a ($src | path join "csr.json") } | ignore
|
||||
}
|
||||
$"\"${domain_name}\", \"$cluster_name\"],\"key\": {" | tee { save -a $csr_json_file } | ignore
|
||||
if $signature == "ECC" {
|
||||
$"\"algo\": \"ecdsa\",\"size\": ($long_sign) " | tee { save -a $csr_json_file } | ignore
|
||||
} else {
|
||||
$"\"algo\": \"rsa\",\"size\": ($long_sign) " | tee { save -a $csr_json_file } | ignore
|
||||
}
|
||||
$"}, \"names\": [{ \"C\":\"($etcd_c)\", \"CN\": \"($domain_name)\" }]" | tee { save -a $csr_json_file } | ignore
|
||||
$"}" | tee { save -a $csr_json_file } | ignore
|
||||
#sudo echo '{"CN":"CA","key":{"algo":"rsa","size":2048}}' | cfssl gencert -initca - | cfssljson -bare ca -
|
||||
#$sudo echo '{"signing":{"default":{"expiry":"43800h","usages":["signing","key encipherment","server auth","client auth"]}}}' \&ca-config.json
|
||||
}
|
||||
if not ( $"($cluster_name).key" | path exists) {
|
||||
cd $src
|
||||
if ((^($CFSSL) genkey -initca csr.json | ^($CFSSLJSON) -bare ca) | complete).exit_code == 0 {
|
||||
if ((^($CFSSL) gencert -ca ca.pem -ca-key ca-key.pem csr.json
|
||||
| ^($CFSSLJSON) -bare $cluster_name) | complete).exit_code == 0 {
|
||||
mv ca.pem ca.crt
|
||||
sudo mv ca-key.pem ca.key
|
||||
mv $"($cluster_name).pem" $"($cluster_name).crt"
|
||||
sudo mv $"($cluster_name)-key.pem" $"($cluster_name).key"
|
||||
for server in $defs.defs.servers {
|
||||
cp $"($cluster_name).crt" $"($server.hostname).crt"
|
||||
sudo cp $"($cluster_name).key" $"($server.hostname).key"
|
||||
}
|
||||
cd $ORG
|
||||
copy_certs $defs $src $run_root $cluster_name $signature
|
||||
}
|
||||
}
|
||||
cd $ORG
|
||||
} else {
|
||||
copy_certs $defs $src $run_root $cluster_name $signature
|
||||
}
|
||||
}
|
||||
|
||||
export def make_certs [
|
||||
defs: record
|
||||
src: string
|
||||
run_root: string
|
||||
cluster_name: string
|
||||
signature: string
|
||||
ssl_mode: string
|
||||
settings_root: string
|
||||
long_sign: int
|
||||
] {
|
||||
if $signature == "" { print $"No signatures found" ; return 1 }
|
||||
if not ($src | path exists) { print $"Directory ($src) not found" ; return 1 }
|
||||
let hostname = ($defs.server.hostname | default "")
|
||||
if $hostname == "" { print $"hostname not found in ($env.PROVISIONING_VARS)" ; exit 1 }
|
||||
let servers_list = ($defs.defs.servers | select "hostname" | flatten | get -i "hostname")
|
||||
match $ssl_mode {
|
||||
"open" | "openssl" => {
|
||||
openssl_mode $defs $src $run_root $cluster_name $hostname $signature $long_sign
|
||||
},
|
||||
"cf" | "cfssl" => {
|
||||
cfssl_mode $defs $src $run_root $cluster_name $hostname $signature $long_sign
|
||||
},
|
||||
}
|
||||
}
|
||||
export def etcd_conf [
|
||||
defs: record
|
||||
src: string
|
||||
run_root: string
|
||||
cluster_name: string
|
||||
signature: string
|
||||
ssl_mode: string
|
||||
] {
|
||||
if not ($src | path exists) { mkdir $src }
|
||||
let domain_name = (get_domain_name $defs ($defs.taskserv.domain_name | default ""))
|
||||
let etcd_cn = ( $defs.taskserv.cn | default "")
|
||||
let source_name = $"($cluster_name | default "").($domain_name)"
|
||||
if $domain_name == "" or $domain_name == "" { print $"No names \( cluster_name and domain \) are defined" ; return 1 }
|
||||
if $env.PROVISIONING_DEBUG { print $"nodeport: ($defs.taskserv.peer_port) \nprotocol: ($defs.taskserv.etcd_protocol) \n" }
|
||||
let conf_alt_names_path = ($src | path join "openssl_conf_alt_names")
|
||||
let setup_tpl_path = ($src | path join "setup.tpl")
|
||||
mut n = 0
|
||||
match $ssl_mode {
|
||||
"open"| "openssl" => {
|
||||
rm -f $conf_alt_names_path $setup_tpl_path
|
||||
if $defs.taskserv.use_localhost {
|
||||
if $env.PROVISIONING_DEBUG { print $"localhost: 127.0.0.1" }
|
||||
match $ssl_mode {
|
||||
"open"| "openssl" => {
|
||||
$n += 1
|
||||
$"DNS.$n = localhost" | tee { save -a $conf_alt_names_path } | ignore
|
||||
$"IP.$n = 127.0.0.1" | tee { save -a $conf_alt_names_path } | ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
$n += 1
|
||||
$"DNS.($n) = ($cluster_name)" | tee { save -a $conf_alt_names_path } | ignore
|
||||
$n += 1
|
||||
$"DNS.($n) = ($etcd_cn)" | tee { save -a $conf_alt_names_path } | ignore
|
||||
}
|
||||
}
|
||||
mut cluster_list = ""
|
||||
for server in $defs.defs.servers {
|
||||
let ip = ($server.network_private_ip | default "")
|
||||
if $ip == "" { continue }
|
||||
if $env.PROVISIONING_DEBUG { print $"($server.hostname): ($ip)" }
|
||||
if $cluster_list != "" { $cluster_list += "," }
|
||||
$cluster_list += $"($server.hostname)=($defs.taskserv.etcd_protocol)://($ip):($defs.taskserv.peer_port)"
|
||||
$n += 1
|
||||
match $ssl_mode {
|
||||
"open"| "openssl" => {
|
||||
$"export Node($n)_IP=($ip)" | tee { save -a $setup_tpl_path } | ignore
|
||||
$"DNS.($n) = ($server.hostname)" | tee { save -a $conf_alt_names_path } | ignore
|
||||
$"IP.($n) = ($ip)" | tee { save -a $conf_alt_names_path } | ignore
|
||||
$n += 1
|
||||
$"DNS.($n) = ($server.hostname).($domain_name)" | tee { save -a $conf_alt_names_path } | ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
match $ssl_mode {
|
||||
"open"| "openssl" => {
|
||||
if $source_name != "" and $source_name != $"($cluster_name).($domain_name)" {
|
||||
$n += 1
|
||||
print $"DNS.($n) = ($source_name)" | tee { save -a $conf_alt_names_path } | ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
if $env.PROVISIONING_DEBUG { print $"\ncluster_list: ($cluster_list)" }
|
||||
return 0
|
||||
}
|
||||
|
||||
export def copy_certs [
|
||||
defs: record
|
||||
src: string
|
||||
run_root: string
|
||||
cluster_name: string
|
||||
signature: string
|
||||
] {
|
||||
print $"Copy certs to ($run_root) ..."
|
||||
let hostname = $defs.server.hostname
|
||||
if $hostname == "" { print $"hostname not found for ($env.PROVISIONING_VARS)" ; exit 1 }
|
||||
if (glob ($src | path join "*.csr") | length) > 0 {
|
||||
rm -f ...(glob ($src | path join "*.csr"))
|
||||
}
|
||||
if not ($run_root | path join "certs" | path exists) { mkdir ($run_root | path join "certs") }
|
||||
for name in [ ca $hostname $cluster_name] {
|
||||
if not ($src | path join $"($name).key" | path exists) { continue }
|
||||
if (sops_cmd "is_sops" ($src | path join $"($name).key")) {
|
||||
let content = (sops_cmd "decrypt" ($src | path join $"($name).key") --error_exit)
|
||||
if $content != "" { $content | save -f ($run_root | path join "certs" | path join $"($name).key") }
|
||||
} else {
|
||||
cp ($src | path join $"($name).key") ($run_root | path join "certs" | path join $"($name).key" )
|
||||
sops_cmd "encrypt" ($src | path join $"($name).key") --error_exit | save -f ($src | path join $"($name).key")
|
||||
}
|
||||
chmod 400 ($src | path join $"($name).key") ($run_root | path join "certs" | path join $"($name).key")
|
||||
if ($src | path join $"($name).crt" | path exists) {
|
||||
cp ($src | path join $"($name).crt") ($run_root | path join "certs")
|
||||
}
|
||||
}
|
||||
if ($src | path join $"($cluster_name).crt" | path exists) {
|
||||
#if not ($run_root | path join "certs" | path join $"($cluster_name).crt" | path exists) {
|
||||
# cp ($src | path join $"($cluster_name).crt") ($run_root | path join "certs")
|
||||
#}
|
||||
if not ($run_root | path join "certs" | path join $"($hostname).crt" | path exists) {
|
||||
cp ($src | path join $"($cluster_name).crt") ($run_root | path join "certs" | path join $"($hostname).crt")
|
||||
}
|
||||
if not ($run_root | path join "certs" | path join $"($hostname).key" | path exists) {
|
||||
cp ($run_root | path join "certs" | path join $"($cluster_name).key") ($run_root | path join "certs" | path join $"($hostname).key")
|
||||
}
|
||||
print $"Certificate for ($hostname) signed ($signature) in ($src) copy to deployment"
|
||||
}
|
||||
if (glob ($run_root | path join "openssl.*") | length) > 0 {
|
||||
rm -r ...(glob ($run_root | path join "openssl.*"))
|
||||
}
|
||||
}
|
||||
|
||||
def main [] {
|
||||
|
||||
print $"(_ansi green_bold)ETCD(_ansi reset) with ($env.PROVISIONING_VARS?) "
|
||||
let run_root = $env.PROVISIONING_WK_ENV_PATH
|
||||
|
||||
let defs = load_defs
|
||||
let src = ($env.PROVISIONING_SETTINGS_SRC_PATH | path join "resources" | path join $defs.taskserv.prov_path)
|
||||
if not ($env.PROVISIONING_SETTINGS_SRC_PATH | path join "resources" | path exists) {
|
||||
^mkdir -p ($env.PROVISIONING_SETTINGS_SRC_PATH | path join "resources")
|
||||
}
|
||||
let provision_path = ($defs.taskserv.prov_path | default "" | str replace "~" $env.HOME)
|
||||
if $provision_path == "" {
|
||||
print $"🛑 prov_path not found taskserv definition"
|
||||
exit 1
|
||||
}
|
||||
let cluster_name = $defs.taskserv.cluster_name | default ""
|
||||
if $cluster_name == "" {
|
||||
print $"🛑 cluster_name not foundi taskserv definition"
|
||||
exit 1
|
||||
}
|
||||
let domain_name = (get_domain_name $defs ($defs.taskserv.domain_name | default ""))
|
||||
if $domain_name == "" {
|
||||
print $"🛑 domain_name nor found in settings"
|
||||
exit 1
|
||||
}
|
||||
|
||||
let source_name = $"($cluster_name | default "").($domain_name)"
|
||||
|
||||
let settings_root = ($env.PROVISIONING_SETTINGS_SRC_PATH | default "" )
|
||||
let signature = ($defs.taskserv.ssl_sign | default "")
|
||||
let ssl_mode = ($defs.taskserv.ssl_mode | default "")
|
||||
let long_sign = ($defs.taskserv.long_sign | default 0)
|
||||
|
||||
if ($env.PROVISIONING_SETTINGS_SRC_PATH | path join $provision_path | path join $"($cluster_name).crt" | path exists) {
|
||||
copy_certs $defs $src $run_root $cluster_name $signature
|
||||
} else {
|
||||
if not ($env.PROVISIONING_SETTINGS_SRC_PATH | path join $provision_path | path exists) {
|
||||
^mkdir -p ($env.PROVISIONING_SETTINGS_SRC_PATH | path join $provision_path)
|
||||
}
|
||||
etcd_conf $defs $src $run_root $cluster_name $signature $ssl_mode
|
||||
make_certs $defs $src $run_root $cluster_name $signature $ssl_mode $settings_root $long_sign
|
||||
}
|
||||
}
|
||||
113
taskservs/external-nfs/default/core-nfs.yaml
Normal file
113
taskservs/external-nfs/default/core-nfs.yaml
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: nfs-provisioner
|
||||
---
|
||||
apiVersion: storage.k8s.io/v1
|
||||
kind: StorageClass
|
||||
metadata:
|
||||
name: nfs-client
|
||||
parameters:
|
||||
archiveOnDelete: "false"
|
||||
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
|
||||
reclaimPolicy: Retain
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: nfs-client-provisioner
|
||||
namespace: nfs-provisioner
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: leader-locking-nfs-client-provisioner
|
||||
namespace: nfs-provisioner
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- endpoints
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- create
|
||||
- update
|
||||
- patch
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: nfs-client-provisioner-runner
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- nodes
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- persistentvolumes
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- create
|
||||
- delete
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- persistentvolumeclaims
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- update
|
||||
- apiGroups:
|
||||
- storage.k8s.io
|
||||
resources:
|
||||
- storageclasses
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- events
|
||||
verbs:
|
||||
- create
|
||||
- update
|
||||
- patch
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: leader-locking-nfs-client-provisioner
|
||||
namespace: nfs-provisioner
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: leader-locking-nfs-client-provisioner
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: nfs-client-provisioner
|
||||
namespace: nfs-provisioner
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: run-nfs-client-provisioner
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: nfs-client-provisioner-runner
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: nfs-client-provisioner
|
||||
namespace: nfs-provisioner
|
||||
47
taskservs/external-nfs/default/deploy-external-nfs.yaml.j2
Normal file
47
taskservs/external-nfs/default/deploy-external-nfs.yaml.j2
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app: nfs-client-provisioner
|
||||
name: nfs-client-provisioner
|
||||
namespace: nfs-provisioner
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nfs-client-provisioner
|
||||
strategy:
|
||||
type: Recreate
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nfs-client-provisioner
|
||||
spec:
|
||||
containers:
|
||||
- env:
|
||||
- name: NFS_SERVER
|
||||
{%- if taskserv.ip == "$network_private_ip" %}
|
||||
value: "{{server.network_private_ip}}"
|
||||
{%- else -%}
|
||||
value: "{{server.tasks[task_pos].ip}}"
|
||||
{%- endif %}
|
||||
- name: NFS_PATH
|
||||
value: {{taskserv.shared}}
|
||||
- name: PROVISIONER_NAME
|
||||
value: k8s-sigs.io/nfs-subdir-external-provisioner
|
||||
image: registry.k8s.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2
|
||||
name: nfs-client-provisioner
|
||||
volumeMounts:
|
||||
- mountPath: /persistentvolumes
|
||||
name: nfs-client-root
|
||||
serviceAccountName: nfs-client-provisioner
|
||||
volumes:
|
||||
- name: nfs-client-root
|
||||
nfs:
|
||||
path: {{taskserv.shared}}
|
||||
{%- if taskserv.ip == "$network_private_ip" %}
|
||||
server: "{{server.network_private_ip}}"
|
||||
{%- else -%}
|
||||
server: "{{server.tasks[task_pos].ip}}"
|
||||
{%- endif %}
|
||||
15
taskservs/external-nfs/default/env-external-nfs.j2
Normal file
15
taskservs/external-nfs/default/env-external-nfs.j2
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{%- if taskserv.ip == "$network_private_ip" %}
|
||||
NFS_IP="{{server.network_private_ip}}"
|
||||
{%- else %}
|
||||
NFS_IP="{{taskserv.ip}}"
|
||||
{%- endif %}
|
||||
NFS_SHARE_PATH="{{taskserv.shared}}"
|
||||
{%- if taskserv.net == "$priv_cidr_block" %}
|
||||
{%- if "server.priv_cidr_block" %}
|
||||
NFS_NET="{{server.priv_cidr_block}}"
|
||||
{%- else %}
|
||||
NFS_NET="{{server.priv_cidr_block}}"
|
||||
{%- endif %}
|
||||
{%- else %}
|
||||
NFS_NET="{{taskserv.net}}"
|
||||
{%- endif %}
|
||||
5
taskservs/external-nfs/default/exports.j2
Normal file
5
taskservs/external-nfs/default/exports.j2
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{%- if taskserv.net == "$priv_cidr_block" %}
|
||||
{{taskserv.shared}} {{server.priv_cidr_block}}(rw,sync,no_subtree_check,no_root_squash)
|
||||
{%- else %}
|
||||
{{taskserv.shared}} {{taskserv.net}}(rw,sync,no_subtree_check,no_root_squash)
|
||||
{%- endif %}
|
||||
45
taskservs/external-nfs/default/install-external-nfs.sh
Executable file
45
taskservs/external-nfs/default/install-external-nfs.sh
Executable file
|
|
@ -0,0 +1,45 @@
|
|||
#!/bin/bash
|
||||
# Info: Script to install nfs packages
|
||||
# Author: JesusPerezLorenzo
|
||||
# Release: 1.1
|
||||
# Date: 8-07-2024
|
||||
|
||||
USAGE="install.sh "
|
||||
[ "$1" == "-h" ] && echo "$USAGE" && exit 1
|
||||
|
||||
_add_nfs_server() {
|
||||
chmod 1777 /tmp
|
||||
echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections
|
||||
DEBIAN_FRONTEND=noninteractive sudo apt-get -y -qq install sudo nfs-server
|
||||
}
|
||||
|
||||
# Update and add packages to installation
|
||||
[ -z "$(type -P exporfs)" ] && _add_nfs_server
|
||||
|
||||
[ -r "env-external-nfs" ] && . env-external-nfs
|
||||
|
||||
WORK_PATH=${WORK_PATH:-/tmp}
|
||||
|
||||
if [ -z "$NFS_IP" ] || [ -z "$NFS_NET" ] || [ -z "$NFS_SHARE_PATH" ] ; then
|
||||
echo "Error: IP NET SHARE_PATH not all set for NFS"
|
||||
exit 1
|
||||
fi
|
||||
[ ! -d "$NFS_SHARE_PATH" ] && mkdir -p "$NFS_SHARE_PATH" && chmod 777 "$NFS_SHARE_PATH"
|
||||
if ! grep -q "$NFS_NET" /etc/exports ; then
|
||||
[ -r "exports" ] && cat exports | sudo tee -a /etc/exports && exportfs -a
|
||||
fi
|
||||
if [ -r "/etc/kubernetes/manifests/kube-apiserver.yaml" ] ; then
|
||||
has_kubectl=$(type -P kubectl 2>/dev/null)
|
||||
[ -z "$has_kubectl" ] && echo "kubectl command not found" && exit 0
|
||||
if kubectl apply -f core-nfs.yaml && kubectl apply -f storage-class.yaml ; then
|
||||
[ -r "deploy-external-nfs.yaml" ] && kubectl apply -f deploy-external-nfs.yaml
|
||||
[ "$WORK_PATH" != "/tmp" ] && {
|
||||
sudo mkdir -p "$WORK_PATH/external-nfs"
|
||||
sudo mv core-nfs.yaml stroge-class.yaml deploy-external-nfs.yaml "$WORK_PATH/external-nfs"
|
||||
}
|
||||
exit 0
|
||||
else
|
||||
echo "Error kubectl install errors " && exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
8
taskservs/external-nfs/default/storage-class.yaml
Normal file
8
taskservs/external-nfs/default/storage-class.yaml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
apiVersion: storage.k8s.io/v1
|
||||
kind: StorageClass
|
||||
metadata:
|
||||
name: nfs-client
|
||||
parameters:
|
||||
archiveOnDelete: "false"
|
||||
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
|
||||
reclaimPolicy: Retain
|
||||
173
taskservs/gitea/default/app.ini.j2
Normal file
173
taskservs/gitea/default/app.ini.j2
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
{%- if server %}
|
||||
APP_NAME = {{taskserv.app_name}}
|
||||
RUN_MODE = prod
|
||||
RUN_USER = {{taskserv.run_user}}
|
||||
WORK_PATH = {{taskserv.work_path}}
|
||||
|
||||
[repository]
|
||||
ROOT = {{taskserv.work_path}}/data/git/repositories
|
||||
|
||||
[repository.local]
|
||||
LOCAL_COPY_PATH = {{taskserv.work_path}}/tmp/local-repo
|
||||
|
||||
[repository.upload]
|
||||
TEMP_PATH = {{taskserv.work_path}}/uploads
|
||||
|
||||
[server]
|
||||
PROTOCOL = {{taskserv.protocol}}
|
||||
APP_DATA_PATH = {{taskserv.work_path}}/data
|
||||
SSH_DOMAIN = {{taskserv.ssh_domain}}
|
||||
DOMAIN = {{taskserv.domain}}
|
||||
{% if taskserv.http_addr == "$network_private_ip" %}
|
||||
HTTP_ADDR="{{server.network_private_ip}}"
|
||||
{% elif taskserv.http_addr == "$network_public_ip" %}
|
||||
HTTP_ADDR="{{server.network_public_ip}}"
|
||||
{%- else %}
|
||||
HTTP_ADDR = {{taskserv.http_addr}}
|
||||
{%- endif %}
|
||||
HTTP_PORT = {{taskserv.http_port}}
|
||||
ROOT_URL = {{taskserv.root_url}}
|
||||
DISABLE_SSH = false
|
||||
LFS_START_SERVER = true
|
||||
shFS_MAX_FILE_SIZE = 0
|
||||
LFS_LOCK_PAGING_NUM = 50
|
||||
; Permission for unix socket
|
||||
UNIX_SOCKET_PERMISSION = 666
|
||||
START_SSH_SERVER = {{taskserv.start_ssh_server}}
|
||||
BUILTIN_SSH_SERVER_USER = {{taskserv.builtin_ssh_server_user}}
|
||||
; The network interface the builtin SSH server should listen on
|
||||
; SSH_LISTEN_HOST =
|
||||
; Port number to be exposed in clone URL
|
||||
SSH_PORT = {{taskserv.ssh_port}}
|
||||
; The port number the builtin SSH server should listen on
|
||||
SSH_LISTEN_PORT = %(SSH_PORT)s
|
||||
; Root path of SSH directory, default is '~/.ssh', but you have to use '/home/git/.ssh'.
|
||||
; SSH_ROOT_PATH =
|
||||
SSH_ROOT_PATH = {{taskserv.ssh_root_path}}
|
||||
; Gitea will create a authorized_keys file by default when it is not using the internal ssh server
|
||||
; If you intend to use the AuthorizedKeysCommand functionality then you should turn this off.
|
||||
SSH_CREATE_AUTHORIZED_KEYS_FILE = false
|
||||
; For the built-in SSH server, choose the ciphers to support for SSH connections,
|
||||
; for system SSH this setting has no effect
|
||||
SSH_SERVER_CIPHERS = aes128-ctr, aes192-ctr, aes256-ctr, aes128-gcm@openssh.com, arcfour256, arcfour128
|
||||
; For the built-in SSH server, choose the key exchange algorithms to support for SSH connections
|
||||
; for system SSH this setting has no effect
|
||||
SSH_SERVER_KEY_EXCHANGES = diffie-hellman-group1-sha1, diffie-hellman-group14-sha1, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, curve25519-sha256@libssh.org
|
||||
; for system SSH this setting has no effect
|
||||
SSH_SERVER_MACS = hmac-sha2-256-etm@openssh.com, hmac-sha2-256, hmac-sha1, hmac-sha1-96
|
||||
; Directory to create temporary files in when testing public keys using ssh-keygen,
|
||||
; default is the system temporary directory.
|
||||
; SSH_KEY_TEST_PATH =
|
||||
; Path to ssh-keygen, default is 'ssh-keygen' which means the shell is responsible for finding out which one to call.
|
||||
SSH_KEYGEN_PATH = ssh-keygen
|
||||
; Enable SSH Authorized Key Backup when rewriting all keys, default is true
|
||||
SSH_BACKUP_AUTHORIZED_KEYS = true
|
||||
; Enable exposure of SSH clone URL to anonymous visitors, default is false
|
||||
SSH_EXPOSE_ANONYMOUS = false
|
||||
; Indicate whether to check minimum key size with corresponding type
|
||||
MINIMUM_KEY_SIZE_CHECK = false
|
||||
; Disable CDN even in "prod" mode
|
||||
DISABLE_ROUTER_LOG = false
|
||||
OFFLINE_MODE = true
|
||||
; Generate steps:
|
||||
; $ ./gitea cert -ca=true -duration=8760h0m0s -host=myhost.example.com
|
||||
;
|
||||
; Or from a .pfx file exported from the Windows certificate store (do
|
||||
; not forget to export the private key):
|
||||
; $ openssl pkcs12 -in cert.pfx -out cert.pem -nokeys
|
||||
; $ openssl pkcs12 -in cert.pfx -out key.pem -nocerts -nodes
|
||||
# CERT_FILE = {{taskserv.work_path}}/conf/ssl/fullchain.pem
|
||||
# KEY_FILE = {{taskserv.work_path}}/conf/ssl/privkey.pem
|
||||
; $ openssl pkcs12 -in cert.pfx -out key.pem -nocerts -nodes
|
||||
CERT_FILE = {{taskserv.cert_file}}
|
||||
KEY_FILE = {{taskserv.key_file}}
|
||||
|
||||
[database]
|
||||
PATH = {{taskserv.db.path}}
|
||||
DB_TYPE = {{taskserv.db.typ}}
|
||||
{% if taskserv.db.typ != "sqlite" %}
|
||||
HOST = {{taskserv.db.host | replace(from="$network_private_ip", to=server.network_private_ip)}}
|
||||
NAME = {{taskserv.db.name}}
|
||||
USER = {{taskserv.db.user}}
|
||||
PASSWD = {{taskserv.db.password}}
|
||||
LOG_SQL = false
|
||||
SCHEMA =
|
||||
CHARSET = {{taskserv.db.charset}}
|
||||
SSL_MODE = {{taskserv.db.ssl_mode}}
|
||||
{%- endif %}
|
||||
|
||||
[indexer]
|
||||
ISSUE_INDEXER_PATH = {{taskserv.work_path}}/indexers/issues.bleve
|
||||
|
||||
[session]
|
||||
PROVIDER_CONFIG = {{taskserv.work_path}}/sessions
|
||||
PROVIDER = file
|
||||
|
||||
[picture]
|
||||
AVATAR_UPLOAD_PATH = {{taskserv.work_path}}/avatars
|
||||
REPOSITORY_AVATAR_UPLOAD_PATH = {{taskserv.work_path}}/repo-avatars
|
||||
|
||||
[attachment]
|
||||
PATH = {{taskserv.work_path}}/attachments
|
||||
|
||||
[log]
|
||||
MODE = console
|
||||
LEVEL = info
|
||||
ROOT_PATH = {{taskserv.work_path}}/log
|
||||
|
||||
[security]
|
||||
INSTALL_LOCK = true
|
||||
SECRET_KEY =
|
||||
REVERSE_PROXY_LIMIT = 1
|
||||
REVERSE_PROXY_TRUSTED_PROXIES = *
|
||||
PASSWORD_HASH_ALGO = pbkdf2
|
||||
|
||||
[service]
|
||||
DISABLE_REGISTRATION = {{taskserv.disable_registration}}
|
||||
REQUIRE_SIGNIN_VIEW = {{taskserv.require_signin_view}}
|
||||
REGISTER_EMAIL_CONFIRM = false
|
||||
ENABLE_NOTIFY_MAIL = false
|
||||
ALLOW_ONLY_EXTERNAL_REGISTRATION = false
|
||||
ENABLE_CAPTCHA = false
|
||||
DEFAULT_KEEP_EMAIL_PRIVATE = false
|
||||
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
|
||||
DEFAULT_ENABLE_TIMETRACKING = true
|
||||
NO_REPLY_ADDRESS = noreply.localrepo.cloudnative.zone
|
||||
|
||||
[lfs]
|
||||
PATH = {{taskserv.work_path}}/data/git/lfs
|
||||
|
||||
[mailer]
|
||||
ENABLED = false
|
||||
|
||||
[openid]
|
||||
ENABLE_OPENID_SIGNIN = true
|
||||
ENABLE_OPENID_SIGNUP = true
|
||||
|
||||
[cron.update_checker]
|
||||
ENABLED = false
|
||||
|
||||
[repository.pull-request]
|
||||
DEFAULT_MERGE_STYLE = merge
|
||||
|
||||
[repository.signing]
|
||||
DEFAULT_TRUST_MODEL = committer
|
||||
|
||||
[oauth2]
|
||||
|
||||
[webhook]
|
||||
; Hook task queue length, increase if webhook shooting starts hanging
|
||||
QUEUE_LENGTH = 1000
|
||||
; Deliver timeout in seconds
|
||||
DELIVER_TIMEOUT =
|
||||
; Allow insecure certification
|
||||
SKIP_TLS_VERIFY = false
|
||||
; Number of history information in each page
|
||||
PAGING_NUM = 10
|
||||
{% if taskserv.webhook_allowed_hosts_list == "$server.priv_cidr_block" %}
|
||||
ALLOWED_HOST_LIST = {{server.priv_cidr_block}}
|
||||
{%- else %}
|
||||
ALLOWED_HOST_LIST = {{taskserv.webhook_allowed_hosts_list}}
|
||||
{%- endif %}
|
||||
|
||||
{%- endif %}
|
||||
19
taskservs/gitea/default/env-gitea.j2
Normal file
19
taskservs/gitea/default/env-gitea.j2
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
GITEA_VERSION="{{taskserv.version}}"
|
||||
GITEA_RUN_MODE=local
|
||||
GITEA_RUN_PATH={{taskserv.run_path}}
|
||||
GITEA_SYSTEMCTL_MODE=enabled
|
||||
GITEA_ETC_PATH={{taskserv.etc_path}}
|
||||
GITEA_LIB_PATH={{taskserv.work_path}}
|
||||
GITEA_DB_TYPE={{taskserv.db.typ}}
|
||||
GITEA_CONFIG_FILE={{taskserv.config_path}}
|
||||
GITEA_RUN_USER={{taskserv.run_user.name}}
|
||||
GITEA_RUN_GROUP={{taskserv.run_user.group}}
|
||||
GITEA_RUN_USER_HOME={{taskserv.run_user.home}}
|
||||
GITEA_SSL_CERTS_PATH={{taskserv.certs_path}}
|
||||
GITEA_ADM_USER={{taskserv.adm_user.name}}
|
||||
GITEA_ADM_PASSWORD={{taskserv.adm_user.password}}
|
||||
GITEA_ADM_EMAIL={{taskserv.adm_user.email}}
|
||||
GITEA_DOMAIN={{taskserv.domain}}
|
||||
GITEA_CDCI_USER={{taskserv.cdci_user}}
|
||||
GITEA_CDCI_GROUP={{taskserv.cdci_group}}
|
||||
GITEA_CDCI_USER_HOME={{taskserv.cdci_user_home}}
|
||||
87
taskservs/gitea/default/gitea.service.j2
Normal file
87
taskservs/gitea/default/gitea.service.j2
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
{%- if server %}
|
||||
[Unit]
|
||||
Description=Gitea ({{taskserv.app_name}})
|
||||
After=syslog.target
|
||||
After=network.target
|
||||
###
|
||||
# Don't forget to add the database service dependencies
|
||||
###
|
||||
#
|
||||
{%- if taskserv.db.typ == "mysql" %}
|
||||
Wants=mysql.service
|
||||
After=mysql.service
|
||||
{%- elif taskserv.db.typ == "mariadb" %}
|
||||
Wants=mariadb.service
|
||||
After=mariadb.service
|
||||
{%- elif taskserv.db.typ == "postgres" %}
|
||||
Wants=postgresql.service
|
||||
After=postgresql.service
|
||||
{%- endif %}
|
||||
#
|
||||
#Wants=memcached.service
|
||||
#After=memcached.service
|
||||
#
|
||||
#Wants=redis.service
|
||||
#After=redis.service
|
||||
#
|
||||
###
|
||||
# If using socket activation for main http/s
|
||||
###
|
||||
#
|
||||
#After=gitea.main.socket
|
||||
#Requires=gitea.main.socket
|
||||
#
|
||||
###
|
||||
# (You can also provide gitea an http fallback and/or ssh socket too)
|
||||
#
|
||||
# An example of /etc/systemd/system/gitea.main.socket
|
||||
###
|
||||
##
|
||||
## [Unit]
|
||||
## Description=Gitea Web Socket
|
||||
## PartOf=gitea.service
|
||||
##
|
||||
## [Socket]
|
||||
## Service=gitea.service
|
||||
## ListenStream=<some_port>
|
||||
## NoDelay=true
|
||||
##
|
||||
## [Install]
|
||||
## WantedBy=sockets.target
|
||||
##
|
||||
###
|
||||
|
||||
[Service]
|
||||
# Modify these two values and uncomment them if you have
|
||||
# repos with lots of files and get an HTTP error 500 because
|
||||
# of that
|
||||
###
|
||||
#LimitMEMLOCK=infinity
|
||||
#LimitNOFILE=65535
|
||||
RestartSec=2s
|
||||
Type=simple
|
||||
User={{taskserv.run_user.name}}
|
||||
Group={{taskserv.run_user.group}}
|
||||
WorkingDirectory={{taskserv.work_path}}
|
||||
# If using Unix socket: tells systemd to create the /run/gitea folder, which will contain the gitea.sock file
|
||||
# (manually creating /run/gitea doesn't work, because it would not persist across reboots)
|
||||
#RuntimeDirectory=gitea
|
||||
ExecStart={{taskserv.run_path}} web --config {{taskserv.etc_path}}/{{taskserv.config_path}}
|
||||
Restart=always
|
||||
Environment=USER={{taskserv.run_user.name}} HOME={{taskserv.run_user.home}} GITEA_WORK_DIR={{taskserv.work_path}}
|
||||
# If you install Git to directory prefix other than default PATH (which happens
|
||||
# for example if you install other versions of Git side-to-side with
|
||||
# distribution version), uncomment below line and add that prefix to PATH
|
||||
# Don't forget to place git-lfs binary on the PATH below if you want to enable
|
||||
# Git LFS support
|
||||
#Environment=PATH=/path/to/git/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
||||
# If you want to bind Gitea to a port below 1024, uncomment
|
||||
# the two values below, or use socket activation to pass Gitea its ports as above
|
||||
###
|
||||
#CapabilityBoundingSet=CAP_NET_BIND_SERVICE
|
||||
#AmbientCapabilities=CAP_NET_BIND_SERVICE
|
||||
###
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
{%- endif %}
|
||||
168
taskservs/gitea/default/install-gitea.sh
Executable file
168
taskservs/gitea/default/install-gitea.sh
Executable file
|
|
@ -0,0 +1,168 @@
|
|||
#!/bin/bash
|
||||
# Info: Script to install Gitea
|
||||
# Author: JesusPerezLorenzo
|
||||
# Release: 1.0
|
||||
# Date: 12-12-2023
|
||||
|
||||
USAGE="install-gitea.sh "
|
||||
[ "$1" == "-h" ] && echo "$USAGE" && exit 1
|
||||
|
||||
[ -r "env-gitea" ] && . ./env-gitea
|
||||
|
||||
GITEA_VERSION=${GITEA_VERSION:-1.21.7}
|
||||
|
||||
GITEA_URL=https://dl.gitea.io/gitea
|
||||
ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')"
|
||||
GITEA_FILE=$GITEA_VERSION/gitea-$GITEA_VERSION-linux-$ARCH
|
||||
GITEA_ARCH=linux-$ARCH
|
||||
|
||||
GITEA_RUN_PATH=${GITEA_RUN_PATH:-/usr/local/bin/gitea}
|
||||
|
||||
GITEA_SYSTEMCTL_MODE=${GITEA_SYSTEMCTL_MODE:-enabled}
|
||||
|
||||
GITEA_ETC_PATH=${GITEA_ETC_PATH:-/etc/gitea}
|
||||
|
||||
GITEA_LIB_PATH=${GITEA_LIB_PATH:-/home2/lib/gitea}
|
||||
GITEA_CONFIG_FILE=${GITEA_CONFIG_FILE:-app.ini}
|
||||
|
||||
GITEA_RUN_USER=${GITEA_RUN_USER:-gitea}
|
||||
GITEA_RUN_GROUP=${GITEA_RUN_GROUP:-gitea}
|
||||
GITEA_RUN_USER_HOME=${GITEA_RUN_USER_HOME:-/home/gitea}
|
||||
|
||||
GITEA_PKG_NAME=gitea
|
||||
|
||||
CMD_TSKSRVC=${1:-install}
|
||||
|
||||
#ORG="$(pwd)"
|
||||
export LC_CTYPE=C.UTF-8
|
||||
export LANG=C.UTF-8
|
||||
|
||||
_init() {
|
||||
local curr_vers
|
||||
[ -z "$GITEA_VERSION" ] || [ -z "$GITEA_ARCH" ] || [ -z "$GITEA_URL" ] || [ -z "$GITEA_FILE" ] && exit 1
|
||||
if [ -x "$GITEA_RUN_PATH" ] ; then
|
||||
curr_vers=$(${GITEA_RUN_PATH} -v | awk '{print $3}')
|
||||
else
|
||||
curr_vers=0
|
||||
fi
|
||||
if [ "$curr_vers" != "$GITEA_VERSION" ] || [ "$curr_vers" != "$GITEA_VERSION" ]; then
|
||||
if curl -fsSL "${GITEA_URL}/${GITEA_VERSION}/gitea-${GITEA_VERSION}-${GITEA_ARCH}" -o gitea ; then
|
||||
sudo mv gitea "${GITEA_RUN_PATH}"
|
||||
sudo chmod +x "${GITEA_RUN_PATH}"
|
||||
else
|
||||
echo "error download ${GITEA_URL}/${GITEA_VERSION}/gitea-${GITEA_VERSION}-${GITEA_ARCH}"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
_config_gitea() {
|
||||
local has_user=""
|
||||
local http_addr
|
||||
local etc_entry
|
||||
has_user=$(grep "$GITEA_RUN_USER" /etc/passwd)
|
||||
if [ -z "$has_user" ] ; then
|
||||
sudo adduser \
|
||||
--system \
|
||||
--shell /bin/bash \
|
||||
--gecos 'Git Version Control' \
|
||||
--group \
|
||||
--disabled-password \
|
||||
--home "$GITEA_RUN_USER_HOME" \
|
||||
"${GITEA_RUN_USER}"
|
||||
fi
|
||||
if [ ! -d "$GITEA_RUN_USER_HOME" ] ; then
|
||||
sudo mkdir -p "$GITEA_RUN_USER_HOME"
|
||||
sudo chown -R "$GITEA_RUN_USER":"$GITEA_RUN_GROUP" "$GITEA_RUN_USER_HOME"
|
||||
fi
|
||||
sudo mkdir -p "${GITEA_LIB_PATH}"/{custom,data,log}
|
||||
sudo chown -R "${GITEA_RUN_USER}:${GITEA_RUN_GROUP}" "${GITEA_LIB_PATH}"
|
||||
sudo chmod -R 750 "${GITEA_LIB_PATH}"
|
||||
[ ! -d "${GITEA_ETC_PATH}" ] && sudo mkdir "${GITEA_ETC_PATH}"
|
||||
sudo chmod 750 "${GITEA_ETC_PATH}"
|
||||
sudo chown -R root:"${GITEA_RUN_GROUP}" "${GITEA_ETC_PATH}"
|
||||
|
||||
[ ! -r "${GITEA_ETC_PATH}/${GITEA_CONFIG_FILE}" ] && [ -r "app.ini" ] && sudo cp app.ini "${GITEA_ETC_PATH}/${GITEA_CONFIG_FILE}"
|
||||
sudo chown "$GITEA_RUN_USER":"$GITEA_RUN_GROUP" "${GITEA_ETC_PATH}/${GITEA_CONFIG_FILE}"
|
||||
[ -r "${GITEA_ETC_PATH}/${GITEA_CONFIG_FILE}" ] && sudo chmod 640 "${GITEA_ETC_PATH}/${GITEA_CONFIG_FILE}"
|
||||
|
||||
if [ ! -r "${GITEA_ETC_PATH}/.psql.sql" ] && [ -r "psql.sql" ] ; then
|
||||
sudo cp psql.sql "${GITEA_ETC_PATH}/.psql.sql"
|
||||
case "$GITEA_DB_TYPE" in
|
||||
postgres) sudo -u postgres psql < psql.sql
|
||||
;;
|
||||
esac
|
||||
rm -f psql.sql
|
||||
sudo chmod 400 "${GITEA_ETC_PATH}/.psql.sql"
|
||||
fi
|
||||
if [ -d "ssl" ] ; then
|
||||
sudo rm -rf "${GITEA_SSL_CERTS_PATH}"
|
||||
sudo cp -pr ssl "${GITEA_SSL_CERTS_PATH}"
|
||||
sudo chown -R "${GITEA_RUN_USER}:${GITEA_RUN_GROUP}" "${GITEA_SSL_CERTS_PATH}"
|
||||
sudo chmod 400 "${GITEA_SSL_CERTS_PATH}"/*key*pem 2>/dev/null
|
||||
fi
|
||||
if [ -r "${GITEA_RUN_PATH}" ] && [ -r "gitea.service" ] ; then
|
||||
sudo cp gitea.service /lib/systemd/system/gitea.service
|
||||
[ "${GITEA_SYSTEMCTL_MODE}" == "enabled" ] && sudo systemctl enable gitea --now >/dev/null 2>&1
|
||||
# [ "${GITEA_SYSTEMCTL_MODE}" == "start" ] && sudo systemctl start gitea >/dev/null 2>&1
|
||||
fi
|
||||
if [ -d "${GITEA_CDCI_USER_HOME}" ] && [ -n "${GITEA_CDCI_USER_HOME}" ] && [ -r "ssh-config" ] ; then
|
||||
sudo cp ssh-config "${GITEA_CDCI_USER_HOME}/.ssh/config"
|
||||
if [ -d ".ssh" ] ; then
|
||||
sudo cp -pr .ssh/* "${GITEA_CDCI_USER_HOME}/.ssh"
|
||||
sudo chown -R "${GITEA_CDCI_USER}:${GITEA_CDCI_GROUP}" "${GITEA_CDCI_USER_HOME}/.ssh"
|
||||
fi
|
||||
fi
|
||||
[ -d ".ssh" ] && rm -rf .ssh
|
||||
http_addr=$(sudo grep HTTP_ADDR /etc/gitea/app.ini | cut -f2 -d"=" | sed "s/ //g")
|
||||
if [ -n "$http_addr" ] && [ -n "$GITEA_DOMAIN" ]; then
|
||||
etc_entry=$(sudo grep "$http_addr" /etc/hosts | grep -v "$GITEA_DOMAIN")
|
||||
[ -n "$etc_entry" ] && sudo sed -i "s/$etc_entry/$etc_entry $GITEA_DOMAIN/g" /etc/hosts
|
||||
fi
|
||||
if [ ! -r "$GITEA_ETC_PATH/.done" ] && [ -n "$GITEA_ADM_USER" ] ; then
|
||||
_start_gitea
|
||||
echo "wait 11 to gitea init ..."
|
||||
sleep 11
|
||||
if sudo -u "$GITEA_RUN_USER" gitea admin user create --username "$GITEA_ADM_USER" --password "$GITEA_ADM_PASSWORD" --email "$GITEA_ADM_EMAIL" --admin --config "${GITEA_ETC_PATH}/${GITEA_CONFIG_FILE}" ; then
|
||||
date +%Y_%m_%d_%H_%M_%S | sudo tee "$GITEA_ETC_PATH/.done"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
_remove_gitea() {
|
||||
sudo timeout -k 10 20 systemctl stop "$GITEA_PKG_NAME" >/dev/null 2>&1
|
||||
sudo timeout -k 10 20 systemctl disable "$GITEA_PKG_NAME" >/dev/null 2>&1
|
||||
sudo rm -f "${GITEA_RUN_PATH}"
|
||||
}
|
||||
|
||||
_start_gitea() {
|
||||
if [ "$GITEA_SYSTEMCTL_MODE" == "enabled" ] ; then
|
||||
sudo timeout -k 10 20 systemctl enable "$GITEA_PKG_NAME" >/dev/null 2>&1
|
||||
else
|
||||
sudo timeout -k 10 20 systemctl disable "$GITEA_PKG_NAME" >/dev/null 2>&1
|
||||
fi
|
||||
[ -r "/lib/systemd/system/gitea.service" ] && _restart_gitea && return
|
||||
sudo timeout -k 10 20 systemctl start "$GITEA_PKG_NAME" >/dev/null 2>&1
|
||||
}
|
||||
_restart_gitea() {
|
||||
sudo timeout -k 10 20 systemctl restart "$GITEA_PKG_NAME" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
if [ "$CMD_TSKSRVC" == "remove" ] ; then
|
||||
_remove_gitea
|
||||
exit
|
||||
fi
|
||||
if ! _init ; then
|
||||
echo "error gitea install"
|
||||
exit 1
|
||||
fi
|
||||
[ "$CMD_TSKSRVC" == "update" ] && _restart_gitea && exit 0
|
||||
if ! _config_gitea ; then
|
||||
echo "error gitea config"
|
||||
exit 1
|
||||
fi
|
||||
if ! _start_gitea ; then
|
||||
echo "error gitea start"
|
||||
exit 1
|
||||
fi
|
||||
26
taskservs/gitea/default/prepare
Executable file
26
taskservs/gitea/default/prepare
Executable file
|
|
@ -0,0 +1,26 @@
|
|||
#!/usr/bin/env nu
|
||||
# Info: Prepare for gitea installation
|
||||
# Author: JesusPerezLorenzo
|
||||
# Release: 1.0.2
|
||||
# Date: 19-11-2023
|
||||
|
||||
use lib_provisioning/cmd/env.nu *
|
||||
use lib_provisioning/cmd/lib.nu *
|
||||
|
||||
use lib_provisioning/utils/ui.nu *
|
||||
|
||||
print $"(_ansi green_bold)Gitea(_ansi reset) with ($env.PROVISIONING_VARS) "
|
||||
|
||||
let defs = load_defs
|
||||
|
||||
let ssh_keys = ($defs.taskserv.cdci_key | str replace "~" $env.HOME | str trim)
|
||||
|
||||
if $ssh_keys != "" {
|
||||
let target_path = $env.PROVISIONING_WK_ENV_PATH
|
||||
^mkdir -p $"($target_path)/.ssh"
|
||||
for key in ($ssh_keys | split row " ") {
|
||||
log_debug $"on ($key)"
|
||||
if ($key | path exists) { cp $key $"($target_path)/.ssh" }
|
||||
if ($"($key).pub" | path exists) { cp $"($key).pub" $"($target_path)/.ssh" }
|
||||
}
|
||||
}
|
||||
9
taskservs/gitea/default/psql.sql.j2
Normal file
9
taskservs/gitea/default/psql.sql.j2
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
-- su -
|
||||
-- su -u postgres
|
||||
-- psql
|
||||
create database {{taskserv.db.name}};
|
||||
create user {{taskserv.db.user}} with encrypted password '{{taskserv.db.password}}';
|
||||
grant all privileges on database {{taskserv.db.name}} to {{taskserv.db.user}};
|
||||
|
||||
GRANT CREATE ON SCHEMA public TO {{taskserv.db.user}};
|
||||
ALTER DATABASE {{taskserv.db.name}} OWNER TO {{taskserv.db.user}};
|
||||
8
taskservs/gitea/default/ssh-config.j2
Normal file
8
taskservs/gitea/default/ssh-config.j2
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
Host {{taskserv.domain}}
|
||||
User git
|
||||
HostName {{taskserv.domain}}
|
||||
IdentityFile {{taskserv.cdci_key}}
|
||||
ServerAliveInterval 240
|
||||
StrictHostKeyChecking no
|
||||
UserKnownHostsFile=/dev/null
|
||||
Port {{taskserv.ssh_port}}
|
||||
180
taskservs/info.md
Normal file
180
taskservs/info.md
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
Perfect! I've successfully created comprehensive README.md files for all three taskservs. Here's a summary of what was created:
|
||||
|
||||
📚 README.md Files Created
|
||||
|
||||
🌐 Radicle Task Service (/taskservs/radicle/README.md)
|
||||
|
||||
- Peer-to-peer Git hosting and code collaboration
|
||||
- Cryptographic identities and decentralized workflows
|
||||
- Web interface with HTTP daemon configuration
|
||||
- Network configuration for P2P connectivity
|
||||
- Command-line usage examples and service management
|
||||
|
||||
💻 Coder Task Service (/taskservs/coder/README.md)
|
||||
|
||||
- Remote development environments with web-based IDE access
|
||||
- Database support (SQLite, PostgreSQL) with production configurations
|
||||
- OAuth/OIDC authentication for GitHub, Google, and custom providers
|
||||
- Workspace templates (Docker, Kubernetes) with Terraform examples
|
||||
- TLS/SSL configuration and wildcard domain support
|
||||
|
||||
🔐 Cosmian KMS Task Service (/taskservs/kms/README.md)
|
||||
|
||||
- Enterprise key management with post-quantum cryptography
|
||||
- Multi-database support (SQLite, PostgreSQL, MySQL, Redis)
|
||||
- FIPS 140-2 compliance and hardware security module integration
|
||||
- Attribute-based encryption and secure multi-party computation
|
||||
- JWT authentication with OpenID Connect integration
|
||||
|
||||
🎯 Key Features of Each README
|
||||
|
||||
Comprehensive Documentation
|
||||
|
||||
- Configuration examples (basic → production → enterprise)
|
||||
- Usage instructions with CLI examples
|
||||
- Troubleshooting guides for common issues
|
||||
- Security considerations and best practices
|
||||
- Performance optimization recommendations
|
||||
|
||||
Practical Examples
|
||||
|
||||
- Service management commands
|
||||
- API integration examples
|
||||
- Monitoring integration snippets
|
||||
- Backup/recovery procedures
|
||||
- Architecture diagrams and file structure layouts
|
||||
|
||||
Production-Ready Guidance
|
||||
|
||||
- System requirements (minimum vs production)
|
||||
- Network configuration and firewall rules
|
||||
- High availability setups
|
||||
- Integration patterns with CI/CD and monitoring systems
|
||||
- Security hardening recommendations
|
||||
|
||||
Each README provides complete deployment and operational guidance for the respective taskserv, making them ready for production use in
|
||||
cloud-native environments.
|
||||
|
||||
Perfect! I've successfully created comprehensive README.md files for all Polkadot-related taskservs. Here's a summary of what was
|
||||
created:
|
||||
|
||||
📚 Polkadot Ecosystem README.md Files Created
|
||||
|
||||
🚀 Polkadot Bootnode (/taskservs/polkadot-bootnode/README.md)
|
||||
|
||||
- Network Discovery Service - Helps new nodes find and connect to Polkadot networks
|
||||
- Multi-Protocol Support - P2P (30310), WebSocket (30311), WSS (30312)
|
||||
- SSL/TLS Integration - Complete HTTPS/WSS encryption with certificate management
|
||||
- High Availability - Stable peer discovery for production networks
|
||||
- Chain Support - Polkadot, Kusama, Westend, and custom chains
|
||||
|
||||
🔗 Polkadot Node (/taskservs/polkadot-node/README.md)
|
||||
|
||||
- Multiple Node Types - Full, Light, Archive, and Validator nodes
|
||||
- Synchronization Modes - Full, Fast, and Warp sync options
|
||||
- Network Support - Polkadot, Kusama, Westend networks
|
||||
- Performance Optimization - Configurable caching, pruning, and execution strategies
|
||||
- RPC Services - WebSocket and HTTP endpoints with rate limiting
|
||||
|
||||
⛓️ Polkadot Solochain (/taskservs/polkadot-solochain/README.md)
|
||||
|
||||
- Independent Blockchain - Standalone blockchain using Polkadot SDK
|
||||
- PVM Support - Full Polkadot Virtual Machine with WASM execution
|
||||
- Substrate Framework - Modular pallet system with custom runtime
|
||||
- Consensus Mechanisms - Aura (block authoring) + GRANDPA (finality)
|
||||
- Development & Production - Both environments with automated build system
|
||||
|
||||
🔒 Polkadot Validator (/taskservs/polkadot-validator/README.md)
|
||||
|
||||
- Production Validator - Enterprise-grade validator with security hardening
|
||||
- Security Features - Firewall, fail2ban, SSH restrictions, encrypted key backup
|
||||
- Session Key Management - Automated generation, rotation, and secure backup
|
||||
- Comprehensive Monitoring - Health checks, Prometheus metrics, alerting system
|
||||
- High Availability - Failover support and backup node configuration
|
||||
|
||||
🧟 Polkadot Zombienet (/taskservs/polkadot-zombienet/README.md)
|
||||
|
||||
- Network Testing Framework - Spawn ephemeral networks for comprehensive testing
|
||||
- Multi-Provider Support - Native, Kubernetes, Docker, and Podman providers
|
||||
- Parachain Testing - Full parachain deployment with XCM cross-chain messaging
|
||||
- Test Automation - Domain-specific language (DSL) for test scenarios
|
||||
- CI/CD Integration - Complete integration with testing pipelines
|
||||
|
||||
🎯 Key Features Across All Services
|
||||
|
||||
Comprehensive Documentation
|
||||
|
||||
- Configuration Examples - Basic → Production → Enterprise setups
|
||||
- Architecture Diagrams - Clear system and network architecture
|
||||
- Usage Instructions - Complete CLI examples and service management
|
||||
- Troubleshooting Guides - Detailed problem resolution procedures
|
||||
|
||||
Production-Ready Features
|
||||
|
||||
- Security Hardening - Comprehensive security configurations
|
||||
- Performance Optimization - Hardware and software tuning guidance
|
||||
- Monitoring Integration - Prometheus metrics and alerting
|
||||
- High Availability - Clustering and failover configurations
|
||||
|
||||
Developer Experience
|
||||
|
||||
- Multiple Deployment Options - Native, containerized, and Kubernetes
|
||||
- Integration Examples - CI/CD, monitoring, and load balancer configurations
|
||||
- Development Workflows - Complete development and testing procedures
|
||||
- Resource Requirements - Clear minimum and recommended specifications
|
||||
|
||||
Operational Excellence
|
||||
|
||||
- Backup & Recovery - Complete backup and disaster recovery procedures
|
||||
- Service Management - Systemd integration with health monitoring
|
||||
- Log Management - Structured logging with troubleshooting guidance
|
||||
- Performance Tuning - System and application optimization
|
||||
|
||||
Each README provides complete operational guidance for deploying and managing Polkadot infrastructure components, from simple
|
||||
development setups to enterprise-grade production deployments with comprehensive security, monitoring, and high-availability features.
|
||||
|
||||
|
||||
✅ Completed Tasks
|
||||
|
||||
1. Updated polkadot-solochain - Added ELVES consensus configuration examples including hybrid consensus support and Ethereum
|
||||
compatibility
|
||||
2. Updated polkadot-validator - Enhanced with ELVES-specific validator configuration and operational commands
|
||||
3. Updated polkadot-node - Added ELVES consensus support with configuration examples and RPC commands
|
||||
4. Updated polkadot-zombienet - Integrated ELVES consensus testing capabilities with hybrid consensus testing scenarios
|
||||
|
||||
Key ELVES Features Added
|
||||
|
||||
- Configuration Examples - Complete KCL configuration schemas for ELVES consensus
|
||||
- Operational Commands - RPC calls for monitoring ELVES consensus state, epochs, and validator participation
|
||||
- Testing Support - Zombienet configurations for testing ELVES consensus and hybrid scenarios
|
||||
- Ethereum Compatibility - EVM runtime support and Ethereum-compatible features
|
||||
- Hybrid Consensus - Support for Aura + ELVES consensus with automatic transitions
|
||||
|
||||
All Polkadot taskservs that use consensus mechanisms now include comprehensive ELVES support as requested.
|
||||
|
||||
Perfect! I have successfully created comprehensive README.md files for all the requested taskservs:
|
||||
|
||||
✅ Completed README.md Files
|
||||
|
||||
1. ✅ etcd - Distributed key-value store with clustering, replication, and security features
|
||||
2. ✅ gitea - Self-hosted Git service with CI/CD, SSH, SSL, and enterprise features
|
||||
3. ✅ postgres - Advanced PostgreSQL with high availability, replication, and performance tuning
|
||||
4. ✅ proxy (HAProxy) - Load balancer with SSL termination, health checks, and high availability
|
||||
5. ✅ rook-ceph - Cloud-native storage with block, object, and file storage capabilities
|
||||
|
||||
Each README.md includes:
|
||||
|
||||
- Comprehensive Overview - Detailed feature descriptions and capabilities
|
||||
- Multiple Configuration Examples - From basic to production and enterprise setups using KCL schemas
|
||||
- Complete Usage Instructions - Deployment, management, and operational commands
|
||||
- Architecture Diagrams - Visual representations of system architecture
|
||||
- System Requirements - Minimum and production requirements
|
||||
- Troubleshooting Guides - Common issues and resolution steps
|
||||
- Security Considerations - Best practices and security configurations
|
||||
- Performance Optimization - Tuning recommendations and optimization strategies
|
||||
- Integration Examples - Real-world integration scenarios
|
||||
- Resource Links - Official documentation and community resources
|
||||
|
||||
All files are production-ready documentation that completely replace the info.md files and provide comprehensive operational guidance
|
||||
for each taskserv. The documentation follows a consistent structure and provides everything needed to deploy, manage, and operate
|
||||
these critical infrastructure components.
|
||||
146
taskservs/ip-aliases/default/alias_sdn.sh
Executable file
146
taskservs/ip-aliases/default/alias_sdn.sh
Executable file
|
|
@ -0,0 +1,146 @@
|
|||
#!/bin/bash
|
||||
USAGE="alias_sdn.sh up(default)|down|check"
|
||||
[ "$1" == "-h" ] && echo "$USAGE" && exit
|
||||
|
||||
[ -z "$1" ] && echo "Task not found" && exit 1
|
||||
TASK="$1"
|
||||
IP_LIST=$2
|
||||
[ -z "$2" ] && echo "IP List not found" && exit 1
|
||||
SETUP_MODE=${SETUP_MODE:-alias}
|
||||
INTERFACE=${INTERFACE:-eth2:1}
|
||||
DEV_INTERFACE=${DEV_INTERFACE:-eth2}
|
||||
NETMASK=${NETMASK:-255.255.255.0}
|
||||
|
||||
ROOT_INTERFACES=${ROOT_INTERFACES:-/etc/network/interfaces}
|
||||
BACKUP_INTERFACES=${BACKUP_INTERFACES:-/etc/network/_interfaces}
|
||||
|
||||
_ping_ip_host() {
|
||||
[ -z "$1" ] && return 1
|
||||
local str_wait=""
|
||||
case $(uname -s) in
|
||||
Darwin|darwin) str_wait="" ;;
|
||||
*) str_wait="-w2"
|
||||
esac
|
||||
ping "$1" -c2 -q $str_wait >/dev/null 2>/dev/null
|
||||
}
|
||||
_add_interface() {
|
||||
echo "
|
||||
auto $INTERFACE
|
||||
iface $INTERFACE inet static
|
||||
address $IP
|
||||
netmask $NETMASK
|
||||
" >> "$ROOT_INTERFACES"
|
||||
}
|
||||
_add_as_alias() {
|
||||
if _ping_ip_host "$IP" ; then
|
||||
echo "$IP is alive"
|
||||
return
|
||||
fi
|
||||
ip addr add "$IP"/24 dev "$DEV_INTERFACE" label "$INTERFACE"
|
||||
}
|
||||
_remove_as_alias() {
|
||||
if ! _ping_ip_host "$IP" ; then
|
||||
echo "$IP is not alive"
|
||||
return
|
||||
fi
|
||||
ip addr delete "$IP"/24 dev "$DEV_INTERFACE" label "$INTERFACE"
|
||||
}
|
||||
_add_as_system() {
|
||||
if _ping_ip_host "$IP" ; then
|
||||
echo "$IP is alive"
|
||||
return
|
||||
fi
|
||||
local has_ip=""
|
||||
has_ip=$(grep "$IP" "$ROOT_INTERFACES")
|
||||
if [ -z "$has_ip" ] ; then
|
||||
[ ! -r "$BACKUP_INTERFACES" ] && cp "$ROOT_INTERFACES" "$BACKUP_INTERFACES"
|
||||
_add_interface
|
||||
fi
|
||||
}
|
||||
_remove_as_system() {
|
||||
local has_ip=""
|
||||
has_ip=$(grep "$IP" "$ROOT_INTERFACES")
|
||||
if [ -n "$has_ip" ] ; then
|
||||
[ -r "$BACKUP_INTERFACES" ] && cp "$BACKUP_INTERFACES" "$ROOT_INTERFACES"
|
||||
has_ip=$(grep "$IP" "$ROOT_INTERFACES")
|
||||
[ -n "$has_ip" ] && echo "Unable to remove $IP from $$ROOT_INTERFACES" && exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
_check_interface() {
|
||||
local ip_a
|
||||
#ifaces_data=$(ip a | grep "inet " | grep dynamic | sed 's/inet //g' | awk '{print $7":"$1}' | grep "$INTERFACE")
|
||||
ip_a=$(ip a | grep "inet " | grep "$INTERFACE" | awk '{print $2}' | cut -f1 -d"/" | grep "$IP")
|
||||
if [ "$IP" != "$ip_a" ] ; then
|
||||
echo "$IP for $INTERFACE not found"
|
||||
IP_ACTIVE=""
|
||||
else
|
||||
echo "$IP active on $INTERFACE"
|
||||
IP_ACTIVE="on"
|
||||
fi
|
||||
if _ping_ip_host "$IP" ; then
|
||||
echo "$IP is alive"
|
||||
fi
|
||||
}
|
||||
|
||||
_restart_networking() {
|
||||
systemctl restart networing
|
||||
}
|
||||
|
||||
_on_ip() {
|
||||
IP_ACTIVE=""
|
||||
_check_interface
|
||||
|
||||
case "$TASK" in
|
||||
up|u) [ -n "$IP_ACTIVE" ] && return
|
||||
TASK="up"
|
||||
;;
|
||||
down|d) [ -z "$IP_ACTIVE" ] && return
|
||||
TASK="down"
|
||||
;;
|
||||
check|c|status|s)
|
||||
return
|
||||
;;
|
||||
ping|p|resp|r)
|
||||
if _ping_ip_host "$IP" ; then
|
||||
echo "$IP responding"
|
||||
else
|
||||
echo "$IP not responding"
|
||||
fi
|
||||
return
|
||||
;;
|
||||
*) echo "Option $TASK unknown"
|
||||
exit 1
|
||||
esac
|
||||
|
||||
case "$SETUP_MODE" in
|
||||
system|sys)
|
||||
if [ "$TASK" == "up" ] ; then
|
||||
_add_as_system
|
||||
else
|
||||
_remove_as_system
|
||||
fi
|
||||
_restart_networking
|
||||
_check_interface
|
||||
;;
|
||||
alias|a)
|
||||
if [ "$TASK" == "up" ] ; then
|
||||
_add_as_alias
|
||||
else
|
||||
_remove_as_alias
|
||||
fi
|
||||
_check_interface
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
if [ -r "$IP_LIST" ] ; then
|
||||
TARGET_IPS=$(grep -v "^#" "$IP_LIST")
|
||||
else
|
||||
TARGET_IPS=$IP_LIST
|
||||
fi
|
||||
for it in $TARGET_IPS
|
||||
do
|
||||
IP="$it"
|
||||
_on_ip
|
||||
done
|
||||
55
taskservs/ip-aliases/default/create_alias.sh.j2
Executable file
55
taskservs/ip-aliases/default/create_alias.sh.j2
Executable file
|
|
@ -0,0 +1,55 @@
|
|||
#!/bin/bash
|
||||
|
||||
ALIAS_SDN_BIN=./alias_sdn.sh
|
||||
|
||||
if [ ! -r "$ALIAS_SDN_BIN" ] ; then
|
||||
echo "ALIAS_SDN_BIN not found in $ALIAS_SDN_BIN"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
_check_resolution() {
|
||||
local hostname="$1"
|
||||
local ip=$2
|
||||
local main_hostname=${3:-""}
|
||||
local has_ip=""
|
||||
has_ip=$(grep "$ip" /etc/hosts | grep -v "^#" | awk '{print $1}')
|
||||
[ -z "$has_ip" ] && echo "$ip ${hostname}" | sudo tee -a /etc/hosts 2>/dev/null >/dev/null
|
||||
if [ "$main_hostname" == "true" ] && [ "$hostname" != "$(cat /etc/hostname)" ] ; then
|
||||
echo "$hostname" | sudo tee /etc/hostname 2>/dev/null >/dev/null
|
||||
sudo hostname "$hostname"
|
||||
fi
|
||||
}
|
||||
|
||||
[ -r "./env-ip-aliases" ] && . ./env-ip-aliases
|
||||
|
||||
NET_INTERFACES=/etc/network/interfaces
|
||||
|
||||
{% if taskserv.aliases %}
|
||||
{%- for ip in taskserv.aliases %}
|
||||
has_ip=$(grep {{ip.address}} $NET_INTERFACES)
|
||||
if [ -z "$has_ip" ] ; then
|
||||
echo "
|
||||
auto {{ip.dev_interface}}
|
||||
iface {{ip.dev_interface}} inet static
|
||||
address {{ip.address}}
|
||||
netmask {{ ip.netmask }}
|
||||
{% if ip.search and ip.nameservers != "" -%}
|
||||
dns-nameserver {{it}}
|
||||
{% endif %}
|
||||
{% if ip.search and ip.search != "" -%}
|
||||
search {{ ip.search }}
|
||||
{% endif %}
|
||||
" | sudo tee -a $NET_INTERFACES &>/dev/null
|
||||
#export SETUP_MODE={{ ip.setup_mode }}
|
||||
#export INTERFACE={{ ip.interface }}
|
||||
#export DEV_INTERFACE={{ ip.dev_interface }}
|
||||
#export NETMASK={{ ip.netmask }}
|
||||
#$ALIAS_SDN_BIN up {{ ip.address }}
|
||||
_check_resolution {{ ip.hostname }} {{ ip.address }} {{ ip.main_hostname }}
|
||||
fi
|
||||
{% endfor %}
|
||||
sudo systemctl restart networking
|
||||
{% endif %}
|
||||
|
||||
#sudo cp $ALIAS_SDN_BIN /etc
|
||||
|
||||
2
taskservs/ip-aliases/default/env-ip-aliases.sh
Normal file
2
taskservs/ip-aliases/default/env-ip-aliases.sh
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
export ROOT_INTERFACES=${ROOT_INTERFACES:-/etc/network/interfaces}
|
||||
export BACKUP_INTERFACES=${BACKUP_INTERFACES:-/etc/network/_interfaces}
|
||||
18
taskservs/ip-aliases/default/install-ip-aliases.sh
Executable file
18
taskservs/ip-aliases/default/install-ip-aliases.sh
Executable file
|
|
@ -0,0 +1,18 @@
|
|||
#!/bin/bash
|
||||
# Info: Script to install IP aliases packages and tools
|
||||
# Author: JesusPerezLorenzo
|
||||
# Release: 1.0
|
||||
# Date: 4-08-2024
|
||||
|
||||
USAGE="install-ip-aliases.sh"
|
||||
[ "$1" == "-h" ] && echo "$USAGE" && exit 1
|
||||
|
||||
#ORG=$(pwd)
|
||||
|
||||
[ -r "./env-ip-aliases" ] && . ./env-ip-aliases
|
||||
|
||||
if [ -r "create_alias.sh" ] ; then
|
||||
chmod +x ./create_alias.sh
|
||||
./create_alias.sh
|
||||
fi
|
||||
|
||||
55
taskservs/kms/default/env-kms.j2
Normal file
55
taskservs/kms/default/env-kms.j2
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
# Cosmian KMS Environment Configuration
|
||||
# Generated by provisioning system
|
||||
|
||||
KMS_VERSION={{ kms.version }}
|
||||
KMS_RUN_USER={{ kms.run_user.name }}
|
||||
KMS_RUN_GROUP={{ kms.run_user.group }}
|
||||
KMS_RUN_USER_HOME={{ kms.run_user.home }}
|
||||
KMS_WORK_PATH={{ kms.work_path }}
|
||||
KMS_CONFIG_PATH={{ kms.config_path }}
|
||||
KMS_CONFIG_FILE={{ kms.config_file }}
|
||||
KMS_RUN_PATH={{ kms.run_path }}
|
||||
|
||||
# Server Configuration
|
||||
KMS_BIND_ADDR={{ kms.bind_addr }}
|
||||
KMS_PORT={{ kms.port }}
|
||||
KMS_LOG_LEVEL={{ kms.log_level }}
|
||||
KMS_FIPS_MODE={{ kms.fips_mode | lower }}
|
||||
|
||||
# Database Configuration
|
||||
KMS_DATABASE_TYPE={{ kms.database.typ }}
|
||||
{% if kms.database.typ != "sqlite" %}
|
||||
KMS_DATABASE_HOST={{ kms.database.host }}
|
||||
KMS_DATABASE_PORT={{ kms.database.port }}
|
||||
KMS_DATABASE_NAME={{ kms.database.database }}
|
||||
KMS_DATABASE_USERNAME={{ kms.database.username }}
|
||||
KMS_DATABASE_PASSWORD={{ kms.database.password }}
|
||||
KMS_DATABASE_SSL_MODE={{ kms.database.ssl_mode }}
|
||||
{% else %}
|
||||
KMS_DATABASE_PATH={{ kms.database.path }}
|
||||
{% endif %}
|
||||
|
||||
# TLS Configuration
|
||||
KMS_TLS_ENABLED={{ kms.tls_enabled | lower }}
|
||||
{% if kms.tls_enabled %}
|
||||
KMS_CERT_FILE={{ kms.cert_file }}
|
||||
KMS_KEY_FILE={{ kms.key_file }}
|
||||
{% if kms.ca_cert_file is defined %}
|
||||
KMS_CA_CERT_FILE={{ kms.ca_cert_file }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
# Authentication Configuration
|
||||
KMS_AUTH_ENABLED={{ kms.auth.enabled | lower }}
|
||||
{% if kms.auth.enabled %}
|
||||
KMS_JWT_ISSUER_URI={{ kms.auth.jwt_issuer_uri }}
|
||||
{% if kms.auth.jwks_uri is defined %}
|
||||
KMS_JWKS_URI={{ kms.auth.jwks_uri }}
|
||||
{% endif %}
|
||||
{% if kms.auth.jwt_audience is defined %}
|
||||
KMS_JWT_AUDIENCE={{ kms.auth.jwt_audience }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
# Configuration file path for runtime
|
||||
COSMIAN_KMS_CONF={{ kms.config_path }}/{{ kms.config_file }}
|
||||
185
taskservs/kms/default/install-kms.sh
Executable file
185
taskservs/kms/default/install-kms.sh
Executable file
|
|
@ -0,0 +1,185 @@
|
|||
#!/bin/bash
|
||||
# Info: Script to install Cosmian KMS
|
||||
# Author: Provisioning System
|
||||
# Release: 1.0
|
||||
# Date: 2025-07-24
|
||||
|
||||
USAGE="install-kms.sh"
|
||||
[ "$1" == "-h" ] && echo "$USAGE" && exit 1
|
||||
|
||||
[ -r "env-kms" ] && . ./env-kms
|
||||
|
||||
KMS_VERSION=${KMS_VERSION:-4.17.0}
|
||||
|
||||
# Determine architecture
|
||||
ARCH="$(uname -m)"
|
||||
case $ARCH in
|
||||
x86_64) ARCH="x86_64" ;;
|
||||
aarch64) ARCH="aarch64" ;;
|
||||
*) echo "Unsupported architecture: $ARCH" && exit 1 ;;
|
||||
esac
|
||||
|
||||
KMS_URL=https://github.com/Cosmian/kms/releases/download
|
||||
KMS_BINARY=v${KMS_VERSION}/cosmian_kms_server-${KMS_VERSION}-${ARCH}-unknown-linux-gnu
|
||||
KMS_CLI_BINARY=v${KMS_VERSION}/ckms-${KMS_VERSION}-${ARCH}-unknown-linux-gnu
|
||||
|
||||
KMS_RUN_PATH=${KMS_RUN_PATH:-/usr/local/bin/cosmian_kms}
|
||||
KMS_CLI_PATH=${KMS_CLI_PATH:-/usr/local/bin/ckms}
|
||||
KMS_SYSTEMCTL_MODE=${KMS_SYSTEMCTL_MODE:-enabled}
|
||||
|
||||
KMS_CONFIG_PATH=${KMS_CONFIG_PATH:-/etc/cosmian}
|
||||
KMS_WORK_PATH=${KMS_WORK_PATH:-/var/lib/kms}
|
||||
KMS_CONFIG_FILE=${KMS_CONFIG_FILE:-kms.toml}
|
||||
|
||||
KMS_RUN_USER=${KMS_RUN_USER:-kms}
|
||||
KMS_RUN_GROUP=${KMS_RUN_GROUP:-kms}
|
||||
KMS_RUN_USER_HOME=${KMS_RUN_USER_HOME:-/home/kms}
|
||||
|
||||
KMS_PORT=${KMS_PORT:-9998}
|
||||
KMS_LOG_LEVEL=${KMS_LOG_LEVEL:-info}
|
||||
KMS_DATABASE_TYPE=${KMS_DATABASE_TYPE:-sqlite}
|
||||
KMS_DATABASE_PATH=${KMS_DATABASE_PATH:-/var/lib/kms/kms.db}
|
||||
|
||||
echo "Installing Cosmian KMS ${KMS_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 openssl libssl3
|
||||
elif command -v yum >/dev/null 2>&1; then
|
||||
yum update -y
|
||||
yum install -y curl ca-certificates openssl openssl-libs
|
||||
elif command -v dnf >/dev/null 2>&1; then
|
||||
dnf update -y
|
||||
dnf install -y curl ca-certificates openssl openssl-libs
|
||||
else
|
||||
echo "Package manager not found. Please install curl, ca-certificates, and openssl manually."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create user and group
|
||||
if ! id "$KMS_RUN_USER" &>/dev/null; then
|
||||
groupadd -r "$KMS_RUN_GROUP"
|
||||
useradd -r -g "$KMS_RUN_GROUP" -d "$KMS_RUN_USER_HOME" -s /bin/bash -c "Cosmian KMS service user" "$KMS_RUN_USER"
|
||||
fi
|
||||
|
||||
# Create directories
|
||||
mkdir -p "$KMS_CONFIG_PATH"
|
||||
mkdir -p "$KMS_WORK_PATH"
|
||||
mkdir -p "$KMS_RUN_USER_HOME"
|
||||
mkdir -p "$(dirname "$KMS_DATABASE_PATH")"
|
||||
|
||||
# Download and install KMS server
|
||||
cd /tmp
|
||||
echo "Downloading KMS server from ${KMS_URL}/${KMS_BINARY}..."
|
||||
curl -L -o cosmian_kms_server "${KMS_URL}/${KMS_BINARY}"
|
||||
|
||||
if [ ! -f "cosmian_kms_server" ]; then
|
||||
echo "Failed to download KMS server binary"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Download and install KMS CLI
|
||||
echo "Downloading KMS CLI from ${KMS_URL}/${KMS_CLI_BINARY}..."
|
||||
curl -L -o ckms "${KMS_URL}/${KMS_CLI_BINARY}"
|
||||
|
||||
if [ ! -f "ckms" ]; then
|
||||
echo "Failed to download KMS CLI binary"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Install binaries
|
||||
chmod +x cosmian_kms_server ckms
|
||||
mv cosmian_kms_server "$(dirname "$KMS_RUN_PATH")/"
|
||||
mv ckms "$(dirname "$KMS_CLI_PATH")/"
|
||||
|
||||
# Create configuration file from template if it exists
|
||||
if [ -f "kms.toml.j2" ] && command -v jinja2 >/dev/null 2>&1; then
|
||||
echo "Generating configuration file..."
|
||||
# This would typically be handled by the provisioning system's template engine
|
||||
cp kms.toml.j2 "$KMS_CONFIG_PATH/$KMS_CONFIG_FILE.template"
|
||||
else
|
||||
# Create basic configuration file
|
||||
cat > "$KMS_CONFIG_PATH/$KMS_CONFIG_FILE" << EOF
|
||||
[server]
|
||||
port = $KMS_PORT
|
||||
bind_addr = "0.0.0.0"
|
||||
|
||||
[database]
|
||||
database_type = "$KMS_DATABASE_TYPE"
|
||||
$(if [ "$KMS_DATABASE_TYPE" = "sqlite" ]; then echo "database_path = \"$KMS_DATABASE_PATH\""; fi)
|
||||
|
||||
[logging]
|
||||
level = "$KMS_LOG_LEVEL"
|
||||
EOF
|
||||
fi
|
||||
|
||||
# Set ownership
|
||||
chown -R "$KMS_RUN_USER:$KMS_RUN_GROUP" "$KMS_WORK_PATH"
|
||||
chown -R "$KMS_RUN_USER:$KMS_RUN_GROUP" "$KMS_RUN_USER_HOME"
|
||||
chown -R "$KMS_RUN_USER:$KMS_RUN_GROUP" "$KMS_CONFIG_PATH"
|
||||
|
||||
# Initialize database if using SQLite
|
||||
if [ "$KMS_DATABASE_TYPE" = "sqlite" ]; then
|
||||
# Ensure database directory exists and has proper permissions
|
||||
mkdir -p "$(dirname "$KMS_DATABASE_PATH")"
|
||||
chown -R "$KMS_RUN_USER:$KMS_RUN_GROUP" "$(dirname "$KMS_DATABASE_PATH")"
|
||||
fi
|
||||
|
||||
# Create systemd service file
|
||||
cat > /etc/systemd/system/cosmian-kms.service << EOF
|
||||
[Unit]
|
||||
Description=Cosmian KMS Server
|
||||
Documentation=https://github.com/Cosmian/kms
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=$KMS_RUN_USER
|
||||
Group=$KMS_RUN_GROUP
|
||||
Environment=COSMIAN_KMS_CONF=$KMS_CONFIG_PATH/$KMS_CONFIG_FILE
|
||||
Environment=RUST_LOG=$KMS_LOG_LEVEL
|
||||
WorkingDirectory=$KMS_WORK_PATH
|
||||
ExecStart=$KMS_RUN_PATH --config-file $KMS_CONFIG_PATH/$KMS_CONFIG_FILE
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
# Security settings
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
ReadWritePaths=$KMS_WORK_PATH $KMS_CONFIG_PATH
|
||||
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Enable and start service
|
||||
systemctl daemon-reload
|
||||
systemctl "$KMS_SYSTEMCTL_MODE" cosmian-kms.service
|
||||
|
||||
if [ "$KMS_SYSTEMCTL_MODE" = "enabled" ]; then
|
||||
systemctl start cosmian-kms.service
|
||||
fi
|
||||
|
||||
# Cleanup
|
||||
cd /
|
||||
rm -rf /tmp/cosmian_kms_server /tmp/ckms
|
||||
|
||||
echo "Cosmian KMS installation completed!"
|
||||
echo "Service: cosmian-kms.service"
|
||||
echo "KMS Server available at: http://$(hostname):$KMS_PORT"
|
||||
echo "CLI tool: $KMS_CLI_PATH"
|
||||
echo "Configuration: $KMS_CONFIG_PATH/$KMS_CONFIG_FILE"
|
||||
echo "Data directory: $KMS_WORK_PATH"
|
||||
|
||||
# Display service status
|
||||
if systemctl is-active --quiet cosmian-kms.service; then
|
||||
echo "✅ KMS service is running"
|
||||
else
|
||||
echo "⚠️ KMS service status:"
|
||||
systemctl status cosmian-kms.service --no-pager -l
|
||||
fi
|
||||
40
taskservs/kms/default/kms.service.j2
Normal file
40
taskservs/kms/default/kms.service.j2
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
[Unit]
|
||||
Description=Cosmian KMS Server
|
||||
Documentation=https://github.com/Cosmian/kms
|
||||
After=network.target
|
||||
{% if kms.database.typ == "mysql" %}
|
||||
After=mysql.service
|
||||
Wants=mysql.service
|
||||
{% elif kms.database.typ == "postgresql" %}
|
||||
After=postgresql.service
|
||||
Wants=postgresql.service
|
||||
{% elif kms.database.typ == "redis" %}
|
||||
After=redis.service
|
||||
Wants=redis.service
|
||||
{% endif %}
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User={{ kms.run_user.name }}
|
||||
Group={{ kms.run_user.group }}
|
||||
Environment=COSMIAN_KMS_CONF={{ kms.config_path }}/{{ kms.config_file }}
|
||||
Environment=RUST_LOG={{ kms.log_level }}{% if kms.fips_mode %},cosmian_kms_server=debug{% endif %}
|
||||
|
||||
WorkingDirectory={{ kms.work_path }}
|
||||
ExecStart={{ kms.run_path }} --config-file {{ kms.config_path }}/{{ kms.config_file }}
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
# Security settings
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
ReadWritePaths={{ kms.work_path }} {{ kms.config_path }}{% if kms.database.typ == "sqlite" %} {{ kms.database.path | dirname }}{% endif %}
|
||||
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
|
||||
|
||||
# Resource limits
|
||||
LimitNOFILE=65536
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
47
taskservs/kms/default/kms.toml.j2
Normal file
47
taskservs/kms/default/kms.toml.j2
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
# Cosmian KMS Configuration File
|
||||
# Generated by provisioning system
|
||||
|
||||
[server]
|
||||
port = {{ kms.port }}
|
||||
bind_addr = "{{ kms.bind_addr }}"
|
||||
|
||||
{% if kms.tls_enabled %}
|
||||
[tls]
|
||||
cert_file = "{{ kms.cert_file }}"
|
||||
key_file = "{{ kms.key_file }}"
|
||||
{% if kms.ca_cert_file is defined %}
|
||||
ca_cert_file = "{{ kms.ca_cert_file }}"
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
[database]
|
||||
{% if kms.database.typ == "sqlite" %}
|
||||
database_type = "sqlite"
|
||||
database_path = "{{ kms.database.path }}"
|
||||
{% elif kms.database.typ == "mysql" %}
|
||||
database_type = "mysql"
|
||||
database_url = "mysql://{{ kms.database.username }}:{{ kms.database.password }}@{{ kms.database.host }}:{{ kms.database.port }}/{{ kms.database.database }}"
|
||||
{% elif kms.database.typ == "postgresql" %}
|
||||
database_type = "postgresql"
|
||||
database_url = "postgresql://{{ kms.database.username }}:{{ kms.database.password }}@{{ kms.database.host }}:{{ kms.database.port }}/{{ kms.database.database }}"
|
||||
{% elif kms.database.typ == "redis" %}
|
||||
database_type = "redis-findex"
|
||||
database_url = "redis://{{ kms.database.host }}:{{ kms.database.port }}"
|
||||
{% if kms.database.password %}
|
||||
redis_master_password = "{{ kms.database.password }}"
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if kms.auth.enabled %}
|
||||
[auth]
|
||||
jwt_issuer_uri = "{{ kms.auth.jwt_issuer_uri }}"
|
||||
{% if kms.auth.jwks_uri is defined %}
|
||||
jwks_uri = "{{ kms.auth.jwks_uri }}"
|
||||
{% endif %}
|
||||
{% if kms.auth.jwt_audience is defined %}
|
||||
jwt_audience = "{{ kms.auth.jwt_audience }}"
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
[logging]
|
||||
level = "{{ kms.log_level }}"
|
||||
80
taskservs/kms/default/prepare
Executable file
80
taskservs/kms/default/prepare
Executable file
|
|
@ -0,0 +1,80 @@
|
|||
#!/bin/bash
|
||||
# Info: Cosmian KMS preparation script
|
||||
# Author: Provisioning System
|
||||
# Release: 1.0
|
||||
|
||||
echo "Preparing Cosmian KMS installation..."
|
||||
|
||||
# Load environment variables
|
||||
[ -r "env-kms" ] && . ./env-kms
|
||||
|
||||
# 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 systemctl >/dev/null 2>&1 || { echo "systemctl is required but not installed." >&2; exit 1; }
|
||||
|
||||
# Check OpenSSL version (KMS requires OpenSSL v3.2.0+)
|
||||
if command -v openssl >/dev/null 2>&1; then
|
||||
OPENSSL_VERSION=$(openssl version | awk '{print $2}')
|
||||
echo "Found OpenSSL version: $OPENSSL_VERSION"
|
||||
|
||||
# Basic version check (simplified)
|
||||
MAJOR_VERSION=$(echo "$OPENSSL_VERSION" | cut -d. -f1)
|
||||
if [ "$MAJOR_VERSION" -lt "3" ]; then
|
||||
echo "Warning: OpenSSL version 3.2.0+ is recommended for KMS"
|
||||
fi
|
||||
else
|
||||
echo "Warning: OpenSSL not found. KMS requires OpenSSL v3.2.0+"
|
||||
fi
|
||||
|
||||
# Validate configuration
|
||||
if [ -z "$KMS_VERSION" ]; then
|
||||
echo "KMS_VERSION must be set" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$KMS_PORT" ]; then
|
||||
echo "KMS_PORT must be set" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check port availability
|
||||
if command -v netstat >/dev/null 2>&1; then
|
||||
if netstat -tuln | grep -q ":${KMS_PORT:-9998} "; then
|
||||
echo "Warning: Port ${KMS_PORT:-9998} appears to be in use"
|
||||
fi
|
||||
elif command -v ss >/dev/null 2>&1; then
|
||||
if ss -tuln | grep -q ":${KMS_PORT:-9998} "; then
|
||||
echo "Warning: Port ${KMS_PORT:-9998} appears to be in use"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Validate database configuration
|
||||
case "${KMS_DATABASE_TYPE:-sqlite}" in
|
||||
sqlite)
|
||||
echo "Using SQLite database"
|
||||
;;
|
||||
mysql)
|
||||
if [ -z "$KMS_DATABASE_HOST" ] || [ -z "$KMS_DATABASE_USERNAME" ] || [ -z "$KMS_DATABASE_PASSWORD" ]; then
|
||||
echo "MySQL requires host, username, and password configuration" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
postgresql)
|
||||
if [ -z "$KMS_DATABASE_HOST" ] || [ -z "$KMS_DATABASE_USERNAME" ] || [ -z "$KMS_DATABASE_PASSWORD" ]; then
|
||||
echo "PostgreSQL requires host, username, and password configuration" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
redis)
|
||||
if [ -z "$KMS_DATABASE_HOST" ]; then
|
||||
echo "Redis requires host configuration" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported database type: ${KMS_DATABASE_TYPE}" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "Preparation completed successfully."
|
||||
2
taskservs/kms/default/provisioning.toml
Normal file
2
taskservs/kms/default/provisioning.toml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
info = "cosmian-kms"
|
||||
release = "1.0"
|
||||
22
taskservs/kms/info.md
Normal file
22
taskservs/kms/info.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
Cosmian KMS taskserv has been successfully added to the provisioning system! The service includes:
|
||||
|
||||
Created files:
|
||||
- taskservs/kms/kcl/kms.k - KCL schema definitions for KMS configuration
|
||||
- taskservs/kms/default/provisioning.toml - Service metadata
|
||||
- taskservs/kms/default/env-kms.j2 - Environment variable template
|
||||
- taskservs/kms/default/kms.toml.j2 - KMS configuration file template
|
||||
- taskservs/kms/default/kms.service.j2 - Systemd service template
|
||||
- taskservs/kms/default/install-kms.sh - Installation script
|
||||
- taskservs/kms/default/prepare - Preparation script
|
||||
|
||||
Features:
|
||||
- Configurable Cosmian KMS server (default port 9998)
|
||||
- Multiple database backends: SQLite, MySQL, PostgreSQL, Redis
|
||||
- JWT authentication support with configurable IdP
|
||||
- TLS/SSL support with certificate configuration
|
||||
- FIPS mode support
|
||||
- Systemd service integration with security hardening
|
||||
- User and permission management
|
||||
- Automatic service discovery
|
||||
|
||||
The service can now be deployed using: ./core/nulib/provisioning taskserv create kms
|
||||
12
taskservs/kubectl/default/env-kubectl.j2
Normal file
12
taskservs/kubectl/default/env-kubectl.j2
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# Kubernetes URL for releases download
|
||||
URL="https://github.com/kubernetes/kubernetes/releases"
|
||||
FILE="."
|
||||
|
||||
# kubernetes version
|
||||
VERSION="1.29.1"
|
||||
export MAJOR_VERSION="1.29"
|
||||
K8S_VERSION=v$VERSION
|
||||
|
||||
# Default Arch
|
||||
ARCH="linux-amd64"
|
||||
if [ "$(uname -m)" = "aarch64" ]; then ARCH="linux-arm64"; fi
|
||||
60
taskservs/kubectl/default/install-kubectl.sh
Executable file
60
taskservs/kubectl/default/install-kubectl.sh
Executable file
|
|
@ -0,0 +1,60 @@
|
|||
#!/bin/bash
|
||||
# Info: Script to install/create/delete/update kubectl from file settings
|
||||
# Author: JesusPerezLorenzo
|
||||
# Release: 1.0
|
||||
# Date: 12-11-2024
|
||||
|
||||
USAGE="install-kubectl.sh install | update | remvoe"
|
||||
[ "$1" == "-h" ] && echo "$USAGE" && exit 1
|
||||
|
||||
[ -r "env-kubectl" ] && . env-kubectl
|
||||
|
||||
[ -z "$VERSION" ] && echo "No VERSION value " && exit 1
|
||||
|
||||
export LC_CTYPE=C.UTF-8
|
||||
export LANG=C.UTF-8
|
||||
cmd_out=/dev/null
|
||||
|
||||
[ -n "$1" ] && CMD_TSK=$1 && shift
|
||||
|
||||
_install_kubectl() {
|
||||
[ -z "$VERSION" ] || [ -z "$ARCH" ] || [ -z "$URL" ] || [ -z "$FILE" ] && exit 1
|
||||
_check_resolution
|
||||
curr_vers=$(kubectl version 2>/dev/null | grep Client | awk '{print $3}' | sed 's/^v//g' 2>/dev/null)
|
||||
#sudo chmod 1777 /tmp
|
||||
if [ "v$curr_vers" != "$K8S_VERSION" ]; then
|
||||
echo "Install packages"
|
||||
if [ "$CMD_TSK" != "update" ] && [ ! -r "/etc/apt/keyrings/kubernetes-apt-keyring.gpg" ]; then
|
||||
sudo apt-get update && sudo apt-get install -y apt-transport-https gnupg2 curl
|
||||
curl -fsSL https://pkgs.k8s.io/core:/stable:/v$MAJOR_VERSION/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
|
||||
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v$MAJOR_VERSION/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list
|
||||
fi
|
||||
_off_swap
|
||||
sudo apt-get update -q
|
||||
sudo apt-mark unhold kubectl
|
||||
if ! sudo apt-get install -y kubectl ; then
|
||||
echo "error installing kubernetes"
|
||||
return 1
|
||||
fi
|
||||
# Hold your horse !
|
||||
sudo apt-mark hold kubectl
|
||||
echo "init done"
|
||||
fi
|
||||
}
|
||||
case "$CMD_TSK" in
|
||||
remove)
|
||||
suto apt-get remove kubectl
|
||||
exit 0
|
||||
;;
|
||||
update)
|
||||
suto apt-get update -q
|
||||
sudo apt-mark unhold kubectl
|
||||
sudo apt-get upgrade -y
|
||||
sudo apt-mark hold kubectl
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
if ! _install_kubectl; then
|
||||
echo "error kubectl install"
|
||||
exit 1
|
||||
fi
|
||||
3
taskservs/kubernetes/default/_cri/crio/crictl.yaml
Normal file
3
taskservs/kubernetes/default/_cri/crio/crictl.yaml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
runtime-endpoint: "unix:///var/run/crio/crio.sock"
|
||||
timeout: 0
|
||||
debug: false
|
||||
137
taskservs/kubernetes/default/_cri/crio/install.sh
Executable file
137
taskservs/kubernetes/default/_cri/crio/install.sh
Executable file
|
|
@ -0,0 +1,137 @@
|
|||
#!/bin/bash
|
||||
# Info: Script to install/create/delete/update crio from file settings
|
||||
# Author: JesusPerezLorenzo
|
||||
# Release: 1.0
|
||||
# Date: 12-11-2024
|
||||
|
||||
USAGE="install.sh install | update | remvoe"
|
||||
[ "$1" == "-h" ] && echo "$USAGE" && exit 1
|
||||
|
||||
OS=$(uname | tr '[:upper:]' '[:lower:]')
|
||||
ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')"
|
||||
|
||||
CRIO_VERSION="${CRIO_VERSION:-1.29.1}"
|
||||
#CRIO_URL=https://raw.githubusercontent.com/cri-o/cri-o/master/scripts/get
|
||||
CRIO_URL=https://storage.googleapis.com/cri-o/artifacts/cri-o.$ARCH.v$CRIO_VERSION.tar.gz
|
||||
|
||||
CRICTL_VERSION="${CRICTL_VERSION:-1.29.0}"
|
||||
CRICTL_URL="https://github.com/kubernetes-sigs/cri-tools/releases/download"
|
||||
|
||||
CRIO_SYSTEMCTL_MODE=enabled
|
||||
|
||||
CMD_TSKSRVC=${1:-install}
|
||||
|
||||
export LC_CTYPE=C.UTF-8
|
||||
export LANG=C.UTF-8
|
||||
|
||||
ORG=$(pwd)
|
||||
|
||||
PKG_ORG=${PKG_ORG:-.}
|
||||
|
||||
_clean_others() {
|
||||
[ -d "/etc/cni" ] && sudo rm -r /etc/cni
|
||||
[ -d "/var/lib/containers" ] && sudo rm -r /var/lib/containers
|
||||
sudo rm -f /etc/systemd/system/podman* 2>/dev/null
|
||||
}
|
||||
_init() {
|
||||
[ -z "$CRIO_VERSION" ] || [ -z "$ARCH" ] || [ -z "$CRIO_URL" ] && exit 1
|
||||
local curr_vers
|
||||
local has_crio
|
||||
has_crio=$(type crio 2>/dev/null)
|
||||
if [ -n "$has_crio" ] ; then
|
||||
curr_vers=$(crio --version | grep "^Version" | awk '{print $2}')
|
||||
else
|
||||
_clean_others
|
||||
fi
|
||||
if [ "$curr_vers" != "$CRIO_VERSION" ] ; then
|
||||
if ! curl -fsSL "$CRIO_URL" -o /tmp/crio.tar.gz ; then
|
||||
echo "error downloading crio r"
|
||||
return 1
|
||||
fi
|
||||
tar xzf /tmp/crio.tar.gz
|
||||
if [ -r "cri-o/install" ] ; then
|
||||
cd cri-o || exit 1
|
||||
[ -n "$has_crio" ] && sudo timeout -k 10 20 systemctl stop crio
|
||||
sudo bash ./install &>/dev/null
|
||||
cd "$ORG" || exit 1
|
||||
else
|
||||
echo "error installing crio"
|
||||
ret=1
|
||||
fi
|
||||
rm -fr cri-o
|
||||
rm -f /tmp/crio_installer.sh
|
||||
[ "$ret" == 1 ] && return 1
|
||||
fi
|
||||
curr_vers=$(crictl --version | awk '{print $3}' | sed 's/v//g')
|
||||
if [ "$curr_vers" != "$CRICTL_VERSION" ] ; then
|
||||
if ! curl -fsSL "${CRICTL_URL}/v${CRICTL_VERSION}/crictl-v${CRICTL_VERSION}-${OS}-${ARCH}.tar.gz" -o /tmp/crictl.tar.gz ; then
|
||||
echo "error downloading crictl installer"
|
||||
return 1
|
||||
fi
|
||||
tar xzf /tmp/crictl.tar.gz
|
||||
if [ -r "crictl" ] ; then
|
||||
chmod +x crictl
|
||||
sudo mv crictl /usr/local/bin
|
||||
fi
|
||||
rm -f /tmp/crictl.tar.gz
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
_config_crio() {
|
||||
[ ! -d "/etc/crio" ] && mkdir -p /etc/crio
|
||||
if [ -r "$PKG_ORG/crio_config.toml" ] && [ ! -r "/etc/crio/config.toml" ] ; then
|
||||
sudo cp "$PKG_ORG"/crio_config.toml /etc/crio/config.toml
|
||||
fi
|
||||
if [ -r "$PKG_ORG/crictl.yaml" ] && [ ! -r "/etc/crictl.yaml" ] ; then
|
||||
sudo cp "$PKG_ORG"/crictl.yaml /etc/crictl.yaml
|
||||
fi
|
||||
|
||||
if [ -r "$PKG_ORG/crio.service" ] && [ ! -r "/lib/systemd/crio.service" ] ; then
|
||||
sudo cp "$PKG_ORG"/crio.service /lib/systemd/system
|
||||
[ ! -L "/etc/systemd/system/crio.service" ] && sudo ln -s /lib/systemd/system/crio.service /etc/systemd/system
|
||||
sudo timeout -k 10 20 systemctl daemon-reload
|
||||
fi
|
||||
TARGET=/etc/modules-load.d/crio.conf
|
||||
ITEMS="overlay br_netfilter"
|
||||
for it in $ITEMS
|
||||
do
|
||||
has_item=$(sudo grep ^"$it" $TARGET 2>/dev/null)
|
||||
[ -z "$has_item" ] && echo "$it" | sudo tee -a /etc/modules-load.d/crio.conf
|
||||
done
|
||||
[ ! -d "/etc/containers" ] && sudo mkdir /etc/containers
|
||||
[ -r "$PKG_ORG/registries.conf" ] && sudo cp "$PKG_ORG"/registries.conf /etc/containers
|
||||
_start_crio
|
||||
}
|
||||
|
||||
_remove_crio() {
|
||||
sudo timeout -k 10 20 systemctl stop crio
|
||||
sudo timeout -k 10 20 systemctl disable crio
|
||||
}
|
||||
|
||||
_start_crio() {
|
||||
if [ "$CRIO_SYSTEMCTL_MODE" == "enabled" ] ; then
|
||||
sudo timeout -k 10 20 systemctl enable crio
|
||||
else
|
||||
sudo timeout -k 10 20 systemctl disable crio
|
||||
fi
|
||||
sudo timeout -k 10 20 systemctl start crio
|
||||
}
|
||||
|
||||
_restart_crio() {
|
||||
sudo timeout -k 10 20 systemctl restart crio
|
||||
}
|
||||
[ "$CMD_TSKSRVC" == "remove" ] && _remove_crio && exit 0
|
||||
if ! _init ; then
|
||||
echo "error crio install"
|
||||
exit 1
|
||||
fi
|
||||
[ "$CMD_TSKSRVC" == "update" ] && _restart_crio && exit 0
|
||||
if ! _config_crio ; then
|
||||
echo "error crio config"
|
||||
exit 1
|
||||
fi
|
||||
if ! _start_crio ; then
|
||||
echo "error crio start"
|
||||
exit 1
|
||||
fi
|
||||
77
taskservs/kubernetes/default/_cri/crio/registries.conf
Normal file
77
taskservs/kubernetes/default/_cri/crio/registries.conf
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
# For more information on this configuration file, see containers-registries.conf(5).
|
||||
#
|
||||
# NOTE: RISK OF USING UNQUALIFIED IMAGE NAMES
|
||||
# We recommend always using fully qualified image names including the registry
|
||||
# server (full dns name), namespace, image name, and tag
|
||||
# (e.g., registry.redhat.io/ubi8/ubi:latest). Pulling by digest (i.e.,
|
||||
# quay.io/repository/name@digest) further eliminates the ambiguity of tags.
|
||||
# When using short names, there is always an inherent risk that the image being
|
||||
# pulled could be spoofed. For example, a user wants to pull an image named
|
||||
# `foobar` from a registry and expects it to come from myregistry.com. If
|
||||
# myregistry.com is not first in the search list, an attacker could place a
|
||||
# different `foobar` image at a registry earlier in the search list. The user
|
||||
# would accidentally pull and run the attacker's image and code rather than the
|
||||
# intended content. We recommend only adding registries which are completely
|
||||
# trusted (i.e., registries which don't allow unknown or anonymous users to
|
||||
# create accounts with arbitrary names). This will prevent an image from being
|
||||
# spoofed, squatted or otherwise made insecure. If it is necessary to use one
|
||||
# of these registries, it should be added at the end of the list.
|
||||
#
|
||||
# # An array of host[:port] registries to try when pulling an unqualified image, in order.
|
||||
unqualified-search-registries = ["docker.io", "quay.io"]
|
||||
#
|
||||
# [[registry]]
|
||||
# # The "prefix" field is used to choose the relevant [[registry]] TOML table;
|
||||
# # (only) the TOML table with the longest match for the input image name
|
||||
# # (taking into account namespace/repo/tag/digest separators) is used.
|
||||
# #
|
||||
# # The prefix can also be of the form: *.example.com for wildcard subdomain
|
||||
# # matching.
|
||||
# #
|
||||
# # If the prefix field is missing, it defaults to be the same as the "location" field.
|
||||
# prefix = "example.com/foo"
|
||||
#
|
||||
# # If true, unencrypted HTTP as well as TLS connections with untrusted
|
||||
# # certificates are allowed.
|
||||
# insecure = false
|
||||
#
|
||||
# # If true, pulling images with matching names is forbidden.
|
||||
# blocked = false
|
||||
#
|
||||
# # The physical location of the "prefix"-rooted namespace.
|
||||
# #
|
||||
# # By default, this is equal to "prefix" (in which case "prefix" can be omitted
|
||||
# # and the [[registry]] TOML table can only specify "location").
|
||||
# #
|
||||
# # Example: Given
|
||||
# # prefix = "example.com/foo"
|
||||
# # location = "internal-registry-for-example.net/bar"
|
||||
# # requests for the image example.com/foo/myimage:latest will actually work with the
|
||||
# # internal-registry-for-example.net/bar/myimage:latest image.
|
||||
#
|
||||
# # The location can be empty iff prefix is in a
|
||||
# # wildcarded format: "*.example.com". In this case, the input reference will
|
||||
# # be used as-is without any rewrite.
|
||||
# location = internal-registry-for-example.com/bar"
|
||||
#
|
||||
# # (Possibly-partial) mirrors for the "prefix"-rooted namespace.
|
||||
# #
|
||||
# # The mirrors are attempted in the specified order; the first one that can be
|
||||
# # contacted and contains the image will be used (and if none of the mirrors contains the image,
|
||||
# # the primary location specified by the "registry.location" field, or using the unmodified
|
||||
# # user-specified reference, is tried last).
|
||||
# #
|
||||
# # Each TOML table in the "mirror" array can contain the following fields, with the same semantics
|
||||
# # as if specified in the [[registry]] TOML table directly:
|
||||
# # - location
|
||||
# # - insecure
|
||||
# [[registry.mirror]]
|
||||
# location = "example-mirror-0.local/mirror-for-foo"
|
||||
# [[registry.mirror]]
|
||||
# location = "example-mirror-1.local/mirrors/foo"
|
||||
# insecure = true
|
||||
# # Given the above, a pull of example.com/foo/image:latest will try:
|
||||
# # 1. example-mirror-0.local/mirror-for-foo/image:latest
|
||||
# # 2. example-mirror-1.local/mirrors/foo/image:latest
|
||||
# # 3. internal-registry-for-example.net/bar/image:latest
|
||||
# # in order, and use the first one that exists.
|
||||
195
taskservs/kubernetes/default/_cri/crio/storage.conf
Normal file
195
taskservs/kubernetes/default/_cri/crio/storage.conf
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
# This file is is the configuration file for all tools
|
||||
# that use the containers/storage library.
|
||||
# See man 5 containers-storage.conf for more information
|
||||
# The "container storage" table contains all of the server options.
|
||||
[storage]
|
||||
|
||||
# Default Storage Driver, Must be set for proper operation.
|
||||
driver = "overlay"
|
||||
|
||||
# Temporary storage location
|
||||
runroot = "/run/containers/storage"
|
||||
|
||||
# Primary Read/Write location of container storage
|
||||
graphroot = "/var/lib/containers/storage"
|
||||
|
||||
# Storage path for rootless users
|
||||
#
|
||||
# rootless_storage_path = "$HOME/.local/share/containers/storage"
|
||||
|
||||
[storage.options]
|
||||
# Storage options to be passed to underlying storage drivers
|
||||
|
||||
# AdditionalImageStores is used to pass paths to additional Read/Only image stores
|
||||
# Must be comma separated list.
|
||||
additionalimagestores = [
|
||||
]
|
||||
|
||||
# Remap-UIDs/GIDs is the mapping from UIDs/GIDs as they should appear inside of
|
||||
# a container, to the UIDs/GIDs as they should appear outside of the container,
|
||||
# and the length of the range of UIDs/GIDs. Additional mapped sets can be
|
||||
# listed and will be heeded by libraries, but there are limits to the number of
|
||||
# mappings which the kernel will allow when you later attempt to run a
|
||||
# container.
|
||||
#
|
||||
# remap-uids = 0:1668442479:65536
|
||||
# remap-gids = 0:1668442479:65536
|
||||
|
||||
# Remap-User/Group is a user name which can be used to look up one or more UID/GID
|
||||
# ranges in the /etc/subuid or /etc/subgid file. Mappings are set up starting
|
||||
# with an in-container ID of 0 and then a host-level ID taken from the lowest
|
||||
# range that matches the specified name, and using the length of that range.
|
||||
# Additional ranges are then assigned, using the ranges which specify the
|
||||
# lowest host-level IDs first, to the lowest not-yet-mapped in-container ID,
|
||||
# until all of the entries have been used for maps.
|
||||
#
|
||||
# remap-user = "containers"
|
||||
# remap-group = "containers"
|
||||
|
||||
# Root-auto-userns-user is a user name which can be used to look up one or more UID/GID
|
||||
# ranges in the /etc/subuid and /etc/subgid file. These ranges will be partitioned
|
||||
# to containers configured to create automatically a user namespace. Containers
|
||||
# configured to automatically create a user namespace can still overlap with containers
|
||||
# having an explicit mapping set.
|
||||
# This setting is ignored when running as rootless.
|
||||
# root-auto-userns-user = "storage"
|
||||
#
|
||||
# Auto-userns-min-size is the minimum size for a user namespace created automatically.
|
||||
# auto-userns-min-size=1024
|
||||
#
|
||||
# Auto-userns-max-size is the minimum size for a user namespace created automatically.
|
||||
# auto-userns-max-size=65536
|
||||
|
||||
[storage.options.overlay]
|
||||
# ignore_chown_errors can be set to allow a non privileged user running with
|
||||
# a single UID within a user namespace to run containers. The user can pull
|
||||
# and use any image even those with multiple uids. Note multiple UIDs will be
|
||||
# squashed down to the default uid in the container. These images will have no
|
||||
# separation between the users in the container. Only supported for the overlay
|
||||
# and vfs drivers.
|
||||
#ignore_chown_errors = "false"
|
||||
|
||||
# Inodes is used to set a maximum inodes of the container image.
|
||||
# inodes = ""
|
||||
|
||||
# Path to an helper program to use for mounting the file system instead of mounting it
|
||||
# directly.
|
||||
#mount_program = "/usr/bin/fuse-overlayfs"
|
||||
|
||||
# mountopt specifies comma separated list of extra mount options
|
||||
mountopt = "nodev,metacopy=on"
|
||||
|
||||
# Set to skip a PRIVATE bind mount on the storage home directory.
|
||||
# skip_mount_home = "false"
|
||||
|
||||
# Size is used to set a maximum size of the container image.
|
||||
# size = ""
|
||||
|
||||
# ForceMask specifies the permissions mask that is used for new files and
|
||||
# directories.
|
||||
#
|
||||
# The values "shared" and "private" are accepted.
|
||||
# Octal permission masks are also accepted.
|
||||
#
|
||||
# "": No value specified.
|
||||
# All files/directories, get set with the permissions identified within the
|
||||
# image.
|
||||
# "private": it is equivalent to 0700.
|
||||
# All files/directories get set with 0700 permissions. The owner has rwx
|
||||
# access to the files. No other users on the system can access the files.
|
||||
# This setting could be used with networked based homedirs.
|
||||
# "shared": it is equivalent to 0755.
|
||||
# The owner has rwx access to the files and everyone else can read, access
|
||||
# and execute them. This setting is useful for sharing containers storage
|
||||
# with other users. For instance have a storage owned by root but shared
|
||||
# to rootless users as an additional store.
|
||||
# NOTE: All files within the image are made readable and executable by any
|
||||
# user on the system. Even /etc/shadow within your image is now readable by
|
||||
# any user.
|
||||
#
|
||||
# OCTAL: Users can experiment with other OCTAL Permissions.
|
||||
#
|
||||
# Note: The force_mask Flag is an experimental feature, it could change in the
|
||||
# future. When "force_mask" is set the original permission mask is stored in
|
||||
# the "user.containers.override_stat" xattr and the "mount_program" option must
|
||||
# be specified. Mount programs like "/usr/bin/fuse-overlayfs" present the
|
||||
# extended attribute permissions to processes within containers rather then the
|
||||
# "force_mask" permissions.
|
||||
#
|
||||
# force_mask = ""
|
||||
|
||||
[storage.options.thinpool]
|
||||
# Storage Options for thinpool
|
||||
|
||||
# autoextend_percent determines the amount by which pool needs to be
|
||||
# grown. This is specified in terms of % of pool size. So a value of 20 means
|
||||
# that when threshold is hit, pool will be grown by 20% of existing
|
||||
# pool size.
|
||||
# autoextend_percent = "20"
|
||||
|
||||
# autoextend_threshold determines the pool extension threshold in terms
|
||||
# of percentage of pool size. For example, if threshold is 60, that means when
|
||||
# pool is 60% full, threshold has been hit.
|
||||
# autoextend_threshold = "80"
|
||||
|
||||
# basesize specifies the size to use when creating the base device, which
|
||||
# limits the size of images and containers.
|
||||
# basesize = "10G"
|
||||
|
||||
# blocksize specifies a custom blocksize to use for the thin pool.
|
||||
# blocksize="64k"
|
||||
|
||||
# directlvm_device specifies a custom block storage device to use for the
|
||||
# thin pool. Required if you setup devicemapper.
|
||||
# directlvm_device = ""
|
||||
|
||||
# directlvm_device_force wipes device even if device already has a filesystem.
|
||||
# directlvm_device_force = "True"
|
||||
|
||||
# fs specifies the filesystem type to use for the base device.
|
||||
# fs="xfs"
|
||||
|
||||
# log_level sets the log level of devicemapper.
|
||||
# 0: LogLevelSuppress 0 (Default)
|
||||
# 2: LogLevelFatal
|
||||
# 3: LogLevelErr
|
||||
# 4: LogLevelWarn
|
||||
# 5: LogLevelNotice
|
||||
# 6: LogLevelInfo
|
||||
# 7: LogLevelDebug
|
||||
# log_level = "7"
|
||||
|
||||
# min_free_space specifies the min free space percent in a thin pool require for
|
||||
# new device creation to succeed. Valid values are from 0% - 99%.
|
||||
# Value 0% disables
|
||||
# min_free_space = "10%"
|
||||
|
||||
# mkfsarg specifies extra mkfs arguments to be used when creating the base
|
||||
# device.
|
||||
# mkfsarg = ""
|
||||
|
||||
# metadata_size is used to set the `pvcreate --metadatasize` options when
|
||||
# creating thin devices. Default is 128k
|
||||
# metadata_size = ""
|
||||
|
||||
# Size is used to set a maximum size of the container image.
|
||||
# size = ""
|
||||
|
||||
# use_deferred_removal marks devicemapper block device for deferred removal.
|
||||
# If the thinpool is in use when the driver attempts to remove it, the driver
|
||||
# tells the kernel to remove it as soon as possible. Note this does not free
|
||||
# up the disk space, use deferred deletion to fully remove the thinpool.
|
||||
# use_deferred_removal = "True"
|
||||
|
||||
# use_deferred_deletion marks thinpool device for deferred deletion.
|
||||
# If the device is busy when the driver attempts to delete it, the driver
|
||||
# will attempt to delete device every 30 seconds until successful.
|
||||
# If the program using the driver exits, the driver will continue attempting
|
||||
# to cleanup the next time the driver is used. Deferred deletion permanently
|
||||
# deletes the device and all data stored in device will be lost.
|
||||
# use_deferred_deletion = "True"
|
||||
|
||||
# xfs_nospace_max_retries specifies the maximum number of retries XFS should
|
||||
# attempt to complete IO when ENOSPC (no space) error is returned by
|
||||
# underlying storage device.
|
||||
# xfs_nospace_max_retries = "0"
|
||||
114
taskservs/kubernetes/default/_postrun
Executable file
114
taskservs/kubernetes/default/_postrun
Executable file
|
|
@ -0,0 +1,114 @@
|
|||
#!/bin/bash
|
||||
# Info: Postrun for kubernetes default installation
|
||||
# Author: JesusPerezLorenzo
|
||||
# Release: 1.0.2
|
||||
# Date: 30-12-2023
|
||||
|
||||
set +o errexit
|
||||
set +o pipefail
|
||||
|
||||
SETTINGS_FILE=$1
|
||||
SERVER_POS=$2
|
||||
TASK_POS=$3
|
||||
SETTINGS_ROOT=$4
|
||||
RUN_ROOT=$(dirname "$0")
|
||||
|
||||
[ -z "$SETTINGS_FILE" ] && [ -z "$SERVER_POS" ] && [ -z "$TASK_POS" ] && exit 0
|
||||
|
||||
YQ=$(type -P yq)
|
||||
JQ=$(type -P jq)
|
||||
[ -z "$YQ" ] && echo "yq not installed " && exit 1
|
||||
[ -z "$JQ" ] && echo "jq not installed " && exit 1
|
||||
|
||||
[ -r "$RUN_ROOT/env-kubernetes" ] && . "$RUN_ROOT"/env-kubernetes
|
||||
|
||||
provision_path=$($YQ e '.taskserv.prov_etcd_path' < "$SETTINGS_FILE" | sed 's/"//g' | sed 's/null//g' | sed "s,~,$HOME,g")
|
||||
#cluster_name=$($YQ e '.taskserv.cluster_name' < "$SETTINGS_FILE" | sed 's/null//g')
|
||||
|
||||
[ -z "$PROVISIONING" ] && echo "PROVISIONING not found in environment" && exit 1
|
||||
|
||||
. "$PROVISIONING"/core/lib/sops
|
||||
|
||||
K8S_MODE="$($YQ e '.taskserv.mode' < "$SETTINGS_FILE" | sed 's/"//g' | sed 's/null//g')"
|
||||
|
||||
TEMPLATES_PATH="$RUN_ROOT"/templates
|
||||
|
||||
WORK_PATH=${WORK_PATH:-/tmp}
|
||||
[ ! -d "$WORK_PATH" ] && mkdir -p "$WORK_PATH"
|
||||
export LC_CTYPE=C.UTF-8
|
||||
export LANG=C.UTF-8
|
||||
|
||||
|
||||
_load_file() {
|
||||
local target_file
|
||||
local hostname
|
||||
local ssh_key_path
|
||||
local source_host
|
||||
[ -z "$ERR_OUT" ] && ERR_OUT=/dev/null
|
||||
[ -z "$SSH_USER" ] && SSH_USER=$($YQ -er < "$SETTINGS_FILE" '.defaults.installer_user ' 2>"$ERR_OUT" | sed 's/"//g' | sed 's/null//g')
|
||||
SSH_OPS="-o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=/dev/null"
|
||||
ssh_key_path=$($YQ -er < "$SETTINGS_FILE" '.defaults.ssh_key_path ' 2>"$ERR_OUT" | sed 's/"//g' | sed 's/null//g')
|
||||
source_host=$($YQ -er < "$SETTINGS_FILE" ".servers[$SERVER_POS].network_public_ip" 2>"$ERR_OUT" | sed 's/"//g' | sed 's/null//g'
|
||||
if ssh $SSH_OPS -i "${ssh_key_path//.pub/}" "$SSH_USER@$source_host" "sudo ls $TARGET_FILE" 2>"$ERR_OUT" ; then
|
||||
scp $SSH_OPS -i "${ssh_key_path//.pub/}" "$SSH_USER@$source_host:$TARGET_FILE" /tmp 2>"$ERR_OUT"
|
||||
else
|
||||
echo "Error load file $GET_FILE from $source_host"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
_copy_certs() {
|
||||
local src
|
||||
local etcd_certs_path
|
||||
local etcd_cluster_name
|
||||
local etcd_peer
|
||||
src="$SETTINGS_ROOT/$provision_path"
|
||||
[ -z "$provision_path" ] && echo "Error prov_etcd_path not found" && exit 1
|
||||
etcd_certs_path=$($YQ e '.taskserv.etcd_certs_path' < "$SETTINGS_FILE" | sed 's/"//g' | sed 's/null//g' | sed "s,~,$HOME,g")
|
||||
[ -z "$etcd_certs_path" ] && echo "Error etcd_certs_path not found" && exit 1
|
||||
[ ! -d "$RUN_ROOT/$etcd_certs_path" ] && mkdir -p "$RUN_ROOT/$etcd_certs_path"
|
||||
etcd_cluster_name=$($YQ e '.taskserv.etcd_cluster_name' < "$SETTINGS_FILE" | sed 's/null//g')
|
||||
etcd_peer=$($YQ e '.taskserv.etcd_peers' < "$SETTINGS_FILE" | sed 's/null//g')
|
||||
for name in ca $etcd_peer $etcd_cluster_name
|
||||
do
|
||||
[ ! -r "$src/$name.key" ] && continue
|
||||
if [ -n "$($YQ -er '.sops' < "$src/$name.key" 2>/dev/null | sed 's/null//g' )" ] ; then
|
||||
_decode_sops_file "$src/$name.key" "$RUN_ROOT/$etcd_certs_path/$name.key" "quiet"
|
||||
else
|
||||
cp "$src/$name.key" "$RUN_ROOT/$etcd_certs_path/$name.key"
|
||||
fi
|
||||
done
|
||||
if [ -r "$RUN_ROOT/$etcd_certs_path/$etcd_peer.key" ] ; then
|
||||
cp "$RUN_ROOT/$etcd_certs_path/$etcd_peer.key" "$RUN_ROOT/$etcd_certs_path/server.key"
|
||||
mv "$RUN_ROOT/$etcd_certs_path/$etcd_peer.key" "$RUN_ROOT/$etcd_certs_path/peer.key"
|
||||
fi
|
||||
[ -r "$src/ca.crt" ] && cp "$src/ca.crt" "$RUN_ROOT/$etcd_certs_path/ca.crt"
|
||||
if [ -r "$src/$etcd_peer.crt" ] ; then
|
||||
cp "$src/$etcd_peer.crt" "$RUN_ROOT/$etcd_certs_path/server.crt"
|
||||
cp "$src/$etcd_peer.crt" "$RUN_ROOT/$etcd_certs_path/peer.crt"
|
||||
fi
|
||||
if [ -r "$RUN_ROOT/$etcd_certs_path/$etcd_cluster_name.key" ] ; then
|
||||
mv "$RUN_ROOT/$etcd_certs_path/$etcd_cluster_name.key" "$RUN_ROOT/$etcd_certs_path/healthcheck-client.key"
|
||||
fi
|
||||
if [ -r "$src/$etcd_cluster_name.crt" ] ; then
|
||||
cp "$src/$etcd_cluster_name.crt" "$RUN_ROOT/$etcd_certs_path/healthcheck-client.crt"
|
||||
fi
|
||||
echo "ETCD Certs copied from $src to $RUN_ROOT/$etcd_certs_path"
|
||||
}
|
||||
|
||||
# If HOSTNAME == K8S_MASTER it will be MASTER_0
|
||||
# othewise set HOSTNAME value to be resolved in same K8S_MASTER network
|
||||
# By using -cp- as part of HOSTNAME will be consider node as controlpanel
|
||||
# Other options = "-wk-0" or "-wkr-0" for worker nodes
|
||||
[[ "$HOSTNAME" == *-cp-* ]] && [ "$K8S_MODE" != "controlplane" ] && K8S_MODE="controlplane"
|
||||
if [ -n "$HOSTNAME" ] && [ "$HOSTNAME" == "$K8S_MASTER" ] && [ "$K8S_MODE" == "controlplane" ] && [ -n "$K8S_TPL" ]; then
|
||||
[ ! -d "$RUN_ROOT/resources" ] && mkdir -p "$RUN_ROOT/resources"
|
||||
"/tmp/k8s_join.sh"
|
||||
if [ -r "$TEMPLATES_PATH/$K8S_TPL" ] ; then
|
||||
cp "$TEMPLATES_PATH/$K8S_TPL" "$RUN_ROOT/resources/$K8S_CONFIG.j2"
|
||||
elif [ -r "$TEMPLATES_PATH/${K8S_TPL/.j2/}" ] ; then
|
||||
cp "$TEMPLATES_PATH/${K8S_TPL/.j2/}" "$RUN_ROOT/resources/$K8S_CONFIG"
|
||||
fi
|
||||
fi
|
||||
[ "$K8S_MODE" == "controlplane" ] && [ "$ETCD_MODE" == "external" ] && _copy_certs
|
||||
|
||||
rm -rf "$RUN_ROOT/templates"
|
||||
19
taskservs/kubernetes/default/addons/istio/install.sh
Executable file
19
taskservs/kubernetes/default/addons/istio/install.sh
Executable file
|
|
@ -0,0 +1,19 @@
|
|||
#!/bin/bash
|
||||
# Info: Script to install/create/delete/update istio from file settings
|
||||
# Author: JesusPerezLorenzo
|
||||
# Release: 1.0
|
||||
# Date: 12-11-2024
|
||||
|
||||
USAGE="install.sh install | update | remvoe"
|
||||
[ "$1" == "-h" ] && echo "$USAGE" && exit 1
|
||||
|
||||
INSTALL_LOG=${INSTALL_LOG:-"/tmp/k8s.log"}
|
||||
kubectl get crd gateways.gateway.networking.k8s.io &> /dev/null || \
|
||||
{ kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=v1.0.0" | kubectl apply -f -; }
|
||||
|
||||
curl -sL https://istio.io/downloadIstio | sh -
|
||||
cd istio-1.* || exit
|
||||
./bin/istioctl install --set profile=demo -y
|
||||
sudo cp ./bin/istioctl /usr/local/bin
|
||||
cd .. || exit
|
||||
sudo rm -rf istio-1.*
|
||||
56
taskservs/kubernetes/default/cni/cilium/install.sh
Executable file
56
taskservs/kubernetes/default/cni/cilium/install.sh
Executable file
|
|
@ -0,0 +1,56 @@
|
|||
#!/bin/bash
|
||||
# Info: Script to install/create/delete/update cilium from file settings
|
||||
# Author: JesusPerezLorenzo
|
||||
# Release: 1.0
|
||||
# Date: 12-11-2024
|
||||
|
||||
USAGE="install.sh install | update | remvoe"
|
||||
[ "$1" == "-h" ] && echo "$USAGE" && exit 1
|
||||
|
||||
OS=$(uname | tr '[:upper:]' '[:lower:]')
|
||||
ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')"
|
||||
|
||||
CILIUM_CLI_VERSION=${CILIUM_CLI_VERSION:-$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/master/stable.txt)}
|
||||
CILIUM_URL="https://github.com/cilium/cilium-cli/releases/download"
|
||||
|
||||
_cilium_init() {
|
||||
local curr_version
|
||||
curr_version=$(cilium version 2>/dev/null | grep cli | awk '{ print $2 }')
|
||||
if [ "$curr_version" != "${CILIUM_CLI_VERSION}" ] ; then
|
||||
curl -sL --remote-name-all "$CILIUM_URL/${CILIUM_CLI_VERSION}/cilium-${OS}-${ARCH}.tar.gz"{,.sha256sum}
|
||||
# sha256sum --check cilium-${OS}-${ARCH}.tar.gz.sha256sum
|
||||
sudo tar xzfC "cilium-${OS}-${ARCH}.tar.gz" /usr/local/bin
|
||||
rm cilium-"${OS}"-"${ARCH}".tar.gz{,.sha256sum}
|
||||
fi
|
||||
}
|
||||
_cilium_delete() {
|
||||
sudo cilium uninstall
|
||||
}
|
||||
_cilium_install() {
|
||||
[ "$K8S_MODE" == "image" ] && return 0
|
||||
local status
|
||||
status=$(cilium status 2>/dev/null | grep Operator | awk '{print $4}')
|
||||
[[ "$status" == *OK* ]] && return 0
|
||||
#if ! sudo /usr/local/bin/cilium install --cluster-name $CLUSTER_NAME ; then
|
||||
if ! /usr/local/bin/cilium install &>/dev/null; then
|
||||
echo "Error installing cilium $?"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
_cilium_update() {
|
||||
sudo cilium update
|
||||
}
|
||||
|
||||
if [ "$TSKSRVC" == "remove" ] ; then
|
||||
_cilium_delete
|
||||
exit
|
||||
fi
|
||||
[ "$TSKSRVC" == "update" ] && _cilium_update && exit 0
|
||||
if ! _cilium_init ; then
|
||||
echo "error cilium init"
|
||||
exit 1
|
||||
fi
|
||||
if ! _cilium_install ; then
|
||||
echo "error cilium install"
|
||||
exit 1
|
||||
fi
|
||||
104
taskservs/kubernetes/default/env-kubernetes.j2
Normal file
104
taskservs/kubernetes/default/env-kubernetes.j2
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
{%- if taskserv.name == "kubernetes" %}
|
||||
# CLuster Name
|
||||
CLUSTER_NAME="{{taskserv.cluster_name}}"
|
||||
|
||||
# K8s cluster role: controlpnlane or worker
|
||||
MODE="{{taskserv.mode}}"
|
||||
|
||||
# If HOSTNAME == K8S_MASTER it will be MASTER_0
|
||||
# othewise set HOSTNAME value to be resolved in same K8S_MASTER network
|
||||
# By using -cp- as part of HOSTNAME will be consider node as controlpanel
|
||||
# Other options: -wk-0 or -wkr-0 for worker nodes
|
||||
{% if taskserv.hostname == "$hostname" and server.hostname %}
|
||||
HOSTNAME="{{server.hostname}}"
|
||||
{%- else %}
|
||||
HOSTNAME="{{taskserv.hostname}}"
|
||||
{%- endif %}
|
||||
K8S_MASTER_IP="{{taskserv.cp_ip}}"
|
||||
{%- if taskserv.cp_name == "$hostname" and server.hostname %}
|
||||
K8S_MASTER="{{server.hostname}}"
|
||||
{%- else %}
|
||||
K8S_MASTER="{{taskserv.cp_name}}"
|
||||
{%- endif %}
|
||||
|
||||
# Main Ip for node should be in same K8S_MASTER network
|
||||
# Be sure MAIN_IP is alive and reachable
|
||||
{% if taskserv.ip == "$network_private_ip" and server.network_private_ip %}
|
||||
MAIN_IP="{{server.network_private_ip}}"
|
||||
{% elif taskserv.ip == "$network_public_ip" and settings[server_pos].ip_addresses.pub %}
|
||||
MAIN_IP="{{settings[server_pos].ip_addresses.pub}}"
|
||||
{%- else %}
|
||||
MAIN_IP="{{taskserv.ip}}"
|
||||
{%- endif %}
|
||||
|
||||
# LOG path for kubeadm
|
||||
export INSTALL_LOG="{{taskserv.install_log_path | replace(from="$cluster_name",to=taskserv.cluster_name)}}"
|
||||
# Work path for config generated file
|
||||
export WORK_PATH="{{ taskserv.work_path | replace(from="$cluster_name",to=taskserv.cluster_name) }}"
|
||||
|
||||
# Kubernetes URL for releases download
|
||||
#URL="https://github.com/kubernetes/kubernetes/releases"
|
||||
#FILE="."
|
||||
|
||||
# kubernetes version
|
||||
VERSION="{{taskserv.version}}"
|
||||
export MAJOR_VERSION="{{taskserv.major_version}}"
|
||||
K8S_VERSION=v$VERSION
|
||||
|
||||
# Default Arch
|
||||
OS=$(uname | tr '[:upper:]' '[:lower:]')
|
||||
ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')"
|
||||
|
||||
# Kubernetes CRI
|
||||
K8S_CRI="{{taskserv.cri}}"
|
||||
|
||||
# Kubernetes CNI
|
||||
{% if taskserv.cni -%}
|
||||
K8S_CNI="{{taskserv.cni}}"
|
||||
{% if taskserv.cni == "cilium" %}
|
||||
{% if taskserv.cni_version %}
|
||||
export CILIUM_CLI_VERSION="{{taskserv.cni_version}}"
|
||||
{%- else %}
|
||||
export CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt)
|
||||
{%- endif %}
|
||||
{%- endif %}
|
||||
{%- endif %}
|
||||
|
||||
# Kubernetes ADDONS
|
||||
{% if taskserv.addons -%}
|
||||
K8S_ADDONS="{{taskserv.addons}}"
|
||||
K8S_EXTERNAL_IPS="{%- for ip in taskserv.external_ips -%}
|
||||
{%- if ip == "$pub_ip" and settings[server_pos] and settings[server_pos].ip_addresses.pub -%}
|
||||
{{settings[server_pos].ip_addresses.pub}},
|
||||
{%- else -%}
|
||||
{{ip}},
|
||||
{%- endif -%}{%- endfor -%}"
|
||||
{%- endif %}
|
||||
|
||||
# ETCD mode could be used for multi-master
|
||||
{% if taskserv.etcd_mode == "external" %}
|
||||
ETCD_MODE="{{taskserv.etcd_mode}}"
|
||||
|
||||
{% endif %}
|
||||
|
||||
# Defaul CMD_TSK, can be set as argument in kubernetes/install.sh
|
||||
CMD_TSK=${1:-install}
|
||||
|
||||
# Set taint mode for controlpanels TAINT_NODE=no_schedule
|
||||
{% if taskserv.taint_node %} TAINT_NODE=schedule{% endif %}
|
||||
|
||||
# OS systemctl mode for CRI and kubelet services
|
||||
SYSTEMCTL_MODE=enabled
|
||||
|
||||
# Template file name for kubeadm config
|
||||
K8S_TPL="{{taskserv.tpl}}"
|
||||
K8S_CONFIG=${K8S_TPL//.j2/}
|
||||
|
||||
# Dev Adm user
|
||||
USER="{{taskserv.admin_user}}"
|
||||
USER_HOME="/home/{{taskserv.admin_user}}"
|
||||
|
||||
CMD_TSK="{{taskserv.cmd_task}}"
|
||||
{% set target_taskserv = server.taskservs | filter(attribute="name", value=taskserv.name) | first %}
|
||||
TARGET_SAVE_PATH="{{target_taskserv.target_save_path | default(value = "")}}"
|
||||
{%- endif %}
|
||||
418
taskservs/kubernetes/default/install-kubernetes.sh
Executable file
418
taskservs/kubernetes/default/install-kubernetes.sh
Executable file
|
|
@ -0,0 +1,418 @@
|
|||
#!/bin/bash
|
||||
# Info: Script to install/create/delete/update Kubernetes from file settings
|
||||
# Author: JesusPerezLorenzo
|
||||
# Release: 1.0
|
||||
# Date: 30-10-2023
|
||||
|
||||
USAGE="install-kubernetes.sh full-path-settings-file [ -m controlplane (hostname -cp-) | worker] [*install | update | makejoin | remove | fullremove]"
|
||||
[ "$1" == "-h" ] && echo "$USAGE" && exit 1
|
||||
|
||||
_save_target() {
|
||||
[ -z "$TARGET_SAVE_PATH" ] && return
|
||||
local file_path=$1
|
||||
mkdir -p "$TARGET_SAVE_PATH"
|
||||
if cp "$file_path" "$TARGET_SAVE_PATH" ; then
|
||||
echo "$file_path saved in $TARGET_SAVE_PATH"
|
||||
fi
|
||||
}
|
||||
# shellcheck disable=SC1090
|
||||
[[ "$1" == *setting* ]] && [ -r "$1" ] && . "$1" && shift
|
||||
# shellcheck disable=SC1090
|
||||
[[ "$1" == env-* ]] && [ -r "$1" ] && . "$1" && shift
|
||||
[ -r "env-kubernetes" ] && . env-kubernetes
|
||||
|
||||
[ -z "$CLUSTER_NAME" ] && echo "No CLUSTER_NAME value " && exit 1
|
||||
[ -z "$VERSION" ] && echo "No VERSION value " && exit 1
|
||||
|
||||
INSTALL_LOG=${INSTALL_LOG:-/tmp/k8s.log}
|
||||
WORK_PATH=${WORK_PATH:-/tmp}
|
||||
[ ! -d "$WORK_PATH" ] && sudo mkdir -p "$WORK_PATH"
|
||||
export LC_CTYPE=C.UTF-8
|
||||
export LANG=C.UTF-8
|
||||
cmd_out=/dev/null
|
||||
|
||||
echo "Log path to $INSTALL_LOG"
|
||||
[ ! -d "$(dirname "$INSTALL_LOG")" ] && mkdir -p "$(dirname "$INSTALL_LOG")"
|
||||
echo "Work path to $WORK_PATH"
|
||||
|
||||
if [ -z "$K8S_MODE" ] ; then
|
||||
if [[ "$HOSTNAME" == *-cp-* ]] ; then
|
||||
K8S_MODE="controlplane"
|
||||
else
|
||||
K8S_MODE="worker"
|
||||
fi
|
||||
fi
|
||||
[ "$1" == "-m" ] && K8S_MODE=$2 && shift 2
|
||||
[ -n "$1" ] && CMD_TSK=$1 && shift
|
||||
|
||||
_check_resolution() {
|
||||
local hostname=""
|
||||
hostname=$HOSTNAME
|
||||
local clustername=""
|
||||
local ip=""
|
||||
[ "$K8S_MODE" == "controlplane" ] && clustername="$CLUSTER_NAME"
|
||||
#sudo sed -i /^127.0.1.1/d /etc/hosts 2>>$cmd_out
|
||||
ip=$(grep "$hostname" /etc/hosts | grep -v "^#" | awk '{print $1}')
|
||||
[ -n "$ip" ] && [ "$ip" == "127.0.1.1" ] && sudo sed -i /^"$ip"/d /etc/hosts 2>>$cmd_out
|
||||
ip=$(grep "$MAIN_IP" /etc/hosts | grep -v "^#" | awk '{print $1}')
|
||||
[ -z "$ip" ] && echo "$MAIN_IP $hostname $clustername" | sudo tee -a /etc/hosts 2>>$cmd_out
|
||||
if [ "$hostname" != "$(cat /etc/hostname)" ] ; then
|
||||
echo "$hostname" | sudo tee /etc/hostname 2>>$cmd_out
|
||||
sudo hostname "$hostname"
|
||||
fi
|
||||
}
|
||||
_off_swap() {
|
||||
local fs_swap
|
||||
local fs_tab
|
||||
fs_tab=/etc/fstab
|
||||
fs_swap=$(grep -v "^#" $fs_tab | grep swap)
|
||||
if [ -n "$fs_swap" ] ; then
|
||||
sudo sed -i "s;$fs_swap;#$fs_swap;g" $fs_tab
|
||||
fi
|
||||
sudo swapoff -a
|
||||
}
|
||||
|
||||
_kubernetes_init() {
|
||||
[ -z "$VERSION" ] && exit 1
|
||||
_check_resolution
|
||||
curr_vers=$(kubectl version 2>/dev/null | grep Client | awk '{print $3}' | sed 's/^v//g' 2>/dev/null)
|
||||
chmod 1777 /tmp
|
||||
if [ "v$curr_vers" != "$K8S_VERSION" ]; then
|
||||
echo "Install packages"
|
||||
#if [ "$CMD_TSK" != "update" ] && [ ! -r "/etc/apt/keyrings/kubernetes-apt-keyring.gpg" ]; then
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-get update && sudo DEBIAN_FRONTEND=noninteractive apt-get install -y apt-transport-https gnupg2 curl
|
||||
sudo rm -f /etc/apt/keyrings/kubernetes-apt-keyring.gpg
|
||||
curl -fsSL https://pkgs.k8s.io/core:/stable:/v"$MAJOR_VERSION"/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
|
||||
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v$MAJOR_VERSION/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list
|
||||
#fi
|
||||
_off_swap
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-get update -q
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-mark unhold kubelet kubectl kubeadm
|
||||
if ! sudo DEBIAN_FRONTEND=noninteractive apt-get install -y kubectl kubelet kubeadm ; then
|
||||
echo "error installing kubernetes"
|
||||
return 1
|
||||
fi
|
||||
# Hold your horse !
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-mark hold kubelet kubectl kubeadm
|
||||
echo "init done"
|
||||
fi
|
||||
}
|
||||
_kubernetes_taint() {
|
||||
case "$TAINT_NODE" in
|
||||
no_schedule)
|
||||
kubectl taint nodes "$HOSTNAME" node-role.kubernetes.io/master:NoSchedule
|
||||
;;
|
||||
schedule)
|
||||
kubectl taint nodes "$HOSTNAME" node-role.kubernetes.io/master:NoSchedule
|
||||
kubectl taint nodes "$HOSTNAME" node-role.kubernetes.io/master:NoSchedule- 2>>$cmd_out
|
||||
;;
|
||||
esac
|
||||
return 0
|
||||
}
|
||||
_kubernetes_cri() {
|
||||
[ ! -d "/etc/${K8S_CRI}" ] && echo "No /etc/${K8S_CRI} path found! " && exit 1
|
||||
# if [ -r "cri/$K8S_CRI/install.sh" ] ; then
|
||||
# #PKG_ORG=cri/"$K8S_CRI"
|
||||
# echo "cri $K8S_CRI"
|
||||
# # shellcheck disable=SC1090
|
||||
# . "cri/$K8S_CRI/install.sh" | sudo tee -a "$INSTALL_LOG" >>$cmd_out
|
||||
# else
|
||||
# echo "$K8S_CRI not defined" && exit 1
|
||||
# fi
|
||||
return 0
|
||||
}
|
||||
_kubernetes_cni() {
|
||||
if [ -r "cni/$K8S_CNI/install.sh" ] ; then
|
||||
echo "cni $K8S_CNI"
|
||||
# shellcheck disable=SC1090
|
||||
. "cni/$K8S_CNI/install.sh" | sudo tee -a "$INSTALL_LOG" 2>>$cmd_out
|
||||
else
|
||||
echo "mode $K8S_CNI not defined" && exit 1
|
||||
fi
|
||||
}
|
||||
_kubernetes_addons() {
|
||||
local yaml_file
|
||||
for item in ${K8S_ADDONS//,/ } #ls addons 2>/dev/null)
|
||||
do
|
||||
if [ -r "addons/$item/install.sh" ] ; then
|
||||
echo "Install addon $item "| sudo tee -a "$INSTALL_LOG"
|
||||
# shellcheck disable=SC1090
|
||||
. "addons/$item/install.sh"
|
||||
if [ "$item" == "istio" ] && [ -n "$K8S_EXTERNAL_IPS" ]; then
|
||||
yaml_file=/tmp/externalIPs.yaml
|
||||
echo "spec:" > $yaml_file
|
||||
echo " externalIPs: " >> $yaml_file
|
||||
for ip in ${K8S_EXTERNAL_IPS//,/ }
|
||||
do
|
||||
echo " - $ip" >> "$yaml_file"
|
||||
done
|
||||
# Patch istio ingressgateway to use ExternalIPs
|
||||
kubectl patch service -n istio-system istio-ingressgateway --type merge --patch-file $yaml_file
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
_kubernetes_kube() {
|
||||
local user=${1:-root}
|
||||
local home_user=${2:-/home/root}
|
||||
local uid
|
||||
local gid
|
||||
local has_aliases
|
||||
uid=$(sudo id -u "$user" 2>/dev/null)
|
||||
gid=$(sudo id -g "$user" 2>/dev/null)
|
||||
if [ -f "/etc/kubernetes/admin.conf" ] ; then
|
||||
sudo mkdir -p /root/.kube
|
||||
sudo cp /etc/kubernetes/admin.conf /root/.kube/config
|
||||
sudo chown root:root /root/.kube/config
|
||||
if [ "$uid" == "0" ] ; then
|
||||
mkdir -p "$home_user"/.kube
|
||||
sudo cp /etc/kubernetes/admin.conf "$home_user"/.kube/config
|
||||
sudo chown -R "$uid:$gid" "$home_user"/.kube
|
||||
fi
|
||||
has_aliases=$(grep bash_aliases "$HOME"/.bashrc)
|
||||
[ -z "$has_aliases" ] && echo "[ -f ~/.bash_aliases ] && . ~/.bash_aliases" | sudo tee -a "$HOME"/.bashrc
|
||||
if [ -r "$USER_HOME" ] && [ -n "$USER" ] ; then
|
||||
mkdir -p "$USER_HOME"/.kube
|
||||
sudo cp /etc/kubernetes/admin.conf "$USER_HOME"/.kube/config
|
||||
sudo chown -R "$USER" "$USER_HOME"/.kube
|
||||
if [ -r "$USER_HOME/.bash_aliases" ] && [ ! -r "$HOME/.bash_aliases" ] ; then
|
||||
has_aliases=$(grep bash_aliases "$USER_HOME"/.bashrc)
|
||||
[ -z "$has_aliases" ] && echo "[ -f ~/.bash_aliases ] && . ~/.bash_aliases" | sudo tee -a "$USER_HOME"/.bashrc
|
||||
sudo cp "$USER_HOME"/.bash_aliases "$HOME"
|
||||
sudo chown -R "$uid:$gid" "$HOME"/.bash_aliases
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
_kubectl_appy() {
|
||||
export KUBECONFIG=/etc/kubernetes/admin.conf
|
||||
[ ! -r "$KUBECONFIG" ] && echo "$KUBECONFIG not found " && return 1
|
||||
[ ! -r "$1" ] && echo "File $1 not found" && return 1
|
||||
if ! kubectl apply -f "$1" ; then
|
||||
echo "Error kubectl apply $1 "
|
||||
fi
|
||||
}
|
||||
_kubernetes_install_master_0() {
|
||||
_check_resolution
|
||||
local has_apiserver=""
|
||||
has_apiserver=$(sudo ps -aux | awk '{print $11}'| grep "kube-apiserver")
|
||||
if [ ! -r "resources/$K8S_CONFIG" ] ; then
|
||||
echo "resources/$K8S_CONFIG not found"
|
||||
exit 1
|
||||
fi
|
||||
if [ "$ETCD_MODE" == "external" ] && [ -d "etcd_certs" ] ; then
|
||||
[ ! -d "/etc/kubernetes/pki/etcd" ] && sudo mkdir -p /etc/kubernetes/pki/etcd
|
||||
sudo cp -pr etcd_certs/* /etc/kubernetes/pki/etcd
|
||||
if [ -n "$HOSTNAME" ] && [ "$HOSTNAME" != "$INSTALL_MASTER" ] && [ -d "pki" ] ; then
|
||||
sudo cp -pr pki/* /etc/kubernetes/pki
|
||||
fi
|
||||
fi
|
||||
echo "Install kubernetes master"
|
||||
[ ! -r "resources/$K8S_CONFIG" ] && echo "Error resources/$K8S_CONFIG not found !" && exit 1
|
||||
[ "resources/$K8S_CONFIG" != "$WORK_PATH/kubeadm-config.yaml" ] && cp "resources/$K8S_CONFIG" "$WORK_PATH"/kubeadm-config.yaml
|
||||
if [ -z "$has_apiserver" ] ; then
|
||||
sudo systemctl start kubelet 2>>$cmd_out
|
||||
echo "You can follow kubeadm installation by using in another terminal: tail -f $INSTALL_LOG"
|
||||
sudo kubeadm init --config "$WORK_PATH"/kubeadm-config.yaml --ignore-preflight-errors=all | sudo tee "$INSTALL_LOG"
|
||||
_save_target "$WORK_PATH"/kubeadm-config.yaml
|
||||
fi
|
||||
local has_success=""
|
||||
has_success=$(sudo grep "initialized successfully" "$INSTALL_LOG")
|
||||
if [ -n "$has_success" ]; then
|
||||
echo "$has_success"
|
||||
_save_target "$INSTALL_LOG"
|
||||
sudo grep -A1 "^kubeadm join" "$INSTALL_LOG" | sudo tee "$WORK_PATH"/k8s_join.sh
|
||||
sudo chmod +x "$WORK_PATH/k8s_join.sh"
|
||||
[ "$WORK_PATH" != "/tmp" ] && cp "$WORK_PATH/k8s_join.sh" /tmp
|
||||
_kubernetes_kube "$(whoami)"
|
||||
_kubernetes_cni
|
||||
_kubernetes_addons
|
||||
sudo mv "$INSTALL_LOG" "$WORK_PATH"
|
||||
[ -r "runtimes.yaml" ] && _kubectl_appy runtimes.yaml
|
||||
fi
|
||||
}
|
||||
_make_join_kubernetes() {
|
||||
if ! kubeadm token create --print-join-command > "$WORK_PATH"/k8s_join.sh ; then
|
||||
echo "Error to get token for join node "
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
_join_kubernetes() {
|
||||
local join_path
|
||||
[ -r "k8s_join.sh" ] && join_path="k8s_join.sh"
|
||||
[ -r "/tmp/k8s_join.sh" ] && join_path="/tmp/k8s_join.sh"
|
||||
if [ -r "$join_path" ] ; then
|
||||
local cmd_join
|
||||
if [ "$1" == "controlplane" ] ; then
|
||||
cmd_join=$(sed 's/join /join --control-plane /g' < $join_path)
|
||||
else
|
||||
cmd_join=$(cat $join_path | sed 's/\\//g')
|
||||
fi
|
||||
[ -z "$cmd_join" ] && echo "Error cmd_join content" && exit 1
|
||||
# shellcheck disable=SC2086
|
||||
if ! sudo $cmd_join --ignore-preflight-errors=all | sudo tee "$INSTALL_LOG" >"$cmd_out"; then
|
||||
echo "Error $HOSTNAME join command -> $cmd_join "
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "No k8s_join.sh found"
|
||||
return 0
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
_install_kubernetes_controlplane() {
|
||||
if [ "$ETCD_MODE" == "external" ] && [ -d "etcd_certs" ] ; then
|
||||
[ ! -d "/etc/kubernetes/pki/etcd" ] && sudo mkdir -p /etc/kubernetes/pki/etcd
|
||||
sudo cp -pr etcd_certs/* /etc/kubernetes/pki/etcd
|
||||
if [ -n "$HOSTNAME" ] && [ "$HOSTNAME" != "$INSTALL_MASTER" ] && [ -d "pki" ] ; then
|
||||
sudo cp -pr pki/* /etc/kubernetes/pki
|
||||
fi
|
||||
fi
|
||||
if ! _join_kubernetes controlplane ; then
|
||||
exit 2
|
||||
else
|
||||
_kubernetes_kube "$USER" "$USER_HOME"
|
||||
_kubernetes_cni
|
||||
_kubernetes_addons
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
_install_kubernetes_worker() {
|
||||
if ! _join_kubernetes worker ; then
|
||||
exit 2
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
_install_kubernetes() {
|
||||
[ ! -d "/etc/${K8S_CRI}" ] && echo "No /etc/${K8S_CRI} path found! " && exit 1
|
||||
sudo systemctl start "${K8S_CRI}"
|
||||
_check_resolution
|
||||
if [ -f "/etc/kubernetes/admin.conf" ] ; then
|
||||
local server=""
|
||||
local has_apiserver=""
|
||||
has_apiserver=$(sudo ps -aux | awk '{print $11}'| grep "kube-apiserver")
|
||||
server=$(sudo grep "server: " /etc/kubernetes/admin.conf | awk '{print $2}')
|
||||
echo "$(date +%Y_%m_%d_%H%M%S) | Kubernetes already installed in $HOSTNAME with server: $server ($has_apiserver)" | sudo tee -a "$INSTALL_LOG"
|
||||
if [ "$CMD_TSK" == "reinstall" ] ; then
|
||||
echo "$(date +%Y_%m_%d_%H%M%S) | Kubernetes RESET installation in $HOSTNAME with server: $server ($has_apiserver) ..." | sudo tee -a "$INSTALL_LOG"
|
||||
if sudo kubeadm reset -f ; then
|
||||
echo "$(date +%Y_%m_%d_%H%M%S) | Kubernetes ready to be re-installed in $HOSTNAME " | sudo tee -a "$INSTALL_LOG"
|
||||
fi
|
||||
else
|
||||
_kubernetes_kube "$USER" "$USER_HOME"
|
||||
return
|
||||
fi
|
||||
elif [ -f "/etc/kubernetes/kubelet.conf" ] ; then
|
||||
echo "$(date +%Y_%m_%d_%H%M%S) | Kubernetes kubelet already running in $HOSTNAME"
|
||||
if [ "$CMD_TSK" == "reinstall" ] ; then
|
||||
echo "$(date +%Y_%m_%d_%H%M%S) | Kubernetes kubelet RESET in $HOSTNAME ..."
|
||||
if sudo kubeadm reset -f ; then
|
||||
echo "$(date +%Y_%m_%d_%H%M%S) | Kubernetes ready to be re-installed in $HOSTNAME " | sudo tee -a "$INSTALL_LOG"
|
||||
fi
|
||||
else
|
||||
return
|
||||
fi
|
||||
fi
|
||||
has_kubelet=$(sudo ps -aux | awk '{print $11}'| grep "kubelet")
|
||||
if [ -n "$has_kubelet" ] ; then
|
||||
if [ "$CMD_TSK" == "reinstall" ] ; then
|
||||
if sudo kubeadm reset -f ; then
|
||||
echo "$(date +%Y_%m_%d_%H%M%S) | Kubernetes ready to be re-installed in $HOSTNAME " | sudo tee -a "$INSTALL_LOG"
|
||||
fi
|
||||
else
|
||||
echo "$(date +%Y_%m_%d_%H%M%S) | Kubernetes kubelet already runnint in $HOSTNAME"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
if [ -n "$HOSTNAME" ] && [ "$HOSTNAME" == "$K8S_MASTER" ] ; then
|
||||
#IS_MASTER_0="yes"
|
||||
_kubernetes_install_master_0
|
||||
_kubernetes_taint
|
||||
else
|
||||
case "$K8S_MODE" in
|
||||
controlplane)
|
||||
_install_kubernetes_controlplane
|
||||
_kubernetes_taint
|
||||
;;
|
||||
worker)
|
||||
_install_kubernetes_worker
|
||||
;;
|
||||
*) echo "mode $K8S_MODE not defined" && exit 1
|
||||
esac
|
||||
fi
|
||||
}
|
||||
_config_kubernetes() {
|
||||
[ ! -d "/etc/${K8S_CRI}" ] && echo "No /etc/${K8S_CRI} path found! " && exit 1
|
||||
sudo systemctl start "${K8S_CRI}"
|
||||
sudo sed -i 's/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/' /etc/sysctl.conf
|
||||
has_nolocal_bind=$(sudo grep "net.ipv4.ip_nonlocal_bind = 1" /etc/sysctl.conf)
|
||||
if [ -z "$has_nolocal_bind" ] ; then
|
||||
echo "net.ipv4.ip_nonlocal_bind = 1" | sudo tee -a /etc/sysctl.conf >>$cmd_out
|
||||
#echo "net.bridge.bridge-nf-call-iptables=1" | sudo tee -a /etc/sysctl.conf
|
||||
sudo modprobe br_netfilter
|
||||
echo 1 | sudo tee -a /proc/sys/net/bridge/bridge-nf-call-iptables >>$cmd_out
|
||||
fi
|
||||
sudo sysctl -p >>$cmd_out
|
||||
return 0
|
||||
}
|
||||
_remove_kubernetes() {
|
||||
sudo systemctl stop kubelet
|
||||
sudo systemctl disable kubelet
|
||||
}
|
||||
_full_remove_kubernetes() {
|
||||
_remove_kubernetes
|
||||
sudo kubeadm reset -y
|
||||
sudo rm -r /etc/kubernetes /etc/cni
|
||||
}
|
||||
_start_kubernetes() {
|
||||
if [ "$SYSTEMCTL_MODE" == "enabled" ] ; then
|
||||
sudo systemctl enable kubelet
|
||||
else
|
||||
sudo systemctl disable kubelet
|
||||
fi
|
||||
sudo systemctl start kubelet
|
||||
}
|
||||
_restart_kubernetes() {
|
||||
sudo systemctl restart kubelet
|
||||
}
|
||||
|
||||
case "$CMD_TSK" in
|
||||
remove)
|
||||
_remove_kubernetes
|
||||
exit 0
|
||||
;;
|
||||
fullremove|full-remove)
|
||||
_full_remove_kubernetes
|
||||
exit 0
|
||||
;;
|
||||
update)
|
||||
_restart_kubernetes
|
||||
;;
|
||||
makejoin)
|
||||
_make_join_kubernetes
|
||||
exit 0
|
||||
;;
|
||||
reinstall) ;;
|
||||
esac
|
||||
if ! _kubernetes_cri ; then
|
||||
echo "error CRI install"
|
||||
exit 1
|
||||
fi
|
||||
if ! _kubernetes_init ; then
|
||||
echo "error kubernetes install"
|
||||
exit 1
|
||||
fi
|
||||
if ! _config_kubernetes ; then
|
||||
echo "error kubernetes config"
|
||||
exit 1
|
||||
fi
|
||||
if ! _install_kubernetes ; then
|
||||
echo "error kubernetes install"
|
||||
exit 1
|
||||
fi
|
||||
if ! _start_kubernetes ; then
|
||||
echo "error kubernetes start"
|
||||
exit 1
|
||||
fi
|
||||
echo "Work path: $WORK_PATH"
|
||||
echo "Log info: $INSTALL_LOG"
|
||||
119
taskservs/kubernetes/default/prepare
Executable file
119
taskservs/kubernetes/default/prepare
Executable file
|
|
@ -0,0 +1,119 @@
|
|||
#!/usr/bin/env nu
|
||||
# Info: Prepare for kubernetes default installation
|
||||
# Author: JesusPerezLorenzo
|
||||
# Release: 1.0.2
|
||||
# Date: 30-12-2023
|
||||
|
||||
use lib_provisioning/cmd/env.nu *
|
||||
use lib_provisioning/cmd/lib.nu *
|
||||
|
||||
use lib_provisioning/utils/ui.nu *
|
||||
|
||||
print $"(_ansi green_bold)OS(_ansi reset) with ($env.PROVISIONING_VARS) "
|
||||
|
||||
let defs = load_defs
|
||||
|
||||
if $env.PROVISIONING_RESOURCES == null {
|
||||
print $"🛑 PROVISIONING_RESOURCES not found"
|
||||
exit 1
|
||||
}
|
||||
let resources_path = $env.PROVISIONING_RESOURCES
|
||||
if not ($resources_path | path exists) { ^mkdir -p $resources_path }
|
||||
|
||||
#let WORK_PATH = ${WORK_PATH:-/tmp}
|
||||
#[ ! -d "$WORK_PATH" ] && mkdir -p "$WORK_PATH"
|
||||
#export LC_CTYPE=C.UTF-8
|
||||
#export LANG=C.UTF-8
|
||||
|
||||
export def copy_certs [
|
||||
run_root: string
|
||||
] {
|
||||
let provision_path = ($defs.taskserv.prov_etcd_path | default "" | str replace "~" $env.HOME)
|
||||
if $provision_path == "" {
|
||||
print $"🛑 prov_path not found taskserv definition"
|
||||
return false
|
||||
}
|
||||
let src = if ($defs.taskserv.prov_etcd_path | str starts-with "/" ) {
|
||||
$defs.taskserv.prov_etcd_path
|
||||
} else if ($defs.taskserv.prov_etcd_path | str starts-with "resources/" ) {
|
||||
($env.PROVISIONING_SETTINGS_SRC_PATH | path join $defs.taskserv.prov_etcd_path)
|
||||
} else {
|
||||
($env.PROVISIONING_SETTINGS_SRC_PATH | path join "resources" | path join $defs.taskserv.prov_etcd_path)
|
||||
}
|
||||
let etcd_certs_path = ($defs.taskserv.etcd_certs_path | default "" | str replace "~" $env.HOME)
|
||||
if $etcd_certs_path == "" { print "Error etcd_certs_path not found" ; exit 1 }
|
||||
if not ($run_root | path join $etcd_certs_path | path exists) { ^mkdir -p ($run_root | path join $etcd_certs_path) }
|
||||
let etcd_cluster_name = ($defs.taskserv.etcd_cluster_name | default "")
|
||||
if $etcd_cluster_name == "" {
|
||||
print $"🛑 etcd_cluster_name not found in taskserv definition"
|
||||
return false
|
||||
}
|
||||
let etcd_peer = ($defs.taskserv.etcd_peers | default "")
|
||||
for name in [ca $etcd_peer $etcd_cluster_name] {
|
||||
if not ($src | path join $"($name).key" | path exists) { continue }
|
||||
open ($src | path join $"($name).key") -r | from json |
|
||||
if (sops_cmd "is_sops" ($src | path join $"($name).key")) {
|
||||
let content = (sops_cmd "decrypt" ($src | path join $"($name).key") --error_exit)
|
||||
if $content != "" { $content | save -f ($run_root | path join $etcd_certs_path | path join $"($name).key") }
|
||||
} else {
|
||||
cp ($src | path join $"($name).key") ($run_root | path join $etcd_certs_path | path join $"($name).key" )
|
||||
}
|
||||
}
|
||||
if ($run_root | path join $etcd_certs_path | path join $"($etcd_peer).key" | path exists ) {
|
||||
(cp ($run_root | path join $etcd_certs_path | path join $"($etcd_peer).key")
|
||||
($run_root | path join $etcd_certs_path | path join "server.key"))
|
||||
(mv ($run_root | path join $etcd_certs_path | path join $"($etcd_peer).key")
|
||||
($run_root | path join $etcd_certs_path | path join "peer.key"))
|
||||
}
|
||||
if ($src | path join "ca.crt" | path exists) {
|
||||
cp ($src | path join "ca.crt") ($run_root | path join $etcd_certs_path | path join "ca.crt")
|
||||
}
|
||||
if ($src | path join $"($etcd_peer).crt" | path exists) {
|
||||
cp ($src | path join $"($etcd_peer).crt") ($run_root | path join $etcd_certs_path | path join "server.crt")
|
||||
cp ($src | path join $"($etcd_peer).crt") ($run_root | path join $etcd_certs_path | path join "peer.crt")
|
||||
}
|
||||
if ($run_root | path join $etcd_certs_path | path join $"($etcd_cluster_name).key" | path exists) {
|
||||
( mv ($run_root | path join $etcd_certs_path | path join $"($etcd_cluster_name).key")
|
||||
($run_root | path join $etcd_certs_path | path join "healthcheck-client.key"))
|
||||
}
|
||||
if ($src | path join $"($etcd_cluster_name).crt" | path exists) {
|
||||
( cp ($src | path join $"($etcd_cluster_name).crt")
|
||||
($run_root | path join $etcd_certs_path | path join "healthcheck-client.crt"))
|
||||
}
|
||||
print $"ETCD Certs copied from ($src) to ($run_root | path join $etcd_certs_path)"
|
||||
true
|
||||
}
|
||||
|
||||
def main [] {
|
||||
let K8S_MODE = ( $defs.taskserv.mode | default "")
|
||||
let run_root = $env.PROVISIONING_WK_ENV_PATH
|
||||
let TEMPLATES_PATH = ($run_root | path join "templates")
|
||||
|
||||
# If HOSTNAME == K8S_MASTER it will be MASTER_0
|
||||
# othewise set HOSTNAME value to be resolved in same K8S_MASTER network
|
||||
# By using -cp- as part of HOSTNAME will be consider node as controlpanel
|
||||
# Other options = "-wk-0" or "-wkr-0" for worker nodes
|
||||
|
||||
#if ($defs.server.hostname | str contains "-cp-") and $K8S_MODE != "controlplane" and $K8S_MODE == "" {
|
||||
let K8S_MASTER = if $defs.taskserv.cp_name == $defs.server.hostname {
|
||||
($defs.server.hostname | default "")
|
||||
} else {
|
||||
($defs.taskserv.cp_name | default "")
|
||||
}
|
||||
let K8S_TPL = ($defs.taskserv.tpl | default "" | str replace ".j2" "")
|
||||
let K8S_CONFIG = ($K8S_TPL | str replace ".j2" "")
|
||||
#if ( $defs.server.hostname != "" and $defs.server.hostname == $K8S_MASTER
|
||||
if ($K8S_MODE == "controlplane" and $K8S_TPL != "" ) {
|
||||
if not ($run_root | path join "resources" | path exists) { ^mkdir -p ($run_root | path join "resources") }
|
||||
if ($TEMPLATES_PATH | path join $K8S_TPL | path exists ) {
|
||||
cp ($TEMPLATES_PATH | path join $K8S_TPL) ($run_root | path join "resources"| path join $K8S_CONFIG)
|
||||
} else if ($TEMPLATES_PATH | path join $"($K8S_TPL).j2" | path exists) {
|
||||
cp ($TEMPLATES_PATH | path join $"($K8S_TPL).j2") ($run_root | path join "resources"| path join $"($K8S_CONFIG).j2")
|
||||
}
|
||||
}
|
||||
let res = if $K8S_MODE == "controlplane" and $defs.taskserv.etcd_mode == "external" {
|
||||
copy_certs $run_root
|
||||
} else { true }
|
||||
rm -rf ($run_root | path join "templates")
|
||||
$res
|
||||
}
|
||||
2
taskservs/kubernetes/default/provisioning.toml
Normal file
2
taskservs/kubernetes/default/provisioning.toml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
info = "Kubernetes"
|
||||
release = "1.0"
|
||||
11
taskservs/kubernetes/default/runtimes.yaml.j2
Normal file
11
taskservs/kubernetes/default/runtimes.yaml.j2
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{% set runtimes_list = taskserv.runtimes | split(pat=",") %}
|
||||
{% for runtime in runtimes_list -%}
|
||||
{% if runtime != taskserv.runtime_default -%}
|
||||
apiVersion: node.k8s.io/v1
|
||||
kind: RuntimeClass
|
||||
metadata:
|
||||
name: {{runtime}}
|
||||
# The name of the corresponding CRI configuration
|
||||
handler: {{runtime}}
|
||||
{% endif -%}
|
||||
{% endfor %}
|
||||
27
taskservs/kubernetes/images/Kubernetes_logo.svg
Normal file
27
taskservs/kubernetes/images/Kubernetes_logo.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 11 KiB |
21
taskservs/kubernetes/k8s-nodejoin/env-kubernetes.j2
Normal file
21
taskservs/kubernetes/k8s-nodejoin/env-kubernetes.j2
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
{%- if taskserv.name == "k8s-nodejoin" %}
|
||||
# Main Ip for node should be in same K8S_MASTER network
|
||||
# Be sure MAIN_IP is alive and reachable
|
||||
CLUSTER="{{taskserv.cluster}}"
|
||||
CP_HOSTNAME="{{taskserv.cp_hostname}}"
|
||||
{%- if defs and defs.servers -%}
|
||||
CP_IP="{%- for server in defs.servers -%}
|
||||
{%- if server.hostname and server.hostname == taskserv.cp_hostname -%}
|
||||
{%- if server.network_private_ip -%}{{server.network_private_ip}}{%- endif -%}
|
||||
{%- endif -%}{%- endfor -%}"
|
||||
{%- else %}
|
||||
CP_IP=""
|
||||
{%- endif %}
|
||||
ADMIN_USER="{{taskserv.admin_user}}"
|
||||
TARGET_PATH="{{taskserv.target_path}}"
|
||||
SOURCE_PATH="{{taskserv.source_path}}"
|
||||
ADMIN_HOST="{{taskserv.admin_host}}"
|
||||
ADMIN_PORT="{{taskserv.admin_port}}"
|
||||
SOURCE_CMD="{{taskserv.source_cmd}}"
|
||||
TARGET_CMD="{{taskserv.target_cmd}}"
|
||||
{%- endif %}
|
||||
17
taskservs/kubernetes/k8s-nodejoin/install-kubernetes.sh
Executable file
17
taskservs/kubernetes/k8s-nodejoin/install-kubernetes.sh
Executable file
|
|
@ -0,0 +1,17 @@
|
|||
#!/bin/bash
|
||||
# Info: Script to collect kubeconfig
|
||||
# Author: JesusPerezLorenzo
|
||||
# Release: 1.0
|
||||
# Date: 30-10-2023
|
||||
|
||||
USAGE="install-kubernetes.sh "
|
||||
[ "$1" == "-h" ] && echo "$USAGE" && exit 1
|
||||
|
||||
[[ "$1" == env-* ]] && [ -r "$1" ] && . $1 && shift
|
||||
[ -r "env-kubernetes" ] && . env-kubernetes
|
||||
|
||||
#[ -z "$MAIN_IP" ] && echo "No MAIN_IP value " && exit 1
|
||||
|
||||
if [ -n "$TARGET_CMD" ] ; then
|
||||
$TARGET_CMD
|
||||
fi
|
||||
104
taskservs/kubernetes/k8s-nodejoin/prepare
Executable file
104
taskservs/kubernetes/k8s-nodejoin/prepare
Executable file
|
|
@ -0,0 +1,104 @@
|
|||
#!/usr/bin/env nu
|
||||
# Info: Prepare for kubernetes default installation
|
||||
# Author: JesusPerezLorenzo
|
||||
# Release: 1.0.2
|
||||
# Date: 30-12-2023
|
||||
|
||||
use lib_provisioning/cmd/env.nu *
|
||||
use lib_provisioning/cmd/lib.nu *
|
||||
|
||||
use lib_provisioning/utils/ui.nu *
|
||||
use lib_provisioning/plugins_defs.nu port_scan
|
||||
|
||||
print $"(_ansi green_bold)OS(_ansi reset) with ($env.PROVISIONING_VARS) "
|
||||
|
||||
let settings = load_defs
|
||||
|
||||
if $env.PROVISIONING_RESOURCES == null {
|
||||
print $"🛑 PROVISIONING_RESOURCES not found"
|
||||
exit 1
|
||||
}
|
||||
let resources_path = $env.PROVISIONING_RESOURCES
|
||||
if not ($resources_path | path exists) { ^mkdir -p $resources_path }
|
||||
|
||||
def main [] {
|
||||
let cp_hostname = ($settings.taskserv | get -i cp_hostname | default "")
|
||||
if ($cp_hostname | is-empty) {
|
||||
print $"🛑 Error (_ansi red_bold)prepare ($settings.taskserv.name) (_ansi reset) (_ansi green_bold) no cp_hostname(_ansi reset)"
|
||||
exit
|
||||
}
|
||||
let target_server = ($settings.defs.servers | filter {|srv| $srv.hostname == $cp_hostname } | get -i 0)
|
||||
let cp_pub_ip = ($target_server | get -i network_public_ip | default "127.0.0.1")
|
||||
if ($target_server | get -i hostname | is-empty) {
|
||||
print $"🛑 Error (_ansi red_bold)prepare(_ansi reset) server (_ansi green_bold)($cp_hostname)(_ansi reset)"
|
||||
exit 1
|
||||
}
|
||||
let cp_pub_ip = ($target_server | get -i network_public_ip | default "127.0.0.1")
|
||||
if ($cp_pub_ip | is-empty) {
|
||||
print $"🛑 Error (_ansi red_bold)cp_public_ip(_ansi reset) for server (_ansi green_bold)($cp_hostname)(_ansi reset)"
|
||||
exit 1
|
||||
}
|
||||
let src_target_path = ($settings.taskserv | get -i target_path | default "")
|
||||
let target_path = if ($src_target_path | str starts-with "/") { $src_target_path } else { ($env.PROVISIONING_WK_ENV_PATH | path join $src_target_path) }
|
||||
let save_target_path = ($settings.defs.created_taskservs_dirpath | path join ($target_path | path basename))
|
||||
if ($save_target_path | path exists) {
|
||||
cp $save_target_path $target_path
|
||||
print $"(_ansi blue_bold)($save_target_path)(_ansi reset) already exists, copied into (_ansi blue_bold)($target_path)(_ansi reset)"
|
||||
exit
|
||||
}
|
||||
let str_target_host = ($settings.taskserv | get -i admin_host | default $cp_pub_ip)
|
||||
let target_port = ($settings.taskserv | get -i admin_port | default 22)
|
||||
let target_host = (open /etc/hosts | grep $str_target_host | lines | get -i 0 | default "" | split row " " | get -i 0)
|
||||
if ($env.PROVISIONING_ARGS? | default "" | str contains "--check ") or ($env.PROVISIONING_ARGS? | default "" | str contains "-c ") {
|
||||
print (
|
||||
$"\n(_ansi red)Check mode no connection(_ansi reset) to (_ansi blue)($target_host)(_ansi reset) " +
|
||||
$"(_ansi blue_bold)($target_port)(_ansi reset) (_ansi red_bold)failed(_ansi reset) "
|
||||
)
|
||||
exit
|
||||
}
|
||||
if not (port_scan $target_host $target_port 1) {
|
||||
print (
|
||||
$"\n🛑 (_ansi red)Error connection(_ansi reset) to (_ansi blue)($target_host)(_ansi reset) " +
|
||||
$"(_ansi blue_bold)($target_port)(_ansi reset) (_ansi red_bold)(_ansi reset) "
|
||||
)
|
||||
exit 1
|
||||
}
|
||||
let ssh_loglevel = if $env.PROVISIONING_DEBUG {
|
||||
"-o LogLevel=info"
|
||||
} else {
|
||||
"-o LogLevel=quiet"
|
||||
}
|
||||
let ssh_ops = [StrictHostKeyChecking=accept-new UserKnownHostsFile=/dev/null]
|
||||
let k8s_nodes = "kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{\"\\n\"}{end}'"
|
||||
let res = (^ssh "-o" ($ssh_ops | get -i 0) "-o" ($ssh_ops | get -i 1) "-o" IdentitiesOnly=yes $ssh_loglevel
|
||||
"-i" ($settings.taskserv.ssh_key_path | str replace ".pub" "")
|
||||
$"($settings.taskserv | get -i admin_user)@($target_host)" ($k8s_nodes) | complete)
|
||||
if $res.exit_code != 0 {
|
||||
print $"❗ run ($k8s_nodes) in ($settings.taskserv | get -i admin_host) errors ($res.stdout ) "
|
||||
exit 1
|
||||
}
|
||||
if ($res.stdout | find $target_host | get -i 0 | default "" | is-not-empty) {
|
||||
print $"node ($target_host) already in cluster "
|
||||
exit
|
||||
}
|
||||
let remote_cmd = ($settings | get -i taskserv | get -i source_cmd | default "")
|
||||
if $env.PROVISIONING_DEBUG {
|
||||
print $"Run ($remote_cmd) in ($settings.taskserv | get -i admin_user)@($target_host)"
|
||||
}
|
||||
let res = (^ssh "-o" ($ssh_ops | get -i 0) "-o" ($ssh_ops | get -i 1) "-o" IdentitiesOnly=yes $ssh_loglevel
|
||||
"-i" ($settings.taskserv.ssh_key_path | str replace ".pub" "")
|
||||
$"($settings.taskserv | get -i admin_user)@($target_host)" ($remote_cmd) | complete)
|
||||
if $res.exit_code != 0 {
|
||||
print $"❗ run ($remote_cmd) in ($settings.taskserv | get -i admin_host) errors ($res.stdout ) "
|
||||
exit 1
|
||||
}
|
||||
let source_path = ($settings.taskserv | get -i source_path | default "")
|
||||
let res = (^scp "-o" ($ssh_ops | get -i 0) "-o" ($ssh_ops | get -i 1) "-o" IdentitiesOnly=yes $ssh_loglevel
|
||||
"-i" ($settings.taskserv.ssh_key_path | str replace ".pub" "")
|
||||
$"($settings.taskserv | get -i admin_user)@($target_host):($source_path)" $target_path | complete)
|
||||
if $res.exit_code != 0 {
|
||||
print $"❗ run scp ($source_path) in ($settings.taskserv | get -i admin_host) errors ($res.stdout ) "
|
||||
exit 1
|
||||
}
|
||||
if $env.PROVISIONING_DEBUG { print $res.stdout }
|
||||
}
|
||||
97
taskservs/kubernetes/kubeconfig/_prepare
Executable file
97
taskservs/kubernetes/kubeconfig/_prepare
Executable file
|
|
@ -0,0 +1,97 @@
|
|||
#!/bin/bash
|
||||
# Info: Prepare for kubeconfig installation
|
||||
# Author: JesusPerezLorenzo
|
||||
# Release: 1.0.2
|
||||
# Date: 30-12-2023
|
||||
|
||||
set +o errexit
|
||||
set +o pipefail
|
||||
|
||||
SETTINGS_FILE=$1
|
||||
SERVER_POS=$2
|
||||
TASK_POS=$3
|
||||
SETTINGS_ROOT=$4
|
||||
RUN_ROOT=$(dirname "$0")
|
||||
|
||||
[ -z "$SETTINGS_FILE" ] && [ -z "$SERVER_POS" ] && [ -z "$TASK_POS" ] && exit 0
|
||||
|
||||
YQ=$(type -P yq)
|
||||
JQ=$(type -P jq)
|
||||
[ -z "$YQ" ] && echo "yq not installed " && exit 1
|
||||
[ -z "$JQ" ] && echo "jq not installed " && exit 1
|
||||
|
||||
[ -r "$RUN_ROOT/env-kubeconfig" ] && . "$RUN_ROOT"/env-kubeconfig
|
||||
|
||||
#provision_path=$($YQ e '.taskserv.prov_etcd_path' < "$SETTINGS_FILE" | sed 's/"//g' | sed 's/null//g' | sed "s,~,$HOME,g")
|
||||
#cluster_name=$($YQ e '.taskserv.cluster_name' < "$SETTINGS_FILE" | sed 's/null//g')
|
||||
|
||||
[ -z "$PROVISIONING" ] && echo "PROVISIONING not found in environment" && exit 1
|
||||
|
||||
. "$PROVISIONING"/core/lib/sops
|
||||
|
||||
K8S_MODE="$($YQ e '.taskserv.mode' < "$SETTINGS_FILE" | sed 's/"//g' | sed 's/null//g')"
|
||||
|
||||
# TODO Get from SSH master config files and copy to resources
|
||||
|
||||
TEMPLATES_PATH="$RUN_ROOT"/templates
|
||||
|
||||
WORK_PATH=${WORK_PATH:-/tmp}
|
||||
[ ! -d "$WORK_PATH" ] && mkdir -p "$WORK_PATH"
|
||||
export LC_CTYPE=C.UTF-8
|
||||
export LANG=C.UTF-8
|
||||
|
||||
_copy_certs() {
|
||||
local src
|
||||
local etcd_certs_path
|
||||
local etcd_cluster_name
|
||||
local etcd_peer
|
||||
src="$SETTINGS_ROOT/$provision_path"
|
||||
[ -z "$provision_path" ] && echo "Error prov_etcd_path not found" && exit 1
|
||||
etcd_certs_path=$($YQ e '.taskserv.etcd_certs_path' < "$SETTINGS_FILE" | sed 's/"//g' | sed 's/null//g' | sed "s,~,$HOME,g")
|
||||
[ -z "$etcd_certs_path" ] && echo "Error etcd_certs_path not found" && exit 1
|
||||
[ ! -d "$RUN_ROOT/$etcd_certs_path" ] && mkdir -p "$RUN_ROOT/$etcd_certs_path"
|
||||
etcd_cluster_name=$($YQ e '.taskserv.etcd_cluster_name' < "$SETTINGS_FILE" | sed 's/null//g')
|
||||
etcd_peer=$($YQ e '.taskserv.etcd_peers' < "$SETTINGS_FILE" | sed 's/null//g')
|
||||
for name in ca $etcd_peer $etcd_cluster_name
|
||||
do
|
||||
[ ! -r "$src/$name.key" ] && continue
|
||||
if [ -n "$($YQ -er '.sops' < "$src/$name.key" 2>/dev/null | sed 's/null//g' )" ] ; then
|
||||
_decode_sops_file "$src/$name.key" "$RUN_ROOT/$etcd_certs_path/$name.key" "quiet"
|
||||
else
|
||||
cp "$src/$name.key" "$RUN_ROOT/$etcd_certs_path/$name.key"
|
||||
fi
|
||||
done
|
||||
if [ -r "$RUN_ROOT/$etcd_certs_path/$etcd_peer.key" ] ; then
|
||||
cp "$RUN_ROOT/$etcd_certs_path/$etcd_peer.key" "$RUN_ROOT/$etcd_certs_path/server.key"
|
||||
mv "$RUN_ROOT/$etcd_certs_path/$etcd_peer.key" "$RUN_ROOT/$etcd_certs_path/peer.key"
|
||||
fi
|
||||
[ -r "$src/ca.crt" ] && cp "$src/ca.crt" "$RUN_ROOT/$etcd_certs_path/ca.crt"
|
||||
if [ -r "$src/$etcd_peer.crt" ] ; then
|
||||
cp "$src/$etcd_peer.crt" "$RUN_ROOT/$etcd_certs_path/server.crt"
|
||||
cp "$src/$etcd_peer.crt" "$RUN_ROOT/$etcd_certs_path/peer.crt"
|
||||
fi
|
||||
if [ -r "$RUN_ROOT/$etcd_certs_path/$etcd_cluster_name.key" ] ; then
|
||||
mv "$RUN_ROOT/$etcd_certs_path/$etcd_cluster_name.key" "$RUN_ROOT/$etcd_certs_path/healthcheck-client.key"
|
||||
fi
|
||||
if [ -r "$src/$etcd_cluster_name.crt" ] ; then
|
||||
cp "$src/$etcd_cluster_name.crt" "$RUN_ROOT/$etcd_certs_path/healthcheck-client.crt"
|
||||
fi
|
||||
echo "ETCD Certs copied from $src to $RUN_ROOT/$etcd_certs_path"
|
||||
}
|
||||
|
||||
# If HOSTNAME == K8S_MASTER it will be MASTER_0
|
||||
# othewise set HOSTNAME value to be resolved in same K8S_MASTER network
|
||||
# By using -cp- as part of HOSTNAME will be consider node as controlpanel
|
||||
# Other options = "-wk-0" or "-wkr-0" for worker nodes
|
||||
[[ "$HOSTNAME" == *-cp-* ]] && [ "$K8S_MODE" != "controlplane" ] && K8S_MODE="controlplane"
|
||||
if [ -n "$HOSTNAME" ] && [ "$HOSTNAME" == "$K8S_MASTER" ] && [ "$K8S_MODE" == "controlplane" ] && [ -n "$K8S_TPL" ]; then
|
||||
[ ! -d "$RUN_ROOT/resources" ] && mkdir -p "$RUN_ROOT/resources"
|
||||
if [ -r "$TEMPLATES_PATH/$K8S_TPL" ] ; then
|
||||
cp "$TEMPLATES_PATH/$K8S_TPL" "$RUN_ROOT/resources/$K8S_CONFIG.j2"
|
||||
elif [ -r "$TEMPLATES_PATH/${K8S_TPL/.j2/}" ] ; then
|
||||
cp "$TEMPLATES_PATH/${K8S_TPL/.j2/}" "$RUN_ROOT/resources/$K8S_CONFIG"
|
||||
fi
|
||||
fi
|
||||
[ "$K8S_MODE" == "controlplane" ] && [ "$ETCD_MODE" == "external" ] && _copy_certs
|
||||
|
||||
rm -rf "$RUN_ROOT/templates"
|
||||
13
taskservs/kubernetes/kubeconfig/env-kubernetes.j2
Normal file
13
taskservs/kubernetes/kubeconfig/env-kubernetes.j2
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{%- if taskserv.name == "kubernetes" %}
|
||||
# Main Ip for node should be in same K8S_MASTER network
|
||||
# Be sure MAIN_IP is alive and reachable
|
||||
{% if taskserv.cp_ip == "$network_private_ip" %}
|
||||
MAIN_IP="{{server.network_private_ip}}"
|
||||
{% elif taskserv.cp_ip == "$network_public_ip" and server.ip_addresses.pub -%}
|
||||
MAIN_IP={{server.ip_addresses.pub}}
|
||||
{%- else %}
|
||||
MAIN_IP=""
|
||||
{%- endif %}
|
||||
ADMIN_USER="{{taskserv.admin_user}}"
|
||||
TARGET_PATH="{{taskserv.target_path}}"
|
||||
{%- endif %}
|
||||
13
taskservs/kubernetes/kubeconfig/install-kubernetes.sh
Executable file
13
taskservs/kubernetes/kubeconfig/install-kubernetes.sh
Executable file
|
|
@ -0,0 +1,13 @@
|
|||
#!/bin/bash
|
||||
# Info: Script to collect kubeconfig
|
||||
# Author: JesusPerezLorenzo
|
||||
# Release: 1.0
|
||||
# Date: 30-10-2023
|
||||
|
||||
USAGE="install-kubernetes.sh "
|
||||
[ "$1" == "-h" ] && echo "$USAGE" && exit 1
|
||||
|
||||
[[ "$1" == env-* ]] && [ -r "$1" ] && . $1 && shift
|
||||
[ -r "env-kubernetes" ] && . env-kubernetes
|
||||
|
||||
[ -z "$MAIN_IP" ] && echo "No MAIN_IP value " && exit 1
|
||||
15
taskservs/kubernetes/kubectl/env-kubernetes.j2
Normal file
15
taskservs/kubernetes/kubectl/env-kubernetes.j2
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{%- if taskserv.name == "kubernetes" %}
|
||||
# Kubernetes URL for releases download
|
||||
URL="https://github.com/kubernetes/kubernetes/releases"
|
||||
FILE="."
|
||||
|
||||
# kubernetes version
|
||||
VERSION="{{taskserv.version}}"
|
||||
export MAJOR_VERSION="{{taskserv.major_version}}"
|
||||
K8S_VERSION=v$VERSION
|
||||
|
||||
# Default Arch
|
||||
ARCH="linux-amd64"
|
||||
if [ "$(uname -m)" = "aarch64" ]; then ARCH="linux-arm64"; fi
|
||||
|
||||
{% endif %}
|
||||
59
taskservs/kubernetes/kubectl/install-kubernetes.sh
Executable file
59
taskservs/kubernetes/kubectl/install-kubernetes.sh
Executable file
|
|
@ -0,0 +1,59 @@
|
|||
#!/bin/bash
|
||||
# Info: Script to install/create/delete/update kubectl from file settings
|
||||
# Author: JesusPerezLorenzo
|
||||
# Release: 1.0
|
||||
# Date: 12-11-2024
|
||||
|
||||
USAGE="install-kubernetes.sh install | update | remvoe"
|
||||
[ "$1" == "-h" ] && echo "$USAGE" && exit 1
|
||||
|
||||
[ -r "env-kubernetes" ] && . env-kubernetes
|
||||
|
||||
[ -z "$VERSION" ] && echo "No VERSION value " && exit 1
|
||||
|
||||
export LC_CTYPE=C.UTF-8
|
||||
export LANG=C.UTF-8
|
||||
#cmd_out=/dev/null
|
||||
|
||||
[ -n "$1" ] && CMD_TSK=$1 && shift
|
||||
|
||||
_install_kubectl() {
|
||||
[ -z "$VERSION" ] || [ -z "$ARCH" ] || [ -z "$URL" ] || [ -z "$FILE" ] && exit 1
|
||||
curr_vers=$(kubectl version 2>/dev/null | grep Client | awk '{print $3}' | sed 's/^v//g' 2>/dev/null)
|
||||
chmod 1777 /tmp
|
||||
if [ "v$curr_vers" != "$K8S_VERSION" ]; then
|
||||
echo "Install packages"
|
||||
if [ "$CMD_TSK" != "update" ] && [ ! -r "/etc/apt/keyrings/kubernetes-apt-keyring.gpg" ]; then
|
||||
sudo apt-get update && sudo apt-get install -y apt-transport-https gnupg2 curl
|
||||
sudo rm -f /etc/apt/keyrings/kubernetes-apt-keyring.gpg
|
||||
curl -fsSL "https://pkgs.k8s.io/core:/stable:/v$MAJOR_VERSION/deb/Release.key" | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
|
||||
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v$MAJOR_VERSION/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list
|
||||
fi
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-get update -q
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-mark unhold kubectl
|
||||
if ! sudo apt-get install -y kubectl ; then
|
||||
echo "error installing kubernetes"
|
||||
return 1
|
||||
fi
|
||||
# Hold your horse !
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-mark hold kubectl
|
||||
echo "init done"
|
||||
fi
|
||||
}
|
||||
case "$CMD_TSK" in
|
||||
remove)
|
||||
suto apt-get remove kubectl
|
||||
exit 0
|
||||
;;
|
||||
update)
|
||||
suto DEBIAN_FRONTEND=noninteractive apt-get update -q
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-mark unhold kubectl
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-get upgrade -y
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-mark hold kubectl
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
if ! _install_kubectl; then
|
||||
echo "error kubectl install"
|
||||
exit 1
|
||||
fi
|
||||
3
taskservs/mayastor/default/env-mayastor.j2
Normal file
3
taskservs/mayastor/default/env-mayastor.j2
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{%- if taskserv.name == "mayastor" %}
|
||||
NR_HUGEPAGE={{taskserv.nr_hugepages}}
|
||||
{%- endif %}
|
||||
22
taskservs/mayastor/default/install-mayastor.sh
Executable file
22
taskservs/mayastor/default/install-mayastor.sh
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
#!/bin/bash
|
||||
# Info: Script to install/create/delete/update mayastor from file settings
|
||||
# Author: JesusPerezLorenzo
|
||||
# Release: 1.0
|
||||
# Date: 15-12-2023
|
||||
|
||||
USAGE="install-mayastor.sh full-path-settings-file [ -m controlplane (hostname -cp-) | worker] [*install | update | makejoin | remove | fullremove]"
|
||||
|
||||
[ "$1" == "-h" ] && echo "$USAGE" && exit 1
|
||||
|
||||
[[ "$1" == *setting* ]] && [ -r "$1" ] && . $1 && shift
|
||||
[[ "$1" == env-* ]] && [ -r "$1" ] && . $1 && shift
|
||||
[ -r "env-mayastor" ] && . env-mayastor
|
||||
|
||||
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt install nvme-cli xfsprogs -y
|
||||
|
||||
if [ -n "$NR_HUGEPAGE" ] ; then
|
||||
echo "$NR_HUGEPAGE" | sudo tee /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
|
||||
echo vm.nr_hugepages = "$NR_HUGEPAGE" | sudo tee -a /etc/sysctl.conf
|
||||
fi
|
||||
|
||||
10
taskservs/oci-reg/default/env-oci-reg.j2
Normal file
10
taskservs/oci-reg/default/env-oci-reg.j2
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{%- if taskserv.name == "oci-reg" %}
|
||||
VERSION="{{taskserv.version}}"
|
||||
OCI_DATA="{{taskserv.oci_data}}"
|
||||
OCI_ETC="{{taskserv.oci_etc}}"
|
||||
OCI_LOG="{{taskserv.oci_log}}"
|
||||
OCI_USER="{{taskserv.oci_user}}"
|
||||
OCI_USER_GROUP="{{taskserv.oci_user_group}}"
|
||||
OCI_CMDS="{{taskserv.oci_cmds}}"
|
||||
OCI_BIN_PATH="{{taskserv.oci_bin_path}}"
|
||||
{%- endif %}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue