Skip to content

Commit 40c02ea

Browse files
fix: detect Docker Desktop socket and complete migrations
1 parent 7a326da commit 40c02ea

3 files changed

Lines changed: 38 additions & 23 deletions

File tree

‎cmd/stackhost/applications.go‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,8 +306,10 @@ func (a *app) applicationRuntime(w http.ResponseWriter, r *http.Request, id int6
306306
_ = a.db.QueryRow("SELECT runtime_mode FROM environment_settings WHERE id=1").Scan(&mode)
307307
services := []map[string]any{}
308308
status := "not_deployed"
309+
ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
310+
defer cancel()
309311
if mode == "swarm" {
310-
cmd := exec.CommandContext(r.Context(), "docker", "service", "ls", "--filter", "label=com.docker.stack.namespace="+stackName, "--format", "{{json .}}")
312+
cmd := exec.CommandContext(ctx, "docker", "service", "ls", "--filter", "label=com.docker.stack.namespace="+stackName, "--format", "{{json .}}")
311313
if output, err := cmd.Output(); err == nil {
312314
for _, line := range strings.Split(strings.TrimSpace(string(output)), "\n") {
313315
var item struct{ Name, Image, Replicas string }
@@ -321,7 +323,7 @@ func (a *app) applicationRuntime(w http.ResponseWriter, r *http.Request, id int6
321323
}
322324
}
323325
} else {
324-
cmd := exec.CommandContext(r.Context(), "docker", "compose", "--project-name", stackName, "ps", "--format", "json")
326+
cmd := exec.CommandContext(ctx, "docker", "compose", "--project-name", stackName, "ps", "--format", "json")
325327
if output, err := cmd.Output(); err == nil {
326328
var items []struct{ Service, Image, State string }
327329
if json.Unmarshal(output, &items) != nil {

‎cmd/stackhost/main.go‎

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -119,29 +119,30 @@ func migrate(db *sql.DB) error {
119119
}
120120
var version2 int
121121
_ = db.QueryRow("SELECT count(*) FROM schema_migrations WHERE version=2").Scan(&version2)
122-
if version2 > 0 {
123-
_, _ = db.Exec(`CREATE TABLE IF NOT EXISTS environment_settings(id INTEGER PRIMARY KEY, runtime_mode TEXT NOT NULL DEFAULT 'standalone', updated_at TEXT NOT NULL)`)
124-
_, _ = db.Exec(`INSERT INTO environment_settings(id,runtime_mode,updated_at) SELECT 1,'standalone',? WHERE NOT EXISTS (SELECT 1 FROM environment_settings WHERE id=1)`, time.Now().UTC().Format(time.RFC3339))
125-
return nil
126-
}
127-
tx, err := db.Begin()
128-
if err != nil {
129-
return err
130-
}
131-
defer tx.Rollback()
132-
for _, column := range []string{"description TEXT NOT NULL DEFAULT ''", "configuration_status TEXT NOT NULL DEFAULT 'draft'", "configured_at TEXT", "last_validated_at TEXT", "source_revision INTEGER NOT NULL DEFAULT 0"} {
133-
if _, err = tx.Exec("ALTER TABLE applications ADD COLUMN " + column); err != nil && !strings.Contains(err.Error(), "duplicate column") {
122+
if version2 == 0 {
123+
tx, err := db.Begin()
124+
if err != nil {
125+
return err
126+
}
127+
defer tx.Rollback()
128+
for _, column := range []string{"description TEXT NOT NULL DEFAULT ''", "configuration_status TEXT NOT NULL DEFAULT 'draft'", "configured_at TEXT", "last_validated_at TEXT", "source_revision INTEGER NOT NULL DEFAULT 0"} {
129+
if _, err = tx.Exec("ALTER TABLE applications ADD COLUMN " + column); err != nil && !strings.Contains(err.Error(), "duplicate column") {
130+
return err
131+
}
132+
}
133+
if _, err = tx.Exec(`UPDATE applications SET configuration_status='draft' WHERE status='unknown'; CREATE TABLE IF NOT EXISTS application_sources(id INTEGER PRIMARY KEY, application_id INTEGER NOT NULL UNIQUE REFERENCES applications(id) ON DELETE CASCADE, source_type TEXT NOT NULL, encrypted_payload BLOB NOT NULL, encryption_nonce BLOB NOT NULL, payload_version INTEGER NOT NULL DEFAULT 1, checksum TEXT NOT NULL, validation_status TEXT NOT NULL DEFAULT 'draft', validation_errors TEXT NOT NULL DEFAULT '[]', validation_warnings TEXT NOT NULL DEFAULT '[]', summary_json TEXT NOT NULL DEFAULT '{}', created_at TEXT NOT NULL, updated_at TEXT NOT NULL); CREATE INDEX IF NOT EXISTS idx_application_sources_application ON application_sources(application_id); INSERT INTO schema_migrations(version,applied_at) VALUES(2,?)`, time.Now().UTC().Format(time.RFC3339)); err != nil {
134+
return err
135+
}
136+
if err := tx.Commit(); err != nil {
134137
return err
135138
}
136139
}
137-
if _, err = tx.Exec(`UPDATE applications SET configuration_status='draft' WHERE status='unknown'; CREATE TABLE IF NOT EXISTS application_sources(id INTEGER PRIMARY KEY, application_id INTEGER NOT NULL UNIQUE REFERENCES applications(id) ON DELETE CASCADE, source_type TEXT NOT NULL, encrypted_payload BLOB NOT NULL, encryption_nonce BLOB NOT NULL, payload_version INTEGER NOT NULL DEFAULT 1, checksum TEXT NOT NULL, validation_status TEXT NOT NULL DEFAULT 'draft', validation_errors TEXT NOT NULL DEFAULT '[]', validation_warnings TEXT NOT NULL DEFAULT '[]', summary_json TEXT NOT NULL DEFAULT '{}', created_at TEXT NOT NULL, updated_at TEXT NOT NULL); CREATE INDEX IF NOT EXISTS idx_application_sources_application ON application_sources(application_id); INSERT INTO schema_migrations(version,applied_at) VALUES(2,?)`, time.Now().UTC().Format(time.RFC3339)); err != nil {
138-
return err
139-
}
140-
if err := tx.Commit(); err != nil {
141-
return err
142-
}
143-
if _, err := db.Exec(`CREATE TABLE IF NOT EXISTS environment_settings(id INTEGER PRIMARY KEY, runtime_mode TEXT NOT NULL DEFAULT 'standalone', updated_at TEXT NOT NULL); INSERT OR IGNORE INTO environment_settings(id,runtime_mode,updated_at) VALUES(1,'standalone',?)`, time.Now().UTC().Format(time.RFC3339)); err != nil {
144-
return err
140+
var version3 int
141+
_ = db.QueryRow("SELECT count(*) FROM schema_migrations WHERE version=3").Scan(&version3)
142+
if version3 == 0 {
143+
if _, err := db.Exec(`CREATE TABLE IF NOT EXISTS environment_settings(id INTEGER PRIMARY KEY, runtime_mode TEXT NOT NULL DEFAULT 'standalone', updated_at TEXT NOT NULL); INSERT OR IGNORE INTO environment_settings(id,runtime_mode,updated_at) VALUES(1,'standalone',?); INSERT INTO schema_migrations(version,applied_at) VALUES(3,?)`, time.Now().UTC().Format(time.RFC3339), time.Now().UTC().Format(time.RFC3339)); err != nil {
144+
return err
145+
}
145146
}
146147
return nil
147148
}
@@ -201,7 +202,7 @@ func (a *app) ready(w http.ResponseWriter, r *http.Request) {
201202
return
202203
}
203204
var migrations int
204-
if err := a.db.QueryRow("SELECT count(*) FROM schema_migrations WHERE version=2").Scan(&migrations); err != nil || migrations != 1 {
205+
if err := a.db.QueryRow("SELECT count(*) FROM schema_migrations WHERE version=3").Scan(&migrations); err != nil || migrations != 1 {
205206
http.Error(w, `{"status":"not_ready","reason":"migrations"}`, 503)
206207
return
207208
}

‎internal/docker/reader.go‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"fmt"
66
"os"
7+
"path/filepath"
78
"strings"
89
"time"
910

@@ -106,6 +107,17 @@ func activeSwarm(info swarm.Info) bool {
106107

107108
func NewReader() (*Reader, error) {
108109
host := os.Getenv("STACKHOST_DOCKER_HOST")
110+
if host == "" {
111+
host = os.Getenv("DOCKER_HOST")
112+
}
113+
if host == "" {
114+
if home, err := os.UserHomeDir(); err == nil {
115+
desktopSocket := filepath.Join(home, ".docker", "run", "docker.sock")
116+
if _, err := os.Stat(desktopSocket); err == nil {
117+
host = "unix://" + desktopSocket
118+
}
119+
}
120+
}
109121
opts := []client.Opt{client.FromEnv}
110122
if host != "" {
111123
opts = []client.Opt{client.WithHost(host)}

0 commit comments

Comments
 (0)