Skip to content

Commit 61d2c99

Browse files
author
TP Honey
committed
ssh agent support
1 parent 84d8664 commit 61d2c99

File tree

5 files changed

+57
-50
lines changed

5 files changed

+57
-50
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
release
22
coverage.out
33
vendor
4+
.vscode/
5+
Dockerfile

cmd/drone-docker/main.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -274,10 +274,10 @@ func main() {
274274
Usage: "platform value to pass to docker",
275275
EnvVar: "PLUGIN_PLATFORM",
276276
},
277-
cli.StringSliceFlag{
278-
Name: "ssh-agent",
279-
Usage: "mount ssh agent",
280-
EnvVar: "PLUGIN_SSH_AGENT",
277+
cli.StringFlag{
278+
Name: "ssh-agent-key",
279+
Usage: "base64 encoded ssh agent key to use",
280+
EnvVar: "PLUGIN_SSH_AGENT_KEY",
281281
},
282282
}
283283

@@ -323,7 +323,7 @@ func run(c *cli.Context) error {
323323
AddHost: c.StringSlice("add-host"),
324324
Quiet: c.Bool("quiet"),
325325
Platform: c.String("platform"),
326-
SSHAgent: c.StringSlice("ssh-agent"),
326+
SSHAgentKey: c.String("ssh-agent-key"),
327327
},
328328
Daemon: docker.Daemon{
329329
Registry: c.String("docker.registry"),

daemon.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1+
//go:build !windows
12
// +build !windows
23

34
package docker
45

56
import (
6-
"io/ioutil"
7+
"io"
78
"os"
89
)
910

@@ -17,8 +18,8 @@ func (p Plugin) startDaemon() {
1718
cmd.Stdout = os.Stdout
1819
cmd.Stderr = os.Stderr
1920
} else {
20-
cmd.Stdout = ioutil.Discard
21-
cmd.Stderr = ioutil.Discard
21+
cmd.Stdout = io.Discard
22+
cmd.Stderr = io.Discard
2223
}
2324
go func() {
2425
trace(cmd)

docker.go

Lines changed: 26 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ package docker
33
import (
44
"encoding/base64"
55
"fmt"
6-
"io/ioutil"
7-
"log"
86
"os"
97
"os/exec"
108
"path/filepath"
@@ -13,11 +11,6 @@ import (
1311
"time"
1412
)
1513

16-
const (
17-
SSHAgentSockPath = "/tmp/drone-ssh-agent-sock"
18-
SSHPrivateKeyFromEnv = "SSH_KEY"
19-
)
20-
2114
type (
2215
// Daemon defines Docker daemon parameters.
2316
Daemon struct {
@@ -71,7 +64,8 @@ type (
7164
AddHost []string // Docker build add-host
7265
Quiet bool // Docker build quiet
7366
Platform string // Docker build platform
74-
SSHAgent []string // Docker build ssh
67+
SSHAgentKey string // Docker build ssh agent key
68+
SSHKeyPath string // Docker build ssh key path
7569
}
7670

7771
// Plugin defines the Docker plugin parameters.
@@ -153,7 +147,7 @@ func (p Plugin) Exec() error {
153147
os.MkdirAll(dockerHome, 0600)
154148

155149
path := filepath.Join(dockerHome, "config.json")
156-
err := ioutil.WriteFile(path, []byte(p.Login.Config), 0600)
150+
err := os.WriteFile(path, []byte(p.Login.Config), 0600)
157151
if err != nil {
158152
return fmt.Errorf("Error writing config.json: %s", err)
159153
}
@@ -189,10 +183,13 @@ func (p Plugin) Exec() error {
189183
}
190184

191185
// setup for using ssh agent (https://docs.docker.com/develop/develop-images/build_enhancements/#using-ssh-to-access-private-data-in-builds)
192-
193-
if len(p.Build.SSHAgent) > 0 {
194-
fmt.Printf("ssh agent set to \"%s\"\n", p.Build.SSHAgent)
195-
cmds = append(cmds, commandSSHAgentForwardingSetup(p.Build)...)
186+
if p.Build.SSHAgentKey != "" {
187+
var sshErr error
188+
fmt.Printf("ssh agent key set\n", len(p.Build.SSHAgentKey))
189+
p.Build.SSHKeyPath, sshErr = writeSSHPrivateKey(p.Build.SSHAgentKey)
190+
if sshErr != nil {
191+
return sshErr
192+
}
196193
}
197194

198195
cmds = append(cmds, commandBuild(p.Build)) // docker build
@@ -344,8 +341,8 @@ func commandBuild(build Build) *exec.Cmd {
344341
if build.Platform != "" {
345342
args = append(args, "--platform", build.Platform)
346343
}
347-
for _, sshagent := range build.SSHAgent {
348-
args = append(args, "--ssh", sshagent)
344+
if build.SSHKeyPath != "" {
345+
args = append(args, "--ssh", build.SSHKeyPath)
349346
}
350347

351348
if build.AutoLabel {
@@ -373,7 +370,7 @@ func commandBuild(build Build) *exec.Cmd {
373370
}
374371

375372
// we need to enable buildkit, for secret support and ssh agent support
376-
if build.Secret != "" || len(build.SecretEnvs) > 0 || len(build.SecretFiles) > 0 || len(build.SSHAgent) > 0 {
373+
if build.Secret != "" || len(build.SecretEnvs) > 0 || len(build.SecretFiles) > 0 || build.SSHAgentKey != "" {
377374
os.Setenv("DOCKER_BUILDKIT", "1")
378375
}
379376
return exec.Command(dockerExe, args...)
@@ -526,38 +523,25 @@ func commandRmi(tag string) *exec.Cmd {
526523
return exec.Command(dockerExe, "rmi", tag)
527524
}
528525

529-
func commandSSHAgentForwardingSetup(build Build) []*exec.Cmd {
530-
cmds := make([]*exec.Cmd, 0)
531-
if err := writeSSHPrivateKey(); err != nil {
532-
log.Fatalf("unable to setup ssh agent forwarding: %s", err)
533-
}
534-
os.Setenv("SSH_AUTH_SOCK", SSHAgentSockPath)
535-
cmds = append(cmds, exec.Command("ssh-agent", "-a", SSHAgentSockPath))
536-
cmds = append(cmds, exec.Command("ssh-add"))
537-
return cmds
538-
}
539-
540-
func writeSSHPrivateKey() error {
541-
privateKeyBase64 := os.Getenv(SSHPrivateKeyFromEnv)
542-
if privateKeyBase64 == "" {
543-
return fmt.Errorf("%s must be defined and contain the base64 encoded private key to use for ssh agent forwarding", SSHPrivateKeyFromEnv)
544-
}
545-
var err error
546-
privateKey, err := base64.StdEncoding.DecodeString(privateKeyBase64)
547-
if err != nil {
548-
return fmt.Errorf("unable to base64 decode private key")
549-
}
526+
func writeSSHPrivateKey(key string) (path string, err error) {
550527
home, err := os.UserHomeDir()
551528
if err != nil {
552-
return fmt.Errorf("unable to determine home directory: %s", err)
529+
return "", fmt.Errorf("unable to determine home directory: %s", err)
553530
}
554531
if err := os.MkdirAll(filepath.Join(home, ".ssh"), 0700); err != nil {
555-
return fmt.Errorf("unable to create .ssh directory: %s", err)
532+
return "", fmt.Errorf("unable to create .ssh directory: %s", err)
556533
}
557-
if err := os.WriteFile(filepath.Join(home, ".ssh", "id_rsa"), privateKey, 0400); err != nil {
558-
return fmt.Errorf("unable to write ssh key: %s", err)
534+
privateKey, err := base64.StdEncoding.DecodeString(key)
535+
if err != nil {
536+
return "", fmt.Errorf("unable to base64 decode private ssh key: %s", err)
559537
}
560-
return nil
538+
pathToKey := filepath.Join(home, ".ssh", "id_rsa")
539+
if err := os.WriteFile(pathToKey, privateKey, 0400); err != nil {
540+
return "", fmt.Errorf("unable to write ssh key %s: %s", pathToKey, err)
541+
}
542+
path = fmt.Sprintf("default=%s", pathToKey)
543+
544+
return path, nil
561545
}
562546

563547
// trace writes each command to stdout with the command wrapped in an xml

docker_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,26 @@ func TestCommandBuild(t *testing.T) {
135135
"test/platform",
136136
),
137137
},
138+
{
139+
name: "ssh agent",
140+
build: Build{
141+
Name: "plugins/drone-docker:latest",
142+
Dockerfile: "Dockerfile",
143+
Context: ".",
144+
SSHKeyPath: "id_rsa=/root/.ssh/id_rsa",
145+
},
146+
want: exec.Command(
147+
dockerExe,
148+
"build",
149+
"--rm=true",
150+
"-f",
151+
"Dockerfile",
152+
"-t",
153+
"plugins/drone-docker:latest",
154+
".",
155+
"--ssh id_rsa=/root/.ssh/id_rsa",
156+
),
157+
},
138158
}
139159

140160
for _, tc := range tcs {

0 commit comments

Comments
 (0)