Skip to content

Commit

Permalink
Revert "Remove creds-init intContainer"
Browse files Browse the repository at this point in the history
This reverts commit bbb767c.

In #2671 I removed the creds-init
initContainer from Task Pods so that credentials could be used by containers
running with non-root users.  The intention was for this change to be free
of any side-effects to end-users.  Unfortunately a
[backwards incompatible issue](#2951)
has cropped up with this change:

When a user does not specify the `known_hosts` field in a creds-init Secret,
the credential code will perform an `ssh-keyscan` of the remote server to get
its public key.  The problem is that previously we could guarantee `ssh-keyscan`
was available since the code ran in our own creds-init container with our own
docker image. Since we've now moved that code into Steps' entrypoint the Steps
container is required to provide `ssh-keyscan`.  This is a change in container
contract and therefore backwards-incompatible.

In this PR I've reverted the creds-init change for the 0.14 branch rather than
attempt to fix the `ssh-keyscan` issue and possibly introduce more problems.

Before 0.15 I'd like to get a better backwards-compatible fix organized.
So I plan to leave the creds-init change in place in the `master` branch for
the time being.
  • Loading branch information
Scott authored and tekton-robot committed Jul 16, 2020
1 parent aaaa24a commit 9168151
Show file tree
Hide file tree
Showing 22 changed files with 322 additions and 681 deletions.
3 changes: 1 addition & 2 deletions cmd/creds-init/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ 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"
Expand All @@ -38,7 +37,7 @@ func main() {

builders := []credentials.Builder{dockercreds.NewBuilder(), gitcreds.NewBuilder()}
for _, c := range builders {
if err := c.Write(pipeline.CredsDir); err != nil {
if err := c.Write(); err != nil {
logger.Fatalf("Error initializing credentials: %v", err)
}
}
Expand Down
18 changes: 1 addition & 17 deletions cmd/entrypoint/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ 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"
)
Expand All @@ -43,22 +41,8 @@ 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, ","),
Expand All @@ -72,7 +56,7 @@ func main() {
Results: strings.Split(*results, ","),
}

// Copy any creds injected by the controller into the $HOME directory of the current
// Copy any creds injected by creds-init 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)
Expand Down
28 changes: 1 addition & 27 deletions docs/auth.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,14 +121,10 @@ 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:** The additional symlink is not required if you are using the
**Note:** This 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
Expand Down Expand Up @@ -379,28 +375,6 @@ 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`
Expand Down
2 changes: 1 addition & 1 deletion docs/variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ This page documents the variable substitions supported by `Tasks` and `Pipelines
| `workspaces.<workspaceName>.path` | The path to the mounted `Workspace`. |
| `workspaces.<workspaceName>.claim` | The name of the `PersistentVolumeClaim` specified as a volume source for the `Workspace`. Empty string for other volume types. |
| `workspaces.<workspaceName>.volume` | The name of the volume populating the `Workspace`. |
| `credentials.path` | The path to credentials injected from Secrets with matching annotations. |
| `credentials.path` | The path to the credentials written by the `creds-init` init container. |
| `context.taskRun.name` | The name of the `TaskRun` that this `Task` is running in. |
| `context.task.name` | The name of this `Task`. |

Expand Down
204 changes: 0 additions & 204 deletions examples/v1beta1/taskruns/authenticating-git-commands.yaml

This file was deleted.

2 changes: 0 additions & 2 deletions pkg/apis/pipeline/paths.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,4 @@ 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"
)
13 changes: 6 additions & 7 deletions pkg/credentials/dockercreds/creds.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,17 @@ 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.")
fs.StringVar(&dockerConfig, "docker-config", "", "Docker config.json secret file.")
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 {
Expand Down Expand Up @@ -149,8 +148,8 @@ func (*basicDockerBuilder) MatchingAnnotations(secret *corev1.Secret) []string {
return flags
}

func (*basicDockerBuilder) Write(directory string) error {
dockerDir := filepath.Join(directory, ".docker")
func (*basicDockerBuilder) Write() error {
dockerDir := filepath.Join(os.Getenv("HOME"), ".docker")
basicDocker := filepath.Join(dockerDir, "config.json")
if err := os.MkdirAll(dockerDir, os.ModePerm); err != nil {
return err
Expand Down
Loading

0 comments on commit 9168151

Please sign in to comment.