added support for stream type npipe (Windows named pipe)

Signed-off-by: Sam Alba <samalba@users.noreply.github.com>
This commit is contained in:
Sam Alba 2021-11-08 17:16:38 -08:00
parent 72935fbc06
commit e6de59a340
4 changed files with 68 additions and 26 deletions

View File

@ -574,11 +574,9 @@ func (p *Pipeline) mount(ctx context.Context, dest string, mnt *compiler.Value)
return nil, fmt.Errorf("invalid stream %q: not a stream", stream.Path().String()) return nil, fmt.Errorf("invalid stream %q: not a stream", stream.Path().String())
} }
// Unix socket
unixValue := stream.Lookup("unix") unixValue := stream.Lookup("unix")
if !unixValue.Exists() { if unixValue.Exists() {
return nil, fmt.Errorf("invalid stream %q: not a unix socket", stream.Path().String())
}
unix, err := unixValue.String() unix, err := unixValue.String()
if err != nil { if err != nil {
return nil, fmt.Errorf("invalid unix path id: %w", err) return nil, fmt.Errorf("invalid unix path id: %w", err)
@ -590,6 +588,23 @@ func (p *Pipeline) mount(ctx context.Context, dest string, mnt *compiler.Value)
), nil ), nil
} }
// Windows named pipe
npipeValue := stream.Lookup("npipe")
if npipeValue.Exists() {
npipe, err := npipeValue.String()
if err != nil {
return nil, fmt.Errorf("invalid npipe path id: %w", err)
}
return llb.AddSSHSocket(
llb.SSHID(fmt.Sprintf("npipe=%s", npipe)),
llb.SSHSocketTarget(dest),
), nil
}
return nil, fmt.Errorf("invalid stream %q: not a valid stream", stream.Path().String())
}
// eg. mount: "/foo": { from: www.source } // eg. mount: "/foo": { from: www.source }
if !mnt.Lookup("from").Exists() { if !mnt.Lookup("from").Exists() {
return nil, fmt.Errorf("invalid mount: should have %s structure", return nil, fmt.Errorf("invalid mount: should have %s structure",

View File

@ -7,6 +7,7 @@ import (
"strings" "strings"
"time" "time"
"github.com/Microsoft/go-winio"
"github.com/moby/buildkit/session" "github.com/moby/buildkit/session"
"github.com/moby/buildkit/session/sshforward" "github.com/moby/buildkit/session/sshforward"
"google.golang.org/grpc" "google.golang.org/grpc"
@ -15,6 +16,7 @@ import (
const ( const (
unixPrefix = "unix=" unixPrefix = "unix="
npipePrefix = "npipe="
) )
type SocketProvider struct { type SocketProvider struct {
@ -33,12 +35,26 @@ func (sp *SocketProvider) CheckAgent(ctx context.Context, req *sshforward.CheckA
if req.ID != "" { if req.ID != "" {
id = req.ID id = req.ID
} }
if !strings.HasPrefix(id, unixPrefix) { if !strings.HasPrefix(id, unixPrefix) && !strings.HasPrefix(id, npipePrefix) {
return &sshforward.CheckAgentResponse{}, fmt.Errorf("invalid socket forward key %s", id) return &sshforward.CheckAgentResponse{}, fmt.Errorf("invalid socket forward key %s", id)
} }
return &sshforward.CheckAgentResponse{}, nil return &sshforward.CheckAgentResponse{}, nil
} }
func dialStream(id string) (net.Conn, error) {
switch {
case strings.HasPrefix(id, unixPrefix):
id = strings.TrimPrefix(id, unixPrefix)
return net.DialTimeout("unix", id, time.Second)
case strings.HasPrefix(id, npipePrefix):
id = strings.TrimPrefix(id, npipePrefix)
dur := time.Second
return winio.DialPipe(id, &dur)
default:
return nil, fmt.Errorf("invalid socket forward key %s", id)
}
}
func (sp *SocketProvider) ForwardAgent(stream sshforward.SSH_ForwardAgentServer) error { func (sp *SocketProvider) ForwardAgent(stream sshforward.SSH_ForwardAgentServer) error {
id := sshforward.DefaultID id := sshforward.DefaultID
@ -48,13 +64,7 @@ func (sp *SocketProvider) ForwardAgent(stream sshforward.SSH_ForwardAgentServer)
id = v[0] id = v[0]
} }
if !strings.HasPrefix(id, unixPrefix) { conn, err := dialStream(id)
return fmt.Errorf("invalid socket forward key %s", id)
}
id = strings.TrimPrefix(id, unixPrefix)
conn, err := net.DialTimeout("unix", id, time.Second)
if err != nil { if err != nil {
return fmt.Errorf("failed to connect to %s: %w", id, err) return fmt.Errorf("failed to connect to %s: %w", id, err)
} }

View File

@ -280,7 +280,7 @@ func FileInput(data string) Input {
} }
type fileInput struct { type fileInput struct {
Path string `json:"data,omitempty"` Path string `yaml:"path,omitempty"`
} }
func (i fileInput) Compile(_ string, _ *State) (*compiler.Value, error) { func (i fileInput) Compile(_ string, _ *State) (*compiler.Value, error) {
@ -296,20 +296,31 @@ func (i fileInput) Compile(_ string, _ *State) (*compiler.Value, error) {
} }
// A socket input value // A socket input value
func SocketInput(data string) Input { func SocketInput(data, socketType string) Input {
i := socketInput{ i := socketInput{}
Unix: data,
switch socketType {
case "npipe":
i.Npipe = data
case "unix":
i.Unix = data
} }
return Input{ return Input{
Socket: &i, Socket: &i,
} }
} }
type socketInput struct { type socketInput struct {
Unix string `json:"unix,omitempty"` Unix string `json:"unix,omitempty" yaml:"unix,omitempty"`
Npipe string `json:"npipe,omitempty" yaml:"npipe,omitempty"`
} }
func (i socketInput) Compile(_ string, _ *State) (*compiler.Value, error) { func (i socketInput) Compile(_ string, _ *State) (*compiler.Value, error) {
socketValue := fmt.Sprintf(`{unix: %q}`, i.Unix) socketValue, err := json.Marshal(i)
return compiler.Compile("", socketValue) if err != nil {
return nil, err
}
return compiler.Compile("", string(socketValue))
} }

View File

@ -18,7 +18,13 @@ import (
#Stream: { #Stream: {
@dagger(stream) @dagger(stream)
{
// Unix Socket
unix: string unix: string
} | {
// Windows Named Pipe
npipe: string
}
} }
// Secret value // Secret value