Skip to content

Commit a296da2

Browse files
authored
refactor: use mount type instead of strings (#48)
Refactors how container mounts (volumes) are managed within the system. Instead of relying on simple string representations, a new, more explicit Mount data structure is now used. This change enhances type safety, improves the clarity of mount configurations, makes the system easier to extend, and streamlines the underlying logic for volume management across various components.
1 parent 04e5519 commit a296da2

File tree

9 files changed

+50
-58
lines changed

9 files changed

+50
-58
lines changed

internal/engine/clients/runner/docker/runner.go

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,12 @@ func (r *dockerRunner) Run(ctx context.Context, opts ...runner.RunOption) (strin
5252

5353
var mounts []mount.Mount
5454

55-
for _, v := range options.Volumes {
56-
vol := strings.Split(v, ":")
57-
if len(vol) != 2 {
58-
return "", runner.ErrInvalidVolumeName
59-
}
60-
mount := mount.Mount{
55+
for _, m := range options.Mounts {
56+
mounts = append(mounts, mount.Mount{
6157
Type: mount.TypeVolume,
62-
Source: vol[0],
63-
Target: vol[1],
64-
}
65-
mounts = append(mounts, mount)
58+
Source: m["source"],
59+
Target: m["target"],
60+
})
6661
}
6762

6863
hc := container.HostConfig{

internal/engine/clients/runner/errors.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@ package runner
33
import "errors"
44

55
var (
6-
ErrPullingImage = errors.New("failed to pull image")
7-
ErrVolumeNotFound = errors.New("volume not found")
8-
ErrInvalidVolumeName = errors.New("invalid volume name")
9-
ErrBadExitCode = errors.New("bad exit code")
10-
ErrRunnerClosing = errors.New("runner is closing")
6+
ErrPullingImage = errors.New("failed to pull image")
7+
ErrVolumeNotFound = errors.New("volume not found")
8+
ErrBadExitCode = errors.New("bad exit code")
9+
ErrRunnerClosing = errors.New("runner is closing")
1110
)

internal/engine/clients/runner/options.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ type RunOptions struct {
4848
Image string
4949
Cmd []string
5050
Env []string
51-
Volumes []string
51+
Mounts []map[string]string
5252
Networks []string
5353
Context context.Context
5454
}
@@ -77,9 +77,9 @@ func RunWithEnv(env []string) RunOption {
7777
}
7878
}
7979

80-
func RunWithVolumes(volumes []string) RunOption {
80+
func RunWithMounts(mounts []map[string]string) RunOption {
8181
return func(o *RunOptions) {
82-
o.Volumes = volumes
82+
o.Mounts = mounts
8383
}
8484
}
8585

internal/engine/services/coordinator/service.go

Lines changed: 5 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -143,43 +143,18 @@ func (s *Service) RestartTask(ctx context.Context, id string) (*task.Task, error
143143
return nil, task.ErrTaskNotRestartable
144144
}
145145

146-
if len(t.Volumes) > 0 {
147-
var cleanedVolumes []string
148-
for _, v := range t.Volumes {
149-
parts := strings.Split(v, ":")
150-
if len(parts) == 2 {
151-
cleanedVolumes = append(cleanedVolumes, parts[1])
152-
} else {
153-
cleanedVolumes = append(cleanedVolumes, v)
154-
}
146+
if len(t.Mounts) > 0 {
147+
for _, m := range t.Mounts {
148+
m.Source = ""
155149
}
156-
t.Volumes = cleanedVolumes
157150
}
158151

159152
for _, pre := range t.Pre {
160-
var cleanedPreVolumes []string
161-
for _, v := range pre.Volumes {
162-
parts := strings.Split(v, ":")
163-
if len(parts) == 2 {
164-
cleanedPreVolumes = append(cleanedPreVolumes, parts[1])
165-
} else {
166-
cleanedPreVolumes = append(cleanedPreVolumes, v)
167-
}
168-
}
169-
pre.Volumes = cleanedPreVolumes
153+
pre.Mounts = nil
170154
}
171155

172156
for _, post := range t.Post {
173-
var cleanedPostVolumes []string
174-
for _, v := range post.Volumes {
175-
parts := strings.Split(v, ":")
176-
if len(parts) == 2 {
177-
cleanedPostVolumes = append(cleanedPostVolumes, parts[1])
178-
} else {
179-
cleanedPostVolumes = append(cleanedPostVolumes, v)
180-
}
181-
}
182-
post.Volumes = cleanedPostVolumes
157+
post.Mounts = nil
183158
}
184159

185160
now := time.Now()

internal/engine/services/worker/service.go

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package worker
33
import (
44
"context"
55
"encoding/json"
6-
"fmt"
76
"log/slog"
87
"strings"
98
"sync"
@@ -113,9 +112,9 @@ func (s *Service) runTask(ctx context.Context, t *task.Task) error {
113112
return err
114113
}
115114

116-
var vs []string
115+
var ms []*task.Mount
117116

118-
for _, v := range t.Volumes {
117+
for _, m := range t.Mounts {
119118
volName := strings.ReplaceAll(uuid.NewString(), "-", "")
120119
opts := []runner.CreateVolumeOption{
121120
runner.CreateVolumeWithName(volName),
@@ -147,14 +146,17 @@ func (s *Service) runTask(ctx context.Context, t *task.Task) error {
147146
slog.ErrorContext(ctx, "failed to delete volume", "name", volName)
148147
}
149148
}(volName)
150-
vs = append(vs, fmt.Sprintf("%s:%s", volName, v))
149+
ms = append(ms, &task.Mount{
150+
Source: volName,
151+
Target: m.Target,
152+
})
151153
}
152154

153-
t.Volumes = vs
155+
t.Mounts = ms
154156

155157
for _, pre := range t.Pre {
156158
pre.ID = strings.ReplaceAll(uuid.NewString(), "-", "")
157-
pre.Volumes = t.Volumes
159+
pre.Mounts = t.Mounts
158160
pre.Networks = t.Networks
159161
result, err := s.run(ctx, pre)
160162
finished := time.Now()
@@ -202,7 +204,7 @@ func (s *Service) runTask(ctx context.Context, t *task.Task) error {
202204

203205
for _, post := range t.Post {
204206
post.ID = strings.ReplaceAll(uuid.NewString(), "-", "")
205-
post.Volumes = t.Volumes
207+
post.Mounts = t.Mounts
206208
post.Networks = t.Networks
207209
result, err := s.run(ctx, post)
208210
finished := time.Now()
@@ -251,12 +253,21 @@ func (s *Service) run(ctx context.Context, t *task.Task) (string, error) {
251253
ctx = timeoutCtx
252254
}
253255

256+
var mounts []map[string]string
257+
258+
for _, m := range t.Mounts {
259+
mounts = append(mounts, map[string]string{
260+
"source": m.Source,
261+
"target": m.Target,
262+
})
263+
}
264+
254265
runOpts := []runner.RunOption{
255266
runner.RunWithID(t.ID),
256267
runner.RunWithImage(t.Image),
257268
runner.RunWithCmd(t.Cmd),
258269
runner.RunWithEnv(t.Env),
259-
runner.RunWithVolumes(t.Volumes),
270+
runner.RunWithMounts(mounts),
260271
runner.RunWithNetworks(t.Networks),
261272
}
262273

internal/task/domain.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,17 @@ type Task struct {
3030
Error string `json:"error,omitempty"`
3131
Pre []*Task `json:"pre,omitempty"`
3232
Post []*Task `json:"post,omitempty"`
33-
Volumes []string `json:"volumes,omitempty"`
33+
Mounts []*Mount `json:"mounts,omitempty"`
3434
Networks []string `json:"networks,omitempty"`
3535
Retry *Retry `json:"retry,omitempty"`
3636
Timeout string `json:"timeout,omitempty"`
3737
}
3838

39+
type Mount struct {
40+
Source string `json:"source,omitempty"`
41+
Target string `json:"target,omitempty"`
42+
}
43+
3944
type Retry struct {
4045
Limit int `json:"limit,omitempty"`
4146
Attempts int `json:"attempts,omitempty"`

internal/task/errors.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import "errors"
55
var (
66
ErrTaskNotFound = errors.New("task not found")
77
ErrMissingImage = errors.New("task is missing image")
8+
ErrMountMissingTarget = errors.New("mount missing target")
89
ErrAttemptsSpecified = errors.New("may not specify retry attempts")
910
ErrExcessiveLimit = errors.New("may not specify retry limit > 10")
1011
ErrInvalidTimeout = errors.New("invalid timeout")

internal/task/task.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ func Factory(bs []byte) (*Task, error) {
1919

2020
// TODO: validate queue field
2121

22+
for _, m := range t.Mounts {
23+
if m == nil || len(strings.TrimSpace(m.Target)) == 0 {
24+
return nil, ErrMountMissingTarget
25+
}
26+
}
27+
2228
if t.Retry != nil {
2329
if t.Retry.Attempts != 0 {
2430
return nil, ErrAttemptsSpecified

tests/testdata/convert.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"5",
99
"/tmp/output.mp4"
1010
],
11-
"volumes": ["/tmp"],
11+
"mounts": [{"target": "/tmp"}],
1212
"pre": [{
1313
"name": "download the remote file",
1414
"image": "alpine:3.18.3",

0 commit comments

Comments
 (0)