2023-08-10 09:06:00 +00:00
|
|
|
// Copyright 2023 Woodpecker Authors
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
2023-06-06 07:14:21 +00:00
|
|
|
package types
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"gopkg.in/yaml.v3"
|
|
|
|
|
|
|
|
"github.com/woodpecker-ci/woodpecker/pipeline/frontend/yaml/constraint"
|
|
|
|
"github.com/woodpecker-ci/woodpecker/pipeline/frontend/yaml/types/base"
|
2023-07-09 21:41:13 +00:00
|
|
|
"github.com/woodpecker-ci/woodpecker/pipeline/frontend/yaml/utils"
|
2023-06-06 07:14:21 +00:00
|
|
|
"github.com/woodpecker-ci/woodpecker/shared/constant"
|
|
|
|
)
|
|
|
|
|
|
|
|
type (
|
|
|
|
// ContainerList denotes an ordered collection of containers.
|
|
|
|
ContainerList struct {
|
|
|
|
ContainerList []*Container
|
|
|
|
}
|
|
|
|
|
|
|
|
// Container defines a container.
|
|
|
|
Container struct {
|
|
|
|
BackendOptions BackendOptions `yaml:"backend_options,omitempty"`
|
|
|
|
Commands base.StringOrSlice `yaml:"commands,omitempty"`
|
|
|
|
Detached bool `yaml:"detach,omitempty"`
|
|
|
|
Directory string `yaml:"directory,omitempty"`
|
|
|
|
Environment base.SliceOrMap `yaml:"environment,omitempty"`
|
|
|
|
Failure string `yaml:"failure,omitempty"`
|
|
|
|
Group string `yaml:"group,omitempty"`
|
|
|
|
Image string `yaml:"image,omitempty"`
|
|
|
|
Name string `yaml:"name,omitempty"`
|
|
|
|
Pull bool `yaml:"pull,omitempty"`
|
|
|
|
Secrets Secrets `yaml:"secrets,omitempty"`
|
|
|
|
Settings map[string]interface{} `yaml:"settings"`
|
|
|
|
Volumes Volumes `yaml:"volumes,omitempty"`
|
|
|
|
When constraint.When `yaml:"when,omitempty"`
|
|
|
|
|
|
|
|
// Docker Specific
|
|
|
|
Privileged bool `yaml:"privileged,omitempty"`
|
|
|
|
|
|
|
|
// Undocumented
|
2023-07-09 10:32:19 +00:00
|
|
|
CPUQuota base.StringOrInt `yaml:"cpu_quota,omitempty"`
|
|
|
|
CPUSet string `yaml:"cpuset,omitempty"`
|
|
|
|
CPUShares base.StringOrInt `yaml:"cpu_shares,omitempty"`
|
|
|
|
Devices []string `yaml:"devices,omitempty"`
|
|
|
|
DNSSearch base.StringOrSlice `yaml:"dns_search,omitempty"`
|
|
|
|
DNS base.StringOrSlice `yaml:"dns,omitempty"`
|
|
|
|
ExtraHosts []string `yaml:"extra_hosts,omitempty"`
|
|
|
|
IpcMode string `yaml:"ipc_mode,omitempty"`
|
|
|
|
MemLimit base.MemStringOrInt `yaml:"mem_limit,omitempty"`
|
|
|
|
MemSwapLimit base.MemStringOrInt `yaml:"memswap_limit,omitempty"`
|
|
|
|
NetworkMode string `yaml:"network_mode,omitempty"`
|
|
|
|
Networks Networks `yaml:"networks,omitempty"`
|
|
|
|
ShmSize base.MemStringOrInt `yaml:"shm_size,omitempty"`
|
|
|
|
Sysctls base.SliceOrMap `yaml:"sysctls,omitempty"`
|
|
|
|
Tmpfs []string `yaml:"tmpfs,omitempty"`
|
2023-06-06 07:14:21 +00:00
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
// UnmarshalYAML implements the Unmarshaler interface.
|
|
|
|
func (c *ContainerList) UnmarshalYAML(value *yaml.Node) error {
|
|
|
|
switch value.Kind {
|
|
|
|
// We support maps ...
|
|
|
|
case yaml.MappingNode:
|
|
|
|
c.ContainerList = make([]*Container, 0, len(value.Content)/2+1)
|
|
|
|
// We cannot use decode on specific values
|
|
|
|
// since if we try to load from a map, the order
|
|
|
|
// will not be kept. Therefor use value.Content
|
|
|
|
// and take the map values i%2=1
|
|
|
|
for i, n := range value.Content {
|
|
|
|
if i%2 == 1 {
|
|
|
|
container := &Container{}
|
|
|
|
if err := n.Decode(container); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if container.Name == "" {
|
|
|
|
container.Name = fmt.Sprintf("%v", value.Content[i-1].Value)
|
|
|
|
}
|
|
|
|
|
|
|
|
c.ContainerList = append(c.ContainerList, container)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ... and lists
|
|
|
|
case yaml.SequenceNode:
|
|
|
|
c.ContainerList = make([]*Container, 0, len(value.Content))
|
|
|
|
for i, n := range value.Content {
|
|
|
|
container := &Container{}
|
|
|
|
if err := n.Decode(container); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if container.Name == "" {
|
|
|
|
container.Name = fmt.Sprintf("step-%d", i)
|
|
|
|
}
|
|
|
|
|
|
|
|
c.ContainerList = append(c.ContainerList, container)
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
return fmt.Errorf("yaml node type[%d]: '%s' not supported", value.Kind, value.Tag)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Container) IsPlugin() bool {
|
|
|
|
return len(c.Commands) == 0
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Container) IsTrustedCloneImage() bool {
|
2023-07-09 21:41:13 +00:00
|
|
|
return c.IsPlugin() && utils.MatchImage(c.Image, constant.TrustedCloneImages...)
|
2023-06-06 07:14:21 +00:00
|
|
|
}
|