From 02b4932dbcfbaf987db05ad0fbc628bc6872c727 Mon Sep 17 00:00:00 2001 From: "Sofiane A." Date: Wed, 14 Oct 2026 02:54:13 +0200 Subject: [PATCH 1/3] feat: add native Komodo Periphery addon --- docs/komodo-periphery.md | 113 +++++++++++++++ tools/addon/komodo-periphery.sh | 239 ++++++++++++++++++++++++++++++++ 2 files changed, 352 insertions(+) create mode 100644 docs/komodo-periphery.md create mode 100644 tools/addon/komodo-periphery.sh diff --git a/docs/komodo-periphery.md b/docs/komodo-periphery.md new file mode 100644 index 0000000000..530e9c3b0c --- /dev/null +++ b/docs/komodo-periphery.md @@ -0,0 +1,113 @@ +# Komodo Periphery addon + +Install the native Komodo Periphery agent on an existing Debian or Ubuntu Docker +LXC or VM. It runs under systemd and connects outbound to an existing Komodo Core +v2 server. No Komodo Core or database is installed, no Docker TCP socket is exposed, +and Periphery's inbound server is disabled. + +For a new Docker host, create a Docker LXC with the existing ProxmoxVE Docker +script, then run this addon **inside that LXC**. Periphery manages that host's +Docker containers and Compose stacks; it does not manage Proxmox LXC/VM resources. +Internet access is required for the shared engine and official Komodo releases. + +## Install + +Create a Server Onboarding Key in Komodo Core and run inside the Docker guest: + +```bash +bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/DevScripts/main/tools/addon/komodo-periphery.sh)" +``` + +Enter the Core URL, a unique server name and the onboarding key. Secret input is +masked. Confirm the server's connection status in Komodo Core after installation: +an active systemd service alone does not confirm successful registration. + +For a fork or branch, set the script source explicitly so the generated update +command continues to use it: + +```bash +export COMMUNITY_SCRIPTS_URL=https://raw.githubusercontent.com/YOUR_USER/DevScripts/YOUR_BRANCH +bash -c "$(curl -fsSL "$COMMUNITY_SCRIPTS_URL/tools/addon/komodo-periphery.sh")" +``` + +The same script can be run from a local checkout. Set `COMMUNITY_SCRIPTS_CORE_DIR` +to a local `community-scripts/core` checkout to load the shared helpers locally. +The generated updater downloads its script from `COMMUNITY_SCRIPTS_URL`. + +## Configuration + +| Variable | Meaning | Default | +| --- | --- | --- | +| `var_komodo_core_address` | Reachable Core URL, such as `https://komodo.example.com` or `http://192.168.1.10:9120` | Prompted | +| `var_komodo_server_name` | Server name to register in Core | Guest hostname | +| `var_komodo_onboarding_key` | Server Onboarding Key | Required; prompted interactively | +| `var_komodo_core_public_key` | Optional trusted Core public key | Pin the first Core to `file:/etc/komodo/keys/core.pub` | +| `var_komodo_agent_version` | `latest` or a stable v2 release, with or without `v` | `latest` | + +Supply variables before launching to avoid interaction. HTTPS requires a +certificate trusted by the guest. Core public keys and onboarding keys are +different credentials. The optional public key field allows explicitly pinning +a known Core instead of trusting the first connection. + +Configuration is stored in `/etc/komodo/periphery.config.json` with mode `0600`. +Keys and stack/repository data live in `/etc/komodo`. After successful registration, +the onboarding key can be removed from the configuration and revoked in Core. +Preserve `/etc/komodo/keys` for subsequent authenticated connections. + +The binary is `/opt/komodo-periphery/periphery`. Upstream publishes x86_64 and +aarch64 Linux binaries. ARM64 execution has not been verified by the contributor. +Alpine is not supported by this systemd addon. + +## Updates + +```bash +update_komodo_periphery +``` + +The selected version policy is persisted. To switch to an explicit release, +replace `v2.X.Y` below with a published version compatible with your Core: + +```bash +var_komodo_agent_version=v2.X.Y update_komodo_periphery +``` + +To resume tracking the latest stable v2 release: + +```bash +var_komodo_agent_version=latest update_komodo_periphery +``` + +The addon uses the shared release-check and download helpers. Downloads complete +before the agent is stopped. The previous binary and release cache are backed up +under `/opt/komodo-periphery.backup` and restored if the new agent cannot start. +Configuration, private keys, stacks and repositories are retained. + +The addon updates Periphery only. Use the Docker LXC's existing `update` command +for Docker/system maintenance and Komodo for application container updates. The +addon does not replace an existing guest's `update` command. On a guest dedicated +to Periphery, you can explicitly choose the shorter command: + +```bash +ln -sf /usr/local/bin/update_komodo_periphery /usr/local/bin/update +``` + +Verify `command -v update` resolves to this link before using it. Calling this +alias updates Periphery; it does not update Docker or application containers. + +## Checks and existing installations + +```bash +systemctl status periphery --no-pager +journalctl -u periphery -n 100 --no-pager +docker info +docker compose version +``` + +If Periphery was installed by another method, the addon refuses to overwrite its +configuration or service. An installation with the same binary/config paths as +this addon can use its update path without replacing configuration. Review those +paths before adopting an existing installation. + +Sources: [Komodo setup](https://komo.do/docs/setup/connect-servers), +[upstream systemd installer](https://github.com/moghtech/komodo/blob/main/scripts/setup-periphery.py), +[Periphery configuration](https://github.com/moghtech/komodo/blob/main/config/periphery.config.toml). diff --git a/tools/addon/komodo-periphery.sh b/tools/addon/komodo-periphery.sh new file mode 100644 index 0000000000..696c1006d7 --- /dev/null +++ b/tools/addon/komodo-periphery.sh @@ -0,0 +1,239 @@ +#!/usr/bin/env bash + +# Copyright (c) 2026 community-scripts ORG +# Author: Sofiane A. (soflane) +# License: MIT | https://github.com/community-scripts/DevScripts/raw/main/LICENSE +# Source: https://komo.do/ | https://github.com/moghtech/komodo + +for _cs_file in core/core.func lib/tools.func core/error_handler.func; do + if [[ -n "${COMMUNITY_SCRIPTS_CORE_DIR:-}" && -f "${COMMUNITY_SCRIPTS_CORE_DIR}/${_cs_file}" ]]; then + # shellcheck source=/dev/null + source "${COMMUNITY_SCRIPTS_CORE_DIR}/${_cs_file}" + else + # shellcheck source=/dev/null + source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/${_cs_file}") + fi +done + +APP="Komodo Periphery" +APP_TYPE="addon" +NSAPP="komodo-periphery" +BACKUP_DIR="/opt/komodo-periphery.backup" +INSTALL_PATH="/opt/komodo-periphery" +CONFIG_PATH="/etc/komodo/periphery.config.json" +COMMUNITY_SCRIPTS_URL="${COMMUNITY_SCRIPTS_URL:-https://raw.githubusercontent.com/community-scripts/DevScripts/main}" + +load_functions +set -Eeuo pipefail +trap 'error_handler' ERR +header_info + +if [[ "$EUID" -ne 0 ]]; then + msg_error "Run the Komodo Periphery addon as root inside a Docker LXC or VM." + exit 1 +fi +confirm_not_pve_host +require_debian_like +if [[ ! -d /run/systemd/system ]]; then + msg_error "Komodo Periphery requires a running systemd instance." + exit 238 +fi +case "$(uname -m)" in +x86_64 | aarch64 | arm64) ;; +*) + msg_error "Komodo Periphery supports x86_64 and aarch64 only." + exit 238 + ;; +esac +if ! command -v docker &>/dev/null; then + msg_error "Install Docker first, for example with the Docker LXC script." + exit 237 +fi +ensure_docker +$STD docker info +ensure_dependencies git jq + +var_komodo_agent_version="${var_komodo_agent_version:-$(cat "${INSTALL_PATH}/version-policy" 2>/dev/null || echo latest)}" +release="$var_komodo_agent_version" +if [[ "$release" == "latest" ]]; then + release=$(get_latest_github_release "moghtech/komodo" false) +fi +if [[ ! "$release" =~ ^v?2\.[0-9]+\.[0-9]+$ ]]; then + msg_error "Choose a stable Komodo v2 release compatible with Core using var_komodo_agent_version." + exit 1 +fi +release="v${release#v}" + +function write_update_command() { + local scripts_url core_url update_file + printf -v scripts_url '%q' "$COMMUNITY_SCRIPTS_URL" + printf -v core_url '%q' "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}" + msg_info "Creating Komodo Periphery update command" + update_file=$(mktemp /usr/local/bin/.update_komodo_periphery.XXXXXX) + cat <"$update_file" +#!/usr/bin/env bash +set -Eeuo pipefail +export COMMUNITY_SCRIPTS_URL=${scripts_url} +export COMMUNITY_SCRIPTS_CORE_URL=${core_url} +addon_script=\$(curl -fsSL "\${COMMUNITY_SCRIPTS_URL}/tools/addon/komodo-periphery.sh") +type=update bash -c "\$addon_script" +EOF + chmod 755 "$update_file" + mv -f "$update_file" /usr/local/bin/update_komodo_periphery + cat <"${INSTALL_PATH}/version-policy" +${var_komodo_agent_version} +EOF + chmod 600 "${INSTALL_PATH}/version-policy" + msg_ok "Created Komodo Periphery update command" +} + +function update_periphery() { + if [[ ! -x "${INSTALL_PATH}/periphery" || ! -f "$CONFIG_PATH" ]]; then + msg_error "No Komodo Periphery installation managed by this addon was found." + exit 233 + fi + + local update_status staging_dir + if check_for_gh_release "periphery" "moghtech/komodo" "$release"; then + create_backup "${INSTALL_PATH}/periphery" "$HOME/.periphery" + staging_dir=$(mktemp -d "${INSTALL_PATH}/.download.XXXXXX") + # The release helper caches versions even when the download target is only staging. + if ! FORCE_UPDATE=1 var_appversion="$release" fetch_and_deploy_gh_release \ + "periphery" "moghtech/komodo" "singlefile" "$release" "$staging_dir" \ + "periphery-$(arch_resolve "x86_64" "aarch64")"; then + restore_backup + rm -rf "$staging_dir" + msg_error "Komodo Periphery download failed. The existing service was kept running." + exit 1 + fi + if [[ "$(cat "$HOME/.periphery")" != "${release#v}" ]]; then + restore_backup + rm -rf "$staging_dir" + msg_error "Komodo Periphery download did not match the requested release. Kept the existing agent." + exit 1 + fi + + msg_info "Replacing Komodo Periphery binary" + systemctl stop periphery + if ! command install -m 755 "$staging_dir/periphery" "${INSTALL_PATH}/periphery.new" || + ! mv -f "${INSTALL_PATH}/periphery.new" "${INSTALL_PATH}/periphery"; then + restore_backup + systemctl start periphery + rm -rf "$staging_dir" + msg_error "Could not replace Komodo Periphery. Restored the previous agent." + exit 1 + fi + rm -rf "$staging_dir" + if ! systemctl start periphery || ! sleep 2 || ! systemctl is-active --quiet periphery; then + systemctl stop periphery + restore_backup + systemctl start periphery + msg_error "Komodo Periphery could not start. Restored the previous binary; check journalctl -u periphery." + exit 1 + fi + msg_ok "Replaced Komodo Periphery binary" + rm -rf "$BACKUP_DIR" + else + update_status=$? + if [[ "$update_status" -ne 1 ]]; then + msg_error "Could not check Komodo Periphery releases. The existing agent was kept." + exit "$update_status" + fi + systemctl start periphery + $STD systemctl is-active --quiet periphery + fi + write_update_command + msg_ok "Komodo Periphery update completed" +} + +function install_periphery() { + if [[ -e "$CONFIG_PATH" || -e /etc/komodo/periphery.config.toml || -e /etc/systemd/system/periphery.service ]]; then + msg_error "An existing Periphery configuration or service was found. Keep it and use its existing updater." + exit 233 + fi + var_komodo_core_address=$(prompt_input_required "Komodo Core URL:" "" 120 "var_komodo_core_address") + if [[ -z "$var_komodo_core_address" || "$var_komodo_core_address" == *[[:space:]]* ]]; then + msg_error "A reachable Komodo Core v2 URL without whitespace is required." + exit 1 + fi + var_komodo_server_name=$(prompt_input_required "Komodo server name:" "$(hostname)" 120 "var_komodo_server_name") + if [[ -z "${var_komodo_onboarding_key:-}" && -t 0 ]]; then + read -r -s -p "${TAB3}Komodo Server Onboarding Key: " var_komodo_onboarding_key || true + echo + fi + if [[ -z "${var_komodo_onboarding_key:-}" ]]; then + msg_error "Supply var_komodo_onboarding_key or enter a Server Onboarding Key interactively." + exit 1 + fi + + FORCE_UPDATE=1 var_appversion="$release" fetch_and_deploy_gh_release \ + "periphery" "moghtech/komodo" "singlefile" "$release" "$INSTALL_PATH" \ + "periphery-$(arch_resolve "x86_64" "aarch64")" + if [[ "$(cat "$HOME/.periphery")" != "${release#v}" ]]; then + msg_error "The downloaded Komodo Periphery release did not match the requested version." + exit 1 + fi + + msg_info "Configuring Komodo Periphery" + command install -d -m 700 /etc/komodo /etc/komodo/keys + local config_file + config_file=$(mktemp /etc/komodo/.periphery.config.XXXXXX) + # JSON is an upstream-supported format; jq escapes user-supplied credentials and names. + jq -n \ + --arg address "$var_komodo_core_address" \ + --arg name "$var_komodo_server_name" \ + --arg key "$var_komodo_onboarding_key" \ + --arg core_key "${var_komodo_core_public_key:-file:/etc/komodo/keys/core.pub}" \ + '{root_directory: "/etc/komodo", core_address: $address, connect_as: $name, + onboarding_key: $key, core_public_keys: $core_key, server_enabled: false}' >"$config_file" + chmod 600 "$config_file" + mv -f "$config_file" "$CONFIG_PATH" + unset var_komodo_onboarding_key + msg_ok "Configured Komodo Periphery" + + msg_info "Creating Komodo Periphery service" + cat <<'EOF' >/etc/systemd/system/periphery.service +[Unit] +Description=Komodo Periphery agent +Documentation=https://komo.do/docs/setup/connect-servers +Wants=network-online.target +After=network-online.target docker.service +Requires=docker.service + +[Service] +Type=simple +User=root +Environment=HOME=/root +WorkingDirectory=/etc/komodo +ExecStart=/opt/komodo-periphery/periphery --config-path /etc/komodo/periphery.config.json +Restart=on-failure +RestartSec=5 +UMask=0077 + +[Install] +WantedBy=multi-user.target +EOF + systemctl enable -q --now periphery + sleep 2 + $STD systemctl is-active --quiet periphery + msg_ok "Created Komodo Periphery service" + write_update_command + msg_ok "Confirm the server is connected in Komodo Core. Check journalctl -u periphery if it is not." +} + +case "${type:-}" in +update) + update_periphery + ;; +"" | install) + if [[ -x "${INSTALL_PATH}/periphery" && -f "$CONFIG_PATH" ]]; then + update_periphery + else + install_periphery + fi + ;; +*) + msg_error "Komodo Periphery supports type=install or type=update." + exit 1 + ;; +esac From 879fcb7c5ef34049378ad00d48a671c4d2c3ee2b Mon Sep 17 00:00:00 2001 From: "Sofiane A." Date: Wed, 14 Oct 2026 13:05:48 +0200 Subject: [PATCH 2/3] fix: move Periphery instructions into frontend metadata --- docs/komodo-periphery.md | 113 --------------------------------- json/komodo-periphery.json | 124 +++++++++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+), 113 deletions(-) delete mode 100644 docs/komodo-periphery.md create mode 100644 json/komodo-periphery.json diff --git a/docs/komodo-periphery.md b/docs/komodo-periphery.md deleted file mode 100644 index 530e9c3b0c..0000000000 --- a/docs/komodo-periphery.md +++ /dev/null @@ -1,113 +0,0 @@ -# Komodo Periphery addon - -Install the native Komodo Periphery agent on an existing Debian or Ubuntu Docker -LXC or VM. It runs under systemd and connects outbound to an existing Komodo Core -v2 server. No Komodo Core or database is installed, no Docker TCP socket is exposed, -and Periphery's inbound server is disabled. - -For a new Docker host, create a Docker LXC with the existing ProxmoxVE Docker -script, then run this addon **inside that LXC**. Periphery manages that host's -Docker containers and Compose stacks; it does not manage Proxmox LXC/VM resources. -Internet access is required for the shared engine and official Komodo releases. - -## Install - -Create a Server Onboarding Key in Komodo Core and run inside the Docker guest: - -```bash -bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/DevScripts/main/tools/addon/komodo-periphery.sh)" -``` - -Enter the Core URL, a unique server name and the onboarding key. Secret input is -masked. Confirm the server's connection status in Komodo Core after installation: -an active systemd service alone does not confirm successful registration. - -For a fork or branch, set the script source explicitly so the generated update -command continues to use it: - -```bash -export COMMUNITY_SCRIPTS_URL=https://raw.githubusercontent.com/YOUR_USER/DevScripts/YOUR_BRANCH -bash -c "$(curl -fsSL "$COMMUNITY_SCRIPTS_URL/tools/addon/komodo-periphery.sh")" -``` - -The same script can be run from a local checkout. Set `COMMUNITY_SCRIPTS_CORE_DIR` -to a local `community-scripts/core` checkout to load the shared helpers locally. -The generated updater downloads its script from `COMMUNITY_SCRIPTS_URL`. - -## Configuration - -| Variable | Meaning | Default | -| --- | --- | --- | -| `var_komodo_core_address` | Reachable Core URL, such as `https://komodo.example.com` or `http://192.168.1.10:9120` | Prompted | -| `var_komodo_server_name` | Server name to register in Core | Guest hostname | -| `var_komodo_onboarding_key` | Server Onboarding Key | Required; prompted interactively | -| `var_komodo_core_public_key` | Optional trusted Core public key | Pin the first Core to `file:/etc/komodo/keys/core.pub` | -| `var_komodo_agent_version` | `latest` or a stable v2 release, with or without `v` | `latest` | - -Supply variables before launching to avoid interaction. HTTPS requires a -certificate trusted by the guest. Core public keys and onboarding keys are -different credentials. The optional public key field allows explicitly pinning -a known Core instead of trusting the first connection. - -Configuration is stored in `/etc/komodo/periphery.config.json` with mode `0600`. -Keys and stack/repository data live in `/etc/komodo`. After successful registration, -the onboarding key can be removed from the configuration and revoked in Core. -Preserve `/etc/komodo/keys` for subsequent authenticated connections. - -The binary is `/opt/komodo-periphery/periphery`. Upstream publishes x86_64 and -aarch64 Linux binaries. ARM64 execution has not been verified by the contributor. -Alpine is not supported by this systemd addon. - -## Updates - -```bash -update_komodo_periphery -``` - -The selected version policy is persisted. To switch to an explicit release, -replace `v2.X.Y` below with a published version compatible with your Core: - -```bash -var_komodo_agent_version=v2.X.Y update_komodo_periphery -``` - -To resume tracking the latest stable v2 release: - -```bash -var_komodo_agent_version=latest update_komodo_periphery -``` - -The addon uses the shared release-check and download helpers. Downloads complete -before the agent is stopped. The previous binary and release cache are backed up -under `/opt/komodo-periphery.backup` and restored if the new agent cannot start. -Configuration, private keys, stacks and repositories are retained. - -The addon updates Periphery only. Use the Docker LXC's existing `update` command -for Docker/system maintenance and Komodo for application container updates. The -addon does not replace an existing guest's `update` command. On a guest dedicated -to Periphery, you can explicitly choose the shorter command: - -```bash -ln -sf /usr/local/bin/update_komodo_periphery /usr/local/bin/update -``` - -Verify `command -v update` resolves to this link before using it. Calling this -alias updates Periphery; it does not update Docker or application containers. - -## Checks and existing installations - -```bash -systemctl status periphery --no-pager -journalctl -u periphery -n 100 --no-pager -docker info -docker compose version -``` - -If Periphery was installed by another method, the addon refuses to overwrite its -configuration or service. An installation with the same binary/config paths as -this addon can use its update path without replacing configuration. Review those -paths before adopting an existing installation. - -Sources: [Komodo setup](https://komo.do/docs/setup/connect-servers), -[upstream systemd installer](https://github.com/moghtech/komodo/blob/main/scripts/setup-periphery.py), -[Periphery configuration](https://github.com/moghtech/komodo/blob/main/config/periphery.config.toml). diff --git a/json/komodo-periphery.json b/json/komodo-periphery.json new file mode 100644 index 0000000000..bafc7478e6 --- /dev/null +++ b/json/komodo-periphery.json @@ -0,0 +1,124 @@ +{ + "name": "Komodo Periphery", + "slug": "komodo-periphery", + "categories": [ + 3 + ], + "date_created": "2026-10-14", + "type": "addon", + "updateable": true, + "privileged": false, + "architectures": [ + "amd64", + "arm64" + ], + "platforms": [ + "pve" + ], + "interface_port": null, + "documentation": "https://komo.do/docs/setup/connect-servers", + "website": "https://komo.do/", + "repository": "https://github.com/moghtech/komodo", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/komodo.webp", + "description": "Komodo Periphery is the agent that connects a Docker host to an existing Komodo Core server for centralized container and Compose stack management. This addon installs the official native Linux binary as a systemd service and uses outbound authentication. It does not install Komodo Core, a database, or Docker.", + "install_methods": [ + { + "type": "default", + "script": "tools/addon/komodo-periphery.sh", + "config_path": "/etc/komodo/periphery.config.json", + "resources": { + "cpu": null, + "ram": null, + "hdd": null, + "os": null, + "version": null + } + } + ], + "default_credentials": { + "username": null, + "password": null + }, + "app_vars": [ + { + "name": "var_komodo_core_address", + "label": "Komodo Core URL", + "type": "text", + "required": true, + "help": "A Core v2 URL reachable from the guest, such as https://komodo.example.com or http://192.168.1.10:9120. HTTPS requires a certificate trusted by the guest." + }, + { + "name": "var_komodo_server_name", + "label": "Komodo Server Name", + "type": "text", + "help": "A unique server name to register in Core. Defaults to the guest hostname when omitted." + }, + { + "name": "var_komodo_onboarding_key", + "label": "Server Onboarding Key", + "type": "password", + "secret": true, + "required": true, + "help": "Create a Server Onboarding Key in Komodo Core before installation. It is different from the Core public key." + }, + { + "name": "var_komodo_core_public_key", + "label": "Core Public Key", + "type": "text", + "help": "Optional explicit Core public-key pin. By default, the first Core is trusted and its public key is stored in /etc/komodo/keys/core.pub." + }, + { + "name": "var_komodo_agent_version", + "label": "Periphery Version", + "type": "text", + "default": "latest", + "help": "Use latest or a published stable v2 release compatible with your Core, with or without the v prefix. The selected policy is retained for subsequent updates." + } + ], + "notes": [ + { + "text": "Run this addon as root inside an existing Debian or Ubuntu Docker LXC or VM, with Docker Compose available. For a new host, first create a Docker LXC using the existing Docker script. Alpine is not supported by this systemd addon.", + "type": "info" + }, + { + "text": "The installer asks for the Core URL, a server name and an onboarding key; secret input is masked. Supply the corresponding var_komodo_* variables before launching for unattended installation. Confirm that the server is connected in Komodo Core after installation: a running systemd service alone does not confirm registration.", + "type": "info" + }, + { + "text": "Periphery connects outbound to Core. Its inbound server is disabled, so there is no Periphery web interface or listener on port 8120. The Docker socket stays local. Periphery manages this guest's Docker containers and stacks, not Proxmox LXC or VM resources.", + "type": "info" + }, + { + "text": "By default, the first Core public key is pinned in /etc/komodo/keys/core.pub. Use var_komodo_core_public_key to trust a known Core key from the start. The onboarding key can be removed from the configuration and revoked in Core after successful registration; preserve the private keys for later connections.", + "type": "info" + }, + { + "text": "Configuration is stored in /etc/komodo/periphery.config.json with root-only permissions. Keys, repositories and stack data live under /etc/komodo. The native binary is /opt/komodo-periphery/periphery. Updates retain the configuration, keys and data.", + "type": "info" + }, + { + "text": "Update the agent with update_komodo_periphery, or rerun the addon. To select a version, run var_komodo_agent_version=v2.X.Y update_komodo_periphery, replacing v2.X.Y with a published release compatible with Core. Use var_komodo_agent_version=latest update_komodo_periphery to resume tracking the latest stable v2 release. The choice is persisted.", + "type": "info" + }, + { + "text": "Downloads finish before the agent is stopped. The previous binary and release cache are backed up under /opt/komodo-periphery.backup and restored if replacement or startup fails. To troubleshoot, run systemctl status periphery --no-pager and journalctl -u periphery -n 100 --no-pager.", + "type": "info" + }, + { + "text": "The addon updates Periphery only. Existing guest update commands are retained for Docker/system maintenance, and application container updates remain managed in Komodo. On a guest dedicated to Periphery, you can choose the shorter command with ln -sf /usr/local/bin/update_komodo_periphery /usr/local/bin/update; verify command -v update resolves to this link.", + "type": "info" + }, + { + "text": "For a fork or test branch, export COMMUNITY_SCRIPTS_URL=https://raw.githubusercontent.com/YOUR_USER/DevScripts/YOUR_BRANCH before running the addon from that URL. The generated updater retains this source. The addon can also run from a local checkout; COMMUNITY_SCRIPTS_CORE_DIR can point to a local community-scripts/core checkout.", + "type": "info" + }, + { + "text": "The addon refuses to overwrite a Periphery configuration or service installed by another method. An installation already using /opt/komodo-periphery/periphery and /etc/komodo/periphery.config.json can enter update mode without replacing configuration; review those paths before adopting it.", + "type": "info" + }, + { + "text": "Upstream publishes x86_64 and aarch64 Linux binaries. ARM64 asset selection was verified, but ARM64 execution has not been tested by the contributor.", + "type": "warning" + } + ] +} From 131c1c08244aab1e05ff7bfa845d302bc26c5b34 Mon Sep 17 00:00:00 2001 From: "Sofiane A." Date: Wed, 14 Oct 2026 17:21:37 +0200 Subject: [PATCH 3/3] feat(ct): add Komodo Periphery LXC creation and simplify native addon --- ct/komodo-periphery.sh | 91 ++++++++++ install/komodo-periphery-install.sh | 36 ++++ json/komodo-periphery.json | 71 ++------ tools/addon/komodo-periphery.sh | 258 +++++++++++++--------------- 4 files changed, 259 insertions(+), 197 deletions(-) create mode 100644 ct/komodo-periphery.sh create mode 100644 install/komodo-periphery-install.sh diff --git a/ct/komodo-periphery.sh b/ct/komodo-periphery.sh new file mode 100644 index 0000000000..52cc5e0f71 --- /dev/null +++ b/ct/komodo-periphery.sh @@ -0,0 +1,91 @@ +#!/usr/bin/env bash +_CS_DEFAULT_URL="https://raw.githubusercontent.com/community-scripts/DevScripts/main" +_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func" +# shellcheck source=/dev/null +source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func") + +# Copyright (c) 2026 community-scripts ORG +# Author: Sofiane A. (soflane) +# License: MIT | https://github.com/community-scripts/DevScripts/raw/main/LICENSE +# Source: https://komo.do/ | https://github.com/moghtech/komodo + +APP="Komodo-Periphery" +var_tags="${var_tags:-docker;komodo}" +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}" +#var_arm64="${var_arm64:-no}" # unset = ask the user; set yes/no only when verified + +export var_komodo_core_address="${var_komodo_core_address:-}" +export var_komodo_server_name="${var_komodo_server_name:-}" +export var_komodo_onboarding_key="${var_komodo_onboarding_key:-}" +export var_komodo_core_public_key="${var_komodo_core_public_key:-}" + +header_info "$APP" +variables +color +catch_errors + +function update_script() { + header_info + check_container_storage + check_container_resources + if [[ ! -x /opt/komodo-periphery/periphery || ! -f /etc/komodo/periphery.config.json ]]; then + msg_error "No Komodo Periphery installation found!" + exit 233 + fi + + if ! var_komodo_addon_script="$(_cs_fetch_text "tools/addon/komodo-periphery.sh")" || + [[ -z "$var_komodo_addon_script" ]]; then + msg_error "Could not load the Komodo Periphery addon." + exit 115 + fi + mkdir -p /usr/local/lib/komodo-periphery + addon_file=$(mktemp /usr/local/lib/komodo-periphery/.addon.XXXXXX) + cat <"$addon_file" +$var_komodo_addon_script +EOF + chmod 755 "$addon_file" + mv -f "$addon_file" /usr/local/lib/komodo-periphery/addon.sh + type=update bash /usr/local/lib/komodo-periphery/addon.sh + exit +} + +if on_pve_host; then + root_check + if is_unattended && [[ -z "$var_komodo_core_address" || -z "$var_komodo_onboarding_key" ]]; then + msg_error "Supply var_komodo_core_address and var_komodo_onboarding_key before creating the Komodo Periphery LXC." + exit 1 + fi + var_komodo_core_address=$(prompt_input_required "Komodo Core URL:" "" 120 "var_komodo_core_address") + if [[ ! "$var_komodo_core_address" =~ ^https?://[^[:space:]/]+(/[^[:space:]]*)?$ ]]; then + msg_error "Komodo Periphery requires an HTTP or HTTPS Core URL without whitespace." + exit 1 + fi + if [[ -z "$var_komodo_onboarding_key" ]] && ! is_unattended; then + read -r -s -p "${TAB3}Komodo Server Onboarding Key: " var_komodo_onboarding_key /usr/local/lib/komodo-periphery/addon.sh +$var_komodo_addon_script +EOF +chmod 755 /usr/local/lib/komodo-periphery/addon.sh +msg_ok "Prepared Komodo Periphery installer" + +# The CT creation wizard authorizes Docker installation in this new guest. +var_komodo_setup_docker=yes bash /usr/local/lib/komodo-periphery/addon.sh +unset var_komodo_addon_script var_komodo_onboarding_key + +motd_ssh +customize +cleanup_lxc diff --git a/json/komodo-periphery.json b/json/komodo-periphery.json index bafc7478e6..02cac06102 100644 --- a/json/komodo-periphery.json +++ b/json/komodo-periphery.json @@ -5,13 +5,9 @@ 3 ], "date_created": "2026-10-14", - "type": "addon", + "type": "ct", "updateable": true, "privileged": false, - "architectures": [ - "amd64", - "arm64" - ], "platforms": [ "pve" ], @@ -20,18 +16,18 @@ "website": "https://komo.do/", "repository": "https://github.com/moghtech/komodo", "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/komodo.webp", - "description": "Komodo Periphery is the agent that connects a Docker host to an existing Komodo Core server for centralized container and Compose stack management. This addon installs the official native Linux binary as a systemd service and uses outbound authentication. It does not install Komodo Core, a database, or Docker.", + "description": "A Docker LXC with the native Komodo Periphery agent, connecting to an existing Core for centralized container and Compose stack management.", "install_methods": [ { "type": "default", - "script": "tools/addon/komodo-periphery.sh", + "script": "ct/komodo-periphery.sh", "config_path": "/etc/komodo/periphery.config.json", "resources": { - "cpu": null, - "ram": null, - "hdd": null, - "os": null, - "version": null + "cpu": 2, + "ram": 2048, + "hdd": 8, + "os": "Debian", + "version": "13" } } ], @@ -45,13 +41,13 @@ "label": "Komodo Core URL", "type": "text", "required": true, - "help": "A Core v2 URL reachable from the guest, such as https://komodo.example.com or http://192.168.1.10:9120. HTTPS requires a certificate trusted by the guest." + "help": "Reachable HTTP or HTTPS Core URL, such as https://komodo.example.com." }, { "name": "var_komodo_server_name", "label": "Komodo Server Name", "type": "text", - "help": "A unique server name to register in Core. Defaults to the guest hostname when omitted." + "help": "Server name in Core; defaults to the guest hostname." }, { "name": "var_komodo_onboarding_key", @@ -59,65 +55,30 @@ "type": "password", "secret": true, "required": true, - "help": "Create a Server Onboarding Key in Komodo Core before installation. It is different from the Core public key." + "help": "Create a Server Onboarding Key in Komodo Core before installation." }, { "name": "var_komodo_core_public_key", "label": "Core Public Key", "type": "text", - "help": "Optional explicit Core public-key pin. By default, the first Core is trusted and its public key is stored in /etc/komodo/keys/core.pub." - }, - { - "name": "var_komodo_agent_version", - "label": "Periphery Version", - "type": "text", - "default": "latest", - "help": "Use latest or a published stable v2 release compatible with your Core, with or without the v prefix. The selected policy is retained for subsequent updates." + "help": "Optional Core public key; defaults to trusting and pinning the first Core in /etc/komodo/keys/core.pub." } ], "notes": [ { - "text": "Run this addon as root inside an existing Debian or Ubuntu Docker LXC or VM, with Docker Compose available. For a new host, first create a Docker LXC using the existing Docker script. Alpine is not supported by this systemd addon.", - "type": "info" - }, - { - "text": "The installer asks for the Core URL, a server name and an onboarding key; secret input is masked. Supply the corresponding var_komodo_* variables before launching for unattended installation. Confirm that the server is connected in Komodo Core after installation: a running systemd service alone does not confirm registration.", - "type": "info" - }, - { - "text": "Periphery connects outbound to Core. Its inbound server is disabled, so there is no Periphery web interface or listener on port 8120. The Docker socket stays local. Periphery manages this guest's Docker containers and stacks, not Proxmox LXC or VM resources.", - "type": "info" - }, - { - "text": "By default, the first Core public key is pinned in /etc/komodo/keys/core.pub. Use var_komodo_core_public_key to trust a known Core key from the start. The onboarding key can be removed from the configuration and revoked in Core after successful registration; preserve the private keys for later connections.", - "type": "info" - }, - { - "text": "Configuration is stored in /etc/komodo/periphery.config.json with root-only permissions. Keys, repositories and stack data live under /etc/komodo. The native binary is /opt/komodo-periphery/periphery. Updates retain the configuration, keys and data.", - "type": "info" - }, - { - "text": "Update the agent with update_komodo_periphery, or rerun the addon. To select a version, run var_komodo_agent_version=v2.X.Y update_komodo_periphery, replacing v2.X.Y with a published release compatible with Core. Use var_komodo_agent_version=latest update_komodo_periphery to resume tracking the latest stable v2 release. The choice is persisted.", - "type": "info" - }, - { - "text": "Downloads finish before the agent is stopped. The previous binary and release cache are backed up under /opt/komodo-periphery.backup and restored if replacement or startup fails. To troubleshoot, run systemctl status periphery --no-pager and journalctl -u periphery -n 100 --no-pager.", - "type": "info" - }, - { - "text": "The addon updates Periphery only. Existing guest update commands are retained for Docker/system maintenance, and application container updates remain managed in Komodo. On a guest dedicated to Periphery, you can choose the shorter command with ln -sf /usr/local/bin/update_komodo_periphery /usr/local/bin/update; verify command -v update resolves to this link.", + "text": "Run the CT creator on Proxmox VE. It creates a Debian LXC, installs Docker/Compose and runs Periphery natively under systemd.", "type": "info" }, { - "text": "For a fork or test branch, export COMMUNITY_SCRIPTS_URL=https://raw.githubusercontent.com/YOUR_USER/DevScripts/YOUR_BRANCH before running the addon from that URL. The generated updater retains this source. The addon can also run from a local checkout; COMMUNITY_SCRIPTS_CORE_DIR can point to a local community-scripts/core checkout.", + "text": "Create an onboarding key in Core before installation, then confirm the server is connected. See the linked documentation for onboarding and authentication.", "type": "info" }, { - "text": "The addon refuses to overwrite a Periphery configuration or service installed by another method. An installation already using /opt/komodo-periphery/periphery and /etc/komodo/periphery.config.json can enter update mode without replacing configuration; review those paths before adopting it.", + "text": "Run update_komodo_periphery for the latest stable agent. Configuration, keys and stack data are retained under /etc/komodo; the guest's existing update command is preserved.", "type": "info" }, { - "text": "Upstream publishes x86_64 and aarch64 Linux binaries. ARM64 asset selection was verified, but ARM64 execution has not been tested by the contributor.", + "text": "ARM64 has not been tested. The installer asks for confirmation before attempting it.", "type": "warning" } ] diff --git a/tools/addon/komodo-periphery.sh b/tools/addon/komodo-periphery.sh index 696c1006d7..d309629725 100644 --- a/tools/addon/komodo-periphery.sh +++ b/tools/addon/komodo-periphery.sh @@ -16,169 +16,139 @@ for _cs_file in core/core.func lib/tools.func core/error_handler.func; do done APP="Komodo Periphery" -APP_TYPE="addon" +export APP_TYPE="addon" NSAPP="komodo-periphery" -BACKUP_DIR="/opt/komodo-periphery.backup" +BACKUP_DIR="/opt/${NSAPP}.backup" INSTALL_PATH="/opt/komodo-periphery" CONFIG_PATH="/etc/komodo/periphery.config.json" COMMUNITY_SCRIPTS_URL="${COMMUNITY_SCRIPTS_URL:-https://raw.githubusercontent.com/community-scripts/DevScripts/main}" load_functions -set -Eeuo pipefail -trap 'error_handler' ERR -header_info +catch_errors +header_info "$APP" -if [[ "$EUID" -ne 0 ]]; then - msg_error "Run the Komodo Periphery addon as root inside a Docker LXC or VM." - exit 1 +root_check +if on_pve_host; then + msg_error "Run the Komodo Periphery addon inside an LXC or VM, not on the Proxmox VE host." + exit 232 fi -confirm_not_pve_host require_debian_like if [[ ! -d /run/systemd/system ]]; then msg_error "Komodo Periphery requires a running systemd instance." exit 238 fi -case "$(uname -m)" in -x86_64 | aarch64 | arm64) ;; +arch_check + +case "${type:-install}" in +install | update) ;; *) - msg_error "Komodo Periphery supports x86_64 and aarch64 only." - exit 238 + msg_error "Komodo Periphery supports type=install or type=update." + exit 1 ;; esac -if ! command -v docker &>/dev/null; then - msg_error "Install Docker first, for example with the Docker LXC script." - exit 237 -fi -ensure_docker -$STD docker info -ensure_dependencies git jq -var_komodo_agent_version="${var_komodo_agent_version:-$(cat "${INSTALL_PATH}/version-policy" 2>/dev/null || echo latest)}" -release="$var_komodo_agent_version" -if [[ "$release" == "latest" ]]; then - release=$(get_latest_github_release "moghtech/komodo" false) +if [[ -x "${INSTALL_PATH}/periphery" && -f "$CONFIG_PATH" && -f /etc/systemd/system/periphery.service ]] && + grep -qxF "ExecStart=${INSTALL_PATH}/periphery --config-path ${CONFIG_PATH}" /etc/systemd/system/periphery.service; then + type=update +elif [[ "${type:-}" == "update" || -e "$INSTALL_PATH" || -e "$CONFIG_PATH" || + -e /etc/komodo/periphery.config.toml || -e /etc/komodo/keys/periphery.key || + -e /etc/systemd/system/periphery.service ]]; then + msg_error "Komodo Periphery installation is missing, incomplete or managed by another installer." + exit 233 +else + type=install fi -if [[ ! "$release" =~ ^v?2\.[0-9]+\.[0-9]+$ ]]; then - msg_error "Choose a stable Komodo v2 release compatible with Core using var_komodo_agent_version." - exit 1 -fi -release="v${release#v}" - -function write_update_command() { - local scripts_url core_url update_file - printf -v scripts_url '%q' "$COMMUNITY_SCRIPTS_URL" - printf -v core_url '%q' "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}" - msg_info "Creating Komodo Periphery update command" - update_file=$(mktemp /usr/local/bin/.update_komodo_periphery.XXXXXX) - cat <"$update_file" -#!/usr/bin/env bash -set -Eeuo pipefail -export COMMUNITY_SCRIPTS_URL=${scripts_url} -export COMMUNITY_SCRIPTS_CORE_URL=${core_url} -addon_script=\$(curl -fsSL "\${COMMUNITY_SCRIPTS_URL}/tools/addon/komodo-periphery.sh") -type=update bash -c "\$addon_script" -EOF - chmod 755 "$update_file" - mv -f "$update_file" /usr/local/bin/update_komodo_periphery - cat <"${INSTALL_PATH}/version-policy" -${var_komodo_agent_version} -EOF - chmod 600 "${INSTALL_PATH}/version-policy" - msg_ok "Created Komodo Periphery update command" -} -function update_periphery() { - if [[ ! -x "${INSTALL_PATH}/periphery" || ! -f "$CONFIG_PATH" ]]; then - msg_error "No Komodo Periphery installation managed by this addon was found." - exit 233 +if [[ "$type" == "install" ]]; then + if is_unattended && [[ -z "${var_komodo_core_address:-}" || -z "${var_komodo_onboarding_key:-}" ]]; then + msg_error "Supply var_komodo_core_address and var_komodo_onboarding_key for unattended Komodo Periphery installation." + exit 1 + fi + var_komodo_core_address=$(prompt_input_required "Komodo Core URL:" "" 120 "var_komodo_core_address") + if [[ ! "$var_komodo_core_address" =~ ^https?://[^[:space:]/]+(/[^[:space:]]*)?$ ]]; then + msg_error "Komodo Periphery requires an HTTP or HTTPS Core URL without whitespace." + exit 1 + fi + var_komodo_server_name=$(prompt_input_required "Komodo server name:" "$(hostname)" 120 "var_komodo_server_name") + if [[ -z "${var_komodo_onboarding_key:-}" ]] && ! is_unattended; then + read -r -s -p "${TAB3}Komodo Server Onboarding Key: " var_komodo_onboarding_key "$update_file" +#!/usr/bin/env bash +set -Eeuo pipefail +export COMMUNITY_SCRIPTS_URL=${scripts_url} +export COMMUNITY_SCRIPTS_CORE_URL=${core_url} +if [[ -f /usr/local/lib/komodo-periphery/addon.sh ]]; then + type=update bash /usr/local/lib/komodo-periphery/addon.sh +else + addon_script=\$(curl -fsSL "\$COMMUNITY_SCRIPTS_URL/tools/addon/komodo-periphery.sh") + type=update bash -c "\$addon_script" +fi +EOF +chmod 755 "$update_file" +mv -f "$update_file" /usr/local/bin/update_komodo_periphery +rm -f "${INSTALL_PATH}/version-policy" +msg_ok "Created Komodo Periphery update command" +msg_ok "Komodo Periphery setup completed" +echo -e "${INFO}Confirm the server connection in Komodo Core; check journalctl -u periphery if needed."