summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml26
-rw-r--r--cmd/podman/common/create.go5
-rw-r--r--cmd/podman/containers/prune.go4
-rw-r--r--cmd/podman/images/search.go47
-rw-r--r--cmd/podman/play/kube.go10
-rw-r--r--cmd/podman/pods/inspect.go5
-rw-r--r--cmd/podman/pods/prune.go2
-rw-r--r--cmd/podman/pods/rm.go4
-rw-r--r--cmd/podman/system/prune.go4
-rw-r--r--cmd/podman/system/service.go2
-rwxr-xr-xcontrib/cirrus/runner.sh12
-rw-r--r--libpod/container_internal_linux.go17
-rw-r--r--libpod/image/image.go16
-rw-r--r--libpod/image/prune.go2
-rw-r--r--libpod/image/pull.go7
-rw-r--r--libpod/in_memory_state.go20
-rw-r--r--libpod/network/netconflist.go2
-rw-r--r--libpod/oci_conmon_linux.go1
-rw-r--r--libpod/options.go2
-rw-r--r--pkg/api/handlers/libpod/images.go3
-rw-r--r--pkg/domain/filters/containers.go2
-rw-r--r--pkg/domain/filters/pods.go2
-rw-r--r--pkg/domain/filters/volumes.go4
-rw-r--r--pkg/domain/infra/abi/containers.go20
-rw-r--r--pkg/domain/infra/abi/images.go3
-rw-r--r--pkg/domain/infra/abi/manifest.go3
-rw-r--r--pkg/domain/infra/abi/system.go5
-rw-r--r--pkg/specgen/generate/config_linux.go3
-rw-r--r--pkg/specgen/generate/oci.go2
-rw-r--r--pkg/specgen/generate/storage.go8
-rw-r--r--pkg/specgen/generate/validate.go2
-rw-r--r--pkg/systemd/generate/common.go27
-rw-r--r--pkg/systemd/generate/containers.go80
-rw-r--r--pkg/systemd/generate/containers_test.go243
-rw-r--r--pkg/systemd/generate/pods.go40
-rw-r--r--pkg/systemd/generate/pods_test.go103
-rw-r--r--test/e2e/generate_systemd_test.go171
-rw-r--r--test/e2e/search_test.go10
38 files changed, 637 insertions, 282 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index 3eaa4ede8..f04fcaba1 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -67,6 +67,7 @@ gcp_credentials: ENCRYPTED[a28959877b2c9c36f151781b0a05407218cda646c7d047fc556e4
ext_svc_check_task:
alias: 'ext_svc_check' # int. ref. name - required for depends_on reference
name: "Ext. services" # Displayed Title - has no other significance
+ skip: &tags "$CIRRUS_TAG != ''" # Don't run on tags
# Default/small container image to execute tasks with
container: &smallcontainer
image: ${CTR_FQIN}
@@ -90,7 +91,7 @@ ext_svc_check_task:
automation_task:
alias: 'automation'
name: "Check Automation"
- skip: &branch "$CIRRUS_PR == '' || $CIRRUS_TAG != ''" # Don't run for branches
+ skip: &branches_and_tags "$CIRRUS_PR == '' || $CIRRUS_TAG != ''" # Don't run on branches/tags
container: *smallcontainer
env:
TEST_FLAVOR: automation
@@ -107,6 +108,7 @@ automation_task:
smoke_task:
alias: 'smoke'
name: "Smoke Test"
+ skip: *tags
container: &bigcontainer
image: ${CTR_FQIN}
# Leave some resources for smallcontainer
@@ -209,6 +211,7 @@ build_task:
validate_task:
name: "Validate $DISTRO_NV Build"
alias: validate
+ skip: *tags
depends_on:
- ext_svc_check
- automation
@@ -237,7 +240,7 @@ bindings_task:
name: "Test Bindings"
alias: bindings
only_if: &not_docs $CIRRUS_CHANGE_TITLE !=~ '.*CI:DOCS.*'
- skip: *branch
+ skip: *branches_and_tags
depends_on:
- build
gce_instance: *standardvm
@@ -275,6 +278,7 @@ swagger_task:
vendor_task:
name: "Test Vendoring"
alias: vendor
+ skip: *tags
depends_on:
- build
container: *smallcontainer
@@ -375,6 +379,7 @@ osx_alt_build_task:
docker-py_test_task:
name: Docker-py Compat.
alias: docker-py_test
+ skip: *tags
only_if: *not_docs
depends_on:
- build
@@ -395,6 +400,7 @@ docker-py_test_task:
unit_test_task:
name: "Unit tests on $DISTRO_NV"
alias: unit_test
+ skip: *tags
only_if: *not_docs
depends_on:
- validate
@@ -412,6 +418,7 @@ unit_test_task:
apiv2_test_task:
name: "APIv2 test on $DISTRO_NV"
alias: apiv2_test
+ skip: *tags
depends_on:
- validate
gce_instance: *standardvm
@@ -439,6 +446,7 @@ apiv2_test_task:
compose_test_task:
name: "compose test on $DISTRO_NV"
alias: compose_test
+ skip: *tags
depends_on:
- validate
gce_instance: *standardvm
@@ -460,7 +468,7 @@ local_integration_test_task: &local_integration_test_task
name: &std_name_fmt "$TEST_FLAVOR $PODBIN_NAME $DISTRO_NV $PRIV_NAME $TEST_ENVIRON"
alias: local_integration_test
only_if: *not_docs
- skip: *branch
+ skip: *branches_and_tags
depends_on:
- unit_test
matrix: *platform_axis
@@ -492,7 +500,7 @@ container_integration_test_task:
name: *std_name_fmt
alias: container_integration_test
only_if: *not_docs
- skip: *branch
+ skip: *branches_and_tags
depends_on:
- unit_test
matrix: &fedora_vm_axis
@@ -523,7 +531,7 @@ rootless_integration_test_task:
name: *std_name_fmt
alias: rootless_integration_test
only_if: *not_docs
- skip: *branch
+ skip: *branches_and_tags
depends_on:
- unit_test
matrix: *fedora_vm_axis
@@ -546,6 +554,7 @@ rootless_integration_test_task:
local_system_test_task: &local_system_test_task
name: *std_name_fmt
alias: local_system_test
+ skip: *tags
only_if: *not_docs
depends_on:
- local_integration_test
@@ -573,6 +582,7 @@ remote_system_test_task:
rootless_system_test_task:
name: *std_name_fmt
alias: rootless_system_test
+ skip: *tags
only_if: *not_docs
depends_on:
- rootless_integration_test
@@ -658,7 +668,7 @@ success_task:
release_task:
name: "Verify Release"
alias: release
- only_if: $CIRRUS_TAG != ''
+ only_if: *tags
depends_on:
- success
gce_instance: *standardvm
@@ -673,7 +683,9 @@ release_task:
# When preparing to release a new version, this task may be manually
-# activated at the PR stage to verify the code is in a proper state.
+# activated at the PR stage to verify the build is proper for a potential
+# podman release.
+#
# Note: This cannot use a YAML alias on 'release_task' as of this
# comment, it is incompatible with 'trigger_type: manual'
release_test_task:
diff --git a/cmd/podman/common/create.go b/cmd/podman/common/create.go
index 24703eda2..280175f95 100644
--- a/cmd/podman/common/create.go
+++ b/cmd/podman/common/create.go
@@ -1,7 +1,6 @@
package common
import (
- "fmt"
"os"
"github.com/containers/common/pkg/auth"
@@ -181,7 +180,7 @@ func DefineCreateFlags(cmd *cobra.Command, cf *ContainerCLIOpts) {
createFlags.StringSliceVar(
&cf.Devices,
deviceFlagName, devices(),
- fmt.Sprintf("Add a host device to the container"),
+ "Add a host device to the container",
)
_ = cmd.RegisterFlagCompletionFunc(deviceFlagName, completion.AutocompleteDefault)
@@ -359,7 +358,7 @@ func DefineCreateFlags(cmd *cobra.Command, cf *ContainerCLIOpts) {
&cf.InitPath,
initPathFlagName, initPath(),
// Do not use the Value field for setting the default value to determine user input (i.e., non-empty string)
- fmt.Sprintf("Path to the container-init binary"),
+ "Path to the container-init binary",
)
_ = cmd.RegisterFlagCompletionFunc(initPathFlagName, completion.AutocompleteDefault)
diff --git a/cmd/podman/containers/prune.go b/cmd/podman/containers/prune.go
index d3842778b..50731dd21 100644
--- a/cmd/podman/containers/prune.go
+++ b/cmd/podman/containers/prune.go
@@ -18,9 +18,9 @@ import (
)
var (
- pruneDescription = fmt.Sprintf(`podman container prune
+ pruneDescription = `podman container prune
- Removes all non running containers`)
+ Removes all non running containers`
pruneCommand = &cobra.Command{
Use: "prune [options]",
Short: "Remove all non running containers",
diff --git a/cmd/podman/images/search.go b/cmd/podman/images/search.go
index c2ef7d767..c8ea4b04a 100644
--- a/cmd/podman/images/search.go
+++ b/cmd/podman/images/search.go
@@ -26,6 +26,12 @@ type searchOptionsWrapper struct {
Format string // For go templating
}
+// listEntryTag is a utility structure used for json serialization.
+type listEntryTag struct {
+ Name string
+ Tags []string
+}
+
var (
searchOptions = searchOptionsWrapper{}
searchDescription = `Search registries for a given image. Can search all the default registries or a specific registry.
@@ -149,14 +155,13 @@ func imageSearch(cmd *cobra.Command, args []string) error {
if len(searchOptions.Filters) != 0 {
return errors.Errorf("filters are not applicable to list tags result")
}
+ if report.IsJSON(searchOptions.Format) {
+ listTagsEntries := buildListTagsJson(searchReport)
+ return printJson(listTagsEntries)
+ }
row = "{{.Name}}\t{{.Tag}}\n"
case report.IsJSON(searchOptions.Format):
- prettyJSON, err := json.MarshalIndent(searchReport, "", " ")
- if err != nil {
- return err
- }
- fmt.Println(string(prettyJSON))
- return nil
+ return printJson(searchReport)
case cmd.Flags().Changed("format"):
renderHeaders = parse.HasTable(searchOptions.Format)
row = report.NormalizeFormat(searchOptions.Format)
@@ -180,3 +185,33 @@ func imageSearch(cmd *cobra.Command, args []string) error {
return tmpl.Execute(w, searchReport)
}
+
+func printJson(v interface{}) error {
+ prettyJSON, err := json.MarshalIndent(v, "", " ")
+ if err != nil {
+ return err
+ }
+ fmt.Println(string(prettyJSON))
+ return nil
+}
+
+func buildListTagsJson(searchReport []entities.ImageSearchReport) []listEntryTag {
+ entries := []listEntryTag{}
+
+ReportLoop:
+ for _, report := range searchReport {
+ for idx, entry := range entries {
+ if entry.Name == report.Name {
+ entries[idx].Tags = append(entries[idx].Tags, report.Tag)
+ continue ReportLoop
+ }
+ }
+ newElem := listEntryTag{
+ report.Name,
+ []string{report.Tag},
+ }
+
+ entries = append(entries, newElem)
+ }
+ return entries
+}
diff --git a/cmd/podman/play/kube.go b/cmd/podman/play/kube.go
index 1f54db203..4c44fa30f 100644
--- a/cmd/podman/play/kube.go
+++ b/cmd/podman/play/kube.go
@@ -127,23 +127,23 @@ func kube(cmd *cobra.Command, args []string) error {
for _, pod := range report.Pods {
for _, l := range pod.Logs {
- fmt.Fprintf(os.Stderr, l)
+ fmt.Fprint(os.Stderr, l)
}
}
ctrsFailed := 0
for _, pod := range report.Pods {
- fmt.Printf("Pod:\n")
+ fmt.Println("Pod:")
fmt.Println(pod.ID)
switch len(pod.Containers) {
case 0:
continue
case 1:
- fmt.Printf("Container:\n")
+ fmt.Println("Container:")
default:
- fmt.Printf("Containers:\n")
+ fmt.Println("Containers:")
}
for _, ctr := range pod.Containers {
fmt.Println(ctr)
@@ -154,7 +154,7 @@ func kube(cmd *cobra.Command, args []string) error {
fmt.Println()
}
for _, err := range pod.ContainerErrors {
- fmt.Fprintf(os.Stderr, err+"\n")
+ fmt.Fprintln(os.Stderr, err)
}
// Empty line for space for next block
fmt.Println()
diff --git a/cmd/podman/pods/inspect.go b/cmd/podman/pods/inspect.go
index 091094ff6..e809be0c9 100644
--- a/cmd/podman/pods/inspect.go
+++ b/cmd/podman/pods/inspect.go
@@ -2,7 +2,6 @@ package pods
import (
"context"
- "fmt"
"os"
"text/tabwriter"
"text/template"
@@ -21,9 +20,9 @@ var (
)
var (
- inspectDescription = fmt.Sprintf(`Display the configuration for a pod by name or id
+ inspectDescription = `Display the configuration for a pod by name or id
- By default, this will render all results in a JSON array.`)
+ By default, this will render all results in a JSON array.`
inspectCmd = &cobra.Command{
Use: "inspect [options] POD [POD...]",
diff --git a/cmd/podman/pods/prune.go b/cmd/podman/pods/prune.go
index 965c36398..a040a21b6 100644
--- a/cmd/podman/pods/prune.go
+++ b/cmd/podman/pods/prune.go
@@ -20,7 +20,7 @@ var (
)
var (
- pruneDescription = fmt.Sprintf(`podman pod prune Removes all exited pods`)
+ pruneDescription = `podman pod prune Removes all exited pods`
pruneCommand = &cobra.Command{
Use: "prune [options]",
diff --git a/cmd/podman/pods/rm.go b/cmd/podman/pods/rm.go
index ff238aa20..109f18b78 100644
--- a/cmd/podman/pods/rm.go
+++ b/cmd/podman/pods/rm.go
@@ -25,9 +25,9 @@ type podRmOptionsWrapper struct {
var (
rmOptions = podRmOptionsWrapper{}
- podRmDescription = fmt.Sprintf(`podman rm will remove one or more stopped pods and their containers from the host.
+ podRmDescription = `podman rm will remove one or more stopped pods and their containers from the host.
- The pod name or ID can be used. A pod with containers will not be removed without --force. If --force is specified, all containers will be stopped, then removed.`)
+ The pod name or ID can be used. A pod with containers will not be removed without --force. If --force is specified, all containers will be stopped, then removed.`
rmCommand = &cobra.Command{
Use: "rm [options] POD [POD...]",
Short: "Remove one or more pods",
diff --git a/cmd/podman/system/prune.go b/cmd/podman/system/prune.go
index 87bb947ed..5e96a654a 100644
--- a/cmd/podman/system/prune.go
+++ b/cmd/podman/system/prune.go
@@ -20,11 +20,11 @@ import (
var (
pruneOptions = entities.SystemPruneOptions{}
filters []string
- pruneDescription = fmt.Sprintf(`
+ pruneDescription = `
podman system prune
Remove unused data
-`)
+`
pruneCommand = &cobra.Command{
Use: "prune [options]",
diff --git a/cmd/podman/system/service.go b/cmd/podman/system/service.go
index f8bdbfa10..f5760e172 100644
--- a/cmd/podman/system/service.go
+++ b/cmd/podman/system/service.go
@@ -80,7 +80,7 @@ func service(cmd *cobra.Command, args []string) error {
}
// socket activation uses a unix:// socket in the shipped unit files but apiURI is coded as "" at this layer.
- if "unix" == uri.Scheme && !registry.IsRemote() {
+ if uri.Scheme == "unix" && !registry.IsRemote() {
if err := syscall.Unlink(uri.Path); err != nil && !os.IsNotExist(err) {
return err
}
diff --git a/contrib/cirrus/runner.sh b/contrib/cirrus/runner.sh
index e09b2af9c..2f909876a 100755
--- a/contrib/cirrus/runner.sh
+++ b/contrib/cirrus/runner.sh
@@ -202,8 +202,16 @@ function _run_altbuild() {
}
function _run_release() {
- if bin/podman info |& grep -Eq -- '-dev'; then
- die "Releases must never contain '-dev' in output of 'podman info'"
+ # TODO: These tests should come from code external to the podman repo.
+ # to allow test-changes (and re-runs) in the case of a correctible test
+ # flaw or flake at release tag-push time. For now, the test is here
+ # given it's simplicity.
+
+ msg "Checking podman release (or potential release) criteria."
+ info_output=$(bin/podman info 2>&1)
+ if grep -q -- '-dev'<<<"$info_output"; then
+ die "Releases must never contain '-dev' in output of 'podman info':
+$info_output"
fi
}
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index 705086bda..575047f95 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -40,7 +40,6 @@ import (
"github.com/containers/storage/pkg/idtools"
securejoin "github.com/cyphar/filepath-securejoin"
runcuser "github.com/opencontainers/runc/libcontainer/user"
- "github.com/opencontainers/runtime-spec/specs-go"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/runtime-tools/generate"
"github.com/opencontainers/selinux/go-selinux/label"
@@ -284,7 +283,7 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
return nil, err
}
- g := generate.NewFromSpec(c.config.Spec)
+ g := generate.Generator{Config: c.config.Spec}
// If network namespace was requested, add it now
if c.config.CreateNetNS {
@@ -400,7 +399,7 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
return nil, errors.Wrapf(err, "failed to create TempDir in the %s directory", c.config.StaticDir)
}
- var overlayMount specs.Mount
+ var overlayMount spec.Mount
if volume.ReadWrite {
overlayMount, err = overlay.Mount(contentDir, mountPoint, volume.Dest, c.RootUID(), c.RootGID(), c.runtime.store.GraphOptions())
} else {
@@ -1519,18 +1518,14 @@ func (c *Container) makeBindMounts() error {
}
if newPasswd != "" {
// Make /etc/passwd
- if _, ok := c.state.BindMounts["/etc/passwd"]; ok {
- // If it already exists, delete so we can recreate
- delete(c.state.BindMounts, "/etc/passwd")
- }
+ // If it already exists, delete so we can recreate
+ delete(c.state.BindMounts, "/etc/passwd")
c.state.BindMounts["/etc/passwd"] = newPasswd
}
if newGroup != "" {
// Make /etc/group
- if _, ok := c.state.BindMounts["/etc/group"]; ok {
- // If it already exists, delete so we can recreate
- delete(c.state.BindMounts, "/etc/group")
- }
+ // If it already exists, delete so we can recreate
+ delete(c.state.BindMounts, "/etc/group")
c.state.BindMounts["/etc/group"] = newGroup
}
diff --git a/libpod/image/image.go b/libpod/image/image.go
index a9082b2c6..39d740b7a 100644
--- a/libpod/image/image.go
+++ b/libpod/image/image.go
@@ -17,7 +17,6 @@ import (
"github.com/containers/common/pkg/retry"
cp "github.com/containers/image/v5/copy"
"github.com/containers/image/v5/directory"
- "github.com/containers/image/v5/docker/archive"
dockerarchive "github.com/containers/image/v5/docker/archive"
"github.com/containers/image/v5/docker/reference"
"github.com/containers/image/v5/image"
@@ -37,7 +36,6 @@ import (
"github.com/containers/podman/v2/pkg/util"
"github.com/containers/storage"
digest "github.com/opencontainers/go-digest"
- imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
ociv1 "github.com/opencontainers/image-spec/specs-go/v1"
opentracing "github.com/opentracing/opentracing-go"
"github.com/pkg/errors"
@@ -185,7 +183,7 @@ func (ir *Runtime) SaveImages(ctx context.Context, namesOrIDs []string, format s
sys := GetSystemContext("", "", false)
- archWriter, err := archive.NewWriter(sys, outputFile)
+ archWriter, err := dockerarchive.NewWriter(sys, outputFile)
if err != nil {
return err
}
@@ -291,7 +289,7 @@ func (ir *Runtime) LoadAllImagesFromDockerArchive(ctx context.Context, fileName
}
sc := GetSystemContext(signaturePolicyPath, "", false)
- reader, err := archive.NewReader(sc, fileName)
+ reader, err := dockerarchive.NewReader(sc, fileName)
if err != nil {
return nil, err
}
@@ -1148,7 +1146,7 @@ func (i *Image) GetLabel(ctx context.Context, label string) (string, error) {
}
for k, v := range labels {
- if strings.ToLower(k) == strings.ToLower(label) {
+ if strings.EqualFold(k, label) {
return v, nil
}
}
@@ -1326,7 +1324,7 @@ func (ir *Runtime) Import(ctx context.Context, path, reference string, writer io
annotations := make(map[string]string)
- // config imgspecv1.Image
+ // config ociv1.Image
err = updater.ConfigUpdate(imageConfig, annotations)
if err != nil {
return nil, errors.Wrapf(err, "error updating image config")
@@ -1435,7 +1433,7 @@ func (i *Image) IsParent(ctx context.Context) (bool, error) {
// historiesMatch returns the number of entries in the histories which have the
// same contents
-func historiesMatch(a, b []imgspecv1.History) int {
+func historiesMatch(a, b []ociv1.History) int {
i := 0
for i < len(a) && i < len(b) {
if a[i].Created != nil && b[i].Created == nil {
@@ -1468,7 +1466,7 @@ func historiesMatch(a, b []imgspecv1.History) int {
// areParentAndChild checks diff ID and history in the two images and return
// true if the second should be considered to be directly based on the first
-func areParentAndChild(parent, child *imgspecv1.Image) bool {
+func areParentAndChild(parent, child *ociv1.Image) bool {
// the child and candidate parent should share all of the
// candidate parent's diff IDs, which together would have
// controlled which layers were used
@@ -1621,7 +1619,7 @@ func (i *Image) Save(ctx context.Context, source, format, output string, moreTag
if err != nil {
return errors.Wrapf(err, "error getting the OCI directory ImageReference for (%q, %q)", output, destImageName)
}
- manifestType = imgspecv1.MediaTypeImageManifest
+ manifestType = ociv1.MediaTypeImageManifest
case "docker-dir":
destRef, err = directory.NewReference(output)
if err != nil {
diff --git a/libpod/image/prune.go b/libpod/image/prune.go
index 3c06a89c2..587c99333 100644
--- a/libpod/image/prune.go
+++ b/libpod/image/prune.go
@@ -29,7 +29,7 @@ func generatePruneFilterFuncs(filter, filterValue string) (ImageFilter, error) {
return false
}
for labelKey, labelValue := range labels {
- if labelKey == filterKey && ("" == filterValue || labelValue == filterValue) {
+ if labelKey == filterKey && (filterValue == "" || labelValue == filterValue) {
return true
}
}
diff --git a/libpod/image/pull.go b/libpod/image/pull.go
index c37929927..996b5995a 100644
--- a/libpod/image/pull.go
+++ b/libpod/image/pull.go
@@ -11,7 +11,6 @@ import (
cp "github.com/containers/image/v5/copy"
"github.com/containers/image/v5/directory"
"github.com/containers/image/v5/docker"
- "github.com/containers/image/v5/docker/archive"
dockerarchive "github.com/containers/image/v5/docker/archive"
ociarchive "github.com/containers/image/v5/oci/archive"
oci "github.com/containers/image/v5/oci/layout"
@@ -130,7 +129,7 @@ func (ir *Runtime) getSinglePullRefPairGoal(srcRef types.ImageReference, destNam
// getPullRefPairsFromDockerArchiveReference returns a slice of pullRefPairs
// for the specified docker reference and the corresponding archive.Reader.
-func (ir *Runtime) getPullRefPairsFromDockerArchiveReference(ctx context.Context, reader *archive.Reader, ref types.ImageReference, sc *types.SystemContext) ([]pullRefPair, error) {
+func (ir *Runtime) getPullRefPairsFromDockerArchiveReference(ctx context.Context, reader *dockerarchive.Reader, ref types.ImageReference, sc *types.SystemContext) ([]pullRefPair, error) {
destNames, err := reader.ManifestTagsForReference(ref)
if err != nil {
return nil, err
@@ -178,7 +177,7 @@ func (ir *Runtime) pullGoalFromImageReference(ctx context.Context, srcRef types.
// supports pulling from docker-archive, oci, and registries
switch srcRef.Transport().Name() {
case DockerArchive:
- reader, readerRef, err := archive.NewReaderForReference(sc, srcRef)
+ reader, readerRef, err := dockerarchive.NewReaderForReference(sc, srcRef)
if err != nil {
return nil, err
}
@@ -432,7 +431,7 @@ func checkRemoteImageForLabel(ctx context.Context, label string, imageInfo pullR
}
// Labels are case insensitive; so we iterate instead of simple lookup
for k := range remoteInspect.Labels {
- if strings.ToLower(label) == strings.ToLower(k) {
+ if strings.EqualFold(label, k) {
return nil
}
}
diff --git a/libpod/in_memory_state.go b/libpod/in_memory_state.go
index 6c0cde531..9285589b1 100644
--- a/libpod/in_memory_state.go
+++ b/libpod/in_memory_state.go
@@ -437,12 +437,8 @@ func (s *InMemoryState) RemoveContainer(ctr *Container) error {
}
// Remove our network aliases
- if _, ok := s.ctrNetworkAliases[ctr.ID()]; ok {
- delete(s.ctrNetworkAliases, ctr.ID())
- }
- if _, ok := s.ctrNetworks[ctr.ID()]; ok {
- delete(s.ctrNetworks, ctr.ID())
- }
+ delete(s.ctrNetworkAliases, ctr.ID())
+ delete(s.ctrNetworks, ctr.ID())
return nil
}
@@ -680,9 +676,7 @@ func (s *InMemoryState) NetworkDisconnect(ctr *Container, network string) error
ctrAliases = make(map[string][]string)
s.ctrNetworkAliases[ctr.ID()] = ctrAliases
}
- if _, ok := ctrAliases[network]; ok {
- delete(ctrAliases, network)
- }
+ delete(ctrAliases, network)
return nil
}
@@ -1523,12 +1517,8 @@ func (s *InMemoryState) RemoveContainerFromPod(pod *Pod, ctr *Container) error {
}
// Remove our network aliases
- if _, ok := s.ctrNetworkAliases[ctr.ID()]; ok {
- delete(s.ctrNetworkAliases, ctr.ID())
- }
- if _, ok := s.ctrNetworks[ctr.ID()]; ok {
- delete(s.ctrNetworks, ctr.ID())
- }
+ delete(s.ctrNetworkAliases, ctr.ID())
+ delete(s.ctrNetworks, ctr.ID())
return nil
}
diff --git a/libpod/network/netconflist.go b/libpod/network/netconflist.go
index bf7d03501..165a9067b 100644
--- a/libpod/network/netconflist.go
+++ b/libpod/network/netconflist.go
@@ -216,7 +216,7 @@ func IfPassesFilter(netconf *libcni.NetworkConfigList, filters map[string][]stri
filterValue = ""
}
for labelKey, labelValue := range labels {
- if labelKey == filterKey && ("" == filterValue || labelValue == filterValue) {
+ if labelKey == filterKey && (filterValue == "" || labelValue == filterValue) {
result = true
continue outer
}
diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go
index 70896cda4..23bfb29d7 100644
--- a/libpod/oci_conmon_linux.go
+++ b/libpod/oci_conmon_linux.go
@@ -1387,6 +1387,7 @@ func (r *ConmonOCIRuntime) sharedConmonArgs(ctr *Container, cuuid, bundlePath, p
logDriverArg = define.NoLogging
case define.JSONLogging:
fallthrough
+ //lint:ignore ST1015 the default case has to be here
default: //nolint-stylecheck
// No case here should happen except JSONLogging, but keep this here in case the options are extended
logrus.Errorf("%s logging specified but not supported. Choosing k8s-file logging instead", ctr.LogDriver())
diff --git a/libpod/options.go b/libpod/options.go
index ef7db3235..31c0b9ac9 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -910,7 +910,7 @@ func WithUserNSFrom(nsCtr *Container) CtrCreateOption {
ctr.config.UserNsCtr = nsCtr.ID()
ctr.config.IDMappings = nsCtr.config.IDMappings
- g := generate.NewFromSpec(ctr.config.Spec)
+ g := generate.Generator{Config: ctr.config.Spec}
g.ClearLinuxUIDMappings()
for _, uidmap := range nsCtr.config.IDMappings.UIDMap {
diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go
index 979a8adc4..b2b93de17 100644
--- a/pkg/api/handlers/libpod/images.go
+++ b/pkg/api/handlers/libpod/images.go
@@ -16,7 +16,6 @@ import (
"github.com/containers/podman/v2/libpod"
"github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/libpod/image"
- image2 "github.com/containers/podman/v2/libpod/image"
"github.com/containers/podman/v2/pkg/api/handlers"
"github.com/containers/podman/v2/pkg/api/handlers/utils"
"github.com/containers/podman/v2/pkg/auth"
@@ -524,7 +523,7 @@ func CommitContainer(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "failed to get runtime config", http.StatusInternalServerError, errors.Wrap(err, "failed to get runtime config"))
return
}
- sc := image2.GetSystemContext(rtc.Engine.SignaturePolicyPath, "", false)
+ sc := image.GetSystemContext(rtc.Engine.SignaturePolicyPath, "", false)
tag := "latest"
options := libpod.ContainerCommitOptions{
Pause: true,
diff --git a/pkg/domain/filters/containers.go b/pkg/domain/filters/containers.go
index 09ef6201a..1de5aca91 100644
--- a/pkg/domain/filters/containers.go
+++ b/pkg/domain/filters/containers.go
@@ -35,7 +35,7 @@ func GenerateContainerFilterFuncs(filter string, filterValues []string, r *libpo
filterValue = ""
}
for labelKey, labelValue := range labels {
- if labelKey == filterKey && ("" == filterValue || labelValue == filterValue) {
+ if labelKey == filterKey && (filterValue == "" || labelValue == filterValue) {
matched = true
break
}
diff --git a/pkg/domain/filters/pods.go b/pkg/domain/filters/pods.go
index 685c182ba..ce7028d2a 100644
--- a/pkg/domain/filters/pods.go
+++ b/pkg/domain/filters/pods.go
@@ -124,7 +124,7 @@ func GeneratePodFilterFunc(filter string, filterValues []string) (
filterValue = ""
}
for labelKey, labelValue := range labels {
- if labelKey == filterKey && ("" == filterValue || labelValue == filterValue) {
+ if labelKey == filterKey && (filterValue == "" || labelValue == filterValue) {
matched = true
break
}
diff --git a/pkg/domain/filters/volumes.go b/pkg/domain/filters/volumes.go
index 69bef4961..7890459f5 100644
--- a/pkg/domain/filters/volumes.go
+++ b/pkg/domain/filters/volumes.go
@@ -39,7 +39,7 @@ func GenerateVolumeFilters(filters url.Values) ([]libpod.VolumeFilter, error) {
}
vf = append(vf, func(v *libpod.Volume) bool {
for labelKey, labelValue := range v.Labels() {
- if labelKey == filterKey && ("" == filterVal || labelValue == filterVal) {
+ if labelKey == filterKey && (filterVal == "" || labelValue == filterVal) {
return true
}
}
@@ -56,7 +56,7 @@ func GenerateVolumeFilters(filters url.Values) ([]libpod.VolumeFilter, error) {
}
vf = append(vf, func(v *libpod.Volume) bool {
for labelKey, labelValue := range v.Options() {
- if labelKey == filterKey && ("" == filterVal || labelValue == filterVal) {
+ if labelKey == filterKey && (filterVal == "" || labelValue == filterVal) {
return true
}
}
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go
index 2c79b6187..b5f5a0e91 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -113,15 +113,7 @@ func (ic *ContainerEngine) ContainerWait(ctx context.Context, namesOrIds []strin
}
func (ic *ContainerEngine) ContainerPause(ctx context.Context, namesOrIds []string, options entities.PauseUnPauseOptions) ([]*entities.PauseUnpauseReport, error) {
- var (
- err error
- )
- ctrs := []*libpod.Container{} //nolint
- if options.All {
- ctrs, err = ic.Libpod.GetAllContainers()
- } else {
- ctrs, err = getContainersByContext(false, false, namesOrIds, ic.Libpod)
- }
+ ctrs, err := getContainersByContext(options.All, false, namesOrIds, ic.Libpod)
if err != nil {
return nil, err
}
@@ -134,15 +126,7 @@ func (ic *ContainerEngine) ContainerPause(ctx context.Context, namesOrIds []stri
}
func (ic *ContainerEngine) ContainerUnpause(ctx context.Context, namesOrIds []string, options entities.PauseUnPauseOptions) ([]*entities.PauseUnpauseReport, error) {
- var (
- err error
- )
- ctrs := []*libpod.Container{} //nolint
- if options.All {
- ctrs, err = ic.Libpod.GetAllContainers()
- } else {
- ctrs, err = getContainersByContext(false, false, namesOrIds, ic.Libpod)
- }
+ ctrs, err := getContainersByContext(options.All, false, namesOrIds, ic.Libpod)
if err != nil {
return nil, err
}
diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go
index 19f081abb..3487dc3f4 100644
--- a/pkg/domain/infra/abi/images.go
+++ b/pkg/domain/infra/abi/images.go
@@ -22,7 +22,6 @@ import (
"github.com/containers/image/v5/types"
"github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/libpod/image"
- libpodImage "github.com/containers/podman/v2/libpod/image"
"github.com/containers/podman/v2/pkg/domain/entities"
"github.com/containers/podman/v2/pkg/domain/entities/reports"
domainUtils "github.com/containers/podman/v2/pkg/domain/utils"
@@ -206,7 +205,7 @@ func (ir *ImageEngine) Unmount(ctx context.Context, nameOrIDs []string, options
return reports, nil
}
-func ToDomainHistoryLayer(layer *libpodImage.History) entities.ImageHistoryLayer {
+func ToDomainHistoryLayer(layer *image.History) entities.ImageHistoryLayer {
l := entities.ImageHistoryLayer{}
l.ID = layer.ID
l.Created = *layer.Created
diff --git a/pkg/domain/infra/abi/manifest.go b/pkg/domain/infra/abi/manifest.go
index 0c734d10d..a68ed8788 100644
--- a/pkg/domain/infra/abi/manifest.go
+++ b/pkg/domain/infra/abi/manifest.go
@@ -13,7 +13,6 @@ import (
"github.com/containers/buildah/manifests"
buildahManifests "github.com/containers/buildah/pkg/manifests"
- "github.com/containers/buildah/util"
buildahUtil "github.com/containers/buildah/util"
cp "github.com/containers/image/v5/copy"
"github.com/containers/image/v5/docker"
@@ -60,7 +59,7 @@ func (ir *ImageEngine) ManifestInspect(ctx context.Context, name string) ([]byte
}
}
sc := ir.Libpod.SystemContext()
- refs, err := util.ResolveNameToReferences(ir.Libpod.GetStore(), sc, name)
+ refs, err := buildahUtil.ResolveNameToReferences(ir.Libpod.GetStore(), sc, name)
if err != nil {
return nil, err
}
diff --git a/pkg/domain/infra/abi/system.go b/pkg/domain/infra/abi/system.go
index 67c018122..97fa9d374 100644
--- a/pkg/domain/infra/abi/system.go
+++ b/pkg/domain/infra/abi/system.go
@@ -162,11 +162,6 @@ func movePauseProcessToScope(r *libpod.Runtime) error {
return utils.RunUnderSystemdScope(int(pid), "user.slice", "podman-pause.scope")
}
-// checkInput can be used to verify any of the globalopt values
-func checkInput() error { // nolint:deadcode,unused
- return nil
-}
-
// SystemPrune removes unused data from the system. Pruning pods, containers, volumes and images.
func (ic *ContainerEngine) SystemPrune(ctx context.Context, options entities.SystemPruneOptions) (*entities.SystemPruneReport, error) {
var systemPruneReport = new(entities.SystemPruneReport)
diff --git a/pkg/specgen/generate/config_linux.go b/pkg/specgen/generate/config_linux.go
index e0b039fb7..1290a8eb6 100644
--- a/pkg/specgen/generate/config_linux.go
+++ b/pkg/specgen/generate/config_linux.go
@@ -21,9 +21,6 @@ var (
errNotADevice = errors.New("not a device node")
)
-func u32Ptr(i int64) *uint32 { u := uint32(i); return &u }
-func fmPtr(i int64) *os.FileMode { fm := os.FileMode(i); return &fm }
-
func addPrivilegedDevices(g *generate.Generator) error {
hostDevices, err := getDevices("/dev")
if err != nil {
diff --git a/pkg/specgen/generate/oci.go b/pkg/specgen/generate/oci.go
index ba68de6fd..7dc32a314 100644
--- a/pkg/specgen/generate/oci.go
+++ b/pkg/specgen/generate/oci.go
@@ -110,7 +110,7 @@ func makeCommand(ctx context.Context, s *specgen.SpecGenerator, img *image.Image
// Only use image command if the user did not manually set an
// entrypoint.
command := s.Command
- if (command == nil || len(command) == 0) && img != nil && (s.Entrypoint == nil || len(s.Entrypoint) == 0) {
+ if len(command) == 0 && img != nil && len(s.Entrypoint) == 0 {
newCmd, err := img.Cmd(ctx)
if err != nil {
return nil, err
diff --git a/pkg/specgen/generate/storage.go b/pkg/specgen/generate/storage.go
index f523ac5bf..63713726e 100644
--- a/pkg/specgen/generate/storage.go
+++ b/pkg/specgen/generate/storage.go
@@ -124,14 +124,10 @@ func finalizeMounts(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Ru
// named volumes, and vice versa.
// We'll delete the conflicts here as we supersede.
for dest := range unifiedMounts {
- if _, ok := baseVolumes[dest]; ok {
- delete(baseVolumes, dest)
- }
+ delete(baseVolumes, dest)
}
for dest := range unifiedVolumes {
- if _, ok := baseMounts[dest]; ok {
- delete(baseMounts, dest)
- }
+ delete(baseMounts, dest)
}
// Supersede volumes-from/image volumes with unified volumes from above.
diff --git a/pkg/specgen/generate/validate.go b/pkg/specgen/generate/validate.go
index f0ab4b994..77cccad3e 100644
--- a/pkg/specgen/generate/validate.go
+++ b/pkg/specgen/generate/validate.go
@@ -48,7 +48,7 @@ func verifyContainerResourcesCgroupV1(s *specgen.SpecGenerator) ([]string, error
warnings = append(warnings, "Your kernel does not support memory swappiness capabilities, or the cgroup is not mounted. Memory swappiness discarded.")
memory.Swappiness = nil
} else {
- if *memory.Swappiness < 0 || *memory.Swappiness > 100 {
+ if *memory.Swappiness > 100 {
return warnings, errors.Errorf("invalid value: %v, valid memory swappiness range is 0-100", *memory.Swappiness)
}
}
diff --git a/pkg/systemd/generate/common.go b/pkg/systemd/generate/common.go
index fb921cd72..8901298db 100644
--- a/pkg/systemd/generate/common.go
+++ b/pkg/systemd/generate/common.go
@@ -71,3 +71,30 @@ func quoteArguments(command []string) []string {
}
return command
}
+
+func removeDetachArg(args []string, argCount int) []string {
+ // "--detach=false" could also be in the container entrypoint
+ // split them off so we do not remove it there
+ realArgs := args[len(args)-argCount:]
+ flagArgs := removeArg("-d=false", args[:len(args)-argCount])
+ flagArgs = removeArg("--detach=false", flagArgs)
+ return append(flagArgs, realArgs...)
+}
+
+func removeReplaceArg(args []string, argCount int) []string {
+ // "--replace=false" could also be in the container entrypoint
+ // split them off so we do not remove it there
+ realArgs := args[len(args)-argCount:]
+ flagArgs := removeArg("--replace=false", args[:len(args)-argCount])
+ return append(flagArgs, realArgs...)
+}
+
+func removeArg(arg string, args []string) []string {
+ newArgs := []string{}
+ for _, a := range args {
+ if a != arg {
+ newArgs = append(newArgs, a)
+ }
+ }
+ return newArgs
+}
diff --git a/pkg/systemd/generate/containers.go b/pkg/systemd/generate/containers.go
index cfa02dc9d..b64b2593c 100644
--- a/pkg/systemd/generate/containers.go
+++ b/pkg/systemd/generate/containers.go
@@ -14,6 +14,7 @@ import (
"github.com/containers/podman/v2/version"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
+ "github.com/spf13/pflag"
)
// containerInfo contains data required for generating a container's systemd
@@ -44,6 +45,9 @@ type containerInfo struct {
// Executable is the path to the podman executable. Will be auto-filled if
// left empty.
Executable string
+ // RootFlags contains the root flags which were used to create the container
+ // Only used with --new
+ RootFlags string
// TimeStamp at the time of creating the unit file. Will be set internally.
TimeStamp string
// CreateCommand is the full command plus arguments of the process the
@@ -185,22 +189,30 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst
info.ContainerIDFile = "%t/" + info.ServiceName + ".ctr-id"
// The create command must at least have three arguments:
// /usr/bin/podman run $IMAGE
- index := 2
- if info.CreateCommand[1] == "container" {
- index = 3
+ index := 0
+ for i, arg := range info.CreateCommand {
+ if arg == "run" || arg == "create" {
+ index = i + 1
+ break
+ }
}
- if len(info.CreateCommand) < index+1 {
+ if index == 0 {
return "", errors.Errorf("container's create command is too short or invalid: %v", info.CreateCommand)
}
// We're hard-coding the first five arguments and append the
// CreateCommand with a stripped command and subcommand.
- startCommand := []string{
- info.Executable,
+ startCommand := []string{info.Executable}
+ if index > 2 {
+ // include root flags
+ info.RootFlags = strings.Join(quoteArguments(info.CreateCommand[1:index-1]), " ")
+ startCommand = append(startCommand, info.CreateCommand[1:index-1]...)
+ }
+ startCommand = append(startCommand,
"run",
"--conmon-pidfile", "{{.PIDFile}}",
"--cidfile", "{{.ContainerIDFile}}",
"--cgroups=no-conmon",
- }
+ )
// If the container is in a pod, make sure that the
// --pod-id-file is set correctly.
if info.pod != nil {
@@ -210,23 +222,27 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst
}
// Presence check for certain flags/options.
- hasDetachParam := false
- hasNameParam := false
- hasReplaceParam := false
- for _, p := range info.CreateCommand[index:] {
- switch p {
- case "--detach", "-d":
- hasDetachParam = true
- case "--name":
- hasNameParam = true
- case "--replace":
- hasReplaceParam = true
- }
- if strings.HasPrefix(p, "--name=") {
- hasNameParam = true
- }
+ fs := pflag.NewFlagSet("args", pflag.ContinueOnError)
+ fs.ParseErrorsWhitelist.UnknownFlags = true
+ fs.Usage = func() {}
+ fs.SetInterspersed(false)
+ fs.BoolP("detach", "d", false, "")
+ fs.String("name", "", "")
+ fs.Bool("replace", false, "")
+ fs.Parse(info.CreateCommand[index:])
+
+ hasDetachParam, err := fs.GetBool("detach")
+ if err != nil {
+ return "", err
+ }
+ hasNameParam := fs.Lookup("name").Changed
+ hasReplaceParam, err := fs.GetBool("replace")
+ if err != nil {
+ return "", err
}
+ remainingCmd := info.CreateCommand[index:]
+
if !hasDetachParam {
// Enforce detaching
//
@@ -240,6 +256,13 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst
// will wait the `podman run` command exit until failed
// with timeout error.
startCommand = append(startCommand, "-d")
+
+ if fs.Changed("detach") {
+ // this can only happen if --detach=false is set
+ // in that case we need to remove it otherwise we
+ // would overwrite the previous detach arg to false
+ remainingCmd = removeDetachArg(remainingCmd, fs.NArg())
+ }
}
if hasNameParam && !hasReplaceParam {
// Enforce --replace for named containers. This will
@@ -247,14 +270,21 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst
// start after system crashes (see
// github.com/containers/podman/issues/5485).
startCommand = append(startCommand, "--replace")
+
+ if fs.Changed("replace") {
+ // this can only happen if --replace=false is set
+ // in that case we need to remove it otherwise we
+ // would overwrite the previous replace arg to false
+ remainingCmd = removeReplaceArg(remainingCmd, fs.NArg())
+ }
}
- startCommand = append(startCommand, info.CreateCommand[index:]...)
+ startCommand = append(startCommand, remainingCmd...)
startCommand = quoteArguments(startCommand)
info.ExecStartPre = "/bin/rm -f {{.PIDFile}} {{.ContainerIDFile}}"
info.ExecStart = strings.Join(startCommand, " ")
- info.ExecStop = "{{.Executable}} stop --ignore --cidfile {{.ContainerIDFile}} {{if (ge .StopTimeout 0)}}-t {{.StopTimeout}}{{end}}"
- info.ExecStopPost = "{{.Executable}} 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
diff --git a/pkg/systemd/generate/containers_test.go b/pkg/systemd/generate/containers_test.go
index b8f3a90f9..c8e65bfe3 100644
--- a/pkg/systemd/generate/containers_test.go
+++ b/pkg/systemd/generate/containers_test.go
@@ -122,9 +122,9 @@ 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 jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN "foo=arg \"with \" space"
-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
+ExecStart=/usr/bin/podman container run --conmon-pidfile %t/jadda-jadda.pid --cidfile %t/jadda-jadda.ctr-id --cgroups=no-conmon -d --replace --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN "foo=arg \"with \" space"
+ExecStop=/usr/bin/podman container stop --ignore --cidfile %t/jadda-jadda.ctr-id -t 10
+ExecStopPost=/usr/bin/podman container rm --ignore -f --cidfile %t/jadda-jadda.ctr-id
PIDFile=%t/jadda-jadda.pid
Type=forking
@@ -228,6 +228,107 @@ Type=forking
WantedBy=multi-user.target default.target
`
+ genGoodNewDetach := func(detachparam string) string {
+ goodNewDetach := `# 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=102
+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 ` +
+ detachparam +
+ ` awesome-image:latest
+ExecStop=/usr/bin/podman stop --ignore --cidfile %t/jadda-jadda.ctr-id -t 42
+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
+`
+ return goodNewDetach
+ }
+
+ goodNameNewDetachFalseWithCmd := `# 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=102
+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 -p 80:80 awesome-image:latest somecmd --detach=false
+ExecStop=/usr/bin/podman stop --ignore --cidfile %t/jadda-jadda.ctr-id -t 42
+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
+`
+
+ goodNewRootFlags := `# 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=102
+ExecStartPre=/bin/rm -f %t/jadda-jadda.pid %t/jadda-jadda.ctr-id
+ExecStart=/usr/bin/podman --events-backend none --runroot /root run --conmon-pidfile %t/jadda-jadda.pid --cidfile %t/jadda-jadda.ctr-id --cgroups=no-conmon -d awesome-image:latest
+ExecStop=/usr/bin/podman --events-backend none --runroot /root stop --ignore --cidfile %t/jadda-jadda.ctr-id -t 42
+ExecStopPost=/usr/bin/podman --events-backend none --runroot /root rm --ignore -f --cidfile %t/jadda-jadda.ctr-id
+PIDFile=%t/jadda-jadda.pid
+Type=forking
+
+[Install]
+WantedBy=multi-user.target default.target
+`
+
+ goodContainerCreate := `# 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 container run --conmon-pidfile %t/jadda-jadda.pid --cidfile %t/jadda-jadda.ctr-id --cgroups=no-conmon -d awesome-image:latest
+ExecStop=/usr/bin/podman container stop --ignore --cidfile %t/jadda-jadda.ctr-id -t 10
+ExecStopPost=/usr/bin/podman container 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
@@ -321,7 +422,7 @@ WantedBy=multi-user.target default.target
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 10,
PodmanVersion: "CI",
- CreateCommand: []string{"I'll get stripped", "container", "run", "-d", "--name", "jadda-jadda", "--hostname", "hello-world", "awesome-image:latest", "command", "arg1", "...", "argN"},
+ CreateCommand: []string{"I'll get stripped", "run", "-d", "--name", "jadda-jadda", "--hostname", "hello-world", "awesome-image:latest", "command", "arg1", "...", "argN"},
EnvVariable: EnvVariable,
},
goodWithExplicitShortDetachParam,
@@ -337,7 +438,7 @@ WantedBy=multi-user.target default.target
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 10,
PodmanVersion: "CI",
- CreateCommand: []string{"I'll get stripped", "container", "run", "-d", "--name", "jadda-jadda", "--hostname", "hello-world", "awesome-image:latest", "command", "arg1", "...", "argN"},
+ CreateCommand: []string{"I'll get stripped", "run", "-d", "--name", "jadda-jadda", "--hostname", "hello-world", "awesome-image:latest", "command", "arg1", "...", "argN"},
EnvVariable: EnvVariable,
pod: &podInfo{
PodIDFile: "/tmp/pod-foobar.pod-id-file",
@@ -356,7 +457,7 @@ WantedBy=multi-user.target default.target
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 10,
PodmanVersion: "CI",
- CreateCommand: []string{"I'll get stripped", "container", "run", "--detach", "--name", "jadda-jadda", "--hostname", "hello-world", "awesome-image:latest", "command", "arg1", "...", "argN"},
+ CreateCommand: []string{"I'll get stripped", "run", "--detach", "--name", "jadda-jadda", "--hostname", "hello-world", "awesome-image:latest", "command", "arg1", "...", "argN"},
EnvVariable: EnvVariable,
},
goodNameNewDetach,
@@ -372,13 +473,141 @@ WantedBy=multi-user.target default.target
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 10,
PodmanVersion: "CI",
- CreateCommand: []string{"I'll get stripped", "container", "run", "awesome-image:latest"},
+ CreateCommand: []string{"I'll get stripped", "run", "awesome-image:latest"},
EnvVariable: EnvVariable,
},
goodIDNew,
true,
false,
},
+ {"good with explicit detach=true param",
+ 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: 42,
+ PodmanVersion: "CI",
+ CreateCommand: []string{"I'll get stripped", "run", "--detach=true", "awesome-image:latest"},
+ EnvVariable: EnvVariable,
+ },
+ genGoodNewDetach("--detach=true"),
+ true,
+ false,
+ },
+ {"good with explicit detach=false param",
+ 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: 42,
+ PodmanVersion: "CI",
+ CreateCommand: []string{"I'll get stripped", "run", "--detach=false", "awesome-image:latest"},
+ EnvVariable: EnvVariable,
+ },
+ genGoodNewDetach("-d"),
+ true,
+ false,
+ },
+ {"good with explicit detach=false param",
+ 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: 42,
+ PodmanVersion: "CI",
+ CreateCommand: []string{"I'll get stripped", "run", "--name", "test", "-p", "80:80", "--detach=false", "awesome-image:latest", "somecmd", "--detach=false"},
+ EnvVariable: EnvVariable,
+ },
+ goodNameNewDetachFalseWithCmd,
+ true,
+ false,
+ },
+ {"good with multiple detach=false params",
+ 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: 42,
+ PodmanVersion: "CI",
+ CreateCommand: []string{"I'll get stripped", "run", "--name", "test", "-p", "80:80", "--detach=false", "--detach=false", "awesome-image:latest", "somecmd", "--detach=false"},
+ EnvVariable: EnvVariable,
+ },
+ goodNameNewDetachFalseWithCmd,
+ true,
+ false,
+ },
+ {"good with multiple shorthand params detach first",
+ 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: 42,
+ PodmanVersion: "CI",
+ CreateCommand: []string{"I'll get stripped", "run", "-dti", "awesome-image:latest"},
+ EnvVariable: EnvVariable,
+ },
+ genGoodNewDetach("-dti"),
+ true,
+ false,
+ },
+ {"good with multiple shorthand params detach last",
+ 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: 42,
+ PodmanVersion: "CI",
+ CreateCommand: []string{"I'll get stripped", "run", "-tid", "awesome-image:latest"},
+ EnvVariable: EnvVariable,
+ },
+ genGoodNewDetach("-tid"),
+ true,
+ false,
+ },
+ {"good with root flags",
+ 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: 42,
+ PodmanVersion: "CI",
+ CreateCommand: []string{"I'll get stripped", "--events-backend", "none", "--runroot", "/root", "run", "awesome-image:latest"},
+ EnvVariable: EnvVariable,
+ },
+ goodNewRootFlags,
+ true,
+ false,
+ },
+ {"good with container create",
+ 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", "container", "create", "awesome-image:latest"},
+ EnvVariable: EnvVariable,
+ },
+ goodContainerCreate,
+ true,
+ false,
+ },
}
for _, tt := range tests {
test := tt
diff --git a/pkg/systemd/generate/pods.go b/pkg/systemd/generate/pods.go
index fc582e42a..7678a240f 100644
--- a/pkg/systemd/generate/pods.go
+++ b/pkg/systemd/generate/pods.go
@@ -14,6 +14,7 @@ import (
"github.com/containers/podman/v2/version"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
+ "github.com/spf13/pflag"
)
// podInfo contains data required for generating a pod's systemd
@@ -44,6 +45,9 @@ type podInfo struct {
// Executable is the path to the podman executable. Will be auto-filled if
// left empty.
Executable string
+ // RootFlags contains the root flags which were used to create the container
+ // Only used with --new
+ RootFlags string
// TimeStamp at the time of creating the unit file. Will be set internally.
TimeStamp string
// CreateCommand is the full command plus arguments of the process the
@@ -264,7 +268,8 @@ func executePodTemplate(info *podInfo, options entities.GenerateSystemdOptions)
if podCreateIndex == 0 {
return "", errors.Errorf("pod does not appear to be created via `podman pod create`: %v", info.CreateCommand)
}
- podRootArgs = info.CreateCommand[0 : podCreateIndex-2]
+ podRootArgs = info.CreateCommand[1 : podCreateIndex-1]
+ info.RootFlags = strings.Join(quoteArguments(podRootArgs), " ")
podCreateArgs = filterPodFlags(info.CreateCommand[podCreateIndex+1:])
}
// We're hard-coding the first five arguments and append the
@@ -277,17 +282,26 @@ func executePodTemplate(info *podInfo, options entities.GenerateSystemdOptions)
"--pod-id-file", "{{.PodIDFile}}"}...)
// Presence check for certain flags/options.
- hasNameParam := false
- hasReplaceParam := false
- for _, p := range podCreateArgs {
- switch p {
- case "--name":
- hasNameParam = true
- case "--replace":
- hasReplaceParam = true
- }
+ fs := pflag.NewFlagSet("args", pflag.ContinueOnError)
+ fs.ParseErrorsWhitelist.UnknownFlags = true
+ fs.Usage = func() {}
+ fs.SetInterspersed(false)
+ fs.String("name", "", "")
+ fs.Bool("replace", false, "")
+ fs.Parse(podCreateArgs)
+
+ hasNameParam := fs.Lookup("name").Changed
+ hasReplaceParam, err := fs.GetBool("replace")
+ if err != nil {
+ return "", err
}
if hasNameParam && !hasReplaceParam {
+ if fs.Changed("replace") {
+ // this can only happen if --replace=false is set
+ // in that case we need to remove it otherwise we
+ // would overwrite the previous replace arg to false
+ podCreateArgs = removeReplaceArg(podCreateArgs, fs.NArg())
+ }
podCreateArgs = append(podCreateArgs, "--replace")
}
@@ -296,9 +310,9 @@ func executePodTemplate(info *podInfo, options entities.GenerateSystemdOptions)
info.ExecStartPre1 = "/bin/rm -f {{.PIDFile}} {{.PodIDFile}}"
info.ExecStartPre2 = strings.Join(startCommand, " ")
- info.ExecStart = "{{.Executable}} pod start --pod-id-file {{.PodIDFile}}"
- info.ExecStop = "{{.Executable}} pod stop --ignore --pod-id-file {{.PodIDFile}} {{if (ge .StopTimeout 0)}}-t {{.StopTimeout}}{{end}}"
- info.ExecStopPost = "{{.Executable}} 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
diff --git a/pkg/systemd/generate/pods_test.go b/pkg/systemd/generate/pods_test.go
index 93432ef96..c0d98df45 100644
--- a/pkg/systemd/generate/pods_test.go
+++ b/pkg/systemd/generate/pods_test.go
@@ -89,6 +89,60 @@ Type=forking
WantedBy=multi-user.target default.target
`
+ podGoodNamedNewWithRootArgs := `# 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 --events-backend none --runroot /root pod create --infra-conmon-pidfile %t/pod-123abc.pid --pod-id-file %t/pod-123abc.pod-id --name foo "bar=arg with space" --replace
+ExecStart=/usr/bin/podman --events-backend none --runroot /root pod start --pod-id-file %t/pod-123abc.pod-id
+ExecStop=/usr/bin/podman --events-backend none --runroot /root pod stop --ignore --pod-id-file %t/pod-123abc.pod-id -t 10
+ExecStopPost=/usr/bin/podman --events-backend none --runroot /root 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
+`
+
+ podGoodNamedNewWithReplaceFalse := `# 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 --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
@@ -106,6 +160,23 @@ WantedBy=multi-user.target default.target
StopTimeout: 42,
PodmanVersion: "CI",
RequiredServices: []string{"container-1", "container-2"},
+ CreateCommand: []string{"podman", "pod", "create", "--name", "foo", "bar=arg with space"},
+ },
+ podGood,
+ false,
+ false,
+ },
+ {"pod with root args",
+ podInfo{
+ Executable: "/usr/bin/podman",
+ ServiceName: "pod-123abc",
+ InfraNameOrID: "jadda-jadda-infra",
+ RestartPolicy: "always",
+ PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
+ StopTimeout: 42,
+ PodmanVersion: "CI",
+ RequiredServices: []string{"container-1", "container-2"},
+ CreateCommand: []string{"podman", "--events-backend", "none", "--runroot", "/root", "pod", "create", "--name", "foo", "bar=arg with space"},
},
podGood,
false,
@@ -127,6 +198,38 @@ WantedBy=multi-user.target default.target
true,
false,
},
+ {"pod --new with root args",
+ podInfo{
+ Executable: "/usr/bin/podman",
+ ServiceName: "pod-123abc",
+ InfraNameOrID: "jadda-jadda-infra",
+ RestartPolicy: "on-failure",
+ PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
+ StopTimeout: 10,
+ PodmanVersion: "CI",
+ RequiredServices: []string{"container-1", "container-2"},
+ CreateCommand: []string{"podman", "--events-backend", "none", "--runroot", "/root", "pod", "create", "--name", "foo", "bar=arg with space"},
+ },
+ podGoodNamedNewWithRootArgs,
+ true,
+ false,
+ },
+ {"pod --new with --replace=false",
+ podInfo{
+ Executable: "/usr/bin/podman",
+ ServiceName: "pod-123abc",
+ InfraNameOrID: "jadda-jadda-infra",
+ RestartPolicy: "on-failure",
+ PIDFile: "/var/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", "--replace=false"},
+ },
+ podGoodNamedNewWithReplaceFalse,
+ true,
+ false,
+ },
}
for _, tt := range tests {
diff --git a/test/e2e/generate_systemd_test.go b/test/e2e/generate_systemd_test.go
index 3f059300b..be9727591 100644
--- a/test/e2e/generate_systemd_test.go
+++ b/test/e2e/generate_systemd_test.go
@@ -59,8 +59,7 @@ var _ = Describe("Podman generate systemd", func() {
session = podmanTest.Podman([]string{"generate", "systemd", "--restart-policy", "bogus", "foobar"})
session.WaitWithDefaultTimeout()
Expect(session).To(ExitWithError())
- found, _ := session.ErrorGrepString("bogus is not a valid restart policy")
- Expect(found).Should(BeTrue())
+ Expect(session.ErrorToString()).To(ContainSubstring("bogus is not a valid restart policy"))
})
It("podman generate systemd good timeout value", func() {
@@ -71,12 +70,8 @@ var _ = Describe("Podman generate systemd", func() {
session = podmanTest.Podman([]string{"generate", "systemd", "--time", "1234", "foobar"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
-
- found, _ := session.GrepString(" stop -t 1234 ")
- Expect(found).To(BeTrue())
-
- found, _ = session.GrepString("TimeoutStopSec=1294")
- Expect(found).To(BeTrue())
+ Expect(session.OutputToString()).To(ContainSubstring("TimeoutStopSec=1294"))
+ Expect(session.OutputToString()).To(ContainSubstring(" stop -t 1234 "))
})
It("podman generate systemd", func() {
@@ -87,6 +82,9 @@ var _ = Describe("Podman generate systemd", func() {
session := podmanTest.Podman([]string{"generate", "systemd", "nginx"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
+
+ // The podman commands in the unit should not contain the root flags
+ Expect(session.OutputToString()).ToNot(ContainSubstring(" --runroot"))
})
It("podman generate systemd --files --name", func() {
@@ -101,9 +99,7 @@ var _ = Describe("Podman generate systemd", func() {
for _, file := range session.OutputToStringArray() {
os.Remove(file)
}
-
- found, _ := session.GrepString("/container-nginx.service")
- Expect(found).To(BeTrue())
+ Expect(session.OutputToString()).To(ContainSubstring("/container-nginx.service"))
})
It("podman generate systemd with timeout", func() {
@@ -114,9 +110,7 @@ var _ = Describe("Podman generate systemd", func() {
session := podmanTest.Podman([]string{"generate", "systemd", "--time", "5", "nginx"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
-
- found, _ := session.GrepString("podman stop -t 5")
- Expect(found).To(BeTrue())
+ Expect(session.OutputToString()).To(ContainSubstring("podman stop -t 5"))
})
It("podman generate systemd pod --name", func() {
@@ -137,35 +131,19 @@ var _ = Describe("Podman generate systemd", func() {
Expect(session.ExitCode()).To(Equal(0))
// Grepping the output (in addition to unit tests)
- found, _ := session.GrepString("# pod-foo.service")
- Expect(found).To(BeTrue())
-
- found, _ = session.GrepString("Requires=container-foo-1.service container-foo-2.service")
- Expect(found).To(BeTrue())
-
- found, _ = session.GrepString("# container-foo-1.service")
- Expect(found).To(BeTrue())
-
- found, _ = session.GrepString(" start foo-1")
- Expect(found).To(BeTrue())
-
- found, _ = session.GrepString("-infra") // infra container
- Expect(found).To(BeTrue())
-
- found, _ = session.GrepString("# container-foo-2.service")
- Expect(found).To(BeTrue())
-
- found, _ = session.GrepString(" stop -t 42 foo-2")
- Expect(found).To(BeTrue())
-
- found, _ = session.GrepString("BindsTo=pod-foo.service")
- Expect(found).To(BeTrue())
-
- found, _ = session.GrepString("PIDFile=")
- Expect(found).To(BeTrue())
-
- found, _ = session.GrepString("/userdata/conmon.pid")
- Expect(found).To(BeTrue())
+ Expect(session.OutputToString()).To(ContainSubstring("# pod-foo.service"))
+ Expect(session.OutputToString()).To(ContainSubstring("Requires=container-foo-1.service container-foo-2.service"))
+ Expect(session.OutputToString()).To(ContainSubstring("# container-foo-1.service"))
+ Expect(session.OutputToString()).To(ContainSubstring(" start foo-1"))
+ Expect(session.OutputToString()).To(ContainSubstring("-infra")) // infra container
+ Expect(session.OutputToString()).To(ContainSubstring("# container-foo-2.service"))
+ Expect(session.OutputToString()).To(ContainSubstring(" stop -t 42 foo-2"))
+ Expect(session.OutputToString()).To(ContainSubstring("BindsTo=pod-foo.service"))
+ Expect(session.OutputToString()).To(ContainSubstring("PIDFile="))
+ Expect(session.OutputToString()).To(ContainSubstring("/userdata/conmon.pid"))
+
+ // The podman commands in the unit should not contain the root flags
+ Expect(session.OutputToString()).ToNot(ContainSubstring(" --runroot"))
})
It("podman generate systemd pod --name --files", func() {
@@ -185,11 +163,8 @@ var _ = Describe("Podman generate systemd", func() {
os.Remove(file)
}
- found, _ := session.GrepString("/pod-foo.service")
- Expect(found).To(BeTrue())
-
- found, _ = session.GrepString("/container-foo-1.service")
- Expect(found).To(BeTrue())
+ Expect(session.OutputToString()).To(ContainSubstring("/pod-foo.service"))
+ Expect(session.OutputToString()).To(ContainSubstring("/container-foo-1.service"))
})
It("podman generate systemd --new --name foo", func() {
@@ -202,14 +177,13 @@ var _ = Describe("Podman generate systemd", func() {
Expect(session.ExitCode()).To(Equal(0))
// Grepping the output (in addition to unit tests)
- found, _ := session.GrepString("# container-foo.service")
- Expect(found).To(BeTrue())
-
- found, _ = session.GrepString(" --replace ")
- Expect(found).To(BeTrue())
-
- found, _ = session.GrepString("stop --ignore --cidfile %t/container-foo.ctr-id -t 42")
- Expect(found).To(BeTrue())
+ Expect(session.OutputToString()).To(ContainSubstring("# container-foo.service"))
+ Expect(session.OutputToString()).To(ContainSubstring(" --replace "))
+ Expect(session.OutputToString()).To(ContainSubstring(" stop --ignore --cidfile %t/container-foo.ctr-id -t 42"))
+ if !IsRemote() {
+ // The podman commands in the unit should contain the root flags if generate systemd --new is used
+ Expect(session.OutputToString()).To(ContainSubstring(" --runroot"))
+ }
})
It("podman generate systemd --new --name=foo", func() {
@@ -222,14 +196,9 @@ var _ = Describe("Podman generate systemd", func() {
Expect(session.ExitCode()).To(Equal(0))
// Grepping the output (in addition to unit tests)
- found, _ := session.GrepString("# container-foo.service")
- Expect(found).To(BeTrue())
-
- found, _ = session.GrepString(" --replace ")
- Expect(found).To(BeTrue())
-
- found, _ = session.GrepString("stop --ignore --cidfile %t/container-foo.ctr-id -t 42")
- Expect(found).To(BeTrue())
+ Expect(session.OutputToString()).To(ContainSubstring("# container-foo.service"))
+ Expect(session.OutputToString()).To(ContainSubstring(" --replace "))
+ Expect(session.OutputToString()).To(ContainSubstring(" stop --ignore --cidfile %t/container-foo.ctr-id -t 42"))
})
It("podman generate systemd --new without explicit detaching param", func() {
@@ -242,8 +211,7 @@ var _ = Describe("Podman generate systemd", func() {
Expect(session.ExitCode()).To(Equal(0))
// Grepping the output (in addition to unit tests)
- found, _ := session.GrepString("--cgroups=no-conmon -d")
- Expect(found).To(BeTrue())
+ Expect(session.OutputToString()).To(ContainSubstring("--cgroups=no-conmon -d"))
})
It("podman generate systemd --new with explicit detaching param in middle", func() {
@@ -256,8 +224,7 @@ var _ = Describe("Podman generate systemd", func() {
Expect(session.ExitCode()).To(Equal(0))
// Grepping the output (in addition to unit tests)
- found, _ := session.GrepString("--name foo alpine top")
- Expect(found).To(BeTrue())
+ Expect(session.OutputToString()).To(ContainSubstring("--name foo alpine top"))
})
It("podman generate systemd --new pod", func() {
@@ -280,8 +247,8 @@ var _ = Describe("Podman generate systemd", func() {
Expect(session.ExitCode()).To(Equal(0))
// Grepping the output (in addition to unit tests)
- found, _ := session.GrepString("# con-foo.service")
- Expect(found).To(BeTrue())
+ Expect(session.OutputToString()).To(ContainSubstring("# con-foo.service"))
+
})
It("podman generate systemd --separator _", func() {
@@ -294,8 +261,7 @@ var _ = Describe("Podman generate systemd", func() {
Expect(session.ExitCode()).To(Equal(0))
// Grepping the output (in addition to unit tests)
- found, _ := session.GrepString("# container_foo.service")
- Expect(found).To(BeTrue())
+ Expect(session.OutputToString()).To(ContainSubstring("# container_foo.service"))
})
It("podman generate systemd pod --pod-prefix p", func() {
@@ -316,17 +282,10 @@ var _ = Describe("Podman generate systemd", func() {
Expect(session.ExitCode()).To(Equal(0))
// Grepping the output (in addition to unit tests)
- found, _ := session.GrepString("# p-foo.service")
- Expect(found).To(BeTrue())
-
- found, _ = session.GrepString("Requires=container-foo-1.service container-foo-2.service")
- Expect(found).To(BeTrue())
-
- found, _ = session.GrepString("# container-foo-1.service")
- Expect(found).To(BeTrue())
-
- found, _ = session.GrepString("BindsTo=p-foo.service")
- Expect(found).To(BeTrue())
+ Expect(session.OutputToString()).To(ContainSubstring("# p-foo.service"))
+ Expect(session.OutputToString()).To(ContainSubstring("Requires=container-foo-1.service container-foo-2.service"))
+ Expect(session.OutputToString()).To(ContainSubstring("# container-foo-1.service"))
+ Expect(session.OutputToString()).To(ContainSubstring("BindsTo=p-foo.service"))
})
It("podman generate systemd pod --pod-prefix p --container-prefix con --separator _ change all prefixes/separator", func() {
@@ -347,20 +306,11 @@ var _ = Describe("Podman generate systemd", func() {
Expect(session.ExitCode()).To(Equal(0))
// Grepping the output (in addition to unit tests)
- found, _ := session.GrepString("# p_foo.service")
- Expect(found).To(BeTrue())
-
- found, _ = session.GrepString("Requires=con_foo-1.service con_foo-2.service")
- Expect(found).To(BeTrue())
-
- found, _ = session.GrepString("# con_foo-1.service")
- Expect(found).To(BeTrue())
-
- found, _ = session.GrepString("# con_foo-2.service")
- Expect(found).To(BeTrue())
-
- found, _ = session.GrepString("BindsTo=p_foo.service")
- Expect(found).To(BeTrue())
+ Expect(session.OutputToString()).To(ContainSubstring("# p_foo.service"))
+ Expect(session.OutputToString()).To(ContainSubstring("Requires=con_foo-1.service con_foo-2.service"))
+ Expect(session.OutputToString()).To(ContainSubstring("# con_foo-1.service"))
+ Expect(session.OutputToString()).To(ContainSubstring("# con_foo-2.service"))
+ Expect(session.OutputToString()).To(ContainSubstring("BindsTo=p_foo.service"))
})
It("podman generate systemd pod with containers --new", func() {
@@ -386,26 +336,13 @@ var _ = Describe("Podman generate systemd", func() {
Expect(session.ExitCode()).To(Equal(0))
// Grepping the output (in addition to unit tests)
- found, _ := session.GrepString("# pod-foo.service")
- Expect(found).To(BeTrue())
-
- found, _ = session.GrepString("Requires=container-foo-1.service container-foo-2.service")
- Expect(found).To(BeTrue())
-
- found, _ = session.GrepString("BindsTo=pod-foo.service")
- Expect(found).To(BeTrue())
-
- found, _ = session.GrepString("pod create --infra-conmon-pidfile %t/pod-foo.pid --pod-id-file %t/pod-foo.pod-id --name foo")
- Expect(found).To(BeTrue())
-
- found, _ = session.GrepString("ExecStartPre=/bin/rm -f %t/pod-foo.pid %t/pod-foo.pod-id")
- Expect(found).To(BeTrue())
-
- found, _ = session.GrepString("pod stop --ignore --pod-id-file %t/pod-foo.pod-id -t 10")
- Expect(found).To(BeTrue())
-
- found, _ = session.GrepString("pod rm --ignore -f --pod-id-file %t/pod-foo.pod-id")
- Expect(found).To(BeTrue())
+ Expect(session.OutputToString()).To(ContainSubstring("# pod-foo.service"))
+ Expect(session.OutputToString()).To(ContainSubstring("Requires=container-foo-1.service container-foo-2.service"))
+ Expect(session.OutputToString()).To(ContainSubstring("BindsTo=pod-foo.service"))
+ Expect(session.OutputToString()).To(ContainSubstring("pod create --infra-conmon-pidfile %t/pod-foo.pid --pod-id-file %t/pod-foo.pod-id --name foo"))
+ Expect(session.OutputToString()).To(ContainSubstring("ExecStartPre=/bin/rm -f %t/pod-foo.pid %t/pod-foo.pod-id"))
+ Expect(session.OutputToString()).To(ContainSubstring("pod stop --ignore --pod-id-file %t/pod-foo.pod-id -t 10"))
+ Expect(session.OutputToString()).To(ContainSubstring("pod rm --ignore -f --pod-id-file %t/pod-foo.pod-id"))
})
It("podman generate systemd --format json", func() {
diff --git a/test/e2e/search_test.go b/test/e2e/search_test.go
index f809c5afe..1d86ae744 100644
--- a/test/e2e/search_test.go
+++ b/test/e2e/search_test.go
@@ -124,6 +124,16 @@ registries = ['{{.Host}}:{{.Port}}']`
Expect(search.OutputToString()).To(ContainSubstring("docker.io/library/alpine"))
})
+ It("podman search format json list tags", func() {
+ search := podmanTest.Podman([]string{"search", "--list-tags", "--format", "json", "alpine"})
+ search.WaitWithDefaultTimeout()
+ Expect(search.ExitCode()).To(Equal(0))
+ Expect(search.IsJSONOutputValid()).To(BeTrue())
+ Expect(search.OutputToString()).To(ContainSubstring("docker.io/library/alpine"))
+ Expect(search.OutputToString()).To(ContainSubstring("3.10"))
+ Expect(search.OutputToString()).To(ContainSubstring("2.7"))
+ })
+
It("podman search no-trunc flag", func() {
search := podmanTest.Podman([]string{"search", "--no-trunc", "alpine"})
search.WaitWithDefaultTimeout()