summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x.github/actions/check_cirrus_cron/cron_failures.sh2
-rw-r--r--cmd/podman/common/completion.go78
-rw-r--r--cmd/podman/containers/commit.go2
-rw-r--r--cmd/podman/containers/cp.go2
-rw-r--r--cmd/podman/containers/exec.go2
-rw-r--r--cmd/podman/containers/logs.go6
-rw-r--r--cmd/podman/containers/port.go2
-rw-r--r--cmd/podman/containers/runlabel.go2
-rw-r--r--cmd/podman/diff.go2
-rw-r--r--cmd/podman/generate/kube.go2
-rw-r--r--cmd/podman/generate/systemd.go2
-rw-r--r--cmd/podman/images/build.go10
-rw-r--r--cmd/podman/images/import.go5
-rw-r--r--cmd/podman/images/push.go2
-rw-r--r--cmd/podman/images/save.go2
-rw-r--r--cmd/podman/images/untag.go2
-rw-r--r--cmd/podman/inspect.go4
-rw-r--r--cmd/podman/manifest/push.go2
-rw-r--r--cmd/podman/networks/create.go2
-rw-r--r--cmd/podman/play/kube.go2
-rw-r--r--cmd/podman/pods/prune.go4
-rw-r--r--cmd/podman/system/service.go3
-rw-r--r--cmd/podman/system/unshare.go2
-rw-r--r--completions/Readme.md2
-rw-r--r--docs/source/markdown/podman-generate-systemd.1.md2
-rw-r--r--docs/source/markdown/podman-network-connect.1.md2
-rw-r--r--go.mod4
-rw-r--r--go.sum18
-rw-r--r--libpod/image/pull.go18
-rw-r--r--pkg/api/handlers/compat/containers_archive.go62
-rw-r--r--pkg/api/handlers/compat/images_build.go2
-rw-r--r--pkg/bindings/images/build.go3
-rw-r--r--pkg/copy/copy.go68
-rw-r--r--pkg/copy/fileinfo.go56
-rw-r--r--pkg/copy/item.go13
-rw-r--r--pkg/copy/parse.go61
-rw-r--r--pkg/domain/infra/abi/cp.go64
-rw-r--r--pkg/domain/infra/abi/manifest.go2
-rw-r--r--pkg/domain/infra/tunnel/containers.go3
-rw-r--r--pkg/specgen/generate/kube/volume.go2
-rw-r--r--test/system/015-help.bats13
-rw-r--r--test/system/070-build.bats42
-rw-r--r--test/system/600-completion.bats272
-rw-r--r--test/system/helpers.bash10
-rw-r--r--vendor/github.com/onsi/gomega/.travis.yml3
-rw-r--r--vendor/github.com/onsi/gomega/CHANGELOG.md7
-rw-r--r--vendor/github.com/onsi/gomega/format/format.go8
-rw-r--r--vendor/github.com/onsi/gomega/gbytes/io_wrappers.go6
-rw-r--r--vendor/github.com/onsi/gomega/go.mod2
-rw-r--r--vendor/github.com/onsi/gomega/go.sum3
-rw-r--r--vendor/github.com/onsi/gomega/gomega_dsl.go2
-rw-r--r--vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go5
-rw-r--r--vendor/github.com/opencontainers/selinux/go-selinux/selinux.go41
-rw-r--r--vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go222
-rw-r--r--vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go4
-rw-r--r--vendor/github.com/opencontainers/selinux/go-selinux/xattrs.go22
-rw-r--r--vendor/github.com/opencontainers/selinux/pkg/pwalk/pwalk.go17
-rw-r--r--vendor/github.com/willf/bitset/Makefile191
-rw-r--r--vendor/github.com/willf/bitset/README.md20
-rw-r--r--vendor/github.com/willf/bitset/bitset.go72
-rw-r--r--vendor/github.com/willf/bitset/go.mod3
-rw-r--r--vendor/github.com/willf/bitset/go.sum0
-rw-r--r--vendor/golang.org/x/net/http2/transport.go4
-rw-r--r--vendor/modules.txt8
64 files changed, 1011 insertions, 490 deletions
diff --git a/.github/actions/check_cirrus_cron/cron_failures.sh b/.github/actions/check_cirrus_cron/cron_failures.sh
index 2693df417..16419c6d6 100755
--- a/.github/actions/check_cirrus_cron/cron_failures.sh
+++ b/.github/actions/check_cirrus_cron/cron_failures.sh
@@ -67,7 +67,7 @@ jq --indent 4 --color-output . <./artifacts/reply.json || \
cat ./artifacts/reply.json
echo "::endgroup::"
-# Desireable to catch non-JSON encoded errors in reply.
+# Desirable to catch non-JSON encoded errors in reply.
if grep -qi 'error' ./artifacts/reply.json; then
err "Found the word 'error' in reply"
fi
diff --git a/cmd/podman/common/completion.go b/cmd/podman/common/completion.go
index 25f4d0f79..f792b2713 100644
--- a/cmd/podman/common/completion.go
+++ b/cmd/podman/common/completion.go
@@ -278,7 +278,6 @@ func validCurrentCmdLine(cmd *cobra.Command, args []string, toComplete string) b
return true
}
}
- cobra.CompDebugln(err.Error(), true)
return false
}
return true
@@ -445,6 +444,29 @@ func AutocompleteNetworks(cmd *cobra.Command, args []string, toComplete string)
return getNetworks(cmd, toComplete)
}
+// AutocompleteDefaultOneArg - Autocomplete path only for the first argument.
+func AutocompleteDefaultOneArg(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
+ if len(args) == 0 {
+ return nil, cobra.ShellCompDirectiveDefault
+ }
+ return nil, cobra.ShellCompDirectiveNoFileComp
+}
+
+// AutocompleteCommitCommand - Autocomplete podman commit command args.
+func AutocompleteCommitCommand(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
+ if !validCurrentCmdLine(cmd, args, toComplete) {
+ return nil, cobra.ShellCompDirectiveNoFileComp
+ }
+ if len(args) == 0 {
+ return getContainers(cmd, toComplete, completeDefault)
+ }
+ if len(args) == 1 {
+ return getImages(cmd, toComplete)
+ }
+ // don't complete more than 2 args
+ return nil, cobra.ShellCompDirectiveNoFileComp
+}
+
// AutocompleteCpCommand - Autocomplete podman cp command args.
func AutocompleteCpCommand(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) {
@@ -465,6 +487,43 @@ func AutocompleteCpCommand(cmd *cobra.Command, args []string, toComplete string)
return nil, cobra.ShellCompDirectiveNoFileComp
}
+// AutocompleteExecCommand - Autocomplete podman exec command args.
+func AutocompleteExecCommand(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
+ if !validCurrentCmdLine(cmd, args, toComplete) {
+ return nil, cobra.ShellCompDirectiveNoFileComp
+ }
+ if len(args) == 0 {
+ return getContainers(cmd, toComplete, completeDefault, "running")
+ }
+ return nil, cobra.ShellCompDirectiveDefault
+}
+
+// AutocompleteRunlabelCommand - Autocomplete podman container runlabel command args.
+func AutocompleteRunlabelCommand(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
+ if !validCurrentCmdLine(cmd, args, toComplete) {
+ return nil, cobra.ShellCompDirectiveNoFileComp
+ }
+ if len(args) == 0 {
+ // FIXME: What labels can we recommend here?
+ return nil, cobra.ShellCompDirectiveNoFileComp
+ }
+ if len(args) == 1 {
+ return getImages(cmd, toComplete)
+ }
+ return nil, cobra.ShellCompDirectiveDefault
+}
+
+// AutocompletePortCommand - Autocomplete podman port command args.
+func AutocompletePortCommand(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
+ if !validCurrentCmdLine(cmd, args, toComplete) {
+ return nil, cobra.ShellCompDirectiveNoFileComp
+ }
+ if len(args) == 0 {
+ return getContainers(cmd, toComplete, completeDefault)
+ }
+ return nil, cobra.ShellCompDirectiveNoFileComp
+}
+
// AutocompleteNetworkConnectCmd - Autocomplete podman network connect/disconnect command args.
func AutocompleteNetworkConnectCmd(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if len(args) == 0 {
@@ -496,6 +555,23 @@ func AutocompleteTopCmd(cmd *cobra.Command, args []string, toComplete string) ([
return descriptors, cobra.ShellCompDirectiveNoFileComp
}
+// AutocompleteInspect - Autocomplete podman inspect.
+func AutocompleteInspect(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
+ if !validCurrentCmdLine(cmd, args, toComplete) {
+ return nil, cobra.ShellCompDirectiveNoFileComp
+ }
+ containers, _ := getContainers(cmd, toComplete, completeDefault)
+ images, _ := getImages(cmd, toComplete)
+ pods, _ := getPods(cmd, toComplete, completeDefault)
+ networks, _ := getNetworks(cmd, toComplete)
+ volumes, _ := getVolumes(cmd, toComplete)
+ suggestions := append(containers, images...)
+ suggestions = append(suggestions, pods...)
+ suggestions = append(suggestions, networks...)
+ suggestions = append(suggestions, volumes...)
+ return suggestions, cobra.ShellCompDirectiveNoFileComp
+}
+
// AutocompleteSystemConnections - Autocomplete system connections.
func AutocompleteSystemConnections(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) {
diff --git a/cmd/podman/containers/commit.go b/cmd/podman/containers/commit.go
index c5c7673b2..ff06e10f7 100644
--- a/cmd/podman/containers/commit.go
+++ b/cmd/podman/containers/commit.go
@@ -24,7 +24,7 @@ var (
Long: commitDescription,
RunE: commit,
Args: cobra.RangeArgs(1, 2),
- ValidArgsFunction: common.AutocompleteContainers,
+ ValidArgsFunction: common.AutocompleteCommitCommand,
Example: `podman commit -q --message "committing container to image" reverent_golick image-committed
podman commit -q --author "firstName lastName" reverent_golick image-committed
podman commit -q --pause=false containerID image-committed
diff --git a/cmd/podman/containers/cp.go b/cmd/podman/containers/cp.go
index fd3aa7680..9b0a01a2f 100644
--- a/cmd/podman/containers/cp.go
+++ b/cmd/podman/containers/cp.go
@@ -13,7 +13,7 @@ var (
You can copy from the container's file system to the local machine or the reverse, from the local filesystem to the container. If "-" is specified for either the SRC_PATH or DEST_PATH, you can also stream a tar archive from STDIN or to STDOUT. The CONTAINER can be a running or stopped container. The SRC_PATH or DEST_PATH can be a file or directory.
`
cpCommand = &cobra.Command{
- Use: "cp [options] SRC_PATH DEST_PATH",
+ Use: "cp [options] [CONTAINER:]SRC_PATH [CONTAINER:]DEST_PATH",
Short: "Copy files/folders between a container and the local filesystem",
Long: cpDescription,
Args: cobra.ExactArgs(2),
diff --git a/cmd/podman/containers/exec.go b/cmd/podman/containers/exec.go
index 306bae58e..3d4918d50 100644
--- a/cmd/podman/containers/exec.go
+++ b/cmd/podman/containers/exec.go
@@ -26,7 +26,7 @@ var (
Long: execDescription,
RunE: exec,
DisableFlagsInUseLine: true,
- ValidArgsFunction: common.AutocompleteContainersRunning,
+ ValidArgsFunction: common.AutocompleteExecCommand,
Example: `podman exec -it ctrID ls
podman exec -it -w /tmp myCtr pwd
podman exec --user root ctrID ls`,
diff --git a/cmd/podman/containers/logs.go b/cmd/podman/containers/logs.go
index 1fa4ac11f..d4ede370a 100644
--- a/cmd/podman/containers/logs.go
+++ b/cmd/podman/containers/logs.go
@@ -69,6 +69,12 @@ var (
)
func init() {
+ // if run remotely we only allow one container arg
+ if registry.IsRemote() {
+ logsCommand.Use = "logs [options] CONTAINER"
+ containerLogsCommand.Use = logsCommand.Use
+ }
+
// logs
registry.Commands = append(registry.Commands, registry.CliCommand{
Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
diff --git a/cmd/podman/containers/port.go b/cmd/podman/containers/port.go
index ac31e158e..d59161149 100644
--- a/cmd/podman/containers/port.go
+++ b/cmd/podman/containers/port.go
@@ -26,7 +26,7 @@ var (
Args: func(cmd *cobra.Command, args []string) error {
return validate.CheckAllLatestAndCIDFile(cmd, args, true, false)
},
- ValidArgsFunction: common.AutocompleteContainers,
+ ValidArgsFunction: common.AutocompletePortCommand,
Example: `podman port --all
podman port ctrID 80/tcp
podman port --latest 80`,
diff --git a/cmd/podman/containers/runlabel.go b/cmd/podman/containers/runlabel.go
index 2f6d2eb05..6ebba4935 100644
--- a/cmd/podman/containers/runlabel.go
+++ b/cmd/podman/containers/runlabel.go
@@ -30,7 +30,7 @@ var (
Long: runlabelDescription,
RunE: runlabel,
Args: cobra.MinimumNArgs(2),
- ValidArgsFunction: common.AutocompleteImages,
+ ValidArgsFunction: common.AutocompleteRunlabelCommand,
Example: `podman container runlabel run imageID
podman container runlabel install imageID arg1 arg2
podman container runlabel --display run myImage`,
diff --git a/cmd/podman/diff.go b/cmd/podman/diff.go
index 5e6abe243..e094e6bdd 100644
--- a/cmd/podman/diff.go
+++ b/cmd/podman/diff.go
@@ -18,7 +18,7 @@ var (
// Command: podman _diff_ Object_ID
diffDescription = `Displays changes on a container or image's filesystem. The container or image will be compared to its parent layer.`
diffCmd = &cobra.Command{
- Use: "diff [options] {CONTAINER_ID | IMAGE_ID}",
+ Use: "diff [options] {CONTAINER|IMAGE}",
Args: validate.IDOrLatestArgs,
Short: "Display the changes to the object's file system",
Long: diffDescription,
diff --git a/cmd/podman/generate/kube.go b/cmd/podman/generate/kube.go
index 0517db19a..cb608e7b5 100644
--- a/cmd/podman/generate/kube.go
+++ b/cmd/podman/generate/kube.go
@@ -22,7 +22,7 @@ var (
Whether the input is for a container or pod, Podman will always generate the specification as a pod.`
kubeCmd = &cobra.Command{
- Use: "kube [options] CONTAINER... | POD",
+ Use: "kube [options] {CONTAINER...|POD}",
Short: "Generate Kubernetes YAML from a container or pod.",
Long: kubeDescription,
RunE: kube,
diff --git a/cmd/podman/generate/systemd.go b/cmd/podman/generate/systemd.go
index e9cf76aae..f9099d3b8 100644
--- a/cmd/podman/generate/systemd.go
+++ b/cmd/podman/generate/systemd.go
@@ -26,7 +26,7 @@ var (
The generated units can later be controlled via systemctl(1).`
systemdCmd = &cobra.Command{
- Use: "systemd [options] CTR|POD",
+ Use: "systemd [options] {CONTAINER|POD}",
Short: "Generate systemd units.",
Long: systemdDescription,
RunE: systemd,
diff --git a/cmd/podman/images/build.go b/cmd/podman/images/build.go
index 739e1c265..fbea1e3d8 100644
--- a/cmd/podman/images/build.go
+++ b/cmd/podman/images/build.go
@@ -11,6 +11,7 @@ import (
"github.com/containers/buildah/pkg/parse"
"github.com/containers/common/pkg/completion"
"github.com/containers/common/pkg/config"
+ "github.com/containers/podman/v2/cmd/podman/common"
"github.com/containers/podman/v2/cmd/podman/registry"
"github.com/containers/podman/v2/cmd/podman/utils"
"github.com/containers/podman/v2/pkg/domain/entities"
@@ -44,7 +45,7 @@ var (
Long: buildDescription,
Args: cobra.MaximumNArgs(1),
RunE: build,
- ValidArgsFunction: completion.AutocompleteDefault,
+ ValidArgsFunction: common.AutocompleteDefaultOneArg,
Example: `podman build .
podman build --creds=username:password -t imageName -f Containerfile.simple .
podman build --layers --force-rm --tag imageName .`,
@@ -115,6 +116,7 @@ func buildFlags(cmd *cobra.Command) {
// --layers flag
flag = layerFlags.Lookup("layers")
useLayersVal := useLayers()
+ buildOpts.Layers = useLayersVal == "true"
if err := flag.Value.Set(useLayersVal); err != nil {
logrus.Errorf("unable to set --layers to %v: %v", useLayersVal, err)
}
@@ -274,11 +276,7 @@ func buildFlagsWrapperToOptions(c *cobra.Command, contextDir string, flags *buil
}
}
}
- // Check to see if the BUILDAH_LAYERS environment variable is set and
- // override command-line.
- if _, ok := os.LookupEnv("BUILDAH_LAYERS"); ok {
- flags.Layers = true
- }
+ flags.Layers = buildOpts.Layers
// `buildah bud --layers=false` acts like `docker build --squash` does.
// That is all of the new layers created during the build process are
diff --git a/cmd/podman/images/import.go b/cmd/podman/images/import.go
index f38ab3b19..ac59935ad 100644
--- a/cmd/podman/images/import.go
+++ b/cmd/podman/images/import.go
@@ -25,18 +25,19 @@ var (
Short: "Import a tarball to create a filesystem image",
Long: importDescription,
RunE: importCon,
- ValidArgsFunction: completion.AutocompleteDefault,
+ Args: cobra.RangeArgs(1, 2),
+ ValidArgsFunction: common.AutocompleteDefaultOneArg,
Example: `podman import http://example.com/ctr.tar url-image
cat ctr.tar | podman -q import --message "importing the ctr.tar tarball" - image-imported
cat ctr.tar | podman import -`,
}
imageImportCommand = &cobra.Command{
- Args: cobra.MinimumNArgs(1),
Use: importCommand.Use,
Short: importCommand.Short,
Long: importCommand.Long,
RunE: importCommand.RunE,
+ Args: importCommand.Args,
ValidArgsFunction: importCommand.ValidArgsFunction,
Example: `podman image import http://example.com/ctr.tar url-image
cat ctr.tar | podman -q image import --message "importing the ctr.tar tarball" - image-imported
diff --git a/cmd/podman/images/push.go b/cmd/podman/images/push.go
index 447b02fbe..d82083cd8 100644
--- a/cmd/podman/images/push.go
+++ b/cmd/podman/images/push.go
@@ -29,7 +29,7 @@ var (
// Command: podman push
pushCmd = &cobra.Command{
- Use: "push [options] SOURCE [DESTINATION]",
+ Use: "push [options] IMAGE [DESTINATION]",
Short: "Push an image to a specified destination",
Long: pushDescription,
RunE: imagePush,
diff --git a/cmd/podman/images/save.go b/cmd/podman/images/save.go
index 9ef2d0c91..3a35c4fad 100644
--- a/cmd/podman/images/save.go
+++ b/cmd/podman/images/save.go
@@ -43,7 +43,7 @@ var (
}
return nil
},
- ValidArgsFunction: completion.AutocompleteNone,
+ ValidArgsFunction: common.AutocompleteImages,
Example: `podman save --quiet -o myimage.tar imageID
podman save --format docker-dir -o ubuntu-dir ubuntu
podman save > alpine-all.tar alpine:latest`,
diff --git a/cmd/podman/images/untag.go b/cmd/podman/images/untag.go
index 17dc21203..3cf62713b 100644
--- a/cmd/podman/images/untag.go
+++ b/cmd/podman/images/untag.go
@@ -9,7 +9,7 @@ import (
var (
untagCommand = &cobra.Command{
- Use: "untag IMAGE [NAME...]",
+ Use: "untag IMAGE [IMAGE...]",
Short: "Remove a name from a local image",
Long: "Removes one or more names from a locally-stored image.",
RunE: untag,
diff --git a/cmd/podman/inspect.go b/cmd/podman/inspect.go
index f62abe931..64daae951 100644
--- a/cmd/podman/inspect.go
+++ b/cmd/podman/inspect.go
@@ -20,12 +20,12 @@ var (
// Command: podman _inspect_ Object_ID
inspectCmd = &cobra.Command{
- Use: "inspect [options] {CONTAINER_ID | IMAGE_ID} [...]",
+ Use: "inspect [options] {CONTAINER|IMAGE|POD|NETWORK|VOLUME} [...]",
Short: "Display the configuration of object denoted by ID",
RunE: inspectExec,
Long: inspectDescription,
TraverseChildren: true,
- ValidArgsFunction: common.AutocompleteContainersAndImages,
+ ValidArgsFunction: common.AutocompleteInspect,
Example: `podman inspect fedora
podman inspect --type image fedora
podman inspect CtrID ImgID
diff --git a/cmd/podman/manifest/push.go b/cmd/podman/manifest/push.go
index a3b469491..89faa42a2 100644
--- a/cmd/podman/manifest/push.go
+++ b/cmd/podman/manifest/push.go
@@ -24,7 +24,7 @@ type manifestPushOptsWrapper struct {
var (
manifestPushOpts = manifestPushOptsWrapper{}
pushCmd = &cobra.Command{
- Use: "push [options] SOURCE DESTINATION",
+ Use: "push [options] LIST DESTINATION",
Short: "Push a manifest list or image index to a registry",
Long: "Pushes manifest lists and image indexes to registries.",
RunE: push,
diff --git a/cmd/podman/networks/create.go b/cmd/podman/networks/create.go
index 8db4bb89a..1a091f111 100644
--- a/cmd/podman/networks/create.go
+++ b/cmd/podman/networks/create.go
@@ -17,7 +17,7 @@ import (
var (
networkCreateDescription = `create CNI networks for containers and pods`
networkCreateCommand = &cobra.Command{
- Use: "create [options] [NETWORK]",
+ Use: "create [options] [NAME]",
Short: "network create",
Long: networkCreateDescription,
RunE: networkCreate,
diff --git a/cmd/podman/play/kube.go b/cmd/podman/play/kube.go
index db70ad7d4..5e227d05a 100644
--- a/cmd/podman/play/kube.go
+++ b/cmd/podman/play/kube.go
@@ -39,7 +39,7 @@ var (
Long: kubeDescription,
RunE: kube,
Args: cobra.ExactArgs(1),
- ValidArgsFunction: completion.AutocompleteDefault,
+ ValidArgsFunction: common.AutocompleteDefaultOneArg,
Example: `podman play kube nginx.yml
podman play kube --creds user:password --seccomp-profile-root /custom/path apache.yml`,
}
diff --git a/cmd/podman/pods/prune.go b/cmd/podman/pods/prune.go
index e069c9b7f..965c36398 100644
--- a/cmd/podman/pods/prune.go
+++ b/cmd/podman/pods/prune.go
@@ -7,7 +7,7 @@ import (
"os"
"strings"
- "github.com/containers/podman/v2/cmd/podman/common"
+ "github.com/containers/common/pkg/completion"
"github.com/containers/podman/v2/cmd/podman/registry"
"github.com/containers/podman/v2/cmd/podman/utils"
"github.com/containers/podman/v2/cmd/podman/validate"
@@ -28,7 +28,7 @@ var (
Short: "Remove all stopped pods and their containers",
Long: pruneDescription,
RunE: prune,
- ValidArgsFunction: common.AutocompletePods,
+ ValidArgsFunction: completion.AutocompleteNone,
Example: `podman pod prune`,
}
)
diff --git a/cmd/podman/system/service.go b/cmd/podman/system/service.go
index 42482b5d9..f8bdbfa10 100644
--- a/cmd/podman/system/service.go
+++ b/cmd/podman/system/service.go
@@ -10,6 +10,7 @@ import (
"time"
"github.com/containers/common/pkg/completion"
+ "github.com/containers/podman/v2/cmd/podman/common"
"github.com/containers/podman/v2/cmd/podman/registry"
"github.com/containers/podman/v2/pkg/domain/entities"
"github.com/containers/podman/v2/pkg/rootless"
@@ -32,7 +33,7 @@ Enable a listening service for API access to Podman commands.
Short: "Run API service",
Long: srvDescription,
RunE: service,
- ValidArgsFunction: completion.AutocompleteDefault,
+ ValidArgsFunction: common.AutocompleteDefaultOneArg,
Example: `podman system service --time=0 unix:///tmp/podman.sock`,
}
diff --git a/cmd/podman/system/unshare.go b/cmd/podman/system/unshare.go
index 437cf7b2e..364852979 100644
--- a/cmd/podman/system/unshare.go
+++ b/cmd/podman/system/unshare.go
@@ -14,7 +14,7 @@ import (
var (
unshareDescription = "Runs a command in a modified user namespace."
unshareCommand = &cobra.Command{
- Use: "unshare [COMMAND [ARG ...]]",
+ Use: "unshare [COMMAND [ARG...]]",
DisableFlagsInUseLine: true,
Short: "Run a command in a modified user namespace",
Long: unshareDescription,
diff --git a/completions/Readme.md b/completions/Readme.md
index 9a3eac480..5c9d16f3c 100644
--- a/completions/Readme.md
+++ b/completions/Readme.md
@@ -4,4 +4,4 @@ Podman offers shell completion scripts for bash, zsh and fish. The completion sc
The shell completion scripts are generated by `make completion`, do not edit these files directly. To install them you can run `sudo make install.completions`.
-For information about these sripts see [`man podman-completion`](../docs/source/markdown/podman-completion.1.md)
+For information about these scripts see [`man podman-completion`](../docs/source/markdown/podman-completion.1.md)
diff --git a/docs/source/markdown/podman-generate-systemd.1.md b/docs/source/markdown/podman-generate-systemd.1.md
index 445888d30..032158c56 100644
--- a/docs/source/markdown/podman-generate-systemd.1.md
+++ b/docs/source/markdown/podman-generate-systemd.1.md
@@ -155,7 +155,7 @@ Podman-generated unit files include an `[Install]` section, which carries instal
Once you have generated the systemd unit file, you can copy the generated systemd file to ```/etc/systemd/system``` for installing as a root user and to ```$HOME/.config/systemd/user``` for installing it as a non-root user. Enable the copied unit file or files using `systemctl enable`.
-Note: Coping unit files to ```/etc/systemd/system``` and enabling it marks the unit file to be automatically started at boot. And smillarly, coping a unit file to ```$HOME/.config/systemd/user``` and enabling it marks the unit file to be automatically started on user login.
+Note: Copying unit files to ```/etc/systemd/system``` and enabling it marks the unit file to be automatically started at boot. And similarly, copying a unit file to ```$HOME/.config/systemd/user``` and enabling it marks the unit file to be automatically started on user login.
```
diff --git a/docs/source/markdown/podman-network-connect.1.md b/docs/source/markdown/podman-network-connect.1.md
index a31a415dc..cff4336d6 100644
--- a/docs/source/markdown/podman-network-connect.1.md
+++ b/docs/source/markdown/podman-network-connect.1.md
@@ -15,7 +15,7 @@ This command is not available for rootless users.
## OPTIONS
#### **--alias**
Add network-scoped alias for the container. If the network is using the `dnsname` CNI plugin, these aliases
-can be used for name resolution on the given network. Multiple *--alias* options may be specificed as input.
+can be used for name resolution on the given network. Multiple *--alias* options may be specified as input.
## EXAMPLE
diff --git a/go.mod b/go.mod
index 28a70a1ae..a4a3df590 100644
--- a/go.mod
+++ b/go.mod
@@ -39,13 +39,13 @@ require (
github.com/moby/term v0.0.0-20200915141129-7f0af18e79f2
github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618
github.com/onsi/ginkgo v1.14.2
- github.com/onsi/gomega v1.10.3
+ github.com/onsi/gomega v1.10.4
github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6
github.com/opencontainers/runc v1.0.0-rc91.0.20200708210054-ce54a9d4d79b
github.com/opencontainers/runtime-spec v1.0.3-0.20200817204227-f9c09b4ea1df
github.com/opencontainers/runtime-tools v0.9.0
- github.com/opencontainers/selinux v1.6.0
+ github.com/opencontainers/selinux v1.7.0
github.com/opentracing/opentracing-go v1.2.0
github.com/pkg/errors v0.9.1
github.com/pmezard/go-difflib v1.0.0
diff --git a/go.sum b/go.sum
index 64c404633..806ebaaa1 100644
--- a/go.sum
+++ b/go.sum
@@ -22,7 +22,6 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
-github.com/Microsoft/go-winio v0.4.15-0.20200113171025-3fe6c5262873 h1:93nQ7k53GjoMQ07HVP8g6Zj1fQZDDj7Xy2VkNNtvX8o=
github.com/Microsoft/go-winio v0.4.15-0.20200113171025-3fe6c5262873/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
github.com/Microsoft/go-winio v0.4.15 h1:qkLXKzb1QoVatRyd/YlXZ/Kg0m5K3SPuoD82jjSOaBc=
github.com/Microsoft/go-winio v0.4.15/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
@@ -94,13 +93,11 @@ github.com/containernetworking/plugins v0.8.7 h1:bU7QieuAp+sACI2vCzESJ3FoT860urY
github.com/containernetworking/plugins v0.8.7/go.mod h1:R7lXeZaBzpfqapcAbHRW8/CYwm0dHzbz0XEjofx0uB0=
github.com/containers/buildah v1.18.1-0.20201125084616-dd26b137459c h1:vyc2iYz9b2vfDiigpLyhiXNqXITt/dmDk74HpHzlQow=
github.com/containers/buildah v1.18.1-0.20201125084616-dd26b137459c/go.mod h1:B+0OkXUogxdwsEy4ax3a5/vDtJjL6vCisiV6frQZJ4A=
-github.com/containers/common v0.29.0 h1:hTMC+urdkk5bKfhL/OgCixIX5xjJgQ2l2jPG745ECFQ=
github.com/containers/common v0.29.0/go.mod h1:yT4GTUHsKRmpaDb+mecXRnIMre7W3ZgwXqaYMywXlaA=
github.com/containers/common v0.31.0 h1:SRnjfoqbjfaojpY9YJq9JBPEslwB5hoXJbaE+5zMFwM=
github.com/containers/common v0.31.0/go.mod h1:yT4GTUHsKRmpaDb+mecXRnIMre7W3ZgwXqaYMywXlaA=
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.8.1 h1:aHW8a/Kd0dTJ7PTL/fc6y12sJqHxWgqilu+XyHfjD8Q=
github.com/containers/image/v5 v5.8.1/go.mod h1:blOEFd/iFdeyh891ByhCVUc+xAcaI3gBegXECwz9UbQ=
github.com/containers/image/v5 v5.9.0 h1:dRmUtcluQcmasNo3DpnRoZjfU0rOu1qZeL6wlDJr10Q=
github.com/containers/image/v5 v5.9.0/go.mod h1:blOEFd/iFdeyh891ByhCVUc+xAcaI3gBegXECwz9UbQ=
@@ -230,7 +227,6 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
-github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
@@ -417,8 +413,9 @@ github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
-github.com/onsi/gomega v1.10.3 h1:gph6h/qe9GSUw1NhH1gp+qb+h8rXD8Cy60Z32Qw3ELA=
github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
+github.com/onsi/gomega v1.10.4 h1:NiTx7EEvBzu9sFOD1zORteLSt3o8gnlvZZwSE9TnY9U=
+github.com/onsi/gomega v1.10.4/go.mod h1:g/HbgYopi++010VEqkFgJHKC09uJiW9UkXvMUuKHUCQ=
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
@@ -442,6 +439,8 @@ github.com/opencontainers/runtime-tools v0.9.0/go.mod h1:r3f7wjNzSs2extwzU3Y+6pK
github.com/opencontainers/selinux v1.5.1/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
github.com/opencontainers/selinux v1.6.0 h1:+bIAS/Za3q5FTwWym4fTB0vObnfCf3G/NC7K6Jx62mY=
github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE=
+github.com/opencontainers/selinux v1.7.0 h1:I3Qiu8dbuWHHHfwd4id7zXivJ1qWixGQx8nTvQsKnjs=
+github.com/opencontainers/selinux v1.7.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo=
github.com/openshift/imagebuilder v1.1.8 h1:gjiIl8pbNj0eC4XWvFJHATdDvYm64p9/pLDLQWoLZPA=
github.com/openshift/imagebuilder v1.1.8/go.mod h1:9aJRczxCH0mvT6XQ+5STAQaPWz7OsWcU5/mRkt8IWeo=
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
@@ -561,6 +560,8 @@ github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df h1:OviZH7qLw/7Zo
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243 h1:R43TdZy32XXSXjJn7M/HhALJ9imq6ztLnChfYJpVDnM=
github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
+github.com/willf/bitset v1.1.11 h1:N7Z7E9UvjW+sGsEl7k/SJrvY2reP1A07MrGuCjIOjRE=
+github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonpointer v0.0.0-20190809123943-df4f5c81cb3b h1:6cLsL+2FW6dRAdl5iMtHgRogVCff0QpRi9653YmdcJA=
github.com/xeipuuv/gojsonpointer v0.0.0-20190809123943-df4f5c81cb3b/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
@@ -638,10 +639,10 @@ golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
-golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0 h1:wBouT66WTYFXdxfVdz9sVWARVd/2vfGcmI45D2gj45M=
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U=
+golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -694,7 +695,6 @@ golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13 h1:5jaG59Zhd+8ZXe8C+lgiAGqkOaZBruqrWclLkgAww34=
golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201112073958-5cba982894dd h1:5CtCZbICpIOFdgO940moixOPjc0178IU44m4EjOO5IY=
golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -702,7 +702,6 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
-golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@@ -733,7 +732,6 @@ golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/libpod/image/pull.go b/libpod/image/pull.go
index 2a2d16252..c37929927 100644
--- a/libpod/image/pull.go
+++ b/libpod/image/pull.go
@@ -4,7 +4,6 @@ import (
"context"
"fmt"
"io"
- "os"
"path/filepath"
"strings"
@@ -378,29 +377,12 @@ func (ir *Runtime) doPullImage(ctx context.Context, sc *types.SystemContext, goa
return images, nil
}
-// getShortNameMode looks up the `CONTAINERS_SHORT_NAME_ALIASING` environment
-// variable. If it's "on", return `nil` to use the defaults from
-// containers/image and the registries.conf files on the system. If it's
-// "off", empty or unset, return types.ShortNameModeDisabled to turn off
-// short-name aliasing by default.
-//
-// TODO: remove this function once we want to default to short-name aliasing.
-func getShortNameMode() *types.ShortNameMode {
- env := os.Getenv("CONTAINERS_SHORT_NAME_ALIASING")
- if strings.ToLower(env) == "on" {
- return nil // default to whatever registries.conf and c/image decide
- }
- mode := types.ShortNameModeDisabled
- return &mode
-}
-
// pullGoalFromPossiblyUnqualifiedName looks at inputName and determines the possible
// image references to try pulling in combination with the registries.conf file as well
func (ir *Runtime) pullGoalFromPossiblyUnqualifiedName(sys *types.SystemContext, writer io.Writer, inputName string) (*pullGoal, error) {
if sys == nil {
sys = &types.SystemContext{}
}
- sys.ShortNameMode = getShortNameMode()
resolved, err := shortnames.Resolve(sys, inputName)
if err != nil {
diff --git a/pkg/api/handlers/compat/containers_archive.go b/pkg/api/handlers/compat/containers_archive.go
index 223eb2cd5..d8197415c 100644
--- a/pkg/api/handlers/compat/containers_archive.go
+++ b/pkg/api/handlers/compat/containers_archive.go
@@ -1,13 +1,8 @@
package compat
import (
- "bytes"
- "encoding/base64"
- "encoding/json"
"fmt"
"net/http"
- "os"
- "time"
"github.com/containers/podman/v2/libpod"
"github.com/containers/podman/v2/libpod/define"
@@ -15,6 +10,7 @@ import (
"github.com/containers/podman/v2/pkg/copy"
"github.com/gorilla/schema"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
func Archive(w http.ResponseWriter, r *http.Request) {
@@ -71,12 +67,12 @@ func handleHeadAndGet(w http.ResponseWriter, r *http.Request, decoder *schema.De
utils.Error(w, "Not found.", http.StatusNotFound, errors.Wrapf(err, "error stating container path %q", query.Path))
return
}
- statHeader, err := fileInfoToDockerStats(info)
+ statHeader, err := copy.EncodeFileInfo(info)
if err != nil {
utils.Error(w, "Something went wrong", http.StatusInternalServerError, err)
return
}
- w.Header().Add("X-Docker-Container-Path-Stat", statHeader)
+ w.Header().Add(copy.XDockerContainerPathStatHeader, statHeader)
// Our work is done when the user is interested in the header only.
if r.Method == http.MethodHead {
@@ -91,47 +87,16 @@ func handleHeadAndGet(w http.ResponseWriter, r *http.Request, decoder *schema.De
return
}
- w.WriteHeader(http.StatusOK)
- if err := copy.Copy(&source, &destination, false); err != nil {
+ copier, err := copy.GetCopier(&source, &destination, false)
+ if err != nil {
utils.Error(w, "Something went wrong", http.StatusInternalServerError, err)
return
}
-}
-
-func fileInfoToDockerStats(info *copy.FileInfo) (string, error) {
- dockerStats := struct {
- Name string `json:"name"`
- Size int64 `json:"size"`
- Mode os.FileMode `json:"mode"`
- ModTime time.Time `json:"mtime"`
- LinkTarget string `json:"linkTarget"`
- }{
- Name: info.Name,
- Size: info.Size,
- Mode: info.Mode,
- ModTime: info.ModTime,
- LinkTarget: info.LinkTarget,
- }
-
- jsonBytes, err := json.Marshal(&dockerStats)
- if err != nil {
- return "", errors.Wrap(err, "failed to serialize file stats")
- }
-
- buff := bytes.NewBuffer(make([]byte, 0, 128))
- base64encoder := base64.NewEncoder(base64.StdEncoding, buff)
-
- _, err = base64encoder.Write(jsonBytes)
- if err != nil {
- return "", err
- }
-
- err = base64encoder.Close()
- if err != nil {
- return "", err
+ w.WriteHeader(http.StatusOK)
+ if err := copier.Copy(); err != nil {
+ logrus.Errorf("Error during copy: %v", err)
+ return
}
-
- return buff.String(), nil
}
func handlePut(w http.ResponseWriter, r *http.Request, decoder *schema.Decoder, runtime *libpod.Runtime) {
@@ -170,9 +135,14 @@ func handlePut(w http.ResponseWriter, r *http.Request, decoder *schema.Decoder,
return
}
- w.WriteHeader(http.StatusOK)
- if err := copy.Copy(&source, &destination, false); err != nil {
+ copier, err := copy.GetCopier(&source, &destination, false)
+ if err != nil {
utils.Error(w, "Something went wrong", http.StatusInternalServerError, err)
return
}
+ w.WriteHeader(http.StatusOK)
+ if err := copier.Copy(); err != nil {
+ logrus.Errorf("Error during copy: %v", err)
+ return
+ }
}
diff --git a/pkg/api/handlers/compat/images_build.go b/pkg/api/handlers/compat/images_build.go
index 43478c1d3..415ff85cd 100644
--- a/pkg/api/handlers/compat/images_build.go
+++ b/pkg/api/handlers/compat/images_build.go
@@ -71,6 +71,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
ForceRm bool `schema:"forcerm"`
HTTPProxy bool `schema:"httpproxy"`
Labels string `schema:"labels"`
+ Layers bool `schema:"layers"`
MemSwap int64 `schema:"memswap"`
Memory int64 `schema:"memory"`
NetworkMode string `schema:"networkmode"`
@@ -165,6 +166,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
Registry: query.Registry,
IgnoreUnrecognizedInstructions: true,
Quiet: query.Quiet,
+ Layers: query.Layers,
Isolation: buildah.IsolationChroot,
Compression: archive.Gzip,
Args: buildArgs,
diff --git a/pkg/bindings/images/build.go b/pkg/bindings/images/build.go
index 815ab4e86..d34ab87d9 100644
--- a/pkg/bindings/images/build.go
+++ b/pkg/bindings/images/build.go
@@ -41,6 +41,9 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO
if options.NoCache {
params.Set("nocache", "1")
}
+ if options.Layers {
+ params.Set("layers", "1")
+ }
// TODO cachefrom
if options.PullPolicy == buildah.PullAlways {
params.Set("pull", "1")
diff --git a/pkg/copy/copy.go b/pkg/copy/copy.go
index 0e68eb450..13893deb2 100644
--- a/pkg/copy/copy.go
+++ b/pkg/copy/copy.go
@@ -25,31 +25,61 @@ import (
//
// ****************************************************************************
-// Copy the source item to destination. Use extract to untar the source if
-// it's a tar archive.
-func Copy(source *CopyItem, destination *CopyItem, extract bool) error {
+// Copier copies data from a source to a destination CopyItem.
+type Copier struct {
+ copyFunc func() error
+ cleanUpFuncs []deferFunc
+}
+
+// cleanUp releases resources the Copier may hold open.
+func (c *Copier) cleanUp() {
+ for _, f := range c.cleanUpFuncs {
+ f()
+ }
+}
+
+// Copy data from a source to a destination CopyItem.
+func (c *Copier) Copy() error {
+ defer c.cleanUp()
+ return c.copyFunc()
+}
+
+// GetCopiers returns a Copier to copy the source item to destination. Use
+// extract to untar the source if it's a tar archive.
+func GetCopier(source *CopyItem, destination *CopyItem, extract bool) (*Copier, error) {
+ copier := &Copier{}
+
// First, do the man-page dance. See podman-cp(1) for details.
if err := enforceCopyRules(source, destination); err != nil {
- return err
+ return nil, err
}
// Destination is a stream (e.g., stdout or an http body).
if destination.info.IsStream {
// Source is a stream (e.g., stdin or an http body).
if source.info.IsStream {
- _, err := io.Copy(destination.writer, source.reader)
- return err
+ copier.copyFunc = func() error {
+ _, err := io.Copy(destination.writer, source.reader)
+ return err
+ }
+ return copier, nil
}
root, glob, err := source.buildahGlobs()
if err != nil {
- return err
+ return nil, err
}
- return buildahCopiah.Get(root, "", source.getOptions(), []string{glob}, destination.writer)
+ copier.copyFunc = func() error {
+ return buildahCopiah.Get(root, "", source.getOptions(), []string{glob}, destination.writer)
+ }
+ return copier, nil
}
// Destination is either a file or a directory.
if source.info.IsStream {
- return buildahCopiah.Put(destination.root, destination.resolved, source.putOptions(), source.reader)
+ copier.copyFunc = func() error {
+ return buildahCopiah.Put(destination.root, destination.resolved, source.putOptions(), source.reader)
+ }
+ return copier, nil
}
tarOptions := &archive.TarOptions{
@@ -71,33 +101,36 @@ func Copy(source *CopyItem, destination *CopyItem, extract bool) error {
var tarReader io.ReadCloser
if extract && archive.IsArchivePath(source.resolved) {
if !destination.info.IsDir {
- return errors.Errorf("cannot extract archive %q to file %q", source.original, destination.original)
+ return nil, errors.Errorf("cannot extract archive %q to file %q", source.original, destination.original)
}
reader, err := os.Open(source.resolved)
if err != nil {
- return err
+ return nil, err
}
- defer reader.Close()
+ copier.cleanUpFuncs = append(copier.cleanUpFuncs, func() { reader.Close() })
// The stream from stdin may be compressed (e.g., via gzip).
decompressedStream, err := archive.DecompressStream(reader)
if err != nil {
- return err
+ return nil, err
}
- defer decompressedStream.Close()
+ copier.cleanUpFuncs = append(copier.cleanUpFuncs, func() { decompressedStream.Close() })
tarReader = decompressedStream
} else {
reader, err := archive.TarWithOptions(source.resolved, tarOptions)
if err != nil {
- return err
+ return nil, err
}
- defer reader.Close()
+ copier.cleanUpFuncs = append(copier.cleanUpFuncs, func() { reader.Close() })
tarReader = reader
}
- return buildahCopiah.Put(root, dir, source.putOptions(), tarReader)
+ copier.copyFunc = func() error {
+ return buildahCopiah.Put(root, dir, source.putOptions(), tarReader)
+ }
+ return copier, nil
}
// enforceCopyRules enforces the rules for copying from a source to a
@@ -114,7 +147,6 @@ func enforceCopyRules(source, destination *CopyItem) error {
return nil
}
- // Source is a *stream*.
if source.info.IsStream {
if !(destination.info.IsDir || destination.info.IsStream) {
return errors.New("destination must be a directory or stream when copying from a stream")
diff --git a/pkg/copy/fileinfo.go b/pkg/copy/fileinfo.go
new file mode 100644
index 000000000..08b4eb377
--- /dev/null
+++ b/pkg/copy/fileinfo.go
@@ -0,0 +1,56 @@
+package copy
+
+import (
+ "encoding/base64"
+ "encoding/json"
+ "net/http"
+ "os"
+ "strings"
+ "time"
+
+ "github.com/pkg/errors"
+)
+
+// XDockerContainerPathStatHeader is the *key* in http headers pointing to the
+// base64 encoded JSON payload of stating a path in a container.
+const XDockerContainerPathStatHeader = "X-Docker-Container-Path-Stat"
+
+// FileInfo describes a file or directory and is returned by
+// (*CopyItem).Stat().
+type FileInfo struct {
+ Name string `json:"name"`
+ Size int64 `json:"size"`
+ Mode os.FileMode `json:"mode"`
+ ModTime time.Time `json:"mtime"`
+ IsDir bool `json:"isDir"`
+ IsStream bool `json:"isStream"`
+ LinkTarget string `json:"linkTarget"`
+}
+
+// EncodeFileInfo serializes the specified FileInfo as a base64 encoded JSON
+// payload. Intended for Docker compat.
+func EncodeFileInfo(info *FileInfo) (string, error) {
+ buf, err := json.Marshal(&info)
+ if err != nil {
+ return "", errors.Wrap(err, "failed to serialize file stats")
+ }
+ return base64.URLEncoding.EncodeToString(buf), nil
+}
+
+// ExtractFileInfoFromHeader extracts a base64 encoded JSON payload of a
+// FileInfo in the http header. If no such header entry is found, nil is
+// returned. Intended for Docker compat.
+func ExtractFileInfoFromHeader(header *http.Header) (*FileInfo, error) {
+ rawData := header.Get(XDockerContainerPathStatHeader)
+ if len(rawData) == 0 {
+ return nil, nil
+ }
+
+ info := FileInfo{}
+ base64Decoder := base64.NewDecoder(base64.URLEncoding, strings.NewReader(rawData))
+ if err := json.NewDecoder(base64Decoder).Decode(&info); err != nil {
+ return nil, err
+ }
+
+ return &info, nil
+}
diff --git a/pkg/copy/item.go b/pkg/copy/item.go
index db6bca610..df8bf30b9 100644
--- a/pkg/copy/item.go
+++ b/pkg/copy/item.go
@@ -5,7 +5,6 @@ import (
"os"
"path/filepath"
"strings"
- "time"
buildahCopiah "github.com/containers/buildah/copier"
"github.com/containers/buildah/pkg/chrootuser"
@@ -75,18 +74,6 @@ type CopyItem struct {
// deferFunc allows for returning functions that must be deferred at call sites.
type deferFunc func()
-// FileInfo describes a file or directory and is returned by
-// (*CopyItem).Stat().
-type FileInfo struct {
- Name string `json:"name"`
- Size int64 `json:"size"`
- Mode os.FileMode `json:"mode"`
- ModTime time.Time `json:"mtime"`
- IsDir bool `json:"isDir"`
- IsStream bool `json:"isStream"`
- LinkTarget string `json:"linkTarget"`
-}
-
// Stat returns the FileInfo.
func (item *CopyItem) Stat() (*FileInfo, error) {
return &item.info, item.statError
diff --git a/pkg/copy/parse.go b/pkg/copy/parse.go
new file mode 100644
index 000000000..39e0e1547
--- /dev/null
+++ b/pkg/copy/parse.go
@@ -0,0 +1,61 @@
+package copy
+
+import (
+ "strings"
+
+ "github.com/pkg/errors"
+)
+
+// ParseSourceAndDestination parses the source and destination input into a
+// possibly specified container and path. The input format is described in
+// podman-cp(1) as "[nameOrID:]path". Colons in paths are supported as long
+// they start with a dot or slash.
+//
+// It returns, in order, the source container and path, followed by the
+// destination container and path, and an error. Note that exactly one
+// container must be specified.
+func ParseSourceAndDestination(source, destination string) (string, string, string, string, error) {
+ sourceContainer, sourcePath := parseUserInput(source)
+ destContainer, destPath := parseUserInput(destination)
+
+ numContainers := 0
+ if len(sourceContainer) > 0 {
+ numContainers++
+ }
+ if len(destContainer) > 0 {
+ numContainers++
+ }
+
+ if numContainers != 1 {
+ return "", "", "", "", errors.Errorf("invalid arguments %q, %q: exactly 1 container expected but %d specified", source, destination, numContainers)
+ }
+
+ if len(sourcePath) == 0 || len(destPath) == 0 {
+ return "", "", "", "", errors.Errorf("invalid arguments %q, %q: you must specify paths", source, destination)
+ }
+
+ return sourceContainer, sourcePath, destContainer, destPath, nil
+}
+
+// parseUserInput parses the input string and returns, if specified, the name
+// or ID of the container and the path. The input format is described in
+// podman-cp(1) as "[nameOrID:]path". Colons in paths are supported as long
+// they start with a dot or slash.
+func parseUserInput(input string) (container string, path string) {
+ if len(input) == 0 {
+ return
+ }
+ path = input
+
+ // If the input starts with a dot or slash, it cannot refer to a
+ // container.
+ if input[0] == '.' || input[0] == '/' {
+ return
+ }
+
+ if spl := strings.SplitN(path, ":", 2); len(spl) == 2 {
+ container = spl[0]
+ path = spl[1]
+ }
+ return
+}
diff --git a/pkg/domain/infra/abi/cp.go b/pkg/domain/infra/abi/cp.go
index 9409df743..362053cce 100644
--- a/pkg/domain/infra/abi/cp.go
+++ b/pkg/domain/infra/abi/cp.go
@@ -2,46 +2,53 @@ package abi
import (
"context"
- "strings"
"github.com/containers/podman/v2/libpod"
"github.com/containers/podman/v2/pkg/copy"
"github.com/containers/podman/v2/pkg/domain/entities"
- "github.com/pkg/errors"
)
func (ic *ContainerEngine) ContainerCp(ctx context.Context, source, dest string, options entities.ContainerCpOptions) error {
- srcCtr, srcPath := parsePath(ic.Libpod, source)
- destCtr, destPath := parsePath(ic.Libpod, dest)
-
- if srcCtr != nil && destCtr != nil {
- return errors.Errorf("invalid arguments %q, %q: you must use just one container", source, dest)
+ // Parse user input.
+ sourceContainerStr, sourcePath, destContainerStr, destPath, err := copy.ParseSourceAndDestination(source, dest)
+ if err != nil {
+ return err
}
- if srcCtr == nil && destCtr == nil {
- return errors.Errorf("invalid arguments %q, %q: you must specify one container", source, dest)
+
+ // Look up containers.
+ var sourceContainer, destContainer *libpod.Container
+ if len(sourceContainerStr) > 0 {
+ sourceContainer, err = ic.Libpod.LookupContainer(sourceContainerStr)
+ if err != nil {
+ return err
+ }
}
- if len(srcPath) == 0 || len(destPath) == 0 {
- return errors.Errorf("invalid arguments %q, %q: you must specify paths", source, dest)
+ if len(destContainerStr) > 0 {
+ destContainer, err = ic.Libpod.LookupContainer(destContainerStr)
+ if err != nil {
+ return err
+ }
}
var sourceItem, destinationItem copy.CopyItem
- var err error
- // Copy from the container to the host.
- if srcCtr != nil {
- sourceItem, err = copy.CopyItemForContainer(srcCtr, srcPath, options.Pause, true)
+
+ // Source ... container OR host.
+ if sourceContainer != nil {
+ sourceItem, err = copy.CopyItemForContainer(sourceContainer, sourcePath, options.Pause, true)
defer sourceItem.CleanUp()
if err != nil {
return err
}
} else {
- sourceItem, err = copy.CopyItemForHost(srcPath, true)
+ sourceItem, err = copy.CopyItemForHost(sourcePath, true)
if err != nil {
return err
}
}
- if destCtr != nil {
- destinationItem, err = copy.CopyItemForContainer(destCtr, destPath, options.Pause, false)
+ // Destination ... container OR host.
+ if destContainer != nil {
+ destinationItem, err = copy.CopyItemForContainer(destContainer, destPath, options.Pause, false)
defer destinationItem.CleanUp()
if err != nil {
return err
@@ -55,22 +62,9 @@ func (ic *ContainerEngine) ContainerCp(ctx context.Context, source, dest string,
}
// Copy from the host to the container.
- return copy.Copy(&sourceItem, &destinationItem, options.Extract)
-}
-
-func parsePath(runtime *libpod.Runtime, path string) (*libpod.Container, string) {
- if len(path) == 0 {
- return nil, ""
- }
- if path[0] == '.' || path[0] == '/' { // A path cannot point to a container.
- return nil, path
- }
- pathArr := strings.SplitN(path, ":", 2)
- if len(pathArr) == 2 {
- ctr, err := runtime.LookupContainer(pathArr[0])
- if err == nil {
- return ctr, pathArr[1]
- }
+ copier, err := copy.GetCopier(&sourceItem, &destinationItem, options.Extract)
+ if err != nil {
+ return err
}
- return nil, path
+ return copier.Copy()
}
diff --git a/pkg/domain/infra/abi/manifest.go b/pkg/domain/infra/abi/manifest.go
index ad7128b42..600d64b1d 100644
--- a/pkg/domain/infra/abi/manifest.go
+++ b/pkg/domain/infra/abi/manifest.go
@@ -54,7 +54,7 @@ func (ir *ImageEngine) ManifestInspect(ctx context.Context, name string) ([]byte
}
return buf, nil
// no return if local image is not a list of images type
- // continue on getting valid manifest through remote serice
+ // continue on getting valid manifest through remote service
} else if errors.Cause(err) != buildahManifests.ErrManifestTypeNotSupported {
return nil, errors.Wrapf(err, "loading manifest %q", name)
}
diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go
index 3584668c7..e65fef0a4 100644
--- a/pkg/domain/infra/tunnel/containers.go
+++ b/pkg/domain/infra/tunnel/containers.go
@@ -732,7 +732,8 @@ func (ic *ContainerEngine) ContainerPort(ctx context.Context, nameOrID string, o
}
func (ic *ContainerEngine) ContainerCp(ctx context.Context, source, dest string, options entities.ContainerCpOptions) error {
- return errors.New("not implemented")
+ return nil
+ // return containers.Copy(ic.ClientCxt, source, dest, options)
}
// Shutdown Libpod engine
diff --git a/pkg/specgen/generate/kube/volume.go b/pkg/specgen/generate/kube/volume.go
index 2ef0f4c23..bb8edabb7 100644
--- a/pkg/specgen/generate/kube/volume.go
+++ b/pkg/specgen/generate/kube/volume.go
@@ -103,7 +103,7 @@ func VolumeFromSource(volumeSource v1.VolumeSource) (*KubeVolume, error) {
} else if volumeSource.PersistentVolumeClaim != nil {
return VolumeFromPersistentVolumeClaim(volumeSource.PersistentVolumeClaim)
} else {
- return nil, errors.Errorf("HostPath and PersistentVolumeClaim are currently the conly supported VolumeSource")
+ return nil, errors.Errorf("HostPath and PersistentVolumeClaim are currently the only supported VolumeSource")
}
}
diff --git a/test/system/015-help.bats b/test/system/015-help.bats
index 22db8be8a..5f38c34a1 100644
--- a/test/system/015-help.bats
+++ b/test/system/015-help.bats
@@ -12,22 +12,11 @@
#
load helpers
-# run 'podman help', parse the output looking for 'Available Commands';
-# return that list.
-function podman_commands() {
- dprint "$@"
- run_podman help "$@" |\
- awk '/^Available Commands:/{ok=1;next}/^Options:/{ok=0}ok { print $1 }' |\
- grep .
- "$output"
-}
-
-
function check_help() {
local count=0
local -A found
- for cmd in $(podman_commands "$@"); do
+ for cmd in $(_podman_commands "$@"); do
# Human-readable podman command string, with multiple spaces collapsed
command_string="podman $* $cmd"
command_string=${command_string// / } # 'podman x' -> 'podman x'
diff --git a/test/system/070-build.bats b/test/system/070-build.bats
index 59da503a6..8e9a2d613 100644
--- a/test/system/070-build.bats
+++ b/test/system/070-build.bats
@@ -381,6 +381,48 @@ a${random3}z"
run_podman rmi -f build_test
}
+@test "podman build --layers test" {
+ rand_content=$(random_string 50)
+ tmpdir=$PODMAN_TMPDIR/build-test
+ run mkdir -p $tmpdir
+ containerfile=$tmpdir/Containerfile
+ cat >$containerfile <<EOF
+FROM $IMAGE
+RUN echo $rand_content
+EOF
+
+ # Build twice to make sure second time uses cache
+ run_podman build -t build_test $tmpdir
+ if [[ "$output" =~ "Using cache" ]]; then
+ is "$output" "[no instance of 'Using cache']" "no cache used"
+ fi
+
+ run_podman build -t build_test $tmpdir
+ is "$output" ".*cache" "used cache"
+
+ run_podman build -t build_test --layers=true $tmpdir
+ is "$output" ".*cache" "used cache"
+
+ run_podman build -t build_test --layers=false $tmpdir
+ if [[ "$output" =~ "Using cache" ]]; then
+ is "$output" "[no instance of 'Using cache']" "no cache used"
+ fi
+
+ BUILDAH_LAYERS=false run_podman build -t build_test $tmpdir
+ if [[ "$output" =~ "Using cache" ]]; then
+ is "$output" "[no instance of 'Using cache']" "no cache used"
+ fi
+
+ BUILDAH_LAYERS=false run_podman build -t build_test --layers=1 $tmpdir
+ is "$output" ".*cache" "used cache"
+
+ BUILDAH_LAYERS=1 run_podman build -t build_test --layers=false $tmpdir
+ if [[ "$output" =~ "Using cache" ]]; then
+ is "$output" "[no instance of 'Using cache']" "no cache used"
+ fi
+
+ run_podman rmi -a --force
+}
function teardown() {
# A timeout or other error in 'build' can leave behind stale images
diff --git a/test/system/600-completion.bats b/test/system/600-completion.bats
new file mode 100644
index 000000000..1e43cdc41
--- /dev/null
+++ b/test/system/600-completion.bats
@@ -0,0 +1,272 @@
+#!/usr/bin/env bats -*- bats -*-
+#
+# Test podman shell completion
+#
+# Shell completion is provided via the cobra library
+# It is implement by calling a hidden subcommand called "__complete"
+#
+
+load helpers
+
+function check_shell_completion() {
+ local count=0
+
+ # Newline character; used for confirming string output
+ local nl="
+"
+
+ for cmd in $(_podman_commands "$@"); do
+ # Human-readable podman command string, with multiple spaces collapsed
+ name="podman"
+ if is_remote; then
+ name="podman-remote"
+ fi
+ command_string="$name $* $cmd"
+ command_string=${command_string// / } # 'podman x' -> 'podman x'
+
+ run_podman "$@" $cmd --help
+ local full_help="$output"
+
+ # The line immediately after 'Usage:' gives us a 1-line synopsis
+ usage=$(echo "$full_help" | grep -A1 '^Usage:' | tail -1)
+ [ -n "$usage" ] || die "podman $cmd: no Usage message found"
+
+ # If usage ends in '[command]', recurse into subcommands
+ if expr "$usage" : '.*\[command\]$' >/dev/null; then
+ check_shell_completion "$@" $cmd
+ continue
+ fi
+
+ # Trim to command path so we only have the args
+ args="${usage/$command_string/}"
+ # Trim leading whitespaces
+ args="${args#"${args%%[![:space:]]*}"}"
+
+ # Extra args is used to match the correct argument number for the command
+ # This is important because some commands provide different suggestions based
+ # on the number of arguments.
+ extra_args=()
+
+ for arg in $args; do
+
+ match=false
+ i=0
+ while true; do
+
+ case $arg in
+
+ # If we have options than we need to check if we are getting flag completion
+ "[options]")
+ # skip this for remote it fails if a command only has the latest flag e.g podman top
+ if ! is_remote; then
+ run_completion "$@" $cmd "--"
+ # If this fails there is most likely a problem with the cobra library
+ is "${lines[0]}" "--.*" "Found flag in suggestions"
+ [ ${#lines[@]} -gt 2 ] || die "No flag suggestions"
+ _check_completion_end NoFileComp
+ fi
+ # continue the outer for args loop
+ continue 2
+ ;;
+
+ *CONTAINER*)
+ run_completion "$@" $cmd "${extra_args[@]}" ""
+ is "$output" ".*-$random_container_name${nl}" "Found expected container in suggestions"
+
+ match=true
+ # resume
+ ;;&
+
+ *POD*)
+ run_completion "$@" $cmd "${extra_args[@]}" ""
+ is "$output" ".*-$random_pod_name${nl}" "Found expected pod in suggestions"
+ _check_completion_end NoFileComp
+
+ match=true
+ # resume
+ ;;&
+
+ *IMAGE*)
+ run_completion "$@" $cmd "${extra_args[@]}" ""
+ is "$output" ".*localhost/$random_image_name:$random_image_tag${nl}" "Found expected image in suggestions"
+
+ # check that we complete the image with and without tag after at least one char is typed
+ run_completion "$@" $cmd "${extra_args[@]}" "${random_image_name:0:1}"
+ is "$output" ".*$random_image_name:$random_image_tag${nl}" "Found expected image with tag in suggestions"
+ is "$output" ".*$random_image_name${nl}" "Found expected image without tag in suggestions"
+
+ # check that we complete the image id after at least two chars are typed
+ run_completion "$@" $cmd "${extra_args[@]}" "${random_image_id:0:2}"
+ is "$output" ".*$random_image_id${nl}" "Found expected image id in suggestions"
+
+ match=true
+ # resume
+ ;;&
+
+ *NETWORK*)
+ run_completion "$@" $cmd "${extra_args[@]}" ""
+ is "$output" ".*$random_network_name${nl}" "Found network in suggestions"
+ _check_completion_end NoFileComp
+
+ match=true
+ # resume
+ ;;&
+
+ *VOLUME*)
+ run_completion "$@" $cmd "${extra_args[@]}" ""
+ is "$output" ".*$random_volume_name${nl}" "Found volume in suggestions"
+ _check_completion_end NoFileComp
+
+ match=true
+ # resume
+ ;;&
+
+ *REGISTRY*)
+ run_completion "$@" $cmd "${extra_args[@]}" ""
+ ### FIXME how can we get the configured registries?
+ _check_completion_end NoFileComp
+ ### FIXME this fails if no registries are configured
+ [[ ${#lines[@]} -gt 2 ]] || die "No registries found in suggestions"
+
+ match=true
+ # resume
+ ;;&
+
+ *PATH* | *CONTEXT* | *KUBEFILE* | *COMMAND* | *ARG...* | *URI*)
+ # default shell completion should be done for everthing which accepts a path
+ run_completion "$@" $cmd "${extra_args[@]}" ""
+
+ # cp is a special case it returns ShellCompDirectiveNoSpace
+ if [[ "$cmd" == "cp" ]]; then
+ _check_completion_end NoSpace
+ else
+ _check_completion_end Default
+ [[ ${#lines[@]} -eq 2 ]] || die "Suggestions are in the output"
+ fi
+ ;;
+
+ *)
+ if [[ "$match" == "false" ]]; then
+ dprint "UNKNOWN arg: $arg for $command_string ${extra_args[*]}"
+ fi
+ ;;
+
+ esac
+
+ # Increment the argument array
+ extra_args+=("arg")
+
+ i=$(($i + 1))
+ # If the argument ends with ...] than we accept 0...n args
+ # Loop three times to make sure we are not only completing the first arg
+ if [[ ! ${arg} =~ "..." ]] || [[ i -gt 3 ]]; then
+ break
+ fi
+
+ done
+
+ done
+
+ # If the command takes no more parameters make sure we are getting no completion
+ if [[ ! ${args##* } =~ "..." ]]; then
+ run_completion "$@" $cmd "${extra_args[@]}" ""
+ _check_completion_end NoFileComp
+ if [ ${#lines[@]} -gt 2 ]; then
+ # checking for line count is not enough since we may inlcude additional debug output
+ # lines starting with [Debug] are allowed
+ i=0
+ length=$(( ${#lines[@]} - 2 ))
+ while [[ i -lt length ]]; do
+ [[ "${lines[$i]:0:7}" == "[Debug]" ]] || die "Suggestions are in the output"
+ i=$(( i + 1 ))
+ done
+ fi
+ fi
+
+ done
+
+}
+
+# run the completion cmd
+function run_completion() {
+ PODMAN="$PODMAN_COMPLETION" run_podman "$@"
+}
+
+# check for the given ShellCompDirective (always last line)
+function _check_completion_end() {
+ is "${lines[-1]}" "Completion ended with directive: ShellCompDirective$1" "Completion has wrong ShellCompDirective set"
+}
+
+
+@test "podman shell completion test" {
+
+ random_container_name=$(random_string 30)
+ random_pod_name=$(random_string 30)
+ random_image_name=$(random_string 30)
+ random_image_name=${random_image_name,,} # name must be lowercase
+ random_image_tag=$(random_string 5)
+ random_network_name=$(random_string 30)
+ random_volume_name=$(random_string 30)
+
+ # create a container for each state since some commands are only suggesting running container for example
+ run_podman create --name created-$random_container_name $IMAGE
+ run_podman run --name running-$random_container_name -d $IMAGE top
+ run_podman run --name pause-$random_container_name -d $IMAGE top
+ run_podman pause pause-$random_container_name
+ run_podman run --name exited-$random_container_name -d $IMAGE echo exited
+
+ # create pods for each state
+ run_podman pod create --name created-$random_pod_name
+ run_podman pod create --name running-$random_pod_name
+ run_podman run -d --name running-$random_pod_name-con --pod running-$random_pod_name $IMAGE top
+ run_podman pod create --name degraded-$random_pod_name
+ run_podman run -d --name degraded-$random_pod_name-con --pod degraded-$random_pod_name $IMAGE echo degraded
+ run_podman pod create --name exited-$random_pod_name
+ run_podman run -d --name exited-$random_pod_name-con --pod exited-$random_pod_name $IMAGE echo exited
+ run_podman pod stop exited-$random_pod_name
+
+ # create image name (just tag with new names no need to pull)
+ run_podman image tag $IMAGE $random_image_name:$random_image_tag
+ run_podman image list --format '{{.ID}}' --filter reference=$random_image_name
+ random_image_id="${lines[0]}"
+
+ # create network
+ run_podman network create $random_network_name
+
+ # create volume
+ run_podman volume create $random_volume_name
+
+
+ # $PODMAN may be a space-separated string, e.g. if we include a --url.
+ local -a podman_as_array=($PODMAN)
+ # __completeNoDesc must be the first arg if we running the completion cmd
+ PODMAN_COMPLETION="${podman_as_array[0]} __completeNoDesc ${podman_as_array[@]:1}"
+
+ # Called with no args -- start with 'podman --help'. check_shell_completion() will
+ # recurse for any subcommands.
+ check_shell_completion
+
+ # cleanup
+ run_podman volume rm $random_volume_name
+
+ run_podman network rm $random_network_name
+
+ run_podman image untag $IMAGE $random_image_name:$random_image_tag
+
+ for state in created running degraded exited; do
+ run_podman pod rm --force $state-$random_pod_name
+ done
+
+ for state in created running pause exited; do
+ run_podman rm --force $state-$random_container_name
+ done
+
+ # Clean up the pod pause image
+ run_podman image list --format '{{.ID}} {{.Repository}}'
+ while read id name; do
+ if [[ "$name" =~ /pause ]]; then
+ run_podman rmi $id
+ fi
+ done <<<"$output"
+
+}
diff --git a/test/system/helpers.bash b/test/system/helpers.bash
index 2cced10c2..6a7c6cc42 100644
--- a/test/system/helpers.bash
+++ b/test/system/helpers.bash
@@ -521,5 +521,15 @@ function remove_same_dev_warning() {
output=$(printf '%s\n' "${lines[@]}")
}
+# run 'podman help', parse the output looking for 'Available Commands';
+# return that list.
+function _podman_commands() {
+ dprint "$@"
+ run_podman help "$@" |
+ awk '/^Available Commands:/{ok=1;next}/^Options:/{ok=0}ok { print $1 }' |
+ grep .
+ "$output"
+}
+
# END miscellaneous tools
###############################################################################
diff --git a/vendor/github.com/onsi/gomega/.travis.yml b/vendor/github.com/onsi/gomega/.travis.yml
index e250be4ac..348e3014c 100644
--- a/vendor/github.com/onsi/gomega/.travis.yml
+++ b/vendor/github.com/onsi/gomega/.travis.yml
@@ -1,4 +1,7 @@
language: go
+arch:
+ - amd64
+ - ppc64le
go:
- 1.14.x
diff --git a/vendor/github.com/onsi/gomega/CHANGELOG.md b/vendor/github.com/onsi/gomega/CHANGELOG.md
index 940953394..0f1765d84 100644
--- a/vendor/github.com/onsi/gomega/CHANGELOG.md
+++ b/vendor/github.com/onsi/gomega/CHANGELOG.md
@@ -1,3 +1,10 @@
+## 1.10.4
+
+### Fixes
+- update golang net library to more recent version without vulnerability (#406) [817a8b9]
+- Correct spelling: alloted -> allotted (#403) [0bae715]
+- fix a panic in MessageWithDiff with long message (#402) [ea06b9b]
+
## 1.10.3
### Fixes
diff --git a/vendor/github.com/onsi/gomega/format/format.go b/vendor/github.com/onsi/gomega/format/format.go
index fae25adce..e59d7d75b 100644
--- a/vendor/github.com/onsi/gomega/format/format.go
+++ b/vendor/github.com/onsi/gomega/format/format.go
@@ -105,7 +105,13 @@ func MessageWithDiff(actual, message, expected string) string {
tabLength := 4
spaceFromMessageToActual := tabLength + len("<string>: ") - len(message)
- padding := strings.Repeat(" ", spaceFromMessageToActual+spacesBeforeFormattedMismatch) + "|"
+
+ paddingCount := spaceFromMessageToActual + spacesBeforeFormattedMismatch
+ if paddingCount < 0 {
+ return Message(formattedActual, message, formattedExpected)
+ }
+
+ padding := strings.Repeat(" ", paddingCount) + "|"
return Message(formattedActual, message+padding, formattedExpected)
}
diff --git a/vendor/github.com/onsi/gomega/gbytes/io_wrappers.go b/vendor/github.com/onsi/gomega/gbytes/io_wrappers.go
index 3caed8769..a41ad6232 100644
--- a/vendor/github.com/onsi/gomega/gbytes/io_wrappers.go
+++ b/vendor/github.com/onsi/gomega/gbytes/io_wrappers.go
@@ -9,17 +9,17 @@ import (
// ErrTimeout is returned by TimeoutCloser, TimeoutReader, and TimeoutWriter when the underlying Closer/Reader/Writer does not return within the specified timeout
var ErrTimeout = errors.New("timeout occurred")
-// TimeoutCloser returns an io.Closer that wraps the passed-in io.Closer. If the underlying Closer fails to close within the alloted timeout ErrTimeout is returned.
+// TimeoutCloser returns an io.Closer that wraps the passed-in io.Closer. If the underlying Closer fails to close within the allotted timeout ErrTimeout is returned.
func TimeoutCloser(c io.Closer, timeout time.Duration) io.Closer {
return timeoutReaderWriterCloser{c: c, d: timeout}
}
-// TimeoutReader returns an io.Reader that wraps the passed-in io.Reader. If the underlying Reader fails to read within the alloted timeout ErrTimeout is returned.
+// TimeoutReader returns an io.Reader that wraps the passed-in io.Reader. If the underlying Reader fails to read within the allotted timeout ErrTimeout is returned.
func TimeoutReader(r io.Reader, timeout time.Duration) io.Reader {
return timeoutReaderWriterCloser{r: r, d: timeout}
}
-// TimeoutWriter returns an io.Writer that wraps the passed-in io.Writer. If the underlying Writer fails to write within the alloted timeout ErrTimeout is returned.
+// TimeoutWriter returns an io.Writer that wraps the passed-in io.Writer. If the underlying Writer fails to write within the allotted timeout ErrTimeout is returned.
func TimeoutWriter(w io.Writer, timeout time.Duration) io.Writer {
return timeoutReaderWriterCloser{w: w, d: timeout}
}
diff --git a/vendor/github.com/onsi/gomega/go.mod b/vendor/github.com/onsi/gomega/go.mod
index 0a80d5ec3..02b99ab60 100644
--- a/vendor/github.com/onsi/gomega/go.mod
+++ b/vendor/github.com/onsi/gomega/go.mod
@@ -5,7 +5,7 @@ go 1.14
require (
github.com/golang/protobuf v1.4.2
github.com/onsi/ginkgo v1.12.1
- golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0
+ golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543
gopkg.in/yaml.v2 v2.3.0
)
diff --git a/vendor/github.com/onsi/gomega/go.sum b/vendor/github.com/onsi/gomega/go.sum
index c54e9b88e..fc230153b 100644
--- a/vendor/github.com/onsi/gomega/go.sum
+++ b/vendor/github.com/onsi/gomega/go.sum
@@ -31,6 +31,8 @@ golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 h1:AeiKBIuRw3UomYXSbLy0Mc2dD
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0 h1:wBouT66WTYFXdxfVdz9sVWARVd/2vfGcmI45D2gj45M=
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U=
+golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs=
@@ -42,6 +44,7 @@ golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e h1:N7DeIrjYszNmSW409R3frPPwg
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
diff --git a/vendor/github.com/onsi/gomega/gomega_dsl.go b/vendor/github.com/onsi/gomega/gomega_dsl.go
index 4af1a8c01..a8529f1ca 100644
--- a/vendor/github.com/onsi/gomega/gomega_dsl.go
+++ b/vendor/github.com/onsi/gomega/gomega_dsl.go
@@ -24,7 +24,7 @@ import (
"github.com/onsi/gomega/types"
)
-const GOMEGA_VERSION = "1.10.3"
+const GOMEGA_VERSION = "1.10.4"
const nilFailHandlerPanic = `You are trying to make an assertion, but Gomega's fail handler is nil.
If you're using Ginkgo then you probably forgot to put your assertion in an It().
diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go
index 10ac15a85..988adc8f4 100644
--- a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go
+++ b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go
@@ -27,14 +27,14 @@ var ErrIncompatibleLabel = errors.New("Bad SELinux option z and Z can not be use
// the container. A list of options can be passed into this function to alter
// the labels. The labels returned will include a random MCS String, that is
// guaranteed to be unique.
-func InitLabels(options []string) (plabel string, mlabel string, Err error) {
+func InitLabels(options []string) (plabel string, mlabel string, retErr error) {
if !selinux.GetEnabled() {
return "", "", nil
}
processLabel, mountLabel := selinux.ContainerLabels()
if processLabel != "" {
defer func() {
- if Err != nil {
+ if retErr != nil {
selinux.ReleaseLabel(mountLabel)
}
}()
@@ -57,7 +57,6 @@ func InitLabels(options []string) (plabel string, mlabel string, Err error) {
con := strings.SplitN(opt, ":", 2)
if !validOptions[con[0]] {
return "", "", errors.Errorf("Bad label option %q, valid options 'disable, user, role, level, type, filetype'", con[0])
-
}
if con[0] == "filetype" {
mcon["type"] = con[1]
diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go
index 50760dc93..d9119908b 100644
--- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go
+++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go
@@ -30,6 +30,11 @@ var (
// ErrLevelSyntax is returned when a sensitivity or category do not have correct syntax in a level
ErrLevelSyntax = errors.New("invalid level syntax")
+ // ErrContextMissing is returned if a requested context is not found in a file.
+ ErrContextMissing = errors.New("context does not have a match")
+ // ErrVerifierNil is returned when a context verifier function is nil.
+ ErrVerifierNil = errors.New("verifier function is nil")
+
// CategoryRange allows the upper bound on the category range to be adjusted
CategoryRange = DefaultCategoryRange
)
@@ -63,8 +68,12 @@ func FileLabel(fpath string) (string, error) {
return fileLabel(fpath)
}
-// SetFSCreateLabel tells kernel the label to create all file system objects
-// created by this task. Setting label="" to return to default.
+// SetFSCreateLabel tells the kernel what label to use for all file system objects
+// created by this task.
+// Set the label to an empty string to return to the default label. Calls to SetFSCreateLabel
+// should be wrapped in runtime.LockOSThread()/runtime.UnlockOSThread() until file system
+// objects created by this task are finished to guarantee another goroutine does not migrate
+// to the current thread before execution is complete.
func SetFSCreateLabel(label string) error {
return setFSCreateLabel(label)
}
@@ -113,19 +122,27 @@ func CalculateGlbLub(sourceRange, targetRange string) (string, error) {
}
// SetExecLabel sets the SELinux label that the kernel will use for any programs
-// that are executed by the current process thread, or an error.
+// that are executed by the current process thread, or an error. Calls to SetExecLabel
+// should be wrapped in runtime.LockOSThread()/runtime.UnlockOSThread() until execution
+// of the program is finished to guarantee another goroutine does not migrate to the current
+// thread before execution is complete.
func SetExecLabel(label string) error {
return setExecLabel(label)
}
// SetTaskLabel sets the SELinux label for the current thread, or an error.
-// This requires the dyntransition permission.
+// This requires the dyntransition permission. Calls to SetTaskLabel should
+// be wrapped in runtime.LockOSThread()/runtime.UnlockOSThread() to guarantee
+// the current thread does not run in a new mislabeled thread.
func SetTaskLabel(label string) error {
return setTaskLabel(label)
}
// SetSocketLabel takes a process label and tells the kernel to assign the
-// label to the next socket that gets created
+// label to the next socket that gets created. Calls to SetSocketLabel
+// should be wrapped in runtime.LockOSThread()/runtime.UnlockOSThread() until
+// the the socket is created to guarantee another goroutine does not migrate
+// to the current thread before execution is complete.
func SetSocketLabel(label string) error {
return setSocketLabel(label)
}
@@ -141,7 +158,10 @@ func PeerLabel(fd uintptr) (string, error) {
}
// SetKeyLabel takes a process label and tells the kernel to assign the
-// label to the next kernel keyring that gets created
+// label to the next kernel keyring that gets created. Calls to SetKeyLabel
+// should be wrapped in runtime.LockOSThread()/runtime.UnlockOSThread() until
+// the kernel keyring is created to guarantee another goroutine does not migrate
+// to the current thread before execution is complete.
func SetKeyLabel(label string) error {
return setKeyLabel(label)
}
@@ -247,3 +267,12 @@ func DupSecOpt(src string) ([]string, error) {
func DisableSecOpt() []string {
return disableSecOpt()
}
+
+// GetDefaultContextWithLevel gets a single context for the specified SELinux user
+// identity that is reachable from the specified scon context. The context is based
+// on the per-user /etc/selinux/{SELINUXTYPE}/contexts/users/<username> if it exists,
+// and falls back to the global /etc/selinux/{SELINUXTYPE}/contexts/default_contexts
+// file.
+func GetDefaultContextWithLevel(user, level, scon string) (string, error) {
+ return getDefaultContextWithLevel(user, level, scon)
+}
diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go
index d6b0d49db..904f5b04f 100644
--- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go
+++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go
@@ -28,6 +28,8 @@ const (
minSensLen = 2
contextFile = "/usr/share/containers/selinux/contexts"
selinuxDir = "/etc/selinux/"
+ selinuxUsersDir = "contexts/users"
+ defaultContexts = "contexts/default_contexts"
selinuxConfig = selinuxDir + "config"
selinuxfsMount = "/sys/fs/selinux"
selinuxTypeTag = "SELINUXTYPE"
@@ -35,6 +37,8 @@ const (
xattrNameSelinux = "security.selinux"
)
+var policyRoot = filepath.Join(selinuxDir, readConfig(selinuxTypeTag))
+
type selinuxState struct {
enabledSet bool
enabled bool
@@ -54,6 +58,13 @@ type mlsRange struct {
high *level
}
+type defaultSECtx struct {
+ user, level, scon string
+ userRdr, defaultRdr io.Reader
+
+ verifier func(string) error
+}
+
type levelItem byte
const (
@@ -111,7 +122,7 @@ func verifySELinuxfsMount(mnt string) bool {
if err == nil {
break
}
- if err == unix.EAGAIN {
+ if err == unix.EAGAIN || err == unix.EINTR {
continue
}
return false
@@ -205,28 +216,16 @@ func getEnabled() bool {
}
func readConfig(target string) string {
- var (
- val, key string
- bufin *bufio.Reader
- )
-
in, err := os.Open(selinuxConfig)
if err != nil {
return ""
}
defer in.Close()
- bufin = bufio.NewReader(in)
+ scanner := bufio.NewScanner(in)
- for done := false; !done; {
- var line string
- if line, err = bufin.ReadString('\n'); err != nil {
- if err != io.EOF {
- return ""
- }
- done = true
- }
- line = strings.TrimSpace(line)
+ for scanner.Scan() {
+ line := strings.TrimSpace(scanner.Text())
if len(line) == 0 {
// Skip blank lines
continue
@@ -236,7 +235,7 @@ func readConfig(target string) string {
continue
}
if groups := assignRegex.FindStringSubmatch(line); groups != nil {
- key, val = strings.TrimSpace(groups[1]), strings.TrimSpace(groups[2])
+ key, val := strings.TrimSpace(groups[1]), strings.TrimSpace(groups[2])
if key == target {
return strings.Trim(val, "\"")
}
@@ -245,15 +244,17 @@ func readConfig(target string) string {
return ""
}
-func getSELinuxPolicyRoot() string {
- return filepath.Join(selinuxDir, readConfig(selinuxTypeTag))
-}
-
func isProcHandle(fh *os.File) error {
var buf unix.Statfs_t
- err := unix.Fstatfs(int(fh.Fd()), &buf)
- if err != nil {
- return errors.Wrapf(err, "statfs(%q) failed", fh.Name())
+
+ for {
+ err := unix.Fstatfs(int(fh.Fd()), &buf)
+ if err == nil {
+ break
+ }
+ if err != unix.EINTR {
+ return errors.Wrapf(err, "statfs(%q) failed", fh.Name())
+ }
}
if buf.Type != unix.PROC_SUPER_MAGIC {
return errors.Errorf("file %q is not on procfs", fh.Name())
@@ -307,9 +308,16 @@ func setFileLabel(fpath string, label string) error {
if fpath == "" {
return ErrEmptyPath
}
- if err := unix.Lsetxattr(fpath, xattrNameSelinux, []byte(label), 0); err != nil {
- return errors.Wrapf(err, "failed to set file label on %s", fpath)
+ for {
+ err := unix.Lsetxattr(fpath, xattrNameSelinux, []byte(label), 0)
+ if err == nil {
+ break
+ }
+ if err != unix.EINTR {
+ return errors.Wrapf(err, "failed to set file label on %s", fpath)
+ }
}
+
return nil
}
@@ -751,7 +759,7 @@ func reserveLabel(label string) {
if len(label) != 0 {
con := strings.SplitN(label, ":", 4)
if len(con) > 3 {
- mcsAdd(con[3])
+ _ = mcsAdd(con[3])
}
}
}
@@ -828,11 +836,11 @@ func intToMcs(id int, catRange uint32) string {
}
for ORD > TIER {
- ORD = ORD - TIER
+ ORD -= TIER
TIER--
}
TIER = SETSIZE - TIER
- ORD = ORD + TIER
+ ORD += TIER
return fmt.Sprintf("s0:c%d,c%d", TIER, ORD)
}
@@ -844,16 +852,14 @@ func uniqMcs(catRange uint32) string {
)
for {
- binary.Read(rand.Reader, binary.LittleEndian, &n)
+ _ = binary.Read(rand.Reader, binary.LittleEndian, &n)
c1 = n % catRange
- binary.Read(rand.Reader, binary.LittleEndian, &n)
+ _ = binary.Read(rand.Reader, binary.LittleEndian, &n)
c2 = n % catRange
if c1 == c2 {
continue
- } else {
- if c1 > c2 {
- c1, c2 = c2, c1
- }
+ } else if c1 > c2 {
+ c1, c2 = c2, c1
}
mcs = fmt.Sprintf("s0:c%d,c%d", c1, c2)
if err := mcsAdd(mcs); err != nil {
@@ -884,18 +890,13 @@ func openContextFile() (*os.File, error) {
if f, err := os.Open(contextFile); err == nil {
return f, nil
}
- lxcPath := filepath.Join(getSELinuxPolicyRoot(), "/contexts/lxc_contexts")
+ lxcPath := filepath.Join(policyRoot, "/contexts/lxc_contexts")
return os.Open(lxcPath)
}
var labels = loadLabels()
func loadLabels() map[string]string {
- var (
- val, key string
- bufin *bufio.Reader
- )
-
labels := make(map[string]string)
in, err := openContextFile()
if err != nil {
@@ -903,18 +904,10 @@ func loadLabels() map[string]string {
}
defer in.Close()
- bufin = bufio.NewReader(in)
+ scanner := bufio.NewScanner(in)
- for done := false; !done; {
- var line string
- if line, err = bufin.ReadString('\n'); err != nil {
- if err == io.EOF {
- done = true
- } else {
- break
- }
- }
- line = strings.TrimSpace(line)
+ for scanner.Scan() {
+ line := strings.TrimSpace(scanner.Text())
if len(line) == 0 {
// Skip blank lines
continue
@@ -924,7 +917,7 @@ func loadLabels() map[string]string {
continue
}
if groups := assignRegex.FindStringSubmatch(line); groups != nil {
- key, val = strings.TrimSpace(groups[1]), strings.TrimSpace(groups[2])
+ key, val := strings.TrimSpace(groups[1]), strings.TrimSpace(groups[2])
labels[key] = strings.Trim(val, "\"")
}
}
@@ -1015,7 +1008,7 @@ func copyLevel(src, dest string) (string, error) {
return "", err
}
mcsDelete(tcon["level"])
- mcsAdd(scon["level"])
+ _ = mcsAdd(scon["level"])
tcon["level"] = scon["level"]
return tcon.Get(), nil
}
@@ -1095,3 +1088,124 @@ func dupSecOpt(src string) ([]string, error) {
func disableSecOpt() []string {
return []string{"disable"}
}
+
+// findUserInContext scans the reader for a valid SELinux context
+// match that is verified with the verifier. Invalid contexts are
+// skipped. It returns a matched context or an empty string if no
+// match is found. If a scanner error occurs, it is returned.
+func findUserInContext(context Context, r io.Reader, verifier func(string) error) (string, error) {
+ fromRole := context["role"]
+ fromType := context["type"]
+ scanner := bufio.NewScanner(r)
+
+ for scanner.Scan() {
+ fromConns := strings.Fields(scanner.Text())
+ if len(fromConns) == 0 {
+ // Skip blank lines
+ continue
+ }
+
+ line := fromConns[0]
+
+ if line[0] == ';' || line[0] == '#' {
+ // Skip comments
+ continue
+ }
+
+ // user context files contexts are formatted as
+ // role_r:type_t:s0 where the user is missing.
+ lineArr := strings.SplitN(line, ":", 4)
+ // skip context with typo, or role and type do not match
+ if len(lineArr) != 3 ||
+ lineArr[0] != fromRole ||
+ lineArr[1] != fromType {
+ continue
+ }
+
+ for _, cc := range fromConns[1:] {
+ toConns := strings.SplitN(cc, ":", 4)
+ if len(toConns) != 3 {
+ continue
+ }
+
+ context["role"] = toConns[0]
+ context["type"] = toConns[1]
+
+ outConn := context.get()
+ if err := verifier(outConn); err != nil {
+ continue
+ }
+
+ return outConn, nil
+ }
+ }
+
+ if err := scanner.Err(); err != nil {
+ return "", errors.Wrap(err, "failed to scan for context")
+ }
+
+ return "", nil
+}
+
+func getDefaultContextFromReaders(c *defaultSECtx) (string, error) {
+ if c.verifier == nil {
+ return "", ErrVerifierNil
+ }
+
+ context, err := newContext(c.scon)
+ if err != nil {
+ return "", errors.Wrapf(err, "failed to create label for %s", c.scon)
+ }
+
+ // set so the verifier validates the matched context with the provided user and level.
+ context["user"] = c.user
+ context["level"] = c.level
+
+ conn, err := findUserInContext(context, c.userRdr, c.verifier)
+ if err != nil {
+ return "", err
+ }
+
+ if conn != "" {
+ return conn, nil
+ }
+
+ conn, err = findUserInContext(context, c.defaultRdr, c.verifier)
+ if err != nil {
+ return "", err
+ }
+
+ if conn != "" {
+ return conn, nil
+ }
+
+ return "", errors.Wrapf(ErrContextMissing, "context not found: %q", c.scon)
+}
+
+func getDefaultContextWithLevel(user, level, scon string) (string, error) {
+ userPath := filepath.Join(policyRoot, selinuxUsersDir, user)
+ defaultPath := filepath.Join(policyRoot, defaultContexts)
+
+ fu, err := os.Open(userPath)
+ if err != nil {
+ return "", err
+ }
+ defer fu.Close()
+
+ fd, err := os.Open(defaultPath)
+ if err != nil {
+ return "", err
+ }
+ defer fd.Close()
+
+ c := defaultSECtx{
+ user: user,
+ level: level,
+ scon: scon,
+ userRdr: fu,
+ defaultRdr: fd,
+ verifier: securityCheckContext,
+ }
+
+ return getDefaultContextFromReaders(&c)
+}
diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go
index c526b210f..e4b65c9e2 100644
--- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go
+++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go
@@ -146,3 +146,7 @@ func dupSecOpt(src string) ([]string, error) {
func disableSecOpt() []string {
return []string{"disable"}
}
+
+func getDefaultContextWithLevel(user, level, scon string) (string, error) {
+ return "", nil
+}
diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/xattrs.go b/vendor/github.com/opencontainers/selinux/go-selinux/xattrs.go
index de5c80ef3..2365b4bda 100644
--- a/vendor/github.com/opencontainers/selinux/go-selinux/xattrs.go
+++ b/vendor/github.com/opencontainers/selinux/go-selinux/xattrs.go
@@ -6,21 +6,21 @@ import (
"golang.org/x/sys/unix"
)
-// Returns a []byte slice if the xattr is set and nil otherwise
-// Requires path and its attribute as arguments
-func lgetxattr(path string, attr string) ([]byte, error) {
+// lgetxattr returns a []byte slice containing the value of
+// an extended attribute attr set for path.
+func lgetxattr(path, attr string) ([]byte, error) {
// Start with a 128 length byte array
dest := make([]byte, 128)
- sz, errno := unix.Lgetxattr(path, attr, dest)
+ sz, errno := doLgetxattr(path, attr, dest)
for errno == unix.ERANGE {
// Buffer too small, use zero-sized buffer to get the actual size
- sz, errno = unix.Lgetxattr(path, attr, []byte{})
+ sz, errno = doLgetxattr(path, attr, []byte{})
if errno != nil {
return nil, errno
}
dest = make([]byte, sz)
- sz, errno = unix.Lgetxattr(path, attr, dest)
+ sz, errno = doLgetxattr(path, attr, dest)
}
if errno != nil {
return nil, errno
@@ -28,3 +28,13 @@ func lgetxattr(path string, attr string) ([]byte, error) {
return dest[:sz], nil
}
+
+// doLgetxattr is a wrapper that retries on EINTR
+func doLgetxattr(path, attr string, dest []byte) (int, error) {
+ for {
+ sz, err := unix.Lgetxattr(path, attr, dest)
+ if err != unix.EINTR {
+ return sz, err
+ }
+ }
+}
diff --git a/vendor/github.com/opencontainers/selinux/pkg/pwalk/pwalk.go b/vendor/github.com/opencontainers/selinux/pkg/pwalk/pwalk.go
index 63fde1842..437b12b3e 100644
--- a/vendor/github.com/opencontainers/selinux/pkg/pwalk/pwalk.go
+++ b/vendor/github.com/opencontainers/selinux/pkg/pwalk/pwalk.go
@@ -20,17 +20,16 @@ type WalkFunc = filepath.WalkFunc
//
// Note that this implementation only supports primitive error handling:
//
-// * no errors are ever passed to WalkFn
+// - no errors are ever passed to WalkFn;
//
-// * once a walkFn returns any error, all further processing stops
-// and the error is returned to the caller of Walk;
+// - once a walkFn returns any error, all further processing stops
+// and the error is returned to the caller of Walk;
//
-// * filepath.SkipDir is not supported;
-//
-// * if more than one walkFn instance will return an error, only one
-// of such errors will be propagated and returned by Walk, others
-// will be silently discarded.
+// - filepath.SkipDir is not supported;
//
+// - if more than one walkFn instance will return an error, only one
+// of such errors will be propagated and returned by Walk, others
+// will be silently discarded.
func Walk(root string, walkFn WalkFunc) error {
return WalkN(root, walkFn, runtime.NumCPU()*2)
}
@@ -38,6 +37,8 @@ func Walk(root string, walkFn WalkFunc) error {
// WalkN is a wrapper for filepath.Walk which can call multiple walkFn
// in parallel, allowing to handle each item concurrently. A maximum of
// num walkFn will be called at any one time.
+//
+// Please see Walk documentation for caveats of using this function.
func WalkN(root string, walkFn WalkFunc, num int) error {
// make sure limit is sensible
if num < 1 {
diff --git a/vendor/github.com/willf/bitset/Makefile b/vendor/github.com/willf/bitset/Makefile
deleted file mode 100644
index db8377106..000000000
--- a/vendor/github.com/willf/bitset/Makefile
+++ /dev/null
@@ -1,191 +0,0 @@
-# MAKEFILE
-#
-# @author Nicola Asuni <info@tecnick.com>
-# @link https://github.com/willf/bitset
-# ------------------------------------------------------------------------------
-
-# List special make targets that are not associated with files
-.PHONY: help all test format fmtcheck vet lint coverage cyclo ineffassign misspell structcheck varcheck errcheck gosimple astscan qa deps clean nuke
-
-# Use bash as shell (Note: Ubuntu now uses dash which doesn't support PIPESTATUS).
-SHELL=/bin/bash
-
-# CVS path (path to the parent dir containing the project)
-CVSPATH=github.com/willf
-
-# Project owner
-OWNER=willf
-
-# Project vendor
-VENDOR=willf
-
-# Project name
-PROJECT=bitset
-
-# Project version
-VERSION=$(shell cat VERSION)
-
-# Name of RPM or DEB package
-PKGNAME=${VENDOR}-${PROJECT}
-
-# Current directory
-CURRENTDIR=$(shell pwd)
-
-# GO lang path
-ifneq ($(GOPATH),)
- ifeq ($(findstring $(GOPATH),$(CURRENTDIR)),)
- # the defined GOPATH is not valid
- GOPATH=
- endif
-endif
-ifeq ($(GOPATH),)
- # extract the GOPATH
- GOPATH=$(firstword $(subst /src/, ,$(CURRENTDIR)))
-endif
-
-# --- MAKE TARGETS ---
-
-# Display general help about this command
-help:
- @echo ""
- @echo "$(PROJECT) Makefile."
- @echo "GOPATH=$(GOPATH)"
- @echo "The following commands are available:"
- @echo ""
- @echo " make qa : Run all the tests"
- @echo " make test : Run the unit tests"
- @echo ""
- @echo " make format : Format the source code"
- @echo " make fmtcheck : Check if the source code has been formatted"
- @echo " make vet : Check for suspicious constructs"
- @echo " make lint : Check for style errors"
- @echo " make coverage : Generate the coverage report"
- @echo " make cyclo : Generate the cyclomatic complexity report"
- @echo " make ineffassign : Detect ineffectual assignments"
- @echo " make misspell : Detect commonly misspelled words in source files"
- @echo " make structcheck : Find unused struct fields"
- @echo " make varcheck : Find unused global variables and constants"
- @echo " make errcheck : Check that error return values are used"
- @echo " make gosimple : Suggest code simplifications"
- @echo " make astscan : GO AST scanner"
- @echo ""
- @echo " make docs : Generate source code documentation"
- @echo ""
- @echo " make deps : Get the dependencies"
- @echo " make clean : Remove any build artifact"
- @echo " make nuke : Deletes any intermediate file"
- @echo ""
-
-# Alias for help target
-all: help
-
-# Run the unit tests
-test:
- @mkdir -p target/test
- @mkdir -p target/report
- GOPATH=$(GOPATH) \
- go test \
- -covermode=atomic \
- -bench=. \
- -race \
- -cpuprofile=target/report/cpu.out \
- -memprofile=target/report/mem.out \
- -mutexprofile=target/report/mutex.out \
- -coverprofile=target/report/coverage.out \
- -v ./... | \
- tee >(PATH=$(GOPATH)/bin:$(PATH) go-junit-report > target/test/report.xml); \
- test $${PIPESTATUS[0]} -eq 0
-
-# Format the source code
-format:
- @find . -type f -name "*.go" -exec gofmt -s -w {} \;
-
-# Check if the source code has been formatted
-fmtcheck:
- @mkdir -p target
- @find . -type f -name "*.go" -exec gofmt -s -d {} \; | tee target/format.diff
- @test ! -s target/format.diff || { echo "ERROR: the source code has not been formatted - please use 'make format' or 'gofmt'"; exit 1; }
-
-# Check for syntax errors
-vet:
- GOPATH=$(GOPATH) go vet .
-
-# Check for style errors
-lint:
- GOPATH=$(GOPATH) PATH=$(GOPATH)/bin:$(PATH) golint .
-
-# Generate the coverage report
-coverage:
- @mkdir -p target/report
- GOPATH=$(GOPATH) \
- go tool cover -html=target/report/coverage.out -o target/report/coverage.html
-
-# Report cyclomatic complexity
-cyclo:
- @mkdir -p target/report
- GOPATH=$(GOPATH) gocyclo -avg ./ | tee target/report/cyclo.txt ; test $${PIPESTATUS[0]} -eq 0
-
-# Detect ineffectual assignments
-ineffassign:
- @mkdir -p target/report
- GOPATH=$(GOPATH) ineffassign ./ | tee target/report/ineffassign.txt ; test $${PIPESTATUS[0]} -eq 0
-
-# Detect commonly misspelled words in source files
-misspell:
- @mkdir -p target/report
- GOPATH=$(GOPATH) misspell -error ./ | tee target/report/misspell.txt ; test $${PIPESTATUS[0]} -eq 0
-
-# Find unused struct fields
-structcheck:
- @mkdir -p target/report
- GOPATH=$(GOPATH) structcheck -a ./ | tee target/report/structcheck.txt
-
-# Find unused global variables and constants
-varcheck:
- @mkdir -p target/report
- GOPATH=$(GOPATH) varcheck -e ./ | tee target/report/varcheck.txt
-
-# Check that error return values are used
-errcheck:
- @mkdir -p target/report
- GOPATH=$(GOPATH) errcheck ./ | tee target/report/errcheck.txt
-
-# AST scanner
-astscan:
- @mkdir -p target/report
- GOPATH=$(GOPATH) gosec . | tee target/report/astscan.txt ; test $${PIPESTATUS[0]} -eq 0 || true
-
-# Generate source docs
-docs:
- @mkdir -p target/docs
- nohup sh -c 'GOPATH=$(GOPATH) godoc -http=127.0.0.1:6060' > target/godoc_server.log 2>&1 &
- wget --directory-prefix=target/docs/ --execute robots=off --retry-connrefused --recursive --no-parent --adjust-extension --page-requisites --convert-links http://127.0.0.1:6060/pkg/github.com/${VENDOR}/${PROJECT}/ ; kill -9 `lsof -ti :6060`
- @echo '<html><head><meta http-equiv="refresh" content="0;./127.0.0.1:6060/pkg/'${CVSPATH}'/'${PROJECT}'/index.html"/></head><a href="./127.0.0.1:6060/pkg/'${CVSPATH}'/'${PROJECT}'/index.html">'${PKGNAME}' Documentation ...</a></html>' > target/docs/index.html
-
-# Alias to run all quality-assurance checks
-qa: fmtcheck test vet lint coverage cyclo ineffassign misspell structcheck varcheck errcheck gosimple astscan
-
-# --- INSTALL ---
-
-# Get the dependencies
-deps:
- GOPATH=$(GOPATH) go get ./...
- GOPATH=$(GOPATH) go get golang.org/x/lint/golint
- GOPATH=$(GOPATH) go get github.com/jstemmer/go-junit-report
- GOPATH=$(GOPATH) go get github.com/axw/gocov/gocov
- GOPATH=$(GOPATH) go get github.com/fzipp/gocyclo
- GOPATH=$(GOPATH) go get github.com/gordonklaus/ineffassign
- GOPATH=$(GOPATH) go get github.com/client9/misspell/cmd/misspell
- GOPATH=$(GOPATH) go get github.com/opennota/check/cmd/structcheck
- GOPATH=$(GOPATH) go get github.com/opennota/check/cmd/varcheck
- GOPATH=$(GOPATH) go get github.com/kisielk/errcheck
- GOPATH=$(GOPATH) go get github.com/securego/gosec/cmd/gosec/...
-
-# Remove any build artifact
-clean:
- GOPATH=$(GOPATH) go clean ./...
-
-# Deletes any intermediate file
-nuke:
- rm -rf ./target
- GOPATH=$(GOPATH) go clean -i ./...
diff --git a/vendor/github.com/willf/bitset/README.md b/vendor/github.com/willf/bitset/README.md
index 6c62b20c6..50338e71d 100644
--- a/vendor/github.com/willf/bitset/README.md
+++ b/vendor/github.com/willf/bitset/README.md
@@ -2,10 +2,10 @@
*Go language library to map between non-negative integers and boolean values*
-[![Master Build Status](https://secure.travis-ci.org/willf/bitset.png?branch=master)](https://travis-ci.org/willf/bitset?branch=master)
+[![Test](https://github.com/willf/bitset/workflows/Test/badge.svg)](https://github.com/willf/bitset/actions?query=workflow%3ATest)
[![Master Coverage Status](https://coveralls.io/repos/willf/bitset/badge.svg?branch=master&service=github)](https://coveralls.io/github/willf/bitset?branch=master)
[![Go Report Card](https://goreportcard.com/badge/github.com/willf/bitset)](https://goreportcard.com/report/github.com/willf/bitset)
-[![GoDoc](https://godoc.org/github.com/willf/bitset?status.svg)](http://godoc.org/github.com/willf/bitset)
+[![PkgGoDev](https://pkg.go.dev/badge/github.com/willf/bitset?tab=doc)](https://pkg.go.dev/github.com/willf/bitset?tab=doc)
## Description
@@ -63,8 +63,11 @@ func main() {
As an alternative to BitSets, one should check out the 'big' package, which provides a (less set-theoretical) view of bitsets.
-Godoc documentation is at: https://godoc.org/github.com/willf/bitset
+Package documentation is at: https://pkg.go.dev/github.com/willf/bitset?tab=doc
+## Memory Usage
+
+The memory usage of a bitset using N bits is at least N/8 bytes. The number of bits in a bitset is at least as large as one plus the greatest bit index you have accessed. Thus it is possible to run out of memory while using a bitset. If you have lots of bits, you might prefer compressed bitsets, like the [Roaring bitmaps](http://roaringbitmap.org) and its [Go implementation](https://github.com/RoaringBitmap/roaring).
## Implementation Note
@@ -82,15 +85,10 @@ go get github.com/willf/bitset
If you wish to contribute to this project, please branch and issue a pull request against master ("[GitHub Flow](https://guides.github.com/introduction/flow/)")
-This project include a Makefile that allows you to test and build the project with simple commands.
-To see all available options:
-```bash
-make help
-```
-
## Running all tests
-Before committing the code, please check if it passes all tests using (note: this will install some dependencies):
+Before committing the code, please check if it passes tests, has adequate coverage, etc.
```bash
-make qa
+go test
+go test -cover
```
diff --git a/vendor/github.com/willf/bitset/bitset.go b/vendor/github.com/willf/bitset/bitset.go
index 22e5d42e5..21e889da2 100644
--- a/vendor/github.com/willf/bitset/bitset.go
+++ b/vendor/github.com/willf/bitset/bitset.go
@@ -138,6 +138,9 @@ func (b *BitSet) Len() uint {
// extendSetMaybe adds additional words to incorporate new bits if needed
func (b *BitSet) extendSetMaybe(i uint) {
if i >= b.length { // if we need more bits, make 'em
+ if i >= Cap() {
+ panic("You are exceeding the capacity")
+ }
nsize := wordsNeeded(i + 1)
if b.set == nil {
b.set = make([]uint64, nsize)
@@ -160,7 +163,12 @@ func (b *BitSet) Test(i uint) bool {
return b.set[i>>log2WordSize]&(1<<(i&(wordSize-1))) != 0
}
-// Set bit i to 1
+// Set bit i to 1, the capacity of the bitset is automatically
+// increased accordingly.
+// If i>= Cap(), this function will panic.
+// Warning: using a very large value for 'i'
+// may lead to a memory shortage and a panic: the caller is responsible
+// for providing sensible parameters in line with their memory capacity.
func (b *BitSet) Set(i uint) *BitSet {
b.extendSetMaybe(i)
b.set[i>>log2WordSize] |= 1 << (i & (wordSize - 1))
@@ -176,7 +184,11 @@ func (b *BitSet) Clear(i uint) *BitSet {
return b
}
-// SetTo sets bit i to value
+// SetTo sets bit i to value.
+// If i>= Cap(), this function will panic.
+// Warning: using a very large value for 'i'
+// may lead to a memory shortage and a panic: the caller is responsible
+// for providing sensible parameters in line with their memory capacity.
func (b *BitSet) SetTo(i uint, value bool) *BitSet {
if value {
return b.Set(i)
@@ -184,7 +196,11 @@ func (b *BitSet) SetTo(i uint, value bool) *BitSet {
return b.Clear(i)
}
-// Flip bit at i
+// Flip bit at i.
+// If i>= Cap(), this function will panic.
+// Warning: using a very large value for 'i'
+// may lead to a memory shortage and a panic: the caller is responsible
+// for providing sensible parameters in line with their memory capacity.
func (b *BitSet) Flip(i uint) *BitSet {
if i >= b.length {
return b.Set(i)
@@ -193,26 +209,51 @@ func (b *BitSet) Flip(i uint) *BitSet {
return b
}
-// Shrink shrinks BitSet to desired length in bits. It clears all bits > length
-// and reduces the size and length of the set.
+// Shrink shrinks BitSet so that the provided value is the last possible
+// set value. It clears all bits > the provided index and reduces the size
+// and length of the set.
+//
+// Note that the parameter value is not the new length in bits: it is the
+// maximal value that can be stored in the bitset after the function call.
+// The new length in bits is the parameter value + 1. Thus it is not possible
+// to use this function to set the length to 0, the minimal value of the length
+// after this function call is 1.
//
// A new slice is allocated to store the new bits, so you may see an increase in
// memory usage until the GC runs. Normally this should not be a problem, but if you
// have an extremely large BitSet its important to understand that the old BitSet will
// remain in memory until the GC frees it.
-func (b *BitSet) Shrink(length uint) *BitSet {
- idx := wordsNeeded(length + 1)
+func (b *BitSet) Shrink(lastbitindex uint) *BitSet {
+ length := lastbitindex + 1
+ idx := wordsNeeded(length)
if idx > len(b.set) {
return b
}
shrunk := make([]uint64, idx)
copy(shrunk, b.set[:idx])
b.set = shrunk
- b.length = length + 1
- b.set[idx-1] &= (allBits >> (uint64(64) - uint64(length&(wordSize-1)) - 1))
+ b.length = length
+ b.set[idx-1] &= (allBits >> (uint64(64) - uint64(length&(wordSize-1))))
return b
}
+// Compact shrinks BitSet to so that we preserve all set bits, while minimizing
+// memory usage. Compact calls Shrink.
+func (b *BitSet) Compact() *BitSet {
+ idx := len(b.set) - 1
+ for ; idx >= 0 && b.set[idx] == 0; idx-- {
+ }
+ newlength := uint((idx + 1) << log2WordSize)
+ if newlength >= b.length {
+ return b // nothing to do
+ }
+ if newlength > 0 {
+ return b.Shrink(newlength - 1)
+ }
+ // We preserve one word
+ return b.Shrink(63)
+}
+
// InsertAt takes an index which indicates where a bit should be
// inserted. Then it shifts all the bits in the set to the left by 1, starting
// from the given index position, and sets the index position to 0.
@@ -323,6 +364,9 @@ func (b *BitSet) DeleteAt(i uint) *BitSet {
// including possibly the current index
// along with an error code (true = valid, false = no set bit found)
// for i,e := v.NextSet(0); e; i,e = v.NextSet(i + 1) {...}
+//
+// Users concerned with performance may want to use NextSetMany to
+// retrieve several values at once.
func (b *BitSet) NextSet(i uint) (uint, bool) {
x := int(i >> log2WordSize)
if x >= len(b.set) {
@@ -358,6 +402,14 @@ func (b *BitSet) NextSet(i uint) (uint, bool) {
// j += 1
// }
//
+//
+// It is possible to retrieve all set bits as follow:
+//
+// indices := make([]uint, bitmap.Count())
+// bitmap.NextSetMany(0, indices)
+//
+// However if bitmap.Count() is large, it might be preferable to
+// use several calls to NextSetMany, for performance reasons.
func (b *BitSet) NextSetMany(i uint, buffer []uint) (uint, []uint) {
myanswer := buffer
capacity := cap(buffer)
@@ -809,7 +861,7 @@ func (b *BitSet) ReadFrom(stream io.Reader) (int64, error) {
newset := New(uint(length))
if uint64(newset.length) != length {
- return 0, errors.New("Unmarshalling error: type mismatch")
+ return 0, errors.New("unmarshalling error: type mismatch")
}
// Read remaining bytes as set
diff --git a/vendor/github.com/willf/bitset/go.mod b/vendor/github.com/willf/bitset/go.mod
new file mode 100644
index 000000000..583ecab78
--- /dev/null
+++ b/vendor/github.com/willf/bitset/go.mod
@@ -0,0 +1,3 @@
+module github.com/willf/bitset
+
+go 1.14
diff --git a/vendor/github.com/willf/bitset/go.sum b/vendor/github.com/willf/bitset/go.sum
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/vendor/github.com/willf/bitset/go.sum
diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go
index 8b129b794..7688d72c3 100644
--- a/vendor/golang.org/x/net/http2/transport.go
+++ b/vendor/golang.org/x/net/http2/transport.go
@@ -2632,7 +2632,9 @@ func (t *Transport) getBodyWriterState(cs *clientStream, body io.Reader) (s body
func (s bodyWriterState) cancel() {
if s.timer != nil {
- s.timer.Stop()
+ if s.timer.Stop() {
+ s.resc <- nil
+ }
}
}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index b78e059db..422a6d88d 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -422,7 +422,7 @@ github.com/onsi/ginkgo/reporters/stenographer
github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable
github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty
github.com/onsi/ginkgo/types
-# github.com/onsi/gomega v1.10.3
+# github.com/onsi/gomega v1.10.4
github.com/onsi/gomega
github.com/onsi/gomega/format
github.com/onsi/gomega/gbytes
@@ -459,7 +459,7 @@ github.com/opencontainers/runtime-tools/generate
github.com/opencontainers/runtime-tools/generate/seccomp
github.com/opencontainers/runtime-tools/specerror
github.com/opencontainers/runtime-tools/validate
-# github.com/opencontainers/selinux v1.6.0
+# github.com/opencontainers/selinux v1.7.0
github.com/opencontainers/selinux/go-selinux
github.com/opencontainers/selinux/go-selinux/label
github.com/opencontainers/selinux/pkg/pwalk
@@ -568,7 +568,7 @@ github.com/vishvananda/netlink
github.com/vishvananda/netlink/nl
# github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df
github.com/vishvananda/netns
-# github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243
+# github.com/willf/bitset v1.1.11
github.com/willf/bitset
# github.com/xeipuuv/gojsonpointer v0.0.0-20190809123943-df4f5c81cb3b
github.com/xeipuuv/gojsonpointer
@@ -609,7 +609,7 @@ golang.org/x/crypto/ssh/agent
golang.org/x/crypto/ssh/internal/bcrypt_pbkdf
golang.org/x/crypto/ssh/knownhosts
golang.org/x/crypto/ssh/terminal
-# golang.org/x/net v0.0.0-20201110031124-69a78807bb2b
+# golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb
golang.org/x/net/context
golang.org/x/net/context/ctxhttp
golang.org/x/net/html