Skip to content

Commit 33e0870

Browse files
committed
Merge branch '240-run-ci' into 'master'
feat: provide service to automatically validate DB migrations in the CI pipeline (#240) Closes #240 See merge request postgres-ai/database-lab!275
2 parents 2602645 + 6c13b5c commit 33e0870

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+1693
-282
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@
88
/deploy/
99

1010
/configs/config.yml
11+
/configs/run_ci.yaml

.gitlab-ci.yml

+11
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,17 @@ build-image-feature-server:
124124
DOCKER_NAME: "registry.gitlab.com/postgres-ai/database-lab/dblab-server"
125125
TAGS: "${DOCKER_NAME}:${CI_COMMIT_REF_SLUG}"
126126

127+
build-image-feature-ci-checker:
128+
<<: *build_image_definition
129+
<<: *only_feature
130+
variables:
131+
REGISTRY_USER: "${CI_REGISTRY_USER}"
132+
REGISTRY_PASSWORD: "${CI_REGISTRY_PASSWORD}"
133+
REGISTRY: "${CI_REGISTRY}"
134+
DOCKER_FILE: "Dockerfile.ci-checker"
135+
DOCKER_NAME: "registry.gitlab.com/postgres-ai/database-lab/dblab-ci-checker"
136+
TAGS: "${DOCKER_NAME}:${CI_COMMIT_REF_SLUG}"
137+
127138
build-image-feature-client:
128139
<<: *build_image_definition
129140
<<: *only_feature

.golangci.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,4 +99,4 @@ issues:
9999
max-issues-per-linter: 0
100100
max-same-issues: 0
101101

102-
new-from-rev: 66fcab89
102+
new-from-rev: 9e951ebe

Dockerfile.ci-checker

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
FROM docker:19.03.14
2+
3+
# Install dependencies.
4+
RUN apk update && apk add --no-cache bash
5+
6+
WORKDIR /home/dblab
7+
8+
COPY ./bin/run-ci ./bin/run-ci
9+
COPY ./configs ./configs
10+
11+
CMD ./bin/run-ci

Dockerfile.runci

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
FROM sqitch/sqitch:1.0.0
2+
3+
ENTRYPOINT ["/bin/bash"]
4+
5+
RUN echo "#!/bin/bash" > /tmp/pg_start.sh && chmod a+x /tmp/pg_start.sh \
6+
&& echo "/bin/bash -c \"trap : TERM INT; sleep infinity & wait\"" \
7+
>> /tmp/pg_start.sh
8+
9+
CMD ["/tmp/pg_start.sh"]

Makefile

+5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
.DEFAULT_GOAL = all
22

33
SERVER_BINARY = dblab-server
4+
RUN_CI_BINARY = run-ci
45
CLI_BINARY = dblab
56
GOARCH = amd64
67

@@ -38,8 +39,12 @@ lint: install-lint run-lint
3839

3940
build:
4041
${GOBUILD} -o bin/${SERVER_BINARY} ./cmd/database-lab/main.go
42+
${GOBUILD} -o bin/${RUN_CI_BINARY} ./cmd/runci/main.go
4143
${GOBUILD} -o bin/${CLI_BINARY} ./cmd/cli/main.go
4244

45+
build-ci-checker:
46+
${GOBUILD} -o bin/${RUN_CI_BINARY} ./cmd/runci/main.go
47+
4348
build-client:
4449
$(foreach GOOS, $(CLIENT_PLATFORMS),\
4550
$(foreach GOARCH, $(ARCHITECTURES), \

cmd/cli/commands/clone/actions.go

+34-3
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,21 @@ package clone
88
import (
99
"encoding/json"
1010
"fmt"
11+
"io"
1112
"net/url"
13+
"os"
14+
"path"
1215
"strings"
1316
"sync"
1417

18+
"github.com/pkg/errors"
1519
"github.com/urfave/cli/v2"
1620

1721
"gitlab.com/postgres-ai/database-lab/v2/cmd/cli/commands"
1822
"gitlab.com/postgres-ai/database-lab/v2/pkg/client/dblabapi/types"
1923
"gitlab.com/postgres-ai/database-lab/v2/pkg/log"
2024
"gitlab.com/postgres-ai/database-lab/v2/pkg/models"
25+
"gitlab.com/postgres-ai/database-lab/v2/pkg/observer"
2126
)
2227

2328
// list runs a request to list clones of an instance.
@@ -291,14 +296,40 @@ func downloadArtifact(cliCtx *cli.Context) error {
291296
cloneID := cliCtx.String("clone-id")
292297
sessionID := cliCtx.String("session-id")
293298
artifactType := cliCtx.String("artifact-type")
294-
outputFile := cliCtx.String("output")
299+
outputPath := cliCtx.String("output")
295300

296-
artifactPath, err := dblabClient.DownloadArtifact(cliCtx.Context, cloneID, sessionID, artifactType, outputFile)
301+
body, err := dblabClient.DownloadArtifact(cliCtx.Context, cloneID, sessionID, artifactType)
297302
if err != nil {
298303
return err
299304
}
300305

301-
_, err = fmt.Fprintf(cliCtx.App.Writer, "The file has been successfully downloaded: %s\n", artifactPath)
306+
defer func() {
307+
if err := body.Close(); err != nil {
308+
log.Err(err)
309+
}
310+
}()
311+
312+
if outputPath == "" {
313+
wd, err := os.Getwd()
314+
if err != nil {
315+
return err
316+
}
317+
318+
outputPath = path.Join(wd, observer.BuildArtifactFilename(artifactType))
319+
}
320+
321+
artifactFile, err := os.Create(outputPath)
322+
if err != nil {
323+
return errors.Wrapf(err, "failed to create file %s", outputPath)
324+
}
325+
326+
defer func() { _ = artifactFile.Close() }()
327+
328+
if _, err := io.Copy(artifactFile, body); err != nil {
329+
return err
330+
}
331+
332+
_, err = fmt.Fprintf(cliCtx.App.Writer, "The file has been successfully downloaded: %s\n", outputPath)
302333

303334
return err
304335
}

cmd/cli/main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func main() {
2727
},
2828
Before: loadEnvironmentParams,
2929
Commands: joinCommands(
30-
// Global commands.
30+
// Config commands.
3131
global.List(),
3232

3333
// Database Lab API.

cmd/database-lab/main.go

+64-3
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,14 @@ import (
1616
"syscall"
1717
"time"
1818

19+
"github.com/docker/docker/api/types"
20+
"github.com/docker/docker/api/types/network"
1921
"github.com/docker/docker/client"
2022
"github.com/pkg/errors"
2123
"github.com/rs/xid"
2224

2325
"gitlab.com/postgres-ai/database-lab/v2/pkg/config"
26+
"gitlab.com/postgres-ai/database-lab/v2/pkg/config/global"
2427
"gitlab.com/postgres-ai/database-lab/v2/pkg/estimator"
2528
"gitlab.com/postgres-ai/database-lab/v2/pkg/log"
2629
"gitlab.com/postgres-ai/database-lab/v2/pkg/observer"
@@ -33,6 +36,7 @@ import (
3336
"gitlab.com/postgres-ai/database-lab/v2/pkg/services/provision/resources"
3437
"gitlab.com/postgres-ai/database-lab/v2/pkg/services/provision/runners"
3538
"gitlab.com/postgres-ai/database-lab/v2/pkg/srv"
39+
"gitlab.com/postgres-ai/database-lab/v2/pkg/util/networks"
3640
"gitlab.com/postgres-ai/database-lab/v2/version"
3741
)
3842

@@ -67,6 +71,63 @@ func main() {
6771
ctx, cancel := context.WithCancel(context.Background())
6872
defer cancel()
6973

74+
hostname := os.Getenv("HOSTNAME")
75+
if hostname == "" {
76+
log.Err("hostname is empty")
77+
}
78+
79+
networkID := "network_" + instanceID
80+
81+
internalNetwork, err := dockerCLI.NetworkCreate(ctx, networkID, types.NetworkCreate{
82+
Labels: map[string]string{
83+
"instance": instanceID,
84+
"app": networks.DLEApp,
85+
"type": networks.InternalType,
86+
},
87+
Attachable: true,
88+
Internal: true,
89+
})
90+
if err != nil {
91+
log.Errf(err.Error())
92+
return
93+
}
94+
95+
defer func() {
96+
networkInspect, err := dockerCLI.NetworkInspect(context.Background(), internalNetwork.ID, types.NetworkInspectOptions{})
97+
if err != nil {
98+
log.Errf(err.Error())
99+
return
100+
}
101+
102+
for _, resource := range networkInspect.Containers {
103+
log.Dbg("Disconnecting container: ", resource.Name)
104+
105+
if err := dockerCLI.NetworkDisconnect(context.Background(), internalNetwork.ID, resource.Name, true); err != nil {
106+
log.Errf(err.Error())
107+
return
108+
}
109+
}
110+
111+
if err := dockerCLI.NetworkRemove(context.Background(), internalNetwork.ID); err != nil {
112+
log.Errf(err.Error())
113+
return
114+
}
115+
}()
116+
117+
log.Dbg("New network: ", internalNetwork.ID)
118+
119+
if err := dockerCLI.NetworkConnect(ctx, internalNetwork.ID, hostname, &network.EndpointSettings{}); err != nil {
120+
log.Errf(err.Error())
121+
return
122+
}
123+
124+
defer func() {
125+
if err := dockerCLI.NetworkDisconnect(context.Background(), internalNetwork.ID, hostname, true); err != nil {
126+
log.Errf(err.Error())
127+
return
128+
}
129+
}()
130+
70131
// Create a platform service to make requests to Platform.
71132
platformSvc, err := platform.New(ctx, cfg.Platform)
72133
if err != nil {
@@ -95,7 +156,7 @@ func main() {
95156
}
96157

97158
// Create a cloning service to provision new clones.
98-
provisionSvc, err := provision.New(ctx, &cfg.Provision, dbCfg, dockerCLI, pm)
159+
provisionSvc, err := provision.New(ctx, &cfg.Provision, dbCfg, dockerCLI, pm, internalNetwork.ID)
99160
if err != nil {
100161
log.Errf(errors.WithMessage(err, `error in the "provision" section of the config`).Error())
101162
}
@@ -113,7 +174,7 @@ func main() {
113174

114175
go removeObservingClones(obsCh, obs)
115176

116-
server := srv.NewServer(&cfg.Server, obs, cloningSvc, platformSvc, dockerCLI, est)
177+
server := srv.NewServer(&cfg.Server, &cfg.Global, obs, cloningSvc, platformSvc, dockerCLI, est, pm)
117178

118179
reloadCh := setReloadListener()
119180

@@ -220,7 +281,7 @@ func setShutdownListener() chan os.Signal {
220281
return c
221282
}
222283

223-
func shutdownDatabaseLabEngine(ctx context.Context, dockerCLI *client.Client, global config.Global, fsp *resources.Pool) {
284+
func shutdownDatabaseLabEngine(ctx context.Context, dockerCLI *client.Client, global global.Config, fsp *resources.Pool) {
224285
log.Msg("Stopping control containers")
225286

226287
if err := cont.StopControlContainers(ctx, dockerCLI, global.InstanceID, fsp.DataDir()); err != nil {

0 commit comments

Comments
 (0)