Skip to content

Commit a2f8157

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

File tree

5 files changed

+56
-50
lines changed

5 files changed

+56
-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: 25 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,12 @@ 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+
p.Build.SSHKeyPath, sshErr = writeSSHPrivateKey(p.Build.SSHAgentKey)
189+
if sshErr != nil {
190+
return sshErr
191+
}
196192
}
197193

198194
cmds = append(cmds, commandBuild(p.Build)) // docker build
@@ -344,8 +340,8 @@ func commandBuild(build Build) *exec.Cmd {
344340
if build.Platform != "" {
345341
args = append(args, "--platform", build.Platform)
346342
}
347-
for _, sshagent := range build.SSHAgent {
348-
args = append(args, "--ssh", sshagent)
343+
if build.SSHKeyPath != "" {
344+
args = append(args, "--ssh", build.SSHKeyPath)
349345
}
350346

351347
if build.AutoLabel {
@@ -373,7 +369,7 @@ func commandBuild(build Build) *exec.Cmd {
373369
}
374370

375371
// 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 {
372+
if build.Secret != "" || len(build.SecretEnvs) > 0 || len(build.SecretFiles) > 0 || build.SSHAgentKey != "" {
377373
os.Setenv("DOCKER_BUILDKIT", "1")
378374
}
379375
return exec.Command(dockerExe, args...)
@@ -526,38 +522,25 @@ func commandRmi(tag string) *exec.Cmd {
526522
return exec.Command(dockerExe, "rmi", tag)
527523
}
528524

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-
}
525+
func writeSSHPrivateKey(key string) (path string, err error) {
550526
home, err := os.UserHomeDir()
551527
if err != nil {
552-
return fmt.Errorf("unable to determine home directory: %s", err)
528+
return "", fmt.Errorf("unable to determine home directory: %s", err)
553529
}
554530
if err := os.MkdirAll(filepath.Join(home, ".ssh"), 0700); err != nil {
555-
return fmt.Errorf("unable to create .ssh directory: %s", err)
531+
return "", fmt.Errorf("unable to create .ssh directory: %s", err)
556532
}
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)
533+
privateKey, err := base64.StdEncoding.DecodeString(key)
534+
if err != nil {
535+
return "", fmt.Errorf("unable to base64 decode private ssh key: %s", err)
559536
}
560-
return nil
537+
pathToKey := filepath.Join(home, ".ssh", "id_rsa")
538+
if err := os.WriteFile(pathToKey, privateKey, 0400); err != nil {
539+
return "", fmt.Errorf("unable to write ssh key %s: %s", pathToKey, err)
540+
}
541+
path = fmt.Sprintf("default=%s", pathToKey)
542+
543+
return path, nil
561544
}
562545

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