diff --git a/src/snek/service/container.py b/src/snek/service/container.py
index 9d2706c..7c0a013 100644
--- a/src/snek/service/container.py
+++ b/src/snek/service/container.py
@@ -17,6 +17,12 @@ class ContainerService(BaseService):
async def get_container_name(self, channel_uid):
return f"channel-{channel_uid}"
+ async def get(self,channel_uid):
+ return await self.compose.get_instance(await self.get_container_name(channel_uid))
+
+ async def get_status(self, channel_uid):
+ return await self.compose.get_instance_status(await self.get_container_name(channel_uid))
+
async def create(
self,
channel_uid,
@@ -61,11 +67,3 @@ class ContainerService(BaseService):
return model
raise Exception(f"Failed to create container: {model.errors}")
- async def get(self, id):
- return await self.mapper.get(id)
-
- async def update(self, model):
- return await self.mapper.update(model)
-
- async def delete(self, id):
- return await self.mapper.delete(id)
diff --git a/src/snek/static/base.css b/src/snek/static/base.css
index 5300ce2..c9a2de9 100644
--- a/src/snek/static/base.css
+++ b/src/snek/static/base.css
@@ -591,7 +591,31 @@ dialog .dialog-button.secondary {
dialog .dialog-button.secondary:hover {
background-color: #f0b84c;
}
+dialog .dialog-button.primary:disabled,
+dialog .dialog-button.primary[aria-disabled="true"] {
+ /* slightly darker + lower saturation of the live colour */
+ background-color: #70321e; /* muted burnt orange */
+ color: #bfbfbf; /* light grey text */
+ opacity: .55; /* unified fade */
+ cursor: not-allowed;
+ pointer-events: none;
+}
+
+/* ---------- SECONDARY (yellow) ---------- */
+dialog .dialog-button.secondary:disabled,
+dialog .dialog-button.secondary[aria-disabled="true"] {
+ background-color: #6c5619; /* muted mustard */
+ color: #bfbfbf;
+
+ opacity: .55;
+ cursor: not-allowed;
+ pointer-events: none;
+}
+
+dialog .dialog-button:disabled:focus {
+ outline: none;
+}
.embed-url-link {
display: flex;
@@ -633,4 +657,8 @@ dialog .dialog-button.secondary:hover {
color: #f05a28;
text-decoration: none;
margin-top: 10px;
-}
\ No newline at end of file
+}
+
+th {
+ min-width: 100px;
+}
diff --git a/src/snek/system/docker.py b/src/snek/system/docker.py
index add91e4..d37789d 100644
--- a/src/snek/system/docker.py
+++ b/src/snek/system/docker.py
@@ -2,6 +2,10 @@ import copy
import yaml
+import yaml
+import copy
+import asyncio
+import subprocess
class ComposeFileManager:
def __init__(self, compose_path="docker-compose.yml"):
@@ -58,8 +62,14 @@ class ComposeFileManager:
del self.compose["services"][name]
self._save()
- def get_instance(self, name):
- return self.compose.get("services", {}).get(name)
+ async def get_instance(self, name):
+ instance = self.compose.get("services", {}).get(name)
+ print(self.compose.get("services", {}))
+ print(instance)
+ instance['status'] = await self.get_instance_status(name)
+ print("INSTANCE",instance)
+
+ return instance
def duplicate_instance(self, name, new_name):
orig = self.get_instance(name)
@@ -78,6 +88,18 @@ class ComposeFileManager:
self.compose["services"][name] = service
self._save()
+ async def get_instance_status(self, name):
+ """Asynchronously check the status of a docker-compose service instance."""
+ if name not in self.list_instances():
+ return "error"
+ proc = await asyncio.create_subprocess_exec(
+ "docker", "compose", "-f", self.compose_path, "ps", "--services", "--filter", f"status=running",
+ stdout=asyncio.subprocess.PIPE,
+ stderr=asyncio.subprocess.PIPE,
+ )
+ stdout, _ = await proc.communicate()
+ running_services = stdout.decode().split()
+ return "running" if name in running_services else "stopped"
# Storage size is not tracked in compose files; would need Docker API for that.
diff --git a/src/snek/templates/dialog_container.html b/src/snek/templates/dialog_container.html
new file mode 100644
index 0000000..8167360
--- /dev/null
+++ b/src/snek/templates/dialog_container.html
@@ -0,0 +1,185 @@
+
+
+
diff --git a/src/snek/templates/web.html b/src/snek/templates/web.html
index 5160b00..b9c02b4 100644
--- a/src/snek/templates/web.html
+++ b/src/snek/templates/web.html
@@ -29,6 +29,7 @@
+{% include "dialog_container.html" %}
{% include "dialog_help.html" %}
{% include "dialog_online.html" %}