Update
This commit is contained in:
+47
-1
@@ -14,7 +14,6 @@ const __dirname = path.dirname(__filename);
|
|||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
|
|
||||||
app.use(express.static(path.join(__dirname, 'public')));
|
app.use(express.static(path.join(__dirname, 'public')));
|
||||||
|
|
||||||
app.get('*', (req, res, next) => {
|
app.get('*', (req, res, next) => {
|
||||||
@@ -49,6 +48,7 @@ const broadcastRedeployStatus = (stackId, status) => {
|
|||||||
|
|
||||||
// --- API Endpoints ---
|
// --- API Endpoints ---
|
||||||
|
|
||||||
|
// Stacks abrufen
|
||||||
app.get('/api/stacks', async (req, res) => {
|
app.get('/api/stacks', async (req, res) => {
|
||||||
console.log("ℹ️ [API] GET /api/stacks: Abruf gestartet");
|
console.log("ℹ️ [API] GET /api/stacks: Abruf gestartet");
|
||||||
try {
|
try {
|
||||||
@@ -89,6 +89,7 @@ app.get('/api/stacks', async (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Einzel-Redeploy
|
||||||
app.put('/api/stacks/:id/redeploy', async (req, res) => {
|
app.put('/api/stacks/:id/redeploy', async (req, res) => {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
console.log(`🔄 PUT /api/stacks/${id}/redeploy: Redeploy gestartet`);
|
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', () => {
|
server.listen(PORT, '0.0.0.0', () => {
|
||||||
console.log(`🚀 Backend läuft auf Port ${PORT}`);
|
console.log(`🚀 Backend läuft auf Port ${PORT}`);
|
||||||
});
|
});
|
||||||
|
|||||||
+24
-1
@@ -68,11 +68,33 @@ 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 <p className="text-gray-400">Lade Stacks...</p>;
|
if (loading) return <p className="text-gray-400">Lade Stacks...</p>;
|
||||||
if (error) return <p className="text-red-400">{error}</p>;
|
if (error) return <p className="text-red-400">{error}</p>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 p-6">
|
<div className="p-6">
|
||||||
|
<div className="flex justify-end mb-4">
|
||||||
|
<button
|
||||||
|
onClick={handleRedeployAll}
|
||||||
|
className="px-5 py-2 rounded-lg font-medium transition bg-purple-500 hover:bg-purple-600"
|
||||||
|
>
|
||||||
|
Redeploy All
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
{stacks.map(stack => {
|
{stacks.map(stack => {
|
||||||
const isRedeploying = stack.redeploying;
|
const isRedeploying = stack.redeploying;
|
||||||
|
|
||||||
@@ -108,5 +130,6 @@ export default function Stacks() {
|
|||||||
})}
|
})}
|
||||||
{stacks.length === 0 && <p className="text-gray-400">Keine Stacks gefunden.</p>}
|
{stacks.length === 0 && <p className="text-gray-400">Keine Stacks gefunden.</p>}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+33
-1
@@ -10,8 +10,9 @@ CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
|||||||
echo "Aktueller Branch: $CURRENT_BRANCH"
|
echo "Aktueller Branch: $CURRENT_BRANCH"
|
||||||
echo "Was möchtest du tun?"
|
echo "Was möchtest du tun?"
|
||||||
echo "1) Neuen Stash anlegen"
|
echo "1) Neuen Stash anlegen"
|
||||||
echo "2) Vorhandenen Stash laden"
|
echo "2) Vorhandenen Stash laden (apply)"
|
||||||
echo "3) Vorhandenen Stash löschen"
|
echo "3) Vorhandenen Stash löschen"
|
||||||
|
echo "4) Stash anwenden und löschen (pop)"
|
||||||
read -p "Auswahl: " action
|
read -p "Auswahl: " action
|
||||||
|
|
||||||
case $action in
|
case $action in
|
||||||
@@ -99,6 +100,37 @@ case $action in
|
|||||||
git stash drop "$SELECTED_STASH"
|
git stash drop "$SELECTED_STASH"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
4)
|
||||||
|
# ========== Stash anwenden und löschen (pop) ==========
|
||||||
|
echo "Liste aller Stashes für Branch '$CURRENT_BRANCH':"
|
||||||
|
STASHES=$(git stash list | grep "$CURRENT_BRANCH")
|
||||||
|
|
||||||
|
if [[ -z "$STASHES" ]]; then
|
||||||
|
echo "Keine Stashes für diesen Branch vorhanden."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
i=1
|
||||||
|
declare -A STASH_MAP
|
||||||
|
while IFS= read -r line; do
|
||||||
|
STASH_REF=$(echo "$line" | awk -F: '{print $1}')
|
||||||
|
STASH_MSG=$(echo "$line" | cut -d':' -f3- | sed 's/^ //')
|
||||||
|
echo "$i) $STASH_REF -> $STASH_MSG"
|
||||||
|
STASH_MAP[$i]=$STASH_REF
|
||||||
|
((i++))
|
||||||
|
done <<< "$STASHES"
|
||||||
|
|
||||||
|
read -p "Wähle einen Stash zum Anwenden & Löschen (Nummer): " choice
|
||||||
|
if [[ -z "${STASH_MAP[$choice]}" ]]; then
|
||||||
|
echo "Ungültige Auswahl!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
SELECTED_STASH=${STASH_MAP[$choice]}
|
||||||
|
echo "Wende Stash an und lösche ihn: $SELECTED_STASH"
|
||||||
|
git stash pop "$SELECTED_STASH"
|
||||||
|
;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
echo "Ungültige Auswahl!"
|
echo "Ungültige Auswahl!"
|
||||||
exit 1
|
exit 1
|
||||||
|
|||||||
Reference in New Issue
Block a user