summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
authorBrent Baude <bbaude@redhat.com>2021-08-16 09:37:50 -0500
committerBrent Baude <bbaude@redhat.com>2021-08-24 14:26:14 -0500
commit1e176923b15360559d859000f2fb0c0a3e30f792 (patch)
tree5a888021a0fa58375ebe947b86e5dc37fd8d22a0 /pkg
parente9daaf62e3921b8c696f3abd92f001a9447c8aa1 (diff)
downloadpodman-1e176923b15360559d859000f2fb0c0a3e30f792.tar.gz
podman-1e176923b15360559d859000f2fb0c0a3e30f792.tar.bz2
podman-1e176923b15360559d859000f2fb0c0a3e30f792.zip
teardown play kube
add the ability for play kube to tear down based on the yaml used to play it. it is indicated by --down in the play kube command. volumes are NOT deleted during the teardown. pods and their containers are stopped and removed. Signed-off-by: Brent Baude <bbaude@redhat.com>
Diffstat (limited to 'pkg')
-rw-r--r--pkg/api/handlers/libpod/play.go44
-rw-r--r--pkg/api/server/register_play.go15
-rw-r--r--pkg/bindings/play/play.go29
-rw-r--r--pkg/bindings/play/types.go4
-rw-r--r--pkg/domain/entities/engine_container.go1
-rw-r--r--pkg/domain/entities/play.go13
-rw-r--r--pkg/domain/infra/abi/play.go70
-rw-r--r--pkg/domain/infra/tunnel/play.go4
8 files changed, 176 insertions, 4 deletions
diff --git a/pkg/api/handlers/libpod/play.go b/pkg/api/handlers/libpod/play.go
index 90332924c..4f79d5f20 100644
--- a/pkg/api/handlers/libpod/play.go
+++ b/pkg/api/handlers/libpod/play.go
@@ -15,6 +15,7 @@ import (
"github.com/containers/podman/v3/pkg/domain/infra/abi"
"github.com/gorilla/schema"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
func PlayKube(w http.ResponseWriter, r *http.Request) {
@@ -66,9 +67,15 @@ func PlayKube(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to create tempfile"))
return
}
- defer os.Remove(tmpfile.Name())
+ defer func() {
+ if err := os.Remove(tmpfile.Name()); err != nil {
+ logrus.Warn(err)
+ }
+ }()
if _, err := io.Copy(tmpfile, r.Body); err != nil && err != io.EOF {
- tmpfile.Close()
+ if err := tmpfile.Close(); err != nil {
+ logrus.Warn(err)
+ }
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to write archive to temporary file"))
return
}
@@ -105,12 +112,43 @@ func PlayKube(w http.ResponseWriter, r *http.Request) {
if _, found := r.URL.Query()["start"]; found {
options.Start = types.NewOptionalBool(query.Start)
}
-
report, err := containerEngine.PlayKube(r.Context(), tmpfile.Name(), options)
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error playing YAML file"))
return
}
+ utils.WriteResponse(w, http.StatusOK, report)
+}
+func PlayKubeDown(w http.ResponseWriter, r *http.Request) {
+ runtime := r.Context().Value("runtime").(*libpod.Runtime)
+ tmpfile, err := ioutil.TempFile("", "libpod-play-kube.yml")
+ if err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to create tempfile"))
+ return
+ }
+ defer func() {
+ if err := os.Remove(tmpfile.Name()); err != nil {
+ logrus.Warn(err)
+ }
+ }()
+ if _, err := io.Copy(tmpfile, r.Body); err != nil && err != io.EOF {
+ if err := tmpfile.Close(); err != nil {
+ logrus.Warn(err)
+ }
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to write archive to temporary file"))
+ return
+ }
+ if err := tmpfile.Close(); err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error closing temporary file"))
+ return
+ }
+ containerEngine := abi.ContainerEngine{Libpod: runtime}
+ options := new(entities.PlayKubeDownOptions)
+ report, err := containerEngine.PlayKubeDown(r.Context(), tmpfile.Name(), *options)
+ if err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error tearing down YAML file"))
+ return
+ }
utils.WriteResponse(w, http.StatusOK, report)
}
diff --git a/pkg/api/server/register_play.go b/pkg/api/server/register_play.go
index c51301aa8..915d0d02e 100644
--- a/pkg/api/server/register_play.go
+++ b/pkg/api/server/register_play.go
@@ -59,5 +59,20 @@ func (s *APIServer) registerPlayHandlers(r *mux.Router) error {
// 500:
// $ref: "#/responses/InternalError"
r.HandleFunc(VersionedPath("/libpod/play/kube"), s.APIHandler(libpod.PlayKube)).Methods(http.MethodPost)
+ // swagger:operation DELETE /libpod/play/kube libpod PlayKubeDownLibpod
+ // ---
+ // tags:
+ // - containers
+ // - pods
+ // summary: Remove pods from play kube
+ // description: Tears down pods defined in a YAML file
+ // produces:
+ // - application/json
+ // responses:
+ // 200:
+ // $ref: "#/responses/DocsLibpodPlayKubeResponse"
+ // 500:
+ // $ref: "#/responses/InternalError"
+ r.HandleFunc(VersionedPath("/libpod/play/kube"), s.APIHandler(libpod.PlayKubeDown)).Methods(http.MethodDelete)
return nil
}
diff --git a/pkg/bindings/play/play.go b/pkg/bindings/play/play.go
index 4b735c821..a45508fed 100644
--- a/pkg/bindings/play/play.go
+++ b/pkg/bindings/play/play.go
@@ -6,6 +6,8 @@ import (
"os"
"strconv"
+ "github.com/sirupsen/logrus"
+
"github.com/containers/podman/v3/pkg/auth"
"github.com/containers/podman/v3/pkg/bindings"
"github.com/containers/podman/v3/pkg/domain/entities"
@@ -54,3 +56,30 @@ func Kube(ctx context.Context, path string, options *KubeOptions) (*entities.Pla
return &report, nil
}
+
+func KubeDown(ctx context.Context, path string) (*entities.PlayKubeReport, error) {
+ var report entities.PlayKubeReport
+ conn, err := bindings.GetClient(ctx)
+ if err != nil {
+ return nil, err
+ }
+
+ f, err := os.Open(path)
+ if err != nil {
+ return nil, err
+ }
+ defer func() {
+ if err := f.Close(); err != nil {
+ logrus.Warn(err)
+ }
+ }()
+ response, err := conn.DoRequest(f, http.MethodDelete, "/play/kube", nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ if err := response.Process(&report); err != nil {
+ return nil, err
+ }
+
+ return &report, nil
+}
diff --git a/pkg/bindings/play/types.go b/pkg/bindings/play/types.go
index 52a72c7b6..787069169 100644
--- a/pkg/bindings/play/types.go
+++ b/pkg/bindings/play/types.go
@@ -1,6 +1,8 @@
package play
-import "net"
+import (
+ "net"
+)
//go:generate go run ../generator/generator.go KubeOptions
// KubeOptions are optional options for replaying kube YAML files
diff --git a/pkg/domain/entities/engine_container.go b/pkg/domain/entities/engine_container.go
index 5d3c9480e..5acf7211c 100644
--- a/pkg/domain/entities/engine_container.go
+++ b/pkg/domain/entities/engine_container.go
@@ -67,6 +67,7 @@ type ContainerEngine interface {
NetworkReload(ctx context.Context, names []string, options NetworkReloadOptions) ([]*NetworkReloadReport, error)
NetworkRm(ctx context.Context, namesOrIds []string, options NetworkRmOptions) ([]*NetworkRmReport, error)
PlayKube(ctx context.Context, path string, opts PlayKubeOptions) (*PlayKubeReport, error)
+ PlayKubeDown(ctx context.Context, path string, opts PlayKubeDownOptions) (*PlayKubeReport, error)
PodCreate(ctx context.Context, opts PodCreateOptions) (*PodCreateReport, error)
PodExists(ctx context.Context, nameOrID string) (*BoolReport, error)
PodInspect(ctx context.Context, options PodInspectOptions) (*PodInspectReport, error)
diff --git a/pkg/domain/entities/play.go b/pkg/domain/entities/play.go
index 01de73ebe..77329e328 100644
--- a/pkg/domain/entities/play.go
+++ b/pkg/domain/entities/play.go
@@ -14,6 +14,9 @@ type PlayKubeOptions struct {
Build bool
// CertDir - to a directory containing TLS certifications and keys.
CertDir string
+ // Down indicates whether to bring contents of a yaml file "down"
+ // as in stop
+ Down bool
// Username for authenticating against the registry.
Username string
// Password for authenticating against the registry.
@@ -67,4 +70,14 @@ type PlayKubeReport struct {
Pods []PlayKubePod
// Volumes - volumes created by play kube.
Volumes []PlayKubeVolume
+ PlayKubeTeardown
+}
+
+// PlayKubeDownOptions are options for tearing down pods
+type PlayKubeDownOptions struct{}
+
+// PlayKubeDownReport contains the results of tearing down play kube
+type PlayKubeTeardown struct {
+ StopReport []*PodStopReport
+ RmReport []*PodRmReport
}
diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go
index 6224feff5..f22b2dbbb 100644
--- a/pkg/domain/infra/abi/play.go
+++ b/pkg/domain/infra/abi/play.go
@@ -586,3 +586,73 @@ func getBuildFile(imageName string, cwd string) (string, error) {
}
return "", err
}
+
+func (ic *ContainerEngine) PlayKubeDown(ctx context.Context, path string, _ entities.PlayKubeDownOptions) (*entities.PlayKubeReport, error) {
+ var (
+ podNames []string
+ )
+ reports := new(entities.PlayKubeReport)
+
+ // read yaml document
+ content, err := ioutil.ReadFile(path)
+ if err != nil {
+ return nil, err
+ }
+
+ // split yaml document
+ documentList, err := splitMultiDocYAML(content)
+ if err != nil {
+ return nil, err
+ }
+
+ // sort kube kinds
+ documentList, err = sortKubeKinds(documentList)
+ if err != nil {
+ return nil, errors.Wrapf(err, "unable to sort kube kinds in %q", path)
+ }
+
+ for _, document := range documentList {
+ kind, err := getKubeKind(document)
+ if err != nil {
+ return nil, errors.Wrapf(err, "unable to read %q as kube YAML", path)
+ }
+
+ switch kind {
+ case "Pod":
+ var podYAML v1.Pod
+ if err := yaml.Unmarshal(document, &podYAML); err != nil {
+ return nil, errors.Wrapf(err, "unable to read YAML %q as Kube Pod", path)
+ }
+ podNames = append(podNames, podYAML.ObjectMeta.Name)
+ case "Deployment":
+ var deploymentYAML v1apps.Deployment
+
+ if err := yaml.Unmarshal(document, &deploymentYAML); err != nil {
+ return nil, errors.Wrapf(err, "unable to read YAML %q as Kube Deployment", path)
+ }
+ var numReplicas int32 = 1
+ deploymentName := deploymentYAML.ObjectMeta.Name
+ if deploymentYAML.Spec.Replicas != nil {
+ numReplicas = *deploymentYAML.Spec.Replicas
+ }
+ for i := 0; i < int(numReplicas); i++ {
+ podName := fmt.Sprintf("%s-pod-%d", deploymentName, i)
+ podNames = append(podNames, podName)
+ }
+ default:
+ continue
+ }
+ }
+
+ // Add the reports
+ reports.StopReport, err = ic.PodStop(ctx, podNames, entities.PodStopOptions{})
+ if err != nil {
+ return nil, err
+ }
+
+ reports.RmReport, err = ic.PodRm(ctx, podNames, entities.PodRmOptions{})
+ if err != nil {
+ return nil, err
+ }
+ return reports, nil
+}
diff --git a/pkg/domain/infra/tunnel/play.go b/pkg/domain/infra/tunnel/play.go
index e66ff0308..e39751a18 100644
--- a/pkg/domain/infra/tunnel/play.go
+++ b/pkg/domain/infra/tunnel/play.go
@@ -22,3 +22,7 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, path string, opts entit
}
return play.Kube(ic.ClientCtx, path, options)
}
+
+func (ic *ContainerEngine) PlayKubeDown(ctx context.Context, path string, _ entities.PlayKubeDownOptions) (*entities.PlayKubeReport, error) {
+ return play.KubeDown(ic.ClientCtx, path)
+}