mirror of
https://github.com/containers/podman.git
synced 2025-05-21 09:05:56 +08:00
add "podman kube down" command
The "podman kube down" reads in a structured file of Kubernetes YAML and removes pods based on the Kubernetes kind described in the YAML, similiar to "podman play kube --down". Users will still be able to use "podman play kube --down" and "podman kube play --down" to perform the same function. Signed-off-by: Niall Crowe <nicrowe@redhat.com>
This commit is contained in:
39
cmd/podman/kube/down.go
Normal file
39
cmd/podman/kube/down.go
Normal file
@ -0,0 +1,39 @@
|
||||
package pods
|
||||
|
||||
import (
|
||||
"github.com/containers/podman/v4/cmd/podman/common"
|
||||
"github.com/containers/podman/v4/cmd/podman/registry"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var (
|
||||
downDescription = `Reads in a structured file of Kubernetes YAML.
|
||||
|
||||
Removes pods that have been based on the Kubernetes kind described in the YAML.`
|
||||
|
||||
downCmd = &cobra.Command{
|
||||
Use: "down KUBEFILE|-",
|
||||
Short: "Remove pods based on Kubernetes YAML.",
|
||||
Long: downDescription,
|
||||
RunE: down,
|
||||
Args: cobra.ExactArgs(1),
|
||||
ValidArgsFunction: common.AutocompleteDefaultOneArg,
|
||||
Example: `podman kube down nginx.yml
|
||||
cat nginx.yml | podman kube down -`,
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
registry.Commands = append(registry.Commands, registry.CliCommand{
|
||||
Command: downCmd,
|
||||
Parent: kubeCmd,
|
||||
})
|
||||
}
|
||||
|
||||
func down(cmd *cobra.Command, args []string) error {
|
||||
reader, err := readerFromArg(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return teardown(reader)
|
||||
}
|
@ -1,8 +1,10 @@
|
||||
package pods
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
@ -37,9 +39,9 @@ var (
|
||||
// https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/
|
||||
defaultSeccompRoot = "/var/lib/kubelet/seccomp"
|
||||
playOptions = playKubeOptionsWrapper{}
|
||||
playDescription = `Command reads in a structured file of Kubernetes YAML.
|
||||
playDescription = `Reads in a structured file of Kubernetes YAML.
|
||||
|
||||
It creates pods or volumes based on the Kubernetes kind described in the YAML. Supported kinds are Pods, Deployments and PersistentVolumeClaims.`
|
||||
Creates pods or volumes based on the Kubernetes kind described in the YAML. Supported kinds are Pods, Deployments and PersistentVolumeClaims.`
|
||||
|
||||
playCmd = &cobra.Command{
|
||||
Use: "play [options] KUBEFILE|-",
|
||||
@ -139,6 +141,7 @@ func playFlags(cmd *cobra.Command) {
|
||||
|
||||
downFlagName := "down"
|
||||
flags.BoolVar(&playOptions.Down, downFlagName, false, "Stop pods defined in the YAML file")
|
||||
_ = flags.MarkHidden("down")
|
||||
|
||||
replaceFlagName := "replace"
|
||||
flags.BoolVar(&playOptions.Replace, replaceFlagName, false, "Delete and recreate pods defined in the YAML file")
|
||||
@ -164,7 +167,7 @@ func playFlags(cmd *cobra.Command) {
|
||||
_ = cmd.RegisterFlagCompletionFunc(contextDirFlagName, completion.AutocompleteDefault)
|
||||
|
||||
// NOTE: The service-container flag is marked as hidden as it
|
||||
// is purely designed for running kube-play or play-kube in systemd units.
|
||||
// is purely designed for running kube-play in systemd units.
|
||||
// It is not something users should need to know or care about.
|
||||
//
|
||||
// Having a flag rather than an env variable is cleaner.
|
||||
@ -223,10 +226,6 @@ func Play(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
playOptions.Annotations[splitN[0]] = annotation
|
||||
}
|
||||
yamlfile := args[0]
|
||||
if yamlfile == "-" {
|
||||
yamlfile = "/dev/stdin"
|
||||
}
|
||||
|
||||
for _, mac := range playOptions.macs {
|
||||
m, err := net.ParseMAC(mac)
|
||||
@ -235,36 +234,62 @@ func Play(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
playOptions.StaticMACs = append(playOptions.StaticMACs, m)
|
||||
}
|
||||
if playOptions.Down {
|
||||
return teardown(yamlfile)
|
||||
|
||||
reader, err := readerFromArg(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if playOptions.Down {
|
||||
return teardown(reader)
|
||||
}
|
||||
|
||||
if playOptions.Replace {
|
||||
if err := teardown(yamlfile); err != nil && !errorhandling.Contains(err, define.ErrNoSuchPod) {
|
||||
if err := teardown(reader); err != nil && !errorhandling.Contains(err, define.ErrNoSuchPod) {
|
||||
return err
|
||||
}
|
||||
if _, err := reader.Seek(0, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return kubeplay(yamlfile)
|
||||
return kubeplay(reader)
|
||||
}
|
||||
|
||||
func playKube(cmd *cobra.Command, args []string) error {
|
||||
return Play(cmd, args)
|
||||
}
|
||||
|
||||
func teardown(yamlfile string) error {
|
||||
func readerFromArg(fileName string) (*bytes.Reader, error) {
|
||||
if fileName == "-" { // Read from stdin
|
||||
data, err := io.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return bytes.NewReader(data), nil
|
||||
}
|
||||
f, err := os.Open(fileName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
data, err := io.ReadAll(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return bytes.NewReader(data), nil
|
||||
}
|
||||
|
||||
func teardown(body io.Reader) error {
|
||||
var (
|
||||
podStopErrors utils.OutputErrors
|
||||
podRmErrors utils.OutputErrors
|
||||
)
|
||||
options := new(entities.PlayKubeDownOptions)
|
||||
f, err := os.Open(yamlfile)
|
||||
reports, err := registry.ContainerEngine().PlayKubeDown(registry.GetContext(), body, *options)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
reports, err := registry.ContainerEngine().PlayKubeDown(registry.GetContext(), f, *options)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%v: %w", yamlfile, err)
|
||||
}
|
||||
|
||||
// Output stopped pods
|
||||
fmt.Println("Pods stopped:")
|
||||
@ -290,19 +315,15 @@ func teardown(yamlfile string) error {
|
||||
podRmErrors = append(podRmErrors, removed.Err)
|
||||
}
|
||||
}
|
||||
|
||||
return podRmErrors.PrintErrors()
|
||||
}
|
||||
|
||||
func kubeplay(yamlfile string) error {
|
||||
f, err := os.Open(yamlfile)
|
||||
func kubeplay(body io.Reader) error {
|
||||
report, err := registry.ContainerEngine().PlayKube(registry.GetContext(), body, playOptions.PlayKubeOptions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
report, err := registry.ContainerEngine().PlayKube(registry.GetContext(), f, playOptions.PlayKubeOptions)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: %w", yamlfile, err)
|
||||
}
|
||||
// Print volumes report
|
||||
for i, volume := range report.Volumes {
|
||||
if i == 0 {
|
||||
|
43
docs/source/markdown/podman-kube-down.1.md
Normal file
43
docs/source/markdown/podman-kube-down.1.md
Normal file
@ -0,0 +1,43 @@
|
||||
% podman-kube-down(1)
|
||||
|
||||
## NAME
|
||||
podman-kube-down - Remove containers and pods based on Kubernetes YAML
|
||||
|
||||
## SYNOPSIS
|
||||
**podman kube down** *file.yml|-*
|
||||
|
||||
## DESCRIPTION
|
||||
**podman kube down** reads a specified Kubernetes YAML file, tearing down pods that were created by the `podman kube play` command via the same Kubernetes YAML file. Any volumes that were created by the previous `podman kube play` command remain intact. If the YAML file is specified as `-`, `podman kube down` reads the YAML from stdin.
|
||||
|
||||
## EXAMPLES
|
||||
|
||||
Example YAML file `demo.yml`:
|
||||
```
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
...
|
||||
spec:
|
||||
containers:
|
||||
- command:
|
||||
- top
|
||||
- name: container
|
||||
value: podman
|
||||
image: foobar
|
||||
...
|
||||
```
|
||||
|
||||
Remove the pod and containers as described in the `demo.yml` file
|
||||
```
|
||||
$ podman kube down demo.yml
|
||||
52182811df2b1e73f36476003a66ec872101ea59034ac0d4d3a7b40903b955a6
|
||||
```
|
||||
|
||||
Remove the pod and containers as described in the`demo.yml` file YAML sent to stdin
|
||||
```
|
||||
$ cat demo.yml | podman kube play -
|
||||
52182811df2b1e73f36476003a66ec872101ea59034ac0d4d3a7b40903b955a6
|
||||
```
|
||||
|
||||
## SEE ALSO
|
||||
**[podman(1)](podman.1.md)**, **[podman-kube(1)](podman-kube.1.md)**, **[podman-kube-play(1)](podman-kube-play.1.md)**, **[podman-generate-kube(1)](podman-generate-kube.1.md)**, **[containers-certs.d(5)](https://github.com/containers/image/blob/main/docs/containers-certs.d.5.md)**
|
@ -1,7 +1,7 @@
|
||||
% podman-kube-play(1)
|
||||
|
||||
## NAME
|
||||
podman-kube-play - Create containers, pods or volumes based on Kubernetes YAML
|
||||
podman-kube-play - Create containers, pods and volumes based on Kubernetes YAML
|
||||
|
||||
## SYNOPSIS
|
||||
**podman kube play** [*options*] *file.yml|-*
|
||||
@ -30,6 +30,9 @@ Note: If the `:latest` tag is used, Podman will attempt to pull the image from a
|
||||
|
||||
Note: The command `podman play kube` is an alias of `podman kube play`, and will perform the same function.
|
||||
|
||||
Note: The command `podman kube down` can be used to stop and remove pods or containers based on the same Kubernetes YAML used
|
||||
by `podman kube play` to create them.
|
||||
|
||||
`Kubernetes PersistentVolumeClaims`
|
||||
|
||||
A Kubernetes PersistentVolumeClaim represents a Podman named volume. Only the PersistentVolumeClaim name is required by Podman to create a volume. Kubernetes annotations can be used to make use of the available options for Podman volumes.
|
||||
@ -145,11 +148,6 @@ The [username[:password]] to use to authenticate with the registry if required.
|
||||
If one or both values are not supplied, a command line prompt will appear and the
|
||||
value can be entered. The password is entered without echo.
|
||||
|
||||
#### **--down**
|
||||
|
||||
Tears down the pods that were created by a previous run of `kube play`. The pods are stopped and then
|
||||
removed. Any volumes created are left intact.
|
||||
|
||||
#### **--help**, **-h**
|
||||
|
||||
Print usage statement
|
||||
@ -325,7 +323,7 @@ $ podman kube play demo.yml --network net1:ip=10.89.1.5 --network net2:ip=10.89.
|
||||
Please take into account that networks must be created first using podman-network-create(1).
|
||||
|
||||
## SEE ALSO
|
||||
**[podman(1)](podman.1.md)**, **[podman-kube(1)](podman-kube.1.md)**, **[podman-network-create(1)](podman-network-create.1.md)**, **[podman-generate-kube(1)](podman-generate-kube.1.md)**, **[containers-certs.d(5)](https://github.com/containers/image/blob/main/docs/containers-certs.d.5.md)**
|
||||
**[podman(1)](podman.1.md)**, **[podman-kube(1)](podman-kube.1.md)**, **[podman-kube-down(1)](podman-kube-down.1.md)**, **[podman-network-create(1)](podman-network-create.1.md)**, **[podman-generate-kube(1)](podman-generate-kube.1.md)**, **[containers-certs.d(5)](https://github.com/containers/image/blob/main/docs/containers-certs.d.5.md)**
|
||||
|
||||
## HISTORY
|
||||
December 2018, Originally compiled by Brent Baude (bbaude at redhat dot com)
|
||||
|
@ -14,7 +14,8 @@ file input. Containers will be automatically started.
|
||||
|
||||
| Command | Man Page | Description |
|
||||
| ------- | --------------------------------------------------- | ---------------------------------------------------------------------------- |
|
||||
| play | [podman-kube-play(1)](podman-kube-play.1.md) | Create containers, pods or volumes based on Kubernetes YAML. |
|
||||
| down | [podman-kube-down(1)](podman-kube-down.1.md) | Remove containers and pods based on Kubernetes YAML. |
|
||||
| play | [podman-kube-play(1)](podman-kube-play.1.md) | Create containers, pods and volumes based on Kubernetes YAML. |
|
||||
|
||||
## SEE ALSO
|
||||
**[podman(1)](podman.1.md)**, **[podman-pod(1)](podman-pod.1.md)**, **[podman-container(1)](podman-container.1.md)**, **[podman-generate(1)](podman-generate.1.md)**, **[podman-kube-play(1)](podman-kube-play.1.md)**
|
||||
**[podman(1)](podman.1.md)**, **[podman-pod(1)](podman-pod.1.md)**, **[podman-container(1)](podman-container.1.md)**, **[podman-generate(1)](podman-generate.1.md)**, **[podman-kube-play(1)](podman-kube-play.1.md)**, **[podman-kube-down(1)](podman-kube-down.1.md)**
|
||||
|
@ -182,8 +182,11 @@ EOF
|
||||
run_podman container inspect --format "{{.HostConfig.NetworkMode}}" $infraID
|
||||
is "$output" "none" "network mode none is set for the container"
|
||||
|
||||
run_podman stop -a -t 0
|
||||
run_podman pod rm -t 0 -f test_pod
|
||||
run_podman kube down - < $PODMAN_TMPDIR/test.yaml
|
||||
run_podman 125 inspect test_pod-test
|
||||
is "$output" ".*Error: inspecting object: no such object: \"test_pod-test\""
|
||||
run_podman pod rm -a
|
||||
run_podman rm -a
|
||||
}
|
||||
|
||||
@test "podman play with user from image" {
|
||||
@ -325,7 +328,6 @@ spec:
|
||||
- name: TERM
|
||||
value: xterm
|
||||
- name: container
|
||||
|
||||
value: podman
|
||||
image: quay.io/libpod/userimage
|
||||
name: test
|
||||
@ -353,6 +355,9 @@ status: {}
|
||||
run_podman inspect --format "{{.HostConfig.LogConfig.Type}}" test_pod-test
|
||||
is "$output" "$default_driver" "play kube uses default log driver"
|
||||
|
||||
run_podman stop -a -t 0
|
||||
run_podman pod rm -t 0 -f test_pod
|
||||
run_podman kube down $PODMAN_TMPDIR/test.yaml
|
||||
run_podman 125 inspect test_pod-test
|
||||
is "$output" ".*Error: inspecting object: no such object: \"test_pod-test\""
|
||||
run_podman pod rm -a
|
||||
run_podman rm -a
|
||||
}
|
||||
|
Reference in New Issue
Block a user