Skip to content

Commit 2dcf4a5

Browse files
author
TP Honey
authored
Merge pull request #382 from tphoney/enable-ssh-agent
Add option to mount host ssh agent (--ssh)
2 parents 94c8139 + d704148 commit 2dcf4a5

File tree

5 files changed

+67
-7
lines changed

5 files changed

+67
-7
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: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,11 @@ func main() {
274274
Usage: "platform value to pass to docker",
275275
EnvVar: "PLUGIN_PLATFORM",
276276
},
277+
cli.StringFlag{
278+
Name: "ssh-agent-key",
279+
Usage: "ssh agent key to use",
280+
EnvVar: "PLUGIN_SSH_AGENT_KEY",
281+
},
277282
}
278283

279284
if err := app.Run(os.Args); err != nil {
@@ -318,6 +323,7 @@ func run(c *cli.Context) error {
318323
AddHost: c.StringSlice("add-host"),
319324
Quiet: c.Bool("quiet"),
320325
Platform: c.String("platform"),
326+
SSHAgentKey: c.String("ssh-agent-key"),
321327
},
322328
Daemon: docker.Daemon{
323329
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: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package docker
22

33
import (
44
"fmt"
5-
"io/ioutil"
65
"os"
76
"os/exec"
87
"path/filepath"
@@ -64,6 +63,8 @@ type (
6463
AddHost []string // Docker build add-host
6564
Quiet bool // Docker build quiet
6665
Platform string // Docker build platform
66+
SSHAgentKey string // Docker build ssh agent key
67+
SSHKeyPath string // Docker build ssh key path
6768
}
6869

6970
// Plugin defines the Docker plugin parameters.
@@ -106,6 +107,7 @@ type (
106107

107108
// Exec executes the plugin step
108109
func (p Plugin) Exec() error {
110+
109111
// start the Docker daemon server
110112
if !p.Daemon.Disabled {
111113
p.startDaemon()
@@ -144,7 +146,7 @@ func (p Plugin) Exec() error {
144146
os.MkdirAll(dockerHome, 0600)
145147

146148
path := filepath.Join(dockerHome, "config.json")
147-
err := ioutil.WriteFile(path, []byte(p.Login.Config), 0600)
149+
err := os.WriteFile(path, []byte(p.Login.Config), 0600)
148150
if err != nil {
149151
return fmt.Errorf("Error writing config.json: %s", err)
150152
}
@@ -179,6 +181,15 @@ func (p Plugin) Exec() error {
179181
cmds = append(cmds, commandPull(img))
180182
}
181183

184+
// setup for using ssh agent (https://docs.docker.com/develop/develop-images/build_enhancements/#using-ssh-to-access-private-data-in-builds)
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+
}
191+
}
192+
182193
cmds = append(cmds, commandBuild(p.Build)) // docker build
183194

184195
for _, tag := range p.Build.Tags {
@@ -328,6 +339,9 @@ func commandBuild(build Build) *exec.Cmd {
328339
if build.Platform != "" {
329340
args = append(args, "--platform", build.Platform)
330341
}
342+
if build.SSHKeyPath != "" {
343+
args = append(args, "--ssh", build.SSHKeyPath)
344+
}
331345

332346
if build.AutoLabel {
333347
labelSchema := []string{
@@ -353,8 +367,8 @@ func commandBuild(build Build) *exec.Cmd {
353367
}
354368
}
355369

356-
// we need to enable buildkit, for secret support
357-
if build.Secret != "" || len(build.SecretEnvs) > 0 || len(build.SecretFiles) > 0 {
370+
// we need to enable buildkit, for secret support and ssh agent support
371+
if build.Secret != "" || len(build.SecretEnvs) > 0 || len(build.SecretFiles) > 0 || build.SSHAgentKey != "" {
358372
os.Setenv("DOCKER_BUILDKIT", "1")
359373
}
360374
return exec.Command(dockerExe, args...)
@@ -507,6 +521,23 @@ func commandRmi(tag string) *exec.Cmd {
507521
return exec.Command(dockerExe, "rmi", tag)
508522
}
509523

524+
func writeSSHPrivateKey(key string) (path string, err error) {
525+
home, err := os.UserHomeDir()
526+
if err != nil {
527+
return "", fmt.Errorf("unable to determine home directory: %s", err)
528+
}
529+
if err := os.MkdirAll(filepath.Join(home, ".ssh"), 0700); err != nil {
530+
return "", fmt.Errorf("unable to create .ssh directory: %s", err)
531+
}
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)
535+
}
536+
path = fmt.Sprintf("default=%s", pathToKey)
537+
538+
return path, nil
539+
}
540+
510541
// trace writes each command to stdout with the command wrapped in an xml
511542
// tag so that it can be extracted and displayed in the logs.
512543
func trace(cmd *exec.Cmd) {

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)