From bbb767cd8fb3e52ded726ddbbc531745e3fe17c0 Mon Sep 17 00:00:00 2001 From: Scott Date: Tue, 19 May 2020 16:18:14 -0400 Subject: [PATCH] Remove creds-init intContainer Creds-init is an initContainer that writes credential files (like .ssh) to /tekton/home. One side-effect of relying on an initContainer to write these files is that they receive the UID / Group ID of the initContainer's process. This side-effect breaks any Step in the Task that relies on these credentials but runs with a different UID. An example of where this can happen is on OpenShift, where the UID of the user is randomized for each container in order to limit the fallout of malicious process breaking out. This commit removes the creds-init initContainer from all TaskRun Pods. I haven't removed the creds-init binary from our build process in this changeset. Doing so generates a lot of extra line noise which distracts from the core modification being presented here. This commit introduces an example YAML that successfully exercises creds-init with vanilla git commands both when the disable-home-env-overwrite flag is "false" (the current default) and when it's "true". In addition the example demonstrates working with creds-init credentials when a non-root securityContext is set on a Step. --- cmd/creds-init/main.go | 3 +- cmd/entrypoint/main.go | 18 +- docs/auth.md | 28 +- docs/variables.md | 2 +- .../taskruns/authenticating-git-commands.yaml | 204 ++++++++++++++ pkg/apis/pipeline/paths.go | 2 + pkg/credentials/dockercreds/creds.go | 13 +- pkg/credentials/dockercreds/creds_test.go | 12 +- pkg/credentials/gitcreds/basic.go | 7 +- pkg/credentials/gitcreds/creds.go | 15 +- pkg/credentials/gitcreds/creds_test.go | 16 +- pkg/credentials/gitcreds/ssh.go | 4 +- pkg/credentials/initialize.go | 15 +- pkg/pod/creds_init.go | 110 +++----- pkg/pod/creds_init_test.go | 87 +++--- pkg/pod/entrypoint.go | 3 +- pkg/pod/entrypoint_test.go | 8 +- pkg/pod/pod.go | 33 ++- pkg/pod/pod_test.go | 256 ++++++++++++------ pkg/reconciler/taskrun/resources/apply.go | 4 +- pkg/reconciler/taskrun/taskrun.go | 2 +- pkg/reconciler/taskrun/taskrun_test.go | 161 +++++++---- 22 files changed, 681 insertions(+), 322 deletions(-) create mode 100644 examples/v1beta1/taskruns/authenticating-git-commands.yaml diff --git a/cmd/creds-init/main.go b/cmd/creds-init/main.go index a7453a0d798..7c1f461b000 100644 --- a/cmd/creds-init/main.go +++ b/cmd/creds-init/main.go @@ -18,6 +18,7 @@ package main import ( "flag" + "github.com/tektoncd/pipeline/pkg/apis/pipeline" "github.com/tektoncd/pipeline/pkg/credentials" "github.com/tektoncd/pipeline/pkg/credentials/dockercreds" "github.com/tektoncd/pipeline/pkg/credentials/gitcreds" @@ -37,7 +38,7 @@ func main() { builders := []credentials.Builder{dockercreds.NewBuilder(), gitcreds.NewBuilder()} for _, c := range builders { - if err := c.Write(); err != nil { + if err := c.Write(pipeline.CredsDir); err != nil { logger.Fatalf("Error initializing credentials: %v", err) } } diff --git a/cmd/entrypoint/main.go b/cmd/entrypoint/main.go index 908a5b59050..d675fcd8763 100644 --- a/cmd/entrypoint/main.go +++ b/cmd/entrypoint/main.go @@ -26,6 +26,8 @@ import ( "time" "github.com/tektoncd/pipeline/pkg/credentials" + "github.com/tektoncd/pipeline/pkg/credentials/dockercreds" + "github.com/tektoncd/pipeline/pkg/credentials/gitcreds" "github.com/tektoncd/pipeline/pkg/entrypoint" "github.com/tektoncd/pipeline/pkg/termination" ) @@ -41,8 +43,22 @@ var ( ) func main() { + // Add credential flags originally used in creds-init. + gitcreds.AddFlags(flag.CommandLine) + dockercreds.AddFlags(flag.CommandLine) + flag.Parse() + // 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. + builders := []credentials.Builder{dockercreds.NewBuilder(), gitcreds.NewBuilder()} + for _, c := range builders { + if err := c.Write("/tekton/creds"); err != nil { + log.Printf("Error initializing credentials: %s", err) + } + } + e := entrypoint.Entrypointer{ Entrypoint: *ep, WaitFiles: strings.Split(*waitFiles, ","), @@ -56,7 +72,7 @@ func main() { Results: strings.Split(*results, ","), } - // Copy any creds injected by creds-init into the $HOME directory of the current + // Copy any creds injected by the controller into the $HOME directory of the current // user so that they're discoverable by git / ssh. if err := credentials.CopyCredsToHome(credentials.CredsInitCredentials); err != nil { log.Printf("non-fatal error copying credentials: %q", err) diff --git a/docs/auth.md b/docs/auth.md index 6cf527acadc..c75689c6b6f 100644 --- a/docs/auth.md +++ b/docs/auth.md @@ -121,10 +121,14 @@ This is required because while Tekton does set the $HOME environment variable to `/tekton/home` by default, `ssh` ignores that environment variable and only considers the user's home as that described in `/etc/passwd`. -**Note:** This additional symlink is not required if you are using the +**Note:** The additional symlink is not required if you are using the [`git-clone` catalog Task](https://github.com/tektoncd/catalog/tree/v1beta1/git) or Git PipelineResource. +For an example of vanilla git commands using the SSH credentials described +above, see the +[authenticating-git-commands example](../examples/v1beta1/taskruns/authenticating-git-commands.yaml). + ## Basic authentication (Git) 1. Define a `Secret` containing the username and password that the `Run` should @@ -375,6 +379,28 @@ Credential annotation keys must begin with `tekton.dev/docker-` or `tekton.dev/git-`, and the value describes the URL of the host with which to use the credential. +## Using credentials as non-root user + +For a number of reasons you may need to use the credentials described in this +doc in non-root contexts: + +- Your platform may randomize the user and/or groups that your containers run as. +- The Steps of Tasks that you use may define a non-root `securityContext`. +- Tasks themselves may specify non-root `securityContext`s applied to all `Steps`. + +Running as a non-root user has several effects that need to be accounted for +when using the credentials mounted with the process described above: + +1. Certain credential types (SSH/git) require that the user have a valid home +directory defined in `/etc/passwd`. Just having a random UID but no home directory +will result in SSH erroring out. +2. Credentials may need to be moved or symlinked from the `$HOME` directory that +Tekton defines (`/tekton/home`) to the correct `home` directory for your user. +This is true for SSH, which ignores the `$HOME` environment variable completely. + +For an example of using SSH credentials in a non-root `securityContext`, see the +[authenticating-git-commands example](../examples/v1beta1/taskruns/authenticating-git-commands.yaml). + ## Implementation details ### Docker `basic-auth` diff --git a/docs/variables.md b/docs/variables.md index e30a40aeab3..3d1f95830d9 100644 --- a/docs/variables.md +++ b/docs/variables.md @@ -29,7 +29,7 @@ This page documents the variable substitions supported by `Tasks` and `Pipelines | `workspaces..path` | The path to the mounted `Workspace`. | | `workspaces..claim` | The name of the `PersistentVolumeClaim` specified as a volume source for the `Workspace`. Empty string for other volume types. | | `workspaces..volume` | The name of the volume populating the `Workspace`. | -| `credentials.path` | The path to the credentials written by the `creds-init` init container. | +| `credentials.path` | The path to credentials injected from Secrets with matching annotations. | | `context.taskRun.name` | The name of the `TaskRun` that this `Task` is running in. | | `context.task.name` | The name of this `Task`. | diff --git a/examples/v1beta1/taskruns/authenticating-git-commands.yaml b/examples/v1beta1/taskruns/authenticating-git-commands.yaml new file mode 100644 index 00000000000..330aaa44603 --- /dev/null +++ b/examples/v1beta1/taskruns/authenticating-git-commands.yaml @@ -0,0 +1,204 @@ +# This example demonstrates usage of creds-init credentials to issue +# git commands without a Git PipelineResource or git-clone catalog task. +# +# In order to exercise creds-init a sidecar is used to run a +# git server fronted by SSH. The sidecar does the following things: +# - Generates a host key pair, providing the public key to Steps for their known_hosts file +# - Accepts a public key generated from creds-init credentials and uses that for an authorized_keys file +# - Creates a bare git repo for the test git commands to run against +# - Starts sshd and tails its log, waiting for the git commands to come in over SSH +# +# Two separate Steps then perform authenticated git actions against the sidecar +# git server using the credentials mounted by creds-init: + +# The first step makes a git clone of the bare repository and populates it +# with a file. +# +# The second step makes a git clone of the populated repository and checks +# the contents of the repo match expectations. This step runs as a non-root +# user in order to exercise creds-init credentials when a securityContext +# is set. +# +# Notice that in each Step there is different code for handling creds-init +# credentials when the disable-home-env-overwrite flag is "false" and when +# it's "true". +apiVersion: v1 +kind: Secret +type: kubernetes.io/ssh-auth +metadata: + name: ssh-key-for-git + annotations: + tekton.dev/git-0: localhost +data: + # This key was generated for this test and isn't used for anything else. + ssh-privatekey: LS0tLS1CRUdJTiBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0KYjNCbGJuTnphQzFyWlhrdGRqRUFBQUFBQkc1dmJtVUFBQUFFYm05dVpRQUFBQUFBQUFBQkFBQUJsd0FBQUFkemMyZ3RjbgpOaEFBQUFBd0VBQVFBQUFZRUF5T1g3ZG5OWlFBZVk4cHNMOXlaUnp3NXNDVG1yWGh6Zld1YTZuZ2VDQ0VRRTY4YjVUSThTCkNlbEhlNG9oTUtBdXZ0ZTE4YXJMK2EvVldpeFN6a2tBMmFIZVhkdUJ1bStkS2R2TlVVSUhNc1dOUythcENQYmE4R3ZGaHYKdG81Tkx0bWpxT2M0WjJkK1RPS3AvakMrS3pvUDFHQWdRL25QMitMTldabzlvTTc4TzQ3Z1dSem9FNlFKeGJqbFlPMHRMbwp4YXUxdTNrbUtsNSthbUxsNHpGN25wdmV1dGlSWDhmY2hGam5Ka2dqK3BVeFJvTGF4SDdDN0NTcDExWUkyMEhKRVFXeEk3CllaekNTYml5KzZ1a2l0Tk1MZ29qMnpSTGl2ZTVvZm9nenpYbkdWUUpZdUIzOFhQM0ZIQWMvOXhzUXdzd3dQS2hkQ3g4T0QKbjErYXpLOHp5SGhXK0dxckJhS1R4cDlrcVRpKzZSMWk4ZjVxOEt6NXpGVTZmd05qQXZ3STFBZ3IwS2FzU1JxWTVMcGxnTgpZcW1DY01JODZKUnRGWHRWWVQrT05tdWFhYUQ1QUErbnpkNW81R0haZTlFSlNqUThZMHZwbjhmNjNjeEw2RTdzVmxpMnpzCnNhN1RST2JMK3YyVnFuSlpEY2pIZXMzS1M5Mld0V3RJbXdXOG81VkRBQUFGaU04K0NUL1BQZ2svQUFBQUIzTnphQzF5YzIKRUFBQUdCQU1qbCszWnpXVUFIbVBLYkMvY21VYzhPYkFrNXExNGMzMXJtdXA0SGdnaEVCT3ZHK1V5UEVnbnBSM3VLSVRDZwpMcjdYdGZHcXkvbXYxVm9zVXM1SkFObWgzbDNiZ2Jwdm5TbmJ6VkZDQnpMRmpVdm1xUWoyMnZCcnhZYjdhT1RTN1pvNmpuCk9HZG5ma3ppcWY0d3ZpczZEOVJnSUVQNXo5dml6Vm1hUGFETy9EdU80RmtjNkJPa0NjVzQ1V0R0TFM2TVdydGJ0NUppcGUKZm1waTVlTXhlNTZiM3JyWWtWL0gzSVJZNXlaSUkvcVZNVWFDMnNSK3d1d2txZGRXQ050QnlSRUZzU08yR2N3a200c3Z1cgpwSXJUVEM0S0k5czBTNHIzdWFINklNODE1eGxVQ1dMZ2QvRno5eFJ3SFAvY2JFTUxNTUR5b1hRc2ZEZzU5Zm1zeXZNOGg0ClZ2aHFxd1dpazhhZlpLazR2dWtkWXZIK2F2Q3MrY3hWT244RFl3TDhDTlFJSzlDbXJFa2FtT1M2WllEV0twZ25EQ1BPaVUKYlJWN1ZXRS9qalpybW1tZytRQVBwODNlYU9SaDJYdlJDVW8wUEdOTDZaL0grdDNNUytoTzdGWll0czdMR3UwMFRteS9yOQpsYXB5V1EzSXgzck55a3ZkbHJWclNKc0Z2S09WUXdBQUFBTUJBQUVBQUFHQUNQSGtmbU9vWjZkdThlNWhYQUhDeHJ0WHFCCmwvUGROL1JtYmJqRW05U216czR5cWEwd1BUdzhrMU81VHM0V05nY1hMZFVRTlB6YkE4aWFWTGtvL0JqKzhiSFlhMmdmeVMKUE5qaWpXbXBOR09EWlF2Q0h2b095WUdpNjkycHovWnNTZCt0bEFzNm54LzY1ZjcwZHdVREJub0FjZnFLY28wQnVMRlNBKworamY5RnhISGYzQkFEUS9TdDVFQjlZelo1Q2F2cTRQcjZvS2w3R3RpbnRIbTZIbUlwTUlubWVEMnV3cjl2ZGZ1RGJhVDdYClVOSm10elVGck1uOUhlOWd1WkoyTXd3a015S09ScnRhVFA3VjFZK3FOM3ZncStmRkNtU0VkekxBU3BWTHMyL1hQTCtwTnAKTTVZUVRRMFJSZWdKTEdtTHZ0ZmpkK1RRMFQ0bjBucnBJVGRXRTRsL05sTG9taTVhUndzQXFtY2hZSGxhN0g3YlNyS2lKawpyWTg1RTliZm8wSXJqUDNQNzFYNmxjcTB0VDhDTklUQUNleWJQT3kwcDVDc3JwZTdhZEJBOXF4MTZjR2tkZ0NPWk9GMnRpCktoWWJHeTc4ei9YNEh2OEptVmhaSHF3RlFQQzVleWljbE1PTFJXNDJOcUJhNEVFc3RHT3l4MHZwa0lVS3VhRlJuQkFBQUEKd1FESytXYzU1WHVpWjgySXM5NnN2bWIrR0Y5c2pBRWVaWHpHSWpDL1NHVEhIWTZSQmc1TnlQOUdZNmtoWnBjd0cyTU52dQpZUjhuN0psRWlVanU2cjY2Smh0WGtvdTR4WlU1dDkvMlJvdHRmeWpKODJmYm8yTHZmNERUOVNvSURxZnk5VmlMSjhSWUNkCkt6NnpYSHFTZ1RBRU1vaUhjbFpIZzRqTitrOW1ma2tPMDBQbEJJaE1YU0ZMLzUrZUhGdStQTmxaU1g5NUlMRjJvZ0Y1RG0KWTFuaTRUOGJjdzY2dmFzamthcjFZekptM1VidEVnSzQ2VVllNGJac2NXbWt4dngwMEFBQURCQVA4UysyTmtheWkvb3NzVApTQXpJMi9QU2tJMDVEY1lTYnNOQjZ4a3pobzdKaDlHeUNvbW5xZ1IxR2ZBOTBqV3AxVks0TG43TmtYYWJaVmJPc0xoT21DCkdBbVRZTHRjaTB0bkhhYk5HTEZ3ZmdiUitqRzZNQ2p4cEh5anM5MDlKSHhtYmswbElpczdPN1N3VThERGcrSEVxc0EvNUoKQ1VMTWU3em9mNERhUnZXdFhTRks2ZW5LNnpGaHBINjVQY29TN0o0NjJhNzdUMDVGQXhMemNaRkc5VWZ5WUdMa1ZmdHRTTApNVDhudW9LaW5XTGNLSlVQeis1MjJlM3lIcis4c3pVUUFBQU1FQXlhQ28xSnRBcjRpczY0YTBuZTFUV0o0dXcyT3FDdUlDCm9acG1QN2UyRnh3bVRCSWMrbzZkSEVNVHo2c2ZZSkFxU2l4ZzYydXYzWlRTc25STWljaDZ0b1k0SVI4cWFMa1prLzU5cmEKQWFONFlvTkdpQTZxY0Jzc3NLMmZuM2YxRFJhckxPbWZHTnpTMU41S1RvSFVlUkVGWDExdHVNM1pqOGxTelFBOWZSakk1OQpFWmFnOWJaOXRJOEg5dmEvTGRMK3U3dTZZWkVRSEJCS1MxMW1tOVVXd1pDMkdUV3ZnNzRlTnRmemtZeDQxdlhIeTZBbW9ECmxuOHo2N3lvWEZzbEpUQUFBQURuTmpiM1IwUUcxbFkyZ3ViR0Z1QVFJREJBPT0KLS0tLS1FTkQgT1BFTlNTSCBQUklWQVRFIEtFWS0tLS0tCg== + # This known_hosts file doesn't actually get used; we overwrite it with the public key + # of our temporary test git server. But it's required here because otherwise creds-init + # calls ssh-keyscan which in turn tries to reach out over the network, will fail to make + # contact with the localhost SSH server because it isn't running yet, and the TaskRun + # will end in failure. + known_hosts: Cg== +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: ssh-key-service-account +secrets: +- name: ssh-key-for-git +--- +apiVersion: tekton.dev/v1beta1 +kind: TaskRun +metadata: + name: authenticating-git-commands +spec: + serviceAccountName: ssh-key-service-account + taskSpec: + volumes: + - name: messages + emptyDir: {} + sidecars: + - name: server + image: alpine/git:v2.24.3 + securityContext: + runAsUser: 0 + volumeMounts: + - name: messages + mountPath: /messages + script: | + #!/usr/bin/env ash + + # Generate a private host key and give the Steps access to its public + # key for their known_hosts file. + ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key + chmod 0600 /etc/ssh/ssh_host_rsa_key* + HOST_PUBLIC_KEY=$(cat /etc/ssh/ssh_host_rsa_key.pub | awk '{ print $2 }') + echo "localhost ssh-rsa $HOST_PUBLIC_KEY" > /messages/known_hosts + + # Wait for a Step to supply the server a public key generated from creds-init + # credentials. + while [ ! -f /messages/authorized_keys ] ; do + sleep 1 + done + + # Allow Steps to SSH login as root to this server. + mkdir /root/.ssh + cp /messages/authorized_keys /root/.ssh/ + + # "Unlock" the root account, allowing SSH login to succeed. + sed -i s/root:!/"root:*"/g /etc/shadow + + # Create the git repo we're going to test against. + cd /root/ + mkdir repo + cd repo + git init . --bare + + # Start the sshd server. + /usr/sbin/sshd -E /var/log/sshd + touch /messages/sshd-ready + tail -f /var/log/sshd + steps: + - name: setup + # This Step is only necessary as part of the test, it's not something you'll + # ever need in a real-world scenario involving an external git repo. + image: alpine/git:v2.24.3 + securityContext: + runAsUser: 0 + volumeMounts: + - name: messages + mountPath: /messages + script: | + #!/usr/bin/env ash + + # Generate authorized_keys file from the creds-init private key and give + # it to the sidecar server so that Steps can successfully SSH login + # using creds-init credentials. + ssh-keygen -y -f $(credentials.path)/.ssh/id_ssh-key-for-git > /messages/authorized_keys + + # Wait for sshd to start on the git server. + while [ ! -f /messages/sshd-ready ] ; do + sleep 1 + done + - name: git-clone-and-push + image: alpine/git:v2.24.3 + securityContext: + runAsUser: 0 + workingDir: /root + volumeMounts: + - name: messages + mountPath: /messages + script: | + #!/usr/bin/env ash + set -xe + + if [ -d /tekton/home/.ssh ] ; then + # When disable-home-env-overwrite is "false", creds-init credentials + # will be copied to /tekton/home/.ssh by the entrypoint. But we need + # them in /root/.ssh. + + # Overwrite the creds-init known_hosts file with that of our test + # git server. You wouldn't need to do this in any kind of real-world + # scenario involving an external git repo. + cp /messages/known_hosts $(credentials.path)/.ssh/ + + # Symlink /tekton/creds/.ssh to /root/.ssh because this script issues + # vanilla git commands of its own. Git PipelineResources and the git-clone + # catalog task handle this for you. + ln -s $(credentials.path)/.ssh /root/.ssh + else + # When disable-home-env-overwrite is "true", creds-init credentials + # will be copied to /root/.ssh by the entrypoint. We just need to + # overwrite the known_hosts file with that of our test git server. + cp /messages/known_hosts /root/.ssh/known_hosts + fi + + git clone root@localhost:/root/repo ./repo + cd repo + git config user.email "example@example.com" + git config user.name "Example" + echo "Hello, world!" > README + git add README + git commit -m "Test commit!" + git push origin master + - name: git-clone-and-check + image: gcr.io/tekton-releases/dogfooding/alpine-git-nonroot:mario + # Because this Step runs with a non-root security context, the creds-init + # credentials will fail to copy into /tekton/home. This happens because + # our previous step _already_ wrote to /tekton/home and ran as a root + # user. So there will be warning messages reporting "unsuccessful cred + # copy". These can be safely ignored and instead this Step will copy + # the credentials out of /tekton/creds to nonroot's HOME directory. + securityContext: + runAsUser: 1000 + workingDir: /home/nonroot + volumeMounts: + - name: messages + mountPath: /messages + script: | + #!/usr/bin/env ash + set -xe + + if [ -d /tekton/home/.ssh ] ; then + # When disable-home-env-overwrite is "false", creds-init credentials + # will be copied to /tekton/home/.ssh by the entrypoint. But we need + # them in /home/nonroot/.ssh. + + # Overwrite the creds-init known_hosts file with that of our test + # git server. You wouldn't need to do this in any kind of real-world + # scenario involving an external git repo. + cp /messages/known_hosts $(credentials.path)/.ssh/ + + # Symlink /tekton/creds/.ssh to /home/nonroot/.ssh because this script issues + # vanilla git commands of its own and we're running as a non-root user. + # Git PipelineResources and the git-clone catalog task handle this for you. + ln -s $(credentials.path)/.ssh /home/nonroot/.ssh + else + # When disable-home-env-overwrite is "true", creds-init credentials + # will be copied to /home/nonroot/.ssh by the entrypoint. We just need to + # overwrite the known_hosts file with that of our test git server. + cp /messages/known_hosts /home/nonroot/ssh/known_hosts + fi + + git clone root@localhost:/root/repo ./repo + cd repo + cat README | grep "Hello, world!" diff --git a/pkg/apis/pipeline/paths.go b/pkg/apis/pipeline/paths.go index c0c62f73776..124f54de28e 100644 --- a/pkg/apis/pipeline/paths.go +++ b/pkg/apis/pipeline/paths.go @@ -23,4 +23,6 @@ const ( DefaultResultPath = "/tekton/results" // HomeDir is the HOME directory of PipelineResources HomeDir = "/tekton/home" + // CredsDir is the directory where credentials are placed to meet the creds-init contract + CredsDir = "/tekton/creds" ) diff --git a/pkg/credentials/dockercreds/creds.go b/pkg/credentials/dockercreds/creds.go index fc060591e0b..51926ddda3b 100644 --- a/pkg/credentials/dockercreds/creds.go +++ b/pkg/credentials/dockercreds/creds.go @@ -37,6 +37,11 @@ var config basicDocker var dockerConfig string var dockerCfg string +// AddFlags adds CLI flags that dockercreds supports to a given flag.FlagSet. +func AddFlags(flagSet *flag.FlagSet) { + flags(flagSet) +} + func flags(fs *flag.FlagSet) { config = basicDocker{make(map[string]entry)} fs.Var(&config, "basic-docker", "List of secret=url pairs.") @@ -44,10 +49,6 @@ func flags(fs *flag.FlagSet) { fs.StringVar(&dockerCfg, "docker-cfg", "", "Docker .dockercfg secret file.") } -func init() { - flags(flag.CommandLine) -} - // As the flag is read, this status is populated. // basicDocker implements flag.Value type basicDocker struct { @@ -148,8 +149,8 @@ func (*basicDockerBuilder) MatchingAnnotations(secret *corev1.Secret) []string { return flags } -func (*basicDockerBuilder) Write() error { - dockerDir := filepath.Join(os.Getenv("HOME"), ".docker") +func (*basicDockerBuilder) Write(directory string) error { + dockerDir := filepath.Join(directory, ".docker") basicDocker := filepath.Join(dockerDir, "config.json") if err := os.MkdirAll(dockerDir, os.ModePerm); err != nil { return err diff --git a/pkg/credentials/dockercreds/creds_test.go b/pkg/credentials/dockercreds/creds_test.go index 182c9751f6f..43d00a04f55 100644 --- a/pkg/credentials/dockercreds/creds_test.go +++ b/pkg/credentials/dockercreds/creds_test.go @@ -45,7 +45,7 @@ func TestFlagHandling(t *testing.T) { } fs := flag.NewFlagSet("test", flag.ContinueOnError) - flags(fs) + AddFlags(fs) err := fs.Parse([]string{ "-basic-docker=foo=https://us.gcr.io", }) @@ -54,7 +54,7 @@ func TestFlagHandling(t *testing.T) { } os.Setenv("HOME", credentials.VolumePath) - if err := NewBuilder().Write(); err != nil { + if err := NewBuilder().Write(credentials.VolumePath); err != nil { t.Fatalf("Write() = %v", err) } @@ -94,7 +94,7 @@ func TestFlagHandlingTwice(t *testing.T) { } fs := flag.NewFlagSet("test", flag.ContinueOnError) - flags(fs) + AddFlags(fs) err := fs.Parse([]string{ "-basic-docker=foo=https://us.gcr.io", "-basic-docker=bar=https://eu.gcr.io", @@ -104,7 +104,7 @@ func TestFlagHandlingTwice(t *testing.T) { } os.Setenv("HOME", credentials.VolumePath) - if err := NewBuilder().Write(); err != nil { + if err := NewBuilder().Write(credentials.VolumePath); err != nil { t.Fatalf("Write() = %v", err) } @@ -253,7 +253,7 @@ func TestMultipleFlagHandling(t *testing.T) { } fs := flag.NewFlagSet("test", flag.ContinueOnError) - flags(fs) + AddFlags(fs) err := fs.Parse([]string{ "-basic-docker=foo=https://us.gcr.io", "-docker-config=bar", @@ -264,7 +264,7 @@ func TestMultipleFlagHandling(t *testing.T) { } os.Setenv("HOME", credentials.VolumePath) - if err := NewBuilder().Write(); err != nil { + if err := NewBuilder().Write(credentials.VolumePath); err != nil { t.Fatalf("Write() = %v", err) } diff --git a/pkg/credentials/gitcreds/basic.go b/pkg/credentials/gitcreds/basic.go index 4d0e23a49eb..4030444e829 100644 --- a/pkg/credentials/gitcreds/basic.go +++ b/pkg/credentials/gitcreds/basic.go @@ -20,7 +20,6 @@ import ( "fmt" "io/ioutil" "net/url" - "os" "path/filepath" "strings" @@ -71,8 +70,8 @@ func (dc *basicGitConfig) Set(value string) error { return nil } -func (dc *basicGitConfig) Write() error { - gitConfigPath := filepath.Join(os.Getenv("HOME"), ".gitconfig") +func (dc *basicGitConfig) Write(directory string) error { + gitConfigPath := filepath.Join(directory, ".gitconfig") gitConfigs := []string{ "[credential]\n helper = store\n", } @@ -85,7 +84,7 @@ func (dc *basicGitConfig) Write() error { return err } - gitCredentialsPath := filepath.Join(os.Getenv("HOME"), ".git-credentials") + gitCredentialsPath := filepath.Join(directory, ".git-credentials") var gitCredentials []string for _, k := range dc.order { v := dc.entries[k] diff --git a/pkg/credentials/gitcreds/creds.go b/pkg/credentials/gitcreds/creds.go index 234e2c8c03c..71331f48bdc 100644 --- a/pkg/credentials/gitcreds/creds.go +++ b/pkg/credentials/gitcreds/creds.go @@ -36,6 +36,11 @@ var ( sshConfig sshGitConfig ) +// AddFlags adds CLI flags that gitcreds supports to a given flag.FlagSet. +func AddFlags(flagSet *flag.FlagSet) { + flags(flagSet) +} + func flags(fs *flag.FlagSet) { basicConfig = basicGitConfig{entries: make(map[string]basicEntry)} fs.Var(&basicConfig, basicAuthFlag, "List of secret=url pairs.") @@ -44,10 +49,6 @@ func flags(fs *flag.FlagSet) { fs.Var(&sshConfig, sshFlag, "List of secret=url pairs.") } -func init() { - flags(flag.CommandLine) -} - type gitConfigBuilder struct{} // NewBuilder returns a new builder for Git credentials. @@ -76,9 +77,9 @@ func (*gitConfigBuilder) MatchingAnnotations(secret *corev1.Secret) []string { return flags } -func (*gitConfigBuilder) Write() error { - if err := basicConfig.Write(); err != nil { +func (*gitConfigBuilder) Write(directory string) error { + if err := basicConfig.Write(directory); err != nil { return err } - return sshConfig.Write() + return sshConfig.Write(directory) } diff --git a/pkg/credentials/gitcreds/creds_test.go b/pkg/credentials/gitcreds/creds_test.go index 9f19a9905a5..770c757d1cb 100644 --- a/pkg/credentials/gitcreds/creds_test.go +++ b/pkg/credentials/gitcreds/creds_test.go @@ -45,7 +45,7 @@ func TestBasicFlagHandling(t *testing.T) { } fs := flag.NewFlagSet("test", flag.ContinueOnError) - flags(fs) + AddFlags(fs) err := fs.Parse([]string{ "-basic-git=foo=https://github.com", }) @@ -54,7 +54,7 @@ func TestBasicFlagHandling(t *testing.T) { } os.Setenv("HOME", credentials.VolumePath) - if err := NewBuilder().Write(); err != nil { + if err := NewBuilder().Write(credentials.VolumePath); err != nil { t.Fatalf("Write() = %v", err) } @@ -108,7 +108,7 @@ func TestBasicFlagHandlingTwice(t *testing.T) { } fs := flag.NewFlagSet("test", flag.ContinueOnError) - flags(fs) + AddFlags(fs) err := fs.Parse([]string{ "-basic-git=foo=https://github.com", "-basic-git=bar=https://gitlab.com", @@ -118,7 +118,7 @@ func TestBasicFlagHandlingTwice(t *testing.T) { } os.Setenv("HOME", credentials.VolumePath) - if err := NewBuilder().Write(); err != nil { + if err := NewBuilder().Write(credentials.VolumePath); err != nil { t.Fatalf("Write() = %v", err) } @@ -201,7 +201,7 @@ func TestSSHFlagHandling(t *testing.T) { } fs := flag.NewFlagSet("test", flag.ContinueOnError) - flags(fs) + AddFlags(fs) err := fs.Parse([]string{ "-ssh-git=foo=github.com", }) @@ -210,7 +210,7 @@ func TestSSHFlagHandling(t *testing.T) { } os.Setenv("HOME", credentials.VolumePath) - if err := NewBuilder().Write(); err != nil { + if err := NewBuilder().Write(credentials.VolumePath); err != nil { t.Fatalf("Write() = %v", err) } @@ -282,7 +282,7 @@ func TestSSHFlagHandlingThrice(t *testing.T) { } fs := flag.NewFlagSet("test", flag.ContinueOnError) - flags(fs) + AddFlags(fs) err := fs.Parse([]string{ // Two secrets target github.com, and both will end up in the // ssh config. @@ -295,7 +295,7 @@ func TestSSHFlagHandlingThrice(t *testing.T) { } os.Setenv("HOME", credentials.VolumePath) - if err := NewBuilder().Write(); err != nil { + if err := NewBuilder().Write(credentials.VolumePath); err != nil { t.Fatalf("Write() = %v", err) } diff --git a/pkg/credentials/gitcreds/ssh.go b/pkg/credentials/gitcreds/ssh.go index caf822d89cc..bac6c77a7ce 100644 --- a/pkg/credentials/gitcreds/ssh.go +++ b/pkg/credentials/gitcreds/ssh.go @@ -73,8 +73,8 @@ func (dc *sshGitConfig) Set(value string) error { return nil } -func (dc *sshGitConfig) Write() error { - sshDir := filepath.Join(os.Getenv("HOME"), ".ssh") +func (dc *sshGitConfig) Write(directory string) error { + sshDir := filepath.Join(directory, ".ssh") if err := os.MkdirAll(sshDir, os.ModePerm); err != nil { return err } diff --git a/pkg/credentials/initialize.go b/pkg/credentials/initialize.go index 59fd886dd5c..28bd8bc7e02 100644 --- a/pkg/credentials/initialize.go +++ b/pkg/credentials/initialize.go @@ -26,14 +26,11 @@ import ( "strings" "github.com/mitchellh/go-homedir" + "github.com/tektoncd/pipeline/pkg/apis/pipeline" corev1 "k8s.io/api/core/v1" ) const ( - // credsPath is the path where creds-init will store credentials - // when HOME is not being explicitly set to /tekton/home. - credsPath = "/tekton/creds" - // credsDirPermissions are the persmission bits assigned to the directories // copied out of the /tekton/creds and into a Step's HOME. credsDirPermissions = 0700 @@ -57,8 +54,8 @@ type Builder interface { // length 0 or greater) of applicable domains. MatchingAnnotations(*corev1.Secret) []string - // Write writes the credentials to the correct location. - Write() error + // Write writes the credentials to the provided directory. + Write(string) error } // VolumeName returns the full path to the secret, inside the VolumePath. @@ -84,7 +81,7 @@ func SortAnnotations(secrets map[string]string, annotationPrefix string) []strin // copy is given as an arg, for example, []string{".docker", ".ssh"}. A missing // /tekton/creds directory is not considered an error. func CopyCredsToHome(credPaths []string) error { - if info, err := os.Stat(credsPath); err != nil || !info.IsDir() { + if info, err := os.Stat(pipeline.CredsDir); err != nil || !info.IsDir() { return nil } @@ -94,11 +91,11 @@ func CopyCredsToHome(credPaths []string) error { } for _, cred := range credPaths { - source := filepath.Join(credsPath, cred) + source := filepath.Join(pipeline.CredsDir, cred) destination := filepath.Join(homepath, cred) err := tryCopyCred(source, destination) if err != nil { - log.Printf("unsuccessful cred copy: %q from %q to %q: %v", cred, credsPath, homepath, err) + log.Printf("unsuccessful cred copy: %q from %q to %q: %v", cred, pipeline.CredsDir, homepath, err) } } return nil diff --git a/pkg/pod/creds_init.go b/pkg/pod/creds_init.go index 3940a3e4ae6..a3056007bd9 100644 --- a/pkg/pod/creds_init.go +++ b/pkg/pod/creds_init.go @@ -29,48 +29,38 @@ import ( "k8s.io/client-go/kubernetes" ) -const homeEnvVar = "HOME" -const credsInitHomeMountName = "tekton-creds-init-home" -const credsInitHomeDir = "/tekton/creds" - -var credsInitHomeVolume = corev1.Volume{ - Name: credsInitHomeMountName, - VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{ - Medium: corev1.StorageMediumMemory, - }}, -} - -var credsInitHomeVolumeMount = corev1.VolumeMount{ - Name: credsInitHomeMountName, - MountPath: credsInitHomeDir, -} - -// credsInit returns an init container that initializes credentials based on -// annotated secrets available to the service account. +const credsInitHomeMountPrefix = "tekton-creds-init-home" + +// credsInit reads secrets available to the given service account and +// searches for annotations matching a specific format (documented in +// docs/auth.md). Matching secrets are turned into Volumes for the Pod +// and VolumeMounts to be given to each Step. Additionally, a list of +// entrypointer arguments are returned, each with a meaning specific to +// the credential type it describes: git credentials expect one set of +// args while docker credentials expect another. // -// If no such secrets are found, it returns a nil container, and no creds init -// process is necessary. -// -// If it finds secrets, it also returns a set of Volumes to attach to the Pod -// to provide those secrets to this initialization. -func credsInit(credsImage string, serviceAccountName, namespace string, kubeclient kubernetes.Interface, volumeMounts []corev1.VolumeMount, implicitEnvVars []corev1.EnvVar) (*corev1.Container, []corev1.Volume, error) { +// Any errors encountered during this process are returned to the +// caller. If no matching annotated secrets are found, nil lists with a +// nil error are returned. +func credsInit(serviceAccountName, namespace string, kubeclient kubernetes.Interface) ([]string, []corev1.Volume, []corev1.VolumeMount, error) { if serviceAccountName == "" { serviceAccountName = "default" } sa, err := kubeclient.CoreV1().ServiceAccounts(namespace).Get(serviceAccountName, metav1.GetOptions{}) if err != nil { - return nil, nil, err + return nil, nil, nil, err } builders := []credentials.Builder{dockercreds.NewBuilder(), gitcreds.NewBuilder()} + var volumeMounts []corev1.VolumeMount var volumes []corev1.Volume args := []string{} for _, secretEntry := range sa.Secrets { secret, err := kubeclient.CoreV1().Secrets(namespace).Get(secretEntry.Name, metav1.GetOptions{}) if err != nil { - return nil, nil, err + return nil, nil, nil, err } matched := false @@ -100,63 +90,25 @@ func credsInit(credsImage string, serviceAccountName, namespace string, kubeclie if len(args) == 0 { // There are no creds to initialize. - return nil, nil, nil + return nil, nil, nil, nil } - env := ensureCredsInitHomeEnv(implicitEnvVars) - - return &corev1.Container{ - Name: "credential-initializer", - Image: credsImage, - Command: []string{"/ko-app/creds-init"}, - Args: args, - Env: env, - VolumeMounts: volumeMounts, - }, volumes, nil + return args, volumes, volumeMounts, nil } -// CredentialsPath returns a string path to the location that the creds-init -// helper binary will write its credentials to. The only argument is a boolean -// true if Tekton will overwrite Steps' default HOME environment variable -// with /tekton/home. -func CredentialsPath(shouldOverrideHomeEnv bool) string { - if shouldOverrideHomeEnv { - return pipeline.HomeDir +// getCredsInitVolume returns a Volume and VolumeMount for /tekton/creds. Each call +// will return a new volume and volume mount with randomized name. +func getCredsInitVolume() (corev1.Volume, corev1.VolumeMount) { + name := names.SimpleNameGenerator.RestrictLengthWithRandomSuffix(credsInitHomeMountPrefix) + v := corev1.Volume{ + Name: name, + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{ + Medium: corev1.StorageMediumMemory, + }}, } - return credsInitHomeDir -} - -// ensureCredsInitHomeEnv ensures that creds-init always has its HOME environment -// variable set to /tekton/creds unless it's already been explicitly set to -// something else. -// -// We do this because Tekton's HOME override is being deprecated: -// creds-init doesn't know the HOME directories of every Step in -// the Task, and may not even be able to tell this in advance because -// of randomized container UIDs like those of OpenShift. So, instead, -// creds-init writes credentials to a single known location (/tekton/creds) -// and leaves it up to the user's Steps to put those credentials in the -// correct place. -func ensureCredsInitHomeEnv(existingEnvVars []corev1.EnvVar) []corev1.EnvVar { - env := []corev1.EnvVar{} - setHome := true - for _, e := range existingEnvVars { - if e.Name == homeEnvVar { - setHome = false - } - env = append(env, e) + vm := corev1.VolumeMount{ + Name: name, + MountPath: pipeline.CredsDir, } - if setHome { - env = append(env, corev1.EnvVar{ - Name: homeEnvVar, - Value: credsInitHomeDir, - }) - } - return env -} - -// getCredsInitVolume returns the Volume and VolumeMount configuration needed -// to mount the creds-init volume in Steps. -func getCredsInitVolume(volumes []corev1.Volume) (corev1.Volume, corev1.VolumeMount) { - return credsInitHomeVolume, credsInitHomeVolumeMount + return v, vm } diff --git a/pkg/pod/creds_init_test.go b/pkg/pod/creds_init_test.go index 8d49272b02e..f22bc34edd7 100644 --- a/pkg/pod/creds_init_test.go +++ b/pkg/pod/creds_init_test.go @@ -34,33 +34,24 @@ const ( ) func TestCredsInit(t *testing.T) { - volumeMounts := []corev1.VolumeMount{{ - Name: "implicit-volume-mount", - }} - fooEnvVar := corev1.EnvVar{ - Name: "FOO", - Value: "bar", - } - credsInitHomeEnvVar := corev1.EnvVar{ - Name: "HOME", - Value: credsInitHomeDir, - } customHomeEnvVar := corev1.EnvVar{ Name: "HOME", Value: "/users/home/my-test-user", } for _, c := range []struct { - desc string - want *corev1.Container - objs []runtime.Object - envVars []corev1.EnvVar + desc string + wantArgs []string + wantVolumeMounts []corev1.VolumeMount + objs []runtime.Object + envVars []corev1.EnvVar }{{ desc: "service account exists with no secrets; nothing to initialize", objs: []runtime.Object{ &corev1.ServiceAccount{ObjectMeta: metav1.ObjectMeta{Name: serviceAccountName, Namespace: namespace}}, }, - want: nil, + wantArgs: nil, + wantVolumeMounts: nil, }, { desc: "service account has no annotated secrets; nothing to initialize", objs: []runtime.Object{ @@ -80,7 +71,8 @@ func TestCredsInit(t *testing.T) { }, }, }, - want: nil, + wantArgs: nil, + wantVolumeMounts: nil, }, { desc: "service account has annotated secret and no HOME env var passed in; initialize creds in /tekton/creds", objs: []runtime.Object{ @@ -108,23 +100,17 @@ func TestCredsInit(t *testing.T) { }, }, }, - envVars: []corev1.EnvVar{fooEnvVar}, - want: &corev1.Container{ - Name: "credential-initializer", - Image: images.CredsImage, - Command: []string{"/ko-app/creds-init"}, - Args: []string{ - "-basic-docker=my-creds=https://docker.io", - "-basic-docker=my-creds=https://us.gcr.io", - "-basic-git=my-creds=github.com", - "-basic-git=my-creds=gitlab.com", - }, - Env: []corev1.EnvVar{fooEnvVar, credsInitHomeEnvVar}, - VolumeMounts: append(volumeMounts, corev1.VolumeMount{ - Name: "tekton-internal-secret-volume-my-creds-9l9zj", - MountPath: "/tekton/creds-secrets/my-creds", - }), + envVars: []corev1.EnvVar{}, + wantArgs: []string{ + "-basic-docker=my-creds=https://docker.io", + "-basic-docker=my-creds=https://us.gcr.io", + "-basic-git=my-creds=github.com", + "-basic-git=my-creds=gitlab.com", }, + wantVolumeMounts: []corev1.VolumeMount{{ + Name: "tekton-internal-secret-volume-my-creds-9l9zj", + MountPath: "/tekton/creds-secrets/my-creds", + }}, }, { desc: "service account with secret and HOME env var passed in", objs: []runtime.Object{ @@ -153,34 +139,31 @@ func TestCredsInit(t *testing.T) { }, }, envVars: []corev1.EnvVar{customHomeEnvVar}, - want: &corev1.Container{ - Name: "credential-initializer", - Image: images.CredsImage, - Command: []string{"/ko-app/creds-init"}, - Args: []string{ - "-basic-docker=my-creds=https://docker.io", - "-basic-docker=my-creds=https://us.gcr.io", - "-basic-git=my-creds=github.com", - "-basic-git=my-creds=gitlab.com", - }, - Env: []corev1.EnvVar{customHomeEnvVar}, - VolumeMounts: append(volumeMounts, corev1.VolumeMount{ - Name: "tekton-internal-secret-volume-my-creds-9l9zj", - MountPath: "/tekton/creds-secrets/my-creds", - }), + wantArgs: []string{ + "-basic-docker=my-creds=https://docker.io", + "-basic-docker=my-creds=https://us.gcr.io", + "-basic-git=my-creds=github.com", + "-basic-git=my-creds=gitlab.com", }, + wantVolumeMounts: []corev1.VolumeMount{{ + Name: "tekton-internal-secret-volume-my-creds-9l9zj", + MountPath: "/tekton/creds-secrets/my-creds", + }}, }} { t.Run(c.desc, func(t *testing.T) { names.TestingSeed() kubeclient := fakek8s.NewSimpleClientset(c.objs...) - got, volumes, err := credsInit(images.CredsImage, serviceAccountName, namespace, kubeclient, volumeMounts, c.envVars) + args, volumes, volumeMounts, err := credsInit(serviceAccountName, namespace, kubeclient) if err != nil { t.Fatalf("credsInit: %v", err) } - if got == nil && len(volumes) > 0 { - t.Errorf("Got nil creds-init container, with non-empty volumes: %v", volumes) + if len(args) == 0 && len(volumes) != 0 { + t.Fatalf("credsInit returned secret volumes but no arguments") + } + if d := cmp.Diff(c.wantArgs, args); d != "" { + t.Fatalf("Diff %s", diff.PrintWantGot(d)) } - if d := cmp.Diff(c.want, got); d != "" { + if d := cmp.Diff(c.wantVolumeMounts, volumeMounts); d != "" { t.Fatalf("Diff %s", diff.PrintWantGot(d)) } }) diff --git a/pkg/pod/entrypoint.go b/pkg/pod/entrypoint.go index 47ce8d7b1e7..f4fbded8994 100644 --- a/pkg/pod/entrypoint.go +++ b/pkg/pod/entrypoint.go @@ -86,7 +86,7 @@ var ( // method, using entrypoint_lookup.go. // // TODO(#1605): Also use entrypoint injection to order sidecar start/stop. -func orderContainers(entrypointImage string, steps []corev1.Container, results []v1beta1.TaskResult) (corev1.Container, []corev1.Container, error) { +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, @@ -118,6 +118,7 @@ func orderContainers(entrypointImage string, steps []corev1.Container, results [ "-termination_path", terminationPath, } } + argsForEntrypoint = append(argsForEntrypoint, extraEntrypointArgs...) argsForEntrypoint = append(argsForEntrypoint, resultArgument(steps, results)...) cmd, args := s.Command, s.Args diff --git a/pkg/pod/entrypoint_test.go b/pkg/pod/entrypoint_test.go index fb5c8dd49bb..cfbe4663f7b 100644 --- a/pkg/pod/entrypoint_test.go +++ b/pkg/pod/entrypoint_test.go @@ -87,7 +87,7 @@ func TestOrderContainers(t *testing.T) { VolumeMounts: []corev1.VolumeMount{toolsMount}, TerminationMessagePath: "/tekton/termination", }} - gotInit, got, err := orderContainers(images.EntrypointImage, steps, nil) + gotInit, got, err := orderContainers(images.EntrypointImage, []string{}, steps, nil) if err != nil { t.Fatalf("orderContainers: %v", err) } @@ -171,7 +171,7 @@ func TestEntryPointResults(t *testing.T) { VolumeMounts: []corev1.VolumeMount{toolsMount}, TerminationMessagePath: "/tekton/termination", }} - _, got, err := orderContainers(images.EntrypointImage, steps, results) + _, got, err := orderContainers(images.EntrypointImage, []string{}, steps, results) if err != nil { t.Fatalf("orderContainers: %v", err) } @@ -209,7 +209,7 @@ func TestEntryPointResultsSingleStep(t *testing.T) { VolumeMounts: []corev1.VolumeMount{toolsMount, downwardMount}, TerminationMessagePath: "/tekton/termination", }} - _, got, err := orderContainers(images.EntrypointImage, steps, results) + _, got, err := orderContainers(images.EntrypointImage, []string{}, steps, results) if err != nil { t.Fatalf("orderContainers: %v", err) } @@ -243,7 +243,7 @@ func TestEntryPointSingleResultsSingleStep(t *testing.T) { VolumeMounts: []corev1.VolumeMount{toolsMount, downwardMount}, TerminationMessagePath: "/tekton/termination", }} - _, got, err := orderContainers(images.EntrypointImage, steps, results) + _, got, err := orderContainers(images.EntrypointImage, []string{}, steps, results) if err != nil { t.Fatalf("orderContainers: %v", err) } diff --git a/pkg/pod/pod.go b/pkg/pod/pod.go index 7e4839b3e84..182bc2674e6 100644 --- a/pkg/pod/pod.go +++ b/pkg/pod/pod.go @@ -34,6 +34,8 @@ import ( ) const ( + homeDir = "/tekton/home" + // ResultsDir is the folder used by default to create the results file ResultsDir = "/tekton/results" @@ -56,7 +58,7 @@ var ( MountPath: pipeline.WorkspaceDir, }, { Name: "tekton-internal-home", - MountPath: pipeline.HomeDir, + MountPath: homeDir, }, { Name: "tekton-internal-results", MountPath: ResultsDir, @@ -88,23 +90,19 @@ func MakePod(ctx context.Context, images pipeline.Images, taskRun *v1beta1.TaskR if overrideHomeEnv { implicitEnvVars = append(implicitEnvVars, corev1.EnvVar{ Name: "HOME", - Value: pipeline.HomeDir, + Value: homeDir, }) - } else { - // Add the volume that creds-init will write to when - // there's no consistent $HOME for Steps. - v, vm := getCredsInitVolume(volumes) - volumes = append(volumes, v) - volumeMounts = append(volumeMounts, vm) } - // Inititalize any credentials found in annotated Secrets. - if credsInitContainer, secretsVolumes, err := credsInit(images.CredsImage, taskRun.Spec.ServiceAccountName, taskRun.Namespace, kubeclient, volumeMounts, implicitEnvVars); err != nil { + // Create Volumes and VolumeMounts for any credentials found in annotated + // Secrets, along with any arguments needed by Step entrypoints to process + // those secrets. + credEntrypointArgs, credVolumes, credVolumeMounts, err := credsInit(taskRun.Spec.ServiceAccountName, taskRun.Namespace, kubeclient) + if err != nil { return nil, err - } else if credsInitContainer != nil { - initContainers = append(initContainers, *credsInitContainer) - volumes = append(volumes, secretsVolumes...) } + volumes = append(volumes, credVolumes...) + volumeMounts = append(volumeMounts, credVolumeMounts...) // Merge step template with steps. // TODO(#1605): Move MergeSteps to pkg/pod @@ -134,7 +132,7 @@ func MakePod(ctx context.Context, images pipeline.Images, taskRun *v1beta1.TaskR // Rewrite steps with entrypoint binary. Append the entrypoint init // container to place the entrypoint binary. - entrypointInit, stepContainers, err := orderContainers(images.EntrypointImage, stepContainers, taskSpec.Results) + entrypointInit, stepContainers, err := orderContainers(images.EntrypointImage, credEntrypointArgs, stepContainers, taskSpec.Results) if err != nil { return nil, err } @@ -160,6 +158,13 @@ func MakePod(ctx context.Context, images pipeline.Images, taskRun *v1beta1.TaskR // Add implicit volume mounts to each step, unless the step specifies // its own volume mount at that path. for i, s := range stepContainers { + // Mount /tekton/creds with a fresh volume for each Step. It needs to + // be world-writeable and empty so creds can be initialized in there. Cant + // guarantee what UID container runs with. + v, vm := getCredsInitVolume() + volumes = append(volumes, v) + s.VolumeMounts = append(s.VolumeMounts, vm) + requestedVolumeMounts := map[string]bool{} for _, vm := range s.VolumeMounts { requestedVolumeMounts[filepath.Clean(vm.MountPath)] = true diff --git a/pkg/pod/pod_test.go b/pkg/pod/pod_test.go index 43864586b2d..86531b832bb 100644 --- a/pkg/pod/pod_test.go +++ b/pkg/pod/pod_test.go @@ -58,12 +58,8 @@ var ( func TestMakePod(t *testing.T) { implicitEnvVars := []corev1.EnvVar{{ Name: "HOME", - Value: pipeline.HomeDir, + Value: homeDir, }} - secretsVolumeMount := corev1.VolumeMount{ - Name: "tekton-internal-secret-volume-multi-creds-9l9zj", - MountPath: "/tekton/creds-secrets/multi-creds", - } secretsVolume := corev1.Volume{ Name: "tekton-internal-secret-volume-multi-creds-9l9zj", VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{SecretName: "multi-creds"}}, @@ -116,13 +112,19 @@ func TestMakePod(t *testing.T) { "cmd", "--", }, - Env: implicitEnvVars, - VolumeMounts: append([]corev1.VolumeMount{toolsMount, downwardMount}, implicitVolumeMounts...), + Env: implicitEnvVars, + VolumeMounts: append([]corev1.VolumeMount{toolsMount, downwardMount, { + Name: "tekton-creds-init-home-9l9zj", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), WorkingDir: pipeline.WorkspaceDir, Resources: corev1.ResourceRequirements{Requests: allZeroQty()}, TerminationMessagePath: "/tekton/termination", }}, - Volumes: append(implicitVolumes, toolsVolume, downwardVolume), + Volumes: append(implicitVolumes, toolsVolume, downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-9l9zj", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), }, }, { desc: "simple with running-in-environment-with-injected-sidecar set to false", @@ -155,13 +157,19 @@ func TestMakePod(t *testing.T) { "cmd", "--", }, - Env: implicitEnvVars, - VolumeMounts: append([]corev1.VolumeMount{toolsMount, downwardMount}, implicitVolumeMounts...), + Env: implicitEnvVars, + VolumeMounts: append([]corev1.VolumeMount{toolsMount, downwardMount, { + Name: "tekton-creds-init-home-9l9zj", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), WorkingDir: pipeline.WorkspaceDir, Resources: corev1.ResourceRequirements{Requests: allZeroQty()}, TerminationMessagePath: "/tekton/termination", }}, - Volumes: append(implicitVolumes, toolsVolume, downwardVolume), + Volumes: append(implicitVolumes, toolsVolume, downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-9l9zj", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), }, wantAnnotations: map[string]string{ readyAnnotation: readyAnnotationValue, @@ -181,21 +189,7 @@ func TestMakePod(t *testing.T) { want: &corev1.PodSpec{ ServiceAccountName: "service-account", RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{{ - Name: "credential-initializer", - Image: images.CredsImage, - Command: []string{"/ko-app/creds-init"}, - Args: []string{ - "-basic-docker=multi-creds=https://docker.io", - "-basic-docker=multi-creds=https://us.gcr.io", - "-basic-git=multi-creds=github.com", - "-basic-git=multi-creds=gitlab.com", - }, - VolumeMounts: append(implicitVolumeMounts, secretsVolumeMount), - Env: implicitEnvVars, - }, - placeToolsInit, - }, + InitContainers: []corev1.Container{placeToolsInit}, Containers: []corev1.Container{{ Name: "step-name", Image: "image", @@ -208,17 +202,30 @@ func TestMakePod(t *testing.T) { "/tekton/tools/0", "-termination_path", "/tekton/termination", + "-basic-docker=multi-creds=https://docker.io", + "-basic-docker=multi-creds=https://us.gcr.io", + "-basic-git=multi-creds=github.com", + "-basic-git=multi-creds=gitlab.com", "-entrypoint", "cmd", "--", }, - Env: implicitEnvVars, - VolumeMounts: append([]corev1.VolumeMount{toolsMount, downwardMount}, implicitVolumeMounts...), + Env: implicitEnvVars, + VolumeMounts: append([]corev1.VolumeMount{toolsMount, downwardMount, { + Name: "tekton-creds-init-home-mz4c7", + MountPath: "/tekton/creds", + }}, append(append([]corev1.VolumeMount{}, implicitVolumeMounts...), corev1.VolumeMount{ + Name: "tekton-internal-secret-volume-multi-creds-9l9zj", + MountPath: "/tekton/creds-secrets/multi-creds", + })...), WorkingDir: pipeline.WorkspaceDir, Resources: corev1.ResourceRequirements{Requests: allZeroQty()}, TerminationMessagePath: "/tekton/termination", }}, - Volumes: append(implicitVolumes, secretsVolume, toolsVolume, downwardVolume), + Volumes: append(implicitVolumes, secretsVolume, toolsVolume, downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-mz4c7", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), }, }, { desc: "with-pod-template", @@ -266,13 +273,20 @@ func TestMakePod(t *testing.T) { "cmd", "--", }, - Env: implicitEnvVars, - VolumeMounts: append([]corev1.VolumeMount{toolsMount, downwardMount}, implicitVolumeMounts...), + Env: implicitEnvVars, + VolumeMounts: append([]corev1.VolumeMount{ + toolsMount, + downwardMount, + {Name: "tekton-creds-init-home-9l9zj", MountPath: "/tekton/creds"}, + }, implicitVolumeMounts...), WorkingDir: pipeline.WorkspaceDir, Resources: corev1.ResourceRequirements{Requests: allZeroQty()}, TerminationMessagePath: "/tekton/termination", }}, - Volumes: append(implicitVolumes, toolsVolume, downwardVolume), + Volumes: append(implicitVolumes, toolsVolume, downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-9l9zj", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), SecurityContext: &corev1.PodSecurityContext{ Sysctls: []corev1.Sysctl{ {Name: "net.ipv4.tcp_syncookies", Value: "1"}, @@ -316,13 +330,19 @@ func TestMakePod(t *testing.T) { "cmd", "--", }, - Env: implicitEnvVars, - VolumeMounts: append([]corev1.VolumeMount{toolsMount, downwardMount}, implicitVolumeMounts...), + Env: implicitEnvVars, + VolumeMounts: append([]corev1.VolumeMount{toolsMount, downwardMount, { + Name: "tekton-creds-init-home-9l9zj", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), WorkingDir: pipeline.WorkspaceDir, Resources: corev1.ResourceRequirements{Requests: allZeroQty()}, TerminationMessagePath: "/tekton/termination", }}, - Volumes: append(implicitVolumes, toolsVolume, downwardVolume), + Volumes: append(implicitVolumes, toolsVolume, downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-9l9zj", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), }, }, { desc: "step name ends with non alphanumeric", @@ -352,13 +372,19 @@ func TestMakePod(t *testing.T) { "cmd", "--", }, - Env: implicitEnvVars, - VolumeMounts: append([]corev1.VolumeMount{toolsMount, downwardMount}, implicitVolumeMounts...), + Env: implicitEnvVars, + VolumeMounts: append([]corev1.VolumeMount{toolsMount, downwardMount, { + Name: "tekton-creds-init-home-9l9zj", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), WorkingDir: pipeline.WorkspaceDir, Resources: corev1.ResourceRequirements{Requests: allZeroQty()}, TerminationMessagePath: "/tekton/termination", }}, - Volumes: append(implicitVolumes, toolsVolume, downwardVolume), + Volumes: append(implicitVolumes, toolsVolume, downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-9l9zj", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), }, }, { desc: "workingDir in workspace", @@ -399,13 +425,19 @@ func TestMakePod(t *testing.T) { "cmd", "--", }, - Env: implicitEnvVars, - VolumeMounts: append([]corev1.VolumeMount{toolsMount, downwardMount}, implicitVolumeMounts...), + Env: implicitEnvVars, + VolumeMounts: append([]corev1.VolumeMount{toolsMount, downwardMount, { + Name: "tekton-creds-init-home-9l9zj", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), WorkingDir: filepath.Join(pipeline.WorkspaceDir, "test"), Resources: corev1.ResourceRequirements{Requests: allZeroQty()}, TerminationMessagePath: "/tekton/termination", }}, - Volumes: append(implicitVolumes, toolsVolume, downwardVolume), + Volumes: append(implicitVolumes, toolsVolume, downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-9l9zj", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), }, }, { desc: "sidecar container", @@ -442,8 +474,11 @@ func TestMakePod(t *testing.T) { "cmd", "--", }, - Env: implicitEnvVars, - VolumeMounts: append([]corev1.VolumeMount{toolsMount, downwardMount}, implicitVolumeMounts...), + Env: implicitEnvVars, + VolumeMounts: append([]corev1.VolumeMount{toolsMount, downwardMount, { + Name: "tekton-creds-init-home-9l9zj", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), WorkingDir: pipeline.WorkspaceDir, Resources: corev1.ResourceRequirements{Requests: allZeroQty()}, TerminationMessagePath: "/tekton/termination", @@ -454,7 +489,10 @@ func TestMakePod(t *testing.T) { Requests: nil, }, }}, - Volumes: append(implicitVolumes, toolsVolume, downwardVolume), + Volumes: append(implicitVolumes, toolsVolume, downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-9l9zj", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), }, }, { desc: "sidecar container with script", @@ -508,8 +546,11 @@ sidecar-script-heredoc-randomly-generated-mz4c7 "cmd", "--", }, - Env: implicitEnvVars, - VolumeMounts: append([]corev1.VolumeMount{toolsMount, downwardMount}, implicitVolumeMounts...), + Env: implicitEnvVars, + VolumeMounts: append([]corev1.VolumeMount{toolsMount, downwardMount, { + Name: "tekton-creds-init-home-mssqb", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), WorkingDir: pipeline.WorkspaceDir, Resources: corev1.ResourceRequirements{Requests: allZeroQty()}, TerminationMessagePath: "/tekton/termination", @@ -522,7 +563,10 @@ sidecar-script-heredoc-randomly-generated-mz4c7 Command: []string{"/tekton/scripts/sidecar-script-0-9l9zj"}, VolumeMounts: []corev1.VolumeMount{scriptsVolumeMount}, }}, - Volumes: append(implicitVolumes, scriptsVolume, toolsVolume, downwardVolume), + Volumes: append(implicitVolumes, scriptsVolume, toolsVolume, downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-mssqb", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), }, }, { desc: "sidecar container with enable-ready-annotation-on-pod-create", @@ -562,8 +606,11 @@ sidecar-script-heredoc-randomly-generated-mz4c7 "cmd", "--", }, - Env: implicitEnvVars, - VolumeMounts: append([]corev1.VolumeMount{toolsMount, downwardMount}, implicitVolumeMounts...), + Env: implicitEnvVars, + VolumeMounts: append([]corev1.VolumeMount{toolsMount, downwardMount, { + Name: "tekton-creds-init-home-9l9zj", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), WorkingDir: pipeline.WorkspaceDir, Resources: corev1.ResourceRequirements{Requests: allZeroQty()}, TerminationMessagePath: "/tekton/termination", @@ -574,7 +621,10 @@ sidecar-script-heredoc-randomly-generated-mz4c7 Requests: nil, }, }}, - Volumes: append(implicitVolumes, toolsVolume, downwardVolume), + Volumes: append(implicitVolumes, toolsVolume, downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-9l9zj", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), }, }, { desc: "resource request", @@ -618,9 +668,12 @@ sidecar-script-heredoc-randomly-generated-mz4c7 "cmd", "--", }, - Env: implicitEnvVars, - VolumeMounts: append([]corev1.VolumeMount{toolsMount, downwardMount}, implicitVolumeMounts...), - WorkingDir: pipeline.WorkspaceDir, + Env: implicitEnvVars, + VolumeMounts: append([]corev1.VolumeMount{toolsMount, downwardMount, { + Name: "tekton-creds-init-home-9l9zj", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), + WorkingDir: pipeline.WorkspaceDir, Resources: corev1.ResourceRequirements{ Requests: corev1.ResourceList{ corev1.ResourceCPU: resource.MustParse("8"), @@ -644,9 +697,12 @@ sidecar-script-heredoc-randomly-generated-mz4c7 "cmd", "--", }, - Env: implicitEnvVars, - VolumeMounts: append([]corev1.VolumeMount{toolsMount}, implicitVolumeMounts...), - WorkingDir: pipeline.WorkspaceDir, + Env: implicitEnvVars, + VolumeMounts: append([]corev1.VolumeMount{toolsMount, { + Name: "tekton-creds-init-home-mz4c7", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), + WorkingDir: pipeline.WorkspaceDir, Resources: corev1.ResourceRequirements{ Requests: corev1.ResourceList{ corev1.ResourceCPU: zeroQty, @@ -656,7 +712,13 @@ sidecar-script-heredoc-randomly-generated-mz4c7 }, TerminationMessagePath: "/tekton/termination", }}, - Volumes: append(implicitVolumes, toolsVolume, downwardVolume), + Volumes: append(implicitVolumes, toolsVolume, downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-9l9zj", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }, corev1.Volume{ + Name: "tekton-creds-init-home-mz4c7", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), }, }, { desc: "step with script and stepTemplate", @@ -734,8 +796,11 @@ script-heredoc-randomly-generated-78c5n "template", "args", }, - Env: append(implicitEnvVars, corev1.EnvVar{Name: "FOO", Value: "bar"}), - VolumeMounts: append([]corev1.VolumeMount{scriptsVolumeMount, toolsMount, downwardMount}, implicitVolumeMounts...), + Env: append(implicitEnvVars, corev1.EnvVar{Name: "FOO", Value: "bar"}), + VolumeMounts: append([]corev1.VolumeMount{scriptsVolumeMount, toolsMount, downwardMount, { + Name: "tekton-creds-init-home-6nl7g", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), WorkingDir: pipeline.WorkspaceDir, Resources: corev1.ResourceRequirements{Requests: allZeroQty()}, TerminationMessagePath: "/tekton/termination", @@ -756,8 +821,11 @@ script-heredoc-randomly-generated-78c5n "template", "args", }, - Env: append(implicitEnvVars, corev1.EnvVar{Name: "FOO", Value: "bar"}), - VolumeMounts: append([]corev1.VolumeMount{{Name: "i-have-a-volume-mount"}, scriptsVolumeMount, toolsMount}, implicitVolumeMounts...), + Env: append(implicitEnvVars, corev1.EnvVar{Name: "FOO", Value: "bar"}), + VolumeMounts: append([]corev1.VolumeMount{{Name: "i-have-a-volume-mount"}, scriptsVolumeMount, toolsMount, { + Name: "tekton-creds-init-home-j2tds", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), WorkingDir: pipeline.WorkspaceDir, Resources: corev1.ResourceRequirements{Requests: allZeroQty()}, TerminationMessagePath: "/tekton/termination", @@ -779,13 +847,25 @@ script-heredoc-randomly-generated-78c5n "template", "args", }, - Env: append(implicitEnvVars, corev1.EnvVar{Name: "FOO", Value: "bar"}), - VolumeMounts: append([]corev1.VolumeMount{toolsMount}, implicitVolumeMounts...), + Env: append(implicitEnvVars, corev1.EnvVar{Name: "FOO", Value: "bar"}), + VolumeMounts: append([]corev1.VolumeMount{toolsMount, { + Name: "tekton-creds-init-home-vr6ds", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), WorkingDir: pipeline.WorkspaceDir, Resources: corev1.ResourceRequirements{Requests: allZeroQty()}, TerminationMessagePath: "/tekton/termination", }}, - Volumes: append(implicitVolumes, scriptsVolume, toolsVolume, downwardVolume), + Volumes: append(implicitVolumes, scriptsVolume, toolsVolume, downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-6nl7g", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }, corev1.Volume{ + Name: "tekton-creds-init-home-j2tds", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }, corev1.Volume{ + Name: "tekton-creds-init-home-vr6ds", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), }, }, { desc: "using another scheduler", @@ -809,7 +889,10 @@ script-heredoc-randomly-generated-78c5n RestartPolicy: corev1.RestartPolicyNever, InitContainers: []corev1.Container{placeToolsInit}, SchedulerName: "there-scheduler", - Volumes: append(implicitVolumes, toolsVolume, downwardVolume), + Volumes: append(implicitVolumes, toolsVolume, downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-9l9zj", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), Containers: []corev1.Container{{ Name: "step-schedule-me", Image: "image", @@ -826,8 +909,11 @@ script-heredoc-randomly-generated-78c5n "cmd", "--", }, - Env: implicitEnvVars, - VolumeMounts: append([]corev1.VolumeMount{toolsMount, downwardMount}, implicitVolumeMounts...), + Env: implicitEnvVars, + VolumeMounts: append([]corev1.VolumeMount{toolsMount, downwardMount, { + Name: "tekton-creds-init-home-9l9zj", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), WorkingDir: pipeline.WorkspaceDir, Resources: corev1.ResourceRequirements{Requests: allZeroQty()}, TerminationMessagePath: "/tekton/termination", @@ -854,7 +940,10 @@ script-heredoc-randomly-generated-78c5n want: &corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, InitContainers: []corev1.Container{placeToolsInit}, - Volumes: append(implicitVolumes, toolsVolume, downwardVolume), + Volumes: append(implicitVolumes, toolsVolume, downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-9l9zj", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), Containers: []corev1.Container{{ Name: "step-image-pull", Image: "image", @@ -871,8 +960,11 @@ script-heredoc-randomly-generated-78c5n "cmd", "--", }, - Env: implicitEnvVars, - VolumeMounts: append([]corev1.VolumeMount{toolsMount, downwardMount}, implicitVolumeMounts...), + Env: implicitEnvVars, + VolumeMounts: append([]corev1.VolumeMount{toolsMount, downwardMount, { + Name: "tekton-creds-init-home-9l9zj", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), WorkingDir: pipeline.WorkspaceDir, Resources: corev1.ResourceRequirements{Requests: allZeroQty()}, TerminationMessagePath: "/tekton/termination", @@ -900,7 +992,10 @@ script-heredoc-randomly-generated-78c5n RestartPolicy: corev1.RestartPolicyNever, InitContainers: []corev1.Container{placeToolsInit}, HostNetwork: true, - Volumes: append(implicitVolumes, toolsVolume, downwardVolume), + Volumes: append(implicitVolumes, toolsVolume, downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-9l9zj", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), Containers: []corev1.Container{{ Name: "step-use-my-hostNetwork", Image: "image", @@ -917,8 +1012,11 @@ script-heredoc-randomly-generated-78c5n "cmd", "--", }, - Env: implicitEnvVars, - VolumeMounts: append([]corev1.VolumeMount{toolsMount, downwardMount}, implicitVolumeMounts...), + Env: implicitEnvVars, + VolumeMounts: append([]corev1.VolumeMount{toolsMount, downwardMount, { + Name: "tekton-creds-init-home-9l9zj", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), WorkingDir: pipeline.WorkspaceDir, Resources: corev1.ResourceRequirements{Requests: allZeroQty()}, TerminationMessagePath: "/tekton/termination", @@ -960,7 +1058,10 @@ script-heredoc-randomly-generated-78c5n RestartPolicy: corev1.RestartPolicyNever, InitContainers: []corev1.Container{placeToolsInit}, HostNetwork: false, - Volumes: append(implicitVolumes, toolsVolume, downwardVolume), + Volumes: append(implicitVolumes, toolsVolume, downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-9l9zj", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), Containers: []corev1.Container{{ Name: "step-name", Image: "image", @@ -977,8 +1078,11 @@ script-heredoc-randomly-generated-78c5n "cmd", "--", }, - Env: implicitEnvVars, - VolumeMounts: append([]corev1.VolumeMount{toolsMount, downwardMount}, implicitVolumeMounts...), + Env: implicitEnvVars, + VolumeMounts: append([]corev1.VolumeMount{toolsMount, downwardMount, { + Name: "tekton-creds-init-home-9l9zj", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), WorkingDir: pipeline.WorkspaceDir, Resources: corev1.ResourceRequirements{Requests: allZeroQty()}, TerminationMessagePath: "/tekton/termination", diff --git a/pkg/reconciler/taskrun/resources/apply.go b/pkg/reconciler/taskrun/resources/apply.go index 89a9edb1693..832f1a9db0a 100644 --- a/pkg/reconciler/taskrun/resources/apply.go +++ b/pkg/reconciler/taskrun/resources/apply.go @@ -142,8 +142,8 @@ func ApplyTaskResults(spec *v1beta1.TaskSpec) *v1beta1.TaskSpec { return ApplyReplacements(spec, stringReplacements, map[string][]string{}) } -// ApplyCredentialsPath applies a substitution of the key $(credentials.path) with the path that the creds-init -// helper will write its credentials to. +// ApplyCredentialsPath applies a substitution of the key $(credentials.path) with the path that credentials +// from annotated secrets are written to. func ApplyCredentialsPath(spec *v1beta1.TaskSpec, path string) *v1beta1.TaskSpec { stringReplacements := map[string]string{ "credentials.path": path, diff --git a/pkg/reconciler/taskrun/taskrun.go b/pkg/reconciler/taskrun/taskrun.go index 4a296793557..075b75f1660 100644 --- a/pkg/reconciler/taskrun/taskrun.go +++ b/pkg/reconciler/taskrun/taskrun.go @@ -547,7 +547,7 @@ func (c *Reconciler) createPod(ctx context.Context, tr *v1beta1.TaskRun, rtr *re shouldOverrideHomeEnv := podconvert.ShouldOverrideHomeEnv(ctx) // Apply creds-init path substitutions. - ts = resources.ApplyCredentialsPath(ts, podconvert.CredentialsPath(shouldOverrideHomeEnv)) + ts = resources.ApplyCredentialsPath(ts, pipeline.CredsDir) pod, err := podconvert.MakePod(ctx, c.Images, tr, *ts, c.KubeClientSet, c.entrypointCache, shouldOverrideHomeEnv) if err != nil { diff --git a/pkg/reconciler/taskrun/taskrun_test.go b/pkg/reconciler/taskrun/taskrun_test.go index 6bd69d0b60d..7a0b8d91115 100644 --- a/pkg/reconciler/taskrun/taskrun_test.go +++ b/pkg/reconciler/taskrun/taskrun_test.go @@ -223,36 +223,6 @@ var ( }, } - getMkdirResourceContainer = func(name, dir, suffix string, ops ...tb.ContainerOp) tb.PodSpecOp { - actualOps := []tb.ContainerOp{ - tb.Command("/tekton/tools/entrypoint"), - tb.Args("-wait_file", - "/tekton/downward/ready", - "-wait_file_content", - "-post_file", - "/tekton/tools/0", - "-termination_path", - "/tekton/termination", - "-entrypoint", - "mkdir", - "--", - "-p", - dir), - tb.WorkingDir(workspaceDir), - tb.EnvVar("HOME", "/tekton/home"), - tb.VolumeMount("tekton-internal-tools", "/tekton/tools"), - tb.VolumeMount("tekton-internal-downward", "/tekton/downward"), - tb.VolumeMount("tekton-internal-workspace", workspaceDir), - tb.VolumeMount("tekton-internal-home", "/tekton/home"), - tb.VolumeMount("tekton-internal-results", "/tekton/results"), - tb.TerminationMessagePath("/tekton/termination"), - } - - actualOps = append(actualOps, ops...) - - return tb.PodContainer(fmt.Sprintf("step-create-dir-%s-%s", name, suffix), "busybox", actualOps...) - } - getPlaceToolsInitContainer = func(ops ...tb.ContainerOp) tb.PodSpecOp { actualOps := []tb.ContainerOp{ tb.Command("cp", "/ko-app/entrypoint", entrypointLocation), @@ -403,7 +373,10 @@ func TestReconcile_ExplicitDefaultSA(t *testing.T) { tb.OwnerReferenceAPIVersion(currentAPIVersion)), tb.PodSpec( tb.PodServiceAccountName(defaultSAName), - tb.PodVolumes(workspaceVolume, homeVolume, resultsVolume, toolsVolume, downwardVolume), + tb.PodVolumes(workspaceVolume, homeVolume, resultsVolume, toolsVolume, downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-9l9zj", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), tb.PodRestartPolicy(corev1.RestartPolicyNever), getPlaceToolsInitContainer(), tb.PodContainer("step-simple-step", "foo", @@ -423,6 +396,7 @@ func TestReconcile_ExplicitDefaultSA(t *testing.T) { tb.EnvVar("HOME", "/tekton/home"), tb.VolumeMount("tekton-internal-tools", "/tekton/tools"), tb.VolumeMount("tekton-internal-downward", "/tekton/downward"), + tb.VolumeMount("tekton-creds-init-home-9l9zj", "/tekton/creds"), tb.VolumeMount("tekton-internal-workspace", workspaceDir), tb.VolumeMount("tekton-internal-home", "/tekton/home"), tb.VolumeMount("tekton-internal-results", "/tekton/results"), @@ -443,7 +417,10 @@ func TestReconcile_ExplicitDefaultSA(t *testing.T) { tb.OwnerReferenceAPIVersion(currentAPIVersion)), tb.PodSpec( tb.PodServiceAccountName("test-sa"), - tb.PodVolumes(workspaceVolume, homeVolume, resultsVolume, toolsVolume, downwardVolume), + tb.PodVolumes(workspaceVolume, homeVolume, resultsVolume, toolsVolume, downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-9l9zj", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), tb.PodRestartPolicy(corev1.RestartPolicyNever), getPlaceToolsInitContainer(), tb.PodContainer("step-sa-step", "foo", @@ -463,6 +440,7 @@ func TestReconcile_ExplicitDefaultSA(t *testing.T) { tb.EnvVar("HOME", "/tekton/home"), tb.VolumeMount("tekton-internal-tools", "/tekton/tools"), tb.VolumeMount("tekton-internal-downward", "/tekton/downward"), + tb.VolumeMount("tekton-creds-init-home-9l9zj", "/tekton/creds"), tb.VolumeMount("tekton-internal-workspace", workspaceDir), tb.VolumeMount("tekton-internal-home", "/tekton/home"), tb.VolumeMount("tekton-internal-results", "/tekton/results"), @@ -573,7 +551,10 @@ func TestReconcile_FeatureFlags(t *testing.T) { tb.PodOwnerReference("TaskRun", "test-taskrun-run-home-env", tb.OwnerReferenceAPIVersion(currentAPIVersion)), tb.PodSpec( - tb.PodVolumes(workspaceVolume, homeVolume, resultsVolume, credsVolume, toolsVolume, downwardVolume), + tb.PodVolumes(workspaceVolume, homeVolume, resultsVolume, toolsVolume, downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-9l9zj", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), tb.PodRestartPolicy(corev1.RestartPolicyNever), getPlaceToolsInitContainer(), tb.PodContainer("step-simple-step", "foo", @@ -593,10 +574,10 @@ func TestReconcile_FeatureFlags(t *testing.T) { tb.EnvVar("foo", "bar"), tb.VolumeMount("tekton-internal-tools", "/tekton/tools"), tb.VolumeMount("tekton-internal-downward", "/tekton/downward"), + tb.VolumeMount("tekton-creds-init-home-9l9zj", "/tekton/creds"), tb.VolumeMount("tekton-internal-workspace", workspaceDir), tb.VolumeMount("tekton-internal-home", "/tekton/home"), tb.VolumeMount("tekton-internal-results", "/tekton/results"), - tb.VolumeMount("tekton-creds-init-home", "/tekton/creds"), tb.TerminationMessagePath("/tekton/termination"), ), ), @@ -614,7 +595,10 @@ func TestReconcile_FeatureFlags(t *testing.T) { tb.PodOwnerReference("TaskRun", "test-taskrun-run-working-dir", tb.OwnerReferenceAPIVersion(currentAPIVersion)), tb.PodSpec( - tb.PodVolumes(workspaceVolume, homeVolume, resultsVolume, toolsVolume, downwardVolume), + tb.PodVolumes(workspaceVolume, homeVolume, resultsVolume, toolsVolume, downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-9l9zj", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), tb.PodRestartPolicy(corev1.RestartPolicyNever), getPlaceToolsInitContainer(), tb.PodContainer("step-simple-step", "foo", @@ -633,6 +617,7 @@ func TestReconcile_FeatureFlags(t *testing.T) { tb.EnvVar("HOME", "/tekton/home"), tb.VolumeMount("tekton-internal-tools", "/tekton/tools"), tb.VolumeMount("tekton-internal-downward", "/tekton/downward"), + tb.VolumeMount("tekton-creds-init-home-9l9zj", "/tekton/creds"), tb.VolumeMount("tekton-internal-workspace", workspaceDir), tb.VolumeMount("tekton-internal-home", "/tekton/home"), tb.VolumeMount("tekton-internal-results", "/tekton/results"), @@ -934,7 +919,10 @@ func TestReconcile(t *testing.T) { tb.PodOwnerReference("TaskRun", "test-taskrun-run-success", tb.OwnerReferenceAPIVersion(currentAPIVersion)), tb.PodSpec( - tb.PodVolumes(workspaceVolume, homeVolume, resultsVolume, toolsVolume, downwardVolume), + tb.PodVolumes(workspaceVolume, homeVolume, resultsVolume, toolsVolume, downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-9l9zj", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), tb.PodRestartPolicy(corev1.RestartPolicyNever), getPlaceToolsInitContainer(), tb.PodContainer("step-simple-step", "foo", @@ -954,6 +942,7 @@ func TestReconcile(t *testing.T) { tb.EnvVar("HOME", "/tekton/home"), tb.VolumeMount("tekton-internal-tools", "/tekton/tools"), tb.VolumeMount("tekton-internal-downward", "/tekton/downward"), + tb.VolumeMount("tekton-creds-init-home-9l9zj", "/tekton/creds"), tb.VolumeMount("tekton-internal-workspace", workspaceDir), tb.VolumeMount("tekton-internal-home", "/tekton/home"), tb.VolumeMount("tekton-internal-results", "/tekton/results"), @@ -978,7 +967,10 @@ func TestReconcile(t *testing.T) { tb.OwnerReferenceAPIVersion(currentAPIVersion)), tb.PodSpec( tb.PodServiceAccountName("test-sa"), - tb.PodVolumes(workspaceVolume, homeVolume, resultsVolume, toolsVolume, downwardVolume), + tb.PodVolumes(workspaceVolume, homeVolume, resultsVolume, toolsVolume, downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-9l9zj", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), tb.PodRestartPolicy(corev1.RestartPolicyNever), getPlaceToolsInitContainer(), tb.PodContainer("step-sa-step", "foo", @@ -998,6 +990,7 @@ func TestReconcile(t *testing.T) { tb.EnvVar("HOME", "/tekton/home"), tb.VolumeMount("tekton-internal-tools", "/tekton/tools"), tb.VolumeMount("tekton-internal-downward", "/tekton/downward"), + tb.VolumeMount("tekton-creds-init-home-9l9zj", "/tekton/creds"), tb.VolumeMount("tekton-internal-workspace", workspaceDir), tb.VolumeMount("tekton-internal-home", "/tekton/home"), tb.VolumeMount("tekton-internal-results", "/tekton/results"), @@ -1022,7 +1015,26 @@ func TestReconcile(t *testing.T) { tb.OwnerReferenceAPIVersion(currentAPIVersion)), tb.PodSpec( tb.PodVolumes( - workspaceVolume, homeVolume, resultsVolume, toolsVolume, downwardVolume, + workspaceVolume, homeVolume, resultsVolume, toolsVolume, downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-78c5n", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }, + corev1.Volume{ + Name: "tekton-creds-init-home-6nl7g", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }, + corev1.Volume{ + Name: "tekton-creds-init-home-j2tds", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }, + corev1.Volume{ + Name: "tekton-creds-init-home-vr6ds", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }, + corev1.Volume{ + Name: "tekton-creds-init-home-l22wn", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }, corev1.Volume{ Name: "volume-configmap", VolumeSource: corev1.VolumeSource{ @@ -1036,7 +1048,30 @@ func TestReconcile(t *testing.T) { ), tb.PodRestartPolicy(corev1.RestartPolicyNever), getPlaceToolsInitContainer(), - getMkdirResourceContainer("myimage", "/workspace/output/myimage", "mssqb"), + tb.PodContainer("step-create-dir-myimage-mssqb", "busybox", + tb.Command("/tekton/tools/entrypoint"), + tb.Args("-wait_file", + "/tekton/downward/ready", + "-wait_file_content", + "-post_file", + "/tekton/tools/0", + "-termination_path", + "/tekton/termination", + "-entrypoint", + "mkdir", + "--", + "-p", + "/workspace/output/myimage"), + tb.WorkingDir(workspaceDir), + tb.EnvVar("HOME", "/tekton/home"), + tb.VolumeMount("tekton-internal-tools", "/tekton/tools"), + tb.VolumeMount("tekton-internal-downward", "/tekton/downward"), + tb.VolumeMount("tekton-creds-init-home-78c5n", "/tekton/creds"), + tb.VolumeMount("tekton-internal-workspace", workspaceDir), + tb.VolumeMount("tekton-internal-home", "/tekton/home"), + tb.VolumeMount("tekton-internal-results", "/tekton/results"), + tb.TerminationMessagePath("/tekton/termination"), + ), tb.PodContainer("step-git-source-workspace-mz4c7", "override-with-git:latest", tb.Command(entrypointLocation), tb.Args("-wait_file", "/tekton/tools/0", "-post_file", "/tekton/tools/1", "-termination_path", @@ -1047,6 +1082,7 @@ func TestReconcile(t *testing.T) { tb.EnvVar("TEKTON_RESOURCE_NAME", "workspace"), tb.EnvVar("HOME", "/tekton/home"), tb.VolumeMount("tekton-internal-tools", "/tekton/tools"), + tb.VolumeMount("tekton-creds-init-home-6nl7g", "/tekton/creds"), tb.VolumeMount("tekton-internal-workspace", workspaceDir), tb.VolumeMount("tekton-internal-home", "/tekton/home"), tb.VolumeMount("tekton-internal-results", "/tekton/results"), @@ -1061,6 +1097,7 @@ func TestReconcile(t *testing.T) { tb.WorkingDir(workspaceDir), tb.EnvVar("HOME", "/tekton/home"), tb.VolumeMount("tekton-internal-tools", "/tekton/tools"), + tb.VolumeMount("tekton-creds-init-home-j2tds", "/tekton/creds"), tb.VolumeMount("tekton-internal-workspace", workspaceDir), tb.VolumeMount("tekton-internal-home", "/tekton/home"), tb.VolumeMount("tekton-internal-results", "/tekton/results"), @@ -1073,6 +1110,7 @@ func TestReconcile(t *testing.T) { tb.WorkingDir(workspaceDir), tb.EnvVar("HOME", "/tekton/home"), tb.VolumeMount("tekton-internal-tools", "/tekton/tools"), + tb.VolumeMount("tekton-creds-init-home-vr6ds", "/tekton/creds"), tb.VolumeMount("tekton-internal-workspace", workspaceDir), tb.VolumeMount("tekton-internal-home", "/tekton/home"), tb.VolumeMount("tekton-internal-results", "/tekton/results"), @@ -1086,6 +1124,7 @@ func TestReconcile(t *testing.T) { tb.WorkingDir(workspaceDir), tb.EnvVar("HOME", "/tekton/home"), tb.VolumeMount("tekton-internal-tools", "/tekton/tools"), + tb.VolumeMount("tekton-creds-init-home-l22wn", "/tekton/creds"), tb.VolumeMount("tekton-internal-workspace", workspaceDir), tb.VolumeMount("tekton-internal-home", "/tekton/home"), tb.VolumeMount("tekton-internal-results", "/tekton/results"), @@ -1108,7 +1147,13 @@ func TestReconcile(t *testing.T) { tb.PodOwnerReference("TaskRun", "test-taskrun-with-taskspec", tb.OwnerReferenceAPIVersion(currentAPIVersion)), tb.PodSpec( - tb.PodVolumes(workspaceVolume, homeVolume, resultsVolume, toolsVolume, downwardVolume), + tb.PodVolumes(workspaceVolume, homeVolume, resultsVolume, toolsVolume, downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-mz4c7", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }, corev1.Volume{ + Name: "tekton-creds-init-home-mssqb", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), tb.PodRestartPolicy(corev1.RestartPolicyNever), getPlaceToolsInitContainer(), tb.PodContainer("step-git-source-workspace-9l9zj", "override-with-git:latest", @@ -1137,6 +1182,7 @@ func TestReconcile(t *testing.T) { tb.EnvVar("HOME", "/tekton/home"), tb.VolumeMount("tekton-internal-tools", "/tekton/tools"), tb.VolumeMount("tekton-internal-downward", "/tekton/downward"), + tb.VolumeMount("tekton-creds-init-home-mz4c7", "/tekton/creds"), tb.VolumeMount("tekton-internal-workspace", workspaceDir), tb.VolumeMount("tekton-internal-home", "/tekton/home"), tb.VolumeMount("tekton-internal-results", "/tekton/results"), @@ -1149,6 +1195,7 @@ func TestReconcile(t *testing.T) { "/tekton/termination", "-entrypoint", "/mycmd", "--", "--my-arg=foo"), tb.EnvVar("HOME", "/tekton/home"), tb.VolumeMount("tekton-internal-tools", "/tekton/tools"), + tb.VolumeMount("tekton-creds-init-home-mssqb", "/tekton/creds"), tb.VolumeMount("tekton-internal-workspace", workspaceDir), tb.VolumeMount("tekton-internal-home", "/tekton/home"), tb.VolumeMount("tekton-internal-results", "/tekton/results"), @@ -1173,7 +1220,10 @@ func TestReconcile(t *testing.T) { tb.PodOwnerReference("TaskRun", "test-taskrun-with-cluster-task", tb.OwnerReferenceAPIVersion(currentAPIVersion)), tb.PodSpec( - tb.PodVolumes(workspaceVolume, homeVolume, resultsVolume, toolsVolume, downwardVolume), + tb.PodVolumes(workspaceVolume, homeVolume, resultsVolume, toolsVolume, downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-9l9zj", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), tb.PodRestartPolicy(corev1.RestartPolicyNever), getPlaceToolsInitContainer(), tb.PodContainer("step-simple-step", "foo", @@ -1193,6 +1243,7 @@ func TestReconcile(t *testing.T) { tb.EnvVar("HOME", "/tekton/home"), tb.VolumeMount("tekton-internal-tools", "/tekton/tools"), tb.VolumeMount("tekton-internal-downward", "/tekton/downward"), + tb.VolumeMount("tekton-creds-init-home-9l9zj", "/tekton/creds"), tb.VolumeMount("tekton-internal-workspace", workspaceDir), tb.VolumeMount("tekton-internal-home", "/tekton/home"), tb.VolumeMount("tekton-internal-results", "/tekton/results"), @@ -1215,7 +1266,13 @@ func TestReconcile(t *testing.T) { tb.PodOwnerReference("TaskRun", "test-taskrun-with-resource-spec", tb.OwnerReferenceAPIVersion(currentAPIVersion)), tb.PodSpec( - tb.PodVolumes(workspaceVolume, homeVolume, resultsVolume, toolsVolume, downwardVolume), + tb.PodVolumes(workspaceVolume, homeVolume, resultsVolume, toolsVolume, downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-mz4c7", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }, corev1.Volume{ + Name: "tekton-creds-init-home-mssqb", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), tb.PodRestartPolicy(corev1.RestartPolicyNever), getPlaceToolsInitContainer(), tb.PodContainer("step-git-source-workspace-9l9zj", "override-with-git:latest", @@ -1245,6 +1302,7 @@ func TestReconcile(t *testing.T) { tb.EnvVar("HOME", "/tekton/home"), tb.VolumeMount("tekton-internal-tools", "/tekton/tools"), tb.VolumeMount("tekton-internal-downward", "/tekton/downward"), + tb.VolumeMount("tekton-creds-init-home-mz4c7", "/tekton/creds"), tb.VolumeMount("tekton-internal-workspace", workspaceDir), tb.VolumeMount("tekton-internal-home", "/tekton/home"), tb.VolumeMount("tekton-internal-results", "/tekton/results"), @@ -1257,6 +1315,7 @@ func TestReconcile(t *testing.T) { tb.WorkingDir(workspaceDir), tb.EnvVar("HOME", "/tekton/home"), tb.VolumeMount("tekton-internal-tools", "/tekton/tools"), + tb.VolumeMount("tekton-creds-init-home-mssqb", "/tekton/creds"), tb.VolumeMount("tekton-internal-workspace", workspaceDir), tb.VolumeMount("tekton-internal-home", "/tekton/home"), tb.VolumeMount("tekton-internal-results", "/tekton/results"), @@ -1280,7 +1339,10 @@ func TestReconcile(t *testing.T) { tb.PodOwnerReference("TaskRun", "test-taskrun-with-pod", tb.OwnerReferenceAPIVersion(currentAPIVersion)), tb.PodSpec( - tb.PodVolumes(workspaceVolume, homeVolume, resultsVolume, toolsVolume, downwardVolume), + tb.PodVolumes(workspaceVolume, homeVolume, resultsVolume, toolsVolume, downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-9l9zj", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), tb.PodRestartPolicy(corev1.RestartPolicyNever), getPlaceToolsInitContainer(), tb.PodContainer("step-simple-step", "foo", @@ -1299,6 +1361,7 @@ func TestReconcile(t *testing.T) { tb.EnvVar("HOME", "/tekton/home"), tb.VolumeMount("tekton-internal-tools", "/tekton/tools"), tb.VolumeMount("tekton-internal-downward", "/tekton/downward"), + tb.VolumeMount("tekton-creds-init-home-9l9zj", "/tekton/creds"), tb.VolumeMount("tekton-internal-workspace", workspaceDir), tb.VolumeMount("tekton-internal-home", "/tekton/home"), tb.VolumeMount("tekton-internal-results", "/tekton/results"), @@ -1307,7 +1370,7 @@ func TestReconcile(t *testing.T) { ), ), }, { - name: "taskrun-with-credentials-variable-default-tekton-home", + name: "taskrun-with-credentials-variable-default-tekton-creds", taskRun: taskRunWithCredentialsVariable, wantEvents: []string{ "Normal Started ", @@ -1321,7 +1384,10 @@ func TestReconcile(t *testing.T) { tb.PodOwnerReference("TaskRun", "test-taskrun-with-credentials-variable", tb.OwnerReferenceAPIVersion(currentAPIVersion)), tb.PodSpec( - tb.PodVolumes(workspaceVolume, homeVolume, resultsVolume, toolsVolume, downwardVolume), + tb.PodVolumes(workspaceVolume, homeVolume, resultsVolume, toolsVolume, downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-9l9zj", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), tb.PodRestartPolicy(corev1.RestartPolicyNever), getPlaceToolsInitContainer(), tb.PodContainer("step-mycontainer", "myimage", @@ -1334,13 +1400,14 @@ func TestReconcile(t *testing.T) { "-termination_path", "/tekton/termination", "-entrypoint", - // Important bit here: /tekton/home - "/mycmd /tekton/home", + // Important bit here: /tekton/creds + "/mycmd /tekton/creds", "--"), tb.WorkingDir(workspaceDir), tb.EnvVar("HOME", "/tekton/home"), tb.VolumeMount("tekton-internal-tools", "/tekton/tools"), tb.VolumeMount("tekton-internal-downward", "/tekton/downward"), + tb.VolumeMount("tekton-creds-init-home-9l9zj", "/tekton/creds"), tb.VolumeMount("tekton-internal-workspace", workspaceDir), tb.VolumeMount("tekton-internal-home", "/tekton/home"), tb.VolumeMount("tekton-internal-results", "/tekton/results"),