summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
authorOpenShift Merge Robot <openshift-merge-robot@users.noreply.github.com>2020-03-27 16:25:30 +0100
committerGitHub <noreply@github.com>2020-03-27 16:25:30 +0100
commit4233250c430a8f769048548b6ad6affd0d9e65e0 (patch)
tree0cf0c3dc86ccf85be3d5098f278021798c3f6b6c /pkg
parent3ddb5b10d53df54346a6d795047124fc4e995699 (diff)
parente56d5295614b745115abf0198f7b67ae157aae1e (diff)
downloadpodman-4233250c430a8f769048548b6ad6affd0d9e65e0.tar.gz
podman-4233250c430a8f769048548b6ad6affd0d9e65e0.tar.bz2
podman-4233250c430a8f769048548b6ad6affd0d9e65e0.zip
Merge pull request #5611 from baude/v2podcreate
podmanv2 pod create using podspecgen
Diffstat (limited to 'pkg')
-rw-r--r--pkg/adapter/runtime.go8
-rw-r--r--pkg/api/handlers/libpod/pods.go74
-rw-r--r--pkg/api/handlers/libpod/volumes.go9
-rw-r--r--pkg/api/handlers/types.go13
-rw-r--r--pkg/api/server/register_pods.go2
-rw-r--r--pkg/bindings/pods/pods.go24
-rw-r--r--pkg/bindings/test/pods_test.go12
-rw-r--r--pkg/domain/entities/engine_container.go2
-rw-r--r--pkg/domain/entities/pods.go51
-rw-r--r--pkg/domain/entities/types.go27
-rw-r--r--pkg/domain/infra/abi/pods.go11
-rw-r--r--pkg/domain/infra/abi/volumes.go15
-rw-r--r--pkg/domain/infra/tunnel/pods.go7
-rw-r--r--pkg/specgen/container_create.go (renamed from pkg/specgen/create.go)2
-rw-r--r--pkg/specgen/container_validate.go (renamed from pkg/specgen/validate.go)4
-rw-r--r--pkg/specgen/pod_create.go83
-rw-r--r--pkg/specgen/pod_validate.go104
-rw-r--r--pkg/specgen/podspecgen.go (renamed from pkg/specgen/pod.go)13
-rw-r--r--pkg/specgen/specgen.go6
-rw-r--r--pkg/varlinkapi/volumes.go10
20 files changed, 371 insertions, 106 deletions
diff --git a/pkg/adapter/runtime.go b/pkg/adapter/runtime.go
index 7817a1f98..76e221fae 100644
--- a/pkg/adapter/runtime.go
+++ b/pkg/adapter/runtime.go
@@ -356,11 +356,11 @@ func (r *LocalRuntime) PruneVolumes(ctx context.Context) ([]string, []error) {
errs = append(errs, err)
return vids, errs
}
- for _, r := range reports {
- if r.Err == nil {
- vids = append(vids, r.Id)
+ for k, v := range reports {
+ if v == nil {
+ vids = append(vids, k)
} else {
- errs = append(errs, r.Err)
+ errs = append(errs, v)
}
}
return vids, errs
diff --git a/pkg/api/handlers/libpod/pods.go b/pkg/api/handlers/libpod/pods.go
index 5baf61ac9..7e9c2e2c0 100644
--- a/pkg/api/handlers/libpod/pods.go
+++ b/pkg/api/handlers/libpod/pods.go
@@ -4,15 +4,13 @@ import (
"encoding/json"
"fmt"
"net/http"
- "strings"
- "github.com/containers/libpod/cmd/podman/shared"
- "github.com/containers/libpod/cmd/podman/shared/parse"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/pkg/api/handlers"
"github.com/containers/libpod/pkg/api/handlers/utils"
"github.com/containers/libpod/pkg/domain/entities"
+ "github.com/containers/libpod/pkg/specgen"
"github.com/containers/libpod/pkg/util"
"github.com/gorilla/schema"
"github.com/pkg/errors"
@@ -21,76 +19,14 @@ import (
func PodCreate(w http.ResponseWriter, r *http.Request) {
var (
runtime = r.Context().Value("runtime").(*libpod.Runtime)
- options []libpod.PodCreateOption
err error
)
- labels := make(map[string]string)
- input := handlers.PodCreateConfig{}
- if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
- utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Decode()"))
+ var psg specgen.PodSpecGenerator
+ if err := json.NewDecoder(r.Body).Decode(&psg); err != nil {
+ utils.Error(w, "Failed to decode specgen", http.StatusInternalServerError, errors.Wrap(err, "failed to decode specgen"))
return
}
- if len(input.InfraCommand) > 0 || len(input.InfraImage) > 0 {
- utils.Error(w, "Something went wrong.", http.StatusInternalServerError,
- errors.New("infra-command and infra-image are not implemented yet"))
- return
- }
- // TODO long term we should break the following out of adapter and into libpod proper
- // so that the cli and api can share the creation of a pod with the same options
- if len(input.CGroupParent) > 0 {
- options = append(options, libpod.WithPodCgroupParent(input.CGroupParent))
- }
-
- if len(input.Labels) > 0 {
- labels, err = parse.GetAllLabels([]string{}, input.Labels)
- if err != nil {
- utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err)
- return
- }
- }
-
- if len(labels) != 0 {
- options = append(options, libpod.WithPodLabels(labels))
- }
-
- if len(input.Name) > 0 {
- options = append(options, libpod.WithPodName(input.Name))
- }
-
- if len(input.Hostname) > 0 {
- options = append(options, libpod.WithPodHostname(input.Hostname))
- }
-
- if input.Infra {
- // TODO infra-image and infra-command are not supported in the libpod API yet. Will fix
- // when implemented in libpod
- options = append(options, libpod.WithInfraContainer())
- sharedNamespaces := shared.DefaultKernelNamespaces
- if len(input.Share) > 0 {
- sharedNamespaces = input.Share
- }
- nsOptions, err := shared.GetNamespaceOptions(strings.Split(sharedNamespaces, ","))
- if err != nil {
- utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err)
- return
- }
- options = append(options, nsOptions...)
- }
-
- if len(input.Publish) > 0 {
- portBindings, err := shared.CreatePortBindings(input.Publish)
- if err != nil {
- utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err)
- return
- }
- options = append(options, libpod.WithInfraContainerPorts(portBindings))
-
- }
- // always have containers use pod cgroups
- // User Opt out is not yet supported
- options = append(options, libpod.WithPodCgroups())
-
- pod, err := runtime.NewPod(r.Context(), options...)
+ pod, err := psg.MakePod(runtime)
if err != nil {
http_code := http.StatusInternalServerError
if errors.Cause(err) == define.ErrPodExists {
diff --git a/pkg/api/handlers/libpod/volumes.go b/pkg/api/handlers/libpod/volumes.go
index e61d272f4..5a6fc021e 100644
--- a/pkg/api/handlers/libpod/volumes.go
+++ b/pkg/api/handlers/libpod/volumes.go
@@ -149,13 +149,20 @@ func ListVolumes(w http.ResponseWriter, r *http.Request) {
func PruneVolumes(w http.ResponseWriter, r *http.Request) {
var (
runtime = r.Context().Value("runtime").(*libpod.Runtime)
+ reports []*entities.VolumePruneReport
)
pruned, err := runtime.PruneVolumes(r.Context())
if err != nil {
utils.InternalServerError(w, err)
return
}
- utils.WriteResponse(w, http.StatusOK, pruned)
+ for k, v := range pruned {
+ reports = append(reports, &entities.VolumePruneReport{
+ Err: v,
+ Id: k,
+ })
+ }
+ utils.WriteResponse(w, http.StatusOK, reports)
}
func RemoveVolume(w http.ResponseWriter, r *http.Request) {
diff --git a/pkg/api/handlers/types.go b/pkg/api/handlers/types.go
index fe4198c37..1ca5db3f9 100644
--- a/pkg/api/handlers/types.go
+++ b/pkg/api/handlers/types.go
@@ -133,19 +133,6 @@ type ContainerTopOKBody struct {
dockerContainer.ContainerTopOKBody
}
-// swagger:model PodCreateConfig
-type PodCreateConfig struct {
- Name string `json:"name"`
- CGroupParent string `json:"cgroup-parent"`
- Hostname string `json:"hostname"`
- Infra bool `json:"infra"`
- InfraCommand string `json:"infra-command"`
- InfraImage string `json:"infra-image"`
- Labels []string `json:"labels"`
- Publish []string `json:"publish"`
- Share string `json:"share"`
-}
-
type ErrorModel struct {
Message string `json:"message"`
}
diff --git a/pkg/api/server/register_pods.go b/pkg/api/server/register_pods.go
index 87194fdd7..5ba2263e8 100644
--- a/pkg/api/server/register_pods.go
+++ b/pkg/api/server/register_pods.go
@@ -37,7 +37,7 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error {
// description: attributes for creating a pod
// schema:
// type: object
- // $ref: "#/definitions/PodCreateConfig"
+ // $ref: "#/definitions/PodSpecGenerator"
// responses:
// 200:
// $ref: "#/definitions/IdResponse"
diff --git a/pkg/bindings/pods/pods.go b/pkg/bindings/pods/pods.go
index 49cce6e2b..bb0abebc4 100644
--- a/pkg/bindings/pods/pods.go
+++ b/pkg/bindings/pods/pods.go
@@ -5,15 +5,33 @@ import (
"net/http"
"net/url"
"strconv"
+ "strings"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/bindings"
"github.com/containers/libpod/pkg/domain/entities"
+ "github.com/containers/libpod/pkg/specgen"
+ jsoniter "github.com/json-iterator/go"
)
-func CreatePod() error {
- // TODO
- return bindings.ErrNotImplemented
+func CreatePodFromSpec(ctx context.Context, s *specgen.PodSpecGenerator) (*entities.PodCreateReport, error) {
+ var (
+ pcr entities.PodCreateReport
+ )
+ conn, err := bindings.GetClient(ctx)
+ if err != nil {
+ return nil, err
+ }
+ specgenString, err := jsoniter.MarshalToString(s)
+ if err != nil {
+ return nil, err
+ }
+ stringReader := strings.NewReader(specgenString)
+ response, err := conn.DoRequest(stringReader, http.MethodPost, "/pods/create", nil)
+ if err != nil {
+ return nil, err
+ }
+ return &pcr, response.Process(&pcr)
}
// Exists is a lightweight method to determine if a pod exists in local storage
diff --git a/pkg/bindings/test/pods_test.go b/pkg/bindings/test/pods_test.go
index c54170648..0f786e341 100644
--- a/pkg/bindings/test/pods_test.go
+++ b/pkg/bindings/test/pods_test.go
@@ -7,6 +7,7 @@ import (
"github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/pkg/bindings"
"github.com/containers/libpod/pkg/bindings/pods"
+ "github.com/containers/libpod/pkg/specgen"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gexec"
@@ -307,4 +308,15 @@ var _ = Describe("Podman pods", func() {
Expect(err).To(BeNil())
Expect(len(podSummary)).To(Equal(0))
})
+
+ It("simple create pod", func() {
+ ps := specgen.PodSpecGenerator{}
+ ps.Name = "foobar"
+ _, err := pods.CreatePodFromSpec(bt.conn, &ps)
+ Expect(err).To(BeNil())
+
+ exists, err := pods.Exists(bt.conn, "foobar")
+ Expect(err).To(BeNil())
+ Expect(exists).To(BeTrue())
+ })
})
diff --git a/pkg/domain/entities/engine_container.go b/pkg/domain/entities/engine_container.go
index 21a674c43..fceed1003 100644
--- a/pkg/domain/entities/engine_container.go
+++ b/pkg/domain/entities/engine_container.go
@@ -15,7 +15,7 @@ type ContainerEngine interface {
ContainerStop(ctx context.Context, namesOrIds []string, options StopOptions) ([]*StopReport, error)
ContainerWait(ctx context.Context, namesOrIds []string, options WaitOptions) ([]WaitReport, error)
ContainerTop(ctx context.Context, options TopOptions) (*StringSliceReport, error)
-
+ PodCreate(ctx context.Context, opts PodCreateOptions) (*PodCreateReport, error)
PodExists(ctx context.Context, nameOrId string) (*BoolReport, error)
PodKill(ctx context.Context, namesOrIds []string, options PodKillOptions) ([]*PodKillReport, error)
PodPause(ctx context.Context, namesOrIds []string, options PodPauseOptions) ([]*PodPauseReport, error)
diff --git a/pkg/domain/entities/pods.go b/pkg/domain/entities/pods.go
index 8d594620f..efda17d65 100644
--- a/pkg/domain/entities/pods.go
+++ b/pkg/domain/entities/pods.go
@@ -1,6 +1,10 @@
package entities
-import "time"
+import (
+ "time"
+
+ "github.com/containers/libpod/pkg/specgen"
+)
type PodKillOptions struct {
All bool
@@ -92,3 +96,48 @@ type PodRmReport struct {
Err error
Id string
}
+
+type PodCreateOptions struct {
+ CGroupParent string
+ Hostname string
+ Infra bool
+ InfraImage string
+ InfraCommand string
+ Labels map[string]string
+ Name string
+ Net *NetOptions
+ Share []string
+}
+
+type PodCreateReport struct {
+ Id string
+}
+
+func (p PodCreateOptions) ToPodSpecGen(s *specgen.PodSpecGenerator) {
+ // Basic Config
+ s.Name = p.Name
+ s.Hostname = p.Hostname
+ s.Labels = p.Labels
+ s.NoInfra = !p.Infra
+ s.InfraCommand = []string{p.InfraCommand}
+ s.InfraImage = p.InfraImage
+ s.SharedNamespaces = p.Share
+
+ // Networking config
+ s.NetNS = p.Net.Network
+ s.StaticIP = p.Net.StaticIP
+ s.StaticMAC = p.Net.StaticMAC
+ s.PortMappings = p.Net.PublishPorts
+ s.CNINetworks = p.Net.CNINetworks
+ if p.Net.DNSHost {
+ s.NoManageResolvConf = true
+ }
+ s.DNSServer = p.Net.DNSServers
+ s.DNSSearch = p.Net.DNSSearch
+ s.DNSOption = p.Net.DNSOptions
+ s.NoManageHosts = p.Net.NoHosts
+ s.HostAdd = p.Net.AddHosts
+
+ // Cgroup
+ s.CgroupParent = p.CGroupParent
+}
diff --git a/pkg/domain/entities/types.go b/pkg/domain/entities/types.go
index e7757a74b..a1a729584 100644
--- a/pkg/domain/entities/types.go
+++ b/pkg/domain/entities/types.go
@@ -1,5 +1,12 @@
package entities
+import (
+ "net"
+
+ "github.com/containers/libpod/pkg/specgen"
+ "github.com/cri-o/ocicni/pkg/ocicni"
+)
+
type Container struct {
IdOrNamed
}
@@ -15,3 +22,23 @@ type Report struct {
type PodDeleteReport struct{ Report }
type PodPruneOptions struct{}
+
+type PodPruneReport struct{ Report }
+type VolumeDeleteOptions struct{}
+type VolumeDeleteReport struct{ Report }
+
+// NetOptions reflect the shared network options between
+// pods and containers
+type NetOptions struct {
+ AddHosts []string
+ CNINetworks []string
+ DNSHost bool
+ DNSOptions []string
+ DNSSearch []string
+ DNSServers []net.IP
+ Network specgen.Namespace
+ NoHosts bool
+ PublishPorts []ocicni.PortMapping
+ StaticIP *net.IP
+ StaticMAC *net.HardwareAddr
+}
diff --git a/pkg/domain/infra/abi/pods.go b/pkg/domain/infra/abi/pods.go
index 4f68ad5f9..619e973cf 100644
--- a/pkg/domain/infra/abi/pods.go
+++ b/pkg/domain/infra/abi/pods.go
@@ -9,6 +9,7 @@ import (
"github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/pkg/domain/entities"
"github.com/containers/libpod/pkg/signal"
+ "github.com/containers/libpod/pkg/specgen"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
@@ -239,3 +240,13 @@ func (ic *ContainerEngine) PodRm(ctx context.Context, namesOrIds []string, optio
}
return reports, nil
}
+
+func (ic *ContainerEngine) PodCreate(ctx context.Context, opts entities.PodCreateOptions) (*entities.PodCreateReport, error) {
+ podSpec := specgen.NewPodSpecGenerator()
+ opts.ToPodSpecGen(podSpec)
+ pod, err := podSpec.MakePod(ic.Libpod)
+ if err != nil {
+ return nil, err
+ }
+ return &entities.PodCreateReport{Id: pod.ID()}, nil
+}
diff --git a/pkg/domain/infra/abi/volumes.go b/pkg/domain/infra/abi/volumes.go
index 5527bb82e..bdae4359d 100644
--- a/pkg/domain/infra/abi/volumes.go
+++ b/pkg/domain/infra/abi/volumes.go
@@ -113,7 +113,20 @@ func (ic *ContainerEngine) VolumeInspect(ctx context.Context, namesOrIds []strin
}
func (ic *ContainerEngine) VolumePrune(ctx context.Context, opts entities.VolumePruneOptions) ([]*entities.VolumePruneReport, error) {
- return ic.Libpod.PruneVolumes(ctx)
+ var (
+ reports []*entities.VolumePruneReport
+ )
+ pruned, err := ic.Libpod.PruneVolumes(ctx)
+ if err != nil {
+ return nil, err
+ }
+ for k, v := range pruned {
+ reports = append(reports, &entities.VolumePruneReport{
+ Err: v,
+ Id: k,
+ })
+ }
+ return reports, nil
}
func (ic *ContainerEngine) VolumeList(ctx context.Context, opts entities.VolumeListOptions) ([]*entities.VolumeListReport, error) {
diff --git a/pkg/domain/infra/tunnel/pods.go b/pkg/domain/infra/tunnel/pods.go
index 53003da42..4894874e5 100644
--- a/pkg/domain/infra/tunnel/pods.go
+++ b/pkg/domain/infra/tunnel/pods.go
@@ -5,6 +5,7 @@ import (
"github.com/containers/libpod/pkg/bindings/pods"
"github.com/containers/libpod/pkg/domain/entities"
+ "github.com/containers/libpod/pkg/specgen"
)
func (ic *ContainerEngine) PodExists(ctx context.Context, nameOrId string) (*entities.BoolReport, error) {
@@ -170,3 +171,9 @@ func (ic *ContainerEngine) PodRm(ctx context.Context, namesOrIds []string, optio
}
return reports, nil
}
+
+func (ic *ContainerEngine) PodCreate(ctx context.Context, opts entities.PodCreateOptions) (*entities.PodCreateReport, error) {
+ podSpec := specgen.NewPodSpecGenerator()
+ opts.ToPodSpecGen(podSpec)
+ return pods.CreatePodFromSpec(ic.ClientCxt, podSpec)
+}
diff --git a/pkg/specgen/create.go b/pkg/specgen/container_create.go
index aefbe7405..cf082441d 100644
--- a/pkg/specgen/create.go
+++ b/pkg/specgen/container_create.go
@@ -13,7 +13,7 @@ import (
// MakeContainer creates a container based on the SpecGenerator
func (s *SpecGenerator) MakeContainer(rt *libpod.Runtime) (*libpod.Container, error) {
- if err := s.validate(rt); err != nil {
+ if err := s.validate(); err != nil {
return nil, errors.Wrap(err, "invalid config provided")
}
rtc, err := rt.GetConfig()
diff --git a/pkg/specgen/validate.go b/pkg/specgen/container_validate.go
index 5f567f725..b27659f5f 100644
--- a/pkg/specgen/validate.go
+++ b/pkg/specgen/container_validate.go
@@ -4,8 +4,6 @@ import (
"strings"
"github.com/containers/libpod/pkg/rootless"
-
- "github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/util"
"github.com/pkg/errors"
)
@@ -25,7 +23,7 @@ func exclusiveOptions(opt1, opt2 string) error {
// Validate verifies that the given SpecGenerator is valid and satisfies required
// input for creating a container.
-func (s *SpecGenerator) validate(rt *libpod.Runtime) error {
+func (s *SpecGenerator) validate() error {
//
// ContainerBasicConfig
diff --git a/pkg/specgen/pod_create.go b/pkg/specgen/pod_create.go
new file mode 100644
index 000000000..06aa24e22
--- /dev/null
+++ b/pkg/specgen/pod_create.go
@@ -0,0 +1,83 @@
+package specgen
+
+import (
+ "context"
+
+ "github.com/containers/libpod/cmd/podman/shared"
+ "github.com/containers/libpod/libpod"
+ "github.com/sirupsen/logrus"
+)
+
+func (p *PodSpecGenerator) MakePod(rt *libpod.Runtime) (*libpod.Pod, error) {
+ if err := p.validate(); err != nil {
+ return nil, err
+ }
+ options, err := p.createPodOptions()
+ if err != nil {
+ return nil, err
+ }
+ return rt.NewPod(context.Background(), options...)
+}
+
+func (p *PodSpecGenerator) createPodOptions() ([]libpod.PodCreateOption, error) {
+ var (
+ options []libpod.PodCreateOption
+ )
+ if !p.NoInfra {
+ options = append(options, libpod.WithInfraContainer())
+ nsOptions, err := shared.GetNamespaceOptions(p.SharedNamespaces)
+ if err != nil {
+ return nil, err
+ }
+ options = append(options, nsOptions...)
+ }
+ if len(p.CgroupParent) > 0 {
+ options = append(options, libpod.WithPodCgroupParent(p.CgroupParent))
+ }
+ if len(p.Labels) > 0 {
+ options = append(options, libpod.WithPodLabels(p.Labels))
+ }
+ if len(p.Name) > 0 {
+ options = append(options, libpod.WithPodName(p.Name))
+ }
+ if len(p.Hostname) > 0 {
+ options = append(options, libpod.WithPodHostname(p.Hostname))
+ }
+ if len(p.HostAdd) > 0 {
+ options = append(options, libpod.WithPodHosts(p.HostAdd))
+ }
+ if len(p.DNSOption) > 0 {
+ options = append(options, libpod.WithPodDNSOption(p.DNSOption))
+ }
+ if len(p.DNSSearch) > 0 {
+ options = append(options, libpod.WithPodDNSSearch(p.DNSSearch))
+ }
+ if p.StaticIP != nil {
+ options = append(options, libpod.WithPodStaticIP(*p.StaticIP))
+ }
+ if p.StaticMAC != nil {
+ options = append(options, libpod.WithPodStaticMAC(*p.StaticMAC))
+ }
+ if p.NoManageResolvConf {
+ options = append(options, libpod.WithPodUseImageResolvConf())
+ }
+ switch p.NetNS.NSMode {
+ case Bridge:
+ logrus.Debugf("Pod using default network mode")
+ case Host:
+ logrus.Debugf("Pod will use host networking")
+ options = append(options, libpod.WithPodHostNetwork())
+ default:
+ logrus.Debugf("Pod joining CNI networks: %v", p.CNINetworks)
+ options = append(options, libpod.WithPodNetworks(p.CNINetworks))
+ }
+
+ if p.NoManageHosts {
+ options = append(options, libpod.WithPodUseImageHosts())
+ }
+ if len(p.PortMappings) > 0 {
+ options = append(options, libpod.WithInfraContainerPorts(p.PortMappings))
+ }
+ options = append(options, libpod.WithPodCgroups())
+ return options, nil
+}
diff --git a/pkg/specgen/pod_validate.go b/pkg/specgen/pod_validate.go
new file mode 100644
index 000000000..50309f096
--- /dev/null
+++ b/pkg/specgen/pod_validate.go
@@ -0,0 +1,104 @@
+package specgen
+
+import (
+ "github.com/containers/libpod/libpod/define"
+ "github.com/containers/libpod/pkg/rootless"
+ "github.com/pkg/errors"
+)
+
+var (
+ // ErrInvalidPodSpecConfig describes an error given when the podspecgenerator is invalid
+ ErrInvalidPodSpecConfig error = errors.New("invalid pod spec")
+)
+
+func exclusivePodOptions(opt1, opt2 string) error {
+ return errors.Wrapf(ErrInvalidPodSpecConfig, "%s and %s are mutually exclusive pod options", opt1, opt2)
+}
+
+func (p *PodSpecGenerator) validate() error {
+ // PodBasicConfig
+ if p.NoInfra {
+ if len(p.InfraCommand) > 0 {
+ return exclusivePodOptions("NoInfra", "InfraCommand")
+ }
+ if len(p.InfraImage) > 0 {
+ return exclusivePodOptions("NoInfra", "InfraImage")
+ }
+ if len(p.SharedNamespaces) > 0 {
+ return exclusivePodOptions("NoInfo", "SharedNamespaces")
+ }
+ }
+
+ // PodNetworkConfig
+ if err := p.NetNS.validate(); err != nil {
+ return err
+ }
+ if p.NoInfra {
+ if p.NetNS.NSMode == NoNetwork {
+ return errors.New("NoInfra and a none network cannot be used toegther")
+ }
+ if p.StaticIP != nil {
+ return exclusivePodOptions("NoInfra", "StaticIP")
+ }
+ if p.StaticMAC != nil {
+ return exclusivePodOptions("NoInfra", "StaticMAC")
+ }
+ if len(p.DNSOption) > 0 {
+ return exclusivePodOptions("NoInfra", "DNSOption")
+ }
+ if len(p.DNSSearch) > 0 {
+ return exclusivePodOptions("NoInfo", "DNSSearch")
+ }
+ if len(p.DNSServer) > 0 {
+ return exclusivePodOptions("NoInfra", "DNSServer")
+ }
+ if len(p.HostAdd) > 0 {
+ return exclusivePodOptions("NoInfra", "HostAdd")
+ }
+ if p.NoManageResolvConf {
+ return exclusivePodOptions("NoInfra", "NoManageResolvConf")
+ }
+ }
+ if p.NetNS.NSMode != Bridge {
+ if len(p.PortMappings) > 0 {
+ return errors.New("PortMappings can only be used with Bridge mode networking")
+ }
+ if len(p.CNINetworks) > 0 {
+ return errors.New("CNINetworks can only be used with Bridge mode networking")
+ }
+ }
+ if p.NoManageResolvConf {
+ if len(p.DNSServer) > 0 {
+ return exclusivePodOptions("NoManageResolvConf", "DNSServer")
+ }
+ if len(p.DNSSearch) > 0 {
+ return exclusivePodOptions("NoManageResolvConf", "DNSSearch")
+ }
+ if len(p.DNSOption) > 0 {
+ return exclusivePodOptions("NoManageResolvConf", "DNSOption")
+ }
+ }
+ if p.NoManageHosts && len(p.HostAdd) > 0 {
+ return exclusivePodOptions("NoManageHosts", "HostAdd")
+ }
+
+ if err := p.NetNS.validate(); err != nil {
+ return err
+ }
+
+ // Set Defaults
+ if p.NetNS.Value == "" {
+ if rootless.IsRootless() {
+ p.NetNS.NSMode = Slirp
+ } else {
+ p.NetNS.NSMode = Bridge
+ }
+ }
+ if len(p.InfraImage) < 1 {
+ p.InfraImage = define.DefaultInfraImage
+ }
+ if len(p.InfraCommand) < 1 {
+ p.InfraCommand = []string{define.DefaultInfraCommand}
+ }
+ return nil
+}
diff --git a/pkg/specgen/pod.go b/pkg/specgen/podspecgen.go
index 1aada83c4..3f830014d 100644
--- a/pkg/specgen/pod.go
+++ b/pkg/specgen/podspecgen.go
@@ -138,3 +138,16 @@ type PodCgroupConfig struct {
// Optional.
CgroupParent string `json:"cgroup_parent,omitempty"`
}
+
+// PodSpecGenerator describes options to create a pod
+// swagger:model PodSpecGenerator
+type PodSpecGenerator struct {
+ PodBasicConfig
+ PodNetworkConfig
+ PodCgroupConfig
+}
+
+// NewPodSpecGenerator creates a new pod spec
+func NewPodSpecGenerator() *PodSpecGenerator {
+ return &PodSpecGenerator{}
+}
diff --git a/pkg/specgen/specgen.go b/pkg/specgen/specgen.go
index b123c1da5..89c76c273 100644
--- a/pkg/specgen/specgen.go
+++ b/pkg/specgen/specgen.go
@@ -394,18 +394,18 @@ type SpecGenerator struct {
// NewSpecGenerator returns a SpecGenerator struct given one of two mandatory inputs
func NewSpecGenerator(image string) *SpecGenerator {
- net := ContainerNetworkConfig{
+ networkConfig := ContainerNetworkConfig{
NetNS: Namespace{
NSMode: Bridge,
},
}
csc := ContainerStorageConfig{Image: image}
if rootless.IsRootless() {
- net.NetNS.NSMode = Slirp
+ networkConfig.NetNS.NSMode = Slirp
}
return &SpecGenerator{
ContainerStorageConfig: csc,
- ContainerNetworkConfig: net,
+ ContainerNetworkConfig: networkConfig,
}
}
diff --git a/pkg/varlinkapi/volumes.go b/pkg/varlinkapi/volumes.go
index cbb4a70cc..e497cb537 100644
--- a/pkg/varlinkapi/volumes.go
+++ b/pkg/varlinkapi/volumes.go
@@ -6,7 +6,7 @@ import (
"encoding/json"
"github.com/containers/libpod/cmd/podman/shared"
- "github.com/containers/libpod/cmd/podman/varlink"
+ iopodman "github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/libpod"
)
@@ -113,11 +113,11 @@ func (i *LibpodAPI) VolumesPrune(call iopodman.VarlinkCall) error {
if err != nil {
return call.ReplyVolumesPrune([]string{}, []string{err.Error()})
}
- for _, i := range responses {
- if i.Err == nil {
- prunedNames = append(prunedNames, i.Id)
+ for k, v := range responses {
+ if v == nil {
+ prunedNames = append(prunedNames, k)
} else {
- prunedErrors = append(prunedErrors, i.Err.Error())
+ prunedErrors = append(prunedErrors, v.Error())
}
}
return call.ReplyVolumesPrune(prunedNames, prunedErrors)