Skip to content

Commit 04afa48

Browse files
committed
feat(infra): make database engine configurable
Add support for pluggable database backends via SHELLHUB_DATABASE env var. MongoDB service moved from main docker-compose.yml to separate compose files. - Add SHELLHUB_DATABASE env var (defaults to mongo) - Add logic in bin/utils to load database-specific compose files - Remove hardcoded mongo service from main docker-compose.yml
1 parent 73f28f5 commit 04afa48

File tree

8 files changed

+125
-93
lines changed

8 files changed

+125
-93
lines changed

.env

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ SHELLHUB_PROXY=false
3434
# Enable automatic HTTPS with Let's Encrypt.
3535
SHELLHUB_AUTO_SSL=false
3636

37+
SHELLHUB_DATABASE=mongo
38+
3739
# The domain of the server.
3840
# NOTICE: Required only if automatic HTTPS is enabled.
3941
# VALUES: A valid domain name

bin/utils

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,18 @@ COMPOSE_FILE="docker-compose.yml"
7171
[ "$SHELLHUB_ENTERPRISE" = "true" ] && [ "$SHELLHUB_ENV" != "development" ] && COMPOSE_FILE="${COMPOSE_FILE}:docker-compose.enterprise.yml"
7272
[ -f docker-compose.override.yml ] && COMPOSE_FILE="${COMPOSE_FILE}:docker-compose.override.yml"
7373

74+
SHELLHUB_DATABASE=${SHELLHUB_DATABASE:-mongo}
75+
case "$SHELLHUB_DATABASE" in
76+
mongo)
77+
COMPOSE_FILE="${COMPOSE_FILE}:docker-compose.${SHELLHUB_DATABASE}.yml"
78+
;;
79+
*)
80+
echo "⚠️ WARNING: Unknown SHELLHUB_DATABASE '$SHELLHUB_DATABASE'. Defaulting to mongodb."
81+
SHELLHUB_DATABASE="mongodb"
82+
COMPOSE_FILE="${COMPOSE_FILE}:docker-compose.mongodb.yml"
83+
;;
84+
esac
85+
7486
[ -f "$EXTRA_COMPOSE_FILE" ] && COMPOSE_FILE="${COMPOSE_FILE}:${EXTRA_COMPOSE_FILE}"
7587

7688
export COMPOSE_FILE

docker-compose.mongo.test.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
services:
2+
mongo:
3+
image: mongo:4.4.29
4+
restart: unless-stopped
5+
healthcheck:
6+
test: 'test $$(echo "rs.initiate({ _id: ''rs'', members: [ { _id: 0, host: ''mongo:27017'' } ] }).ok || rs.status().ok" | mongo --quiet) -eq 1'
7+
interval: 30s
8+
start_period: 10s
9+
command: ["--replSet", "rs", "--bind_ip_all"]
10+
networks:
11+
- shellhub
12+
api:
13+
depends_on:
14+
mongo:
15+
condition: service_healthy

docker-compose.mongo.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
services:
2+
mongo:
3+
image: mongo:4.4.29
4+
restart: unless-stopped
5+
healthcheck:
6+
test: 'test $$(echo "rs.initiate({ _id: ''rs'', members: [ { _id: 0, host: ''mongo:27017'' } ] }).ok || rs.status().ok" | mongo --quiet) -eq 1'
7+
interval: 30s
8+
start_period: 10s
9+
command: ["--replSet", "rs", "--bind_ip_all"]
10+
networks:
11+
- shellhub
12+
api:
13+
depends_on:
14+
mongo:
15+
condition: service_healthy

docker-compose.test.yml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,3 @@ services:
3434
start_period: 10s
3535
retries: 20
3636
ports: []
37-
mongo:
38-
healthcheck:
39-
interval: 5s
40-
start_period: 10s
41-
retries: 20
42-
ports: []

docker-compose.yml

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,8 @@ services:
6060
- SHELLHUB_INTERNAL_HTTP_CLIENT_API_BASE_URL=${SHELLHUB_INTERNAL_HTTP_CLIENT_API_BASE_URL}
6161
- SHELLHUB_INTERNAL_HTTP_CLIENT_ENTERPRISE_BASE_URL=${SHELLHUB_INTERNAL_HTTP_CLIENT_ENTERPRISE_BASE_URL}
6262
depends_on:
63-
- mongo
6463
- redis
6564
links:
66-
- mongo
6765
- redis
6866
secrets:
6967
- api_private_key
@@ -145,16 +143,6 @@ services:
145143
- SHELLHUB_LOG_FORMAT=${SHELLHUB_LOG_FORMAT}
146144
networks:
147145
- shellhub
148-
mongo:
149-
image: mongo:4.4.29
150-
restart: unless-stopped
151-
healthcheck:
152-
test: 'test $$(echo "rs.initiate({ _id: ''rs'', members: [ { _id: 0, host: ''mongo:27017'' } ] }).ok || rs.status().ok" | mongo --quiet) -eq 1'
153-
interval: 30s
154-
start_period: 10s
155-
command: ["--replSet", "rs", "--bind_ip_all"]
156-
networks:
157-
- shellhub
158146
redis:
159147
image: redis
160148
restart: unless-stopped

tests/environment/configurator.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,15 @@ func (dcc *DockerComposeConfigurator) Up(ctx context.Context) *DockerCompose {
9696
down: nil,
9797
}
9898

99-
tcDc, err := compose.NewDockerComposeWith(
100-
compose.WithStackFiles("../docker-compose.yml", "../docker-compose.test.yml"),
101-
compose.WithLogger(log.New(io.Discard, "", log.LstdFlags)),
102-
)
99+
dockerFiles := []string{"../docker-compose.yml", "../docker-compose.test.yml"}
100+
switch dc.envs["SHELLHUB_DATABASE"] {
101+
case "postgres":
102+
dockerFiles = append(dockerFiles, "../docker-compose.postgres.test.yml")
103+
default:
104+
dockerFiles = append(dockerFiles, "../docker-compose.mongo.test.yml")
105+
}
106+
107+
tcDc, err := compose.NewDockerComposeWith(compose.WithStackFiles(dockerFiles...), compose.WithLogger(log.New(io.Discard, "", log.LstdFlags)))
103108
if !assert.NoError(dcc.t, err) {
104109
assert.FailNow(dcc.t, err.Error())
105110
}

tests/ssh_test.go

Lines changed: 72 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1324,87 +1324,88 @@ func TestSSH(t *testing.T) {
13241324

13251325
ctx := context.Background()
13261326

1327-
compose := environment.New(t).Up(ctx)
1328-
t.Cleanup(func() {
1329-
compose.Down()
1330-
})
1327+
databases := []string{"mongo"}
1328+
for _, db := range databases {
1329+
compose := environment.New(t).WithEnv("SHELLHUB_DATABASE", db).Up(ctx)
1330+
compose.NewUser(t, ShellHubUsername, ShellHubEmail, ShellHubPassword)
1331+
compose.NewNamespace(t, ShellHubUsername, ShellHubNamespaceName, ShellHubNamespace)
13311332

1332-
compose.NewUser(t, ShellHubUsername, ShellHubEmail, ShellHubPassword)
1333-
compose.NewNamespace(t, ShellHubUsername, ShellHubNamespaceName, ShellHubNamespace)
1334-
1335-
auth := models.UserAuthResponse{}
1336-
1337-
require.EventuallyWithT(t, func(tt *assert.CollectT) {
1338-
resp, err := compose.R(ctx).
1339-
SetBody(map[string]string{
1340-
"username": ShellHubUsername,
1341-
"password": ShellHubPassword,
1342-
}).
1343-
SetResult(&auth).
1344-
Post("/api/login")
1345-
assert.Equal(tt, 200, resp.StatusCode())
1346-
assert.NoError(tt, err)
1347-
}, 30*time.Second, 1*time.Second)
1348-
1349-
compose.JWT(auth.Token)
1350-
1351-
for _, tc := range tests {
1352-
test := tc
1353-
t.Run(test.name, func(tt *testing.T) {
1354-
agent, err := NewAgentContainer(
1355-
ctx,
1356-
compose.Env("SHELLHUB_HTTP_PORT"),
1357-
test.options...,
1358-
)
1359-
require.NoError(tt, err)
1360-
1361-
agent.Stop(ctx, nil)
1362-
1363-
err = agent.Start(ctx)
1364-
require.NoError(tt, err)
1365-
1366-
tt.Cleanup(func() {
1367-
agent.Stop(context.Background(), nil)
1368-
})
1369-
1370-
t.Cleanup(func() {
1371-
agent.Terminate(context.Background())
1372-
})
1333+
auth := models.UserAuthResponse{}
13731334

1374-
devices := []models.Device{}
1335+
require.EventuallyWithT(t, func(tt *assert.CollectT) {
1336+
resp, err := compose.R(ctx).
1337+
SetBody(map[string]string{
1338+
"username": ShellHubUsername,
1339+
"password": ShellHubPassword,
1340+
}).
1341+
SetResult(&auth).
1342+
Post("/api/login")
1343+
assert.Equal(tt, 200, resp.StatusCode())
1344+
assert.NoError(tt, err)
1345+
}, 30*time.Second, 1*time.Second)
1346+
1347+
compose.JWT(auth.Token)
1348+
1349+
for _, tc := range tests {
1350+
test := tc
1351+
t.Run(db+" "+test.name, func(tt *testing.T) {
1352+
agent, err := NewAgentContainer(
1353+
ctx,
1354+
compose.Env("SHELLHUB_HTTP_PORT"),
1355+
test.options...,
1356+
)
1357+
require.NoError(tt, err)
1358+
1359+
agent.Stop(ctx, nil)
1360+
1361+
err = agent.Start(ctx)
1362+
require.NoError(tt, err)
1363+
1364+
tt.Cleanup(func() {
1365+
agent.Stop(context.Background(), nil)
1366+
})
13751367

1376-
require.EventuallyWithT(tt, func(tt *assert.CollectT) {
1377-
resp, err := compose.R(ctx).SetResult(&devices).
1378-
Get("/api/devices?status=pending")
1379-
assert.Equal(tt, 200, resp.StatusCode())
1380-
assert.NoError(tt, err)
1368+
t.Cleanup(func() {
1369+
agent.Terminate(context.Background())
1370+
})
13811371

1382-
assert.Len(tt, devices, 1)
1383-
}, 30*time.Second, 1*time.Second)
1372+
devices := []models.Device{}
13841373

1385-
resp, err := compose.R(ctx).
1386-
Patch(fmt.Sprintf("/api/devices/%s/accept", devices[0].UID))
1387-
require.Equal(tt, 200, resp.StatusCode())
1388-
require.NoError(tt, err)
1374+
require.EventuallyWithT(tt, func(tt *assert.CollectT) {
1375+
resp, err := compose.R(ctx).SetResult(&devices).
1376+
Get("/api/devices?status=pending")
1377+
assert.Equal(tt, 200, resp.StatusCode())
1378+
assert.NoError(tt, err)
13891379

1390-
device := models.Device{}
1380+
assert.Len(tt, devices, 1)
1381+
}, 30*time.Second, 1*time.Second)
13911382

1392-
require.EventuallyWithT(tt, func(tt *assert.CollectT) {
13931383
resp, err := compose.R(ctx).
1394-
SetResult(&device).
1395-
Get(fmt.Sprintf("/api/devices/%s", devices[0].UID))
1396-
assert.Equal(tt, 200, resp.StatusCode())
1397-
assert.NoError(tt, err)
1384+
Patch(fmt.Sprintf("/api/devices/%s/accept", devices[0].UID))
1385+
require.Equal(tt, 200, resp.StatusCode())
1386+
require.NoError(tt, err)
1387+
1388+
device := models.Device{}
1389+
1390+
require.EventuallyWithT(tt, func(tt *assert.CollectT) {
1391+
resp, err := compose.R(ctx).
1392+
SetResult(&device).
1393+
Get(fmt.Sprintf("/api/devices/%s", devices[0].UID))
1394+
assert.Equal(tt, 200, resp.StatusCode())
1395+
assert.NoError(tt, err)
13981396

1399-
assert.True(tt, device.Online)
1400-
}, 30*time.Second, 1*time.Second)
1397+
assert.True(tt, device.Online)
1398+
}, 30*time.Second, 1*time.Second)
14011399

1402-
// --
1400+
// --
14031401

1404-
test.run(tt, &Environment{
1405-
services: compose,
1406-
agent: agent,
1407-
}, &device)
1408-
})
1402+
test.run(tt, &Environment{
1403+
services: compose,
1404+
agent: agent,
1405+
}, &device)
1406+
})
1407+
}
1408+
1409+
compose.Down()
14091410
}
14101411
}

0 commit comments

Comments
 (0)