From 08b94337add9c68ab10b3a27ebb55bda00b32bbc Mon Sep 17 00:00:00 2001 From: DungTT Date: Fri, 5 Jun 2026 14:56:03 +0700 Subject: [PATCH] fix remote ubuntu server --- agent/app/config.py | 13 +- .../systemd/local-installer-agent.service | 2 +- agent/scripts/build-deb.sh | 8 +- web-client/src/main.jsx | 144 +++++++++++++----- web-server/server.js | 10 +- 5 files changed, 130 insertions(+), 47 deletions(-) diff --git a/agent/app/config.py b/agent/app/config.py index f2ee9a6..9f8348f 100644 --- a/agent/app/config.py +++ b/agent/app/config.py @@ -63,12 +63,21 @@ def get_settings() -> Settings: robot_package_base_url = os.getenv("ROBOT_PACKAGE_BASE_URL", "https://package.pnkr.cloud").rstrip("/") return Settings( agent_version=os.getenv("AGENT_VERSION", "1.0.0"), - host=os.getenv("AGENT_HOST", "127.0.0.1"), + host=os.getenv("AGENT_HOST", "0.0.0.0"), port=int(os.getenv("AGENT_PORT", "5010")), robot_package_base_url=robot_package_base_url, allowed_origins=_csv( os.getenv("ALLOWED_ORIGINS"), - ["https://app.pnkr.cloud", "https://package.pnkr.cloud", "http://localhost:3000", "http://localhost:5173"], + [ + "https://app.pnkr.cloud", + "https://package.pnkr.cloud", + "http://localhost:3000", + "http://127.0.0.1:3000", + "http://localhost:5173", + "http://127.0.0.1:5173", + "http://localhost:8080", + "http://127.0.0.1:8080", + ], ), allowed_download_hosts=_csv( os.getenv("ALLOWED_DOWNLOAD_HOSTS"), diff --git a/agent/packaging/systemd/local-installer-agent.service b/agent/packaging/systemd/local-installer-agent.service index d870d60..cda0955 100644 --- a/agent/packaging/systemd/local-installer-agent.service +++ b/agent/packaging/systemd/local-installer-agent.service @@ -4,7 +4,7 @@ After=network.target [Service] WorkingDirectory=/opt/local-installer-agent -ExecStart=/opt/local-installer-agent/venv/bin/python -m uvicorn app.main:app --host 127.0.0.1 --port 5010 +ExecStart=/opt/local-installer-agent/venv/bin/python -m uvicorn app.main:app --host ${AGENT_HOST} --port ${AGENT_PORT} Restart=always User=root EnvironmentFile=/etc/local-installer-agent/agent.env diff --git a/agent/scripts/build-deb.sh b/agent/scripts/build-deb.sh index 6daa0c8..bc6a612 100644 --- a/agent/scripts/build-deb.sh +++ b/agent/scripts/build-deb.sh @@ -3,6 +3,8 @@ set -euo pipefail VERSION="${VERSION:-1.0.0}" ARCH="${ARCH:-amd64}" +AGENT_HOST="${AGENT_HOST:-0.0.0.0}" +AGENT_PORT="${AGENT_PORT:-5010}" DEB_COMPRESSION="${DEB_COMPRESSION:-gzip}" PKG_NAME="local-installer-agent" BUILD_ROOT="${BUILD_ROOT:-build}" @@ -53,10 +55,10 @@ chmod 755 "${BUILD_DIR}/DEBIAN" cat > "${BUILD_DIR}/etc/local-installer-agent/agent.env" < detectClientOs(), []); const isClientLinux = clientOs === 'linux'; const isClientWindows = clientOs === 'windows'; - const canShowAgentCommand = isClientLinux || isClientWindows; + const isLocalAgentEndpoint = useMemo(() => isLoopbackAgentEndpoint(agentBaseUrl), [agentBaseUrl]); + const isRemoteAgentEndpoint = !isLocalAgentEndpoint; + const canUseAgentEndpoint = isRemoteAgentEndpoint || isClientLinux; + const canManageApps = canUseAgentEndpoint; + const canShowAgentCommand = isClientLinux || isClientWindows || isRemoteAgentEndpoint; const clientOsLabel = getClientOsLabel(clientOs); + const agentTargetLabel = isRemoteAgentEndpoint ? 'Remote Ubuntu Agent' : 'Local Agent'; + const agentTargetMachine = isRemoteAgentEndpoint ? 'remote Ubuntu server' : 'local machine'; const installedByAppId = useMemo(() => { return new Map(installedApps.map((app) => [app.appId, app])); @@ -284,24 +334,24 @@ function App() { }, [packageBaseUrl]); const refreshAgent = useCallback(async () => { - if (!isClientLinux) { + if (!canUseAgentEndpoint) { setAgentHealth(null); setSystemInfo(null); setInstalledApps([]); setAgentStatus({ state: 'warning', message: isClientWindows - ? 'Windows detected. Copy the Agent command and run it in Ubuntu SSH.' - : `Current client is ${clientOsLabel}. Web Client only supports Linux.` + ? 'Local endpoint points to this Windows machine. Use a remote Ubuntu Agent endpoint.' + : `Local endpoint requires Linux. Current client is ${clientOsLabel}.` }); return false; } - setAgentStatus({ state: 'loading', message: 'Đang kiểm tra Agent local' }); + setAgentStatus({ state: 'loading', message: `Checking ${agentTargetLabel}` }); try { const health = await fetchAgentHealth(agentBaseUrl); setAgentHealth(health); - setAgentStatus({ state: 'success', message: `${health.hostname || 'Agent'} online` }); + setAgentStatus({ state: 'success', message: `${health.hostname || agentTargetLabel} online` }); const [info, installed] = await Promise.all([ fetchAgentSystemInfo(agentBaseUrl).catch(() => null), @@ -317,7 +367,7 @@ function App() { setAgentStatus({ state: 'danger', message: getErrorMessage(error) }); return false; } - }, [agentBaseUrl, clientOsLabel, isClientLinux, isClientWindows]); + }, [agentBaseUrl, agentTargetLabel, canUseAgentEndpoint, clientOsLabel, isClientWindows]); const refreshAll = useCallback(async () => { await Promise.all([refreshPackage(), refreshAgent()]); @@ -431,17 +481,17 @@ function App() { }, []); const runAppAction = useCallback(async (action, app) => { - if (!isClientLinux) { - notify('warning', 'Web Client chỉ hỗ trợ cài đặt trên máy Linux.'); + if (!canManageApps) { + notify('warning', 'Local Agent endpoint can install only from a Linux browser machine. Use a remote Ubuntu Agent endpoint.'); return; } if (!agentHealth) { - notify('warning', 'Agent local đang offline. Cài Agent rồi bấm Retry.'); + notify('warning', `${agentTargetLabel} is offline. Check the endpoint and press Retry.`); return; } - if (action === 'remove' && !window.confirm(`Remove ${app.appName} khỏi máy local?`)) { + if (action === 'remove' && !window.confirm(`Remove ${app.appName} from ${agentTargetMachine}?`)) { return; } @@ -476,7 +526,7 @@ function App() { } finally { setBusyAction(''); } - }, [agentBaseUrl, agentHealth, isClientLinux, notify, packageBaseUrl, startPreflightFailedTask, startTask]); + }, [agentBaseUrl, agentHealth, agentTargetLabel, agentTargetMachine, canManageApps, notify, packageBaseUrl, startPreflightFailedTask, startTask]); const openEndpointDialog = useCallback(() => { setDraftSettings(settings); @@ -502,7 +552,7 @@ function App() { const copyInstallCommand = useCallback(async () => { if (!canShowAgentCommand) { - notify('warning', 'Lệnh cài Agent chỉ hiển thị trên máy Linux.'); + notify('warning', 'Agent command is hidden for this client OS.'); return; } @@ -590,6 +640,19 @@ function App() { return () => window.removeEventListener('keydown', onKeyDown); }, [closeEndpointDialog, endpointDialogOpen]); + const agentStatusTitle = !canUseAgentEndpoint + ? (isClientWindows ? 'Remote endpoint needed' : 'Linux client required') + : (agentNeedsUpdate ? 'Agent update available' : (agentHealth ? 'Agent online' : 'Agent offline')); + const agentStatusDetail = !canUseAgentEndpoint + ? (isClientWindows ? 'Change endpoint to Ubuntu server IP' : `${clientOsLabel} detected`) + : (agentHealth ? `${agentHealth.hostname || agentTargetLabel} · ${agentHealth.agentVersion || '-'}${agentNeedsUpdate ? ` -> ${latestAgentPackage.version}` : ''}` : agentBaseUrl); + const agentStatusTone = !canUseAgentEndpoint + ? 'warning' + : (agentNeedsUpdate ? 'warning' : (agentHealth ? 'success' : (agentStatus.state === 'loading' ? 'info' : 'danger'))); + const topbarAgentState = !canUseAgentEndpoint + ? 'Use Ubuntu Agent endpoint' + : (agentHealth ? `Ready on ${agentTargetMachine}` : `Waiting for ${agentTargetLabel}`); + return (
- Local Agent + Agent endpoint {agentBaseUrl}
@@ -640,7 +703,7 @@ function App() {
robot.installer - {!isClientLinux ? (isClientWindows ? 'Copy command for Ubuntu SSH' : 'Linux client required') : (agentHealth ? 'Ready for install' : 'Waiting for Agent')} + {topbarAgentState}
@@ -657,7 +720,7 @@ function App() {

Application catalog

-

Released apps từ package server và trạng thái cài đặt trên máy local.

+

Released apps from package server and install state on the selected Agent endpoint.

{canShowAgentCommand && (
@@ -665,7 +728,7 @@ function App() {