summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml2
-rw-r--r--.gitignore1
-rw-r--r--Makefile12
-rw-r--r--README.md2
-rw-r--r--cmd/podman/cliconfig/config.go2
-rw-r--r--cmd/podman/errors_remote.go2
-rw-r--r--cmd/podman/generate_systemd.go8
-rw-r--r--cmd/podman/pod_stop.go5
-rw-r--r--cmd/podman/restart.go9
-rw-r--r--cmd/podman/service.go2
-rw-r--r--cmd/podman/shared/intermediate_varlink.go2
-rw-r--r--cmd/podman/stop.go13
-rw-r--r--cmd/podman/utils.go2
-rw-r--r--cmd/podman/varlink.go2
-rw-r--r--cmd/podman/varlink/generate.go3
-rw-r--r--cmd/podmanV2/Makefile2
-rw-r--r--cmd/podmanV2/common/inspect.go18
-rw-r--r--cmd/podmanV2/containers/export.go57
-rw-r--r--cmd/podmanV2/containers/inspect.go32
-rw-r--r--cmd/podmanV2/containers/restart.go11
-rw-r--r--cmd/podmanV2/containers/stop.go16
-rw-r--r--cmd/podmanV2/healthcheck/healthcheck.go33
-rw-r--r--cmd/podmanV2/healthcheck/run.go42
-rw-r--r--cmd/podmanV2/images/import.go87
-rw-r--r--cmd/podmanV2/images/inspect.go141
-rw-r--r--cmd/podmanV2/images/list.go2
-rw-r--r--cmd/podmanV2/images/load.go61
-rw-r--r--cmd/podmanV2/images/pull.go140
-rw-r--r--cmd/podmanV2/images/tag.go34
-rw-r--r--cmd/podmanV2/images/untag.go33
-rw-r--r--cmd/podmanV2/inspect.go62
-rw-r--r--cmd/podmanV2/main.go7
-rw-r--r--cmd/podmanV2/pods/pod.go30
-rw-r--r--cmd/podmanV2/pods/ps.go134
-rw-r--r--cmd/podmanV2/pods/stop.go7
-rw-r--r--cmd/podmanV2/registry/registry.go17
-rw-r--r--cmd/podmanV2/report/templates.go3
-rw-r--r--cmd/podmanV2/root.go5
-rw-r--r--cmd/podmanV2/system/system.go2
-rw-r--r--cmd/podmanV2/utils/alias.go24
-rw-r--r--completions/bash/podman10
-rwxr-xr-xcontrib/build_rpm.sh13
-rw-r--r--contrib/cirrus/README.md4
-rw-r--r--contrib/spec/podman.spec.in6
-rw-r--r--docs/generate.go2
-rw-r--r--docs/source/markdown/podman-generate-systemd.1.md2
-rw-r--r--docs/source/markdown/podman-pod-stop.1.md2
-rw-r--r--docs/source/markdown/podman-restart.1.md2
-rw-r--r--docs/source/markdown/podman-stop.1.md4
-rw-r--r--go.mod4
-rw-r--r--go.sum9
-rwxr-xr-xhack/podmanv2-retry37
-rw-r--r--libpod/container_inspect.go3
-rw-r--r--libpod/image/image.go6
-rw-r--r--libpod/image/image_test.go2
-rw-r--r--libpod/podfilters/pods.go115
-rw-r--r--pkg/adapter/containers.go4
-rw-r--r--pkg/adapter/containers_remote.go2
-rw-r--r--pkg/adapter/errors.go2
-rw-r--r--pkg/adapter/images_remote.go2
-rw-r--r--pkg/adapter/info_remote.go4
-rw-r--r--pkg/adapter/pods_remote.go2
-rw-r--r--pkg/adapter/reset_remote.go2
-rw-r--r--pkg/adapter/runtime_remote.go2
-rw-r--r--pkg/api/handlers/compat/containers_export.go42
-rw-r--r--pkg/api/handlers/libpod/images.go48
-rw-r--r--pkg/api/handlers/swagger.go4
-rw-r--r--pkg/api/handlers/types.go4
-rw-r--r--pkg/api/handlers/utils/pods.go5
-rw-r--r--pkg/api/server/register_containers.go45
-rw-r--r--pkg/api/server/register_images.go34
-rw-r--r--pkg/bindings/containers/containers.go20
-rw-r--r--pkg/bindings/images/images.go82
-rw-r--r--pkg/bindings/test/images_test.go25
-rw-r--r--pkg/domain/entities/containers.go10
-rw-r--r--pkg/domain/entities/engine_container.go20
-rw-r--r--pkg/domain/entities/engine_image.go6
-rw-r--r--pkg/domain/entities/healthcheck.go3
-rw-r--r--pkg/domain/entities/images.go80
-rw-r--r--pkg/domain/entities/pods.go13
-rw-r--r--pkg/domain/entities/types.go7
-rw-r--r--pkg/domain/infra/abi/containers.go10
-rw-r--r--pkg/domain/infra/abi/healthcheck.go26
-rw-r--r--pkg/domain/infra/abi/images.go183
-rw-r--r--pkg/domain/infra/abi/pods.go59
-rw-r--r--pkg/domain/infra/tunnel/containers.go18
-rw-r--r--pkg/domain/infra/tunnel/healthcheck.go13
-rw-r--r--pkg/domain/infra/tunnel/images.go99
-rw-r--r--pkg/domain/infra/tunnel/pods.go4
-rw-r--r--pkg/systemd/generate/systemdgen.go2
-rw-r--r--pkg/varlink/generate.go3
-rw-r--r--pkg/varlink/io.podman.varlink (renamed from cmd/podman/varlink/io.podman.varlink)0
-rw-r--r--pkg/varlinkapi/attach.go4
-rw-r--r--pkg/varlinkapi/config.go2
-rw-r--r--pkg/varlinkapi/containers.go4
-rw-r--r--pkg/varlinkapi/containers_create.go2
-rw-r--r--pkg/varlinkapi/events.go2
-rw-r--r--pkg/varlinkapi/generate.go2
-rw-r--r--pkg/varlinkapi/images.go2
-rw-r--r--pkg/varlinkapi/mount.go4
-rw-r--r--pkg/varlinkapi/pods.go2
-rw-r--r--pkg/varlinkapi/remote_client.go2
-rw-r--r--pkg/varlinkapi/system.go2
-rw-r--r--pkg/varlinkapi/transfers.go2
-rw-r--r--pkg/varlinkapi/util.go2
-rw-r--r--pkg/varlinkapi/volumes.go2
-rw-r--r--test/e2e/common_test.go2
-rw-r--r--test/e2e/generate_systemd_test.go14
-rw-r--r--test/e2e/run_volume_test.go2
-rw-r--r--test/endpoint/endpoint.go2
-rw-r--r--test/endpoint/setup.go14
-rw-r--r--vendor/github.com/rootless-containers/rootlesskit/pkg/port/portutil/portutil.go3
-rw-r--r--vendor/modules.txt4
113 files changed, 1950 insertions, 298 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index 81430de99..01cecd5a8 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -39,7 +39,7 @@ env:
UBUNTU_NAME: "ubuntu-19"
PRIOR_UBUNTU_NAME: "ubuntu-18"
- _BUILT_IMAGE_SUFFIX: "libpod-5633729662025728"
+ _BUILT_IMAGE_SUFFIX: "libpod-6465271544152064"
FEDORA_CACHE_IMAGE_NAME: "${FEDORA_NAME}-${_BUILT_IMAGE_SUFFIX}"
PRIOR_FEDORA_CACHE_IMAGE_NAME: "${PRIOR_FEDORA_NAME}-${_BUILT_IMAGE_SUFFIX}"
UBUNTU_CACHE_IMAGE_NAME: "${UBUNTU_NAME}-${_BUILT_IMAGE_SUFFIX}"
diff --git a/.gitignore b/.gitignore
index ea154fe5d..c1742a27e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,6 +20,7 @@
__pycache__
/cmd/podman/varlink/ioprojectatomicpodman.go
/cmd/podman/varlink/iopodman.go
+/pkg/varlink/iopodman.go
.gopathok
release.txt
podman-remote*.zip
diff --git a/Makefile b/Makefile
index 7e5a564a0..92e0f1539 100644
--- a/Makefile
+++ b/Makefile
@@ -46,7 +46,7 @@ endif
BUILDTAGS_CROSS ?= containers_image_openpgp exclude_graphdriver_btrfs exclude_graphdriver_devicemapper exclude_graphdriver_overlay
ifneq (,$(findstring varlink,$(BUILDTAGS)))
- PODMAN_VARLINK_DEPENDENCIES = cmd/podman/varlink/iopodman.go
+ PODMAN_VARLINK_DEPENDENCIES = pkg/varlink/iopodman.go
endif
CONTAINER_RUNTIME := $(shell command -v podman 2> /dev/null || echo docker)
OCI_RUNTIME ?= ""
@@ -237,7 +237,7 @@ clean: ## Clean artifacts
test/checkseccomp/checkseccomp \
test/goecho/goecho \
test/testdata/redis-image \
- cmd/podman/varlink/iopodman.go \
+ pkg/varlink/iopodman.go \
libpod/container_ffjson.go \
libpod/pod_ffjson.go \
libpod/container_easyjson.go \
@@ -597,7 +597,7 @@ endef
fi
.PHONY: varlink_generate
-varlink_generate: .gopathok cmd/podman/varlink/iopodman.go ## Generate varlink
+varlink_generate: .gopathok pkg/varlink/iopodman.go ## Generate varlink
.PHONY: varlink_api_generate
varlink_api_generate: .gopathok API.md
@@ -609,13 +609,13 @@ install.libseccomp.sudo:
cd ../../seccomp/libseccomp && git checkout --detach $(LIBSECCOMP_COMMIT) && ./autogen.sh && ./configure --prefix=/usr && make all && make install
-cmd/podman/varlink/iopodman.go: .gopathok cmd/podman/varlink/io.podman.varlink
+pkg/varlink/iopodman.go: .gopathok pkg/varlink/io.podman.varlink
ifneq (,$(findstring Linux,$(shell uname -s)))
# Only generate the varlink code on Linux (see issue #4814).
- GO111MODULE=off $(GO) generate ./cmd/podman/varlink/...
+ GO111MODULE=off $(GO) generate ./pkg/varlink/...
endif
-API.md: cmd/podman/varlink/io.podman.varlink
+API.md: pkg/varlink/io.podman.varlink
$(GO) generate ./docs/...
.PHONY: validate.completions
diff --git a/README.md b/README.md
index ea10454be..25d1432e0 100644
--- a/README.md
+++ b/README.md
@@ -49,7 +49,7 @@ and
tracking system.
There is also a [mailing list](https://lists.podman.io/archives/) at `lists.podman.io`.
-You can subscribe by sending a message to `podman@lists.podman.io` with the subject `subscribe`.
+You can subscribe by sending a message to `podman-join@lists.podman.io` with the subject `subscribe`.
## Rootless
Podman can be easily run as a normal user, without requiring a setuid binary.
diff --git a/cmd/podman/cliconfig/config.go b/cmd/podman/cliconfig/config.go
index faf292ea0..99f389799 100644
--- a/cmd/podman/cliconfig/config.go
+++ b/cmd/podman/cliconfig/config.go
@@ -174,7 +174,7 @@ type GenerateSystemdValues struct {
New bool
Files bool
RestartPolicy string
- StopTimeout int
+ StopTimeout uint
}
type HistoryValues struct {
diff --git a/cmd/podman/errors_remote.go b/cmd/podman/errors_remote.go
index 378f9398f..4b543ccd5 100644
--- a/cmd/podman/errors_remote.go
+++ b/cmd/podman/errors_remote.go
@@ -8,8 +8,8 @@ import (
"os/exec"
"syscall"
- "github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/libpod/define"
+ iopodman "github.com/containers/libpod/pkg/varlink"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
diff --git a/cmd/podman/generate_systemd.go b/cmd/podman/generate_systemd.go
index a9775f9cb..fd0d13d78 100644
--- a/cmd/podman/generate_systemd.go
+++ b/cmd/podman/generate_systemd.go
@@ -43,9 +43,10 @@ func init() {
if !remoteclient {
flags.BoolVarP(&containerSystemdCommand.Files, "files", "f", false, "generate files instead of printing to stdout")
}
- flags.IntVarP(&containerSystemdCommand.StopTimeout, "timeout", "t", -1, "stop timeout override")
+ flags.UintVarP(&containerSystemdCommand.StopTimeout, "time", "t", defaultContainerConfig.Engine.StopTimeout, "stop timeout override")
flags.StringVar(&containerSystemdCommand.RestartPolicy, "restart-policy", "on-failure", "applicable systemd restart-policy")
flags.BoolVarP(&containerSystemdCommand.New, "new", "", false, "create a new container instead of starting an existing one")
+ flags.SetNormalizeFunc(aliasFlags)
}
func generateSystemdCmd(c *cliconfig.GenerateSystemdValues) error {
@@ -55,11 +56,6 @@ func generateSystemdCmd(c *cliconfig.GenerateSystemdValues) error {
}
defer runtime.DeferredShutdown(false)
- // User input stop timeout must be 0 or greater
- if c.Flag("timeout").Changed && c.StopTimeout < 0 {
- return errors.New("timeout value must be 0 or greater")
- }
-
unit, err := runtime.GenerateSystemd(c)
if err != nil {
return err
diff --git a/cmd/podman/pod_stop.go b/cmd/podman/pod_stop.go
index 7d3951ec4..395731551 100644
--- a/cmd/podman/pod_stop.go
+++ b/cmd/podman/pod_stop.go
@@ -31,7 +31,7 @@ var (
},
Example: `podman pod stop mywebserverpod
podman pod stop --latest
- podman pod stop --timeout 0 490eb 3557fb`,
+ podman pod stop --time 0 490eb 3557fb`,
}
)
@@ -43,7 +43,8 @@ func init() {
flags.BoolVarP(&podStopCommand.All, "all", "a", false, "Stop all running pods")
flags.BoolVarP(&podStopCommand.Ignore, "ignore", "i", false, "Ignore errors when a specified pod is missing")
flags.BoolVarP(&podStopCommand.Latest, "latest", "l", false, "Stop the latest pod podman is aware of")
- flags.UintVarP(&podStopCommand.Timeout, "timeout", "t", 0, "Seconds to wait for pod stop before killing the container")
+ flags.UintVarP(&podStopCommand.Timeout, "time", "t", defaultContainerConfig.Engine.StopTimeout, "Seconds to wait for pod stop before killing the container")
+ flags.SetNormalizeFunc(aliasFlags)
markFlagHiddenForRemoteClient("ignore", flags)
markFlagHiddenForRemoteClient("latest", flags)
}
diff --git a/cmd/podman/restart.go b/cmd/podman/restart.go
index a55f83c67..4ee043442 100644
--- a/cmd/podman/restart.go
+++ b/cmd/podman/restart.go
@@ -1,6 +1,8 @@
package main
import (
+ "fmt"
+
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/pkg/adapter"
@@ -10,9 +12,9 @@ import (
var (
restartCommand cliconfig.RestartValues
- restartDescription = `Restarts one or more running containers. The container ID or name can be used.
+ restartDescription = fmt.Sprintf(`Restarts one or more running containers. The container ID or name can be used.
- A timeout before forcibly stopping can be set, but defaults to 10 seconds.`
+ A timeout before forcibly stopping can be set, but defaults to %d seconds.`, defaultContainerConfig.Engine.StopTimeout)
_restartCommand = &cobra.Command{
Use: "restart [flags] CONTAINER [CONTAINER...]",
Short: "Restart one or more containers",
@@ -40,10 +42,9 @@ func init() {
flags.BoolVarP(&restartCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
flags.BoolVar(&restartCommand.Running, "running", false, "Restart only running containers when --all is used")
flags.UintVarP(&restartCommand.Timeout, "time", "t", defaultContainerConfig.Engine.StopTimeout, "Seconds to wait for stop before killing the container")
- flags.UintVar(&restartCommand.Timeout, "timeout", defaultContainerConfig.Engine.StopTimeout, "Seconds to wait for stop before killing the container")
- markFlagHidden(flags, "timeout")
markFlagHiddenForRemoteClient("latest", flags)
+ flags.SetNormalizeFunc(aliasFlags)
}
func restartCmd(c *cliconfig.RestartValues) error {
diff --git a/cmd/podman/service.go b/cmd/podman/service.go
index 7606e3009..bcb37eac5 100644
--- a/cmd/podman/service.go
+++ b/cmd/podman/service.go
@@ -12,13 +12,13 @@ import (
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/cmd/podman/libpodruntime"
- iopodman "github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/adapter"
api "github.com/containers/libpod/pkg/api/server"
"github.com/containers/libpod/pkg/rootless"
"github.com/containers/libpod/pkg/systemd"
"github.com/containers/libpod/pkg/util"
+ iopodman "github.com/containers/libpod/pkg/varlink"
"github.com/containers/libpod/pkg/varlinkapi"
"github.com/containers/libpod/version"
"github.com/pkg/errors"
diff --git a/cmd/podman/shared/intermediate_varlink.go b/cmd/podman/shared/intermediate_varlink.go
index d2b048025..82594fb40 100644
--- a/cmd/podman/shared/intermediate_varlink.go
+++ b/cmd/podman/shared/intermediate_varlink.go
@@ -4,8 +4,8 @@ package shared
import (
"github.com/containers/libpod/cmd/podman/cliconfig"
- "github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/pkg/rootless"
+ iopodman "github.com/containers/libpod/pkg/varlink"
"github.com/pkg/errors"
)
diff --git a/cmd/podman/stop.go b/cmd/podman/stop.go
index 383a1f61c..5033218e4 100644
--- a/cmd/podman/stop.go
+++ b/cmd/podman/stop.go
@@ -1,6 +1,8 @@
package main
import (
+ "fmt"
+
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/pkg/adapter"
"github.com/opentracing/opentracing-go"
@@ -10,9 +12,9 @@ import (
var (
stopCommand cliconfig.StopValues
- stopDescription = `Stops one or more running containers. The container name or ID can be used.
+ stopDescription = fmt.Sprintf(`Stops one or more running containers. The container name or ID can be used.
- A timeout to forcibly stop the container can also be set but defaults to 10 seconds otherwise.`
+ A timeout to forcibly stop the container can also be set but defaults to %d seconds otherwise.`, defaultContainerConfig.Engine.StopTimeout)
_stopCommand = &cobra.Command{
Use: "stop [flags] CONTAINER [CONTAINER...]",
Short: "Stop one or more containers",
@@ -42,19 +44,14 @@ func init() {
flags.StringArrayVarP(&stopCommand.CIDFiles, "cidfile", "", nil, "Read the container ID from the file")
flags.BoolVarP(&stopCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
flags.UintVarP(&stopCommand.Timeout, "time", "t", defaultContainerConfig.Engine.StopTimeout, "Seconds to wait for stop before killing the container")
- flags.UintVar(&stopCommand.Timeout, "timeout", defaultContainerConfig.Engine.StopTimeout, "Seconds to wait for stop before killing the container")
- markFlagHidden(flags, "timeout")
markFlagHiddenForRemoteClient("latest", flags)
markFlagHiddenForRemoteClient("cidfile", flags)
markFlagHiddenForRemoteClient("ignore", flags)
+ flags.SetNormalizeFunc(aliasFlags)
}
// stopCmd stops a container or containers
func stopCmd(c *cliconfig.StopValues) error {
- if c.Flag("timeout").Changed && c.Flag("time").Changed {
- return errors.New("the --timeout and --time flags are mutually exclusive")
- }
-
if c.Bool("trace") {
span, _ := opentracing.StartSpanFromContext(Ctx, "stopCmd")
defer span.Finish()
diff --git a/cmd/podman/utils.go b/cmd/podman/utils.go
index 44e65b223..938a3f41e 100644
--- a/cmd/podman/utils.go
+++ b/cmd/podman/utils.go
@@ -63,6 +63,8 @@ func aliasFlags(f *pflag.FlagSet, name string) pflag.NormalizedName {
name = "health-timeout"
case "net":
name = "network"
+ case "timeout":
+ name = "time"
}
return pflag.NormalizedName(name)
}
diff --git a/cmd/podman/varlink.go b/cmd/podman/varlink.go
index 047d94fc2..20334ec96 100644
--- a/cmd/podman/varlink.go
+++ b/cmd/podman/varlink.go
@@ -10,10 +10,10 @@ import (
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/cmd/podman/libpodruntime"
- iopodman "github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/pkg/adapter"
"github.com/containers/libpod/pkg/rootless"
"github.com/containers/libpod/pkg/util"
+ iopodman "github.com/containers/libpod/pkg/varlink"
"github.com/containers/libpod/pkg/varlinkapi"
"github.com/containers/libpod/version"
"github.com/pkg/errors"
diff --git a/cmd/podman/varlink/generate.go b/cmd/podman/varlink/generate.go
deleted file mode 100644
index 2fa2d8e23..000000000
--- a/cmd/podman/varlink/generate.go
+++ /dev/null
@@ -1,3 +0,0 @@
-package iopodman
-
-//go:generate go run ../../../vendor/github.com/varlink/go/cmd/varlink-go-interface-generator/main.go io.podman.varlink
diff --git a/cmd/podmanV2/Makefile b/cmd/podmanV2/Makefile
index 147a78d9c..f2f7bd73c 100644
--- a/cmd/podmanV2/Makefile
+++ b/cmd/podmanV2/Makefile
@@ -1,2 +1,2 @@
all:
- GO111MODULE=off go build -tags 'ABISupport'
+ GO111MODULE=off go build -tags 'ABISupport systemd'
diff --git a/cmd/podmanV2/common/inspect.go b/cmd/podmanV2/common/inspect.go
new file mode 100644
index 000000000..dfc6fe679
--- /dev/null
+++ b/cmd/podmanV2/common/inspect.go
@@ -0,0 +1,18 @@
+package common
+
+import (
+ "github.com/containers/libpod/pkg/domain/entities"
+ "github.com/spf13/cobra"
+)
+
+// AddInspectFlagSet takes a command and adds the inspect flags and returns an InspectOptions object
+// Since this cannot live in `package main` it lives here until a better home is found
+func AddInspectFlagSet(cmd *cobra.Command) *entities.InspectOptions {
+ opts := entities.InspectOptions{}
+
+ flags := cmd.Flags()
+ flags.BoolVarP(&opts.Size, "size", "s", false, "Display total file size")
+ flags.StringVarP(&opts.Format, "format", "f", "", "Change the output format to a Go template")
+
+ return &opts
+}
diff --git a/cmd/podmanV2/containers/export.go b/cmd/podmanV2/containers/export.go
new file mode 100644
index 000000000..b93b60878
--- /dev/null
+++ b/cmd/podmanV2/containers/export.go
@@ -0,0 +1,57 @@
+package containers
+
+import (
+ "context"
+ "os"
+
+ "github.com/containers/libpod/cmd/podmanV2/parse"
+ "github.com/containers/libpod/cmd/podmanV2/registry"
+ "github.com/containers/libpod/pkg/domain/entities"
+ "github.com/pkg/errors"
+ "github.com/spf13/cobra"
+ "golang.org/x/crypto/ssh/terminal"
+)
+
+var (
+ exportDescription = "Exports container's filesystem contents as a tar archive" +
+ " and saves it on the local machine."
+
+ exportCommand = &cobra.Command{
+ Use: "export [flags] CONTAINER",
+ Short: "Export container's filesystem contents as a tar archive",
+ Long: exportDescription,
+ PersistentPreRunE: preRunE,
+ RunE: export,
+ Args: cobra.ExactArgs(1),
+ Example: `podman export ctrID > myCtr.tar
+ podman export --output="myCtr.tar" ctrID`,
+ }
+)
+
+var (
+ exportOpts entities.ContainerExportOptions
+)
+
+func init() {
+ registry.Commands = append(registry.Commands, registry.CliCommand{
+ Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
+ Command: exportCommand,
+ })
+ exportCommand.SetHelpTemplate(registry.HelpTemplate())
+ exportCommand.SetUsageTemplate(registry.UsageTemplate())
+ flags := exportCommand.Flags()
+ flags.StringVarP(&exportOpts.Output, "output", "o", "", "Write to a specified file (default: stdout, which must be redirected)")
+}
+
+func export(cmd *cobra.Command, args []string) error {
+ if len(exportOpts.Output) == 0 {
+ file := os.Stdout
+ if terminal.IsTerminal(int(file.Fd())) {
+ return errors.Errorf("refusing to export to terminal. Use -o flag or redirect")
+ }
+ exportOpts.Output = "/dev/stdout"
+ } else if err := parse.ValidateFileName(exportOpts.Output); err != nil {
+ return err
+ }
+ return registry.ContainerEngine().ContainerExport(context.Background(), args[0], exportOpts)
+}
diff --git a/cmd/podmanV2/containers/inspect.go b/cmd/podmanV2/containers/inspect.go
index 648289f0b..3147426cb 100644
--- a/cmd/podmanV2/containers/inspect.go
+++ b/cmd/podmanV2/containers/inspect.go
@@ -7,9 +7,11 @@ import (
"strings"
"text/template"
+ "github.com/containers/libpod/cmd/podmanV2/common"
"github.com/containers/libpod/cmd/podmanV2/registry"
+
"github.com/containers/libpod/pkg/domain/entities"
- jsoniter "github.com/json-iterator/go"
+ json "github.com/json-iterator/go"
"github.com/spf13/cobra"
)
@@ -24,10 +26,7 @@ var (
Example: `podman container inspect myCtr
podman container inspect -l --format '{{.Id}} {{.Config.Labels}}'`,
}
-)
-
-var (
- inspectOptions entities.ContainerInspectOptions
+ inspectOpts *entities.InspectOptions
)
func init() {
@@ -36,29 +35,29 @@ func init() {
Command: inspectCmd,
Parent: containerCmd,
})
+ inspectOpts = common.AddInspectFlagSet(inspectCmd)
flags := inspectCmd.Flags()
- flags.StringVarP(&inspectOptions.Format, "format", "f", "", "Change the output format to a Go template")
- flags.BoolVarP(&inspectOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
- flags.BoolVarP(&inspectOptions.Size, "size", "s", false, "Display total file size")
- if registry.IsRemote() {
- _ = flags.MarkHidden("latest")
+
+ if !registry.IsRemote() {
+ flags.BoolVarP(&inspectOpts.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
}
+
}
func inspect(cmd *cobra.Command, args []string) error {
- responses, err := registry.ContainerEngine().ContainerInspect(context.Background(), args, inspectOptions)
+ responses, err := registry.ContainerEngine().ContainerInspect(context.Background(), args, *inspectOpts)
if err != nil {
return err
}
- if inspectOptions.Format == "" {
- b, err := jsoniter.MarshalIndent(responses, "", " ")
+ if inspectOpts.Format == "" {
+ b, err := json.MarshalIndent(responses, "", " ")
if err != nil {
return err
}
fmt.Println(string(b))
return nil
}
- format := inspectOptions.Format
+ format := inspectOpts.Format
if !strings.HasSuffix(format, "\n") {
format += "\n"
}
@@ -73,3 +72,8 @@ func inspect(cmd *cobra.Command, args []string) error {
}
return nil
}
+
+func Inspect(cmd *cobra.Command, args []string, options *entities.InspectOptions) error {
+ inspectOpts = options
+ return inspect(cmd, args)
+}
diff --git a/cmd/podmanV2/containers/restart.go b/cmd/podmanV2/containers/restart.go
index 1f1bb11fa..5f1d3fe51 100644
--- a/cmd/podmanV2/containers/restart.go
+++ b/cmd/podmanV2/containers/restart.go
@@ -14,9 +14,10 @@ import (
)
var (
- restartDescription = `Restarts one or more running containers. The container ID or name can be used.
+ restartDescription = fmt.Sprintf(`Restarts one or more running containers. The container ID or name can be used.
+
+ A timeout before forcibly stopping can be set, but defaults to %d seconds.`, defaultContainerConfig.Engine.StopTimeout)
- A timeout before forcibly stopping can be set, but defaults to 10 seconds.`
restartCommand = &cobra.Command{
Use: "restart [flags] CONTAINER [CONTAINER...]",
Short: "Restart one or more containers",
@@ -46,11 +47,11 @@ func init() {
flags.BoolVarP(&restartOptions.All, "all", "a", false, "Restart all non-running containers")
flags.BoolVarP(&restartOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
flags.BoolVar(&restartOptions.Running, "running", false, "Restart only running containers when --all is used")
- flags.UintVarP(&restartTimeout, "timeout", "t", defaultContainerConfig.Engine.StopTimeout, "Seconds to wait for stop before killing the container")
- flags.UintVar(&restartTimeout, "time", defaultContainerConfig.Engine.StopTimeout, "Seconds to wait for stop before killing the container")
+ flags.UintVarP(&restartTimeout, "time", "t", defaultContainerConfig.Engine.StopTimeout, "Seconds to wait for stop before killing the container")
if registry.IsRemote() {
_ = flags.MarkHidden("latest")
}
+ flags.SetNormalizeFunc(utils.AliasFlags)
}
func restart(cmd *cobra.Command, args []string) error {
@@ -61,7 +62,7 @@ func restart(cmd *cobra.Command, args []string) error {
return errors.Wrapf(define.ErrInvalidArg, "you must provide at least one container name or ID")
}
- if cmd.Flag("timeout").Changed || cmd.Flag("time").Changed {
+ if cmd.Flag("time").Changed {
restartOptions.Timeout = &restartTimeout
}
responses, err := registry.ContainerEngine().ContainerRestart(context.Background(), args, restartOptions)
diff --git a/cmd/podmanV2/containers/stop.go b/cmd/podmanV2/containers/stop.go
index 9a106e8fe..d6f31352f 100644
--- a/cmd/podmanV2/containers/stop.go
+++ b/cmd/podmanV2/containers/stop.go
@@ -8,14 +8,13 @@ import (
"github.com/containers/libpod/cmd/podmanV2/registry"
"github.com/containers/libpod/cmd/podmanV2/utils"
"github.com/containers/libpod/pkg/domain/entities"
- "github.com/pkg/errors"
"github.com/spf13/cobra"
)
var (
- stopDescription = `Stops one or more running containers. The container name or ID can be used.
+ stopDescription = fmt.Sprintf(`Stops one or more running containers. The container name or ID can be used.
- A timeout to forcibly stop the container can also be set but defaults to 10 seconds otherwise.`
+ A timeout to forcibly stop the container can also be set but defaults to %d seconds otherwise.`, defaultContainerConfig.Engine.StopTimeout)
stopCommand = &cobra.Command{
Use: "stop [flags] CONTAINER [CONTAINER...]",
Short: "Stop one or more containers",
@@ -27,7 +26,7 @@ var (
},
Example: `podman stop ctrID
podman stop --latest
- podman stop --timeout 2 mywebserver 6e534f14da9d`,
+ podman stop --time 2 mywebserver 6e534f14da9d`,
}
)
@@ -46,24 +45,21 @@ func init() {
flags.BoolVarP(&stopOptions.Ignore, "ignore", "i", false, "Ignore errors when a specified container is missing")
flags.StringArrayVarP(&stopOptions.CIDFiles, "cidfile", "", nil, "Read the container ID from the file")
flags.BoolVarP(&stopOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
- flags.UintVar(&stopTimeout, "time", defaultContainerConfig.Engine.StopTimeout, "Seconds to wait for stop before killing the container")
- flags.UintVarP(&stopTimeout, "timeout", "t", defaultContainerConfig.Engine.StopTimeout, "Seconds to wait for stop before killing the container")
+ flags.UintVarP(&stopTimeout, "time", "t", defaultContainerConfig.Engine.StopTimeout, "Seconds to wait for stop before killing the container")
if registry.EngineOptions.EngineMode == entities.ABIMode {
_ = flags.MarkHidden("latest")
_ = flags.MarkHidden("cidfile")
_ = flags.MarkHidden("ignore")
}
+ flags.SetNormalizeFunc(utils.AliasFlags)
}
func stop(cmd *cobra.Command, args []string) error {
var (
errs utils.OutputErrors
)
- if cmd.Flag("timeout").Changed && cmd.Flag("time").Changed {
- return errors.New("the --timeout and --time flags are mutually exclusive")
- }
stopOptions.Timeout = defaultContainerConfig.Engine.StopTimeout
- if cmd.Flag("timeout").Changed || cmd.Flag("time").Changed {
+ if cmd.Flag("time").Changed {
stopOptions.Timeout = stopTimeout
}
diff --git a/cmd/podmanV2/healthcheck/healthcheck.go b/cmd/podmanV2/healthcheck/healthcheck.go
new file mode 100644
index 000000000..2af398ff0
--- /dev/null
+++ b/cmd/podmanV2/healthcheck/healthcheck.go
@@ -0,0 +1,33 @@
+package healthcheck
+
+import (
+ "github.com/containers/libpod/cmd/podmanV2/registry"
+ "github.com/containers/libpod/pkg/domain/entities"
+ "github.com/spf13/cobra"
+)
+
+var (
+ // Command: healthcheck
+ healthCmd = &cobra.Command{
+ Use: "healthcheck",
+ Short: "Manage Healthcheck",
+ Long: "Manage Healthcheck",
+ TraverseChildren: true,
+ PersistentPreRunE: preRunE,
+ RunE: registry.SubCommandExists,
+ }
+)
+
+func init() {
+ registry.Commands = append(registry.Commands, registry.CliCommand{
+ Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
+ Command: healthCmd,
+ })
+ healthCmd.SetHelpTemplate(registry.HelpTemplate())
+ healthCmd.SetUsageTemplate(registry.UsageTemplate())
+}
+
+func preRunE(cmd *cobra.Command, args []string) error {
+ _, err := registry.NewContainerEngine(cmd, args)
+ return err
+}
diff --git a/cmd/podmanV2/healthcheck/run.go b/cmd/podmanV2/healthcheck/run.go
new file mode 100644
index 000000000..bb2962eaf
--- /dev/null
+++ b/cmd/podmanV2/healthcheck/run.go
@@ -0,0 +1,42 @@
+package healthcheck
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/containers/libpod/cmd/podmanV2/registry"
+ "github.com/containers/libpod/pkg/domain/entities"
+ "github.com/spf13/cobra"
+)
+
+var (
+ healthcheckRunDescription = "run the health check of a container"
+ healthcheckrunCommand = &cobra.Command{
+ Use: "run [flags] CONTAINER",
+ Short: "run the health check of a container",
+ Long: healthcheckRunDescription,
+ Example: `podman healthcheck run mywebapp`,
+ RunE: run,
+ Args: cobra.ExactArgs(1),
+ }
+)
+
+func init() {
+ registry.Commands = append(registry.Commands, registry.CliCommand{
+ Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
+ Command: healthcheckrunCommand,
+ Parent: healthCmd,
+ })
+}
+
+func run(cmd *cobra.Command, args []string) error {
+ response, err := registry.ContainerEngine().HealthCheckRun(context.Background(), args[0], entities.HealthCheckOptions{})
+ if err != nil {
+ return err
+ }
+ if response.Status == "unhealthy" {
+ registry.SetExitCode(1)
+ }
+ fmt.Println(response.Status)
+ return err
+}
diff --git a/cmd/podmanV2/images/import.go b/cmd/podmanV2/images/import.go
new file mode 100644
index 000000000..09a15585f
--- /dev/null
+++ b/cmd/podmanV2/images/import.go
@@ -0,0 +1,87 @@
+package images
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/containers/libpod/cmd/podmanV2/parse"
+ "github.com/containers/libpod/cmd/podmanV2/registry"
+ "github.com/containers/libpod/pkg/domain/entities"
+ "github.com/hashicorp/go-multierror"
+ "github.com/pkg/errors"
+ "github.com/spf13/cobra"
+)
+
+var (
+ importDescription = `Create a container image from the contents of the specified tarball (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz).
+
+ Note remote tar balls can be specified, via web address.
+ Optionally tag the image. You can specify the instructions using the --change option.`
+ importCommand = &cobra.Command{
+ Use: "import [flags] PATH [REFERENCE]",
+ Short: "Import a tarball to create a filesystem image",
+ Long: importDescription,
+ RunE: importCon,
+ PersistentPreRunE: preRunE,
+ 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 -`,
+ }
+)
+
+var (
+ importOpts entities.ImageImportOptions
+)
+
+func init() {
+ registry.Commands = append(registry.Commands, registry.CliCommand{
+ Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
+ Command: importCommand,
+ })
+
+ importCommand.SetHelpTemplate(registry.HelpTemplate())
+ importCommand.SetUsageTemplate(registry.UsageTemplate())
+ flags := importCommand.Flags()
+ flags.StringArrayVarP(&importOpts.Changes, "change", "c", []string{}, "Apply the following possible instructions to the created image (default []): CMD | ENTRYPOINT | ENV | EXPOSE | LABEL | STOPSIGNAL | USER | VOLUME | WORKDIR")
+ flags.StringVarP(&importOpts.Message, "message", "m", "", "Set commit message for imported image")
+ flags.BoolVarP(&importOpts.Quiet, "quiet", "q", false, "Suppress output")
+}
+
+func importCon(cmd *cobra.Command, args []string) error {
+ var (
+ source string
+ reference string
+ )
+ switch len(args) {
+ case 0:
+ return errors.Errorf("need to give the path to the tarball, or must specify a tarball of '-' for stdin")
+ case 1:
+ source = args[0]
+ case 2:
+ source = args[0]
+ // TODO when save is merged, we need to process reference
+ // like it is done in there or we end up with docker.io prepends
+ // instead of the localhost ones
+ reference = args[1]
+ default:
+ return errors.Errorf("too many arguments. Usage TARBALL [REFERENCE]")
+ }
+ errFileName := parse.ValidateFileName(source)
+ errURL := parse.ValidURL(source)
+ if errURL == nil {
+ importOpts.SourceIsURL = true
+ }
+ if errFileName != nil && errURL != nil {
+ return multierror.Append(errFileName, errURL)
+ }
+
+ importOpts.Source = source
+ importOpts.Reference = reference
+
+ response, err := registry.ImageEngine().Import(context.Background(), importOpts)
+ if err != nil {
+ return err
+ }
+ fmt.Println(response.Id)
+ return nil
+}
diff --git a/cmd/podmanV2/images/inspect.go b/cmd/podmanV2/images/inspect.go
index f8fd44571..d7f6b0ee1 100644
--- a/cmd/podmanV2/images/inspect.go
+++ b/cmd/podmanV2/images/inspect.go
@@ -1,71 +1,44 @@
package images
import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "os"
"strings"
+ "text/tabwriter"
+ "text/template"
"github.com/containers/buildah/pkg/formats"
+ "github.com/containers/libpod/cmd/podmanV2/common"
"github.com/containers/libpod/cmd/podmanV2/registry"
"github.com/containers/libpod/pkg/domain/entities"
- "github.com/containers/libpod/pkg/util"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
var (
- inspectOpts = entities.ImageInspectOptions{}
-
// Command: podman image _inspect_
inspectCmd = &cobra.Command{
Use: "inspect [flags] IMAGE",
Short: "Display the configuration of an image",
Long: `Displays the low-level information on an image identified by name or ID.`,
- PreRunE: populateEngines,
- RunE: imageInspect,
+ RunE: inspect,
Example: `podman image inspect alpine`,
}
-
- containerEngine entities.ContainerEngine
+ inspectOpts *entities.InspectOptions
)
-// Inspect is unique in that it needs both an ImageEngine and a ContainerEngine
-func populateEngines(cmd *cobra.Command, args []string) (err error) {
- // Populate registry.ImageEngine
- err = preRunE(cmd, args)
- if err != nil {
- return
- }
-
- // Populate registry.ContainerEngine
- containerEngine, err = registry.NewContainerEngine(cmd, args)
- return
-}
-
func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
Command: inspectCmd,
Parent: imageCmd,
})
-
- flags := inspectCmd.Flags()
- flags.BoolVarP(&inspectOpts.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
- flags.BoolVarP(&inspectOpts.Size, "size", "s", false, "Display total file size")
- flags.StringVarP(&inspectOpts.Format, "format", "f", "", "Change the output format to a Go template")
-
- if registry.EngineOptions.EngineMode == entities.ABIMode {
- // TODO: This is the same as V1. We could skip creating the flag altogether in V2...
- _ = flags.MarkHidden("latest")
- }
+ inspectOpts = common.AddInspectFlagSet(inspectCmd)
}
-const (
- inspectTypeContainer = "container"
- inspectTypeImage = "image"
- inspectAll = "all"
-)
-
-func imageInspect(cmd *cobra.Command, args []string) error {
- inspectType := inspectTypeImage
+func inspect(cmd *cobra.Command, args []string) error {
latestContainer := inspectOpts.Latest
if len(args) == 0 && !latestContainer {
@@ -76,49 +49,61 @@ func imageInspect(cmd *cobra.Command, args []string) error {
return errors.Errorf("you cannot provide additional arguments with --latest")
}
- if !util.StringInSlice(inspectType, []string{inspectTypeContainer, inspectTypeImage, inspectAll}) {
- return errors.Errorf("the only recognized types are %q, %q, and %q", inspectTypeContainer, inspectTypeImage, inspectAll)
+ results, err := registry.ImageEngine().Inspect(context.Background(), args, *inspectOpts)
+ if err != nil {
+ return err
}
- outputFormat := inspectOpts.Format
- if strings.Contains(outputFormat, "{{.Id}}") {
- outputFormat = strings.Replace(outputFormat, "{{.Id}}", formats.IDString, -1)
- }
- // These fields were renamed, so we need to provide backward compat for
- // the old names.
- if strings.Contains(outputFormat, ".Src") {
- outputFormat = strings.Replace(outputFormat, ".Src", ".Source", -1)
+ if len(results.Images) > 0 {
+ if inspectOpts.Format == "" {
+ buf, err := json.MarshalIndent(results.Images, "", " ")
+ if err != nil {
+ return err
+ }
+ fmt.Println(string(buf))
+
+ for id, e := range results.Errors {
+ fmt.Fprintf(os.Stderr, "%s: %s\n", id, e.Error())
+ }
+ return nil
+ }
+
+ row := inspectFormat(inspectOpts.Format)
+ format := "{{range . }}" + row + "{{end}}"
+ tmpl, err := template.New("inspect").Parse(format)
+ if err != nil {
+ return err
+ }
+
+ w := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0)
+ defer func() { _ = w.Flush() }()
+ err = tmpl.Execute(w, results)
+ if err != nil {
+ return err
+ }
}
- if strings.Contains(outputFormat, ".Dst") {
- outputFormat = strings.Replace(outputFormat, ".Dst", ".Destination", -1)
- }
- if strings.Contains(outputFormat, ".ImageID") {
- outputFormat = strings.Replace(outputFormat, ".ImageID", ".Image", -1)
+
+ for id, e := range results.Errors {
+ fmt.Fprintf(os.Stderr, "%s: %s\n", id, e.Error())
}
- _ = outputFormat
- // if latestContainer {
- // lc, err := ctnrRuntime.GetLatestContainer()
- // if err != nil {
- // return err
- // }
- // args = append(args, lc.ID())
- // inspectType = inspectTypeContainer
- // }
-
- // inspectedObjects, iterateErr := iterateInput(getContext(), c.Size, args, runtime, inspectType)
- // if iterateErr != nil {
- // return iterateErr
- // }
- //
- // var out formats.Writer
- // if outputFormat != "" && outputFormat != formats.JSONString {
- // // template
- // out = formats.StdoutTemplateArray{Output: inspectedObjects, Template: outputFormat}
- // } else {
- // // default is json output
- // out = formats.JSONStructArray{Output: inspectedObjects}
- // }
- //
- // return out.Out()
return nil
}
+
+func inspectFormat(row string) string {
+ r := strings.NewReplacer("{{.Id}}", formats.IDString,
+ ".Src", ".Source",
+ ".Dst", ".Destination",
+ ".ImageID", ".Image",
+ )
+ row = r.Replace(row)
+
+ if !strings.HasSuffix(row, "\n") {
+ row += "\n"
+ }
+ return row
+}
+
+func Inspect(cmd *cobra.Command, args []string, options *entities.InspectOptions) error {
+ inspectOpts = options
+ return inspect(cmd, args)
+}
diff --git a/cmd/podmanV2/images/list.go b/cmd/podmanV2/images/list.go
index 9a5b47299..2d6cb3596 100644
--- a/cmd/podmanV2/images/list.go
+++ b/cmd/podmanV2/images/list.go
@@ -152,7 +152,7 @@ func writeTemplate(imageS []*entities.ImageSummary, err error) error {
hdr, row := imageListFormat(listFlag)
format := hdr + "{{range . }}" + row + "{{end}}"
- tmpl := template.Must(template.New("report").Funcs(report.PodmanTemplateFuncs()).Parse(format))
+ tmpl := template.Must(template.New("list").Funcs(report.PodmanTemplateFuncs()).Parse(format))
w := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0)
defer w.Flush()
return tmpl.Execute(w, imgs)
diff --git a/cmd/podmanV2/images/load.go b/cmd/podmanV2/images/load.go
new file mode 100644
index 000000000..f60dc4908
--- /dev/null
+++ b/cmd/podmanV2/images/load.go
@@ -0,0 +1,61 @@
+package images
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/containers/libpod/cmd/podmanV2/registry"
+ "github.com/containers/libpod/libpod/image"
+ "github.com/containers/libpod/pkg/domain/entities"
+ "github.com/spf13/cobra"
+)
+
+var (
+ loadDescription = "Loads an image from a locally stored archive (tar file) into container storage."
+ loadCommand = &cobra.Command{
+ Use: "load [flags] [NAME[:TAG]]",
+ Short: "Load an image from container archive",
+ Long: loadDescription,
+ RunE: load,
+ Args: cobra.MaximumNArgs(1),
+ PersistentPreRunE: preRunE,
+ }
+)
+
+var (
+ loadOpts entities.ImageLoadOptions
+)
+
+func init() {
+ registry.Commands = append(registry.Commands, registry.CliCommand{
+ Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
+ Command: loadCommand,
+ })
+
+ loadCommand.SetHelpTemplate(registry.HelpTemplate())
+ loadCommand.SetUsageTemplate(registry.UsageTemplate())
+ flags := loadCommand.Flags()
+ flags.StringVarP(&loadOpts.Input, "input", "i", "", "Read from specified archive file (default: stdin)")
+ flags.BoolVarP(&loadOpts.Quiet, "quiet", "q", false, "Suppress the output")
+ flags.StringVar(&loadOpts.SignaturePolicy, "signature-policy", "", "Pathname of signature policy file")
+ if registry.IsRemote() {
+ _ = flags.MarkHidden("signature-policy")
+ }
+
+}
+
+func load(cmd *cobra.Command, args []string) error {
+ if len(args) > 0 {
+ repo, err := image.NormalizedTag(args[0])
+ if err != nil {
+ return err
+ }
+ loadOpts.Name = repo.Name()
+ }
+ response, err := registry.ImageEngine().Load(context.Background(), loadOpts)
+ if err != nil {
+ return err
+ }
+ fmt.Println("Loaded image: " + response.Name)
+ return nil
+}
diff --git a/cmd/podmanV2/images/pull.go b/cmd/podmanV2/images/pull.go
new file mode 100644
index 000000000..c7e325409
--- /dev/null
+++ b/cmd/podmanV2/images/pull.go
@@ -0,0 +1,140 @@
+package images
+
+import (
+ "fmt"
+
+ buildahcli "github.com/containers/buildah/pkg/cli"
+ "github.com/containers/image/v5/types"
+ "github.com/containers/libpod/cmd/podmanV2/registry"
+ "github.com/containers/libpod/pkg/domain/entities"
+ "github.com/opentracing/opentracing-go"
+ "github.com/pkg/errors"
+ "github.com/spf13/cobra"
+ "github.com/spf13/pflag"
+)
+
+// pullOptionsWrapper wraps entities.ImagePullOptions and prevents leaking
+// CLI-only fields into the API types.
+type pullOptionsWrapper struct {
+ entities.ImagePullOptions
+ TLSVerifyCLI bool // CLI only
+}
+
+var (
+ pullOptions = pullOptionsWrapper{}
+ pullDescription = `Pulls an image from a registry and stores it locally.
+
+ An image can be pulled by tag or digest. If a tag is not specified, the image with the 'latest' tag is pulled.`
+
+ // Command: podman pull
+ pullCmd = &cobra.Command{
+ Use: "pull [flags] IMAGE",
+ Short: "Pull an image from a registry",
+ Long: pullDescription,
+ PreRunE: preRunE,
+ RunE: imagePull,
+ Example: `podman pull imageName
+ podman pull fedora:latest`,
+ }
+
+ // Command: podman image pull
+ // It's basically a clone of `pullCmd` with the exception of being a
+ // child of the images command.
+ imagesPullCmd = &cobra.Command{
+ Use: pullCmd.Use,
+ Short: pullCmd.Short,
+ Long: pullCmd.Long,
+ PreRunE: pullCmd.PreRunE,
+ RunE: pullCmd.RunE,
+ Example: `podman image pull imageName
+ podman image pull fedora:latest`,
+ }
+)
+
+func init() {
+ // pull
+ registry.Commands = append(registry.Commands, registry.CliCommand{
+ Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
+ Command: pullCmd,
+ })
+
+ pullCmd.SetHelpTemplate(registry.HelpTemplate())
+ pullCmd.SetUsageTemplate(registry.UsageTemplate())
+
+ flags := pullCmd.Flags()
+ pullFlags(flags)
+
+ // images pull
+ registry.Commands = append(registry.Commands, registry.CliCommand{
+ Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
+ Command: imagesPullCmd,
+ Parent: imageCmd,
+ })
+
+ imagesPullCmd.SetHelpTemplate(registry.HelpTemplate())
+ imagesPullCmd.SetUsageTemplate(registry.UsageTemplate())
+ imagesPullFlags := imagesPullCmd.Flags()
+ pullFlags(imagesPullFlags)
+}
+
+// pullFlags set the flags for the pull command.
+func pullFlags(flags *pflag.FlagSet) {
+ flags.BoolVar(&pullOptions.AllTags, "all-tags", false, "All tagged images in the repository will be pulled")
+ flags.StringVar(&pullOptions.Authfile, "authfile", buildahcli.GetDefaultAuthFile(), "Path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override")
+ flags.StringVar(&pullOptions.CertDir, "cert-dir", "", "`Pathname` of a directory containing TLS certificates and keys")
+ flags.StringVar(&pullOptions.Credentials, "creds", "", "`Credentials` (USERNAME:PASSWORD) to use for authenticating to a registry")
+ flags.StringVar(&pullOptions.OverrideArch, "override-arch", "", "Use `ARCH` instead of the architecture of the machine for choosing images")
+ flags.StringVar(&pullOptions.OverrideOS, "override-os", "", "Use `OS` instead of the running OS for choosing images")
+ flags.BoolVarP(&pullOptions.Quiet, "quiet", "q", false, "Suppress output information when pulling images")
+ flags.StringVar(&pullOptions.SignaturePolicy, "signature-policy", "", "`Pathname` of signature policy file (not usually used)")
+ flags.BoolVar(&pullOptions.TLSVerifyCLI, "tls-verify", true, "Require HTTPS and verify certificates when contacting registries")
+
+ if registry.IsRemote() {
+ _ = flags.MarkHidden("authfile")
+ _ = flags.MarkHidden("cert-dir")
+ _ = flags.MarkHidden("signature-policy")
+ _ = flags.MarkHidden("tls-verify")
+ }
+}
+
+// imagePull is implement the command for pulling images.
+func imagePull(cmd *cobra.Command, args []string) error {
+ // Sanity check input.
+ if len(args) == 0 {
+ return errors.Errorf("an image name must be specified")
+ }
+ if len(args) > 1 {
+ return errors.Errorf("too many arguments. Requires exactly 1")
+ }
+
+ // Start tracing if requested.
+ if cmd.Flags().Changed("trace") {
+ span, _ := opentracing.StartSpanFromContext(registry.GetContext(), "pullCmd")
+ defer span.Finish()
+ }
+
+ pullOptsAPI := pullOptions.ImagePullOptions
+ // TLS verification in c/image is controlled via a `types.OptionalBool`
+ // which allows for distinguishing among set-true, set-false, unspecified
+ // which is important to implement a sane way of dealing with defaults of
+ // boolean CLI flags.
+ if cmd.Flags().Changed("tls-verify") {
+ pullOptsAPI.TLSVerify = types.NewOptionalBool(pullOptions.TLSVerifyCLI)
+ }
+
+ // Let's do all the remaining Yoga in the API to prevent us from
+ // scattering logic across (too) many parts of the code.
+ pullReport, err := registry.ImageEngine().Pull(registry.GetContext(), args[0], pullOptsAPI)
+ if err != nil {
+ return err
+ }
+
+ if len(pullReport.Images) > 1 {
+ fmt.Println("Pulled Images:")
+ }
+ for _, img := range pullReport.Images {
+ fmt.Println(img)
+ }
+
+ return nil
+}
diff --git a/cmd/podmanV2/images/tag.go b/cmd/podmanV2/images/tag.go
new file mode 100644
index 000000000..f66fe7857
--- /dev/null
+++ b/cmd/podmanV2/images/tag.go
@@ -0,0 +1,34 @@
+package images
+
+import (
+ "github.com/containers/libpod/cmd/podmanV2/registry"
+ "github.com/containers/libpod/pkg/domain/entities"
+ "github.com/spf13/cobra"
+)
+
+var (
+ tagDescription = "Adds one or more additional names to locally-stored image."
+ tagCommand = &cobra.Command{
+ Use: "tag [flags] IMAGE TARGET_NAME [TARGET_NAME...]",
+ Short: "Add an additional name to a local image",
+ Long: tagDescription,
+ RunE: tag,
+ Args: cobra.MinimumNArgs(2),
+ Example: `podman tag 0e3bbc2 fedora:latest
+ podman tag imageID:latest myNewImage:newTag
+ podman tag httpd myregistryhost:5000/fedora/httpd:v2`,
+ }
+)
+
+func init() {
+ registry.Commands = append(registry.Commands, registry.CliCommand{
+ Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
+ Command: tagCommand,
+ })
+ tagCommand.SetHelpTemplate(registry.HelpTemplate())
+ tagCommand.SetUsageTemplate(registry.UsageTemplate())
+}
+
+func tag(cmd *cobra.Command, args []string) error {
+ return registry.ImageEngine().Tag(registry.GetContext(), args[0], args[1:], entities.ImageTagOptions{})
+}
diff --git a/cmd/podmanV2/images/untag.go b/cmd/podmanV2/images/untag.go
new file mode 100644
index 000000000..c84827bb3
--- /dev/null
+++ b/cmd/podmanV2/images/untag.go
@@ -0,0 +1,33 @@
+package images
+
+import (
+ "github.com/containers/libpod/cmd/podmanV2/registry"
+ "github.com/containers/libpod/pkg/domain/entities"
+ "github.com/spf13/cobra"
+)
+
+var (
+ untagCommand = &cobra.Command{
+ Use: "untag [flags] IMAGE [NAME...]",
+ Short: "Remove a name from a local image",
+ Long: "Removes one or more names from a locally-stored image.",
+ RunE: untag,
+ Args: cobra.MinimumNArgs(1),
+ Example: `podman untag 0e3bbc2
+ podman untag imageID:latest otherImageName:latest
+ podman untag httpd myregistryhost:5000/fedora/httpd:v2`,
+ }
+)
+
+func init() {
+ registry.Commands = append(registry.Commands, registry.CliCommand{
+ Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
+ Command: untagCommand,
+ })
+ untagCommand.SetHelpTemplate(registry.HelpTemplate())
+ untagCommand.SetUsageTemplate(registry.UsageTemplate())
+}
+
+func untag(cmd *cobra.Command, args []string) error {
+ return registry.ImageEngine().Untag(registry.GetContext(), args[0], args[1:], entities.ImageUntagOptions{})
+}
diff --git a/cmd/podmanV2/inspect.go b/cmd/podmanV2/inspect.go
new file mode 100644
index 000000000..4975cf632
--- /dev/null
+++ b/cmd/podmanV2/inspect.go
@@ -0,0 +1,62 @@
+package main
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/containers/libpod/cmd/podmanV2/common"
+ "github.com/containers/libpod/cmd/podmanV2/containers"
+ "github.com/containers/libpod/cmd/podmanV2/images"
+ "github.com/containers/libpod/cmd/podmanV2/registry"
+ "github.com/containers/libpod/pkg/domain/entities"
+ "github.com/spf13/cobra"
+)
+
+// Inspect is one of the out layer commands in that it operates on images/containers/...
+
+var (
+ inspectOpts *entities.InspectOptions
+
+ // Command: podman _inspect_ Object_ID
+ inspectCmd = &cobra.Command{
+ Use: "inspect [flags] {CONTAINER_ID | IMAGE_ID}",
+ Args: cobra.ExactArgs(1),
+ Short: "Display the configuration of object denoted by ID",
+ Long: "Displays the low-level information on an object identified by name or ID",
+ TraverseChildren: true,
+ RunE: inspect,
+ }
+)
+
+func init() {
+ registry.Commands = append(registry.Commands, registry.CliCommand{
+ Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
+ Command: inspectCmd,
+ })
+ inspectOpts = common.AddInspectFlagSet(inspectCmd)
+}
+
+func inspect(cmd *cobra.Command, args []string) error {
+ ie, err := registry.NewImageEngine(cmd, args)
+ if err != nil {
+ return err
+ }
+
+ if found, err := ie.Exists(context.Background(), args[0]); err != nil {
+ return err
+ } else if found.Value {
+ return images.Inspect(cmd, args, inspectOpts)
+ }
+
+ ce, err := registry.NewContainerEngine(cmd, args)
+ if err != nil {
+ return err
+ }
+
+ if found, err := ce.ContainerExists(context.Background(), args[0]); err != nil {
+ return err
+ } else if found.Value {
+ return containers.Inspect(cmd, args, inspectOpts)
+ }
+ return fmt.Errorf("%s not found on system", args[0])
+}
diff --git a/cmd/podmanV2/main.go b/cmd/podmanV2/main.go
index bd9fbb25e..6781a7f06 100644
--- a/cmd/podmanV2/main.go
+++ b/cmd/podmanV2/main.go
@@ -7,6 +7,7 @@ import (
"strings"
_ "github.com/containers/libpod/cmd/podmanV2/containers"
+ _ "github.com/containers/libpod/cmd/podmanV2/healthcheck"
_ "github.com/containers/libpod/cmd/podmanV2/images"
_ "github.com/containers/libpod/cmd/podmanV2/networks"
_ "github.com/containers/libpod/cmd/podmanV2/pods"
@@ -14,6 +15,7 @@ import (
_ "github.com/containers/libpod/cmd/podmanV2/volumes"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/domain/entities"
+ "github.com/containers/storage/pkg/reexec"
"github.com/sirupsen/logrus"
)
@@ -44,6 +46,11 @@ func init() {
}
func main() {
+ if reexec.Init() {
+ // We were invoked with a different argv[0] indicating that we
+ // had a specific job to do as a subprocess, and it's done.
+ return
+ }
for _, c := range registry.Commands {
if Contains(registry.EngineOptions.EngineMode, c.Mode) {
parent := rootCmd
diff --git a/cmd/podmanV2/pods/pod.go b/cmd/podmanV2/pods/pod.go
index 81c0d33e1..3766893bb 100644
--- a/cmd/podmanV2/pods/pod.go
+++ b/cmd/podmanV2/pods/pod.go
@@ -1,6 +1,9 @@
package pods
import (
+ "strings"
+ "text/template"
+
"github.com/containers/libpod/cmd/podmanV2/registry"
"github.com/containers/libpod/pkg/domain/entities"
"github.com/spf13/cobra"
@@ -18,6 +21,33 @@ var (
}
)
+var podFuncMap = template.FuncMap{
+ "numCons": func(cons []*entities.ListPodContainer) int {
+ return len(cons)
+ },
+ "podcids": func(cons []*entities.ListPodContainer) string {
+ var ctrids []string
+ for _, c := range cons {
+ ctrids = append(ctrids, c.Id[:12])
+ }
+ return strings.Join(ctrids, ",")
+ },
+ "podconnames": func(cons []*entities.ListPodContainer) string {
+ var ctrNames []string
+ for _, c := range cons {
+ ctrNames = append(ctrNames, c.Names[:12])
+ }
+ return strings.Join(ctrNames, ",")
+ },
+ "podconstatuses": func(cons []*entities.ListPodContainer) string {
+ var statuses []string
+ for _, c := range cons {
+ statuses = append(statuses, c.Status)
+ }
+ return strings.Join(statuses, ",")
+ },
+}
+
func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
diff --git a/cmd/podmanV2/pods/ps.go b/cmd/podmanV2/pods/ps.go
index d4c625b2e..9546dff9e 100644
--- a/cmd/podmanV2/pods/ps.go
+++ b/cmd/podmanV2/pods/ps.go
@@ -1,8 +1,19 @@
package pods
import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "io"
+ "os"
+ "strings"
+ "text/tabwriter"
+ "text/template"
+
"github.com/containers/libpod/cmd/podmanV2/registry"
+ "github.com/containers/libpod/cmd/podmanV2/report"
"github.com/containers/libpod/pkg/domain/entities"
+ "github.com/pkg/errors"
"github.com/spf13/cobra"
)
@@ -19,14 +30,137 @@ var (
}
)
+var (
+ defaultHeaders string = "POD ID\tNAME\tSTATUS\tCREATED"
+ inputFilters string
+ noTrunc bool
+ psInput entities.PodPSOptions
+)
+
func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
Command: psCmd,
Parent: podCmd,
})
+ flags := psCmd.Flags()
+ flags.BoolVar(&psInput.CtrNames, "ctr-names", false, "Display the container names")
+ flags.BoolVar(&psInput.CtrIds, "ctr-ids", false, "Display the container UUIDs. If no-trunc is not set they will be truncated")
+ flags.BoolVar(&psInput.CtrStatus, "ctr-status", false, "Display the container status")
+ // TODO should we make this a [] ?
+ flags.StringVarP(&inputFilters, "filter", "f", "", "Filter output based on conditions given")
+ flags.StringVar(&psInput.Format, "format", "", "Pretty-print pods to JSON or using a Go template")
+ flags.BoolVarP(&psInput.Latest, "latest", "l", false, "Act on the latest pod podman is aware of")
+ flags.BoolVar(&psInput.Namespace, "namespace", false, "Display namespace information of the pod")
+ flags.BoolVar(&psInput.Namespace, "ns", false, "Display namespace information of the pod")
+ flags.BoolVar(&noTrunc, "no-trunc", false, "Do not truncate pod and container IDs")
+ flags.BoolVarP(&psInput.Quiet, "quiet", "q", false, "Print the numeric IDs of the pods only")
+ flags.StringVar(&psInput.Sort, "sort", "created", "Sort output by created, id, name, or number")
+ if registry.IsRemote() {
+ _ = flags.MarkHidden("latest")
+ }
}
func pods(cmd *cobra.Command, args []string) error {
+ var (
+ w io.Writer = os.Stdout
+ row string
+ )
+ if cmd.Flag("filter").Changed {
+ for _, f := range strings.Split(inputFilters, ",") {
+ split := strings.Split(f, "=")
+ if len(split) < 2 {
+ return errors.Errorf("filter input must be in the form of filter=value: %s is invalid", f)
+ }
+ psInput.Filters[split[0]] = append(psInput.Filters[split[0]], split[1])
+ }
+ }
+ responses, err := registry.ContainerEngine().PodPs(context.Background(), psInput)
+ if err != nil {
+ return err
+ }
+
+ if psInput.Format == "json" {
+ b, err := json.MarshalIndent(responses, "", " ")
+ if err != nil {
+ return err
+ }
+ fmt.Println(string(b))
+ return nil
+ }
+ headers, row := createPodPsOut(cmd)
+ if psInput.Quiet {
+ if noTrunc {
+ row = "{{.Id}}\n"
+ } else {
+ row = "{{slice .Id 0 12}}\n"
+ }
+ }
+ if cmd.Flag("format").Changed {
+ row = psInput.Format
+ if !strings.HasPrefix(row, "\n") {
+ row += "\n"
+ }
+ }
+ format := "{{range . }}" + row + "{{end}}"
+ if !psInput.Quiet && !cmd.Flag("format").Changed {
+ format = headers + format
+ }
+ funcs := report.AppendFuncMap(podFuncMap)
+ tmpl, err := template.New("listPods").Funcs(funcs).Parse(format)
+ if err != nil {
+ return err
+ }
+ if !psInput.Quiet {
+ w = tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0)
+ }
+ if err := tmpl.Execute(w, responses); err != nil {
+ return err
+ }
+ if flusher, ok := w.(interface{ Flush() error }); ok {
+ return flusher.Flush()
+ }
return nil
}
+
+func createPodPsOut(cmd *cobra.Command) (string, string) {
+ var row string
+ headers := defaultHeaders
+ if noTrunc {
+ row += "{{.Id}}"
+ } else {
+ row += "{{slice .Id 0 12}}"
+ }
+
+ row += "\t{{.Name}}\t{{.Status}}\t{{humanDurationFromTime .Created}}"
+
+ //rowFormat string = "{{slice .Id 0 12}}\t{{.Name}}\t{{.Status}}\t{{humanDurationFromTime .Created}}"
+ if psInput.CtrIds {
+ headers += "\tIDS"
+ row += "\t{{podcids .Containers}}"
+ }
+ if psInput.CtrNames {
+ headers += "\tNAMES"
+ row += "\t{{podconnames .Containers}}"
+ }
+ if psInput.CtrStatus {
+ headers += "\tSTATUS"
+ row += "\t{{podconstatuses .Containers}}"
+ }
+ if psInput.Namespace {
+ headers += "\tCGROUP\tNAMESPACES"
+ row += "\t{{.Cgroup}}\t{{.Namespace}}"
+ }
+ if !psInput.CtrStatus && !psInput.CtrNames && !psInput.CtrIds {
+ headers += "\t# OF CONTAINERS"
+ row += "\t{{numCons .Containers}}"
+
+ }
+ headers += "\tINFRA ID\n"
+ if noTrunc {
+ row += "\t{{.InfraId}}\n"
+ } else {
+ row += "\t{{slice .InfraId 0 12}}\n"
+ }
+ return headers, row
+}
diff --git a/cmd/podmanV2/pods/stop.go b/cmd/podmanV2/pods/stop.go
index 2b61850e2..403c7d95d 100644
--- a/cmd/podmanV2/pods/stop.go
+++ b/cmd/podmanV2/pods/stop.go
@@ -26,7 +26,7 @@ var (
},
Example: `podman pod stop mywebserverpod
podman pod stop --latest
- podman pod stop --timeout 0 490eb 3557fb`,
+ podman pod stop --time 0 490eb 3557fb`,
}
)
@@ -47,19 +47,20 @@ func init() {
flags.BoolVarP(&stopOptions.All, "all", "a", false, "Stop all running pods")
flags.BoolVarP(&stopOptions.Ignore, "ignore", "i", false, "Ignore errors when a specified pod is missing")
flags.BoolVarP(&stopOptions.Latest, "latest", "l", false, "Stop the latest pod podman is aware of")
- flags.UintVarP(&timeout, "timeout", "t", 0, "Seconds to wait for pod stop before killing the container")
+ flags.UintVarP(&timeout, "time", "t", 0, "Seconds to wait for pod stop before killing the container")
if registry.IsRemote() {
_ = flags.MarkHidden("latest")
_ = flags.MarkHidden("ignore")
}
+ flags.SetNormalizeFunc(utils.AliasFlags)
}
func stop(cmd *cobra.Command, args []string) error {
var (
errs utils.OutputErrors
)
- if cmd.Flag("timeout").Changed {
+ if cmd.Flag("time").Changed {
stopOptions.Timeout = int(timeout)
}
responses, err := registry.ContainerEngine().PodStop(context.Background(), args, stopOptions)
diff --git a/cmd/podmanV2/registry/registry.go b/cmd/podmanV2/registry/registry.go
index 5cdb8a840..401f82718 100644
--- a/cmd/podmanV2/registry/registry.go
+++ b/cmd/podmanV2/registry/registry.go
@@ -3,7 +3,6 @@ package registry
import (
"context"
- "github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/pkg/domain/entities"
"github.com/containers/libpod/pkg/domain/infra"
"github.com/pkg/errors"
@@ -18,24 +17,24 @@ type CliCommand struct {
Parent *cobra.Command
}
-var (
- Commands []CliCommand
+const ExecErrorCodeGeneric = 125
- imageEngine entities.ImageEngine
- containerEngine entities.ContainerEngine
+var (
cliCtx context.Context
+ containerEngine entities.ContainerEngine
+ exitCode = ExecErrorCodeGeneric
+ imageEngine entities.ImageEngine
+ Commands []CliCommand
EngineOptions entities.EngineOptions
-
- ExitCode = define.ExecErrorCodeGeneric
)
func SetExitCode(code int) {
- ExitCode = code
+ exitCode = code
}
func GetExitCode() int {
- return ExitCode
+ return exitCode
}
// HelpTemplate returns the help template for podman commands
diff --git a/cmd/podmanV2/report/templates.go b/cmd/podmanV2/report/templates.go
index f3bc06405..e46048e97 100644
--- a/cmd/podmanV2/report/templates.go
+++ b/cmd/podmanV2/report/templates.go
@@ -19,6 +19,9 @@ var defaultFuncMap = template.FuncMap{
"humanDuration": func(t int64) string {
return units.HumanDuration(time.Since(time.Unix(t, 0))) + " ago"
},
+ "humanDurationFromTime": func(t time.Time) string {
+ return units.HumanDuration(time.Since(t)) + " ago"
+ },
"humanSize": func(sz int64) string {
s := units.HumanSizeWithPrecision(float64(sz), 3)
i := strings.LastIndexFunc(s, unicode.IsNumber)
diff --git a/cmd/podmanV2/root.go b/cmd/podmanV2/root.go
index cb4cb4e00..6fc12f57e 100644
--- a/cmd/podmanV2/root.go
+++ b/cmd/podmanV2/root.go
@@ -7,7 +7,6 @@ import (
"path"
"github.com/containers/libpod/cmd/podmanV2/registry"
- "github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/pkg/domain/entities"
"github.com/containers/libpod/version"
"github.com/sirupsen/logrus"
@@ -88,8 +87,8 @@ func Execute() {
o := registry.NewOptions(rootCmd.Context(), &registry.EngineOptions)
if err := rootCmd.ExecuteContext(o); err != nil {
fmt.Fprintln(os.Stderr, "Error:", err.Error())
- } else if registry.GetExitCode() == define.ExecErrorCodeGeneric {
- // The exitCode modified from define.ExecErrorCodeGeneric,
+ } else if registry.GetExitCode() == registry.ExecErrorCodeGeneric {
+ // The exitCode modified from registry.ExecErrorCodeGeneric,
// indicates an application
// running inside of a container failed, as opposed to the
// podman command failed. Must exit with that exit code
diff --git a/cmd/podmanV2/system/system.go b/cmd/podmanV2/system/system.go
index 30ed328e8..4e805c7bd 100644
--- a/cmd/podmanV2/system/system.go
+++ b/cmd/podmanV2/system/system.go
@@ -1,4 +1,4 @@
-package images
+package system
import (
"github.com/containers/libpod/cmd/podmanV2/registry"
diff --git a/cmd/podmanV2/utils/alias.go b/cmd/podmanV2/utils/alias.go
new file mode 100644
index 000000000..54b3c5e89
--- /dev/null
+++ b/cmd/podmanV2/utils/alias.go
@@ -0,0 +1,24 @@
+package utils
+
+import "github.com/spf13/pflag"
+
+// AliasFlags is a function to handle backwards compatability with old flags
+func AliasFlags(f *pflag.FlagSet, name string) pflag.NormalizedName {
+ switch name {
+ case "healthcheck-command":
+ name = "health-cmd"
+ case "healthcheck-interval":
+ name = "health-interval"
+ case "healthcheck-retries":
+ name = "health-retries"
+ case "healthcheck-start-period":
+ name = "health-start-period"
+ case "healthcheck-timeout":
+ name = "health-timeout"
+ case "net":
+ name = "network"
+ case "timeout":
+ name = "time"
+ }
+ return pflag.NormalizedName(name)
+}
diff --git a/completions/bash/podman b/completions/bash/podman
index 4a694ca44..77f881d53 100644
--- a/completions/bash/podman
+++ b/completions/bash/podman
@@ -2161,7 +2161,7 @@ _podman_run() {
_podman_restart() {
local options_with_args="
- --timeout -t
+ --time -t
"
local boolean_options="
--all
@@ -2171,8 +2171,6 @@ _podman_restart() {
--latest
-l
--running
- --timeout
- -t
"
case "$cur" in
-*)
@@ -2462,7 +2460,7 @@ _podman_start() {
}
_podman_stop() {
local options_with_args="
- --timeout -t
+ --time -t
"
local boolean_options="
--all
@@ -2656,7 +2654,7 @@ _podman_generate_systemd() {
local options_with_args="
--restart-policy
-t
- --timeout"
+ --time"
local boolean_options="
-h
@@ -3088,7 +3086,7 @@ _podman_pod_start() {
_podman_pod_stop() {
local options_with_args="
-t
- --timeout
+ --time
"
local boolean_options="
diff --git a/contrib/build_rpm.sh b/contrib/build_rpm.sh
index de6941199..a9db029df 100755
--- a/contrib/build_rpm.sh
+++ b/contrib/build_rpm.sh
@@ -7,11 +7,18 @@ echo "Package manager binary: $pkg_manager"
if [[ $pkg_manager == *yum ]]; then
- echo "[virt7-container-common-candidate]
-name=virt7-container-common-candidate
-baseurl=https://cbs.centos.org/repos/virt7-container-common-candidate/x86_64/os/
+ echo "[virt7-container]
+name=virt7-container
+baseurl=https://buildlogs.centos.org/centos/7/virt/x86_64/container/
enabled=1
gpgcheck=0" > /etc/yum.repos.d/container_virt.repo
+ echo "[paas_openshift_origin311]
+name=paas_openshift_origin311
+# Use this if you need the newest *-testing packages
+# baseurl=https://buildlogs.centos.org/centos/7/paas/x86_64/openshift-origin311/
+baseurl=http://mirror.centos.org/centos/7/paas/x86_64/openshift-origin311/
+enabled=1
+gpgcheck=0" > /etc/yum.repos.d/paas_openshift_origin311.repo
fi
declare -a PKGS=(\
diff --git a/contrib/cirrus/README.md b/contrib/cirrus/README.md
index 3789965d6..709985b5b 100644
--- a/contrib/cirrus/README.md
+++ b/contrib/cirrus/README.md
@@ -80,7 +80,7 @@ having `SPECIALMODE` set to 'cgroupv2`
Modifying the contents of cache-images is tested by making changes to
one or more of the ``./contrib/cirrus/packer/*_setup.sh`` files. Then
-in the PR description, add the magic string: ``***CIRRUS: TEST IMAGES***``
+in the PR description, add the magic string: ``[CI:IMG]``
***N/B: Steps below are performed by automation***
@@ -153,7 +153,7 @@ env:
***NOTES:***
* If re-using the same PR with new images in `.cirrus.yml`,
take care to also *update the PR description* to remove
- the magic ``***CIRRUS: TEST IMAGES***`` string. Keeping it and
+ the magic ``[CI:IMG]`` string. Keeping it and
`--force` pushing would needlessly cause Cirrus-CI to build
and test images again.
* In the future, if you need to review the log from the build that produced
diff --git a/contrib/spec/podman.spec.in b/contrib/spec/podman.spec.in
index 817be31b7..9641a52e6 100644
--- a/contrib/spec/podman.spec.in
+++ b/contrib/spec/podman.spec.in
@@ -392,9 +392,9 @@ popd
ln -s vendor src
export GO111MODULE=off
export GOPATH=$(pwd)/_build:$(pwd):$(pwd):%{gopath}
-export BUILDTAGS="varlink selinux seccomp $(%{hackdir}/hack/btrfs_installed_tag.sh) $(%{hackdir}/hack/btrfs_tag.sh) $(%{hackdir}/hack/libdm_tag.sh) exclude_graphdriver_devicemapper"
+export BUILDTAGS="varlink selinux seccomp systemd $(%{hackdir}/hack/btrfs_installed_tag.sh) $(%{hackdir}/hack/btrfs_tag.sh) $(%{hackdir}/hack/libdm_tag.sh) exclude_graphdriver_devicemapper"
-GOPATH=$GOPATH go generate ./cmd/podman/varlink/...
+GOPATH=$GOPATH go generate ./pkg/varlink/...
%if %{with doc}
BUILDTAGS=$BUILDTAGS make binaries docs
@@ -410,7 +410,7 @@ mkdir -p src/%{provider}.%{provider_tld}/{containers,opencontainers}
ln -s $(dirs +1 -l) src/%{import_path_conmon}
popd
-export BUILDTAGS="selinux seccomp $(%{hackdir}/hack/btrfs_installed_tag.sh) $(%{hackdir}/hack/btrfs_tag.sh)"
+export BUILDTAGS="selinux seccomp systemd $(%{hackdir}/hack/btrfs_installed_tag.sh) $(%{hackdir}/hack/btrfs_tag.sh)"
BUILDTAGS=$BUILDTAGS make
popd
diff --git a/docs/generate.go b/docs/generate.go
index 9ab370e2c..2adca8fc1 100644
--- a/docs/generate.go
+++ b/docs/generate.go
@@ -1,3 +1,3 @@
package docs
-//go:generate go run varlink/apidoc.go ../cmd/podman/varlink/io.podman.varlink ../API.md
+//go:generate go run varlink/apidoc.go ../pkg/varlink/io.podman.varlink ../API.md
diff --git a/docs/source/markdown/podman-generate-systemd.1.md b/docs/source/markdown/podman-generate-systemd.1.md
index 27b40bbb6..57ed9a5eb 100644
--- a/docs/source/markdown/podman-generate-systemd.1.md
+++ b/docs/source/markdown/podman-generate-systemd.1.md
@@ -27,7 +27,7 @@ Use the name of the container for the start, stop, and description in the unit f
Create a new container via podman-run instead of starting an existing one. This option relies on container configuration files, which may not map directly to podman CLI flags; please review the generated output carefully before placing in production.
Since we use systemd `Type=forking` service, using this option will force the container run with the detached param `-d`
-**--timeout**, **-t**=*value*
+**--time**, **-t**=*value*
Override the default stop timeout for the container with the given value.
diff --git a/docs/source/markdown/podman-pod-stop.1.md b/docs/source/markdown/podman-pod-stop.1.md
index 42d2a2d3f..b5e7aef7d 100644
--- a/docs/source/markdown/podman-pod-stop.1.md
+++ b/docs/source/markdown/podman-pod-stop.1.md
@@ -27,7 +27,7 @@ Instead of providing the pod name or ID, stop the last created pod.
The latest option is not supported on the remote client.
-**--timeout**, **-t**=*time*
+**--time**, **-t**=*time*
Timeout to wait before forcibly stopping the containers in the pod.
diff --git a/docs/source/markdown/podman-restart.1.md b/docs/source/markdown/podman-restart.1.md
index 247d50685..87217f096 100644
--- a/docs/source/markdown/podman-restart.1.md
+++ b/docs/source/markdown/podman-restart.1.md
@@ -46,7 +46,7 @@ ff6cf1e5e77e6dba1efc7f3fcdb20e8b89ad8947bc0518be1fcb2c78681f226f
Restart two containers by name with a timeout of 4 seconds
```
-$ podman restart --timeout 4 test1 test2
+$ podman restart --time 4 test1 test2
c3bb026838c30e5097f079fa365c9a4769d52e1017588278fa00d5c68ebc1502
17e13a63081a995136f907024bcfe50ff532917988a152da229db9d894c5a9ec
```
diff --git a/docs/source/markdown/podman-stop.1.md b/docs/source/markdown/podman-stop.1.md
index 23b3415e9..1534063a5 100644
--- a/docs/source/markdown/podman-stop.1.md
+++ b/docs/source/markdown/podman-stop.1.md
@@ -9,7 +9,7 @@ podman\-stop - Stop one or more running containers
**podman container stop** [*options*] *container* ...
## DESCRIPTION
-Stops one or more containers. You may use container IDs or names as input. The **--timeout** switch
+Stops one or more containers. You may use container IDs or names as input. The **--time** switch
allows you to specify the number of seconds to wait before forcibly stopping the container after the stop command
is issued to the container. The default is 10 seconds. By default, containers are stopped with SIGTERM
and then SIGKILL after the timeout. The SIGTERM default can be overridden by the image used to create the
@@ -54,7 +54,7 @@ $ podman stop --cidfile /home/user/cidfile-1
$ podman stop --cidfile /home/user/cidfile-1 --cidfile ./cidfile-2
-$ podman stop --timeout 2 860a4b235279
+$ podman stop --time 2 860a4b235279
$ podman stop -a
diff --git a/go.mod b/go.mod
index 37207067f..8ab1eb8a6 100644
--- a/go.mod
+++ b/go.mod
@@ -11,7 +11,7 @@ require (
github.com/containernetworking/plugins v0.8.5
github.com/containers/buildah v1.14.5
github.com/containers/common v0.6.1
- github.com/containers/conmon v2.0.10+incompatible
+ github.com/containers/conmon v2.0.14+incompatible
github.com/containers/image/v5 v5.3.1
github.com/containers/psgo v1.4.0
github.com/containers/storage v1.16.6
@@ -46,7 +46,7 @@ require (
github.com/opentracing/opentracing-go v1.1.0
github.com/pkg/errors v0.9.1
github.com/pmezard/go-difflib v1.0.0
- github.com/rootless-containers/rootlesskit v0.9.2
+ github.com/rootless-containers/rootlesskit v0.9.3
github.com/seccomp/containers-golang v0.0.0-20190312124753-8ca8945ccf5f
github.com/sirupsen/logrus v1.5.0
github.com/spf13/cobra v0.0.7
diff --git a/go.sum b/go.sum
index 3a26a1e3a..ac6a4fca1 100644
--- a/go.sum
+++ b/go.sum
@@ -66,8 +66,8 @@ github.com/containers/buildah v1.14.5 h1:0Q+UgkIG4gAgAEZCu+0Syu/fSKsM1EsrctwV8G2
github.com/containers/buildah v1.14.5/go.mod h1:2rfICEnpTtrMhWF6FZLnAL1Bh7SNmjhiKrjuIo0ZuN8=
github.com/containers/common v0.6.1 h1:z9VeVXYeOnNV99uNLp7zoE5KO1n0hqz1mdm5a6AiIrA=
github.com/containers/common v0.6.1/go.mod h1:m62kenckrWi5rZx32kaLje2Og0hpf6NsaTBn6+b+Oys=
-github.com/containers/conmon v2.0.10+incompatible h1:EiwL41r5vx8SxG+dyUmbJ3baV9GUWjijPOdCkzM6gWU=
-github.com/containers/conmon v2.0.10+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
+github.com/containers/conmon v2.0.14+incompatible h1:knU1O1QxXy5YxtjMQVKEyCajROaehizK9FHaICl+P5Y=
+github.com/containers/conmon v2.0.14+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
github.com/containers/image/v5 v5.2.1/go.mod h1:TfhmLwH+v1/HBVPIWH7diLs8XwcOkP3c7t7JFgqaUEc=
github.com/containers/image/v5 v5.3.1 h1:AL0pR0d1ho3kLUAuBr+wnFlXuD3ChzKVljk0M8JBJHQ=
github.com/containers/image/v5 v5.3.1/go.mod h1:JnCfhbTIL9IxPPZm1JoQwiE0S9KET46M4OZySJsLylk=
@@ -283,6 +283,7 @@ github.com/mistifyio/go-zfs v2.1.1+incompatible h1:gAMO1HM9xBRONLHHYnu5iFsOJUiJd
github.com/mistifyio/go-zfs v2.1.1+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/moby/sys/mountinfo v0.1.0/go.mod h1:w2t2Avltqx8vE7gX5l+QiBKxODu2TX0+Syr3h52Tw4o=
github.com/moby/vpnkit v0.3.1-0.20200304131818-6bc1679a048d/go.mod h1:KyjUrL9cb6ZSNNAUwZfqRjhwwgJ3BJN+kXh0t43WTUQ=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
@@ -300,6 +301,7 @@ github.com/mtrmac/gpgme v0.1.2/go.mod h1:GYYHnGSuS7HK3zVS2n3y73y0okK/BeKzwnn5jgi
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
+github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@@ -383,6 +385,8 @@ github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uY
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rootless-containers/rootlesskit v0.9.2 h1:avrVoGuC8xdrUEwVuxGncEc46bMixvGfjyolMI4H3/U=
github.com/rootless-containers/rootlesskit v0.9.2/go.mod h1:QNzDKFGrnpXx3z7zQRu3nvK6lo9zyaR7O+WvLy6Azu4=
+github.com/rootless-containers/rootlesskit v0.9.3 h1:hrkZzBZT5vEnhAso6H1jHAcc4DT8h6/hp2z4yL0xu/8=
+github.com/rootless-containers/rootlesskit v0.9.3/go.mod h1:fx5DhInDgnR0Upj+2cOVacKuZJYSNKV5P/bCwGa+quQ=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8 h1:2c1EFnZHIPCW8qKWgHMH/fX2PkSabFc5mrVzfUNdg5U=
github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
@@ -593,6 +597,7 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
diff --git a/hack/podmanv2-retry b/hack/podmanv2-retry
new file mode 100755
index 000000000..ea77486ff
--- /dev/null
+++ b/hack/podmanv2-retry
@@ -0,0 +1,37 @@
+#!/bin/bash
+#
+# podman-try - try running a command via PODMAN1; use PODMAN2 as fallback
+#
+# Intended for use with a podmanv2 client. If a command isn't yet
+# implemented, fall back to regular podman:
+#
+# Set PODMAN_V2 to the path to a podman v2 client
+# Set PODMAN_FALLBACK to the path to regular podman
+#
+# THIS IS IMPERFECT. In particular, it will not work if stdin is redirected
+# (e.g. 'podman ... < file' or 'something | podman'); nor for anything
+# that generates continuous output ('podman logs -f'); and probably more
+# situations.
+#
+
+die() {
+ echo "$(basename $0): $*" >&2
+ exit 1
+}
+
+test -n "$PODMAN_V2" || die "Please set \$PODMAN_V2 (path to podman v2)"
+test -n "$PODMAN_FALLBACK" || die "Please set \$PODMAN_FALLBACK (path to podman)"
+
+
+result=$(${PODMAN_V2} "$@" 2>&1)
+rc=$?
+
+if [ $rc == 125 ]; then
+ if [[ "$result" =~ unrecognized\ command|unknown\ flag|unknown\ shorthand ]]; then
+ result=$(${PODMAN_FALLBACK} "$@")
+ rc=$?
+ fi
+fi
+
+echo -n "$result"
+exit $rc
diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go
index f81be8b22..729a00be8 100644
--- a/libpod/container_inspect.go
+++ b/libpod/container_inspect.go
@@ -445,9 +445,6 @@ func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, named
hostConfig.ShmSize = c.config.ShmSize
hostConfig.Runtime = "oci"
- // Default CPUShares is 1024, but we may overwrite below.
- hostConfig.CpuShares = 1024
-
// This is very expensive to initialize.
// So we don't want to initialize it unless we absolutely have to - IE,
// there are things that require a major:minor to path translation.
diff --git a/libpod/image/image.go b/libpod/image/image.go
index 5f914ed79..80cc6f15a 100644
--- a/libpod/image/image.go
+++ b/libpod/image/image.go
@@ -512,8 +512,8 @@ func getImageDigest(ctx context.Context, src types.ImageReference, sc *types.Sys
return "@" + imageDigest.Hex(), nil
}
-// normalizedTag returns the canonical version of tag for use in Image.Names()
-func normalizedTag(tag string) (reference.Named, error) {
+// NormalizedTag returns the canonical version of tag for use in Image.Names()
+func NormalizedTag(tag string) (reference.Named, error) {
decomposedTag, err := decompose(tag)
if err != nil {
return nil, err
@@ -541,7 +541,7 @@ func (i *Image) TagImage(tag string) error {
if err := i.reloadImage(); err != nil {
return err
}
- ref, err := normalizedTag(tag)
+ ref, err := NormalizedTag(tag)
if err != nil {
return err
}
diff --git a/libpod/image/image_test.go b/libpod/image/image_test.go
index 19f7eee1e..3cd368cdc 100644
--- a/libpod/image/image_test.go
+++ b/libpod/image/image_test.go
@@ -292,7 +292,7 @@ func TestNormalizedTag(t *testing.T) {
{"ns/busybox:latest", "localhost/ns/busybox:latest"}, // Unqualified with a dot-less namespace
{"docker.io/busybox:latest", "docker.io/library/busybox:latest"}, // docker.io without /library/
} {
- res, err := normalizedTag(c.input)
+ res, err := NormalizedTag(c.input)
if c.expected == "" {
assert.Error(t, err, c.input)
} else {
diff --git a/libpod/podfilters/pods.go b/libpod/podfilters/pods.go
new file mode 100644
index 000000000..54fa85edc
--- /dev/null
+++ b/libpod/podfilters/pods.go
@@ -0,0 +1,115 @@
+package podfilters
+
+import (
+ "strconv"
+ "strings"
+
+ "github.com/containers/libpod/libpod"
+ "github.com/containers/libpod/libpod/define"
+ "github.com/containers/libpod/pkg/util"
+ "github.com/pkg/errors"
+)
+
+// GeneratePodFilterFunc takes a filter and filtervalue (key, value)
+// and generates a libpod function that can be used to filter
+// pods
+func GeneratePodFilterFunc(filter, filterValue string) (
+ func(pod *libpod.Pod) bool, error) {
+ switch filter {
+ case "ctr-ids":
+ return func(p *libpod.Pod) bool {
+ ctrIds, err := p.AllContainersByID()
+ if err != nil {
+ return false
+ }
+ return util.StringInSlice(filterValue, ctrIds)
+ }, nil
+ case "ctr-names":
+ return func(p *libpod.Pod) bool {
+ ctrs, err := p.AllContainers()
+ if err != nil {
+ return false
+ }
+ for _, ctr := range ctrs {
+ if filterValue == ctr.Name() {
+ return true
+ }
+ }
+ return false
+ }, nil
+ case "ctr-number":
+ return func(p *libpod.Pod) bool {
+ ctrIds, err := p.AllContainersByID()
+ if err != nil {
+ return false
+ }
+
+ fVint, err2 := strconv.Atoi(filterValue)
+ if err2 != nil {
+ return false
+ }
+ return len(ctrIds) == fVint
+ }, nil
+ case "ctr-status":
+ if !util.StringInSlice(filterValue,
+ []string{"created", "restarting", "running", "paused",
+ "exited", "unknown"}) {
+ return nil, errors.Errorf("%s is not a valid status", filterValue)
+ }
+ return func(p *libpod.Pod) bool {
+ ctr_statuses, err := p.Status()
+ if err != nil {
+ return false
+ }
+ for _, ctr_status := range ctr_statuses {
+ state := ctr_status.String()
+ if ctr_status == define.ContainerStateConfigured {
+ state = "created"
+ }
+ if state == filterValue {
+ return true
+ }
+ }
+ return false
+ }, nil
+ case "id":
+ return func(p *libpod.Pod) bool {
+ return strings.Contains(p.ID(), filterValue)
+ }, nil
+ case "name":
+ return func(p *libpod.Pod) bool {
+ return strings.Contains(p.Name(), filterValue)
+ }, nil
+ case "status":
+ if !util.StringInSlice(filterValue, []string{"stopped", "running", "paused", "exited", "dead", "created"}) {
+ return nil, errors.Errorf("%s is not a valid pod status", filterValue)
+ }
+ return func(p *libpod.Pod) bool {
+ status, err := p.GetPodStatus()
+ if err != nil {
+ return false
+ }
+ if strings.ToLower(status) == filterValue {
+ return true
+ }
+ return false
+ }, nil
+ case "label":
+ var filterArray = strings.SplitN(filterValue, "=", 2)
+ var filterKey = filterArray[0]
+ if len(filterArray) > 1 {
+ filterValue = filterArray[1]
+ } else {
+ filterValue = ""
+ }
+ return func(p *libpod.Pod) bool {
+ for labelKey, labelValue := range p.Labels() {
+ if labelKey == filterKey && ("" == filterValue || labelValue == filterValue) {
+ return true
+ }
+ }
+ return false
+ }, nil
+ }
+ return nil, errors.Errorf("%s is an invalid filter", filter)
+}
diff --git a/pkg/adapter/containers.go b/pkg/adapter/containers.go
index a2f73307b..c395ffc7f 100644
--- a/pkg/adapter/containers.go
+++ b/pkg/adapter/containers.go
@@ -1213,8 +1213,8 @@ func (r *LocalRuntime) generateSystemdgenContainerInfo(c *cliconfig.GenerateSyst
return nil, false, err
}
- timeout := int(ctr.StopTimeout())
- if c.StopTimeout >= 0 {
+ timeout := ctr.StopTimeout()
+ if c.Flags().Changed("timeout") || c.Flags().Changed("time") {
timeout = c.StopTimeout
}
diff --git a/pkg/adapter/containers_remote.go b/pkg/adapter/containers_remote.go
index 46db7ebe8..fc8b524d6 100644
--- a/pkg/adapter/containers_remote.go
+++ b/pkg/adapter/containers_remote.go
@@ -15,11 +15,11 @@ import (
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/cmd/podman/shared"
- iopodman "github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/libpod/logs"
envLib "github.com/containers/libpod/pkg/env"
+ iopodman "github.com/containers/libpod/pkg/varlink"
"github.com/containers/libpod/pkg/varlinkapi/virtwriter"
"github.com/cri-o/ocicni/pkg/ocicni"
"github.com/docker/docker/pkg/term"
diff --git a/pkg/adapter/errors.go b/pkg/adapter/errors.go
index ede3d4b1a..012d01d39 100644
--- a/pkg/adapter/errors.go
+++ b/pkg/adapter/errors.go
@@ -3,8 +3,8 @@
package adapter
import (
- iopodman "github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/libpod/define"
+ iopodman "github.com/containers/libpod/pkg/varlink"
"github.com/pkg/errors"
)
diff --git a/pkg/adapter/images_remote.go b/pkg/adapter/images_remote.go
index e7b38dccc..2df0ffcde 100644
--- a/pkg/adapter/images_remote.go
+++ b/pkg/adapter/images_remote.go
@@ -6,8 +6,8 @@ import (
"context"
"encoding/json"
- iopodman "github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/pkg/inspect"
+ iopodman "github.com/containers/libpod/pkg/varlink"
)
// Inspect returns returns an ImageData struct from over a varlink connection
diff --git a/pkg/adapter/info_remote.go b/pkg/adapter/info_remote.go
index c55d1f6ef..0e8fb06d1 100644
--- a/pkg/adapter/info_remote.go
+++ b/pkg/adapter/info_remote.go
@@ -4,9 +4,9 @@ package adapter
import (
"encoding/json"
- "github.com/containers/libpod/libpod/define"
- "github.com/containers/libpod/cmd/podman/varlink"
+ "github.com/containers/libpod/libpod/define"
+ iopodman "github.com/containers/libpod/pkg/varlink"
)
// Info returns information for the host system and its components
diff --git a/pkg/adapter/pods_remote.go b/pkg/adapter/pods_remote.go
index 6b8f22f15..ebd10a92a 100644
--- a/pkg/adapter/pods_remote.go
+++ b/pkg/adapter/pods_remote.go
@@ -10,9 +10,9 @@ import (
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/cmd/podman/shared"
- iopodman "github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/define"
+ iopodman "github.com/containers/libpod/pkg/varlink"
"github.com/containers/libpod/pkg/varlinkapi"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
diff --git a/pkg/adapter/reset_remote.go b/pkg/adapter/reset_remote.go
index 663fab639..284b54a17 100644
--- a/pkg/adapter/reset_remote.go
+++ b/pkg/adapter/reset_remote.go
@@ -3,7 +3,7 @@
package adapter
import (
- "github.com/containers/libpod/cmd/podman/varlink"
+ iopodman "github.com/containers/libpod/pkg/varlink"
)
// Info returns information for the host system and its components
diff --git a/pkg/adapter/runtime_remote.go b/pkg/adapter/runtime_remote.go
index a616e6c7a..a4ac660ea 100644
--- a/pkg/adapter/runtime_remote.go
+++ b/pkg/adapter/runtime_remote.go
@@ -22,12 +22,12 @@ import (
"github.com/containers/image/v5/types"
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/cmd/podman/remoteclientconfig"
- iopodman "github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/libpod/events"
"github.com/containers/libpod/libpod/image"
"github.com/containers/libpod/pkg/util"
+ iopodman "github.com/containers/libpod/pkg/varlink"
"github.com/containers/libpod/utils"
"github.com/containers/storage/pkg/archive"
"github.com/opencontainers/go-digest"
diff --git a/pkg/api/handlers/compat/containers_export.go b/pkg/api/handlers/compat/containers_export.go
new file mode 100644
index 000000000..37b9fbf2b
--- /dev/null
+++ b/pkg/api/handlers/compat/containers_export.go
@@ -0,0 +1,42 @@
+package compat
+
+import (
+ "io/ioutil"
+ "net/http"
+ "os"
+
+ "github.com/containers/libpod/libpod"
+ "github.com/containers/libpod/pkg/api/handlers/utils"
+ "github.com/pkg/errors"
+)
+
+func ExportContainer(w http.ResponseWriter, r *http.Request) {
+ runtime := r.Context().Value("runtime").(*libpod.Runtime)
+ name := utils.GetName(r)
+ con, err := runtime.LookupContainer(name)
+ if err != nil {
+ utils.ContainerNotFound(w, name, err)
+ return
+ }
+ tmpfile, err := ioutil.TempFile("", "api.tar")
+ if err != nil {
+ utils.Error(w, "unable to create tarball tempfile", http.StatusInternalServerError, errors.Wrap(err, "unable to create tempfile"))
+ return
+ }
+ defer os.Remove(tmpfile.Name())
+ if err := tmpfile.Close(); err != nil {
+ utils.Error(w, "unable to close tempfile", http.StatusInternalServerError, errors.Wrap(err, "unable to close tempfile"))
+ return
+ }
+ if err := con.Export(tmpfile.Name()); err != nil {
+ utils.Error(w, "failed to save the image", http.StatusInternalServerError, errors.Wrap(err, "failed to save image"))
+ return
+ }
+ rdr, err := os.Open(tmpfile.Name())
+ if err != nil {
+ utils.Error(w, "failed to read temp tarball", http.StatusInternalServerError, errors.Wrap(err, "failed to read the exported tarfile"))
+ return
+ }
+ defer rdr.Close()
+ utils.WriteResponse(w, http.StatusOK, rdr)
+}
diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go
index 4b24d7d9f..d4fd77cd7 100644
--- a/pkg/api/handlers/libpod/images.go
+++ b/pkg/api/handlers/libpod/images.go
@@ -254,7 +254,7 @@ func ImagesLoad(w http.ResponseWriter, r *http.Request) {
return
}
}
- utils.WriteResponse(w, http.StatusOK, handlers.LibpodImagesLoadReport{ID: loadedImage})
+ utils.WriteResponse(w, http.StatusOK, entities.ImageLoadReport{Name: loadedImage})
}
func ImagesImport(w http.ResponseWriter, r *http.Request) {
@@ -300,9 +300,13 @@ func ImagesImport(w http.ResponseWriter, r *http.Request) {
return
}
- utils.WriteResponse(w, http.StatusOK, handlers.LibpodImagesImportReport{ID: importedImage})
+ utils.WriteResponse(w, http.StatusOK, entities.ImageImportReport{Id: importedImage})
}
+// ImagesPull is the v2 libpod endpoint for pulling images. Note that the
+// mandatory `reference` must be a reference to a registry (i.e., of docker
+// transport or be normalized to one). Other transports are rejected as they
+// do not make sense in a remote context.
func ImagesPull(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
decoder := r.Context().Value("decoder").(*schema.Decoder)
@@ -328,10 +332,11 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) {
return
}
// Enforce the docker transport. This is just a precaution as some callers
- // might accustomed to using the "transport:reference" notation. Using
+ // might be accustomed to using the "transport:reference" notation. Using
// another than the "docker://" transport does not really make sense for a
// remote case. For loading tarballs, the load and import endpoints should
// be used.
+ dockerPrefix := fmt.Sprintf("%s://", docker.Transport.Name())
imageRef, err := alltransports.ParseImageName(query.Reference)
if err == nil && imageRef.Transport().Name() != docker.Transport.Name() {
utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
@@ -339,7 +344,7 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) {
return
} else if err != nil {
origErr := err
- imageRef, err = alltransports.ParseImageName(fmt.Sprintf("%s://%s", docker.Transport.Name(), query.Reference))
+ imageRef, err = alltransports.ParseImageName(fmt.Sprintf("%s%s", dockerPrefix, query.Reference))
if err != nil {
utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
errors.Wrapf(origErr, "reference %q must be a docker reference", query.Reference))
@@ -347,16 +352,19 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) {
}
}
+ // Trim the docker-transport prefix.
+ rawImage := strings.TrimPrefix(query.Reference, dockerPrefix)
+
// all-tags doesn't work with a tagged reference, so let's check early
- namedRef, err := reference.Parse(query.Reference)
+ namedRef, err := reference.Parse(rawImage)
if err != nil {
utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
- errors.Wrapf(err, "error parsing reference %q", query.Reference))
+ errors.Wrapf(err, "error parsing reference %q", rawImage))
return
}
if _, isTagged := namedRef.(reference.Tagged); isTagged && query.AllTags {
utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
- errors.Errorf("reference %q must not have a tag for all-tags", query.Reference))
+ errors.Errorf("reference %q must not have a tag for all-tags", rawImage))
return
}
@@ -502,3 +510,29 @@ func CommitContainer(w http.ResponseWriter, r *http.Request) {
}
utils.WriteResponse(w, http.StatusOK, handlers.IDResponse{ID: commitImage.ID()}) // nolint
}
+
+func UntagImage(w http.ResponseWriter, r *http.Request) {
+ runtime := r.Context().Value("runtime").(*libpod.Runtime)
+
+ name := utils.GetName(r)
+ newImage, err := runtime.ImageRuntime().NewFromLocal(name)
+ if err != nil {
+ utils.ImageNotFound(w, name, errors.Wrapf(err, "Failed to find image %s", name))
+ return
+ }
+ tag := "latest"
+ if len(r.Form.Get("tag")) > 0 {
+ tag = r.Form.Get("tag")
+ }
+ if len(r.Form.Get("repo")) < 1 {
+ utils.Error(w, "repo tag is required", http.StatusBadRequest, errors.New("repo parameter is required to tag an image"))
+ return
+ }
+ repo := r.Form.Get("repo")
+ tagName := fmt.Sprintf("%s:%s", repo, tag)
+ if err := newImage.UntagImage(tagName); err != nil {
+ utils.Error(w, "failed to untag", http.StatusInternalServerError, err)
+ return
+ }
+ utils.WriteResponse(w, http.StatusCreated, "")
+}
diff --git a/pkg/api/handlers/swagger.go b/pkg/api/handlers/swagger.go
index 52763a050..33a9fdd58 100644
--- a/pkg/api/handlers/swagger.go
+++ b/pkg/api/handlers/swagger.go
@@ -31,14 +31,14 @@ type swagImageInspect struct {
// swagger:response DocsLibpodImagesLoadResponse
type swagLibpodImagesLoadResponse struct {
// in:body
- Body []LibpodImagesLoadReport
+ Body entities.ImageLoadReport
}
// Import response
// swagger:response DocsLibpodImagesImportResponse
type swagLibpodImagesImportResponse struct {
// in:body
- Body LibpodImagesImportReport
+ Body entities.ImageImportReport
}
// Pull response
diff --git a/pkg/api/handlers/types.go b/pkg/api/handlers/types.go
index 89a571e67..496512f2e 100644
--- a/pkg/api/handlers/types.go
+++ b/pkg/api/handlers/types.go
@@ -38,10 +38,6 @@ type LibpodImagesLoadReport struct {
ID string `json:"id"`
}
-type LibpodImagesImportReport struct {
- ID string `json:"id"`
-}
-
type LibpodImagesPullReport struct {
ID string `json:"id"`
}
diff --git a/pkg/api/handlers/utils/pods.go b/pkg/api/handlers/utils/pods.go
index 79d1a5090..d47053eda 100644
--- a/pkg/api/handlers/utils/pods.go
+++ b/pkg/api/handlers/utils/pods.go
@@ -59,6 +59,10 @@ func GetPods(w http.ResponseWriter, r *http.Request) ([]*entities.ListPodsReport
if err != nil {
return nil, err
}
+ infraId, err := pod.InfraContainerID()
+ if err != nil {
+ return nil, err
+ }
lp := entities.ListPodsReport{
Cgroup: pod.CgroupParent(),
Created: pod.CreatedTime(),
@@ -66,6 +70,7 @@ func GetPods(w http.ResponseWriter, r *http.Request) ([]*entities.ListPodsReport
Name: pod.Name(),
Namespace: pod.Namespace(),
Status: status,
+ InfraId: infraId,
}
for _, ctr := range ctrs {
state, err := ctr.State()
diff --git a/pkg/api/server/register_containers.go b/pkg/api/server/register_containers.go
index 08834ff01..145c054c0 100644
--- a/pkg/api/server/register_containers.go
+++ b/pkg/api/server/register_containers.go
@@ -587,6 +587,29 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error {
r.HandleFunc(VersionedPath("/containers/{name}/resize"), s.APIHandler(compat.ResizeContainer)).Methods(http.MethodPost)
// Added non version path to URI to support docker non versioned paths
r.HandleFunc("/containers/{name}/resize", s.APIHandler(compat.ResizeContainer)).Methods(http.MethodPost)
+ // swagger:operation GET /containers/{name}/export compat exportContainer
+ // ---
+ // tags:
+ // - containers (compat)
+ // summary: Export a container
+ // description: Export the contents of a container as a tarball.
+ // parameters:
+ // - in: path
+ // name: name
+ // type: string
+ // required: true
+ // description: the name or ID of the container
+ // produces:
+ // - application/json
+ // responses:
+ // 200:
+ // description: tarball is returned in body
+ // 404:
+ // $ref: "#/responses/NoSuchContainer"
+ // 500:
+ // $ref: "#/responses/InternalError"
+ r.HandleFunc(VersionedPath("/containers/{name}/export"), s.APIHandler(compat.ExportContainer)).Methods(http.MethodGet)
+ r.HandleFunc("/containers/{name}/export", s.APIHandler(compat.ExportContainer)).Methods(http.MethodGet)
/*
libpod endpoints
@@ -1237,5 +1260,27 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error {
// 500:
// $ref: "#/responses/InternalError"
r.HandleFunc(VersionedPath("/libpod/containers/{name}/resize"), s.APIHandler(compat.ResizeContainer)).Methods(http.MethodPost)
+ // swagger:operation GET /libpod/containers/{name}/export libpod libpodExportContainer
+ // ---
+ // tags:
+ // - containers
+ // summary: Export a container
+ // description: Export the contents of a container as a tarball.
+ // parameters:
+ // - in: path
+ // name: name
+ // type: string
+ // required: true
+ // description: the name or ID of the container
+ // produces:
+ // - application/json
+ // responses:
+ // 200:
+ // description: tarball is returned in body
+ // 404:
+ // $ref: "#/responses/NoSuchContainer"
+ // 500:
+ // $ref: "#/responses/InternalError"
+ r.HandleFunc(VersionedPath("/libpod/containers/{name}/export"), s.APIHandler(compat.ExportContainer)).Methods(http.MethodGet)
return nil
}
diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go
index e8dfe2fa8..74b245a77 100644
--- a/pkg/api/server/register_images.go
+++ b/pkg/api/server/register_images.go
@@ -1019,5 +1019,39 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// 500:
// $ref: '#/responses/InternalError'
r.Handle(VersionedPath("/libpod/commit"), s.APIHandler(libpod.CommitContainer)).Methods(http.MethodPost)
+ // swagger:operation POST /libpod/images/{name:.*}/untag libpod libpodUntagImage
+ // ---
+ // tags:
+ // - images
+ // summary: Untag an image
+ // description: Untag an image
+ // parameters:
+ // - in: path
+ // name: name:.*
+ // type: string
+ // required: true
+ // description: the name or ID of the container
+ // - in: query
+ // name: repo
+ // type: string
+ // description: the repository to untag
+ // - in: query
+ // name: tag
+ // type: string
+ // description: the name of the tag to untag
+ // produces:
+ // - application/json
+ // responses:
+ // 201:
+ // description: no error
+ // 400:
+ // $ref: '#/responses/BadParamError'
+ // 404:
+ // $ref: '#/responses/NoSuchImage'
+ // 409:
+ // $ref: '#/responses/ConflictError'
+ // 500:
+ // $ref: '#/responses/InternalError'
+ r.Handle(VersionedPath("/libpod/images/{name:.*}/untag"), s.APIHandler(libpod.UntagImage)).Methods(http.MethodPost)
return nil
}
diff --git a/pkg/bindings/containers/containers.go b/pkg/bindings/containers/containers.go
index bad1294f4..49a2dfd58 100644
--- a/pkg/bindings/containers/containers.go
+++ b/pkg/bindings/containers/containers.go
@@ -2,6 +2,7 @@ package containers
import (
"context"
+ "io"
"net/http"
"net/url"
"strconv"
@@ -296,3 +297,22 @@ func Stop(ctx context.Context, nameOrID string, timeout *uint) error {
}
return response.Process(nil)
}
+
+// Export creates a tarball of the given name or ID of a container. It
+// requires an io.Writer be provided to write the tarball.
+func Export(ctx context.Context, nameOrID string, w io.Writer) error {
+ params := url.Values{}
+ conn, err := bindings.GetClient(ctx)
+ if err != nil {
+ return err
+ }
+ response, err := conn.DoRequest(nil, http.MethodGet, "/containers/%s/export", params, nameOrID)
+ if err != nil {
+ return err
+ }
+ if response.StatusCode/100 == 2 {
+ _, err = io.Copy(w, response.Body)
+ return err
+ }
+ return response.Process(nil)
+}
diff --git a/pkg/bindings/images/images.go b/pkg/bindings/images/images.go
index 5e3af7a60..470ce546c 100644
--- a/pkg/bindings/images/images.go
+++ b/pkg/bindings/images/images.go
@@ -8,10 +8,10 @@ import (
"net/url"
"strconv"
+ "github.com/containers/image/v5/types"
"github.com/containers/libpod/pkg/api/handlers"
"github.com/containers/libpod/pkg/bindings"
"github.com/containers/libpod/pkg/domain/entities"
- "github.com/containers/libpod/pkg/inspect"
)
// Exists a lightweight way to determine if an image exists in local storage. It returns a
@@ -56,7 +56,7 @@ func List(ctx context.Context, all *bool, filters map[string][]string) ([]*entit
// Get performs an image inspect. To have the on-disk size of the image calculated, you can
// use the optional size parameter.
-func GetImage(ctx context.Context, nameOrID string, size *bool) (*inspect.ImageData, error) {
+func GetImage(ctx context.Context, nameOrID string, size *bool) (*entities.ImageData, error) {
conn, err := bindings.GetClient(ctx)
if err != nil {
return nil, err
@@ -65,7 +65,7 @@ func GetImage(ctx context.Context, nameOrID string, size *bool) (*inspect.ImageD
if size != nil {
params.Set("size", strconv.FormatBool(*size))
}
- inspectedData := inspect.ImageData{}
+ inspectedData := entities.ImageData{}
response, err := conn.DoRequest(nil, http.MethodGet, "/images/%s/json", params, nameOrID)
if err != nil {
return &inspectedData, err
@@ -91,11 +91,11 @@ func History(ctx context.Context, nameOrID string) ([]*handlers.HistoryResponse,
return history, response.Process(&history)
}
-func Load(ctx context.Context, r io.Reader, name *string) (string, error) {
- var id handlers.IDResponse
+func Load(ctx context.Context, r io.Reader, name *string) (*entities.ImageLoadReport, error) {
+ var report entities.ImageLoadReport
conn, err := bindings.GetClient(ctx)
if err != nil {
- return "", err
+ return nil, err
}
params := url.Values{}
if name != nil {
@@ -103,9 +103,9 @@ func Load(ctx context.Context, r io.Reader, name *string) (string, error) {
}
response, err := conn.DoRequest(r, http.MethodPost, "/images/load", params)
if err != nil {
- return "", err
+ return nil, err
}
- return id.ID, response.Process(&id)
+ return &report, response.Process(&report)
}
// Remove deletes an image from local storage. The optional force parameter will forcibly remove
@@ -196,19 +196,35 @@ func Tag(ctx context.Context, nameOrID, tag, repo string) error {
return response.Process(nil)
}
+// Untag removes a name from locally-stored image. Both the tag and repo parameters are required.
+func Untag(ctx context.Context, nameOrID, tag, repo string) error {
+ conn, err := bindings.GetClient(ctx)
+ if err != nil {
+ return err
+ }
+ params := url.Values{}
+ params.Set("tag", tag)
+ params.Set("repo", repo)
+ response, err := conn.DoRequest(nil, http.MethodPost, "/images/%s/untag", params, nameOrID)
+ if err != nil {
+ return err
+ }
+ return response.Process(nil)
+}
+
func Build(nameOrId string) {}
// Imports adds the given image to the local image store. This can be done by file and the given reader
// or via the url parameter. Additional metadata can be associated with the image by using the changes and
// message parameters. The image can also be tagged given a reference. One of url OR r must be provided.
-func Import(ctx context.Context, changes []string, message, reference, u *string, r io.Reader) (string, error) {
- var id handlers.IDResponse
+func Import(ctx context.Context, changes []string, message, reference, u *string, r io.Reader) (*entities.ImageImportReport, error) {
+ var report entities.ImageImportReport
if r != nil && u != nil {
- return "", errors.New("url and r parameters cannot be used together")
+ return nil, errors.New("url and r parameters cannot be used together")
}
conn, err := bindings.GetClient(ctx)
if err != nil {
- return "", err
+ return nil, err
}
params := url.Values{}
for _, change := range changes {
@@ -225,7 +241,45 @@ func Import(ctx context.Context, changes []string, message, reference, u *string
}
response, err := conn.DoRequest(r, http.MethodPost, "/images/import", params)
if err != nil {
- return "", err
+ return nil, err
+ }
+ return &report, response.Process(&report)
+}
+
+// Pull is the binding for libpod's v2 endpoints for pulling images. Note that
+// `rawImage` must be a reference to a registry (i.e., of docker transport or be
+// normalized to one). Other transports are rejected as they do not make sense
+// in a remote context.
+func Pull(ctx context.Context, rawImage string, options entities.ImagePullOptions) ([]string, error) {
+ conn, err := bindings.GetClient(ctx)
+ if err != nil {
+ return nil, err
}
- return id.ID, response.Process(&id)
+ params := url.Values{}
+ params.Set("reference", rawImage)
+ params.Set("credentials", options.Credentials)
+ params.Set("overrideArch", options.OverrideArch)
+ params.Set("overrideOS", options.OverrideOS)
+ if options.TLSVerify != types.OptionalBoolUndefined {
+ val := bool(options.TLSVerify == types.OptionalBoolTrue)
+ params.Set("tlsVerify", strconv.FormatBool(val))
+ }
+ params.Set("allTags", strconv.FormatBool(options.AllTags))
+
+ response, err := conn.DoRequest(nil, http.MethodPost, "/images/pull", params)
+ if err != nil {
+ return nil, err
+ }
+
+ reports := []handlers.LibpodImagesPullReport{}
+ if err := response.Process(&reports); err != nil {
+ return nil, err
+ }
+
+ pulledImages := []string{}
+ for _, r := range reports {
+ pulledImages = append(pulledImages, r.ID)
+ }
+
+ return pulledImages, nil
}
diff --git a/pkg/bindings/test/images_test.go b/pkg/bindings/test/images_test.go
index 13b6086c3..992720196 100644
--- a/pkg/bindings/test/images_test.go
+++ b/pkg/bindings/test/images_test.go
@@ -9,6 +9,7 @@ import (
"github.com/containers/libpod/pkg/bindings"
"github.com/containers/libpod/pkg/bindings/containers"
"github.com/containers/libpod/pkg/bindings/images"
+ "github.com/containers/libpod/pkg/domain/entities"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gexec"
@@ -218,7 +219,7 @@ var _ = Describe("Podman images", func() {
Expect(err).To(BeNil())
names, err := images.Load(bt.conn, f, nil)
Expect(err).To(BeNil())
- Expect(names).To(Equal(alpine.name))
+ Expect(names.Name).To(Equal(alpine.name))
exists, err = images.Exists(bt.conn, alpine.name)
Expect(err).To(BeNil())
Expect(exists).To(BeTrue())
@@ -234,7 +235,7 @@ var _ = Describe("Podman images", func() {
newName := "quay.io/newname:fizzle"
names, err = images.Load(bt.conn, f, &newName)
Expect(err).To(BeNil())
- Expect(names).To(Equal(alpine.name))
+ Expect(names.Name).To(Equal(alpine.name))
exists, err = images.Exists(bt.conn, newName)
Expect(err).To(BeNil())
Expect(exists).To(BeTrue())
@@ -353,4 +354,24 @@ var _ = Describe("Podman images", func() {
Expect(results).To(ContainElement("docker.io/library/alpine:latest"))
})
+ // TODO: we really need to extent to pull tests once we have a more sophisticated CI.
+ It("Image Pull", func() {
+ rawImage := "docker.io/library/busybox:latest"
+
+ pulledImages, err := images.Pull(bt.conn, rawImage, entities.ImagePullOptions{})
+ Expect(err).To(BeNil())
+ Expect(len(pulledImages)).To(Equal(1))
+
+ exists, err := images.Exists(bt.conn, rawImage)
+ Expect(err).To(BeNil())
+ Expect(exists).To(BeTrue())
+
+ // Make sure the normalization AND the full-transport reference works.
+ _, err = images.Pull(bt.conn, "docker://"+rawImage, entities.ImagePullOptions{})
+ Expect(err).To(BeNil())
+
+ // The v2 endpoint only supports the docker transport. Let's see if that's really true.
+ _, err = images.Pull(bt.conn, "bogus-transport:bogus.com/image:reference", entities.ImagePullOptions{})
+ Expect(err).To(Not(BeNil()))
+ })
})
diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go
index 3389e4db5..d51124f55 100644
--- a/pkg/domain/entities/containers.go
+++ b/pkg/domain/entities/containers.go
@@ -98,12 +98,6 @@ type RmReport struct {
Id string
}
-type ContainerInspectOptions struct {
- Format string
- Latest bool
- Size bool
-}
-
type ContainerInspectReport struct {
*define.InspectContainerData
}
@@ -123,3 +117,7 @@ type CommitOptions struct {
type CommitReport struct {
Id string
}
+
+type ContainerExportOptions struct {
+ Output string
+}
diff --git a/pkg/domain/entities/engine_container.go b/pkg/domain/entities/engine_container.go
index dddaa6013..a122857cd 100644
--- a/pkg/domain/entities/engine_container.go
+++ b/pkg/domain/entities/engine_container.go
@@ -2,34 +2,38 @@ package entities
import (
"context"
+
+ "github.com/containers/libpod/libpod/define"
)
type ContainerEngine interface {
ContainerCommit(ctx context.Context, nameOrId string, options CommitOptions) (*CommitReport, error)
ContainerExists(ctx context.Context, nameOrId string) (*BoolReport, error)
- ContainerInspect(ctx context.Context, namesOrIds []string, options ContainerInspectOptions) ([]*ContainerInspectReport, error)
+ ContainerInspect(ctx context.Context, namesOrIds []string, options InspectOptions) ([]*ContainerInspectReport, error)
+ ContainerExport(ctx context.Context, nameOrId string, options ContainerExportOptions) error
ContainerKill(ctx context.Context, namesOrIds []string, options KillOptions) ([]*KillReport, error)
ContainerPause(ctx context.Context, namesOrIds []string, options PauseUnPauseOptions) ([]*PauseUnpauseReport, error)
ContainerRestart(ctx context.Context, namesOrIds []string, options RestartOptions) ([]*RestartReport, error)
ContainerRm(ctx context.Context, namesOrIds []string, options RmOptions) ([]*RmReport, error)
- ContainerUnpause(ctx context.Context, namesOrIds []string, options PauseUnPauseOptions) ([]*PauseUnpauseReport, error)
ContainerStop(ctx context.Context, namesOrIds []string, options StopOptions) ([]*StopReport, error)
- ContainerWait(ctx context.Context, namesOrIds []string, options WaitOptions) ([]WaitReport, error)
ContainerTop(ctx context.Context, options TopOptions) (*StringSliceReport, error)
+ ContainerUnpause(ctx context.Context, namesOrIds []string, options PauseUnPauseOptions) ([]*PauseUnpauseReport, error)
+ ContainerWait(ctx context.Context, namesOrIds []string, options WaitOptions) ([]WaitReport, error)
+ HealthCheckRun(ctx context.Context, nameOrId string, options HealthCheckOptions) (*define.HealthCheckResults, error)
PodCreate(ctx context.Context, opts PodCreateOptions) (*PodCreateReport, error)
PodExists(ctx context.Context, nameOrId string) (*BoolReport, error)
PodKill(ctx context.Context, namesOrIds []string, options PodKillOptions) ([]*PodKillReport, error)
PodPause(ctx context.Context, namesOrIds []string, options PodPauseOptions) ([]*PodPauseReport, error)
+ PodPs(ctx context.Context, options PodPSOptions) ([]*ListPodsReport, error)
PodRestart(ctx context.Context, namesOrIds []string, options PodRestartOptions) ([]*PodRestartReport, error)
+ PodRm(ctx context.Context, namesOrIds []string, options PodRmOptions) ([]*PodRmReport, error)
PodStart(ctx context.Context, namesOrIds []string, options PodStartOptions) ([]*PodStartReport, error)
PodStop(ctx context.Context, namesOrIds []string, options PodStopOptions) ([]*PodStopReport, error)
- PodRm(ctx context.Context, namesOrIds []string, options PodRmOptions) ([]*PodRmReport, error)
- PodUnpause(ctx context.Context, namesOrIds []string, options PodunpauseOptions) ([]*PodUnpauseReport, error)
PodTop(ctx context.Context, options PodTopOptions) (*StringSliceReport, error)
-
+ PodUnpause(ctx context.Context, namesOrIds []string, options PodunpauseOptions) ([]*PodUnpauseReport, error)
VolumeCreate(ctx context.Context, opts VolumeCreateOptions) (*IdOrNameResponse, error)
VolumeInspect(ctx context.Context, namesOrIds []string, opts VolumeInspectOptions) ([]*VolumeInspectReport, error)
- VolumeRm(ctx context.Context, namesOrIds []string, opts VolumeRmOptions) ([]*VolumeRmReport, error)
- VolumePrune(ctx context.Context, opts VolumePruneOptions) ([]*VolumePruneReport, error)
VolumeList(ctx context.Context, opts VolumeListOptions) ([]*VolumeListReport, error)
+ VolumePrune(ctx context.Context, opts VolumePruneOptions) ([]*VolumePruneReport, error)
+ VolumeRm(ctx context.Context, namesOrIds []string, opts VolumeRmOptions) ([]*VolumeRmReport, error)
}
diff --git a/pkg/domain/entities/engine_image.go b/pkg/domain/entities/engine_image.go
index d0c860a04..ac856c05f 100644
--- a/pkg/domain/entities/engine_image.go
+++ b/pkg/domain/entities/engine_image.go
@@ -8,6 +8,12 @@ type ImageEngine interface {
Delete(ctx context.Context, nameOrId []string, opts ImageDeleteOptions) (*ImageDeleteReport, error)
Exists(ctx context.Context, nameOrId string) (*BoolReport, error)
History(ctx context.Context, nameOrId string, opts ImageHistoryOptions) (*ImageHistoryReport, error)
+ Inspect(ctx context.Context, names []string, opts InspectOptions) (*ImageInspectReport, error)
List(ctx context.Context, opts ImageListOptions) ([]*ImageSummary, error)
Prune(ctx context.Context, opts ImagePruneOptions) (*ImagePruneReport, error)
+ Pull(ctx context.Context, rawImage string, opts ImagePullOptions) (*ImagePullReport, error)
+ Tag(ctx context.Context, nameOrId string, tags []string, options ImageTagOptions) error
+ Untag(ctx context.Context, nameOrId string, tags []string, options ImageUntagOptions) error
+ Load(ctx context.Context, opts ImageLoadOptions) (*ImageLoadReport, error)
+ Import(ctx context.Context, opts ImageImportOptions) (*ImageImportReport, error)
}
diff --git a/pkg/domain/entities/healthcheck.go b/pkg/domain/entities/healthcheck.go
new file mode 100644
index 000000000..a880805f9
--- /dev/null
+++ b/pkg/domain/entities/healthcheck.go
@@ -0,0 +1,3 @@
+package entities
+
+type HealthCheckOptions struct{}
diff --git a/pkg/domain/entities/images.go b/pkg/domain/entities/images.go
index 20af0356f..d136f42fd 100644
--- a/pkg/domain/entities/images.go
+++ b/pkg/domain/entities/images.go
@@ -4,6 +4,8 @@ import (
"net/url"
"github.com/containers/image/v5/manifest"
+ "github.com/containers/image/v5/types"
+ "github.com/containers/libpod/pkg/inspect"
docker "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/opencontainers/go-digest"
@@ -11,7 +13,6 @@ import (
)
type Image struct {
- IdOrNamed
ID string `json:"Id"`
RepoTags []string `json:",omitempty"`
RepoDigests []string `json:",omitempty"`
@@ -110,11 +111,37 @@ type ImageHistoryReport struct {
Layers []ImageHistoryLayer
}
-type ImageInspectOptions struct {
- TypeObject string `json:",omitempty"`
- Format string `json:",omitempty"`
- Size bool `json:",omitempty"`
- Latest bool `json:",omitempty"`
+// ImagePullOptions are the arguments for pulling images.
+type ImagePullOptions struct {
+ // AllTags can be specified to pull all tags of the spiecifed image. Note
+ // that this only works if the specified image does not include a tag.
+ AllTags bool
+ // Authfile is the path to the authentication file. Ignored for remote
+ // calls.
+ Authfile string
+ // CertDir is the path to certificate directories. Ignored for remote
+ // calls.
+ CertDir string
+ // Credentials for authenticating against the registry in the format
+ // USERNAME:PASSWORD.
+ Credentials string
+ // OverrideArch will overwrite the local architecture for image pulls.
+ OverrideArch string
+ // OverrideOS will overwrite the local operating system (OS) for image
+ // pulls.
+ OverrideOS string
+ // Quiet can be specified to suppress pull progress when pulling. Ignored
+ // for remote calls.
+ Quiet bool
+ // SignaturePolicy to use when pulling. Ignored for remote calls.
+ SignaturePolicy string
+ // TLSVerify to enable/disable HTTPS and certificate verification.
+ TLSVerify types.OptionalBool
+}
+
+// ImagePullReport is the response from pulling one or more images.
+type ImagePullReport struct {
+ Images []string
}
type ImageListOptions struct {
@@ -123,10 +150,6 @@ type ImageListOptions struct {
Filters url.Values `json:"filters" schema:"filters"`
}
-// type ImageListReport struct {
-// Images []ImageSummary
-// }
-
type ImagePruneOptions struct {
All bool `json:"all" schema:"all"`
Filter []string `json:"filter" schema:"filter"`
@@ -137,3 +160,40 @@ type ImagePruneReport struct {
Report Report
Size int64
}
+
+type ImageTagOptions struct{}
+type ImageUntagOptions struct{}
+
+type ImageData struct {
+ *inspect.ImageData
+}
+
+type ImageInspectReport struct {
+ Images []*ImageData
+ Errors map[string]error
+}
+
+type ImageLoadOptions struct {
+ Name string
+ Tag string
+ Input string
+ Quiet bool
+ SignaturePolicy string
+}
+
+type ImageLoadReport struct {
+ Name string
+}
+
+type ImageImportOptions struct {
+ Changes []string
+ Message string
+ Quiet bool
+ Reference string
+ Source string
+ SourceIsURL bool
+}
+
+type ImageImportReport struct {
+ Id string
+}
diff --git a/pkg/domain/entities/pods.go b/pkg/domain/entities/pods.go
index d92d1bc7a..a0b2c6cec 100644
--- a/pkg/domain/entities/pods.go
+++ b/pkg/domain/entities/pods.go
@@ -22,6 +22,7 @@ type ListPodsReport struct {
Containers []*ListPodContainer
Created time.Time
Id string
+ InfraId string
Name string
Namespace string
Status string
@@ -151,3 +152,15 @@ type PodTopOptions struct {
Descriptors []string
NameOrID string
}
+
+type PodPSOptions struct {
+ CtrNames bool
+ CtrIds bool
+ CtrStatus bool
+ Filters map[string][]string
+ Format string
+ Latest bool
+ Namespace bool
+ Quiet bool
+ Sort string
+}
diff --git a/pkg/domain/entities/types.go b/pkg/domain/entities/types.go
index a1a729584..dd7aaa07f 100644
--- a/pkg/domain/entities/types.go
+++ b/pkg/domain/entities/types.go
@@ -42,3 +42,10 @@ type NetOptions struct {
StaticIP *net.IP
StaticMAC *net.HardwareAddr
}
+
+// All CLI inspect commands and inspect sub-commands use the same options
+type InspectOptions struct {
+ Format string `json:",omitempty"`
+ Latest bool `json:",omitempty"`
+ Size bool `json:",omitempty"`
+}
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go
index d25af24c5..d4c5ac311 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -243,7 +243,7 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
return reports, nil
}
-func (ic *ContainerEngine) ContainerInspect(ctx context.Context, namesOrIds []string, options entities.ContainerInspectOptions) ([]*entities.ContainerInspectReport, error) {
+func (ic *ContainerEngine) ContainerInspect(ctx context.Context, namesOrIds []string, options entities.InspectOptions) ([]*entities.ContainerInspectReport, error) {
var reports []*entities.ContainerInspectReport
ctrs, err := shortcuts.GetContainersByContext(false, options.Latest, namesOrIds, ic.Libpod)
if err != nil {
@@ -325,3 +325,11 @@ func (ic *ContainerEngine) ContainerCommit(ctx context.Context, nameOrId string,
}
return &entities.CommitReport{Id: newImage.ID()}, nil
}
+
+func (ic *ContainerEngine) ContainerExport(ctx context.Context, nameOrId string, options entities.ContainerExportOptions) error {
+ ctr, err := ic.Libpod.LookupContainer(nameOrId)
+ if err != nil {
+ return err
+ }
+ return ctr.Export(options.Output)
+}
diff --git a/pkg/domain/infra/abi/healthcheck.go b/pkg/domain/infra/abi/healthcheck.go
new file mode 100644
index 000000000..699483243
--- /dev/null
+++ b/pkg/domain/infra/abi/healthcheck.go
@@ -0,0 +1,26 @@
+// +build ABISupport
+
+package abi
+
+import (
+ "context"
+
+ "github.com/containers/libpod/libpod"
+ "github.com/containers/libpod/libpod/define"
+ "github.com/containers/libpod/pkg/domain/entities"
+)
+
+func (ic *ContainerEngine) HealthCheckRun(ctx context.Context, nameOrId string, options entities.HealthCheckOptions) (*define.HealthCheckResults, error) {
+ status, err := ic.Libpod.HealthCheck(nameOrId)
+ if err != nil {
+ return nil, err
+ }
+ hcStatus := "unhealthy"
+ if status == libpod.HealthCheckSuccess {
+ hcStatus = "healthy"
+ }
+ report := define.HealthCheckResults{
+ Status: hcStatus,
+ }
+ return &report, nil
+}
diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go
index 44420c1e1..f8c63730c 100644
--- a/pkg/domain/infra/abi/images.go
+++ b/pkg/domain/infra/abi/images.go
@@ -5,11 +5,23 @@ package abi
import (
"context"
"fmt"
+ "io"
+ "os"
+ "strings"
+ "github.com/containers/image/v5/docker"
+ dockerarchive "github.com/containers/image/v5/docker/archive"
+ "github.com/containers/image/v5/docker/reference"
+ "github.com/containers/image/v5/transports/alltransports"
+ "github.com/containers/image/v5/types"
+ "github.com/containers/libpod/libpod/image"
libpodImage "github.com/containers/libpod/libpod/image"
"github.com/containers/libpod/pkg/domain/entities"
+ domainUtils "github.com/containers/libpod/pkg/domain/utils"
+ "github.com/containers/libpod/pkg/util"
"github.com/containers/storage"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
func (ir *ImageEngine) Exists(_ context.Context, nameOrId string) (*entities.BoolReport, error) {
@@ -134,6 +146,120 @@ func ToDomainHistoryLayer(layer *libpodImage.History) entities.ImageHistoryLayer
return l
}
+func (ir *ImageEngine) Pull(ctx context.Context, rawImage string, options entities.ImagePullOptions) (*entities.ImagePullReport, error) {
+ var writer io.Writer
+ if !options.Quiet {
+ writer = os.Stderr
+ }
+
+ dockerPrefix := fmt.Sprintf("%s://", docker.Transport.Name())
+ imageRef, err := alltransports.ParseImageName(rawImage)
+ if err != nil {
+ imageRef, err = alltransports.ParseImageName(fmt.Sprintf("%s%s", dockerPrefix, rawImage))
+ if err != nil {
+ return nil, errors.Errorf("invalid image reference %q", rawImage)
+ }
+ }
+
+ // Special-case for docker-archive which allows multiple tags.
+ if imageRef.Transport().Name() == dockerarchive.Transport.Name() {
+ newImage, err := ir.Libpod.ImageRuntime().LoadFromArchiveReference(ctx, imageRef, options.SignaturePolicy, writer)
+ if err != nil {
+ return nil, errors.Wrapf(err, "error pulling image %q", rawImage)
+ }
+ return &entities.ImagePullReport{Images: []string{newImage[0].ID()}}, nil
+ }
+
+ var registryCreds *types.DockerAuthConfig
+ if options.Credentials != "" {
+ creds, err := util.ParseRegistryCreds(options.Credentials)
+ if err != nil {
+ return nil, err
+ }
+ registryCreds = creds
+ }
+ dockerRegistryOptions := image.DockerRegistryOptions{
+ DockerRegistryCreds: registryCreds,
+ DockerCertPath: options.CertDir,
+ OSChoice: options.OverrideOS,
+ ArchitectureChoice: options.OverrideArch,
+ DockerInsecureSkipTLSVerify: options.TLSVerify,
+ }
+
+ if !options.AllTags {
+ newImage, err := ir.Libpod.ImageRuntime().New(ctx, rawImage, options.SignaturePolicy, options.Authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, nil, util.PullImageAlways)
+ if err != nil {
+ return nil, errors.Wrapf(err, "error pulling image %q", rawImage)
+ }
+ return &entities.ImagePullReport{Images: []string{newImage.ID()}}, nil
+ }
+
+ // --all-tags requires the docker transport
+ if imageRef.Transport().Name() != docker.Transport.Name() {
+ return nil, errors.New("--all-tags requires docker transport")
+ }
+
+ // Trim the docker-transport prefix.
+ rawImage = strings.TrimPrefix(rawImage, docker.Transport.Name())
+
+ // all-tags doesn't work with a tagged reference, so let's check early
+ namedRef, err := reference.Parse(rawImage)
+ if err != nil {
+ return nil, errors.Wrapf(err, "error parsing %q", rawImage)
+ }
+ if _, isTagged := namedRef.(reference.Tagged); isTagged {
+ return nil, errors.New("--all-tags requires a reference without a tag")
+
+ }
+
+ systemContext := image.GetSystemContext("", options.Authfile, false)
+ tags, err := docker.GetRepositoryTags(ctx, systemContext, imageRef)
+ if err != nil {
+ return nil, errors.Wrapf(err, "error getting repository tags")
+ }
+
+ var foundIDs []string
+ for _, tag := range tags {
+ name := rawImage + ":" + tag
+ newImage, err := ir.Libpod.ImageRuntime().New(ctx, name, options.SignaturePolicy, options.Authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, nil, util.PullImageAlways)
+ if err != nil {
+ logrus.Errorf("error pulling image %q", name)
+ continue
+ }
+ foundIDs = append(foundIDs, newImage.ID())
+ }
+
+ if len(tags) != len(foundIDs) {
+ return nil, errors.Errorf("error pulling image %q", rawImage)
+ }
+ return &entities.ImagePullReport{Images: foundIDs}, nil
+}
+
+func (ir *ImageEngine) Inspect(ctx context.Context, names []string, opts entities.InspectOptions) (*entities.ImageInspectReport, error) {
+ report := entities.ImageInspectReport{
+ Errors: make(map[string]error),
+ }
+
+ for _, id := range names {
+ img, err := ir.Libpod.ImageRuntime().NewFromLocal(id)
+ if err != nil {
+ report.Errors[id] = err
+ continue
+ }
+
+ results, err := img.Inspect(ctx)
+ if err != nil {
+ report.Errors[id] = err
+ continue
+ }
+
+ cookedResults := entities.ImageData{}
+ _ = domainUtils.DeepCopy(&cookedResults, results)
+ report.Images = append(report.Images, &cookedResults)
+ }
+ return &report, nil
+}
+
// func (r *imageRuntime) Delete(ctx context.Context, nameOrId string, opts entities.ImageDeleteOptions) (*entities.ImageDeleteReport, error) {
// image, err := r.libpod.ImageEngine().NewFromLocal(nameOrId)
// if err != nil {
@@ -146,7 +272,7 @@ func ToDomainHistoryLayer(layer *libpodImage.History) entities.ImageHistoryLayer
// }
//
// report := entities.ImageDeleteReport{}
-// if err := utils.DeepCopy(&report, results); err != nil {
+// if err := domainUtils.DeepCopy(&report, results); err != nil {
// return nil, err
// }
// return &report, nil
@@ -164,3 +290,58 @@ func ToDomainHistoryLayer(layer *libpodImage.History) entities.ImageHistoryLayer
// copy(report.Report.Id, id)
// return &report, nil
// }
+
+func (ir *ImageEngine) Tag(ctx context.Context, nameOrId string, tags []string, options entities.ImageTagOptions) error {
+ newImage, err := ir.Libpod.ImageRuntime().NewFromLocal(nameOrId)
+ if err != nil {
+ return err
+ }
+ for _, tag := range tags {
+ if err := newImage.TagImage(tag); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (ir *ImageEngine) Untag(ctx context.Context, nameOrId string, tags []string, options entities.ImageUntagOptions) error {
+ newImage, err := ir.Libpod.ImageRuntime().NewFromLocal(nameOrId)
+ if err != nil {
+ return err
+ }
+ for _, tag := range tags {
+ if err := newImage.UntagImage(tag); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (ir *ImageEngine) Load(ctx context.Context, opts entities.ImageLoadOptions) (*entities.ImageLoadReport, error) {
+ var (
+ writer io.Writer
+ )
+ if !opts.Quiet {
+ writer = os.Stderr
+ }
+ name, err := ir.Libpod.LoadImage(ctx, opts.Name, opts.Input, writer, opts.SignaturePolicy)
+ if err != nil {
+ return nil, err
+ }
+ newImage, err := ir.Libpod.ImageRuntime().NewFromLocal(name)
+ if err != nil {
+ return nil, errors.Wrap(err, "image loaded but no additional tags were created")
+ }
+ if err := newImage.TagImage(opts.Name); err != nil {
+ return nil, errors.Wrapf(err, "error adding %q to image %q", opts.Name, newImage.InputName)
+ }
+ return &entities.ImageLoadReport{Name: name}, nil
+}
+
+func (ir *ImageEngine) Import(ctx context.Context, opts entities.ImageImportOptions) (*entities.ImageImportReport, error) {
+ id, err := ir.Libpod.Import(ctx, opts.Source, opts.Reference, opts.Changes, opts.Message, opts.Quiet)
+ if err != nil {
+ return nil, err
+ }
+ return &entities.ImageImportReport{Id: id}, nil
+}
diff --git a/pkg/domain/infra/abi/pods.go b/pkg/domain/infra/abi/pods.go
index 8abcc6e4b..494a048ec 100644
--- a/pkg/domain/infra/abi/pods.go
+++ b/pkg/domain/infra/abi/pods.go
@@ -7,6 +7,7 @@ import (
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/define"
+ "github.com/containers/libpod/libpod/podfilters"
"github.com/containers/libpod/pkg/domain/entities"
"github.com/containers/libpod/pkg/signal"
"github.com/containers/libpod/pkg/specgen"
@@ -272,3 +273,61 @@ func (ic *ContainerEngine) PodTop(ctx context.Context, options entities.PodTopOp
report.Value, err = pod.GetPodPidInformation(options.Descriptors)
return report, err
}
+
+func (ic *ContainerEngine) PodPs(ctx context.Context, options entities.PodPSOptions) ([]*entities.ListPodsReport, error) {
+ var (
+ filters []libpod.PodFilter
+ reports []*entities.ListPodsReport
+ )
+ for k, v := range options.Filters {
+ for _, filter := range v {
+ f, err := podfilters.GeneratePodFilterFunc(k, filter)
+ if err != nil {
+ return nil, err
+ }
+ filters = append(filters, f)
+
+ }
+ }
+ pds, err := ic.Libpod.Pods(filters...)
+ if err != nil {
+ return nil, err
+ }
+ for _, p := range pds {
+ var lpcs []*entities.ListPodContainer
+ status, err := p.GetPodStatus()
+ if err != nil {
+ return nil, err
+ }
+ cons, err := p.AllContainers()
+ if err != nil {
+ return nil, err
+ }
+ for _, c := range cons {
+ state, err := c.State()
+ if err != nil {
+ return nil, err
+ }
+ lpcs = append(lpcs, &entities.ListPodContainer{
+ Id: c.ID(),
+ Names: c.Name(),
+ Status: state.String(),
+ })
+ }
+ infraId, err := p.InfraContainerID()
+ if err != nil {
+ return nil, err
+ }
+ reports = append(reports, &entities.ListPodsReport{
+ Cgroup: p.CgroupParent(),
+ Containers: lpcs,
+ Created: p.CreatedTime(),
+ Id: p.ID(),
+ InfraId: infraId,
+ Name: p.Name(),
+ Namespace: p.Namespace(),
+ Status: status,
+ })
+ }
+ return reports, nil
+}
diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go
index 3c8be90dc..8885ae7c7 100644
--- a/pkg/domain/infra/tunnel/containers.go
+++ b/pkg/domain/infra/tunnel/containers.go
@@ -2,6 +2,8 @@ package tunnel
import (
"context"
+ "io"
+ "os"
"github.com/containers/image/v5/docker/reference"
@@ -142,7 +144,7 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
return reports, nil
}
-func (ic *ContainerEngine) ContainerInspect(ctx context.Context, namesOrIds []string, options entities.ContainerInspectOptions) ([]*entities.ContainerInspectReport, error) {
+func (ic *ContainerEngine) ContainerInspect(ctx context.Context, namesOrIds []string, options entities.InspectOptions) ([]*entities.ContainerInspectReport, error) {
var (
reports []*entities.ContainerInspectReport
)
@@ -210,3 +212,17 @@ func (ic *ContainerEngine) ContainerCommit(ctx context.Context, nameOrId string,
}
return &entities.CommitReport{Id: response.ID}, nil
}
+
+func (ic *ContainerEngine) ContainerExport(ctx context.Context, nameOrId string, options entities.ContainerExportOptions) error {
+ var (
+ err error
+ w io.Writer
+ )
+ if len(options.Output) > 0 {
+ w, err = os.Create(options.Output)
+ if err != nil {
+ return err
+ }
+ }
+ return containers.Export(ic.ClientCxt, nameOrId, w)
+}
diff --git a/pkg/domain/infra/tunnel/healthcheck.go b/pkg/domain/infra/tunnel/healthcheck.go
new file mode 100644
index 000000000..e589489b3
--- /dev/null
+++ b/pkg/domain/infra/tunnel/healthcheck.go
@@ -0,0 +1,13 @@
+package tunnel
+
+import (
+ "context"
+
+ "github.com/containers/libpod/libpod/define"
+ "github.com/containers/libpod/pkg/bindings/containers"
+ "github.com/containers/libpod/pkg/domain/entities"
+)
+
+func (ic *ContainerEngine) HealthCheckRun(ctx context.Context, nameOrId string, options entities.HealthCheckOptions) (*define.HealthCheckResults, error) {
+ return containers.RunHealthCheck(ic.ClientCxt, nameOrId)
+}
diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go
index 6a3adc9ee..155f5e4bd 100644
--- a/pkg/domain/infra/tunnel/images.go
+++ b/pkg/domain/infra/tunnel/images.go
@@ -2,10 +2,13 @@ package tunnel
import (
"context"
+ "os"
+ "github.com/containers/image/v5/docker/reference"
images "github.com/containers/libpod/pkg/bindings/images"
"github.com/containers/libpod/pkg/domain/entities"
"github.com/containers/libpod/pkg/domain/utils"
+ "github.com/pkg/errors"
)
func (ir *ImageEngine) Exists(_ context.Context, nameOrId string) (*entities.BoolReport, error) {
@@ -85,3 +88,99 @@ func (ir *ImageEngine) Prune(ctx context.Context, opts entities.ImagePruneOption
}
return &report, nil
}
+
+func (ir *ImageEngine) Pull(ctx context.Context, rawImage string, options entities.ImagePullOptions) (*entities.ImagePullReport, error) {
+ pulledImages, err := images.Pull(ir.ClientCxt, rawImage, options)
+ if err != nil {
+ return nil, err
+ }
+ return &entities.ImagePullReport{Images: pulledImages}, nil
+}
+
+func (ir *ImageEngine) Tag(ctx context.Context, nameOrId string, tags []string, options entities.ImageTagOptions) error {
+ for _, newTag := range tags {
+ var (
+ tag, repo string
+ )
+ ref, err := reference.Parse(newTag)
+ if err != nil {
+ return err
+ }
+ if t, ok := ref.(reference.Tagged); ok {
+ tag = t.Tag()
+ }
+ if r, ok := ref.(reference.Named); ok {
+ repo = r.Name()
+ }
+ if len(repo) < 1 {
+ return errors.Errorf("invalid image name %q", nameOrId)
+ }
+ if err := images.Tag(ir.ClientCxt, nameOrId, tag, repo); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (ir *ImageEngine) Untag(ctx context.Context, nameOrId string, tags []string, options entities.ImageUntagOptions) error {
+ for _, newTag := range tags {
+ var (
+ tag, repo string
+ )
+ ref, err := reference.Parse(newTag)
+ if err != nil {
+ return err
+ }
+ if t, ok := ref.(reference.Tagged); ok {
+ tag = t.Tag()
+ }
+ if r, ok := ref.(reference.Named); ok {
+ repo = r.Name()
+ }
+ if len(repo) < 1 {
+ return errors.Errorf("invalid image name %q", nameOrId)
+ }
+ if err := images.Untag(ir.ClientCxt, nameOrId, tag, repo); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (ir *ImageEngine) Inspect(_ context.Context, names []string, opts entities.InspectOptions) (*entities.ImageInspectReport, error) {
+ report := entities.ImageInspectReport{}
+ for _, id := range names {
+ r, err := images.GetImage(ir.ClientCxt, id, &opts.Size)
+ if err != nil {
+ report.Errors[id] = err
+ }
+ report.Images = append(report.Images, r)
+ }
+ return &report, nil
+}
+
+func (ir *ImageEngine) Load(ctx context.Context, opts entities.ImageLoadOptions) (*entities.ImageLoadReport, error) {
+ f, err := os.Open(opts.Input)
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+ return images.Load(ir.ClientCxt, f, &opts.Name)
+}
+
+func (ir *ImageEngine) Import(ctx context.Context, opts entities.ImageImportOptions) (*entities.ImageImportReport, error) {
+ var (
+ err error
+ sourceURL *string
+ f *os.File
+ )
+ if opts.SourceIsURL {
+ sourceURL = &opts.Source
+ } else {
+ f, err = os.Open(opts.Source)
+ if err != nil {
+ return nil, err
+ }
+ }
+ return images.Import(ir.ClientCxt, opts.Changes, &opts.Message, &opts.Reference, sourceURL, f)
+}
diff --git a/pkg/domain/infra/tunnel/pods.go b/pkg/domain/infra/tunnel/pods.go
index 9561a9807..ad87a0a29 100644
--- a/pkg/domain/infra/tunnel/pods.go
+++ b/pkg/domain/infra/tunnel/pods.go
@@ -193,3 +193,7 @@ func (ic *ContainerEngine) PodTop(ctx context.Context, options entities.PodTopOp
}
return &entities.StringSliceReport{Value: topOutput}, nil
}
+
+func (ic *ContainerEngine) PodPs(ctx context.Context, options entities.PodPSOptions) ([]*entities.ListPodsReport, error) {
+ return pods.List(ic.ClientCxt, options.Filters)
+}
diff --git a/pkg/systemd/generate/systemdgen.go b/pkg/systemd/generate/systemdgen.go
index eb15d4927..73fe52c0e 100644
--- a/pkg/systemd/generate/systemdgen.go
+++ b/pkg/systemd/generate/systemdgen.go
@@ -31,7 +31,7 @@ type ContainerInfo struct {
InfraContainer string
// StopTimeout sets the timeout Podman waits before killing the container
// during service stop.
- StopTimeout int
+ StopTimeout uint
// RestartPolicy of the systemd unit (e.g., no, on-failure, always).
RestartPolicy string
// PIDFile of the service. Required for forking services. Must point to the
diff --git a/pkg/varlink/generate.go b/pkg/varlink/generate.go
new file mode 100644
index 000000000..b3f58d4a5
--- /dev/null
+++ b/pkg/varlink/generate.go
@@ -0,0 +1,3 @@
+package iopodman
+
+//go:generate go run ../../vendor/github.com/varlink/go/cmd/varlink-go-interface-generator/main.go io.podman.varlink
diff --git a/cmd/podman/varlink/io.podman.varlink b/pkg/varlink/io.podman.varlink
index 0cb95ef97..0cb95ef97 100644
--- a/cmd/podman/varlink/io.podman.varlink
+++ b/pkg/varlink/io.podman.varlink
diff --git a/pkg/varlinkapi/attach.go b/pkg/varlinkapi/attach.go
index 5beca3c6f..94f4d653e 100644
--- a/pkg/varlinkapi/attach.go
+++ b/pkg/varlinkapi/attach.go
@@ -6,10 +6,10 @@ import (
"bufio"
"io"
- "github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/libpod/events"
+ iopodman "github.com/containers/libpod/pkg/varlink"
"github.com/containers/libpod/pkg/varlinkapi/virtwriter"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -28,7 +28,7 @@ func setupStreams(call iopodman.VarlinkCall) (*bufio.Reader, *bufio.Writer, *io.
stdoutWriter := virtwriter.NewVirtWriteCloser(writer, virtwriter.ToStdout)
// TODO if runc ever starts passing stderr, we can too
- //stderrWriter := NewVirtWriteCloser(writer, ToStderr)
+ // stderrWriter := NewVirtWriteCloser(writer, ToStderr)
streams := libpod.AttachStreams{
OutputStream: stdoutWriter,
diff --git a/pkg/varlinkapi/config.go b/pkg/varlinkapi/config.go
index e75170547..c69dc794a 100644
--- a/pkg/varlinkapi/config.go
+++ b/pkg/varlinkapi/config.go
@@ -4,8 +4,8 @@ package varlinkapi
import (
"github.com/containers/libpod/cmd/podman/cliconfig"
- iopodman "github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/libpod"
+ iopodman "github.com/containers/libpod/pkg/varlink"
"github.com/spf13/cobra"
)
diff --git a/pkg/varlinkapi/containers.go b/pkg/varlinkapi/containers.go
index 55427771c..2d051470f 100644
--- a/pkg/varlinkapi/containers.go
+++ b/pkg/varlinkapi/containers.go
@@ -15,13 +15,13 @@ import (
"time"
"github.com/containers/libpod/cmd/podman/shared"
- iopodman "github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/libpod/logs"
"github.com/containers/libpod/pkg/adapter/shortcuts"
"github.com/containers/libpod/pkg/cgroups"
"github.com/containers/libpod/pkg/rootless"
+ iopodman "github.com/containers/libpod/pkg/varlink"
"github.com/containers/libpod/pkg/varlinkapi/virtwriter"
"github.com/containers/storage/pkg/archive"
"github.com/pkg/errors"
@@ -900,7 +900,7 @@ func (i *LibpodAPI) ExecContainer(call iopodman.VarlinkCall, opts iopodman.ExecO
return ecErr.Error
}
-//HealthCheckRun executes defined container's healthcheck command and returns the container's health status.
+// HealthCheckRun executes defined container's healthcheck command and returns the container's health status.
func (i *LibpodAPI) HealthCheckRun(call iopodman.VarlinkCall, nameOrID string) error {
hcStatus, err := i.Runtime.HealthCheck(nameOrID)
if err != nil && hcStatus != libpod.HealthCheckFailure {
diff --git a/pkg/varlinkapi/containers_create.go b/pkg/varlinkapi/containers_create.go
index 6b23dce5e..bbd4d59f1 100644
--- a/pkg/varlinkapi/containers_create.go
+++ b/pkg/varlinkapi/containers_create.go
@@ -4,7 +4,7 @@ package varlinkapi
import (
"github.com/containers/libpod/cmd/podman/shared"
- "github.com/containers/libpod/cmd/podman/varlink"
+ iopodman "github.com/containers/libpod/pkg/varlink"
)
// CreateContainer ...
diff --git a/pkg/varlinkapi/events.go b/pkg/varlinkapi/events.go
index f9a9d9321..4ae2d1cb2 100644
--- a/pkg/varlinkapi/events.go
+++ b/pkg/varlinkapi/events.go
@@ -6,8 +6,8 @@ import (
"fmt"
"time"
- "github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/libpod/events"
+ iopodman "github.com/containers/libpod/pkg/varlink"
)
// GetEvents is a remote endpoint to get events from the event log
diff --git a/pkg/varlinkapi/generate.go b/pkg/varlinkapi/generate.go
index 19010097d..c19c8dede 100644
--- a/pkg/varlinkapi/generate.go
+++ b/pkg/varlinkapi/generate.go
@@ -6,7 +6,7 @@ import (
"encoding/json"
"github.com/containers/libpod/cmd/podman/shared"
- iopodman "github.com/containers/libpod/cmd/podman/varlink"
+ iopodman "github.com/containers/libpod/pkg/varlink"
)
// GenerateKube ...
diff --git a/pkg/varlinkapi/images.go b/pkg/varlinkapi/images.go
index 82587f5c4..c3b4bd9ae 100644
--- a/pkg/varlinkapi/images.go
+++ b/pkg/varlinkapi/images.go
@@ -21,12 +21,12 @@ import (
"github.com/containers/image/v5/transports/alltransports"
"github.com/containers/image/v5/types"
"github.com/containers/libpod/cmd/podman/shared"
- iopodman "github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/libpod/image"
"github.com/containers/libpod/pkg/channelwriter"
"github.com/containers/libpod/pkg/util"
+ iopodman "github.com/containers/libpod/pkg/varlink"
"github.com/containers/libpod/utils"
"github.com/containers/storage/pkg/archive"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
diff --git a/pkg/varlinkapi/mount.go b/pkg/varlinkapi/mount.go
index 63ce44291..2450f6fd9 100644
--- a/pkg/varlinkapi/mount.go
+++ b/pkg/varlinkapi/mount.go
@@ -2,9 +2,7 @@
package varlinkapi
-import (
- "github.com/containers/libpod/cmd/podman/varlink"
-)
+import iopodman "github.com/containers/libpod/pkg/varlink"
// ListContainerMounts ...
func (i *LibpodAPI) ListContainerMounts(call iopodman.VarlinkCall) error {
diff --git a/pkg/varlinkapi/pods.go b/pkg/varlinkapi/pods.go
index 2ec45f7a1..79ffb6677 100644
--- a/pkg/varlinkapi/pods.go
+++ b/pkg/varlinkapi/pods.go
@@ -8,9 +8,9 @@ import (
"syscall"
"github.com/containers/libpod/cmd/podman/shared"
- "github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/adapter/shortcuts"
+ iopodman "github.com/containers/libpod/pkg/varlink"
)
// CreatePod ...
diff --git a/pkg/varlinkapi/remote_client.go b/pkg/varlinkapi/remote_client.go
index dd0613494..a16d11dec 100644
--- a/pkg/varlinkapi/remote_client.go
+++ b/pkg/varlinkapi/remote_client.go
@@ -3,8 +3,8 @@
package varlinkapi
import (
- "github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/libpod"
+ iopodman "github.com/containers/libpod/pkg/varlink"
)
// ContainerStatsToLibpodContainerStats converts the varlink containerstats to a libpod
diff --git a/pkg/varlinkapi/system.go b/pkg/varlinkapi/system.go
index e88d010c5..04fb9f648 100644
--- a/pkg/varlinkapi/system.go
+++ b/pkg/varlinkapi/system.go
@@ -10,8 +10,8 @@ import (
"time"
"github.com/containers/image/v5/pkg/sysregistriesv2"
- iopodman "github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/libpod/define"
+ iopodman "github.com/containers/libpod/pkg/varlink"
"github.com/sirupsen/logrus"
)
diff --git a/pkg/varlinkapi/transfers.go b/pkg/varlinkapi/transfers.go
index 31d26c3aa..654da276e 100644
--- a/pkg/varlinkapi/transfers.go
+++ b/pkg/varlinkapi/transfers.go
@@ -9,7 +9,7 @@ import (
"io/ioutil"
"os"
- "github.com/containers/libpod/cmd/podman/varlink"
+ iopodman "github.com/containers/libpod/pkg/varlink"
"github.com/sirupsen/logrus"
)
diff --git a/pkg/varlinkapi/util.go b/pkg/varlinkapi/util.go
index d3a41f7ab..6b196f384 100644
--- a/pkg/varlinkapi/util.go
+++ b/pkg/varlinkapi/util.go
@@ -10,10 +10,10 @@ import (
"github.com/containers/buildah"
"github.com/containers/libpod/cmd/podman/shared"
- "github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/pkg/channelwriter"
+ iopodman "github.com/containers/libpod/pkg/varlink"
"github.com/containers/storage/pkg/archive"
)
diff --git a/pkg/varlinkapi/volumes.go b/pkg/varlinkapi/volumes.go
index e497cb537..b0c3608c4 100644
--- a/pkg/varlinkapi/volumes.go
+++ b/pkg/varlinkapi/volumes.go
@@ -6,8 +6,8 @@ import (
"encoding/json"
"github.com/containers/libpod/cmd/podman/shared"
- iopodman "github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/libpod"
+ iopodman "github.com/containers/libpod/pkg/varlink"
)
// VolumeCreate creates a libpod volume based on input from a varlink connection
diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go
index b10c3237d..8c4fe9223 100644
--- a/test/e2e/common_test.go
+++ b/test/e2e/common_test.go
@@ -431,7 +431,7 @@ func (p *PodmanTestIntegration) PodmanPID(args []string) (*PodmanSessionIntegrat
// Cleanup cleans up the temporary store
func (p *PodmanTestIntegration) Cleanup() {
// Remove all containers
- stopall := p.Podman([]string{"stop", "-a", "--timeout", "0"})
+ stopall := p.Podman([]string{"stop", "-a", "--time", "0"})
stopall.Wait(90)
podstop := p.Podman([]string{"pod", "stop", "-a", "-t", "0"})
diff --git a/test/e2e/generate_systemd_test.go b/test/e2e/generate_systemd_test.go
index e5ab0b854..abfca4db9 100644
--- a/test/e2e/generate_systemd_test.go
+++ b/test/e2e/generate_systemd_test.go
@@ -47,7 +47,7 @@ var _ = Describe("Podman generate systemd", func() {
})
It("podman generate systemd bad timeout value", func() {
- session := podmanTest.Podman([]string{"generate", "systemd", "--timeout", "-1", "foobar"})
+ session := podmanTest.Podman([]string{"generate", "systemd", "--time", "-1", "foobar"})
session.WaitWithDefaultTimeout()
Expect(session).To(ExitWithError())
})
@@ -57,7 +57,7 @@ var _ = Describe("Podman generate systemd", func() {
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"generate", "systemd", "--timeout", "1234", "foobar"})
+ session = podmanTest.Podman([]string{"generate", "systemd", "--time", "1234", "foobar"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -97,7 +97,7 @@ var _ = Describe("Podman generate systemd", func() {
n.WaitWithDefaultTimeout()
Expect(n.ExitCode()).To(Equal(0))
- session := podmanTest.Podman([]string{"generate", "systemd", "--timeout", "5", "nginx"})
+ session := podmanTest.Podman([]string{"generate", "systemd", "--time", "5", "nginx"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -118,7 +118,7 @@ var _ = Describe("Podman generate systemd", func() {
n.WaitWithDefaultTimeout()
Expect(n.ExitCode()).To(Equal(0))
- session := podmanTest.Podman([]string{"generate", "systemd", "--timeout", "42", "--name", "foo"})
+ session := podmanTest.Podman([]string{"generate", "systemd", "--time", "42", "--name", "foo"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -183,7 +183,7 @@ var _ = Describe("Podman generate systemd", func() {
n.WaitWithDefaultTimeout()
Expect(n.ExitCode()).To(Equal(0))
- session := podmanTest.Podman([]string{"generate", "systemd", "--timeout", "42", "--name", "--new", "foo"})
+ session := podmanTest.Podman([]string{"generate", "systemd", "-t", "42", "--name", "--new", "foo"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -214,7 +214,7 @@ var _ = Describe("Podman generate systemd", func() {
n.WaitWithDefaultTimeout()
Expect(n.ExitCode()).To(Equal(0))
- session := podmanTest.Podman([]string{"generate", "systemd", "--timeout", "42", "--name", "--new", "foo"})
+ session := podmanTest.Podman([]string{"generate", "systemd", "--time", "42", "--name", "--new", "foo"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -228,7 +228,7 @@ var _ = Describe("Podman generate systemd", func() {
n.WaitWithDefaultTimeout()
Expect(n.ExitCode()).To(Equal(0))
- session := podmanTest.Podman([]string{"generate", "systemd", "--timeout", "42", "--name", "--new", "foo"})
+ session := podmanTest.Podman([]string{"generate", "systemd", "--time", "42", "--name", "--new", "foo"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(125))
})
diff --git a/test/e2e/run_volume_test.go b/test/e2e/run_volume_test.go
index e31338dbc..667f03627 100644
--- a/test/e2e/run_volume_test.go
+++ b/test/e2e/run_volume_test.go
@@ -255,7 +255,7 @@ var _ = Describe("Podman run with volumes", func() {
Expect(strings.Contains(mountOut2, volName)).To(BeTrue())
// Stop the container to unmount
- podmanStopSession := podmanTest.Podman([]string{"stop", "--timeout", "0", ctrName})
+ podmanStopSession := podmanTest.Podman([]string{"stop", "--time", "0", ctrName})
podmanStopSession.WaitWithDefaultTimeout()
Expect(podmanStopSession.ExitCode()).To(Equal(0))
diff --git a/test/endpoint/endpoint.go b/test/endpoint/endpoint.go
index 5b5484865..f1677ec5f 100644
--- a/test/endpoint/endpoint.go
+++ b/test/endpoint/endpoint.go
@@ -11,8 +11,8 @@ import (
"syscall"
"time"
- iopodman "github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/pkg/rootless"
+ iopodman "github.com/containers/libpod/pkg/varlink"
. "github.com/onsi/ginkgo"
"github.com/onsi/gomega/gexec"
)
diff --git a/test/endpoint/setup.go b/test/endpoint/setup.go
index 727f29ec6..11fa77b5c 100644
--- a/test/endpoint/setup.go
+++ b/test/endpoint/setup.go
@@ -8,8 +8,8 @@ import (
"path/filepath"
"strings"
- iopodman "github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/pkg/rootless"
+ iopodman "github.com/containers/libpod/pkg/varlink"
"github.com/containers/storage/pkg/stringid"
"github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
@@ -90,7 +90,7 @@ func Setup(tempDir string) *EndpointTestIntegration {
SignaturePolicyPath: filepath.Join(INTEGRATION_ROOT, "test/policy.json"),
StorageOptions: storageOptions,
TmpDir: tempDir,
- //Timings: nil,
+ // Timings: nil,
VarlinkBinary: VarlinkBinary,
VarlinkCommand: nil,
VarlinkEndpoint: endpoint,
@@ -105,7 +105,7 @@ func (p *EndpointTestIntegration) Cleanup() {
p.stopAllContainers()
- //TODO need to make stop all pods
+ // TODO need to make stop all pods
p.StopVarlink()
// Nuke tempdir
@@ -153,9 +153,9 @@ func (p *EndpointTestIntegration) createArtifact(image string) {
Expect(pull.ExitCode()).To(Equal(0))
imageSave := iopodman.ImageSaveOptions{
- //Name:image,
- //Output: destName,
- //Format: "oci-archive",
+ // Name:image,
+ // Output: destName,
+ // Format: "oci-archive",
}
imageSave.Name = image
imageSave.Output = destName
@@ -186,7 +186,7 @@ func (p *EndpointTestIntegration) RestoreArtifactToCache(image string) error {
fmt.Printf("Restoring %s...\n", image)
dest := strings.Split(image, "/")
destName := fmt.Sprintf("/tmp/%s.tar", strings.Replace(strings.Join(strings.Split(dest[len(dest)-1], "/"), ""), ":", "-", -1))
- //fmt.Println(destName, p.ImageCacheDir)
+ // fmt.Println(destName, p.ImageCacheDir)
load := p.Varlink("LoadImage", fmt.Sprintf("{\"name\": \"%s\", \"inputFile\": \"%s\"}", image, destName), false)
Expect(load.ExitCode()).To(BeZero())
return nil
diff --git a/vendor/github.com/rootless-containers/rootlesskit/pkg/port/portutil/portutil.go b/vendor/github.com/rootless-containers/rootlesskit/pkg/port/portutil/portutil.go
index f1aa5f859..4fc081d43 100644
--- a/vendor/github.com/rootless-containers/rootlesskit/pkg/port/portutil/portutil.go
+++ b/vendor/github.com/rootless-containers/rootlesskit/pkg/port/portutil/portutil.go
@@ -58,8 +58,7 @@ func ValidatePortSpec(spec port.Spec, existingPorts map[int]*port.Status) error
sp := p.Spec
sameProto := sp.Proto == spec.Proto
sameParent := sp.ParentIP == spec.ParentIP && sp.ParentPort == spec.ParentPort
- sameChild := sp.ChildPort == spec.ChildPort
- if sameProto && (sameParent || sameChild) {
+ if sameProto && sameParent {
return errors.Errorf("conflict with ID %d", id)
}
}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index ad801a07a..a1c28b023 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -86,7 +86,7 @@ github.com/containers/buildah/util
github.com/containers/common/pkg/capabilities
github.com/containers/common/pkg/config
github.com/containers/common/pkg/unshare
-# github.com/containers/conmon v2.0.10+incompatible
+# github.com/containers/conmon v2.0.14+incompatible
github.com/containers/conmon/runner/config
# github.com/containers/image/v5 v5.3.1
github.com/containers/image/v5/copy
@@ -450,7 +450,7 @@ github.com/prometheus/common/model
github.com/prometheus/procfs
github.com/prometheus/procfs/internal/fs
github.com/prometheus/procfs/internal/util
-# github.com/rootless-containers/rootlesskit v0.9.2
+# github.com/rootless-containers/rootlesskit v0.9.3
github.com/rootless-containers/rootlesskit/pkg/msgutil
github.com/rootless-containers/rootlesskit/pkg/port
github.com/rootless-containers/rootlesskit/pkg/port/builtin