Merge pull request #19375 from rhatdan/mount

Add support for mounts listed in containers.conf
This commit is contained in:
Daniel J Walsh
2023-07-27 06:29:24 -04:00
committed by GitHub
12 changed files with 188 additions and 98 deletions

4
go.mod
View File

@ -13,7 +13,7 @@ require (
github.com/containernetworking/cni v1.1.2 github.com/containernetworking/cni v1.1.2
github.com/containernetworking/plugins v1.3.0 github.com/containernetworking/plugins v1.3.0
github.com/containers/buildah v1.31.1-0.20230722114901-5ece066f82c6 github.com/containers/buildah v1.31.1-0.20230722114901-5ece066f82c6
github.com/containers/common v0.55.1-0.20230724161016-2966c705a7a3 github.com/containers/common v0.55.1-0.20230726131109-ff8298511408
github.com/containers/conmon v2.0.20+incompatible github.com/containers/conmon v2.0.20+incompatible
github.com/containers/image/v5 v5.26.1-0.20230721194716-30c87d4a5b8d github.com/containers/image/v5 v5.26.1-0.20230721194716-30c87d4a5b8d
github.com/containers/libhvee v0.4.0 github.com/containers/libhvee v0.4.0
@ -44,7 +44,7 @@ require (
github.com/moby/term v0.5.0 github.com/moby/term v0.5.0
github.com/nxadm/tail v1.4.8 github.com/nxadm/tail v1.4.8
github.com/onsi/ginkgo/v2 v2.11.0 github.com/onsi/ginkgo/v2 v2.11.0
github.com/onsi/gomega v1.27.9 github.com/onsi/gomega v1.27.10
github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.1.0-rc4 github.com/opencontainers/image-spec v1.1.0-rc4
github.com/opencontainers/runc v1.1.8 github.com/opencontainers/runc v1.1.8

8
go.sum
View File

@ -247,8 +247,8 @@ github.com/containernetworking/plugins v1.3.0 h1:QVNXMT6XloyMUoO2wUOqWTC1hWFV62Q
github.com/containernetworking/plugins v1.3.0/go.mod h1:Pc2wcedTQQCVuROOOaLBPPxrEXqqXBFt3cZ+/yVg6l0= github.com/containernetworking/plugins v1.3.0/go.mod h1:Pc2wcedTQQCVuROOOaLBPPxrEXqqXBFt3cZ+/yVg6l0=
github.com/containers/buildah v1.31.1-0.20230722114901-5ece066f82c6 h1:K/S8SFQsnnNTF0Ws58SrBD9L0EuClzAG8Zp08d7+6AA= github.com/containers/buildah v1.31.1-0.20230722114901-5ece066f82c6 h1:K/S8SFQsnnNTF0Ws58SrBD9L0EuClzAG8Zp08d7+6AA=
github.com/containers/buildah v1.31.1-0.20230722114901-5ece066f82c6/go.mod h1:0sptTFBBtSznLqoTh80DfvMOCNbdRsNRgVOKhBhrupA= github.com/containers/buildah v1.31.1-0.20230722114901-5ece066f82c6/go.mod h1:0sptTFBBtSznLqoTh80DfvMOCNbdRsNRgVOKhBhrupA=
github.com/containers/common v0.55.1-0.20230724161016-2966c705a7a3 h1:0fHDAdLNfOs5AuBizE7TOECDA4gCLoCgE6geR3k/H78= github.com/containers/common v0.55.1-0.20230726131109-ff8298511408 h1:l1CWncvHE9fXr1oTCbecNCM29pxozduFw3wyALlPpkQ=
github.com/containers/common v0.55.1-0.20230724161016-2966c705a7a3/go.mod h1:SUX+gHoElocPp664K79AEt+GGHwngBJLrKdwNIRW0tQ= github.com/containers/common v0.55.1-0.20230726131109-ff8298511408/go.mod h1:1JS5V5cf9DhEvSGMRfpD4YmTGeyhJ//YUee8qS+8fOw=
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.26.1-0.20230721194716-30c87d4a5b8d h1:g6DFcXXEMd1OwSVtbrUolGzmkMNyQDyc4OKHOFxbNeE= github.com/containers/image/v5 v5.26.1-0.20230721194716-30c87d4a5b8d h1:g6DFcXXEMd1OwSVtbrUolGzmkMNyQDyc4OKHOFxbNeE=
@ -799,8 +799,8 @@ github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoT
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/onsi/gomega v1.27.9 h1:qIyVWbOsvQEye2QCqLsNSeH/5L1RS9vS382erEWfT3o= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
github.com/onsi/gomega v1.27.9/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=

View File

@ -714,7 +714,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions
// Only add read-only tmpfs mounts in case that we are read-only and the // Only add read-only tmpfs mounts in case that we are read-only and the
// read-only tmpfs flag has been set. // read-only tmpfs flag has been set.
mounts, volumes, overlayVolumes, imageVolumes, err := parseVolumes(c.Volume, c.Mount, c.TmpFS) mounts, volumes, overlayVolumes, imageVolumes, err := parseVolumes(rtc, c.Volume, c.Mount, c.TmpFS)
if err != nil { if err != nil {
return err return err
} }

View File

@ -7,6 +7,7 @@ import (
"path" "path"
"strings" "strings"
"github.com/containers/common/pkg/config"
"github.com/containers/common/pkg/parse" "github.com/containers/common/pkg/parse"
"github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/specgen" "github.com/containers/podman/v4/pkg/specgen"
@ -26,9 +27,9 @@ var (
// Does not handle image volumes, init, and --volumes-from flags. // Does not handle image volumes, init, and --volumes-from flags.
// Can also add tmpfs mounts from read-only tmpfs. // Can also add tmpfs mounts from read-only tmpfs.
// TODO: handle options parsing/processing via containers/storage/pkg/mount // TODO: handle options parsing/processing via containers/storage/pkg/mount
func parseVolumes(volumeFlag, mountFlag, tmpfsFlag []string) ([]spec.Mount, []*specgen.NamedVolume, []*specgen.OverlayVolume, []*specgen.ImageVolume, error) { func parseVolumes(rtc *config.Config, volumeFlag, mountFlag, tmpfsFlag []string) ([]spec.Mount, []*specgen.NamedVolume, []*specgen.OverlayVolume, []*specgen.ImageVolume, error) {
// Get mounts from the --mounts flag. // Get mounts from the --mounts flag.
unifiedMounts, unifiedVolumes, unifiedImageVolumes, err := Mounts(mountFlag) unifiedMounts, unifiedVolumes, unifiedImageVolumes, err := Mounts(mountFlag, rtc.Mounts())
if err != nil { if err != nil {
return nil, nil, nil, nil, err return nil, nil, nil, nil, err
} }
@ -166,71 +167,100 @@ func findMountType(input string) (mountType string, tokens []string, err error)
return return
} }
// Mounts takes user-provided input from the --mount flag and creates OCI // Mounts takes user-provided input from the --mount flag as well as Mounts
// spec mounts and Libpod named volumes. // specified in containers.conf and creates OCI spec mounts and Libpod named volumes.
// podman run --mount type=bind,src=/etc/resolv.conf,target=/etc/resolv.conf ... // podman run --mount type=bind,src=/etc/resolv.conf,target=/etc/resolv.conf ...
// podman run --mount type=tmpfs,target=/dev/shm ... // podman run --mount type=tmpfs,target=/dev/shm ...
// podman run --mount type=volume,source=test-volume, ... // podman run --mount type=volume,source=test-volume, ...
func Mounts(mountFlag []string) (map[string]spec.Mount, map[string]*specgen.NamedVolume, map[string]*specgen.ImageVolume, error) { func Mounts(mountFlag []string, configMounts []string) (map[string]spec.Mount, map[string]*specgen.NamedVolume, map[string]*specgen.ImageVolume, error) {
finalMounts := make(map[string]spec.Mount) finalMounts := make(map[string]spec.Mount)
finalNamedVolumes := make(map[string]*specgen.NamedVolume) finalNamedVolumes := make(map[string]*specgen.NamedVolume)
finalImageVolumes := make(map[string]*specgen.ImageVolume) finalImageVolumes := make(map[string]*specgen.ImageVolume)
parseMounts := func(mounts []string, ignoreDup bool) error {
for _, mount := range mounts {
// TODO: Docker defaults to "volume" if no mount type is specified.
mountType, tokens, err := findMountType(mount)
if err != nil {
return err
}
switch mountType {
case define.TypeBind:
mount, err := getBindMount(tokens)
if err != nil {
return err
}
if _, ok := finalMounts[mount.Destination]; ok {
if ignoreDup {
continue
}
return fmt.Errorf("%v: %w", mount.Destination, specgen.ErrDuplicateDest)
}
finalMounts[mount.Destination] = mount
case define.TypeTmpfs:
mount, err := getTmpfsMount(tokens)
if err != nil {
return err
}
if _, ok := finalMounts[mount.Destination]; ok {
if ignoreDup {
continue
}
return fmt.Errorf("%v: %w", mount.Destination, specgen.ErrDuplicateDest)
}
finalMounts[mount.Destination] = mount
case define.TypeDevpts:
mount, err := getDevptsMount(tokens)
if err != nil {
return err
}
if _, ok := finalMounts[mount.Destination]; ok {
if ignoreDup {
continue
}
return fmt.Errorf("%v: %w", mount.Destination, specgen.ErrDuplicateDest)
}
finalMounts[mount.Destination] = mount
case "image":
volume, err := getImageVolume(tokens)
if err != nil {
return err
}
if _, ok := finalImageVolumes[volume.Destination]; ok {
if ignoreDup {
continue
}
return fmt.Errorf("%v: %w", volume.Destination, specgen.ErrDuplicateDest)
}
finalImageVolumes[volume.Destination] = volume
case "volume":
volume, err := getNamedVolume(tokens)
if err != nil {
return err
}
if _, ok := finalNamedVolumes[volume.Dest]; ok {
if ignoreDup {
continue
}
return fmt.Errorf("%v: %w", volume.Dest, specgen.ErrDuplicateDest)
}
finalNamedVolumes[volume.Dest] = volume
default:
return fmt.Errorf("invalid filesystem type %q", mountType)
}
}
return nil
}
for _, mount := range mountFlag { // Parse mounts passed in from the user
// TODO: Docker defaults to "volume" if no mount type is specified. if err := parseMounts(mountFlag, false); err != nil {
mountType, tokens, err := findMountType(mount) return nil, nil, nil, err
if err != nil { }
return nil, nil, nil, err
} // If user specified a mount flag that conflicts with a containers.conf flag, then ignore
switch mountType { // the duplicate. This means that the parseing of containers.conf configMounts, should always
case define.TypeBind: // happen second.
mount, err := getBindMount(tokens) if err := parseMounts(configMounts, true); err != nil {
if err != nil { return nil, nil, nil, fmt.Errorf("parsing containers.conf mounts: %w", err)
return nil, nil, nil, err
}
if _, ok := finalMounts[mount.Destination]; ok {
return nil, nil, nil, fmt.Errorf("%v: %w", mount.Destination, specgen.ErrDuplicateDest)
}
finalMounts[mount.Destination] = mount
case define.TypeTmpfs:
mount, err := getTmpfsMount(tokens)
if err != nil {
return nil, nil, nil, err
}
if _, ok := finalMounts[mount.Destination]; ok {
return nil, nil, nil, fmt.Errorf("%v: %w", mount.Destination, specgen.ErrDuplicateDest)
}
finalMounts[mount.Destination] = mount
case define.TypeDevpts:
mount, err := getDevptsMount(tokens)
if err != nil {
return nil, nil, nil, err
}
if _, ok := finalMounts[mount.Destination]; ok {
return nil, nil, nil, fmt.Errorf("%v: %w", mount.Destination, specgen.ErrDuplicateDest)
}
finalMounts[mount.Destination] = mount
case "image":
volume, err := getImageVolume(tokens)
if err != nil {
return nil, nil, nil, err
}
if _, ok := finalImageVolumes[volume.Destination]; ok {
return nil, nil, nil, fmt.Errorf("%v: %w", volume.Destination, specgen.ErrDuplicateDest)
}
finalImageVolumes[volume.Destination] = volume
case "volume":
volume, err := getNamedVolume(tokens)
if err != nil {
return nil, nil, nil, err
}
if _, ok := finalNamedVolumes[volume.Dest]; ok {
return nil, nil, nil, fmt.Errorf("%v: %w", volume.Dest, specgen.ErrDuplicateDest)
}
finalNamedVolumes[volume.Dest] = volume
default:
return nil, nil, nil, fmt.Errorf("invalid filesystem type %q", mountType)
}
} }
return finalMounts, finalNamedVolumes, finalImageVolumes, nil return finalMounts, finalNamedVolumes, finalImageVolumes, nil

View File

@ -173,6 +173,50 @@ load helpers
run_podman rm -t 0 -f $cid run_podman rm -t 0 -f $cid
} }
@test "podman mount containers.conf" {
skip_if_remote "remote does not support CONTAINERS_CONF*"
dest=/$(random_string 30)
tmpfile1=$PODMAN_TMPDIR/volume-test1
random1=$(random_string 30)
echo $random1 > $tmpfile1
tmpfile2=$PODMAN_TMPDIR/volume-test2
random2=$(random_string 30)
echo $random2 > $tmpfile2
bogus=$(random_string 10)
mountStr1=type=bind,src=$tmpfile1,destination=$dest,ro,Z
mountStr2=type=bind,src=$tmpfile2,destination=$dest,ro,Z
containersconf=$PODMAN_TMPDIR/containers.conf
cat >$containersconf <<EOF
[containers]
mounts=[ "$mountStr1", ]
EOF
badcontainersconf=$PODMAN_TMPDIR/badcontainers.conf
cat >$badcontainersconf <<EOF
[containers]
mounts=[ "type=$bogus,src=$tmpfile2,destination=$dest,ro", ]
EOF
run_podman 1 run $IMAGE cat $dest
is "$output" "cat: can't open '$dest': No such file or directory" "$dest does not exist"
CONTAINERS_CONF_OVERRIDE="$containersconf" run_podman run $IMAGE cat $dest
is "$output" "$random1" "file should contain $random1"
CONTAINERS_CONF_OVERRIDE="$containersconf" run_podman run --mount $mountStr2 $IMAGE cat $dest
is "$output" "$random2" "overridden file should contain $random2"
CONTAINERS_CONF_OVERRIDE="$containersconf" run_podman 125 run --mount $mountStr1 --mount $mountStr2 $IMAGE cat $dest
is "$output" "Error: $dest: duplicate mount destination" "Should through duplicate destination error for $dest"
CONTAINERS_CONF_OVERRIDE="$badcontainersconf" run_podman 125 run $IMAGE cat $dest
is "$output" "Error: parsing containers.conf mounts: invalid filesystem type \"$bogus\"" "containers.conf should fail with bad mounts entry"
run_podman rm --all --force -t 0
}
@test "podman mount external container - basic test" { @test "podman mount external container - basic test" {
# Only works with root (FIXME: does it work with rootless + vfs?) # Only works with root (FIXME: does it work with rootless + vfs?)
skip_if_rootless "mount does not work rootless" skip_if_rootless "mount does not work rootless"

View File

@ -185,6 +185,9 @@ type ContainersConfig struct {
// Containers logs default to truncated container ID as a tag. // Containers logs default to truncated container ID as a tag.
LogTag string `toml:"log_tag,omitempty"` LogTag string `toml:"log_tag,omitempty"`
// Mount to add to all containers
Mounts []string `toml:"mounts,omitempty"`
// NetNS indicates how to create a network namespace for the container // NetNS indicates how to create a network namespace for the container
NetNS string `toml:"netns,omitempty"` NetNS string `toml:"netns,omitempty"`
@ -1021,17 +1024,7 @@ func (c *NetworkConfig) Validate() error {
} }
} }
if stringsEq(c.CNIPluginDirs, DefaultCNIPluginDirs) { return nil
return nil
}
for _, pluginDir := range c.CNIPluginDirs {
if err := isDirectory(pluginDir); err == nil {
return nil
}
}
return fmt.Errorf("invalid cni_plugin_dirs: %s", strings.Join(c.CNIPluginDirs, ","))
} }
// FindConmon iterates over (*Config).ConmonPath and returns the path // FindConmon iterates over (*Config).ConmonPath and returns the path

View File

@ -196,6 +196,13 @@ default_sysctls = [
# #
#log_tag = "" #log_tag = ""
# List of mounts. Specified as
# "type=TYPE,source=<directory-on-host>,destination=<directory-in-container>,<options>", for example:
# "type=bind,source=/var/lib/foobar,destination=/var/lib/foobar,ro".
# If it is empty or commented out, no mounts will be added
#
#mounts = []
# Default way to to create a Network namespace for the container # Default way to to create a Network namespace for the container
# Options are: # Options are:
# `private` Create private Network Namespace for the container. # `private` Create private Network Namespace for the container.
@ -276,7 +283,7 @@ default_sysctls = [
# If it is empty or commented out, no volumes will be added # If it is empty or commented out, no volumes will be added
# #
#volumes = [] #volumes = []
#
#[engine.platform_to_oci_runtime] #[engine.platform_to_oci_runtime]
#"wasi/wasm" = ["crun-wasm"] #"wasi/wasm" = ["crun-wasm"]
#"wasi/wasm32" = ["crun-wasm"] #"wasi/wasm32" = ["crun-wasm"]

View File

@ -186,19 +186,18 @@ func DefaultConfig() (*Config, error) {
return &Config{ return &Config{
Containers: ContainersConfig{ Containers: ContainersConfig{
Devices: []string{},
Volumes: []string{},
Annotations: []string{}, Annotations: []string{},
ApparmorProfile: DefaultApparmorProfile, ApparmorProfile: DefaultApparmorProfile,
BaseHostsFile: "", BaseHostsFile: "",
CgroupNS: cgroupNS, CgroupNS: cgroupNS,
Cgroups: getDefaultCgroupsMode(), Cgroups: getDefaultCgroupsMode(),
DNSOptions: []string{},
DNSSearches: []string{},
DNSServers: []string{},
DefaultCapabilities: DefaultCapabilities, DefaultCapabilities: DefaultCapabilities,
DefaultSysctls: []string{}, DefaultSysctls: []string{},
DefaultUlimits: getDefaultProcessLimits(), DefaultUlimits: getDefaultProcessLimits(),
DNSServers: []string{}, Devices: []string{},
DNSOptions: []string{},
DNSSearches: []string{},
EnableKeyring: true, EnableKeyring: true,
EnableLabeling: selinuxEnabled(), EnableLabeling: selinuxEnabled(),
Env: []string{ Env: []string{
@ -207,20 +206,22 @@ func DefaultConfig() (*Config, error) {
}, },
EnvHost: false, EnvHost: false,
HTTPProxy: true, HTTPProxy: true,
IPCNS: "shareable",
Init: false, Init: false,
InitPath: "", InitPath: "",
IPCNS: "shareable",
LogDriver: defaultLogDriver(), LogDriver: defaultLogDriver(),
LogSizeMax: DefaultLogSizeMax, LogSizeMax: DefaultLogSizeMax,
Mounts: []string{},
NetNS: "private", NetNS: "private",
NoHosts: false, NoHosts: false,
PidsLimit: DefaultPidsLimit,
PidNS: "private", PidNS: "private",
PidsLimit: DefaultPidsLimit,
ShmSize: DefaultShmSize, ShmSize: DefaultShmSize,
TZ: "", TZ: "",
Umask: "0022",
UTSNS: "private", UTSNS: "private",
Umask: "0022",
UserNSSize: DefaultUserNSSize, // Deprecated UserNSSize: DefaultUserNSSize, // Deprecated
Volumes: []string{},
}, },
Network: NetworkConfig{ Network: NetworkConfig{
DefaultNetwork: "podman", DefaultNetwork: "podman",
@ -500,6 +501,11 @@ func (c *Config) Volumes() []string {
return c.Containers.Volumes return c.Containers.Volumes
} }
// Mounts returns the default set of mounts that should be mounted in containers.
func (c *Config) Mounts() []string {
return c.Containers.Mounts
}
// Devices returns the default additional devices for containers. // Devices returns the default additional devices for containers.
func (c *Config) Devices() []string { func (c *Config) Devices() []string {
return c.Containers.Devices return c.Containers.Devices

View File

@ -15,6 +15,8 @@ import (
"golang.org/x/term" "golang.org/x/term"
) )
const sshdPort = 22
func Validate(user *url.Userinfo, path string, port int, identity string) (*config.Destination, *url.URL, error) { func Validate(user *url.Userinfo, path string, port int, identity string) (*config.Destination, *url.URL, error) {
// url.Parse NEEDS ssh://, if this ever fails or returns some nonsense, that is why. // url.Parse NEEDS ssh://, if this ever fails or returns some nonsense, that is why.
uri, err := url.Parse(path) uri, err := url.Parse(path)
@ -28,11 +30,10 @@ func Validate(user *url.Userinfo, path string, port int, identity string) (*conf
} }
if uri.Port() == "" { if uri.Port() == "" {
if port != 0 { if port == 0 {
uri.Host = net.JoinHostPort(uri.Host, strconv.Itoa(port)) port = sshdPort
} else {
uri.Host = net.JoinHostPort(uri.Host, "22")
} }
uri.Host = net.JoinHostPort(uri.Host, strconv.Itoa(port))
} }
if user != nil { if user != nil {
@ -165,11 +166,15 @@ func ParseScpArgs(options ConnectionScpOptions) (string, string, string, bool, e
} }
func DialNet(sshClient *ssh.Client, mode string, url *url.URL) (net.Conn, error) { func DialNet(sshClient *ssh.Client, mode string, url *url.URL) (net.Conn, error) {
port, err := strconv.Atoi(url.Port()) port := sshdPort
if err != nil { if url.Port() != "" {
return nil, err p, err := strconv.Atoi(url.Port())
if err != nil {
return nil, err
}
port = p
} }
if _, _, err = Validate(url.User, url.Hostname(), port, ""); err != nil { if _, _, err := Validate(url.User, url.Hostname(), port, ""); err != nil {
return nil, err return nil, err
} }
return sshClient.Dial(mode, url.Path) return sshClient.Dial(mode, url.Path)

View File

@ -1,3 +1,8 @@
## 1.27.10
### Fixes
- fix: go 1.21 adding goroutine ID to creator+location (#685) [bdc7803]
## 1.27.9 ## 1.27.9
### Fixes ### Fixes

View File

@ -22,7 +22,7 @@ import (
"github.com/onsi/gomega/types" "github.com/onsi/gomega/types"
) )
const GOMEGA_VERSION = "1.27.9" const GOMEGA_VERSION = "1.27.10"
const nilGomegaPanic = `You are trying to make an assertion, but haven't registered Gomega's fail handler. const nilGomegaPanic = `You are trying to make an assertion, but haven't registered Gomega's fail handler.
If you're using Ginkgo then you probably forgot to put your assertion in an It(). If you're using Ginkgo then you probably forgot to put your assertion in an It().

4
vendor/modules.txt vendored
View File

@ -157,7 +157,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.55.1-0.20230724161016-2966c705a7a3 # github.com/containers/common v0.55.1-0.20230726131109-ff8298511408
## explicit; go 1.18 ## explicit; go 1.18
github.com/containers/common/libimage github.com/containers/common/libimage
github.com/containers/common/libimage/define github.com/containers/common/libimage/define
@ -780,7 +780,7 @@ github.com/onsi/ginkgo/v2/internal/parallel_support
github.com/onsi/ginkgo/v2/internal/testingtproxy github.com/onsi/ginkgo/v2/internal/testingtproxy
github.com/onsi/ginkgo/v2/reporters github.com/onsi/ginkgo/v2/reporters
github.com/onsi/ginkgo/v2/types github.com/onsi/ginkgo/v2/types
# github.com/onsi/gomega v1.27.9 # github.com/onsi/gomega v1.27.10
## explicit; go 1.18 ## explicit; go 1.18
github.com/onsi/gomega github.com/onsi/gomega
github.com/onsi/gomega/format github.com/onsi/gomega/format