Merge pull request #14974 from nicrowe00/kubedown1
add "podman kube down" command
This commit is contained in:
		
						commit
						1139cd9b81
					
				|  | @ -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 { | ||||
|  |  | |||
|  | @ -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 | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue