summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml16
-rw-r--r--CODE-OF-CONDUCT.md4
-rw-r--r--Makefile14
-rw-r--r--cmd/podman/common/create.go2
-rw-r--r--cmd/podman/common/create_opts.go7
-rw-r--r--cmd/podman/common/specgen.go2
-rw-r--r--cmd/podman/containers/rm.go15
-rwxr-xr-xcontrib/cirrus/runner.sh6
-rwxr-xr-xcontrib/cirrus/setup_environment.sh2
-rw-r--r--libpod/network/create.go2
-rw-r--r--libpod/network/lock.go13
-rw-r--r--libpod/network/network.go3
-rw-r--r--pkg/api/handlers/compat/containers.go55
-rw-r--r--pkg/bindings/containers/containers.go12
-rw-r--r--pkg/bindings/containers/types.go2
-rw-r--r--pkg/bindings/containers/types_remove_options.go32
-rw-r--r--pkg/domain/entities/containers.go11
-rw-r--r--pkg/domain/infra/abi/containers.go30
-rw-r--r--pkg/domain/infra/tunnel/containers.go8
-rw-r--r--pkg/specgen/generate/container.go8
-rw-r--r--pkg/systemd/generate/common.go12
-rw-r--r--pkg/systemd/generate/containers.go48
-rw-r--r--pkg/systemd/generate/containers_test.go39
-rw-r--r--pkg/systemd/generate/pods.go52
-rw-r--r--pkg/systemd/generate/pods_test.go43
-rw-r--r--test/e2e/generate_systemd_test.go21
-rw-r--r--test/e2e/network_create_test.go94
-rw-r--r--test/e2e/network_test.go35
-rw-r--r--test/e2e/rm_test.go34
-rw-r--r--test/system/040-ps.bats7
30 files changed, 431 insertions, 198 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index bfe293601..6071a6fa7 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -108,7 +108,7 @@ automation_task:
smoke_task:
alias: 'smoke'
name: "Smoke Test"
- skip: *tags
+ skip: *branches_and_tags
container: &bigcontainer
image: ${CTR_FQIN}
# Leave some resources for smallcontainer
@@ -274,17 +274,19 @@ swagger_task:
# Check that all included go modules from other sources match
-# what is expected in `vendor/modules.txt` vs `go.mod`.
-vendor_task:
- name: "Test Vendoring"
- alias: vendor
+# what is expected in `vendor/modules.txt` vs `go.mod`. Also
+# make sure that the generated bindings in pkg/bindings/...
+# are in sync with the code.
+consistency_task:
+ name: "Test Code Consistency"
+ alias: consistency
skip: *tags
depends_on:
- build
container: *smallcontainer
env:
<<: *stdenvars
- TEST_FLAVOR: vendor
+ TEST_FLAVOR: consistency
TEST_ENVIRON: container
CTR_FQIN: ${FEDORA_CONTAINER_FQIN}
clone_script: *full_clone # build-cache not available to container tasks
@@ -642,7 +644,7 @@ success_task:
- validate
- bindings
- swagger
- - vendor
+ - consistency
- alt_build
- static_alt_build
- osx_alt_build
diff --git a/CODE-OF-CONDUCT.md b/CODE-OF-CONDUCT.md
index 850e68db0..b23672b1a 100644
--- a/CODE-OF-CONDUCT.md
+++ b/CODE-OF-CONDUCT.md
@@ -1,3 +1,3 @@
-## The Libpod Project Community Code of Conduct
+## The Podman Project Community Code of Conduct
-The Libpod project which includes Podman, follows the [Containers Community Code of Conduct](https://github.com/containers/common/blob/master/CODE-OF-CONDUCT.md).
+The Podman project which includes Libpod, follows the [Containers Community Code of Conduct](https://github.com/containers/common/blob/master/CODE-OF-CONDUCT.md).
diff --git a/Makefile b/Makefile
index bdedd046f..dfa36e3ef 100644
--- a/Makefile
+++ b/Makefile
@@ -86,7 +86,7 @@ PODMAN_SERVER_LOG ?=
# If GOPATH not specified, use one in the local directory
ifeq ($(GOPATH),)
-export GOPATH := $(CURDIR)/_output
+export GOPATH := $(HOME)/go
unexport GOBIN
endif
FIRST_GOPATH := $(firstword $(subst :, ,$(GOPATH)))
@@ -98,6 +98,8 @@ ifeq ($(GOBIN),)
GOBIN := $(FIRST_GOPATH)/bin
endif
+export PATH := $(PATH):$(GOBIN)
+
GOMD2MAN ?= $(shell command -v go-md2man || echo '$(GOBIN)/go-md2man')
CROSS_BUILD_TARGETS := \
@@ -206,7 +208,7 @@ endif
podman: bin/podman
.PHONY: bin/podman-remote
-bin/podman-remote: .gopathok .generate-bindings $(SOURCES) go.mod go.sum ## Build with podman on remote environment
+bin/podman-remote: .gopathok $(SOURCES) go.mod go.sum ## Build with podman on remote environment
$(GO) build $(BUILDFLAGS) -gcflags '$(GCFLAGS)' -asmflags '$(ASMFLAGS)' -ldflags '$(LDFLAGS_PODMAN)' -tags "${REMOTETAGS}" -o $@ ./cmd/podman
.PHONY: bin/podman-remote-static
@@ -277,7 +279,6 @@ clean: ## Clean artifacts
libpod/container_easyjson.go \
libpod/pod_easyjson.go \
.install.goimports \
- .generate-bindings \
docs/build
make -C docs clean
@@ -463,12 +464,11 @@ podman-remote-%-release:
rm -f release.txt
$(MAKE) podman-remote-release-$*.zip
-BINDINGS_SOURCE = $(wildcard pkg/bindings/**/types.go)
-.generate-bindings: $(BINDINGS_SOURCE)
+.PHONY: generate-bindings
+generate-bindings:
ifneq ($(shell uname -s), Darwin)
- $(GO) generate -mod=vendor ./pkg/bindings/... ;
+ GO111MODULE=off $(GO) generate ./pkg/bindings/... ;
endif
- touch .generate-bindings
.PHONY: docker-docs
docker-docs: docs
diff --git a/cmd/podman/common/create.go b/cmd/podman/common/create.go
index 280175f95..17fba5427 100644
--- a/cmd/podman/common/create.go
+++ b/cmd/podman/common/create.go
@@ -402,7 +402,7 @@ func DefineCreateFlags(cmd *cobra.Command, cf *ContainerCLIOpts) {
logDriverFlagName := "log-driver"
createFlags.StringVar(
&cf.LogDriver,
- logDriverFlagName, "",
+ logDriverFlagName, logDriver(),
"Logging driver for the container",
)
_ = cmd.RegisterFlagCompletionFunc(logDriverFlagName, AutocompleteLogDriver)
diff --git a/cmd/podman/common/create_opts.go b/cmd/podman/common/create_opts.go
index 9635f4135..f252618ce 100644
--- a/cmd/podman/common/create_opts.go
+++ b/cmd/podman/common/create_opts.go
@@ -517,3 +517,10 @@ func volumes() []string {
}
return nil
}
+
+func logDriver() string {
+ if !registry.IsRemote() {
+ return containerConfig.Containers.LogDriver
+ }
+ return ""
+}
diff --git a/cmd/podman/common/specgen.go b/cmd/podman/common/specgen.go
index 287836d9f..4cc53a630 100644
--- a/cmd/podman/common/specgen.go
+++ b/cmd/podman/common/specgen.go
@@ -463,7 +463,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
if s.LogConfiguration == nil {
s.LogConfiguration = &specgen.LogConfig{}
}
- s.LogConfiguration.Driver = define.KubernetesLogging
+
if ld := c.LogDriver; len(ld) > 0 {
s.LogConfiguration.Driver = ld
}
diff --git a/cmd/podman/containers/rm.go b/cmd/podman/containers/rm.go
index ee9dc4c78..ea616b6e5 100644
--- a/cmd/podman/containers/rm.go
+++ b/cmd/podman/containers/rm.go
@@ -3,6 +3,7 @@ package containers
import (
"context"
"fmt"
+ "io/ioutil"
"strings"
"github.com/containers/common/pkg/completion"
@@ -54,6 +55,7 @@ var (
var (
rmOptions = entities.RmOptions{}
+ cidFiles = []string{}
)
func rmFlags(cmd *cobra.Command) {
@@ -65,7 +67,7 @@ func rmFlags(cmd *cobra.Command) {
flags.BoolVarP(&rmOptions.Volumes, "volumes", "v", false, "Remove anonymous volumes associated with the container")
cidfileFlagName := "cidfile"
- flags.StringArrayVarP(&rmOptions.CIDFiles, cidfileFlagName, "", nil, "Read the container ID from the file")
+ flags.StringArrayVar(&cidFiles, cidfileFlagName, nil, "Read the container ID from the file")
_ = cmd.RegisterFlagCompletionFunc(cidfileFlagName, completion.AutocompleteDefault)
if !registry.IsRemote() {
@@ -92,7 +94,16 @@ func init() {
validate.AddLatestFlag(containerRmCommand, &rmOptions.Latest)
}
-func rm(_ *cobra.Command, args []string) error {
+func rm(cmd *cobra.Command, args []string) error {
+ for _, cidFile := range cidFiles {
+ content, err := ioutil.ReadFile(string(cidFile))
+ if err != nil {
+ return errors.Wrap(err, "error reading CIDFile")
+ }
+ id := strings.Split(string(content), "\n")[0]
+ args = append(args, id)
+ }
+
return removeContainers(args, rmOptions, true)
}
diff --git a/contrib/cirrus/runner.sh b/contrib/cirrus/runner.sh
index e968fac45..d9f91c7af 100755
--- a/contrib/cirrus/runner.sh
+++ b/contrib/cirrus/runner.sh
@@ -146,9 +146,11 @@ function _run_swagger() {
cp -v $GOSRC/pkg/api/swagger.yaml $GOSRC/
}
-function _run_vendor() {
+function _run_consistency() {
make vendor
- ./hack/tree_status.sh
+ SUGGESTION="run 'make vendor' and commit all changes" ./hack/tree_status.sh
+ make generate-bindings
+ SUGGESTION="run 'make generate-bindings' and commit all changes" ./hack/tree_status.sh
}
function _run_build() {
diff --git a/contrib/cirrus/setup_environment.sh b/contrib/cirrus/setup_environment.sh
index 5c6f05ac0..7b49caba0 100755
--- a/contrib/cirrus/setup_environment.sh
+++ b/contrib/cirrus/setup_environment.sh
@@ -214,7 +214,7 @@ case "$TEST_FLAVOR" in
install_test_configs
;;
- vendor) make clean ;;
+ consistency) make clean ;;
release) ;;
*) die_unknown TEST_FLAVOR
esac
diff --git a/libpod/network/create.go b/libpod/network/create.go
index 094fbe349..e7f65358b 100644
--- a/libpod/network/create.go
+++ b/libpod/network/create.go
@@ -23,7 +23,7 @@ func Create(name string, options entities.NetworkCreateOptions, runtimeConfig *c
return nil, err
}
// Acquire a lock for CNI
- l, err := acquireCNILock(filepath.Join(runtimeConfig.Engine.TmpDir, LockFileName))
+ l, err := acquireCNILock(runtimeConfig)
if err != nil {
return nil, err
}
diff --git a/libpod/network/lock.go b/libpod/network/lock.go
index 0395359eb..037f41efa 100644
--- a/libpod/network/lock.go
+++ b/libpod/network/lock.go
@@ -1,6 +1,10 @@
package network
import (
+ "os"
+ "path/filepath"
+
+ "github.com/containers/common/pkg/config"
"github.com/containers/storage"
)
@@ -8,8 +12,13 @@ import (
// delete cases to avoid unwanted collisions in network names.
// TODO this uses a file lock and should be converted to shared memory
// when we have a more general shared memory lock in libpod
-func acquireCNILock(lockPath string) (*CNILock, error) {
- l, err := storage.GetLockfile(lockPath)
+func acquireCNILock(config *config.Config) (*CNILock, error) {
+ cniDir := GetCNIConfDir(config)
+ err := os.MkdirAll(cniDir, 0755)
+ if err != nil {
+ return nil, err
+ }
+ l, err := storage.GetLockfile(filepath.Join(cniDir, LockFileName))
if err != nil {
return nil, err
}
diff --git a/libpod/network/network.go b/libpod/network/network.go
index 89f0b67ac..0fb878b18 100644
--- a/libpod/network/network.go
+++ b/libpod/network/network.go
@@ -6,7 +6,6 @@ import (
"encoding/json"
"net"
"os"
- "path/filepath"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/plugins/plugins/ipam/host-local/backend/allocator"
@@ -172,7 +171,7 @@ func ValidateUserNetworkIsAvailable(config *config.Config, userNet *net.IPNet) e
// RemoveNetwork removes a given network by name. If the network has container associated with it, that
// must be handled outside the context of this.
func RemoveNetwork(config *config.Config, name string) error {
- l, err := acquireCNILock(filepath.Join(config.Engine.TmpDir, LockFileName))
+ l, err := acquireCNILock(config)
if err != nil {
return err
}
diff --git a/pkg/api/handlers/compat/containers.go b/pkg/api/handlers/compat/containers.go
index 6e1945db1..aa12afc82 100644
--- a/pkg/api/handlers/compat/containers.go
+++ b/pkg/api/handlers/compat/containers.go
@@ -14,7 +14,9 @@ import (
"github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/pkg/api/handlers"
"github.com/containers/podman/v2/pkg/api/handlers/utils"
+ "github.com/containers/podman/v2/pkg/domain/entities"
"github.com/containers/podman/v2/pkg/domain/filters"
+ "github.com/containers/podman/v2/pkg/domain/infra/abi"
"github.com/containers/podman/v2/pkg/ps"
"github.com/containers/podman/v2/pkg/signal"
"github.com/docker/docker/api/types"
@@ -29,9 +31,11 @@ import (
func RemoveContainer(w http.ResponseWriter, r *http.Request) {
decoder := r.Context().Value("decoder").(*schema.Decoder)
query := struct {
- Force bool `schema:"force"`
- Vols bool `schema:"v"`
- Link bool `schema:"link"`
+ All bool `schema:"all"`
+ Force bool `schema:"force"`
+ Ignore bool `schema:"ignore"`
+ Link bool `schema:"link"`
+ Volumes bool `schema:"v"`
}{
// override any golang type defaults
}
@@ -49,34 +53,31 @@ func RemoveContainer(w http.ResponseWriter, r *http.Request) {
}
runtime := r.Context().Value("runtime").(*libpod.Runtime)
+ // Now use the ABI implementation to prevent us from having duplicate
+ // code.
+ containerEngine := abi.ContainerEngine{Libpod: runtime}
name := utils.GetName(r)
- con, err := runtime.LookupContainer(name)
- if err != nil && errors.Cause(err) == define.ErrNoSuchCtr {
- // Failed to get container. If force is specified, get the container's ID
- // and evict it
- if !query.Force {
+ options := entities.RmOptions{
+ All: query.All,
+ Force: query.Force,
+ Volumes: query.Volumes,
+ Ignore: query.Ignore,
+ }
+ report, err := containerEngine.ContainerRm(r.Context(), []string{name}, options)
+ if err != nil {
+ if errors.Cause(err) == define.ErrNoSuchCtr {
utils.ContainerNotFound(w, name, err)
return
}
- if _, err := runtime.EvictContainer(r.Context(), name, query.Vols); err != nil {
- if errors.Cause(err) == define.ErrNoSuchCtr {
- logrus.Debugf("Ignoring error (--allow-missing): %q", err)
- w.WriteHeader(http.StatusNoContent)
- return
- }
- logrus.Warn(errors.Wrapf(err, "failed to evict container: %q", name))
- utils.InternalServerError(w, err)
- return
- }
- w.WriteHeader(http.StatusNoContent)
+ utils.InternalServerError(w, err)
return
}
-
- if err := runtime.RemoveContainer(r.Context(), con, query.Force, query.Vols); err != nil {
- utils.InternalServerError(w, err)
+ if report[0].Err != nil {
+ utils.InternalServerError(w, report[0].Err)
return
}
+
utils.WriteResponse(w, http.StatusNoContent, nil)
}
@@ -326,6 +327,11 @@ func LibpodToContainerJSON(l *libpod.Container, sz bool) (*types.ContainerJSON,
state.Running = true
}
+ // docker calls the configured state "created"
+ if state.Status == define.ContainerStateConfigured.String() {
+ state.Status = define.ContainerStateCreated.String()
+ }
+
formatCapabilities(inspect.HostConfig.CapDrop)
formatCapabilities(inspect.HostConfig.CapAdd)
@@ -337,6 +343,11 @@ func LibpodToContainerJSON(l *libpod.Container, sz bool) (*types.ContainerJSON,
if err := json.Unmarshal(h, &hc); err != nil {
return nil, err
}
+
+ // k8s-file == json-file
+ if hc.LogConfig.Type == define.KubernetesLogging {
+ hc.LogConfig.Type = define.JSONLogging
+ }
g, err := json.Marshal(inspect.GraphDriver)
if err != nil {
return nil, err
diff --git a/pkg/bindings/containers/containers.go b/pkg/bindings/containers/containers.go
index 73e4d1d3d..40fcfbded 100644
--- a/pkg/bindings/containers/containers.go
+++ b/pkg/bindings/containers/containers.go
@@ -71,8 +71,10 @@ func Prune(ctx context.Context, options *PruneOptions) ([]*reports.PruneReport,
}
// Remove removes a container from local storage. The force bool designates
-// that the container should be removed forcibly (example, even it is running). The volumes
-// bool dictates that a container's volumes should also be removed.
+// that the container should be removed forcibly (example, even it is running).
+// The volumes bool dictates that a container's volumes should also be removed.
+// The All option indicates that all containers should be removed
+// The Ignore option indicates that if a container did not exist, ignore the error
func Remove(ctx context.Context, nameOrID string, options *RemoveOptions) error {
if options == nil {
options = new(RemoveOptions)
@@ -85,9 +87,15 @@ func Remove(ctx context.Context, nameOrID string, options *RemoveOptions) error
if v := options.GetVolumes(); options.Changed("Volumes") {
params.Set("v", strconv.FormatBool(v))
}
+ if all := options.GetAll(); options.Changed("All") {
+ params.Set("all", strconv.FormatBool(all))
+ }
if force := options.GetForce(); options.Changed("Force") {
params.Set("force", strconv.FormatBool(force))
}
+ if ignore := options.GetIgnore(); options.Changed("Ignore") {
+ params.Set("ignore", strconv.FormatBool(ignore))
+ }
response, err := conn.DoRequest(nil, http.MethodDelete, "/containers/%s", params, nil, nameOrID)
if err != nil {
return err
diff --git a/pkg/bindings/containers/types.go b/pkg/bindings/containers/types.go
index 43cb58a54..24604fa83 100644
--- a/pkg/bindings/containers/types.go
+++ b/pkg/bindings/containers/types.go
@@ -122,6 +122,8 @@ type PruneOptions struct {
//go:generate go run ../generator/generator.go RemoveOptions
// RemoveOptions are optional options for removing containers
type RemoveOptions struct {
+ All *bool
+ Ignore *bool
Force *bool
Volumes *bool
}
diff --git a/pkg/bindings/containers/types_remove_options.go b/pkg/bindings/containers/types_remove_options.go
index e21fb41f7..3ef32fa03 100644
--- a/pkg/bindings/containers/types_remove_options.go
+++ b/pkg/bindings/containers/types_remove_options.go
@@ -87,6 +87,38 @@ func (o *RemoveOptions) ToParams() (url.Values, error) {
return params, nil
}
+// WithAll
+func (o *RemoveOptions) WithAll(value bool) *RemoveOptions {
+ v := &value
+ o.All = v
+ return o
+}
+
+// GetAll
+func (o *RemoveOptions) GetAll() bool {
+ var all bool
+ if o.All == nil {
+ return all
+ }
+ return *o.All
+}
+
+// WithIgnore
+func (o *RemoveOptions) WithIgnore(value bool) *RemoveOptions {
+ v := &value
+ o.Ignore = v
+ return o
+}
+
+// GetIgnore
+func (o *RemoveOptions) GetIgnore() bool {
+ var ignore bool
+ if o.Ignore == nil {
+ return ignore
+ }
+ return *o.Ignore
+}
+
// WithForce
func (o *RemoveOptions) WithForce(value bool) *RemoveOptions {
v := &value
diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go
index d8576c101..4c1bd6a7d 100644
--- a/pkg/domain/entities/containers.go
+++ b/pkg/domain/entities/containers.go
@@ -128,12 +128,11 @@ type RestartReport struct {
}
type RmOptions struct {
- All bool
- CIDFiles []string
- Force bool
- Ignore bool
- Latest bool
- Volumes bool
+ All bool
+ Force bool
+ Ignore bool
+ Latest bool
+ Volumes bool
}
type RmReport struct {
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go
index a8f4d44a8..48a32817d 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -264,30 +264,30 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
reports := []*entities.RmReport{}
names := namesOrIds
- for _, cidFile := range options.CIDFiles {
- content, err := ioutil.ReadFile(cidFile)
- if err != nil {
- return nil, errors.Wrap(err, "error reading CIDFile")
- }
- id := strings.Split(string(content), "\n")[0]
- names = append(names, id)
- }
-
// Attempt to remove named containers directly from storage, if container is defined in libpod
// this will fail and code will fall through to removing the container from libpod.`
tmpNames := []string{}
for _, ctr := range names {
report := entities.RmReport{Id: ctr}
- if err := ic.Libpod.RemoveStorageContainer(ctr, options.Force); err != nil {
+ report.Err = ic.Libpod.RemoveStorageContainer(ctr, options.Force)
+ switch errors.Cause(report.Err) {
+ case nil:
// remove container names that we successfully deleted
- tmpNames = append(tmpNames, ctr)
- } else {
reports = append(reports, &report)
+ case define.ErrNoSuchCtr:
+ // There is still a potential this is a libpod container
+ tmpNames = append(tmpNames, ctr)
+ default:
+ if _, err := ic.Libpod.LookupContainer(ctr); errors.Cause(err) == define.ErrNoSuchCtr {
+ // remove container failed, but not a libpod container
+ reports = append(reports, &report)
+ continue
+ }
+ // attempt to remove as a libpod container
+ tmpNames = append(tmpNames, ctr)
}
}
- if len(tmpNames) < len(names) {
- names = tmpNames
- }
+ names = tmpNames
ctrs, err := getContainersByContext(options.All, options.Latest, names, ic.Libpod)
if err != nil && !(options.Ignore && errors.Cause(err) == define.ErrNoSuchCtr) {
diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go
index 84a07f8e9..524b29553 100644
--- a/pkg/domain/infra/tunnel/containers.go
+++ b/pkg/domain/infra/tunnel/containers.go
@@ -173,14 +173,6 @@ func (ic *ContainerEngine) ContainerRestart(ctx context.Context, namesOrIds []st
}
func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string, opts entities.RmOptions) ([]*entities.RmReport, error) {
- for _, cidFile := range opts.CIDFiles {
- content, err := ioutil.ReadFile(cidFile)
- if err != nil {
- return nil, errors.Wrap(err, "error reading CIDFile")
- }
- id := strings.Split(string(content), "\n")[0]
- namesOrIds = append(namesOrIds, id)
- }
ctrs, err := getContainersByContext(ic.ClientCtx, opts.All, opts.Ignore, namesOrIds)
if err != nil {
return nil, err
diff --git a/pkg/specgen/generate/container.go b/pkg/specgen/generate/container.go
index 2feb1d3b2..cc3f7928c 100644
--- a/pkg/specgen/generate/container.go
+++ b/pkg/specgen/generate/container.go
@@ -257,6 +257,14 @@ func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerat
}
}
+ if s.LogConfiguration == nil {
+ s.LogConfiguration = &specgen.LogConfig{}
+ }
+ // set log-driver from common if not already set
+ if len(s.LogConfiguration.Driver) < 1 {
+ s.LogConfiguration.Driver = rtc.Containers.LogDriver
+ }
+
warnings, err := verifyContainerResources(s)
if err != nil {
return warnings, err
diff --git a/pkg/systemd/generate/common.go b/pkg/systemd/generate/common.go
index 8901298db..de6751a17 100644
--- a/pkg/systemd/generate/common.go
+++ b/pkg/systemd/generate/common.go
@@ -30,14 +30,14 @@ func validateRestartPolicy(restart string) error {
return errors.Errorf("%s is not a valid restart policy", restart)
}
-const headerTemplate = `# {{.ServiceName}}.service
-# autogenerated by Podman {{.PodmanVersion}}
-{{- if .TimeStamp}}
-# {{.TimeStamp}}
-{{- end}}
+const headerTemplate = `# {{{{.ServiceName}}}}.service
+# autogenerated by Podman {{{{.PodmanVersion}}}}
+{{{{- if .TimeStamp}}}}
+# {{{{.TimeStamp}}}}
+{{{{- end}}}}
[Unit]
-Description=Podman {{.ServiceName}}.service
+Description=Podman {{{{.ServiceName}}}}.service
Documentation=man:podman-generate-systemd(1)
Wants=network.target
After=network-online.target
diff --git a/pkg/systemd/generate/containers.go b/pkg/systemd/generate/containers.go
index b64b2593c..5f52b0a77 100644
--- a/pkg/systemd/generate/containers.go
+++ b/pkg/systemd/generate/containers.go
@@ -72,22 +72,22 @@ type containerInfo struct {
}
const containerTemplate = headerTemplate + `
-{{- if .BoundToServices}}
-BindsTo={{- range $index, $value := .BoundToServices -}}{{if $index}} {{end}}{{ $value }}.service{{end}}
-After={{- range $index, $value := .BoundToServices -}}{{if $index}} {{end}}{{ $value }}.service{{end}}
-{{- end}}
+{{{{- if .BoundToServices}}}}
+BindsTo={{{{- range $index, $value := .BoundToServices -}}}}{{{{if $index}}}} {{{{end}}}}{{{{ $value }}}}.service{{{{end}}}}
+After={{{{- range $index, $value := .BoundToServices -}}}}{{{{if $index}}}} {{{{end}}}}{{{{ $value }}}}.service{{{{end}}}}
+{{{{- end}}}}
[Service]
-Environment={{.EnvVariable}}=%n
-Restart={{.RestartPolicy}}
-TimeoutStopSec={{.TimeoutStopSec}}
-{{- if .ExecStartPre}}
-ExecStartPre={{.ExecStartPre}}
-{{- end}}
-ExecStart={{.ExecStart}}
-ExecStop={{.ExecStop}}
-ExecStopPost={{.ExecStopPost}}
-PIDFile={{.PIDFile}}
+Environment={{{{.EnvVariable}}}}=%n
+Restart={{{{.RestartPolicy}}}}
+TimeoutStopSec={{{{.TimeoutStopSec}}}}
+{{{{- if .ExecStartPre}}}}
+ExecStartPre={{{{.ExecStartPre}}}}
+{{{{- end}}}}
+ExecStart={{{{.ExecStart}}}}
+ExecStop={{{{.ExecStop}}}}
+ExecStopPost={{{{.ExecStopPost}}}}
+PIDFile={{{{.PIDFile}}}}
Type=forking
[Install]
@@ -173,9 +173,9 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst
}
info.EnvVariable = EnvVariable
- info.ExecStart = "{{.Executable}} start {{.ContainerNameOrID}}"
- info.ExecStop = "{{.Executable}} stop {{if (ge .StopTimeout 0)}}-t {{.StopTimeout}}{{end}} {{.ContainerNameOrID}}"
- info.ExecStopPost = "{{.Executable}} stop {{if (ge .StopTimeout 0)}}-t {{.StopTimeout}}{{end}} {{.ContainerNameOrID}}"
+ info.ExecStart = "{{{{.Executable}}}} start {{{{.ContainerNameOrID}}}}"
+ info.ExecStop = "{{{{.Executable}}}} stop {{{{if (ge .StopTimeout 0)}}}}-t {{{{.StopTimeout}}}}{{{{end}}}} {{{{.ContainerNameOrID}}}}"
+ info.ExecStopPost = "{{{{.Executable}}}} stop {{{{if (ge .StopTimeout 0)}}}}-t {{{{.StopTimeout}}}}{{{{end}}}} {{{{.ContainerNameOrID}}}}"
// Assemble the ExecStart command when creating a new container.
//
@@ -209,8 +209,8 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst
}
startCommand = append(startCommand,
"run",
- "--conmon-pidfile", "{{.PIDFile}}",
- "--cidfile", "{{.ContainerIDFile}}",
+ "--conmon-pidfile", "{{{{.PIDFile}}}}",
+ "--cidfile", "{{{{.ContainerIDFile}}}}",
"--cgroups=no-conmon",
)
// If the container is in a pod, make sure that the
@@ -281,10 +281,10 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst
startCommand = append(startCommand, remainingCmd...)
startCommand = quoteArguments(startCommand)
- info.ExecStartPre = "/bin/rm -f {{.PIDFile}} {{.ContainerIDFile}}"
+ info.ExecStartPre = "/bin/rm -f {{{{.PIDFile}}}} {{{{.ContainerIDFile}}}}"
info.ExecStart = strings.Join(startCommand, " ")
- info.ExecStop = "{{.Executable}} {{if .RootFlags}}{{ .RootFlags}} {{end}}stop --ignore --cidfile {{.ContainerIDFile}} {{if (ge .StopTimeout 0)}}-t {{.StopTimeout}}{{end}}"
- info.ExecStopPost = "{{.Executable}} {{if .RootFlags}}{{ .RootFlags}} {{end}}rm --ignore -f --cidfile {{.ContainerIDFile}}"
+ info.ExecStop = "{{{{.Executable}}}} {{{{if .RootFlags}}}}{{{{ .RootFlags}}}} {{{{end}}}}stop --ignore --cidfile {{{{.ContainerIDFile}}}} {{{{if (ge .StopTimeout 0)}}}}-t {{{{.StopTimeout}}}}{{{{end}}}}"
+ info.ExecStopPost = "{{{{.Executable}}}} {{{{if .RootFlags}}}}{{{{ .RootFlags}}}} {{{{end}}}}rm --ignore -f --cidfile {{{{.ContainerIDFile}}}}"
}
info.TimeoutStopSec = minTimeoutStopSec + info.StopTimeout
@@ -307,7 +307,7 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst
// generation. That's especially needed for embedding the PID and ID
// files in other fields which will eventually get replaced in the 2nd
// template execution.
- templ, err := template.New("container_template").Parse(containerTemplate)
+ templ, err := template.New("container_template").Delims("{{{{", "}}}}").Parse(containerTemplate)
if err != nil {
return "", errors.Wrap(err, "error parsing systemd service template")
}
@@ -318,7 +318,7 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst
}
// Now parse the generated template (i.e., buf) and execute it.
- templ, err = template.New("container_template").Parse(buf.String())
+ templ, err = template.New("container_template").Delims("{{{{", "}}}}").Parse(buf.String())
if err != nil {
return "", errors.Wrap(err, "error parsing systemd service template")
}
diff --git a/pkg/systemd/generate/containers_test.go b/pkg/systemd/generate/containers_test.go
index c8e65bfe3..96d95644b 100644
--- a/pkg/systemd/generate/containers_test.go
+++ b/pkg/systemd/generate/containers_test.go
@@ -329,6 +329,29 @@ Type=forking
WantedBy=multi-user.target default.target
`
+ goodNewWithJournaldTag := `# jadda-jadda.service
+# autogenerated by Podman CI
+
+[Unit]
+Description=Podman jadda-jadda.service
+Documentation=man:podman-generate-systemd(1)
+Wants=network.target
+After=network-online.target
+
+[Service]
+Environment=PODMAN_SYSTEMD_UNIT=%n
+Restart=always
+TimeoutStopSec=70
+ExecStartPre=/bin/rm -f %t/jadda-jadda.pid %t/jadda-jadda.ctr-id
+ExecStart=/usr/bin/podman run --conmon-pidfile %t/jadda-jadda.pid --cidfile %t/jadda-jadda.ctr-id --cgroups=no-conmon -d --replace --name test --log-driver=journald --log-opt=tag={{.Name}} awesome-image:latest
+ExecStop=/usr/bin/podman stop --ignore --cidfile %t/jadda-jadda.ctr-id -t 10
+ExecStopPost=/usr/bin/podman rm --ignore -f --cidfile %t/jadda-jadda.ctr-id
+PIDFile=%t/jadda-jadda.pid
+Type=forking
+
+[Install]
+WantedBy=multi-user.target default.target
+`
tests := []struct {
name string
info containerInfo
@@ -608,6 +631,22 @@ WantedBy=multi-user.target default.target
true,
false,
},
+ {"good with journald log tag (see #9034)",
+ containerInfo{
+ Executable: "/usr/bin/podman",
+ ServiceName: "jadda-jadda",
+ ContainerNameOrID: "jadda-jadda",
+ RestartPolicy: "always",
+ PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
+ StopTimeout: 10,
+ PodmanVersion: "CI",
+ CreateCommand: []string{"I'll get stripped", "create", "--name", "test", "--log-driver=journald", "--log-opt=tag={{.Name}}", "awesome-image:latest"},
+ EnvVariable: EnvVariable,
+ },
+ goodNewWithJournaldTag,
+ true,
+ false,
+ },
}
for _, tt := range tests {
test := tt
diff --git a/pkg/systemd/generate/pods.go b/pkg/systemd/generate/pods.go
index 7678a240f..c7e3aa955 100644
--- a/pkg/systemd/generate/pods.go
+++ b/pkg/systemd/generate/pods.go
@@ -72,23 +72,23 @@ type podInfo struct {
ExecStopPost string
}
-const podTemplate = headerTemplate + `Requires={{- range $index, $value := .RequiredServices -}}{{if $index}} {{end}}{{ $value }}.service{{end}}
-Before={{- range $index, $value := .RequiredServices -}}{{if $index}} {{end}}{{ $value }}.service{{end}}
+const podTemplate = headerTemplate + `Requires={{{{- range $index, $value := .RequiredServices -}}}}{{{{if $index}}}} {{{{end}}}}{{{{ $value }}}}.service{{{{end}}}}
+Before={{{{- range $index, $value := .RequiredServices -}}}}{{{{if $index}}}} {{{{end}}}}{{{{ $value }}}}.service{{{{end}}}}
[Service]
-Environment={{.EnvVariable}}=%n
-Restart={{.RestartPolicy}}
-TimeoutStopSec={{.TimeoutStopSec}}
-{{- if .ExecStartPre1}}
-ExecStartPre={{.ExecStartPre1}}
-{{- end}}
-{{- if .ExecStartPre2}}
-ExecStartPre={{.ExecStartPre2}}
-{{- end}}
-ExecStart={{.ExecStart}}
-ExecStop={{.ExecStop}}
-ExecStopPost={{.ExecStopPost}}
-PIDFile={{.PIDFile}}
+Environment={{{{.EnvVariable}}}}=%n
+Restart={{{{.RestartPolicy}}}}
+TimeoutStopSec={{{{.TimeoutStopSec}}}}
+{{{{- if .ExecStartPre1}}}}
+ExecStartPre={{{{.ExecStartPre1}}}}
+{{{{- end}}}}
+{{{{- if .ExecStartPre2}}}}
+ExecStartPre={{{{.ExecStartPre2}}}}
+{{{{- end}}}}
+ExecStart={{{{.ExecStart}}}}
+ExecStop={{{{.ExecStop}}}}
+ExecStopPost={{{{.ExecStopPost}}}}
+PIDFile={{{{.PIDFile}}}}
Type=forking
[Install]
@@ -236,9 +236,9 @@ func executePodTemplate(info *podInfo, options entities.GenerateSystemdOptions)
}
info.EnvVariable = EnvVariable
- info.ExecStart = "{{.Executable}} start {{.InfraNameOrID}}"
- info.ExecStop = "{{.Executable}} stop {{if (ge .StopTimeout 0)}}-t {{.StopTimeout}}{{end}} {{.InfraNameOrID}}"
- info.ExecStopPost = "{{.Executable}} stop {{if (ge .StopTimeout 0)}}-t {{.StopTimeout}}{{end}} {{.InfraNameOrID}}"
+ info.ExecStart = "{{{{.Executable}}}} start {{{{.InfraNameOrID}}}}"
+ info.ExecStop = "{{{{.Executable}}}} stop {{{{if (ge .StopTimeout 0)}}}}-t {{{{.StopTimeout}}}}{{{{end}}}} {{{{.InfraNameOrID}}}}"
+ info.ExecStopPost = "{{{{.Executable}}}} stop {{{{if (ge .StopTimeout 0)}}}}-t {{{{.StopTimeout}}}}{{{{end}}}} {{{{.InfraNameOrID}}}}"
// Assemble the ExecStart command when creating a new pod.
//
@@ -278,8 +278,8 @@ func executePodTemplate(info *podInfo, options entities.GenerateSystemdOptions)
startCommand = append(startCommand, podRootArgs...)
startCommand = append(startCommand,
[]string{"pod", "create",
- "--infra-conmon-pidfile", "{{.PIDFile}}",
- "--pod-id-file", "{{.PodIDFile}}"}...)
+ "--infra-conmon-pidfile", "{{{{.PIDFile}}}}",
+ "--pod-id-file", "{{{{.PodIDFile}}}}"}...)
// Presence check for certain flags/options.
fs := pflag.NewFlagSet("args", pflag.ContinueOnError)
@@ -308,11 +308,11 @@ func executePodTemplate(info *podInfo, options entities.GenerateSystemdOptions)
startCommand = append(startCommand, podCreateArgs...)
startCommand = quoteArguments(startCommand)
- info.ExecStartPre1 = "/bin/rm -f {{.PIDFile}} {{.PodIDFile}}"
+ info.ExecStartPre1 = "/bin/rm -f {{{{.PIDFile}}}} {{{{.PodIDFile}}}}"
info.ExecStartPre2 = strings.Join(startCommand, " ")
- info.ExecStart = "{{.Executable}} {{if .RootFlags}}{{ .RootFlags}} {{end}}pod start --pod-id-file {{.PodIDFile}}"
- info.ExecStop = "{{.Executable}} {{if .RootFlags}}{{ .RootFlags}} {{end}}pod stop --ignore --pod-id-file {{.PodIDFile}} {{if (ge .StopTimeout 0)}}-t {{.StopTimeout}}{{end}}"
- info.ExecStopPost = "{{.Executable}} {{if .RootFlags}}{{ .RootFlags}} {{end}}pod rm --ignore -f --pod-id-file {{.PodIDFile}}"
+ info.ExecStart = "{{{{.Executable}}}} {{{{if .RootFlags}}}}{{{{ .RootFlags}}}} {{{{end}}}}pod start --pod-id-file {{{{.PodIDFile}}}}"
+ info.ExecStop = "{{{{.Executable}}}} {{{{if .RootFlags}}}}{{{{ .RootFlags}}}} {{{{end}}}}pod stop --ignore --pod-id-file {{{{.PodIDFile}}}} {{{{if (ge .StopTimeout 0)}}}}-t {{{{.StopTimeout}}}}{{{{end}}}}"
+ info.ExecStopPost = "{{{{.Executable}}}} {{{{if .RootFlags}}}}{{{{ .RootFlags}}}} {{{{end}}}}pod rm --ignore -f --pod-id-file {{{{.PodIDFile}}}}"
}
info.TimeoutStopSec = minTimeoutStopSec + info.StopTimeout
@@ -334,7 +334,7 @@ func executePodTemplate(info *podInfo, options entities.GenerateSystemdOptions)
// generation. That's especially needed for embedding the PID and ID
// files in other fields which will eventually get replaced in the 2nd
// template execution.
- templ, err := template.New("pod_template").Parse(podTemplate)
+ templ, err := template.New("pod_template").Delims("{{{{", "}}}}").Parse(podTemplate)
if err != nil {
return "", errors.Wrap(err, "error parsing systemd service template")
}
@@ -345,7 +345,7 @@ func executePodTemplate(info *podInfo, options entities.GenerateSystemdOptions)
}
// Now parse the generated template (i.e., buf) and execute it.
- templ, err = template.New("pod_template").Parse(buf.String())
+ templ, err = template.New("pod_template").Delims("{{{{", "}}}}").Parse(buf.String())
if err != nil {
return "", errors.Wrap(err, "error parsing systemd service template")
}
diff --git a/pkg/systemd/generate/pods_test.go b/pkg/systemd/generate/pods_test.go
index 1c6330160..2b430226b 100644
--- a/pkg/systemd/generate/pods_test.go
+++ b/pkg/systemd/generate/pods_test.go
@@ -143,6 +143,33 @@ Type=forking
WantedBy=multi-user.target default.target
`
+ podNewLabelWithCurlyBraces := `# pod-123abc.service
+# autogenerated by Podman CI
+
+[Unit]
+Description=Podman pod-123abc.service
+Documentation=man:podman-generate-systemd(1)
+Wants=network.target
+After=network-online.target
+Requires=container-1.service container-2.service
+Before=container-1.service container-2.service
+
+[Service]
+Environment=PODMAN_SYSTEMD_UNIT=%n
+Restart=on-failure
+TimeoutStopSec=70
+ExecStartPre=/bin/rm -f %t/pod-123abc.pid %t/pod-123abc.pod-id
+ExecStartPre=/usr/bin/podman pod create --infra-conmon-pidfile %t/pod-123abc.pid --pod-id-file %t/pod-123abc.pod-id --name foo --label key={{someval}} --replace
+ExecStart=/usr/bin/podman pod start --pod-id-file %t/pod-123abc.pod-id
+ExecStop=/usr/bin/podman pod stop --ignore --pod-id-file %t/pod-123abc.pod-id -t 10
+ExecStopPost=/usr/bin/podman pod rm --ignore -f --pod-id-file %t/pod-123abc.pod-id
+PIDFile=%t/pod-123abc.pid
+Type=forking
+
+[Install]
+WantedBy=multi-user.target default.target
+`
+
tests := []struct {
name string
info podInfo
@@ -230,6 +257,22 @@ WantedBy=multi-user.target default.target
true,
false,
},
+ {"pod --new with double curly braces",
+ podInfo{
+ Executable: "/usr/bin/podman",
+ ServiceName: "pod-123abc",
+ InfraNameOrID: "jadda-jadda-infra",
+ RestartPolicy: "on-failure",
+ PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
+ StopTimeout: 10,
+ PodmanVersion: "CI",
+ RequiredServices: []string{"container-1", "container-2"},
+ CreateCommand: []string{"podman", "pod", "create", "--name", "foo", "--label", "key={{someval}}"},
+ },
+ podNewLabelWithCurlyBraces,
+ true,
+ false,
+ },
}
for _, tt := range tests {
diff --git a/test/e2e/generate_systemd_test.go b/test/e2e/generate_systemd_test.go
index be9727591..606d756b0 100644
--- a/test/e2e/generate_systemd_test.go
+++ b/test/e2e/generate_systemd_test.go
@@ -355,4 +355,25 @@ var _ = Describe("Podman generate systemd", func() {
Expect(session.ExitCode()).To(Equal(0))
Expect(session.IsJSONOutputValid()).To(BeTrue())
})
+
+ It("podman generate systemd --new create command with double curly braces", func() {
+ // Regression test for #9034
+ session := podmanTest.Podman([]string{"create", "--name", "foo", "--log-driver=journald", "--log-opt=tag={{.Name}}", ALPINE})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ session = podmanTest.Podman([]string{"generate", "systemd", "--new", "foo"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.OutputToString()).To(ContainSubstring(" --log-opt=tag={{.Name}} "))
+
+ session = podmanTest.Podman([]string{"pod", "create", "--name", "pod", "--label", "key={{someval}}"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ session = podmanTest.Podman([]string{"generate", "systemd", "--new", "pod"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.OutputToString()).To(ContainSubstring(" --label key={{someval}}"))
+ })
})
diff --git a/test/e2e/network_create_test.go b/test/e2e/network_create_test.go
index 7e9a18ab2..73e18cbce 100644
--- a/test/e2e/network_create_test.go
+++ b/test/e2e/network_create_test.go
@@ -10,6 +10,7 @@ import (
cniversion "github.com/containernetworking/cni/pkg/version"
"github.com/containers/podman/v2/libpod/network"
. "github.com/containers/podman/v2/test/utils"
+ "github.com/containers/storage/pkg/stringid"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/pkg/errors"
@@ -116,18 +117,19 @@ var _ = Describe("Podman network create", func() {
results []network.NcList
)
- nc := podmanTest.Podman([]string{"network", "create", "newname"})
+ netName := "inspectnet-" + stringid.GenerateNonCryptoID()
+ nc := podmanTest.Podman([]string{"network", "create", netName})
nc.WaitWithDefaultTimeout()
+ defer podmanTest.removeCNINetwork(netName)
Expect(nc.ExitCode()).To(BeZero())
- defer podmanTest.removeCNINetwork("newname")
- inspect := podmanTest.Podman([]string{"network", "inspect", "newname"})
+ inspect := podmanTest.Podman([]string{"network", "inspect", netName})
inspect.WaitWithDefaultTimeout()
err := json.Unmarshal([]byte(inspect.OutputToString()), &results)
Expect(err).To(BeNil())
result := results[0]
- Expect(result["name"]).To(Equal("newname"))
+ Expect(result["name"]).To(Equal(netName))
})
@@ -135,21 +137,21 @@ var _ = Describe("Podman network create", func() {
var (
results []network.NcList
)
- nc := podmanTest.Podman([]string{"network", "create", "--subnet", "10.11.12.0/24", "newnetwork"})
+ netName := "subnet-" + stringid.GenerateNonCryptoID()
+ nc := podmanTest.Podman([]string{"network", "create", "--subnet", "10.11.12.0/24", netName})
nc.WaitWithDefaultTimeout()
+ defer podmanTest.removeCNINetwork(netName)
Expect(nc.ExitCode()).To(BeZero())
- defer podmanTest.removeCNINetwork("newnetwork")
-
// Inspect the network configuration
- inspect := podmanTest.Podman([]string{"network", "inspect", "newnetwork"})
+ inspect := podmanTest.Podman([]string{"network", "inspect", netName})
inspect.WaitWithDefaultTimeout()
// JSON the network configuration into something usable
err := json.Unmarshal([]byte(inspect.OutputToString()), &results)
Expect(err).To(BeNil())
result := results[0]
- Expect(result["name"]).To(Equal("newnetwork"))
+ Expect(result["name"]).To(Equal(netName))
// JSON the bridge info
bridgePlugin, err := genericPluginsToBridge(result["plugins"], "bridge")
@@ -161,7 +163,7 @@ var _ = Describe("Podman network create", func() {
// best we can
defer removeNetworkDevice(bridgePlugin.BrName)
- try := podmanTest.Podman([]string{"run", "-it", "--rm", "--network", "newnetwork", ALPINE, "sh", "-c", "ip addr show eth0 | awk ' /inet / {print $2}'"})
+ try := podmanTest.Podman([]string{"run", "-it", "--rm", "--network", netName, ALPINE, "sh", "-c", "ip addr show eth0 | awk ' /inet / {print $2}'"})
try.WaitWithDefaultTimeout()
_, subnet, err := net.ParseCIDR("10.11.12.0/24")
@@ -178,21 +180,21 @@ var _ = Describe("Podman network create", func() {
var (
results []network.NcList
)
- nc := podmanTest.Podman([]string{"network", "create", "--subnet", "fd00:1:2:3:4::/64", "newIPv6network"})
+ netName := "ipv6-" + stringid.GenerateNonCryptoID()
+ nc := podmanTest.Podman([]string{"network", "create", "--subnet", "fd00:1:2:3:4::/64", netName})
nc.WaitWithDefaultTimeout()
+ defer podmanTest.removeCNINetwork(netName)
Expect(nc.ExitCode()).To(BeZero())
- defer podmanTest.removeCNINetwork("newIPv6network")
-
// Inspect the network configuration
- inspect := podmanTest.Podman([]string{"network", "inspect", "newIPv6network"})
+ inspect := podmanTest.Podman([]string{"network", "inspect", netName})
inspect.WaitWithDefaultTimeout()
// JSON the network configuration into something usable
err := json.Unmarshal([]byte(inspect.OutputToString()), &results)
Expect(err).To(BeNil())
result := results[0]
- Expect(result["name"]).To(Equal("newIPv6network"))
+ Expect(result["name"]).To(Equal(netName))
// JSON the bridge info
bridgePlugin, err := genericPluginsToBridge(result["plugins"], "bridge")
@@ -203,7 +205,7 @@ var _ = Describe("Podman network create", func() {
// best we can
defer removeNetworkDevice(bridgePlugin.BrName)
- try := podmanTest.Podman([]string{"run", "-it", "--rm", "--network", "newIPv6network", ALPINE, "sh", "-c", "ip addr show eth0 | grep global | awk ' /inet6 / {print $2}'"})
+ try := podmanTest.Podman([]string{"run", "-it", "--rm", "--network", netName, ALPINE, "sh", "-c", "ip addr show eth0 | grep global | awk ' /inet6 / {print $2}'"})
try.WaitWithDefaultTimeout()
_, subnet, err := net.ParseCIDR("fd00:1:2:3:4::/64")
@@ -219,21 +221,21 @@ var _ = Describe("Podman network create", func() {
var (
results []network.NcList
)
- nc := podmanTest.Podman([]string{"network", "create", "--subnet", "fd00:4:3:2:1::/64", "--ipv6", "newDualStacknetwork"})
+ netName := "dual-" + stringid.GenerateNonCryptoID()
+ nc := podmanTest.Podman([]string{"network", "create", "--subnet", "fd00:4:3:2:1::/64", "--ipv6", netName})
nc.WaitWithDefaultTimeout()
+ defer podmanTest.removeCNINetwork(netName)
Expect(nc.ExitCode()).To(BeZero())
- defer podmanTest.removeCNINetwork("newDualStacknetwork")
-
// Inspect the network configuration
- inspect := podmanTest.Podman([]string{"network", "inspect", "newDualStacknetwork"})
+ inspect := podmanTest.Podman([]string{"network", "inspect", netName})
inspect.WaitWithDefaultTimeout()
// JSON the network configuration into something usable
err := json.Unmarshal([]byte(inspect.OutputToString()), &results)
Expect(err).To(BeNil())
result := results[0]
- Expect(result["name"]).To(Equal("newDualStacknetwork"))
+ Expect(result["name"]).To(Equal(netName))
// JSON the bridge info
bridgePlugin, err := genericPluginsToBridge(result["plugins"], "bridge")
@@ -245,7 +247,7 @@ var _ = Describe("Podman network create", func() {
// best we can
defer removeNetworkDevice(bridgePlugin.BrName)
- try := podmanTest.Podman([]string{"run", "-it", "--rm", "--network", "newDualStacknetwork", ALPINE, "sh", "-c", "ip addr show eth0 | grep global | awk ' /inet6 / {print $2}'"})
+ try := podmanTest.Podman([]string{"run", "-it", "--rm", "--network", netName, ALPINE, "sh", "-c", "ip addr show eth0 | grep global | awk ' /inet6 / {print $2}'"})
try.WaitWithDefaultTimeout()
_, subnet, err := net.ParseCIDR("fd00:4:3:2:1::/64")
@@ -255,7 +257,7 @@ var _ = Describe("Podman network create", func() {
// Ensure that the IP the container got is within the subnet the user asked for
Expect(subnet.Contains(containerIP)).To(BeTrue())
// verify the container has an IPv4 address too (the IPv4 subnet is autogenerated)
- try = podmanTest.Podman([]string{"run", "-it", "--rm", "--network", "newDualStacknetwork", ALPINE, "sh", "-c", "ip addr show eth0 | awk ' /inet / {print $2}'"})
+ try = podmanTest.Podman([]string{"run", "-it", "--rm", "--network", netName, ALPINE, "sh", "-c", "ip addr show eth0 | awk ' /inet / {print $2}'"})
try.WaitWithDefaultTimeout()
containerIP, _, err = net.ParseCIDR(try.OutputToString())
Expect(err).To(BeNil())
@@ -263,66 +265,73 @@ var _ = Describe("Podman network create", func() {
})
It("podman network create with invalid subnet", func() {
- nc := podmanTest.Podman([]string{"network", "create", "--subnet", "10.11.12.0/17000", "fail"})
+ nc := podmanTest.Podman([]string{"network", "create", "--subnet", "10.11.12.0/17000", stringid.GenerateNonCryptoID()})
nc.WaitWithDefaultTimeout()
Expect(nc).To(ExitWithError())
})
It("podman network create with ipv4 subnet and ipv6 flag", func() {
- nc := podmanTest.Podman([]string{"network", "create", "--subnet", "10.11.12.0/24", "--ipv6", "fail"})
+ nc := podmanTest.Podman([]string{"network", "create", "--subnet", "10.11.12.0/24", "--ipv6", stringid.GenerateNonCryptoID()})
nc.WaitWithDefaultTimeout()
Expect(nc).To(ExitWithError())
})
It("podman network create with empty subnet and ipv6 flag", func() {
- nc := podmanTest.Podman([]string{"network", "create", "--ipv6", "fail"})
+ nc := podmanTest.Podman([]string{"network", "create", "--ipv6", stringid.GenerateNonCryptoID()})
nc.WaitWithDefaultTimeout()
Expect(nc).To(ExitWithError())
})
It("podman network create with invalid IP", func() {
- nc := podmanTest.Podman([]string{"network", "create", "--subnet", "10.11.0/17000", "fail"})
+ nc := podmanTest.Podman([]string{"network", "create", "--subnet", "10.11.0/17000", stringid.GenerateNonCryptoID()})
nc.WaitWithDefaultTimeout()
Expect(nc).To(ExitWithError())
})
It("podman network create with invalid gateway for subnet", func() {
- nc := podmanTest.Podman([]string{"network", "create", "--subnet", "10.11.12.0/24", "--gateway", "192.168.1.1", "fail"})
+ nc := podmanTest.Podman([]string{"network", "create", "--subnet", "10.11.12.0/24", "--gateway", "192.168.1.1", stringid.GenerateNonCryptoID()})
nc.WaitWithDefaultTimeout()
Expect(nc).To(ExitWithError())
})
It("podman network create two networks with same name should fail", func() {
- nc := podmanTest.Podman([]string{"network", "create", "samename"})
+ netName := "same-" + stringid.GenerateNonCryptoID()
+ nc := podmanTest.Podman([]string{"network", "create", netName})
nc.WaitWithDefaultTimeout()
+ defer podmanTest.removeCNINetwork(netName)
Expect(nc.ExitCode()).To(BeZero())
- defer podmanTest.removeCNINetwork("samename")
- ncFail := podmanTest.Podman([]string{"network", "create", "samename"})
+ ncFail := podmanTest.Podman([]string{"network", "create", netName})
ncFail.WaitWithDefaultTimeout()
Expect(ncFail).To(ExitWithError())
})
It("podman network create two networks with same subnet should fail", func() {
- nc := podmanTest.Podman([]string{"network", "create", "--subnet", "10.11.13.0/24", "subnet1"})
+ netName1 := "sub1-" + stringid.GenerateNonCryptoID()
+ nc := podmanTest.Podman([]string{"network", "create", "--subnet", "10.11.13.0/24", netName1})
nc.WaitWithDefaultTimeout()
+ defer podmanTest.removeCNINetwork(netName1)
Expect(nc.ExitCode()).To(BeZero())
- defer podmanTest.removeCNINetwork("subnet1")
- ncFail := podmanTest.Podman([]string{"network", "create", "--subnet", "10.11.13.0/24", "subnet2"})
+ netName2 := "sub2-" + stringid.GenerateNonCryptoID()
+ ncFail := podmanTest.Podman([]string{"network", "create", "--subnet", "10.11.13.0/24", netName2})
ncFail.WaitWithDefaultTimeout()
+ defer podmanTest.removeCNINetwork(netName2)
Expect(ncFail).To(ExitWithError())
})
It("podman network create two IPv6 networks with same subnet should fail", func() {
SkipIfRootless("FIXME It needs the ip6tables modules loaded")
- nc := podmanTest.Podman([]string{"network", "create", "--subnet", "fd00:4:4:4:4::/64", "--ipv6", "subnet1v6"})
+ netName1 := "subipv61-" + stringid.GenerateNonCryptoID()
+ nc := podmanTest.Podman([]string{"network", "create", "--subnet", "fd00:4:4:4:4::/64", "--ipv6", netName1})
nc.WaitWithDefaultTimeout()
+ defer podmanTest.removeCNINetwork(netName1)
Expect(nc.ExitCode()).To(BeZero())
- defer podmanTest.removeCNINetwork("subnet1v6")
- ncFail := podmanTest.Podman([]string{"network", "create", "--subnet", "fd00:4:4:4:4::/64", "--ipv6", "subnet2v6"})
+ netName2 := "subipv62-" + stringid.GenerateNonCryptoID()
+ ncFail := podmanTest.Podman([]string{"network", "create", "--subnet", "fd00:4:4:4:4::/64", "--ipv6", netName2})
ncFail.WaitWithDefaultTimeout()
+ defer podmanTest.removeCNINetwork(netName2)
Expect(ncFail).To(ExitWithError())
})
@@ -333,11 +342,11 @@ var _ = Describe("Podman network create", func() {
})
It("podman network create with mtu option", func() {
- net := "mtu-test"
+ net := "mtu-test" + stringid.GenerateNonCryptoID()
nc := podmanTest.Podman([]string{"network", "create", "--opt", "mtu=9000", net})
nc.WaitWithDefaultTimeout()
- Expect(nc.ExitCode()).To(BeZero())
defer podmanTest.removeCNINetwork(net)
+ Expect(nc.ExitCode()).To(BeZero())
nc = podmanTest.Podman([]string{"network", "inspect", net})
nc.WaitWithDefaultTimeout()
@@ -346,11 +355,11 @@ var _ = Describe("Podman network create", func() {
})
It("podman network create with vlan option", func() {
- net := "vlan-test"
+ net := "vlan-test" + stringid.GenerateNonCryptoID()
nc := podmanTest.Podman([]string{"network", "create", "--opt", "vlan=9", net})
nc.WaitWithDefaultTimeout()
- Expect(nc.ExitCode()).To(BeZero())
defer podmanTest.removeCNINetwork(net)
+ Expect(nc.ExitCode()).To(BeZero())
nc = podmanTest.Podman([]string{"network", "inspect", net})
nc.WaitWithDefaultTimeout()
@@ -359,9 +368,10 @@ var _ = Describe("Podman network create", func() {
})
It("podman network create with invalid option", func() {
- net := "invalid-test"
+ net := "invalid-test" + stringid.GenerateNonCryptoID()
nc := podmanTest.Podman([]string{"network", "create", "--opt", "foo=bar", net})
nc.WaitWithDefaultTimeout()
+ defer podmanTest.removeCNINetwork(net)
Expect(nc).To(ExitWithError())
})
diff --git a/test/e2e/network_test.go b/test/e2e/network_test.go
index 98512f01a..e2080244b 100644
--- a/test/e2e/network_test.go
+++ b/test/e2e/network_test.go
@@ -238,11 +238,11 @@ var _ = Describe("Podman network", func() {
})
It("podman inspect container single CNI network", func() {
- netName := "testNetSingleCNI"
+ netName := "net-" + stringid.GenerateNonCryptoID()
network := podmanTest.Podman([]string{"network", "create", "--subnet", "10.50.50.0/24", netName})
network.WaitWithDefaultTimeout()
- Expect(network.ExitCode()).To(BeZero())
defer podmanTest.removeCNINetwork(netName)
+ Expect(network.ExitCode()).To(BeZero())
ctrName := "testCtr"
container := podmanTest.Podman([]string{"run", "-dt", "--network", netName, "--name", ctrName, ALPINE, "top"})
@@ -268,17 +268,17 @@ var _ = Describe("Podman network", func() {
})
It("podman inspect container two CNI networks (container not running)", func() {
- netName1 := "testNetThreeCNI1"
+ netName1 := "net1-" + stringid.GenerateNonCryptoID()
network1 := podmanTest.Podman([]string{"network", "create", netName1})
network1.WaitWithDefaultTimeout()
- Expect(network1.ExitCode()).To(BeZero())
defer podmanTest.removeCNINetwork(netName1)
+ Expect(network1.ExitCode()).To(BeZero())
- netName2 := "testNetThreeCNI2"
+ netName2 := "net2-" + stringid.GenerateNonCryptoID()
network2 := podmanTest.Podman([]string{"network", "create", netName2})
network2.WaitWithDefaultTimeout()
- Expect(network2.ExitCode()).To(BeZero())
defer podmanTest.removeCNINetwork(netName2)
+ Expect(network2.ExitCode()).To(BeZero())
ctrName := "testCtr"
container := podmanTest.Podman([]string{"create", "--network", fmt.Sprintf("%s,%s", netName1, netName2), "--name", ctrName, ALPINE, "top"})
@@ -305,17 +305,17 @@ var _ = Describe("Podman network", func() {
})
It("podman inspect container two CNI networks", func() {
- netName1 := "testNetTwoCNI1"
+ netName1 := "net1-" + stringid.GenerateNonCryptoID()
network1 := podmanTest.Podman([]string{"network", "create", "--subnet", "10.50.51.0/25", netName1})
network1.WaitWithDefaultTimeout()
- Expect(network1.ExitCode()).To(BeZero())
defer podmanTest.removeCNINetwork(netName1)
+ Expect(network1.ExitCode()).To(BeZero())
- netName2 := "testNetTwoCNI2"
+ netName2 := "net2-" + stringid.GenerateNonCryptoID()
network2 := podmanTest.Podman([]string{"network", "create", "--subnet", "10.50.51.128/26", netName2})
network2.WaitWithDefaultTimeout()
- Expect(network2.ExitCode()).To(BeZero())
defer podmanTest.removeCNINetwork(netName2)
+ Expect(network2.ExitCode()).To(BeZero())
ctrName := "testCtr"
container := podmanTest.Podman([]string{"run", "-dt", "--network", fmt.Sprintf("%s,%s", netName1, netName2), "--name", ctrName, ALPINE, "top"})
@@ -352,11 +352,11 @@ var _ = Describe("Podman network", func() {
})
It("podman network remove --force with pod", func() {
- netName := "testnet"
+ netName := "net-" + stringid.GenerateNonCryptoID()
session := podmanTest.Podman([]string{"network", "create", netName})
session.WaitWithDefaultTimeout()
- Expect(session.ExitCode()).To(BeZero())
defer podmanTest.removeCNINetwork(netName)
+ Expect(session.ExitCode()).To(BeZero())
session = podmanTest.Podman([]string{"pod", "create", "--network", netName})
session.WaitWithDefaultTimeout()
@@ -388,17 +388,17 @@ var _ = Describe("Podman network", func() {
})
It("podman network remove with two networks", func() {
- netName1 := "net1"
+ netName1 := "net1-" + stringid.GenerateNonCryptoID()
session := podmanTest.Podman([]string{"network", "create", netName1})
session.WaitWithDefaultTimeout()
- Expect(session.ExitCode()).To(BeZero())
defer podmanTest.removeCNINetwork(netName1)
+ Expect(session.ExitCode()).To(BeZero())
- netName2 := "net2"
+ netName2 := "net2-" + stringid.GenerateNonCryptoID()
session = podmanTest.Podman([]string{"network", "create", netName2})
session.WaitWithDefaultTimeout()
- Expect(session.ExitCode()).To(BeZero())
defer podmanTest.removeCNINetwork(netName2)
+ Expect(session.ExitCode()).To(BeZero())
session = podmanTest.Podman([]string{"network", "rm", netName1, netName2})
session.WaitWithDefaultTimeout()
@@ -413,8 +413,8 @@ var _ = Describe("Podman network", func() {
netName := "aliasTest" + stringid.GenerateNonCryptoID()
session := podmanTest.Podman([]string{"network", "create", netName})
session.WaitWithDefaultTimeout()
- Expect(session.ExitCode()).To(BeZero())
defer podmanTest.removeCNINetwork(netName)
+ Expect(session.ExitCode()).To(BeZero())
top := podmanTest.Podman([]string{"run", "-dt", "--name=web", "--network=" + netName, "--network-alias=web1", "--network-alias=web2", nginx})
top.WaitWithDefaultTimeout()
@@ -450,6 +450,7 @@ var _ = Describe("Podman network", func() {
net := "macvlan" + stringid.GenerateNonCryptoID()
nc := podmanTest.Podman([]string{"network", "create", "--macvlan", "lo", net})
nc.WaitWithDefaultTimeout()
+ defer podmanTest.removeCNINetwork(net)
Expect(nc.ExitCode()).To(Equal(0))
nc = podmanTest.Podman([]string{"network", "rm", net})
diff --git a/test/e2e/rm_test.go b/test/e2e/rm_test.go
index 524c07cc6..ca142d7f3 100644
--- a/test/e2e/rm_test.go
+++ b/test/e2e/rm_test.go
@@ -215,6 +215,40 @@ var _ = Describe("Podman rm", func() {
Expect(result.ExitCode()).To(Equal(125))
})
+ It("podman rm --all", func() {
+ session := podmanTest.Podman([]string{"create", ALPINE, "ls"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(podmanTest.NumberOfContainers()).To(Equal(1))
+
+ session = podmanTest.Podman([]string{"create", ALPINE, "ls"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(podmanTest.NumberOfContainers()).To(Equal(2))
+
+ session = podmanTest.Podman([]string{"rm", "--all"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(podmanTest.NumberOfContainers()).To(Equal(0))
+ })
+
+ It("podman rm --ignore", func() {
+ session := podmanTest.Podman([]string{"create", ALPINE, "ls"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ cid := session.OutputToStringArray()[0]
+ Expect(podmanTest.NumberOfContainers()).To(Equal(1))
+
+ session = podmanTest.Podman([]string{"rm", "bogus", cid})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(1))
+
+ session = podmanTest.Podman([]string{"rm", "--ignore", "bogus", cid})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(podmanTest.NumberOfContainers()).To(Equal(0))
+ })
+
It("podman rm bogus container", func() {
session := podmanTest.Podman([]string{"rm", "bogus"})
session.WaitWithDefaultTimeout()
diff --git a/test/system/040-ps.bats b/test/system/040-ps.bats
index 0447122b1..0ae8b0ce0 100644
--- a/test/system/040-ps.bats
+++ b/test/system/040-ps.bats
@@ -111,8 +111,11 @@ EOF
run_podman ps --storage -a
is "${#lines[@]}" "2" "podman ps -a --storage sees buildah container"
- # This is what deletes the container
- # FIXME: why doesn't "podman rm --storage $cid" do anything?
+ # We can't rm it without -f, but podman should issue a helpful message
+ run_podman 2 rm "$cid"
+ is "$output" "Error: container .* is mounted and cannot be removed without using force: container state improper" "podman rm <buildah container> without -f"
+
+ # With -f, we can remove it.
run_podman rm -f "$cid"
run_podman ps --storage -a