Hermes Agent commited on
Commit
63faace
·
1 Parent(s): 01b5c2b

feat: implement database self-healing daemon to clean corrupted session directories

Browse files
Files changed (2) hide show
  1. Dockerfile +6 -3
  2. cleaner.py +64 -0
Dockerfile CHANGED
@@ -2,11 +2,12 @@ FROM debian:bookworm-slim
2
 
3
  ARG OPENCODE_VERSION=1.18.3
4
 
5
- # Install dependencies (including git for project initialization)
6
  RUN apt-get update && apt-get install -y --no-install-recommends \
7
  curl \
8
  ca-certificates \
9
  git \
 
10
  && rm -rf /var/lib/apt/lists/*
11
 
12
  # Download opencode binary
@@ -19,9 +20,11 @@ RUN useradd -m -s /bin/bash opencode
19
  # Working directory for projects
20
  RUN mkdir -p /projects/default && chown -R opencode:opencode /projects
21
 
 
 
22
  WORKDIR /projects/default
23
 
24
  EXPOSE 4096
25
 
26
- # Default: check if git is initialized (in case of persistent volume mount) and serve
27
- CMD ["sh", "-c", "if [ ! -d .git ]; then git init && git config user.email 'opencode@local.com' && git config user.name 'OpenCode' && git commit --allow-empty -m 'Initial commit'; fi; exec opencode serve --port 4096 --hostname 0.0.0.0"]
 
2
 
3
  ARG OPENCODE_VERSION=1.18.3
4
 
5
+ # Install dependencies (including git for project initialization and python3 for DB self-healing)
6
  RUN apt-get update && apt-get install -y --no-install-recommends \
7
  curl \
8
  ca-certificates \
9
  git \
10
+ python3 \
11
  && rm -rf /var/lib/apt/lists/*
12
 
13
  # Download opencode binary
 
20
  # Working directory for projects
21
  RUN mkdir -p /projects/default && chown -R opencode:opencode /projects
22
 
23
+ COPY cleaner.py /cleaner.py
24
+
25
  WORKDIR /projects/default
26
 
27
  EXPOSE 4096
28
 
29
+ # Default: start database self-healing daemon, check if git is initialized, and serve opencode
30
+ CMD ["sh", "-c", "python3 /cleaner.py & if [ ! -d .git ]; then git init && git config user.email 'opencode@local.com' && git config user.name 'OpenCode' && git commit --allow-empty -m 'Initial commit'; fi; exec opencode serve --port 4096 --hostname 0.0.0.0"]
cleaner.py ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sqlite3
2
+ import time
3
+ import os
4
+
5
+ db_paths = [
6
+ "/root/.local/share/opencode/opencode.db",
7
+ "/home/opencode/.local/share/opencode/opencode.db",
8
+ ]
9
+
10
+ # Find the active database file
11
+ db_path = None
12
+ for path in db_paths:
13
+ if os.path.exists(path):
14
+ db_path = path
15
+ break
16
+
17
+ if not db_path:
18
+ db_path = os.path.expanduser("~/.local/share/opencode/opencode.db")
19
+
20
+ print(f"OpenCode Self-Healing Daemon: watching database {db_path}...", flush=True)
21
+
22
+ while True:
23
+ time.sleep(5)
24
+ if not os.path.exists(db_path):
25
+ continue
26
+ try:
27
+ conn = sqlite3.connect(db_path)
28
+ cursor = conn.cursor()
29
+
30
+ # Check if session table exists
31
+ cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='session'")
32
+ if not cursor.fetchone():
33
+ conn.close()
34
+ continue
35
+
36
+ # 1. Update directory to a safe path if it contains invalid characters
37
+ cursor.execute("SELECT id, directory FROM session")
38
+ rows = cursor.fetchall()
39
+ for row_id, directory in rows:
40
+ if directory and ("\ufffd" in directory or "\xef\xbf\xbd" in directory or "??#y" in directory):
41
+ print(f"[Self-Healing] Found corrupted directory '{directory}' in session '{row_id}'. Fixing to '/projects/default'...", flush=True)
42
+ cursor.execute(
43
+ "UPDATE session SET directory = ? WHERE id = ?",
44
+ ("/projects/default", row_id)
45
+ )
46
+ conn.commit()
47
+
48
+ # 2. Clean up project_directory table if it exists
49
+ cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='project_directory'")
50
+ if cursor.fetchone():
51
+ cursor.execute("SELECT project_id, directory FROM project_directory")
52
+ p_rows = cursor.fetchall()
53
+ for p_id, directory in p_rows:
54
+ if directory and ("\ufffd" in directory or "\xef\xbf\xbd" in directory or "??#y" in directory):
55
+ print(f"[Self-Healing] Found corrupted directory '{directory}' in project_directory '{p_id}'. Deleting...", flush=True)
56
+ cursor.execute(
57
+ "DELETE FROM project_directory WHERE project_id = ? AND directory = ?",
58
+ (p_id, directory)
59
+ )
60
+ conn.commit()
61
+
62
+ conn.close()
63
+ except Exception as e:
64
+ print("[Self-Healing Error]:", e, flush=True)