/
volume.go
121 lines (100 loc) · 3.48 KB
/
volume.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// SPDX-License-Identifier: Apache-2.0
package yaml
import (
"fmt"
"strings"
"github.com/go-vela/types/pipeline"
"github.com/go-vela/types/raw"
)
type (
// VolumeSlice is the yaml representation of
// the volumes block for a step in a pipeline.
VolumeSlice []*Volume
// Volume is the yaml representation of a volume
// from a volumes block for a step in a pipeline.
Volume struct {
Source string `yaml:"source,omitempty" json:"source,omitempty" jsonschema:"required,minLength=1,description=Set the source directory to be mounted.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-volume-tag"`
Destination string `yaml:"destination,omitempty" json:"destination,omitempty" jsonschema:"required,minLength=1,description=Set the destination directory for the mount in the container.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-volume-tag"`
AccessMode string `yaml:"access_mode,omitempty" json:"access_mode,omitempty" jsonschema:"default=ro,description=Set the access mode for the mounted volume.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-volume-tag"`
}
)
// ToPipeline converts the VolumeSlice type
// to a pipeline VolumeSlice type.
func (v *VolumeSlice) ToPipeline() *pipeline.VolumeSlice {
// volume slice we want to return
volumes := new(pipeline.VolumeSlice)
// iterate through each element in the volume slice
for _, volume := range *v {
// append the element to the pipeline volume slice
*volumes = append(*volumes, &pipeline.Volume{
Source: volume.Source,
Destination: volume.Destination,
AccessMode: volume.AccessMode,
})
}
return volumes
}
// UnmarshalYAML implements the Unmarshaler interface for the VolumeSlice type.
func (v *VolumeSlice) UnmarshalYAML(unmarshal func(interface{}) error) error {
// string slice we try unmarshalling to
stringSlice := new(raw.StringSlice)
// attempt to unmarshal as a string slice type
err := unmarshal(stringSlice)
if err == nil {
// iterate through each element in the string slice
for _, volume := range *stringSlice {
// split each slice element into source, destination and access mode
parts := strings.Split(volume, ":")
switch {
case len(parts) == 1:
// append the element to the volume slice
*v = append(*v, &Volume{
Source: parts[0],
Destination: parts[0],
AccessMode: "ro",
})
continue
case len(parts) == 2:
// append the element to the volume slice
*v = append(*v, &Volume{
Source: parts[0],
Destination: parts[1],
AccessMode: "ro",
})
continue
case len(parts) == 3:
// append the element to the volume slice
*v = append(*v, &Volume{
Source: parts[0],
Destination: parts[1],
AccessMode: parts[2],
})
continue
default:
return fmt.Errorf("volume %s must contain at least 1 but no more than 2 `:`(colons)", volume)
}
}
return nil
}
// volume slice we try unmarshalling to
volumes := new([]*Volume)
// attempt to unmarshal as a volume slice type
err = unmarshal(volumes)
if err != nil {
return err
}
// iterate through each element in the volume slice
for _, volume := range *volumes {
// implicitly set `destination` field if empty
if len(volume.Destination) == 0 {
volume.Destination = volume.Source
}
// implicitly set `access_mode` field if empty
if len(volume.AccessMode) == 0 {
volume.AccessMode = "ro"
}
}
// overwrite existing VolumeSlice
*v = VolumeSlice(*volumes)
return nil
}