summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/common/create.go17
-rw-r--r--cmd/podman/play/kube.go1
-rw-r--r--cmd/podman/pods/create.go14
-rw-r--r--docs/source/markdown/podman-play-kube.1.md4
-rw-r--r--docs/source/markdown/podman-pod-create.1.md6
-rw-r--r--libpod/container_inspect.go56
-rw-r--r--libpod/define/pod_inspect.go2
-rw-r--r--libpod/pod_api.go54
-rw-r--r--pkg/api/handlers/libpod/play.go2
-rw-r--r--pkg/bindings/play/play.go3
-rw-r--r--pkg/bindings/play/types.go2
-rw-r--r--pkg/bindings/play/types_kube_options.go15
-rw-r--r--pkg/domain/entities/play.go3
-rw-r--r--pkg/domain/entities/pods.go5
-rw-r--r--pkg/domain/infra/abi/play.go2
-rw-r--r--pkg/domain/infra/tunnel/play.go2
-rw-r--r--pkg/specgen/generate/container.go52
-rw-r--r--pkg/specgen/generate/container_create.go38
-rw-r--r--pkg/specgen/generate/kube/kube.go7
-rw-r--r--pkg/specgen/podspecgen.go2
-rw-r--r--pkg/specgen/specgen.go16
-rw-r--r--test/e2e/play_kube_test.go43
-rw-r--r--test/e2e/pod_create_test.go21
23 files changed, 273 insertions, 94 deletions
diff --git a/cmd/podman/common/create.go b/cmd/podman/common/create.go
index e490fa121..e714b6785 100644
--- a/cmd/podman/common/create.go
+++ b/cmd/podman/common/create.go
@@ -164,14 +164,6 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
)
_ = cmd.RegisterFlagCompletionFunc(deviceCgroupRuleFlagName, completion.AutocompleteNone)
- deviceReadBpsFlagName := "device-read-bps"
- createFlags.StringSliceVar(
- &cf.DeviceReadBPs,
- deviceReadBpsFlagName, []string{},
- "Limit read rate (bytes per second) from a device (e.g. --device-read-bps=/dev/sda:1mb)",
- )
- _ = cmd.RegisterFlagCompletionFunc(deviceReadBpsFlagName, completion.AutocompleteDefault)
-
deviceReadIopsFlagName := "device-read-iops"
createFlags.StringSliceVar(
&cf.DeviceReadIOPs,
@@ -869,6 +861,7 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
volumeDesciption,
)
_ = cmd.RegisterFlagCompletionFunc(volumeFlagName, AutocompleteVolumeFlag)
+
deviceFlagName := "device"
createFlags.StringSliceVar(
&cf.Devices,
@@ -876,4 +869,12 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
"Add a host device to the container",
)
_ = cmd.RegisterFlagCompletionFunc(deviceFlagName, completion.AutocompleteDefault)
+
+ deviceReadBpsFlagName := "device-read-bps"
+ createFlags.StringSliceVar(
+ &cf.DeviceReadBPs,
+ deviceReadBpsFlagName, []string{},
+ "Limit read rate (bytes per second) from a device (e.g. --device-read-bps=/dev/sda:1mb)",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(deviceReadBpsFlagName, completion.AutocompleteDefault)
}
diff --git a/cmd/podman/play/kube.go b/cmd/podman/play/kube.go
index 9308371d2..85e0c279c 100644
--- a/cmd/podman/play/kube.go
+++ b/cmd/podman/play/kube.go
@@ -78,6 +78,7 @@ func init() {
flags.StringVar(&kubeOptions.LogDriver, logDriverFlagName, "", "Logging driver for the container")
_ = kubeCmd.RegisterFlagCompletionFunc(logDriverFlagName, common.AutocompleteLogDriver)
+ flags.BoolVar(&kubeOptions.NoHosts, "no-hosts", false, "Do not create /etc/hosts within the pod's containers, instead use the version from the image")
flags.BoolVarP(&kubeOptions.Quiet, "quiet", "q", false, "Suppress output information when pulling images")
flags.BoolVar(&kubeOptions.TLSVerifyCLI, "tls-verify", true, "Require HTTPS and verify certificates when contacting registries")
flags.BoolVar(&kubeOptions.StartCLI, "start", true, "Start the pod after creating it")
diff --git a/cmd/podman/pods/create.go b/cmd/podman/pods/create.go
index ca73a8356..d5aaf09ce 100644
--- a/cmd/podman/pods/create.go
+++ b/cmd/podman/pods/create.go
@@ -101,6 +101,7 @@ func create(cmd *cobra.Command, args []string) error {
podIDFD *os.File
imageName string
rawImageName string
+ podName string
)
labelFile = infraOptions.LabelFile
labels = infraOptions.Label
@@ -158,10 +159,12 @@ func create(cmd *cobra.Command, args []string) error {
return err
}
}
+ podName = createOptions.Name
err = common.ContainerToPodOptions(&infraOptions, &createOptions)
if err != nil {
return err
}
+ createOptions.Name = podName
}
if cmd.Flag("pod-id-file").Changed {
@@ -264,6 +267,17 @@ func create(cmd *cobra.Command, args []string) error {
podSpec.ImageVolumes = podSpec.InfraContainerSpec.ImageVolumes
podSpec.OverlayVolumes = podSpec.InfraContainerSpec.OverlayVolumes
podSpec.Mounts = podSpec.InfraContainerSpec.Mounts
+
+ // Marshall and Unmarshal the spec in order to map similar entities
+ wrapped, err := json.Marshal(podSpec.InfraContainerSpec)
+ if err != nil {
+ return err
+ }
+ err = json.Unmarshal(wrapped, podSpec)
+ if err != nil {
+ return err
+ }
+ podSpec.Name = podName
}
PodSpec := entities.PodSpec{PodSpecGen: *podSpec}
response, err := registry.ContainerEngine().PodCreate(context.Background(), PodSpec)
diff --git a/docs/source/markdown/podman-play-kube.1.md b/docs/source/markdown/podman-play-kube.1.md
index 7e3e0f431..a4b9722b8 100644
--- a/docs/source/markdown/podman-play-kube.1.md
+++ b/docs/source/markdown/podman-play-kube.1.md
@@ -138,6 +138,10 @@ Valid _mode_ values are:
Note: Rootlesskit changes the source IP address of incoming packets to a IP address in the container network namespace, usually `10.0.2.100`. If your application requires the real source IP address, e.g. web server logs, use the slirp4netns port handler. The rootlesskit port handler is also used for rootless containers when connected to user-defined networks.
- **port_handler=slirp4netns**: Use the slirp4netns port forwarding, it is slower than rootlesskit but preserves the correct source IP address. This port handler cannot be used for user-defined networks.
+#### **--no-hosts**
+
+Do not create /etc/hosts within the pod's containers, instead use the version from the image
+
#### **--quiet**, **-q**
Suppress output information when pulling images
diff --git a/docs/source/markdown/podman-pod-create.1.md b/docs/source/markdown/podman-pod-create.1.md
index fcb8ddeb9..4c36c66ca 100644
--- a/docs/source/markdown/podman-pod-create.1.md
+++ b/docs/source/markdown/podman-pod-create.1.md
@@ -41,7 +41,7 @@ Examples of the List Format:
#### **--device**=_host-device_[**:**_container-device_][**:**_permissions_]
Add a host device to the pod. Optional *permissions* parameter
-can be used to specify device permissions It is a combination of
+can be used to specify device permissions. It is a combination of
**r** for read, **w** for write, and **m** for **mknod**(2).
Example: **--device=/dev/sdc:/dev/xvdc:rwm**.
@@ -55,6 +55,10 @@ Podman may load kernel modules required for using the specified
device. The devices that Podman will load modules for when necessary are:
/dev/fuse.
+#### **--device-read-bps**=*path*
+
+Limit read rate (bytes per second) from a device (e.g. --device-read-bps=/dev/sda:1mb)
+
#### **--dns**=*ipaddr*
Set custom DNS servers in the /etc/resolv.conf file that will be shared between all containers in the pod. A special option, "none" is allowed which disables creation of /etc/resolv.conf for the pod.
diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go
index ab79d82d9..277c3b960 100644
--- a/libpod/container_inspect.go
+++ b/libpod/container_inspect.go
@@ -531,49 +531,25 @@ func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, named
hostConfig.BlkioWeightDevice = append(hostConfig.BlkioWeightDevice, weightDev)
}
- handleThrottleDevice := func(devs []spec.LinuxThrottleDevice) ([]define.InspectBlkioThrottleDevice, error) {
- out := []define.InspectBlkioThrottleDevice{}
- for _, dev := range devs {
- key := fmt.Sprintf("%d:%d", dev.Major, dev.Minor)
- if deviceNodes == nil {
- nodes, err := util.FindDeviceNodes()
- if err != nil {
- return nil, err
- }
- deviceNodes = nodes
- }
- path, ok := deviceNodes[key]
- if !ok {
- logrus.Infof("Could not locate throttle device %s in system devices", key)
- continue
- }
- throttleDev := define.InspectBlkioThrottleDevice{}
- throttleDev.Path = path
- throttleDev.Rate = dev.Rate
- out = append(out, throttleDev)
- }
- return out, nil
- }
-
- readBps, err := handleThrottleDevice(ctrSpec.Linux.Resources.BlockIO.ThrottleReadBpsDevice)
+ readBps, err := blkioDeviceThrottle(deviceNodes, ctrSpec.Linux.Resources.BlockIO.ThrottleReadBpsDevice)
if err != nil {
return nil, err
}
hostConfig.BlkioDeviceReadBps = readBps
- writeBps, err := handleThrottleDevice(ctrSpec.Linux.Resources.BlockIO.ThrottleWriteBpsDevice)
+ writeBps, err := blkioDeviceThrottle(deviceNodes, ctrSpec.Linux.Resources.BlockIO.ThrottleWriteBpsDevice)
if err != nil {
return nil, err
}
hostConfig.BlkioDeviceWriteBps = writeBps
- readIops, err := handleThrottleDevice(ctrSpec.Linux.Resources.BlockIO.ThrottleReadIOPSDevice)
+ readIops, err := blkioDeviceThrottle(deviceNodes, ctrSpec.Linux.Resources.BlockIO.ThrottleReadIOPSDevice)
if err != nil {
return nil, err
}
hostConfig.BlkioDeviceReadIOps = readIops
- writeIops, err := handleThrottleDevice(ctrSpec.Linux.Resources.BlockIO.ThrottleWriteIOPSDevice)
+ writeIops, err := blkioDeviceThrottle(deviceNodes, ctrSpec.Linux.Resources.BlockIO.ThrottleWriteIOPSDevice)
if err != nil {
return nil, err
}
@@ -894,3 +870,27 @@ func (c *Container) GetDevices(priv bool, ctrSpec spec.Spec, deviceNodes map[str
}
return devices, nil
}
+
+func blkioDeviceThrottle(deviceNodes map[string]string, devs []spec.LinuxThrottleDevice) ([]define.InspectBlkioThrottleDevice, error) {
+ out := []define.InspectBlkioThrottleDevice{}
+ for _, dev := range devs {
+ key := fmt.Sprintf("%d:%d", dev.Major, dev.Minor)
+ if deviceNodes == nil {
+ nodes, err := util.FindDeviceNodes()
+ if err != nil {
+ return nil, err
+ }
+ deviceNodes = nodes
+ }
+ path, ok := deviceNodes[key]
+ if !ok {
+ logrus.Infof("Could not locate throttle device %s in system devices", key)
+ continue
+ }
+ throttleDev := define.InspectBlkioThrottleDevice{}
+ throttleDev.Path = path
+ throttleDev.Rate = dev.Rate
+ out = append(out, throttleDev)
+ }
+ return out, nil
+}
diff --git a/libpod/define/pod_inspect.go b/libpod/define/pod_inspect.go
index e78d97850..bc2c1d81f 100644
--- a/libpod/define/pod_inspect.go
+++ b/libpod/define/pod_inspect.go
@@ -61,6 +61,8 @@ type InspectPodData struct {
Mounts []InspectMount `json:"mounts,omitempty"`
// Devices contains the specified host devices
Devices []InspectDevice `json:"devices,omitempty"`
+ // BlkioDeviceReadBps contains the Read/Access limit for the pod's devices
+ BlkioDeviceReadBps []InspectBlkioThrottleDevice `json:"device_read_bps,omitempty"`
}
// InspectPodInfraConfig contains the configuration of the pod's infra
diff --git a/libpod/pod_api.go b/libpod/pod_api.go
index 971309f77..05349aff5 100644
--- a/libpod/pod_api.go
+++ b/libpod/pod_api.go
@@ -584,6 +584,7 @@ func (p *Pod) Inspect() (*define.InspectPodData, error) {
var infraConfig *define.InspectPodInfraConfig
var inspectMounts []define.InspectMount
var devices []define.InspectDevice
+ var deviceLimits []define.InspectBlkioThrottleDevice
if p.state.InfraContainerID != "" {
infra, err := p.runtime.GetContainer(p.state.InfraContainerID)
if err != nil {
@@ -604,12 +605,18 @@ func (p *Pod) Inspect() (*define.InspectPodData, error) {
if err != nil {
return nil, err
}
-
var nodes map[string]string
devices, err = infra.GetDevices(false, *infra.config.Spec, nodes)
if err != nil {
return nil, err
}
+ spec := infra.config.Spec
+ if spec.Linux != nil && spec.Linux.Resources != nil && spec.Linux.Resources.BlockIO != nil {
+ deviceLimits, err = blkioDeviceThrottle(nodes, spec.Linux.Resources.BlockIO.ThrottleReadBpsDevice)
+ if err != nil {
+ return nil, err
+ }
+ }
if len(infra.config.ContainerNetworkConfig.DNSServer) > 0 {
infraConfig.DNSServer = make([]string, 0, len(infra.config.ContainerNetworkConfig.DNSServer))
@@ -638,28 +645,29 @@ func (p *Pod) Inspect() (*define.InspectPodData, error) {
}
inspectData := define.InspectPodData{
- ID: p.ID(),
- Name: p.Name(),
- Namespace: p.Namespace(),
- Created: p.CreatedTime(),
- CreateCommand: p.config.CreateCommand,
- State: podState,
- Hostname: p.config.Hostname,
- Labels: p.Labels(),
- CreateCgroup: p.config.UsePodCgroup,
- CgroupParent: p.CgroupParent(),
- CgroupPath: p.state.CgroupPath,
- CreateInfra: infraConfig != nil,
- InfraContainerID: p.state.InfraContainerID,
- InfraConfig: infraConfig,
- SharedNamespaces: sharesNS,
- NumContainers: uint(len(containers)),
- Containers: ctrs,
- CPUSetCPUs: p.ResourceLim().CPU.Cpus,
- CPUPeriod: p.CPUPeriod(),
- CPUQuota: p.CPUQuota(),
- Mounts: inspectMounts,
- Devices: devices,
+ ID: p.ID(),
+ Name: p.Name(),
+ Namespace: p.Namespace(),
+ Created: p.CreatedTime(),
+ CreateCommand: p.config.CreateCommand,
+ State: podState,
+ Hostname: p.config.Hostname,
+ Labels: p.Labels(),
+ CreateCgroup: p.config.UsePodCgroup,
+ CgroupParent: p.CgroupParent(),
+ CgroupPath: p.state.CgroupPath,
+ CreateInfra: infraConfig != nil,
+ InfraContainerID: p.state.InfraContainerID,
+ InfraConfig: infraConfig,
+ SharedNamespaces: sharesNS,
+ NumContainers: uint(len(containers)),
+ Containers: ctrs,
+ CPUSetCPUs: p.ResourceLim().CPU.Cpus,
+ CPUPeriod: p.CPUPeriod(),
+ CPUQuota: p.CPUQuota(),
+ Mounts: inspectMounts,
+ Devices: devices,
+ BlkioDeviceReadBps: deviceLimits,
}
return &inspectData, nil
diff --git a/pkg/api/handlers/libpod/play.go b/pkg/api/handlers/libpod/play.go
index 0def32821..851e0f6c8 100644
--- a/pkg/api/handlers/libpod/play.go
+++ b/pkg/api/handlers/libpod/play.go
@@ -29,6 +29,7 @@ func PlayKube(w http.ResponseWriter, r *http.Request) {
Start bool `schema:"start"`
StaticIPs []string `schema:"staticIPs"`
StaticMACs []string `schema:"staticMACs"`
+ NoHosts bool `schema:"noHosts"`
}{
TLSVerify: true,
Start: true,
@@ -102,6 +103,7 @@ func PlayKube(w http.ResponseWriter, r *http.Request) {
Username: username,
Password: password,
Network: query.Network,
+ NoHosts: query.NoHosts,
Quiet: true,
LogDriver: query.LogDriver,
StaticIPs: staticIPs,
diff --git a/pkg/bindings/play/play.go b/pkg/bindings/play/play.go
index 89a6f9b65..bdd13d03d 100644
--- a/pkg/bindings/play/play.go
+++ b/pkg/bindings/play/play.go
@@ -6,11 +6,10 @@ import (
"os"
"strconv"
- "github.com/sirupsen/logrus"
-
"github.com/containers/podman/v3/pkg/auth"
"github.com/containers/podman/v3/pkg/bindings"
"github.com/containers/podman/v3/pkg/domain/entities"
+ "github.com/sirupsen/logrus"
)
func Kube(ctx context.Context, path string, options *KubeOptions) (*entities.PlayKubeReport, error) {
diff --git a/pkg/bindings/play/types.go b/pkg/bindings/play/types.go
index 787069169..fdfc4a6fa 100644
--- a/pkg/bindings/play/types.go
+++ b/pkg/bindings/play/types.go
@@ -17,6 +17,8 @@ type KubeOptions struct {
Password *string
// Network - name of the CNI network to connect to.
Network *string
+ // NoHosts - do not generate /etc/hosts file in pod's containers
+ NoHosts *bool
// Quiet - suppress output when pulling images.
Quiet *bool
// SignaturePolicy - path to a signature-policy file.
diff --git a/pkg/bindings/play/types_kube_options.go b/pkg/bindings/play/types_kube_options.go
index 65757cc5e..1a6324302 100644
--- a/pkg/bindings/play/types_kube_options.go
+++ b/pkg/bindings/play/types_kube_options.go
@@ -93,6 +93,21 @@ func (o *KubeOptions) GetNetwork() string {
return *o.Network
}
+// WithNoHosts set field NoHosts to given value
+func (o *KubeOptions) WithNoHosts(value bool) *KubeOptions {
+ o.NoHosts = &value
+ return o
+}
+
+// GetNoHosts returns value of field NoHosts
+func (o *KubeOptions) GetNoHosts() bool {
+ if o.NoHosts == nil {
+ var z bool
+ return z
+ }
+ return *o.NoHosts
+}
+
// WithQuiet set field Quiet to given value
func (o *KubeOptions) WithQuiet(value bool) *KubeOptions {
o.Quiet = &value
diff --git a/pkg/domain/entities/play.go b/pkg/domain/entities/play.go
index f630b3f24..af4b0fc35 100644
--- a/pkg/domain/entities/play.go
+++ b/pkg/domain/entities/play.go
@@ -17,6 +17,9 @@ type PlayKubeOptions struct {
// Down indicates whether to bring contents of a yaml file "down"
// as in stop
Down bool
+ // Do not create /etc/hosts within the pod's containers,
+ // instead use the version from the image
+ NoHosts bool
// Username for authenticating against the registry.
Username string
// Password for authenticating against the registry.
diff --git a/pkg/domain/entities/pods.go b/pkg/domain/entities/pods.go
index f0c88d77e..0356383ec 100644
--- a/pkg/domain/entities/pods.go
+++ b/pkg/domain/entities/pods.go
@@ -119,6 +119,7 @@ type PodCreateOptions struct {
CGroupParent string `json:"cgroup_parent,omitempty"`
CreateCommand []string `json:"create_command,omitempty"`
Devices []string `json:"devices,omitempty"`
+ DeviceReadBPs []string `json:"device_read_bps,omitempty"`
Hostname string `json:"hostname,omitempty"`
Infra bool `json:"infra,omitempty"`
InfraImage string `json:"infra_image,omitempty"`
@@ -167,7 +168,7 @@ type ContainerCreateOptions struct {
CPUSetMems string
Devices []string `json:"devices,omitempty"`
DeviceCGroupRule []string
- DeviceReadBPs []string
+ DeviceReadBPs []string `json:"device_read_bps,omitempty"`
DeviceReadIOPs []string
DeviceWriteBPs []string
DeviceWriteIOPs []string
@@ -200,7 +201,7 @@ type ContainerCreateOptions struct {
MemoryReservation string
MemorySwap string
MemorySwappiness int64
- Name string `json:"container_name,omitempty"`
+ Name string `json:"container_name"`
NoHealthCheck bool
OOMKillDisable bool
OOMScoreAdj int
diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go
index cf72a6253..751d6cc05 100644
--- a/pkg/domain/infra/abi/play.go
+++ b/pkg/domain/infra/abi/play.go
@@ -181,7 +181,7 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
}
}
- podOpt := entities.PodCreateOptions{Infra: true, Net: &entities.NetOptions{StaticIP: &net.IP{}, StaticMAC: &net.HardwareAddr{}}}
+ podOpt := entities.PodCreateOptions{Infra: true, Net: &entities.NetOptions{StaticIP: &net.IP{}, StaticMAC: &net.HardwareAddr{}, NoHosts: options.NoHosts}}
podOpt, err = kube.ToPodOpt(ctx, podName, podOpt, podYAML)
if err != nil {
return nil, err
diff --git a/pkg/domain/infra/tunnel/play.go b/pkg/domain/infra/tunnel/play.go
index e39751a18..0b1c3d2ca 100644
--- a/pkg/domain/infra/tunnel/play.go
+++ b/pkg/domain/infra/tunnel/play.go
@@ -13,7 +13,7 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, path string, opts entit
options.WithCertDir(opts.CertDir).WithQuiet(opts.Quiet).WithSignaturePolicy(opts.SignaturePolicy).WithConfigMaps(opts.ConfigMaps)
options.WithLogDriver(opts.LogDriver).WithNetwork(opts.Network).WithSeccompProfileRoot(opts.SeccompProfileRoot)
options.WithStaticIPs(opts.StaticIPs).WithStaticMACs(opts.StaticMACs)
-
+ options.WithNoHosts(opts.NoHosts)
if s := opts.SkipTLSVerify; s != types.OptionalBoolUndefined {
options.WithSkipTLSVerify(s == types.OptionalBoolTrue)
}
diff --git a/pkg/specgen/generate/container.go b/pkg/specgen/generate/container.go
index 71b882510..f126aa018 100644
--- a/pkg/specgen/generate/container.go
+++ b/pkg/specgen/generate/container.go
@@ -18,19 +18,43 @@ import (
"golang.org/x/sys/unix"
)
+func getImageFromSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerator) (*libimage.Image, string, *libimage.ImageData, error) {
+ if s.Image == "" || s.Rootfs != "" {
+ return nil, "", nil, nil
+ }
+
+ // Image may already have been set in the generator.
+ image, resolvedName := s.GetImage()
+ if image != nil {
+ inspectData, err := image.Inspect(ctx, false)
+ if err != nil {
+ return nil, "", nil, err
+ }
+ return image, resolvedName, inspectData, nil
+ }
+
+ // Need to look up image.
+ image, resolvedName, err := r.LibimageRuntime().LookupImage(s.Image, nil)
+ if err != nil {
+ return nil, "", nil, err
+ }
+ s.SetImage(image, resolvedName)
+ inspectData, err := image.Inspect(ctx, false)
+ if err != nil {
+ return nil, "", nil, err
+ }
+ return image, resolvedName, inspectData, err
+}
+
// Fill any missing parts of the spec generator (e.g. from the image).
// Returns a set of warnings or any fatal error that occurred.
func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerator) ([]string, error) {
// Only add image configuration if we have an image
- var newImage *libimage.Image
- var inspectData *libimage.ImageData
- var err error
- if s.Image != "" {
- newImage, _, err = r.LibimageRuntime().LookupImage(s.Image, nil)
- if err != nil {
- return nil, err
- }
-
+ newImage, _, inspectData, err := getImageFromSpec(ctx, r, s)
+ if err != nil {
+ return nil, err
+ }
+ if inspectData != nil {
inspectData, err = newImage.Inspect(ctx, false)
if err != nil {
return nil, err
@@ -191,9 +215,6 @@ func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerat
if len(s.User) == 0 && inspectData != nil {
s.User = inspectData.Config.User
}
- if err := finishThrottleDevices(s); err != nil {
- return nil, err
- }
// Unless already set via the CLI, check if we need to disable process
// labels or set the defaults.
if len(s.SelinuxOpts) == 0 {
@@ -251,10 +272,10 @@ func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerat
return warnings, nil
}
-// finishThrottleDevices takes the temporary representation of the throttle
+// FinishThrottleDevices takes the temporary representation of the throttle
// devices in the specgen and looks up the major and major minors. it then
// sets the throttle devices proper in the specgen
-func finishThrottleDevices(s *specgen.SpecGenerator) error {
+func FinishThrottleDevices(s *specgen.SpecGenerator) error {
if bps := s.ThrottleReadBpsDevice; len(bps) > 0 {
for k, v := range bps {
statT := unix.Stat_t{}
@@ -263,6 +284,9 @@ func finishThrottleDevices(s *specgen.SpecGenerator) error {
}
v.Major = (int64(unix.Major(uint64(statT.Rdev))))
v.Minor = (int64(unix.Minor(uint64(statT.Rdev))))
+ if s.ResourceLimits.BlockIO == nil {
+ s.ResourceLimits.BlockIO = new(spec.LinuxBlockIO)
+ }
s.ResourceLimits.BlockIO.ThrottleReadBpsDevice = append(s.ResourceLimits.BlockIO.ThrottleReadBpsDevice, v)
}
}
diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go
index 6100e7a5b..92c0f22d9 100644
--- a/pkg/specgen/generate/container_create.go
+++ b/pkg/specgen/generate/container_create.go
@@ -2,6 +2,7 @@ package generate
import (
"context"
+ "fmt"
"os"
"path/filepath"
"strings"
@@ -52,6 +53,24 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener
if infraConfig != nil && len(infraConfig.Spec.Linux.Devices) > 0 {
s.DevicesFrom = append(s.DevicesFrom, infraConfig.ID)
}
+ if infraConfig != nil && infraConfig.Spec.Linux.Resources != nil && infraConfig.Spec.Linux.Resources.BlockIO != nil && len(infraConfig.Spec.Linux.Resources.BlockIO.ThrottleReadBpsDevice) > 0 {
+ tempDev := make(map[string]spec.LinuxThrottleDevice)
+ for _, val := range infraConfig.Spec.Linux.Resources.BlockIO.ThrottleReadBpsDevice {
+ nodes, err := util.FindDeviceNodes()
+ if err != nil {
+ return nil, nil, nil, err
+ }
+ key := fmt.Sprintf("%d:%d", val.Major, val.Minor)
+ tempDev[nodes[key]] = spec.LinuxThrottleDevice{Rate: uint64(val.Rate)}
+ }
+ for i, dev := range s.ThrottleReadBpsDevice {
+ tempDev[i] = dev
+ }
+ s.ThrottleReadBpsDevice = tempDev
+ }
+ if err := FinishThrottleDevices(s); err != nil {
+ return nil, nil, nil, err
+ }
// Set defaults for unset namespaces
if s.PidNS.IsDefault() {
defaultNS, err := GetDefaultNamespaceMode("pid", rtc, pod)
@@ -102,20 +121,15 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener
options = append(options, libpod.WithCreateCommand(s.ContainerCreateCommand))
}
- var newImage *libimage.Image
- var imageData *libimage.ImageData
if s.Rootfs != "" {
options = append(options, libpod.WithRootFS(s.Rootfs, s.RootfsOverlay))
- } else {
- var resolvedImageName string
- newImage, resolvedImageName, err = rt.LibimageRuntime().LookupImage(s.Image, nil)
- if err != nil {
- return nil, nil, nil, err
- }
- imageData, err = newImage.Inspect(ctx, false)
- if err != nil {
- return nil, nil, nil, err
- }
+ }
+
+ newImage, resolvedImageName, imageData, err := getImageFromSpec(ctx, rt, s)
+ if err != nil {
+ return nil, nil, nil, err
+ }
+ if newImage != nil {
// If the input name changed, we could properly resolve the
// image. Otherwise, it must have been an ID where we're
// defaulting to the first name or an empty one if no names are
diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go
index 9389b1a20..194c8dce5 100644
--- a/pkg/specgen/generate/kube/kube.go
+++ b/pkg/specgen/generate/kube/kube.go
@@ -26,8 +26,8 @@ import (
)
func ToPodOpt(ctx context.Context, podName string, p entities.PodCreateOptions, podYAML *v1.PodTemplateSpec) (entities.PodCreateOptions, error) {
- // p := specgen.NewPodSpecGenerator()
- p.Net = &entities.NetOptions{}
+ p.Net = &entities.NetOptions{NoHosts: p.Net.NoHosts}
+
p.Name = podName
p.Labels = podYAML.ObjectMeta.Labels
// Kube pods must share {ipc, net, uts} by default
@@ -47,6 +47,9 @@ func ToPodOpt(ctx context.Context, podName string, p entities.PodCreateOptions,
p.Net.Network = specgen.Namespace{NSMode: "host"}
}
if podYAML.Spec.HostAliases != nil {
+ if p.Net.NoHosts {
+ return p, errors.New("HostAliases in yaml file will not work with --no-hosts")
+ }
hosts := make([]string, 0, len(podYAML.Spec.HostAliases))
for _, hostAlias := range podYAML.Spec.HostAliases {
for _, host := range hostAlias.Hostnames {
diff --git a/pkg/specgen/podspecgen.go b/pkg/specgen/podspecgen.go
index 83fa9426c..ee4fbc13a 100644
--- a/pkg/specgen/podspecgen.go
+++ b/pkg/specgen/podspecgen.go
@@ -201,6 +201,8 @@ type PodResourceConfig struct {
CPUPeriod uint64 `json:"cpu_period,omitempty"`
// CPU quota of the cpuset, determined by --cpus
CPUQuota int64 `json:"cpu_quota,omitempty"`
+ // ThrottleReadBpsDevice contains the rate at which the devices in the pod can be read from/accessed
+ ThrottleReadBpsDevice map[string]spec.LinuxThrottleDevice `json:"throttleReadBpsDevice,omitempty"`
}
// NewPodSpecGenerator creates a new pod spec
diff --git a/pkg/specgen/specgen.go b/pkg/specgen/specgen.go
index 70b2aa1ef..dbb669291 100644
--- a/pkg/specgen/specgen.go
+++ b/pkg/specgen/specgen.go
@@ -5,6 +5,7 @@ import (
"strings"
"syscall"
+ "github.com/containers/common/libimage"
"github.com/containers/image/v5/manifest"
nettypes "github.com/containers/podman/v3/libpod/network/types"
"github.com/containers/storage/types"
@@ -512,6 +513,21 @@ type SpecGenerator struct {
ContainerNetworkConfig
ContainerResourceConfig
ContainerHealthCheckConfig
+
+ image *libimage.Image `json:"-"`
+ resolvedImageName string `json:"-"`
+}
+
+// SetImage sets the associated for the generator.
+func (s *SpecGenerator) SetImage(image *libimage.Image, resolvedImageName string) {
+ s.image = image
+ s.resolvedImageName = resolvedImageName
+}
+
+// Image returns the associated image for the generator.
+// May be nil if no image has been set yet.
+func (s *SpecGenerator) GetImage() (*libimage.Image, string) {
+ return s.image, s.resolvedImageName
}
type Secret struct {
diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go
index 83ce751e6..a29d0ad46 100644
--- a/test/e2e/play_kube_test.go
+++ b/test/e2e/play_kube_test.go
@@ -1137,6 +1137,49 @@ var _ = Describe("Podman play kube", func() {
Expect(infraContainerImage).To(Equal(config.DefaultInfraImage))
})
+ It("podman play kube --no-host", func() {
+ err := writeYaml(checkInfraImagePodYaml, kubeYaml)
+ Expect(err).To(BeNil())
+
+ kube := podmanTest.Podman([]string{"play", "kube", "--no-hosts", kubeYaml})
+ kube.WaitWithDefaultTimeout()
+ Expect(kube).Should(Exit(0))
+
+ podInspect := podmanTest.Podman([]string{"pod", "inspect", "check-infra-image"})
+ podInspect.WaitWithDefaultTimeout()
+ Expect(podInspect).Should(Exit(0))
+
+ data := podInspect.InspectPodToJSON()
+ for _, ctr := range data.Containers {
+ if strings.HasSuffix(ctr.Name, "-infra") {
+ continue
+ }
+ exec := podmanTest.Podman([]string{"exec", ctr.ID, "cat", "/etc/hosts"})
+ exec.WaitWithDefaultTimeout()
+ Expect(exec).Should(Exit(0))
+ Expect(exec.OutputToString()).To(Not(ContainSubstring("check-infra-image")))
+ }
+ })
+
+ It("podman play kube test HostAliases with --no-hosts", func() {
+ pod := getPod(withHostAliases("192.168.1.2", []string{
+ "test1.podman.io",
+ "test2.podman.io",
+ }),
+ withHostAliases("192.168.1.3", []string{
+ "test3.podman.io",
+ "test4.podman.io",
+ }),
+ )
+ err := generateKubeYaml("pod", pod, kubeYaml)
+ Expect(err).To(BeNil())
+
+ kube := podmanTest.Podman([]string{"play", "kube", "--no-hosts", kubeYaml})
+ kube.WaitWithDefaultTimeout()
+ Expect(kube).Should(Exit(125))
+ Expect(kube.ErrorToString()).To(ContainSubstring("HostAliases in yaml file will not work with --no-hosts"))
+ })
+
It("podman play kube should use customized infra_image", func() {
conffile := filepath.Join(podmanTest.TempDir, "container.conf")
diff --git a/test/e2e/pod_create_test.go b/test/e2e/pod_create_test.go
index c9924be72..e8bc871da 100644
--- a/test/e2e/pod_create_test.go
+++ b/test/e2e/pod_create_test.go
@@ -903,4 +903,25 @@ ENTRYPOINT ["sleep","99999"]
})
+ It("podman pod create --device-read-bps", func() {
+ SkipIfRootless("Cannot create devices in /dev in rootless mode")
+ SkipIfRootlessCgroupsV1("Setting device-read-bps not supported on cgroupv1 for rootless users")
+
+ podName := "testPod"
+ session := podmanTest.Podman([]string{"pod", "create", "--device-read-bps", "/dev/zero:1mb", "--name", podName})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ if CGROUPSV2 {
+ session = podmanTest.Podman([]string{"run", "--rm", "--pod", podName, ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.max"})
+ } else {
+ session = podmanTest.Podman([]string{"run", "--rm", "--pod", podName, ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.read_bps_device"})
+ }
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ if !CGROUPSV2 {
+ Expect(session.OutputToString()).To(ContainSubstring("1048576"))
+ }
+ })
+
})