mirror of
https://github.com/containers/podman.git
synced 2025-06-24 11:28:24 +08:00
Merge pull request #13908 from n1hility/win-mounts
Implement Windows volume/mount support
This commit is contained in:
@ -347,7 +347,7 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, rtc *c
|
|||||||
cliOpts.Volume = append(cliOpts.Volume, vol)
|
cliOpts.Volume = append(cliOpts.Volume, vol)
|
||||||
// Extract the destination so we don't add duplicate mounts in
|
// Extract the destination so we don't add duplicate mounts in
|
||||||
// the volumes phase.
|
// the volumes phase.
|
||||||
splitVol := strings.SplitN(vol, ":", 3)
|
splitVol := specgen.SplitVolumeString(vol)
|
||||||
switch len(splitVol) {
|
switch len(splitVol) {
|
||||||
case 1:
|
case 1:
|
||||||
volDestinations[vol] = true
|
volDestinations[vol] = true
|
||||||
|
2
go.mod
2
go.mod
@ -12,7 +12,7 @@ require (
|
|||||||
github.com/containernetworking/cni v1.0.1
|
github.com/containernetworking/cni v1.0.1
|
||||||
github.com/containernetworking/plugins v1.1.1
|
github.com/containernetworking/plugins v1.1.1
|
||||||
github.com/containers/buildah v1.25.2-0.20220406205807-5b8e79118057
|
github.com/containers/buildah v1.25.2-0.20220406205807-5b8e79118057
|
||||||
github.com/containers/common v0.47.5-0.20220421111103-112a47964ddb
|
github.com/containers/common v0.47.5-0.20220425182415-4081e6be9356
|
||||||
github.com/containers/conmon v2.0.20+incompatible
|
github.com/containers/conmon v2.0.20+incompatible
|
||||||
github.com/containers/image/v5 v5.21.1-0.20220421124950-8527e238867c
|
github.com/containers/image/v5 v5.21.1-0.20220421124950-8527e238867c
|
||||||
github.com/containers/ocicrypt v1.1.3
|
github.com/containers/ocicrypt v1.1.3
|
||||||
|
4
go.sum
4
go.sum
@ -357,8 +357,8 @@ github.com/containernetworking/plugins v1.1.1/go.mod h1:Sr5TH/eBsGLXK/h71HeLfX19
|
|||||||
github.com/containers/buildah v1.25.2-0.20220406205807-5b8e79118057 h1:lKSxhMBpcHyyQrj2QJYzcm56uiSeibRdSL2KoppF6rg=
|
github.com/containers/buildah v1.25.2-0.20220406205807-5b8e79118057 h1:lKSxhMBpcHyyQrj2QJYzcm56uiSeibRdSL2KoppF6rg=
|
||||||
github.com/containers/buildah v1.25.2-0.20220406205807-5b8e79118057/go.mod h1:iSoopbYRb6K4b5c3hXgXNkGTI/T085t2+XiGjceud94=
|
github.com/containers/buildah v1.25.2-0.20220406205807-5b8e79118057/go.mod h1:iSoopbYRb6K4b5c3hXgXNkGTI/T085t2+XiGjceud94=
|
||||||
github.com/containers/common v0.47.5-0.20220331143923-5f14ec785c18/go.mod h1:Vr2Fn6EdzD6JNAbz8L8bTv3uWLv2p31Ih2O3EAK6Hyc=
|
github.com/containers/common v0.47.5-0.20220331143923-5f14ec785c18/go.mod h1:Vr2Fn6EdzD6JNAbz8L8bTv3uWLv2p31Ih2O3EAK6Hyc=
|
||||||
github.com/containers/common v0.47.5-0.20220421111103-112a47964ddb h1:TBrx1KcmWcesByqTb4Cq7F6bg7bDOjqCf6+6rbi8x4k=
|
github.com/containers/common v0.47.5-0.20220425182415-4081e6be9356 h1:eJ1ghvyswTLRywF4YYEWrzZyOFEzlD1FUPLzJSz+wKo=
|
||||||
github.com/containers/common v0.47.5-0.20220421111103-112a47964ddb/go.mod h1:r80nWTmJrG9EoLkuI6WfbWQDUNQVqkVuB8Oaj1VVjOA=
|
github.com/containers/common v0.47.5-0.20220425182415-4081e6be9356/go.mod h1:r80nWTmJrG9EoLkuI6WfbWQDUNQVqkVuB8Oaj1VVjOA=
|
||||||
github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg=
|
github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg=
|
||||||
github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
|
github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
|
||||||
github.com/containers/image/v5 v5.19.2-0.20220224100137-1045fb70b094/go.mod h1:XoYK6kE0dpazFNcuS+a8lra+QfbC6s8tzv+cUuCrZpE=
|
github.com/containers/image/v5 v5.19.2-0.20220224100137-1045fb70b094/go.mod h1:XoYK6kE0dpazFNcuS+a8lra+QfbC6s8tzv+cUuCrZpE=
|
||||||
|
@ -23,6 +23,7 @@ import (
|
|||||||
"github.com/containers/common/libnetwork/etchosts"
|
"github.com/containers/common/libnetwork/etchosts"
|
||||||
"github.com/containers/common/libnetwork/types"
|
"github.com/containers/common/libnetwork/types"
|
||||||
"github.com/containers/common/pkg/config"
|
"github.com/containers/common/pkg/config"
|
||||||
|
"github.com/containers/common/pkg/machine"
|
||||||
"github.com/containers/common/pkg/netns"
|
"github.com/containers/common/pkg/netns"
|
||||||
"github.com/containers/podman/v4/libpod/define"
|
"github.com/containers/podman/v4/libpod/define"
|
||||||
"github.com/containers/podman/v4/libpod/events"
|
"github.com/containers/podman/v4/libpod/events"
|
||||||
@ -62,7 +63,7 @@ const (
|
|||||||
// This is need because a HostIP of 127.0.0.1 would now allow the gvproxy forwarder to reach to open ports.
|
// This is need because a HostIP of 127.0.0.1 would now allow the gvproxy forwarder to reach to open ports.
|
||||||
// For machine the HostIP must only be used by gvproxy and never in the VM.
|
// For machine the HostIP must only be used by gvproxy and never in the VM.
|
||||||
func (c *Container) convertPortMappings() []types.PortMapping {
|
func (c *Container) convertPortMappings() []types.PortMapping {
|
||||||
if !c.runtime.config.Engine.MachineEnabled || len(c.config.PortMappings) == 0 {
|
if !machine.IsGvProxyBased() || len(c.config.PortMappings) == 0 {
|
||||||
return c.config.PortMappings
|
return c.config.PortMappings
|
||||||
}
|
}
|
||||||
// if we run in a machine VM we have to ignore the host IP part
|
// if we run in a machine VM we have to ignore the host IP part
|
||||||
|
@ -14,6 +14,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containers/common/libnetwork/types"
|
"github.com/containers/common/libnetwork/types"
|
||||||
|
"github.com/containers/common/pkg/machine"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -117,7 +118,7 @@ func annotateGvproxyResponseError(r io.Reader) error {
|
|||||||
|
|
||||||
// exposeMachinePorts exposes the ports for podman machine via gvproxy
|
// exposeMachinePorts exposes the ports for podman machine via gvproxy
|
||||||
func (r *Runtime) exposeMachinePorts(ports []types.PortMapping) error {
|
func (r *Runtime) exposeMachinePorts(ports []types.PortMapping) error {
|
||||||
if !r.config.Engine.MachineEnabled {
|
if !machine.IsGvProxyBased() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return requestMachinePorts(true, ports)
|
return requestMachinePorts(true, ports)
|
||||||
@ -125,7 +126,7 @@ func (r *Runtime) exposeMachinePorts(ports []types.PortMapping) error {
|
|||||||
|
|
||||||
// unexposeMachinePorts closes the ports for podman machine via gvproxy
|
// unexposeMachinePorts closes the ports for podman machine via gvproxy
|
||||||
func (r *Runtime) unexposeMachinePorts(ports []types.PortMapping) error {
|
func (r *Runtime) unexposeMachinePorts(ports []types.PortMapping) error {
|
||||||
if !r.config.Engine.MachineEnabled {
|
if !machine.IsGvProxyBased() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return requestMachinePorts(false, ports)
|
return requestMachinePorts(false, ports)
|
||||||
|
@ -304,6 +304,8 @@ ExecStart=/usr/bin/sleep infinity
|
|||||||
containers := `[containers]
|
containers := `[containers]
|
||||||
netns="bridge"
|
netns="bridge"
|
||||||
`
|
`
|
||||||
|
// Set deprecated machine_enabled until podman package on fcos is
|
||||||
|
// current enough to no longer require it
|
||||||
rootContainers := `[engine]
|
rootContainers := `[engine]
|
||||||
machine_enabled=true
|
machine_enabled=true
|
||||||
`
|
`
|
||||||
@ -392,7 +394,7 @@ Delegate=memory pids cpu io
|
|||||||
FileEmbedded1: FileEmbedded1{Mode: intToPtr(0644)},
|
FileEmbedded1: FileEmbedded1{Mode: intToPtr(0644)},
|
||||||
})
|
})
|
||||||
|
|
||||||
// Set machine_enabled to true to indicate we're in a VM
|
// Set deprecated machine_enabled to true to indicate we're in a VM
|
||||||
files = append(files, File{
|
files = append(files, File{
|
||||||
Node: Node{
|
Node: Node{
|
||||||
Group: getNodeGrp("root"),
|
Group: getNodeGrp("root"),
|
||||||
@ -408,6 +410,22 @@ Delegate=memory pids cpu io
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Set machine marker file to indicate podman is in a qemu based machine
|
||||||
|
files = append(files, File{
|
||||||
|
Node: Node{
|
||||||
|
Group: getNodeGrp("root"),
|
||||||
|
Path: "/etc/containers/podman-machine",
|
||||||
|
User: getNodeUsr("root"),
|
||||||
|
},
|
||||||
|
FileEmbedded1: FileEmbedded1{
|
||||||
|
Append: nil,
|
||||||
|
Contents: Resource{
|
||||||
|
Source: encodeDataURLPtr("qemu\n"),
|
||||||
|
},
|
||||||
|
Mode: intToPtr(0644),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
// Issue #11489: make sure that we can inject a custom registries.conf
|
// Issue #11489: make sure that we can inject a custom registries.conf
|
||||||
// file on the system level to force a single search registry.
|
// file on the system level to force a single search registry.
|
||||||
// The remote client does not yet support prompting for short-name
|
// The remote client does not yet support prompting for short-name
|
||||||
|
@ -448,6 +448,10 @@ func configureSystem(v *MachineVM, dist string) error {
|
|||||||
return errors.Wrap(err, "could not create containers.conf for guest OS")
|
return errors.Wrap(err, "could not create containers.conf for guest OS")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := runCmdPassThrough("wsl", "-d", dist, "sh", "-c", "echo wsl > /etc/containers/podman-machine"); err != nil {
|
||||||
|
return errors.Wrap(err, "could not create podman-machine file for guest OS")
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ func GenVolumeMounts(volumeFlag []string) (map[string]spec.Mount, map[string]*Na
|
|||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
splitVol := strings.Split(vol, ":")
|
splitVol := SplitVolumeString(vol)
|
||||||
if len(splitVol) > 3 {
|
if len(splitVol) > 3 {
|
||||||
return nil, nil, nil, errors.Wrapf(volumeFormatErr, vol)
|
return nil, nil, nil, errors.Wrapf(volumeFormatErr, vol)
|
||||||
}
|
}
|
||||||
@ -93,7 +93,7 @@ func GenVolumeMounts(volumeFlag []string) (map[string]spec.Mount, map[string]*Na
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(src, "/") || strings.HasPrefix(src, ".") {
|
if strings.HasPrefix(src, "/") || strings.HasPrefix(src, ".") || isHostWinPath(src) {
|
||||||
// This is not a named volume
|
// This is not a named volume
|
||||||
overlayFlag := false
|
overlayFlag := false
|
||||||
chownFlag := false
|
chownFlag := false
|
||||||
@ -152,3 +152,26 @@ func GenVolumeMounts(volumeFlag []string) (map[string]spec.Mount, map[string]*Na
|
|||||||
|
|
||||||
return mounts, volumes, overlayVolumes, nil
|
return mounts, volumes, overlayVolumes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Splits a volume string, accounting for Win drive paths
|
||||||
|
// when running as a WSL linux guest or Windows client
|
||||||
|
func SplitVolumeString(vol string) []string {
|
||||||
|
parts := strings.Split(vol, ":")
|
||||||
|
if !shouldResolveWinPaths() {
|
||||||
|
return parts
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip extended marker prefix if present
|
||||||
|
n := 0
|
||||||
|
if strings.HasPrefix(vol, `\\?\`) {
|
||||||
|
n = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
if hasWinDriveScheme(vol, n) {
|
||||||
|
first := parts[0] + ":" + parts[1]
|
||||||
|
parts = parts[1:]
|
||||||
|
parts[0] = first
|
||||||
|
}
|
||||||
|
|
||||||
|
return parts
|
||||||
|
}
|
||||||
|
59
pkg/specgen/winpath.go
Normal file
59
pkg/specgen/winpath.go
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
package specgen
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"unicode"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
func isHostWinPath(path string) bool {
|
||||||
|
return shouldResolveWinPaths() && strings.HasPrefix(path, `\\`) || hasWinDriveScheme(path, 0) || winPathExists(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
func hasWinDriveScheme(path string, start int) bool {
|
||||||
|
if len(path) < start+2 || path[start+1] != ':' {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
drive := rune(path[start])
|
||||||
|
return drive < unicode.MaxASCII && unicode.IsLetter(drive)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Converts a Windows path to a WSL guest path if local env is a WSL linux guest or this is a Windows client.
|
||||||
|
func ConvertWinMountPath(path string) (string, error) {
|
||||||
|
if !shouldResolveWinPaths() {
|
||||||
|
return path, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(path, "/") {
|
||||||
|
// Handle /[driveletter]/windows/path form (e.g. c:\Users\bar == /c/Users/bar)
|
||||||
|
if len(path) > 2 && path[2] == '/' && shouldResolveUnixWinVariant(path) {
|
||||||
|
drive := unicode.ToLower(rune(path[1]))
|
||||||
|
if unicode.IsLetter(drive) && drive <= unicode.MaxASCII {
|
||||||
|
return fmt.Sprintf("/mnt/%c/%s", drive, path[3:]), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// unix path - pass through
|
||||||
|
return path, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert remote win client relative paths to absolute
|
||||||
|
path = resolveRelativeOnWindows(path)
|
||||||
|
|
||||||
|
// Strip extended marker prefix if present
|
||||||
|
path = strings.TrimPrefix(path, `\\?\`)
|
||||||
|
|
||||||
|
// Drive installed via wsl --mount
|
||||||
|
if strings.HasPrefix(path, `\\.\`) {
|
||||||
|
path = "/mnt/wsl/" + path[4:]
|
||||||
|
} else if len(path) > 1 && path[1] == ':' {
|
||||||
|
path = "/mnt/" + strings.ToLower(path[0:1]) + path[2:]
|
||||||
|
} else {
|
||||||
|
return path, errors.New("unsupported UNC path")
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.ReplaceAll(path, `\`, "/"), nil
|
||||||
|
}
|
24
pkg/specgen/winpath_linux.go
Normal file
24
pkg/specgen/winpath_linux.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package specgen
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/containers/common/pkg/machine"
|
||||||
|
)
|
||||||
|
|
||||||
|
func shouldResolveWinPaths() bool {
|
||||||
|
return machine.MachineHostType() == "wsl"
|
||||||
|
}
|
||||||
|
|
||||||
|
func shouldResolveUnixWinVariant(path string) bool {
|
||||||
|
_, err := os.Stat(path)
|
||||||
|
return err != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resolveRelativeOnWindows(path string) string {
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
|
||||||
|
func winPathExists(path string) bool {
|
||||||
|
return false
|
||||||
|
}
|
20
pkg/specgen/winpath_unsupported.go
Normal file
20
pkg/specgen/winpath_unsupported.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
//go:build !linux && !windows
|
||||||
|
// +build !linux,!windows
|
||||||
|
|
||||||
|
package specgen
|
||||||
|
|
||||||
|
func shouldResolveWinPaths() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func shouldResolveUnixWinVariant(path string) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func resolveRelativeOnWindows(path string) string {
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
|
||||||
|
func winPathExists(path string) bool {
|
||||||
|
return false
|
||||||
|
}
|
30
pkg/specgen/winpath_windows.go
Normal file
30
pkg/specgen/winpath_windows.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package specgen
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
func shouldResolveUnixWinVariant(path string) bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func shouldResolveWinPaths() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func resolveRelativeOnWindows(path string) string {
|
||||||
|
ret, err := filepath.Abs(path)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Debugf("problem resolving possible relative path %q: %s", path, err.Error())
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func winPathExists(path string) bool {
|
||||||
|
_, err := os.Stat(path)
|
||||||
|
return err == nil
|
||||||
|
}
|
77
pkg/specgenutil/specgenutil_test.go
Normal file
77
pkg/specgenutil/specgenutil_test.go
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
//go:build linux
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package specgenutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/containers/common/pkg/machine"
|
||||||
|
"github.com/containers/podman/v4/pkg/domain/entities"
|
||||||
|
"github.com/containers/podman/v4/pkg/specgen"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestWinPath(t *testing.T) {
|
||||||
|
const (
|
||||||
|
fail = false
|
||||||
|
pass = true
|
||||||
|
)
|
||||||
|
tests := []struct {
|
||||||
|
vol string
|
||||||
|
source string
|
||||||
|
dest string
|
||||||
|
isN bool
|
||||||
|
outcome bool
|
||||||
|
mach string
|
||||||
|
}{
|
||||||
|
{`C:\Foo:/blah`, "/mnt/c/Foo", "/blah", false, pass, "wsl"},
|
||||||
|
{`C:\Foo:/blah`, "/mnt/c/Foo", "/blah", false, fail, ""},
|
||||||
|
{`\\?\C:\Foo:/blah`, "/mnt/c/Foo", "/blah", false, pass, "wsl"},
|
||||||
|
{`/c/bar:/blah`, "/mnt/c/bar", "/blah", false, pass, "wsl"},
|
||||||
|
{`/c/bar:/blah`, "/c/bar", "/blah", false, pass, ""},
|
||||||
|
{`/test/this:/blah`, "/test/this", "/blah", false, pass, "wsl"},
|
||||||
|
{`c:/bar/something:/other`, "/mnt/c/bar/something", "/other", false, pass, "wsl"},
|
||||||
|
{`c:/foo:ro`, "c", "/foo", true, pass, ""},
|
||||||
|
{`\\computer\loc:/dest`, "", "", false, fail, "wsl"},
|
||||||
|
{`\\.\drive\loc:/target`, "/mnt/wsl/drive/loc", "/target", false, pass, "wsl"},
|
||||||
|
}
|
||||||
|
|
||||||
|
f := func(vol string, mach string) (*specgen.SpecGenerator, error) {
|
||||||
|
machine := machine.GetMachineMarker()
|
||||||
|
oldEnable, oldType := machine.Enabled, machine.Type
|
||||||
|
machine.Enabled, machine.Type = len(mach) > 0, mach
|
||||||
|
sg := specgen.NewSpecGenerator("nothing", false)
|
||||||
|
err := FillOutSpecGen(sg, &entities.ContainerCreateOptions{
|
||||||
|
ImageVolume: "ignore",
|
||||||
|
Volume: []string{vol}}, []string{},
|
||||||
|
)
|
||||||
|
machine.Enabled, machine.Type = oldEnable, oldType
|
||||||
|
return sg, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
msg := "Checking: " + test.vol
|
||||||
|
sg, err := f(test.vol, test.mach)
|
||||||
|
if test.outcome == fail {
|
||||||
|
assert.NotNil(t, err, msg)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !assert.Nil(t, err, msg) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if test.isN {
|
||||||
|
if !assert.Equal(t, 1, len(sg.Volumes), msg) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
assert.Equal(t, test.source, sg.Volumes[0].Name, msg)
|
||||||
|
assert.Equal(t, test.dest, sg.Volumes[0].Dest, msg)
|
||||||
|
} else {
|
||||||
|
if !assert.Equal(t, 1, len(sg.Mounts), msg) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
assert.Equal(t, test.source, sg.Mounts[0].Source, msg)
|
||||||
|
assert.Equal(t, test.dest, sg.Mounts[0].Destination, msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,7 @@ package specgenutil
|
|||||||
import (
|
import (
|
||||||
"encoding/csv"
|
"encoding/csv"
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/containers/common/pkg/parse"
|
"github.com/containers/common/pkg/parse"
|
||||||
@ -123,7 +123,7 @@ func parseVolumes(volumeFlag, mountFlag, tmpfsFlag []string, addReadOnlyTmpfs bo
|
|||||||
finalMounts := make([]spec.Mount, 0, len(unifiedMounts))
|
finalMounts := make([]spec.Mount, 0, len(unifiedMounts))
|
||||||
for _, mount := range unifiedMounts {
|
for _, mount := range unifiedMounts {
|
||||||
if mount.Type == define.TypeBind {
|
if mount.Type == define.TypeBind {
|
||||||
absSrc, err := filepath.Abs(mount.Source)
|
absSrc, err := specgen.ConvertWinMountPath(mount.Source)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, nil, errors.Wrapf(err, "error getting absolute path of %s", mount.Source)
|
return nil, nil, nil, nil, errors.Wrapf(err, "error getting absolute path of %s", mount.Source)
|
||||||
}
|
}
|
||||||
@ -334,7 +334,7 @@ func getBindMount(args []string) (spec.Mount, error) {
|
|||||||
if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil {
|
if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil {
|
||||||
return newMount, err
|
return newMount, err
|
||||||
}
|
}
|
||||||
newMount.Destination = filepath.Clean(kv[1])
|
newMount.Destination = unixPathClean(kv[1])
|
||||||
setDest = true
|
setDest = true
|
||||||
case "relabel":
|
case "relabel":
|
||||||
if setRelabel {
|
if setRelabel {
|
||||||
@ -456,7 +456,7 @@ func getTmpfsMount(args []string) (spec.Mount, error) {
|
|||||||
if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil {
|
if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil {
|
||||||
return newMount, err
|
return newMount, err
|
||||||
}
|
}
|
||||||
newMount.Destination = filepath.Clean(kv[1])
|
newMount.Destination = unixPathClean(kv[1])
|
||||||
setDest = true
|
setDest = true
|
||||||
case "U", "chown":
|
case "U", "chown":
|
||||||
if setOwnership {
|
if setOwnership {
|
||||||
@ -507,7 +507,7 @@ func getDevptsMount(args []string) (spec.Mount, error) {
|
|||||||
if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil {
|
if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil {
|
||||||
return newMount, err
|
return newMount, err
|
||||||
}
|
}
|
||||||
newMount.Destination = filepath.Clean(kv[1])
|
newMount.Destination = unixPathClean(kv[1])
|
||||||
setDest = true
|
setDest = true
|
||||||
default:
|
default:
|
||||||
return newMount, errors.Wrapf(util.ErrBadMntOption, "%s", kv[0])
|
return newMount, errors.Wrapf(util.ErrBadMntOption, "%s", kv[0])
|
||||||
@ -572,7 +572,7 @@ func getNamedVolume(args []string) (*specgen.NamedVolume, error) {
|
|||||||
if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil {
|
if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
newVolume.Dest = filepath.Clean(kv[1])
|
newVolume.Dest = unixPathClean(kv[1])
|
||||||
setDest = true
|
setDest = true
|
||||||
case "U", "chown":
|
case "U", "chown":
|
||||||
if setOwnership {
|
if setOwnership {
|
||||||
@ -624,7 +624,7 @@ func getImageVolume(args []string) (*specgen.ImageVolume, error) {
|
|||||||
if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil {
|
if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
newVolume.Destination = filepath.Clean(kv[1])
|
newVolume.Destination = unixPathClean(kv[1])
|
||||||
case "rw", "readwrite":
|
case "rw", "readwrite":
|
||||||
switch kv[1] {
|
switch kv[1] {
|
||||||
case "true":
|
case "true":
|
||||||
@ -670,7 +670,7 @@ func getTmpfsMounts(tmpfsFlag []string) (map[string]spec.Mount, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mount := spec.Mount{
|
mount := spec.Mount{
|
||||||
Destination: filepath.Clean(destPath),
|
Destination: unixPathClean(destPath),
|
||||||
Type: define.TypeTmpfs,
|
Type: define.TypeTmpfs,
|
||||||
Options: options,
|
Options: options,
|
||||||
Source: define.TypeTmpfs,
|
Source: define.TypeTmpfs,
|
||||||
@ -700,3 +700,8 @@ func validChownFlag(flag string) (bool, error) {
|
|||||||
|
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use path instead of filepath to preserve Unix style paths on Windows
|
||||||
|
func unixPathClean(p string) string {
|
||||||
|
return path.Clean(p)
|
||||||
|
}
|
||||||
|
5
vendor/github.com/containers/common/libnetwork/etchosts/ip.go
generated
vendored
5
vendor/github.com/containers/common/libnetwork/etchosts/ip.go
generated
vendored
@ -6,6 +6,7 @@ import (
|
|||||||
"github.com/containers/common/libnetwork/types"
|
"github.com/containers/common/libnetwork/types"
|
||||||
"github.com/containers/common/libnetwork/util"
|
"github.com/containers/common/libnetwork/util"
|
||||||
"github.com/containers/common/pkg/config"
|
"github.com/containers/common/pkg/config"
|
||||||
|
"github.com/containers/common/pkg/machine"
|
||||||
"github.com/containers/storage/pkg/unshare"
|
"github.com/containers/storage/pkg/unshare"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -15,8 +16,8 @@ func GetHostContainersInternalIP(conf *config.Config, netStatus map[string]types
|
|||||||
switch conf.Containers.HostContainersInternalIP {
|
switch conf.Containers.HostContainersInternalIP {
|
||||||
case "":
|
case "":
|
||||||
// if empty (default) we will automatically choose one below
|
// if empty (default) we will automatically choose one below
|
||||||
// if machine we let the gvproxy dns server handle the dns name so do not add it
|
// if machine using gvproxy we let the gvproxy dns server handle the dns name so do not add it
|
||||||
if conf.Engine.MachineEnabled {
|
if machine.IsGvProxyBased() {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
case "none":
|
case "none":
|
||||||
|
2
vendor/github.com/containers/common/libnetwork/netavark/network.go
generated
vendored
2
vendor/github.com/containers/common/libnetwork/netavark/network.go
generated
vendored
@ -27,7 +27,7 @@ type netavarkNetwork struct {
|
|||||||
// networkRunDir is where temporary files are stored, i.e.the ipam db, aardvark config etc
|
// networkRunDir is where temporary files are stored, i.e.the ipam db, aardvark config etc
|
||||||
networkRunDir string
|
networkRunDir string
|
||||||
|
|
||||||
// tells netavark whether this is rootless mode or rootfull, "true" or "false"
|
// tells netavark whether this is rootless mode or rootful, "true" or "false"
|
||||||
networkRootless bool
|
networkRootless bool
|
||||||
|
|
||||||
// netavarkBinary is the path to the netavark binary.
|
// netavarkBinary is the path to the netavark binary.
|
||||||
|
3
vendor/github.com/containers/common/libnetwork/network/interface.go
generated
vendored
3
vendor/github.com/containers/common/libnetwork/network/interface.go
generated
vendored
@ -14,6 +14,7 @@ import (
|
|||||||
"github.com/containers/common/libnetwork/netavark"
|
"github.com/containers/common/libnetwork/netavark"
|
||||||
"github.com/containers/common/libnetwork/types"
|
"github.com/containers/common/libnetwork/types"
|
||||||
"github.com/containers/common/pkg/config"
|
"github.com/containers/common/pkg/config"
|
||||||
|
"github.com/containers/common/pkg/machine"
|
||||||
"github.com/containers/storage"
|
"github.com/containers/storage"
|
||||||
"github.com/containers/storage/pkg/homedir"
|
"github.com/containers/storage/pkg/homedir"
|
||||||
"github.com/containers/storage/pkg/ioutils"
|
"github.com/containers/storage/pkg/ioutils"
|
||||||
@ -173,7 +174,7 @@ func getCniInterface(conf *config.Config) (types.ContainerNetwork, error) {
|
|||||||
DefaultNetwork: conf.Network.DefaultNetwork,
|
DefaultNetwork: conf.Network.DefaultNetwork,
|
||||||
DefaultSubnet: conf.Network.DefaultSubnet,
|
DefaultSubnet: conf.Network.DefaultSubnet,
|
||||||
DefaultsubnetPools: conf.Network.DefaultSubnetPools,
|
DefaultsubnetPools: conf.Network.DefaultSubnetPools,
|
||||||
IsMachine: conf.Engine.MachineEnabled,
|
IsMachine: machine.IsGvProxyBased(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
vendor/github.com/containers/common/pkg/config/config.go
generated
vendored
2
vendor/github.com/containers/common/pkg/config/config.go
generated
vendored
@ -312,6 +312,8 @@ type EngineConfig struct {
|
|||||||
LockType string `toml:"lock_type,omitempty"`
|
LockType string `toml:"lock_type,omitempty"`
|
||||||
|
|
||||||
// MachineEnabled indicates if Podman is running in a podman-machine VM
|
// MachineEnabled indicates if Podman is running in a podman-machine VM
|
||||||
|
//
|
||||||
|
// This method is soft deprecated, use machine.IsPodmanMachine instead
|
||||||
MachineEnabled bool `toml:"machine_enabled,omitempty"`
|
MachineEnabled bool `toml:"machine_enabled,omitempty"`
|
||||||
|
|
||||||
// MultiImageArchive - if true, the container engine allows for storing
|
// MultiImageArchive - if true, the container engine allows for storing
|
||||||
|
25
vendor/github.com/containers/common/pkg/config/config_freebsd.go
generated
vendored
Normal file
25
vendor/github.com/containers/common/pkg/config/config_freebsd.go
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// podman remote clients on freebsd cannot use unshare.isRootless() to determine the configuration file locations.
|
||||||
|
func customConfigFile() (string, error) {
|
||||||
|
if path, found := os.LookupEnv("CONTAINERS_CONF"); found {
|
||||||
|
return path, nil
|
||||||
|
}
|
||||||
|
return rootlessConfigPath()
|
||||||
|
}
|
||||||
|
|
||||||
|
func ifRootlessConfigPath() (string, error) {
|
||||||
|
return rootlessConfigPath()
|
||||||
|
}
|
||||||
|
|
||||||
|
var defaultHelperBinariesDir = []string{
|
||||||
|
"/usr/local/bin",
|
||||||
|
"/usr/local/libexec/podman",
|
||||||
|
"/usr/local/lib/podman",
|
||||||
|
"/usr/local/libexec/podman",
|
||||||
|
"/usr/local/lib/podman",
|
||||||
|
}
|
10
vendor/github.com/containers/common/pkg/config/containers.conf
generated
vendored
10
vendor/github.com/containers/common/pkg/config/containers.conf
generated
vendored
@ -455,12 +455,6 @@ default_sysctls = [
|
|||||||
#
|
#
|
||||||
#lock_type** = "shm"
|
#lock_type** = "shm"
|
||||||
|
|
||||||
# Indicates if Podman is running inside a VM via Podman Machine.
|
|
||||||
# Podman uses this value to do extra setup around networking from the
|
|
||||||
# container inside the VM to to host.
|
|
||||||
#
|
|
||||||
#machine_enabled = false
|
|
||||||
|
|
||||||
# MultiImageArchive - if true, the container engine allows for storing archives
|
# MultiImageArchive - if true, the container engine allows for storing archives
|
||||||
# (e.g., of the docker-archive transport) with multiple images. By default,
|
# (e.g., of the docker-archive transport) with multiple images. By default,
|
||||||
# Podman creates single-image archives.
|
# Podman creates single-image archives.
|
||||||
@ -572,9 +566,9 @@ default_sysctls = [
|
|||||||
# URI to access the Podman service
|
# URI to access the Podman service
|
||||||
# Examples:
|
# Examples:
|
||||||
# rootless "unix://run/user/$UID/podman/podman.sock" (Default)
|
# rootless "unix://run/user/$UID/podman/podman.sock" (Default)
|
||||||
# rootfull "unix://run/podman/podman.sock (Default)
|
# rootful "unix://run/podman/podman.sock (Default)
|
||||||
# remote rootless ssh://engineering.lab.company.com/run/user/1000/podman/podman.sock
|
# remote rootless ssh://engineering.lab.company.com/run/user/1000/podman/podman.sock
|
||||||
# remote rootfull ssh://root@10.10.1.136:22/run/podman/podman.sock
|
# remote rootful ssh://root@10.10.1.136:22/run/podman/podman.sock
|
||||||
#
|
#
|
||||||
# uri = "ssh://user@production.example.com/run/user/1001/podman/podman.sock"
|
# uri = "ssh://user@production.example.com/run/user/1001/podman/podman.sock"
|
||||||
# Path to file containing ssh identity key
|
# Path to file containing ssh identity key
|
||||||
|
70
vendor/github.com/containers/common/pkg/machine/machine.go
generated
vendored
Normal file
70
vendor/github.com/containers/common/pkg/machine/machine.go
generated
vendored
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
package machine
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/containers/common/pkg/config"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MachineMarker struct {
|
||||||
|
Enabled bool
|
||||||
|
Type string
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
markerFile = "/etc/containers/podman-machine"
|
||||||
|
Wsl = "wsl"
|
||||||
|
Qemu = "qemu"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
markerSync sync.Once
|
||||||
|
machineMarker *MachineMarker
|
||||||
|
)
|
||||||
|
|
||||||
|
func loadMachineMarker(file string) {
|
||||||
|
var kind string
|
||||||
|
|
||||||
|
// Support deprecated config value for compatibility
|
||||||
|
enabled := isLegacyConfigSet()
|
||||||
|
|
||||||
|
if content, err := os.ReadFile(file); err == nil {
|
||||||
|
enabled = true
|
||||||
|
kind = strings.TrimSpace(string(content))
|
||||||
|
}
|
||||||
|
|
||||||
|
machineMarker = &MachineMarker{enabled, kind}
|
||||||
|
}
|
||||||
|
|
||||||
|
func isLegacyConfigSet() bool {
|
||||||
|
config, err := config.Default()
|
||||||
|
if err != nil {
|
||||||
|
logrus.Warnf("could not obtain container configuration")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
//nolint:staticcheck //lint:ignore SA1019 deprecated call
|
||||||
|
return config.Engine.MachineEnabled
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsPodmanMachine() bool {
|
||||||
|
return GetMachineMarker().Enabled
|
||||||
|
}
|
||||||
|
|
||||||
|
func MachineHostType() string {
|
||||||
|
return GetMachineMarker().Type
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsGvProxyBased() bool {
|
||||||
|
return IsPodmanMachine() && MachineHostType() != Wsl
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetMachineMarker() *MachineMarker {
|
||||||
|
markerSync.Do(func() {
|
||||||
|
loadMachineMarker(markerFile)
|
||||||
|
})
|
||||||
|
return machineMarker
|
||||||
|
}
|
3
vendor/modules.txt
vendored
3
vendor/modules.txt
vendored
@ -109,7 +109,7 @@ github.com/containers/buildah/pkg/rusage
|
|||||||
github.com/containers/buildah/pkg/sshagent
|
github.com/containers/buildah/pkg/sshagent
|
||||||
github.com/containers/buildah/pkg/util
|
github.com/containers/buildah/pkg/util
|
||||||
github.com/containers/buildah/util
|
github.com/containers/buildah/util
|
||||||
# github.com/containers/common v0.47.5-0.20220421111103-112a47964ddb
|
# github.com/containers/common v0.47.5-0.20220425182415-4081e6be9356
|
||||||
## explicit
|
## explicit
|
||||||
github.com/containers/common/libimage
|
github.com/containers/common/libimage
|
||||||
github.com/containers/common/libimage/manifests
|
github.com/containers/common/libimage/manifests
|
||||||
@ -132,6 +132,7 @@ github.com/containers/common/pkg/config
|
|||||||
github.com/containers/common/pkg/download
|
github.com/containers/common/pkg/download
|
||||||
github.com/containers/common/pkg/filters
|
github.com/containers/common/pkg/filters
|
||||||
github.com/containers/common/pkg/flag
|
github.com/containers/common/pkg/flag
|
||||||
|
github.com/containers/common/pkg/machine
|
||||||
github.com/containers/common/pkg/manifests
|
github.com/containers/common/pkg/manifests
|
||||||
github.com/containers/common/pkg/netns
|
github.com/containers/common/pkg/netns
|
||||||
github.com/containers/common/pkg/parse
|
github.com/containers/common/pkg/parse
|
||||||
|
Reference in New Issue
Block a user