Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Base entrypoint image on distroless #3286

Merged
merged 1 commit into from
Sep 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions .ko.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@ baseImageOverrides:
# They are produced from ./images/Dockerfile
github.com/tektoncd/pipeline/cmd/creds-init: gcr.io/tekton-nightly/github.com/tektoncd/pipeline/build-base:latest
github.com/tektoncd/pipeline/cmd/git-init: gcr.io/tekton-nightly/github.com/tektoncd/pipeline/build-base:latest

# GCS fetcher needs root due to workspace permissions
github.com/tektoncd/pipeline/vendor/github.com/GoogleCloudPlatform/cloud-builders/gcs-fetcher/cmd/gcs-fetcher: gcr.io/distroless/static:latest
# PullRequest resource needs root because in output mode it needs to access pr.json
# which might have been copied or written with any level of permissions.
github.com/tektoncd/pipeline/cmd/pullrequest-init: gcr.io/distroless/static:latest

# Our entrypoint image does not need root, it simply needs to be able to 'cp' the binary into a shared location.
github.com/tektoncd/pipeline/cmd/entrypoint: gcr.io/distroless/base:debug-nonroot
33 changes: 33 additions & 0 deletions cmd/entrypoint/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package main

import (
"flag"
"io"
"log"
"os"
"os/exec"
Expand All @@ -42,13 +43,45 @@ var (
waitPollingInterval = time.Second
)

func cp(src, dst string) error {
s, err := os.Open(src)
if err != nil {
return err
}
defer s.Close()

// Owner has permission to write and execute, and anybody has
// permission to execute.
d, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE, 0311)
if err != nil {
return err
}
defer d.Close()

_, err = io.Copy(d, s)
return err
}

func main() {
// Add credential flags originally used in creds-init.
gitcreds.AddFlags(flag.CommandLine)
dockercreds.AddFlags(flag.CommandLine)

flag.Parse()

// If invoked in "cp mode" (`entrypoint cp <src> <dst>`), simply copy
// the src path to the dst path. This is used to place the entrypoint
// binary in the tools directory, without requiring the cp command to
// exist in the base image.
if len(flag.Args()) == 3 && flag.Args()[0] == "cp" {
src, dst := flag.Args()[1], flag.Args()[2]
if err := cp(src, dst); err != nil {
log.Fatal(err)
}
log.Println("Copied", src, "to", dst)
return
}

// Copy creds-init credentials from secret volume mounts to /tekton/creds
// This is done to support the expansion of a variable, $(credentials.path), that
// resolves to a single place with all the stored credentials.
Expand Down
8 changes: 5 additions & 3 deletions pkg/pod/entrypoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,11 @@ var (
// TODO(#1605): Also use entrypoint injection to order sidecar start/stop.
func orderContainers(entrypointImage string, extraEntrypointArgs []string, steps []corev1.Container, results []v1beta1.TaskResult) (corev1.Container, []corev1.Container, error) {
initContainer := corev1.Container{
Name: "place-tools",
Image: entrypointImage,
Command: []string{"cp", "/ko-app/entrypoint", entrypointBinary},
Name: "place-tools",
Image: entrypointImage,
// Invoke the entrypoint binary in "cp mode" to copy itself
// into the correct location for later steps.
Command: []string{"/ko-app/entrypoint", "cp", "/ko-app/entrypoint", entrypointBinary},
VolumeMounts: []corev1.VolumeMount{toolsMount},
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/pod/entrypoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func TestOrderContainers(t *testing.T) {
wantInit := corev1.Container{
Name: "place-tools",
Image: images.EntrypointImage,
Command: []string{"cp", "/ko-app/entrypoint", entrypointBinary},
Command: []string{"/ko-app/entrypoint", "cp", "/ko-app/entrypoint", entrypointBinary},
VolumeMounts: []corev1.VolumeMount{toolsMount},
}
if d := cmp.Diff(wantInit, gotInit); d != "" {
Expand Down
4 changes: 2 additions & 2 deletions pkg/pod/pod_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func TestPodBuild(t *testing.T) {
placeToolsInit := corev1.Container{
Name: "place-tools",
Image: images.EntrypointImage,
Command: []string{"cp", "/ko-app/entrypoint", "/tekton/tools/entrypoint"},
Command: []string{"/ko-app/entrypoint", "cp", "/ko-app/entrypoint", "/tekton/tools/entrypoint"},
VolumeMounts: []corev1.VolumeMount{toolsMount},
}
runtimeClassName := "gvisor"
Expand Down Expand Up @@ -772,7 +772,7 @@ script-heredoc-randomly-generated-78c5n
{
Name: "place-tools",
Image: images.EntrypointImage,
Command: []string{"cp", "/ko-app/entrypoint", "/tekton/tools/entrypoint"},
Command: []string{"/ko-app/entrypoint", "cp", "/ko-app/entrypoint", "/tekton/tools/entrypoint"},
VolumeMounts: []corev1.VolumeMount{toolsMount},
}},
Containers: []corev1.Container{{
Expand Down
2 changes: 1 addition & 1 deletion pkg/reconciler/taskrun/taskrun_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ var (

getPlaceToolsInitContainer = func(ops ...tb.ContainerOp) tb.PodSpecOp {
actualOps := []tb.ContainerOp{
tb.Command("cp", "/ko-app/entrypoint", entrypointLocation),
tb.Command("/ko-app/entrypoint", "cp", "/ko-app/entrypoint", entrypointLocation),
tb.VolumeMount("tekton-internal-tools", "/tekton/tools"),
tb.Args(),
}
Expand Down