Skip to content

Commit d704148

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

File tree

5 files changed

+52
-51
lines changed

5 files changed

+52
-51
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: "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: 21 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
package docker
22

33
import (
4-
"encoding/base64"
54
"fmt"
6-
"io/ioutil"
7-
"log"
85
"os"
96
"os/exec"
107
"path/filepath"
@@ -13,11 +10,6 @@ import (
1310
"time"
1411
)
1512

16-
const (
17-
SSHAgentSockPath = "/tmp/drone-ssh-agent-sock"
18-
SSHPrivateKeyFromEnv = "SSH_KEY"
19-
)
20-
2113
type (
2214
// Daemon defines Docker daemon parameters.
2315
Daemon struct {
@@ -71,7 +63,8 @@ type (
7163
AddHost []string // Docker build add-host
7264
Quiet bool // Docker build quiet
7365
Platform string // Docker build platform
74-
SSHAgent []string // Docker build ssh
66+
SSHAgentKey string // Docker build ssh agent key
67+
SSHKeyPath string // Docker build ssh key path
7568
}
7669

7770
// Plugin defines the Docker plugin parameters.
@@ -153,7 +146,7 @@ func (p Plugin) Exec() error {
153146
os.MkdirAll(dockerHome, 0600)
154147

155148
path := filepath.Join(dockerHome, "config.json")
156-
err := ioutil.WriteFile(path, []byte(p.Login.Config), 0600)
149+
err := os.WriteFile(path, []byte(p.Login.Config), 0600)
157150
if err != nil {
158151
return fmt.Errorf("Error writing config.json: %s", err)
159152
}
@@ -189,10 +182,12 @@ func (p Plugin) Exec() error {
189182
}
190183

191184
// 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)...)
185+
if p.Build.SSHAgentKey != "" {
186+
var sshErr error
187+
p.Build.SSHKeyPath, sshErr = writeSSHPrivateKey(p.Build.SSHAgentKey)
188+
if sshErr != nil {
189+
return sshErr
190+
}
196191
}
197192

198193
cmds = append(cmds, commandBuild(p.Build)) // docker build
@@ -344,8 +339,8 @@ func commandBuild(build Build) *exec.Cmd {
344339
if build.Platform != "" {
345340
args = append(args, "--platform", build.Platform)
346341
}
347-
for _, sshagent := range build.SSHAgent {
348-
args = append(args, "--ssh", sshagent)
342+
if build.SSHKeyPath != "" {
343+
args = append(args, "--ssh", build.SSHKeyPath)
349344
}
350345

351346
if build.AutoLabel {
@@ -373,7 +368,7 @@ func commandBuild(build Build) *exec.Cmd {
373368
}
374369

375370
// 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 {
371+
if build.Secret != "" || len(build.SecretEnvs) > 0 || len(build.SecretFiles) > 0 || build.SSHAgentKey != "" {
377372
os.Setenv("DOCKER_BUILDKIT", "1")
378373
}
379374
return exec.Command(dockerExe, args...)
@@ -526,38 +521,21 @@ func commandRmi(tag string) *exec.Cmd {
526521
return exec.Command(dockerExe, "rmi", tag)
527522
}
528523

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-
}
524+
func writeSSHPrivateKey(key string) (path string, err error) {
550525
home, err := os.UserHomeDir()
551526
if err != nil {
552-
return fmt.Errorf("unable to determine home directory: %s", err)
527+
return "", fmt.Errorf("unable to determine home directory: %s", err)
553528
}
554529
if err := os.MkdirAll(filepath.Join(home, ".ssh"), 0700); err != nil {
555-
return fmt.Errorf("unable to create .ssh directory: %s", err)
530+
return "", fmt.Errorf("unable to create .ssh directory: %s", err)
556531
}
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)
532+
pathToKey := filepath.Join(home, ".ssh", "id_rsa")
533+
if err := os.WriteFile(pathToKey, []byte(key), 0400); err != nil {
534+
return "", fmt.Errorf("unable to write ssh key %s: %s", pathToKey, err)
559535
}
560-
return nil
536+
path = fmt.Sprintf("default=%s", pathToKey)
537+
538+
return path, nil
561539
}
562540

563541
// 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)