-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add experimental hermetic execution mode to TaskRun
This PR adds supoprt for an experimental hermetic execution mode. If users specify this on their TaskRun, then all user containers are run without network access. Any containers created or injected by tekton (init containers or sidecar containers) are not affected, and user sidecar containers are also not affected. Some notes around this PR: 1. Adds documentation around hermetic execution mode and points to it from taskrun.md 2. Removes the API change & instead specify execution mode as an annotation on a TaskRun 3. Also puts hermetic execution mode behind the `alpha` feature flag 4. Adds a unit test to make sure that the TEKTON_HERMETIC env var is set such that it can't be overridden Relevant TEP: https://github.com/tektoncd/community/blob/main/teps/0025-hermekton.md
- Loading branch information
Priya Wadhwa
committed
May 20, 2021
1 parent
55ae856
commit 19d9eda
Showing
8 changed files
with
266 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
<!-- | ||
--- | ||
linkTitle: "Hermetic" | ||
weight: 10 | ||
--- | ||
--> | ||
# Hermetic Execution Mode | ||
A Hermetic Build is a release engineering best practice for increasing the reliability and consistency of software builds. | ||
They are self-contained, and do not depend on anything outside of the build environment. | ||
This means they do not have network access, and cannot fetch dependencies at runtime. | ||
|
||
When hermetic execution mode is enabled, all TaskRun steps will be run without access to a network. | ||
_Note: hermetic execution mode does NOT apply to sidecar containers_ | ||
|
||
Hermetic execution mode is currently an alpha experimental feature. | ||
|
||
## Enabling Hermetic Execution Mode | ||
To enable hermetic execution mode: | ||
1. Make sure `enable-api-fields` is set to `"alpha"` in the `feature-flags` configmap, see [`install.md`](./install.md#customizing-the-pipelines-controller-behavior) for details | ||
1. Set the following annotation on any TaskRun you want to run hermetically: | ||
|
||
```yaml | ||
experimental.tekton.dev/execution-mode: hermetic | ||
``` | ||
## Sample Hermetic TaskRun | ||
This example TaskRun demonstrates running a container in a hermetic environment. | ||
The Step attempts to install curl, but this step **SHOULD FAIL** if the hermetic environment is working as expected. | ||
```yaml | ||
kind: TaskRun | ||
apiVersion: tekton.dev/v1beta1 | ||
metadata: | ||
generateName: hermetic-should-fail | ||
annotations: | ||
experimental.tekton.dev/execution-mode: hermetic | ||
spec: | ||
timeout: 60s | ||
taskSpec: | ||
steps: | ||
- name: hermetic | ||
image: ubuntu | ||
script: | | ||
#!/usr/bin/env bash | ||
apt-get update | ||
apt-get install -y curl | ||
``` | ||
## Further Details | ||
To learn more about hermetic execution mode, check out the [TEP](https://github.com/tektoncd/community/blob/main/teps/0025-hermekton.md). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
// +build e2e | ||
|
||
/* | ||
Copyright 2021 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 | ||
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. | ||
*/ | ||
|
||
package test | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
"time" | ||
|
||
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" | ||
corev1 "k8s.io/api/core/v1" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
) | ||
|
||
// TestHermeticTaskRun make sure that the hermetic execution mode actually drops network from a TaskRun step | ||
// it does this by first running the TaskRun normally to make sure it passes | ||
// Then, it enables hermetic mode and makes sure the same TaskRun fails because it no longer has access to a network. | ||
func TestHermeticTaskRun(t *testing.T) { | ||
ctx := context.Background() | ||
ctx, cancel := context.WithCancel(ctx) | ||
defer cancel() | ||
|
||
c, namespace := setup(ctx, t, requireAnyGate(map[string]string{"enable-api-fields": "alpha"})) | ||
t.Parallel() | ||
defer tearDown(ctx, t, c, namespace) | ||
|
||
// first, run the task run with hermetic=false to prove that it succeeds | ||
regularTaskRunName := "not-hermetic" | ||
regularTaskRun := taskRun(regularTaskRunName, namespace, "") | ||
t.Logf("Creating TaskRun %s, hermetic=false", regularTaskRunName) | ||
if _, err := c.TaskRunClient.Create(ctx, regularTaskRun, metav1.CreateOptions{}); err != nil { | ||
t.Fatalf("Failed to create TaskRun `%s`: %s", regularTaskRunName, err) | ||
} | ||
if err := WaitForTaskRunState(ctx, c, regularTaskRunName, Succeed(regularTaskRunName), "TaskRunCompleted"); err != nil { | ||
t.Fatalf("Error waiting for TaskRun %s to finish: %s", regularTaskRunName, err) | ||
} | ||
|
||
// now, run the task mode with hermetic mode | ||
// it should fail, since it shouldn't be able to access any network | ||
hermeticTaskRunName := "hermetic-should-fail" | ||
hermeticTaskRun := taskRun(hermeticTaskRunName, namespace, "hermetic") | ||
t.Logf("Creating TaskRun %s, hermetic=true", hermeticTaskRunName) | ||
if _, err := c.TaskRunClient.Create(ctx, hermeticTaskRun, metav1.CreateOptions{}); err != nil { | ||
t.Fatalf("Failed to create TaskRun `%s`: %s", regularTaskRun.Name, err) | ||
} | ||
if err := WaitForTaskRunState(ctx, c, hermeticTaskRunName, Failed(hermeticTaskRunName), "Failed"); err != nil { | ||
t.Fatalf("Error waiting for TaskRun %s to fail: %s", hermeticTaskRunName, err) | ||
} | ||
} | ||
|
||
func taskRun(name, namespace, executionMode string) *v1beta1.TaskRun { | ||
return &v1beta1.TaskRun{ | ||
ObjectMeta: metav1.ObjectMeta{Name: name, | ||
Namespace: namespace, | ||
Annotations: map[string]string{ | ||
"experimental.tekton.dev/execution-mode": executionMode, | ||
}, | ||
}, | ||
Spec: v1beta1.TaskRunSpec{ | ||
Timeout: &metav1.Duration{Duration: time.Minute}, | ||
TaskSpec: &v1beta1.TaskSpec{ | ||
Steps: []v1beta1.Step{ | ||
{ | ||
Container: corev1.Container{ | ||
Name: "access-network", | ||
Image: "ubuntu", | ||
}, | ||
Script: `#!/bin/bash | ||
set -ex | ||
apt-get update | ||
apt-get install -y curl`, | ||
}, | ||
}, | ||
}, | ||
}, | ||
} | ||
} |