Skip to content

Commit

Permalink
Base entrypoint image on distroless
Browse files Browse the repository at this point in the history
The only reason it was based on busybox was to have access to `cp`,
which it used to copy its binary to /tekton/tools for use in later
steps.

Instead of relying on `cp`, this adds a "cp mode" to the entrypoint
binary itself. When invoked with the positional args `cp <src> <dst>`,
it copies src to dst using Go's os and io packages.
  • Loading branch information
imjasonh committed May 7, 2020
1 parent 4280425 commit d51fa66
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 10 deletions.
1 change: 0 additions & 1 deletion .ko.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
baseImageOverrides:
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
github.com/tektoncd/pipeline/cmd/entrypoint: busybox # image must have `cp` in $PATH
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 @@ -39,9 +40,41 @@ 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() {
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
}

e := entrypoint.Entrypointer{
Entrypoint: *ep,
WaitFiles: strings.Split(*waitFiles, ","),
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, steps []corev1.Container, results []v1alpha1.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 @@ -97,7 +97,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 @@ -62,7 +62,7 @@ func TestMakePod(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},
}

Expand Down Expand Up @@ -609,7 +609,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
4 changes: 1 addition & 3 deletions pkg/reconciler/taskrun/taskrun_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import (
"github.com/tektoncd/pipeline/pkg/apis/pipeline"
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1"
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"

podconvert "github.com/tektoncd/pipeline/pkg/pod"
"github.com/tektoncd/pipeline/pkg/reconciler/taskrun/resources/cloudevent"
ttesting "github.com/tektoncd/pipeline/pkg/reconciler/testing"
Expand All @@ -40,7 +39,6 @@ import (
test "github.com/tektoncd/pipeline/test/v1alpha1"
corev1 "k8s.io/api/core/v1"
k8sapierrors "k8s.io/apimachinery/pkg/api/errors"

"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
Expand Down Expand Up @@ -241,7 +239,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

0 comments on commit d51fa66

Please sign in to comment.