Skip to content

Commit 84d8664

Browse files
bkk-bcdTP Honey
authored andcommitted
support agent forwarding
missed error check add debugging fix empty val for SSHAgent fix flag type remove [] debug base64 encode ssh key fix remove debug output code cleanup Update docker.go
1 parent 4d92e81 commit 84d8664

1 file changed

Lines changed: 53 additions & 4 deletions

File tree

docker.go

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package docker
22

33
import (
4+
"encoding/base64"
45
"fmt"
56
"io/ioutil"
7+
"log"
68
"os"
79
"os/exec"
810
"path/filepath"
@@ -11,6 +13,11 @@ import (
1113
"time"
1214
)
1315

16+
const (
17+
SSHAgentSockPath = "/tmp/drone-ssh-agent-sock"
18+
SSHPrivateKeyFromEnv = "SSH_KEY"
19+
)
20+
1421
type (
1522
// Daemon defines Docker daemon parameters.
1623
Daemon struct {
@@ -107,6 +114,7 @@ type (
107114

108115
// Exec executes the plugin step
109116
func (p Plugin) Exec() error {
117+
110118
// start the Docker daemon server
111119
if !p.Daemon.Disabled {
112120
p.startDaemon()
@@ -180,6 +188,13 @@ func (p Plugin) Exec() error {
180188
cmds = append(cmds, commandPull(img))
181189
}
182190

191+
// 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)...)
196+
}
197+
183198
cmds = append(cmds, commandBuild(p.Build)) // docker build
184199

185200
for _, tag := range p.Build.Tags {
@@ -329,8 +344,8 @@ func commandBuild(build Build) *exec.Cmd {
329344
if build.Platform != "" {
330345
args = append(args, "--platform", build.Platform)
331346
}
332-
if build.SSHAgent != "" {
333-
args = append(args, "--ssh", build.SSHAgent)
347+
for _, sshagent := range build.SSHAgent {
348+
args = append(args, "--ssh", sshagent)
334349
}
335350

336351
if build.AutoLabel {
@@ -357,8 +372,8 @@ func commandBuild(build Build) *exec.Cmd {
357372
}
358373
}
359374

360-
// we need to enable buildkit, for secret support
361-
if build.Secret != "" || len(build.SecretEnvs) > 0 || len(build.SecretFiles) > 0 {
375+
// 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 {
362377
os.Setenv("DOCKER_BUILDKIT", "1")
363378
}
364379
return exec.Command(dockerExe, args...)
@@ -511,6 +526,40 @@ func commandRmi(tag string) *exec.Cmd {
511526
return exec.Command(dockerExe, "rmi", tag)
512527
}
513528

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+
}
550+
home, err := os.UserHomeDir()
551+
if err != nil {
552+
return fmt.Errorf("unable to determine home directory: %s", err)
553+
}
554+
if err := os.MkdirAll(filepath.Join(home, ".ssh"), 0700); err != nil {
555+
return fmt.Errorf("unable to create .ssh directory: %s", err)
556+
}
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)
559+
}
560+
return nil
561+
}
562+
514563
// trace writes each command to stdout with the command wrapped in an xml
515564
// tag so that it can be extracted and displayed in the logs.
516565
func trace(cmd *exec.Cmd) {

0 commit comments

Comments
 (0)