github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/atc/worker/container_spec.go (about) 1 package worker 2 3 import ( 4 "fmt" 5 "strings" 6 7 "code.cloudfoundry.org/garden" 8 "github.com/pf-qiu/concourse/v6/atc/db" 9 "github.com/pf-qiu/concourse/v6/atc/runtime" 10 ) 11 12 type WorkerSpec struct { 13 Platform string 14 ResourceType string 15 Tags []string 16 TeamID int 17 } 18 19 type ContainerSpec struct { 20 TeamID int 21 ImageSpec ImageSpec 22 Env []string 23 Type db.ContainerType 24 25 // Working directory for processes run in the container. 26 Dir string 27 28 // artifacts configured as usable. The key reps the mount path of the input artifact 29 // and value is the artifact itself 30 ArtifactByPath map[string]runtime.Artifact 31 32 // Inputs to provide to the container. Inputs with a volume local to the 33 // selected worker will be made available via a COW volume; others will be 34 // streamed. 35 Inputs []InputSource 36 37 // Outputs for which volumes should be created and mounted into the container. 38 Outputs OutputPaths 39 40 // Resource limits to be set on the container when creating in garden. 41 Limits ContainerLimits 42 43 // Local volumes to bind mount directly to the container when creating in garden. 44 BindMounts []BindMountSource 45 46 // Optional user to run processes as. Overwrites the one specified in the docker image. 47 User string 48 } 49 50 // The below methods cause ContainerSpec to fulfill the 51 // go.opentelemetry.io/otel/api/propagation.HTTPSupplier interface 52 53 func (cs *ContainerSpec) Get(key string) string { 54 for _, env := range cs.Env { 55 assignment := strings.SplitN("=", env, 2) 56 if assignment[0] == strings.ToUpper(key) { 57 return assignment[1] 58 } 59 } 60 return "" 61 } 62 63 func (cs *ContainerSpec) Set(key string, value string) { 64 varName := strings.ToUpper(key) 65 envVar := varName + "=" + value 66 for i, env := range cs.Env { 67 if strings.SplitN("=", env, 2)[0] == varName { 68 cs.Env[i] = envVar 69 return 70 } 71 } 72 cs.Env = append(cs.Env, envVar) 73 } 74 75 //go:generate counterfeiter . InputSource 76 77 type InputSource interface { 78 Source() ArtifactSource 79 DestinationPath() string 80 } 81 82 //go:generate counterfeiter . BindMountSource 83 84 type BindMountSource interface { 85 VolumeOn(Worker) (garden.BindMount, bool, error) 86 } 87 88 // OutputPaths is a mapping from output name to its path in the container. 89 type OutputPaths map[string]string 90 91 type ImageSpec struct { 92 ResourceType string 93 ImageURL string 94 ImageArtifactSource StreamableArtifactSource 95 ImageArtifact runtime.Artifact 96 Privileged bool 97 } 98 99 type ContainerLimits struct { 100 CPU *uint64 101 Memory *uint64 102 } 103 104 type inputSource struct { 105 source ArtifactSource 106 path string 107 } 108 109 func (src inputSource) Source() ArtifactSource { 110 return src.source 111 } 112 113 func (src inputSource) DestinationPath() string { 114 return src.path 115 } 116 117 var GardenLimitDefault = uint64(0) 118 119 func (cl ContainerLimits) ToGardenLimits() garden.Limits { 120 gardenLimits := garden.Limits{} 121 if cl.CPU == nil { 122 gardenLimits.CPU = garden.CPULimits{LimitInShares: GardenLimitDefault} 123 } else { 124 gardenLimits.CPU = garden.CPULimits{LimitInShares: *cl.CPU} 125 } 126 if cl.Memory == nil { 127 gardenLimits.Memory = garden.MemoryLimits{LimitInBytes: GardenLimitDefault} 128 } else { 129 gardenLimits.Memory = garden.MemoryLimits{LimitInBytes: *cl.Memory} 130 } 131 return gardenLimits 132 } 133 134 func (spec WorkerSpec) Description() string { 135 var attrs []string 136 137 if spec.ResourceType != "" { 138 attrs = append(attrs, fmt.Sprintf("resource type '%s'", spec.ResourceType)) 139 } 140 141 if spec.Platform != "" { 142 attrs = append(attrs, fmt.Sprintf("platform '%s'", spec.Platform)) 143 } 144 145 for _, tag := range spec.Tags { 146 attrs = append(attrs, fmt.Sprintf("tag '%s'", tag)) 147 } 148 149 return strings.Join(attrs, ", ") 150 }