Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 563d014

Browse filesBrowse files
Merge branch '88-lvm-support' into 'master'
feat: LVM snapshots/clone as an alternative to ZFS Closes #88 and #103 See merge request postgres-ai/database-lab!82
2 parents c015cb1 + c8f76e5 commit 563d014
Copy full SHA for 563d014

20 files changed

+1248
-847
lines changed

‎.gitlab-ci.yml

Copy file name to clipboardExpand all lines: .gitlab-ci.yml
+33-1Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ build-binary-alpine:
2020
stage: build-binary
2121
only:
2222
refs:
23-
- master
23+
- branches
2424
- tags
2525
artifacts:
2626
paths:
@@ -67,6 +67,38 @@ build-binary-generic:
6767
only:
6868
- master
6969

70+
.only_var_template: &only_feature
71+
only:
72+
variables:
73+
- $CI_COMMIT_TAG == null
74+
- $CI_COMMIT_REF_SLUG != "master"
75+
76+
build-image-feature-server:
77+
<<: *build_image_definition
78+
<<: *only_feature
79+
variables:
80+
REGISTRY_USER: "${CI_REGISTRY_USER}"
81+
REGISTRY_PASSWORD: "${CI_REGISTRY_PASSWORD}"
82+
REGISTRY: "${CI_REGISTRY}"
83+
DOCKER_FILE: "Dockerfile.dblab-server"
84+
DOCKER_NAME: "registry.gitlab.com/postgres-ai/database-lab/dblab-server"
85+
TAGS: "${DOCKER_NAME}:${CI_COMMIT_REF_SLUG}"
86+
before_script:
87+
- cp ./bin/dblab-server-alpine ./bin/dblab-server
88+
89+
build-image-feature-client:
90+
<<: *build_image_definition
91+
<<: *only_feature
92+
variables:
93+
REGISTRY_USER: "${CI_REGISTRY_USER}"
94+
REGISTRY_PASSWORD: "${CI_REGISTRY_PASSWORD}"
95+
REGISTRY: "${CI_REGISTRY}"
96+
DOCKER_FILE: "Dockerfile.dblab"
97+
DOCKER_NAME: "registry.gitlab.com/postgres-ai/database-lab/dblab"
98+
TAGS: "${DOCKER_NAME}:${CI_COMMIT_REF_SLUG}"
99+
before_script:
100+
- cp ./bin/dblab-alpine ./bin/dblab
101+
70102
build-image-master-server:
71103
<<: *build_image_definition
72104
<<: *only_master

‎Dockerfile.dblab-server

Copy file name to clipboardExpand all lines: Dockerfile.dblab-server
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
FROM docker:19
3333

3434
# Install dependecies.
35-
RUN apk update && apk add --no-cache zfs bash
35+
RUN apk update && apk add --no-cache zfs lvm2 bash
3636

3737
WORKDIR /home/dblab
3838

‎cmd/database-lab/main.go

Copy file name to clipboardExpand all lines: cmd/database-lab/main.go
+3-3Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,15 @@ func main() {
5757

5858
// TODO(anatoly): Annotate envs in configs. Use different lib for flags/configs?
5959
if len(opts.MountDir) > 0 {
60-
cfg.Provision.ModeZfs.MountDir = opts.MountDir
60+
cfg.Provision.ModeLocal.MountDir = opts.MountDir
6161
}
6262

6363
if len(opts.UnixSocketDir) > 0 {
64-
cfg.Provision.ModeZfs.UnixSocketDir = opts.UnixSocketDir
64+
cfg.Provision.ModeLocal.UnixSocketDir = opts.UnixSocketDir
6565
}
6666

6767
if len(opts.DockerImage) > 0 {
68-
cfg.Provision.ModeZfs.DockerImage = opts.DockerImage
68+
cfg.Provision.ModeLocal.DockerImage = opts.DockerImage
6969
}
7070

7171
provisionSvc, err := provision.NewProvision(ctx, cfg.Provision)

‎configs/config.sample.yml

Copy file name to clipboardExpand all lines: configs/config.sample.yml
+9-6Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ server:
66
port: 3000
77

88
provision:
9-
# Provision mode to use. More comming soon (e.g., LVM, Ceph).
10-
mode: "zfs"
9+
# Provision mode to use.
10+
mode: "local"
1111

1212
# Subdir where PGDATA located relative to the pool root dir.
1313
pgDataSubdir: "/"
@@ -16,9 +16,12 @@ provision:
1616
# The user should exist.
1717
pgMgmtUsername: "postgres"
1818

19-
# ZFS mode related parameters.
20-
zfs:
21-
# Name of your ZFS pool.
19+
# "Local" mode related parameters.
20+
local:
21+
# Which volume manager to use. Available options: "zfs", "lvm".
22+
volumeManager: "zfs"
23+
24+
# Name of your pool or volume group with logic volume name (e.g. "dblab_vg/pg1_lv").
2225
pool: "dblab_pool"
2326

2427
# Pool of ports for Postgres clones.
@@ -45,7 +48,7 @@ provision:
4548
# is recommended in case if customization is needed.
4649
dockerImage: "postgres:12-alpine"
4750

48-
# Use sudo for ZFS and Docker commands if Database Lab server running
51+
# Use sudo for ZFS/LVM and Docker commands if Database Lab server running
4952
# outside a container.
5053
useSudo: false
5154

‎pkg/services/cloning/cloning.go

Copy file name to clipboardExpand all lines: pkg/services/cloning/cloning.go
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"gitlab.com/postgres-ai/database-lab/pkg/log"
1515
"gitlab.com/postgres-ai/database-lab/pkg/models"
1616
"gitlab.com/postgres-ai/database-lab/pkg/services/provision"
17+
"gitlab.com/postgres-ai/database-lab/pkg/services/provision/resources"
1718
)
1819

1920
const (
@@ -56,7 +57,7 @@ type Cloning interface {
5657
// CloneWrapper represents a cloning service wrapper.
5758
type CloneWrapper struct {
5859
clone *models.Clone
59-
session *provision.Session
60+
session *resources.Session
6061

6162
timeCreatedAt time.Time
6263
timeStartedAt time.Time

‎pkg/services/cloning/mode_base.go

Copy file name to clipboardExpand all lines: pkg/services/cloning/mode_base.go
+12-9Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"gitlab.com/postgres-ai/database-lab/pkg/log"
2121
"gitlab.com/postgres-ai/database-lab/pkg/models"
2222
"gitlab.com/postgres-ai/database-lab/pkg/services/provision"
23+
"gitlab.com/postgres-ai/database-lab/pkg/services/provision/resources"
2324
"gitlab.com/postgres-ai/database-lab/pkg/util"
2425
"gitlab.com/postgres-ai/database-lab/pkg/util/pglog"
2526
)
@@ -122,11 +123,13 @@ func (c *baseCloning) CreateClone(clone *models.Clone) error {
122123
session, err := c.provision.StartSession(w.username, w.password, w.snapshot.ID)
123124
if err != nil {
124125
// TODO(anatoly): Empty room case.
126+
log.Errf("Failed to create a clone: %+v.", err)
127+
125128
if err := c.updateCloneStatus(cloneID, models.Status{
126129
Code: models.StatusFatal,
127130
Message: models.CloneMessageFatal,
128131
}); err != nil {
129-
log.Errf("failed to update clone status: %v", err)
132+
log.Errf("Failed to update clone status: %v", err)
130133
}
131134

132135
return
@@ -193,15 +196,15 @@ func (c *baseCloning) DestroyClone(cloneID string) error {
193196

194197
go func() {
195198
if err := c.provision.StopSession(w.session); err != nil {
199+
log.Errf("Failed to delete a clone: %+v.", err)
200+
196201
if err := c.updateCloneStatus(cloneID, models.Status{
197202
Code: models.StatusFatal,
198203
Message: models.CloneMessageFatal,
199204
}); err != nil {
200205
log.Errf("Failed to update clone status: %v", err)
201206
}
202207

203-
log.Errf("Failed to delete clone: %+v.", err)
204-
205208
return
206209
}
207210

@@ -304,15 +307,15 @@ func (c *baseCloning) ResetClone(cloneID string) error {
304307
go func() {
305308
err := c.provision.ResetSession(w.session, w.snapshot.ID)
306309
if err != nil {
310+
log.Errf("Failed to reset a clone: %+v.", err)
311+
307312
if err := c.updateCloneStatus(cloneID, models.Status{
308313
Code: models.StatusFatal,
309314
Message: models.CloneMessageFatal,
310315
}); err != nil {
311316
log.Errf("failed to update clone status: %v", err)
312317
}
313318

314-
log.Errf("Failed to reset session: %+v.", err)
315-
316319
return
317320
}
318321

@@ -541,7 +544,7 @@ func (c *baseCloning) isIdleClone(wrapper *CloneWrapper) (bool, error) {
541544
const pgDriverName = "postgres"
542545

543546
// hasNotQueryActivity opens connection and checks if there is no any query running by a user.
544-
func hasNotQueryActivity(session *provision.Session) (bool, error) {
547+
func hasNotQueryActivity(session *resources.Session) (bool, error) {
545548
log.Dbg(fmt.Sprintf("Check an active query for: %q.", session.ID))
546549

547550
db, err := sql.Open(pgDriverName, getSocketConnStr(session))
@@ -560,7 +563,7 @@ func hasNotQueryActivity(session *provision.Session) (bool, error) {
560563
}
561564

562565
// TODO(akartasov): Move the function to the provision service.
563-
func getSocketConnStr(session *provision.Session) string {
566+
func getSocketConnStr(session *resources.Session) string {
564567
return fmt.Sprintf("host=%s user=%s dbname=postgres", session.SocketHost, session.User)
565568
}
566569

@@ -569,8 +572,8 @@ func checkActiveQueryNotExists(db *sql.DB) (bool, error) {
569572
var isRunningQueryNotExists bool
570573

571574
query := `select not exists (
572-
select * from pg_stat_activity
573-
where state <> 'idle' and query not like 'autovacuum: %' and pid <> pg_backend_pid()
575+
select * from pg_stat_activity
576+
where state <> 'idle' and query not like 'autovacuum: %' and pid <> pg_backend_pid()
574577
)`
575578
err := db.QueryRow(query).Scan(&isRunningQueryNotExists)
576579

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.