woodpecker/yaml/container.go

164 lines
4.7 KiB
Go

package yaml
import (
"fmt"
"github.com/drone/drone/yaml/types"
"gopkg.in/yaml.v2"
)
// Auth defines Docker authentication credentials.
type Auth struct {
Username string
Password string
Email string
}
// Container defines a Docker container.
type Container struct {
ID string
Name string
Image string
Build string
Pull bool
AuthConfig Auth
Detached bool
Disabled bool
Privileged bool
WorkingDir string
Environment map[string]string
Labels map[string]string
Entrypoint []string
Command []string
Commands []string
ExtraHosts []string
Volumes []string
VolumesFrom []string
Devices []string
Network string
DNS []string
DNSSearch []string
MemSwapLimit int64
MemLimit int64
ShmSize int64
CPUQuota int64
CPUShares int64
CPUSet string
OomKillDisable bool
Constraints Constraints
Vargs map[string]interface{}
}
// container is an intermediate type used for decoding a container in a format
// compatible with docker-compose.yml.
// this file has a bunch of custom types that are annoying to work with, which
// is why this is used for intermediate purposes and converted to something
// easier to work with.
type container struct {
Name string `yaml:"name"`
Image string `yaml:"image"`
Build string `yaml:"build"`
Pull bool `yaml:"pull"`
Privileged bool `yaml:"privileged"`
Environment types.MapEqualSlice `yaml:"environment"`
Labels types.MapEqualSlice `yaml:"labels"`
Entrypoint types.StringOrSlice `yaml:"entrypoint"`
Command types.StringOrSlice `yaml:"command"`
Commands types.StringOrSlice `yaml:"commands"`
ExtraHosts types.StringOrSlice `yaml:"extra_hosts"`
Volumes types.StringOrSlice `yaml:"volumes"`
VolumesFrom types.StringOrSlice `yaml:"volumes_from"`
Devices types.StringOrSlice `yaml:"devices"`
Network string `yaml:"network_mode"`
DNS types.StringOrSlice `yaml:"dns"`
DNSSearch types.StringOrSlice `yaml:"dns_search"`
MemSwapLimit int64 `yaml:"memswap_limit"`
MemLimit int64 `yaml:"mem_limit"`
ShmSize int64 `yaml:"shm_size"`
CPUQuota int64 `yaml:"cpu_quota"`
CPUShares int64 `yaml:"cpu_shares"`
CPUSet string `yaml:"cpuset"`
OomKillDisable bool `yaml:"oom_kill_disable"`
AuthConfig struct {
Username string `yaml:"username"`
Password string `yaml:"password"`
Email string `yaml:"email"`
Token string `yaml:"registry_token"`
} `yaml:"auth_config"`
Constraints Constraints `yaml:"when"`
Vargs map[string]interface{} `yaml:",inline"`
}
// containerList is an intermediate type used for decoding a slice of containers
// in a format compatible with docker-compose.yml
type containerList struct {
containers []*Container
}
// UnmarshalYAML implements custom Yaml unmarshaling.
func (c *containerList) UnmarshalYAML(unmarshal func(interface{}) error) error {
slice := yaml.MapSlice{}
err := unmarshal(&slice)
if err != nil {
return err
}
for _, s := range slice {
cc := container{}
out, merr := yaml.Marshal(s.Value)
if err != nil {
return merr
}
err = yaml.Unmarshal(out, &cc)
if err != nil {
return err
}
if cc.Name == "" {
cc.Name = fmt.Sprintf("%v", s.Key)
}
if cc.Image == "" {
cc.Image = fmt.Sprintf("%v", s.Key)
}
c.containers = append(c.containers, &Container{
Name: cc.Name,
Image: cc.Image,
Build: cc.Build,
Pull: cc.Pull,
Privileged: cc.Privileged,
Environment: cc.Environment.Map(),
Labels: cc.Labels.Map(),
Entrypoint: cc.Entrypoint.Slice(),
Command: cc.Command.Slice(),
Commands: cc.Commands.Slice(),
ExtraHosts: cc.ExtraHosts.Slice(),
Volumes: cc.Volumes.Slice(),
VolumesFrom: cc.VolumesFrom.Slice(),
Devices: cc.Devices.Slice(),
Network: cc.Network,
DNS: cc.DNS.Slice(),
DNSSearch: cc.DNSSearch.Slice(),
MemSwapLimit: cc.MemSwapLimit,
MemLimit: cc.MemLimit,
ShmSize: cc.ShmSize,
CPUQuota: cc.CPUQuota,
CPUShares: cc.CPUShares,
CPUSet: cc.CPUSet,
OomKillDisable: cc.OomKillDisable,
Vargs: cc.Vargs,
AuthConfig: Auth{
Username: cc.AuthConfig.Username,
Password: cc.AuthConfig.Password,
Email: cc.AuthConfig.Email,
},
Constraints: cc.Constraints,
})
}
return err
}