mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2026-02-25 14:35:56 +01:00
Compare commits
12 Commits
2026-02-23
...
add-script
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e653ae11e6 | ||
|
|
9eb0bc9aa0 | ||
|
|
72eb8b9575 | ||
|
|
65a67347bd | ||
|
|
25d54ff69a | ||
|
|
5c85c5098e | ||
|
|
7b8080438d | ||
|
|
2041371a04 | ||
|
|
b172301e0f | ||
|
|
4b6cb1601b | ||
|
|
d9f766cca6 | ||
|
|
a4973fa3b7 |
111
.github/workflows/stale_pr_close.yml
generated
vendored
Normal file
111
.github/workflows/stale_pr_close.yml
generated
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
name: Stale PR Management
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0 * * *"
|
||||
workflow_dispatch:
|
||||
pull_request_target:
|
||||
types:
|
||||
- labeled
|
||||
|
||||
jobs:
|
||||
stale-prs:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
pull-requests: write
|
||||
issues: write
|
||||
contents: read
|
||||
steps:
|
||||
- name: Handle stale PRs
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const now = new Date();
|
||||
const owner = context.repo.owner;
|
||||
const repo = context.repo.repo;
|
||||
|
||||
// --- When stale label is added, comment immediately ---
|
||||
if (context.eventName === "pull_request_target" && context.payload.action === "labeled") {
|
||||
const label = context.payload.label?.name;
|
||||
if (label === "stale") {
|
||||
const author = context.payload.pull_request.user.login;
|
||||
await github.rest.issues.createComment({
|
||||
owner,
|
||||
repo,
|
||||
issue_number: context.payload.pull_request.number,
|
||||
body: `@${author} This PR has been marked as stale. It will be closed if no new commits are added in 7 days.`
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// --- Scheduled run: check all stale PRs ---
|
||||
const { data: prs } = await github.rest.pulls.list({
|
||||
owner,
|
||||
repo,
|
||||
state: "open",
|
||||
per_page: 100
|
||||
});
|
||||
|
||||
for (const pr of prs) {
|
||||
const hasStale = pr.labels.some(l => l.name === "stale");
|
||||
if (!hasStale) continue;
|
||||
|
||||
// Get timeline events to find when stale label was added
|
||||
const { data: events } = await github.rest.issues.listEvents({
|
||||
owner,
|
||||
repo,
|
||||
issue_number: pr.number,
|
||||
per_page: 100
|
||||
});
|
||||
|
||||
// Find the most recent time the stale label was added
|
||||
const staleLabelEvents = events
|
||||
.filter(e => e.event === "labeled" && e.label?.name === "stale")
|
||||
.sort((a, b) => new Date(b.created_at) - new Date(a.created_at));
|
||||
|
||||
if (staleLabelEvents.length === 0) continue;
|
||||
|
||||
const staleLabelDate = new Date(staleLabelEvents[0].created_at);
|
||||
const daysSinceStale = (now - staleLabelDate) / (1000 * 60 * 60 * 24);
|
||||
|
||||
// Check for new commits since stale label was added
|
||||
const { data: commits } = await github.rest.pulls.listCommits({
|
||||
owner,
|
||||
repo,
|
||||
pull_number: pr.number
|
||||
});
|
||||
|
||||
const lastCommitDate = new Date(commits[commits.length - 1].commit.author.date);
|
||||
const author = pr.user.login;
|
||||
|
||||
// If there are new commits after the stale label, remove it
|
||||
if (lastCommitDate > staleLabelDate) {
|
||||
await github.rest.issues.removeLabel({
|
||||
owner,
|
||||
repo,
|
||||
issue_number: pr.number,
|
||||
name: "stale"
|
||||
});
|
||||
await github.rest.issues.createComment({
|
||||
owner,
|
||||
repo,
|
||||
issue_number: pr.number,
|
||||
body: `@${author} Recent activity detected. Removing stale label.`
|
||||
});
|
||||
}
|
||||
// If 7 days have passed since stale label, close the PR
|
||||
else if (daysSinceStale > 7) {
|
||||
await github.rest.pulls.update({
|
||||
owner,
|
||||
repo,
|
||||
pull_number: pr.number,
|
||||
state: "closed"
|
||||
});
|
||||
await github.rest.issues.createComment({
|
||||
owner,
|
||||
repo,
|
||||
issue_number: pr.number,
|
||||
body: `@${author} Closing stale PR due to inactivity (no commits for 7 days after stale label).`
|
||||
});
|
||||
}
|
||||
}
|
||||
16
CHANGELOG.md
16
CHANGELOG.md
@@ -409,6 +409,22 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
||||
|
||||
## 2026-02-24
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- adds further documentation during the installation script. [@d12rio](https://github.com/d12rio) ([#12248](https://github.com/community-scripts/ProxmoxVE/pull/12248))
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- Firefly: PHP bump [@tremor021](https://github.com/tremor021) ([#12247](https://github.com/community-scripts/ProxmoxVE/pull/12247))
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- make searxng updateable [@shtefko](https://github.com/shtefko) ([#12207](https://github.com/community-scripts/ProxmoxVE/pull/12207))
|
||||
|
||||
### 📂 Github
|
||||
|
||||
- add: workflow to close stale PRs [@CrazyWolf13](https://github.com/CrazyWolf13) ([#12243](https://github.com/community-scripts/ProxmoxVE/pull/12243))
|
||||
|
||||
## 2026-02-23
|
||||
|
||||
### 🆕 New Scripts
|
||||
|
||||
@@ -28,7 +28,10 @@ function update_script() {
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
setup_mariadb
|
||||
PHP_VERSION="8.5" PHP_APACHE="YES" setup_php
|
||||
|
||||
if check_for_gh_release "firefly" "firefly-iii/firefly-iii"; then
|
||||
systemctl stop apache2
|
||||
cp /opt/firefly/.env /opt/.env
|
||||
|
||||
@@ -27,12 +27,33 @@ function update_script() {
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
msg_ok "There is currently no update available."
|
||||
# sed -i 's/^\([[:space:]]*limiter:\)[[:space:]]*true/\1 false/' /etc/searxng/settings.yml
|
||||
# if cd /usr/local/searxng/searxng-src && git pull | grep -q 'Already up to date'; then
|
||||
# msg_ok "There is currently no update available."
|
||||
# fi
|
||||
exit
|
||||
|
||||
chown -R searxng:searxng /usr/local/searxng/searxng-src
|
||||
if su -s /bin/bash -c "git -C /usr/local/searxng/searxng-src pull" searxng | grep -q 'Already up to date'; then
|
||||
msg_ok "There is currently no update available."
|
||||
exit
|
||||
fi
|
||||
|
||||
msg_info "Updating SearXNG installation"
|
||||
msg_info "Stopping Service"
|
||||
systemctl stop searxng
|
||||
msg_ok "Stopped Service"
|
||||
|
||||
msg_info "Updating SearXNG"
|
||||
$STD su -s /bin/bash searxng -c '
|
||||
python3 -m venv /usr/local/searxng/searx-pyenv &&
|
||||
. /usr/local/searxng/searx-pyenv/bin/activate &&
|
||||
pip install -U pip setuptools wheel pyyaml lxml msgspec typing_extensions &&
|
||||
pip install --use-pep517 --no-build-isolation -e /usr/local/searxng/searxng-src
|
||||
'
|
||||
msg_ok "Updated SearXNG"
|
||||
|
||||
msg_info "Starting Services"
|
||||
systemctl start searxng
|
||||
msg_ok "Started Services"
|
||||
msg_ok "Updated successfully!"
|
||||
fi
|
||||
exit
|
||||
}
|
||||
start
|
||||
build_container
|
||||
|
||||
40
frontend/public/json/arcane.json
Normal file
40
frontend/public/json/arcane.json
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "Arcane",
|
||||
"slug": "arcane",
|
||||
"categories": [
|
||||
3
|
||||
],
|
||||
"date_created": "2026-02-18",
|
||||
"type": "addon",
|
||||
"updateable": true,
|
||||
"privileged": false,
|
||||
"interface_port": 3552,
|
||||
"documentation": "https://getarcane.app/docs",
|
||||
"website": "https://getarcane.app/",
|
||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/arcane.webp",
|
||||
"config_path": "/opt/arcane/.env",
|
||||
"description": "Arcane is designed to be an easy and modern Docker management platform, built with everybody in mind. The goal of Arcane is to be built for and by the community to make sure nobody feels left out or behind with their specific features or processes. ",
|
||||
"install_methods": [
|
||||
{
|
||||
"type": "default",
|
||||
"script": "tools/addon/arcane.sh",
|
||||
"resources": {
|
||||
"cpu": null,
|
||||
"ram": null,
|
||||
"hdd": null,
|
||||
"os": null,
|
||||
"version": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"default_credentials": {
|
||||
"username": "arcane",
|
||||
"password": "arcane-admin"
|
||||
},
|
||||
"notes": [
|
||||
{
|
||||
"text": "This is an addon script intended to be used on top of an existing Docker container.",
|
||||
"type": "info"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"generated": "2026-02-24T00:22:35Z",
|
||||
"generated": "2026-02-24T06:23:39Z",
|
||||
"versions": [
|
||||
{
|
||||
"slug": "2fauth",
|
||||
@@ -151,9 +151,9 @@
|
||||
{
|
||||
"slug": "booklore",
|
||||
"repo": "booklore-app/BookLore",
|
||||
"version": "v2.0.0",
|
||||
"version": "v2.0.1",
|
||||
"pinned": false,
|
||||
"date": "2026-02-23T17:00:00Z"
|
||||
"date": "2026-02-24T04:15:33Z"
|
||||
},
|
||||
{
|
||||
"slug": "bookstack",
|
||||
@@ -452,9 +452,9 @@
|
||||
{
|
||||
"slug": "gitea-mirror",
|
||||
"repo": "RayLabsHQ/gitea-mirror",
|
||||
"version": "v3.9.2",
|
||||
"version": "v3.9.4",
|
||||
"pinned": false,
|
||||
"date": "2025-11-08T05:36:48Z"
|
||||
"date": "2026-02-24T06:17:56Z"
|
||||
},
|
||||
{
|
||||
"slug": "glance",
|
||||
@@ -613,9 +613,9 @@
|
||||
{
|
||||
"slug": "jackett",
|
||||
"repo": "Jackett/Jackett",
|
||||
"version": "v0.24.1184",
|
||||
"version": "v0.24.1193",
|
||||
"pinned": false,
|
||||
"date": "2026-02-23T05:55:36Z"
|
||||
"date": "2026-02-24T05:58:04Z"
|
||||
},
|
||||
{
|
||||
"slug": "jellystat",
|
||||
@@ -1271,9 +1271,9 @@
|
||||
{
|
||||
"slug": "rdtclient",
|
||||
"repo": "rogerfar/rdt-client",
|
||||
"version": "v2.0.123",
|
||||
"version": "v2.0.124",
|
||||
"pinned": false,
|
||||
"date": "2026-02-21T23:08:13Z"
|
||||
"date": "2026-02-24T03:18:03Z"
|
||||
},
|
||||
{
|
||||
"slug": "reactive-resume",
|
||||
@@ -1453,9 +1453,9 @@
|
||||
{
|
||||
"slug": "stirling-pdf",
|
||||
"repo": "Stirling-Tools/Stirling-PDF",
|
||||
"version": "v2.5.2",
|
||||
"version": "v2.5.3",
|
||||
"pinned": false,
|
||||
"date": "2026-02-20T23:20:20Z"
|
||||
"date": "2026-02-23T23:23:39Z"
|
||||
},
|
||||
{
|
||||
"slug": "streamlink-webui",
|
||||
@@ -1740,9 +1740,9 @@
|
||||
{
|
||||
"slug": "wishlist",
|
||||
"repo": "cmintey/wishlist",
|
||||
"version": "v0.60.0",
|
||||
"version": "v0.60.1",
|
||||
"pinned": false,
|
||||
"date": "2026-02-10T04:05:26Z"
|
||||
"date": "2026-02-24T04:01:37Z"
|
||||
},
|
||||
{
|
||||
"slug": "wizarr",
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
],
|
||||
"date_created": "2025-08-26",
|
||||
"type": "ct",
|
||||
"updateable": false,
|
||||
"updateable": true,
|
||||
"privileged": false,
|
||||
"interface_port": 8888,
|
||||
"documentation": "https://docs.searxng.org/",
|
||||
|
||||
@@ -21,6 +21,8 @@ msg_ok "Installed Dependencies"
|
||||
|
||||
NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs
|
||||
|
||||
echo "${TAB3}It is important to choose the name for your server before you install Synapse, because it cannot be changed later."
|
||||
echo "${TAB3}The server name determines the “domain” part of user-ids for users on your server: these will all be of the format @user:my.domain.name. It also determines how other matrix servers will reach yours for federation."
|
||||
read -p "${TAB3}Please enter the name for your server: " servername
|
||||
|
||||
msg_info "Installing Element Synapse"
|
||||
|
||||
@@ -13,7 +13,7 @@ setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
PHP_VERSION="8.4" PHP_APACHE="YES" setup_php
|
||||
PHP_VERSION="8.5" PHP_APACHE="YES" setup_php
|
||||
setup_composer
|
||||
setup_mariadb
|
||||
MARIADB_DB_NAME="firefly" MARIADB_DB_USER="firefly" setup_mariadb_db
|
||||
|
||||
219
tools/addon/arcane.sh
Normal file
219
tools/addon/arcane.sh
Normal file
@@ -0,0 +1,219 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: summoningpixels
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/getarcaneapp/arcane
|
||||
if ! command -v curl &>/dev/null; then
|
||||
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
||||
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/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
|
||||
|
||||
# Enable error handling
|
||||
set -Eeuo pipefail
|
||||
trap 'error_handler' ERR
|
||||
|
||||
# ==============================================================================
|
||||
# CONFIGURATION
|
||||
# ==============================================================================
|
||||
APP="Arcane"
|
||||
APP_TYPE="addon"
|
||||
INSTALL_PATH="/opt/arcane"
|
||||
COMPOSE_FILE="${INSTALL_PATH}/compose.yaml"
|
||||
ENV_FILE="${INSTALL_PATH}/.env"
|
||||
DEFAULT_PORT=3552
|
||||
|
||||
# Initialize all core functions (colors, formatting, icons, STD mode)
|
||||
load_functions
|
||||
|
||||
# ==============================================================================
|
||||
# HEADER
|
||||
# ==============================================================================
|
||||
function header_info {
|
||||
clear
|
||||
cat <<"EOF"
|
||||
___ ____ _________ _ ________
|
||||
/ | / __ \/ ____/ | / | / / ____/
|
||||
/ /| | / /_/ / / / /| | / |/ / __/
|
||||
/ ___ |/ _, _/ /___/ ___ |/ /| / /___
|
||||
/_/ |_/_/ |_|\____/_/ |_/_/ |_/_____/
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# UNINSTALL
|
||||
# ==============================================================================
|
||||
function uninstall() {
|
||||
msg_info "Uninstalling ${APP}"
|
||||
|
||||
if [[ -f "$COMPOSE_FILE" ]]; then
|
||||
msg_info "Stopping and removing Docker containers"
|
||||
cd "$INSTALL_PATH"
|
||||
$STD docker compose down --volumes --remove-orphans
|
||||
msg_ok "Stopped and removed Docker containers"
|
||||
fi
|
||||
|
||||
rm -rf "$INSTALL_PATH"
|
||||
rm -f "/usr/local/bin/update_arcane"
|
||||
msg_ok "${APP} has been uninstalled"
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# UPDATE
|
||||
# ==============================================================================
|
||||
function update() {
|
||||
msg_info "Pulling latest ${APP} image"
|
||||
cd "$INSTALL_PATH"
|
||||
$STD docker compose pull
|
||||
msg_ok "Pulled latest image"
|
||||
|
||||
msg_info "Restarting ${APP}"
|
||||
$STD docker compose up -d --remove-orphans
|
||||
msg_ok "Restarted ${APP}"
|
||||
|
||||
msg_ok "Updated successfully"
|
||||
exit
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# CHECK DOCKER
|
||||
# ==============================================================================
|
||||
function check_docker() {
|
||||
if ! command -v docker &>/dev/null; then
|
||||
msg_error "Docker is not installed. This script requires an existing Docker LXC. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
if ! docker compose version &>/dev/null; then
|
||||
msg_error "Docker Compose plugin is not available. Please install it before running this script. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
msg_ok "Docker $(docker --version | cut -d' ' -f3 | tr -d ',') and Docker Compose are available"
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# INSTALL
|
||||
# ==============================================================================
|
||||
function install() {
|
||||
check_docker
|
||||
|
||||
msg_info "Creating install directory"
|
||||
mkdir -p "$INSTALL_PATH"
|
||||
msg_ok "Created ${INSTALL_PATH}"
|
||||
|
||||
# Generate secrets and config values
|
||||
local ENCRYPTION_KEY JWT_SECRET PROJ_DIR
|
||||
ENCRYPTION_KEY=$(openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | head -c32)
|
||||
JWT_SECRET=$(openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | head -c32)
|
||||
PROJ_DIR="/etc/arcane/projects"
|
||||
|
||||
msg_info "Creating stacks directory"
|
||||
mkdir -p "$PROJ_DIR"
|
||||
msg_ok "Created ${PROJ_DIR}"
|
||||
|
||||
msg_info "Downloading Docker Compose file"
|
||||
curl -fsSL "https://raw.githubusercontent.com/getarcaneapp/arcane/refs/heads/main/docker/examples/compose.basic.yaml" -o "$COMPOSE_FILE"
|
||||
msg_ok "Downloaded Docker Compose file"
|
||||
|
||||
msg_info "Downloading .env file"
|
||||
curl -fsSL "https://raw.githubusercontent.com/getarcaneapp/arcane/refs/heads/main/.env.example" -o "$ENV_FILE"
|
||||
chmod 600 "$ENV_FILE"
|
||||
msg_ok "Downloaded .env file"
|
||||
|
||||
msg_info "Configuring compose and env files"
|
||||
sed -i '/^[[:space:]]*#/!s|/host/path/to/projects|'"$PROJ_DIR"'|g' "$COMPOSE_FILE"
|
||||
sed -i '/^[[:space:]]*#/!s|ENCRYPTION_KEY=.*|ENCRYPTION_KEY='"$ENCRYPTION_KEY"'|g' "$COMPOSE_FILE"
|
||||
sed -i '/^[[:space:]]*#/!s|JWT_SECRET=.*|JWT_SECRET='"$JWT_SECRET"'|g' "$COMPOSE_FILE"
|
||||
sed -i '/^[[:space:]]*#/!s|APP_URL=.*|APP_URL=http://localhost:'"$DEFAULT_PORT"'|g' "$ENV_FILE"
|
||||
sed -i '/^[[:space:]]*#/!s|ENCRYPTION_KEY=.*|#&|g' "$ENV_FILE"
|
||||
sed -i '/^[[:space:]]*#/!s|JWT_SECRET=.*|#&|g' "$ENV_FILE"
|
||||
msg_ok "Configured compose and env files"
|
||||
|
||||
msg_info "Starting ${APP}"
|
||||
cd "$INSTALL_PATH"
|
||||
$STD docker compose up -d
|
||||
msg_ok "Started ${APP}"
|
||||
|
||||
# Create update script
|
||||
msg_info "Creating update script"
|
||||
cat <<'UPDATEEOF' >/usr/local/bin/update_arcane
|
||||
#!/usr/bin/env bash
|
||||
# Arcane Update Script
|
||||
type=update bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/arcane.sh)"
|
||||
UPDATEEOF
|
||||
chmod +x /usr/local/bin/update_arcane
|
||||
msg_ok "Created update script (/usr/local/bin/update_arcane)"
|
||||
|
||||
echo ""
|
||||
msg_ok "${APP} is reachable at: ${BL}http://${LOCAL_IP}:${DEFAULT_PORT}${CL}"
|
||||
echo ""
|
||||
echo -e "Arcane Credentials"
|
||||
echo -e "=================="
|
||||
echo -e "User: arcane"
|
||||
echo -e "Password: arcane-admin"
|
||||
echo ""
|
||||
msg_warn "On first access, you'll be prompted to change your password."
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# MAIN
|
||||
# ==============================================================================
|
||||
|
||||
# Handle type=update (called from update script)
|
||||
if [[ "${type:-}" == "update" ]]; then
|
||||
header_info
|
||||
if [[ -f "$COMPOSE_FILE" ]]; then
|
||||
update
|
||||
else
|
||||
msg_error "${APP} is not installed. Nothing to update."
|
||||
exit 1
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
header_info
|
||||
get_lxc_ip
|
||||
|
||||
# Check if already installed
|
||||
if [[ -f "$COMPOSE_FILE" ]]; then
|
||||
msg_warn "${APP} is already installed."
|
||||
echo ""
|
||||
|
||||
echo -n "${TAB}Uninstall ${APP}? (y/N): "
|
||||
read -r uninstall_prompt
|
||||
if [[ "${uninstall_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
uninstall
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo -n "${TAB}Update ${APP}? (y/N): "
|
||||
read -r update_prompt
|
||||
if [[ "${update_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
update
|
||||
exit 0
|
||||
fi
|
||||
|
||||
msg_warn "No action selected. Exiting."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Fresh installation
|
||||
msg_warn "${APP} is not installed."
|
||||
echo ""
|
||||
echo -e "${TAB}${INFO} This will install:"
|
||||
echo -e "${TAB} - Arcane (via Docker Compose)"
|
||||
echo ""
|
||||
|
||||
echo -n "${TAB}Install ${APP}? (y/N): "
|
||||
read -r install_prompt
|
||||
if [[ "${install_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
install
|
||||
else
|
||||
msg_warn "Installation cancelled. Exiting."
|
||||
exit 0
|
||||
fi
|
||||
Reference in New Issue
Block a user