From 255eea5afc5259da1e829031910b59b4695f266f Mon Sep 17 00:00:00 2001 From: igorpecovnik <6281704+igorpecovnik@users.noreply.github.com> Date: Sat, 3 May 2025 08:28:16 +0000 Subject: [PATCH] `Automatic` documentation update --- docs/User-Guide_Armbian-Software/Armbian.md | 124 ++++++++++++++ docs/User-Guide_Armbian-Software/DevTools.md | 39 ----- docs/User-Guide_Armbian-Software/Software.md | 160 ++++++++++++++----- docs/images/ART001.png | Bin 0 -> 4427 bytes docs/images/GHR001.png | Bin 0 -> 11385 bytes 5 files changed, 245 insertions(+), 78 deletions(-) create mode 100644 docs/User-Guide_Armbian-Software/Armbian.md create mode 100644 docs/images/ART001.png create mode 100644 docs/images/GHR001.png diff --git a/docs/User-Guide_Armbian-Software/Armbian.md b/docs/User-Guide_Armbian-Software/Armbian.md new file mode 100644 index 00000000..7dad6f65 --- /dev/null +++ b/docs/User-Guide_Armbian-Software/Armbian.md @@ -0,0 +1,124 @@ +--- +comments: true +--- + +# Armbian infrastructure services + +## CDN router + + +Router for repository mirror automation + + + +[![CDN router](/images/ART001.png)](#) + + + + +The Armbian Router is an intelligent redirector system that optimizes file downloads by automatically directing users to the best available mirror. It evaluates each download request based on geographic location, server health, and file availability, ensuring faster downloads, balanced load distribution, and high availability. This core service underpins Armbian's scalable mirror network, seamlessly routing traffic to improve performance and reliability for end users worldwide. + + + +**Author:** @efectn + +**Status:** Stable + + +~~~ custombash +armbian-config --cmd ART001 +~~~ + + +~~~ bash title="Remove CDN router:" +armbian-config --cmd ART002 +~~~ + + + +## GH runners + + +GitHub runners for Armbian automation + + + +[![GH runners](/images/GHR001.png)](#) + + + + +This module automates the installation, removal, and status checking of GitHub self-hosted runners for the Armbian project. It supports batch operations and user input through dialog prompts when running interactively. + + + +**Author:** @efectn + +**Status:** Stable + + +~~~ custombash +armbian-config --cmd GHR001 +~~~ + + + +=== "Supported Commands" + +- **`install`** + Installs one or more GitHub runners using the provided configuration or interactively prompted values. + +- **`purge` / `remove`** + Removes runners based on the provided runner name series and target organization or repository. + +- **`status`** + Quietly checks if any `actions.runner` services are currently running on the system. + +=== "Available Switches" + +| Switch | Description | +|--------------------|-----------------------------------------------------------------------------| +| `gh_token` | GitHub token with admin rights to manage self-hosted runners. | +| `runner_name` | Name prefix for the runner series (default: `armbian`). | +| `start` | Start index of the runner series (e.g., `01`). | +| `stop` | End index of the runner series (e.g., `05`). | +| `label_primary` | Labels for the first runner (default: `alfa`). | +| `label_secondary` | Labels for additional runners (default: `fast,images`). | +| `organisation` | GitHub organization name (default: `armbian`). | +| `owner` | GitHub user or organization owner (used for repo-level runners). | +| `repository` | GitHub repository name (used for repo-level runners). | + +=== "Behavior" + +- Prompts the user for missing switches via `dialog` **only in interactive mode**. +- Supports bulk installation of runners using sequential numbering (`start` to `stop`). +- Calls internal `actions.runner.install` and `actions.runner.remove` helpers. +- Returns `0` if any runner services are active, `1` otherwise (for scripting use). +- Suppresses errors and outputs when checking status to remain quiet in background use. + + + + +~~~ bash title="Remove GitHub runners for Armbian automation:" +armbian-config --cmd GHR002 +~~~ + + + +## Rsyncd server + +**Author:** @igorpecovnik + +**Status:** Stable + + +~~~ custombash +armbian-config --cmd RSD001 +~~~ + + +~~~ bash title="Remove Armbian rsyncd server:" +armbian-config --cmd RSD002 +~~~ + + diff --git a/docs/User-Guide_Armbian-Software/DevTools.md b/docs/User-Guide_Armbian-Software/DevTools.md index dca45b78..eb395a3c 100644 --- a/docs/User-Guide_Armbian-Software/DevTools.md +++ b/docs/User-Guide_Armbian-Software/DevTools.md @@ -24,42 +24,3 @@ armbian-config --cmd GIT002 ~~~ - -## Armbian CDN router - - -Armbian router for repository mirror automation - -**Author:** @efectn - -**Status:** Stable - - -~~~ custombash -armbian-config --cmd ART001 -~~~ - - -~~~ bash title="Remove Armbian router:" -armbian-config --cmd ART002 -~~~ - - - -## Armbian rsyncd server - -**Author:** @igorpecovnik - -**Status:** Stable - - -~~~ custombash -armbian-config --cmd RSD001 -~~~ - - -~~~ bash title="Remove Armbian rsyncd server:" -armbian-config --cmd RSD002 -~~~ - - diff --git a/docs/User-Guide_Armbian-Software/Software.md b/docs/User-Guide_Armbian-Software/Software.md index 1f5de434..023e9e52 100644 --- a/docs/User-Guide_Armbian-Software/Software.md +++ b/docs/User-Guide_Armbian-Software/Software.md @@ -1614,6 +1614,127 @@ armbian-config --cmd MYA003 +## Armbian infrastructure services + +#### CDN router + + +Router for repository mirror automation + + + +[![CDN router](/images/ART001.png)](#) + + + + +The Armbian Router is an intelligent redirector system that optimizes file downloads by automatically directing users to the best available mirror. It evaluates each download request based on geographic location, server health, and file availability, ensuring faster downloads, balanced load distribution, and high availability. This core service underpins Armbian's scalable mirror network, seamlessly routing traffic to improve performance and reliability for end users worldwide. + + + +**Author:** @efectn + +**Status:** Stable + + +~~~ custombash +armbian-config --cmd ART001 +~~~ + + +~~~ bash title="Remove CDN router:" +armbian-config --cmd ART002 +~~~ + + + +#### GH runners + + +GitHub runners for Armbian automation + + + +[![GH runners](/images/GHR001.png)](#) + + + + +This module automates the installation, removal, and status checking of GitHub self-hosted runners for the Armbian project. It supports batch operations and user input through dialog prompts when running interactively. + + + +**Author:** @efectn + +**Status:** Stable + + +~~~ custombash +armbian-config --cmd GHR001 +~~~ + + + +=== "Supported Commands" + +- **`install`** + Installs one or more GitHub runners using the provided configuration or interactively prompted values. + +- **`purge` / `remove`** + Removes runners based on the provided runner name series and target organization or repository. + +- **`status`** + Quietly checks if any `actions.runner` services are currently running on the system. + +=== "Available Switches" + +| Switch | Description | +|--------------------|-----------------------------------------------------------------------------| +| `gh_token` | GitHub token with admin rights to manage self-hosted runners. | +| `runner_name` | Name prefix for the runner series (default: `armbian`). | +| `start` | Start index of the runner series (e.g., `01`). | +| `stop` | End index of the runner series (e.g., `05`). | +| `label_primary` | Labels for the first runner (default: `alfa`). | +| `label_secondary` | Labels for additional runners (default: `fast,images`). | +| `organisation` | GitHub organization name (default: `armbian`). | +| `owner` | GitHub user or organization owner (used for repo-level runners). | +| `repository` | GitHub repository name (used for repo-level runners). | + +=== "Behavior" + +- Prompts the user for missing switches via `dialog` **only in interactive mode**. +- Supports bulk installation of runners using sequential numbering (`start` to `stop`). +- Calls internal `actions.runner.install` and `actions.runner.remove` helpers. +- Returns `0` if any runner services are active, `1` otherwise (for scripting use). +- Suppresses errors and outputs when checking status to remain quiet in background use. + + + + +~~~ bash title="Remove GitHub runners for Armbian automation:" +armbian-config --cmd GHR002 +~~~ + + + +#### Rsyncd server + +**Author:** @igorpecovnik + +**Status:** Stable + + +~~~ custombash +armbian-config --cmd RSD001 +~~~ + + +~~~ bash title="Remove Armbian rsyncd server:" +armbian-config --cmd RSD002 +~~~ + + + ## Applications and tools for development #### Git CLI @@ -1637,45 +1758,6 @@ armbian-config --cmd GIT002 -#### Armbian CDN router - - -Armbian router for repository mirror automation - -**Author:** @efectn - -**Status:** Stable - - -~~~ custombash -armbian-config --cmd ART001 -~~~ - - -~~~ bash title="Remove Armbian router:" -armbian-config --cmd ART002 -~~~ - - - -#### Armbian rsyncd server - -**Author:** @igorpecovnik - -**Status:** Stable - - -~~~ custombash -armbian-config --cmd RSD001 -~~~ - - -~~~ bash title="Remove Armbian rsyncd server:" -armbian-config --cmd RSD002 -~~~ - - - ## Docker containerization and KVM virtual machines #### Docker diff --git a/docs/images/ART001.png b/docs/images/ART001.png new file mode 100644 index 0000000000000000000000000000000000000000..d4e966d4943815c966fadc73d6baeaefed2875ea GIT binary patch literal 4427 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 literal 0 HcmV?d00001 diff --git a/docs/images/GHR001.png b/docs/images/GHR001.png new file mode 100644 index 0000000000000000000000000000000000000000..10fd031c509a6eff14c8ba4222de1eaf4966ab4f GIT binary patch literal 11385 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 a)|tYpI^X