1
1
package dockerfile
2
2
3
3
import (
4
+ "bytes"
4
5
"crypto/rand"
5
6
"crypto/rsa"
6
7
"crypto/x509"
7
8
"encoding/pem"
8
9
"os"
10
+ "os/exec"
9
11
"path/filepath"
10
12
"testing"
13
+ "time"
11
14
12
15
"github.com/containerd/continuity/fs/fstest"
13
16
"github.com/moby/buildkit/client"
@@ -20,6 +23,7 @@ import (
20
23
21
24
var sshTests = integration .TestFuncs (
22
25
testSSHSocketParams ,
26
+ testSSHFileDescriptorsClosed ,
23
27
)
24
28
25
29
func init () {
@@ -73,3 +77,74 @@ RUN --mount=type=ssh,mode=741,uid=100,gid=102 [ "$(stat -c "%u %g %f" $SSH_AUTH_
73
77
}, nil )
74
78
require .NoError (t , err )
75
79
}
80
+
81
+ func testSSHFileDescriptorsClosed (t * testing.T , sb integration.Sandbox ) {
82
+ f := getFrontend (t , sb )
83
+
84
+ dockerfile := []byte (`
85
+ FROM alpine
86
+ RUN --mount=type=ssh apk update \
87
+ && apk add openssh-client-default \
88
+ && mkdir -p -m 0600 ~/.ssh \
89
+ && ssh-keyscan github.com >> ~/.ssh/known_hosts \
90
+ && for i in $(seq 1 3); do \
91
+
92
+ done; \
93
+ exit 0;
94
+ ` )
95
+
96
+ dir , err := integration .Tmpdir (
97
+ t ,
98
+ fstest .CreateFile ("Dockerfile" , dockerfile , 0600 ),
99
+ )
100
+ require .NoError (t , err )
101
+
102
+ c , err := client .New (sb .Context (), sb .Address ())
103
+ require .NoError (t , err )
104
+ defer c .Close ()
105
+
106
+ // not using t.TempDir() here because the path ends up longer than the unix socket max length
107
+ tmpDir , err := os .MkdirTemp ("" , "buildkit-ssh-test-" )
108
+ require .NoError (t , err )
109
+ t .Cleanup (func () {
110
+ os .RemoveAll (tmpDir )
111
+ })
112
+ sockPath := filepath .Join (tmpDir , "ssh-agent.sock" )
113
+
114
+ sshAgentCmd := exec .CommandContext (sb .Context (), "ssh-agent" , "-s" , "-d" , "-a" , sockPath )
115
+ sshAgentOutputBuf := & bytes.Buffer {}
116
+ sshAgentCmd .Stderr = sshAgentOutputBuf
117
+ require .NoError (t , sshAgentCmd .Start ())
118
+ var found bool
119
+ for i := 0 ; i < 100 ; i ++ {
120
+ _ , err := os .Stat (sockPath )
121
+ if err == nil {
122
+ found = true
123
+ break
124
+ }
125
+ time .Sleep (100 * time .Millisecond )
126
+ }
127
+ if ! found {
128
+ sshAgentOutput := sshAgentOutputBuf .String ()
129
+ t .Fatalf ("ssh-agent failed to start: %s" , sshAgentOutput )
130
+ }
131
+
132
+ ssh , err := sshprovider .NewSSHAgentProvider ([]sshprovider.AgentConfig {{
133
+ Paths : []string {sockPath },
134
+ }})
135
+ require .NoError (t , err )
136
+
137
+ _ , err = f .Solve (sb .Context (), c , client.SolveOpt {
138
+ LocalDirs : map [string ]string {
139
+ dockerui .DefaultLocalNameDockerfile : dir ,
140
+ dockerui .DefaultLocalNameContext : dir ,
141
+ },
142
+ Session : []session.Attachable {ssh },
143
+ }, nil )
144
+ require .NoError (t , err )
145
+
146
+ sshAgentOutput := sshAgentOutputBuf .String ()
147
+ require .Contains (t , sshAgentOutput , "process_message: socket 1" )
148
+ require .NotContains (t , sshAgentOutput , "process_message: socket 2" )
149
+ require .NotContains (t , sshAgentOutput , "process_message: socket 3" )
150
+ }
0 commit comments