Merge pull request #1112 from samalba/windows-input-stream

Add support for Windows named pipe as Input stream
This commit is contained in:
Andrea Luzzardi 2021-11-08 18:06:50 -08:00 committed by GitHub
commit 8ffee8922e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 122 additions and 40 deletions

View File

@ -11,6 +11,9 @@ dagger:
dagger-debug: dagger-debug:
go build -race -o ./cmd/dagger/dagger-debug -ldflags '-X go.dagger.io/dagger/version.Revision=$(GIT_REVISION)' ./cmd/dagger/ go build -race -o ./cmd/dagger/dagger-debug -ldflags '-X go.dagger.io/dagger/version.Revision=$(GIT_REVISION)' ./cmd/dagger/
.PHONY: install
go install ./cmd/dagger
.PHONY: test .PHONY: test
test: test:
go test -race -v ./... go test -race -v ./...

View File

@ -1,8 +1,11 @@
package input package input
import ( import (
"context"
"os" "os"
"runtime"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
"go.dagger.io/dagger/cmd/dagger/logger" "go.dagger.io/dagger/cmd/dagger/logger"
@ -24,26 +27,40 @@ var socketCmd = &cobra.Command{
lg := logger.New() lg := logger.New()
ctx := lg.WithContext(cmd.Context()) ctx := lg.WithContext(cmd.Context())
unix := args[1]
st, err := os.Stat(unix)
if err != nil {
lg.Fatal().Err(err).Str("path", unix).Msg("invalid unix socket")
}
if st.Mode()&os.ModeSocket == 0 {
lg.Fatal().Str("path", unix).Msg("not a unix socket")
}
updateEnvironmentInput( updateEnvironmentInput(
ctx, ctx,
cmd, cmd,
args[0], args[0],
state.SocketInput(unix), state.SocketInput(detectStreamType(ctx, args[1])),
) )
}, },
} }
func detectStreamType(ctx context.Context, path string) (string, string) {
lg := log.Ctx(ctx)
if runtime.GOOS == "windows" {
// support the unix format for convenience
if path == "/var/run/docker.sock" || path == "\\var\\run\\docker.sock" {
path = "\\\\.\\pipe\\docker_engine"
lg.Info().Str("path", path).Msg("Windows detected, override unix socket path")
}
return path, "npipe"
}
st, err := os.Stat(path)
if err != nil {
lg.Fatal().Err(err).Str("path", path).Msg("invalid unix socket")
}
if st.Mode()&os.ModeSocket == 0 {
lg.Fatal().Str("path", path).Msg("not a unix socket")
}
return path, "unix"
}
func init() { func init() {
if err := viper.BindPFlags(boolCmd.Flags()); err != nil { if err := viper.BindPFlags(boolCmd.Flags()); err != nil {
panic(err) panic(err)

View File

@ -574,20 +574,35 @@ 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()
if err != nil {
return nil, fmt.Errorf("invalid unix path id: %w", err)
}
return llb.AddSSHSocket(
llb.SSHID(fmt.Sprintf("unix=%s", unix)),
llb.SSHSocketTarget(dest),
), nil
} }
unix, err := unixValue.String() // Windows named pipe
if err != nil { npipeValue := stream.Lookup("npipe")
return nil, fmt.Errorf("invalid unix path id: %w", err) 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 llb.AddSSHSocket( return nil, fmt.Errorf("invalid stream %q: not a valid stream", stream.Path().String())
llb.SSHID(fmt.Sprintf("unix=%s", unix)),
llb.SSHSocketTarget(dest),
), nil
} }
// eg. mount: "/foo": { from: www.source } // eg. mount: "/foo": { from: www.source }

1
go.mod
View File

@ -6,6 +6,7 @@ require (
cuelang.org/go v0.4.0 cuelang.org/go v0.4.0
filippo.io/age v1.0.0 filippo.io/age v1.0.0
github.com/KromDaniel/jonson v0.0.0-20180630143114-d2f9c3c389db github.com/KromDaniel/jonson v0.0.0-20180630143114-d2f9c3c389db
github.com/Microsoft/go-winio v0.5.1 // indirect
github.com/containerd/console v1.0.3 github.com/containerd/console v1.0.3
github.com/containerd/containerd v1.5.7 github.com/containerd/containerd v1.5.7
github.com/docker/buildx v0.6.2 github.com/docker/buildx v0.6.2

2
go.sum
View File

@ -154,6 +154,8 @@ github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JP
github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/go-winio v0.4.17 h1:iT12IBVClFevaf8PuVyi3UmZOVh4OqnaLxDTW2O6j3w= github.com/Microsoft/go-winio v0.4.17 h1:iT12IBVClFevaf8PuVyi3UmZOVh4OqnaLxDTW2O6j3w=
github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY=
github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
github.com/Microsoft/hcsshim v0.8.7-0.20190325164909-8abdbb8205e4/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= github.com/Microsoft/hcsshim v0.8.7-0.20190325164909-8abdbb8205e4/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ= github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ=

View File

@ -3,9 +3,7 @@ package solver
import ( import (
"context" "context"
"fmt" "fmt"
"net"
"strings" "strings"
"time"
"github.com/moby/buildkit/session" "github.com/moby/buildkit/session"
"github.com/moby/buildkit/session/sshforward" "github.com/moby/buildkit/session/sshforward"
@ -14,7 +12,8 @@ import (
) )
const ( const (
unixPrefix = "unix=" unixPrefix = "unix="
npipePrefix = "npipe="
) )
type SocketProvider struct { type SocketProvider struct {
@ -33,7 +32,7 @@ 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
@ -48,13 +47,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

@ -0,0 +1,20 @@
//go:build !windows
// +build !windows
package solver
import (
"fmt"
"net"
"strings"
"time"
)
func dialStream(id string) (net.Conn, error) {
if !strings.HasPrefix(id, unixPrefix) {
return nil, fmt.Errorf("invalid socket forward key %s", id)
}
id = strings.TrimPrefix(id, unixPrefix)
return net.DialTimeout("unix", id, time.Second)
}

View File

@ -0,0 +1,14 @@
//go:build windows
// +build windows
package solver
func dialStream(id string) (net.Conn, error) {
if !strings.HasPrefix(id, unixPrefix) {
return nil, fmt.Errorf("invalid socket forward key %s", id)
}
id = strings.TrimPrefix(id, npipePrefix)
dur := time.Second
return winio.DialPipe(id, &dur)
}

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: string {
// Unix Socket
unix: string
} | {
// Windows Named Pipe
npipe: string
}
} }
// Secret value // Secret value