From 2659a930d6df035c12b0ee847d7f736b6abb4b3d Mon Sep 17 00:00:00 2001
From: Muhammad Ibrahim
Date: Sat, 4 Oct 2025 13:37:05 +0100
Subject: [PATCH] Add force flag to bypass broken packages upon installation
---
agents/proxmox_auto_enroll.sh | 10 +++++-
backend/src/routes/autoEnrollmentRoutes.js | 6 +++-
frontend/src/pages/HostDetail.jsx | 32 +++++++++++++++++--
frontend/src/pages/settings/Integrations.jsx | 33 ++++++++++++++++++--
4 files changed, 75 insertions(+), 6 deletions(-)
diff --git a/agents/proxmox_auto_enroll.sh b/agents/proxmox_auto_enroll.sh
index ebfb20f..f999b90 100755
--- a/agents/proxmox_auto_enroll.sh
+++ b/agents/proxmox_auto_enroll.sh
@@ -33,6 +33,7 @@ HOST_PREFIX="${HOST_PREFIX:-}"
SKIP_STOPPED="${SKIP_STOPPED:-true}"
PARALLEL_INSTALL="${PARALLEL_INSTALL:-false}"
MAX_PARALLEL="${MAX_PARALLEL:-5}"
+FORCE_INSTALL="${FORCE_INSTALL:-false}"
# ===== COLOR OUTPUT =====
RED='\033[0;31m'
@@ -243,6 +244,13 @@ while IFS= read -r line; do
# Install PatchMon agent in container
info " Installing PatchMon agent..."
+ # Build install URL with force flag if enabled
+ install_url="$PATCHMON_URL/api/v1/hosts/install"
+ if [[ "$FORCE_INSTALL" == "true" ]]; then
+ install_url="$install_url?force=true"
+ info " Using force mode - will bypass broken packages"
+ fi
+
# Reset exit code for this container
install_exit_code=0
@@ -253,7 +261,7 @@ while IFS= read -r line; do
-H \"X-API-ID: $api_id\" \
-H \"X-API-KEY: $api_key\" \
-o patchmon-install.sh \
- '$PATCHMON_URL/api/v1/hosts/install' && \
+ '$install_url' && \
bash patchmon-install.sh && \
rm -f patchmon-install.sh
" 2>&1 {
}
} catch (_) {}
- // Inject the token credentials, server URL, and curl flags into the script
+ // Check for --force parameter
+ const force_install = req.query.force === "true" || req.query.force === "1";
+
+ // Inject the token credentials, server URL, curl flags, and force flag into the script
const env_vars = `#!/bin/bash
# PatchMon Auto-Enrollment Configuration (Auto-generated)
export PATCHMON_URL="${server_url}"
export AUTO_ENROLLMENT_KEY="${token.token_key}"
export AUTO_ENROLLMENT_SECRET="${token_secret}"
export CURL_FLAGS="${curl_flags}"
+export FORCE_INSTALL="${force_install ? "true" : "false"}"
`;
diff --git a/frontend/src/pages/HostDetail.jsx b/frontend/src/pages/HostDetail.jsx
index 8d185ac..e2027b9 100644
--- a/frontend/src/pages/HostDetail.jsx
+++ b/frontend/src/pages/HostDetail.jsx
@@ -45,6 +45,7 @@ const HostDetail = () => {
const [showDeleteModal, setShowDeleteModal] = useState(false);
const [showAllUpdates, setShowAllUpdates] = useState(false);
const [activeTab, setActiveTab] = useState("host");
+ const [forceInstall, setForceInstall] = useState(false);
const {
data: host,
@@ -1083,6 +1084,7 @@ const HostDetail = () => {
const CredentialsModal = ({ host, isOpen, onClose }) => {
const [showApiKey, setShowApiKey] = useState(false);
const [activeTab, setActiveTab] = useState("quick-install");
+ const [forceInstall, setForceInstall] = useState(false);
const apiIdInputId = useId();
const apiKeyInputId = useId();
@@ -1104,6 +1106,12 @@ const CredentialsModal = ({ host, isOpen, onClose }) => {
return settings?.ignore_ssl_self_signed ? "-sk" : "-s";
};
+ // Helper function to build installation URL with optional force flag
+ const getInstallUrl = () => {
+ const baseUrl = `${serverUrl}/api/v1/hosts/install`;
+ return forceInstall ? `${baseUrl}?force=true` : baseUrl;
+ };
+
const copyToClipboard = async (text) => {
try {
// Try modern clipboard API first
@@ -1197,10 +1205,30 @@ const CredentialsModal = ({ host, isOpen, onClose }) => {
Copy and run this command on the target host to securely install
and configure the PatchMon agent:
+
+ {/* Force Install Toggle */}
+
+
+
+ Enable this if the target host has broken packages
+ (CloudPanel, WHM, etc.) that block apt-get operations
+
+
+
@@ -1208,7 +1236,7 @@ const CredentialsModal = ({ host, isOpen, onClose }) => {
type="button"
onClick={() =>
copyToClipboard(
- `curl ${getCurlFlags()} ${serverUrl}/api/v1/hosts/install -H "X-API-ID: ${host.api_id}" -H "X-API-KEY: ${host.api_key}" | bash`,
+ `curl ${getCurlFlags()} ${getInstallUrl()} -H "X-API-ID: ${host.api_id}" -H "X-API-KEY: ${host.api_key}" | bash`,
)
}
className="btn-primary flex items-center gap-1"
diff --git a/frontend/src/pages/settings/Integrations.jsx b/frontend/src/pages/settings/Integrations.jsx
index 0887350..8732c12 100644
--- a/frontend/src/pages/settings/Integrations.jsx
+++ b/frontend/src/pages/settings/Integrations.jsx
@@ -22,6 +22,7 @@ const Integrations = () => {
const [new_token, setNewToken] = useState(null);
const [show_secret, setShowSecret] = useState(false);
const [server_url, setServerUrl] = useState("");
+ const [force_proxmox_install, setForceProxmoxInstall] = useState(false);
// Form state
const [form_data, setFormData] = useState({
@@ -34,6 +35,12 @@ const Integrations = () => {
const [copy_success, setCopySuccess] = useState({});
+ // Helper function to build Proxmox enrollment URL with optional force flag
+ const getProxmoxUrl = () => {
+ const baseUrl = `${server_url}/api/v1/auto-enrollment/proxmox-lxc?token_key=${new_token.token_key}&token_secret=${new_token.token_secret}`;
+ return force_proxmox_install ? `${baseUrl}&force=true` : baseUrl;
+ };
+
const handleTabChange = (tabName) => {
setActiveTab(tabName);
};
@@ -664,10 +671,32 @@ const Integrations = () => {
Run this command on your Proxmox host to download and
execute the enrollment script:
+
+ {/* Force Install Toggle */}
+
+
+
+ Enable this if your LXC containers have broken packages
+ (CloudPanel, WHM, etc.) that block apt-get operations
+
+
+
@@ -675,7 +704,7 @@ const Integrations = () => {
type="button"
onClick={() =>
copy_to_clipboard(
- `curl -s "${server_url}/api/v1/auto-enrollment/proxmox-lxc?token_key=${new_token.token_key}&token_secret=${new_token.token_secret}" | bash`,
+ `curl -s "${getProxmoxUrl()}" | bash`,
"curl-command",
)
}