chore: go mod tidy / vendor / make deps

This commit is contained in:
2025-10-02 08:25:31 +02:00
parent 1c10e64c58
commit d63a1c28ea
505 changed files with 34448 additions and 35285 deletions

View File

@ -0,0 +1,40 @@
package volumespec
// VolumeConfig are references to a volume used by a service
type VolumeConfig struct {
Type string `yaml:",omitempty" json:"type,omitempty"`
Source string `yaml:",omitempty" json:"source,omitempty"`
Target string `yaml:",omitempty" json:"target,omitempty"`
ReadOnly bool `mapstructure:"read_only" yaml:"read_only,omitempty" json:"read_only,omitempty"`
Consistency string `yaml:",omitempty" json:"consistency,omitempty"`
Bind *BindOpts `yaml:",omitempty" json:"bind,omitempty"`
Volume *VolumeOpts `yaml:",omitempty" json:"volume,omitempty"`
Image *ImageOpts `yaml:",omitempty" json:"image,omitempty"`
Tmpfs *TmpFsOpts `yaml:",omitempty" json:"tmpfs,omitempty"`
Cluster *ClusterOpts `yaml:",omitempty" json:"cluster,omitempty"`
}
// BindOpts are options for a service volume of type bind
type BindOpts struct {
Propagation string `yaml:",omitempty" json:"propagation,omitempty"`
}
// VolumeOpts are options for a service volume of type volume
type VolumeOpts struct {
NoCopy bool `mapstructure:"nocopy" yaml:"nocopy,omitempty" json:"nocopy,omitempty"`
Subpath string `mapstructure:"subpath" yaml:"subpath,omitempty" json:"subpath,omitempty"`
}
// ImageOpts are options for a service volume of type image
type ImageOpts struct {
Subpath string `mapstructure:"subpath" yaml:"subpath,omitempty" json:"subpath,omitempty"`
}
// TmpFsOpts are options for a service volume of type tmpfs
type TmpFsOpts struct {
Size int64 `yaml:",omitempty" json:"size,omitempty"`
}
// ClusterOpts are options for a service volume of type cluster.
// Deliberately left blank for future options, but unused now.
type ClusterOpts struct{}

View File

@ -0,0 +1,124 @@
package volumespec
import (
"strings"
"unicode"
"unicode/utf8"
"github.com/docker/docker/api/types/mount"
"github.com/pkg/errors"
)
const endOfSpec = rune(0)
// Parse parses a volume spec without any knowledge of the target platform
func Parse(spec string) (VolumeConfig, error) {
volume := VolumeConfig{}
switch len(spec) {
case 0:
return volume, errors.New("invalid empty volume spec")
case 1, 2:
volume.Target = spec
volume.Type = string(mount.TypeVolume)
return volume, nil
}
buffer := []rune{}
for _, char := range spec + string(endOfSpec) {
switch {
case isWindowsDrive(buffer, char):
buffer = append(buffer, char)
case char == ':' || char == endOfSpec:
if err := populateFieldFromBuffer(char, buffer, &volume); err != nil {
populateType(&volume)
return volume, errors.Wrapf(err, "invalid spec: %s", spec)
}
buffer = []rune{}
default:
buffer = append(buffer, char)
}
}
populateType(&volume)
return volume, nil
}
func isWindowsDrive(buffer []rune, char rune) bool {
return char == ':' && len(buffer) == 1 && unicode.IsLetter(buffer[0])
}
func populateFieldFromBuffer(char rune, buffer []rune, volume *VolumeConfig) error {
strBuffer := string(buffer)
switch {
case len(buffer) == 0:
return errors.New("empty section between colons")
// Anonymous volume
case volume.Source == "" && char == endOfSpec:
volume.Target = strBuffer
return nil
case volume.Source == "":
volume.Source = strBuffer
return nil
case volume.Target == "":
volume.Target = strBuffer
return nil
case char == ':':
return errors.New("too many colons")
}
for _, option := range strings.Split(strBuffer, ",") {
switch option {
case "ro":
volume.ReadOnly = true
case "rw":
volume.ReadOnly = false
case "nocopy":
volume.Volume = &VolumeOpts{NoCopy: true}
default:
if isBindOption(option) {
volume.Bind = &BindOpts{Propagation: option}
}
// ignore unknown options
}
}
return nil
}
func isBindOption(option string) bool {
for _, propagation := range mount.Propagations {
if mount.Propagation(option) == propagation {
return true
}
}
return false
}
func populateType(volume *VolumeConfig) {
switch {
// Anonymous volume
case volume.Source == "":
volume.Type = string(mount.TypeVolume)
case isFilePath(volume.Source):
volume.Type = string(mount.TypeBind)
default:
volume.Type = string(mount.TypeVolume)
}
}
func isFilePath(source string) bool {
switch source[0] {
case '.', '/', '~':
return true
}
if len([]rune(source)) == 1 {
return false
}
// windows named pipes
if strings.HasPrefix(source, `\\`) {
return true
}
first, nextIndex := utf8.DecodeRuneInString(source)
return isWindowsDrive([]rune{first}, rune(source[nextIndex]))
}