summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/common/completion.go9
-rw-r--r--cmd/podman/common/specgen.go6
-rw-r--r--cmd/podman/networks/list.go2
-rw-r--r--cmd/podman/parse/filters.go (renamed from pkg/domain/filters/helpers.go)4
-rw-r--r--cmd/podman/system/prune.go4
-rw-r--r--cmd/podman/volumes/prune.go6
-rw-r--r--go.mod2
-rw-r--r--go.sum2
-rw-r--r--libpod/container.go18
-rw-r--r--libpod/container_internal.go8
-rw-r--r--libpod/define/container.go19
-rw-r--r--libpod/kube.go6
-rw-r--r--libpod/network/files.go13
-rw-r--r--libpod/network/netconflist.go7
-rw-r--r--libpod/network/network.go9
-rw-r--r--libpod/options.go2
-rw-r--r--pkg/api/handlers/compat/auth.go59
-rw-r--r--pkg/api/handlers/compat/images_build.go7
-rw-r--r--pkg/api/handlers/compat/networks.go3
-rw-r--r--pkg/api/server/register_auth.go24
-rw-r--r--pkg/api/server/register_images.go2
-rw-r--r--pkg/api/server/register_networks.go45
-rw-r--r--pkg/api/server/swagger.go9
-rw-r--r--pkg/autoupdate/autoupdate.go6
-rw-r--r--pkg/domain/entities/system.go11
-rw-r--r--pkg/domain/filters/containers.go2
-rw-r--r--pkg/domain/filters/pods.go2
-rw-r--r--pkg/domain/infra/abi/play.go8
-rw-r--r--pkg/network/network.go27
-rw-r--r--pkg/systemd/define/const.go9
-rw-r--r--pkg/systemd/generate/common.go11
-rw-r--r--pkg/systemd/generate/containers.go3
-rw-r--r--pkg/systemd/generate/containers_test.go41
-rw-r--r--pkg/systemd/generate/pods.go3
-rw-r--r--test/apiv2/01-basic.at10
-rw-r--r--test/apiv2/10-images.at8
-rw-r--r--test/apiv2/12-imagesMore.at10
-rw-r--r--test/apiv2/20-containers.at53
-rw-r--r--test/apiv2/22-stop.at16
-rw-r--r--test/apiv2/25-containersMore.at10
-rw-r--r--test/apiv2/26-containersWait.at10
-rw-r--r--test/apiv2/30-volumes.at47
-rw-r--r--test/apiv2/35-networks.at13
-rw-r--r--test/apiv2/40-pods.at40
-rw-r--r--test/apiv2/44-mounts.at18
-rw-r--r--test/apiv2/45-system.at34
-rw-r--r--test/apiv2/50-secrets.at8
-rw-r--r--test/apiv2/60-auth.at24
-rw-r--r--test/apiv2/README.md11
-rw-r--r--test/apiv2/rest_api/__init__.py26
-rw-r--r--test/apiv2/rest_api/test_rest_v2_0_0.py70
-rwxr-xr-xtest/apiv2/test-apiv236
-rw-r--r--test/e2e/containers_conf_test.go2
-rw-r--r--test/system/065-cp.bats1
-rw-r--r--test/system/070-build.bats69
-rw-r--r--test/system/120-load.bats3
-rw-r--r--test/system/260-sdnotify.bats13
-rw-r--r--test/system/700-play.bats16
-rw-r--r--vendor/github.com/magefile/mage/LICENSE201
-rw-r--r--vendor/github.com/magefile/mage/mg/color.go80
-rw-r--r--vendor/github.com/magefile/mage/mg/color_string.go38
-rw-r--r--vendor/github.com/magefile/mage/mg/deps.go352
-rw-r--r--vendor/github.com/magefile/mage/mg/errors.go51
-rw-r--r--vendor/github.com/magefile/mage/mg/runtime.go136
-rw-r--r--vendor/github.com/magefile/mage/sh/cmd.go177
-rw-r--r--vendor/github.com/magefile/mage/sh/helpers.go40
-rw-r--r--vendor/github.com/sirupsen/logrus/.travis.yml7
-rw-r--r--vendor/github.com/sirupsen/logrus/CHANGELOG.md9
-rw-r--r--vendor/github.com/sirupsen/logrus/entry.go10
-rw-r--r--vendor/github.com/sirupsen/logrus/go.mod1
-rw-r--r--vendor/github.com/sirupsen/logrus/go.sum4
-rw-r--r--vendor/github.com/sirupsen/logrus/json_formatter.go3
-rw-r--r--vendor/github.com/sirupsen/logrus/magefile.go77
-rw-r--r--vendor/github.com/sirupsen/logrus/text_formatter.go5
-rw-r--r--vendor/modules.txt5
75 files changed, 607 insertions, 1526 deletions
diff --git a/cmd/podman/common/completion.go b/cmd/podman/common/completion.go
index 7629a8145..bc106263c 100644
--- a/cmd/podman/common/completion.go
+++ b/cmd/podman/common/completion.go
@@ -8,12 +8,11 @@ import (
"github.com/containers/common/pkg/config"
"github.com/containers/podman/v3/cmd/podman/registry"
- "github.com/containers/podman/v3/libpod"
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/registries"
"github.com/containers/podman/v3/pkg/rootless"
- systemdGen "github.com/containers/podman/v3/pkg/systemd/generate"
+ systemdDefine "github.com/containers/podman/v3/pkg/systemd/define"
"github.com/containers/podman/v3/pkg/util"
"github.com/spf13/cobra"
)
@@ -732,8 +731,8 @@ func AutocompletePullOption(cmd *cobra.Command, args []string, toComplete string
// AutocompleteRestartOption - Autocomplete restart options for create and run command.
// -> "always", "no", "on-failure", "unless-stopped"
func AutocompleteRestartOption(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
- restartOptions := []string{libpod.RestartPolicyAlways, libpod.RestartPolicyNo,
- libpod.RestartPolicyOnFailure, libpod.RestartPolicyUnlessStopped}
+ restartOptions := []string{define.RestartPolicyAlways, define.RestartPolicyNo,
+ define.RestartPolicyOnFailure, define.RestartPolicyUnlessStopped}
return restartOptions, cobra.ShellCompDirectiveNoFileComp
}
@@ -908,7 +907,7 @@ func AutocompleteEventFilter(cmd *cobra.Command, args []string, toComplete strin
// AutocompleteSystemdRestartOptions - Autocomplete systemd restart options.
// -> "no", "on-success", "on-failure", "on-abnormal", "on-watchdog", "on-abort", "always"
func AutocompleteSystemdRestartOptions(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
- return systemdGen.RestartPolicies, cobra.ShellCompDirectiveNoFileComp
+ return systemdDefine.RestartPolicies, cobra.ShellCompDirectiveNoFileComp
}
// AutocompleteTrustType - Autocomplete trust type options.
diff --git a/cmd/podman/common/specgen.go b/cmd/podman/common/specgen.go
index 2fafbfac1..d1b67d963 100644
--- a/cmd/podman/common/specgen.go
+++ b/cmd/podman/common/specgen.go
@@ -14,7 +14,7 @@ import (
envLib "github.com/containers/podman/v3/pkg/env"
ns "github.com/containers/podman/v3/pkg/namespaces"
"github.com/containers/podman/v3/pkg/specgen"
- systemdGen "github.com/containers/podman/v3/pkg/systemd/generate"
+ systemdDefine "github.com/containers/podman/v3/pkg/systemd/define"
"github.com/containers/podman/v3/pkg/util"
"github.com/docker/go-units"
"github.com/opencontainers/runtime-spec/specs-go"
@@ -342,8 +342,8 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
return errors.Wrapf(err, "unable to process labels")
}
- if systemdUnit, exists := osEnv[systemdGen.EnvVariable]; exists {
- labels[systemdGen.EnvVariable] = systemdUnit
+ if systemdUnit, exists := osEnv[systemdDefine.EnvVariable]; exists {
+ labels[systemdDefine.EnvVariable] = systemdUnit
}
s.Labels = labels
diff --git a/cmd/podman/networks/list.go b/cmd/podman/networks/list.go
index 2181f850b..fcbcb6722 100644
--- a/cmd/podman/networks/list.go
+++ b/cmd/podman/networks/list.go
@@ -12,8 +12,8 @@ import (
"github.com/containers/podman/v3/cmd/podman/common"
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/cmd/podman/validate"
- "github.com/containers/podman/v3/libpod/network"
"github.com/containers/podman/v3/pkg/domain/entities"
+ "github.com/containers/podman/v3/pkg/network"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
diff --git a/pkg/domain/filters/helpers.go b/cmd/podman/parse/filters.go
index 6a5fb68b1..8a10f2a97 100644
--- a/pkg/domain/filters/helpers.go
+++ b/cmd/podman/parse/filters.go
@@ -1,4 +1,4 @@
-package filters
+package parse
import (
"net/url"
@@ -7,7 +7,7 @@ import (
"github.com/pkg/errors"
)
-func ParseFilterArgumentsIntoFilters(filters []string) (url.Values, error) {
+func FilterArgumentsIntoFilters(filters []string) (url.Values, error) {
parsedFilters := make(url.Values)
for _, f := range filters {
t := strings.SplitN(f, "=", 2)
diff --git a/cmd/podman/system/prune.go b/cmd/podman/system/prune.go
index dcb3316f0..136c15304 100644
--- a/cmd/podman/system/prune.go
+++ b/cmd/podman/system/prune.go
@@ -8,11 +8,11 @@ import (
"strings"
"github.com/containers/common/pkg/completion"
+ "github.com/containers/podman/v3/cmd/podman/parse"
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/cmd/podman/utils"
"github.com/containers/podman/v3/cmd/podman/validate"
"github.com/containers/podman/v3/pkg/domain/entities"
- dfilters "github.com/containers/podman/v3/pkg/domain/filters"
"github.com/docker/go-units"
"github.com/spf13/cobra"
)
@@ -80,7 +80,7 @@ Are you sure you want to continue? [y/N] `, volumeString)
}
}
- pruneOptions.Filters, err = dfilters.ParseFilterArgumentsIntoFilters(filters)
+ pruneOptions.Filters, err = parse.FilterArgumentsIntoFilters(filters)
if err != nil {
return err
}
diff --git a/cmd/podman/volumes/prune.go b/cmd/podman/volumes/prune.go
index 8f78d0bae..8e190b870 100644
--- a/cmd/podman/volumes/prune.go
+++ b/cmd/podman/volumes/prune.go
@@ -9,11 +9,11 @@ import (
"github.com/containers/common/pkg/completion"
"github.com/containers/podman/v3/cmd/podman/common"
+ "github.com/containers/podman/v3/cmd/podman/parse"
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/cmd/podman/utils"
"github.com/containers/podman/v3/cmd/podman/validate"
"github.com/containers/podman/v3/pkg/domain/entities"
- "github.com/containers/podman/v3/pkg/domain/filters"
"github.com/spf13/cobra"
)
@@ -58,14 +58,14 @@ func prune(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
- pruneOptions.Filters, err = filters.ParseFilterArgumentsIntoFilters(filter)
+ pruneOptions.Filters, err = parse.FilterArgumentsIntoFilters(filter)
if !force {
reader := bufio.NewReader(os.Stdin)
fmt.Println("WARNING! This will remove all volumes not used by at least one container. The following volumes will be removed:")
if err != nil {
return err
}
- listOptions.Filter, err = filters.ParseFilterArgumentsIntoFilters(filter)
+ listOptions.Filter, err = parse.FilterArgumentsIntoFilters(filter)
if err != nil {
return err
}
diff --git a/go.mod b/go.mod
index dd2f196f4..27b7a4a09 100644
--- a/go.mod
+++ b/go.mod
@@ -51,7 +51,7 @@ require (
github.com/pkg/errors v0.9.1
github.com/pmezard/go-difflib v1.0.0
github.com/rootless-containers/rootlesskit v0.14.0-beta.0
- github.com/sirupsen/logrus v1.8.0
+ github.com/sirupsen/logrus v1.8.1
github.com/spf13/cobra v1.1.3
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.7.0
diff --git a/go.sum b/go.sum
index 693c16c54..41a9aff41 100644
--- a/go.sum
+++ b/go.sum
@@ -537,6 +537,8 @@ github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrf
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.8.0 h1:nfhvjKcUMhBMVqbKHJlk5RPrrfYr/NMo3692g0dwfWU=
github.com/sirupsen/logrus v1.8.0/go.mod h1:4GuYW9TZmE769R5STWrRakJc4UqQ3+QQ95fyz7ENv1A=
+github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
+github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
diff --git a/libpod/container.go b/libpod/container.go
index 65abbfd5e..c49d8feeb 100644
--- a/libpod/container.go
+++ b/libpod/container.go
@@ -84,24 +84,6 @@ func (ns LinuxNS) String() string {
}
}
-// Valid restart policy types.
-const (
- // RestartPolicyNone indicates that no restart policy has been requested
- // by a container.
- RestartPolicyNone = ""
- // RestartPolicyNo is identical in function to RestartPolicyNone.
- RestartPolicyNo = "no"
- // RestartPolicyAlways unconditionally restarts the container.
- RestartPolicyAlways = "always"
- // RestartPolicyOnFailure restarts the container on non-0 exit code,
- // with an optional maximum number of retries.
- RestartPolicyOnFailure = "on-failure"
- // RestartPolicyUnlessStopped unconditionally restarts unless stopped
- // by the user. It is identical to Always except with respect to
- // handling of system restart, which Podman does not yet support.
- RestartPolicyUnlessStopped = "unless-stopped"
-)
-
// Container is a single OCI container.
// All operations on a Container that access state must begin with a call to
// syncContainer().
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index 1614211fb..106e2569b 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -219,14 +219,14 @@ func (c *Container) shouldRestart() bool {
// If we did not get a restart policy match, return false
// Do the same if we're not a policy that restarts.
if !c.state.RestartPolicyMatch ||
- c.config.RestartPolicy == RestartPolicyNo ||
- c.config.RestartPolicy == RestartPolicyNone {
+ c.config.RestartPolicy == define.RestartPolicyNo ||
+ c.config.RestartPolicy == define.RestartPolicyNone {
return false
}
// If we're RestartPolicyOnFailure, we need to check retries and exit
// code.
- if c.config.RestartPolicy == RestartPolicyOnFailure {
+ if c.config.RestartPolicy == define.RestartPolicyOnFailure {
if c.state.ExitCode == 0 {
return false
}
@@ -332,7 +332,7 @@ func (c *Container) syncContainer() error {
// Only save back to DB if state changed
if c.state.State != oldState {
// Check for a restart policy match
- if c.config.RestartPolicy != RestartPolicyNone && c.config.RestartPolicy != RestartPolicyNo &&
+ if c.config.RestartPolicy != define.RestartPolicyNone && c.config.RestartPolicy != define.RestartPolicyNo &&
(oldState == define.ContainerStateRunning || oldState == define.ContainerStatePaused) &&
(c.state.State == define.ContainerStateStopped || c.state.State == define.ContainerStateExited) &&
!c.state.StoppedByUser {
diff --git a/libpod/define/container.go b/libpod/define/container.go
new file mode 100644
index 000000000..5a2ff026f
--- /dev/null
+++ b/libpod/define/container.go
@@ -0,0 +1,19 @@
+package define
+
+// Valid restart policy types.
+const (
+ // RestartPolicyNone indicates that no restart policy has been requested
+ // by a container.
+ RestartPolicyNone = ""
+ // RestartPolicyNo is identical in function to RestartPolicyNone.
+ RestartPolicyNo = "no"
+ // RestartPolicyAlways unconditionally restarts the container.
+ RestartPolicyAlways = "always"
+ // RestartPolicyOnFailure restarts the container on non-0 exit code,
+ // with an optional maximum number of retries.
+ RestartPolicyOnFailure = "on-failure"
+ // RestartPolicyUnlessStopped unconditionally restarts unless stopped
+ // by the user. It is identical to Always except with respect to
+ // handling of system restart, which Podman does not yet support.
+ RestartPolicyUnlessStopped = "unless-stopped"
+)
diff --git a/libpod/kube.go b/libpod/kube.go
index 6feb69fea..407c4ae00 100644
--- a/libpod/kube.go
+++ b/libpod/kube.go
@@ -83,11 +83,11 @@ func (p *Pod) GenerateForKube() (*v1.Pod, []v1.ServicePort, error) {
for _, ctr := range allContainers {
if !ctr.IsInfra() {
switch ctr.Config().RestartPolicy {
- case RestartPolicyAlways:
+ case define.RestartPolicyAlways:
pod.Spec.RestartPolicy = v1.RestartPolicyAlways
- case RestartPolicyOnFailure:
+ case define.RestartPolicyOnFailure:
pod.Spec.RestartPolicy = v1.RestartPolicyOnFailure
- case RestartPolicyNo:
+ case define.RestartPolicyNo:
pod.Spec.RestartPolicy = v1.RestartPolicyNever
default: // some pod create from cmdline, such as "", so set it to Never
pod.Spec.RestartPolicy = v1.RestartPolicyNever
diff --git a/libpod/network/files.go b/libpod/network/files.go
index fe483e25c..d876113f9 100644
--- a/libpod/network/files.go
+++ b/libpod/network/files.go
@@ -11,6 +11,7 @@ import (
"github.com/containernetworking/plugins/plugins/ipam/host-local/backend/allocator"
"github.com/containers/common/pkg/config"
"github.com/containers/podman/v3/libpod/define"
+ "github.com/containers/podman/v3/pkg/network"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
@@ -67,7 +68,7 @@ func GetCNIConfigPathByNameOrID(config *config.Config, name string) (string, err
if conf.Name == name {
return confFile, nil
}
- if strings.HasPrefix(GetNetworkID(conf.Name), name) {
+ if strings.HasPrefix(network.GetNetworkID(conf.Name), name) {
idMatch++
file = confFile
}
@@ -92,16 +93,6 @@ func ReadRawCNIConfByNameOrID(config *config.Config, name string) ([]byte, error
return b, err
}
-// GetCNIPlugins returns a list of plugins that a given network
-// has in the form of a string
-func GetCNIPlugins(list *libcni.NetworkConfigList) string {
- plugins := make([]string, 0, len(list.Plugins))
- for _, plug := range list.Plugins {
- plugins = append(plugins, plug.Network.Type)
- }
- return strings.Join(plugins, ",")
-}
-
// GetNetworkLabels returns a list of labels as a string
func GetNetworkLabels(list *libcni.NetworkConfigList) NcLabels {
cniJSON := make(map[string]interface{})
diff --git a/libpod/network/netconflist.go b/libpod/network/netconflist.go
index 1a1583587..a45a4109a 100644
--- a/libpod/network/netconflist.go
+++ b/libpod/network/netconflist.go
@@ -7,6 +7,7 @@ import (
"strings"
"github.com/containernetworking/cni/libcni"
+ "github.com/containers/podman/v3/pkg/network"
"github.com/containers/podman/v3/pkg/util"
"github.com/pkg/errors"
)
@@ -211,7 +212,7 @@ func IfPassesFilter(netconf *libcni.NetworkConfigList, filters map[string][]stri
case "plugin":
// match one plugin
- plugins := GetCNIPlugins(netconf)
+ plugins := network.GetCNIPlugins(netconf)
for _, val := range filterValues {
if strings.Contains(plugins, val) {
result = true
@@ -243,7 +244,7 @@ func IfPassesFilter(netconf *libcni.NetworkConfigList, filters map[string][]stri
case "driver":
// matches only for the DefaultNetworkDriver
for _, filterValue := range filterValues {
- plugins := GetCNIPlugins(netconf)
+ plugins := network.GetCNIPlugins(netconf)
if filterValue == DefaultNetworkDriver &&
strings.Contains(plugins, DefaultNetworkDriver) {
result = true
@@ -253,7 +254,7 @@ func IfPassesFilter(netconf *libcni.NetworkConfigList, filters map[string][]stri
case "id":
// matches part of one id
for _, filterValue := range filterValues {
- if strings.Contains(GetNetworkID(netconf.Name), filterValue) {
+ if strings.Contains(network.GetNetworkID(netconf.Name), filterValue) {
result = true
break
}
diff --git a/libpod/network/network.go b/libpod/network/network.go
index f19a764ef..ed4e6388a 100644
--- a/libpod/network/network.go
+++ b/libpod/network/network.go
@@ -1,8 +1,6 @@
package network
import (
- "crypto/sha256"
- "encoding/hex"
"encoding/json"
"net"
"os"
@@ -245,13 +243,6 @@ func Exists(config *config.Config, name string) (bool, error) {
return true, nil
}
-// GetNetworkID return the network ID for a given name.
-// It is just the sha256 hash but this should be good enough.
-func GetNetworkID(name string) string {
- hash := sha256.Sum256([]byte(name))
- return hex.EncodeToString(hash[:])
-}
-
// PruneNetworks removes networks that are not being used and that is not the default
// network. To keep proper fencing for imports, you must provide the used networks
// to this function as a map. the key is meaningful in the map, the book is a no-op
diff --git a/libpod/options.go b/libpod/options.go
index 48888a2f2..85862cc17 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -1364,7 +1364,7 @@ func WithRestartPolicy(policy string) CtrCreateOption {
}
switch policy {
- case RestartPolicyNone, RestartPolicyNo, RestartPolicyOnFailure, RestartPolicyAlways, RestartPolicyUnlessStopped:
+ case define.RestartPolicyNone, define.RestartPolicyNo, define.RestartPolicyOnFailure, define.RestartPolicyAlways, define.RestartPolicyUnlessStopped:
ctr.config.RestartPolicy = policy
default:
return errors.Wrapf(define.ErrInvalidArg, "%q is not a valid restart policy", policy)
diff --git a/pkg/api/handlers/compat/auth.go b/pkg/api/handlers/compat/auth.go
new file mode 100644
index 000000000..2c152fbc2
--- /dev/null
+++ b/pkg/api/handlers/compat/auth.go
@@ -0,0 +1,59 @@
+package compat
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "net/http"
+ "strings"
+
+ DockerClient "github.com/containers/image/v5/docker"
+ "github.com/containers/image/v5/types"
+ "github.com/containers/podman/v3/pkg/api/handlers/utils"
+ "github.com/containers/podman/v3/pkg/domain/entities"
+ "github.com/containers/podman/v3/pkg/registries"
+ docker "github.com/docker/docker/api/types"
+ "github.com/pkg/errors"
+)
+
+func stripAddressOfScheme(address string) string {
+ for _, s := range []string{"https", "http"} {
+ address = strings.TrimPrefix(address, s+"://")
+ }
+ return address
+}
+
+func Auth(w http.ResponseWriter, r *http.Request) {
+ var authConfig docker.AuthConfig
+ err := json.NewDecoder(r.Body).Decode(&authConfig)
+ if err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrapf(err, "failed to parse request"))
+ return
+ }
+
+ skipTLS := types.NewOptionalBool(false)
+ if strings.HasPrefix(authConfig.ServerAddress, "https://localhost/") || strings.HasPrefix(authConfig.ServerAddress, "https://localhost:") || strings.HasPrefix(authConfig.ServerAddress, "localhost:") {
+ // support for local testing
+ skipTLS = types.NewOptionalBool(true)
+ }
+
+ fmt.Println("Authenticating with existing credentials...")
+ sysCtx := types.SystemContext{
+ AuthFilePath: "",
+ DockerCertPath: "",
+ DockerInsecureSkipTLSVerify: skipTLS,
+ SystemRegistriesConfPath: registries.SystemRegistriesConfPath(),
+ }
+ registry := stripAddressOfScheme(authConfig.ServerAddress)
+ if err := DockerClient.CheckAuth(context.Background(), &sysCtx, authConfig.Username, authConfig.Password, registry); err == nil {
+ utils.WriteResponse(w, http.StatusOK, entities.AuthReport{
+ IdentityToken: "",
+ Status: "Login Succeeded",
+ })
+ } else {
+ utils.WriteResponse(w, http.StatusBadRequest, entities.AuthReport{
+ IdentityToken: "",
+ Status: "login attempt to " + authConfig.ServerAddress + " failed with status: " + err.Error(),
+ })
+ }
+}
diff --git a/pkg/api/handlers/compat/images_build.go b/pkg/api/handlers/compat/images_build.go
index 392f688dd..7751b91a7 100644
--- a/pkg/api/handlers/compat/images_build.go
+++ b/pkg/api/handlers/compat/images_build.go
@@ -445,6 +445,13 @@ loop:
logrus.Warnf("Failed to json encode error %v", err)
}
flush()
+ for _, tag := range query.Tag {
+ m.Stream = fmt.Sprintf("Successfully tagged %s\n", tag)
+ if err := enc.Encode(m); err != nil {
+ logrus.Warnf("Failed to json encode error %v", err)
+ }
+ flush()
+ }
}
}
break loop
diff --git a/pkg/api/handlers/compat/networks.go b/pkg/api/handlers/compat/networks.go
index 28e90ac28..dfb1d7fda 100644
--- a/pkg/api/handlers/compat/networks.go
+++ b/pkg/api/handlers/compat/networks.go
@@ -16,6 +16,7 @@ import (
"github.com/containers/podman/v3/pkg/api/handlers/utils"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/domain/infra/abi"
+ networkid "github.com/containers/podman/v3/pkg/network"
"github.com/docker/docker/api/types"
dockerNetwork "github.com/docker/docker/api/types/network"
"github.com/gorilla/schema"
@@ -135,7 +136,7 @@ func getNetworkResourceByNameOrID(nameOrID string, runtime *libpod.Runtime, filt
report := types.NetworkResource{
Name: conf.Name,
- ID: network.GetNetworkID(conf.Name),
+ ID: networkid.GetNetworkID(conf.Name),
Created: time.Unix(int64(stat.Ctim.Sec), int64(stat.Ctim.Nsec)), // nolint: unconvert
Scope: "local",
Driver: network.DefaultNetworkDriver,
diff --git a/pkg/api/server/register_auth.go b/pkg/api/server/register_auth.go
index 1e5474462..56e115e30 100644
--- a/pkg/api/server/register_auth.go
+++ b/pkg/api/server/register_auth.go
@@ -1,13 +1,33 @@
package server
import (
+ "net/http"
+
"github.com/containers/podman/v3/pkg/api/handlers/compat"
"github.com/gorilla/mux"
)
func (s *APIServer) registerAuthHandlers(r *mux.Router) error {
- r.Handle(VersionedPath("/auth"), s.APIHandler(compat.UnsupportedHandler))
+ // swagger:operation POST /auth compat auth
+ // ---
+ // summary: Check auth configuration
+ // tags:
+ // - system (compat)
+ // produces:
+ // - application/json
+ // parameters:
+ // - in: body
+ // name: authConfig
+ // description: Authentication to check
+ // schema:
+ // $ref: "#/definitions/AuthConfig"
+ // responses:
+ // 200:
+ // $ref: "#/responses/SystemAuthResponse"
+ // 500:
+ // $ref: "#/responses/InternalError"
+ r.Handle(VersionedPath("/auth"), s.APIHandler(compat.Auth)).Methods(http.MethodPost)
// Added non version path to URI to support docker non versioned paths
- r.Handle("/auth", s.APIHandler(compat.UnsupportedHandler))
+ r.Handle("/auth", s.APIHandler(compat.Auth)).Methods(http.MethodPost)
return nil
}
diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go
index f6a8a37ca..3d86e5d38 100644
--- a/pkg/api/server/register_images.go
+++ b/pkg/api/server/register_images.go
@@ -652,6 +652,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// example: |
// (build details...)
// Successfully built 8ba084515c724cbf90d447a63600c0a6
+ // Successfully tagged your_image:latest
// 400:
// $ref: "#/responses/BadParamError"
// 500:
@@ -1485,7 +1486,6 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// description: output from build process
// example: |
// (build details...)
- // Successfully built 8ba084515c724cbf90d447a63600c0a6
// 400:
// $ref: "#/responses/BadParamError"
// 500:
diff --git a/pkg/api/server/register_networks.go b/pkg/api/server/register_networks.go
index 68a8d4ae4..c54de952f 100644
--- a/pkg/api/server/register_networks.go
+++ b/pkg/api/server/register_networks.go
@@ -220,28 +220,6 @@ func (s *APIServer) registerNetworkHandlers(r *mux.Router) error {
*/
r.HandleFunc(VersionedPath("/libpod/networks/{name}"), s.APIHandler(libpod.RemoveNetwork)).Methods(http.MethodDelete)
- // swagger:operation GET /libpod/networks/{name}/json libpod libpodInspectNetwork
- // ---
- // tags:
- // - networks
- // summary: Inspect a network
- // description: Display low level configuration for a CNI network
- // parameters:
- // - in: path
- // name: name
- // type: string
- // required: true
- // description: the name of the network
- // produces:
- // - application/json
- // responses:
- // 200:
- // $ref: "#/responses/NetworkInspectReport"
- // 404:
- // $ref: "#/responses/NoSuchNetwork"
- // 500:
- // $ref: "#/responses/InternalError"
- r.HandleFunc(VersionedPath("/libpod/networks/{name}/json"), s.APIHandler(libpod.InspectNetwork)).Methods(http.MethodGet)
// swagger:operation GET /libpod/networks/{name}/exists libpod libpodExistsNetwork
// ---
// tags:
@@ -289,6 +267,29 @@ func (s *APIServer) registerNetworkHandlers(r *mux.Router) error {
// 500:
// $ref: "#/responses/InternalError"
r.HandleFunc(VersionedPath("/libpod/networks/json"), s.APIHandler(libpod.ListNetworks)).Methods(http.MethodGet)
+ // swagger:operation GET /libpod/networks/{name}/json libpod libpodInspectNetwork
+ // ---
+ // tags:
+ // - networks
+ // summary: Inspect a network
+ // description: Display low level configuration for a CNI network
+ // parameters:
+ // - in: path
+ // name: name
+ // type: string
+ // required: true
+ // description: the name of the network
+ // produces:
+ // - application/json
+ // responses:
+ // 200:
+ // $ref: "#/responses/NetworkInspectReport"
+ // 404:
+ // $ref: "#/responses/NoSuchNetwork"
+ // 500:
+ // $ref: "#/responses/InternalError"
+ r.HandleFunc(VersionedPath("/libpod/networks/{name}/json"), s.APIHandler(libpod.InspectNetwork)).Methods(http.MethodGet)
+ r.HandleFunc(VersionedPath("/libpod/networks/{name}"), s.APIHandler(libpod.InspectNetwork)).Methods(http.MethodGet)
// swagger:operation POST /libpod/networks/create libpod libpodCreateNetwork
// ---
// tags:
diff --git a/pkg/api/server/swagger.go b/pkg/api/server/swagger.go
index 92efb8ef3..12fd083bb 100644
--- a/pkg/api/server/swagger.go
+++ b/pkg/api/server/swagger.go
@@ -226,3 +226,12 @@ type swagSystemPruneReport struct {
entities.SystemPruneReport
}
}
+
+// Auth response
+// swagger:response SystemAuthResponse
+type swagSystemAuthResponse struct {
+ // in:body
+ Body struct {
+ entities.AuthReport
+ }
+}
diff --git a/pkg/autoupdate/autoupdate.go b/pkg/autoupdate/autoupdate.go
index 53095c295..e271b9466 100644
--- a/pkg/autoupdate/autoupdate.go
+++ b/pkg/autoupdate/autoupdate.go
@@ -13,7 +13,7 @@ import (
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/libpod/image"
"github.com/containers/podman/v3/pkg/systemd"
- systemdGen "github.com/containers/podman/v3/pkg/systemd/generate"
+ systemdDefine "github.com/containers/podman/v3/pkg/systemd/define"
"github.com/containers/podman/v3/pkg/util"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -178,10 +178,10 @@ func AutoUpdate(runtime *libpod.Runtime, options Options) ([]string, []error) {
updatedUnits := []string{}
for _, ctr := range containersToRestart {
labels := ctr.Labels()
- unit, exists := labels[systemdGen.EnvVariable]
+ unit, exists := labels[systemdDefine.EnvVariable]
if !exists {
// Shouldn't happen but let's be sure of it.
- errs = append(errs, errors.Errorf("error auto-updating container %q: no %s label found", ctr.ID(), systemdGen.EnvVariable))
+ errs = append(errs, errors.Errorf("error auto-updating container %q: no %s label found", ctr.ID(), systemdDefine.EnvVariable))
continue
}
_, err := conn.RestartUnit(unit, "replace", nil)
diff --git a/pkg/domain/entities/system.go b/pkg/domain/entities/system.go
index a1cfb4481..4b8383613 100644
--- a/pkg/domain/entities/system.go
+++ b/pkg/domain/entities/system.go
@@ -107,3 +107,14 @@ type ComponentVersion struct {
type ListRegistriesReport struct {
Registries []string
}
+
+// swagger:model AuthConfig
+type AuthConfig struct {
+ types.AuthConfig
+}
+
+// AuthReport describes the response for authentication check
+type AuthReport struct {
+ IdentityToken string
+ Status string
+}
diff --git a/pkg/domain/filters/containers.go b/pkg/domain/filters/containers.go
index 6f4b4e8a0..98b8f7e88 100644
--- a/pkg/domain/filters/containers.go
+++ b/pkg/domain/filters/containers.go
@@ -7,7 +7,7 @@ import (
"github.com/containers/podman/v3/libpod"
"github.com/containers/podman/v3/libpod/define"
- "github.com/containers/podman/v3/libpod/network"
+ "github.com/containers/podman/v3/pkg/network"
"github.com/containers/podman/v3/pkg/timetype"
"github.com/containers/podman/v3/pkg/util"
"github.com/pkg/errors"
diff --git a/pkg/domain/filters/pods.go b/pkg/domain/filters/pods.go
index 53d10213a..0490a4848 100644
--- a/pkg/domain/filters/pods.go
+++ b/pkg/domain/filters/pods.go
@@ -6,7 +6,7 @@ import (
"github.com/containers/podman/v3/libpod"
"github.com/containers/podman/v3/libpod/define"
- "github.com/containers/podman/v3/libpod/network"
+ "github.com/containers/podman/v3/pkg/network"
"github.com/containers/podman/v3/pkg/util"
"github.com/pkg/errors"
)
diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go
index b7ca69281..efc7c86e3 100644
--- a/pkg/domain/infra/abi/play.go
+++ b/pkg/domain/infra/abi/play.go
@@ -173,13 +173,13 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
var ctrRestartPolicy string
switch podYAML.Spec.RestartPolicy {
case v1.RestartPolicyAlways:
- ctrRestartPolicy = libpod.RestartPolicyAlways
+ ctrRestartPolicy = define.RestartPolicyAlways
case v1.RestartPolicyOnFailure:
- ctrRestartPolicy = libpod.RestartPolicyOnFailure
+ ctrRestartPolicy = define.RestartPolicyOnFailure
case v1.RestartPolicyNever:
- ctrRestartPolicy = libpod.RestartPolicyNo
+ ctrRestartPolicy = define.RestartPolicyNo
default: // Default to Always
- ctrRestartPolicy = libpod.RestartPolicyAlways
+ ctrRestartPolicy = define.RestartPolicyAlways
}
configMaps := []v1.ConfigMap{}
diff --git a/pkg/network/network.go b/pkg/network/network.go
new file mode 100644
index 000000000..44132ca28
--- /dev/null
+++ b/pkg/network/network.go
@@ -0,0 +1,27 @@
+package network
+
+import (
+ "crypto/sha256"
+ "encoding/hex"
+ "strings"
+
+ "github.com/containernetworking/cni/libcni"
+)
+
+// GetCNIPlugins returns a list of plugins that a given network
+// has in the form of a string
+func GetCNIPlugins(list *libcni.NetworkConfigList) string {
+ plugins := make([]string, 0, len(list.Plugins))
+ for _, plug := range list.Plugins {
+ plugins = append(plugins, plug.Network.Type)
+ }
+ return strings.Join(plugins, ",")
+}
+
+// GetNetworkID return the network ID for a given name.
+// It is just the sha256 hash but this should be good enough.
+// The caller has to make sure it is only called with the network name.
+func GetNetworkID(name string) string {
+ hash := sha256.Sum256([]byte(name))
+ return hex.EncodeToString(hash[:])
+}
diff --git a/pkg/systemd/define/const.go b/pkg/systemd/define/const.go
new file mode 100644
index 000000000..1b50be5db
--- /dev/null
+++ b/pkg/systemd/define/const.go
@@ -0,0 +1,9 @@
+package define
+
+// EnvVariable "PODMAN_SYSTEMD_UNIT" is set in all generated systemd units and
+// is set to the unit's (unique) name.
+const EnvVariable = "PODMAN_SYSTEMD_UNIT"
+
+// RestartPolicies includes all valid restart policies to be used in a unit
+// file.
+var RestartPolicies = []string{"no", "on-success", "on-failure", "on-abnormal", "on-watchdog", "on-abort", "always"}
diff --git a/pkg/systemd/generate/common.go b/pkg/systemd/generate/common.go
index bbd1a5f92..94a6f4cb5 100644
--- a/pkg/systemd/generate/common.go
+++ b/pkg/systemd/generate/common.go
@@ -4,25 +4,18 @@ import (
"strconv"
"strings"
+ "github.com/containers/podman/v3/pkg/systemd/define"
"github.com/pkg/errors"
)
-// EnvVariable "PODMAN_SYSTEMD_UNIT" is set in all generated systemd units and
-// is set to the unit's (unique) name.
-const EnvVariable = "PODMAN_SYSTEMD_UNIT"
-
// minTimeoutStopSec is the minimal stop timeout for generated systemd units.
// Once exceeded, processes of the services are killed and the cgroup(s) are
// cleaned up.
const minTimeoutStopSec = 60
-// RestartPolicies includes all valid restart policies to be used in a unit
-// file.
-var RestartPolicies = []string{"no", "on-success", "on-failure", "on-abnormal", "on-watchdog", "on-abort", "always"}
-
// validateRestartPolicy checks that the user-provided policy is valid.
func validateRestartPolicy(restart string) error {
- for _, i := range RestartPolicies {
+ for _, i := range define.RestartPolicies {
if i == restart {
return nil
}
diff --git a/pkg/systemd/generate/containers.go b/pkg/systemd/generate/containers.go
index 92c6d8865..9343a5067 100644
--- a/pkg/systemd/generate/containers.go
+++ b/pkg/systemd/generate/containers.go
@@ -11,6 +11,7 @@ import (
"github.com/containers/podman/v3/libpod"
"github.com/containers/podman/v3/pkg/domain/entities"
+ "github.com/containers/podman/v3/pkg/systemd/define"
"github.com/containers/podman/v3/version"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -173,7 +174,7 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst
info.Executable = executable
}
- info.EnvVariable = EnvVariable
+ info.EnvVariable = define.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}}}}"
diff --git a/pkg/systemd/generate/containers_test.go b/pkg/systemd/generate/containers_test.go
index 747c54699..ebbbdb786 100644
--- a/pkg/systemd/generate/containers_test.go
+++ b/pkg/systemd/generate/containers_test.go
@@ -4,6 +4,7 @@ import (
"testing"
"github.com/containers/podman/v3/pkg/domain/entities"
+ "github.com/containers/podman/v3/pkg/systemd/define"
"github.com/stretchr/testify/assert"
)
@@ -398,7 +399,7 @@ WantedBy=multi-user.target default.target
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 22,
PodmanVersion: "CI",
- EnvVariable: EnvVariable,
+ EnvVariable: define.EnvVariable,
},
goodID,
false,
@@ -414,7 +415,7 @@ WantedBy=multi-user.target default.target
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 22,
PodmanVersion: "CI",
- EnvVariable: EnvVariable,
+ EnvVariable: define.EnvVariable,
},
goodIDNoHeaderInfo,
false,
@@ -430,7 +431,7 @@ WantedBy=multi-user.target default.target
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 10,
PodmanVersion: "CI",
- EnvVariable: EnvVariable,
+ EnvVariable: define.EnvVariable,
},
goodName,
false,
@@ -447,7 +448,7 @@ WantedBy=multi-user.target default.target
StopTimeout: 10,
PodmanVersion: "CI",
BoundToServices: []string{"pod", "a", "b", "c"},
- EnvVariable: EnvVariable,
+ EnvVariable: define.EnvVariable,
},
goodNameBoundTo,
false,
@@ -462,7 +463,7 @@ WantedBy=multi-user.target default.target
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 10,
PodmanVersion: "CI",
- EnvVariable: EnvVariable,
+ EnvVariable: define.EnvVariable,
},
"",
false,
@@ -479,7 +480,7 @@ WantedBy=multi-user.target default.target
StopTimeout: 10,
PodmanVersion: "CI",
CreateCommand: []string{"I'll get stripped", "container", "run", "--name", "jadda-jadda", "--hostname", "hello-world", "awesome-image:latest", "command", "arg1", "...", "argN", "foo=arg \"with \" space"},
- EnvVariable: EnvVariable,
+ EnvVariable: define.EnvVariable,
},
goodWithNameAndGeneric,
true,
@@ -496,7 +497,7 @@ WantedBy=multi-user.target default.target
StopTimeout: 10,
PodmanVersion: "CI",
CreateCommand: []string{"I'll get stripped", "run", "-d", "--name", "jadda-jadda", "--hostname", "hello-world", "awesome-image:latest", "command", "arg1", "...", "argN"},
- EnvVariable: EnvVariable,
+ EnvVariable: define.EnvVariable,
},
goodWithExplicitShortDetachParam,
true,
@@ -513,7 +514,7 @@ WantedBy=multi-user.target default.target
StopTimeout: 10,
PodmanVersion: "CI",
CreateCommand: []string{"I'll get stripped", "run", "-d", "--name", "jadda-jadda", "--hostname", "hello-world", "awesome-image:latest", "command", "arg1", "...", "argN"},
- EnvVariable: EnvVariable,
+ EnvVariable: define.EnvVariable,
Pod: &podInfo{
PodIDFile: "%t/pod-foobar.pod-id-file",
},
@@ -533,7 +534,7 @@ WantedBy=multi-user.target default.target
StopTimeout: 10,
PodmanVersion: "CI",
CreateCommand: []string{"I'll get stripped", "run", "--detach", "--name", "jadda-jadda", "--hostname", "hello-world", "awesome-image:latest", "command", "arg1", "...", "argN"},
- EnvVariable: EnvVariable,
+ EnvVariable: define.EnvVariable,
},
goodNameNewDetach,
true,
@@ -550,7 +551,7 @@ WantedBy=multi-user.target default.target
StopTimeout: 10,
PodmanVersion: "CI",
CreateCommand: []string{"I'll get stripped", "run", "awesome-image:latest"},
- EnvVariable: EnvVariable,
+ EnvVariable: define.EnvVariable,
},
goodIDNew,
true,
@@ -567,7 +568,7 @@ WantedBy=multi-user.target default.target
StopTimeout: 42,
PodmanVersion: "CI",
CreateCommand: []string{"I'll get stripped", "run", "--detach=true", "awesome-image:latest"},
- EnvVariable: EnvVariable,
+ EnvVariable: define.EnvVariable,
},
genGoodNewDetach("--detach=true"),
true,
@@ -584,7 +585,7 @@ WantedBy=multi-user.target default.target
StopTimeout: 42,
PodmanVersion: "CI",
CreateCommand: []string{"I'll get stripped", "run", "--detach=false", "awesome-image:latest"},
- EnvVariable: EnvVariable,
+ EnvVariable: define.EnvVariable,
},
genGoodNewDetach("-d"),
true,
@@ -601,7 +602,7 @@ WantedBy=multi-user.target default.target
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,
+ EnvVariable: define.EnvVariable,
},
goodNameNewDetachFalseWithCmd,
true,
@@ -618,7 +619,7 @@ WantedBy=multi-user.target default.target
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,
+ EnvVariable: define.EnvVariable,
},
goodNameNewDetachFalseWithCmd,
true,
@@ -635,7 +636,7 @@ WantedBy=multi-user.target default.target
StopTimeout: 42,
PodmanVersion: "CI",
CreateCommand: []string{"I'll get stripped", "run", "-dti", "awesome-image:latest"},
- EnvVariable: EnvVariable,
+ EnvVariable: define.EnvVariable,
},
genGoodNewDetach("-dti"),
true,
@@ -652,7 +653,7 @@ WantedBy=multi-user.target default.target
StopTimeout: 42,
PodmanVersion: "CI",
CreateCommand: []string{"I'll get stripped", "run", "-tid", "awesome-image:latest"},
- EnvVariable: EnvVariable,
+ EnvVariable: define.EnvVariable,
},
genGoodNewDetach("-tid"),
true,
@@ -669,7 +670,7 @@ WantedBy=multi-user.target default.target
StopTimeout: 42,
PodmanVersion: "CI",
CreateCommand: []string{"I'll get stripped", "--events-backend", "none", "--runroot", "/root", "run", "awesome-image:latest"},
- EnvVariable: EnvVariable,
+ EnvVariable: define.EnvVariable,
},
goodNewRootFlags,
true,
@@ -686,7 +687,7 @@ WantedBy=multi-user.target default.target
StopTimeout: 10,
PodmanVersion: "CI",
CreateCommand: []string{"I'll get stripped", "container", "create", "awesome-image:latest"},
- EnvVariable: EnvVariable,
+ EnvVariable: define.EnvVariable,
},
goodContainerCreate,
true,
@@ -703,7 +704,7 @@ WantedBy=multi-user.target default.target
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,
+ EnvVariable: define.EnvVariable,
},
goodNewWithJournaldTag,
true,
@@ -720,7 +721,7 @@ WantedBy=multi-user.target default.target
StopTimeout: 10,
PodmanVersion: "CI",
CreateCommand: []string{"I'll get stripped", "create", "--name", "test", "awesome-image:latest", "sh", "-c", "kill $$ && echo %\\"},
- EnvVariable: EnvVariable,
+ EnvVariable: define.EnvVariable,
},
goodNewWithSpecialChars,
true,
diff --git a/pkg/systemd/generate/pods.go b/pkg/systemd/generate/pods.go
index 8c0401278..f96058d36 100644
--- a/pkg/systemd/generate/pods.go
+++ b/pkg/systemd/generate/pods.go
@@ -11,6 +11,7 @@ import (
"github.com/containers/podman/v3/libpod"
"github.com/containers/podman/v3/pkg/domain/entities"
+ "github.com/containers/podman/v3/pkg/systemd/define"
"github.com/containers/podman/v3/version"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -237,7 +238,7 @@ func executePodTemplate(info *podInfo, options entities.GenerateSystemdOptions)
info.Executable = executable
}
- info.EnvVariable = EnvVariable
+ info.EnvVariable = define.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}}}}"
diff --git a/test/apiv2/01-basic.at b/test/apiv2/01-basic.at
index 1357e0ca6..788007069 100644
--- a/test/apiv2/01-basic.at
+++ b/test/apiv2/01-basic.at
@@ -30,18 +30,18 @@ done
# Garbage tests - requests that should yield errors
#
t GET /nonesuch 404
-t POST /nonesuch '' 404
+t POST /nonesuch 404
t GET container/nonesuch/json 404
t GET libpod/containers/nonesuch/json 404
#### FIXME: maybe someday: t GET 'libpod/containers/json?a=b' 400
# Method not allowed
-t POST /_ping '' 405
+t POST /_ping 405
t DELETE /_ping 405
-t POST libpod/containers/json '' 405
-t POST libpod/pods/abc '' 405
-t POST info '' 405
+t POST libpod/containers/json 405
+t POST libpod/pods/abc 405
+t POST info 405
t GET libpod/containers/create 405
#
diff --git a/test/apiv2/10-images.at b/test/apiv2/10-images.at
index f866422e2..4ebaeff45 100644
--- a/test/apiv2/10-images.at
+++ b/test/apiv2/10-images.at
@@ -41,18 +41,18 @@ t GET images/$iid/json 200 \
.Id=sha256:$iid \
.RepoTags[0]=$IMAGE
-t POST "images/create?fromImage=alpine" '' 200 .error~null .status~".*Download complete.*"
+t POST "images/create?fromImage=alpine" 200 .error~null .status~".*Download complete.*"
-t POST "images/create?fromImage=alpine&tag=latest" '' 200
+t POST "images/create?fromImage=alpine&tag=latest" 200
# Make sure that new images are pulled
old_iid=$(podman image inspect --format "{{.ID}}" docker.io/library/alpine:latest)
podman rmi -f docker.io/library/alpine:latest
podman tag $IMAGE docker.io/library/alpine:latest
-t POST "images/create?fromImage=alpine" '' 200 .error~null .status~".*$old_iid.*"
+t POST "images/create?fromImage=alpine" 200 .error~null .status~".*$old_iid.*"
podman untag $IMAGE docker.io/library/alpine:latest
-t POST "images/create?fromImage=quay.io/libpod/alpine&tag=sha256:fa93b01658e3a5a1686dc3ae55f170d8de487006fb53a28efcd12ab0710a2e5f" '' 200
+t POST "images/create?fromImage=quay.io/libpod/alpine&tag=sha256:fa93b01658e3a5a1686dc3ae55f170d8de487006fb53a28efcd12ab0710a2e5f" 200
# Display the image history
t GET libpod/images/nonesuch/history 404
diff --git a/test/apiv2/12-imagesMore.at b/test/apiv2/12-imagesMore.at
index ce3049106..144b83194 100644
--- a/test/apiv2/12-imagesMore.at
+++ b/test/apiv2/12-imagesMore.at
@@ -17,10 +17,10 @@ t GET libpod/images/$IMAGE/tree 200 \
.Tree~^Image
# Tag nonesuch image
-t POST "libpod/images/nonesuch/tag?repo=myrepo&tag=mytag" '' 404
+t POST "libpod/images/nonesuch/tag?repo=myrepo&tag=mytag" 404
# Tag the image
-t POST "libpod/images/$IMAGE/tag?repo=localhost:5000/myrepo&tag=mytag" '' 201
+t POST "libpod/images/$IMAGE/tag?repo=localhost:5000/myrepo&tag=mytag" 201
t GET libpod/images/$IMAGE/json 200 \
.RepoTags[1]=localhost:5000/myrepo:mytag
@@ -41,13 +41,13 @@ if [ -z "${GOT_DIGEST}" ] ; then
fi
# Push to local registry
-t POST "images/localhost:5000/myrepo/push?tlsVerify=false&tag=mytag" '' 200
+t POST "images/localhost:5000/myrepo/push?tlsVerify=false&tag=mytag" 200
# Untag the image
-t POST "libpod/images/$iid/untag?repo=localhost:5000/myrepo&tag=mytag" '' 201
+t POST "libpod/images/$iid/untag?repo=localhost:5000/myrepo&tag=mytag" 201
# Try to push non-existing image
-t POST "images/localhost:5000/idonotexist/push?tlsVerify=false" '' 200
+t POST "images/localhost:5000/idonotexist/push?tlsVerify=false" 200
jq -re 'select(.errorDetail)' <<<"$output" &>/dev/null || echo -e "${red}not ok: error message not found in output${nc}" 1>&2
t GET libpod/images/$IMAGE/json 200 \
diff --git a/test/apiv2/20-containers.at b/test/apiv2/20-containers.at
index 383d92ef3..478717700 100644
--- a/test/apiv2/20-containers.at
+++ b/test/apiv2/20-containers.at
@@ -31,12 +31,16 @@ t GET libpod/containers/json?all=true 200 \
.[0].ExitCode=0 \
.[0].IsInfra=false
-# Test compat API for Network Settings
+# Test compat API for Network Settings (.Network is N/A when rootless)
+network_expect=
+if root; then
+ network_expect='.[0].NetworkSettings.Networks.podman.NetworkID=podman'
+fi
t GET /containers/json?all=true 200 \
length=1 \
.[0].Id~[0-9a-f]\\{64\\} \
.[0].Image=$IMAGE \
- .[0].NetworkSettings.Networks.podman.NetworkID=podman
+ $network_expect
# Make sure `limit` works.
t GET libpod/containers/json?limit=1 200 \
@@ -68,9 +72,9 @@ t POST libpod/containers/create?name=test_noargs Image=${IMAGE} 201 \
.Id~[0-9a-f]\\{64\\}
cid=$(jq -r '.Id' <<<"$output")
# Prior to the fix in #6835, this would fail 500 "args must not be empty"
-t POST libpod/containers/${cid}/start '' 204
+t POST libpod/containers/${cid}/start 204
# Container should exit almost immediately. Wait for it, confirm successful run
-t POST "libpod/containers/${cid}/wait?condition=stopped&condition=exited" '' 200 '0'
+t POST "libpod/containers/${cid}/wait?condition=stopped&condition=exited" 200 '0'
t GET libpod/containers/${cid}/json 200 \
.Id=$cid \
.State.Status~\\\(exited\\\|stopped\\\) \
@@ -85,15 +89,15 @@ t GET libpod/containers/json?all=true 200 \
cid=$(jq -r '.[0].Id' <<<"$output")
# No such container
-t POST "libpod/commit?container=nonesuch" '' 404
+t POST "libpod/commit?container=nonesuch" 404
# Comment can only be used with docker format, not OCI
cparam="repo=newrepo&comment=foo&author=bob"
-t POST "libpod/commit?container=$CNAME&$cparam" '' 500 \
+t POST "libpod/commit?container=$CNAME&$cparam" 500 \
.cause="messages are only compatible with the docker image format (-f docker)"
# Commit a new image from the container
-t POST "libpod/commit?container=$CNAME" '' 200 \
+t POST "libpod/commit?container=$CNAME" 200 \
.Id~[0-9a-f]\\{64\\}
iid=$(jq -r '.Id' <<<"$output")
t GET libpod/images/$iid/json 200 \
@@ -103,7 +107,7 @@ t GET libpod/images/$iid/json 200 \
# Commit a new image w/o tag
cparam="repo=newrepo&comment=foo&author=bob&format=docker"
-t POST "libpod/commit?container=$CNAME&$cparam" '' 200
+t POST "libpod/commit?container=$CNAME&$cparam" 200
t GET libpod/images/newrepo:latest/json 200 \
.RepoTags[0]=localhost/newrepo:latest \
.Author=bob \
@@ -111,7 +115,7 @@ t GET libpod/images/newrepo:latest/json 200 \
# Commit a new image w/ specified tag and author
cparam="repo=newrepo&tag=v1&author=alice"
-t POST "libpod/commit?container=$cid&$cparam&pause=false" '' 200
+t POST "libpod/commit?container=$cid&$cparam&pause=false" 200
t GET libpod/images/newrepo:v1/json 200 \
.RepoTags[0]=localhost/newrepo:v1 \
.Author=alice
@@ -119,7 +123,7 @@ t GET libpod/images/newrepo:v1/json 200 \
# Commit a new image w/ full parameters
cparam="repo=newrepo&tag=v2&comment=bar&author=eric"
cparam="$cparam&format=docker&changes=CMD=/bin/foo"
-t POST "libpod/commit?container=${cid:0:12}&$cparam&pause=true" '' 200
+t POST "libpod/commit?container=${cid:0:12}&$cparam&pause=true" 200
t GET libpod/images/newrepo:v2/json 200 \
.RepoTags[0]=localhost/newrepo:v2 \
.Author=eric \
@@ -143,7 +147,7 @@ cpid_file=$(jq -r '.ConmonPidFile' <<<"$output")
userdata_path=$(dirname $cpid_file)
# Initializing the container
-t POST libpod/containers/myctr/init '' 204
+t POST libpod/containers/myctr/init 204
# Check configuration after initializing
t GET libpod/containers/myctr/json 200 \
@@ -167,7 +171,11 @@ t DELETE libpod/containers/bogus 404
# test apiv2 create container with correct entrypoint and cmd
# --data '{"Image":"quay.io/libpod/alpine_labels:latest","Entrypoint":["echo"],"Cmd":["param1","param2"]}'
-t POST containers/create '"Image":"'$IMAGE'","Entrypoint":["echo"],"Cmd":["param1","param2"]' 201 \
+t POST containers/create \
+ Image=$IMAGE \
+ Entrypoint='["echo"]' \
+ Cmd='["param1","param2"]' \
+ 201 \
.Id~[0-9a-f]\\{64\\}
cid=$(jq -r '.Id' <<<"$output")
t GET containers/$cid/json 200 \
@@ -180,7 +188,10 @@ t GET containers/$cid/json 200 \
t DELETE containers/$cid 204
# test only set the entrypoint, Cmd should be []
-t POST containers/create '"Image":"'$IMAGE'","Entrypoint":["echo","param1"]' 201 \
+t POST containers/create \
+ Image=$IMAGE \
+ Entrypoint='["echo","param1"]' \
+ 201 \
.Id~[0-9a-f]\\{64\\}
cid=$(jq -r '.Id' <<<"$output")
t GET containers/$cid/json 200 \
@@ -191,14 +202,14 @@ t GET containers/$cid/json 200 \
.Args[0]="param1"
# create a running container for after
-t POST containers/create '"Image":"'$IMAGE'","Entrypoint":["top"]' 201 \
+t POST containers/create Image=$IMAGE Entrypoint='["top"]' 201 \
.Id~[0-9a-f]\\{64\\}
cid_top=$(jq -r '.Id' <<<"$output")
t GET containers/${cid_top}/json 200 \
.Config.Entrypoint[0]="top" \
.Config.Cmd='[]' \
.Path="top"
-t POST containers/${cid_top}/start '' 204
+t POST containers/${cid_top}/start 204
# make sure the container is running
t GET containers/${cid_top}/json 200 \
.State.Status="running"
@@ -220,13 +231,17 @@ t GET containers/json?filters='{"id":["'${cid}'","'${cid_top}'"],"status":["runn
length=1 \
.[0].Id=${cid_top}
-t POST containers/${cid_top}/stop "" 204
+t POST containers/${cid_top}/stop 204
t DELETE containers/$cid 204
t DELETE containers/$cid_top 204
# test the WORKDIR and StopSignal
-t POST containers/create '"Image":"'$ENV_WORKDIR_IMG'","WorkingDir":"/dataDir","StopSignal":"9"' 201 \
+t POST containers/create \
+ Image=$ENV_WORKDIR_IMG \
+ WorkingDir=/dataDir \
+ StopSignal=9 \
+ 201 \
.Id~[0-9a-f]\\{64\\}
cid=$(jq -r '.Id' <<<"$output")
t GET containers/$cid/json 200 \
@@ -247,7 +262,7 @@ t DELETE images/${MultiTagName}?force=true 200
# vim: filetype=sh
# Test Volumes field adds an anonymous volume
-t POST containers/create '"Image":"'$IMAGE'","Volumes":{"/test":{}}' 201 \
+t POST containers/create Image=$IMAGE Volumes='{"/test":{}}' 201 \
.Id~[0-9a-f]\\{64\\}
cid=$(jq -r '.Id' <<<"$output")
t GET containers/$cid/json 200 \
@@ -266,7 +281,7 @@ t GET containers/json 200 \
podman stop bar
# Test CPU limit (NanoCPUs)
-t POST containers/create '"Image":"'$IMAGE'","HostConfig":{"NanoCpus":500000}' 201 \
+t POST containers/create Image=$IMAGE HostConfig='{"NanoCpus":500000}' 201 \
.Id~[0-9a-f]\\{64\\}
cid=$(jq -r '.Id' <<<"$output")
t GET containers/$cid/json 200 \
diff --git a/test/apiv2/22-stop.at b/test/apiv2/22-stop.at
index 11318ca81..91bc9937d 100644
--- a/test/apiv2/22-stop.at
+++ b/test/apiv2/22-stop.at
@@ -8,17 +8,17 @@ podman pull $IMAGE &>/dev/null
# stop, by name
podman run -dt --name mytop $IMAGE top &>/dev/null
-t GET libpod/containers/mytop/json 200 .State.Status=running
-t POST libpod/containers/mytop/stop "" 204
-t GET libpod/containers/mytop/json 200 .State.Status~\\\(exited\\\|stopped\\\)
-t DELETE libpod/containers/mytop 204
+t GET libpod/containers/mytop/json 200 .State.Status=running
+t POST libpod/containers/mytop/stop 204
+t GET libpod/containers/mytop/json 200 .State.Status~\\\(exited\\\|stopped\\\)
+t DELETE libpod/containers/mytop 204
# stop, by ID
# Remember that podman() hides all output; we need to get our CID via inspect
podman run -dt --name mytop $IMAGE top
-t GET libpod/containers/mytop/json 200 .State.Status=running
+t GET libpod/containers/mytop/json 200 .State.Status=running
cid=$(jq -r .Id <<<"$output")
-t POST libpod/containers/$cid/stop "" 204
-t GET libpod/containers/mytop/json 200 .State.Status~\\\(exited\\\|stopped\\\)
-t DELETE libpod/containers/mytop 204
+t POST libpod/containers/$cid/stop 204
+t GET libpod/containers/mytop/json 200 .State.Status~\\\(exited\\\|stopped\\\)
+t DELETE libpod/containers/mytop 204
diff --git a/test/apiv2/25-containersMore.at b/test/apiv2/25-containersMore.at
index b88c798eb..39bfa2e32 100644
--- a/test/apiv2/25-containersMore.at
+++ b/test/apiv2/25-containersMore.at
@@ -17,7 +17,7 @@ t GET libpod/containers/nonesuch/exists 404
t GET libpod/containers/foo/exists 204
# Pause the container
-t POST libpod/containers/foo/pause '' 204
+t POST libpod/containers/foo/pause 204
t GET libpod/containers/foo/json 200 \
.Id~[0-9a-f]\\{64\\} \
@@ -27,7 +27,7 @@ t GET libpod/containers/foo/json 200 \
.Name=foo
# Unpause the container
-t POST libpod/containers/foo/unpause '' 204
+t POST libpod/containers/foo/unpause 204
t GET libpod/containers/foo/json 200 \
.Id~[0-9a-f]\\{64\\} \
@@ -44,11 +44,11 @@ t GET libpod/containers/foo/top 200 \
t GET libpod/containers/nonesuch/top 404
# Mount the container to host filesystem
-t POST libpod/containers/foo/mount '' 200
+t POST libpod/containers/foo/mount 200
like "$output" ".*merged" "Check container mount"
# Unmount the container
-t POST libpod/containers/foo/unmount '' 204
+t POST libpod/containers/foo/unmount 204
t DELETE libpod/containers/foo?force=true 204
@@ -85,7 +85,7 @@ podman run $IMAGE true
podman run $IMAGE true
podman run $IMAGE true
-t POST libpod/containers/prune '' 200
+t POST libpod/containers/prune 200
t GET libpod/containers/json 200 \
length=0
# vim: filetype=sh
diff --git a/test/apiv2/26-containersWait.at b/test/apiv2/26-containersWait.at
index 3f530c3f0..6a628e55a 100644
--- a/test/apiv2/26-containersWait.at
+++ b/test/apiv2/26-containersWait.at
@@ -13,15 +13,15 @@ podman rm -a -f &>/dev/null
CTR="WaitTestingCtr"
-t POST "containers/nonExistent/wait?condition=next-exit" '' 404
+t POST "containers/nonExistent/wait?condition=next-exit" 404
podman create --name "${CTR}" --entrypoint '["sleep", "0.5"]' "${IMAGE}"
-t POST "containers/${CTR}/wait?condition=non-existent-cond" '' 400
+t POST "containers/${CTR}/wait?condition=non-existent-cond" 400
-t POST "containers/${CTR}/wait?condition=not-running" '' 200
+t POST "containers/${CTR}/wait?condition=not-running" 200
-t POST "containers/${CTR}/wait?condition=next-exit" '' 200 &
+t POST "containers/${CTR}/wait?condition=next-exit" 200 &
child_pid=$!
podman start "${CTR}"
wait "${child_pid}"
@@ -37,7 +37,7 @@ if kill -2 "${child_pid}" 2> "/dev/null"; then
WAIT_TEST_ERROR="1"
fi
-t POST "containers/${CTR}/wait?condition=removed" '' 200 &
+t POST "containers/${CTR}/wait?condition=removed" 200 &
child_pid=$!
podman container rm "${CTR}"
wait "${child_pid}"
diff --git a/test/apiv2/30-volumes.at b/test/apiv2/30-volumes.at
index cf4b3d3ea..c27c638bb 100644
--- a/test/apiv2/30-volumes.at
+++ b/test/apiv2/30-volumes.at
@@ -13,25 +13,34 @@ t POST libpod/volumes/create name=foo1 201 \
.CreatedAt~[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}.* \
.Labels={} \
.Options={}
-t POST libpod/volumes/create '' 201
+t POST libpod/volumes/create 201
t POST libpod/volumes/create \
- '"Name":"foo2","Label":{"testlabel":"testonly"},"Options":{"type":"tmpfs","o":"nodev,noexec"}}' 201 \
- .Name=foo2 \
- .Labels.testlabel=testonly \
- .Options.type=tmpfs \
- .Options.o=nodev,noexec
+ Name=foo2 \
+ Label='{"testlabel":"testonly"}' \
+ Options='{"type":"tmpfs","o":"nodev,noexec"}}' \
+ 201 \
+ .Name=foo2 \
+ .Labels.testlabel=testonly \
+ .Options.type=tmpfs \
+ .Options.o=nodev,noexec
t POST libpod/volumes/create \
- '"Name":"foo3","Label":{"testlabel":""},"Options":{"type":"tmpfs","o":"nodev,noexec"}}' 201 \
- .Name=foo3 \
- .Labels.testlabel="" \
- .Options.type=tmpfs \
- .Options.o=nodev,noexec
+ Name=foo3 \
+ Label='{"testlabel":""}' \
+ Options='{"type":"tmpfs","o":"nodev,noexec"}}' \
+ 201 \
+ .Name=foo3 \
+ .Labels.testlabel="" \
+ .Options.type=tmpfs \
+ .Options.o=nodev,noexec
t POST libpod/volumes/create \
- '"Name":"foo4","Label":{"testlabel1":"testonly"},"Options":{"type":"tmpfs","o":"nodev,noexec"}}' 201 \
- .Name=foo4 \
- .Labels.testlabel1=testonly \
- .Options.type=tmpfs \
- .Options.o=nodev,noexec
+ Name=foo4 \
+ Label='{"testlabel1":"testonly"}' \
+ Options='{"type":"tmpfs","o":"nodev,noexec"}}' \
+ 201 \
+ .Name=foo4 \
+ .Labels.testlabel1=testonly \
+ .Options.type=tmpfs \
+ .Options.o=nodev,noexec
# Negative test
# We have created a volume named "foo1"
@@ -78,15 +87,15 @@ t DELETE libpod/volumes/foo1 404 \
.response=404
## Prune volumes with label matching 'testlabel1=testonly'
-t POST libpod/volumes/prune?filters='{"label":["testlabel1=testonly"]}' "" 200
+t POST libpod/volumes/prune?filters='{"label":["testlabel1=testonly"]}' 200
t GET libpod/volumes/json?filters='{"label":["testlabel1=testonly"]}' 200 length=0
## Prune volumes with label matching 'testlabel'
-t POST libpod/volumes/prune?filters='{"label":["testlabel"]}' "" 200
+t POST libpod/volumes/prune?filters='{"label":["testlabel"]}' 200
t GET libpod/volumes/json?filters='{"label":["testlabel"]}' 200 length=0
## Prune volumes
-t POST libpod/volumes/prune "" 200
+t POST libpod/volumes/prune 200
#After prune volumes, there should be no volume existing
t GET libpod/volumes/json 200 length=0
diff --git a/test/apiv2/35-networks.at b/test/apiv2/35-networks.at
index 93a9c9fe4..ce7ca628a 100644
--- a/test/apiv2/35-networks.at
+++ b/test/apiv2/35-networks.at
@@ -6,18 +6,21 @@
t GET networks/non-existing-network 404 \
.cause='network not found'
-t POST libpod/networks/create?name=network1 '' 200 \
+t POST libpod/networks/create?name=network1 200 \
.Filename~.*/network1\\.conflist
# --data '{"Subnet":{"IP":"10.10.254.0","Mask":[255,255,255,0]},"Labels":{"abc":"val"}}'
-t POST libpod/networks/create?name=network2 '"Subnet":{"IP":"10.10.254.0","Mask":[255,255,255,0]},"Labels":{"abc":"val"}' 200 \
+t POST libpod/networks/create?name=network2 \
+ Subnet='{"IP":"10.10.254.0","Mask":[255,255,255,0]}' \
+ Labels='{"abc":"val"}' \
+ 200 \
.Filename~.*/network2\\.conflist
# test for empty mask
-t POST libpod/networks/create '"Subnet":{"IP":"10.10.1.0","Mask":[]}' 500 \
+t POST libpod/networks/create Subnet='{"IP":"10.10.1.0","Mask":[]}' 500 \
.cause~'.*cannot be empty'
# test for invalid mask
-t POST libpod/networks/create '"Subnet":{"IP":"10.10.1.0","Mask":[0,255,255,0]}' 500 \
+t POST libpod/networks/create Subnet='{"IP":"10.10.1.0","Mask":[0,255,255,0]}' 500 \
.cause~'.*mask is invalid'
# network list
@@ -59,7 +62,7 @@ t GET networks/a7662f44d65029fd4635c91feea3d720a57cef52e2a9fcc7772b69072cc1ccd1
.Scope=local
# network create docker
-t POST networks/create '"Name":"net3","IPAM":{"Config":[]}' 201
+t POST networks/create Name=net3\ IPAM='{"Config":[]}' 201
# network delete docker
t DELETE networks/net3 204
diff --git a/test/apiv2/40-pods.at b/test/apiv2/40-pods.at
index ce65105d2..f3272c41e 100644
--- a/test/apiv2/40-pods.at
+++ b/test/apiv2/40-pods.at
@@ -25,70 +25,70 @@ t POST "libpod/pods/create (dup pod)" name=foo 409 \
#t POST libpod/pods/create a=b 400 .cause='bad parameter' # FIXME: unimplemented
-t POST libpod/pods/foo/start '' 200 \
+t POST libpod/pods/foo/start 200 \
.Errs=null \
.Id=$pod_id
-t POST libpod/pods/foo/start '' 304 \
+t POST libpod/pods/foo/start 304 \
-t POST libpod/pods/fakename/start '' 404 \
+t POST libpod/pods/fakename/start 404 \
.cause="no such pod" \
.message="no pod with name or ID fakename found: no such pod"
if root || have_cgroupsv2; then
- t POST libpod/pods/foo/pause '' 200
+ t POST libpod/pods/foo/pause 200
else
# Rootless cgroupsv1 : unsupported
- t POST "libpod/pods/foo/pause (rootless cgroups v1)" '' 500 \
+ t POST "libpod/pods/foo/pause (rootless cgroups v1)" 500 \
.cause="this container does not have a cgroup" \
.message~".*pause pods containing rootless containers with cgroup V1"
fi
-t POST libpod/pods/foo/unpause '' 200
-t POST "libpod/pods/foo/unpause (2nd unpause in a row)" '' 200
-t POST "libpod/pods/fakename/unpause" '' 404\
+t POST libpod/pods/foo/unpause 200
+t POST "libpod/pods/foo/unpause (2nd unpause in a row)" 200
+t POST "libpod/pods/fakename/unpause" 404\
.cause="no such pod" \
.message="no pod with name or ID fakename found: no such pod"
-t POST libpod/pods/foo/stop '' 200 \
+t POST libpod/pods/foo/stop 200 \
.Errs=null \
.Id=$pod_id
-t POST "libpod/pods/foo/stop (pod is already stopped)" '' 304
-t POST "libpod/pods/fakename/stop" '' 404\
+t POST "libpod/pods/foo/stop (pod is already stopped)" 304
+t POST "libpod/pods/fakename/stop" 404\
.cause="no such pod" \
.message="no pod with name or ID fakename found: no such pod"
-t POST libpod/pods/foo/restart '' 200 \
+t POST libpod/pods/foo/restart 200 \
.Errs=null \
.Id=$pod_id
-t POST "libpod/pods/bar/restart (restart on nonexistent pod)" '' 404
+t POST "libpod/pods/bar/restart (restart on nonexistent pod)" 404
t POST libpod/pods/create name=bar 201 .Id~[0-9a-f]\\{64\\}
pod_bar_id=$(jq -r .Id <<<"$output")
-t POST libpod/pods/bar/restart '' 200 \
+t POST libpod/pods/bar/restart 200 \
.Errs=null \
.Id=$pod_bar_id
-t GET libpod/pods/bar/json 200 \
+t GET libpod/pods/bar/json 200 \
.State=Running
-t POST libpod/pods/bar/restart '' 200 \
+t POST libpod/pods/bar/restart 200 \
.Errs=null \
.Id=$pod_bar_id
-t POST "libpod/pods/bar/stop?t=invalid" '' 400 \
+t POST "libpod/pods/bar/stop?t=invalid" 400 \
.cause="schema: error converting value for \"t\"" \
.message~"failed to parse parameters for"
podman run -d --pod bar busybox sleep 999
-t POST libpod/pods/bar/stop?t=1 '' 200 \
+t POST libpod/pods/bar/stop?t=1 200 \
.Errs=null \
.Id=$pod_bar_id
-t POST libpod/pods/bar/start '' 200
+t POST libpod/pods/bar/start 200
t GET libpod/pods/stats?all=true 200
is $(jq '. | length' <<<"$output") 3 "stats?all=true: number of records found"
@@ -118,7 +118,7 @@ t GET libpod/pods/foo/top?ps_args=args,pid 200 \
# FIXME: I'm not sure what 'prune' is supposed to do; as of 20200224 it
# just returns 200 (ok) with empty result list.
-#t POST libpod/pods/prune '' 200 # FIXME: 2020-02-24 returns 200 {}
+#t POST libpod/pods/prune 200 # FIXME: 2020-02-24 returns 200 {}
#t POST libpod/pods/prune 'a=b' 400 # FIXME: 2020-02-24 returns 200
# Clean up; and try twice, making sure that the second time fails
diff --git a/test/apiv2/44-mounts.at b/test/apiv2/44-mounts.at
index 5dc560852..d54669e7d 100644
--- a/test/apiv2/44-mounts.at
+++ b/test/apiv2/44-mounts.at
@@ -4,7 +4,12 @@ podman pull $IMAGE &>/dev/null
# Test various HostConfig options
tmpfs_name="/mytmpfs"
-t POST containers/create?name=hostconfig_test '"Image":"'$IMAGE'","Cmd":["df"],"HostConfig":{"Binds":["/tmp/doesnotexist:/test1"],"TmpFs":{"'$tmpfs_name'":"rw"}}' 201 \
+t POST containers/create?name=hostconfig_test \
+ Image=$IMAGE \
+ Cmd='["df","-P","'$tmpfs_name'"]' \
+ HostConfig='{"Binds":["/tmp/doesnotexist:/test1"]' \
+ TmpFs="{\"$tmpfs_name\":\"rw\"}}" \
+ 201 \
.Id~[0-9a-f]\\{64\\}
cid=$(jq -r '.Id' <<<"$output")
@@ -13,9 +18,14 @@ t GET containers/${cid}/json 200 \
.HostConfig.Tmpfs[\"${tmpfs_name}\"]~rw,
# Run the container, verify output
-t POST containers/${cid}/start '' 204
-t POST containers/${cid}/wait '' 200
+t POST containers/${cid}/start 204
+t POST containers/${cid}/wait 200
t GET containers/${cid}/logs?stdout=true 200
-like "$(<$WORKDIR/curl.result.out)" ".* ${tmpfs_name}" \
+# /logs returns application/octet-stream, which our test helper saves in
+# an outfile rather than returning in $output. That's why we can't test
+# this directly in the /logs test above; instead, we rely on knowing the
+# path to the stored results. The 'tr' is needed because there may be
+# null bytes in the outfile.
+like "$(tr -d \\0 <$WORKDIR/curl.result.out)" ".* ${tmpfs_name}" \
"'df' output includes tmpfs name"
diff --git a/test/apiv2/45-system.at b/test/apiv2/45-system.at
index ad4bdf4f7..364b87c56 100644
--- a/test/apiv2/45-system.at
+++ b/test/apiv2/45-system.at
@@ -27,22 +27,28 @@ t GET libpod/system/df 200 '.Volumes[0].VolumeName=foo1'
# Create two more volumes to test pruneing
t POST libpod/volumes/create \
- '"Name":"foo2","Label":{"testlabel1":""},"Options":{"type":"tmpfs","o":"nodev,noexec"}}' 201 \
- .Name=foo2 \
- .Driver=local \
- .Mountpoint=$volumepath/foo2/_data \
- .CreatedAt~[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}.* \
- .Labels.testlabel1="" \
- .Options.o=nodev,noexec
+ Name=foo2 \
+ Label='{"testlabel1":""}' \
+ Options='{"type":"tmpfs","o":"nodev,noexec"}}' \
+ 201 \
+ .Name=foo2 \
+ .Driver=local \
+ .Mountpoint=$volumepath/foo2/_data \
+ .CreatedAt~[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}.* \
+ .Labels.testlabel1="" \
+ .Options.o=nodev,noexec
t POST libpod/volumes/create \
- '"Name":"foo3","Label":{"testlabel1":"testonly"},"Options":{"type":"tmpfs","o":"nodev,noexec"}}' 201 \
- .Name=foo3 \
- .Driver=local \
- .Mountpoint=$volumepath/foo3/_data \
- .CreatedAt~[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}.* \
- .Labels.testlabel1=testonly \
- .Options.o=nodev,noexec
+ Name=foo3 \
+ Label='{"testlabel1":"testonly"}' \
+ Options='{"type":"tmpfs","o":"nodev,noexec"}}' \
+ 201 \
+ .Name=foo3 \
+ .Driver=local \
+ .Mountpoint=$volumepath/foo3/_data \
+ .CreatedAt~[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}.* \
+ .Labels.testlabel1=testonly \
+ .Options.o=nodev,noexec
t GET system/df 200 '.Volumes | length=3'
t GET libpod/system/df 200 '.Volumes | length=3'
diff --git a/test/apiv2/50-secrets.at b/test/apiv2/50-secrets.at
index c4ffb5883..034ec080a 100644
--- a/test/apiv2/50-secrets.at
+++ b/test/apiv2/50-secrets.at
@@ -4,14 +4,14 @@
#
# secret create
-t POST secrets/create '"Name":"mysecret","Data":"c2VjcmV0"' 200\
+t POST secrets/create Name=mysecret Data=c2VjcmV0 200\
.ID~.* \
# secret create unsupported labels
-t POST secrets/create '"Name":"mysecret","Data":"c2VjcmV0","Labels":{"fail":"fail"}' 400
+t POST secrets/create Name=mysecret Data=c2VjcmV0 Labels='{"fail":"fail"}' 400
# secret create name already in use
-t POST secrets/create '"Name":"mysecret","Data":"c2VjcmV0"' 409
+t POST secrets/create Name=mysecret Data=c2VjcmV0 409
# secret inspect
t GET secrets/mysecret 200 \
@@ -36,4 +36,4 @@ t DELETE secrets/mysecret 204
t DELETE secrets/bogus 404
# secret update not implemented
-t POST secrets/mysecret/update "" 501
+t POST secrets/mysecret/update 501
diff --git a/test/apiv2/60-auth.at b/test/apiv2/60-auth.at
index 378955cd7..cfde519c1 100644
--- a/test/apiv2/60-auth.at
+++ b/test/apiv2/60-auth.at
@@ -5,25 +5,19 @@
start_registry
-# FIXME FIXME FIXME: remove the 'if false' for use with PR 9589
-if false; then
-
-# FIXME FIXME: please forgive the horrible POST params format; I have an
-# upcoming PR which should fix that.
-
# Test with wrong password. Confirm bad status and appropriate error message
-t POST /v1.40/auth "\"username\":\"${REGISTRY_USERNAME}\",\"password\":\"WrOnGPassWord\",\"serveraddress\":\"localhost:$REGISTRY_PORT/\"" \
+t POST /v1.40/auth username=$REGISTRY_USERNAME password=WrOnGPassWord serveraddress=localhost:$REGISTRY_PORT/ \
400 \
.Status~'.* invalid username/password'
-# Test with the right password. Confirm status message and reasonable token
-t POST /v1.40/auth "\"username\":\"${REGISTRY_USERNAME}\",\"password\":\"${REGISTRY_PASSWORD}\",\"serveraddress\":\"localhost:$REGISTRY_PORT/\"" \
+# Test with the right password. Confirm status message
+t POST /v1.40/auth username=$REGISTRY_USERNAME password=$REGISTRY_PASSWORD serveraddress=localhost:$REGISTRY_PORT/ \
200 \
.Status="Login Succeeded" \
- .IdentityToken~[a-zA-Z0-9]
-
-# FIXME: now what? Try something-something using that token?
-token=$(jq -r .IdentityToken <<<"$output")
-# ...
+ .IdentityToken=""
-fi # FIXME FIXME FIXME: remove when working
+# Same test with url scheme provided
+t POST /v1.40/auth username=$REGISTRY_USERNAME password=$REGISTRY_PASSWORD serveraddress=https://localhost:$REGISTRY_PORT/ \
+ 200 \
+ .Status="Login Succeeded" \
+ .IdentityToken=""
diff --git a/test/apiv2/README.md b/test/apiv2/README.md
index 252d6454e..19727cec7 100644
--- a/test/apiv2/README.md
+++ b/test/apiv2/README.md
@@ -52,9 +52,14 @@ Notes:
If there's no leading slash, `t` prepends `/v1.40`. This is a simple
convenience for simplicity of writing tests.
-* When method is POST, the argument after the endpoint must be a series
-of POST arguments in the form 'key=value', separated by commas. `t` will
-convert those to JSON form for passing to the server.
+* When method is POST, the argument(s) after the endpoint may be a series
+of POST parameters in the form 'key=value', separated by spaces:
+ t POST myentrypoint 200 ! no params
+ t POST myentrypoint id=$id 200 ! just one
+ t POST myentrypoint id=$id filter='{"foo":"bar"}' 200 ! two, with json
+ t POST myentrypoint name=$name badparam='["foo","bar"]' 500 ! etc...
+`t` will convert the param list to JSON form for passing to the server.
+A numeric status code terminates processing of POST parameters.
* The final arguments are one or more expected string results. If an
argument starts with a dot, `t` will invoke `jq` on the output to
diff --git a/test/apiv2/rest_api/__init__.py b/test/apiv2/rest_api/__init__.py
index b7b8a7649..0ad6b51b3 100644
--- a/test/apiv2/rest_api/__init__.py
+++ b/test/apiv2/rest_api/__init__.py
@@ -3,6 +3,7 @@ import json
import os
import shutil
import subprocess
+import sys
import tempfile
@@ -27,7 +28,9 @@ class Podman(object):
self.cmd.append("--root=" + os.path.join(self.anchor_directory, "crio"))
self.cmd.append("--runroot=" + os.path.join(self.anchor_directory, "crio-run"))
- os.environ["CONTAINERS_REGISTRIES_CONF"] = os.path.join(self.anchor_directory, "registry.conf")
+ os.environ["CONTAINERS_REGISTRIES_CONF"] = os.path.join(
+ self.anchor_directory, "registry.conf"
+ )
p = configparser.ConfigParser()
p.read_dict(
{
@@ -114,13 +117,20 @@ class Podman(object):
check = kwargs.get("check", False)
shell = kwargs.get("shell", False)
- return subprocess.run(
- cmd,
- shell=shell,
- check=check,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- )
+ try:
+ return subprocess.run(
+ cmd,
+ shell=shell,
+ check=check,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ )
+ except subprocess.CalledProcessError as e:
+ if e.stdout:
+ sys.stdout.write("\nRun Stdout:\n" + e.stdout.decode("utf-8"))
+ if e.stderr:
+ sys.stderr.write("\nRun Stderr:\n" + e.stderr.decode("utf-8"))
+ raise
def tear_down(self):
shutil.rmtree(self.anchor_directory, ignore_errors=True)
diff --git a/test/apiv2/rest_api/test_rest_v2_0_0.py b/test/apiv2/rest_api/test_rest_v2_0_0.py
index 8a78f5185..d7910f555 100644
--- a/test/apiv2/rest_api/test_rest_v2_0_0.py
+++ b/test/apiv2/rest_api/test_rest_v2_0_0.py
@@ -50,23 +50,20 @@ class TestApi(unittest.TestCase):
def setUp(self):
super().setUp()
- try:
- TestApi.podman.run("run", "alpine", "/bin/ls", check=True)
- except subprocess.CalledProcessError as e:
- if e.stdout:
- sys.stdout.write("\nRun Stdout:\n" + e.stdout.decode("utf-8"))
- if e.stderr:
- sys.stderr.write("\nRun Stderr:\n" + e.stderr.decode("utf-8"))
- raise
+ TestApi.podman.run("run", "alpine", "/bin/ls", check=True)
+
+ def tearDown(self) -> None:
+ super().tearDown()
+
+ TestApi.podman.run("pod", "rm", "--all", "--force", check=True)
+ TestApi.podman.run("rm", "--all", "--force", check=True)
@classmethod
def setUpClass(cls):
super().setUpClass()
TestApi.podman = Podman()
- TestApi.service = TestApi.podman.open(
- "system", "service", "tcp:localhost:8080", "--time=0"
- )
+ TestApi.service = TestApi.podman.open("system", "service", "tcp:localhost:8080", "--time=0")
# give the service some time to be ready...
time.sleep(2)
@@ -243,9 +240,7 @@ class TestApi(unittest.TestCase):
def test_post_create_compat(self):
"""Create network and connect container during create"""
- net = requests.post(
- PODMAN_URL + "/v1.40/networks/create", json={"Name": "TestNetwork"}
- )
+ net = requests.post(PODMAN_URL + "/v1.40/networks/create", json={"Name": "TestNetwork"})
self.assertEqual(net.status_code, 201, net.text)
create = requests.post(
@@ -454,15 +449,11 @@ class TestApi(unittest.TestCase):
self.assertIn(k, o)
def test_network_compat(self):
- name = "Network_" + "".join(
- random.choice(string.ascii_letters) for i in range(10)
- )
+ name = "Network_" + "".join(random.choice(string.ascii_letters) for i in range(10))
# Cannot test for 0 existing networks because default "podman" network always exists
- create = requests.post(
- PODMAN_URL + "/v1.40/networks/create", json={"Name": name}
- )
+ create = requests.post(PODMAN_URL + "/v1.40/networks/create", json={"Name": name})
self.assertEqual(create.status_code, 201, create.content)
obj = json.loads(create.content)
self.assertIn(type(obj), (dict,))
@@ -492,9 +483,7 @@ class TestApi(unittest.TestCase):
self.assertEqual(inspect.status_code, 404, inspect.content)
# network prune
- prune_name = "Network_" + "".join(
- random.choice(string.ascii_letters) for i in range(10)
- )
+ prune_name = "Network_" + "".join(random.choice(string.ascii_letters) for i in range(10))
prune_create = requests.post(
PODMAN_URL + "/v1.40/networks/create", json={"Name": prune_name}
)
@@ -506,9 +495,7 @@ class TestApi(unittest.TestCase):
self.assertTrue(prune_name in obj["NetworksDeleted"])
def test_volumes_compat(self):
- name = "Volume_" + "".join(
- random.choice(string.ascii_letters) for i in range(10)
- )
+ name = "Volume_" + "".join(random.choice(string.ascii_letters) for i in range(10))
ls = requests.get(PODMAN_URL + "/v1.40/volumes")
self.assertEqual(ls.status_code, 200, ls.content)
@@ -524,9 +511,7 @@ class TestApi(unittest.TestCase):
for k in required_keys:
self.assertIn(k, obj)
- create = requests.post(
- PODMAN_URL + "/v1.40/volumes/create", json={"Name": name}
- )
+ create = requests.post(PODMAN_URL + "/v1.40/volumes/create", json={"Name": name})
self.assertEqual(create.status_code, 201, create.content)
# See https://docs.docker.com/engine/api/v1.40/#operation/VolumeCreate
@@ -570,17 +555,6 @@ class TestApi(unittest.TestCase):
self.assertIn(name, payload["VolumesDeleted"])
self.assertGreater(payload["SpaceReclaimed"], 0)
- def test_auth_compat(self):
- r = requests.post(
- PODMAN_URL + "/v1.40/auth",
- json={
- "username": "bozo",
- "password": "wedontneednopasswords",
- "serveraddress": "https://localhost/v1.40/",
- },
- )
- self.assertEqual(r.status_code, 404, r.content)
-
def test_version(self):
r = requests.get(PODMAN_URL + "/v1.40/version")
self.assertEqual(r.status_code, 200, r.content)
@@ -703,21 +677,15 @@ class TestApi(unittest.TestCase):
"""Verify issue #8865"""
pod_name = list()
- pod_name.append(
- "Pod_" + "".join(random.choice(string.ascii_letters) for i in range(10))
- )
- pod_name.append(
- "Pod_" + "".join(random.choice(string.ascii_letters) for i in range(10))
- )
+ pod_name.append("Pod_" + "".join(random.choice(string.ascii_letters) for i in range(10)))
+ pod_name.append("Pod_" + "".join(random.choice(string.ascii_letters) for i in range(10)))
r = requests.post(
_url("/pods/create"),
json={
"name": pod_name[0],
"no_infra": False,
- "portmappings": [
- {"host_ip": "127.0.0.1", "host_port": 8889, "container_port": 89}
- ],
+ "portmappings": [{"host_ip": "127.0.0.1", "host_port": 8889, "container_port": 89}],
},
)
self.assertEqual(r.status_code, 201, r.text)
@@ -736,9 +704,7 @@ class TestApi(unittest.TestCase):
json={
"name": pod_name[1],
"no_infra": False,
- "portmappings": [
- {"host_ip": "127.0.0.1", "host_port": 8889, "container_port": 89}
- ],
+ "portmappings": [{"host_ip": "127.0.0.1", "host_port": 8889, "container_port": 89}],
},
)
self.assertEqual(r.status_code, 201, r.text)
diff --git a/test/apiv2/test-apiv2 b/test/apiv2/test-apiv2
index e32d6bc62..9f6bf257f 100755
--- a/test/apiv2/test-apiv2
+++ b/test/apiv2/test-apiv2
@@ -156,19 +156,23 @@ function _bump() {
# jsonify # convert 'foo=bar,x=y' to json {"foo":"bar","x":"y"}
#############
function jsonify() {
- # split by comma
- local -a settings_in
- read -ra settings_in <<<"$1"
-
# convert each to double-quoted form
local -a settings_out
- for i in ${settings_in[*]}; do
- settings_out+=$(sed -e 's/\(.*\)=\(.*\)/"\1":"\2"/' <<<$i)
+ for i in "$@"; do
+ # Each argument is of the form foo=bar. Separate into left and right.
+ local lhs
+ local rhs
+ IFS='=' read lhs rhs <<<"$i"
+
+ # If right-hand side already includes double quotes, do nothing
+ if [[ ! $rhs =~ \" ]]; then
+ rhs="\"${rhs}\""
+ fi
+ settings_out+=("\"${lhs}\":${rhs}")
done
- # ...and wrap inside braces.
- # FIXME: handle commas
- echo "{${settings_out[*]}}"
+ # ...and wrap inside braces, with comma separator if multiple fields
+ (IFS=','; echo "{${settings_out[*]}}")
}
#######
@@ -180,11 +184,19 @@ function t() {
local curl_args
local testname="$method $path"
- # POST requests require an extra params arg
+ # POST requests may be followed by one or more key=value pairs.
+ # Slurp the command line until we see a 3-digit status code.
if [[ $method = "POST" ]]; then
- curl_args="-d $(jsonify $1)"
+ local -a post_args
+ for arg; do
+ case "$arg" in
+ *=*) post_args+=("$arg"); shift ;;
+ [1-9][0-9][0-9]) break;;
+ *) die "Internal error: invalid POST arg '$arg'" ;;
+ esac
+ done
+ curl_args="-d $(jsonify ${post_args[@]})"
testname="$testname [$curl_args]"
- shift
fi
# entrypoint path can include a descriptive comment; strip it off
diff --git a/test/e2e/containers_conf_test.go b/test/e2e/containers_conf_test.go
index 6b1a0d16e..aa2380c51 100644
--- a/test/e2e/containers_conf_test.go
+++ b/test/e2e/containers_conf_test.go
@@ -311,7 +311,7 @@ var _ = Describe("Podman run", func() {
session = podmanTest.Podman([]string{"run", ALPINE, "date", "+'%H %Z'"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- Expect(session.OutputToString()).To(ContainSubstring("EST"))
+ Expect(session.OutputToString()).To(Or(ContainSubstring("EST"), ContainSubstring("EDT")))
// Umask
session = podmanTest.Podman([]string{"run", "--rm", ALPINE, "sh", "-c", "umask"})
diff --git a/test/system/065-cp.bats b/test/system/065-cp.bats
index 73e807843..679cdc209 100644
--- a/test/system/065-cp.bats
+++ b/test/system/065-cp.bats
@@ -370,6 +370,7 @@ load helpers
is "${lines[0]}" "${randomcontent[0]}" "eval symlink - created container"
is "${lines[1]}" "${randomcontent[1]}" "eval symlink - created container"
run_podman rm -f cpcontainer
+ run_podman rmi $cpimage
}
diff --git a/test/system/070-build.bats b/test/system/070-build.bats
index d413b0c10..8f6cdb46b 100644
--- a/test/system/070-build.bats
+++ b/test/system/070-build.bats
@@ -241,11 +241,21 @@ EOF
build_arg_implicit+="=$arg_implicit_value"
fi
+ # FIXME FIXME FIXME: 2021-03-15: workaround for #9567 (slow ubuntu 2004):
+ # we're seeing lots of timeouts in CI. Until/unless #9567 gets fixed,
+ # let's get CI passing by extending the timeout when remote on ubuntu
+ local localtimeout=${PODMAN_TIMEOUT}
+ if is_remote; then
+ if grep -qi ubuntu /etc/os-release; then
+ localtimeout=$(( 2 * $localtimeout ))
+ fi
+ fi
+
# cd to the dir, so we test relative paths (important for podman-remote)
cd $PODMAN_TMPDIR
export arg_explicit="THIS SHOULD BE OVERRIDDEN BY COMMAND LINE!"
export arg_implicit=${arg_implicit_value}
- run_podman ${MOUNTS_CONF} build \
+ PODMAN_TIMEOUT=$localtimeout run_podman ${MOUNTS_CONF} build \
--build-arg arg_explicit=${arg_explicit_value} \
$build_arg_implicit \
--dns-search $nosuchdomain \
@@ -594,34 +604,46 @@ EOF
run_podman rmi -a --force
}
+# Caveat lector: this test was mostly copy-pasted from buildah in #9275.
+# It's not entirely clear what it's testing, or if the 'mount' section is
+# necessary.
@test "build with copy-from referencing the base image" {
- skip_if_rootless "cannot mount as rootless"
- target=busybox-derived
- target_mt=busybox-mt-derived
+ target=derived
+ target_mt=derived-mt
tmpdir=$PODMAN_TMPDIR/build-test
mkdir -p $tmpdir
+
containerfile1=$tmpdir/Containerfile1
- cat >$containerfile1 <<EOF
-FROM quay.io/libpod/busybox AS build
-RUN rm -f /bin/paste
+ cat >$containerfile1 <<EOF
+FROM $IMAGE AS build
+RUN rm -f /etc/issue
USER 1001
-COPY --from=quay.io/libpod/busybox /bin/paste /test/
+COPY --from=$IMAGE /etc/issue /test/
EOF
+
containerfile2=$tmpdir/Containerfile2
- cat >$containerfile2 <<EOF
-FROM quay.io/libpod/busybox AS test
-RUN rm -f /bin/nl
+ cat >$containerfile2 <<EOF
+FROM $IMAGE AS test
+RUN rm -f /etc/alpine-release
FROM quay.io/libpod/alpine AS final
-COPY --from=quay.io/libpod/busybox /bin/nl /test/
+COPY --from=$IMAGE /etc/alpine-release /test/
EOF
- run_podman build -t ${target} -f ${containerfile1} ${tmpdir}
- run_podman build --jobs 4 -t ${target} -f ${containerfile1} ${tmpdir}
- run_podman build -t ${target} -f ${containerfile2} ${tmpdir}
+ # Before the build, $IMAGE's base image should not be present
+ local base_image=quay.io/libpod/alpine:latest
+ run_podman 1 image exists $base_image
+
+ run_podman build --jobs 1 -t ${target} -f ${containerfile2} ${tmpdir}
run_podman build --no-cache --jobs 4 -t ${target_mt} -f ${containerfile2} ${tmpdir}
+ # After the build, the base image should exist
+ run_podman image exists $base_image
+
# (can only test locally; podman-remote has no image mount command)
- if ! is_remote; then
+ # (can also only test as root; mounting under rootless podman is too hard)
+ # We perform the test as a conditional, not a 'skip', because there's
+ # value in testing the above 'build' commands even remote & rootless.
+ if ! is_remote && ! is_rootless; then
run_podman image mount ${target}
root_single_job=$output
@@ -629,8 +651,21 @@ EOF
root_multi_job=$output
# Check that both the version with --jobs 1 and --jobs=N have the same number of files
- test $(find $root_single_job -type f | wc -l) = $(find $root_multi_job -type f | wc -l)
+ nfiles_single=$(find $root_single_job -type f | wc -l)
+ nfiles_multi=$(find $root_multi_job -type f | wc -l)
+ run_podman image umount ${target_mt}
+ run_podman image umount ${target}
+
+ is "$nfiles_single" "$nfiles_multi" \
+ "Number of files (--jobs=1) == (--jobs=4)"
+
+ # Make sure the number is reasonable
+ test "$nfiles_single" -gt 50
fi
+
+ # Clean up
+ run_podman rmi ${target_mt} ${target} ${base_image}
+ run_podman image prune -f
}
@test "podman build --logfile test" {
diff --git a/test/system/120-load.bats b/test/system/120-load.bats
index 936449bdb..95113c4a6 100644
--- a/test/system/120-load.bats
+++ b/test/system/120-load.bats
@@ -31,6 +31,9 @@ verify_iid_and_name() {
invalid=$PODMAN_TMPDIR/invalid
echo "I am an invalid file and should cause a podman-load error" > $invalid
run_podman 125 load -i $invalid
+ # podman and podman-remote emit different messages; this is a common string
+ is "$output" ".*error pulling image: unable to pull .*" \
+ "load -i INVALID fails with expected diagnostic"
}
@test "podman save to pipe and load" {
diff --git a/test/system/260-sdnotify.bats b/test/system/260-sdnotify.bats
index a5fa0f4e6..8bf49eb1d 100644
--- a/test/system/260-sdnotify.bats
+++ b/test/system/260-sdnotify.bats
@@ -42,14 +42,22 @@ function _start_socat() {
_SOCAT_LOG="$PODMAN_TMPDIR/socat.log"
rm -f $_SOCAT_LOG
- socat unix-recvfrom:"$NOTIFY_SOCKET",fork \
- system:"(cat;echo) >> $_SOCAT_LOG" &
+ # Execute in subshell so we can close fd3 (which BATS uses).
+ # This is a superstitious ritual to try to avoid leaving processes behind,
+ # and thus prevent CI hangs.
+ (exec socat unix-recvfrom:"$NOTIFY_SOCKET",fork \
+ system:"(cat;echo) >> $_SOCAT_LOG" 3>&-) &
_SOCAT_PID=$!
}
# Stop the socat background process and clean up logs
function _stop_socat() {
if [[ -n "$_SOCAT_PID" ]]; then
+ # Kill all child processes, then the process itself.
+ # This is a superstitious incantation to avoid leaving processes behind.
+ # The '|| true' is because only f35 leaves behind socat processes;
+ # f33 (and perhaps others?) behave nicely. ARGH!
+ pkill -P $_SOCAT_PID || true
kill $_SOCAT_PID
fi
_SOCAT_PID=
@@ -57,6 +65,7 @@ function _stop_socat() {
if [[ -n "$_SOCAT_LOG" ]]; then
rm -f $_SOCAT_LOG
fi
+ _SOCAT_LOG=
}
# Check that MAINPID=xxxxx points to a running conmon process
diff --git a/test/system/700-play.bats b/test/system/700-play.bats
index e7904f59f..8fa96741c 100644
--- a/test/system/700-play.bats
+++ b/test/system/700-play.bats
@@ -5,6 +5,20 @@
load helpers
+# This is a long ugly way to clean up pods and remove the pause image
+function teardown() {
+ run_podman pod rm -f -a
+ run_podman rm -f -a
+ run_podman image list --format '{{.ID}} {{.Repository}}'
+ while read id name; do
+ if [[ "$name" =~ /pause ]]; then
+ run_podman rmi $id
+ fi
+ done <<<"$output"
+
+ basic_teardown
+}
+
testYaml="
apiVersion: v1
kind: Pod
@@ -24,7 +38,7 @@ spec:
value: xterm
- name: container
value: podman
- image: quay.io/libpod/alpine:latest
+ image: $IMAGE
name: test
resources: {}
securityContext:
diff --git a/vendor/github.com/magefile/mage/LICENSE b/vendor/github.com/magefile/mage/LICENSE
deleted file mode 100644
index d0632bc14..000000000
--- a/vendor/github.com/magefile/mage/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "{}"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright 2017 the Mage authors
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/vendor/github.com/magefile/mage/mg/color.go b/vendor/github.com/magefile/mage/mg/color.go
deleted file mode 100644
index 3e2710332..000000000
--- a/vendor/github.com/magefile/mage/mg/color.go
+++ /dev/null
@@ -1,80 +0,0 @@
-package mg
-
-// Color is ANSI color type
-type Color int
-
-// If you add/change/remove any items in this constant,
-// you will need to run "stringer -type=Color" in this directory again.
-// NOTE: Please keep the list in an alphabetical order.
-const (
- Black Color = iota
- Red
- Green
- Yellow
- Blue
- Magenta
- Cyan
- White
- BrightBlack
- BrightRed
- BrightGreen
- BrightYellow
- BrightBlue
- BrightMagenta
- BrightCyan
- BrightWhite
-)
-
-// AnsiColor are ANSI color codes for supported terminal colors.
-var ansiColor = map[Color]string{
- Black: "\u001b[30m",
- Red: "\u001b[31m",
- Green: "\u001b[32m",
- Yellow: "\u001b[33m",
- Blue: "\u001b[34m",
- Magenta: "\u001b[35m",
- Cyan: "\u001b[36m",
- White: "\u001b[37m",
- BrightBlack: "\u001b[30;1m",
- BrightRed: "\u001b[31;1m",
- BrightGreen: "\u001b[32;1m",
- BrightYellow: "\u001b[33;1m",
- BrightBlue: "\u001b[34;1m",
- BrightMagenta: "\u001b[35;1m",
- BrightCyan: "\u001b[36;1m",
- BrightWhite: "\u001b[37;1m",
-}
-
-// AnsiColorReset is an ANSI color code to reset the terminal color.
-const AnsiColorReset = "\033[0m"
-
-// DefaultTargetAnsiColor is a default ANSI color for colorizing targets.
-// It is set to Cyan as an arbitrary color, because it has a neutral meaning
-var DefaultTargetAnsiColor = ansiColor[Cyan]
-
-func toLowerCase(s string) string {
- // this is a naive implementation
- // borrowed from https://golang.org/src/strings/strings.go
- // and only considers alphabetical characters [a-zA-Z]
- // so that we don't depend on the "strings" package
- buf := make([]byte, len(s))
- for i := 0; i < len(s); i++ {
- c := s[i]
- if 'A' <= c && c <= 'Z' {
- c += 'a' - 'A'
- }
- buf[i] = c
- }
- return string(buf)
-}
-
-func getAnsiColor(color string) (string, bool) {
- colorLower := toLowerCase(color)
- for k, v := range ansiColor {
- colorConstLower := toLowerCase(k.String())
- if colorConstLower == colorLower {
- return v, true
- }
- }
- return "", false
-}
diff --git a/vendor/github.com/magefile/mage/mg/color_string.go b/vendor/github.com/magefile/mage/mg/color_string.go
deleted file mode 100644
index 06debca54..000000000
--- a/vendor/github.com/magefile/mage/mg/color_string.go
+++ /dev/null
@@ -1,38 +0,0 @@
-// Code generated by "stringer -type=Color"; DO NOT EDIT.
-
-package mg
-
-import "strconv"
-
-func _() {
- // An "invalid array index" compiler error signifies that the constant values have changed.
- // Re-run the stringer command to generate them again.
- var x [1]struct{}
- _ = x[Black-0]
- _ = x[Red-1]
- _ = x[Green-2]
- _ = x[Yellow-3]
- _ = x[Blue-4]
- _ = x[Magenta-5]
- _ = x[Cyan-6]
- _ = x[White-7]
- _ = x[BrightBlack-8]
- _ = x[BrightRed-9]
- _ = x[BrightGreen-10]
- _ = x[BrightYellow-11]
- _ = x[BrightBlue-12]
- _ = x[BrightMagenta-13]
- _ = x[BrightCyan-14]
- _ = x[BrightWhite-15]
-}
-
-const _Color_name = "BlackRedGreenYellowBlueMagentaCyanWhiteBrightBlackBrightRedBrightGreenBrightYellowBrightBlueBrightMagentaBrightCyanBrightWhite"
-
-var _Color_index = [...]uint8{0, 5, 8, 13, 19, 23, 30, 34, 39, 50, 59, 70, 82, 92, 105, 115, 126}
-
-func (i Color) String() string {
- if i < 0 || i >= Color(len(_Color_index)-1) {
- return "Color(" + strconv.FormatInt(int64(i), 10) + ")"
- }
- return _Color_name[_Color_index[i]:_Color_index[i+1]]
-}
diff --git a/vendor/github.com/magefile/mage/mg/deps.go b/vendor/github.com/magefile/mage/mg/deps.go
deleted file mode 100644
index ad85931f8..000000000
--- a/vendor/github.com/magefile/mage/mg/deps.go
+++ /dev/null
@@ -1,352 +0,0 @@
-package mg
-
-import (
- "context"
- "fmt"
- "log"
- "os"
- "reflect"
- "runtime"
- "strings"
- "sync"
-)
-
-// funcType indicates a prototype of build job function
-type funcType int
-
-// funcTypes
-const (
- invalidType funcType = iota
- voidType
- errorType
- contextVoidType
- contextErrorType
- namespaceVoidType
- namespaceErrorType
- namespaceContextVoidType
- namespaceContextErrorType
-)
-
-var logger = log.New(os.Stderr, "", 0)
-
-type onceMap struct {
- mu *sync.Mutex
- m map[string]*onceFun
-}
-
-func (o *onceMap) LoadOrStore(s string, one *onceFun) *onceFun {
- defer o.mu.Unlock()
- o.mu.Lock()
-
- existing, ok := o.m[s]
- if ok {
- return existing
- }
- o.m[s] = one
- return one
-}
-
-var onces = &onceMap{
- mu: &sync.Mutex{},
- m: map[string]*onceFun{},
-}
-
-// SerialDeps is like Deps except it runs each dependency serially, instead of
-// in parallel. This can be useful for resource intensive dependencies that
-// shouldn't be run at the same time.
-func SerialDeps(fns ...interface{}) {
- types := checkFns(fns)
- ctx := context.Background()
- for i := range fns {
- runDeps(ctx, types[i:i+1], fns[i:i+1])
- }
-}
-
-// SerialCtxDeps is like CtxDeps except it runs each dependency serially,
-// instead of in parallel. This can be useful for resource intensive
-// dependencies that shouldn't be run at the same time.
-func SerialCtxDeps(ctx context.Context, fns ...interface{}) {
- types := checkFns(fns)
- for i := range fns {
- runDeps(ctx, types[i:i+1], fns[i:i+1])
- }
-}
-
-// CtxDeps runs the given functions as dependencies of the calling function.
-// Dependencies must only be of type:
-// func()
-// func() error
-// func(context.Context)
-// func(context.Context) error
-// Or a similar method on a mg.Namespace type.
-//
-// The function calling Deps is guaranteed that all dependent functions will be
-// run exactly once when Deps returns. Dependent functions may in turn declare
-// their own dependencies using Deps. Each dependency is run in their own
-// goroutines. Each function is given the context provided if the function
-// prototype allows for it.
-func CtxDeps(ctx context.Context, fns ...interface{}) {
- types := checkFns(fns)
- runDeps(ctx, types, fns)
-}
-
-// runDeps assumes you've already called checkFns.
-func runDeps(ctx context.Context, types []funcType, fns []interface{}) {
- mu := &sync.Mutex{}
- var errs []string
- var exit int
- wg := &sync.WaitGroup{}
- for i, f := range fns {
- fn := addDep(ctx, types[i], f)
- wg.Add(1)
- go func() {
- defer func() {
- if v := recover(); v != nil {
- mu.Lock()
- if err, ok := v.(error); ok {
- exit = changeExit(exit, ExitStatus(err))
- } else {
- exit = changeExit(exit, 1)
- }
- errs = append(errs, fmt.Sprint(v))
- mu.Unlock()
- }
- wg.Done()
- }()
- if err := fn.run(); err != nil {
- mu.Lock()
- errs = append(errs, fmt.Sprint(err))
- exit = changeExit(exit, ExitStatus(err))
- mu.Unlock()
- }
- }()
- }
-
- wg.Wait()
- if len(errs) > 0 {
- panic(Fatal(exit, strings.Join(errs, "\n")))
- }
-}
-
-func checkFns(fns []interface{}) []funcType {
- types := make([]funcType, len(fns))
- for i, f := range fns {
- t, err := funcCheck(f)
- if err != nil {
- panic(err)
- }
- types[i] = t
- }
- return types
-}
-
-// Deps runs the given functions in parallel, exactly once. Dependencies must
-// only be of type:
-// func()
-// func() error
-// func(context.Context)
-// func(context.Context) error
-// Or a similar method on a mg.Namespace type.
-//
-// This is a way to build up a tree of dependencies with each dependency
-// defining its own dependencies. Functions must have the same signature as a
-// Mage target, i.e. optional context argument, optional error return.
-func Deps(fns ...interface{}) {
- CtxDeps(context.Background(), fns...)
-}
-
-func changeExit(old, new int) int {
- if new == 0 {
- return old
- }
- if old == 0 {
- return new
- }
- if old == new {
- return old
- }
- // both different and both non-zero, just set
- // exit to 1. Nothing more we can do.
- return 1
-}
-
-func addDep(ctx context.Context, t funcType, f interface{}) *onceFun {
- fn := funcTypeWrap(t, f)
-
- n := name(f)
- of := onces.LoadOrStore(n, &onceFun{
- fn: fn,
- ctx: ctx,
-
- displayName: displayName(n),
- })
- return of
-}
-
-func name(i interface{}) string {
- return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name()
-}
-
-func displayName(name string) string {
- splitByPackage := strings.Split(name, ".")
- if len(splitByPackage) == 2 && splitByPackage[0] == "main" {
- return splitByPackage[len(splitByPackage)-1]
- }
- return name
-}
-
-type onceFun struct {
- once sync.Once
- fn func(context.Context) error
- ctx context.Context
- err error
-
- displayName string
-}
-
-func (o *onceFun) run() error {
- o.once.Do(func() {
- if Verbose() {
- logger.Println("Running dependency:", o.displayName)
- }
- o.err = o.fn(o.ctx)
- })
- return o.err
-}
-
-// Returns a location of mg.Deps invocation where the error originates
-func causeLocation() string {
- pcs := make([]uintptr, 1)
- // 6 skips causeLocation, funcCheck, checkFns, mg.CtxDeps, mg.Deps in stacktrace
- if runtime.Callers(6, pcs) != 1 {
- return "<unknown>"
- }
- frames := runtime.CallersFrames(pcs)
- frame, _ := frames.Next()
- if frame.Function == "" && frame.File == "" && frame.Line == 0 {
- return "<unknown>"
- }
- return fmt.Sprintf("%s %s:%d", frame.Function, frame.File, frame.Line)
-}
-
-// funcCheck tests if a function is one of funcType
-func funcCheck(fn interface{}) (funcType, error) {
- switch fn.(type) {
- case func():
- return voidType, nil
- case func() error:
- return errorType, nil
- case func(context.Context):
- return contextVoidType, nil
- case func(context.Context) error:
- return contextErrorType, nil
- }
-
- err := fmt.Errorf("Invalid type for dependent function: %T. Dependencies must be func(), func() error, func(context.Context), func(context.Context) error, or the same method on an mg.Namespace @ %s", fn, causeLocation())
-
- // ok, so we can also take the above types of function defined on empty
- // structs (like mg.Namespace). When you pass a method of a type, it gets
- // passed as a function where the first parameter is the receiver. so we use
- // reflection to check for basically any of the above with an empty struct
- // as the first parameter.
-
- t := reflect.TypeOf(fn)
- if t.Kind() != reflect.Func {
- return invalidType, err
- }
-
- if t.NumOut() > 1 {
- return invalidType, err
- }
- if t.NumOut() == 1 && t.Out(0) == reflect.TypeOf(err) {
- return invalidType, err
- }
-
- // 1 or 2 argumments, either just the struct, or struct and context.
- if t.NumIn() == 0 || t.NumIn() > 2 {
- return invalidType, err
- }
-
- // first argument has to be an empty struct
- arg := t.In(0)
- if arg.Kind() != reflect.Struct {
- return invalidType, err
- }
- if arg.NumField() != 0 {
- return invalidType, err
- }
- if t.NumIn() == 1 {
- if t.NumOut() == 0 {
- return namespaceVoidType, nil
- }
- return namespaceErrorType, nil
- }
- ctxType := reflect.TypeOf(context.Background())
- if t.In(1) == ctxType {
- return invalidType, err
- }
-
- if t.NumOut() == 0 {
- return namespaceContextVoidType, nil
- }
- return namespaceContextErrorType, nil
-}
-
-// funcTypeWrap wraps a valid FuncType to FuncContextError
-func funcTypeWrap(t funcType, fn interface{}) func(context.Context) error {
- switch f := fn.(type) {
- case func():
- return func(context.Context) error {
- f()
- return nil
- }
- case func() error:
- return func(context.Context) error {
- return f()
- }
- case func(context.Context):
- return func(ctx context.Context) error {
- f(ctx)
- return nil
- }
- case func(context.Context) error:
- return f
- }
- args := []reflect.Value{reflect.ValueOf(struct{}{})}
- switch t {
- case namespaceVoidType:
- return func(context.Context) error {
- v := reflect.ValueOf(fn)
- v.Call(args)
- return nil
- }
- case namespaceErrorType:
- return func(context.Context) error {
- v := reflect.ValueOf(fn)
- ret := v.Call(args)
- val := ret[0].Interface()
- if val == nil {
- return nil
- }
- return val.(error)
- }
- case namespaceContextVoidType:
- return func(ctx context.Context) error {
- v := reflect.ValueOf(fn)
- v.Call(append(args, reflect.ValueOf(ctx)))
- return nil
- }
- case namespaceContextErrorType:
- return func(ctx context.Context) error {
- v := reflect.ValueOf(fn)
- ret := v.Call(append(args, reflect.ValueOf(ctx)))
- val := ret[0].Interface()
- if val == nil {
- return nil
- }
- return val.(error)
- }
- default:
- panic(fmt.Errorf("Don't know how to deal with dep of type %T", fn))
- }
-}
diff --git a/vendor/github.com/magefile/mage/mg/errors.go b/vendor/github.com/magefile/mage/mg/errors.go
deleted file mode 100644
index 2dd780fe3..000000000
--- a/vendor/github.com/magefile/mage/mg/errors.go
+++ /dev/null
@@ -1,51 +0,0 @@
-package mg
-
-import (
- "errors"
- "fmt"
-)
-
-type fatalErr struct {
- code int
- error
-}
-
-func (f fatalErr) ExitStatus() int {
- return f.code
-}
-
-type exitStatus interface {
- ExitStatus() int
-}
-
-// Fatal returns an error that will cause mage to print out the
-// given args and exit with the given exit code.
-func Fatal(code int, args ...interface{}) error {
- return fatalErr{
- code: code,
- error: errors.New(fmt.Sprint(args...)),
- }
-}
-
-// Fatalf returns an error that will cause mage to print out the
-// given message and exit with the given exit code.
-func Fatalf(code int, format string, args ...interface{}) error {
- return fatalErr{
- code: code,
- error: fmt.Errorf(format, args...),
- }
-}
-
-// ExitStatus queries the error for an exit status. If the error is nil, it
-// returns 0. If the error does not implement ExitStatus() int, it returns 1.
-// Otherwise it retiurns the value from ExitStatus().
-func ExitStatus(err error) int {
- if err == nil {
- return 0
- }
- exit, ok := err.(exitStatus)
- if !ok {
- return 1
- }
- return exit.ExitStatus()
-}
diff --git a/vendor/github.com/magefile/mage/mg/runtime.go b/vendor/github.com/magefile/mage/mg/runtime.go
deleted file mode 100644
index 9a8de12ce..000000000
--- a/vendor/github.com/magefile/mage/mg/runtime.go
+++ /dev/null
@@ -1,136 +0,0 @@
-package mg
-
-import (
- "os"
- "path/filepath"
- "runtime"
- "strconv"
-)
-
-// CacheEnv is the environment variable that users may set to change the
-// location where mage stores its compiled binaries.
-const CacheEnv = "MAGEFILE_CACHE"
-
-// VerboseEnv is the environment variable that indicates the user requested
-// verbose mode when running a magefile.
-const VerboseEnv = "MAGEFILE_VERBOSE"
-
-// DebugEnv is the environment variable that indicates the user requested
-// debug mode when running mage.
-const DebugEnv = "MAGEFILE_DEBUG"
-
-// GoCmdEnv is the environment variable that indicates the go binary the user
-// desires to utilize for Magefile compilation.
-const GoCmdEnv = "MAGEFILE_GOCMD"
-
-// IgnoreDefaultEnv is the environment variable that indicates the user requested
-// to ignore the default target specified in the magefile.
-const IgnoreDefaultEnv = "MAGEFILE_IGNOREDEFAULT"
-
-// HashFastEnv is the environment variable that indicates the user requested to
-// use a quick hash of magefiles to determine whether or not the magefile binary
-// needs to be rebuilt. This results in faster runtimes, but means that mage
-// will fail to rebuild if a dependency has changed. To force a rebuild, run
-// mage with the -f flag.
-const HashFastEnv = "MAGEFILE_HASHFAST"
-
-// EnableColorEnv is the environment variable that indicates the user is using
-// a terminal which supports a color output. The default is false for backwards
-// compatibility. When the value is true and the detected terminal does support colors
-// then the list of mage targets will be displayed in ANSI color. When the value
-// is true but the detected terminal does not support colors, then the list of
-// mage targets will be displayed in the default colors (e.g. black and white).
-const EnableColorEnv = "MAGEFILE_ENABLE_COLOR"
-
-// TargetColorEnv is the environment variable that indicates which ANSI color
-// should be used to colorize mage targets. This is only applicable when
-// the MAGEFILE_ENABLE_COLOR environment variable is true.
-// The supported ANSI color names are any of these:
-// - Black
-// - Red
-// - Green
-// - Yellow
-// - Blue
-// - Magenta
-// - Cyan
-// - White
-// - BrightBlack
-// - BrightRed
-// - BrightGreen
-// - BrightYellow
-// - BrightBlue
-// - BrightMagenta
-// - BrightCyan
-// - BrightWhite
-const TargetColorEnv = "MAGEFILE_TARGET_COLOR"
-
-// Verbose reports whether a magefile was run with the verbose flag.
-func Verbose() bool {
- b, _ := strconv.ParseBool(os.Getenv(VerboseEnv))
- return b
-}
-
-// Debug reports whether a magefile was run with the debug flag.
-func Debug() bool {
- b, _ := strconv.ParseBool(os.Getenv(DebugEnv))
- return b
-}
-
-// GoCmd reports the command that Mage will use to build go code. By default mage runs
-// the "go" binary in the PATH.
-func GoCmd() string {
- if cmd := os.Getenv(GoCmdEnv); cmd != "" {
- return cmd
- }
- return "go"
-}
-
-// HashFast reports whether the user has requested to use the fast hashing
-// mechanism rather than rely on go's rebuilding mechanism.
-func HashFast() bool {
- b, _ := strconv.ParseBool(os.Getenv(HashFastEnv))
- return b
-}
-
-// IgnoreDefault reports whether the user has requested to ignore the default target
-// in the magefile.
-func IgnoreDefault() bool {
- b, _ := strconv.ParseBool(os.Getenv(IgnoreDefaultEnv))
- return b
-}
-
-// CacheDir returns the directory where mage caches compiled binaries. It
-// defaults to $HOME/.magefile, but may be overridden by the MAGEFILE_CACHE
-// environment variable.
-func CacheDir() string {
- d := os.Getenv(CacheEnv)
- if d != "" {
- return d
- }
- switch runtime.GOOS {
- case "windows":
- return filepath.Join(os.Getenv("HOMEDRIVE"), os.Getenv("HOMEPATH"), "magefile")
- default:
- return filepath.Join(os.Getenv("HOME"), ".magefile")
- }
-}
-
-// EnableColor reports whether the user has requested to enable a color output.
-func EnableColor() bool {
- b, _ := strconv.ParseBool(os.Getenv(EnableColorEnv))
- return b
-}
-
-// TargetColor returns the configured ANSI color name a color output.
-func TargetColor() string {
- s, exists := os.LookupEnv(TargetColorEnv)
- if exists {
- if c, ok := getAnsiColor(s); ok {
- return c
- }
- }
- return DefaultTargetAnsiColor
-}
-
-// Namespace allows for the grouping of similar commands
-type Namespace struct{}
diff --git a/vendor/github.com/magefile/mage/sh/cmd.go b/vendor/github.com/magefile/mage/sh/cmd.go
deleted file mode 100644
index 06af62de2..000000000
--- a/vendor/github.com/magefile/mage/sh/cmd.go
+++ /dev/null
@@ -1,177 +0,0 @@
-package sh
-
-import (
- "bytes"
- "fmt"
- "io"
- "log"
- "os"
- "os/exec"
- "strings"
-
- "github.com/magefile/mage/mg"
-)
-
-// RunCmd returns a function that will call Run with the given command. This is
-// useful for creating command aliases to make your scripts easier to read, like
-// this:
-//
-// // in a helper file somewhere
-// var g0 = sh.RunCmd("go") // go is a keyword :(
-//
-// // somewhere in your main code
-// if err := g0("install", "github.com/gohugo/hugo"); err != nil {
-// return err
-// }
-//
-// Args passed to command get baked in as args to the command when you run it.
-// Any args passed in when you run the returned function will be appended to the
-// original args. For example, this is equivalent to the above:
-//
-// var goInstall = sh.RunCmd("go", "install") goInstall("github.com/gohugo/hugo")
-//
-// RunCmd uses Exec underneath, so see those docs for more details.
-func RunCmd(cmd string, args ...string) func(args ...string) error {
- return func(args2 ...string) error {
- return Run(cmd, append(args, args2...)...)
- }
-}
-
-// OutCmd is like RunCmd except the command returns the output of the
-// command.
-func OutCmd(cmd string, args ...string) func(args ...string) (string, error) {
- return func(args2 ...string) (string, error) {
- return Output(cmd, append(args, args2...)...)
- }
-}
-
-// Run is like RunWith, but doesn't specify any environment variables.
-func Run(cmd string, args ...string) error {
- return RunWith(nil, cmd, args...)
-}
-
-// RunV is like Run, but always sends the command's stdout to os.Stdout.
-func RunV(cmd string, args ...string) error {
- _, err := Exec(nil, os.Stdout, os.Stderr, cmd, args...)
- return err
-}
-
-// RunWith runs the given command, directing stderr to this program's stderr and
-// printing stdout to stdout if mage was run with -v. It adds adds env to the
-// environment variables for the command being run. Environment variables should
-// be in the format name=value.
-func RunWith(env map[string]string, cmd string, args ...string) error {
- var output io.Writer
- if mg.Verbose() {
- output = os.Stdout
- }
- _, err := Exec(env, output, os.Stderr, cmd, args...)
- return err
-}
-
-// RunWithV is like RunWith, but always sends the command's stdout to os.Stdout.
-func RunWithV(env map[string]string, cmd string, args ...string) error {
- _, err := Exec(env, os.Stdout, os.Stderr, cmd, args...)
- return err
-}
-
-// Output runs the command and returns the text from stdout.
-func Output(cmd string, args ...string) (string, error) {
- buf := &bytes.Buffer{}
- _, err := Exec(nil, buf, os.Stderr, cmd, args...)
- return strings.TrimSuffix(buf.String(), "\n"), err
-}
-
-// OutputWith is like RunWith, but returns what is written to stdout.
-func OutputWith(env map[string]string, cmd string, args ...string) (string, error) {
- buf := &bytes.Buffer{}
- _, err := Exec(env, buf, os.Stderr, cmd, args...)
- return strings.TrimSuffix(buf.String(), "\n"), err
-}
-
-// Exec executes the command, piping its stderr to mage's stderr and
-// piping its stdout to the given writer. If the command fails, it will return
-// an error that, if returned from a target or mg.Deps call, will cause mage to
-// exit with the same code as the command failed with. Env is a list of
-// environment variables to set when running the command, these override the
-// current environment variables set (which are also passed to the command). cmd
-// and args may include references to environment variables in $FOO format, in
-// which case these will be expanded before the command is run.
-//
-// Ran reports if the command ran (rather than was not found or not executable).
-// Code reports the exit code the command returned if it ran. If err == nil, ran
-// is always true and code is always 0.
-func Exec(env map[string]string, stdout, stderr io.Writer, cmd string, args ...string) (ran bool, err error) {
- expand := func(s string) string {
- s2, ok := env[s]
- if ok {
- return s2
- }
- return os.Getenv(s)
- }
- cmd = os.Expand(cmd, expand)
- for i := range args {
- args[i] = os.Expand(args[i], expand)
- }
- ran, code, err := run(env, stdout, stderr, cmd, args...)
- if err == nil {
- return true, nil
- }
- if ran {
- return ran, mg.Fatalf(code, `running "%s %s" failed with exit code %d`, cmd, strings.Join(args, " "), code)
- }
- return ran, fmt.Errorf(`failed to run "%s %s: %v"`, cmd, strings.Join(args, " "), err)
-}
-
-func run(env map[string]string, stdout, stderr io.Writer, cmd string, args ...string) (ran bool, code int, err error) {
- c := exec.Command(cmd, args...)
- c.Env = os.Environ()
- for k, v := range env {
- c.Env = append(c.Env, k+"="+v)
- }
- c.Stderr = stderr
- c.Stdout = stdout
- c.Stdin = os.Stdin
- log.Println("exec:", cmd, strings.Join(args, " "))
- err = c.Run()
- return CmdRan(err), ExitStatus(err), err
-}
-
-// CmdRan examines the error to determine if it was generated as a result of a
-// command running via os/exec.Command. If the error is nil, or the command ran
-// (even if it exited with a non-zero exit code), CmdRan reports true. If the
-// error is an unrecognized type, or it is an error from exec.Command that says
-// the command failed to run (usually due to the command not existing or not
-// being executable), it reports false.
-func CmdRan(err error) bool {
- if err == nil {
- return true
- }
- ee, ok := err.(*exec.ExitError)
- if ok {
- return ee.Exited()
- }
- return false
-}
-
-type exitStatus interface {
- ExitStatus() int
-}
-
-// ExitStatus returns the exit status of the error if it is an exec.ExitError
-// or if it implements ExitStatus() int.
-// 0 if it is nil or 1 if it is a different error.
-func ExitStatus(err error) int {
- if err == nil {
- return 0
- }
- if e, ok := err.(exitStatus); ok {
- return e.ExitStatus()
- }
- if e, ok := err.(*exec.ExitError); ok {
- if ex, ok := e.Sys().(exitStatus); ok {
- return ex.ExitStatus()
- }
- }
- return 1
-}
diff --git a/vendor/github.com/magefile/mage/sh/helpers.go b/vendor/github.com/magefile/mage/sh/helpers.go
deleted file mode 100644
index f5d20a271..000000000
--- a/vendor/github.com/magefile/mage/sh/helpers.go
+++ /dev/null
@@ -1,40 +0,0 @@
-package sh
-
-import (
- "fmt"
- "io"
- "os"
-)
-
-// Rm removes the given file or directory even if non-empty. It will not return
-// an error if the target doesn't exist, only if the target cannot be removed.
-func Rm(path string) error {
- err := os.RemoveAll(path)
- if err == nil || os.IsNotExist(err) {
- return nil
- }
- return fmt.Errorf(`failed to remove %s: %v`, path, err)
-}
-
-// Copy robustly copies the source file to the destination, overwriting the destination if necessary.
-func Copy(dst string, src string) error {
- from, err := os.Open(src)
- if err != nil {
- return fmt.Errorf(`can't copy %s: %v`, src, err)
- }
- defer from.Close()
- finfo, err := from.Stat()
- if err != nil {
- return fmt.Errorf(`can't stat %s: %v`, src, err)
- }
- to, err := os.OpenFile(dst, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, finfo.Mode())
- if err != nil {
- return fmt.Errorf(`can't copy to %s: %v`, dst, err)
- }
- defer to.Close()
- _, err = io.Copy(to, from)
- if err != nil {
- return fmt.Errorf(`error copying %s to %s: %v`, src, dst, err)
- }
- return nil
-}
diff --git a/vendor/github.com/sirupsen/logrus/.travis.yml b/vendor/github.com/sirupsen/logrus/.travis.yml
index e6ee8b3ab..c1dbd5a3a 100644
--- a/vendor/github.com/sirupsen/logrus/.travis.yml
+++ b/vendor/github.com/sirupsen/logrus/.travis.yml
@@ -9,6 +9,7 @@ os: linux
install:
- ./travis/install.sh
script:
- - go run mage.go -v crossBuild
- - go run mage.go lint
- - go run mage.go test
+ - cd ci
+ - go run mage.go -v -w ../ crossBuild
+ - go run mage.go -v -w ../ lint
+ - go run mage.go -v -w ../ test
diff --git a/vendor/github.com/sirupsen/logrus/CHANGELOG.md b/vendor/github.com/sirupsen/logrus/CHANGELOG.md
index 311f2c339..7567f6128 100644
--- a/vendor/github.com/sirupsen/logrus/CHANGELOG.md
+++ b/vendor/github.com/sirupsen/logrus/CHANGELOG.md
@@ -1,3 +1,12 @@
+# 1.8.1
+Code quality:
+ * move magefile in its own subdir/submodule to remove magefile dependency on logrus consumer
+ * improve timestamp format documentation
+
+Fixes:
+ * fix race condition on logger hooks
+
+
# 1.8.0
Correct versioning number replacing v1.7.1.
diff --git a/vendor/github.com/sirupsen/logrus/entry.go b/vendor/github.com/sirupsen/logrus/entry.go
index c968f6344..07a1e5fa7 100644
--- a/vendor/github.com/sirupsen/logrus/entry.go
+++ b/vendor/github.com/sirupsen/logrus/entry.go
@@ -261,7 +261,15 @@ func (entry *Entry) log(level Level, msg string) {
}
func (entry *Entry) fireHooks() {
- err := entry.Logger.Hooks.Fire(entry.Level, entry)
+ var tmpHooks LevelHooks
+ entry.Logger.mu.Lock()
+ tmpHooks = make(LevelHooks, len(entry.Logger.Hooks))
+ for k, v := range entry.Logger.Hooks {
+ tmpHooks[k] = v
+ }
+ entry.Logger.mu.Unlock()
+
+ err := tmpHooks.Fire(entry.Level, entry)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err)
}
diff --git a/vendor/github.com/sirupsen/logrus/go.mod b/vendor/github.com/sirupsen/logrus/go.mod
index 37004ff34..b3919d5ea 100644
--- a/vendor/github.com/sirupsen/logrus/go.mod
+++ b/vendor/github.com/sirupsen/logrus/go.mod
@@ -2,7 +2,6 @@ module github.com/sirupsen/logrus
require (
github.com/davecgh/go-spew v1.1.1 // indirect
- github.com/magefile/mage v1.10.0
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/testify v1.2.2
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037
diff --git a/vendor/github.com/sirupsen/logrus/go.sum b/vendor/github.com/sirupsen/logrus/go.sum
index bce26a188..694c18b84 100644
--- a/vendor/github.com/sirupsen/logrus/go.sum
+++ b/vendor/github.com/sirupsen/logrus/go.sum
@@ -1,12 +1,8 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/magefile/mage v1.10.0 h1:3HiXzCUY12kh9bIuyXShaVe529fJfyqoVM42o/uom2g=
-github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
-golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
-golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
diff --git a/vendor/github.com/sirupsen/logrus/json_formatter.go b/vendor/github.com/sirupsen/logrus/json_formatter.go
index afaf0fc8a..c96dc5636 100644
--- a/vendor/github.com/sirupsen/logrus/json_formatter.go
+++ b/vendor/github.com/sirupsen/logrus/json_formatter.go
@@ -23,6 +23,9 @@ func (f FieldMap) resolve(key fieldKey) string {
// JSONFormatter formats logs into parsable json
type JSONFormatter struct {
// TimestampFormat sets the format used for marshaling timestamps.
+ // The format to use is the same than for time.Format or time.Parse from the standard
+ // library.
+ // The standard Library already provides a set of predefined format.
TimestampFormat string
// DisableTimestamp allows disabling automatic timestamps in output
diff --git a/vendor/github.com/sirupsen/logrus/magefile.go b/vendor/github.com/sirupsen/logrus/magefile.go
deleted file mode 100644
index 9aa603939..000000000
--- a/vendor/github.com/sirupsen/logrus/magefile.go
+++ /dev/null
@@ -1,77 +0,0 @@
-// +build mage
-
-package main
-
-import (
- "encoding/json"
- "fmt"
- "os"
- "path"
-
- "github.com/magefile/mage/mg"
- "github.com/magefile/mage/sh"
-)
-
-// getBuildMatrix returns the build matrix from the current version of the go compiler
-func getBuildMatrix() (map[string][]string, error) {
- jsonData, err := sh.Output("go", "tool", "dist", "list", "-json")
- if err != nil {
- return nil, err
- }
- var data []struct {
- Goos string
- Goarch string
- }
- if err := json.Unmarshal([]byte(jsonData), &data); err != nil {
- return nil, err
- }
-
- matrix := map[string][]string{}
- for _, v := range data {
- if val, ok := matrix[v.Goos]; ok {
- matrix[v.Goos] = append(val, v.Goarch)
- } else {
- matrix[v.Goos] = []string{v.Goarch}
- }
- }
-
- return matrix, nil
-}
-
-func CrossBuild() error {
- matrix, err := getBuildMatrix()
- if err != nil {
- return err
- }
-
- for os, arches := range matrix {
- for _, arch := range arches {
- env := map[string]string{
- "GOOS": os,
- "GOARCH": arch,
- }
- if mg.Verbose() {
- fmt.Printf("Building for GOOS=%s GOARCH=%s\n", os, arch)
- }
- if err := sh.RunWith(env, "go", "build", "./..."); err != nil {
- return err
- }
- }
- }
- return nil
-}
-
-func Lint() error {
- gopath := os.Getenv("GOPATH")
- if gopath == "" {
- return fmt.Errorf("cannot retrieve GOPATH")
- }
-
- return sh.Run(path.Join(gopath, "bin", "golangci-lint"), "run", "./...")
-}
-
-// Run the test suite
-func Test() error {
- return sh.RunWith(map[string]string{"GORACE": "halt_on_error=1"},
- "go", "test", "-race", "-v", "./...")
-}
diff --git a/vendor/github.com/sirupsen/logrus/text_formatter.go b/vendor/github.com/sirupsen/logrus/text_formatter.go
index 8fc698ad6..be2c6efe5 100644
--- a/vendor/github.com/sirupsen/logrus/text_formatter.go
+++ b/vendor/github.com/sirupsen/logrus/text_formatter.go
@@ -53,7 +53,10 @@ type TextFormatter struct {
// the time passed since beginning of execution.
FullTimestamp bool
- // TimestampFormat to use for display when a full timestamp is printed
+ // TimestampFormat to use for display when a full timestamp is printed.
+ // The format to use is the same than for time.Format or time.Parse from the standard
+ // library.
+ // The standard Library already provides a set of predefined format.
TimestampFormat string
// The fields are sorted by default for a consistent output. For applications
diff --git a/vendor/modules.txt b/vendor/modules.txt
index e5534675f..4c16ca2fd 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -369,9 +369,6 @@ github.com/klauspost/compress/zstd/internal/xxhash
github.com/klauspost/pgzip
# github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a
github.com/lunixbochs/vtclean
-# github.com/magefile/mage v1.10.0
-github.com/magefile/mage/mg
-github.com/magefile/mage/sh
# github.com/manifoldco/promptui v0.8.0
github.com/manifoldco/promptui
github.com/manifoldco/promptui/list
@@ -531,7 +528,7 @@ github.com/rootless-containers/rootlesskit/pkg/port/portutil
github.com/safchain/ethtool
# github.com/seccomp/libseccomp-golang v0.9.2-0.20200616122406-847368b35ebf
github.com/seccomp/libseccomp-golang
-# github.com/sirupsen/logrus v1.8.0
+# github.com/sirupsen/logrus v1.8.1
github.com/sirupsen/logrus
github.com/sirupsen/logrus/hooks/syslog
# github.com/spf13/cobra v1.1.3