From 41df5516c95fd6f1fe10557222e36686a951e62b Mon Sep 17 00:00:00 2001 From: "CanbiZ (MickLesk)" <47820557+MickLesk@users.noreply.github.com> Date: Fri, 27 Mar 2026 11:32:26 +0100 Subject: [PATCH] Add IronClaw CT and refine CronMaster addon Add IronClaw container templates and install scripts (ct/ironclaw.sh, install/ironclaw-install.sh, json/ironclaw.json) to provide automated setup, service unit, and default config for the IronClaw AI agent. Refactor tools/addon/cronmaster.sh to use the ProxmoxVE misc endpoints, initialize optional telemetry, improve function loading, and strengthen OS detection (Debian/Ubuntu-only). Make service and install behaviors more robust: ensure /usr/local/bin persistence, create/update the update script from the new repo URL, change systemd WantedBy to multi-user.target, enable service quietly, save generated credentials to /root/cronmaster.creds, and use distinct exit codes for unsupported/invalid states. Misc license URL fix and other small reliability improvements. --- ct/ironclaw.sh | 69 +++++++++++++++++++++++++++++++++++++ install/ironclaw-install.sh | 61 ++++++++++++++++++++++++++++++++ json/ironclaw.json | 44 +++++++++++++++++++++++ tools/addon/cronmaster.sh | 61 ++++++++++++++++---------------- 4 files changed, 206 insertions(+), 29 deletions(-) create mode 100644 ct/ironclaw.sh create mode 100644 install/ironclaw-install.sh create mode 100644 json/ironclaw.json diff --git a/ct/ironclaw.sh b/ct/ironclaw.sh new file mode 100644 index 00000000..e462b4dd --- /dev/null +++ b/ct/ironclaw.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) +# Copyright (c) 2021-2026 community-scripts ORG +# Author: MickLesk (CanbiZ) +# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE +# Source: https://github.com/nearai/ironclaw + +APP="IronClaw" +var_tags="${var_tags:-ai;agent;security}" +var_cpu="${var_cpu:-2}" +var_ram="${var_ram:-2048}" +var_disk="${var_disk:-8}" +var_os="${var_os:-debian}" +var_version="${var_version:-13}" +var_unprivileged="${var_unprivileged:-1}" + +header_info "$APP" +variables +color +catch_errors + +function update_script() { + header_info + check_container_storage + check_container_resources + + if [[ ! -f /usr/local/bin/ironclaw ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + + if check_for_gh_release "ironclaw-bin" "nearai/ironclaw"; then + msg_info "Stopping Service" + systemctl stop ironclaw + msg_ok "Stopped Service" + + msg_info "Backing up Configuration" + cp /root/.ironclaw/.env /root/ironclaw.env.bak + msg_ok "Backed up Configuration" + + fetch_and_deploy_gh_release "ironclaw-bin" "nearai/ironclaw" "prebuild" "latest" "/usr/local/bin" \ + "ironclaw-$(uname -m)-unknown-linux-$([[ -f /etc/alpine-release ]] && echo "musl" || echo "gnu").tar.gz" + chmod +x /usr/local/bin/ironclaw + + msg_info "Restoring Configuration" + cp /root/ironclaw.env.bak /root/.ironclaw/.env + rm -f /root/ironclaw.env.bak + msg_ok "Restored Configuration" + + msg_info "Starting Service" + systemctl start ironclaw + msg_ok "Started Service" + msg_ok "Updated successfully!" + fi + exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" +echo -e "${INFO}${YW} Access the Web UI at:${CL}" +echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}" +echo -e "${INFO}${YW} Auth token and database credentials:${CL}" +echo -e "${TAB}${BGN}cat /root/.ironclaw/.env${CL}" +echo -e "${INFO}${YW} Configure your LLM provider with:${CL}" +echo -e "${TAB}${BGN}ironclaw onboard${CL}" diff --git a/install/ironclaw-install.sh b/install/ironclaw-install.sh new file mode 100644 index 00000000..c35670d4 --- /dev/null +++ b/install/ironclaw-install.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2026 community-scripts ORG +# Author: MickLesk (CanbiZ) +# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE +# Source: https://github.com/nearai/ironclaw + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +PG_VERSION="17" PG_MODULES="pgvector" setup_postgresql +PG_DB_NAME="ironclaw" PG_DB_USER="ironclaw" PG_DB_EXTENSIONS="vector" setup_postgresql_db + +fetch_and_deploy_gh_release "ironclaw-bin" "nearai/ironclaw" "prebuild" "latest" "/usr/local/bin" \ + "ironclaw-$(uname -m)-unknown-linux-$([[ -f /etc/alpine-release ]] && echo "musl" || echo "gnu").tar.gz" +chmod +x /usr/local/bin/ironclaw + +msg_info "Configuring IronClaw" +mkdir -p /root/.ironclaw +GATEWAY_TOKEN=$(openssl rand -hex 32) +cat </root/.ironclaw/.env +DATABASE_URL=postgresql://${PG_DB_USER}:${PG_DB_PASS}@localhost:5432/${PG_DB_NAME} +GATEWAY_ENABLED=true +GATEWAY_HOST=0.0.0.0 +GATEWAY_PORT=3000 +GATEWAY_AUTH_TOKEN=${GATEWAY_TOKEN} +CLI_ENABLED=false +AGENT_NAME=ironclaw +RUST_LOG=ironclaw=info,tower_http=info +EOF +chmod 600 /root/.ironclaw/.env +msg_ok "Configured IronClaw" + +msg_info "Creating Service" +cat </etc/systemd/system/ironclaw.service +[Unit] +Description=IronClaw AI Agent +After=network.target postgresql.service + +[Service] +Type=simple +User=root +WorkingDirectory=/root +ExecStart=/usr/local/bin/ironclaw +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now ironclaw +msg_ok "Created Service" + +motd_ssh +customize +cleanup_lxc diff --git a/json/ironclaw.json b/json/ironclaw.json new file mode 100644 index 00000000..1e83e653 --- /dev/null +++ b/json/ironclaw.json @@ -0,0 +1,44 @@ +{ + "name": "IronClaw", + "slug": "ironclaw", + "categories": [ + 20 + ], + "date_created": "2026-03-27", + "type": "ct", + "updateable": true, + "privileged": false, + "interface_port": 3000, + "documentation": "https://github.com/nearai/ironclaw/tree/staging/docs", + "website": "https://github.com/nearai/ironclaw", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/ironclaw.webp", + "config_path": "/root/.ironclaw/.env", + "description": "IronClaw is a secure, self-hosted AI agent with a web browser interface, multi-LLM support, hybrid memory search, and WASM-sandboxed tool execution — all data stays on your server.", + "install_methods": [ + { + "type": "default", + "script": "ct/ironclaw.sh", + "resources": { + "cpu": 2, + "ram": 2048, + "hdd": 8, + "os": "Debian", + "version": "13" + } + } + ], + "default_credentials": { + "username": null, + "password": null + }, + "notes": [ + { + "text": "The gateway auth token is auto-generated and stored in /root/.ironclaw/.env.", + "type": "info" + }, + { + "text": "Configure your LLM provider after installation by running: ironclaw onboard", + "type": "info" + } + ] +} diff --git a/tools/addon/cronmaster.sh b/tools/addon/cronmaster.sh index faf2780b..b8ae5502 100644 --- a/tools/addon/cronmaster.sh +++ b/tools/addon/cronmaster.sh @@ -2,7 +2,7 @@ # Copyright (c) 2021-2026 community-scripts ORG # Author: MickLesk (CanbiZ) -# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # Source: https://github.com/fccview/cronmaster if ! command -v curl &>/dev/null; then @@ -10,13 +10,16 @@ if ! command -v curl &>/dev/null; then apt-get update >/dev/null 2>&1 apt-get install -y curl >/dev/null 2>&1 fi -source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/core.func) -source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/tools.func) -source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/error_handler.func) +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func) +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func) +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func) +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true +declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "cronmaster" "addon" # Enable error handling set -Eeuo pipefail trap 'error_handler' ERR +load_functions # ============================================================================== # CONFIGURATION @@ -25,11 +28,9 @@ APP="CronMaster" APP_TYPE="addon" INSTALL_PATH="/opt/cronmaster" CONFIG_PATH="/opt/cronmaster/.env" +SERVICE_PATH="/etc/systemd/system/cronmaster.service" DEFAULT_PORT=3000 -# Initialize all core functions (colors, formatting, icons, STD mode) -load_functions - # ============================================================================== # HEADER # ============================================================================== @@ -48,15 +49,9 @@ EOF # ============================================================================== # OS DETECTION # ============================================================================== -if [[ -f "/etc/alpine-release" ]]; then - msg_error "Alpine is not supported for ${APP}. Use Debian/Ubuntu." - exit 1 -elif [[ -f "/etc/debian_version" ]]; then - OS="Debian" - SERVICE_PATH="/etc/systemd/system/cronmaster.service" -else - echo -e "${CROSS} Unsupported OS detected. Exiting." - exit 1 +if ! grep -qE 'ID=debian|ID=ubuntu' /etc/os-release 2>/dev/null; then + echo -e "${CROSS} Unsupported OS detected. This script only supports Debian and Ubuntu." + exit 238 fi # ============================================================================== @@ -69,6 +64,7 @@ function uninstall() { rm -rf "$INSTALL_PATH" rm -f "/usr/local/bin/update_cronmaster" rm -f "$HOME/.cronmaster" + rm -f "/root/cronmaster.creds" msg_ok "${APP} has been uninstalled" } @@ -111,8 +107,6 @@ function install() { NODE_VERSION="22" setup_nodejs fi - # Force fresh download by removing version cache - rm -f "$HOME/.cronmaster" fetch_and_deploy_gh_release "cronmaster" "fccview/cronmaster" "prebuild" "latest" "$INSTALL_PATH" "cronmaster_*_prebuild.tar.gz" local AUTH_PASS @@ -145,46 +139,55 @@ Restart=always RestartSec=10 [Install] -WantedBy=multi-target.target +WantedBy=multi-user.target EOF - systemctl enable --now cronmaster &>/dev/null + systemctl enable -q --now cronmaster msg_ok "Created and started service" # Create update script msg_info "Creating update script" - cat <<'UPDATEEOF' >/usr/local/bin/update_cronmaster + ensure_usr_local_bin_persist + cat </usr/local/bin/update_cronmaster #!/usr/bin/env bash # CronMaster Update Script -type=update bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/tools/addon/cronmaster.sh)" -UPDATEEOF +type=update bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/cronmaster.sh)" +EOF chmod +x /usr/local/bin/update_cronmaster msg_ok "Created update script (/usr/local/bin/update_cronmaster)" + # Save credentials + local CREDS_FILE="/root/cronmaster.creds" + cat <"$CREDS_FILE" +CronMaster Credentials +====================== +Password: ${AUTH_PASS} + +Web UI: http://${LOCAL_IP}:${DEFAULT_PORT} +EOF echo "" msg_ok "${APP} is reachable at: ${BL}http://${LOCAL_IP}:${DEFAULT_PORT}${CL}" - msg_ok "Password: ${BL}${AUTH_PASS}${CL}" + msg_ok "Credentials saved to: ${BL}${CREDS_FILE}${CL}" echo "" } # ============================================================================== # MAIN # ============================================================================== +header_info +ensure_usr_local_bin_persist +get_lxc_ip # Handle type=update (called from update script) if [[ "${type:-}" == "update" ]]; then - header_info if [[ -d "$INSTALL_PATH" ]]; then update else msg_error "${APP} is not installed. Nothing to update." - exit 1 + exit 233 fi exit 0 fi -header_info -get_lxc_ip - # Check if already installed if [[ -d "$INSTALL_PATH" && -n "$(ls -A "$INSTALL_PATH" 2>/dev/null)" ]]; then msg_warn "${APP} is already installed."