Skip to content

Commit 9506bd2

Browse files
added support for docker volumes (#198)
* added support for docker volumes * fixed linting * added test cases for docker volumes * minor fix * fixed linting Co-authored-by: Saurabh Prakash <[email protected]>
1 parent 3be71cf commit 9506bd2

File tree

15 files changed

+296
-117
lines changed

15 files changed

+296
-117
lines changed

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22
"go.lintTool": "golangci-lint",
33
"go.lintFlags": [
44
"--fast"
5-
]
5+
],
6+
"go.testTimeout": "90s"
67
}

cmd/synapse/bin.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ func run(cmd *cobra.Command, args []string) {
9898

9999
// setting up cron handler
100100
wg.Add(1)
101-
go cron.Setup(ctx, &wg, logger)
101+
go cron.Setup(ctx, &wg, logger, runner)
102102

103103
// All attempts to connect to lambdatest server failed
104104
connectionFailed := make(chan struct{})

config/parse.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ func recursivelySet(val reflect.Value, prefix string) error {
9090
return fmt.Errorf("unexpected type detected ~ aborting: %s", thisField.Kind())
9191
}
9292
}
93-
9493
}
9594

9695
return nil

pkg/core/runner.go

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package core
22

33
import (
44
"context"
5+
"time"
56

67
"github.com/LambdaTest/test-at-scale/config"
78
"github.com/LambdaTest/test-at-scale/pkg/errs"
@@ -45,7 +46,7 @@ type DockerRunner interface {
4546
// Run runs the execution engine
4647
Run(context.Context, *RunnerOptions) ContainerStatus
4748

48-
//WaitForRunning waits for runner to get completed
49+
// WaitForRunning waits for runner to get completed
4950
WaitForCompletion(ctx context.Context, r *RunnerOptions) error
5051

5152
// Destroy the execution engine
@@ -62,6 +63,32 @@ type DockerRunner interface {
6263

6364
// KillRunningDocker kills container spawn by synapse
6465
KillRunningDocker(ctx context.Context)
66+
67+
CreateVolume(ctx context.Context, r *RunnerOptions) error
68+
69+
// RemoveOldVolumes removes volumes that are older than X hours
70+
RemoveOldVolumes(ctx context.Context)
71+
72+
// CopyFileToContainer copies content to container in file
73+
CopyFileToContainer(ctx context.Context, path, fileName, containerID string, content []byte) error
74+
75+
// FindVolumes checks if docker volume is available
76+
FindVolumes(volumeName string) (bool, error)
77+
78+
// RemoveVolume removes volume
79+
RemoveVolume(ctx context.Context, volumeName string) error
80+
}
81+
82+
// VolumeDetails docker volume options
83+
type VolumeDetails struct {
84+
CreatedAt time.Time `json:"CreatedAt,omitempty"`
85+
Driver string `json:"Driver"`
86+
Labels map[string]string `json:"Labels"`
87+
Mountpoint string `json:"Mountpoint"`
88+
Name string `json:"Name"`
89+
Options map[string]string `json:"Options"`
90+
Scope string `json:"Scope"`
91+
Status map[string]interface{} `json:"Status,omitempty"`
6592
}
6693

6794
// RunnerOptions provides the the required instructions for execution engine.

pkg/core/secrets.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,15 @@ type SecretsManager interface {
1515
// GetLambdatestSecrets returns lambdatest config
1616
GetLambdatestSecrets() *config.LambdatestConfig
1717

18-
// WriteGitSecrets writes git secrets to file
19-
WriteGitSecrets(path string) error
20-
21-
// WriteRepoSecrets writes repo secrets to file
22-
WriteRepoSecrets(repo string, path string) error
23-
2418
// GetDockerSecrets returns Mode , RegistryAuth, and URL for pulling remote docker image
2519
GetDockerSecrets(r *RunnerOptions) (ContainerImageConfig, error)
20+
2621
// GetSynapseName returns synapse name mentioned in config
2722
GetSynapseName() string
23+
24+
// GetGitSecretBytes get git secrets in bytes
25+
GetGitSecretBytes() ([]byte, error)
26+
27+
// GetRepoSecretBytes get repo secrets in bytes
28+
GetRepoSecretBytes(repo string) ([]byte, error)
2829
}

pkg/cron/setup.go

Lines changed: 5 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,19 @@ package cron
22

33
import (
44
"context"
5-
"fmt"
6-
"os"
75
"sync"
8-
"time"
96

7+
"github.com/LambdaTest/test-at-scale/pkg/core"
108
"github.com/LambdaTest/test-at-scale/pkg/lumber"
11-
"github.com/LambdaTest/test-at-scale/pkg/utils"
129
"github.com/robfig/cron/v3"
1310
)
1411

15-
const (
16-
buildCacheExpiry time.Duration = 4 * time.Hour
17-
buildCacheDir string = "/tmp/synapse"
18-
)
19-
2012
// Setup initializes all crons on service startup
21-
func Setup(ctx context.Context, wg *sync.WaitGroup, logger lumber.Logger) {
13+
func Setup(ctx context.Context, wg *sync.WaitGroup, logger lumber.Logger, runner core.DockerRunner) {
2214
defer wg.Done()
2315

2416
c := cron.New()
25-
if _, err := c.AddFunc("@every 5m", func() { cleanupBuildCache(logger) }); err != nil {
17+
if _, err := c.AddFunc("@every 5m", func() { cleanupBuildCache(runner) }); err != nil {
2618
logger.Errorf("error setting up cron")
2719
return
2820
}
@@ -33,23 +25,6 @@ func Setup(ctx context.Context, wg *sync.WaitGroup, logger lumber.Logger) {
3325
logger.Infof("Caller has requested graceful shutdown. Returning.....")
3426
}
3527

36-
func cleanupBuildCache(logger lumber.Logger) {
37-
files, err := os.ReadDir(buildCacheDir)
38-
if err != nil {
39-
logger.Errorf("error in reading directory: %s", err)
40-
return
41-
}
42-
for _, file := range files {
43-
now := time.Now()
44-
info, err := file.Info()
45-
if err != nil {
46-
logger.Errorf("error retrieving file info")
47-
}
48-
if diff := now.Sub(info.ModTime()); diff > buildCacheExpiry {
49-
filePath := fmt.Sprintf("%s/%s", buildCacheDir, file.Name())
50-
if err := utils.DeleteDirectory(filePath); err != nil {
51-
logger.Errorf("error deleting directory: %s", err.Error())
52-
}
53-
}
54-
}
28+
func cleanupBuildCache(runner core.DockerRunner) {
29+
runner.RemoveOldVolumes(context.Background())
5530
}

pkg/errs/synapse.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ func ERR_FIL_CRT(err string) Err {
180180
Message: fmt.Sprintf("Unable to create file : \n%s", err)}
181181
}
182182

183-
//ERR_API_WEB_HOK function returns error with code ERR::API::WEB::HOK
183+
// ERR_API_WEB_HOK function returns error with code ERR::API::WEB::HOK
184184
func ERR_API_WEB_HOK(err string) Err {
185185
return Err{
186186
Code: "ERR::API::WEB::HOK",
@@ -208,6 +208,27 @@ func ERR_DOCKER_STRT(err string) Err {
208208
Message: fmt.Sprintf("Docker start failed with error: \n%s", err)}
209209
}
210210

211+
// ErrDockerVolCrt function returns error with code "ERR::DOCKER::VOL::CRT"
212+
func ErrDockerVolCrt(err string) Err {
213+
return Err{
214+
Code: "ERR::DOCKER::VOL::CRT",
215+
Message: fmt.Sprintf("Docker volume create failed with error: \n%s", err)}
216+
}
217+
218+
// ErrDockerCP function returns error with code "ERR::DOCKER::CP"
219+
func ErrDockerCP(err string) Err {
220+
return Err{
221+
Code: "ERR::DOCKER::CP",
222+
Message: fmt.Sprintf("Error copying file to docker: \n%s", err)}
223+
}
224+
225+
// ErrSecretLoad function returns error with code "ERR::SECRET::LOAD"
226+
func ErrSecretLoad(err string) Err {
227+
return Err{
228+
Code: "ERR::SECRET::LOAD",
229+
Message: fmt.Sprintf("Error in loading secrets: \n%s", err)}
230+
}
231+
211232
// ERR_JSON_MAR function returns error with code "ERR::JSON::MAR"
212233
func ERR_JSON_MAR(err string) Err {
213234
return Err{

pkg/global/synapseconstants.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const (
1010
ProxyServerPort = "8000"
1111
DirectoryPermissions = 0755
1212
FilePermissions = 0755
13+
VaultSecretDir = "/vault/secrets"
1314
GitConfigFileName = "oauth"
1415
RepoSecretsFileName = "reposecrets"
1516
SynapseContainerURL = "http://synapse:8000"

pkg/proxyserver/setup.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,4 @@ func ListenAndServe(ctx context.Context, proxyHandler *ProxyHandler, config *con
4545
case <-done:
4646
return nil
4747
}
48-
4948
}

pkg/runner/docker/config.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,29 @@ import (
1515
"github.com/docker/docker/api/types/filters"
1616
"github.com/docker/docker/api/types/mount"
1717
"github.com/docker/docker/api/types/network"
18+
"github.com/docker/docker/api/types/volume"
1819
"github.com/docker/go-units"
1920
)
2021

2122
const (
2223
defaultVaultPath = "/vault/secrets"
2324
repoSourcePath = "/tmp/synapse/%s/nucleus"
2425
nanoCPUUnit = 1e9
26+
volumePrefix = "tas-build"
2527
)
2628

29+
func (d *docker) getVolumeName(r *core.RunnerOptions) string {
30+
return fmt.Sprintf("%s-%s", volumePrefix, r.Label[synapse.BuildID])
31+
}
32+
33+
func (d *docker) getVolumeConfiguration(r *core.RunnerOptions) *volume.VolumeCreateBody {
34+
return &volume.VolumeCreateBody{
35+
Driver: "local",
36+
Name: d.getVolumeName(r),
37+
Labels: map[string]string{synapse.BuildID: r.Label[synapse.BuildID]},
38+
}
39+
}
40+
2741
func (d *docker) getContainerConfiguration(r *core.RunnerOptions) *container.Config {
2842
return &container.Config{
2943
Image: r.DockerImage,
@@ -44,8 +58,8 @@ func (d *docker) getContainerHostConfiguration(r *core.RunnerOptions) *container
4458
d.logger.Infof("Specs %+v", specs)
4559
mounts := []mount.Mount{
4660
{
47-
Type: mount.TypeBind,
48-
Source: r.HostVolumePath,
61+
Type: mount.TypeVolume,
62+
Source: d.getVolumeName(r),
4963
Target: defaultVaultPath,
5064
},
5165
}
@@ -55,8 +69,8 @@ func (d *docker) getContainerHostConfiguration(r *core.RunnerOptions) *container
5569
d.logger.Errorf("error creating directory: %v", err)
5670
}
5771
mounts = append(mounts, mount.Mount{
58-
Type: mount.TypeBind,
59-
Source: repoBuildSourcePath,
72+
Type: mount.TypeVolume,
73+
Source: d.getVolumeName(r),
6074
Target: global.WorkspaceCacheDir,
6175
})
6276
}

0 commit comments

Comments
 (0)