Settle on v1 setup method. Test run completed successfully from bootstrap to service setup.
- Refactor dnsmasq configuration and scripts for improved variable handling and clarity - Updated dnsmasq configuration files to use direct variable references instead of data source functions for better readability. - Modified setup scripts to ensure they are run from the correct environment and directory, checking for the WC_HOME variable. - Changed paths in README and scripts to reflect the new directory structure. - Enhanced error handling in setup scripts to provide clearer guidance on required configurations. - Adjusted kernel and initramfs URLs in boot.ipxe to use the updated variable references.
This commit is contained in:
23
bin/backup
Executable file
23
bin/backup
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
# Simple backup script for your personal cloud
|
||||
# This is a placeholder for future implementation
|
||||
|
||||
SCRIPT_PATH="$(realpath "${BASH_SOURCE[0]}")"
|
||||
SCRIPT_DIR="$(dirname "$SCRIPT_PATH")"
|
||||
cd "$SCRIPT_DIR"
|
||||
if [[ -f "../load-env.sh" ]]; then
|
||||
source ../load-env.sh
|
||||
fi
|
||||
|
||||
BACKUP_DIR="${PROJECT_DIR}/backups/$(date +%Y-%m-%d)"
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
# Back up Kubernetes resources
|
||||
kubectl get all -A -o yaml > "$BACKUP_DIR/all-resources.yaml"
|
||||
kubectl get secrets -A -o yaml > "$BACKUP_DIR/secrets.yaml"
|
||||
kubectl get configmaps -A -o yaml > "$BACKUP_DIR/configmaps.yaml"
|
||||
|
||||
# Back up persistent volumes
|
||||
# TODO: Add logic to back up persistent volume data
|
||||
|
||||
echo "Backup completed: $BACKUP_DIR"
|
136
bin/helm-chart-to-kustomize
Executable file
136
bin/helm-chart-to-kustomize
Executable file
@@ -0,0 +1,136 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
usage() {
|
||||
echo "Usage: helm-chart-to-kustomize <repo/chart> <release-name> <namespace> [values-file]"
|
||||
echo ""
|
||||
echo "Convert a Helm chart to Kustomize manifests."
|
||||
echo ""
|
||||
echo "Arguments:"
|
||||
echo " repo/chart Helm chart repository and name (e.g., nginx-stable/nginx-ingress)"
|
||||
echo " release-name Name for the Helm release (e.g., ingress-controller)"
|
||||
echo " namespace Kubernetes namespace to deploy to"
|
||||
echo " values-file Optional values.yaml file for customization"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " helm-chart-to-kustomize nginx-stable/nginx-ingress ingress-controller ingress"
|
||||
echo " helm-chart-to-kustomize nginx-stable/nginx-ingress ingress-controller ingress values.yaml"
|
||||
echo ""
|
||||
echo "Output:"
|
||||
echo " Creates base/<release-name>/ directory with Kustomize-ready manifests"
|
||||
}
|
||||
|
||||
# Parse arguments
|
||||
if [[ $# -lt 3 || "$1" == "-h" || "$1" == "--help" ]]; then
|
||||
usage
|
||||
exit 0
|
||||
fi
|
||||
|
||||
chart_repo="$1"
|
||||
release_name="$2"
|
||||
namespace="$3"
|
||||
values_file="${4:-}"
|
||||
|
||||
# Extract chart name from repo/chart
|
||||
chart_name="${chart_repo##*/}"
|
||||
|
||||
echo "Converting Helm chart to Kustomize: $chart_repo -> base/$release_name"
|
||||
|
||||
# Create working directories
|
||||
mkdir -p charts base
|
||||
|
||||
# Fetch the Helm chart if not already present
|
||||
if [[ -d "charts/$chart_name" ]]; then
|
||||
echo "Chart '$chart_name' already exists in 'charts/' directory. Skipping fetch."
|
||||
else
|
||||
echo "Fetching Helm chart: $chart_repo"
|
||||
|
||||
# Add repository if not already added
|
||||
repo_name="$(echo "$chart_repo" | cut -d'/' -f1)"
|
||||
if ! helm repo list 2>/dev/null | grep -q "^$repo_name"; then
|
||||
echo "Adding Helm repository: $repo_name"
|
||||
# Handle common repository URLs
|
||||
case "$repo_name" in
|
||||
"traefik")
|
||||
helm repo add "$repo_name" "https://traefik.github.io/charts"
|
||||
;;
|
||||
"nginx-stable")
|
||||
helm repo add "$repo_name" "https://helm.nginx.com/stable"
|
||||
;;
|
||||
*)
|
||||
# Try generic helm.sh pattern first
|
||||
helm repo add "$repo_name" "https://charts.helm.sh/$repo_name" 2>/dev/null || {
|
||||
echo "Error: Unknown repository '$repo_name'. Please add manually with 'helm repo add'."
|
||||
exit 1
|
||||
}
|
||||
;;
|
||||
esac
|
||||
helm repo update
|
||||
fi
|
||||
|
||||
if ! helm search repo "$chart_repo" >/dev/null 2>&1; then
|
||||
echo "Error: Helm chart '$chart_repo' not found in repositories."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
helm fetch --untar --untardir charts "$chart_repo"
|
||||
fi
|
||||
|
||||
# Build helm template command
|
||||
template_cmd="helm template --output-dir base --namespace $namespace"
|
||||
if [[ -n "$values_file" && -f "$values_file" ]]; then
|
||||
template_cmd="$template_cmd --values $values_file"
|
||||
echo "Using values file: $values_file"
|
||||
fi
|
||||
template_cmd="$template_cmd $release_name charts/$chart_name"
|
||||
|
||||
# Clean existing base directory if it exists
|
||||
if [[ -d "base/$release_name" ]]; then
|
||||
echo "Existing base/$release_name directory found. Cleaning..."
|
||||
rm -rf "base/$release_name"
|
||||
fi
|
||||
|
||||
# Generate manifests with Helm template
|
||||
echo "Generating manifests with Helm template..."
|
||||
eval "$template_cmd"
|
||||
|
||||
# Create namespace manifest
|
||||
echo "Creating namespace manifest..."
|
||||
cat <<EOF > "base/$release_name/namespace.yaml"
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: $namespace
|
||||
EOF
|
||||
|
||||
# Generate kustomization.yaml
|
||||
echo "Generating kustomization.yaml..."
|
||||
cd "base/$release_name"
|
||||
|
||||
# Find all YAML files recursively and create kustomization
|
||||
resources=()
|
||||
while IFS= read -r -d '' file; do
|
||||
# Get relative path from current directory
|
||||
rel_path="${file#./}"
|
||||
resources+=("$rel_path")
|
||||
done < <(find . -name "*.yaml" -not -name "kustomization.yaml" -print0 | sort -z)
|
||||
|
||||
# Create kustomization.yaml with all resources
|
||||
cat > kustomization.yaml << EOF
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
EOF
|
||||
|
||||
for resource in "${resources[@]}"; do
|
||||
echo "- $resource" >> kustomization.yaml
|
||||
done
|
||||
|
||||
echo "✅ Conversion complete!"
|
||||
echo ""
|
||||
echo "Generated files in: base/$release_name/"
|
||||
echo "To apply with kubectl:"
|
||||
echo " kubectl apply -k base/$release_name"
|
||||
echo ""
|
||||
echo "To customize further, edit the files in base/$release_name/ and regenerate kustomization.yaml if needed."
|
@@ -7,7 +7,7 @@ set -o pipefail
|
||||
usage() {
|
||||
echo "Usage: wild-compile-template [options]"
|
||||
echo ""
|
||||
echo "Compile a gomplate template from stdin using ./config.yaml as context."
|
||||
echo "Compile a gomplate template from stdin using \$WC_HOME/config.yaml as context."
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " echo 'Hello {{.config.cluster.name}}' | wild-compile-template"
|
||||
@@ -37,17 +37,26 @@ while [[ $# -gt 0 ]]; do
|
||||
esac
|
||||
done
|
||||
|
||||
if [ ! -f "./config.yaml" ]; then
|
||||
echo "Error: ./config.yaml not found in current directory" >&2
|
||||
# Check if WC_HOME is set
|
||||
if [ -z "${WC_HOME:-}" ]; then
|
||||
echo "Error: WC_HOME environment variable not set" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Build gomplate command with config context (enables .config shorthand)
|
||||
gomplate_cmd="gomplate -c config=./config.yaml"
|
||||
CONFIG_FILE="${WC_HOME}/config.yaml"
|
||||
SECRETS_FILE="${WC_HOME}/secrets.yaml"
|
||||
|
||||
if [ ! -f "${CONFIG_FILE}" ]; then
|
||||
echo "Error: config.yaml not found at ${CONFIG_FILE}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Build gomplate command with config context
|
||||
gomplate_cmd="gomplate -c .=${CONFIG_FILE}"
|
||||
|
||||
# Add secrets context if secrets.yaml exists (enables .secrets shorthand)
|
||||
if [ -f "./secrets.yaml" ]; then
|
||||
gomplate_cmd="${gomplate_cmd} -c secrets=./secrets.yaml"
|
||||
if [ -f "${SECRETS_FILE}" ]; then
|
||||
gomplate_cmd="${gomplate_cmd} -c secrets=${SECRETS_FILE}"
|
||||
fi
|
||||
|
||||
# Execute gomplate with stdin
|
||||
|
98
bin/wild-compile-template-dir
Executable file
98
bin/wild-compile-template-dir
Executable file
@@ -0,0 +1,98 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
usage() {
|
||||
echo "Usage: wild-compile-template-dir [options] <source_dir> [dest_dir]"
|
||||
echo ""
|
||||
echo "Recursively copy all files from source_dir to dest_dir, processing text files through wild-compile-template."
|
||||
echo "Binary files are copied as-is. Directory structure is preserved."
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " --clean Delete destination directory before processing"
|
||||
echo " -h, --help Show this help message"
|
||||
echo ""
|
||||
echo "Arguments:"
|
||||
echo " source_dir Source directory to process"
|
||||
echo " dest_dir Destination directory (default: source_dir_compiled)"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " wild-compile-template-dir ./templates"
|
||||
echo " wild-compile-template-dir ./templates ./output"
|
||||
echo " wild-compile-template-dir --clean ./templates"
|
||||
echo " wild-compile-template-dir --clean ./templates ./output"
|
||||
}
|
||||
|
||||
# Parse arguments
|
||||
clean_flag=false
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--clean)
|
||||
clean_flag=true
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
-*)
|
||||
echo "Unknown option: $1" >&2
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ $# -eq 0 ]]; then
|
||||
usage
|
||||
exit 0
|
||||
fi
|
||||
|
||||
source_dir="$1"
|
||||
dest_dir="${2:-${source_dir}_compiled}"
|
||||
|
||||
|
||||
# Validate source directory
|
||||
if [[ ! -d "$source_dir" ]]; then
|
||||
echo "Error: Source directory does not exist: $source_dir" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Clean destination directory if requested
|
||||
if [[ "$clean_flag" == true && -d "$dest_dir" ]]; then
|
||||
echo "Cleaning destination directory: $dest_dir"
|
||||
rm -rf "$dest_dir"
|
||||
fi
|
||||
|
||||
# Create destination directory
|
||||
mkdir -p "$dest_dir"
|
||||
|
||||
echo "Processing directory: $source_dir -> $dest_dir"
|
||||
|
||||
# Process all files recursively
|
||||
find "$source_dir" -type f -print0 | while IFS= read -r -d '' file; do
|
||||
# Get relative path from source directory
|
||||
rel_path="${file#$source_dir/}"
|
||||
dest_file="$dest_dir/$rel_path"
|
||||
dest_file_dir="$(dirname "$dest_file")"
|
||||
|
||||
# Create destination directory structure
|
||||
mkdir -p "$dest_file_dir"
|
||||
|
||||
# Check if file is text using file command
|
||||
if file --mime-type "$file" 2>/dev/null | grep -q 'text/'; then
|
||||
echo " Processing: $rel_path"
|
||||
if ! cat "$file" | wild-compile-template > "$dest_file"; then
|
||||
echo " ✗ Failed to process: $rel_path" >&2
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo " Copying: $rel_path"
|
||||
cp "$file" "$dest_file"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "✅ Complete: All files processed successfully"
|
@@ -7,7 +7,7 @@ set -o pipefail
|
||||
usage() {
|
||||
echo "Usage: wild-config <yaml_key_path>"
|
||||
echo ""
|
||||
echo "Read a value from ./config.yaml using a YAML key path."
|
||||
echo "Read a value from \$WC_HOME/config.yaml using a YAML key path."
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " wild-config 'cluster.name' # Get cluster name"
|
||||
@@ -49,17 +49,25 @@ if [ -z "${KEY_PATH}" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "./config.yaml" ]; then
|
||||
echo "Error: ./config.yaml not found in current directory"
|
||||
# Check if WC_HOME is set
|
||||
if [ -z "${WC_HOME:-}" ]; then
|
||||
echo "Error: WC_HOME environment variable not set" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CONFIG_FILE="${WC_HOME}/config.yaml"
|
||||
|
||||
if [ ! -f "${CONFIG_FILE}" ]; then
|
||||
echo "Error: config file not found at ${CONFIG_FILE}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Use yq to extract the value from the YAML file
|
||||
result=$(yq eval ".${KEY_PATH}" ./config.yaml)
|
||||
result=$(yq eval ".${KEY_PATH}" "${CONFIG_FILE}") 2>/dev/null
|
||||
|
||||
# Check if result is null (key not found)
|
||||
if [ "${result}" = "null" ]; then
|
||||
echo "Error: Key path '${KEY_PATH}' not found in ./config.yaml" >&2
|
||||
echo "Error: Key path '${KEY_PATH}' not found in ${CONFIG_FILE}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
74
bin/wild-secret
Executable file
74
bin/wild-secret
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
# Usage function
|
||||
usage() {
|
||||
echo "Usage: wild-secret <yaml_key_path>"
|
||||
echo ""
|
||||
echo "Read a value from ./secrets.yaml using a YAML key path."
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " wild-secret 'database.password' # Get database password"
|
||||
echo " wild-secret 'api.keys.github' # Get GitHub API key"
|
||||
echo " wild-secret 'credentials[0].token' # Get first credential token"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " -h, --help Show this help message"
|
||||
}
|
||||
|
||||
# Parse arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
-*)
|
||||
echo "Unknown option $1"
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
if [ -z "${KEY_PATH}" ]; then
|
||||
KEY_PATH="$1"
|
||||
else
|
||||
echo "Too many arguments"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "${KEY_PATH}" ]; then
|
||||
echo "Error: YAML key path is required"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if WC_HOME is set
|
||||
if [ -z "${WC_HOME:-}" ]; then
|
||||
echo "Error: WC_HOME environment variable not set" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SECRETS_FILE="${WC_HOME}/secrets.yaml"
|
||||
|
||||
if [ ! -f "${SECRETS_FILE}" ]; then
|
||||
echo "Error: secrets file not found at ${SECRETS_FILE}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Use yq to extract the value from the YAML file
|
||||
result=$(yq eval ".${KEY_PATH}" "${SECRETS_FILE}" 2>/dev/null)
|
||||
|
||||
# Check if result is null (key not found)
|
||||
if [ "${result}" = "null" ]; then
|
||||
echo "Error: Key path '${KEY_PATH}' not found in ${SECRETS_FILE}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "${result}"
|
137
bin/wild-talos-iso
Executable file
137
bin/wild-talos-iso
Executable file
@@ -0,0 +1,137 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Talos ISO download script
|
||||
# Downloads custom Talos ISO with system extensions for USB boot
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Check if WC_HOME is set
|
||||
if [ -z "${WC_HOME:-}" ]; then
|
||||
echo "Error: WC_HOME environment variable not set. Run \`source .env\`."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CONFIG_FILE="${WC_HOME}/config.yaml"
|
||||
ISO_DIR="${WC_HOME}/.wildcloud/iso"
|
||||
FORCE_DOWNLOAD=false
|
||||
|
||||
# Parse arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--force)
|
||||
FORCE_DOWNLOAD=true
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
echo "Usage: wild-talos-iso [--force]"
|
||||
echo ""
|
||||
echo "Downloads custom Talos ISO with system extensions for USB boot."
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " --force Force re-download even if ISO already exists"
|
||||
echo " -h, --help Show this help message"
|
||||
echo ""
|
||||
echo "This script:"
|
||||
echo " 1. Gets schematic ID and Talos version from config.yaml"
|
||||
echo " 2. Downloads custom ISO from Talos Image Factory"
|
||||
echo " 3. Saves ISO to .wildcloud/iso/ directory"
|
||||
echo ""
|
||||
echo "The ISO includes extensions configured in config.yaml:"
|
||||
echo " (.cluster.nodes.talos.schematic.customization.systemExtensions)"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1"
|
||||
echo "Use --help for usage information"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo "Downloading custom Talos ISO with system extensions..."
|
||||
|
||||
# Get Talos version and schematic ID from config
|
||||
TALOS_VERSION=$(yq eval '.cluster.nodes.talos.version' "$CONFIG_FILE")
|
||||
SCHEMATIC_ID=$(yq eval '.cluster.nodes.talos.schematicId // ""' "$CONFIG_FILE")
|
||||
|
||||
if [ -z "$TALOS_VERSION" ] || [ "$TALOS_VERSION" = "null" ]; then
|
||||
echo "Error: No Talos version found in config.yaml at .cluster.nodes.talos.version"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$SCHEMATIC_ID" ] || [ "$SCHEMATIC_ID" = "null" ]; then
|
||||
echo "Error: No schematic ID found in config.yaml"
|
||||
echo "Run 'wild-talos-schema' first to upload schematic and get ID"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Talos version: $TALOS_VERSION"
|
||||
echo "Schematic ID: $SCHEMATIC_ID"
|
||||
echo ""
|
||||
echo "ISO includes extensions:"
|
||||
yq eval '.cluster.nodes.talos.schematic.customization.systemExtensions.officialExtensions[]' "$CONFIG_FILE" | sed 's/^/ - /'
|
||||
echo ""
|
||||
|
||||
# Create ISO directory
|
||||
mkdir -p "$ISO_DIR"
|
||||
|
||||
# Define ISO filename and path
|
||||
ISO_FILENAME="talos-${TALOS_VERSION}-metal-amd64.iso"
|
||||
ISO_PATH="${ISO_DIR}/${ISO_FILENAME}"
|
||||
|
||||
# Check if ISO already exists
|
||||
if [ -f "$ISO_PATH" ] && [ "$FORCE_DOWNLOAD" = false ]; then
|
||||
echo "✅ ISO already exists: $ISO_PATH"
|
||||
echo "Use --force to re-download"
|
||||
echo ""
|
||||
echo "To create a bootable USB:"
|
||||
echo " See docs/node_setup.md for USB creation instructions"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Download ISO from Image Factory
|
||||
ISO_URL="https://factory.talos.dev/image/${SCHEMATIC_ID}/${TALOS_VERSION}/metal-amd64.iso"
|
||||
echo "Downloading ISO from: $ISO_URL"
|
||||
echo "Saving to: $ISO_PATH"
|
||||
echo ""
|
||||
|
||||
# Download with progress bar
|
||||
if command -v wget >/dev/null 2>&1; then
|
||||
wget --progress=bar:force -O "$ISO_PATH" "$ISO_URL"
|
||||
elif command -v curl >/dev/null 2>&1; then
|
||||
curl -L --progress-bar -o "$ISO_PATH" "$ISO_URL"
|
||||
else
|
||||
echo "Error: Neither wget nor curl is available for downloading"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verify download
|
||||
if [ ! -f "$ISO_PATH" ] || [ ! -s "$ISO_PATH" ]; then
|
||||
echo "Error: Download failed or file is empty"
|
||||
rm -f "$ISO_PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get file size for verification
|
||||
FILE_SIZE=$(du -h "$ISO_PATH" | cut -f1)
|
||||
|
||||
echo ""
|
||||
echo "✅ Custom Talos ISO downloaded successfully!"
|
||||
echo ""
|
||||
echo "ISO Details:"
|
||||
echo " File: $ISO_PATH"
|
||||
echo " Size: $FILE_SIZE"
|
||||
echo " Version: $TALOS_VERSION"
|
||||
echo " Extensions: $(yq eval '.cluster.nodes.talos.schematic.customization.systemExtensions.officialExtensions | length' "$CONFIG_FILE") extensions included"
|
||||
echo " Auto-wipe: Enabled (will wipe existing Talos installations)"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo "1. Create bootable USB drive (see docs/node_setup.md)"
|
||||
echo "2. Boot target machine from USB"
|
||||
echo "3. Run hardware detection: ./detect-node-hardware.sh <maintenance-ip> <node-number>"
|
||||
echo "4. Apply machine configuration"
|
||||
echo ""
|
||||
echo "USB Creation Quick Reference:"
|
||||
echo " Linux: sudo dd if=$ISO_PATH of=/dev/sdX bs=4M status=progress"
|
||||
echo " macOS: sudo dd if=$ISO_PATH of=/dev/rdiskX bs=4m"
|
||||
echo " Windows: Use Rufus, Balena Etcher, or similar tool"
|
113
bin/wild-talos-schema
Executable file
113
bin/wild-talos-schema
Executable file
@@ -0,0 +1,113 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Talos schematic management script
|
||||
# This script manages Talos Image Factory schematics centrally
|
||||
# Usage: wild-talos-schema [--force]
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Check if WC_HOME is set
|
||||
if [ -z "${WC_HOME:-}" ]; then
|
||||
echo "Error: WC_HOME environment variable not set. Run \`source .env\`."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CONFIG_FILE="${WC_HOME}/config.yaml"
|
||||
FORCE_UPLOAD=false
|
||||
|
||||
# Parse arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--force)
|
||||
FORCE_UPLOAD=true
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
echo "Usage: wild-talos-schema [--force]"
|
||||
echo ""
|
||||
echo "Manages Talos Image Factory schematics centrally."
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " --force Force re-upload even if schematicId already exists"
|
||||
echo " -h, --help Show this help message"
|
||||
echo ""
|
||||
echo "This script:"
|
||||
echo " 1. Reads schematic from config.yaml (.cluster.nodes.talos.schematic)"
|
||||
echo " 2. Uploads it to Image Factory if needed"
|
||||
echo " 3. Stores the schematicId in config.yaml (.cluster.nodes.talos.schematicId)"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1"
|
||||
echo "Use --help for usage information"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo "Managing Talos schematic for wildcloud..."
|
||||
|
||||
# Check if schematic exists in config.yaml
|
||||
if ! yq eval '.cluster.nodes.talos.schematic' "$CONFIG_FILE" | grep -v "null" >/dev/null 2>&1; then
|
||||
echo "Error: No schematic found in config.yaml at .cluster.nodes.talos.schematic"
|
||||
echo "Expected schematic configuration with systemExtensions"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if schematicId already exists (unless force)
|
||||
EXISTING_ID=$(yq eval '.cluster.nodes.talos.schematicId // ""' "$CONFIG_FILE")
|
||||
if [ -n "$EXISTING_ID" ] && [ "$FORCE_UPLOAD" = false ]; then
|
||||
echo "✅ Schematic ID already exists: $EXISTING_ID"
|
||||
echo "Use --force to re-upload and generate a new ID"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Extracting schematic from config.yaml..."
|
||||
|
||||
# Create temporary schematic file
|
||||
TEMP_SCHEMATIC=$(mktemp)
|
||||
trap "rm -f $TEMP_SCHEMATIC" EXIT
|
||||
|
||||
# Extract schematic from config.yaml
|
||||
yq eval '.cluster.nodes.talos.schematic' "$CONFIG_FILE" > "$TEMP_SCHEMATIC"
|
||||
|
||||
echo "Schematic contents:"
|
||||
cat "$TEMP_SCHEMATIC"
|
||||
echo ""
|
||||
|
||||
# Upload schematic to Image Factory
|
||||
echo "Uploading schematic to Talos Image Factory..."
|
||||
SCHEMATIC_RESPONSE=$(curl -s -X POST --data-binary @"$TEMP_SCHEMATIC" https://factory.talos.dev/schematics)
|
||||
|
||||
if [ -z "$SCHEMATIC_RESPONSE" ]; then
|
||||
echo "Error: Failed to upload schematic to Image Factory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Parse schematic ID from JSON response
|
||||
SCHEMATIC_ID=$(echo "$SCHEMATIC_RESPONSE" | sed 's/.*"id":"\([^"]*\)".*/\1/')
|
||||
|
||||
if [ -z "$SCHEMATIC_ID" ] || [ "$SCHEMATIC_ID" = "$SCHEMATIC_RESPONSE" ]; then
|
||||
echo "Error: Failed to parse schematic ID from response: $SCHEMATIC_RESPONSE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Schematic uploaded successfully!"
|
||||
echo "Schematic ID: $SCHEMATIC_ID"
|
||||
|
||||
# Update config.yaml with schematic ID
|
||||
echo "Updating config.yaml with schematic ID..."
|
||||
yq eval ".cluster.nodes.talos.schematicId = \"$SCHEMATIC_ID\"" -i "$CONFIG_FILE"
|
||||
|
||||
echo ""
|
||||
echo "🎉 Schematic management complete!"
|
||||
echo ""
|
||||
echo "Schematic ID: $SCHEMATIC_ID"
|
||||
echo "Saved to: config.yaml (.cluster.nodes.talos.schematicId)"
|
||||
echo ""
|
||||
echo "This schematic includes:"
|
||||
yq eval '.cluster.nodes.talos.schematic.customization.systemExtensions.officialExtensions[]' "$CONFIG_FILE" | sed 's/^/ - /'
|
||||
echo ""
|
||||
echo "Other scripts can now use this schematicId:"
|
||||
echo " - setup/dnsmasq/bin/create-setup-bundle.sh (PXE boot assets)"
|
||||
echo " - setup/cluster-nodes/create-installer-image.sh (custom installer)"
|
Reference in New Issue
Block a user