summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/common/completion.go31
-rw-r--r--cmd/podman/containers/create.go3
-rw-r--r--cmd/podman/images/save.go2
-rw-r--r--cmd/podman/images/trust_set.go2
-rw-r--r--cmd/podman/pods/ps.go2
-rw-r--r--cmd/podman/root.go2
-rw-r--r--libpod/container_internal_linux.go5
-rw-r--r--libpod/kube.go15
-rw-r--r--libpod/networking_linux.go2
-rw-r--r--libpod/options.go3
-rw-r--r--libpod/runtime_ctr.go5
-rw-r--r--libpod/runtime_pod.go2
-rw-r--r--pkg/api/handlers/compat/images_build.go29
-rw-r--r--pkg/domain/filters/containers.go3
-rw-r--r--pkg/domain/filters/pods.go7
-rw-r--r--pkg/domain/infra/abi/network.go2
-rw-r--r--pkg/domain/infra/abi/system.go3
-rw-r--r--pkg/machine/e2e/list_test.go2
-rw-r--r--pkg/signal/signal_common.go4
-rw-r--r--pkg/signal/signal_linux.go8
-rw-r--r--pkg/signal/signal_linux_mipsx.go8
-rw-r--r--pkg/signal/signal_unix.go4
-rw-r--r--pkg/signal/signal_unsupported.go4
-rw-r--r--pkg/specgen/container_validate.go2
-rw-r--r--pkg/specgen/generate/kube/kube.go3
-rw-r--r--pkg/specgen/generate/ports.go2
-rw-r--r--pkg/specgen/generate/security.go5
-rw-r--r--pkg/specgen/namespaces.go3
-rw-r--r--pkg/util/utils.go10
-rw-r--r--test/apiv2/10-images.at12
-rw-r--r--test/system/015-help.bats58
31 files changed, 154 insertions, 89 deletions
diff --git a/cmd/podman/common/completion.go b/cmd/podman/common/completion.go
index c29218d01..285cab1b9 100644
--- a/cmd/podman/common/completion.go
+++ b/cmd/podman/common/completion.go
@@ -7,6 +7,7 @@ import (
"reflect"
"strconv"
"strings"
+ "unicode"
libimageDefine "github.com/containers/common/libimage/define"
"github.com/containers/common/libnetwork/types"
@@ -17,6 +18,7 @@ import (
"github.com/containers/podman/v4/libpod/events"
"github.com/containers/podman/v4/pkg/domain/entities"
"github.com/containers/podman/v4/pkg/rootless"
+ "github.com/containers/podman/v4/pkg/signal"
systemdDefine "github.com/containers/podman/v4/pkg/systemd/define"
"github.com/containers/podman/v4/pkg/util"
"github.com/spf13/cobra"
@@ -601,7 +603,9 @@ func AutocompleteRunlabelCommand(cmd *cobra.Command, args []string, toComplete s
return nil, cobra.ShellCompDirectiveNoFileComp
}
if len(args) == 0 {
- // FIXME: What labels can we recommend here?
+ // This is unfortunate because the argument order is label followed by image.
+ // If it would be the other way around we could inspect the first arg and get
+ // all labels from it to suggest them.
return nil, cobra.ShellCompDirectiveNoFileComp
}
if len(args) == 1 {
@@ -806,8 +810,7 @@ func AutocompleteLogDriver(cmd *cobra.Command, args []string, toComplete string)
// AutocompleteLogOpt - Autocomplete log-opt options.
// -> "path=", "tag="
func AutocompleteLogOpt(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
- // FIXME: are these the only one? the man page states these but in the current shell completion they are more options
- logOptions := []string{"path=", "tag="}
+ logOptions := []string{"path=", "tag=", "max-size="}
if strings.HasPrefix(toComplete, "path=") {
return nil, cobra.ShellCompDirectiveDefault
}
@@ -846,10 +849,26 @@ func AutocompleteSecurityOption(cmd *cobra.Command, args []string, toComplete st
}
// AutocompleteStopSignal - Autocomplete stop signal options.
-// -> "SIGHUP", "SIGINT", "SIGKILL", "SIGTERM"
+// Autocompletes signals both lower or uppercase depending on the user input.
func AutocompleteStopSignal(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
- // FIXME: add more/different signals?
- stopSignals := []string{"SIGHUP", "SIGINT", "SIGKILL", "SIGTERM"}
+ // convertCase will convert a string to lowercase only if the user input is lowercase
+ convertCase := func(s string) string { return s }
+ if len(toComplete) > 0 && unicode.IsLower(rune(toComplete[0])) {
+ convertCase = strings.ToLower
+ }
+
+ prefix := ""
+ // if input starts with "SI" we have to add SIG in front
+ // since the signal map does not have this prefix but the option
+ // allows signals with and without SIG prefix
+ if strings.HasPrefix(toComplete, convertCase("SI")) {
+ prefix = "SIG"
+ }
+
+ stopSignals := make([]string, 0, len(signal.SignalMap))
+ for sig := range signal.SignalMap {
+ stopSignals = append(stopSignals, convertCase(prefix+sig))
+ }
return stopSignals, cobra.ShellCompDirectiveNoFileComp
}
diff --git a/cmd/podman/containers/create.go b/cmd/podman/containers/create.go
index 29e138e30..c62ddd6eb 100644
--- a/cmd/podman/containers/create.go
+++ b/cmd/podman/containers/create.go
@@ -9,6 +9,7 @@ import (
"github.com/containers/common/pkg/completion"
"github.com/containers/common/pkg/config"
+ cutil "github.com/containers/common/pkg/util"
"github.com/containers/image/v5/transports/alltransports"
"github.com/containers/image/v5/types"
"github.com/containers/podman/v4/cmd/podman/common"
@@ -116,7 +117,7 @@ func create(cmd *cobra.Command, args []string) error {
if !cmd.Flags().Changed("pod") {
return errors.New("must specify pod value with init-ctr")
}
- if !util.StringInSlice(initctr, []string{define.AlwaysInitContainer, define.OneShotInitContainer}) {
+ if !cutil.StringInSlice(initctr, []string{define.AlwaysInitContainer, define.OneShotInitContainer}) {
return errors.Errorf("init-ctr value must be '%s' or '%s'", define.AlwaysInitContainer, define.OneShotInitContainer)
}
cliVals.InitContainerType = initctr
diff --git a/cmd/podman/images/save.go b/cmd/podman/images/save.go
index 3394c2e99..d85d688ee 100644
--- a/cmd/podman/images/save.go
+++ b/cmd/podman/images/save.go
@@ -6,12 +6,12 @@ import (
"strings"
"github.com/containers/common/pkg/completion"
+ "github.com/containers/common/pkg/util"
"github.com/containers/podman/v4/cmd/podman/common"
"github.com/containers/podman/v4/cmd/podman/parse"
"github.com/containers/podman/v4/cmd/podman/registry"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/domain/entities"
- "github.com/containers/podman/v4/pkg/util"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"golang.org/x/term"
diff --git a/cmd/podman/images/trust_set.go b/cmd/podman/images/trust_set.go
index fff035d12..f4ff0cffc 100644
--- a/cmd/podman/images/trust_set.go
+++ b/cmd/podman/images/trust_set.go
@@ -5,10 +5,10 @@ import (
"regexp"
"github.com/containers/common/pkg/completion"
+ "github.com/containers/common/pkg/util"
"github.com/containers/podman/v4/cmd/podman/common"
"github.com/containers/podman/v4/cmd/podman/registry"
"github.com/containers/podman/v4/pkg/domain/entities"
- "github.com/containers/podman/v4/pkg/util"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
diff --git a/cmd/podman/pods/ps.go b/cmd/podman/pods/ps.go
index 1275e65dc..a89448275 100644
--- a/cmd/podman/pods/ps.go
+++ b/cmd/podman/pods/ps.go
@@ -24,7 +24,7 @@ var (
// Command: podman pod _ps_
psCmd = &cobra.Command{
- Use: "ps [options]",
+ Use: "ps [options]",
Aliases: []string{"ls", "list"},
Short: "List pods",
Long: psDescription,
diff --git a/cmd/podman/root.go b/cmd/podman/root.go
index 2bd4fa723..1892ff9f7 100644
--- a/cmd/podman/root.go
+++ b/cmd/podman/root.go
@@ -423,7 +423,7 @@ func rootFlags(cmd *cobra.Command, opts *entities.PodmanConfig) {
// -s is deprecated due to conflict with -s on subcommands
storageDriverFlagName := "storage-driver"
pFlags.StringVar(&opts.StorageDriver, storageDriverFlagName, "", "Select which storage driver is used to manage storage of images and containers")
- _ = cmd.RegisterFlagCompletionFunc(storageDriverFlagName, completion.AutocompleteNone) //TODO: what can we recommend here?
+ _ = cmd.RegisterFlagCompletionFunc(storageDriverFlagName, completion.AutocompleteNone)
tmpdirFlagName := "tmpdir"
pFlags.StringVar(&opts.Engine.TmpDir, tmpdirFlagName, "", "Path to the tmp directory for libpod state content.\n\nNote: use the environment variable 'TMPDIR' to change the temporary storage location for container images, '/var/tmp'.\n")
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index d7683cce9..82e5fa992 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -36,6 +36,7 @@ import (
"github.com/containers/common/pkg/config"
"github.com/containers/common/pkg/subscriptions"
"github.com/containers/common/pkg/umask"
+ cutil "github.com/containers/common/pkg/util"
is "github.com/containers/image/v5/storage"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/libpod/events"
@@ -393,7 +394,7 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
overrides := c.getUserOverrides()
execUser, err := lookup.GetUserGroupInfo(c.state.Mountpoint, c.config.User, overrides)
if err != nil {
- if util.StringInSlice(c.config.User, c.config.HostUsers) {
+ if cutil.StringInSlice(c.config.User, c.config.HostUsers) {
execUser, err = lookupHostUser(c.config.User)
}
if err != nil {
@@ -2389,7 +2390,7 @@ func (c *Container) generateResolvConf() error {
}
if len(c.config.DNSSearch) > 0 || len(c.runtime.config.Containers.DNSSearches) > 0 {
- if !util.StringInSlice(".", c.config.DNSSearch) {
+ if !cutil.StringInSlice(".", c.config.DNSSearch) {
search = append(search, c.runtime.config.Containers.DNSSearches...)
search = append(search, c.config.DNSSearch...)
}
diff --git a/libpod/kube.go b/libpod/kube.go
index 5a5fe9d35..20c4612d1 100644
--- a/libpod/kube.go
+++ b/libpod/kube.go
@@ -14,6 +14,7 @@ import (
"github.com/containers/common/libnetwork/types"
"github.com/containers/common/pkg/config"
+ cutil "github.com/containers/common/pkg/util"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/env"
v1 "github.com/containers/podman/v4/pkg/k8s.io/api/core/v1"
@@ -515,7 +516,7 @@ func simplePodWithV1Containers(ctx context.Context, ctrs []*Container) (*v1.Pod,
podDNS.Nameservers = make([]string, 0)
}
for _, s := range servers {
- if !util.StringInSlice(s, podDNS.Nameservers) { // only append if it does not exist
+ if !cutil.StringInSlice(s, podDNS.Nameservers) { // only append if it does not exist
podDNS.Nameservers = append(podDNS.Nameservers, s)
}
}
@@ -526,7 +527,7 @@ func simplePodWithV1Containers(ctx context.Context, ctrs []*Container) (*v1.Pod,
podDNS.Searches = make([]string, 0)
}
for _, d := range domains {
- if !util.StringInSlice(d, podDNS.Searches) { // only append if it does not exist
+ if !cutil.StringInSlice(d, podDNS.Searches) { // only append if it does not exist
podDNS.Searches = append(podDNS.Searches, d)
}
}
@@ -543,7 +544,7 @@ func simplePodWithV1Containers(ctx context.Context, ctrs []*Container) (*v1.Pod,
podName := removeUnderscores(ctrs[0].Name())
// Check if the pod name and container name will end up conflicting
// Append -pod if so
- if util.StringInSlice(podName, ctrNames) {
+ if cutil.StringInSlice(podName, ctrNames) {
podName += "-pod"
}
@@ -824,7 +825,7 @@ func libpodMountsToKubeVolumeMounts(c *Container) ([]v1.VolumeMount, []v1.Volume
// generateKubePersistentVolumeClaim converts a ContainerNamedVolume to a Kubernetes PersistentVolumeClaim
func generateKubePersistentVolumeClaim(v *ContainerNamedVolume) (v1.VolumeMount, v1.Volume) {
- ro := util.StringInSlice("ro", v.Options)
+ ro := cutil.StringInSlice("ro", v.Options)
// To avoid naming conflicts with any host path mounts, add a unique suffix to the volume's name.
name := v.Name + "-pvc"
@@ -857,7 +858,7 @@ func generateKubeVolumeMount(m specs.Mount) (v1.VolumeMount, v1.Volume, error) {
name += "-host"
vm.Name = name
vm.MountPath = m.Destination
- if util.StringInSlice("ro", m.Options) {
+ if cutil.StringInSlice("ro", m.Options) {
vm.ReadOnly = true
}
@@ -915,7 +916,7 @@ func determineCapAddDropFromCapabilities(defaultCaps, containerCaps []string) *v
// Find caps in the defaultCaps but not in the container's
// those indicate a dropped cap
for _, capability := range defaultCaps {
- if !util.StringInSlice(capability, containerCaps) {
+ if !cutil.StringInSlice(capability, containerCaps) {
if _, ok := dedupDrop[capability]; !ok {
drop = append(drop, v1.Capability(capability))
dedupDrop[capability] = true
@@ -925,7 +926,7 @@ func determineCapAddDropFromCapabilities(defaultCaps, containerCaps []string) *v
// Find caps in the container but not in the defaults; those indicate
// an added cap
for _, capability := range containerCaps {
- if !util.StringInSlice(capability, defaultCaps) {
+ if !cutil.StringInSlice(capability, defaultCaps) {
if _, ok := dedupAdd[capability]; !ok {
add = append(add, v1.Capability(capability))
dedupAdd[capability] = true
diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go
index 0c124cf0b..73e64530e 100644
--- a/libpod/networking_linux.go
+++ b/libpod/networking_linux.go
@@ -25,13 +25,13 @@ import (
"github.com/containers/common/pkg/config"
"github.com/containers/common/pkg/machine"
"github.com/containers/common/pkg/netns"
+ "github.com/containers/common/pkg/util"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/libpod/events"
"github.com/containers/podman/v4/pkg/errorhandling"
"github.com/containers/podman/v4/pkg/namespaces"
"github.com/containers/podman/v4/pkg/resolvconf"
"github.com/containers/podman/v4/pkg/rootless"
- "github.com/containers/podman/v4/pkg/util"
"github.com/containers/podman/v4/utils"
"github.com/containers/storage/pkg/lockfile"
spec "github.com/opencontainers/runtime-spec/specs-go"
diff --git a/libpod/options.go b/libpod/options.go
index feb89510f..a02c05537 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -12,6 +12,7 @@ import (
nettypes "github.com/containers/common/libnetwork/types"
"github.com/containers/common/pkg/config"
"github.com/containers/common/pkg/secrets"
+ cutil "github.com/containers/common/pkg/util"
"github.com/containers/image/v5/manifest"
"github.com/containers/image/v5/types"
"github.com/containers/podman/v4/libpod/define"
@@ -605,7 +606,7 @@ func WithSdNotifyMode(mode string) CtrCreateOption {
}
// verify values
- if len(mode) > 0 && !util.StringInSlice(strings.ToLower(mode), SdNotifyModeValues) {
+ if len(mode) > 0 && !cutil.StringInSlice(strings.ToLower(mode), SdNotifyModeValues) {
return errors.Wrapf(define.ErrInvalidArg, "--sdnotify values must be one of %q", strings.Join(SdNotifyModeValues, ", "))
}
diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go
index 2eaa77572..bdfc102ba 100644
--- a/libpod/runtime_ctr.go
+++ b/libpod/runtime_ctr.go
@@ -13,6 +13,7 @@ import (
"github.com/containers/common/libnetwork/types"
"github.com/containers/common/pkg/cgroups"
"github.com/containers/common/pkg/config"
+ cutil "github.com/containers/common/pkg/util"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/libpod/events"
"github.com/containers/podman/v4/libpod/shutdown"
@@ -246,7 +247,7 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
for _, opts := range ctr.config.Networks {
if opts.InterfaceName != "" {
// check that no name is assigned to more than network
- if util.StringInSlice(opts.InterfaceName, usedIfNames) {
+ if cutil.StringInSlice(opts.InterfaceName, usedIfNames) {
return nil, errors.Errorf("network interface name %q is already assigned to another network", opts.InterfaceName)
}
usedIfNames = append(usedIfNames, opts.InterfaceName)
@@ -262,7 +263,7 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
if opts.InterfaceName == "" {
for i < 100000 {
ifName := fmt.Sprintf("eth%d", i)
- if !util.StringInSlice(ifName, usedIfNames) {
+ if !cutil.StringInSlice(ifName, usedIfNames) {
opts.InterfaceName = ifName
usedIfNames = append(usedIfNames, ifName)
break
diff --git a/libpod/runtime_pod.go b/libpod/runtime_pod.go
index dca0ffc8a..ee3d40484 100644
--- a/libpod/runtime_pod.go
+++ b/libpod/runtime_pod.go
@@ -4,8 +4,8 @@ import (
"context"
"time"
+ "github.com/containers/common/pkg/util"
"github.com/containers/podman/v4/libpod/define"
- "github.com/containers/podman/v4/pkg/util"
"github.com/pkg/errors"
)
diff --git a/pkg/api/handlers/compat/images_build.go b/pkg/api/handlers/compat/images_build.go
index bcd102901..0a1bc941d 100644
--- a/pkg/api/handlers/compat/images_build.go
+++ b/pkg/api/handlers/compat/images_build.go
@@ -674,15 +674,17 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
enc := json.NewEncoder(body)
enc.SetEscapeHTML(true)
+ var stepErrors []string
for {
- m := struct {
+ type BuildResponse struct {
Stream string `json:"stream,omitempty"`
Error *jsonmessage.JSONError `json:"errorDetail,omitempty"`
// NOTE: `error` is being deprecated check https://github.com/moby/moby/blob/master/pkg/jsonmessage/jsonmessage.go#L148
ErrorMessage string `json:"error,omitempty"` // deprecate this slowly
Aux json.RawMessage `json:"aux,omitempty"`
- }{}
+ }
+ m := BuildResponse{}
select {
case e := <-stdout.Chan():
@@ -698,12 +700,27 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
}
flush()
case e := <-auxout.Chan():
- m.Stream = string(e)
- if err := enc.Encode(m); err != nil {
- stderr.Write([]byte(err.Error()))
+ if !query.Quiet {
+ m.Stream = string(e)
+ if err := enc.Encode(m); err != nil {
+ stderr.Write([]byte(err.Error()))
+ }
+ flush()
+ } else {
+ stepErrors = append(stepErrors, string(e))
}
- flush()
case e := <-stderr.Chan():
+ // Docker-API Compat parity : Build failed so
+ // output all step errors irrespective of quiet
+ // flag.
+ for _, stepError := range stepErrors {
+ t := BuildResponse{}
+ t.Stream = stepError
+ if err := enc.Encode(t); err != nil {
+ stderr.Write([]byte(err.Error()))
+ }
+ flush()
+ }
m.ErrorMessage = string(e)
m.Error = &jsonmessage.JSONError{
Message: m.ErrorMessage,
diff --git a/pkg/domain/filters/containers.go b/pkg/domain/filters/containers.go
index 3e5b9cad9..e2ab8d70c 100644
--- a/pkg/domain/filters/containers.go
+++ b/pkg/domain/filters/containers.go
@@ -6,6 +6,7 @@ import (
"strings"
"time"
+ cutil "github.com/containers/common/pkg/util"
"github.com/containers/podman/v4/libpod"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/util"
@@ -257,7 +258,7 @@ func GenerateContainerFilterFuncs(filter string, filterValues []string, r *libpo
return false
}
for _, net := range networks {
- if util.StringInSlice(net, inputNetNames) {
+ if cutil.StringInSlice(net, inputNetNames) {
return true
}
}
diff --git a/pkg/domain/filters/pods.go b/pkg/domain/filters/pods.go
index e22480006..c2ed359f5 100644
--- a/pkg/domain/filters/pods.go
+++ b/pkg/domain/filters/pods.go
@@ -4,6 +4,7 @@ import (
"strconv"
"strings"
+ cutil "github.com/containers/common/pkg/util"
"github.com/containers/podman/v4/libpod"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/util"
@@ -57,7 +58,7 @@ func GeneratePodFilterFunc(filter string, filterValues []string, r *libpod.Runti
}, nil
case "ctr-status":
for _, filterValue := range filterValues {
- if !util.StringInSlice(filterValue, []string{"created", "running", "paused", "stopped", "exited", "unknown"}) {
+ if !cutil.StringInSlice(filterValue, []string{"created", "running", "paused", "stopped", "exited", "unknown"}) {
return nil, errors.Errorf("%s is not a valid status", filterValue)
}
}
@@ -94,7 +95,7 @@ func GeneratePodFilterFunc(filter string, filterValues []string, r *libpod.Runti
}, nil
case "status":
for _, filterValue := range filterValues {
- if !util.StringInSlice(filterValue, []string{"stopped", "running", "paused", "exited", "dead", "created", "degraded"}) {
+ if !cutil.StringInSlice(filterValue, []string{"stopped", "running", "paused", "exited", "dead", "created", "degraded"}) {
return nil, errors.Errorf("%s is not a valid pod status", filterValue)
}
}
@@ -150,7 +151,7 @@ func GeneratePodFilterFunc(filter string, filterValues []string, r *libpod.Runti
return false
}
for _, net := range networks {
- if util.StringInSlice(net, inputNetNames) {
+ if cutil.StringInSlice(net, inputNetNames) {
return true
}
}
diff --git a/pkg/domain/infra/abi/network.go b/pkg/domain/infra/abi/network.go
index 910008fc7..47f7917f4 100644
--- a/pkg/domain/infra/abi/network.go
+++ b/pkg/domain/infra/abi/network.go
@@ -5,9 +5,9 @@ import (
"github.com/containers/common/libnetwork/types"
netutil "github.com/containers/common/libnetwork/util"
+ "github.com/containers/common/pkg/util"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/domain/entities"
- "github.com/containers/podman/v4/pkg/util"
"github.com/pkg/errors"
)
diff --git a/pkg/domain/infra/abi/system.go b/pkg/domain/infra/abi/system.go
index 10f3e70b1..2ce190464 100644
--- a/pkg/domain/infra/abi/system.go
+++ b/pkg/domain/infra/abi/system.go
@@ -10,6 +10,7 @@ import (
"github.com/containers/common/pkg/cgroups"
"github.com/containers/common/pkg/config"
+ cutil "github.com/containers/common/pkg/util"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/domain/entities"
"github.com/containers/podman/v4/pkg/domain/entities/reports"
@@ -307,7 +308,7 @@ func (ic *ContainerEngine) SystemDf(ctx context.Context, options entities.System
reclaimableSize += volSize
}
for _, viu := range inUse {
- if util.StringInSlice(viu, runningContainers) {
+ if cutil.StringInSlice(viu, runningContainers) {
consInUse++
}
}
diff --git a/pkg/machine/e2e/list_test.go b/pkg/machine/e2e/list_test.go
index 0bc867047..1c8c6ac81 100644
--- a/pkg/machine/e2e/list_test.go
+++ b/pkg/machine/e2e/list_test.go
@@ -3,7 +3,7 @@ package e2e
import (
"strings"
- "github.com/containers/buildah/util"
+ "github.com/containers/common/pkg/util"
"github.com/containers/podman/v4/cmd/podman/machine"
jsoniter "github.com/json-iterator/go"
. "github.com/onsi/ginkgo"
diff --git a/pkg/signal/signal_common.go b/pkg/signal/signal_common.go
index 5ea67843a..fe5a76dae 100644
--- a/pkg/signal/signal_common.go
+++ b/pkg/signal/signal_common.go
@@ -17,7 +17,7 @@ func ParseSignal(rawSignal string) (syscall.Signal, error) {
}
return syscall.Signal(s), nil
}
- sig, ok := signalMap[strings.TrimPrefix(strings.ToUpper(rawSignal), "SIG")]
+ sig, ok := SignalMap[strings.TrimPrefix(strings.ToUpper(rawSignal), "SIG")]
if !ok {
return -1, fmt.Errorf("invalid signal: %s", rawSignal)
}
@@ -32,7 +32,7 @@ func ParseSignalNameOrNumber(rawSignal string) (syscall.Signal, error) {
if err == nil {
return s, nil
}
- for k, v := range signalMap {
+ for k, v := range SignalMap {
if k == strings.ToUpper(basename) {
return v, nil
}
diff --git a/pkg/signal/signal_linux.go b/pkg/signal/signal_linux.go
index 21e09c9fe..a114ea019 100644
--- a/pkg/signal/signal_linux.go
+++ b/pkg/signal/signal_linux.go
@@ -23,8 +23,8 @@ const (
SIGWINCH = syscall.SIGWINCH // For cross-compilation with Windows
)
-// signalMap is a map of Linux signals.
-var signalMap = map[string]syscall.Signal{
+// SignalMap is a map of Linux signals.
+var SignalMap = map[string]syscall.Signal{
"ABRT": unix.SIGABRT,
"ALRM": unix.SIGALRM,
"BUS": unix.SIGBUS,
@@ -94,8 +94,8 @@ var signalMap = map[string]syscall.Signal{
// CatchAll catches all signals and relays them to the specified channel.
func CatchAll(sigc chan os.Signal) {
- handledSigs := make([]os.Signal, 0, len(signalMap))
- for _, s := range signalMap {
+ handledSigs := make([]os.Signal, 0, len(SignalMap))
+ for _, s := range SignalMap {
handledSigs = append(handledSigs, s)
}
signal.Notify(sigc, handledSigs...)
diff --git a/pkg/signal/signal_linux_mipsx.go b/pkg/signal/signal_linux_mipsx.go
index 52b07aaf4..9021a10e7 100644
--- a/pkg/signal/signal_linux_mipsx.go
+++ b/pkg/signal/signal_linux_mipsx.go
@@ -24,8 +24,8 @@ const (
SIGWINCH = syscall.SIGWINCH
)
-// signalMap is a map of Linux signals.
-var signalMap = map[string]syscall.Signal{
+// SignalMap is a map of Linux signals.
+var SignalMap = map[string]syscall.Signal{
"ABRT": unix.SIGABRT,
"ALRM": unix.SIGALRM,
"BUS": unix.SIGBUS,
@@ -95,8 +95,8 @@ var signalMap = map[string]syscall.Signal{
// CatchAll catches all signals and relays them to the specified channel.
func CatchAll(sigc chan os.Signal) {
- handledSigs := make([]os.Signal, 0, len(signalMap))
- for _, s := range signalMap {
+ handledSigs := make([]os.Signal, 0, len(SignalMap))
+ for _, s := range SignalMap {
handledSigs = append(handledSigs, s)
}
signal.Notify(sigc, handledSigs...)
diff --git a/pkg/signal/signal_unix.go b/pkg/signal/signal_unix.go
index c0aa62d21..0f43e21b7 100644
--- a/pkg/signal/signal_unix.go
+++ b/pkg/signal/signal_unix.go
@@ -16,12 +16,12 @@ const (
SIGWINCH = syscall.SIGWINCH
)
-// signalMap is a map of Linux signals.
+// SignalMap is a map of Linux signals.
// These constants are sourced from the Linux version of golang.org/x/sys/unix
// (I don't see much risk of this changing).
// This should work as long as Podman only runs containers on Linux, which seems
// a safe assumption for now.
-var signalMap = map[string]syscall.Signal{
+var SignalMap = map[string]syscall.Signal{
"ABRT": syscall.Signal(0x6),
"ALRM": syscall.Signal(0xe),
"BUS": syscall.Signal(0x7),
diff --git a/pkg/signal/signal_unsupported.go b/pkg/signal/signal_unsupported.go
index d8bba7c90..9d0cee317 100644
--- a/pkg/signal/signal_unsupported.go
+++ b/pkg/signal/signal_unsupported.go
@@ -16,12 +16,12 @@ const (
SIGWINCH = syscall.Signal(0xff)
)
-// signalMap is a map of Linux signals.
+// SignalMap is a map of Linux signals.
// These constants are sourced from the Linux version of golang.org/x/sys/unix
// (I don't see much risk of this changing).
// This should work as long as Podman only runs containers on Linux, which seems
// a safe assumption for now.
-var signalMap = map[string]syscall.Signal{
+var SignalMap = map[string]syscall.Signal{
"ABRT": syscall.Signal(0x6),
"ALRM": syscall.Signal(0xe),
"BUS": syscall.Signal(0x7),
diff --git a/pkg/specgen/container_validate.go b/pkg/specgen/container_validate.go
index 355fbc368..532a2094f 100644
--- a/pkg/specgen/container_validate.go
+++ b/pkg/specgen/container_validate.go
@@ -4,9 +4,9 @@ import (
"strconv"
"strings"
+ "github.com/containers/common/pkg/util"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/rootless"
- "github.com/containers/podman/v4/pkg/util"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
)
diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go
index f37d79798..689c740f0 100644
--- a/pkg/specgen/generate/kube/kube.go
+++ b/pkg/specgen/generate/kube/kube.go
@@ -16,6 +16,7 @@ import (
"github.com/containers/common/libnetwork/types"
"github.com/containers/common/pkg/parse"
"github.com/containers/common/pkg/secrets"
+ cutil "github.com/containers/common/pkg/util"
"github.com/containers/image/v5/manifest"
"github.com/containers/podman/v4/libpod/define"
ann "github.com/containers/podman/v4/pkg/annotations"
@@ -356,7 +357,7 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener
// a selinux mount option exists for it
for k, v := range opts.Annotations {
// Make sure the z/Z option is not already there (from editing the YAML)
- if strings.Replace(k, define.BindMountPrefix, "", 1) == volumeSource.Source && !util.StringInSlice("z", options) && !util.StringInSlice("Z", options) {
+ if strings.Replace(k, define.BindMountPrefix, "", 1) == volumeSource.Source && !cutil.StringInSlice("z", options) && !cutil.StringInSlice("Z", options) {
options = append(options, v)
}
}
diff --git a/pkg/specgen/generate/ports.go b/pkg/specgen/generate/ports.go
index bec548d3b..4243630e2 100644
--- a/pkg/specgen/generate/ports.go
+++ b/pkg/specgen/generate/ports.go
@@ -10,9 +10,9 @@ import (
"github.com/containers/common/libnetwork/types"
"github.com/containers/podman/v4/utils"
+ "github.com/containers/common/pkg/util"
"github.com/containers/podman/v4/pkg/specgen"
"github.com/containers/podman/v4/pkg/specgenutil"
- "github.com/containers/podman/v4/pkg/util"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
diff --git a/pkg/specgen/generate/security.go b/pkg/specgen/generate/security.go
index ec52164ab..7268ec318 100644
--- a/pkg/specgen/generate/security.go
+++ b/pkg/specgen/generate/security.go
@@ -7,6 +7,7 @@ import (
"github.com/containers/common/pkg/apparmor"
"github.com/containers/common/pkg/capabilities"
"github.com/containers/common/pkg/config"
+ cutil "github.com/containers/common/pkg/util"
"github.com/containers/podman/v4/libpod"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/specgen"
@@ -120,7 +121,7 @@ func securityConfigureGenerator(s *specgen.SpecGenerator, g *generate.Generator,
// capabilities, required to run the container.
var capsRequiredRequested []string
for key, val := range s.Labels {
- if util.StringInSlice(key, capabilities.ContainerImageLabels) {
+ if cutil.StringInSlice(key, capabilities.ContainerImageLabels) {
capsRequiredRequested = strings.Split(val, ",")
}
}
@@ -132,7 +133,7 @@ func securityConfigureGenerator(s *specgen.SpecGenerator, g *generate.Generator,
}
// Verify all capRequired are in the capList
for _, cap := range capsRequired {
- if !util.StringInSlice(cap, caplist) {
+ if !cutil.StringInSlice(cap, caplist) {
privCapsRequired = append(privCapsRequired, cap)
}
}
diff --git a/pkg/specgen/namespaces.go b/pkg/specgen/namespaces.go
index 7a7ca2706..5a3b94ca4 100644
--- a/pkg/specgen/namespaces.go
+++ b/pkg/specgen/namespaces.go
@@ -8,6 +8,7 @@ import (
"github.com/containers/common/libnetwork/types"
"github.com/containers/common/pkg/cgroups"
+ cutil "github.com/containers/common/pkg/util"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/rootless"
"github.com/containers/podman/v4/pkg/util"
@@ -472,7 +473,7 @@ func ParseNetworkFlag(networks []string) (Namespace, map[string]types.PerNetwork
if parts[0] == "" {
return toReturn, nil, nil, errors.Wrapf(define.ErrInvalidArg, "network name cannot be empty")
}
- if util.StringInSlice(parts[0], []string{string(Bridge), string(Slirp), string(FromPod), string(NoNetwork),
+ if cutil.StringInSlice(parts[0], []string{string(Bridge), string(Slirp), string(FromPod), string(NoNetwork),
string(Default), string(Private), string(Path), string(FromContainer), string(Host)}) {
return toReturn, nil, nil, errors.Wrapf(define.ErrInvalidArg, "can only set extra network names, selected mode %s conflicts with bridge", parts[0])
}
diff --git a/pkg/util/utils.go b/pkg/util/utils.go
index a0bf8b50d..1b7663330 100644
--- a/pkg/util/utils.go
+++ b/pkg/util/utils.go
@@ -17,6 +17,7 @@ import (
"github.com/BurntSushi/toml"
"github.com/containers/common/pkg/config"
+ "github.com/containers/common/pkg/util"
"github.com/containers/image/v5/types"
"github.com/containers/podman/v4/pkg/errorhandling"
"github.com/containers/podman/v4/pkg/namespaces"
@@ -78,14 +79,9 @@ func ParseRegistryCreds(creds string) (*types.DockerAuthConfig, error) {
}, nil
}
-// StringInSlice determines if a string is in a string slice, returns bool
+// StringInSlice is depracated, use containers/common/pkg/util/StringInSlice
func StringInSlice(s string, sl []string) bool {
- for _, i := range sl {
- if i == s {
- return true
- }
- }
- return false
+ return util.StringInSlice(s, sl)
}
// StringMatchRegexSlice determines if a given string matches one of the given regexes, returns bool
diff --git a/test/apiv2/10-images.at b/test/apiv2/10-images.at
index fd04e3f1b..13aaea317 100644
--- a/test/apiv2/10-images.at
+++ b/test/apiv2/10-images.at
@@ -225,6 +225,18 @@ t POST "images/load" ${TMPD}/test.tar 200 \
t GET libpod/images/quay.io/libpod/alpine:latest/exists 204
t GET libpod/images/quay.io/libpod/busybox:latest/exists 204
+CONTAINERFILE_WITH_ERR_TAR="${TMPD}/containerfile.tar"
+cat > $TMPD/containerfile << EOF
+FROM quay.io/fedora/fedora
+RUN echo 'some error' >&2
+EOF
+tar --format=posix -C $TMPD -cvf ${CONTAINERFILE_WITH_ERR_TAR} containerfile &> /dev/null
+t POST "build?q=1&dockerfile=containerfile" $CONTAINERFILE_WITH_ERR_TAR 200
+response_output=$(cat "$WORKDIR/curl.result.out")
+if [[ ${response_output} == *"some error"* ]];then
+ _show_ok 0 "compat quiet build" "~ $response_output" "found output from stderr in API"
+fi
+
cleanBuildTest
# vim: filetype=sh
diff --git a/test/system/015-help.bats b/test/system/015-help.bats
index 5757d51dc..1356c99a0 100644
--- a/test/system/015-help.bats
+++ b/test/system/015-help.bats
@@ -34,10 +34,16 @@ function check_help() {
# has no ' [options]'
is "$usage " " $command_string .*" "Usage string matches command"
+ # Strip off the leading command string; we no longer need it
+ usage=$(sed -e "s/^ $command_string \?//" <<<"$usage")
+
# If usage ends in '[command]', recurse into subcommands
- if expr "$usage" : '.*\[command\]$' >/dev/null; then
+ if expr "$usage" : '\[command\]' >/dev/null; then
found[subcommands]=1
- check_help "$@" $cmd
+ # (except for 'podman help', which is a special case)
+ if [[ $cmd != "help" ]]; then
+ check_help "$@" $cmd
+ fi
continue
fi
@@ -49,10 +55,26 @@ function check_help() {
assert "$usage" !~ '[A-Z].*\[option' \
"'options' must precede arguments in usage"
+ # Strip off '[options]' but remember if we've seen it.
+ local has_options=
+ if [[ $usage =~ \[options\] ]]; then
+ has_options=1
+ usage=$(sed -e 's/^\[options\] \?//' <<<"$usage")
+ fi
+
+ # From this point on, remaining argument descriptions must be UPPER CASE
+ # e.g., 'podman cmd [options] arg' or 'podman cmd [arg]' are invalid.
+ assert "$usage" !~ '[a-z]' \
+ "$command_string: argument names must be UPPER CASE"
+
+ # It makes no sense to have an optional arg followed by a mandatory one
+ assert "$usage" !~ '\[.*\] [A-Z]' \
+ "$command_string: optional args must be _after_ required ones"
+
# Cross-check: if usage includes '[options]', there must be a
# longer 'Options:' section in the full --help output; vice-versa,
# if 'Options:' is in full output, usage line must have '[options]'.
- if expr "$usage" : '.*\[option' >/dev/null; then
+ if [[ $has_options ]]; then
if ! expr "$full_help" : ".*Options:" >/dev/null; then
die "$command_string: Usage includes '[options]' but has no 'Options:' subsection"
fi
@@ -95,9 +117,7 @@ function check_help() {
fi
# If usage has required arguments, try running without them.
- # The expression here is 'first capital letter is not in [BRACKETS]'.
- # It is intended to handle 'podman foo [options] ARG' but not ' [ARG]'.
- if expr "$usage" : '[^A-Z]\+ [A-Z]' >/dev/null; then
+ if expr "$usage" : '[A-Z]' >/dev/null; then
# Exceptions: these commands don't work rootless
if is_rootless; then
# "pause is not supported for rootless containers"
@@ -126,25 +146,15 @@ function check_help() {
# the required args, then invoke with one extra. We should get a
# usage error.
if ! expr "$usage" : ".*\.\.\."; then
- # "podman help" can take infinite args, so skip that one
- if [ "$cmd" != "help" ]; then
- # Get the args part of the command line; this should be
- # everything from the first CAPITAL LETTER onward. We
- # don't actually care about the letter itself, so just
- # make it 'X'. And we don't care about [OPTIONAL] brackets
- # either. What we do care about is stuff like 'IMAGE | CTR'
- # which is actually one argument; convert to 'IMAGE-or-CTR'
- local rhs=$(sed -e 's/^[^A-Z]\+[A-Z]/X/' -e 's/ | /-or-/g' <<<"$usage")
- local n_args=$(wc -w <<<"$rhs")
-
- run_podman '?' "$@" $cmd $(seq --format='x%g' 0 $n_args)
- is "$status" 125 \
- "'$usage' indicates a maximum of $n_args args. I invoked it with more, and expected this exit status"
- is "$output" "Error:.* \(takes no arguments\|requires exactly $n_args arg\|accepts at most\|too many arguments\|accepts $n_args arg(s), received\|accepts between .* and .* arg(s), received \)" \
- "'$usage' indicates a maximum of $n_args args. I invoked it with more, and expected one of these error messages"
+ local n_args=$(wc -w <<<"$usage")
- found[fixed_args]=1
- fi
+ run_podman '?' "$@" $cmd $(seq --format='x%g' 0 $n_args)
+ is "$status" 125 \
+ "'$usage' indicates a maximum of $n_args args. I invoked it with more, and expected this exit status"
+ is "$output" "Error:.* \(takes no arguments\|requires exactly $n_args arg\|accepts at most\|too many arguments\|accepts $n_args arg(s), received\|accepts between .* and .* arg(s), received \)" \
+ "'$usage' indicates a maximum of $n_args args. I invoked it with more, and expected one of these error messages"
+
+ found[fixed_args]=1
fi
count=$(expr $count + 1)