diff options
-rw-r--r-- | .cirrus.yml | 1 | ||||
-rw-r--r-- | go.mod | 2 | ||||
-rw-r--r-- | go.sum | 4 | ||||
-rw-r--r-- | libpod/container_inspect.go | 16 | ||||
-rw-r--r-- | libpod/define/container_inspect.go | 8 | ||||
-rw-r--r-- | pkg/specgenutil/specgen.go | 8 | ||||
-rw-r--r-- | podman.spec.rpkg | 45 | ||||
-rw-r--r-- | test/e2e/run_userns_test.go | 29 | ||||
-rw-r--r-- | vendor/github.com/containers/common/libnetwork/network/interface.go | 67 | ||||
-rw-r--r-- | vendor/github.com/containers/common/pkg/config/config.go | 15 | ||||
-rw-r--r-- | vendor/github.com/containers/common/pkg/config/containers.conf | 26 | ||||
-rw-r--r-- | vendor/github.com/containers/common/pkg/config/default.go | 14 | ||||
-rw-r--r-- | vendor/modules.txt | 2 |
13 files changed, 191 insertions, 46 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index c33ed9c0c..9837c2814 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -327,6 +327,7 @@ alt_build_task: osx_alt_build_task: name: "OSX Cross" alias: osx_alt_build + only_if: $CI != $CI # Temporarily disabled while infra. non-functional depends_on: - build env: @@ -12,7 +12,7 @@ require ( github.com/containernetworking/cni v1.0.1 github.com/containernetworking/plugins v1.0.1 github.com/containers/buildah v1.23.1-0.20220112160421-d744ebc4b1d5 - github.com/containers/common v0.46.1-0.20220112112017-31e8cc4aeeab + github.com/containers/common v0.46.1-0.20220117145719-da777f8b15b1 github.com/containers/conmon v2.0.20+incompatible github.com/containers/image/v5 v5.18.0 github.com/containers/ocicrypt v1.1.2 @@ -315,8 +315,8 @@ github.com/containernetworking/plugins v1.0.1/go.mod h1:QHCfGpaTwYTbbH+nZXKVTxNB github.com/containers/buildah v1.23.1-0.20220112160421-d744ebc4b1d5 h1:J4ZMQgpzjClLNuRDCIYDY2KZE1yO9A1I3A/jEaFvtaY= github.com/containers/buildah v1.23.1-0.20220112160421-d744ebc4b1d5/go.mod h1:pA9nL58rY+rtoyZkzPmkv02Nwb9ifvYlChg95gKkNAY= github.com/containers/common v0.46.1-0.20220110165509-08c2c97e5e25/go.mod h1:hXUU9gtA8V9dSLHhizp/k/s0ZXBzrnUSScUfrsw8z2Y= -github.com/containers/common v0.46.1-0.20220112112017-31e8cc4aeeab h1:Pf1kwI8sZPiPMuen619noeltwtB2cIFC1iY42fE87AY= -github.com/containers/common v0.46.1-0.20220112112017-31e8cc4aeeab/go.mod h1:hXUU9gtA8V9dSLHhizp/k/s0ZXBzrnUSScUfrsw8z2Y= +github.com/containers/common v0.46.1-0.20220117145719-da777f8b15b1 h1:TGXTygk3STL+G4F1zGgSITdIEE5i+BgsSDLOmGuUYTY= +github.com/containers/common v0.46.1-0.20220117145719-da777f8b15b1/go.mod h1:lJkY5VdkdU2BEDdbO5vgi3G69KWEgWBWXi6tNgm2BlM= 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/image/v5 v5.17.1-0.20220106205022-73f80d60f0e1/go.mod h1:daAiRXgcGIf/7eD7B2EkuHHw084/8M8Kh35rzOu56y0= diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go index 615a7522b..086d51f04 100644 --- a/libpod/container_inspect.go +++ b/libpod/container_inspect.go @@ -9,6 +9,7 @@ import ( "github.com/containers/podman/v3/libpod/define" "github.com/containers/podman/v3/libpod/driver" "github.com/containers/podman/v3/pkg/util" + "github.com/containers/storage/types" units "github.com/docker/go-units" spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/runtime-tools/generate" @@ -403,6 +404,17 @@ func (c *Container) generateInspectContainerConfig(spec *spec.Spec) *define.Insp return ctrConfig } +func generateIDMappings(idMappings types.IDMappingOptions) *define.InspectIDMappings { + var inspectMappings define.InspectIDMappings + for _, uid := range idMappings.UIDMap { + inspectMappings.UIDMap = append(inspectMappings.UIDMap, fmt.Sprintf("%d:%d:%d", uid.ContainerID, uid.HostID, uid.Size)) + } + for _, gid := range idMappings.GIDMap { + inspectMappings.GIDMap = append(inspectMappings.GIDMap, fmt.Sprintf("%d:%d:%d", gid.ContainerID, gid.HostID, gid.Size)) + } + return &inspectMappings +} + // Generate the InspectContainerHostConfig struct for the HostConfig field of // Inspect. func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, namedVolumes []*ContainerNamedVolume, mounts []spec.Mount) (*define.InspectContainerHostConfig, error) { @@ -815,7 +827,9 @@ func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, named } } hostConfig.UsernsMode = usernsMode - + if c.config.IDMappings.UIDMap != nil && c.config.IDMappings.GIDMap != nil { + hostConfig.IDMappings = generateIDMappings(c.config.IDMappings) + } // Devices // Do not include if privileged - assumed that all devices will be // included. diff --git a/libpod/define/container_inspect.go b/libpod/define/container_inspect.go index 6db1b025e..804b2b143 100644 --- a/libpod/define/container_inspect.go +++ b/libpod/define/container_inspect.go @@ -6,6 +6,11 @@ import ( "github.com/containers/image/v5/manifest" ) +type InspectIDMappings struct { + UIDMap []string `json:"UidMap"` + GIDMap []string `json:"GidMap"` +} + // InspectContainerConfig holds further data about how a container was initially // configured. type InspectContainerConfig struct { @@ -401,7 +406,10 @@ type InspectContainerHostConfig struct { // TODO Rootless has an additional 'keep-id' option, presently not // reflected here. UsernsMode string `json:"UsernsMode"` + // IDMappings is the UIDMapping and GIDMapping used within the container + IDMappings *InspectIDMappings `json:"IDMappings,omitempty"` // ShmSize is the size of the container's SHM device. + ShmSize int64 `json:"ShmSize"` // Runtime is provided purely for Docker compatibility. // It is set unconditionally to "oci" as Podman does not presently diff --git a/pkg/specgenutil/specgen.go b/pkg/specgenutil/specgen.go index 59ac19c2c..ee089695e 100644 --- a/pkg/specgenutil/specgen.go +++ b/pkg/specgenutil/specgen.go @@ -206,9 +206,13 @@ func setNamespaces(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions) return err } } - // userns must be treated differently + userns := os.Getenv("PODMAN_USERNS") if c.UserNS != "" { - s.UserNS, err = specgen.ParseUserNamespace(c.UserNS) + userns = c.UserNS + } + // userns must be treated differently + if userns != "" { + s.UserNS, err = specgen.ParseUserNamespace(userns) if err != nil { return err } diff --git a/podman.spec.rpkg b/podman.spec.rpkg index cff5eb3d9..5c203b24a 100644 --- a/podman.spec.rpkg +++ b/podman.spec.rpkg @@ -52,9 +52,52 @@ VCS: {{{ git_dir_vcs }}} # and returns its filename. The tarball will be used to build the rpm. Source: {{{ git_dir_pack }}} +%if 0%{?fedora} && ! 0%{?rhel} +BuildRequires: btrfs-progs-devel +%endif +BuildRequires: gcc +BuildRequires: golang >= 1.16.6 +BuildRequires: glib2-devel +BuildRequires: glibc-devel +BuildRequires: glibc-static +BuildRequires: git-core +BuildRequires: go-md2man +BuildRequires: go-rpm-macros +BuildRequires: gpgme-devel +BuildRequires: libassuan-devel +BuildRequires: libgpg-error-devel +BuildRequires: libseccomp-devel +BuildRequires: libselinux-devel +%if 0%{?fedora} >= 35 +BuildRequires: shadow-utils-subid-devel +%endif +BuildRequires: pkgconfig +BuildRequires: make +BuildRequires: ostree-devel +BuildRequires: systemd +BuildRequires: systemd-devel +Requires: conmon >= 2:2.0.30-2 +Requires: containers-common >= 4:1-30 +Requires: containernetworking-plugins >= 1.0.0-15.1 +Requires: iptables +Requires: nftables +Requires: netavark +Recommends: %{name}-plugins = %{epoch}:%{version}-%{release} +Recommends: catatonit +Suggests: qemu-user-static + # More detailed description of the package %description -This is a hello world package. +%{name} (Pod Manager) is a fully featured container engine that is a simple +daemonless tool. %{name} provides a Docker-CLI comparable command line that +eases the transition from other container engines and allows the management of +pods, containers and images. Simply put: alias docker=%{name}. +Most %{name} commands can be run as a regular user, without requiring +additional privileges. + +%{name} uses Buildah(1) internally to create container images. +Both tools share image (not container) storage, hence each can use or +manipulate images (but not containers) created by the other. %package docker Summary: Emulate Docker CLI using %{name} diff --git a/test/e2e/run_userns_test.go b/test/e2e/run_userns_test.go index c1645af06..e8ba42cf0 100644 --- a/test/e2e/run_userns_test.go +++ b/test/e2e/run_userns_test.go @@ -301,5 +301,34 @@ var _ = Describe("Podman UserNS support", func() { Expect(inspectGID).Should(Exit(0)) Expect(inspectGID.OutputToString()).To(Equal(tt.gid)) } + + }) + It("podman PODMAN_USERNS", func() { + SkipIfNotRootless("keep-id only works in rootless mode") + + podmanUserns, podmanUserusSet := os.LookupEnv("PODMAN_USERNS") + os.Setenv("PODMAN_USERNS", "keep-id") + defer func() { + if podmanUserusSet { + os.Setenv("PODMAN_USERNS", podmanUserns) + } else { + os.Unsetenv("PODMAN_USERNS") + } + }() + if IsRemote() { + podmanTest.RestartRemoteService() + } + + result := podmanTest.Podman([]string{"create", ALPINE, "true"}) + result.WaitWithDefaultTimeout() + Expect(result).Should(Exit(0)) + + inspect := podmanTest.Podman([]string{"inspect", "--format", "{{ .HostConfig.IDMappings }}", result.OutputToString()}) + inspect.WaitWithDefaultTimeout() + Expect(inspect.OutputToString()).To(Not(Equal("<nil>"))) + + if IsRemote() { + podmanTest.RestartRemoteService() + } }) }) diff --git a/vendor/github.com/containers/common/libnetwork/network/interface.go b/vendor/github.com/containers/common/libnetwork/network/interface.go index 190e6945b..37a910a24 100644 --- a/vendor/github.com/containers/common/libnetwork/network/interface.go +++ b/vendor/github.com/containers/common/libnetwork/network/interface.go @@ -14,11 +14,24 @@ import ( "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/config" "github.com/containers/storage" + "github.com/containers/storage/pkg/homedir" "github.com/containers/storage/pkg/ioutils" + "github.com/containers/storage/pkg/unshare" "github.com/sirupsen/logrus" ) -const defaultNetworkBackendFileName = "defaultNetworkBackend" +const ( + // defaultNetworkBackendFileName is the file name for sentinel file to store the backend + defaultNetworkBackendFileName = "defaultNetworkBackend" + // cniConfigDir is the directory where cni configuration is found + cniConfigDir = "/etc/cni/net.d/" + // cniConfigDirRootless is the directory in XDG_CONFIG_HOME for cni plugins + cniConfigDirRootless = "cni/net.d/" + // netavarkConfigDir is the config directory for the rootful network files + netavarkConfigDir = "/etc/containers/networks" + // netavarkRunDir is the run directory for the rootful temporary network files such as the ipam db + netavarkRunDir = "/run/containers/networks" +) // NetworkBackend returns the network backend name and interface // It returns either the CNI or netavark backend depending on what is set in the config. @@ -42,9 +55,24 @@ func NetworkBackend(store storage.Store, conf *config.Config, syslog bool) (type if err != nil { return "", nil, err } + + confDir := conf.Network.NetworkConfigDir + if confDir == "" { + confDir = getDefaultNetavarkConfigDir(store) + } + + // We cannot use the runroot for rootful since the network namespace is shared for all + // libpod instances they also have to share the same ipam db. + // For rootless we have our own network namespace per libpod instances, + // so this is not a problem there. + runDir := netavarkRunDir + if unshare.IsRootless() { + runDir = filepath.Join(store.RunRoot(), "networks") + } + netInt, err := netavark.NewNetworkInterface(&netavark.InitConfig{ - NetworkConfigDir: filepath.Join(store.GraphRoot(), "networks"), - NetworkRunDir: filepath.Join(store.RunRoot(), "networks"), + NetworkConfigDir: confDir, + NetworkRunDir: runDir, NetavarkBinary: netavarkBin, DefaultNetwork: conf.Network.DefaultNetwork, DefaultSubnet: conf.Network.DefaultSubnet, @@ -122,11 +150,42 @@ func defaultNetworkBackend(store storage.Store, conf *config.Config) (backend ty } func getCniInterface(conf *config.Config) (types.ContainerNetwork, error) { + confDir := conf.Network.NetworkConfigDir + if confDir == "" { + var err error + confDir, err = getDefultCNIConfigDir() + if err != nil { + return nil, err + } + } return cni.NewCNINetworkInterface(&cni.InitConfig{ - CNIConfigDir: conf.Network.NetworkConfigDir, + CNIConfigDir: confDir, CNIPluginDirs: conf.Network.CNIPluginDirs, DefaultNetwork: conf.Network.DefaultNetwork, DefaultSubnet: conf.Network.DefaultSubnet, IsMachine: conf.Engine.MachineEnabled, }) } + +func getDefultCNIConfigDir() (string, error) { + if !unshare.IsRootless() { + return cniConfigDir, nil + } + + configHome, err := homedir.GetConfigHome() + if err != nil { + return "", err + } + return filepath.Join(configHome, cniConfigDirRootless), nil +} + +// getDefaultNetavarkConfigDir return the netavark config dir. For rootful it will +// use "/etc/containers/networks" and for rootless "$graphroot/networks". We cannot +// use the graphroot for rootful since the network namespace is shared for all +// libpod instances. +func getDefaultNetavarkConfigDir(store storage.Store) string { + if !unshare.IsRootless() { + return netavarkConfigDir + } + return filepath.Join(store.GraphRoot(), "networks") +} diff --git a/vendor/github.com/containers/common/pkg/config/config.go b/vendor/github.com/containers/common/pkg/config/config.go index 7f89b9252..6837a378a 100644 --- a/vendor/github.com/containers/common/pkg/config/config.go +++ b/vendor/github.com/containers/common/pkg/config/config.go @@ -822,21 +822,6 @@ func (c *ContainersConfig) Validate() error { // execution checks. It returns an `error` on validation failure, otherwise // `nil`. func (c *NetworkConfig) Validate() error { - expectedConfigDir := _cniConfigDir - if unshare.IsRootless() { - home, err := unshare.HomeDir() - if err != nil { - return err - } - expectedConfigDir = filepath.Join(home, _cniConfigDirRootless) - } - if c.NetworkConfigDir != expectedConfigDir { - err := isDirectory(c.NetworkConfigDir) - if err != nil && !os.IsNotExist(err) { - return errors.Wrapf(err, "invalid network_config_dir: %s", c.NetworkConfigDir) - } - } - if stringsEq(c.CNIPluginDirs, DefaultCNIPluginDirs) { return nil } diff --git a/vendor/github.com/containers/common/pkg/config/containers.conf b/vendor/github.com/containers/common/pkg/config/containers.conf index 4e8ad21f8..b1e6f5435 100644 --- a/vendor/github.com/containers/common/pkg/config/containers.conf +++ b/vendor/github.com/containers/common/pkg/config/containers.conf @@ -249,9 +249,6 @@ default_sysctls = [ # #volumes = [] -# The network table contains settings pertaining to the management of -# CNI plugins. - [secrets] #driver = "file" @@ -260,9 +257,15 @@ default_sysctls = [ [network] -# Network backend to use. Default "CNI". +# Network backend determines what network driver will be used to set up and tear down container networks. +# Valid values are "cni" and "netavark". +# The default value is empty which means that it will automatically choose CNI or netavark. If there are +# already containers/images or CNI networks preset it will choose CNI. +# +# Before changing this value all containers must be stopped otherwise it is likely that +# iptables rules and network interfaces might leak on the host. A reboot will fix this. # -#network_backend = "cni" +#network_backend = "" # Path to directory where CNI plugin binaries are located. # @@ -274,18 +277,22 @@ default_sysctls = [ # "/opt/cni/bin", #] -# The network name of the default CNI network to attach pods to. +# The network name of the default network to attach pods to. # #default_network = "podman" -# The default subnet for the default CNI network given in default_network. +# The default subnet for the default network given in default_network. # If a network with that name does not exist, a new network using that name and # this subnet will be created. # Must be a valid IPv4 CIDR prefix. # #default_subnet = "10.88.0.0/16" -# Path to the directory where CNI configuration files are located. +# Path to the directory where network configuration files are located. +# For the CNI backend the default is "/etc/cni/net.d" as root +# and "$HOME/.config/cni/net.d" as rootless. +# For the netavark backend "/etc/containers/networks" is used as root +# and "$graphroot/networks" as rootless. # #network_config_dir = "/etc/cni/net.d/" @@ -351,6 +358,9 @@ default_sysctls = [ # #env = [] +# Define where event logs will be stored, when events_logger is "file". +#events_logfile_path="" + # Selects which logging mechanism to use for container engine events. # Valid values are `journald`, `file` and `none`. # diff --git a/vendor/github.com/containers/common/pkg/config/default.go b/vendor/github.com/containers/common/pkg/config/default.go index 561158b12..55e4e4b67 100644 --- a/vendor/github.com/containers/common/pkg/config/default.go +++ b/vendor/github.com/containers/common/pkg/config/default.go @@ -94,10 +94,6 @@ const ( // InstallPrefix is the prefix where podman will be installed. // It can be overridden at build time. _installPrefix = "/usr" - // _cniConfigDir is the directory where cni configuration is found - _cniConfigDir = "/etc/cni/net.d/" - // _cniConfigDirRootless is the directory in XDG_CONFIG_HOME for cni plugins - _cniConfigDirRootless = "cni/net.d/" // CgroupfsCgroupsManager represents cgroupfs native cgroup manager CgroupfsCgroupsManager = "cgroupfs" // DefaultApparmorProfile specifies the default apparmor profile for the container. @@ -141,8 +137,6 @@ func DefaultConfig() (*Config, error) { return nil, err } - cniConfig := _cniConfigDir - defaultEngineConfig.SignaturePolicyPath = DefaultSignaturePolicyPath if unshare.IsRootless() { configHome, err := homedir.GetConfigHome() @@ -156,7 +150,6 @@ func DefaultConfig() (*Config, error) { defaultEngineConfig.SignaturePolicyPath = DefaultSignaturePolicyPath } } - cniConfig = filepath.Join(configHome, _cniConfigDirRootless) } cgroupNS := "host" @@ -203,10 +196,9 @@ func DefaultConfig() (*Config, error) { UserNSSize: DefaultUserNSSize, }, Network: NetworkConfig{ - DefaultNetwork: "podman", - DefaultSubnet: DefaultSubnet, - NetworkConfigDir: cniConfig, - CNIPluginDirs: DefaultCNIPluginDirs, + DefaultNetwork: "podman", + DefaultSubnet: DefaultSubnet, + CNIPluginDirs: DefaultCNIPluginDirs, }, Engine: *defaultEngineConfig, Secrets: defaultSecretConfig(), diff --git a/vendor/modules.txt b/vendor/modules.txt index 671f37644..abf1fbbc2 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -109,7 +109,7 @@ github.com/containers/buildah/pkg/rusage github.com/containers/buildah/pkg/sshagent github.com/containers/buildah/pkg/util github.com/containers/buildah/util -# github.com/containers/common v0.46.1-0.20220112112017-31e8cc4aeeab +# github.com/containers/common v0.46.1-0.20220117145719-da777f8b15b1 ## explicit github.com/containers/common/libimage github.com/containers/common/libimage/manifests |