Merge pull request #1112 from samalba/windows-input-stream
Add support for Windows named pipe as Input stream
This commit is contained in:
commit
8ffee8922e
3
Makefile
3
Makefile
@ -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 ./...
|
||||||
|
@ -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)
|
||||||
|
@ -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",
|
||||||
|
1
go.mod
1
go.mod
@ -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
2
go.sum
@ -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=
|
||||||
|
@ -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"
|
||||||
@ -15,6 +13,7 @@ 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)
|
||||||
}
|
}
|
||||||
|
20
solver/socketprovider_unix.go
Normal file
20
solver/socketprovider_unix.go
Normal 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)
|
||||||
|
}
|
14
solver/socketprovider_windows.go
Normal file
14
solver/socketprovider_windows.go
Normal 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)
|
||||||
|
}
|
@ -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))
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
Reference in New Issue
Block a user