summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/common/create_opts.go41
-rw-r--r--cmd/podman/images/search.go10
-rw-r--r--docs/source/markdown/podman-import.1.md3
-rw-r--r--docs/source/markdown/podman-pull.1.md11
-rw-r--r--pkg/api/handlers/compat/containers_create.go7
-rw-r--r--pkg/bindings/containers/logs.go2
-rw-r--r--pkg/specgen/container_validate.go35
-rw-r--r--test/e2e/search_test.go8
8 files changed, 98 insertions, 19 deletions
diff --git a/cmd/podman/common/create_opts.go b/cmd/podman/common/create_opts.go
index 05bb9de13..8b2efc988 100644
--- a/cmd/podman/common/create_opts.go
+++ b/cmd/podman/common/create_opts.go
@@ -7,7 +7,9 @@ import (
"strings"
"github.com/containers/podman/v2/pkg/api/handlers"
+ "github.com/containers/podman/v2/pkg/cgroups"
"github.com/containers/podman/v2/pkg/domain/entities"
+ "github.com/containers/podman/v2/pkg/rootless"
"github.com/containers/podman/v2/pkg/specgen"
)
@@ -129,7 +131,7 @@ func stringMaptoArray(m map[string]string) []string {
// ContainerCreateToContainerCLIOpts converts a compat input struct to cliopts so it can be converted to
// a specgen spec.
-func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig) (*ContainerCLIOpts, []string, error) {
+func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, cgroupsManager string) (*ContainerCLIOpts, []string, error) {
var (
capAdd []string
cappDrop []string
@@ -346,16 +348,23 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig) (*Cont
Systemd: "true", // podman default
TmpFS: stringMaptoArray(cc.HostConfig.Tmpfs),
TTY: cc.Config.Tty,
- //Ulimit: cc.HostConfig.Ulimits, // ask dan, no documented format
- Ulimit: []string{"nproc=4194304:4194304"},
- User: cc.Config.User,
- UserNS: string(cc.HostConfig.UsernsMode),
- UTS: string(cc.HostConfig.UTSMode),
- Mount: mounts,
- Volume: volumes,
- VolumesFrom: cc.HostConfig.VolumesFrom,
- Workdir: cc.Config.WorkingDir,
- Net: &netInfo,
+ User: cc.Config.User,
+ UserNS: string(cc.HostConfig.UsernsMode),
+ UTS: string(cc.HostConfig.UTSMode),
+ Mount: mounts,
+ Volume: volumes,
+ VolumesFrom: cc.HostConfig.VolumesFrom,
+ Workdir: cc.Config.WorkingDir,
+ Net: &netInfo,
+ }
+ if !rootless.IsRootless() {
+ var ulimits []string
+ if len(cc.HostConfig.Ulimits) > 0 {
+ for _, ul := range cc.HostConfig.Ulimits {
+ ulimits = append(ulimits, ul.String())
+ }
+ cliOpts.Ulimit = ulimits
+ }
}
if len(cc.HostConfig.BlkioWeightDevice) > 0 {
@@ -377,7 +386,11 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig) (*Cont
cliOpts.MemoryReservation = strconv.Itoa(int(cc.HostConfig.MemoryReservation))
}
- if cc.HostConfig.MemorySwap > 0 {
+ cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
+ if err != nil {
+ return nil, nil, err
+ }
+ if cc.HostConfig.MemorySwap > 0 && (!rootless.IsRootless() || (rootless.IsRootless() && cgroupsv2)) {
cliOpts.MemorySwap = strconv.Itoa(int(cc.HostConfig.MemorySwap))
}
@@ -401,8 +414,10 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig) (*Cont
cliOpts.Restart = policy
}
- if cc.HostConfig.MemorySwappiness != nil {
+ if cc.HostConfig.MemorySwappiness != nil && (!rootless.IsRootless() || rootless.IsRootless() && cgroupsv2 && cgroupsManager == "systemd") {
cliOpts.MemorySwappiness = *cc.HostConfig.MemorySwappiness
+ } else {
+ cliOpts.MemorySwappiness = -1
}
if cc.HostConfig.OomKillDisable != nil {
cliOpts.OOMKillDisable = *cc.HostConfig.OomKillDisable
diff --git a/cmd/podman/images/search.go b/cmd/podman/images/search.go
index 774b39d3a..7de6a7316 100644
--- a/cmd/podman/images/search.go
+++ b/cmd/podman/images/search.go
@@ -1,6 +1,7 @@
package images
import (
+ "fmt"
"os"
"text/tabwriter"
"text/template"
@@ -81,7 +82,7 @@ func init() {
// searchFlags set the flags for the pull command.
func searchFlags(flags *pflag.FlagSet) {
flags.StringSliceVarP(&searchOptions.Filters, "filter", "f", []string{}, "Filter output based on conditions provided (default [])")
- flags.StringVar(&searchOptions.Format, "format", "", "Change the output format to a Go template")
+ flags.StringVar(&searchOptions.Format, "format", "", "Change the output format to JSON or a Go template")
flags.IntVar(&searchOptions.Limit, "limit", 0, "Limit the number of results")
flags.BoolVar(&searchOptions.NoTrunc, "no-trunc", false, "Do not truncate the output")
flags.StringVar(&searchOptions.Authfile, "authfile", auth.GetDefaultAuthFile(), "Path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override")
@@ -135,6 +136,13 @@ func imageSearch(cmd *cobra.Command, args []string) error {
return errors.Errorf("filters are not applicable to list tags result")
}
row = "{{.Name}}\t{{.Tag}}\n"
+ case report.IsJSON(searchOptions.Format):
+ prettyJSON, err := json.MarshalIndent(searchReport, "", " ")
+ if err != nil {
+ return err
+ }
+ fmt.Println(string(prettyJSON))
+ return nil
case cmd.Flags().Changed("format"):
renderHeaders = parse.HasTable(searchOptions.Format)
row = report.NormalizeFormat(searchOptions.Format)
diff --git a/docs/source/markdown/podman-import.1.md b/docs/source/markdown/podman-import.1.md
index 946b680dd..b6d88aeac 100644
--- a/docs/source/markdown/podman-import.1.md
+++ b/docs/source/markdown/podman-import.1.md
@@ -22,6 +22,7 @@ Note: `:` is a restricted character and cannot be part of the file name.
Apply the following possible instructions to the created image:
**CMD** | **ENTRYPOINT** | **ENV** | **EXPOSE** | **LABEL** | **STOPSIGNAL** | **USER** | **VOLUME** | **WORKDIR**
+
Can be set multiple times
**--message**, **-m**=*message*
@@ -55,7 +56,7 @@ db65d991f3bbf7f31ed1064db9a6ced7652e3f8166c4736aa9133dadd3c7acb3
```
```
-$ podman import --change "ENTRYPOINT ["/bin/sh","-c","test-image"]" --change LABEL=blue=image test-image.tar image-imported
+$ podman import --change 'ENTRYPOINT ["/bin/sh","-c","test-image"]' --change LABEL=blue=image test-image.tar image-imported
Getting image source signatures
Copying blob e3b0c44298fc skipped: already exists
Copying config 1105523502 done
diff --git a/docs/source/markdown/podman-pull.1.md b/docs/source/markdown/podman-pull.1.md
index 46beb4c42..9e3911704 100644
--- a/docs/source/markdown/podman-pull.1.md
+++ b/docs/source/markdown/podman-pull.1.md
@@ -120,6 +120,17 @@ Storing signatures
```
```
+$ podman pull alpine@sha256:d7342993700f8cd7aba8496c2d0e57be0666e80b4c441925fc6f9361fa81d10e
+Trying to pull docker.io/library/alpine@sha256:d7342993700f8cd7aba8496c2d0e57be0666e80b4c441925fc6f9361fa81d10e...
+Getting image source signatures
+Copying blob 188c0c94c7c5 done
+Copying config d6e46aa247 done
+Writing manifest to image destination
+Storing signatures
+d6e46aa2470df1d32034c6707c8041158b652f38d2a9ae3d7ad7e7532d22ebe0
+```
+
+```
$ podman pull --authfile temp-auths/myauths.json docker://docker.io/umohnani/finaltest
Trying to pull docker.io/umohnani/finaltest:latest...Getting image source signatures
Copying blob sha256:6d987f6f42797d81a318c40d442369ba3dc124883a0964d40b0c8f4f7561d913
diff --git a/pkg/api/handlers/compat/containers_create.go b/pkg/api/handlers/compat/containers_create.go
index 24e25f526..4efe770b3 100644
--- a/pkg/api/handlers/compat/containers_create.go
+++ b/pkg/api/handlers/compat/containers_create.go
@@ -38,6 +38,11 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) {
utils.Error(w, utils.ErrLinkNotSupport.Error(), http.StatusBadRequest, errors.Wrapf(utils.ErrLinkNotSupport, "bad parameter"))
return
}
+ rtc, err := runtime.GetConfig()
+ if err != nil {
+ utils.Error(w, "unable to obtain runtime config", http.StatusInternalServerError, errors.Wrap(err, "unable to get runtime config"))
+ }
+
newImage, err := runtime.ImageRuntime().NewFromLocal(input.Image)
if err != nil {
if errors.Cause(err) == define.ErrNoSuchImage {
@@ -53,7 +58,7 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) {
input.Name = query.Name
// Take input structure and convert to cliopts
- cliOpts, args, err := common.ContainerCreateToContainerCLIOpts(input)
+ cliOpts, args, err := common.ContainerCreateToContainerCLIOpts(input, rtc.Engine.CgroupManager)
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "make cli opts()"))
return
diff --git a/pkg/bindings/containers/logs.go b/pkg/bindings/containers/logs.go
index 750a6dbe1..a73517bac 100644
--- a/pkg/bindings/containers/logs.go
+++ b/pkg/bindings/containers/logs.go
@@ -1,7 +1,6 @@
package containers
import (
- "bytes"
"context"
"fmt"
"io"
@@ -64,7 +63,6 @@ func Logs(ctx context.Context, nameOrID string, opts LogOptions, stdoutChan, std
if err != nil {
return err
}
- frame = bytes.Replace(frame[0:l], []byte{13}, []byte{10}, -1)
switch fd {
case 0:
diff --git a/pkg/specgen/container_validate.go b/pkg/specgen/container_validate.go
index dc9e6b9d8..a0d36f865 100644
--- a/pkg/specgen/container_validate.go
+++ b/pkg/specgen/container_validate.go
@@ -1,11 +1,13 @@
package specgen
import (
+ "strconv"
"strings"
"github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/pkg/rootless"
"github.com/containers/podman/v2/pkg/util"
+ "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
)
@@ -144,7 +146,38 @@ func (s *SpecGenerator) Validate() error {
//default:
// return errors.New("unrecognized option for cgroups; supported are 'default', 'disabled', 'no-conmon'")
//}
-
+ invalidUlimitFormatError := errors.New("invalid default ulimit definition must be form of type=soft:hard")
+ //set ulimits if not rootless
+ if len(s.ContainerResourceConfig.Rlimits) < 1 && !rootless.IsRootless() {
+ // Containers common defines this as something like nproc=4194304:4194304
+ tmpnproc := containerConfig.Ulimits()
+ var posixLimits []specs.POSIXRlimit
+ for _, limit := range tmpnproc {
+ limitSplit := strings.SplitN(limit, "=", 2)
+ if len(limitSplit) < 2 {
+ return errors.Wrapf(invalidUlimitFormatError, "missing = in %s", limit)
+ }
+ valueSplit := strings.SplitN(limitSplit[1], ":", 2)
+ if len(valueSplit) < 2 {
+ return errors.Wrapf(invalidUlimitFormatError, "missing : in %s", limit)
+ }
+ hard, err := strconv.Atoi(valueSplit[0])
+ if err != nil {
+ return err
+ }
+ soft, err := strconv.Atoi(valueSplit[1])
+ if err != nil {
+ return err
+ }
+ posixLimit := specs.POSIXRlimit{
+ Type: limitSplit[0],
+ Hard: uint64(hard),
+ Soft: uint64(soft),
+ }
+ posixLimits = append(posixLimits, posixLimit)
+ }
+ s.ContainerResourceConfig.Rlimits = posixLimits
+ }
// Namespaces
if err := s.UtsNS.validate(); err != nil {
return err
diff --git a/test/e2e/search_test.go b/test/e2e/search_test.go
index 424a191c5..edd2fedad 100644
--- a/test/e2e/search_test.go
+++ b/test/e2e/search_test.go
@@ -116,6 +116,14 @@ registries = ['{{.Host}}:{{.Port}}']`
Expect(search.LineInOutputContains("docker.io/library/alpine")).To(BeTrue())
})
+ It("podman search format json", func() {
+ search := podmanTest.Podman([]string{"search", "--format", "json", "alpine"})
+ search.WaitWithDefaultTimeout()
+ Expect(search.ExitCode()).To(Equal(0))
+ Expect(search.IsJSONOutputValid()).To(BeTrue())
+ Expect(search.OutputToString()).To(ContainSubstring("docker.io/library/alpine"))
+ })
+
It("podman search no-trunc flag", func() {
search := podmanTest.Podman([]string{"search", "--no-trunc", "alpine"})
search.WaitWithDefaultTimeout()