diff options
Diffstat (limited to 'cmd')
-rw-r--r-- | cmd/podman/containers/create.go | 61 | ||||
-rw-r--r-- | cmd/podman/containers/stats.go | 16 | ||||
-rw-r--r-- | cmd/podman/pods/create.go | 53 |
3 files changed, 87 insertions, 43 deletions
diff --git a/cmd/podman/containers/create.go b/cmd/podman/containers/create.go index 68a17abd0..1e11c53d5 100644 --- a/cmd/podman/containers/create.go +++ b/cmd/podman/containers/create.go @@ -8,7 +8,6 @@ import ( "strings" "github.com/containers/common/pkg/config" - storageTransport "github.com/containers/image/v5/storage" "github.com/containers/image/v5/transports/alltransports" "github.com/containers/podman/v3/cmd/podman/common" "github.com/containers/podman/v3/cmd/podman/registry" @@ -16,9 +15,7 @@ import ( "github.com/containers/podman/v3/pkg/domain/entities" "github.com/containers/podman/v3/pkg/specgen" "github.com/containers/podman/v3/pkg/util" - "github.com/containers/storage" "github.com/pkg/errors" - "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -225,7 +222,6 @@ func createInit(c *cobra.Command) error { } cliVals.Env = env } - if c.Flag("cgroups").Changed && cliVals.CGroupsMode == "split" && registry.IsRemote() { return errors.Errorf("the option --cgroups=%q is not supported in remote mode", cliVals.CGroupsMode) } @@ -236,30 +232,12 @@ func createInit(c *cobra.Command) error { return nil } -// TODO: we should let the backend take care of the pull policy (which it -// does!). The code below is at risk of causing regression and code divergence. func pullImage(imageName string) (string, error) { pullPolicy, err := config.ValidatePullPolicy(cliVals.Pull) if err != nil { return "", err } - // Check if the image is missing and hence if we need to pull it. - imageMissing := true - imageRef, err := alltransports.ParseImageName(imageName) - switch { - case err != nil: - // Assume we specified a local image without the explicit storage transport. - fallthrough - - case imageRef.Transport().Name() == storageTransport.Transport.Name(): - br, err := registry.ImageEngine().Exists(registry.GetContext(), imageName) - if err != nil { - return "", err - } - imageMissing = !br.Value - } - if cliVals.Platform != "" || cliVals.Arch != "" || cliVals.OS != "" { if cliVals.Platform != "" { if cliVals.Arch != "" || cliVals.OS != "" { @@ -271,31 +249,28 @@ func pullImage(imageName string) (string, error) { cliVals.Arch = split[1] } } + } - if pullPolicy != config.PullPolicyAlways { - logrus.Info("--platform --arch and --os causes the pull policy to be \"always\"") - pullPolicy = config.PullPolicyAlways - } + pullReport, pullErr := registry.ImageEngine().Pull(registry.GetContext(), imageName, entities.ImagePullOptions{ + Authfile: cliVals.Authfile, + Quiet: cliVals.Quiet, + Arch: cliVals.Arch, + OS: cliVals.OS, + Variant: cliVals.Variant, + SignaturePolicy: cliVals.SignaturePolicy, + PullPolicy: pullPolicy, + }) + if pullErr != nil { + return "", pullErr } - if imageMissing || pullPolicy == config.PullPolicyAlways { - if pullPolicy == config.PullPolicyNever { - return "", errors.Wrap(storage.ErrImageUnknown, imageName) - } - pullReport, pullErr := registry.ImageEngine().Pull(registry.GetContext(), imageName, entities.ImagePullOptions{ - Authfile: cliVals.Authfile, - Quiet: cliVals.Quiet, - Arch: cliVals.Arch, - OS: cliVals.OS, - Variant: cliVals.Variant, - SignaturePolicy: cliVals.SignaturePolicy, - PullPolicy: pullPolicy, - }) - if pullErr != nil { - return "", pullErr - } + // Return the input name such that the image resolves to correct + // repo/tag in the backend (see #8082). Unless we're referring to + // the image via a transport. + if _, err := alltransports.ParseImageName(imageName); err == nil { imageName = pullReport.Images[0] } + return imageName, nil } @@ -316,6 +291,8 @@ func createPodIfNecessary(s *specgen.SpecGenerator, netOpts *entities.NetOptions Net: netOpts, CreateCommand: os.Args, Hostname: s.ContainerBasicConfig.Hostname, + Cpus: cliVals.CPUS, + CpusetCpus: cliVals.CPUSetCPUs, } // Unset config values we passed to the pod to prevent them being used twice for the container and pod. s.ContainerBasicConfig.Hostname = "" diff --git a/cmd/podman/containers/stats.go b/cmd/podman/containers/stats.go index 27c5147a5..208d5d58f 100644 --- a/cmd/podman/containers/stats.go +++ b/cmd/podman/containers/stats.go @@ -143,7 +143,9 @@ func stats(cmd *cobra.Command, args []string) error { func outputStats(reports []define.ContainerStats) error { headers := report.Headers(define.ContainerStats{}, map[string]string{ "ID": "ID", + "UpTime": "CPU TIME", "CPUPerc": "CPU %", + "AVGCPU": "Avg CPU %", "MemUsage": "MEM USAGE / LIMIT", "MemUsageBytes": "MEM USAGE / LIMIT", "MemPerc": "MEM %", @@ -163,7 +165,7 @@ func outputStats(reports []define.ContainerStats) error { if report.IsJSON(statsOptions.Format) { return outputJSON(stats) } - format := "{{.ID}}\t{{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.MemPerc}}\t{{.NetIO}}\t{{.BlockIO}}\t{{.PIDS}}\n" + format := "{{.ID}}\t{{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.MemPerc}}\t{{.NetIO}}\t{{.BlockIO}}\t{{.PIDS}}\t{{.UpTime}}\t{{.AVGCPU}}\n" if len(statsOptions.Format) > 0 { format = report.NormalizeFormat(statsOptions.Format) } @@ -203,6 +205,14 @@ func (s *containerStats) CPUPerc() string { return floatToPercentString(s.CPU) } +func (s *containerStats) AVGCPU() string { + return floatToPercentString(s.AvgCPU) +} + +func (s *containerStats) Up() string { + return (s.UpTime.String()) +} + func (s *containerStats) MemPerc() string { return floatToPercentString(s.ContainerStats.MemPerc) } @@ -258,7 +268,9 @@ func outputJSON(stats []containerStats) error { type jstat struct { Id string `json:"id"` // nolint Name string `json:"name"` + CPUTime string `json:"cpu_time"` CpuPercent string `json:"cpu_percent"` // nolint + AverageCPU string `json:"avg_cpu"` MemUsage string `json:"mem_usage"` MemPerc string `json:"mem_percent"` NetIO string `json:"net_io"` @@ -270,7 +282,9 @@ func outputJSON(stats []containerStats) error { jstats = append(jstats, jstat{ Id: j.ID(), Name: j.Name, + CPUTime: j.Up(), CpuPercent: j.CPUPerc(), + AverageCPU: j.AVGCPU(), MemUsage: j.MemUsage(), MemPerc: j.MemPerc(), NetIO: j.NetIO(), diff --git a/cmd/podman/pods/create.go b/cmd/podman/pods/create.go index 735dfa78c..03e3ffaa0 100644 --- a/cmd/podman/pods/create.go +++ b/cmd/podman/pods/create.go @@ -5,9 +5,13 @@ import ( "fmt" "io/ioutil" "os" + "runtime" + "sort" + "strconv" "strings" "github.com/containers/common/pkg/completion" + "github.com/containers/common/pkg/sysinfo" "github.com/containers/podman/v3/cmd/podman/common" "github.com/containers/podman/v3/cmd/podman/parse" "github.com/containers/podman/v3/cmd/podman/registry" @@ -16,6 +20,7 @@ import ( "github.com/containers/podman/v3/pkg/errorhandling" "github.com/containers/podman/v3/pkg/specgen" "github.com/containers/podman/v3/pkg/util" + "github.com/docker/docker/pkg/parsers" "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -55,6 +60,14 @@ func init() { common.DefineNetFlags(createCommand) + cpusetflagName := "cpuset-cpus" + flags.StringVar(&createOptions.CpusetCpus, cpusetflagName, "", "CPUs in which to allow execution") + _ = createCommand.RegisterFlagCompletionFunc(cpusetflagName, completion.AutocompleteDefault) + + cpusflagName := "cpus" + flags.Float64Var(&createOptions.Cpus, cpusflagName, 0.000, "set amount of CPUs for the pod") + _ = createCommand.RegisterFlagCompletionFunc(cpusflagName, completion.AutocompleteDefault) + cgroupParentflagName := "cgroup-parent" flags.StringVar(&createOptions.CGroupParent, cgroupParentflagName, "", "Set parent cgroup for the pod") _ = createCommand.RegisterFlagCompletionFunc(cgroupParentflagName, completion.AutocompleteDefault) @@ -185,6 +198,46 @@ func create(cmd *cobra.Command, args []string) error { } } + numCPU := sysinfo.NumCPU() + if numCPU == 0 { + numCPU = runtime.NumCPU() + } + if createOptions.Cpus > float64(numCPU) { + createOptions.Cpus = float64(numCPU) + } + copy := createOptions.CpusetCpus + cpuSet := createOptions.Cpus + if cpuSet == 0 { + cpuSet = float64(sysinfo.NumCPU()) + } + ret, err := parsers.ParseUintList(copy) + copy = "" + if err != nil { + errors.Wrapf(err, "could not parse list") + } + var vals []int + for ind, val := range ret { + if val { + vals = append(vals, ind) + } + } + sort.Ints(vals) + for ind, core := range vals { + if core > int(cpuSet) { + if copy == "" { + copy = "0-" + strconv.Itoa(int(cpuSet)) + createOptions.CpusetCpus = copy + break + } else { + createOptions.CpusetCpus = copy + break + } + } else if ind != 0 { + copy += "," + strconv.Itoa(core) + } else { + copy = "" + strconv.Itoa(core) + } + } response, err := registry.ContainerEngine().PodCreate(context.Background(), createOptions) if err != nil { return err |