diff --git a/backend/index.js b/backend/index.js index 398d5a3..2843036 100644 --- a/backend/index.js +++ b/backend/index.js @@ -14,7 +14,6 @@ const __dirname = path.dirname(__filename); const app = express(); app.use(express.json()); - app.use(express.static(path.join(__dirname, 'public'))); app.get('*', (req, res, next) => { @@ -49,6 +48,7 @@ const broadcastRedeployStatus = (stackId, status) => { // --- API Endpoints --- +// Stacks abrufen app.get('/api/stacks', async (req, res) => { console.log("ℹ️ [API] GET /api/stacks: Abruf gestartet"); try { @@ -89,6 +89,7 @@ app.get('/api/stacks', async (req, res) => { } }); +// Einzel-Redeploy app.put('/api/stacks/:id/redeploy', async (req, res) => { const { id } = req.params; console.log(`🔄 PUT /api/stacks/${id}/redeploy: Redeploy gestartet`); @@ -142,6 +143,51 @@ app.put('/api/stacks/:id/redeploy', async (req, res) => { } }); +// Redeploy ALL +app.put('/api/stacks/redeploy-all', async (req, res) => { + console.log(`🚀 PUT /api/stacks/redeploy-all: Redeploy ALL gestartet`); + + try { + const stacksRes = await axiosInstance.get('/api/stacks'); + const filteredStacks = stacksRes.data.filter(stack => stack.EndpointId === ENDPOINT_ID); + + console.log("📦 Redeploy ALL für folgende Stacks:"); + filteredStacks.forEach(s => console.log(` - ${s.Name}`)); + + filteredStacks.forEach(async (stack) => { + try { + broadcastRedeployStatus(stack.Id, true); + + if (stack.Type === 1) { + console.log(`🔄 [Redeploy] Git Stack "${stack.Name}" (${stack.Id})`); + await axiosInstance.put(`/api/stacks/${stack.Id}/git/redeploy?endpointId=${stack.EndpointId}`); + } else if (stack.Type === 2) { + console.log(`🔄 [Redeploy] Compose Stack "${stack.Name}" (${stack.Id})`); + const fileRes = await axiosInstance.get(`/api/stacks/${stack.Id}/file`); + const stackFileContent = fileRes.data?.StackFileContent; + if (stackFileContent) { + await axiosInstance.put(`/api/stacks/${stack.Id}`, + { StackFileContent: stackFileContent, Prune: false, PullImage: true }, + { params: { endpointId: stack.EndpointId } } + ); + } + } + + broadcastRedeployStatus(stack.Id, false); + console.log(`✅ Redeploy abgeschlossen: ${stack.Name}`); + } catch (err) { + broadcastRedeployStatus(stack.Id, false); + console.error(`❌ Fehler beim Redeploy von Stack ${stack.Name}:`, err.message); + } + }); + + res.json({ success: true, message: 'Redeploy ALL gestartet' }); + } catch (err) { + console.error(`❌ Fehler beim Redeploy ALL:`, err.message); + res.status(500).json({ error: err.message }); + } +}); + server.listen(PORT, '0.0.0.0', () => { console.log(`🚀 Backend läuft auf Port ${PORT}`); }); diff --git a/frontend/src/Stacks.jsx b/frontend/src/Stacks.jsx index cc6c353..00b9ac5 100644 --- a/frontend/src/Stacks.jsx +++ b/frontend/src/Stacks.jsx @@ -68,45 +68,68 @@ export default function Stacks() { } }; + const handleRedeployAll = async () => { + setStacks(prev => prev.map(stack => ({ ...stack, redeploying: true }))); + + try { + await axios.put("/api/stacks/redeploy-all"); + // Statusupdates kommen über Socket.IO + } catch (err) { + console.error("❌ Fehler beim Redeploy ALL:", err); + setStacks(prev => prev.map(stack => ({ ...stack, redeploying: false }))); + } + }; + if (loading) return
Lade Stacks...
; if (error) return{error}
; return ( -{stack.Name}
-ID: {stack.Id}
-Keine Stacks gefunden.
} +