mirror of
https://github.com/containers/podman.git
synced 2025-11-30 01:58:46 +08:00
Implement publishing API UNIX socket on Windows platforms
gvproxy and win-sshproxy have capabilities to serve this type of enpoint. This change only adds one additional API enpoint publishing by appending proxy command lines. Signed-off-by: Arthur Sengileyev <arthur.sengileyev@gmail.com>
This commit is contained in:
96
pkg/machine/e2e/api_test.go
Normal file
96
pkg/machine/e2e/api_test.go
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
package e2e_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
|
"github.com/containers/podman/v5/pkg/machine"
|
||||||
|
"github.com/docker/docker/client"
|
||||||
|
jsoniter "github.com/json-iterator/go"
|
||||||
|
. "github.com/onsi/ginkgo/v2"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
. "github.com/onsi/gomega/gexec"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
NamedPipeProto = "npipe://"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("run podman API test calls", func() {
|
||||||
|
|
||||||
|
It("client connect to machine socket", func() {
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
Skip("Go docker client doesn't support unix socket on Windows")
|
||||||
|
}
|
||||||
|
name := randomString()
|
||||||
|
i := new(initMachine)
|
||||||
|
session, err := mb.setName(name).setCmd(i.withImage(mb.imagePath).withNow()).run()
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(session).To(Exit(0))
|
||||||
|
|
||||||
|
inspectJSON := new(inspectMachine)
|
||||||
|
inspectSession, err := mb.setName(name).setCmd(inspectJSON).run()
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(inspectSession).To(Exit(0))
|
||||||
|
|
||||||
|
var inspectInfo []machine.InspectInfo
|
||||||
|
err = jsoniter.Unmarshal(inspectSession.Bytes(), &inspectInfo)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
sockPath := inspectInfo[0].ConnectionInfo.PodmanSocket.GetPath()
|
||||||
|
|
||||||
|
cli, err := client.NewClientWithOpts(client.WithHost("unix://" + sockPath))
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
_, err = cli.Ping(context.Background())
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("client connect to machine named pipe", func() {
|
||||||
|
if runtime.GOOS != "windows" {
|
||||||
|
Skip("test is only supported on Windows")
|
||||||
|
}
|
||||||
|
name := randomString()
|
||||||
|
i := new(initMachine)
|
||||||
|
session, err := mb.setName(name).setCmd(i.withImage(mb.imagePath).withNow()).run()
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(session).To(Exit(0))
|
||||||
|
|
||||||
|
inspectJSON := new(inspectMachine)
|
||||||
|
inspectSession, err := mb.setName(name).setCmd(inspectJSON).run()
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(inspectSession).To(Exit(0))
|
||||||
|
|
||||||
|
var inspectInfo []machine.InspectInfo
|
||||||
|
err = jsoniter.Unmarshal(inspectSession.Bytes(), &inspectInfo)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
pipePath := inspectInfo[0].ConnectionInfo.PodmanPipe.GetPath()
|
||||||
|
|
||||||
|
cli, err := client.NewClientWithOpts(client.WithHost(NamedPipeProto + filepath.ToSlash(pipePath)))
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
_, err = cli.Ping(context.Background())
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("curl connect to machine socket", func() {
|
||||||
|
name := randomString()
|
||||||
|
i := new(initMachine)
|
||||||
|
session, err := mb.setName(name).setCmd(i.withImage(mb.imagePath).withNow()).run()
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(session).To(Exit(0))
|
||||||
|
|
||||||
|
inspectJSON := new(inspectMachine)
|
||||||
|
inspectSession, err := mb.setName(name).setCmd(inspectJSON).run()
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(inspectSession).To(Exit(0))
|
||||||
|
|
||||||
|
var inspectInfo []machine.InspectInfo
|
||||||
|
err = jsoniter.Unmarshal(inspectSession.Bytes(), &inspectInfo)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
sockPath := inspectInfo[0].ConnectionInfo.PodmanSocket.GetPath()
|
||||||
|
|
||||||
|
cmd := exec.Command("curl", "--unix-socket", sockPath, "http://d/v5.0.0/libpod/info")
|
||||||
|
err = cmd.Run()
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -80,9 +80,6 @@ var _ = Describe("podman inspect stop", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("inspect shows a unique socket name per machine", func() {
|
It("inspect shows a unique socket name per machine", func() {
|
||||||
skipIfVmtype(define.WSLVirt, "test is only relevant for Unix based providers")
|
|
||||||
skipIfVmtype(define.HyperVVirt, "test is only relevant for Unix based machines")
|
|
||||||
|
|
||||||
var socks []string
|
var socks []string
|
||||||
for c := 0; c < 2; c++ {
|
for c := 0; c < 2; c++ {
|
||||||
name := randomString()
|
name := randomString()
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import (
|
|||||||
winio "github.com/Microsoft/go-winio"
|
winio "github.com/Microsoft/go-winio"
|
||||||
"github.com/containers/podman/v5/pkg/machine/define"
|
"github.com/containers/podman/v5/pkg/machine/define"
|
||||||
"github.com/containers/podman/v5/pkg/machine/env"
|
"github.com/containers/podman/v5/pkg/machine/env"
|
||||||
|
"github.com/containers/podman/v5/pkg/machine/sockets"
|
||||||
"github.com/containers/storage/pkg/fileutils"
|
"github.com/containers/storage/pkg/fileutils"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
@@ -45,6 +46,7 @@ type WinProxyOpts struct {
|
|||||||
RemoteUsername string
|
RemoteUsername string
|
||||||
Rootful bool
|
Rootful bool
|
||||||
VMType define.VMType
|
VMType define.VMType
|
||||||
|
Socket *define.VMFile
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetProcessState(pid int) (active bool, exitCode int) {
|
func GetProcessState(pid int) (active bool, exitCode int) {
|
||||||
@@ -160,6 +162,12 @@ func launchWinProxy(opts WinProxyOpts) (bool, string, error) {
|
|||||||
waitPipe = GlobalNamedPipe
|
waitPipe = GlobalNamedPipe
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hostURL, err := sockets.ToUnixURL(opts.Socket)
|
||||||
|
if err != nil {
|
||||||
|
return false, "", err
|
||||||
|
}
|
||||||
|
args = append(args, hostURL.String(), dest, opts.IdentityPath)
|
||||||
|
|
||||||
cmd := exec.Command(command, args...)
|
cmd := exec.Command(command, args...)
|
||||||
logrus.Debugf("winssh command: %s %v", command, args)
|
logrus.Debugf("winssh command: %s %v", command, args)
|
||||||
if err := cmd.Start(); err != nil {
|
if err := cmd.Start(); err != nil {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"github.com/containers/podman/v5/pkg/machine"
|
"github.com/containers/podman/v5/pkg/machine"
|
||||||
"github.com/containers/podman/v5/pkg/machine/define"
|
"github.com/containers/podman/v5/pkg/machine/define"
|
||||||
"github.com/containers/podman/v5/pkg/machine/env"
|
"github.com/containers/podman/v5/pkg/machine/env"
|
||||||
|
sc "github.com/containers/podman/v5/pkg/machine/sockets"
|
||||||
"github.com/containers/podman/v5/pkg/machine/vmconfigs"
|
"github.com/containers/podman/v5/pkg/machine/vmconfigs"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -22,5 +23,16 @@ func setupMachineSockets(mc *vmconfigs.MachineConfig, dirs *define.MachineDirs)
|
|||||||
state = machine.DockerGlobal
|
state = machine.DockerGlobal
|
||||||
}
|
}
|
||||||
|
|
||||||
return sockets, sockets[len(sockets)-1], state, nil
|
hostSocket, err := mc.APISocket()
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
hostURL, err := sc.ToUnixURL(hostSocket)
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", 0, err
|
||||||
|
}
|
||||||
|
sockets = append(sockets, hostURL.String())
|
||||||
|
|
||||||
|
return sockets, sockets[len(sockets)-2], state, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import (
|
|||||||
"github.com/containers/podman/v5/pkg/errorhandling"
|
"github.com/containers/podman/v5/pkg/errorhandling"
|
||||||
"github.com/containers/podman/v5/pkg/machine/connection"
|
"github.com/containers/podman/v5/pkg/machine/connection"
|
||||||
"github.com/containers/podman/v5/pkg/machine/define"
|
"github.com/containers/podman/v5/pkg/machine/define"
|
||||||
"github.com/containers/podman/v5/pkg/machine/env"
|
|
||||||
"github.com/containers/podman/v5/pkg/machine/lock"
|
"github.com/containers/podman/v5/pkg/machine/lock"
|
||||||
"github.com/containers/podman/v5/pkg/machine/ports"
|
"github.com/containers/podman/v5/pkg/machine/ports"
|
||||||
"github.com/containers/storage/pkg/fileutils"
|
"github.com/containers/storage/pkg/fileutils"
|
||||||
@@ -331,19 +330,8 @@ func (mc *MachineConfig) IsFirstBoot() (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (mc *MachineConfig) ConnectionInfo(vmtype define.VMType) (*define.VMFile, *define.VMFile, error) {
|
func (mc *MachineConfig) ConnectionInfo(vmtype define.VMType) (*define.VMFile, *define.VMFile, error) {
|
||||||
var (
|
|
||||||
socket *define.VMFile
|
|
||||||
pipe *define.VMFile
|
|
||||||
)
|
|
||||||
|
|
||||||
if vmtype == define.HyperVVirt || vmtype == define.WSLVirt {
|
|
||||||
pipeName := env.WithPodmanPrefix(mc.Name)
|
|
||||||
pipe = &define.VMFile{Path: `\\.\pipe\` + pipeName}
|
|
||||||
return nil, pipe, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
socket, err := mc.APISocket()
|
socket, err := mc.APISocket()
|
||||||
return socket, nil, err
|
return socket, getPipe(mc.Name), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadMachineByName returns a machine config based on the vm name and provider
|
// LoadMachineByName returns a machine config based on the vm name and provider
|
||||||
|
|||||||
11
pkg/machine/vmconfigs/machine_unix.go
Normal file
11
pkg/machine/vmconfigs/machine_unix.go
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd
|
||||||
|
|
||||||
|
package vmconfigs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/containers/podman/v5/pkg/machine/define"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getPipe(name string) *define.VMFile {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
11
pkg/machine/vmconfigs/machine_windows.go
Normal file
11
pkg/machine/vmconfigs/machine_windows.go
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package vmconfigs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/containers/podman/v5/pkg/machine/define"
|
||||||
|
"github.com/containers/podman/v5/pkg/machine/env"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getPipe(name string) *define.VMFile {
|
||||||
|
pipeName := env.WithPodmanPrefix(name)
|
||||||
|
return &define.VMFile{Path: `\\.\pipe\` + pipeName}
|
||||||
|
}
|
||||||
@@ -191,6 +191,10 @@ func (w WSLStubber) RequireExclusiveActive() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w WSLStubber) PostStartNetworking(mc *vmconfigs.MachineConfig, noInfo bool) error {
|
func (w WSLStubber) PostStartNetworking(mc *vmconfigs.MachineConfig, noInfo bool) error {
|
||||||
|
socket, err := mc.APISocket()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
winProxyOpts := machine.WinProxyOpts{
|
winProxyOpts := machine.WinProxyOpts{
|
||||||
Name: mc.Name,
|
Name: mc.Name,
|
||||||
IdentityPath: mc.SSH.IdentityPath,
|
IdentityPath: mc.SSH.IdentityPath,
|
||||||
@@ -198,6 +202,7 @@ func (w WSLStubber) PostStartNetworking(mc *vmconfigs.MachineConfig, noInfo bool
|
|||||||
RemoteUsername: mc.SSH.RemoteUsername,
|
RemoteUsername: mc.SSH.RemoteUsername,
|
||||||
Rootful: mc.HostUser.Rootful,
|
Rootful: mc.HostUser.Rootful,
|
||||||
VMType: w.VMType(),
|
VMType: w.VMType(),
|
||||||
|
Socket: socket,
|
||||||
}
|
}
|
||||||
machine.LaunchWinProxy(winProxyOpts, noInfo)
|
machine.LaunchWinProxy(winProxyOpts, noInfo)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user