Skip to content

Commit

Permalink
#7617 support k8s native sidecar
Browse files Browse the repository at this point in the history
  • Loading branch information
kgcarr committed Jul 11, 2024
1 parent 0db5ca2 commit 4c438da
Show file tree
Hide file tree
Showing 23 changed files with 426 additions and 10 deletions.
2 changes: 2 additions & 0 deletions config/config-feature-flags.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,5 @@ data:
disable-inline-spec: ""
# Setting this flag to "true" will enable the use of concise resolver syntax
enable-concise-resolver-syntax: "false"
# Setthing this flag to "true" will enable native Kubernetes Sidecar support
enable-kubernetes-sidecar: "false"
34 changes: 34 additions & 0 deletions docs/pipeline-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -4135,6 +4135,23 @@ other Step or Sidecar that does not also request this Workspace will
not have access to it.</p>
</td>
</tr>
<tr>
<td>
<code>restartPolicy</code><br/>
<em>
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#containerrestartpolicy-v1-core">
Kubernetes core/v1.ContainerRestartPolicy
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>RestartPolicy refers to kubernetes RestartPolicy. It can only be set for an
initContainer and must have it&rsquo;s policy set to &ldquo;Always&rdquo;. It is currently
left optional to help support Kubernetes versions prior to 1.29 when this feature
was introduced.</p>
</td>
</tr>
</tbody>
</table>
<h3 id="tekton.dev/v1.SidecarState">SidecarState
Expand Down Expand Up @@ -13459,6 +13476,23 @@ other Step or Sidecar that does not also request this Workspace will
not have access to it.</p>
</td>
</tr>
<tr>
<td>
<code>restartPolicy</code><br/>
<em>
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#containerrestartpolicy-v1-core">
Kubernetes core/v1.ContainerRestartPolicy
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>RestartPolicy refers to kubernetes RestartPolicy. It can only be set for an
initContainer and must have it&rsquo;s policy set to &ldquo;Always&rdquo;. It is currently
left optional to help support Kubernetes versions prior to 1.29 when this feature
was introduced.</p>
</td>
</tr>
</tbody>
</table>
<h3 id="tekton.dev/v1beta1.SidecarState">SidecarState
Expand Down
9 changes: 9 additions & 0 deletions examples/v1/taskruns/sidecar-ready.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ spec:
- -c
- sleep 5 && touch /shared/ready
timeoutSeconds: 10
# Adding startup probe for k8s native sidecar support
# Readiness Probe is not honored for k8s native sidecar support
startupProbe:
exec:
command:
- sh
- -c
- sleep 5 && touch /shared/ready
timeoutSeconds: 10
volumeMounts:
- name: shared
mountPath: /shared
Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module github.com/tektoncd/pipeline

go 1.22
go 1.22.3

toolchain go1.22.4

require (
Expand Down
8 changes: 8 additions & 0 deletions pkg/apis/config/feature_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ const (
EnableParamEnum = "enable-param-enum"
// EnableConciseResolverSyntax is the flag to enable concise resolver syntax
EnableConciseResolverSyntax = "enable-concise-resolver-syntax"
// EnableKubernetesSidecar is the flag to enable kubernetes sidecar support
EnableKubernetesSidecar = "enable-kubernetes-sidecar"
// DefaultEnableKubernetesSidecar is the default value for EnableKubernetesSidecar
DefaultEnableKubernetesSidecar = false

// DisableInlineSpec is the flag to disable embedded spec
// in Taskrun or Pipelinerun
Expand Down Expand Up @@ -208,6 +212,7 @@ type FeatureFlags struct {
EnableArtifacts bool
DisableInlineSpec string
EnableConciseResolverSyntax bool
EnableKubernetesSidecar bool
}

// GetFeatureFlagsConfigName returns the name of the configmap containing all
Expand Down Expand Up @@ -312,6 +317,9 @@ func NewFeatureFlagsFromMap(cfgMap map[string]string) (*FeatureFlags, error) {
if err := setPerFeatureFlag(EnableConciseResolverSyntax, DefaultEnableConciseResolverSyntax, &tc.EnableConciseResolverSyntax); err != nil {
return nil, err
}
if err := setFeature(EnableKubernetesSidecar, DefaultEnableKubernetesSidecar, &tc.EnableKubernetesSidecar); err != nil {
return nil, err
}

return &tc, nil
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/apis/config/feature_flags_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ func TestNewFeatureFlagsFromConfigMap(t *testing.T) {
EnableParamEnum: true,
DisableInlineSpec: "pipeline,pipelinerun,taskrun",
EnableConciseResolverSyntax: true,
EnableKubernetesSidecar: true,
},
fileName: "feature-flags-all-flags-set",
},
Expand Down Expand Up @@ -314,6 +315,9 @@ func TestNewFeatureFlagsConfigMapErrors(t *testing.T) {
}, {
fileName: "feature-flags-invalid-enable-concise-resolver-syntax",
want: `failed parsing feature flags config "invalid": strconv.ParseBool: parsing "invalid": invalid syntax for feature enable-concise-resolver-syntax`,
}, {
fileName: "feature-flags-invalid-enable-kubernetes-sidecar",
want: `failed parsing feature flags config "invalid": strconv.ParseBool: parsing "invalid": invalid syntax for feature enable-kubernetes-sidecar`,
}} {
t.Run(tc.fileName, func(t *testing.T) {
cm := test.ConfigMapFromTestFile(t, tc.fileName)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Copyright 2024 The Tekton 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
#
# https://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.

apiVersion: v1
kind: ConfigMap
metadata:
name: feature-flags
namespace: tekton-pipelines
data:
enable-kubernetes-sidecar: "invalid"
37 changes: 36 additions & 1 deletion pkg/apis/pipeline/v1/container_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -543,10 +543,43 @@ type Sidecar struct {
// +optional
// +listType=atomic
Workspaces []WorkspaceUsage `json:"workspaces,omitempty"`

// RestartPolicy refers to kubernetes RestartPolicy. It can only be set for an
// initContainer and must have it's policy set to "Always". It is currently
// left optional to help support Kubernetes versions prior to 1.29 when this feature
// was introduced.
// +optional
RestartPolicy *corev1.ContainerRestartPolicy `json:"restartPolicy,omitempty"`
}

// ToK8sContainer converts the Sidecar to a Kubernetes Container struct
func (s *Sidecar) ToK8sContainer() *corev1.Container {
if s.RestartPolicy == nil {
return &corev1.Container{
Name: s.Name,
Image: s.Image,
Command: s.Command,
Args: s.Args,
WorkingDir: s.WorkingDir,
Ports: s.Ports,
EnvFrom: s.EnvFrom,
Env: s.Env,
Resources: s.ComputeResources,
VolumeMounts: s.VolumeMounts,
VolumeDevices: s.VolumeDevices,
LivenessProbe: s.LivenessProbe,
ReadinessProbe: s.ReadinessProbe,
StartupProbe: s.StartupProbe,
Lifecycle: s.Lifecycle,
TerminationMessagePath: s.TerminationMessagePath,
TerminationMessagePolicy: s.TerminationMessagePolicy,
ImagePullPolicy: s.ImagePullPolicy,
SecurityContext: s.SecurityContext,
Stdin: s.Stdin,
StdinOnce: s.StdinOnce,
TTY: s.TTY,
}
}
return &corev1.Container{
Name: s.Name,
Image: s.Image,
Expand All @@ -561,6 +594,7 @@ func (s *Sidecar) ToK8sContainer() *corev1.Container {
VolumeDevices: s.VolumeDevices,
LivenessProbe: s.LivenessProbe,
ReadinessProbe: s.ReadinessProbe,
RestartPolicy: s.RestartPolicy,
StartupProbe: s.StartupProbe,
Lifecycle: s.Lifecycle,
TerminationMessagePath: s.TerminationMessagePath,
Expand All @@ -587,7 +621,7 @@ func (s *Sidecar) SetContainerFields(c corev1.Container) {
s.VolumeMounts = c.VolumeMounts
s.VolumeDevices = c.VolumeDevices
s.LivenessProbe = c.LivenessProbe
s.ReadinessProbe = c.ReadinessProbe
s.ReadinessProbe = c.ReadinessProbe // May need to move this into if statement
s.StartupProbe = c.StartupProbe
s.Lifecycle = c.Lifecycle
s.TerminationMessagePath = c.TerminationMessagePath
Expand All @@ -597,6 +631,7 @@ func (s *Sidecar) SetContainerFields(c corev1.Container) {
s.Stdin = c.Stdin
s.StdinOnce = c.StdinOnce
s.TTY = c.TTY
s.RestartPolicy = c.RestartPolicy
}

// GetVarSubstitutionExpressions walks all the places a substitution reference can be used
Expand Down
32 changes: 32 additions & 0 deletions pkg/apis/pipeline/v1/container_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,35 @@ func TestSidecarGetVarSubstitutionExpressions(t *testing.T) {
t.Fatalf("Unexpected result (-want, +got): %s", d)
}
}

func TestSidecarRestartPolicyToK8sContainer(t *testing.T) {
always := corev1.ContainerRestartPolicyAlways
s := Sidecar{
Name: "sidecarName",
RestartPolicy: &always,
}

expectedContainer := corev1.Container{
Name: "sidecarName",
RestartPolicy: &always,
}

c := s.ToK8sContainer()

if !(c.RestartPolicy == expectedContainer.RestartPolicy) {
t.Fatalf("Unexpected result with RestartPolicy")
}

s = Sidecar{
Name: "sidecarName",
}

expectedContainer = corev1.Container{
Name: "sidecarName",
}

c = s.ToK8sContainer()
if !(c.RestartPolicy == expectedContainer.RestartPolicy) {
t.Fatalf("Unexpected result without RestartPolicy")
}
}
7 changes: 7 additions & 0 deletions pkg/apis/pipeline/v1/openapi_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions pkg/apis/pipeline/v1/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -1325,6 +1325,10 @@
"description": "Periodic probe of Sidecar service readiness. Container will be removed from service endpoints if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes",
"$ref": "#/definitions/v1.Probe"
},
"restartPolicy": {
"description": "RestartPolicy refers to kubernetes RestartPolicy. It can only be set for an initContainer and must have it's policy set to \"Always\". It is currently left optional to help support Kubernetes versions prior to 1.29 when this feature was introduced.",
"type": "string"
},
"script": {
"description": "Script is the contents of an executable file to execute.\n\nIf Script is not empty, the Step cannot have an Command or Args.",
"type": "string"
Expand Down
5 changes: 5 additions & 0 deletions pkg/apis/pipeline/v1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 35 additions & 0 deletions pkg/apis/pipeline/v1beta1/container_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -747,10 +747,43 @@ type Sidecar struct {
// +optional
// +listType=atomic
Workspaces []WorkspaceUsage `json:"workspaces,omitempty"`

// RestartPolicy refers to kubernetes RestartPolicy. It can only be set for an
// initContainer and must have it's policy set to "Always". It is currently
// left optional to help support Kubernetes versions prior to 1.29 when this feature
// was introduced.
// +optional
RestartPolicy *corev1.ContainerRestartPolicy `json:"restartPolicy,omitempty"`
}

// ToK8sContainer converts the Sidecar to a Kubernetes Container struct
func (s *Sidecar) ToK8sContainer() *corev1.Container {
if s.RestartPolicy == nil {
return &corev1.Container{
Name: s.Name,
Image: s.Image,
Command: s.Command,
Args: s.Args,
WorkingDir: s.WorkingDir,
Ports: s.Ports,
EnvFrom: s.EnvFrom,
Env: s.Env,
Resources: s.Resources,
VolumeMounts: s.VolumeMounts,
VolumeDevices: s.VolumeDevices,
LivenessProbe: s.LivenessProbe,
ReadinessProbe: s.ReadinessProbe,
StartupProbe: s.StartupProbe,
Lifecycle: s.Lifecycle,
TerminationMessagePath: s.TerminationMessagePath,
TerminationMessagePolicy: s.TerminationMessagePolicy,
ImagePullPolicy: s.ImagePullPolicy,
SecurityContext: s.SecurityContext,
Stdin: s.Stdin,
StdinOnce: s.StdinOnce,
TTY: s.TTY,
}
}
return &corev1.Container{
Name: s.Name,
Image: s.Image,
Expand All @@ -765,6 +798,7 @@ func (s *Sidecar) ToK8sContainer() *corev1.Container {
VolumeDevices: s.VolumeDevices,
LivenessProbe: s.LivenessProbe,
ReadinessProbe: s.ReadinessProbe,
RestartPolicy: s.RestartPolicy,
StartupProbe: s.StartupProbe,
Lifecycle: s.Lifecycle,
TerminationMessagePath: s.TerminationMessagePath,
Expand Down Expand Up @@ -801,4 +835,5 @@ func (s *Sidecar) SetContainerFields(c corev1.Container) {
s.Stdin = c.Stdin
s.StdinOnce = c.StdinOnce
s.TTY = c.TTY
s.RestartPolicy = c.RestartPolicy
}
7 changes: 7 additions & 0 deletions pkg/apis/pipeline/v1beta1/openapi_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions pkg/apis/pipeline/v1beta1/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -1932,6 +1932,10 @@
"default": {},
"$ref": "#/definitions/v1.ResourceRequirements"
},
"restartPolicy": {
"description": "RestartPolicy refers to kubernetes RestartPolicy. It can only be set for an initContainer and must have it's policy set to \"Always\". It is currently left optional to help support Kubernetes versions prior to 1.29 when this feature was introduced.",
"type": "string"
},
"script": {
"description": "Script is the contents of an executable file to execute.\n\nIf Script is not empty, the Step cannot have an Command or Args.",
"type": "string"
Expand Down
5 changes: 5 additions & 0 deletions pkg/apis/pipeline/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 4c438da

Please sign in to comment.