summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/api/handlers/compat/containers.go31
-rw-r--r--pkg/api/handlers/compat/containers_prune.go62
-rw-r--r--pkg/api/handlers/compat/images.go45
-rw-r--r--pkg/api/handlers/compat/images_prune.go75
-rw-r--r--pkg/api/handlers/compat/unsupported.go5
-rw-r--r--pkg/api/handlers/compat/volumes.go60
-rw-r--r--pkg/api/handlers/libpod/containers.go1
-rw-r--r--pkg/api/handlers/libpod/images.go22
-rw-r--r--pkg/api/handlers/libpod/images_pull.go4
-rw-r--r--pkg/api/handlers/libpod/pods.go11
-rw-r--r--pkg/api/handlers/libpod/system.go21
-rw-r--r--pkg/api/handlers/libpod/volumes.go63
-rw-r--r--pkg/api/handlers/utils/errors.go4
-rw-r--r--pkg/api/handlers/utils/pods.go87
-rw-r--r--pkg/api/server/docs.go2
-rw-r--r--pkg/api/server/register_containers.go62
-rw-r--r--pkg/api/server/register_images.go4
-rw-r--r--pkg/api/server/register_networks.go13
-rw-r--r--pkg/api/server/swagger.go32
-rw-r--r--pkg/bindings/containers/containers.go5
-rw-r--r--pkg/bindings/containers/rename.go28
-rw-r--r--pkg/bindings/containers/types.go7
-rw-r--r--pkg/bindings/containers/types_attach_options.go4
-rw-r--r--pkg/bindings/containers/types_checkpoint_options.go4
-rw-r--r--pkg/bindings/containers/types_commit_options.go4
-rw-r--r--pkg/bindings/containers/types_create_options.go4
-rw-r--r--pkg/bindings/containers/types_diff_options.go4
-rw-r--r--pkg/bindings/containers/types_execinspect_options.go4
-rw-r--r--pkg/bindings/containers/types_execstart_options.go4
-rw-r--r--pkg/bindings/containers/types_execstartandattach_options.go4
-rw-r--r--pkg/bindings/containers/types_export_options.go4
-rw-r--r--pkg/bindings/containers/types_healthcheck_options.go4
-rw-r--r--pkg/bindings/containers/types_init_options.go4
-rw-r--r--pkg/bindings/containers/types_inspect_options.go4
-rw-r--r--pkg/bindings/containers/types_kill_options.go4
-rw-r--r--pkg/bindings/containers/types_list_options.go2
-rw-r--r--pkg/bindings/containers/types_log_options.go4
-rw-r--r--pkg/bindings/containers/types_mount_options.go4
-rw-r--r--pkg/bindings/containers/types_mountedcontainerpaths_options.go4
-rw-r--r--pkg/bindings/containers/types_pause_options.go4
-rw-r--r--pkg/bindings/containers/types_prune_options.go4
-rw-r--r--pkg/bindings/containers/types_remove_options.go4
-rw-r--r--pkg/bindings/containers/types_rename_options.go104
-rw-r--r--pkg/bindings/containers/types_resizeexectty_options.go4
-rw-r--r--pkg/bindings/containers/types_resizetty_options.go4
-rw-r--r--pkg/bindings/containers/types_restart_options.go4
-rw-r--r--pkg/bindings/containers/types_restore_options.go4
-rw-r--r--pkg/bindings/containers/types_shouldrestart_options.go4
-rw-r--r--pkg/bindings/containers/types_start_options.go4
-rw-r--r--pkg/bindings/containers/types_stats_options.go4
-rw-r--r--pkg/bindings/containers/types_stop_options.go4
-rw-r--r--pkg/bindings/containers/types_top_options.go4
-rw-r--r--pkg/bindings/containers/types_unmount_options.go4
-rw-r--r--pkg/bindings/containers/types_unpause_options.go4
-rw-r--r--pkg/bindings/containers/types_wait_options.go4
-rw-r--r--pkg/bindings/errors.go6
-rw-r--r--pkg/bindings/generate/types_kube_options.go4
-rw-r--r--pkg/bindings/generate/types_systemd_options.go4
-rw-r--r--pkg/bindings/generator/generator.go6
-rw-r--r--pkg/bindings/images/images.go19
-rw-r--r--pkg/bindings/images/types_diff_options.go4
-rw-r--r--pkg/bindings/images/types_export_options.go4
-rw-r--r--pkg/bindings/images/types_get_options.go4
-rw-r--r--pkg/bindings/images/types_history_options.go4
-rw-r--r--pkg/bindings/images/types_import_options.go4
-rw-r--r--pkg/bindings/images/types_list_options.go4
-rw-r--r--pkg/bindings/images/types_load_options.go4
-rw-r--r--pkg/bindings/images/types_prune_options.go4
-rw-r--r--pkg/bindings/images/types_pull_options.go4
-rw-r--r--pkg/bindings/images/types_push_options.go4
-rw-r--r--pkg/bindings/images/types_remove_options.go4
-rw-r--r--pkg/bindings/images/types_search_options.go4
-rw-r--r--pkg/bindings/images/types_tag_options.go4
-rw-r--r--pkg/bindings/images/types_tree_options.go4
-rw-r--r--pkg/bindings/images/types_untag_options.go4
-rw-r--r--pkg/bindings/manifests/types_add_options.go4
-rw-r--r--pkg/bindings/manifests/types_create_options.go4
-rw-r--r--pkg/bindings/manifests/types_inspect_options.go4
-rw-r--r--pkg/bindings/manifests/types_push_options.go4
-rw-r--r--pkg/bindings/manifests/types_remove_options.go4
-rw-r--r--pkg/bindings/network/types_connect_options.go4
-rw-r--r--pkg/bindings/network/types_create_options.go8
-rw-r--r--pkg/bindings/network/types_disconnect_options.go4
-rw-r--r--pkg/bindings/network/types_inspect_options.go4
-rw-r--r--pkg/bindings/network/types_list_options.go4
-rw-r--r--pkg/bindings/network/types_remove_options.go4
-rw-r--r--pkg/bindings/play/types_kube_options.go4
-rw-r--r--pkg/bindings/pods/types_create_options.go4
-rw-r--r--pkg/bindings/pods/types_inspect_options.go4
-rw-r--r--pkg/bindings/pods/types_kill_options.go4
-rw-r--r--pkg/bindings/pods/types_list_options.go4
-rw-r--r--pkg/bindings/pods/types_pause_options.go4
-rw-r--r--pkg/bindings/pods/types_prune_options.go4
-rw-r--r--pkg/bindings/pods/types_remove_options.go4
-rw-r--r--pkg/bindings/pods/types_restart_options.go4
-rw-r--r--pkg/bindings/pods/types_start_options.go4
-rw-r--r--pkg/bindings/pods/types_stats_options.go4
-rw-r--r--pkg/bindings/pods/types_stop_options.go4
-rw-r--r--pkg/bindings/pods/types_top_options.go4
-rw-r--r--pkg/bindings/pods/types_unpause_options.go4
-rw-r--r--pkg/bindings/system/types_disk_options.go4
-rw-r--r--pkg/bindings/system/types_events_options.go4
-rw-r--r--pkg/bindings/system/types_info_options.go4
-rw-r--r--pkg/bindings/system/types_prune_options.go4
-rw-r--r--pkg/bindings/system/types_version_options.go4
-rw-r--r--pkg/bindings/test/common_test.go2
-rw-r--r--pkg/bindings/test/containers_test.go15
-rw-r--r--pkg/bindings/test/images_test.go17
-rw-r--r--pkg/bindings/test/system_test.go35
-rw-r--r--pkg/bindings/test/volumes_test.go3
-rw-r--r--pkg/bindings/volumes/types_create_options.go4
-rw-r--r--pkg/bindings/volumes/types_inspect_options.go4
-rw-r--r--pkg/bindings/volumes/types_list_options.go4
-rw-r--r--pkg/bindings/volumes/types_prune_options.go4
-rw-r--r--pkg/bindings/volumes/types_remove_options.go4
-rw-r--r--pkg/bindings/volumes/volumes.go5
-rw-r--r--pkg/checkpoint/checkpoint_restore.go29
-rw-r--r--pkg/domain/entities/container_ps.go2
-rw-r--r--pkg/domain/entities/containers.go18
-rw-r--r--pkg/domain/entities/engine_container.go6
-rw-r--r--pkg/domain/entities/engine_image.go3
-rw-r--r--pkg/domain/entities/images.go7
-rw-r--r--pkg/domain/entities/play.go3
-rw-r--r--pkg/domain/entities/pods.go25
-rw-r--r--pkg/domain/entities/reports/prune.go40
-rw-r--r--pkg/domain/entities/system.go10
-rw-r--r--pkg/domain/entities/types.go24
-rw-r--r--pkg/domain/entities/volumes.go40
-rw-r--r--pkg/domain/filters/containers.go22
-rw-r--r--pkg/domain/filters/pods.go26
-rw-r--r--pkg/domain/filters/volumes.go4
-rw-r--r--pkg/domain/infra/abi/containers.go60
-rw-r--r--pkg/domain/infra/abi/containers_stat.go17
-rw-r--r--pkg/domain/infra/abi/images.go31
-rw-r--r--pkg/domain/infra/abi/images_list.go5
-rw-r--r--pkg/domain/infra/abi/manifest.go3
-rw-r--r--pkg/domain/infra/abi/play.go17
-rw-r--r--pkg/domain/infra/abi/pods.go12
-rw-r--r--pkg/domain/infra/abi/pods_stats.go26
-rw-r--r--pkg/domain/infra/abi/system.go53
-rw-r--r--pkg/domain/infra/abi/volumes.go48
-rw-r--r--pkg/domain/infra/tunnel/containers.go10
-rw-r--r--pkg/domain/infra/tunnel/images.go31
-rw-r--r--pkg/domain/infra/tunnel/network.go3
-rw-r--r--pkg/domain/infra/tunnel/volumes.go6
-rw-r--r--pkg/errorhandling/errorhandling.go24
-rw-r--r--pkg/inspect/inspect.go4
-rw-r--r--pkg/netns/netns_linux.go4
-rw-r--r--pkg/ps/ps.go6
-rw-r--r--pkg/rootless/rootless.go153
-rw-r--r--pkg/rootless/rootless_test.go101
-rw-r--r--pkg/signal/signal_linux_mipsx.go2
-rw-r--r--pkg/specgen/generate/config_linux.go3
-rw-r--r--pkg/specgen/generate/container.go30
-rw-r--r--pkg/specgen/generate/kube/kube.go21
-rw-r--r--pkg/specgen/generate/kube/volume.go2
-rw-r--r--pkg/specgen/generate/namespaces.go7
-rw-r--r--pkg/specgen/generate/oci.go41
-rw-r--r--pkg/specgen/generate/security.go15
-rw-r--r--pkg/specgen/generate/storage.go8
-rw-r--r--pkg/specgen/generate/validate.go2
-rw-r--r--pkg/specgen/volumes.go2
-rw-r--r--pkg/systemd/generate/common.go32
-rw-r--r--pkg/systemd/generate/containers.go86
-rw-r--r--pkg/systemd/generate/containers_test.go308
-rw-r--r--pkg/systemd/generate/pods.go46
-rw-r--r--pkg/systemd/generate/pods_test.go124
167 files changed, 1808 insertions, 988 deletions
diff --git a/pkg/api/handlers/compat/containers.go b/pkg/api/handlers/compat/containers.go
index 0f89c859e..6e1945db1 100644
--- a/pkg/api/handlers/compat/containers.go
+++ b/pkg/api/handlers/compat/containers.go
@@ -465,3 +465,34 @@ func formatCapabilities(slice []string) {
slice[i] = strings.TrimPrefix(slice[i], "CAP_")
}
}
+
+func RenameContainer(w http.ResponseWriter, r *http.Request) {
+ runtime := r.Context().Value("runtime").(*libpod.Runtime)
+ decoder := r.Context().Value("decoder").(*schema.Decoder)
+
+ name := utils.GetName(r)
+ query := struct {
+ Name string `schema:"name"`
+ }{}
+ if err := decoder.Decode(&query, r.URL.Query()); err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
+ return
+ }
+
+ ctr, err := runtime.LookupContainer(name)
+ if err != nil {
+ utils.ContainerNotFound(w, name, err)
+ return
+ }
+
+ if _, err := runtime.RenameContainer(r.Context(), ctr, query.Name); err != nil {
+ if errors.Cause(err) == define.ErrPodExists || errors.Cause(err) == define.ErrCtrExists {
+ utils.Error(w, "Something went wrong.", http.StatusConflict, err)
+ return
+ }
+ utils.InternalServerError(w, err)
+ return
+ }
+
+ utils.WriteResponse(w, http.StatusNoContent, nil)
+}
diff --git a/pkg/api/handlers/compat/containers_prune.go b/pkg/api/handlers/compat/containers_prune.go
index a1e35dd97..7bba38475 100644
--- a/pkg/api/handlers/compat/containers_prune.go
+++ b/pkg/api/handlers/compat/containers_prune.go
@@ -1,22 +1,19 @@
package compat
import (
+ "bytes"
"net/http"
"github.com/containers/podman/v2/libpod"
+ "github.com/containers/podman/v2/pkg/api/handlers"
"github.com/containers/podman/v2/pkg/api/handlers/utils"
- "github.com/containers/podman/v2/pkg/domain/entities"
+ "github.com/containers/podman/v2/pkg/domain/entities/reports"
"github.com/containers/podman/v2/pkg/domain/filters"
- "github.com/docker/docker/api/types"
"github.com/gorilla/schema"
"github.com/pkg/errors"
)
func PruneContainers(w http.ResponseWriter, r *http.Request) {
- var (
- delContainers []string
- space int64
- )
runtime := r.Context().Value("runtime").(*libpod.Runtime)
decoder := r.Context().Value("decoder").(*schema.Decoder)
@@ -37,48 +34,45 @@ func PruneContainers(w http.ResponseWriter, r *http.Request) {
filterFuncs = append(filterFuncs, generatedFunc)
}
+ report, err := PruneContainersHelper(r, filterFuncs)
+ if err != nil {
+ utils.InternalServerError(w, err)
+ return
+ }
+
// Libpod response differs
if utils.IsLibpodRequest(r) {
- report, err := PruneContainersHelper(w, r, filterFuncs)
- if err != nil {
- utils.InternalServerError(w, err)
- return
- }
-
utils.WriteResponse(w, http.StatusOK, report)
return
}
- prunedContainers, pruneErrors, err := runtime.PruneContainers(filterFuncs)
- if err != nil {
- utils.InternalServerError(w, err)
- return
- }
- for ctrID, size := range prunedContainers {
- if pruneErrors[ctrID] == nil {
- space += size
- delContainers = append(delContainers, ctrID)
+ var payload handlers.ContainersPruneReport
+ var errorMsg bytes.Buffer
+ for _, pr := range report {
+ if pr.Err != nil {
+ // Docker stops on first error vs. libpod which keeps going. Given API constraints, concatenate all errors
+ // and return that string.
+ errorMsg.WriteString(pr.Err.Error())
+ errorMsg.WriteString("; ")
+ continue
}
+ payload.ContainersDeleted = append(payload.ContainersDeleted, pr.Id)
+ payload.SpaceReclaimed += pr.Size
}
- report := types.ContainersPruneReport{
- ContainersDeleted: delContainers,
- SpaceReclaimed: uint64(space),
+ if errorMsg.Len() > 0 {
+ utils.InternalServerError(w, errors.New(errorMsg.String()))
+ return
}
- utils.WriteResponse(w, http.StatusOK, report)
+
+ utils.WriteResponse(w, http.StatusOK, payload)
}
-func PruneContainersHelper(w http.ResponseWriter, r *http.Request, filterFuncs []libpod.ContainerFilter) (
- *entities.ContainerPruneReport, error) {
+func PruneContainersHelper(r *http.Request, filterFuncs []libpod.ContainerFilter) ([]*reports.PruneReport, error) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
- prunedContainers, pruneErrors, err := runtime.PruneContainers(filterFuncs)
+
+ report, err := runtime.PruneContainers(filterFuncs)
if err != nil {
- utils.InternalServerError(w, err)
return nil, err
}
-
- report := &entities.ContainerPruneReport{
- Err: pruneErrors,
- ID: prunedContainers,
- }
return report, nil
}
diff --git a/pkg/api/handlers/compat/images.go b/pkg/api/handlers/compat/images.go
index dc72500e4..0ae0f3bcf 100644
--- a/pkg/api/handlers/compat/images.go
+++ b/pkg/api/handlers/compat/images.go
@@ -18,7 +18,6 @@ import (
"github.com/containers/podman/v2/pkg/api/handlers/utils"
"github.com/containers/podman/v2/pkg/auth"
"github.com/containers/podman/v2/pkg/domain/entities"
- "github.com/docker/docker/api/types"
"github.com/gorilla/schema"
"github.com/opencontainers/go-digest"
"github.com/pkg/errors"
@@ -74,50 +73,6 @@ func ExportImage(w http.ResponseWriter, r *http.Request) {
utils.WriteResponse(w, http.StatusOK, rdr)
}
-func PruneImages(w http.ResponseWriter, r *http.Request) {
- var (
- filters []string
- )
- decoder := r.Context().Value("decoder").(*schema.Decoder)
- runtime := r.Context().Value("runtime").(*libpod.Runtime)
-
- query := struct {
- All bool
- Filters map[string][]string `schema:"filters"`
- }{
- // This is where you can override the golang default value for one of fields
- }
-
- if err := decoder.Decode(&query, r.URL.Query()); err != nil {
- utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
- return
- }
-
- idr := []types.ImageDeleteResponseItem{}
- for k, v := range query.Filters {
- for _, val := range v {
- filters = append(filters, fmt.Sprintf("%s=%s", k, val))
- }
- }
- pruneCids, err := runtime.ImageRuntime().PruneImages(r.Context(), query.All, filters)
- if err != nil {
- utils.InternalServerError(w, err)
- return
- }
- for _, p := range pruneCids {
- idr = append(idr, types.ImageDeleteResponseItem{
- Deleted: p,
- })
- }
-
- // FIXME/TODO to do this exactly correct, pruneimages needs to return idrs and space-reclaimed, then we are golden
- ipr := types.ImagesPruneReport{
- ImagesDeleted: idr,
- SpaceReclaimed: 1, // TODO we cannot supply this right now
- }
- utils.WriteResponse(w, http.StatusOK, handlers.ImagesPruneReport{ImagesPruneReport: ipr})
-}
-
func CommitContainer(w http.ResponseWriter, r *http.Request) {
var (
destImage string
diff --git a/pkg/api/handlers/compat/images_prune.go b/pkg/api/handlers/compat/images_prune.go
new file mode 100644
index 000000000..c7e84804b
--- /dev/null
+++ b/pkg/api/handlers/compat/images_prune.go
@@ -0,0 +1,75 @@
+package compat
+
+import (
+ "bytes"
+ "fmt"
+ "net/http"
+
+ "github.com/containers/podman/v2/libpod"
+ "github.com/containers/podman/v2/pkg/api/handlers"
+ "github.com/containers/podman/v2/pkg/api/handlers/utils"
+ "github.com/docker/docker/api/types"
+ "github.com/gorilla/schema"
+ "github.com/pkg/errors"
+)
+
+func PruneImages(w http.ResponseWriter, r *http.Request) {
+ var (
+ filters []string
+ )
+ decoder := r.Context().Value("decoder").(*schema.Decoder)
+ runtime := r.Context().Value("runtime").(*libpod.Runtime)
+
+ query := struct {
+ All bool
+ Filters map[string][]string `schema:"filters"`
+ }{
+ // This is where you can override the golang default value for one of fields
+ }
+
+ if err := decoder.Decode(&query, r.URL.Query()); err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
+ return
+ }
+
+ for k, v := range query.Filters {
+ for _, val := range v {
+ filters = append(filters, fmt.Sprintf("%s=%s", k, val))
+ }
+ }
+ imagePruneReports, err := runtime.ImageRuntime().PruneImages(r.Context(), query.All, filters)
+ if err != nil {
+ utils.InternalServerError(w, err)
+ return
+ }
+
+ idr := make([]types.ImageDeleteResponseItem, len(imagePruneReports))
+ var reclaimedSpace uint64
+ var errorMsg bytes.Buffer
+ for _, p := range imagePruneReports {
+ if p.Err != nil {
+ // Docker stops on first error vs. libpod which keeps going. Given API constraints, concatenate all errors
+ // and return that string.
+ errorMsg.WriteString(p.Err.Error())
+ errorMsg.WriteString("; ")
+ continue
+ }
+
+ idr = append(idr, types.ImageDeleteResponseItem{
+ Deleted: p.Id,
+ })
+ reclaimedSpace = reclaimedSpace + p.Size
+ }
+ if errorMsg.Len() > 0 {
+ utils.InternalServerError(w, errors.New(errorMsg.String()))
+ return
+ }
+
+ payload := handlers.ImagesPruneReport{
+ ImagesPruneReport: types.ImagesPruneReport{
+ ImagesDeleted: idr,
+ SpaceReclaimed: reclaimedSpace,
+ },
+ }
+ utils.WriteResponse(w, http.StatusOK, payload)
+}
diff --git a/pkg/api/handlers/compat/unsupported.go b/pkg/api/handlers/compat/unsupported.go
index e5ff266f9..1c518690f 100644
--- a/pkg/api/handlers/compat/unsupported.go
+++ b/pkg/api/handlers/compat/unsupported.go
@@ -4,9 +4,8 @@ import (
"fmt"
"net/http"
- "github.com/containers/podman/v2/pkg/domain/entities"
-
"github.com/containers/podman/v2/pkg/api/handlers/utils"
+ "github.com/containers/podman/v2/pkg/errorhandling"
log "github.com/sirupsen/logrus"
)
@@ -14,5 +13,5 @@ func UnsupportedHandler(w http.ResponseWriter, r *http.Request) {
msg := fmt.Sprintf("Path %s is not supported", r.URL.Path)
log.Infof("Request Failed: %s", msg)
- utils.WriteJSON(w, http.StatusNotFound, entities.ErrorModel{Message: msg})
+ utils.WriteJSON(w, http.StatusNotFound, errorhandling.ErrorModel{Message: msg})
}
diff --git a/pkg/api/handlers/compat/volumes.go b/pkg/api/handlers/compat/volumes.go
index f49f06b17..82e70eb90 100644
--- a/pkg/api/handlers/compat/volumes.go
+++ b/pkg/api/handlers/compat/volumes.go
@@ -1,6 +1,7 @@
package compat
import (
+ "bytes"
"encoding/json"
"net/http"
"net/url"
@@ -8,6 +9,7 @@ import (
"github.com/containers/podman/v2/libpod"
"github.com/containers/podman/v2/libpod/define"
+ "github.com/containers/podman/v2/pkg/api/handlers"
"github.com/containers/podman/v2/pkg/api/handlers/utils"
"github.com/containers/podman/v2/pkg/domain/filters"
"github.com/containers/podman/v2/pkg/domain/infra/abi/parse"
@@ -56,10 +58,15 @@ func ListVolumes(w http.ResponseWriter, r *http.Request) {
}
volumeConfigs := make([]*docker_api_types.Volume, 0, len(vols))
for _, v := range vols {
+ mp, err := v.MountPoint()
+ if err != nil {
+ utils.InternalServerError(w, err)
+ return
+ }
config := docker_api_types.Volume{
Name: v.Name(),
Driver: v.Driver(),
- Mountpoint: v.MountPoint(),
+ Mountpoint: mp,
CreatedAt: v.CreatedTime().Format(time.RFC3339),
Labels: v.Labels(),
Scope: v.Scope(),
@@ -104,11 +111,16 @@ func CreateVolume(w http.ResponseWriter, r *http.Request) {
// if using the compat layer and the volume already exists, we
// must return a 201 with the same information as create
if existingVolume != nil && !utils.IsLibpodRequest(r) {
+ mp, err := existingVolume.MountPoint()
+ if err != nil {
+ utils.InternalServerError(w, err)
+ return
+ }
response := docker_api_types.Volume{
CreatedAt: existingVolume.CreatedTime().Format(time.RFC3339),
Driver: existingVolume.Driver(),
Labels: existingVolume.Labels(),
- Mountpoint: existingVolume.MountPoint(),
+ Mountpoint: mp,
Name: existingVolume.Name(),
Options: existingVolume.Options(),
Scope: existingVolume.Scope(),
@@ -144,10 +156,15 @@ func CreateVolume(w http.ResponseWriter, r *http.Request) {
utils.InternalServerError(w, err)
return
}
+ mp, err := vol.MountPoint()
+ if err != nil {
+ utils.InternalServerError(w, err)
+ return
+ }
volResponse := docker_api_types.Volume{
Name: config.Name,
Driver: config.Driver,
- Mountpoint: config.MountPoint,
+ Mountpoint: mp,
CreatedAt: config.CreatedTime.Format(time.RFC3339),
Labels: config.Labels,
Options: config.Options,
@@ -171,10 +188,15 @@ func InspectVolume(w http.ResponseWriter, r *http.Request) {
utils.VolumeNotFound(w, name, err)
return
}
+ mp, err := vol.MountPoint()
+ if err != nil {
+ utils.InternalServerError(w, err)
+ return
+ }
volResponse := docker_api_types.Volume{
Name: vol.Name(),
Driver: vol.Driver(),
- Mountpoint: vol.MountPoint(),
+ Mountpoint: mp,
CreatedAt: vol.CreatedTime().Format(time.RFC3339),
Labels: vol.Labels(),
Options: vol.Options(),
@@ -268,17 +290,29 @@ func PruneVolumes(w http.ResponseWriter, r *http.Request) {
utils.InternalServerError(w, err)
return
}
+
+ var errorMsg bytes.Buffer
+ var reclaimedSpace uint64
prunedIds := make([]string, 0, len(pruned))
- for k := range pruned {
- // XXX: This drops any pruning per-volume error messages on the floor
- prunedIds = append(prunedIds, k)
+ for _, v := range pruned {
+ if v.Err != nil {
+ errorMsg.WriteString(v.Err.Error())
+ errorMsg.WriteString("; ")
+ continue
+ }
+ prunedIds = append(prunedIds, v.Id)
+ reclaimedSpace += v.Size
}
- pruneResponse := docker_api_types.VolumesPruneReport{
- VolumesDeleted: prunedIds,
- // TODO: We don't have any insight into how much space was reclaimed
- // from `PruneVolumes()` but it's not nullable
- SpaceReclaimed: 0,
+ if errorMsg.Len() > 0 {
+ utils.InternalServerError(w, errors.New(errorMsg.String()))
+ return
}
- utils.WriteResponse(w, http.StatusOK, pruneResponse)
+ payload := handlers.VolumesPruneReport{
+ VolumesPruneReport: docker_api_types.VolumesPruneReport{
+ VolumesDeleted: prunedIds,
+ SpaceReclaimed: reclaimedSpace,
+ },
+ }
+ utils.WriteResponse(w, http.StatusOK, payload)
}
diff --git a/pkg/api/handlers/libpod/containers.go b/pkg/api/handlers/libpod/containers.go
index 14eb44831..6b07b1cc5 100644
--- a/pkg/api/handlers/libpod/containers.go
+++ b/pkg/api/handlers/libpod/containers.go
@@ -275,6 +275,7 @@ func Restore(w http.ResponseWriter, r *http.Request) {
Import bool `schema:"import"`
Name string `schema:"name"`
IgnoreRootFS bool `schema:"ignoreRootFS"`
+ IgnoreVolumes bool `schema:"ignoreVolumes"`
IgnoreStaticIP bool `schema:"ignoreStaticIP"`
IgnoreStaticMAC bool `schema:"ignoreStaticMAC"`
}{
diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go
index 0b8712f16..5b15527b7 100644
--- a/pkg/api/handlers/libpod/images.go
+++ b/pkg/api/handlers/libpod/images.go
@@ -16,7 +16,6 @@ import (
"github.com/containers/podman/v2/libpod"
"github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/libpod/image"
- image2 "github.com/containers/podman/v2/libpod/image"
"github.com/containers/podman/v2/pkg/api/handlers"
"github.com/containers/podman/v2/pkg/api/handlers/utils"
"github.com/containers/podman/v2/pkg/auth"
@@ -156,12 +155,12 @@ func PruneImages(w http.ResponseWriter, r *http.Request) {
}
}
- cids, err := runtime.ImageRuntime().PruneImages(r.Context(), query.All, libpodFilters)
+ imagePruneReports, err := runtime.ImageRuntime().PruneImages(r.Context(), query.All, libpodFilters)
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err)
return
}
- utils.WriteResponse(w, http.StatusOK, cids)
+ utils.WriteResponse(w, http.StatusOK, imagePruneReports)
}
func ExportImage(w http.ResponseWriter, r *http.Request) {
@@ -354,20 +353,7 @@ func ImagesLoad(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to load image"))
return
}
- split := strings.Split(loadedImage, ",")
- newImage, err := runtime.ImageRuntime().NewFromLocal(split[0])
- if err != nil {
- utils.InternalServerError(w, err)
- return
- }
- // TODO this should go into libpod proper at some point.
- if len(query.Reference) > 0 {
- if err := newImage.TagImage(query.Reference); err != nil {
- utils.InternalServerError(w, err)
- return
- }
- }
- utils.WriteResponse(w, http.StatusOK, entities.ImageLoadReport{Names: split})
+ utils.WriteResponse(w, http.StatusOK, entities.ImageLoadReport{Names: strings.Split(loadedImage, ",")})
}
func ImagesImport(w http.ResponseWriter, r *http.Request) {
@@ -524,7 +510,7 @@ func CommitContainer(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "failed to get runtime config", http.StatusInternalServerError, errors.Wrap(err, "failed to get runtime config"))
return
}
- sc := image2.GetSystemContext(rtc.Engine.SignaturePolicyPath, "", false)
+ sc := image.GetSystemContext(rtc.Engine.SignaturePolicyPath, "", false)
tag := "latest"
options := libpod.ContainerCommitOptions{
Pause: true,
diff --git a/pkg/api/handlers/libpod/images_pull.go b/pkg/api/handlers/libpod/images_pull.go
index 5e2727e95..bacba006d 100644
--- a/pkg/api/handlers/libpod/images_pull.go
+++ b/pkg/api/handlers/libpod/images_pull.go
@@ -115,10 +115,10 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) {
}
}
- writer := channel.NewWriter(make(chan []byte, 1))
+ writer := channel.NewWriter(make(chan []byte))
defer writer.Close()
- stderr := channel.NewWriter(make(chan []byte, 1))
+ stderr := channel.NewWriter(make(chan []byte))
defer stderr.Close()
images := make([]string, 0, len(imagesToPull))
diff --git a/pkg/api/handlers/libpod/pods.go b/pkg/api/handlers/libpod/pods.go
index 5422411cf..2409d3a20 100644
--- a/pkg/api/handlers/libpod/pods.go
+++ b/pkg/api/handlers/libpod/pods.go
@@ -43,6 +43,7 @@ func PodCreate(w http.ResponseWriter, r *http.Request) {
}
func Pods(w http.ResponseWriter, r *http.Request) {
+ runtime := r.Context().Value("runtime").(*libpod.Runtime)
decoder := r.Context().Value("decoder").(*schema.Decoder)
query := struct {
Filters map[string][]string `schema:"filters"`
@@ -55,7 +56,11 @@ func Pods(w http.ResponseWriter, r *http.Request) {
return
}
- pods, err := utils.GetPods(w, r)
+ containerEngine := abi.ContainerEngine{Libpod: runtime}
+ podPSOptions := entities.PodPSOptions{
+ Filters: query.Filters,
+ }
+ pods, err := containerEngine.PodPs(r.Context(), podPSOptions)
if err != nil {
utils.Error(w, "Something went wrong", http.StatusInternalServerError, err)
return
@@ -235,7 +240,7 @@ func PodRestart(w http.ResponseWriter, r *http.Request) {
}
func PodPrune(w http.ResponseWriter, r *http.Request) {
- reports, err := PodPruneHelper(w, r)
+ reports, err := PodPruneHelper(r)
if err != nil {
utils.InternalServerError(w, err)
return
@@ -243,7 +248,7 @@ func PodPrune(w http.ResponseWriter, r *http.Request) {
utils.WriteResponse(w, http.StatusOK, reports)
}
-func PodPruneHelper(w http.ResponseWriter, r *http.Request) ([]*entities.PodPruneReport, error) {
+func PodPruneHelper(r *http.Request) ([]*entities.PodPruneReport, error) {
var (
runtime = r.Context().Value("runtime").(*libpod.Runtime)
)
diff --git a/pkg/api/handlers/libpod/system.go b/pkg/api/handlers/libpod/system.go
index b157dfc7b..c48c186ed 100644
--- a/pkg/api/handlers/libpod/system.go
+++ b/pkg/api/handlers/libpod/system.go
@@ -30,7 +30,7 @@ func SystemPrune(w http.ResponseWriter, r *http.Request) {
return
}
- podPruneReport, err := PodPruneHelper(w, r)
+ podPruneReport, err := PodPruneHelper(r)
if err != nil {
utils.InternalServerError(w, err)
return
@@ -38,35 +38,28 @@ func SystemPrune(w http.ResponseWriter, r *http.Request) {
systemPruneReport.PodPruneReport = podPruneReport
// We could parallelize this, should we?
- containerPruneReport, err := compat.PruneContainersHelper(w, r, nil)
+ containerPruneReports, err := compat.PruneContainersHelper(r, nil)
if err != nil {
utils.InternalServerError(w, err)
return
}
- systemPruneReport.ContainerPruneReport = containerPruneReport
+ systemPruneReport.ContainerPruneReports = containerPruneReports
- results, err := runtime.ImageRuntime().PruneImages(r.Context(), query.All, nil)
+ imagePruneReports, err := runtime.ImageRuntime().PruneImages(r.Context(), query.All, nil)
if err != nil {
utils.InternalServerError(w, err)
return
}
- report := entities.ImagePruneReport{
- Report: entities.Report{
- Id: results,
- Err: nil,
- },
- }
-
- systemPruneReport.ImagePruneReport = &report
+ systemPruneReport.ImagePruneReports = imagePruneReports
if query.Volumes {
- volumePruneReport, err := pruneVolumesHelper(r)
+ volumePruneReports, err := pruneVolumesHelper(r)
if err != nil {
utils.InternalServerError(w, err)
return
}
- systemPruneReport.VolumePruneReport = volumePruneReport
+ systemPruneReport.VolumePruneReports = volumePruneReports
}
utils.WriteResponse(w, http.StatusOK, systemPruneReport)
}
diff --git a/pkg/api/handlers/libpod/volumes.go b/pkg/api/handlers/libpod/volumes.go
index b02a6a8ce..38fdf1b4d 100644
--- a/pkg/api/handlers/libpod/volumes.go
+++ b/pkg/api/handlers/libpod/volumes.go
@@ -9,6 +9,7 @@ import (
"github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/pkg/api/handlers/utils"
"github.com/containers/podman/v2/pkg/domain/entities"
+ "github.com/containers/podman/v2/pkg/domain/entities/reports"
"github.com/containers/podman/v2/pkg/domain/filters"
"github.com/containers/podman/v2/pkg/domain/infra/abi/parse"
"github.com/gorilla/schema"
@@ -59,20 +60,13 @@ func CreateVolume(w http.ResponseWriter, r *http.Request) {
utils.InternalServerError(w, err)
return
}
- config, err := vol.Config()
+ inspectOut, err := vol.Inspect()
if err != nil {
utils.InternalServerError(w, err)
return
}
volResponse := entities.VolumeConfigResponse{
- Name: config.Name,
- Driver: config.Driver,
- Mountpoint: config.MountPoint,
- CreatedAt: config.CreatedTime,
- Labels: config.Labels,
- Options: config.Options,
- UID: config.UID,
- GID: config.GID,
+ InspectVolumeData: *inspectOut,
}
utils.WriteResponse(w, http.StatusCreated, volResponse)
}
@@ -87,27 +81,13 @@ func InspectVolume(w http.ResponseWriter, r *http.Request) {
utils.VolumeNotFound(w, name, err)
return
}
- var uid, gid int
- uid, err = vol.UID()
+ inspectOut, err := vol.Inspect()
if err != nil {
- utils.Error(w, "Error fetching volume UID", http.StatusInternalServerError, err)
- return
- }
- gid, err = vol.GID()
- if err != nil {
- utils.Error(w, "Error fetching volume GID", http.StatusInternalServerError, err)
+ utils.InternalServerError(w, err)
return
}
volResponse := entities.VolumeConfigResponse{
- Name: vol.Name(),
- Driver: vol.Driver(),
- Mountpoint: vol.MountPoint(),
- CreatedAt: vol.CreatedTime(),
- Labels: vol.Labels(),
- Scope: vol.Scope(),
- Options: vol.Options(),
- UID: uid,
- GID: gid,
+ InspectVolumeData: *inspectOut,
}
utils.WriteResponse(w, http.StatusOK, volResponse)
}
@@ -142,27 +122,13 @@ func ListVolumes(w http.ResponseWriter, r *http.Request) {
}
volumeConfigs := make([]*entities.VolumeListReport, 0, len(vols))
for _, v := range vols {
- var uid, gid int
- uid, err = v.UID()
+ inspectOut, err := v.Inspect()
if err != nil {
- utils.Error(w, "Error fetching volume UID", http.StatusInternalServerError, err)
- return
- }
- gid, err = v.GID()
- if err != nil {
- utils.Error(w, "Error fetching volume GID", http.StatusInternalServerError, err)
+ utils.InternalServerError(w, err)
return
}
config := entities.VolumeConfigResponse{
- Name: v.Name(),
- Driver: v.Driver(),
- Mountpoint: v.MountPoint(),
- CreatedAt: v.CreatedTime(),
- Labels: v.Labels(),
- Scope: v.Scope(),
- Options: v.Options(),
- UID: uid,
- GID: gid,
+ InspectVolumeData: *inspectOut,
}
volumeConfigs = append(volumeConfigs, &entities.VolumeListReport{VolumeConfigResponse: config})
}
@@ -178,7 +144,7 @@ func PruneVolumes(w http.ResponseWriter, r *http.Request) {
utils.WriteResponse(w, http.StatusOK, reports)
}
-func pruneVolumesHelper(r *http.Request) ([]*entities.VolumePruneReport, error) {
+func pruneVolumesHelper(r *http.Request) ([]*reports.PruneReport, error) {
var (
runtime = r.Context().Value("runtime").(*libpod.Runtime)
decoder = r.Context().Value("decoder").(*schema.Decoder)
@@ -199,17 +165,10 @@ func pruneVolumesHelper(r *http.Request) ([]*entities.VolumePruneReport, error)
return nil, err
}
- pruned, err := runtime.PruneVolumes(r.Context(), filterFuncs)
+ reports, err := runtime.PruneVolumes(r.Context(), filterFuncs)
if err != nil {
return nil, err
}
- reports := make([]*entities.VolumePruneReport, 0, len(pruned))
- for k, v := range pruned {
- reports = append(reports, &entities.VolumePruneReport{
- Err: v,
- Id: k,
- })
- }
return reports, nil
}
func RemoveVolume(w http.ResponseWriter, r *http.Request) {
diff --git a/pkg/api/handlers/utils/errors.go b/pkg/api/handlers/utils/errors.go
index fc77b8ec0..e2c287c45 100644
--- a/pkg/api/handlers/utils/errors.go
+++ b/pkg/api/handlers/utils/errors.go
@@ -5,7 +5,7 @@ import (
"net/http"
"github.com/containers/podman/v2/libpod/define"
- "github.com/containers/podman/v2/pkg/domain/entities"
+ "github.com/containers/podman/v2/pkg/errorhandling"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
)
@@ -24,7 +24,7 @@ var (
func Error(w http.ResponseWriter, apiMessage string, code int, err error) {
// Log detailed message of what happened to machine running podman service
log.Infof("Request Failed(%s): %s", http.StatusText(code), err.Error())
- em := entities.ErrorModel{
+ em := errorhandling.ErrorModel{
Because: (errors.Cause(err)).Error(),
Message: err.Error(),
ResponseCode: code,
diff --git a/pkg/api/handlers/utils/pods.go b/pkg/api/handlers/utils/pods.go
deleted file mode 100644
index 0fe3a308b..000000000
--- a/pkg/api/handlers/utils/pods.go
+++ /dev/null
@@ -1,87 +0,0 @@
-package utils
-
-import (
- "net/http"
-
- "github.com/containers/podman/v2/libpod"
- "github.com/containers/podman/v2/pkg/domain/entities"
- dfilters "github.com/containers/podman/v2/pkg/domain/filters"
- "github.com/gorilla/schema"
-)
-
-func GetPods(w http.ResponseWriter, r *http.Request) ([]*entities.ListPodsReport, error) {
- var (
- pods []*libpod.Pod
- )
- runtime := r.Context().Value("runtime").(*libpod.Runtime)
- decoder := r.Context().Value("decoder").(*schema.Decoder)
-
- query := struct {
- All bool
- Filters map[string][]string `schema:"filters"`
- Digests bool
- }{}
-
- if err := decoder.Decode(&query, r.URL.Query()); err != nil {
- return nil, err
- }
- if _, found := r.URL.Query()["digests"]; found && query.Digests {
- UnSupportedParameter("digests")
- }
-
- filters := make([]libpod.PodFilter, 0, len(query.Filters))
- for k, v := range query.Filters {
- f, err := dfilters.GeneratePodFilterFunc(k, v)
- if err != nil {
- return nil, err
- }
- filters = append(filters, f)
- }
- pods, err := runtime.Pods(filters...)
- if err != nil {
- return nil, err
- }
-
- if len(pods) == 0 {
- return []*entities.ListPodsReport{}, nil
- }
-
- lps := make([]*entities.ListPodsReport, 0, len(pods))
- for _, pod := range pods {
- status, err := pod.GetPodStatus()
- if err != nil {
- return nil, err
- }
- ctrs, err := pod.AllContainers()
- if err != nil {
- return nil, err
- }
- infraID, err := pod.InfraContainerID()
- if err != nil {
- return nil, err
- }
- lp := entities.ListPodsReport{
- Cgroup: pod.CgroupParent(),
- Created: pod.CreatedTime(),
- Id: pod.ID(),
- Name: pod.Name(),
- Namespace: pod.Namespace(),
- Status: status,
- InfraId: infraID,
- Labels: pod.Labels(),
- }
- for _, ctr := range ctrs {
- state, err := ctr.State()
- if err != nil {
- return nil, err
- }
- lp.Containers = append(lp.Containers, &entities.ListPodContainer{
- Id: ctr.ID(),
- Names: ctr.Name(),
- Status: state.String(),
- })
- }
- lps = append(lps, &lp)
- }
- return lps, nil
-}
diff --git a/pkg/api/server/docs.go b/pkg/api/server/docs.go
index 1aaf31117..a99fefd7b 100644
--- a/pkg/api/server/docs.go
+++ b/pkg/api/server/docs.go
@@ -13,7 +13,7 @@
// You can then use cURL on the socket using requests documented below.
//
// NOTE: if you install the package podman-docker, it will create a symbolic
-// link for /var/run/docker.sock to /run/podman/podman.sock
+// link for /run/docker.sock to /run/podman/podman.sock
//
// See podman-service(1) for more information.
//
diff --git a/pkg/api/server/register_containers.go b/pkg/api/server/register_containers.go
index b80dea545..74a04b2e6 100644
--- a/pkg/api/server/register_containers.go
+++ b/pkg/api/server/register_containers.go
@@ -291,9 +291,6 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error {
r.HandleFunc(VersionedPath("/containers/{name}/pause"), s.APIHandler(compat.PauseContainer)).Methods(http.MethodPost)
// Added non version path to URI to support docker non versioned paths
r.HandleFunc("/containers/{name}/pause", s.APIHandler(compat.PauseContainer)).Methods(http.MethodPost)
- r.HandleFunc(VersionedPath("/containers/{name}/rename"), s.APIHandler(compat.UnsupportedHandler)).Methods(http.MethodPost)
- // Added non version path to URI to support docker non versioned paths
- r.HandleFunc("/containers/{name}/rename", s.APIHandler(compat.UnsupportedHandler)).Methods(http.MethodPost)
// swagger:operation POST /containers/{name}/restart compat restartContainer
// ---
// tags:
@@ -610,6 +607,36 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error {
// $ref: "#/responses/InternalError"
r.HandleFunc(VersionedPath("/containers/{name}/export"), s.APIHandler(compat.ExportContainer)).Methods(http.MethodGet)
r.HandleFunc("/containers/{name}/export", s.APIHandler(compat.ExportContainer)).Methods(http.MethodGet)
+ // swagger:operation POST /containers/{name}/rename compat renameContainer
+ // ---
+ // tags:
+ // - containers (compat)
+ // summary: Rename an existing container
+ // description: Change the name of an existing container.
+ // parameters:
+ // - in: path
+ // name: name
+ // type: string
+ // required: true
+ // description: Full or partial ID or full name of the container to rename
+ // - in: query
+ // name: name
+ // type: string
+ // required: true
+ // description: New name for the container
+ // produces:
+ // - application/json
+ // responses:
+ // 204:
+ // description: no error
+ // 404:
+ // $ref: "#/responses/NoSuchContainer"
+ // 409:
+ // $ref: "#/responses/ConflictError"
+ // 500:
+ // $ref: "#/responses/InternalError"
+ r.HandleFunc(VersionedPath("/containers/{name}/rename"), s.APIHandler(compat.RenameContainer)).Methods(http.MethodPost)
+ r.HandleFunc("/containers/{name}/rename", s.APIHandler(compat.RenameContainer)).Methods(http.MethodPost)
/*
libpod endpoints
@@ -1463,5 +1490,34 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error {
// 500:
// $ref: "#/responses/InternalError"
r.HandleFunc(VersionedPath("/libpod/containers/{name}/init"), s.APIHandler(libpod.InitContainer)).Methods(http.MethodPost)
+ // swagger:operation POST /libpod/containers/{name}/rename libpod libpodRenameContainer
+ // ---
+ // tags:
+ // - containers
+ // summary: Rename an existing container
+ // description: Change the name of an existing container.
+ // parameters:
+ // - in: path
+ // name: name
+ // type: string
+ // required: true
+ // description: Full or partial ID or full name of the container to rename
+ // - in: query
+ // name: name
+ // type: string
+ // required: true
+ // description: New name for the container
+ // produces:
+ // - application/json
+ // responses:
+ // 204:
+ // description: no error
+ // 404:
+ // $ref: "#/responses/NoSuchContainer"
+ // 409:
+ // $ref: "#/responses/ConflictError"
+ // 500:
+ // $ref: "#/responses/InternalError"
+ r.HandleFunc(VersionedPath("/libpod/containers/{name}/rename"), s.APIHandler(compat.RenameContainer)).Methods(http.MethodPost)
return nil
}
diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go
index 7e6de8783..8d0c0800b 100644
--- a/pkg/api/server/register_images.go
+++ b/pkg/api/server/register_images.go
@@ -797,10 +797,6 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// summary: Load image
// description: Load an image (oci-archive or docker-archive) stream.
// parameters:
- // - in: query
- // name: reference
- // description: "Optional Name[:TAG] for the image"
- // type: string
// - in: formData
// name: upload
// description: tarball of container image
diff --git a/pkg/api/server/register_networks.go b/pkg/api/server/register_networks.go
index e6c85d244..967d7da76 100644
--- a/pkg/api/server/register_networks.go
+++ b/pkg/api/server/register_networks.go
@@ -9,6 +9,19 @@ import (
)
func (s *APIServer) registerNetworkHandlers(r *mux.Router) error {
+ // swagger:operation POST /networks/prune compat compatPruneNetwork
+ // ---
+ // tags:
+ // - networks (compat)
+ // Summary: Delete unused networks
+ // description: Not supported
+ // produces:
+ // - application/json
+ // responses:
+ // 404:
+ // $ref: "#/responses/NoSuchNetwork"
+ r.HandleFunc(VersionedPath("/networks/prune"), compat.UnsupportedHandler).Methods(http.MethodPost)
+ r.HandleFunc("/networks/prune", compat.UnsupportedHandler).Methods(http.MethodPost)
// swagger:operation DELETE /networks/{name} compat compatRemoveNetwork
// ---
// tags:
diff --git a/pkg/api/server/swagger.go b/pkg/api/server/swagger.go
index 6d349bb7d..d4fc33442 100644
--- a/pkg/api/server/swagger.go
+++ b/pkg/api/server/swagger.go
@@ -4,6 +4,8 @@ import (
"github.com/containers/podman/v2/libpod"
"github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/pkg/domain/entities"
+ "github.com/containers/podman/v2/pkg/domain/entities/reports"
+ "github.com/containers/podman/v2/pkg/errorhandling"
)
// No such image
@@ -11,7 +13,7 @@ import (
type swagErrNoSuchImage struct {
// in:body
Body struct {
- entities.ErrorModel
+ errorhandling.ErrorModel
}
}
@@ -20,7 +22,7 @@ type swagErrNoSuchImage struct {
type swagErrNoSuchContainer struct {
// in:body
Body struct {
- entities.ErrorModel
+ errorhandling.ErrorModel
}
}
@@ -29,7 +31,7 @@ type swagErrNoSuchContainer struct {
type swagErrNoSuchNetwork struct {
// in:body
Body struct {
- entities.ErrorModel
+ errorhandling.ErrorModel
}
}
@@ -38,7 +40,7 @@ type swagErrNoSuchNetwork struct {
type swagErrNoSuchExecInstance struct {
// in:body
Body struct {
- entities.ErrorModel
+ errorhandling.ErrorModel
}
}
@@ -47,7 +49,7 @@ type swagErrNoSuchExecInstance struct {
type swagErrNoSuchVolume struct {
// in:body
Body struct {
- entities.ErrorModel
+ errorhandling.ErrorModel
}
}
@@ -56,7 +58,7 @@ type swagErrNoSuchVolume struct {
type swagErrNoSuchPod struct {
// in:body
Body struct {
- entities.ErrorModel
+ errorhandling.ErrorModel
}
}
@@ -65,7 +67,7 @@ type swagErrNoSuchPod struct {
type swagErrNoSuchManifest struct {
// in:body
Body struct {
- entities.ErrorModel
+ errorhandling.ErrorModel
}
}
@@ -74,7 +76,7 @@ type swagErrNoSuchManifest struct {
type swagInternalError struct {
// in:body
Body struct {
- entities.ErrorModel
+ errorhandling.ErrorModel
}
}
@@ -83,7 +85,7 @@ type swagInternalError struct {
type swagConflictError struct {
// in:body
Body struct {
- entities.ErrorModel
+ errorhandling.ErrorModel
}
}
@@ -92,7 +94,7 @@ type swagConflictError struct {
type swagBadParamError struct {
// in:body
Body struct {
- entities.ErrorModel
+ errorhandling.ErrorModel
}
}
@@ -101,7 +103,7 @@ type swagBadParamError struct {
type swagContainerAlreadyStartedError struct {
// in:body
Body struct {
- entities.ErrorModel
+ errorhandling.ErrorModel
}
}
@@ -110,7 +112,7 @@ type swagContainerAlreadyStartedError struct {
type swagContainerAlreadyStopped struct {
// in:body
Body struct {
- entities.ErrorModel
+ errorhandling.ErrorModel
}
}
@@ -119,7 +121,7 @@ type swagContainerAlreadyStopped struct {
type swagPodAlreadyStartedError struct {
// in:body
Body struct {
- entities.ErrorModel
+ errorhandling.ErrorModel
}
}
@@ -128,7 +130,7 @@ type swagPodAlreadyStartedError struct {
type swagPodAlreadyStopped struct {
// in:body
Body struct {
- entities.ErrorModel
+ errorhandling.ErrorModel
}
}
@@ -170,7 +172,7 @@ type ok struct {
// swagger:response VolumePruneResponse
type swagVolumePruneResponse struct {
// in:body
- Body []entities.VolumePruneReport
+ Body []reports.PruneReport
}
// Volume create response
diff --git a/pkg/bindings/containers/containers.go b/pkg/bindings/containers/containers.go
index 650aa9ac5..1081a0e61 100644
--- a/pkg/bindings/containers/containers.go
+++ b/pkg/bindings/containers/containers.go
@@ -12,6 +12,7 @@ import (
"github.com/containers/podman/v2/pkg/api/handlers"
"github.com/containers/podman/v2/pkg/bindings"
"github.com/containers/podman/v2/pkg/domain/entities"
+ "github.com/containers/podman/v2/pkg/domain/entities/reports"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
@@ -49,11 +50,11 @@ func List(ctx context.Context, options *ListOptions) ([]entities.ListContainer,
// used for more granular selection of containers. The main error returned indicates if there were runtime
// errors like finding containers. Errors specific to the removal of a container are in the PruneContainerResponse
// structure.
-func Prune(ctx context.Context, options *PruneOptions) (*entities.ContainerPruneReport, error) {
+func Prune(ctx context.Context, options *PruneOptions) ([]*reports.PruneReport, error) {
if options == nil {
options = new(PruneOptions)
}
- var reports *entities.ContainerPruneReport
+ var reports []*reports.PruneReport
conn, err := bindings.GetClient(ctx)
if err != nil {
return nil, err
diff --git a/pkg/bindings/containers/rename.go b/pkg/bindings/containers/rename.go
new file mode 100644
index 000000000..0e8c7f198
--- /dev/null
+++ b/pkg/bindings/containers/rename.go
@@ -0,0 +1,28 @@
+package containers
+
+import (
+ "context"
+ "net/http"
+
+ "github.com/containers/podman/v2/pkg/bindings"
+)
+
+// Rename an existing container.
+func Rename(ctx context.Context, nameOrID string, options *RenameOptions) error {
+ if options == nil {
+ options = new(RenameOptions)
+ }
+ conn, err := bindings.GetClient(ctx)
+ if err != nil {
+ return err
+ }
+ params, err := options.ToParams()
+ if err != nil {
+ return err
+ }
+ response, err := conn.DoRequest(nil, http.MethodPost, "/containers/%s/rename", params, nil, nameOrID)
+ if err != nil {
+ return err
+ }
+ return response.Process(nil)
+}
diff --git a/pkg/bindings/containers/types.go b/pkg/bindings/containers/types.go
index 24402e982..10f553e52 100644
--- a/pkg/bindings/containers/types.go
+++ b/pkg/bindings/containers/types.go
@@ -194,6 +194,13 @@ type InitOptions struct{}
// ShouldRestartOptions
type ShouldRestartOptions struct{}
+//go:generate go run ../generator/generator.go RenameOptions
+// RenameOptions are options for renaming containers.
+// The Name field is required.
+type RenameOptions struct {
+ Name *string
+}
+
//go:generate go run ../generator/generator.go ResizeTTYOptions
// ResizeTTYOptions are optional options for resizing
// container TTYs
diff --git a/pkg/bindings/containers/types_attach_options.go b/pkg/bindings/containers/types_attach_options.go
index 4ffb8ab17..6d8c1cb01 100644
--- a/pkg/bindings/containers/types_attach_options.go
+++ b/pkg/bindings/containers/types_attach_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 13:33:18.566804404 -0600 CST m=+0.000258831
*/
// Changed
@@ -39,6 +38,7 @@ func (o *AttachOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/containers/types_checkpoint_options.go b/pkg/bindings/containers/types_checkpoint_options.go
index d03dc8231..ec766de4a 100644
--- a/pkg/bindings/containers/types_checkpoint_options.go
+++ b/pkg/bindings/containers/types_checkpoint_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 13:33:18.714853285 -0600 CST m=+0.000319103
*/
// Changed
@@ -39,6 +38,7 @@ func (o *CheckpointOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/containers/types_commit_options.go b/pkg/bindings/containers/types_commit_options.go
index a8b215141..b745bebe2 100644
--- a/pkg/bindings/containers/types_commit_options.go
+++ b/pkg/bindings/containers/types_commit_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 13:33:18.420656951 -0600 CST m=+0.000259662
*/
// Changed
@@ -39,6 +38,7 @@ func (o *CommitOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/containers/types_create_options.go b/pkg/bindings/containers/types_create_options.go
index 4dbce0203..4b9574cf1 100644
--- a/pkg/bindings/containers/types_create_options.go
+++ b/pkg/bindings/containers/types_create_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 13:33:19.011789618 -0600 CST m=+0.000259413
*/
// Changed
@@ -39,6 +38,7 @@ func (o *CreateOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/containers/types_diff_options.go b/pkg/bindings/containers/types_diff_options.go
index be3bbf554..55fa6930d 100644
--- a/pkg/bindings/containers/types_diff_options.go
+++ b/pkg/bindings/containers/types_diff_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 13:33:19.159128927 -0600 CST m=+0.000255635
*/
// Changed
@@ -39,6 +38,7 @@ func (o *DiffOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/containers/types_execinspect_options.go b/pkg/bindings/containers/types_execinspect_options.go
index 3c4c870be..c5d1f931a 100644
--- a/pkg/bindings/containers/types_execinspect_options.go
+++ b/pkg/bindings/containers/types_execinspect_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 13:33:19.303239014 -0600 CST m=+0.000256861
*/
// Changed
@@ -39,6 +38,7 @@ func (o *ExecInspectOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/containers/types_execstart_options.go b/pkg/bindings/containers/types_execstart_options.go
index 66fdc82cb..9ecb70a3e 100644
--- a/pkg/bindings/containers/types_execstart_options.go
+++ b/pkg/bindings/containers/types_execstart_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 13:33:19.447714428 -0600 CST m=+0.000257278
*/
// Changed
@@ -39,6 +38,7 @@ func (o *ExecStartOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/containers/types_execstartandattach_options.go b/pkg/bindings/containers/types_execstartandattach_options.go
index 43900d29d..a5a691e35 100644
--- a/pkg/bindings/containers/types_execstartandattach_options.go
+++ b/pkg/bindings/containers/types_execstartandattach_options.go
@@ -6,6 +6,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -13,8 +14,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 13:33:22.827903078 -0600 CST m=+0.000269906
*/
// Changed
@@ -41,6 +40,7 @@ func (o *ExecStartAndAttachOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/containers/types_export_options.go b/pkg/bindings/containers/types_export_options.go
index e325bd2cd..55e413c72 100644
--- a/pkg/bindings/containers/types_export_options.go
+++ b/pkg/bindings/containers/types_export_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 13:33:22.101679998 -0600 CST m=+0.000261669
*/
// Changed
@@ -39,6 +38,7 @@ func (o *ExportOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/containers/types_healthcheck_options.go b/pkg/bindings/containers/types_healthcheck_options.go
index 8c4300366..9d8b25bf4 100644
--- a/pkg/bindings/containers/types_healthcheck_options.go
+++ b/pkg/bindings/containers/types_healthcheck_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 13:33:19.593883686 -0600 CST m=+0.000289845
*/
// Changed
@@ -39,6 +38,7 @@ func (o *HealthCheckOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/containers/types_init_options.go b/pkg/bindings/containers/types_init_options.go
index 655362f62..6fb5795c0 100644
--- a/pkg/bindings/containers/types_init_options.go
+++ b/pkg/bindings/containers/types_init_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 13:33:22.245077233 -0600 CST m=+0.000255461
*/
// Changed
@@ -39,6 +38,7 @@ func (o *InitOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/containers/types_inspect_options.go b/pkg/bindings/containers/types_inspect_options.go
index 884f5524d..722372414 100644
--- a/pkg/bindings/containers/types_inspect_options.go
+++ b/pkg/bindings/containers/types_inspect_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 13:33:20.635987603 -0600 CST m=+0.000260270
*/
// Changed
@@ -39,6 +38,7 @@ func (o *InspectOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/containers/types_kill_options.go b/pkg/bindings/containers/types_kill_options.go
index 3d6fa6224..dd84f0d9f 100644
--- a/pkg/bindings/containers/types_kill_options.go
+++ b/pkg/bindings/containers/types_kill_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 13:33:20.781581076 -0600 CST m=+0.000259040
*/
// Changed
@@ -39,6 +38,7 @@ func (o *KillOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/containers/types_list_options.go b/pkg/bindings/containers/types_list_options.go
index dd74d37b7..43326fa59 100644
--- a/pkg/bindings/containers/types_list_options.go
+++ b/pkg/bindings/containers/types_list_options.go
@@ -12,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 13:33:20.199081744 -0600 CST m=+0.000270626
*/
// Changed
diff --git a/pkg/bindings/containers/types_log_options.go b/pkg/bindings/containers/types_log_options.go
index a6958242f..364f29de4 100644
--- a/pkg/bindings/containers/types_log_options.go
+++ b/pkg/bindings/containers/types_log_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 13:33:18.273264471 -0600 CST m=+0.000274536
*/
// Changed
@@ -39,6 +38,7 @@ func (o *LogOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/containers/types_mount_options.go b/pkg/bindings/containers/types_mount_options.go
index c0e253094..6f4349b73 100644
--- a/pkg/bindings/containers/types_mount_options.go
+++ b/pkg/bindings/containers/types_mount_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 13:33:19.740822464 -0600 CST m=+0.000250074
*/
// Changed
@@ -39,6 +38,7 @@ func (o *MountOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/containers/types_mountedcontainerpaths_options.go b/pkg/bindings/containers/types_mountedcontainerpaths_options.go
index e368ff131..0d8b69654 100644
--- a/pkg/bindings/containers/types_mountedcontainerpaths_options.go
+++ b/pkg/bindings/containers/types_mountedcontainerpaths_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 13:33:20.048233253 -0600 CST m=+0.000307223
*/
// Changed
@@ -39,6 +38,7 @@ func (o *MountedContainerPathsOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/containers/types_pause_options.go b/pkg/bindings/containers/types_pause_options.go
index 26ad86793..0cc65f64e 100644
--- a/pkg/bindings/containers/types_pause_options.go
+++ b/pkg/bindings/containers/types_pause_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 13:33:20.929891294 -0600 CST m=+0.000261081
*/
// Changed
@@ -39,6 +38,7 @@ func (o *PauseOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/containers/types_prune_options.go b/pkg/bindings/containers/types_prune_options.go
index e3c0f4de7..10adf0a2a 100644
--- a/pkg/bindings/containers/types_prune_options.go
+++ b/pkg/bindings/containers/types_prune_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 13:33:20.344278799 -0600 CST m=+0.000263499
*/
// Changed
@@ -39,6 +38,7 @@ func (o *PruneOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/containers/types_remove_options.go b/pkg/bindings/containers/types_remove_options.go
index 6f59f0ed5..e21fb41f7 100644
--- a/pkg/bindings/containers/types_remove_options.go
+++ b/pkg/bindings/containers/types_remove_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 13:33:20.489968735 -0600 CST m=+0.000264450
*/
// Changed
@@ -39,6 +38,7 @@ func (o *RemoveOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/containers/types_rename_options.go b/pkg/bindings/containers/types_rename_options.go
new file mode 100644
index 000000000..b7a723f7a
--- /dev/null
+++ b/pkg/bindings/containers/types_rename_options.go
@@ -0,0 +1,104 @@
+package containers
+
+import (
+ "net/url"
+ "reflect"
+ "strconv"
+ "strings"
+
+ jsoniter "github.com/json-iterator/go"
+ "github.com/pkg/errors"
+)
+
+/*
+This file is generated automatically by go generate. Do not edit.
+*/
+
+// Changed
+func (o *RenameOptions) Changed(fieldName string) bool {
+ r := reflect.ValueOf(o)
+ value := reflect.Indirect(r).FieldByName(fieldName)
+ return !value.IsNil()
+}
+
+// ToParams
+func (o *RenameOptions) ToParams() (url.Values, error) {
+ params := url.Values{}
+ if o == nil {
+ return params, nil
+ }
+ json := jsoniter.ConfigCompatibleWithStandardLibrary
+ s := reflect.ValueOf(o)
+ if reflect.Ptr == s.Kind() {
+ s = s.Elem()
+ }
+ sType := s.Type()
+ for i := 0; i < s.NumField(); i++ {
+ fieldName := sType.Field(i).Name
+ if !o.Changed(fieldName) {
+ continue
+ }
+ fieldName = strings.ToLower(fieldName)
+ f := s.Field(i)
+ if reflect.Ptr == f.Kind() {
+ f = f.Elem()
+ }
+ switch f.Kind() {
+ case reflect.Bool:
+ params.Set(fieldName, strconv.FormatBool(f.Bool()))
+ case reflect.String:
+ params.Set(fieldName, f.String())
+ case reflect.Int, reflect.Int64:
+ // f.Int() is always an int64
+ params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
+ case reflect.Uint, reflect.Uint64:
+ // f.Uint() is always an uint64
+ params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
+ case reflect.Slice:
+ typ := reflect.TypeOf(f.Interface()).Elem()
+ switch typ.Kind() {
+ case reflect.String:
+ sl := f.Slice(0, f.Len())
+ s, ok := sl.Interface().([]string)
+ if !ok {
+ return nil, errors.New("failed to convert to string slice")
+ }
+ for _, val := range s {
+ params.Add(fieldName, val)
+ }
+ default:
+ return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
+ }
+ case reflect.Map:
+ lowerCaseKeys := make(map[string][]string)
+ iter := f.MapRange()
+ for iter.Next() {
+ lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string)
+
+ }
+ s, err := json.MarshalToString(lowerCaseKeys)
+ if err != nil {
+ return nil, err
+ }
+
+ params.Set(fieldName, s)
+ }
+ }
+ return params, nil
+}
+
+// WithName
+func (o *RenameOptions) WithName(value string) *RenameOptions {
+ v := &value
+ o.Name = v
+ return o
+}
+
+// GetName
+func (o *RenameOptions) GetName() string {
+ var name string
+ if o.Name == nil {
+ return name
+ }
+ return *o.Name
+}
diff --git a/pkg/bindings/containers/types_resizeexectty_options.go b/pkg/bindings/containers/types_resizeexectty_options.go
index 33bb4e78b..0212adeb2 100644
--- a/pkg/bindings/containers/types_resizeexectty_options.go
+++ b/pkg/bindings/containers/types_resizeexectty_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 13:33:22.680735758 -0600 CST m=+0.000267081
*/
// Changed
@@ -39,6 +38,7 @@ func (o *ResizeExecTTYOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/containers/types_resizetty_options.go b/pkg/bindings/containers/types_resizetty_options.go
index 29ec54988..cee607902 100644
--- a/pkg/bindings/containers/types_resizetty_options.go
+++ b/pkg/bindings/containers/types_resizetty_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 13:33:22.535788375 -0600 CST m=+0.000266528
*/
// Changed
@@ -39,6 +38,7 @@ func (o *ResizeTTYOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/containers/types_restart_options.go b/pkg/bindings/containers/types_restart_options.go
index 13ac099b1..8dcc6b5b7 100644
--- a/pkg/bindings/containers/types_restart_options.go
+++ b/pkg/bindings/containers/types_restart_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 13:33:21.076709643 -0600 CST m=+0.000303354
*/
// Changed
@@ -39,6 +38,7 @@ func (o *RestartOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/containers/types_restore_options.go b/pkg/bindings/containers/types_restore_options.go
index be6e94736..491d678a5 100644
--- a/pkg/bindings/containers/types_restore_options.go
+++ b/pkg/bindings/containers/types_restore_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 13:33:18.861536405 -0600 CST m=+0.000300026
*/
// Changed
@@ -39,6 +38,7 @@ func (o *RestoreOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/containers/types_shouldrestart_options.go b/pkg/bindings/containers/types_shouldrestart_options.go
index c833d0d8b..30ab618c7 100644
--- a/pkg/bindings/containers/types_shouldrestart_options.go
+++ b/pkg/bindings/containers/types_shouldrestart_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 13:33:22.388596051 -0600 CST m=+0.000253693
*/
// Changed
@@ -39,6 +38,7 @@ func (o *ShouldRestartOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/containers/types_start_options.go b/pkg/bindings/containers/types_start_options.go
index 5918af89b..4050a8993 100644
--- a/pkg/bindings/containers/types_start_options.go
+++ b/pkg/bindings/containers/types_start_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 13:33:21.221364502 -0600 CST m=+0.000276575
*/
// Changed
@@ -39,6 +38,7 @@ func (o *StartOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/containers/types_stats_options.go b/pkg/bindings/containers/types_stats_options.go
index f821ea1cd..74f419913 100644
--- a/pkg/bindings/containers/types_stats_options.go
+++ b/pkg/bindings/containers/types_stats_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 13:33:21.370213399 -0600 CST m=+0.000264334
*/
// Changed
@@ -39,6 +38,7 @@ func (o *StatsOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/containers/types_stop_options.go b/pkg/bindings/containers/types_stop_options.go
index 14d7633a0..db692dbf0 100644
--- a/pkg/bindings/containers/types_stop_options.go
+++ b/pkg/bindings/containers/types_stop_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 13:33:21.95469621 -0600 CST m=+0.000261399
*/
// Changed
@@ -39,6 +38,7 @@ func (o *StopOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/containers/types_top_options.go b/pkg/bindings/containers/types_top_options.go
index 95a1ee686..5f2717c28 100644
--- a/pkg/bindings/containers/types_top_options.go
+++ b/pkg/bindings/containers/types_top_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 13:33:21.515867629 -0600 CST m=+0.000257106
*/
// Changed
@@ -39,6 +38,7 @@ func (o *TopOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/containers/types_unmount_options.go b/pkg/bindings/containers/types_unmount_options.go
index a29bd8216..060327c4a 100644
--- a/pkg/bindings/containers/types_unmount_options.go
+++ b/pkg/bindings/containers/types_unmount_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 13:33:19.891657824 -0600 CST m=+0.000326668
*/
// Changed
@@ -39,6 +38,7 @@ func (o *UnmountOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/containers/types_unpause_options.go b/pkg/bindings/containers/types_unpause_options.go
index 44c077df2..e02bf2c95 100644
--- a/pkg/bindings/containers/types_unpause_options.go
+++ b/pkg/bindings/containers/types_unpause_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 13:33:21.661356277 -0600 CST m=+0.000262608
*/
// Changed
@@ -39,6 +38,7 @@ func (o *UnpauseOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/containers/types_wait_options.go b/pkg/bindings/containers/types_wait_options.go
index 18d36c377..470d67611 100644
--- a/pkg/bindings/containers/types_wait_options.go
+++ b/pkg/bindings/containers/types_wait_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
"github.com/containers/podman/v2/libpod/define"
jsoniter "github.com/json-iterator/go"
@@ -12,8 +13,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 13:33:21.809397978 -0600 CST m=+0.000267049
*/
// Changed
@@ -40,6 +39,7 @@ func (o *WaitOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/errors.go b/pkg/bindings/errors.go
index 603299389..e75ce898d 100644
--- a/pkg/bindings/errors.go
+++ b/pkg/bindings/errors.go
@@ -4,7 +4,7 @@ import (
"encoding/json"
"io/ioutil"
- "github.com/containers/podman/v2/pkg/domain/entities"
+ "github.com/containers/podman/v2/pkg/errorhandling"
"github.com/pkg/errors"
)
@@ -13,7 +13,7 @@ var (
)
func handleError(data []byte) error {
- e := entities.ErrorModel{}
+ e := errorhandling.ErrorModel{}
if err := json.Unmarshal(data, &e); err != nil {
return err
}
@@ -36,7 +36,7 @@ func (a APIResponse) Process(unmarshalInto interface{}) error {
}
func CheckResponseCode(inError error) (int, error) {
- e, ok := inError.(entities.ErrorModel)
+ e, ok := inError.(errorhandling.ErrorModel)
if !ok {
return -1, errors.New("error is not type ErrorModel")
}
diff --git a/pkg/bindings/generate/types_kube_options.go b/pkg/bindings/generate/types_kube_options.go
index 68488aaee..5fb965c9f 100644
--- a/pkg/bindings/generate/types_kube_options.go
+++ b/pkg/bindings/generate/types_kube_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:20.522950566 -0600 CST m=+0.000154384
*/
// Changed
@@ -39,6 +38,7 @@ func (o *KubeOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/generate/types_systemd_options.go b/pkg/bindings/generate/types_systemd_options.go
index 0e8a46aa0..ce7286b3a 100644
--- a/pkg/bindings/generate/types_systemd_options.go
+++ b/pkg/bindings/generate/types_systemd_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:20.661450253 -0600 CST m=+0.000135779
*/
// Changed
@@ -39,6 +38,7 @@ func (o *SystemdOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/generator/generator.go b/pkg/bindings/generator/generator.go
index 8c79aebae..6a7f600a8 100644
--- a/pkg/bindings/generator/generator.go
+++ b/pkg/bindings/generator/generator.go
@@ -19,13 +19,10 @@ var bodyTmpl = `package {{.PackageName}}
import (
{{range $import := .Imports}} {{$import}}
{{end}}
-
)
/*
This file is generated automatically by go generate. Do not edit.
-
-Created {{.Date}}
*/
// Changed
@@ -52,6 +49,7 @@ func (o *{{.StructName}}) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
@@ -239,7 +237,7 @@ func main() {
closed = true
// go fmt file
- gofmt := exec.Command("gofmt", "-w", "-s", out.Name())
+ gofmt := exec.Command("go", "fmt", out.Name())
gofmt.Stderr = os.Stdout
if err := gofmt.Run(); err != nil {
fmt.Println(err)
diff --git a/pkg/bindings/images/images.go b/pkg/bindings/images/images.go
index 9beb493c8..ae6962c8c 100644
--- a/pkg/bindings/images/images.go
+++ b/pkg/bindings/images/images.go
@@ -12,6 +12,7 @@ import (
"github.com/containers/podman/v2/pkg/auth"
"github.com/containers/podman/v2/pkg/bindings"
"github.com/containers/podman/v2/pkg/domain/entities"
+ "github.com/containers/podman/v2/pkg/domain/entities/reports"
"github.com/pkg/errors"
)
@@ -112,20 +113,13 @@ func History(ctx context.Context, nameOrID string, options *HistoryOptions) ([]*
return history, response.Process(&history)
}
-func Load(ctx context.Context, r io.Reader, options *LoadOptions) (*entities.ImageLoadReport, error) {
- if options == nil {
- options = new(LoadOptions)
- }
+func Load(ctx context.Context, r io.Reader) (*entities.ImageLoadReport, error) {
var report entities.ImageLoadReport
conn, err := bindings.GetClient(ctx)
if err != nil {
return nil, err
}
- params, err := options.ToParams()
- if err != nil {
- return nil, err
- }
- response, err := conn.DoRequest(r, http.MethodPost, "/images/load", params, nil)
+ response, err := conn.DoRequest(r, http.MethodPost, "/images/load", nil, nil)
if err != nil {
return nil, err
}
@@ -163,9 +157,9 @@ func Export(ctx context.Context, nameOrIDs []string, w io.Writer, options *Expor
// Prune removes unused images from local storage. The optional filters can be used to further
// define which images should be pruned.
-func Prune(ctx context.Context, options *PruneOptions) ([]string, error) {
+func Prune(ctx context.Context, options *PruneOptions) ([]*reports.PruneReport, error) {
var (
- deleted []string
+ deleted []*reports.PruneReport
)
if options == nil {
options = new(PruneOptions)
@@ -182,7 +176,8 @@ func Prune(ctx context.Context, options *PruneOptions) ([]string, error) {
if err != nil {
return deleted, err
}
- return deleted, response.Process(&deleted)
+ err = response.Process(&deleted)
+ return deleted, err
}
// Tag adds an additional name to locally-stored image. Both the tag and repo parameters are required.
diff --git a/pkg/bindings/images/types_diff_options.go b/pkg/bindings/images/types_diff_options.go
index d27c8945e..34a5bf2df 100644
--- a/pkg/bindings/images/types_diff_options.go
+++ b/pkg/bindings/images/types_diff_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:26.320022698 -0600 CST m=+0.000277796
*/
// Changed
@@ -39,6 +38,7 @@ func (o *DiffOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/images/types_export_options.go b/pkg/bindings/images/types_export_options.go
index 078b27fc0..172cb2b5c 100644
--- a/pkg/bindings/images/types_export_options.go
+++ b/pkg/bindings/images/types_export_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:27.173810543 -0600 CST m=+0.000239871
*/
// Changed
@@ -39,6 +38,7 @@ func (o *ExportOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/images/types_get_options.go b/pkg/bindings/images/types_get_options.go
index 1161657f7..c91ddb170 100644
--- a/pkg/bindings/images/types_get_options.go
+++ b/pkg/bindings/images/types_get_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:26.609005517 -0600 CST m=+0.000241828
*/
// Changed
@@ -39,6 +38,7 @@ func (o *GetOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/images/types_history_options.go b/pkg/bindings/images/types_history_options.go
index 6f9854e03..bd4224cd8 100644
--- a/pkg/bindings/images/types_history_options.go
+++ b/pkg/bindings/images/types_history_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:26.890854681 -0600 CST m=+0.000243668
*/
// Changed
@@ -39,6 +38,7 @@ func (o *HistoryOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/images/types_import_options.go b/pkg/bindings/images/types_import_options.go
index f5e6c8f7e..81eda946e 100644
--- a/pkg/bindings/images/types_import_options.go
+++ b/pkg/bindings/images/types_import_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:27.740585278 -0600 CST m=+0.000340441
*/
// Changed
@@ -39,6 +38,7 @@ func (o *ImportOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/images/types_list_options.go b/pkg/bindings/images/types_list_options.go
index 209d72e34..5dc4242fc 100644
--- a/pkg/bindings/images/types_list_options.go
+++ b/pkg/bindings/images/types_list_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:26.462967928 -0600 CST m=+0.000289760
*/
// Changed
@@ -39,6 +38,7 @@ func (o *ListOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/images/types_load_options.go b/pkg/bindings/images/types_load_options.go
index 6bba573d4..7bbd56c09 100644
--- a/pkg/bindings/images/types_load_options.go
+++ b/pkg/bindings/images/types_load_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:27.031848205 -0600 CST m=+0.000279409
*/
// Changed
@@ -39,6 +38,7 @@ func (o *LoadOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/images/types_prune_options.go b/pkg/bindings/images/types_prune_options.go
index c29fdae12..c290bb379 100644
--- a/pkg/bindings/images/types_prune_options.go
+++ b/pkg/bindings/images/types_prune_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:27.316938584 -0600 CST m=+0.000239843
*/
// Changed
@@ -39,6 +38,7 @@ func (o *PruneOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/images/types_pull_options.go b/pkg/bindings/images/types_pull_options.go
index 07f3e079d..5163a6341 100644
--- a/pkg/bindings/images/types_pull_options.go
+++ b/pkg/bindings/images/types_pull_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
"github.com/containers/common/pkg/config"
jsoniter "github.com/json-iterator/go"
@@ -12,8 +13,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:28.164648348 -0600 CST m=+0.000243264
*/
// Changed
@@ -40,6 +39,7 @@ func (o *PullOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/images/types_push_options.go b/pkg/bindings/images/types_push_options.go
index f9ce1b835..15210f30b 100644
--- a/pkg/bindings/images/types_push_options.go
+++ b/pkg/bindings/images/types_push_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:27.881232044 -0600 CST m=+0.000242458
*/
// Changed
@@ -39,6 +38,7 @@ func (o *PushOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/images/types_remove_options.go b/pkg/bindings/images/types_remove_options.go
index c9692c2b7..66a6bea7d 100644
--- a/pkg/bindings/images/types_remove_options.go
+++ b/pkg/bindings/images/types_remove_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:26.180391541 -0600 CST m=+0.000290244
*/
// Changed
@@ -39,6 +38,7 @@ func (o *RemoveOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/images/types_search_options.go b/pkg/bindings/images/types_search_options.go
index e6168ac33..299d27505 100644
--- a/pkg/bindings/images/types_search_options.go
+++ b/pkg/bindings/images/types_search_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:28.023569573 -0600 CST m=+0.000245548
*/
// Changed
@@ -39,6 +38,7 @@ func (o *SearchOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/images/types_tag_options.go b/pkg/bindings/images/types_tag_options.go
index f6396e590..40cd4a35b 100644
--- a/pkg/bindings/images/types_tag_options.go
+++ b/pkg/bindings/images/types_tag_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:27.457906682 -0600 CST m=+0.000245071
*/
// Changed
@@ -39,6 +38,7 @@ func (o *TagOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/images/types_tree_options.go b/pkg/bindings/images/types_tree_options.go
index fb2493f85..a671fa4e0 100644
--- a/pkg/bindings/images/types_tree_options.go
+++ b/pkg/bindings/images/types_tree_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:26.749625305 -0600 CST m=+0.000267624
*/
// Changed
@@ -39,6 +38,7 @@ func (o *TreeOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/images/types_untag_options.go b/pkg/bindings/images/types_untag_options.go
index 8faf5c14e..e38c5f18e 100644
--- a/pkg/bindings/images/types_untag_options.go
+++ b/pkg/bindings/images/types_untag_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:27.600379913 -0600 CST m=+0.000251449
*/
// Changed
@@ -39,6 +38,7 @@ func (o *UntagOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/manifests/types_add_options.go b/pkg/bindings/manifests/types_add_options.go
index d45effedc..1e588c668 100644
--- a/pkg/bindings/manifests/types_add_options.go
+++ b/pkg/bindings/manifests/types_add_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:57:55.92237379 -0600 CST m=+0.000150701
*/
// Changed
@@ -39,6 +38,7 @@ func (o *AddOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/manifests/types_create_options.go b/pkg/bindings/manifests/types_create_options.go
index da07f1abf..3a564a92b 100644
--- a/pkg/bindings/manifests/types_create_options.go
+++ b/pkg/bindings/manifests/types_create_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:57:55.784206871 -0600 CST m=+0.000157049
*/
// Changed
@@ -39,6 +38,7 @@ func (o *CreateOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/manifests/types_inspect_options.go b/pkg/bindings/manifests/types_inspect_options.go
index 0d32d5bb9..2af4190d4 100644
--- a/pkg/bindings/manifests/types_inspect_options.go
+++ b/pkg/bindings/manifests/types_inspect_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:57:55.631746481 -0600 CST m=+0.000143104
*/
// Changed
@@ -39,6 +38,7 @@ func (o *InspectOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/manifests/types_push_options.go b/pkg/bindings/manifests/types_push_options.go
index 4226733c9..1d689f699 100644
--- a/pkg/bindings/manifests/types_push_options.go
+++ b/pkg/bindings/manifests/types_push_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:57:56.197438009 -0600 CST m=+0.000149060
*/
// Changed
@@ -39,6 +38,7 @@ func (o *PushOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/manifests/types_remove_options.go b/pkg/bindings/manifests/types_remove_options.go
index f99220f6c..3b35c38b8 100644
--- a/pkg/bindings/manifests/types_remove_options.go
+++ b/pkg/bindings/manifests/types_remove_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:57:56.059954408 -0600 CST m=+0.000146015
*/
// Changed
@@ -39,6 +38,7 @@ func (o *RemoveOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/network/types_connect_options.go b/pkg/bindings/network/types_connect_options.go
index 6fcc4536e..b6081ba57 100644
--- a/pkg/bindings/network/types_connect_options.go
+++ b/pkg/bindings/network/types_connect_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:34.075822786 -0600 CST m=+0.000167237
*/
// Changed
@@ -39,6 +38,7 @@ func (o *ConnectOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/network/types_create_options.go b/pkg/bindings/network/types_create_options.go
index daec6a254..5b0abe870 100644
--- a/pkg/bindings/network/types_create_options.go
+++ b/pkg/bindings/network/types_create_options.go
@@ -5,6 +5,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -12,8 +13,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:33.37307678 -0600 CST m=+0.000176739
*/
// Changed
@@ -40,6 +39,7 @@ func (o *CreateOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
@@ -193,9 +193,9 @@ func (o *CreateOptions) WithIPRange(value net.IPNet) *CreateOptions {
// GetIPRange
func (o *CreateOptions) GetIPRange() net.IPNet {
- var ipRange net.IPNet
+ var iPRange net.IPNet
if o.IPRange == nil {
- return ipRange
+ return iPRange
}
return *o.IPRange
}
diff --git a/pkg/bindings/network/types_disconnect_options.go b/pkg/bindings/network/types_disconnect_options.go
index 821279976..8b2a9cb71 100644
--- a/pkg/bindings/network/types_disconnect_options.go
+++ b/pkg/bindings/network/types_disconnect_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:33.936088242 -0600 CST m=+0.000168680
*/
// Changed
@@ -39,6 +38,7 @@ func (o *DisconnectOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/network/types_inspect_options.go b/pkg/bindings/network/types_inspect_options.go
index 7704904ce..cec5ef7b2 100644
--- a/pkg/bindings/network/types_inspect_options.go
+++ b/pkg/bindings/network/types_inspect_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:33.520438264 -0600 CST m=+0.000172934
*/
// Changed
@@ -39,6 +38,7 @@ func (o *InspectOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/network/types_list_options.go b/pkg/bindings/network/types_list_options.go
index bbd2a71db..6a33fb7b6 100644
--- a/pkg/bindings/network/types_list_options.go
+++ b/pkg/bindings/network/types_list_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:33.796794129 -0600 CST m=+0.000180368
*/
// Changed
@@ -39,6 +38,7 @@ func (o *ListOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/network/types_remove_options.go b/pkg/bindings/network/types_remove_options.go
index b24835ae4..861fe1f2c 100644
--- a/pkg/bindings/network/types_remove_options.go
+++ b/pkg/bindings/network/types_remove_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:33.658228151 -0600 CST m=+0.000172527
*/
// Changed
@@ -39,6 +38,7 @@ func (o *RemoveOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/play/types_kube_options.go b/pkg/bindings/play/types_kube_options.go
index 91cdd30aa..5aec4b479 100644
--- a/pkg/bindings/play/types_kube_options.go
+++ b/pkg/bindings/play/types_kube_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:02.386833736 -0600 CST m=+0.000171080
*/
// Changed
@@ -39,6 +38,7 @@ func (o *KubeOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/pods/types_create_options.go b/pkg/bindings/pods/types_create_options.go
index b6cf0fc53..b501d1151 100644
--- a/pkg/bindings/pods/types_create_options.go
+++ b/pkg/bindings/pods/types_create_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:40.05490508 -0600 CST m=+0.000156396
*/
// Changed
@@ -39,6 +38,7 @@ func (o *CreateOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/pods/types_inspect_options.go b/pkg/bindings/pods/types_inspect_options.go
index 1c881ce9c..a2eb25fef 100644
--- a/pkg/bindings/pods/types_inspect_options.go
+++ b/pkg/bindings/pods/types_inspect_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:40.258801519 -0600 CST m=+0.000175055
*/
// Changed
@@ -39,6 +38,7 @@ func (o *InspectOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/pods/types_kill_options.go b/pkg/bindings/pods/types_kill_options.go
index cb5bdfd01..f9cad3579 100644
--- a/pkg/bindings/pods/types_kill_options.go
+++ b/pkg/bindings/pods/types_kill_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:40.398857339 -0600 CST m=+0.000160135
*/
// Changed
@@ -39,6 +38,7 @@ func (o *KillOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/pods/types_list_options.go b/pkg/bindings/pods/types_list_options.go
index d095bf3db..02e7adf2d 100644
--- a/pkg/bindings/pods/types_list_options.go
+++ b/pkg/bindings/pods/types_list_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:40.818123838 -0600 CST m=+0.000164328
*/
// Changed
@@ -39,6 +38,7 @@ func (o *ListOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/pods/types_pause_options.go b/pkg/bindings/pods/types_pause_options.go
index 06ee6f81d..2e4fdb4a6 100644
--- a/pkg/bindings/pods/types_pause_options.go
+++ b/pkg/bindings/pods/types_pause_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:40.538407099 -0600 CST m=+0.000193274
*/
// Changed
@@ -39,6 +38,7 @@ func (o *PauseOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/pods/types_prune_options.go b/pkg/bindings/pods/types_prune_options.go
index 6610aa7cc..616ad6dc9 100644
--- a/pkg/bindings/pods/types_prune_options.go
+++ b/pkg/bindings/pods/types_prune_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:40.678507342 -0600 CST m=+0.000183891
*/
// Changed
@@ -39,6 +38,7 @@ func (o *PruneOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/pods/types_remove_options.go b/pkg/bindings/pods/types_remove_options.go
index 8f18e43c9..6960d8839 100644
--- a/pkg/bindings/pods/types_remove_options.go
+++ b/pkg/bindings/pods/types_remove_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:41.80320679 -0600 CST m=+0.000158149
*/
// Changed
@@ -39,6 +38,7 @@ func (o *RemoveOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/pods/types_restart_options.go b/pkg/bindings/pods/types_restart_options.go
index 9030de1e7..427833044 100644
--- a/pkg/bindings/pods/types_restart_options.go
+++ b/pkg/bindings/pods/types_restart_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:40.958315383 -0600 CST m=+0.000168360
*/
// Changed
@@ -39,6 +38,7 @@ func (o *RestartOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/pods/types_start_options.go b/pkg/bindings/pods/types_start_options.go
index 0fce21099..e98798459 100644
--- a/pkg/bindings/pods/types_start_options.go
+++ b/pkg/bindings/pods/types_start_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:41.099102916 -0600 CST m=+0.000159629
*/
// Changed
@@ -39,6 +38,7 @@ func (o *StartOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/pods/types_stats_options.go b/pkg/bindings/pods/types_stats_options.go
index d38a9a115..845a534a3 100644
--- a/pkg/bindings/pods/types_stats_options.go
+++ b/pkg/bindings/pods/types_stats_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:41.658228243 -0600 CST m=+0.000160769
*/
// Changed
@@ -39,6 +38,7 @@ func (o *StatsOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/pods/types_stop_options.go b/pkg/bindings/pods/types_stop_options.go
index ac698b8c5..86000eb57 100644
--- a/pkg/bindings/pods/types_stop_options.go
+++ b/pkg/bindings/pods/types_stop_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:41.237892781 -0600 CST m=+0.000155040
*/
// Changed
@@ -39,6 +38,7 @@ func (o *StopOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/pods/types_top_options.go b/pkg/bindings/pods/types_top_options.go
index 895f62957..ada0b1e25 100644
--- a/pkg/bindings/pods/types_top_options.go
+++ b/pkg/bindings/pods/types_top_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:41.375876994 -0600 CST m=+0.000154839
*/
// Changed
@@ -39,6 +38,7 @@ func (o *TopOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/pods/types_unpause_options.go b/pkg/bindings/pods/types_unpause_options.go
index 3d647cf25..6a9ee8fcd 100644
--- a/pkg/bindings/pods/types_unpause_options.go
+++ b/pkg/bindings/pods/types_unpause_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:41.515225789 -0600 CST m=+0.000158667
*/
// Changed
@@ -39,6 +38,7 @@ func (o *UnpauseOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/system/types_disk_options.go b/pkg/bindings/system/types_disk_options.go
index f7d2cca06..c5eb2f94c 100644
--- a/pkg/bindings/system/types_disk_options.go
+++ b/pkg/bindings/system/types_disk_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:08.087362343 -0600 CST m=+0.000150636
*/
// Changed
@@ -39,6 +38,7 @@ func (o *DiskOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/system/types_events_options.go b/pkg/bindings/system/types_events_options.go
index 6dd64b055..2e95339e6 100644
--- a/pkg/bindings/system/types_events_options.go
+++ b/pkg/bindings/system/types_events_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:07.675150173 -0600 CST m=+0.000140977
*/
// Changed
@@ -39,6 +38,7 @@ func (o *EventsOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/system/types_info_options.go b/pkg/bindings/system/types_info_options.go
index 3a8960e1b..263513b0f 100644
--- a/pkg/bindings/system/types_info_options.go
+++ b/pkg/bindings/system/types_info_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:08.233760126 -0600 CST m=+0.000142369
*/
// Changed
@@ -39,6 +38,7 @@ func (o *InfoOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/system/types_prune_options.go b/pkg/bindings/system/types_prune_options.go
index 2cd3c8000..a9a6a6cda 100644
--- a/pkg/bindings/system/types_prune_options.go
+++ b/pkg/bindings/system/types_prune_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:07.812719858 -0600 CST m=+0.000143214
*/
// Changed
@@ -39,6 +38,7 @@ func (o *PruneOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/system/types_version_options.go b/pkg/bindings/system/types_version_options.go
index 4974e8d8f..be07581fa 100644
--- a/pkg/bindings/system/types_version_options.go
+++ b/pkg/bindings/system/types_version_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:07.950759332 -0600 CST m=+0.000140376
*/
// Changed
@@ -39,6 +38,7 @@ func (o *VersionOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/test/common_test.go b/pkg/bindings/test/common_test.go
index 232d7136f..c2b1347d2 100644
--- a/pkg/bindings/test/common_test.go
+++ b/pkg/bindings/test/common_test.go
@@ -182,7 +182,7 @@ func (b *bindingTest) RestoreImagesFromCache() {
}
}
func (b *bindingTest) restoreImageFromCache(i testImage) {
- p := b.runPodman([]string{"load", "-i", filepath.Join(ImageCacheDir, i.tarballName), i.name})
+ p := b.runPodman([]string{"load", "-i", filepath.Join(ImageCacheDir, i.tarballName)})
p.Wait(45)
}
diff --git a/pkg/bindings/test/containers_test.go b/pkg/bindings/test/containers_test.go
index 2ab5e45d0..fa601e7e5 100644
--- a/pkg/bindings/test/containers_test.go
+++ b/pkg/bindings/test/containers_test.go
@@ -8,6 +8,7 @@ import (
"github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/pkg/bindings"
"github.com/containers/podman/v2/pkg/bindings/containers"
+ "github.com/containers/podman/v2/pkg/domain/entities/reports"
"github.com/containers/podman/v2/pkg/specgen"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
@@ -533,8 +534,8 @@ var _ = Describe("Podman containers ", func() {
// Prune container should return no errors and one pruned container ID.
pruneResponse, err := containers.Prune(bt.conn, nil)
Expect(err).To(BeNil())
- Expect(len(pruneResponse.Err)).To(Equal(0))
- Expect(len(pruneResponse.ID)).To(Equal(1))
+ Expect(len(reports.PruneReportsErrs(pruneResponse))).To(Equal(0))
+ Expect(len(reports.PruneReportsIds(pruneResponse))).To(Equal(1))
})
It("podman prune stopped containers with filters", func() {
@@ -558,8 +559,8 @@ var _ = Describe("Podman containers ", func() {
}
pruneResponse, err = containers.Prune(bt.conn, new(containers.PruneOptions).WithFilters(filtersIncorrect))
Expect(err).To(BeNil())
- Expect(len(pruneResponse.Err)).To(Equal(0))
- Expect(len(pruneResponse.ID)).To(Equal(0))
+ Expect(len(reports.PruneReportsIds(pruneResponse))).To(Equal(0))
+ Expect(len(reports.PruneReportsErrs(pruneResponse))).To(Equal(0))
// Valid filter params container should be pruned now.
filters := map[string][]string{
@@ -567,8 +568,8 @@ var _ = Describe("Podman containers ", func() {
}
pruneResponse, err = containers.Prune(bt.conn, new(containers.PruneOptions).WithFilters(filters))
Expect(err).To(BeNil())
- Expect(len(pruneResponse.Err)).To(Equal(0))
- Expect(len(pruneResponse.ID)).To(Equal(1))
+ Expect(len(reports.PruneReportsErrs(pruneResponse))).To(Equal(0))
+ Expect(len(reports.PruneReportsIds(pruneResponse))).To(Equal(1))
})
It("podman prune running containers", func() {
@@ -585,7 +586,7 @@ var _ = Describe("Podman containers ", func() {
// Prune. Should return no error no prune response ID.
pruneResponse, err := containers.Prune(bt.conn, nil)
Expect(err).To(BeNil())
- Expect(len(pruneResponse.ID)).To(Equal(0))
+ Expect(len(pruneResponse)).To(Equal(0))
})
It("podman inspect bogus container", func() {
diff --git a/pkg/bindings/test/images_test.go b/pkg/bindings/test/images_test.go
index e178f4219..81959e813 100644
--- a/pkg/bindings/test/images_test.go
+++ b/pkg/bindings/test/images_test.go
@@ -9,6 +9,7 @@ import (
"github.com/containers/podman/v2/pkg/bindings"
"github.com/containers/podman/v2/pkg/bindings/containers"
"github.com/containers/podman/v2/pkg/bindings/images"
+ dreports "github.com/containers/podman/v2/pkg/domain/entities/reports"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gexec"
@@ -218,7 +219,7 @@ var _ = Describe("Podman images", func() {
f, err := os.Open(filepath.Join(ImageCacheDir, alpine.tarballName))
defer f.Close()
Expect(err).To(BeNil())
- names, err := images.Load(bt.conn, f, nil)
+ names, err := images.Load(bt.conn, f)
Expect(err).To(BeNil())
Expect(names.Names[0]).To(Equal(alpine.name))
exists, err = images.Exists(bt.conn, alpine.name)
@@ -233,14 +234,9 @@ var _ = Describe("Podman images", func() {
exists, err = images.Exists(bt.conn, alpine.name)
Expect(err).To(BeNil())
Expect(exists).To(BeFalse())
- newName := "quay.io/newname:fizzle"
- options := new(images.LoadOptions).WithReference(newName)
- names, err = images.Load(bt.conn, f, options)
+ names, err = images.Load(bt.conn, f)
Expect(err).To(BeNil())
Expect(names.Names[0]).To(Equal(alpine.name))
- exists, err = images.Exists(bt.conn, newName)
- Expect(err).To(BeNil())
- Expect(exists).To(BeTrue())
// load with a bad repo name should trigger a 500
f, err = os.Open(filepath.Join(ImageCacheDir, alpine.tarballName))
@@ -250,11 +246,6 @@ var _ = Describe("Podman images", func() {
exists, err = images.Exists(bt.conn, alpine.name)
Expect(err).To(BeNil())
Expect(exists).To(BeFalse())
- options = new(images.LoadOptions).WithReference("quay.io/newName:fizzle")
- _, err = images.Load(bt.conn, f, options)
- Expect(err).ToNot(BeNil())
- code, _ := bindings.CheckResponseCode(err)
- Expect(code).To(BeNumerically("==", http.StatusInternalServerError))
})
It("Export Image", func() {
@@ -355,7 +346,7 @@ var _ = Describe("Podman images", func() {
results, err := images.Prune(bt.conn, options)
Expect(err).NotTo(HaveOccurred())
Expect(len(results)).To(BeNumerically(">", 0))
- Expect(results).To(ContainElement("docker.io/library/alpine:latest"))
+ Expect(dreports.PruneReportsIds(results)).To(ContainElement("docker.io/library/alpine:latest"))
})
// TODO: we really need to extent to pull tests once we have a more sophisticated CI.
diff --git a/pkg/bindings/test/system_test.go b/pkg/bindings/test/system_test.go
index 25fda5575..44067b61d 100644
--- a/pkg/bindings/test/system_test.go
+++ b/pkg/bindings/test/system_test.go
@@ -10,6 +10,7 @@ import (
"github.com/containers/podman/v2/pkg/bindings/system"
"github.com/containers/podman/v2/pkg/bindings/volumes"
"github.com/containers/podman/v2/pkg/domain/entities"
+ "github.com/containers/podman/v2/pkg/domain/entities/reports"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gexec"
@@ -80,12 +81,12 @@ var _ = Describe("Podman system", func() {
systemPruneResponse, err := system.Prune(bt.conn, options)
Expect(err).To(BeNil())
Expect(len(systemPruneResponse.PodPruneReport)).To(Equal(1))
- Expect(len(systemPruneResponse.ContainerPruneReport.ID)).To(Equal(1))
- Expect(len(systemPruneResponse.ImagePruneReport.Report.Id)).
+ Expect(len(systemPruneResponse.ContainerPruneReports)).To(Equal(1))
+ Expect(len(systemPruneResponse.ImagePruneReports)).
To(BeNumerically(">", 0))
- Expect(systemPruneResponse.ImagePruneReport.Report.Id).
+ Expect(reports.PruneReportsIds(systemPruneResponse.ImagePruneReports)).
To(ContainElement("docker.io/library/alpine:latest"))
- Expect(len(systemPruneResponse.VolumePruneReport)).To(Equal(0))
+ Expect(len(systemPruneResponse.VolumePruneReports)).To(Equal(0))
})
It("podman system prune running alpine container", func() {
@@ -114,14 +115,14 @@ var _ = Describe("Podman system", func() {
systemPruneResponse, err := system.Prune(bt.conn, options)
Expect(err).To(BeNil())
Expect(len(systemPruneResponse.PodPruneReport)).To(Equal(1))
- Expect(len(systemPruneResponse.ContainerPruneReport.ID)).To(Equal(1))
- Expect(len(systemPruneResponse.ImagePruneReport.Report.Id)).
+ Expect(len(systemPruneResponse.ContainerPruneReports)).To(Equal(1))
+ Expect(len(systemPruneResponse.ImagePruneReports)).
To(BeNumerically(">", 0))
// Alpine image should not be pruned as used by running container
- Expect(systemPruneResponse.ImagePruneReport.Report.Id).
+ Expect(reports.PruneReportsIds(systemPruneResponse.ImagePruneReports)).
ToNot(ContainElement("docker.io/library/alpine:latest"))
// Though unused volume is available it should not be pruned as flag set to false.
- Expect(len(systemPruneResponse.VolumePruneReport)).To(Equal(0))
+ Expect(len(systemPruneResponse.VolumePruneReports)).To(Equal(0))
})
It("podman system prune running alpine container volume prune", func() {
@@ -149,14 +150,14 @@ var _ = Describe("Podman system", func() {
systemPruneResponse, err := system.Prune(bt.conn, options)
Expect(err).To(BeNil())
Expect(len(systemPruneResponse.PodPruneReport)).To(Equal(0))
- Expect(len(systemPruneResponse.ContainerPruneReport.ID)).To(Equal(1))
- Expect(len(systemPruneResponse.ImagePruneReport.Report.Id)).
+ Expect(len(systemPruneResponse.ContainerPruneReports)).To(Equal(1))
+ Expect(len(systemPruneResponse.ImagePruneReports)).
To(BeNumerically(">", 0))
// Alpine image should not be pruned as used by running container
- Expect(systemPruneResponse.ImagePruneReport.Report.Id).
+ Expect(reports.PruneReportsIds(systemPruneResponse.ImagePruneReports)).
ToNot(ContainElement("docker.io/library/alpine:latest"))
// Volume should be pruned now as flag set true
- Expect(len(systemPruneResponse.VolumePruneReport)).To(Equal(1))
+ Expect(len(systemPruneResponse.VolumePruneReports)).To(Equal(1))
})
It("podman system prune running alpine container volume prune --filter", func() {
@@ -197,14 +198,14 @@ var _ = Describe("Podman system", func() {
// This check **should** be "Equal(0)" since we are passing label
// filters however the Prune function doesn't seem to pass filters
// to each component.
- Expect(len(systemPruneResponse.ContainerPruneReport.ID)).To(Equal(1))
- Expect(len(systemPruneResponse.ImagePruneReport.Report.Id)).
+ Expect(len(systemPruneResponse.ContainerPruneReports)).To(Equal(1))
+ Expect(len(systemPruneResponse.ImagePruneReports)).
To(BeNumerically(">", 0))
// Alpine image should not be pruned as used by running container
- Expect(systemPruneResponse.ImagePruneReport.Report.Id).
+ Expect(reports.PruneReportsIds(systemPruneResponse.ImagePruneReports)).
ToNot(ContainElement("docker.io/library/alpine:latest"))
// Volume shouldn't be pruned because the PruneOptions filters doesn't match
- Expect(len(systemPruneResponse.VolumePruneReport)).To(Equal(0))
+ Expect(len(systemPruneResponse.VolumePruneReports)).To(Equal(0))
// Fix filter and re prune
f["label"] = []string{"label1=value1"}
@@ -213,6 +214,6 @@ var _ = Describe("Podman system", func() {
Expect(err).To(BeNil())
// Volume should be pruned because the PruneOptions filters now match
- Expect(len(systemPruneResponse.VolumePruneReport)).To(Equal(1))
+ Expect(len(systemPruneResponse.VolumePruneReports)).To(Equal(1))
})
})
diff --git a/pkg/bindings/test/volumes_test.go b/pkg/bindings/test/volumes_test.go
index e0d854b66..1f1da3cfa 100644
--- a/pkg/bindings/test/volumes_test.go
+++ b/pkg/bindings/test/volumes_test.go
@@ -10,6 +10,7 @@ import (
"github.com/containers/podman/v2/pkg/bindings/containers"
"github.com/containers/podman/v2/pkg/bindings/volumes"
"github.com/containers/podman/v2/pkg/domain/entities"
+ "github.com/containers/podman/v2/pkg/domain/entities/reports"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gexec"
@@ -166,7 +167,7 @@ var _ = Describe("Podman volumes", func() {
session.Wait(45)
vols, err = volumes.Prune(connText, nil)
Expect(err).To(BeNil())
- Expect(len(vols)).To(BeNumerically("==", 1))
+ Expect(len(reports.PruneReportsIds(vols))).To(BeNumerically("==", 1))
_, err = volumes.Inspect(connText, "homer", nil)
Expect(err).To(BeNil())
diff --git a/pkg/bindings/volumes/types_create_options.go b/pkg/bindings/volumes/types_create_options.go
index 80bdac2d2..171090afe 100644
--- a/pkg/bindings/volumes/types_create_options.go
+++ b/pkg/bindings/volumes/types_create_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:14.043860791 -0600 CST m=+0.000188944
*/
// Changed
@@ -39,6 +38,7 @@ func (o *CreateOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/volumes/types_inspect_options.go b/pkg/bindings/volumes/types_inspect_options.go
index ba8c70b63..3a1d396a7 100644
--- a/pkg/bindings/volumes/types_inspect_options.go
+++ b/pkg/bindings/volumes/types_inspect_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:14.189902005 -0600 CST m=+0.000151439
*/
// Changed
@@ -39,6 +38,7 @@ func (o *InspectOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/volumes/types_list_options.go b/pkg/bindings/volumes/types_list_options.go
index 99dec132c..56033a575 100644
--- a/pkg/bindings/volumes/types_list_options.go
+++ b/pkg/bindings/volumes/types_list_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:14.326721724 -0600 CST m=+0.000172471
*/
// Changed
@@ -39,6 +38,7 @@ func (o *ListOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/volumes/types_prune_options.go b/pkg/bindings/volumes/types_prune_options.go
index cdbc03fc9..c043d69d0 100644
--- a/pkg/bindings/volumes/types_prune_options.go
+++ b/pkg/bindings/volumes/types_prune_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:14.463307398 -0600 CST m=+0.000180868
*/
// Changed
@@ -39,6 +38,7 @@ func (o *PruneOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/volumes/types_remove_options.go b/pkg/bindings/volumes/types_remove_options.go
index 923d1353c..1f8ba4e22 100644
--- a/pkg/bindings/volumes/types_remove_options.go
+++ b/pkg/bindings/volumes/types_remove_options.go
@@ -4,6 +4,7 @@ import (
"net/url"
"reflect"
"strconv"
+ "strings"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -11,8 +12,6 @@ import (
/*
This file is generated automatically by go generate. Do not edit.
-
-Created 2020-12-18 15:58:14.60278922 -0600 CST m=+0.000134408
*/
// Changed
@@ -39,6 +38,7 @@ func (o *RemoveOptions) ToParams() (url.Values, error) {
if !o.Changed(fieldName) {
continue
}
+ fieldName = strings.ToLower(fieldName)
f := s.Field(i)
if reflect.Ptr == f.Kind() {
f = f.Elem()
diff --git a/pkg/bindings/volumes/volumes.go b/pkg/bindings/volumes/volumes.go
index 626f52d39..fe081eb46 100644
--- a/pkg/bindings/volumes/volumes.go
+++ b/pkg/bindings/volumes/volumes.go
@@ -7,6 +7,7 @@ import (
"github.com/containers/podman/v2/pkg/bindings"
"github.com/containers/podman/v2/pkg/domain/entities"
+ "github.com/containers/podman/v2/pkg/domain/entities/reports"
jsoniter "github.com/json-iterator/go"
)
@@ -77,9 +78,9 @@ func List(ctx context.Context, options *ListOptions) ([]*entities.VolumeListRepo
}
// Prune removes unused volumes from the local filesystem.
-func Prune(ctx context.Context, options *PruneOptions) ([]*entities.VolumePruneReport, error) {
+func Prune(ctx context.Context, options *PruneOptions) ([]*reports.PruneReport, error) {
var (
- pruned []*entities.VolumePruneReport
+ pruned []*reports.PruneReport
)
conn, err := bindings.GetClient(ctx)
if err != nil {
diff --git a/pkg/checkpoint/checkpoint_restore.go b/pkg/checkpoint/checkpoint_restore.go
index 9de04266f..f6cd3b38f 100644
--- a/pkg/checkpoint/checkpoint_restore.go
+++ b/pkg/checkpoint/checkpoint_restore.go
@@ -8,6 +8,7 @@ import (
"github.com/containers/podman/v2/libpod"
"github.com/containers/podman/v2/libpod/image"
+ "github.com/containers/podman/v2/pkg/domain/entities"
"github.com/containers/podman/v2/pkg/errorhandling"
"github.com/containers/podman/v2/pkg/util"
"github.com/containers/storage/pkg/archive"
@@ -36,10 +37,10 @@ func crImportFromJSON(filePath string, v interface{}) error {
// CRImportCheckpoint it the function which imports the information
// from checkpoint tarball and re-creates the container from that information
-func CRImportCheckpoint(ctx context.Context, runtime *libpod.Runtime, input string, name string) ([]*libpod.Container, error) {
+func CRImportCheckpoint(ctx context.Context, runtime *libpod.Runtime, restoreOptions entities.RestoreOptions) ([]*libpod.Container, error) {
// First get the container definition from the
// tarball to a temporary directory
- archiveFile, err := os.Open(input)
+ archiveFile, err := os.Open(restoreOptions.Import)
if err != nil {
return nil, errors.Wrap(err, "failed to open checkpoint archive for import")
}
@@ -53,6 +54,7 @@ func CRImportCheckpoint(ctx context.Context, runtime *libpod.Runtime, input stri
"rootfs-diff.tar",
"network.status",
"deleted.files",
+ "volumes",
},
}
dir, err := ioutil.TempDir("", "checkpoint")
@@ -66,7 +68,7 @@ func CRImportCheckpoint(ctx context.Context, runtime *libpod.Runtime, input stri
}()
err = archive.Untar(archiveFile, dir, options)
if err != nil {
- return nil, errors.Wrapf(err, "Unpacking of checkpoint archive %s failed", input)
+ return nil, errors.Wrapf(err, "Unpacking of checkpoint archive %s failed", restoreOptions.Import)
}
// Load spec.dump from temporary directory
@@ -82,17 +84,30 @@ func CRImportCheckpoint(ctx context.Context, runtime *libpod.Runtime, input stri
}
// This should not happen as checkpoints with these options are not exported.
- if (len(config.Dependencies) > 0) || (len(config.NamedVolumes) > 0) {
- return nil, errors.Errorf("Cannot import checkpoints of containers with named volumes or dependencies")
+ if len(config.Dependencies) > 0 {
+ return nil, errors.Errorf("Cannot import checkpoints of containers with dependencies")
+ }
+
+ // Volumes included in the checkpoint should not exist
+ if !restoreOptions.IgnoreVolumes {
+ for _, vol := range config.NamedVolumes {
+ exists, err := runtime.HasVolume(vol.Name)
+ if err != nil {
+ return nil, err
+ }
+ if exists {
+ return nil, errors.Errorf("volume with name %s already exists. Use --ignore-volumes to not restore content of volumes", vol.Name)
+ }
+ }
}
ctrID := config.ID
newName := false
// Check if the restored container gets a new name
- if name != "" {
+ if restoreOptions.Name != "" {
config.ID = ""
- config.Name = name
+ config.Name = restoreOptions.Name
newName = true
}
diff --git a/pkg/domain/entities/container_ps.go b/pkg/domain/entities/container_ps.go
index ff3b087ed..6709ca48a 100644
--- a/pkg/domain/entities/container_ps.go
+++ b/pkg/domain/entities/container_ps.go
@@ -43,6 +43,8 @@ type ListContainer struct {
// Namespaces the container belongs to. Requires the
// namespace boolean to be true
Namespaces ListContainerNamespaces
+ // The network names assigned to the container
+ Networks []string
// The process id of the container
Pid int
// If the container is part of Pod, the Pod ID. Requires the pod
diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go
index b8d49d067..d8576c101 100644
--- a/pkg/domain/entities/containers.go
+++ b/pkg/domain/entities/containers.go
@@ -173,10 +173,13 @@ type CheckpointOptions struct {
All bool
Export string
IgnoreRootFS bool
+ IgnoreVolumes bool
Keep bool
Latest bool
LeaveRunning bool
TCPEstablished bool
+ PreCheckPoint bool
+ WithPrevious bool
}
type CheckpointReport struct {
@@ -187,6 +190,7 @@ type CheckpointReport struct {
type RestoreOptions struct {
All bool
IgnoreRootFS bool
+ IgnoreVolumes bool
IgnoreStaticIP bool
IgnoreStaticMAC bool
Import string
@@ -194,6 +198,7 @@ type RestoreOptions struct {
Latest bool
Name string
TCPEstablished bool
+ ImportPrevious string
}
type RestoreReport struct {
@@ -390,13 +395,6 @@ type ContainerPruneOptions struct {
Filters url.Values `json:"filters" schema:"filters"`
}
-// ContainerPruneReport describes the results after pruning the
-// stopped containers.
-type ContainerPruneReport struct {
- ID map[string]int64
- Err map[string]error
-}
-
// ContainerPortOptions describes the options to obtain
// port information on containers
type ContainerPortOptions struct {
@@ -436,3 +434,9 @@ type ContainerStatsReport struct {
// Results, set when there is no error.
Stats []define.ContainerStats
}
+
+// ContainerRenameOptions describes input options for renaming a container.
+type ContainerRenameOptions struct {
+ // NewName is the new name that will be given to the container.
+ NewName string
+}
diff --git a/pkg/domain/entities/engine_container.go b/pkg/domain/entities/engine_container.go
index 80127ea45..d2552770c 100644
--- a/pkg/domain/entities/engine_container.go
+++ b/pkg/domain/entities/engine_container.go
@@ -6,6 +6,7 @@ import (
"github.com/containers/common/pkg/config"
"github.com/containers/podman/v2/libpod/define"
+ "github.com/containers/podman/v2/pkg/domain/entities/reports"
"github.com/containers/podman/v2/pkg/specgen"
"github.com/spf13/cobra"
)
@@ -35,7 +36,8 @@ type ContainerEngine interface {
ContainerMount(ctx context.Context, nameOrIDs []string, options ContainerMountOptions) ([]*ContainerMountReport, error)
ContainerPause(ctx context.Context, namesOrIds []string, options PauseUnPauseOptions) ([]*PauseUnpauseReport, error)
ContainerPort(ctx context.Context, nameOrID string, options ContainerPortOptions) ([]*ContainerPortReport, error)
- ContainerPrune(ctx context.Context, options ContainerPruneOptions) (*ContainerPruneReport, error)
+ ContainerPrune(ctx context.Context, options ContainerPruneOptions) ([]*reports.PruneReport, error)
+ ContainerRename(ctr context.Context, nameOrID string, options ContainerRenameOptions) error
ContainerRestart(ctx context.Context, namesOrIds []string, options RestartOptions) ([]*RestartReport, error)
ContainerRestore(ctx context.Context, namesOrIds []string, options RestoreOptions) ([]*RestoreReport, error)
ContainerRm(ctx context.Context, namesOrIds []string, options RmOptions) ([]*RmReport, error)
@@ -85,6 +87,6 @@ type ContainerEngine interface {
VolumeCreate(ctx context.Context, opts VolumeCreateOptions) (*IDOrNameResponse, error)
VolumeInspect(ctx context.Context, namesOrIds []string, opts InspectOptions) ([]*VolumeInspectReport, []error, error)
VolumeList(ctx context.Context, opts VolumeListOptions) ([]*VolumeListReport, error)
- VolumePrune(ctx context.Context, options VolumePruneOptions) ([]*VolumePruneReport, error)
+ VolumePrune(ctx context.Context, options VolumePruneOptions) ([]*reports.PruneReport, error)
VolumeRm(ctx context.Context, namesOrIds []string, opts VolumeRmOptions) ([]*VolumeRmReport, error)
}
diff --git a/pkg/domain/entities/engine_image.go b/pkg/domain/entities/engine_image.go
index 7f33d8e9d..26a136f13 100644
--- a/pkg/domain/entities/engine_image.go
+++ b/pkg/domain/entities/engine_image.go
@@ -4,6 +4,7 @@ import (
"context"
"github.com/containers/common/pkg/config"
+ "github.com/containers/podman/v2/pkg/domain/entities/reports"
)
type ImageEngine interface {
@@ -17,7 +18,7 @@ type ImageEngine interface {
List(ctx context.Context, opts ImageListOptions) ([]*ImageSummary, error)
Load(ctx context.Context, opts ImageLoadOptions) (*ImageLoadReport, error)
Mount(ctx context.Context, images []string, options ImageMountOptions) ([]*ImageMountReport, error)
- Prune(ctx context.Context, opts ImagePruneOptions) (*ImagePruneReport, error)
+ Prune(ctx context.Context, opts ImagePruneOptions) ([]*reports.PruneReport, error)
Pull(ctx context.Context, rawImage string, opts ImagePullOptions) (*ImagePullReport, error)
Push(ctx context.Context, source string, destination string, opts ImagePushOptions) error
Remove(ctx context.Context, images []string, opts ImageRemoveOptions) (*ImageRemoveReport, []error)
diff --git a/pkg/domain/entities/images.go b/pkg/domain/entities/images.go
index 67910a34c..0805152c3 100644
--- a/pkg/domain/entities/images.go
+++ b/pkg/domain/entities/images.go
@@ -247,11 +247,6 @@ type ImagePruneOptions struct {
Filter []string `json:"filter" schema:"filter"`
}
-type ImagePruneReport struct {
- Report Report
- Size int64
-}
-
type ImageTagOptions struct{}
type ImageUntagOptions struct{}
@@ -261,8 +256,6 @@ type ImageInspectReport struct {
}
type ImageLoadOptions struct {
- Name string
- Tag string
Input string
Quiet bool
SignaturePolicy string
diff --git a/pkg/domain/entities/play.go b/pkg/domain/entities/play.go
index 0b42e1a3f..6883fe6c5 100644
--- a/pkg/domain/entities/play.go
+++ b/pkg/domain/entities/play.go
@@ -40,6 +40,9 @@ type PlayKubePod struct {
Containers []string
// Logs - non-fatal errors and log messages while processing.
Logs []string
+ // ContainerErrors - any errors that occurred while starting containers
+ // in the pod.
+ ContainerErrors []string
}
// PlayKubeReport contains the results of running play kube.
diff --git a/pkg/domain/entities/pods.go b/pkg/domain/entities/pods.go
index 426419833..32900d536 100644
--- a/pkg/domain/entities/pods.go
+++ b/pkg/domain/entities/pods.go
@@ -28,8 +28,10 @@ type ListPodsReport struct {
InfraId string //nolint
Name string
Namespace string
- Status string
- Labels map[string]string
+ // Network names connected to infra container
+ Networks []string
+ Status string
+ Labels map[string]string
}
type ListPodContainer struct {
@@ -210,15 +212,16 @@ type PodStatsOptions struct {
// PodStatsReport includes pod-resource statistics data.
type PodStatsReport struct {
- CPU string
- MemUsage string
- Mem string
- NetIO string
- BlockIO string
- PIDS string
- Pod string
- CID string
- Name string
+ CPU string
+ MemUsage string
+ MemUsageBytes string
+ Mem string
+ NetIO string
+ BlockIO string
+ PIDS string
+ Pod string
+ CID string
+ Name string
}
// ValidatePodStatsOptions validates the specified slice and options. Allows
diff --git a/pkg/domain/entities/reports/prune.go b/pkg/domain/entities/reports/prune.go
new file mode 100644
index 000000000..5494ac3ae
--- /dev/null
+++ b/pkg/domain/entities/reports/prune.go
@@ -0,0 +1,40 @@
+package reports
+
+type PruneReport struct {
+ Id string //nolint
+ Err error
+ Size uint64
+}
+
+func PruneReportsIds(r []*PruneReport) []string {
+ ids := make([]string, 0, len(r))
+ for _, v := range r {
+ if v == nil || v.Id == "" {
+ continue
+ }
+ ids = append(ids, v.Id)
+ }
+ return ids
+}
+
+func PruneReportsErrs(r []*PruneReport) []error {
+ errs := make([]error, 0, len(r))
+ for _, v := range r {
+ if v == nil || v.Err == nil {
+ continue
+ }
+ errs = append(errs, v.Err)
+ }
+ return errs
+}
+
+func PruneReportsSize(r []*PruneReport) uint64 {
+ size := uint64(0)
+ for _, v := range r {
+ if v == nil {
+ continue
+ }
+ size = size + v.Size
+ }
+ return size
+}
diff --git a/pkg/domain/entities/system.go b/pkg/domain/entities/system.go
index d5118f6a8..99fa947f0 100644
--- a/pkg/domain/entities/system.go
+++ b/pkg/domain/entities/system.go
@@ -4,6 +4,7 @@ import (
"time"
"github.com/containers/podman/v2/libpod/define"
+ "github.com/containers/podman/v2/pkg/domain/entities/reports"
"github.com/docker/docker/api/types"
"github.com/spf13/cobra"
)
@@ -24,10 +25,11 @@ type SystemPruneOptions struct {
// SystemPruneReport provides report after system prune is executed.
type SystemPruneReport struct {
- PodPruneReport []*PodPruneReport
- *ContainerPruneReport
- *ImagePruneReport
- VolumePruneReport []*VolumePruneReport
+ PodPruneReport []*PodPruneReport
+ ContainerPruneReports []*reports.PruneReport
+ ImagePruneReports []*reports.PruneReport
+ VolumePruneReports []*reports.PruneReport
+ ReclaimedSpace uint64
}
// SystemMigrateOptions describes the options needed for the
diff --git a/pkg/domain/entities/types.go b/pkg/domain/entities/types.go
index 12135c2b1..e5473dc62 100644
--- a/pkg/domain/entities/types.go
+++ b/pkg/domain/entities/types.go
@@ -1,7 +1,6 @@
package entities
import (
- "errors"
"net"
"github.com/containers/buildah/imagebuildah"
@@ -90,29 +89,6 @@ type ContainerCreateResponse struct {
Warnings []string `json:"Warnings"`
}
-type ErrorModel struct {
- // API root cause formatted for automated parsing
- // example: API root cause
- Because string `json:"cause"`
- // human error message, formatted for a human to read
- // example: human error message
- Message string `json:"message"`
- // http response code
- ResponseCode int `json:"response"`
-}
-
-func (e ErrorModel) Error() string {
- return e.Message
-}
-
-func (e ErrorModel) Cause() error {
- return errors.New(e.Because)
-}
-
-func (e ErrorModel) Code() int {
- return e.ResponseCode
-}
-
// BuildOptions describe the options for building container images.
type BuildOptions struct {
imagebuildah.BuildOptions
diff --git a/pkg/domain/entities/volumes.go b/pkg/domain/entities/volumes.go
index e6b29e374..c826ee389 100644
--- a/pkg/domain/entities/volumes.go
+++ b/pkg/domain/entities/volumes.go
@@ -2,8 +2,8 @@ package entities
import (
"net/url"
- "time"
+ "github.com/containers/podman/v2/libpod/define"
docker_api_types "github.com/docker/docker/api/types"
docker_api_types_volume "github.com/docker/docker/api/types/volume"
)
@@ -26,38 +26,7 @@ type IDOrNameResponse struct {
}
type VolumeConfigResponse struct {
- // Name is the name of the volume.
- Name string `json:"Name"`
- // Driver is the driver used to create the volume.
- // This will be properly implemented in a future version.
- Driver string `json:"Driver"`
- // Mountpoint is the path on the host where the volume is mounted.
- Mountpoint string `json:"Mountpoint"`
- // CreatedAt is the date and time the volume was created at. This is not
- // stored for older Libpod volumes; if so, it will be omitted.
- CreatedAt time.Time `json:"CreatedAt,omitempty"`
- // Status is presently unused and provided only for Docker compatibility.
- // In the future it will be used to return information on the volume's
- // current state.
- Status map[string]string `json:"Status,omitempty"`
- // Labels includes the volume's configured labels, key:value pairs that
- // can be passed during volume creation to provide information for third
- // party tools.
- Labels map[string]string `json:"Labels"`
- // Scope is unused and provided solely for Docker compatibility. It is
- // unconditionally set to "local".
- Scope string `json:"Scope"`
- // Options is a set of options that were used when creating the volume.
- // It is presently not used.
- Options map[string]string `json:"Options"`
- // UID is the UID that the volume was created with.
- UID int `json:"UID"`
- // GID is the GID that the volume was created with.
- GID int `json:"GID"`
- // Anonymous indicates that the volume was created as an anonymous
- // volume for a specific container, and will be be removed when any
- // container using it is removed.
- Anonymous bool `json:"Anonymous"`
+ define.InspectVolumeData
}
// VolumeInfo Volume list response
@@ -116,11 +85,6 @@ type VolumePruneOptions struct {
Filters url.Values `json:"filters" schema:"filters"`
}
-type VolumePruneReport struct {
- Err error
- Id string //nolint
-}
-
type VolumeListOptions struct {
Filter map[string][]string
}
diff --git a/pkg/domain/filters/containers.go b/pkg/domain/filters/containers.go
index 6abdd6b57..1de5aca91 100644
--- a/pkg/domain/filters/containers.go
+++ b/pkg/domain/filters/containers.go
@@ -7,6 +7,7 @@ import (
"github.com/containers/podman/v2/libpod"
"github.com/containers/podman/v2/libpod/define"
+ "github.com/containers/podman/v2/libpod/network"
"github.com/containers/podman/v2/pkg/timetype"
"github.com/containers/podman/v2/pkg/util"
"github.com/pkg/errors"
@@ -34,7 +35,7 @@ func GenerateContainerFilterFuncs(filter string, filterValues []string, r *libpo
filterValue = ""
}
for labelKey, labelValue := range labels {
- if labelKey == filterKey && ("" == filterValue || labelValue == filterValue) {
+ if labelKey == filterKey && (filterValue == "" || labelValue == filterValue) {
matched = true
break
}
@@ -233,7 +234,24 @@ func GenerateContainerFilterFuncs(filter string, filterValues []string, r *libpo
}
return false
}, nil
-
+ case "network":
+ return func(c *libpod.Container) bool {
+ networks, _, err := c.Networks()
+ // if err or no networks, quick out
+ if err != nil || len(networks) == 0 {
+ return false
+ }
+ for _, net := range networks {
+ netID := network.GetNetworkID(net)
+ for _, val := range filterValues {
+ // match by network name or id
+ if val == net || val == netID {
+ return true
+ }
+ }
+ }
+ return false
+ }, nil
}
return nil, errors.Errorf("%s is an invalid filter", filter)
}
diff --git a/pkg/domain/filters/pods.go b/pkg/domain/filters/pods.go
index 7e6b7f2cc..ce7028d2a 100644
--- a/pkg/domain/filters/pods.go
+++ b/pkg/domain/filters/pods.go
@@ -6,6 +6,7 @@ import (
"github.com/containers/podman/v2/libpod"
"github.com/containers/podman/v2/libpod/define"
+ "github.com/containers/podman/v2/libpod/network"
"github.com/containers/podman/v2/pkg/util"
"github.com/pkg/errors"
)
@@ -123,7 +124,7 @@ func GeneratePodFilterFunc(filter string, filterValues []string) (
filterValue = ""
}
for labelKey, labelValue := range labels {
- if labelKey == filterKey && ("" == filterValue || labelValue == filterValue) {
+ if labelKey == filterKey && (filterValue == "" || labelValue == filterValue) {
matched = true
break
}
@@ -134,6 +135,29 @@ func GeneratePodFilterFunc(filter string, filterValues []string) (
}
return true
}, nil
+ case "network":
+ return func(p *libpod.Pod) bool {
+ infra, err := p.InfraContainer()
+ // no infra, quick out
+ if err != nil {
+ return false
+ }
+ networks, _, err := infra.Networks()
+ // if err or no networks, quick out
+ if err != nil || len(networks) == 0 {
+ return false
+ }
+ for _, net := range networks {
+ netID := network.GetNetworkID(net)
+ for _, val := range filterValues {
+ // match by network name or id
+ if val == net || val == netID {
+ return true
+ }
+ }
+ }
+ return false
+ }, nil
}
return nil, errors.Errorf("%s is an invalid filter", filter)
}
diff --git a/pkg/domain/filters/volumes.go b/pkg/domain/filters/volumes.go
index 69bef4961..7890459f5 100644
--- a/pkg/domain/filters/volumes.go
+++ b/pkg/domain/filters/volumes.go
@@ -39,7 +39,7 @@ func GenerateVolumeFilters(filters url.Values) ([]libpod.VolumeFilter, error) {
}
vf = append(vf, func(v *libpod.Volume) bool {
for labelKey, labelValue := range v.Labels() {
- if labelKey == filterKey && ("" == filterVal || labelValue == filterVal) {
+ if labelKey == filterKey && (filterVal == "" || labelValue == filterVal) {
return true
}
}
@@ -56,7 +56,7 @@ func GenerateVolumeFilters(filters url.Values) ([]libpod.VolumeFilter, error) {
}
vf = append(vf, func(v *libpod.Volume) bool {
for labelKey, labelValue := range v.Options() {
- if labelKey == filterKey && ("" == filterVal || labelValue == filterVal) {
+ if labelKey == filterKey && (filterVal == "" || labelValue == filterVal) {
return true
}
}
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go
index cfb3421ba..a8f4d44a8 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -21,6 +21,7 @@ import (
"github.com/containers/podman/v2/pkg/cgroups"
"github.com/containers/podman/v2/pkg/checkpoint"
"github.com/containers/podman/v2/pkg/domain/entities"
+ "github.com/containers/podman/v2/pkg/domain/entities/reports"
dfilters "github.com/containers/podman/v2/pkg/domain/filters"
"github.com/containers/podman/v2/pkg/domain/infra/abi/terminal"
parallelctr "github.com/containers/podman/v2/pkg/parallel/ctr"
@@ -112,15 +113,7 @@ func (ic *ContainerEngine) ContainerWait(ctx context.Context, namesOrIds []strin
}
func (ic *ContainerEngine) ContainerPause(ctx context.Context, namesOrIds []string, options entities.PauseUnPauseOptions) ([]*entities.PauseUnpauseReport, error) {
- var (
- err error
- )
- ctrs := []*libpod.Container{} //nolint
- if options.All {
- ctrs, err = ic.Libpod.GetAllContainers()
- } else {
- ctrs, err = getContainersByContext(false, false, namesOrIds, ic.Libpod)
- }
+ ctrs, err := getContainersByContext(options.All, false, namesOrIds, ic.Libpod)
if err != nil {
return nil, err
}
@@ -133,15 +126,7 @@ func (ic *ContainerEngine) ContainerPause(ctx context.Context, namesOrIds []stri
}
func (ic *ContainerEngine) ContainerUnpause(ctx context.Context, namesOrIds []string, options entities.PauseUnPauseOptions) ([]*entities.PauseUnpauseReport, error) {
- var (
- err error
- )
- ctrs := []*libpod.Container{} //nolint
- if options.All {
- ctrs, err = ic.Libpod.GetAllContainers()
- } else {
- ctrs, err = getContainersByContext(false, false, namesOrIds, ic.Libpod)
- }
+ ctrs, err := getContainersByContext(options.All, false, namesOrIds, ic.Libpod)
if err != nil {
return nil, err
}
@@ -204,7 +189,7 @@ func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []strin
return reports, nil
}
-func (ic *ContainerEngine) ContainerPrune(ctx context.Context, options entities.ContainerPruneOptions) (*entities.ContainerPruneReport, error) {
+func (ic *ContainerEngine) ContainerPrune(ctx context.Context, options entities.ContainerPruneOptions) ([]*reports.PruneReport, error) {
filterFuncs := make([]libpod.ContainerFilter, 0, len(options.Filters))
for k, v := range options.Filters {
generatedFunc, err := dfilters.GenerateContainerFilterFuncs(k, v, ic.Libpod)
@@ -213,19 +198,7 @@ func (ic *ContainerEngine) ContainerPrune(ctx context.Context, options entities.
}
filterFuncs = append(filterFuncs, generatedFunc)
}
- return ic.pruneContainersHelper(filterFuncs)
-}
-
-func (ic *ContainerEngine) pruneContainersHelper(filterFuncs []libpod.ContainerFilter) (*entities.ContainerPruneReport, error) {
- prunedContainers, pruneErrors, err := ic.Libpod.PruneContainers(filterFuncs)
- if err != nil {
- return nil, err
- }
- report := entities.ContainerPruneReport{
- ID: prunedContainers,
- Err: pruneErrors,
- }
- return &report, nil
+ return ic.Libpod.PruneContainers(filterFuncs)
}
func (ic *ContainerEngine) ContainerKill(ctx context.Context, namesOrIds []string, options entities.KillOptions) ([]*entities.KillReport, error) {
@@ -498,7 +471,10 @@ func (ic *ContainerEngine) ContainerCheckpoint(ctx context.Context, namesOrIds [
TCPEstablished: options.TCPEstablished,
TargetFile: options.Export,
IgnoreRootfs: options.IgnoreRootFS,
+ IgnoreVolumes: options.IgnoreVolumes,
KeepRunning: options.LeaveRunning,
+ PreCheckPoint: options.PreCheckPoint,
+ WithPrevious: options.WithPrevious,
}
if options.All {
@@ -536,8 +512,10 @@ func (ic *ContainerEngine) ContainerRestore(ctx context.Context, namesOrIds []st
TargetFile: options.Import,
Name: options.Name,
IgnoreRootfs: options.IgnoreRootFS,
+ IgnoreVolumes: options.IgnoreVolumes,
IgnoreStaticIP: options.IgnoreStaticIP,
IgnoreStaticMAC: options.IgnoreStaticMAC,
+ ImportPrevious: options.ImportPrevious,
}
filterFuncs := []libpod.ContainerFilter{
@@ -549,7 +527,7 @@ func (ic *ContainerEngine) ContainerRestore(ctx context.Context, namesOrIds []st
switch {
case options.Import != "":
- cons, err = checkpoint.CRImportCheckpoint(ctx, ic.Libpod, options.Import, options.Name)
+ cons, err = checkpoint.CRImportCheckpoint(ctx, ic.Libpod, options)
case options.All:
cons, err = ic.Libpod.GetContainers(filterFuncs...)
default:
@@ -924,7 +902,7 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
if err := ic.Libpod.RemoveContainer(ctx, ctr, false, true); err != nil {
if errors.Cause(err) == define.ErrNoSuchCtr ||
errors.Cause(err) == define.ErrCtrRemoved {
- logrus.Warnf("Container %s does not exist: %v", ctr.ID(), err)
+ logrus.Infof("Container %s was already removed, skipping --rm", ctr.ID())
} else {
logrus.Errorf("Error removing container %s: %v", ctr.ID(), err)
}
@@ -1334,3 +1312,17 @@ func (ic *ContainerEngine) ShouldRestart(ctx context.Context, nameOrID string) (
return &entities.BoolReport{Value: ctr.ShouldRestart(ctx)}, nil
}
+
+// ContainerRename renames the given container.
+func (ic *ContainerEngine) ContainerRename(ctx context.Context, nameOrID string, opts entities.ContainerRenameOptions) error {
+ ctr, err := ic.Libpod.LookupContainer(nameOrID)
+ if err != nil {
+ return err
+ }
+
+ if _, err := ic.Libpod.RenameContainer(ctx, ctr, opts.NewName); err != nil {
+ return err
+ }
+
+ return nil
+}
diff --git a/pkg/domain/infra/abi/containers_stat.go b/pkg/domain/infra/abi/containers_stat.go
index 5b43ee2f4..931e77026 100644
--- a/pkg/domain/infra/abi/containers_stat.go
+++ b/pkg/domain/infra/abi/containers_stat.go
@@ -144,16 +144,29 @@ func resolveContainerPaths(container *libpod.Container, mountPoint string, conta
}
if volume != nil {
logrus.Debugf("Container path %q resolved to volume %q on path %q", containerPath, volume.Name(), searchPath)
+
+ // TODO: We really need to force the volume to mount
+ // before doing this, but that API is not exposed
+ // externally right now and doing so is beyond the scope
+ // of this commit.
+ mountPoint, err := volume.MountPoint()
+ if err != nil {
+ return "", "", err
+ }
+ if mountPoint == "" {
+ return "", "", errors.Errorf("volume %s is not mounted, cannot copy into it", volume.Name())
+ }
+
// We found a matching volume for searchPath. We now
// need to first find the relative path of our input
// path to the searchPath, and then join it with the
// volume's mount point.
pathRelativeToVolume := strings.TrimPrefix(pathRelativeToContainerMountPoint, searchPath)
- absolutePathOnTheVolumeMount, err := securejoin.SecureJoin(volume.MountPoint(), pathRelativeToVolume)
+ absolutePathOnTheVolumeMount, err := securejoin.SecureJoin(mountPoint, pathRelativeToVolume)
if err != nil {
return "", "", err
}
- return volume.MountPoint(), absolutePathOnTheVolumeMount, nil
+ return mountPoint, absolutePathOnTheVolumeMount, nil
}
if mount := findBindMount(container, searchPath); mount != nil {
diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go
index 394ba359c..1c233d9d5 100644
--- a/pkg/domain/infra/abi/images.go
+++ b/pkg/domain/infra/abi/images.go
@@ -22,8 +22,8 @@ import (
"github.com/containers/image/v5/types"
"github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/libpod/image"
- libpodImage "github.com/containers/podman/v2/libpod/image"
"github.com/containers/podman/v2/pkg/domain/entities"
+ "github.com/containers/podman/v2/pkg/domain/entities/reports"
domainUtils "github.com/containers/podman/v2/pkg/domain/utils"
"github.com/containers/podman/v2/pkg/rootless"
"github.com/containers/podman/v2/pkg/util"
@@ -49,19 +49,12 @@ func (ir *ImageEngine) Exists(_ context.Context, nameOrID string) (*entities.Boo
return &entities.BoolReport{Value: err == nil}, nil
}
-func (ir *ImageEngine) Prune(ctx context.Context, opts entities.ImagePruneOptions) (*entities.ImagePruneReport, error) {
- results, err := ir.Libpod.ImageRuntime().PruneImages(ctx, opts.All, opts.Filter)
+func (ir *ImageEngine) Prune(ctx context.Context, opts entities.ImagePruneOptions) ([]*reports.PruneReport, error) {
+ reports, err := ir.Libpod.ImageRuntime().PruneImages(ctx, opts.All, opts.Filter)
if err != nil {
return nil, err
}
-
- report := entities.ImagePruneReport{
- Report: entities.Report{
- Id: results,
- Err: nil,
- },
- }
- return &report, nil
+ return reports, err
}
func (ir *ImageEngine) History(ctx context.Context, nameOrID string, opts entities.ImageHistoryOptions) (*entities.ImageHistoryReport, error) {
@@ -212,7 +205,7 @@ func (ir *ImageEngine) Unmount(ctx context.Context, nameOrIDs []string, options
return reports, nil
}
-func ToDomainHistoryLayer(layer *libpodImage.History) entities.ImageHistoryLayer {
+func ToDomainHistoryLayer(layer *image.History) entities.ImageHistoryLayer {
l := entities.ImageHistoryLayer{}
l.ID = layer.ID
l.Created = *layer.Created
@@ -460,19 +453,7 @@ func (ir *ImageEngine) Load(ctx context.Context, opts entities.ImageLoadOptions)
if err != nil {
return nil, err
}
- names := strings.Split(name, ",")
- if len(names) <= 1 {
- newImage, err := ir.Libpod.ImageRuntime().NewFromLocal(name)
- if err != nil {
- return nil, errors.Wrap(err, "image loaded but no additional tags were created")
- }
- if len(opts.Name) > 0 {
- if err := newImage.TagImage(fmt.Sprintf("%s:%s", opts.Name, opts.Tag)); err != nil {
- return nil, errors.Wrapf(err, "error adding %q to image %q", opts.Name, newImage.InputName)
- }
- }
- }
- return &entities.ImageLoadReport{Names: names}, nil
+ return &entities.ImageLoadReport{Names: strings.Split(name, ",")}, nil
}
func (ir *ImageEngine) Import(ctx context.Context, opts entities.ImageImportOptions) (*entities.ImageImportReport, error) {
diff --git a/pkg/domain/infra/abi/images_list.go b/pkg/domain/infra/abi/images_list.go
index c4b0b7712..2d3b9f36a 100644
--- a/pkg/domain/infra/abi/images_list.go
+++ b/pkg/domain/infra/abi/images_list.go
@@ -44,7 +44,10 @@ func (ir *ImageEngine) List(ctx context.Context, opts entities.ImageListOptions)
}
e.Labels, err = img.Labels(ctx)
if err != nil {
- return nil, errors.Wrapf(err, "error retrieving label for image %q: you may need to remove the image to resolve the error", img.ID())
+ // Ignore empty manifest lists.
+ if errors.Cause(err) != libpodImage.ErrImageIsBareList {
+ return nil, errors.Wrapf(err, "error retrieving label for image %q: you may need to remove the image to resolve the error", img.ID())
+ }
}
ctnrs, err := img.Containers()
diff --git a/pkg/domain/infra/abi/manifest.go b/pkg/domain/infra/abi/manifest.go
index 0c734d10d..a68ed8788 100644
--- a/pkg/domain/infra/abi/manifest.go
+++ b/pkg/domain/infra/abi/manifest.go
@@ -13,7 +13,6 @@ import (
"github.com/containers/buildah/manifests"
buildahManifests "github.com/containers/buildah/pkg/manifests"
- "github.com/containers/buildah/util"
buildahUtil "github.com/containers/buildah/util"
cp "github.com/containers/image/v5/copy"
"github.com/containers/image/v5/docker"
@@ -60,7 +59,7 @@ func (ir *ImageEngine) ManifestInspect(ctx context.Context, name string) ([]byte
}
}
sc := ir.Libpod.SystemContext()
- refs, err := util.ResolveNameToReferences(ir.Libpod.GetStore(), sc, name)
+ refs, err := buildahUtil.ResolveNameToReferences(ir.Libpod.GetStore(), sc, name)
if err != nil {
return nil, err
}
diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go
index cbc74a2f2..70c7104f1 100644
--- a/pkg/domain/infra/abi/play.go
+++ b/pkg/domain/infra/abi/play.go
@@ -10,6 +10,7 @@ import (
"github.com/containers/image/v5/types"
"github.com/containers/podman/v2/libpod"
+ "github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/libpod/image"
"github.com/containers/podman/v2/pkg/domain/entities"
"github.com/containers/podman/v2/pkg/specgen/generate"
@@ -251,21 +252,13 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
}
if options.Start != types.OptionalBoolFalse {
- //start the containers
+ // Start the containers
podStartErrors, err := pod.Start(ctx)
- if err != nil {
+ if err != nil && errors.Cause(err) != define.ErrPodPartialFail {
return nil, err
}
-
- // Previous versions of playkube started containers individually and then
- // looked for errors. Because we now use the uber-Pod start call, we should
- // iterate the map of possible errors and return one if there is a problem. This
- // keeps the behavior the same
-
- for _, e := range podStartErrors {
- if e != nil {
- return nil, e
- }
+ for id, err := range podStartErrors {
+ playKubePod.ContainerErrors = append(playKubePod.ContainerErrors, errors.Wrapf(err, "error starting container %s", id).Error())
}
}
diff --git a/pkg/domain/infra/abi/pods.go b/pkg/domain/infra/abi/pods.go
index f108b770c..2a8445c9f 100644
--- a/pkg/domain/infra/abi/pods.go
+++ b/pkg/domain/infra/abi/pods.go
@@ -333,6 +333,17 @@ func (ic *ContainerEngine) PodPs(ctx context.Context, options entities.PodPSOpti
if err != nil {
return nil, err
}
+ networks := []string{}
+ if len(infraID) > 0 {
+ infra, err := p.InfraContainer()
+ if err != nil {
+ return nil, err
+ }
+ networks, _, err = infra.Networks()
+ if err != nil {
+ return nil, err
+ }
+ }
reports = append(reports, &entities.ListPodsReport{
Cgroup: p.CgroupParent(),
Containers: lpcs,
@@ -341,6 +352,7 @@ func (ic *ContainerEngine) PodPs(ctx context.Context, options entities.PodPSOpti
InfraId: infraID,
Name: p.Name(),
Namespace: p.Namespace(),
+ Networks: networks,
Status: status,
Labels: p.Labels(),
})
diff --git a/pkg/domain/infra/abi/pods_stats.go b/pkg/domain/infra/abi/pods_stats.go
index 16c10710a..29bcbe087 100644
--- a/pkg/domain/infra/abi/pods_stats.go
+++ b/pkg/domain/infra/abi/pods_stats.go
@@ -44,15 +44,16 @@ func (ic *ContainerEngine) podsToStatsReport(pods []*libpod.Pod) ([]*entities.Po
podID := pods[i].ID()[:12]
for j := range podStats {
r := entities.PodStatsReport{
- CPU: floatToPercentString(podStats[j].CPU),
- MemUsage: combineHumanValues(podStats[j].MemUsage, podStats[j].MemLimit),
- Mem: floatToPercentString(podStats[j].MemPerc),
- NetIO: combineHumanValues(podStats[j].NetInput, podStats[j].NetOutput),
- BlockIO: combineHumanValues(podStats[j].BlockInput, podStats[j].BlockOutput),
- PIDS: pidsToString(podStats[j].PIDs),
- CID: podStats[j].ContainerID[:12],
- Name: podStats[j].Name,
- Pod: podID,
+ CPU: floatToPercentString(podStats[j].CPU),
+ MemUsage: combineHumanValues(podStats[j].MemUsage, podStats[j].MemLimit),
+ MemUsageBytes: combineBytesValues(podStats[j].MemUsage, podStats[j].MemLimit),
+ Mem: floatToPercentString(podStats[j].MemPerc),
+ NetIO: combineHumanValues(podStats[j].NetInput, podStats[j].NetOutput),
+ BlockIO: combineHumanValues(podStats[j].BlockInput, podStats[j].BlockOutput),
+ PIDS: pidsToString(podStats[j].PIDs),
+ CID: podStats[j].ContainerID[:12],
+ Name: podStats[j].Name,
+ Pod: podID,
}
reports = append(reports, &r)
}
@@ -68,6 +69,13 @@ func combineHumanValues(a, b uint64) string {
return fmt.Sprintf("%s / %s", units.HumanSize(float64(a)), units.HumanSize(float64(b)))
}
+func combineBytesValues(a, b uint64) string {
+ if a == 0 && b == 0 {
+ return "-- / --"
+ }
+ return fmt.Sprintf("%s / %s", units.BytesSize(float64(a)), units.BytesSize(float64(b)))
+}
+
func floatToPercentString(f float64) string {
strippedFloat, err := utils.RemoveScientificNotationFromFloat(f)
if err != nil || strippedFloat == 0 {
diff --git a/pkg/domain/infra/abi/system.go b/pkg/domain/infra/abi/system.go
index 5f6c95d4f..f29b98696 100644
--- a/pkg/domain/infra/abi/system.go
+++ b/pkg/domain/infra/abi/system.go
@@ -16,6 +16,7 @@ import (
"github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/pkg/cgroups"
"github.com/containers/podman/v2/pkg/domain/entities"
+ "github.com/containers/podman/v2/pkg/domain/entities/reports"
"github.com/containers/podman/v2/pkg/rootless"
"github.com/containers/podman/v2/pkg/util"
"github.com/containers/podman/v2/utils"
@@ -161,15 +162,11 @@ func movePauseProcessToScope(r *libpod.Runtime) error {
return utils.RunUnderSystemdScope(int(pid), "user.slice", "podman-pause.scope")
}
-// checkInput can be used to verify any of the globalopt values
-func checkInput() error { // nolint:deadcode,unused
- return nil
-}
-
// SystemPrune removes unused data from the system. Pruning pods, containers, volumes and images.
func (ic *ContainerEngine) SystemPrune(ctx context.Context, options entities.SystemPruneOptions) (*entities.SystemPruneReport, error) {
var systemPruneReport = new(entities.SystemPruneReport)
var filters []string
+ reclaimedSpace := (uint64)(0)
found := true
for found {
found = false
@@ -186,42 +183,26 @@ func (ic *ContainerEngine) SystemPrune(ctx context.Context, options entities.Sys
containerPruneOptions := entities.ContainerPruneOptions{}
containerPruneOptions.Filters = (url.Values)(options.Filters)
- containerPruneReport, err := ic.ContainerPrune(ctx, containerPruneOptions)
+ containerPruneReports, err := ic.ContainerPrune(ctx, containerPruneOptions)
if err != nil {
return nil, err
}
- if len(containerPruneReport.ID) > 0 {
- found = true
- }
- if systemPruneReport.ContainerPruneReport == nil {
- systemPruneReport.ContainerPruneReport = containerPruneReport
- } else {
- for name, val := range containerPruneReport.ID {
- systemPruneReport.ContainerPruneReport.ID[name] = val
- }
- }
+ reclaimedSpace = reclaimedSpace + reports.PruneReportsSize(containerPruneReports)
+ systemPruneReport.ContainerPruneReports = append(systemPruneReport.ContainerPruneReports, containerPruneReports...)
for k, v := range options.Filters {
filters = append(filters, fmt.Sprintf("%s=%s", k, v[0]))
}
- results, err := ic.Libpod.ImageRuntime().PruneImages(ctx, options.All, filters)
+ imagePruneReports, err := ic.Libpod.ImageRuntime().PruneImages(ctx, options.All, filters)
+ reclaimedSpace = reclaimedSpace + reports.PruneReportsSize(imagePruneReports)
if err != nil {
return nil, err
}
- if len(results) > 0 {
+ if len(imagePruneReports) > 0 {
found = true
}
- if systemPruneReport.ImagePruneReport == nil {
- systemPruneReport.ImagePruneReport = &entities.ImagePruneReport{
- Report: entities.Report{
- Id: results,
- Err: nil,
- },
- }
- } else {
- systemPruneReport.ImagePruneReport.Report.Id = append(systemPruneReport.ImagePruneReport.Report.Id, results...)
- }
+ systemPruneReport.ImagePruneReports = append(systemPruneReport.ImagePruneReports, imagePruneReports...)
if options.Volume {
volumePruneOptions := entities.VolumePruneOptions{}
volumePruneOptions.Filters = (url.Values)(options.Filters)
@@ -232,9 +213,11 @@ func (ic *ContainerEngine) SystemPrune(ctx context.Context, options entities.Sys
if len(volumePruneReport) > 0 {
found = true
}
- systemPruneReport.VolumePruneReport = append(systemPruneReport.VolumePruneReport, volumePruneReport...)
+ reclaimedSpace = reclaimedSpace + reports.PruneReportsSize(volumePruneReport)
+ systemPruneReport.VolumePruneReports = append(systemPruneReport.VolumePruneReports, volumePruneReport...)
}
}
+ systemPruneReport.ReclaimedSpace = reclaimedSpace
return systemPruneReport, nil
}
@@ -329,7 +312,17 @@ func (ic *ContainerEngine) SystemDf(ctx context.Context, options entities.System
var reclaimableSize int64
for _, v := range vols {
var consInUse int
- volSize, err := sizeOfPath(v.MountPoint())
+ mountPoint, err := v.MountPoint()
+ if err != nil {
+ return nil, err
+ }
+ if mountPoint == "" {
+ // We can't get any info on this volume, as it's not
+ // mounted.
+ // TODO: fix this.
+ continue
+ }
+ volSize, err := sizeOfPath(mountPoint)
if err != nil {
return nil, err
}
diff --git a/pkg/domain/infra/abi/volumes.go b/pkg/domain/infra/abi/volumes.go
index 515e52754..823605052 100644
--- a/pkg/domain/infra/abi/volumes.go
+++ b/pkg/domain/infra/abi/volumes.go
@@ -6,6 +6,7 @@ import (
"github.com/containers/podman/v2/libpod"
"github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/pkg/domain/entities"
+ "github.com/containers/podman/v2/pkg/domain/entities/reports"
"github.com/containers/podman/v2/pkg/domain/filters"
"github.com/containers/podman/v2/pkg/domain/infra/abi/parse"
"github.com/pkg/errors"
@@ -102,32 +103,19 @@ func (ic *ContainerEngine) VolumeInspect(ctx context.Context, namesOrIds []strin
}
reports := make([]*entities.VolumeInspectReport, 0, len(vols))
for _, v := range vols {
- var uid, gid int
- uid, err = v.UID()
- if err != nil {
- return nil, nil, err
- }
- gid, err = v.GID()
+ inspectOut, err := v.Inspect()
if err != nil {
return nil, nil, err
}
config := entities.VolumeConfigResponse{
- Name: v.Name(),
- Driver: v.Driver(),
- Mountpoint: v.MountPoint(),
- CreatedAt: v.CreatedTime(),
- Labels: v.Labels(),
- Scope: v.Scope(),
- Options: v.Options(),
- UID: uid,
- GID: gid,
+ InspectVolumeData: *inspectOut,
}
reports = append(reports, &entities.VolumeInspectReport{VolumeConfigResponse: &config})
}
return reports, errs, nil
}
-func (ic *ContainerEngine) VolumePrune(ctx context.Context, options entities.VolumePruneOptions) ([]*entities.VolumePruneReport, error) {
+func (ic *ContainerEngine) VolumePrune(ctx context.Context, options entities.VolumePruneOptions) ([]*reports.PruneReport, error) {
filterFuncs, err := filters.GenerateVolumeFilters(options.Filters)
if err != nil {
return nil, err
@@ -135,19 +123,12 @@ func (ic *ContainerEngine) VolumePrune(ctx context.Context, options entities.Vol
return ic.pruneVolumesHelper(ctx, filterFuncs)
}
-func (ic *ContainerEngine) pruneVolumesHelper(ctx context.Context, filterFuncs []libpod.VolumeFilter) ([]*entities.VolumePruneReport, error) {
+func (ic *ContainerEngine) pruneVolumesHelper(ctx context.Context, filterFuncs []libpod.VolumeFilter) ([]*reports.PruneReport, error) {
pruned, err := ic.Libpod.PruneVolumes(ctx, filterFuncs)
if err != nil {
return nil, err
}
- reports := make([]*entities.VolumePruneReport, 0, len(pruned))
- for k, v := range pruned {
- reports = append(reports, &entities.VolumePruneReport{
- Err: v,
- Id: k,
- })
- }
- return reports, nil
+ return pruned, nil
}
func (ic *ContainerEngine) VolumeList(ctx context.Context, opts entities.VolumeListOptions) ([]*entities.VolumeListReport, error) {
@@ -161,25 +142,12 @@ func (ic *ContainerEngine) VolumeList(ctx context.Context, opts entities.VolumeL
}
reports := make([]*entities.VolumeListReport, 0, len(vols))
for _, v := range vols {
- var uid, gid int
- uid, err = v.UID()
- if err != nil {
- return nil, err
- }
- gid, err = v.GID()
+ inspectOut, err := v.Inspect()
if err != nil {
return nil, err
}
config := entities.VolumeConfigResponse{
- Name: v.Name(),
- Driver: v.Driver(),
- Mountpoint: v.MountPoint(),
- CreatedAt: v.CreatedTime(),
- Labels: v.Labels(),
- Scope: v.Scope(),
- Options: v.Options(),
- UID: uid,
- GID: gid,
+ InspectVolumeData: *inspectOut,
}
reports = append(reports, &entities.VolumeListReport{VolumeConfigResponse: config})
}
diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go
index 0db985dff..4ee623703 100644
--- a/pkg/domain/infra/tunnel/containers.go
+++ b/pkg/domain/infra/tunnel/containers.go
@@ -18,6 +18,7 @@ import (
"github.com/containers/podman/v2/pkg/api/handlers"
"github.com/containers/podman/v2/pkg/bindings/containers"
"github.com/containers/podman/v2/pkg/domain/entities"
+ "github.com/containers/podman/v2/pkg/domain/entities/reports"
"github.com/containers/podman/v2/pkg/errorhandling"
"github.com/containers/podman/v2/pkg/specgen"
"github.com/containers/podman/v2/pkg/util"
@@ -196,7 +197,7 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
return reports, nil
}
-func (ic *ContainerEngine) ContainerPrune(ctx context.Context, opts entities.ContainerPruneOptions) (*entities.ContainerPruneReport, error) {
+func (ic *ContainerEngine) ContainerPrune(ctx context.Context, opts entities.ContainerPruneOptions) ([]*reports.PruneReport, error) {
options := new(containers.PruneOptions).WithFilters(opts.Filters)
return containers.Prune(ic.ClientCtx, options)
}
@@ -210,7 +211,7 @@ func (ic *ContainerEngine) ContainerInspect(ctx context.Context, namesOrIds []st
for _, name := range namesOrIds {
inspect, err := containers.Inspect(ic.ClientCtx, name, options)
if err != nil {
- errModel, ok := err.(entities.ErrorModel)
+ errModel, ok := err.(errorhandling.ErrorModel)
if !ok {
return nil, nil, err
}
@@ -819,3 +820,8 @@ func (ic *ContainerEngine) ContainerStats(ctx context.Context, namesOrIds []stri
func (ic *ContainerEngine) ShouldRestart(_ context.Context, id string) (bool, error) {
return containers.ShouldRestart(ic.ClientCtx, id, nil)
}
+
+// ContainerRename renames the given container.
+func (ic *ContainerEngine) ContainerRename(ctx context.Context, nameOrID string, opts entities.ContainerRenameOptions) error {
+ return containers.Rename(ic.ClientCtx, nameOrID, new(containers.RenameOptions).WithName(opts.NewName))
+}
diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go
index 10bf9682c..7a4aa1fbc 100644
--- a/pkg/domain/infra/tunnel/images.go
+++ b/pkg/domain/infra/tunnel/images.go
@@ -8,15 +8,15 @@ import (
"strings"
"time"
- "github.com/containers/podman/v2/libpod/image"
-
- "github.com/containers/image/v5/types"
-
"github.com/containers/common/pkg/config"
"github.com/containers/image/v5/docker/reference"
+ "github.com/containers/image/v5/types"
+ "github.com/containers/podman/v2/libpod/image"
images "github.com/containers/podman/v2/pkg/bindings/images"
"github.com/containers/podman/v2/pkg/domain/entities"
+ "github.com/containers/podman/v2/pkg/domain/entities/reports"
"github.com/containers/podman/v2/pkg/domain/utils"
+ "github.com/containers/podman/v2/pkg/errorhandling"
utils2 "github.com/containers/podman/v2/utils"
"github.com/pkg/errors"
)
@@ -90,26 +90,18 @@ func (ir *ImageEngine) History(ctx context.Context, nameOrID string, opts entiti
return &history, nil
}
-func (ir *ImageEngine) Prune(ctx context.Context, opts entities.ImagePruneOptions) (*entities.ImagePruneReport, error) {
+func (ir *ImageEngine) Prune(ctx context.Context, opts entities.ImagePruneOptions) ([]*reports.PruneReport, error) {
filters := make(map[string][]string, len(opts.Filter))
for _, filter := range opts.Filter {
f := strings.Split(filter, "=")
filters[f[0]] = f[1:]
}
options := new(images.PruneOptions).WithAll(opts.All).WithFilters(filters)
- results, err := images.Prune(ir.ClientCtx, options)
+ reports, err := images.Prune(ir.ClientCtx, options)
if err != nil {
return nil, err
}
-
- report := entities.ImagePruneReport{
- Report: entities.Report{
- Id: results,
- Err: nil,
- },
- Size: 0,
- }
- return &report, nil
+ return reports, nil
}
func (ir *ImageEngine) Pull(ctx context.Context, rawImage string, opts entities.ImagePullOptions) (*entities.ImagePullReport, error) {
@@ -194,7 +186,7 @@ func (ir *ImageEngine) Inspect(ctx context.Context, namesOrIDs []string, opts en
for _, i := range namesOrIDs {
r, err := images.GetImage(ir.ClientCtx, i, options)
if err != nil {
- errModel, ok := err.(entities.ErrorModel)
+ errModel, ok := err.(errorhandling.ErrorModel)
if !ok {
return nil, nil, err
}
@@ -222,12 +214,7 @@ func (ir *ImageEngine) Load(ctx context.Context, opts entities.ImageLoadOptions)
if fInfo.IsDir() {
return nil, errors.Errorf("remote client supports archives only but %q is a directory", opts.Input)
}
- ref := opts.Name
- if len(opts.Tag) > 0 {
- ref += ":" + opts.Tag
- }
- options := new(images.LoadOptions).WithReference(ref)
- return images.Load(ir.ClientCtx, f, options)
+ return images.Load(ir.ClientCtx, f)
}
func (ir *ImageEngine) Import(ctx context.Context, opts entities.ImageImportOptions) (*entities.ImageImportReport, error) {
diff --git a/pkg/domain/infra/tunnel/network.go b/pkg/domain/infra/tunnel/network.go
index 9afb8db02..d4e827580 100644
--- a/pkg/domain/infra/tunnel/network.go
+++ b/pkg/domain/infra/tunnel/network.go
@@ -5,6 +5,7 @@ import (
"github.com/containers/podman/v2/pkg/bindings/network"
"github.com/containers/podman/v2/pkg/domain/entities"
+ "github.com/containers/podman/v2/pkg/errorhandling"
"github.com/pkg/errors"
)
@@ -22,7 +23,7 @@ func (ic *ContainerEngine) NetworkInspect(ctx context.Context, namesOrIds []stri
for _, name := range namesOrIds {
report, err := network.Inspect(ic.ClientCtx, name, options)
if err != nil {
- errModel, ok := err.(entities.ErrorModel)
+ errModel, ok := err.(errorhandling.ErrorModel)
if !ok {
return nil, nil, err
}
diff --git a/pkg/domain/infra/tunnel/volumes.go b/pkg/domain/infra/tunnel/volumes.go
index e6ad4e0c5..f21336828 100644
--- a/pkg/domain/infra/tunnel/volumes.go
+++ b/pkg/domain/infra/tunnel/volumes.go
@@ -5,6 +5,8 @@ import (
"github.com/containers/podman/v2/pkg/bindings/volumes"
"github.com/containers/podman/v2/pkg/domain/entities"
+ "github.com/containers/podman/v2/pkg/domain/entities/reports"
+ "github.com/containers/podman/v2/pkg/errorhandling"
"github.com/pkg/errors"
)
@@ -54,7 +56,7 @@ func (ic *ContainerEngine) VolumeInspect(ctx context.Context, namesOrIds []strin
for _, id := range namesOrIds {
data, err := volumes.Inspect(ic.ClientCtx, id, nil)
if err != nil {
- errModel, ok := err.(entities.ErrorModel)
+ errModel, ok := err.(errorhandling.ErrorModel)
if !ok {
return nil, nil, err
}
@@ -69,7 +71,7 @@ func (ic *ContainerEngine) VolumeInspect(ctx context.Context, namesOrIds []strin
return reports, errs, nil
}
-func (ic *ContainerEngine) VolumePrune(ctx context.Context, opts entities.VolumePruneOptions) ([]*entities.VolumePruneReport, error) {
+func (ic *ContainerEngine) VolumePrune(ctx context.Context, opts entities.VolumePruneOptions) ([]*reports.PruneReport, error) {
options := new(volumes.PruneOptions).WithFilters(opts.Filters)
return volumes.Prune(ic.ClientCtx, options)
}
diff --git a/pkg/errorhandling/errorhandling.go b/pkg/errorhandling/errorhandling.go
index 21df261fb..b1923be98 100644
--- a/pkg/errorhandling/errorhandling.go
+++ b/pkg/errorhandling/errorhandling.go
@@ -70,3 +70,27 @@ func CloseQuiet(f *os.File) {
func Contains(err error, sub error) bool {
return strings.Contains(err.Error(), sub.Error())
}
+
+// ErrorModel is used in remote connections with podman
+type ErrorModel struct {
+ // API root cause formatted for automated parsing
+ // example: API root cause
+ Because string `json:"cause"`
+ // human error message, formatted for a human to read
+ // example: human error message
+ Message string `json:"message"`
+ // http response code
+ ResponseCode int `json:"response"`
+}
+
+func (e ErrorModel) Error() string {
+ return e.Message
+}
+
+func (e ErrorModel) Cause() error {
+ return errors.New(e.Because)
+}
+
+func (e ErrorModel) Code() int {
+ return e.ResponseCode
+}
diff --git a/pkg/inspect/inspect.go b/pkg/inspect/inspect.go
index 27bff46a0..67c6a5c03 100644
--- a/pkg/inspect/inspect.go
+++ b/pkg/inspect/inspect.go
@@ -4,7 +4,7 @@ import (
"time"
"github.com/containers/image/v5/manifest"
- "github.com/containers/podman/v2/libpod/driver"
+ "github.com/containers/podman/v2/libpod/define"
"github.com/opencontainers/go-digest"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
)
@@ -25,7 +25,7 @@ type ImageData struct {
Os string `json:"Os"`
Size int64 `json:"Size"`
VirtualSize int64 `json:"VirtualSize"`
- GraphDriver *driver.Data `json:"GraphDriver"`
+ GraphDriver *define.DriverData `json:"GraphDriver"`
RootFS *RootFS `json:"RootFS"`
Labels map[string]string `json:"Labels"`
Annotations map[string]string `json:"Annotations"`
diff --git a/pkg/netns/netns_linux.go b/pkg/netns/netns_linux.go
index ed5241632..6817a3abd 100644
--- a/pkg/netns/netns_linux.go
+++ b/pkg/netns/netns_linux.go
@@ -45,7 +45,7 @@ func getNSRunDir() (string, error) {
}
return filepath.Join(rootlessDir, "netns"), nil
}
- return "/var/run/netns", nil
+ return "/run/netns", nil
}
// NewNS creates a new persistent (bind-mounted) network namespace and returns
@@ -80,7 +80,7 @@ func NewNS() (ns.NetNS, error) {
return nil, fmt.Errorf("mount --make-rshared %s failed: %q", nsRunDir, err)
}
- // Recursively remount /var/run/netns on itself. The recursive flag is
+ // Recursively remount /run/netns on itself. The recursive flag is
// so that any existing netns bindmounts are carried over.
err = unix.Mount(nsRunDir, nsRunDir, "none", unix.MS_BIND|unix.MS_REC, "")
if err != nil {
diff --git a/pkg/ps/ps.go b/pkg/ps/ps.go
index 9e0dcb728..dc577890a 100644
--- a/pkg/ps/ps.go
+++ b/pkg/ps/ps.go
@@ -178,6 +178,11 @@ func ListContainerBatch(rt *libpod.Runtime, ctr *libpod.Container, opts entities
return entities.ListContainer{}, err
}
+ networks, _, err := ctr.Networks()
+ if err != nil {
+ return entities.ListContainer{}, err
+ }
+
ps := entities.ListContainer{
AutoRemove: ctr.AutoRemove(),
Command: conConfig.Command,
@@ -192,6 +197,7 @@ func ListContainerBatch(rt *libpod.Runtime, ctr *libpod.Container, opts entities
Labels: conConfig.Labels,
Mounts: ctr.UserVolumes(),
Names: []string{conConfig.Name},
+ Networks: networks,
Pid: pid,
Pod: conConfig.Pod,
Ports: portMappings,
diff --git a/pkg/rootless/rootless.go b/pkg/rootless/rootless.go
index 799c793d8..df35c0d6b 100644
--- a/pkg/rootless/rootless.go
+++ b/pkg/rootless/rootless.go
@@ -2,10 +2,12 @@ package rootless
import (
"os"
+ "sort"
"sync"
"github.com/containers/storage"
"github.com/opencontainers/runc/libcontainer/user"
+ spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
)
@@ -50,24 +52,151 @@ func TryJoinPauseProcess(pausePidPath string) (bool, int, error) {
}
var (
- availableGids int64
- availableGidsErr error
- availableGidsOnce sync.Once
+ uidMap []user.IDMap
+ uidMapError error
+ uidMapOnce sync.Once
+
+ gidMap []user.IDMap
+ gidMapError error
+ gidMapOnce sync.Once
)
-// GetAvailableGids returns how many GIDs are available in the
+// GetAvailableUidMap returns the UID mappings in the
// current user namespace.
-func GetAvailableGids() (int64, error) {
- availableGidsOnce.Do(func() {
- idMap, err := user.ParseIDMapFile("/proc/self/gid_map")
+func GetAvailableUidMap() ([]user.IDMap, error) {
+ uidMapOnce.Do(func() {
+ var err error
+ uidMap, err = user.ParseIDMapFile("/proc/self/uid_map")
if err != nil {
- availableGidsErr = err
+ uidMapError = err
return
}
- availableGids = int64(0)
- for _, r := range idMap {
- availableGids += r.Count
+ })
+ return uidMap, uidMapError
+}
+
+// GetAvailableGidMap returns the GID mappings in the
+// current user namespace.
+func GetAvailableGidMap() ([]user.IDMap, error) {
+ gidMapOnce.Do(func() {
+ var err error
+ gidMap, err = user.ParseIDMapFile("/proc/self/gid_map")
+ if err != nil {
+ gidMapError = err
+ return
}
})
- return availableGids, availableGidsErr
+ return gidMap, gidMapError
+}
+
+// GetAvailableIDMaps returns the UID and GID mappings in the
+// current user namespace.
+func GetAvailableIDMaps() ([]user.IDMap, []user.IDMap, error) {
+ u, err := GetAvailableUidMap()
+ if err != nil {
+ return nil, nil, err
+ }
+ g, err := GetAvailableGidMap()
+ if err != nil {
+ return nil, nil, err
+ }
+ return u, g, nil
+}
+
+func countAvailableIDs(mappings []user.IDMap) int64 {
+ availableUids := int64(0)
+ for _, r := range mappings {
+ availableUids += r.Count
+ }
+ return availableUids
+}
+
+// GetAvailableUids returns how many UIDs are available in the
+// current user namespace.
+func GetAvailableUids() (int64, error) {
+ uids, err := GetAvailableUidMap()
+ if err != nil {
+ return -1, err
+ }
+
+ return countAvailableIDs(uids), nil
+}
+
+// GetAvailableGids returns how many GIDs are available in the
+// current user namespace.
+func GetAvailableGids() (int64, error) {
+ gids, err := GetAvailableGidMap()
+ if err != nil {
+ return -1, err
+ }
+
+ return countAvailableIDs(gids), nil
+}
+
+// findIDInMappings find the the mapping that contains the specified ID.
+// It assumes availableMappings is sorted by ID.
+func findIDInMappings(id int64, availableMappings []user.IDMap) *user.IDMap {
+ i := sort.Search(len(availableMappings), func(i int) bool {
+ return availableMappings[i].ID >= id
+ })
+ if i < 0 || i >= len(availableMappings) {
+ return nil
+ }
+ r := &availableMappings[i]
+ if id >= r.ID && id < r.ID+r.Count {
+ return r
+ }
+ return nil
+}
+
+// MaybeSplitMappings checks whether the specified OCI mappings are possible
+// in the current user namespace or the specified ranges must be split.
+func MaybeSplitMappings(mappings []spec.LinuxIDMapping, availableMappings []user.IDMap) []spec.LinuxIDMapping {
+ var ret []spec.LinuxIDMapping
+ var overflow spec.LinuxIDMapping
+ overflow.Size = 0
+ consumed := 0
+ sort.Slice(availableMappings, func(i, j int) bool {
+ return availableMappings[i].ID < availableMappings[j].ID
+ })
+ for {
+ cur := overflow
+ // if there is no overflow left from the previous request, get the next one
+ if cur.Size == 0 {
+ if consumed == len(mappings) {
+ // all done
+ return ret
+ }
+ cur = mappings[consumed]
+ consumed++
+ }
+
+ // Find the range where the first specified ID is present
+ r := findIDInMappings(int64(cur.HostID), availableMappings)
+ if r == nil {
+ // The requested range is not available. Just return the original request
+ // and let other layers deal with it.
+ return mappings
+ }
+
+ offsetInRange := cur.HostID - uint32(r.ID)
+
+ usableIDs := uint32(r.Count) - offsetInRange
+
+ // the current range can satisfy the whole request
+ if usableIDs >= cur.Size {
+ // reset the overflow
+ overflow.Size = 0
+ } else {
+ // the current range can satisfy the request partially
+ // so move the rest to overflow
+ overflow.Size = cur.Size - usableIDs
+ overflow.ContainerID = cur.ContainerID + usableIDs
+ overflow.HostID = cur.HostID + usableIDs
+
+ // and cap to the usableIDs count
+ cur.Size = usableIDs
+ }
+ ret = append(ret, cur)
+ }
}
diff --git a/pkg/rootless/rootless_test.go b/pkg/rootless/rootless_test.go
new file mode 100644
index 000000000..ef574099c
--- /dev/null
+++ b/pkg/rootless/rootless_test.go
@@ -0,0 +1,101 @@
+package rootless
+
+import (
+ "reflect"
+ "testing"
+
+ "github.com/opencontainers/runc/libcontainer/user"
+ spec "github.com/opencontainers/runtime-spec/specs-go"
+)
+
+func TestMaybeSplitMappings(t *testing.T) {
+ mappings := []spec.LinuxIDMapping{
+ {
+ ContainerID: 0,
+ HostID: 0,
+ Size: 2,
+ },
+ }
+ desiredMappings := []spec.LinuxIDMapping{
+ {
+ ContainerID: 0,
+ HostID: 0,
+ Size: 1,
+ },
+ {
+ ContainerID: 1,
+ HostID: 1,
+ Size: 1,
+ },
+ }
+ availableMappings := []user.IDMap{
+ {
+ ID: 1,
+ ParentID: 1000000,
+ Count: 65536,
+ },
+ {
+ ID: 0,
+ ParentID: 1000,
+ Count: 1,
+ },
+ }
+ newMappings := MaybeSplitMappings(mappings, availableMappings)
+ if !reflect.DeepEqual(newMappings, desiredMappings) {
+ t.Fatal("wrong mappings generated")
+ }
+
+ mappings = []spec.LinuxIDMapping{
+ {
+ ContainerID: 0,
+ HostID: 0,
+ Size: 2,
+ },
+ }
+ desiredMappings = []spec.LinuxIDMapping{
+ {
+ ContainerID: 0,
+ HostID: 0,
+ Size: 2,
+ },
+ }
+ availableMappings = []user.IDMap{
+ {
+ ID: 0,
+ ParentID: 1000000,
+ Count: 65536,
+ },
+ }
+ newMappings = MaybeSplitMappings(mappings, availableMappings)
+
+ if !reflect.DeepEqual(newMappings, desiredMappings) {
+ t.Fatal("wrong mappings generated")
+ }
+
+ mappings = []spec.LinuxIDMapping{
+ {
+ ContainerID: 0,
+ HostID: 0,
+ Size: 1,
+ },
+ }
+ desiredMappings = []spec.LinuxIDMapping{
+ {
+ ContainerID: 0,
+ HostID: 0,
+ Size: 1,
+ },
+ }
+ availableMappings = []user.IDMap{
+ {
+ ID: 10000,
+ ParentID: 10000,
+ Count: 65536,
+ },
+ }
+
+ newMappings = MaybeSplitMappings(mappings, availableMappings)
+ if !reflect.DeepEqual(newMappings, desiredMappings) {
+ t.Fatal("wrong mappings generated")
+ }
+}
diff --git a/pkg/signal/signal_linux_mipsx.go b/pkg/signal/signal_linux_mipsx.go
index 67638e30a..45c9d5af1 100644
--- a/pkg/signal/signal_linux_mipsx.go
+++ b/pkg/signal/signal_linux_mipsx.go
@@ -19,6 +19,8 @@ import (
const (
sigrtmin = 34
sigrtmax = 127
+
+ SIGWINCH = syscall.SIGWINCH
)
// signalMap is a map of Linux signals.
diff --git a/pkg/specgen/generate/config_linux.go b/pkg/specgen/generate/config_linux.go
index e0b039fb7..1290a8eb6 100644
--- a/pkg/specgen/generate/config_linux.go
+++ b/pkg/specgen/generate/config_linux.go
@@ -21,9 +21,6 @@ var (
errNotADevice = errors.New("not a device node")
)
-func u32Ptr(i int64) *uint32 { u := uint32(i); return &u }
-func fmPtr(i int64) *os.FileMode { fm := os.FileMode(i); return &fm }
-
func addPrivilegedDevices(g *generate.Generator) error {
hostDevices, err := getDevices("/dev")
if err != nil {
diff --git a/pkg/specgen/generate/container.go b/pkg/specgen/generate/container.go
index 42fea0277..2feb1d3b2 100644
--- a/pkg/specgen/generate/container.go
+++ b/pkg/specgen/generate/container.go
@@ -100,15 +100,9 @@ func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerat
if err != nil {
return nil, err
}
- // First transform the os env into a map. We need it for the labels later in
- // any case.
- osEnv, err := envLib.ParseSlice(os.Environ())
- if err != nil {
- return nil, errors.Wrap(err, "error parsing host environment variables")
- }
// Get Default Environment from containers.conf
- defaultEnvs, err := envLib.ParseSlice(rtc.GetDefaultEnv())
+ defaultEnvs, err := envLib.ParseSlice(rtc.GetDefaultEnvEx(s.EnvHost, s.HTTPProxy))
if err != nil {
return nil, errors.Wrap(err, "error parsing fields in containers.conf")
}
@@ -133,6 +127,12 @@ func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerat
defaultEnvs = envLib.Join(defaultEnvs, envs)
}
+ // First transform the os env into a map. We need it for the labels later in
+ // any case.
+ osEnv, err := envLib.ParseSlice(os.Environ())
+ if err != nil {
+ return nil, errors.Wrap(err, "error parsing host environment variables")
+ }
// Caller Specified defaults
if s.EnvHost {
defaultEnvs = envLib.Join(defaultEnvs, osEnv)
@@ -282,8 +282,8 @@ func finishThrottleDevices(s *specgen.SpecGenerator) error {
if err := unix.Stat(k, &statT); err != nil {
return err
}
- v.Major = (int64(unix.Major(statT.Rdev)))
- v.Minor = (int64(unix.Minor(statT.Rdev)))
+ v.Major = (int64(unix.Major(uint64(statT.Rdev))))
+ v.Minor = (int64(unix.Minor(uint64(statT.Rdev))))
s.ResourceLimits.BlockIO.ThrottleReadBpsDevice = append(s.ResourceLimits.BlockIO.ThrottleReadBpsDevice, v)
}
}
@@ -293,8 +293,8 @@ func finishThrottleDevices(s *specgen.SpecGenerator) error {
if err := unix.Stat(k, &statT); err != nil {
return err
}
- v.Major = (int64(unix.Major(statT.Rdev)))
- v.Minor = (int64(unix.Minor(statT.Rdev)))
+ v.Major = (int64(unix.Major(uint64(statT.Rdev))))
+ v.Minor = (int64(unix.Minor(uint64(statT.Rdev))))
s.ResourceLimits.BlockIO.ThrottleWriteBpsDevice = append(s.ResourceLimits.BlockIO.ThrottleWriteBpsDevice, v)
}
}
@@ -304,8 +304,8 @@ func finishThrottleDevices(s *specgen.SpecGenerator) error {
if err := unix.Stat(k, &statT); err != nil {
return err
}
- v.Major = (int64(unix.Major(statT.Rdev)))
- v.Minor = (int64(unix.Minor(statT.Rdev)))
+ v.Major = (int64(unix.Major(uint64(statT.Rdev))))
+ v.Minor = (int64(unix.Minor(uint64(statT.Rdev))))
s.ResourceLimits.BlockIO.ThrottleReadIOPSDevice = append(s.ResourceLimits.BlockIO.ThrottleReadIOPSDevice, v)
}
}
@@ -315,8 +315,8 @@ func finishThrottleDevices(s *specgen.SpecGenerator) error {
if err := unix.Stat(k, &statT); err != nil {
return err
}
- v.Major = (int64(unix.Major(statT.Rdev)))
- v.Minor = (int64(unix.Minor(statT.Rdev)))
+ v.Major = (int64(unix.Major(uint64(statT.Rdev))))
+ v.Minor = (int64(unix.Minor(uint64(statT.Rdev))))
s.ResourceLimits.BlockIO.ThrottleWriteIOPSDevice = append(s.ResourceLimits.BlockIO.ThrottleWriteIOPSDevice, v)
}
}
diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go
index e5b09dcd8..e39a700eb 100644
--- a/pkg/specgen/generate/kube/kube.go
+++ b/pkg/specgen/generate/kube/kube.go
@@ -5,7 +5,7 @@ import (
"fmt"
"strings"
- "github.com/containers/buildah/pkg/parse"
+ "github.com/containers/common/pkg/parse"
"github.com/containers/podman/v2/libpod/image"
ann "github.com/containers/podman/v2/pkg/annotations"
"github.com/containers/podman/v2/pkg/specgen"
@@ -129,24 +129,20 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener
// TODO: We don't understand why specgen does not take of this, but
// integration tests clearly pointed out that it was required.
- s.Command = []string{}
imageData, err := opts.Image.Inspect(ctx)
if err != nil {
return nil, err
}
s.WorkDir = "/"
- // We will use "Docker field name" internally here to avoid confusion
- // and reference the "Kubernetes field name" when referencing the YAML
- // ref: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#notes
- entrypoint := []string{}
- cmd := []string{}
+ // Entrypoint/Command handling is based off of
+ // https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#notes
if imageData != nil && imageData.Config != nil {
if imageData.Config.WorkingDir != "" {
s.WorkDir = imageData.Config.WorkingDir
}
// Pull entrypoint and cmd from image
- entrypoint = imageData.Config.Entrypoint
- cmd = imageData.Config.Cmd
+ s.Entrypoint = imageData.Config.Entrypoint
+ s.Command = imageData.Config.Cmd
s.Labels = imageData.Config.Labels
if len(imageData.Config.StopSignal) > 0 {
stopSignal, err := util.ParseSignal(imageData.Config.StopSignal)
@@ -158,16 +154,15 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener
}
// If only the yaml.Command is specified, set it as the entrypoint and drop the image Cmd
if len(opts.Container.Command) != 0 {
- entrypoint = opts.Container.Command
- cmd = []string{}
+ s.Entrypoint = opts.Container.Command
+ s.Command = []string{}
}
// Only override the cmd field if yaml.Args is specified
// Keep the image entrypoint, or the yaml.command if specified
if len(opts.Container.Args) != 0 {
- cmd = opts.Container.Args
+ s.Command = opts.Container.Args
}
- s.Command = append(entrypoint, cmd...)
// FIXME,
// we are currently ignoring imageData.Config.ExposedPorts
if opts.Container.WorkingDir != "" {
diff --git a/pkg/specgen/generate/kube/volume.go b/pkg/specgen/generate/kube/volume.go
index bb8edabb7..f5687f60d 100644
--- a/pkg/specgen/generate/kube/volume.go
+++ b/pkg/specgen/generate/kube/volume.go
@@ -3,7 +3,7 @@ package kube
import (
"os"
- "github.com/containers/buildah/pkg/parse"
+ "github.com/containers/common/pkg/parse"
"github.com/containers/podman/v2/libpod"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
diff --git a/pkg/specgen/generate/namespaces.go b/pkg/specgen/generate/namespaces.go
index 036c7b7a1..f66ad6101 100644
--- a/pkg/specgen/generate/namespaces.go
+++ b/pkg/specgen/generate/namespaces.go
@@ -236,6 +236,9 @@ func namespaceOptions(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.
case specgen.Private:
fallthrough
case specgen.Bridge:
+ if postConfigureNetNS && rootless.IsRootless() {
+ return nil, errors.New("CNI networks not supported with user namespaces")
+ }
portMappings, err := createPortMappings(ctx, s, img)
if err != nil {
return nil, err
@@ -364,7 +367,9 @@ func specConfigureNamespaces(s *specgen.SpecGenerator, g *generate.Generator, rt
// namespaces?
g.SetHostname(hostname)
}
- g.AddProcessEnv("HOSTNAME", hostname)
+ if _, ok := s.Env["HOSTNAME"]; !ok && s.Hostname != "" {
+ g.AddProcessEnv("HOSTNAME", hostname)
+ }
// User
switch s.UserNS.NSMode {
diff --git a/pkg/specgen/generate/oci.go b/pkg/specgen/generate/oci.go
index ba68de6fd..e62131244 100644
--- a/pkg/specgen/generate/oci.go
+++ b/pkg/specgen/generate/oci.go
@@ -110,7 +110,7 @@ func makeCommand(ctx context.Context, s *specgen.SpecGenerator, img *image.Image
// Only use image command if the user did not manually set an
// entrypoint.
command := s.Command
- if (command == nil || len(command) == 0) && img != nil && (s.Entrypoint == nil || len(s.Entrypoint) == 0) {
+ if len(command) == 0 && img != nil && len(s.Entrypoint) == 0 {
newCmd, err := img.Cmd(ctx)
if err != nil {
return nil, err
@@ -138,10 +138,23 @@ func makeCommand(ctx context.Context, s *specgen.SpecGenerator, img *image.Image
return finalCommand, nil
}
+// canMountSys is a best-effort heuristic to detect whether mounting a new sysfs is permitted in the container
+func canMountSys(isRootless, isNewUserns bool, s *specgen.SpecGenerator) bool {
+ if s.NetNS.IsHost() && (isRootless || isNewUserns) {
+ return false
+ }
+ if isNewUserns {
+ switch s.NetNS.NSMode {
+ case specgen.Slirp, specgen.Private, specgen.NoNetwork, specgen.Bridge:
+ return true
+ default:
+ return false
+ }
+ }
+ return true
+}
+
func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runtime, rtc *config.Config, newImage *image.Image, mounts []spec.Mount, pod *libpod.Pod, finalCmd []string) (*spec.Spec, error) {
- var (
- inUserNS bool
- )
cgroupPerm := "ro"
g, err := generate.New("linux")
if err != nil {
@@ -151,23 +164,11 @@ func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runt
g.RemoveMount("/dev/shm")
g.HostSpecific = true
addCgroup := true
- canMountSys := true
isRootless := rootless.IsRootless()
- if isRootless {
- inUserNS = true
- }
- if !s.UserNS.IsHost() {
- if s.UserNS.IsContainer() || s.UserNS.IsPath() {
- inUserNS = true
- }
- if s.UserNS.IsPrivate() {
- inUserNS = true
- }
- }
- if inUserNS && s.NetNS.NSMode != specgen.NoNetwork {
- canMountSys = false
- }
+ isNewUserns := s.UserNS.IsContainer() || s.UserNS.IsPath() || s.UserNS.IsPrivate()
+
+ canMountSys := canMountSys(isRootless, isNewUserns, s)
if s.Privileged && canMountSys {
cgroupPerm = "rw"
@@ -232,6 +233,8 @@ func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runt
g.AddMount(devPts)
}
+ inUserNS := isRootless || isNewUserns
+
if inUserNS && s.IpcNS.IsHost() {
g.RemoveMount("/dev/mqueue")
devMqueue := spec.Mount{
diff --git a/pkg/specgen/generate/security.go b/pkg/specgen/generate/security.go
index 0c97dc496..390b19beb 100644
--- a/pkg/specgen/generate/security.go
+++ b/pkg/specgen/generate/security.go
@@ -133,13 +133,13 @@ func securityConfigureGenerator(s *specgen.SpecGenerator, g *generate.Generator,
configSpec := g.Config
configSpec.Process.Capabilities.Ambient = []string{}
configSpec.Process.Capabilities.Bounding = caplist
- configSpec.Process.Capabilities.Inheritable = caplist
user := strings.Split(s.User, ":")[0]
if (user == "" && s.UserNS.NSMode != specgen.KeepID) || user == "root" || user == "0" {
configSpec.Process.Capabilities.Effective = caplist
configSpec.Process.Capabilities.Permitted = caplist
+ configSpec.Process.Capabilities.Inheritable = caplist
} else {
userCaps, err := capabilities.MergeCapabilities(nil, s.CapAdd, nil)
if err != nil {
@@ -147,6 +147,7 @@ func securityConfigureGenerator(s *specgen.SpecGenerator, g *generate.Generator,
}
configSpec.Process.Capabilities.Effective = userCaps
configSpec.Process.Capabilities.Permitted = userCaps
+ configSpec.Process.Capabilities.Inheritable = userCaps
// Ambient capabilities were added to Linux 4.3. Set ambient
// capabilities only when the kernel supports them.
@@ -172,12 +173,16 @@ func securityConfigureGenerator(s *specgen.SpecGenerator, g *generate.Generator,
// Clear default Seccomp profile from Generator for unconfined containers
// and privileged containers which do not specify a seccomp profile.
- if s.SeccompProfilePath == "unconfined" || (s.Privileged && (s.SeccompProfilePath == config.SeccompOverridePath || s.SeccompProfilePath == config.SeccompDefaultPath)) {
+ if s.SeccompProfilePath == "unconfined" || (s.Privileged && (s.SeccompProfilePath == "" || s.SeccompProfilePath == config.SeccompOverridePath || s.SeccompProfilePath == config.SeccompDefaultPath)) {
configSpec.Linux.Seccomp = nil
}
g.SetRootReadonly(s.ReadOnlyFilesystem)
+ noUseIPC := s.IpcNS.NSMode == specgen.FromContainer || s.IpcNS.NSMode == specgen.FromPod || s.IpcNS.NSMode == specgen.Host
+ noUseNet := s.NetNS.NSMode == specgen.FromContainer || s.NetNS.NSMode == specgen.FromPod || s.NetNS.NSMode == specgen.Host
+ noUseUTS := s.UtsNS.NSMode == specgen.FromContainer || s.UtsNS.NSMode == specgen.FromPod || s.UtsNS.NSMode == specgen.Host
+
// Add default sysctls
defaultSysctls, err := util.ValidateSysctls(rtc.Sysctls())
if err != nil {
@@ -186,20 +191,20 @@ func securityConfigureGenerator(s *specgen.SpecGenerator, g *generate.Generator,
for sysctlKey, sysctlVal := range defaultSysctls {
// Ignore mqueue sysctls if --ipc=host
- if s.IpcNS.IsHost() && strings.HasPrefix(sysctlKey, "fs.mqueue.") {
+ if noUseIPC && strings.HasPrefix(sysctlKey, "fs.mqueue.") {
logrus.Infof("Sysctl %s=%s ignored in containers.conf, since IPC Namespace set to host", sysctlKey, sysctlVal)
continue
}
// Ignore net sysctls if --net=host
- if s.NetNS.IsHost() && strings.HasPrefix(sysctlKey, "net.") {
+ if noUseNet && strings.HasPrefix(sysctlKey, "net.") {
logrus.Infof("Sysctl %s=%s ignored in containers.conf, since Network Namespace set to host", sysctlKey, sysctlVal)
continue
}
// Ignore uts sysctls if --uts=host
- if s.UtsNS.IsHost() && (strings.HasPrefix(sysctlKey, "kernel.domainname") || strings.HasPrefix(sysctlKey, "kernel.hostname")) {
+ if noUseUTS && (strings.HasPrefix(sysctlKey, "kernel.domainname") || strings.HasPrefix(sysctlKey, "kernel.hostname")) {
logrus.Infof("Sysctl %s=%s ignored in containers.conf, since UTS Namespace set to host", sysctlKey, sysctlVal)
continue
}
diff --git a/pkg/specgen/generate/storage.go b/pkg/specgen/generate/storage.go
index f523ac5bf..63713726e 100644
--- a/pkg/specgen/generate/storage.go
+++ b/pkg/specgen/generate/storage.go
@@ -124,14 +124,10 @@ func finalizeMounts(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Ru
// named volumes, and vice versa.
// We'll delete the conflicts here as we supersede.
for dest := range unifiedMounts {
- if _, ok := baseVolumes[dest]; ok {
- delete(baseVolumes, dest)
- }
+ delete(baseVolumes, dest)
}
for dest := range unifiedVolumes {
- if _, ok := baseMounts[dest]; ok {
- delete(baseMounts, dest)
- }
+ delete(baseMounts, dest)
}
// Supersede volumes-from/image volumes with unified volumes from above.
diff --git a/pkg/specgen/generate/validate.go b/pkg/specgen/generate/validate.go
index f0ab4b994..77cccad3e 100644
--- a/pkg/specgen/generate/validate.go
+++ b/pkg/specgen/generate/validate.go
@@ -48,7 +48,7 @@ func verifyContainerResourcesCgroupV1(s *specgen.SpecGenerator) ([]string, error
warnings = append(warnings, "Your kernel does not support memory swappiness capabilities, or the cgroup is not mounted. Memory swappiness discarded.")
memory.Swappiness = nil
} else {
- if *memory.Swappiness < 0 || *memory.Swappiness > 100 {
+ if *memory.Swappiness > 100 {
return warnings, errors.Errorf("invalid value: %v, valid memory swappiness range is 0-100", *memory.Swappiness)
}
}
diff --git a/pkg/specgen/volumes.go b/pkg/specgen/volumes.go
index a4f42d715..83634b4ef 100644
--- a/pkg/specgen/volumes.go
+++ b/pkg/specgen/volumes.go
@@ -4,7 +4,7 @@ import (
"path/filepath"
"strings"
- "github.com/containers/buildah/pkg/parse"
+ "github.com/containers/common/pkg/parse"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
diff --git a/pkg/systemd/generate/common.go b/pkg/systemd/generate/common.go
index 52a214883..8901298db 100644
--- a/pkg/systemd/generate/common.go
+++ b/pkg/systemd/generate/common.go
@@ -11,6 +11,11 @@ import (
// 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"}
@@ -66,3 +71,30 @@ func quoteArguments(command []string) []string {
}
return command
}
+
+func removeDetachArg(args []string, argCount int) []string {
+ // "--detach=false" could also be in the container entrypoint
+ // split them off so we do not remove it there
+ realArgs := args[len(args)-argCount:]
+ flagArgs := removeArg("-d=false", args[:len(args)-argCount])
+ flagArgs = removeArg("--detach=false", flagArgs)
+ return append(flagArgs, realArgs...)
+}
+
+func removeReplaceArg(args []string, argCount int) []string {
+ // "--replace=false" could also be in the container entrypoint
+ // split them off so we do not remove it there
+ realArgs := args[len(args)-argCount:]
+ flagArgs := removeArg("--replace=false", args[:len(args)-argCount])
+ return append(flagArgs, realArgs...)
+}
+
+func removeArg(arg string, args []string) []string {
+ newArgs := []string{}
+ for _, a := range args {
+ if a != arg {
+ newArgs = append(newArgs, a)
+ }
+ }
+ return newArgs
+}
diff --git a/pkg/systemd/generate/containers.go b/pkg/systemd/generate/containers.go
index d84125fc7..b64b2593c 100644
--- a/pkg/systemd/generate/containers.go
+++ b/pkg/systemd/generate/containers.go
@@ -14,6 +14,7 @@ import (
"github.com/containers/podman/v2/version"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
+ "github.com/spf13/pflag"
)
// containerInfo contains data required for generating a container's systemd
@@ -44,6 +45,9 @@ type containerInfo struct {
// Executable is the path to the podman executable. Will be auto-filled if
// left empty.
Executable string
+ // RootFlags contains the root flags which were used to create the container
+ // Only used with --new
+ RootFlags string
// TimeStamp at the time of creating the unit file. Will be set internally.
TimeStamp string
// CreateCommand is the full command plus arguments of the process the
@@ -55,6 +59,8 @@ type containerInfo struct {
ExecStartPre string
// ExecStart of the unit.
ExecStart string
+ // TimeoutStopSec of the unit.
+ TimeoutStopSec uint
// ExecStop of the unit.
ExecStop string
// ExecStopPost of the unit.
@@ -74,6 +80,7 @@ After={{- range $index, $value := .BoundToServices -}}{{if $index}} {{end}}{{ $v
[Service]
Environment={{.EnvVariable}}=%n
Restart={{.RestartPolicy}}
+TimeoutStopSec={{.TimeoutStopSec}}
{{- if .ExecStartPre}}
ExecStartPre={{.ExecStartPre}}
{{- end}}
@@ -81,7 +88,6 @@ ExecStart={{.ExecStart}}
ExecStop={{.ExecStop}}
ExecStopPost={{.ExecStopPost}}
PIDFile={{.PIDFile}}
-KillMode=none
Type=forking
[Install]
@@ -183,22 +189,30 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst
info.ContainerIDFile = "%t/" + info.ServiceName + ".ctr-id"
// The create command must at least have three arguments:
// /usr/bin/podman run $IMAGE
- index := 2
- if info.CreateCommand[1] == "container" {
- index = 3
+ index := 0
+ for i, arg := range info.CreateCommand {
+ if arg == "run" || arg == "create" {
+ index = i + 1
+ break
+ }
}
- if len(info.CreateCommand) < index+1 {
+ if index == 0 {
return "", errors.Errorf("container's create command is too short or invalid: %v", info.CreateCommand)
}
// We're hard-coding the first five arguments and append the
// CreateCommand with a stripped command and subcommand.
- startCommand := []string{
- info.Executable,
+ startCommand := []string{info.Executable}
+ if index > 2 {
+ // include root flags
+ info.RootFlags = strings.Join(quoteArguments(info.CreateCommand[1:index-1]), " ")
+ startCommand = append(startCommand, info.CreateCommand[1:index-1]...)
+ }
+ startCommand = append(startCommand,
"run",
"--conmon-pidfile", "{{.PIDFile}}",
"--cidfile", "{{.ContainerIDFile}}",
"--cgroups=no-conmon",
- }
+ )
// If the container is in a pod, make sure that the
// --pod-id-file is set correctly.
if info.pod != nil {
@@ -208,22 +222,26 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst
}
// Presence check for certain flags/options.
- hasDetachParam := false
- hasNameParam := false
- hasReplaceParam := false
- for _, p := range info.CreateCommand[index:] {
- switch p {
- case "--detach", "-d":
- hasDetachParam = true
- case "--name":
- hasNameParam = true
- case "--replace":
- hasReplaceParam = true
- }
- if strings.HasPrefix(p, "--name=") {
- hasNameParam = true
- }
+ fs := pflag.NewFlagSet("args", pflag.ContinueOnError)
+ fs.ParseErrorsWhitelist.UnknownFlags = true
+ fs.Usage = func() {}
+ fs.SetInterspersed(false)
+ fs.BoolP("detach", "d", false, "")
+ fs.String("name", "", "")
+ fs.Bool("replace", false, "")
+ fs.Parse(info.CreateCommand[index:])
+
+ hasDetachParam, err := fs.GetBool("detach")
+ if err != nil {
+ return "", err
}
+ hasNameParam := fs.Lookup("name").Changed
+ hasReplaceParam, err := fs.GetBool("replace")
+ if err != nil {
+ return "", err
+ }
+
+ remainingCmd := info.CreateCommand[index:]
if !hasDetachParam {
// Enforce detaching
@@ -238,6 +256,13 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst
// will wait the `podman run` command exit until failed
// with timeout error.
startCommand = append(startCommand, "-d")
+
+ if fs.Changed("detach") {
+ // this can only happen if --detach=false is set
+ // in that case we need to remove it otherwise we
+ // would overwrite the previous detach arg to false
+ remainingCmd = removeDetachArg(remainingCmd, fs.NArg())
+ }
}
if hasNameParam && !hasReplaceParam {
// Enforce --replace for named containers. This will
@@ -245,16 +270,25 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst
// start after system crashes (see
// github.com/containers/podman/issues/5485).
startCommand = append(startCommand, "--replace")
+
+ if fs.Changed("replace") {
+ // this can only happen if --replace=false is set
+ // in that case we need to remove it otherwise we
+ // would overwrite the previous replace arg to false
+ remainingCmd = removeReplaceArg(remainingCmd, fs.NArg())
+ }
}
- startCommand = append(startCommand, info.CreateCommand[index:]...)
+ startCommand = append(startCommand, remainingCmd...)
startCommand = quoteArguments(startCommand)
info.ExecStartPre = "/bin/rm -f {{.PIDFile}} {{.ContainerIDFile}}"
info.ExecStart = strings.Join(startCommand, " ")
- info.ExecStop = "{{.Executable}} stop --ignore --cidfile {{.ContainerIDFile}} {{if (ge .StopTimeout 0)}}-t {{.StopTimeout}}{{end}}"
- info.ExecStopPost = "{{.Executable}} rm --ignore -f --cidfile {{.ContainerIDFile}}"
+ info.ExecStop = "{{.Executable}} {{if .RootFlags}}{{ .RootFlags}} {{end}}stop --ignore --cidfile {{.ContainerIDFile}} {{if (ge .StopTimeout 0)}}-t {{.StopTimeout}}{{end}}"
+ info.ExecStopPost = "{{.Executable}} {{if .RootFlags}}{{ .RootFlags}} {{end}}rm --ignore -f --cidfile {{.ContainerIDFile}}"
}
+ info.TimeoutStopSec = minTimeoutStopSec + info.StopTimeout
+
if info.PodmanVersion == "" {
info.PodmanVersion = version.Version.String()
}
diff --git a/pkg/systemd/generate/containers_test.go b/pkg/systemd/generate/containers_test.go
index d27062ef3..c8e65bfe3 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/v2/pkg/domain/entities"
+ "github.com/stretchr/testify/assert"
)
func TestValidateRestartPolicyContainer(t *testing.T) {
@@ -48,11 +49,11 @@ After=network-online.target
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=always
+TimeoutStopSec=82
ExecStart=/usr/bin/podman start 639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401
-ExecStop=/usr/bin/podman stop -t 10 639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401
-ExecStopPost=/usr/bin/podman stop -t 10 639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401
-PIDFile=/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid
-KillMode=none
+ExecStop=/usr/bin/podman stop -t 22 639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401
+ExecStopPost=/usr/bin/podman stop -t 22 639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401
+PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid
Type=forking
[Install]
@@ -71,11 +72,11 @@ After=network-online.target
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=always
+TimeoutStopSec=70
ExecStart=/usr/bin/podman start foobar
ExecStop=/usr/bin/podman stop -t 10 foobar
ExecStopPost=/usr/bin/podman stop -t 10 foobar
-PIDFile=/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid
-KillMode=none
+PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid
Type=forking
[Install]
@@ -96,11 +97,11 @@ After=a.service b.service c.service pod.service
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=always
+TimeoutStopSec=70
ExecStart=/usr/bin/podman start foobar
ExecStop=/usr/bin/podman stop -t 10 foobar
ExecStopPost=/usr/bin/podman stop -t 10 foobar
-PIDFile=/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid
-KillMode=none
+PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid
Type=forking
[Install]
@@ -119,12 +120,12 @@ After=network-online.target
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=always
+TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/jadda-jadda.pid %t/jadda-jadda.ctr-id
-ExecStart=/usr/bin/podman run --conmon-pidfile %t/jadda-jadda.pid --cidfile %t/jadda-jadda.ctr-id --cgroups=no-conmon -d --replace --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN "foo=arg \"with \" space"
-ExecStop=/usr/bin/podman stop --ignore --cidfile %t/jadda-jadda.ctr-id -t 42
-ExecStopPost=/usr/bin/podman rm --ignore -f --cidfile %t/jadda-jadda.ctr-id
+ExecStart=/usr/bin/podman container run --conmon-pidfile %t/jadda-jadda.pid --cidfile %t/jadda-jadda.ctr-id --cgroups=no-conmon -d --replace --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN "foo=arg \"with \" space"
+ExecStop=/usr/bin/podman container stop --ignore --cidfile %t/jadda-jadda.ctr-id -t 10
+ExecStopPost=/usr/bin/podman container rm --ignore -f --cidfile %t/jadda-jadda.ctr-id
PIDFile=%t/jadda-jadda.pid
-KillMode=none
Type=forking
[Install]
@@ -143,12 +144,12 @@ After=network-online.target
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=always
+TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/jadda-jadda.pid %t/jadda-jadda.ctr-id
ExecStart=/usr/bin/podman run --conmon-pidfile %t/jadda-jadda.pid --cidfile %t/jadda-jadda.ctr-id --cgroups=no-conmon --replace -d --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN
-ExecStop=/usr/bin/podman stop --ignore --cidfile %t/jadda-jadda.ctr-id -t 42
+ExecStop=/usr/bin/podman stop --ignore --cidfile %t/jadda-jadda.ctr-id -t 10
ExecStopPost=/usr/bin/podman rm --ignore -f --cidfile %t/jadda-jadda.ctr-id
PIDFile=%t/jadda-jadda.pid
-KillMode=none
Type=forking
[Install]
@@ -167,12 +168,12 @@ After=network-online.target
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=always
+TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/jadda-jadda.pid %t/jadda-jadda.ctr-id
ExecStart=/usr/bin/podman run --conmon-pidfile %t/jadda-jadda.pid --cidfile %t/jadda-jadda.ctr-id --cgroups=no-conmon --pod-id-file /tmp/pod-foobar.pod-id-file --replace -d --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN
-ExecStop=/usr/bin/podman stop --ignore --cidfile %t/jadda-jadda.ctr-id -t 42
+ExecStop=/usr/bin/podman stop --ignore --cidfile %t/jadda-jadda.ctr-id -t 10
ExecStopPost=/usr/bin/podman rm --ignore -f --cidfile %t/jadda-jadda.ctr-id
PIDFile=%t/jadda-jadda.pid
-KillMode=none
Type=forking
[Install]
@@ -191,12 +192,12 @@ After=network-online.target
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=always
+TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/jadda-jadda.pid %t/jadda-jadda.ctr-id
ExecStart=/usr/bin/podman run --conmon-pidfile %t/jadda-jadda.pid --cidfile %t/jadda-jadda.ctr-id --cgroups=no-conmon --replace --detach --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN
-ExecStop=/usr/bin/podman stop --ignore --cidfile %t/jadda-jadda.ctr-id -t 42
+ExecStop=/usr/bin/podman stop --ignore --cidfile %t/jadda-jadda.ctr-id -t 10
ExecStopPost=/usr/bin/podman rm --ignore -f --cidfile %t/jadda-jadda.ctr-id
PIDFile=%t/jadda-jadda.pid
-KillMode=none
Type=forking
[Install]
@@ -215,12 +216,113 @@ After=network-online.target
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=always
+TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/container-639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401.pid %t/container-639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401.ctr-id
ExecStart=/usr/bin/podman run --conmon-pidfile %t/container-639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401.pid --cidfile %t/container-639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401.ctr-id --cgroups=no-conmon -d awesome-image:latest
ExecStop=/usr/bin/podman stop --ignore --cidfile %t/container-639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401.ctr-id -t 10
ExecStopPost=/usr/bin/podman rm --ignore -f --cidfile %t/container-639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401.ctr-id
PIDFile=%t/container-639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401.pid
-KillMode=none
+Type=forking
+
+[Install]
+WantedBy=multi-user.target default.target
+`
+
+ genGoodNewDetach := func(detachparam string) string {
+ goodNewDetach := `# jadda-jadda.service
+# autogenerated by Podman CI
+
+[Unit]
+Description=Podman jadda-jadda.service
+Documentation=man:podman-generate-systemd(1)
+Wants=network.target
+After=network-online.target
+
+[Service]
+Environment=PODMAN_SYSTEMD_UNIT=%n
+Restart=always
+TimeoutStopSec=102
+ExecStartPre=/bin/rm -f %t/jadda-jadda.pid %t/jadda-jadda.ctr-id
+ExecStart=/usr/bin/podman run --conmon-pidfile %t/jadda-jadda.pid --cidfile %t/jadda-jadda.ctr-id --cgroups=no-conmon ` +
+ detachparam +
+ ` awesome-image:latest
+ExecStop=/usr/bin/podman stop --ignore --cidfile %t/jadda-jadda.ctr-id -t 42
+ExecStopPost=/usr/bin/podman rm --ignore -f --cidfile %t/jadda-jadda.ctr-id
+PIDFile=%t/jadda-jadda.pid
+Type=forking
+
+[Install]
+WantedBy=multi-user.target default.target
+`
+ return goodNewDetach
+ }
+
+ goodNameNewDetachFalseWithCmd := `# jadda-jadda.service
+# autogenerated by Podman CI
+
+[Unit]
+Description=Podman jadda-jadda.service
+Documentation=man:podman-generate-systemd(1)
+Wants=network.target
+After=network-online.target
+
+[Service]
+Environment=PODMAN_SYSTEMD_UNIT=%n
+Restart=always
+TimeoutStopSec=102
+ExecStartPre=/bin/rm -f %t/jadda-jadda.pid %t/jadda-jadda.ctr-id
+ExecStart=/usr/bin/podman run --conmon-pidfile %t/jadda-jadda.pid --cidfile %t/jadda-jadda.ctr-id --cgroups=no-conmon -d --replace --name test -p 80:80 awesome-image:latest somecmd --detach=false
+ExecStop=/usr/bin/podman stop --ignore --cidfile %t/jadda-jadda.ctr-id -t 42
+ExecStopPost=/usr/bin/podman rm --ignore -f --cidfile %t/jadda-jadda.ctr-id
+PIDFile=%t/jadda-jadda.pid
+Type=forking
+
+[Install]
+WantedBy=multi-user.target default.target
+`
+
+ goodNewRootFlags := `# jadda-jadda.service
+# autogenerated by Podman CI
+
+[Unit]
+Description=Podman jadda-jadda.service
+Documentation=man:podman-generate-systemd(1)
+Wants=network.target
+After=network-online.target
+
+[Service]
+Environment=PODMAN_SYSTEMD_UNIT=%n
+Restart=always
+TimeoutStopSec=102
+ExecStartPre=/bin/rm -f %t/jadda-jadda.pid %t/jadda-jadda.ctr-id
+ExecStart=/usr/bin/podman --events-backend none --runroot /root run --conmon-pidfile %t/jadda-jadda.pid --cidfile %t/jadda-jadda.ctr-id --cgroups=no-conmon -d awesome-image:latest
+ExecStop=/usr/bin/podman --events-backend none --runroot /root stop --ignore --cidfile %t/jadda-jadda.ctr-id -t 42
+ExecStopPost=/usr/bin/podman --events-backend none --runroot /root rm --ignore -f --cidfile %t/jadda-jadda.ctr-id
+PIDFile=%t/jadda-jadda.pid
+Type=forking
+
+[Install]
+WantedBy=multi-user.target default.target
+`
+
+ goodContainerCreate := `# jadda-jadda.service
+# autogenerated by Podman CI
+
+[Unit]
+Description=Podman jadda-jadda.service
+Documentation=man:podman-generate-systemd(1)
+Wants=network.target
+After=network-online.target
+
+[Service]
+Environment=PODMAN_SYSTEMD_UNIT=%n
+Restart=always
+TimeoutStopSec=70
+ExecStartPre=/bin/rm -f %t/jadda-jadda.pid %t/jadda-jadda.ctr-id
+ExecStart=/usr/bin/podman container run --conmon-pidfile %t/jadda-jadda.pid --cidfile %t/jadda-jadda.ctr-id --cgroups=no-conmon -d awesome-image:latest
+ExecStop=/usr/bin/podman container stop --ignore --cidfile %t/jadda-jadda.ctr-id -t 10
+ExecStopPost=/usr/bin/podman container rm --ignore -f --cidfile %t/jadda-jadda.ctr-id
+PIDFile=%t/jadda-jadda.pid
Type=forking
[Install]
@@ -241,8 +343,8 @@ WantedBy=multi-user.target default.target
ServiceName: "container-639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401",
ContainerNameOrID: "639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401",
RestartPolicy: "always",
- PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
- StopTimeout: 10,
+ PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
+ StopTimeout: 22,
PodmanVersion: "CI",
EnvVariable: EnvVariable,
},
@@ -256,7 +358,7 @@ WantedBy=multi-user.target default.target
ServiceName: "container-foobar",
ContainerNameOrID: "foobar",
RestartPolicy: "always",
- PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
+ PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 10,
PodmanVersion: "CI",
EnvVariable: EnvVariable,
@@ -271,7 +373,7 @@ WantedBy=multi-user.target default.target
ServiceName: "container-foobar",
ContainerNameOrID: "foobar",
RestartPolicy: "always",
- PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
+ PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 10,
PodmanVersion: "CI",
BoundToServices: []string{"pod", "a", "b", "c"},
@@ -286,7 +388,7 @@ WantedBy=multi-user.target default.target
Executable: "/usr/bin/podman",
ServiceName: "639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401",
RestartPolicy: "never",
- PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
+ PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 10,
PodmanVersion: "CI",
EnvVariable: EnvVariable,
@@ -301,8 +403,8 @@ WantedBy=multi-user.target default.target
ServiceName: "jadda-jadda",
ContainerNameOrID: "jadda-jadda",
RestartPolicy: "always",
- PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
- StopTimeout: 42,
+ PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
+ 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,
@@ -317,10 +419,10 @@ WantedBy=multi-user.target default.target
ServiceName: "jadda-jadda",
ContainerNameOrID: "jadda-jadda",
RestartPolicy: "always",
- PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
- StopTimeout: 42,
+ PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
+ StopTimeout: 10,
PodmanVersion: "CI",
- CreateCommand: []string{"I'll get stripped", "container", "run", "-d", "--name", "jadda-jadda", "--hostname", "hello-world", "awesome-image:latest", "command", "arg1", "...", "argN"},
+ CreateCommand: []string{"I'll get stripped", "run", "-d", "--name", "jadda-jadda", "--hostname", "hello-world", "awesome-image:latest", "command", "arg1", "...", "argN"},
EnvVariable: EnvVariable,
},
goodWithExplicitShortDetachParam,
@@ -333,10 +435,10 @@ WantedBy=multi-user.target default.target
ServiceName: "jadda-jadda",
ContainerNameOrID: "jadda-jadda",
RestartPolicy: "always",
- PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
- StopTimeout: 42,
+ PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
+ StopTimeout: 10,
PodmanVersion: "CI",
- CreateCommand: []string{"I'll get stripped", "container", "run", "-d", "--name", "jadda-jadda", "--hostname", "hello-world", "awesome-image:latest", "command", "arg1", "...", "argN"},
+ CreateCommand: []string{"I'll get stripped", "run", "-d", "--name", "jadda-jadda", "--hostname", "hello-world", "awesome-image:latest", "command", "arg1", "...", "argN"},
EnvVariable: EnvVariable,
pod: &podInfo{
PodIDFile: "/tmp/pod-foobar.pod-id-file",
@@ -352,10 +454,10 @@ WantedBy=multi-user.target default.target
ServiceName: "jadda-jadda",
ContainerNameOrID: "jadda-jadda",
RestartPolicy: "always",
- PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
- StopTimeout: 42,
+ PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
+ StopTimeout: 10,
PodmanVersion: "CI",
- CreateCommand: []string{"I'll get stripped", "container", "run", "--detach", "--name", "jadda-jadda", "--hostname", "hello-world", "awesome-image:latest", "command", "arg1", "...", "argN"},
+ CreateCommand: []string{"I'll get stripped", "run", "--detach", "--name", "jadda-jadda", "--hostname", "hello-world", "awesome-image:latest", "command", "arg1", "...", "argN"},
EnvVariable: EnvVariable,
},
goodNameNewDetach,
@@ -368,16 +470,144 @@ WantedBy=multi-user.target default.target
ServiceName: "container-639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401",
ContainerNameOrID: "639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401",
RestartPolicy: "always",
- PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
+ PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 10,
PodmanVersion: "CI",
- CreateCommand: []string{"I'll get stripped", "container", "run", "awesome-image:latest"},
+ CreateCommand: []string{"I'll get stripped", "run", "awesome-image:latest"},
EnvVariable: EnvVariable,
},
goodIDNew,
true,
false,
},
+ {"good with explicit detach=true param",
+ containerInfo{
+ Executable: "/usr/bin/podman",
+ ServiceName: "jadda-jadda",
+ ContainerNameOrID: "jadda-jadda",
+ RestartPolicy: "always",
+ PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
+ StopTimeout: 42,
+ PodmanVersion: "CI",
+ CreateCommand: []string{"I'll get stripped", "run", "--detach=true", "awesome-image:latest"},
+ EnvVariable: EnvVariable,
+ },
+ genGoodNewDetach("--detach=true"),
+ true,
+ false,
+ },
+ {"good with explicit detach=false param",
+ containerInfo{
+ Executable: "/usr/bin/podman",
+ ServiceName: "jadda-jadda",
+ ContainerNameOrID: "jadda-jadda",
+ RestartPolicy: "always",
+ PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
+ StopTimeout: 42,
+ PodmanVersion: "CI",
+ CreateCommand: []string{"I'll get stripped", "run", "--detach=false", "awesome-image:latest"},
+ EnvVariable: EnvVariable,
+ },
+ genGoodNewDetach("-d"),
+ true,
+ false,
+ },
+ {"good with explicit detach=false param",
+ containerInfo{
+ Executable: "/usr/bin/podman",
+ ServiceName: "jadda-jadda",
+ ContainerNameOrID: "jadda-jadda",
+ RestartPolicy: "always",
+ PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
+ StopTimeout: 42,
+ PodmanVersion: "CI",
+ CreateCommand: []string{"I'll get stripped", "run", "--name", "test", "-p", "80:80", "--detach=false", "awesome-image:latest", "somecmd", "--detach=false"},
+ EnvVariable: EnvVariable,
+ },
+ goodNameNewDetachFalseWithCmd,
+ true,
+ false,
+ },
+ {"good with multiple detach=false params",
+ containerInfo{
+ Executable: "/usr/bin/podman",
+ ServiceName: "jadda-jadda",
+ ContainerNameOrID: "jadda-jadda",
+ RestartPolicy: "always",
+ PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
+ StopTimeout: 42,
+ PodmanVersion: "CI",
+ CreateCommand: []string{"I'll get stripped", "run", "--name", "test", "-p", "80:80", "--detach=false", "--detach=false", "awesome-image:latest", "somecmd", "--detach=false"},
+ EnvVariable: EnvVariable,
+ },
+ goodNameNewDetachFalseWithCmd,
+ true,
+ false,
+ },
+ {"good with multiple shorthand params detach first",
+ containerInfo{
+ Executable: "/usr/bin/podman",
+ ServiceName: "jadda-jadda",
+ ContainerNameOrID: "jadda-jadda",
+ RestartPolicy: "always",
+ PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
+ StopTimeout: 42,
+ PodmanVersion: "CI",
+ CreateCommand: []string{"I'll get stripped", "run", "-dti", "awesome-image:latest"},
+ EnvVariable: EnvVariable,
+ },
+ genGoodNewDetach("-dti"),
+ true,
+ false,
+ },
+ {"good with multiple shorthand params detach last",
+ containerInfo{
+ Executable: "/usr/bin/podman",
+ ServiceName: "jadda-jadda",
+ ContainerNameOrID: "jadda-jadda",
+ RestartPolicy: "always",
+ PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
+ StopTimeout: 42,
+ PodmanVersion: "CI",
+ CreateCommand: []string{"I'll get stripped", "run", "-tid", "awesome-image:latest"},
+ EnvVariable: EnvVariable,
+ },
+ genGoodNewDetach("-tid"),
+ true,
+ false,
+ },
+ {"good with root flags",
+ containerInfo{
+ Executable: "/usr/bin/podman",
+ ServiceName: "jadda-jadda",
+ ContainerNameOrID: "jadda-jadda",
+ RestartPolicy: "always",
+ PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
+ StopTimeout: 42,
+ PodmanVersion: "CI",
+ CreateCommand: []string{"I'll get stripped", "--events-backend", "none", "--runroot", "/root", "run", "awesome-image:latest"},
+ EnvVariable: EnvVariable,
+ },
+ goodNewRootFlags,
+ true,
+ false,
+ },
+ {"good with container create",
+ containerInfo{
+ Executable: "/usr/bin/podman",
+ ServiceName: "jadda-jadda",
+ ContainerNameOrID: "jadda-jadda",
+ RestartPolicy: "always",
+ PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
+ StopTimeout: 10,
+ PodmanVersion: "CI",
+ CreateCommand: []string{"I'll get stripped", "container", "create", "awesome-image:latest"},
+ EnvVariable: EnvVariable,
+ },
+ goodContainerCreate,
+ true,
+ false,
+ },
}
for _, tt := range tests {
test := tt
@@ -390,9 +620,7 @@ WantedBy=multi-user.target default.target
t.Errorf("CreateContainerSystemdUnit() error = \n%v, wantErr \n%v", err, test.wantErr)
return
}
- if got != test.want {
- t.Errorf("CreateContainerSystemdUnit() = \n%v\n---------> want\n%v", got, test.want)
- }
+ assert.Equal(t, test.want, got)
})
}
}
diff --git a/pkg/systemd/generate/pods.go b/pkg/systemd/generate/pods.go
index 3c57b03fb..7678a240f 100644
--- a/pkg/systemd/generate/pods.go
+++ b/pkg/systemd/generate/pods.go
@@ -14,6 +14,7 @@ import (
"github.com/containers/podman/v2/version"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
+ "github.com/spf13/pflag"
)
// podInfo contains data required for generating a pod's systemd
@@ -44,6 +45,9 @@ type podInfo struct {
// Executable is the path to the podman executable. Will be auto-filled if
// left empty.
Executable string
+ // RootFlags contains the root flags which were used to create the container
+ // Only used with --new
+ RootFlags string
// TimeStamp at the time of creating the unit file. Will be set internally.
TimeStamp string
// CreateCommand is the full command plus arguments of the process the
@@ -60,6 +64,8 @@ type podInfo struct {
ExecStartPre2 string
// ExecStart of the unit.
ExecStart string
+ // TimeoutStopSec of the unit.
+ TimeoutStopSec uint
// ExecStop of the unit.
ExecStop string
// ExecStopPost of the unit.
@@ -72,6 +78,7 @@ Before={{- range $index, $value := .RequiredServices -}}{{if $index}} {{end}}{{
[Service]
Environment={{.EnvVariable}}=%n
Restart={{.RestartPolicy}}
+TimeoutStopSec={{.TimeoutStopSec}}
{{- if .ExecStartPre1}}
ExecStartPre={{.ExecStartPre1}}
{{- end}}
@@ -82,7 +89,6 @@ ExecStart={{.ExecStart}}
ExecStop={{.ExecStop}}
ExecStopPost={{.ExecStopPost}}
PIDFile={{.PIDFile}}
-KillMode=none
Type=forking
[Install]
@@ -262,7 +268,8 @@ func executePodTemplate(info *podInfo, options entities.GenerateSystemdOptions)
if podCreateIndex == 0 {
return "", errors.Errorf("pod does not appear to be created via `podman pod create`: %v", info.CreateCommand)
}
- podRootArgs = info.CreateCommand[0 : podCreateIndex-2]
+ podRootArgs = info.CreateCommand[1 : podCreateIndex-1]
+ info.RootFlags = strings.Join(quoteArguments(podRootArgs), " ")
podCreateArgs = filterPodFlags(info.CreateCommand[podCreateIndex+1:])
}
// We're hard-coding the first five arguments and append the
@@ -275,17 +282,26 @@ func executePodTemplate(info *podInfo, options entities.GenerateSystemdOptions)
"--pod-id-file", "{{.PodIDFile}}"}...)
// Presence check for certain flags/options.
- hasNameParam := false
- hasReplaceParam := false
- for _, p := range podCreateArgs {
- switch p {
- case "--name":
- hasNameParam = true
- case "--replace":
- hasReplaceParam = true
- }
+ fs := pflag.NewFlagSet("args", pflag.ContinueOnError)
+ fs.ParseErrorsWhitelist.UnknownFlags = true
+ fs.Usage = func() {}
+ fs.SetInterspersed(false)
+ fs.String("name", "", "")
+ fs.Bool("replace", false, "")
+ fs.Parse(podCreateArgs)
+
+ hasNameParam := fs.Lookup("name").Changed
+ hasReplaceParam, err := fs.GetBool("replace")
+ if err != nil {
+ return "", err
}
if hasNameParam && !hasReplaceParam {
+ if fs.Changed("replace") {
+ // this can only happen if --replace=false is set
+ // in that case we need to remove it otherwise we
+ // would overwrite the previous replace arg to false
+ podCreateArgs = removeReplaceArg(podCreateArgs, fs.NArg())
+ }
podCreateArgs = append(podCreateArgs, "--replace")
}
@@ -294,10 +310,12 @@ func executePodTemplate(info *podInfo, options entities.GenerateSystemdOptions)
info.ExecStartPre1 = "/bin/rm -f {{.PIDFile}} {{.PodIDFile}}"
info.ExecStartPre2 = strings.Join(startCommand, " ")
- info.ExecStart = "{{.Executable}} pod start --pod-id-file {{.PodIDFile}}"
- info.ExecStop = "{{.Executable}} pod stop --ignore --pod-id-file {{.PodIDFile}} {{if (ge .StopTimeout 0)}}-t {{.StopTimeout}}{{end}}"
- info.ExecStopPost = "{{.Executable}} pod rm --ignore -f --pod-id-file {{.PodIDFile}}"
+ info.ExecStart = "{{.Executable}} {{if .RootFlags}}{{ .RootFlags}} {{end}}pod start --pod-id-file {{.PodIDFile}}"
+ info.ExecStop = "{{.Executable}} {{if .RootFlags}}{{ .RootFlags}} {{end}}pod stop --ignore --pod-id-file {{.PodIDFile}} {{if (ge .StopTimeout 0)}}-t {{.StopTimeout}}{{end}}"
+ info.ExecStopPost = "{{.Executable}} {{if .RootFlags}}{{ .RootFlags}} {{end}}pod rm --ignore -f --pod-id-file {{.PodIDFile}}"
}
+ info.TimeoutStopSec = minTimeoutStopSec + info.StopTimeout
+
if info.PodmanVersion == "" {
info.PodmanVersion = version.Version.String()
}
diff --git a/pkg/systemd/generate/pods_test.go b/pkg/systemd/generate/pods_test.go
index 7f1f63b7e..1c6330160 100644
--- a/pkg/systemd/generate/pods_test.go
+++ b/pkg/systemd/generate/pods_test.go
@@ -4,6 +4,7 @@ import (
"testing"
"github.com/containers/podman/v2/pkg/domain/entities"
+ "github.com/stretchr/testify/assert"
)
func TestValidateRestartPolicyPod(t *testing.T) {
@@ -50,11 +51,11 @@ Before=container-1.service container-2.service
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=always
+TimeoutStopSec=102
ExecStart=/usr/bin/podman start jadda-jadda-infra
-ExecStop=/usr/bin/podman stop -t 10 jadda-jadda-infra
-ExecStopPost=/usr/bin/podman stop -t 10 jadda-jadda-infra
-PIDFile=/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid
-KillMode=none
+ExecStop=/usr/bin/podman stop -t 42 jadda-jadda-infra
+ExecStopPost=/usr/bin/podman stop -t 42 jadda-jadda-infra
+PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid
Type=forking
[Install]
@@ -75,13 +76,67 @@ Before=container-1.service container-2.service
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=on-failure
+TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/pod-123abc.pid %t/pod-123abc.pod-id
ExecStartPre=/usr/bin/podman pod create --infra-conmon-pidfile %t/pod-123abc.pid --pod-id-file %t/pod-123abc.pod-id --name foo "bar=arg with space" --replace
ExecStart=/usr/bin/podman pod start --pod-id-file %t/pod-123abc.pod-id
ExecStop=/usr/bin/podman pod stop --ignore --pod-id-file %t/pod-123abc.pod-id -t 10
ExecStopPost=/usr/bin/podman pod rm --ignore -f --pod-id-file %t/pod-123abc.pod-id
PIDFile=%t/pod-123abc.pid
-KillMode=none
+Type=forking
+
+[Install]
+WantedBy=multi-user.target default.target
+`
+
+ podGoodNamedNewWithRootArgs := `# pod-123abc.service
+# autogenerated by Podman CI
+
+[Unit]
+Description=Podman pod-123abc.service
+Documentation=man:podman-generate-systemd(1)
+Wants=network.target
+After=network-online.target
+Requires=container-1.service container-2.service
+Before=container-1.service container-2.service
+
+[Service]
+Environment=PODMAN_SYSTEMD_UNIT=%n
+Restart=on-failure
+TimeoutStopSec=70
+ExecStartPre=/bin/rm -f %t/pod-123abc.pid %t/pod-123abc.pod-id
+ExecStartPre=/usr/bin/podman --events-backend none --runroot /root pod create --infra-conmon-pidfile %t/pod-123abc.pid --pod-id-file %t/pod-123abc.pod-id --name foo "bar=arg with space" --replace
+ExecStart=/usr/bin/podman --events-backend none --runroot /root pod start --pod-id-file %t/pod-123abc.pod-id
+ExecStop=/usr/bin/podman --events-backend none --runroot /root pod stop --ignore --pod-id-file %t/pod-123abc.pod-id -t 10
+ExecStopPost=/usr/bin/podman --events-backend none --runroot /root pod rm --ignore -f --pod-id-file %t/pod-123abc.pod-id
+PIDFile=%t/pod-123abc.pid
+Type=forking
+
+[Install]
+WantedBy=multi-user.target default.target
+`
+
+ podGoodNamedNewWithReplaceFalse := `# pod-123abc.service
+# autogenerated by Podman CI
+
+[Unit]
+Description=Podman pod-123abc.service
+Documentation=man:podman-generate-systemd(1)
+Wants=network.target
+After=network-online.target
+Requires=container-1.service container-2.service
+Before=container-1.service container-2.service
+
+[Service]
+Environment=PODMAN_SYSTEMD_UNIT=%n
+Restart=on-failure
+TimeoutStopSec=70
+ExecStartPre=/bin/rm -f %t/pod-123abc.pid %t/pod-123abc.pod-id
+ExecStartPre=/usr/bin/podman pod create --infra-conmon-pidfile %t/pod-123abc.pid --pod-id-file %t/pod-123abc.pod-id --name foo --replace
+ExecStart=/usr/bin/podman pod start --pod-id-file %t/pod-123abc.pod-id
+ExecStop=/usr/bin/podman pod stop --ignore --pod-id-file %t/pod-123abc.pod-id -t 10
+ExecStopPost=/usr/bin/podman pod rm --ignore -f --pod-id-file %t/pod-123abc.pod-id
+PIDFile=%t/pod-123abc.pid
Type=forking
[Install]
@@ -101,10 +156,27 @@ WantedBy=multi-user.target default.target
ServiceName: "pod-123abc",
InfraNameOrID: "jadda-jadda-infra",
RestartPolicy: "always",
- PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
- StopTimeout: 10,
+ PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
+ StopTimeout: 42,
PodmanVersion: "CI",
RequiredServices: []string{"container-1", "container-2"},
+ CreateCommand: []string{"podman", "pod", "create", "--name", "foo", "bar=arg with space"},
+ },
+ podGood,
+ false,
+ false,
+ },
+ {"pod with root args",
+ podInfo{
+ Executable: "/usr/bin/podman",
+ ServiceName: "pod-123abc",
+ InfraNameOrID: "jadda-jadda-infra",
+ RestartPolicy: "always",
+ PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
+ StopTimeout: 42,
+ PodmanVersion: "CI",
+ RequiredServices: []string{"container-1", "container-2"},
+ CreateCommand: []string{"podman", "--events-backend", "none", "--runroot", "/root", "pod", "create", "--name", "foo", "bar=arg with space"},
},
podGood,
false,
@@ -116,7 +188,7 @@ WantedBy=multi-user.target default.target
ServiceName: "pod-123abc",
InfraNameOrID: "jadda-jadda-infra",
RestartPolicy: "on-failure",
- PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
+ PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 10,
PodmanVersion: "CI",
RequiredServices: []string{"container-1", "container-2"},
@@ -126,6 +198,38 @@ WantedBy=multi-user.target default.target
true,
false,
},
+ {"pod --new with root args",
+ podInfo{
+ Executable: "/usr/bin/podman",
+ ServiceName: "pod-123abc",
+ InfraNameOrID: "jadda-jadda-infra",
+ RestartPolicy: "on-failure",
+ PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
+ StopTimeout: 10,
+ PodmanVersion: "CI",
+ RequiredServices: []string{"container-1", "container-2"},
+ CreateCommand: []string{"podman", "--events-backend", "none", "--runroot", "/root", "pod", "create", "--name", "foo", "bar=arg with space"},
+ },
+ podGoodNamedNewWithRootArgs,
+ true,
+ false,
+ },
+ {"pod --new with --replace=false",
+ podInfo{
+ Executable: "/usr/bin/podman",
+ ServiceName: "pod-123abc",
+ InfraNameOrID: "jadda-jadda-infra",
+ RestartPolicy: "on-failure",
+ PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
+ StopTimeout: 10,
+ PodmanVersion: "CI",
+ RequiredServices: []string{"container-1", "container-2"},
+ CreateCommand: []string{"podman", "pod", "create", "--name", "foo", "--replace=false"},
+ },
+ podGoodNamedNewWithReplaceFalse,
+ true,
+ false,
+ },
}
for _, tt := range tests {
@@ -139,9 +243,7 @@ WantedBy=multi-user.target default.target
t.Errorf("CreatePodSystemdUnit() error = \n%v, wantErr \n%v", err, test.wantErr)
return
}
- if got != test.want {
- t.Errorf("CreatePodSystemdUnit() = \n%v\n---------> want\n%v", got, test.want)
- }
+ assert.Equal(t, test.want, got)
})
}
}