2023-08-07 19:13:26 +00:00
// Copyright 2022 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.
2022-09-05 04:01:14 +00:00
package kubernetes
import (
2023-12-19 03:53:52 +00:00
"context"
2023-06-03 22:50:08 +00:00
"fmt"
2023-10-09 07:11:08 +00:00
"maps"
2022-09-05 04:01:14 +00:00
"strings"
2023-07-09 17:22:50 +00:00
"github.com/rs/zerolog/log"
2022-09-05 04:01:14 +00:00
v1 "k8s.io/api/core/v1"
2023-12-19 03:53:52 +00:00
"k8s.io/apimachinery/pkg/api/errors"
2022-09-05 04:01:14 +00:00
"k8s.io/apimachinery/pkg/api/resource"
2024-05-24 20:35:04 +00:00
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2023-10-09 07:11:08 +00:00
2023-12-08 07:15:08 +00:00
"go.woodpecker-ci.org/woodpecker/v2/pipeline/backend/common"
"go.woodpecker-ci.org/woodpecker/v2/pipeline/backend/types"
2022-09-05 04:01:14 +00:00
)
2023-12-19 03:53:52 +00:00
const (
2024-11-02 17:07:27 +00:00
StepLabel = "step"
podPrefix = "wp-"
defaultFSGroup int64 = 1000
2023-12-19 03:53:52 +00:00
)
2022-10-30 23:26:49 +00:00
2024-02-08 17:39:32 +00:00
func mkPod ( step * types . Step , config * config , podName , goos string , options BackendOptions ) ( * v1 . Pod , error ) {
2024-01-26 12:42:21 +00:00
var err error
2024-06-23 16:20:21 +00:00
nsp := newNativeSecretsProcessor ( config , options . Secrets )
err = nsp . process ( )
if err != nil {
return nil , err
}
2024-02-08 17:39:32 +00:00
meta , err := podMeta ( step , config , options , podName )
2024-01-26 12:42:21 +00:00
if err != nil {
return nil , err
}
2023-12-19 03:53:52 +00:00
2024-06-23 16:20:21 +00:00
spec , err := podSpec ( step , config , options , nsp )
2023-12-19 03:53:52 +00:00
if err != nil {
return nil , err
2022-09-05 04:01:14 +00:00
}
2024-06-23 16:20:21 +00:00
container , err := podContainer ( step , podName , goos , options , nsp )
2023-12-19 03:53:52 +00:00
if err != nil {
return nil , err
2022-09-05 04:01:14 +00:00
}
2023-12-19 03:53:52 +00:00
spec . Containers = append ( spec . Containers , container )
2022-09-05 04:01:14 +00:00
2023-12-19 03:53:52 +00:00
pod := & v1 . Pod {
ObjectMeta : meta ,
Spec : spec ,
2022-09-05 04:01:14 +00:00
}
2023-12-19 03:53:52 +00:00
return pod , nil
}
2024-01-09 04:42:36 +00:00
func stepToPodName ( step * types . Step ) ( name string , err error ) {
if step . Type == types . StepTypeService {
return serviceName ( step )
}
return podName ( step )
}
2023-12-19 03:53:52 +00:00
func podName ( step * types . Step ) ( string , error ) {
2024-01-11 15:32:37 +00:00
return dnsName ( podPrefix + step . UUID )
2023-12-19 03:53:52 +00:00
}
2024-05-24 20:35:04 +00:00
func podMeta ( step * types . Step , config * config , options BackendOptions , podName string ) ( meta_v1 . ObjectMeta , error ) {
2024-01-26 12:42:21 +00:00
var err error
2024-05-24 20:35:04 +00:00
meta := meta_v1 . ObjectMeta {
2024-05-11 09:45:29 +00:00
Name : podName ,
Namespace : config . Namespace ,
2024-08-06 17:05:04 +00:00
Annotations : podAnnotations ( config , options ) ,
2023-12-19 03:53:52 +00:00
}
2024-05-11 09:45:29 +00:00
meta . Labels , err = podLabels ( step , config , options )
2024-01-26 12:42:21 +00:00
if err != nil {
return meta , err
}
2023-12-19 03:53:52 +00:00
2024-05-11 09:45:29 +00:00
return meta , nil
}
func podLabels ( step * types . Step , config * config , options BackendOptions ) ( map [ string ] string , error ) {
var err error
labels := make ( map [ string ] string )
if len ( options . Labels ) > 0 {
if config . PodLabelsAllowFromStep {
log . Trace ( ) . Msgf ( "using labels from the backend options: %v" , options . Labels )
maps . Copy ( labels , options . Labels )
} else {
log . Debug ( ) . Msg ( "Pod labels were defined in backend options, but its using disallowed by instance configuration" )
}
}
if len ( config . PodLabels ) > 0 {
log . Trace ( ) . Msgf ( "using labels from the configuration: %v" , config . PodLabels )
maps . Copy ( labels , config . PodLabels )
}
2024-01-23 06:42:47 +00:00
if step . Type == types . StepTypeService {
2024-05-11 09:45:29 +00:00
labels [ ServiceLabel ] , _ = serviceName ( step )
2024-01-23 06:42:47 +00:00
}
2024-05-11 09:45:29 +00:00
labels [ StepLabel ] , err = stepLabel ( step )
if err != nil {
return labels , err
2024-01-15 02:59:08 +00:00
}
2024-01-12 22:32:24 +00:00
2024-05-11 09:45:29 +00:00
return labels , nil
}
func stepLabel ( step * types . Step ) ( string , error ) {
return toDNSName ( step . Name )
}
2024-08-06 17:05:04 +00:00
func podAnnotations ( config * config , options BackendOptions ) map [ string ] string {
2024-05-11 09:45:29 +00:00
annotations := make ( map [ string ] string )
if len ( options . Annotations ) > 0 {
if config . PodAnnotationsAllowFromStep {
log . Trace ( ) . Msgf ( "using annotations from the backend options: %v" , options . Annotations )
maps . Copy ( annotations , options . Annotations )
} else {
log . Debug ( ) . Msg ( "Pod annotations were defined in backend options, but its using disallowed by instance configuration " )
}
}
if len ( config . PodAnnotations ) > 0 {
log . Trace ( ) . Msgf ( "using annotations from the configuration: %v" , config . PodAnnotations )
maps . Copy ( annotations , config . PodAnnotations )
}
2024-01-12 22:32:24 +00:00
2024-05-11 09:45:29 +00:00
return annotations
2023-12-19 03:53:52 +00:00
}
2024-06-23 16:20:21 +00:00
func podSpec ( step * types . Step , config * config , options BackendOptions , nsp nativeSecretsProcessor ) ( v1 . PodSpec , error ) {
2023-12-19 03:53:52 +00:00
var err error
spec := v1 . PodSpec {
RestartPolicy : v1 . RestartPolicyNever ,
2024-03-29 09:29:07 +00:00
RuntimeClassName : options . RuntimeClassName ,
2024-02-08 17:39:32 +00:00
ServiceAccountName : options . ServiceAccountName ,
2024-01-11 15:32:37 +00:00
HostAliases : hostAliases ( step . ExtraHosts ) ,
2024-06-03 15:25:28 +00:00
NodeSelector : nodeSelector ( options . NodeSelector , config . PodNodeSelector , step . Environment [ "CI_SYSTEM_PLATFORM" ] ) ,
2024-02-08 17:39:32 +00:00
Tolerations : tolerations ( options . Tolerations ) ,
2024-03-13 21:41:13 +00:00
SecurityContext : podSecurityContext ( options . SecurityContext , config . SecurityContext , step . Privileged ) ,
2024-01-11 15:32:37 +00:00
}
2024-06-23 16:20:21 +00:00
spec . Volumes , err = pvcVolumes ( step . Volumes )
2023-12-19 03:53:52 +00:00
if err != nil {
return spec , err
2022-09-05 04:01:14 +00:00
}
2024-11-25 16:59:00 +00:00
if len ( step . DNS ) != 0 || len ( step . DNSSearch ) != 0 {
spec . DNSConfig = & v1 . PodDNSConfig { }
if len ( step . DNS ) != 0 {
spec . DNSConfig . Nameservers = step . DNS
}
if len ( step . DNSSearch ) != 0 {
spec . DNSConfig . Searches = step . DNSSearch
}
}
2024-06-23 16:20:21 +00:00
log . Trace ( ) . Msgf ( "using the image pull secrets: %v" , config . ImagePullSecretNames )
spec . ImagePullSecrets = secretsReferences ( config . ImagePullSecretNames )
2024-09-30 00:03:05 +00:00
if needsRegistrySecret ( step ) {
log . Trace ( ) . Msgf ( "using an image pull secret from registries" )
name , err := registrySecretName ( step )
if err != nil {
return spec , err
}
spec . ImagePullSecrets = append ( spec . ImagePullSecrets , secretReference ( name ) )
}
2024-06-23 16:20:21 +00:00
spec . Volumes = append ( spec . Volumes , nsp . volumes ... )
2023-12-19 03:53:52 +00:00
return spec , nil
}
2024-06-23 16:20:21 +00:00
func podContainer ( step * types . Step , podName , goos string , options BackendOptions , nsp nativeSecretsProcessor ) ( v1 . Container , error ) {
2023-06-03 22:50:08 +00:00
var err error
2023-12-19 03:53:52 +00:00
container := v1 . Container {
2024-03-29 08:48:28 +00:00
Name : podName ,
Image : step . Image ,
2024-11-06 22:21:56 +00:00
WorkingDir : step . WorkingDir ,
2024-03-29 08:48:28 +00:00
Ports : containerPorts ( step . Ports ) ,
SecurityContext : containerSecurityContext ( options . SecurityContext , step . Privileged ) ,
2023-12-19 03:53:52 +00:00
}
2024-01-11 15:32:37 +00:00
if step . Pull {
2023-12-19 03:53:52 +00:00
container . ImagePullPolicy = v1 . PullAlways
}
2024-05-02 12:52:01 +00:00
if len ( step . Commands ) > 0 {
2024-11-06 22:21:56 +00:00
scriptEnv , command := common . GenerateContainerConf ( step . Commands , goos , step . WorkingDir )
2023-12-19 03:53:52 +00:00
container . Command = command
2024-01-11 15:32:37 +00:00
maps . Copy ( step . Environment , scriptEnv )
2024-11-06 22:21:56 +00:00
// step.WorkingDir will be respected by the generated script
container . WorkingDir = step . WorkspaceBase
2023-12-19 03:53:52 +00:00
}
2024-05-02 12:52:01 +00:00
if len ( step . Entrypoint ) > 0 {
container . Command = step . Entrypoint
}
2023-12-19 03:53:52 +00:00
2024-01-11 15:32:37 +00:00
container . Env = mapToEnvVars ( step . Environment )
2023-12-19 03:53:52 +00:00
2024-02-08 17:39:32 +00:00
container . Resources , err = resourceRequirements ( options . Resources )
2023-12-19 03:53:52 +00:00
if err != nil {
return container , err
}
2024-01-11 15:32:37 +00:00
container . VolumeMounts , err = volumeMounts ( step . Volumes )
2023-12-19 03:53:52 +00:00
if err != nil {
return container , err
}
2024-06-23 16:20:21 +00:00
container . EnvFrom = append ( container . EnvFrom , nsp . envFromSources ... )
container . Env = append ( container . Env , nsp . envVars ... )
container . VolumeMounts = append ( container . VolumeMounts , nsp . mounts ... )
2023-12-19 03:53:52 +00:00
return container , nil
}
2024-06-23 16:20:21 +00:00
func pvcVolumes ( volumes [ ] string ) ( [ ] v1 . Volume , error ) {
2023-12-19 03:53:52 +00:00
var vols [ ] v1 . Volume
for _ , v := range volumes {
volumeName , err := volumeName ( v )
2023-06-03 22:50:08 +00:00
if err != nil {
2023-12-19 03:53:52 +00:00
return nil , err
2023-06-03 22:50:08 +00:00
}
2024-06-23 16:20:21 +00:00
vols = append ( vols , pvcVolume ( volumeName ) )
2023-12-19 03:53:52 +00:00
}
return vols , nil
}
2024-06-23 16:20:21 +00:00
func pvcVolume ( name string ) v1 . Volume {
2023-12-19 03:53:52 +00:00
pvcSource := v1 . PersistentVolumeClaimVolumeSource {
ClaimName : name ,
ReadOnly : false ,
}
return v1 . Volume {
Name : name ,
VolumeSource : v1 . VolumeSource {
PersistentVolumeClaim : & pvcSource ,
} ,
2023-06-03 22:50:08 +00:00
}
2023-12-19 03:53:52 +00:00
}
func volumeMounts ( volumes [ ] string ) ( [ ] v1 . VolumeMount , error ) {
var mounts [ ] v1 . VolumeMount
for _ , v := range volumes {
volumeName , err := volumeName ( v )
2023-06-03 22:50:08 +00:00
if err != nil {
2023-12-19 03:53:52 +00:00
return nil , err
2023-06-03 22:50:08 +00:00
}
2023-12-19 03:53:52 +00:00
mount := volumeMount ( volumeName , volumeMountPath ( v ) )
mounts = append ( mounts , mount )
2022-09-05 04:01:14 +00:00
}
2023-12-19 03:53:52 +00:00
return mounts , nil
}
2022-09-05 04:01:14 +00:00
2023-12-19 03:53:52 +00:00
func volumeMount ( name , path string ) v1 . VolumeMount {
return v1 . VolumeMount {
Name : name ,
MountPath : path ,
2023-06-12 14:00:59 +00:00
}
2023-12-19 03:53:52 +00:00
}
2023-06-12 14:00:59 +00:00
2024-01-12 22:57:24 +00:00
func containerPorts ( ports [ ] types . Port ) [ ] v1 . ContainerPort {
containerPorts := make ( [ ] v1 . ContainerPort , len ( ports ) )
for i , port := range ports {
containerPorts [ i ] = containerPort ( port )
}
return containerPorts
}
func containerPort ( port types . Port ) v1 . ContainerPort {
return v1 . ContainerPort {
ContainerPort : int32 ( port . Number ) ,
Protocol : v1 . Protocol ( strings . ToUpper ( port . Protocol ) ) ,
}
}
2024-05-13 20:58:21 +00:00
// Here is the service IPs (placed in /etc/hosts in the Pod).
2023-12-22 23:42:30 +00:00
func hostAliases ( extraHosts [ ] types . HostAlias ) [ ] v1 . HostAlias {
2024-01-26 12:42:21 +00:00
var hostAliases [ ] v1 . HostAlias
2023-12-19 03:53:52 +00:00
for _ , extraHost := range extraHosts {
hostAlias := hostAlias ( extraHost )
hostAliases = append ( hostAliases , hostAlias )
}
return hostAliases
}
2023-12-22 23:42:30 +00:00
func hostAlias ( extraHost types . HostAlias ) v1 . HostAlias {
2023-12-19 03:53:52 +00:00
return v1 . HostAlias {
2023-12-22 23:42:30 +00:00
IP : extraHost . IP ,
Hostnames : [ ] string { extraHost . Name } ,
2023-03-21 19:00:45 +00:00
}
2023-12-19 03:53:52 +00:00
}
2023-03-21 19:00:45 +00:00
2024-02-08 17:39:32 +00:00
func resourceRequirements ( resources Resources ) ( v1 . ResourceRequirements , error ) {
2023-12-19 03:53:52 +00:00
var err error
requirements := v1 . ResourceRequirements { }
2022-12-31 00:37:09 +00:00
2023-12-19 03:53:52 +00:00
requirements . Requests , err = resourceList ( resources . Requests )
if err != nil {
return requirements , err
2023-05-18 09:21:20 +00:00
}
2023-12-19 03:53:52 +00:00
requirements . Limits , err = resourceList ( resources . Limits )
if err != nil {
return requirements , err
2023-06-12 14:00:59 +00:00
}
2023-12-19 03:53:52 +00:00
return requirements , nil
}
func resourceList ( resources map [ string ] string ) ( v1 . ResourceList , error ) {
requestResources := v1 . ResourceList { }
for key , val := range resources {
resName := v1 . ResourceName ( key )
resVal , err := resource . ParseQuantity ( val )
if err != nil {
2024-01-10 19:57:12 +00:00
return nil , fmt . Errorf ( "resource request '%s' quantity '%s': %w" , key , val , err )
2023-08-22 20:34:59 +00:00
}
2023-12-19 03:53:52 +00:00
requestResources [ resName ] = resVal
2023-08-22 20:34:59 +00:00
}
2023-12-19 03:53:52 +00:00
return requestResources , nil
}
2023-08-22 20:34:59 +00:00
2024-06-03 15:25:28 +00:00
func nodeSelector ( backendNodeSelector , configNodeSelector map [ string ] string , platform string ) map [ string ] string {
2023-12-19 03:53:52 +00:00
nodeSelector := make ( map [ string ] string )
2023-11-26 07:46:06 +00:00
2023-12-19 03:53:52 +00:00
if platform != "" {
arch := strings . Split ( platform , "/" ) [ 1 ]
nodeSelector [ v1 . LabelArchStable ] = arch
2024-01-11 18:17:07 +00:00
log . Trace ( ) . Msgf ( "using the node selector from the Agent's platform: %v" , nodeSelector )
2022-09-05 04:01:14 +00:00
}
2024-06-03 15:25:28 +00:00
if len ( configNodeSelector ) > 0 {
log . Trace ( ) . Msgf ( "appending labels to the node selector from the configuration: %v" , configNodeSelector )
maps . Copy ( nodeSelector , configNodeSelector )
}
2023-12-19 03:53:52 +00:00
if len ( backendNodeSelector ) > 0 {
2024-01-11 18:17:07 +00:00
log . Trace ( ) . Msgf ( "appending labels to the node selector from the backend options: %v" , backendNodeSelector )
2023-12-19 03:53:52 +00:00
maps . Copy ( nodeSelector , backendNodeSelector )
}
return nodeSelector
2022-09-05 04:01:14 +00:00
}
2024-02-08 17:39:32 +00:00
func tolerations ( backendTolerations [ ] Toleration ) [ ] v1 . Toleration {
2023-12-19 03:53:52 +00:00
var tolerations [ ] v1 . Toleration
if len ( backendTolerations ) > 0 {
2024-01-11 18:17:07 +00:00
log . Trace ( ) . Msgf ( "tolerations that will be used in the backend options: %v" , backendTolerations )
2023-12-19 03:53:52 +00:00
for _ , backendToleration := range backendTolerations {
toleration := toleration ( backendToleration )
tolerations = append ( tolerations , toleration )
}
2022-09-05 04:01:14 +00:00
}
2023-12-19 03:53:52 +00:00
return tolerations
2022-09-05 04:01:14 +00:00
}
2024-02-08 17:39:32 +00:00
func toleration ( backendToleration Toleration ) v1 . Toleration {
2023-12-19 03:53:52 +00:00
return v1 . Toleration {
Key : backendToleration . Key ,
Operator : v1 . TolerationOperator ( backendToleration . Operator ) ,
Value : backendToleration . Value ,
Effect : v1 . TaintEffect ( backendToleration . Effect ) ,
TolerationSeconds : backendToleration . TolerationSeconds ,
2022-09-05 04:01:14 +00:00
}
}
2023-11-26 07:46:06 +00:00
2024-03-13 21:41:13 +00:00
func podSecurityContext ( sc * SecurityContext , secCtxConf SecurityContextConfig , stepPrivileged bool ) * v1 . PodSecurityContext {
2023-11-26 07:46:06 +00:00
var (
2024-08-06 17:05:04 +00:00
nonRoot * bool
user * int64
group * int64
fsGroup * int64
seccomp * v1 . SeccompProfile
apparmor * v1 . AppArmorProfile
2023-11-26 07:46:06 +00:00
)
2024-03-13 21:41:13 +00:00
if secCtxConf . RunAsNonRoot {
nonRoot = newBool ( true )
2023-11-26 07:46:06 +00:00
}
2024-11-02 17:07:27 +00:00
if secCtxConf . FSGroup != nil {
fsGroup = secCtxConf . FSGroup
}
2023-11-26 07:46:06 +00:00
if sc != nil {
2024-03-13 21:41:13 +00:00
// only allow to set user if its not root or step is privileged
if sc . RunAsUser != nil && ( * sc . RunAsUser != 0 || stepPrivileged ) {
user = sc . RunAsUser
}
// only allow to set group if its not root or step is privileged
if sc . RunAsGroup != nil && ( * sc . RunAsGroup != 0 || stepPrivileged ) {
group = sc . RunAsGroup
}
// only allow to set fsGroup if its not root or step is privileged
if sc . FSGroup != nil && ( * sc . FSGroup != 0 || stepPrivileged ) {
fsGroup = sc . FSGroup
}
2024-11-02 17:07:27 +00:00
// if unset, set fsGroup to 1000 by default to support non-root images
if sc . FSGroup != nil {
fsGroup = sc . FSGroup
}
2024-03-13 21:41:13 +00:00
// only allow to set nonRoot if it's not set globally already
if nonRoot == nil && sc . RunAsNonRoot != nil {
nonRoot = sc . RunAsNonRoot
}
2023-11-26 07:46:06 +00:00
2024-01-12 22:32:24 +00:00
seccomp = seccompProfile ( sc . SeccompProfile )
2024-08-06 17:05:04 +00:00
apparmor = apparmorProfile ( sc . ApparmorProfile )
2024-01-12 22:32:24 +00:00
}
2024-12-03 15:29:03 +00:00
if nonRoot == nil && user == nil && group == nil && fsGroup == nil && seccomp == nil && apparmor == nil {
2023-11-26 07:46:06 +00:00
return nil
}
2023-12-19 03:53:52 +00:00
securityContext := & v1 . PodSecurityContext {
2024-08-06 17:05:04 +00:00
RunAsNonRoot : nonRoot ,
RunAsUser : user ,
RunAsGroup : group ,
FSGroup : fsGroup ,
SeccompProfile : seccomp ,
AppArmorProfile : apparmor ,
2023-11-26 07:46:06 +00:00
}
2024-01-11 18:17:07 +00:00
log . Trace ( ) . Msgf ( "pod security context that will be used: %v" , securityContext )
2023-12-19 03:53:52 +00:00
return securityContext
2023-11-26 07:46:06 +00:00
}
2024-02-08 17:39:32 +00:00
func seccompProfile ( scp * SecProfile ) * v1 . SeccompProfile {
2024-01-12 22:32:24 +00:00
if scp == nil || len ( scp . Type ) == 0 {
return nil
}
log . Trace ( ) . Msgf ( "using seccomp profile: %v" , scp )
seccompProfile := & v1 . SeccompProfile {
Type : v1 . SeccompProfileType ( scp . Type ) ,
}
if len ( scp . LocalhostProfile ) > 0 {
seccompProfile . LocalhostProfile = & scp . LocalhostProfile
}
return seccompProfile
}
2024-08-06 17:05:04 +00:00
func apparmorProfile ( scp * SecProfile ) * v1 . AppArmorProfile {
if scp == nil || len ( scp . Type ) == 0 {
return nil
}
log . Trace ( ) . Msgf ( "using AppArmor profile: %v" , scp )
apparmorProfile := & v1 . AppArmorProfile {
Type : v1 . AppArmorProfileType ( scp . Type ) ,
}
if len ( scp . LocalhostProfile ) > 0 {
apparmorProfile . LocalhostProfile = & scp . LocalhostProfile
}
return apparmorProfile
}
2024-02-08 17:39:32 +00:00
func containerSecurityContext ( sc * SecurityContext , stepPrivileged bool ) * v1 . SecurityContext {
2024-03-13 21:41:13 +00:00
if ! stepPrivileged {
2023-11-26 07:46:06 +00:00
return nil
}
2024-05-30 16:53:03 +00:00
privileged := false
// if security context privileged is set explicitly
2024-03-13 21:41:13 +00:00
if sc != nil && sc . Privileged != nil && * sc . Privileged {
2024-05-30 16:53:03 +00:00
privileged = true
}
// if security context privileged is not set explicitly, but step is privileged
if ( sc == nil || sc . Privileged == nil ) && stepPrivileged {
privileged = true
}
if privileged {
2024-03-13 21:41:13 +00:00
securityContext := & v1 . SecurityContext {
Privileged : newBool ( true ) ,
}
log . Trace ( ) . Msgf ( "container security context that will be used: %v" , securityContext )
return securityContext
2023-11-26 07:46:06 +00:00
}
2024-03-13 21:41:13 +00:00
return nil
2023-12-19 03:53:52 +00:00
}
func mapToEnvVars ( m map [ string ] string ) [ ] v1 . EnvVar {
var ev [ ] v1 . EnvVar
for k , v := range m {
ev = append ( ev , v1 . EnvVar {
Name : k ,
Value : v ,
} )
}
return ev
}
2024-02-08 17:39:32 +00:00
func startPod ( ctx context . Context , engine * kube , step * types . Step , options BackendOptions ) ( * v1 . Pod , error ) {
2024-01-21 02:56:37 +00:00
podName , err := stepToPodName ( step )
2023-12-19 03:53:52 +00:00
if err != nil {
return nil , err
}
2024-01-15 02:59:08 +00:00
engineConfig := engine . getConfig ( )
2024-02-08 17:39:32 +00:00
pod , err := mkPod ( step , engineConfig , podName , engine . goos , options )
2023-12-19 03:53:52 +00:00
if err != nil {
return nil , err
}
2024-01-11 18:17:07 +00:00
log . Trace ( ) . Msgf ( "creating pod: %s" , pod . Name )
2024-05-24 20:35:04 +00:00
return engine . client . CoreV1 ( ) . Pods ( engineConfig . Namespace ) . Create ( ctx , pod , meta_v1 . CreateOptions { } )
2023-12-19 03:53:52 +00:00
}
2024-05-24 20:35:04 +00:00
func stopPod ( ctx context . Context , engine * kube , step * types . Step , deleteOpts meta_v1 . DeleteOptions ) error {
2024-01-21 02:56:37 +00:00
podName , err := stepToPodName ( step )
2023-12-19 03:53:52 +00:00
if err != nil {
return err
}
2024-09-30 00:03:05 +00:00
2024-01-11 18:17:07 +00:00
log . Trace ( ) . Str ( "name" , podName ) . Msg ( "deleting pod" )
2023-12-19 03:53:52 +00:00
err = engine . client . CoreV1 ( ) . Pods ( engine . config . Namespace ) . Delete ( ctx , podName , deleteOpts )
if errors . IsNotFound ( err ) {
// Don't abort on 404 errors from k8s, they most likely mean that the pod hasn't been created yet, usually because pipeline was canceled before running all steps.
return nil
}
return err
2023-11-26 07:46:06 +00:00
}