├── .github └── workflows │ ├── ci.yaml │ └── release.yaml ├── .gitignore ├── .golangci.yml ├── .krew.yaml ├── LICENSE ├── Makefile ├── OWNERS ├── README.md ├── cmd ├── plugin │ └── main.go └── resourcedistributiongenerator │ ├── generator │ ├── alias.go │ ├── resourcedistribution.go │ ├── targets.go │ └── utils.go │ ├── main.go │ └── main_test.go ├── docs ├── kubectl-kruise.md ├── kubectl-kruise_create.md ├── kubectl-kruise_create_ContainerRecreateRequest.md ├── kubectl-kruise_create_broadcastJob.md ├── kubectl-kruise_create_job.md ├── kubectl-kruise_describe.md ├── kubectl-kruise_describe_rollout.md ├── kubectl-kruise_expose.md ├── kubectl-kruise_migrate.md ├── kubectl-kruise_rollout.md ├── kubectl-kruise_rollout_approve.md ├── kubectl-kruise_rollout_history.md ├── kubectl-kruise_rollout_pause.md ├── kubectl-kruise_rollout_restart.md ├── kubectl-kruise_rollout_resume.md ├── kubectl-kruise_rollout_status.md ├── kubectl-kruise_rollout_undo.md ├── kubectl-kruise_scaledown.md ├── kubectl-kruise_set.md ├── kubectl-kruise_set_env.md ├── kubectl-kruise_set_image.md ├── kubectl-kruise_set_resources.md ├── kubectl-kruise_set_selector.md ├── kubectl-kruise_set_serviceaccount.md ├── kubectl-kruise_set_subject.md └── yaml │ ├── kubectl-kruise.yaml │ ├── kubectl-kruise_create.yaml │ ├── kubectl-kruise_create_ContainerRecreateRequest.yaml │ ├── kubectl-kruise_create_broadcastJob.yaml │ ├── kubectl-kruise_create_job.yaml │ ├── kubectl-kruise_describe.yaml │ ├── kubectl-kruise_describe_rollout.yaml │ ├── kubectl-kruise_expose.yaml │ ├── kubectl-kruise_migrate.yaml │ ├── kubectl-kruise_rollout.yaml │ ├── kubectl-kruise_rollout_approve.yaml │ ├── kubectl-kruise_rollout_history.yaml │ ├── kubectl-kruise_rollout_pause.yaml │ ├── kubectl-kruise_rollout_restart.yaml │ ├── kubectl-kruise_rollout_resume.yaml │ ├── kubectl-kruise_rollout_status.yaml │ ├── kubectl-kruise_rollout_undo.yaml │ ├── kubectl-kruise_scaledown.yaml │ ├── kubectl-kruise_set.yaml │ ├── kubectl-kruise_set_env.yaml │ ├── kubectl-kruise_set_image.yaml │ ├── kubectl-kruise_set_resources.yaml │ ├── kubectl-kruise_set_selector.yaml │ ├── kubectl-kruise_set_serviceaccount.yaml │ └── kubectl-kruise_set_subject.yaml ├── go.mod ├── go.sum ├── pkg ├── api │ └── api.go ├── cmd │ ├── alpha.go │ ├── auto_completion.go │ ├── cmd.go │ ├── create │ │ ├── create.go │ │ ├── create_broadcast_job.go │ │ ├── create_crr.go │ │ └── create_job.go │ ├── describe │ │ ├── describe.go │ │ └── describe_rollout.go │ ├── exec │ │ ├── exec.go │ │ └── exec_test.go │ ├── expose │ │ ├── expose.go │ │ └── expose_test.go │ ├── generate-docs.go │ ├── get │ │ └── get.go │ ├── migrate │ │ ├── migrate.go │ │ └── migrate_cloneset.go │ ├── profiling.go │ ├── rollout │ │ ├── rollout.go │ │ ├── rollout_approve.go │ │ ├── rollout_history.go │ │ ├── rollout_pause.go │ │ ├── rollout_restart.go │ │ ├── rollout_resume.go │ │ ├── rollout_status.go │ │ └── rollout_undo.go │ ├── scaledown │ │ ├── scaledown.go │ │ └── scaledown_cloneset.go │ ├── set │ │ ├── env │ │ │ ├── doc.go │ │ │ ├── env_parse.go │ │ │ ├── env_parse_test.go │ │ │ └── env_resolve.go │ │ ├── helper.go │ │ ├── set.go │ │ ├── set_env.go │ │ ├── set_env_test.go │ │ ├── set_image.go │ │ ├── set_image_test.go │ │ ├── set_resources.go │ │ ├── set_resources_test.go │ │ ├── set_selector.go │ │ ├── set_selector_test.go │ │ ├── set_serviceaccount.go │ │ ├── set_serviceaccount_test.go │ │ ├── set_subject.go │ │ ├── set_subject_test.go │ │ └── set_test.go │ └── util │ │ ├── cmd.go │ │ ├── factory.go │ │ ├── factory_client_access.go │ │ ├── helpers.go │ │ └── sidecar_set.go ├── conversion │ └── cloneset_convertion.go ├── creation │ ├── api.go │ └── cloneset │ │ └── cloneset_creation.go ├── internal │ ├── apps │ │ └── kind_visitor.go │ └── polymorphichelpers │ │ ├── attachablepodforobject.go │ │ ├── canbeexposed.go │ │ ├── describe_rollout.go │ │ ├── getviewer.go │ │ ├── helpers.go │ │ ├── history.go │ │ ├── historyviewer.go │ │ ├── interface.go │ │ ├── logsforobject.go │ │ ├── mapbasedselectorforobject.go │ │ ├── objectapprover.go │ │ ├── objectpauser.go │ │ ├── objectrestarter.go │ │ ├── objectresumer.go │ │ ├── portsforobject.go │ │ ├── protocolsforobject.go │ │ ├── rollback.go │ │ ├── rollbacker.go │ │ ├── rollout_status.go │ │ ├── rollout_utils.go │ │ ├── rolloutviewer.go │ │ ├── statusviewer.go │ │ ├── steps.go │ │ ├── steps_test.go │ │ └── updatepodspec.go ├── migration │ ├── api.go │ └── cloneset │ │ ├── cloneset_migration.go │ │ └── event_handlers.go ├── utils │ ├── logs │ │ └── logs.go │ ├── math.go │ └── misc.go └── version │ └── version.go ├── testdata ├── apply │ ├── cm.yaml │ ├── deploy-clientside.yaml │ ├── deploy-serverside.yaml │ ├── patch.json │ ├── rc-args.yaml │ ├── rc-lastapplied-args.yaml │ ├── rc-lastapplied.yaml │ ├── rc-no-annotation.yaml │ ├── rc-noexist.yaml │ ├── rc-service.yaml │ ├── rc.json │ ├── rc.yaml │ ├── service.yaml │ ├── testdir │ │ ├── rc.yaml │ │ └── rc1.yaml │ ├── widget-clientside.yaml │ └── widget-serverside.yaml ├── controller.yaml ├── frontend-service.yaml ├── openapi │ └── swagger.json ├── redis-master-controller.yaml ├── redis-master-service.yaml ├── replace │ └── legacy │ │ ├── frontend-controller.yaml │ │ ├── redis-master-controller.yaml │ │ └── redis-slave-controller.yaml └── set │ ├── daemon.yaml │ ├── deployment.yaml │ ├── job.yaml │ ├── multi-resource-yaml.yaml │ ├── namespaced-resource.yaml │ ├── redis-slave.yaml │ └── replication.yaml └── version.sh /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | - release* 8 | pull_request: 9 | branches: 10 | - master 11 | - release* 12 | 13 | env: 14 | # Common versions 15 | GO_VERSION: '1.22' 16 | GOLANGCI_VERSION: 'v1.55.2' 17 | 18 | jobs: 19 | golangci-lint: 20 | runs-on: ubuntu-24.04 21 | steps: 22 | - name: Checkout 23 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 24 | with: 25 | submodules: true 26 | - name: Setup Go 27 | uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0 28 | with: 29 | go-version: ${{ env.GO_VERSION }} 30 | - name: Cache Go Dependencies 31 | uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 32 | with: 33 | path: ~/go/pkg/mod 34 | key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} 35 | restore-keys: ${{ runner.os }}-go- 36 | - name: Lint golang code 37 | uses: golangci/golangci-lint-action@2226d7cb06a077cd73e56eedd38eecad18e5d837 # v6.5.0 38 | with: 39 | version: ${{ env.GOLANGCI_VERSION }} 40 | args: --verbose 41 | 42 | build-and-test: 43 | name: ci-build 44 | runs-on: ubuntu-24.04 45 | steps: 46 | - name: Checkout 47 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 48 | with: 49 | submodules: true 50 | - name: Setup Go 51 | uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0 52 | with: 53 | go-version: ${{ env.GO_VERSION }} 54 | - name: Build 55 | run: | 56 | make build 57 | - name: Test 58 | run: | 59 | make test 60 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | bin/ 8 | 9 | # Test binary, built with `go test -c` 10 | *.test 11 | 12 | # Output of the go coverage tool, specifically when used with LiteIDE 13 | *.out 14 | 15 | # Dependency directories (remove the comment below to include it) 16 | vendor/ 17 | 18 | .idea/ 19 | -------------------------------------------------------------------------------- /.golangci.yml: -------------------------------------------------------------------------------- 1 | run: 2 | concurrency: 4 3 | deadline: 2m 4 | skip-dirs: 5 | - vendor 6 | 7 | linters: 8 | disable-all: true 9 | enable: 10 | - gofmt 11 | - govet 12 | - goimports 13 | - ineffassign 14 | - misspell 15 | - vet 16 | - unconvert 17 | 18 | linters-settings: 19 | golint: 20 | # minimal confidence for issues, default is 0.8 21 | min-confidence: 0.8 22 | gofmt: 23 | # simplify code: gofmt with `-s` option, true by default 24 | simplify: true 25 | goimports: 26 | #local-prefixes: github.com/openkruise/kruise-tools 27 | 28 | issues: 29 | exclude-use-default: false 30 | exclude-rules: 31 | # We don't check metrics naming in the tests. 32 | - path: _test\.go 33 | linters: 34 | - promlinter 35 | -------------------------------------------------------------------------------- /.krew.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: krew.googlecontainertools.github.com/v1alpha2 2 | kind: Plugin 3 | metadata: 4 | name: kruise 5 | spec: 6 | version: "{{ .TagName }}" 7 | platforms: 8 | - selector: 9 | matchLabels: 10 | os: linux 11 | arch: amd64 12 | {{addURIAndSha "https://github.com/openkruise/kruise-tools/releases/download/{{ .TagName }}/kubectl-kruise-linux-amd64.tar.gz" .TagName }} 13 | files: 14 | - from: "*/kubectl-kruise" 15 | to: "." 16 | - from: "*/LICENSE" 17 | to: "." 18 | bin: "kubectl-kruise" 19 | - selector: 20 | matchLabels: 21 | os: linux 22 | arch: arm64 23 | {{addURIAndSha "https://github.com/openkruise/kruise-tools/releases/download/{{ .TagName }}/kubectl-kruise-linux-arm64.tar.gz" .TagName }} 24 | files: 25 | - from: "*/kubectl-kruise" 26 | to: "." 27 | - from: "*/LICENSE" 28 | to: "." 29 | bin: "kubectl-kruise" 30 | - selector: 31 | matchLabels: 32 | os: darwin 33 | arch: amd64 34 | {{addURIAndSha "https://github.com/openkruise/kruise-tools/releases/download/{{ .TagName }}/kubectl-kruise-darwin-amd64.tar.gz" .TagName }} 35 | files: 36 | - from: "*/kubectl-kruise" 37 | to: "." 38 | - from: "*/LICENSE" 39 | to: "." 40 | bin: "kubectl-kruise" 41 | - selector: 42 | matchLabels: 43 | os: darwin 44 | arch: arm64 45 | {{addURIAndSha "https://github.com/openkruise/kruise-tools/releases/download/{{ .TagName }}/kubectl-kruise-darwin-arm64.tar.gz" .TagName }} 46 | files: 47 | - from: "*/kubectl-kruise" 48 | to: "." 49 | - from: "*/LICENSE" 50 | to: "." 51 | bin: "kubectl-kruise" 52 | - selector: 53 | matchLabels: 54 | os: windows 55 | arch: amd64 56 | {{addURIAndSha "https://github.com/openkruise/kruise-tools/releases/download/{{ .TagName }}/kubectl-kruise-windows-amd64.tar.gz" .TagName }} 57 | files: 58 | - from: "*/kubectl-kruise" 59 | to: "." 60 | - from: "*/LICENSE" 61 | to: "." 62 | bin: "kubectl-kruise" 63 | shortDescription: Easily handle OpenKruise workloads 64 | homepage: https://openkruise.io/ 65 | description: | 66 | kubectl kruise is a kubectl plugin from the OpenKruise project. OpenKruise is an extended component suite for Kubernetes, 67 | which mainly focuses on application automations, such as deployment, upgrade, ops and avalibility protection. 68 | This plugin allows you to better handle, manage and maintain OpenKruise workloads. -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: build plugin check 2 | 3 | LDFLAGS = $(shell ./version.sh) 4 | 5 | default: build 6 | 7 | build: kubectl-kruise resource-distribution-generator 8 | 9 | kubectl-kruise: fmt vet 10 | GO111MODULE=on CGO_ENABLED=0 go build -ldflags "$(LDFLAGS)" -o bin/kubectl-kruise cmd/plugin/main.go 11 | 12 | resource-distribution-generator: fmt vet 13 | GO111MODULE=on CGO_ENABLED=0 go build -ldflags "$(LDFLAGS)" -o bin/resourcedistributiongenerator cmd/resourcedistributiongenerator/main.go 14 | 15 | test: 16 | find . -iname '*.go' -type f | grep -v /vendor/ | xargs gofmt -l 17 | GO111MODULE=on go test -v -race ./... 18 | go vet ./... 19 | 20 | fmt: ## Run go fmt against code. 21 | go fmt ./... 22 | 23 | vet: ## Run go vet against code. 24 | go vet ./... -------------------------------------------------------------------------------- /OWNERS: -------------------------------------------------------------------------------- 1 | # See: https://go.k8s.io/owners 2 | approvers: 3 | - FillZpp 4 | - furykerry 5 | - hantmac 6 | reviewers: 7 | - FillZpp 8 | - furykerry 9 | - hantmac 10 | -------------------------------------------------------------------------------- /cmd/plugin/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 The Kruise Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "os" 21 | 22 | "github.com/openkruise/kruise-tools/pkg/cmd" 23 | "github.com/spf13/pflag" 24 | ) 25 | 26 | func main() { 27 | flags := pflag.NewFlagSet("kubectl-kruise", pflag.ExitOnError) 28 | pflag.CommandLine = flags 29 | 30 | root := cmd.NewDefaultKubectlCommand() 31 | if err := root.Execute(); err != nil { 32 | os.Exit(1) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /cmd/resourcedistributiongenerator/generator/alias.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 The Kruise Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package generator 18 | 19 | const tmpl = ` 20 | apiVersion: apps.kruise.io/v1alpha1 21 | kind: ResourceDistribution 22 | spec: 23 | resource: 24 | apiVersion: v1 25 | ` 26 | 27 | // Field names 28 | const ( 29 | kindField = "kind" 30 | nameField = "name" 31 | listField = "list" 32 | allNamespacesField = "allNamespaces" 33 | immutableField = "immutable" 34 | typeField = "type" 35 | matchExpressionsField = "matchExpressions" 36 | keyField = "key" 37 | operatorField = "operator" 38 | valuesField = "values" 39 | ) 40 | 41 | var metadataLabelsPath = []string{"metadata", "labels"} 42 | var metadataAnnotationsPath = []string{"metadata", "annotations"} 43 | var resourcePath = []string{"spec", "resource"} 44 | var metadataPath = []string{"spec", "resource", "metadata"} 45 | var resourceLabelsPath = []string{"spec", "resource", "metadata", "labels"} 46 | var resourceAnnotationsPath = []string{"spec", "resource", "metadata", "annotations"} 47 | var targetsPath = []string{"spec", "targets"} 48 | var includedNamespacesPath = []string{"spec", "targets", "includedNamespaces"} 49 | var excludedNamespacesPath = []string{"spec", "targets", "excludedNamespaces"} 50 | var NamespaceLabelSelectorPath = []string{"spec", "targets", "namespaceLabelSelector"} 51 | var MatchLabelsPath = []string{"spec", "targets", "namespaceLabelSelector", "matchLabels"} 52 | -------------------------------------------------------------------------------- /cmd/resourcedistributiongenerator/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 The Kruise Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "os" 21 | 22 | "github.com/openkruise/kruise-tools/cmd/resourcedistributiongenerator/generator" 23 | ) 24 | 25 | func main() { 26 | cmd := generator.BuildCmd() 27 | if err := cmd.Execute(); err != nil { 28 | os.Exit(1) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /docs/kubectl-kruise.md: -------------------------------------------------------------------------------- 1 | ## kubectl-kruise 2 | 3 | kubectl-kruise controls the OpenKruise CRs 4 | 5 | ### Synopsis 6 | 7 | kubectl-kruise controls the OpenKruise manager. 8 | 9 | Find more information at: https://openkruise.io/ 10 | 11 | ``` 12 | kubectl-kruise [flags] 13 | ``` 14 | 15 | ### Options 16 | 17 | ``` 18 | --as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace. 19 | --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. 20 | --as-uid string UID to impersonate for the operation. 21 | --cache-dir string Default cache directory (default "$HOME/.kube/cache") 22 | --certificate-authority string Path to a cert file for the certificate authority 23 | --client-certificate string Path to a client certificate file for TLS 24 | --client-key string Path to a client key file for TLS 25 | --cluster string The name of the kubeconfig cluster to use 26 | --context string The name of the kubeconfig context to use 27 | --disable-compression If true, opt-out of response compression for all requests to the server 28 | -h, --help help for kubectl-kruise 29 | --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure 30 | --kubeconfig string Path to the kubeconfig file to use for CLI requests. 31 | --match-server-version Require server version to match client version 32 | -n, --namespace string If present, the namespace scope for this CLI request 33 | --password string Password for basic authentication to the API server 34 | --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none") 35 | --profile-output string Name of the file to write the profile to (default "profile.pprof") 36 | --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") 37 | -s, --server string The address and port of the Kubernetes API server 38 | --tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used 39 | --token string Bearer token for authentication to the API server 40 | --user string The name of the kubeconfig user to use 41 | --username string Username for basic authentication to the API server 42 | --warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code 43 | ``` 44 | 45 | ### SEE ALSO 46 | 47 | * [kubectl-kruise create](kubectl-kruise_create.md) - Create a resource from a file or from stdin. 48 | * [kubectl-kruise describe](kubectl-kruise_describe.md) - Show details of a specific resource or group of resources 49 | * [kubectl-kruise expose](kubectl-kruise_expose.md) - Take a workload(e.g. deployment, cloneset), service or pod and expose it as a new Kubernetes Service 50 | * [kubectl-kruise migrate](kubectl-kruise_migrate.md) - Migrate from K8s original workloads to Kruise workloads 51 | * [kubectl-kruise rollout](kubectl-kruise_rollout.md) - Manage the rollout of a resource 52 | * [kubectl-kruise scaledown](kubectl-kruise_scaledown.md) - Scaledown a cloneset with selective Pods 53 | * [kubectl-kruise set](kubectl-kruise_set.md) - Set specific features on objects 54 | 55 | ###### Auto generated by spf13/cobra on 12-Mar-2025 56 | -------------------------------------------------------------------------------- /docs/kubectl-kruise_describe.md: -------------------------------------------------------------------------------- 1 | ## kubectl-kruise describe 2 | 3 | Show details of a specific resource or group of resources 4 | 5 | ### Synopsis 6 | 7 | Show details of a rollout. 8 | 9 | ``` 10 | kubectl-kruise describe SUBCOMMAND 11 | ``` 12 | 13 | ### Examples 14 | 15 | ``` 16 | # Describe the rollout named rollout-demo 17 | kubectl-kruise describe rollout rollout-demo 18 | ``` 19 | 20 | ### Options 21 | 22 | ``` 23 | -h, --help help for describe 24 | ``` 25 | 26 | ### Options inherited from parent commands 27 | 28 | ``` 29 | --as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace. 30 | --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. 31 | --as-uid string UID to impersonate for the operation. 32 | --cache-dir string Default cache directory (default "$HOME/.kube/cache") 33 | --certificate-authority string Path to a cert file for the certificate authority 34 | --client-certificate string Path to a client certificate file for TLS 35 | --client-key string Path to a client key file for TLS 36 | --cluster string The name of the kubeconfig cluster to use 37 | --context string The name of the kubeconfig context to use 38 | --disable-compression If true, opt-out of response compression for all requests to the server 39 | --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure 40 | --kubeconfig string Path to the kubeconfig file to use for CLI requests. 41 | --match-server-version Require server version to match client version 42 | -n, --namespace string If present, the namespace scope for this CLI request 43 | --password string Password for basic authentication to the API server 44 | --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none") 45 | --profile-output string Name of the file to write the profile to (default "profile.pprof") 46 | --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") 47 | -s, --server string The address and port of the Kubernetes API server 48 | --tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used 49 | --token string Bearer token for authentication to the API server 50 | --user string The name of the kubeconfig user to use 51 | --username string Username for basic authentication to the API server 52 | --warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code 53 | ``` 54 | 55 | ### SEE ALSO 56 | 57 | * [kubectl-kruise](kubectl-kruise.md) - kubectl-kruise controls the OpenKruise CRs 58 | * [kubectl-kruise describe rollout](kubectl-kruise_describe_rollout.md) - Get details about a rollout 59 | 60 | ###### Auto generated by spf13/cobra on 12-Mar-2025 61 | -------------------------------------------------------------------------------- /docs/kubectl-kruise_describe_rollout.md: -------------------------------------------------------------------------------- 1 | ## kubectl-kruise describe rollout 2 | 3 | Get details about a rollout 4 | 5 | ### Synopsis 6 | 7 | Get details about and visual representation of a rollout. 8 | 9 | ``` 10 | kubectl-kruise describe rollout SUBCOMMAND 11 | ``` 12 | 13 | ### Examples 14 | 15 | ``` 16 | # Describe the rollout named rollout-demo within namespace default 17 | kubectl-kruise describe rollout rollout-demo/default 18 | 19 | # Watch for changes to the rollout named rollout-demo 20 | kubectl-kruise describe rollout rollout-demo/default -w 21 | ``` 22 | 23 | ### Options 24 | 25 | ``` 26 | --all Show all pods in the rollout 27 | -h, --help help for rollout 28 | --no-color If true, print output without color 29 | --timeout int Timeout after specified seconds 30 | -w, --watch Watch for changes to the rollout 31 | ``` 32 | 33 | ### Options inherited from parent commands 34 | 35 | ``` 36 | --as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace. 37 | --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. 38 | --as-uid string UID to impersonate for the operation. 39 | --cache-dir string Default cache directory (default "$HOME/.kube/cache") 40 | --certificate-authority string Path to a cert file for the certificate authority 41 | --client-certificate string Path to a client certificate file for TLS 42 | --client-key string Path to a client key file for TLS 43 | --cluster string The name of the kubeconfig cluster to use 44 | --context string The name of the kubeconfig context to use 45 | --disable-compression If true, opt-out of response compression for all requests to the server 46 | --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure 47 | --kubeconfig string Path to the kubeconfig file to use for CLI requests. 48 | --match-server-version Require server version to match client version 49 | -n, --namespace string If present, the namespace scope for this CLI request 50 | --password string Password for basic authentication to the API server 51 | --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none") 52 | --profile-output string Name of the file to write the profile to (default "profile.pprof") 53 | --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") 54 | -s, --server string The address and port of the Kubernetes API server 55 | --tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used 56 | --token string Bearer token for authentication to the API server 57 | --user string The name of the kubeconfig user to use 58 | --username string Username for basic authentication to the API server 59 | --warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code 60 | ``` 61 | 62 | ### SEE ALSO 63 | 64 | * [kubectl-kruise describe](kubectl-kruise_describe.md) - Show details of a specific resource or group of resources 65 | 66 | ###### Auto generated by spf13/cobra on 12-Mar-2025 67 | -------------------------------------------------------------------------------- /docs/kubectl-kruise_migrate.md: -------------------------------------------------------------------------------- 1 | ## kubectl-kruise migrate 2 | 3 | Migrate from K8s original workloads to Kruise workloads 4 | 5 | ### Synopsis 6 | 7 | Migrate from K8s original workloads to Kruise workloads 8 | 9 | ``` 10 | kubectl-kruise migrate [DST_KIND] --from [SRC_KIND] [flags] 11 | ``` 12 | 13 | ### Examples 14 | 15 | ``` 16 | 17 | # Create an empty CloneSet from an existing Deployment. 18 | kubectl-kruise migrate CloneSet --from Deployment -n default --dst-name deployment-name --create 19 | 20 | # Create a same replicas CloneSet from an existing Deployment. 21 | kubectl-kruise migrate CloneSet --from Deployment -n default --dst-name deployment-name --create --copy 22 | 23 | # Migrate replicas from an existing Deployment to an existing CloneSet. 24 | kubectl-kruise migrate CloneSet --from Deployment -n default --src-name cloneset-name --dst-name deployment-name --replicas 10 --max-surge=2 25 | 26 | ``` 27 | 28 | ### Options 29 | 30 | ``` 31 | --copy Copy replicas from src workload when create. 32 | --create Create dst workload with replicas=0 from src workload. 33 | --dst-name string Name of the destination workload. 34 | --from string Type of the source workload (e.g. Deployment). 35 | -h, --help help for migrate 36 | --max-surge int32 Max surge during migration. (default 1) 37 | --replicas int32 The replicas needs to migrate, -1 indicates all replicas in src workload. (default -1) 38 | --src-name string Name of the source workload. 39 | --timeout-seconds int32 Timeout seconds for migration, -1 indicates no limited. (default -1) 40 | ``` 41 | 42 | ### Options inherited from parent commands 43 | 44 | ``` 45 | --as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace. 46 | --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. 47 | --as-uid string UID to impersonate for the operation. 48 | --cache-dir string Default cache directory (default "$HOME/.kube/cache") 49 | --certificate-authority string Path to a cert file for the certificate authority 50 | --client-certificate string Path to a client certificate file for TLS 51 | --client-key string Path to a client key file for TLS 52 | --cluster string The name of the kubeconfig cluster to use 53 | --context string The name of the kubeconfig context to use 54 | --disable-compression If true, opt-out of response compression for all requests to the server 55 | --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure 56 | --kubeconfig string Path to the kubeconfig file to use for CLI requests. 57 | --match-server-version Require server version to match client version 58 | -n, --namespace string If present, the namespace scope for this CLI request 59 | --password string Password for basic authentication to the API server 60 | --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none") 61 | --profile-output string Name of the file to write the profile to (default "profile.pprof") 62 | --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") 63 | -s, --server string The address and port of the Kubernetes API server 64 | --tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used 65 | --token string Bearer token for authentication to the API server 66 | --user string The name of the kubeconfig user to use 67 | --username string Username for basic authentication to the API server 68 | --warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code 69 | ``` 70 | 71 | ### SEE ALSO 72 | 73 | * [kubectl-kruise](kubectl-kruise.md) - kubectl-kruise controls the OpenKruise CRs 74 | 75 | ###### Auto generated by spf13/cobra on 12-Mar-2025 76 | -------------------------------------------------------------------------------- /docs/kubectl-kruise_rollout.md: -------------------------------------------------------------------------------- 1 | ## kubectl-kruise rollout 2 | 3 | Manage the rollout of a resource 4 | 5 | ### Synopsis 6 | 7 | Manage the rollout of a resource. 8 | 9 | Valid resource types include: 10 | 11 | * deployments 12 | * daemonsets 13 | * statefulsets 14 | * clonesets 15 | * statefulsets.apps.kruise.io 16 | * daemonsets.apps.kruise.io 17 | * rollouts.rollouts.kruise.io 18 | 19 | ``` 20 | kubectl-kruise rollout SUBCOMMAND 21 | ``` 22 | 23 | ### Examples 24 | 25 | ``` 26 | # Rollback to the previous cloneset 27 | kubectl-kruise rollout undo cloneset/abc 28 | 29 | # Check the rollout status of a daemonset 30 | kubectl-kruise rollout status daemonset/foo 31 | ``` 32 | 33 | ### Options 34 | 35 | ``` 36 | -h, --help help for rollout 37 | ``` 38 | 39 | ### Options inherited from parent commands 40 | 41 | ``` 42 | --as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace. 43 | --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. 44 | --as-uid string UID to impersonate for the operation. 45 | --cache-dir string Default cache directory (default "$HOME/.kube/cache") 46 | --certificate-authority string Path to a cert file for the certificate authority 47 | --client-certificate string Path to a client certificate file for TLS 48 | --client-key string Path to a client key file for TLS 49 | --cluster string The name of the kubeconfig cluster to use 50 | --context string The name of the kubeconfig context to use 51 | --disable-compression If true, opt-out of response compression for all requests to the server 52 | --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure 53 | --kubeconfig string Path to the kubeconfig file to use for CLI requests. 54 | --match-server-version Require server version to match client version 55 | -n, --namespace string If present, the namespace scope for this CLI request 56 | --password string Password for basic authentication to the API server 57 | --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none") 58 | --profile-output string Name of the file to write the profile to (default "profile.pprof") 59 | --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") 60 | -s, --server string The address and port of the Kubernetes API server 61 | --tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used 62 | --token string Bearer token for authentication to the API server 63 | --user string The name of the kubeconfig user to use 64 | --username string Username for basic authentication to the API server 65 | --warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code 66 | ``` 67 | 68 | ### SEE ALSO 69 | 70 | * [kubectl-kruise](kubectl-kruise.md) - kubectl-kruise controls the OpenKruise CRs 71 | * [kubectl-kruise rollout approve](kubectl-kruise_rollout_approve.md) - Approve a resource 72 | * [kubectl-kruise rollout history](kubectl-kruise_rollout_history.md) - View rollout history 73 | * [kubectl-kruise rollout pause](kubectl-kruise_rollout_pause.md) - Mark the provided resource as paused 74 | * [kubectl-kruise rollout restart](kubectl-kruise_rollout_restart.md) - Restart a resource 75 | * [kubectl-kruise rollout resume](kubectl-kruise_rollout_resume.md) - Resume a paused resource 76 | * [kubectl-kruise rollout status](kubectl-kruise_rollout_status.md) - Show the status of the rollout 77 | * [kubectl-kruise rollout undo](kubectl-kruise_rollout_undo.md) - Undo a previous rollout 78 | 79 | ###### Auto generated by spf13/cobra on 12-Mar-2025 80 | -------------------------------------------------------------------------------- /docs/kubectl-kruise_rollout_approve.md: -------------------------------------------------------------------------------- 1 | ## kubectl-kruise rollout approve 2 | 3 | Approve a resource 4 | 5 | ### Synopsis 6 | 7 | Approve a resource which can be continued. 8 | 9 | Paused resources will not be reconciled by a controller. By approving a resource, we allow it to be continue to rollout. Currently only kruise-rollouts support being approved. 10 | 11 | ``` 12 | kubectl-kruise rollout approve RESOURCE 13 | ``` 14 | 15 | ### Examples 16 | 17 | ``` 18 | # approve a kruise rollout resource named "rollout-demo" in "ns-demo" namespace 19 | 20 | kubectl-kruise rollout approve rollout/rollout-demo -n ns-demo 21 | ``` 22 | 23 | ### Options 24 | 25 | ``` 26 | --allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true) 27 | -f, --filename strings Filename, directory, or URL to files identifying the resource to get from a server. 28 | -h, --help help for approve 29 | -k, --kustomize string Process the kustomization directory. This flag can't be used together with -f or -R. 30 | -o, --output string Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file). 31 | -R, --recursive Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory. 32 | --show-managed-fields If true, keep the managedFields when printing objects in JSON or YAML format. 33 | --template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview]. 34 | ``` 35 | 36 | ### Options inherited from parent commands 37 | 38 | ``` 39 | --as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace. 40 | --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. 41 | --as-uid string UID to impersonate for the operation. 42 | --cache-dir string Default cache directory (default "$HOME/.kube/cache") 43 | --certificate-authority string Path to a cert file for the certificate authority 44 | --client-certificate string Path to a client certificate file for TLS 45 | --client-key string Path to a client key file for TLS 46 | --cluster string The name of the kubeconfig cluster to use 47 | --context string The name of the kubeconfig context to use 48 | --disable-compression If true, opt-out of response compression for all requests to the server 49 | --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure 50 | --kubeconfig string Path to the kubeconfig file to use for CLI requests. 51 | --match-server-version Require server version to match client version 52 | -n, --namespace string If present, the namespace scope for this CLI request 53 | --password string Password for basic authentication to the API server 54 | --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none") 55 | --profile-output string Name of the file to write the profile to (default "profile.pprof") 56 | --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") 57 | -s, --server string The address and port of the Kubernetes API server 58 | --tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used 59 | --token string Bearer token for authentication to the API server 60 | --user string The name of the kubeconfig user to use 61 | --username string Username for basic authentication to the API server 62 | --warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code 63 | ``` 64 | 65 | ### SEE ALSO 66 | 67 | * [kubectl-kruise rollout](kubectl-kruise_rollout.md) - Manage the rollout of a resource 68 | 69 | ###### Auto generated by spf13/cobra on 12-Mar-2025 70 | -------------------------------------------------------------------------------- /docs/kubectl-kruise_rollout_history.md: -------------------------------------------------------------------------------- 1 | ## kubectl-kruise rollout history 2 | 3 | View rollout history 4 | 5 | ### Synopsis 6 | 7 | View previous rollout revisions and configurations. 8 | 9 | ``` 10 | kubectl-kruise rollout history (TYPE NAME | TYPE/NAME) [flags] 11 | ``` 12 | 13 | ### Examples 14 | 15 | ``` 16 | # View the rollout history of a cloneset 17 | kubectl-kruise rollout history cloneset/abc 18 | 19 | # View the rollout history of a advanced statefulset 20 | kubectl-kruise rollout history asts/abc 21 | 22 | # View the details of daemonset revision 3 23 | kubectl-kruise rollout history daemonset/abc --revision=3 24 | ``` 25 | 26 | ### Options 27 | 28 | ``` 29 | --allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true) 30 | -f, --filename strings Filename, directory, or URL to files identifying the resource to get from a server. 31 | -h, --help help for history 32 | -k, --kustomize string Process the kustomization directory. This flag can't be used together with -f or -R. 33 | -o, --output string Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file). 34 | -R, --recursive Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory. 35 | --revision int See the details, including podTemplate of the revision specified 36 | --show-managed-fields If true, keep the managedFields when printing objects in JSON or YAML format. 37 | --template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview]. 38 | ``` 39 | 40 | ### Options inherited from parent commands 41 | 42 | ``` 43 | --as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace. 44 | --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. 45 | --as-uid string UID to impersonate for the operation. 46 | --cache-dir string Default cache directory (default "$HOME/.kube/cache") 47 | --certificate-authority string Path to a cert file for the certificate authority 48 | --client-certificate string Path to a client certificate file for TLS 49 | --client-key string Path to a client key file for TLS 50 | --cluster string The name of the kubeconfig cluster to use 51 | --context string The name of the kubeconfig context to use 52 | --disable-compression If true, opt-out of response compression for all requests to the server 53 | --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure 54 | --kubeconfig string Path to the kubeconfig file to use for CLI requests. 55 | --match-server-version Require server version to match client version 56 | -n, --namespace string If present, the namespace scope for this CLI request 57 | --password string Password for basic authentication to the API server 58 | --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none") 59 | --profile-output string Name of the file to write the profile to (default "profile.pprof") 60 | --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") 61 | -s, --server string The address and port of the Kubernetes API server 62 | --tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used 63 | --token string Bearer token for authentication to the API server 64 | --user string The name of the kubeconfig user to use 65 | --username string Username for basic authentication to the API server 66 | --warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code 67 | ``` 68 | 69 | ### SEE ALSO 70 | 71 | * [kubectl-kruise rollout](kubectl-kruise_rollout.md) - Manage the rollout of a resource 72 | 73 | ###### Auto generated by spf13/cobra on 12-Mar-2025 74 | -------------------------------------------------------------------------------- /docs/kubectl-kruise_rollout_pause.md: -------------------------------------------------------------------------------- 1 | ## kubectl-kruise rollout pause 2 | 3 | Mark the provided resource as paused 4 | 5 | ### Synopsis 6 | 7 | Mark the provided resource as paused 8 | 9 | Paused resources will not be reconciled by a controller. Use "kubectl rollout resume" to resume a paused resource. Currently deployments, clonesets, rollouts support being paused. 10 | 11 | ``` 12 | kubectl-kruise rollout pause RESOURCE 13 | ``` 14 | 15 | ### Examples 16 | 17 | ``` 18 | # Mark the nginx deployment as paused. Any current state of 19 | # the deployment will continue its function, new updates to the deployment will not 20 | # have an effect as long as the deployment is paused. 21 | 22 | kubectl-kruise rollout pause deployment/nginx 23 | ``` 24 | 25 | ### Options 26 | 27 | ``` 28 | --allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true) 29 | -f, --filename strings Filename, directory, or URL to files identifying the resource to get from a server. 30 | -h, --help help for pause 31 | -k, --kustomize string Process the kustomization directory. This flag can't be used together with -f or -R. 32 | -o, --output string Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file). 33 | -R, --recursive Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory. 34 | --show-managed-fields If true, keep the managedFields when printing objects in JSON or YAML format. 35 | --template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview]. 36 | ``` 37 | 38 | ### Options inherited from parent commands 39 | 40 | ``` 41 | --as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace. 42 | --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. 43 | --as-uid string UID to impersonate for the operation. 44 | --cache-dir string Default cache directory (default "$HOME/.kube/cache") 45 | --certificate-authority string Path to a cert file for the certificate authority 46 | --client-certificate string Path to a client certificate file for TLS 47 | --client-key string Path to a client key file for TLS 48 | --cluster string The name of the kubeconfig cluster to use 49 | --context string The name of the kubeconfig context to use 50 | --disable-compression If true, opt-out of response compression for all requests to the server 51 | --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure 52 | --kubeconfig string Path to the kubeconfig file to use for CLI requests. 53 | --match-server-version Require server version to match client version 54 | -n, --namespace string If present, the namespace scope for this CLI request 55 | --password string Password for basic authentication to the API server 56 | --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none") 57 | --profile-output string Name of the file to write the profile to (default "profile.pprof") 58 | --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") 59 | -s, --server string The address and port of the Kubernetes API server 60 | --tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used 61 | --token string Bearer token for authentication to the API server 62 | --user string The name of the kubeconfig user to use 63 | --username string Username for basic authentication to the API server 64 | --warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code 65 | ``` 66 | 67 | ### SEE ALSO 68 | 69 | * [kubectl-kruise rollout](kubectl-kruise_rollout.md) - Manage the rollout of a resource 70 | 71 | ###### Auto generated by spf13/cobra on 12-Mar-2025 72 | -------------------------------------------------------------------------------- /docs/kubectl-kruise_rollout_restart.md: -------------------------------------------------------------------------------- 1 | ## kubectl-kruise rollout restart 2 | 3 | Restart a resource 4 | 5 | ### Synopsis 6 | 7 | Restart a resource. 8 | 9 | Resource will be rollout restarted. 10 | 11 | ``` 12 | kubectl-kruise rollout restart RESOURCE 13 | ``` 14 | 15 | ### Examples 16 | 17 | ``` 18 | # Restart a deployment 19 | kubectl-kruise rollout restart deployment/nginx 20 | kubectl-kruise rollout restart cloneset/abc 21 | 22 | # Restart a daemonset 23 | kubectl-kruise rollout restart daemonset/abc 24 | ``` 25 | 26 | ### Options 27 | 28 | ``` 29 | --allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true) 30 | -f, --filename strings Filename, directory, or URL to files identifying the resource to get from a server. 31 | -h, --help help for restart 32 | -k, --kustomize string Process the kustomization directory. This flag can't be used together with -f or -R. 33 | -o, --output string Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file). 34 | -R, --recursive Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory. 35 | --show-managed-fields If true, keep the managedFields when printing objects in JSON or YAML format. 36 | --template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview]. 37 | ``` 38 | 39 | ### Options inherited from parent commands 40 | 41 | ``` 42 | --as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace. 43 | --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. 44 | --as-uid string UID to impersonate for the operation. 45 | --cache-dir string Default cache directory (default "$HOME/.kube/cache") 46 | --certificate-authority string Path to a cert file for the certificate authority 47 | --client-certificate string Path to a client certificate file for TLS 48 | --client-key string Path to a client key file for TLS 49 | --cluster string The name of the kubeconfig cluster to use 50 | --context string The name of the kubeconfig context to use 51 | --disable-compression If true, opt-out of response compression for all requests to the server 52 | --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure 53 | --kubeconfig string Path to the kubeconfig file to use for CLI requests. 54 | --match-server-version Require server version to match client version 55 | -n, --namespace string If present, the namespace scope for this CLI request 56 | --password string Password for basic authentication to the API server 57 | --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none") 58 | --profile-output string Name of the file to write the profile to (default "profile.pprof") 59 | --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") 60 | -s, --server string The address and port of the Kubernetes API server 61 | --tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used 62 | --token string Bearer token for authentication to the API server 63 | --user string The name of the kubeconfig user to use 64 | --username string Username for basic authentication to the API server 65 | --warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code 66 | ``` 67 | 68 | ### SEE ALSO 69 | 70 | * [kubectl-kruise rollout](kubectl-kruise_rollout.md) - Manage the rollout of a resource 71 | 72 | ###### Auto generated by spf13/cobra on 12-Mar-2025 73 | -------------------------------------------------------------------------------- /docs/kubectl-kruise_rollout_resume.md: -------------------------------------------------------------------------------- 1 | ## kubectl-kruise rollout resume 2 | 3 | Resume a paused resource 4 | 5 | ### Synopsis 6 | 7 | Resume a paused resource 8 | 9 | Paused resources will not be reconciled by a controller. By resuming a resource, we allow it to be reconciled again. Currently deployments, cloneset support being resumed. 10 | 11 | ``` 12 | kubectl-kruise rollout resume RESOURCE 13 | ``` 14 | 15 | ### Examples 16 | 17 | ``` 18 | # Resume an already paused rollout/cloneset/deployment resource 19 | 20 | kubectl-kruise rollout resume rollout/nginx 21 | kubectl-kruise rollout resume cloneset/nginx 22 | kubectl-kruise rollout resume deployment/nginx 23 | ``` 24 | 25 | ### Options 26 | 27 | ``` 28 | --allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true) 29 | -f, --filename strings Filename, directory, or URL to files identifying the resource to get from a server. 30 | -h, --help help for resume 31 | -k, --kustomize string Process the kustomization directory. This flag can't be used together with -f or -R. 32 | -o, --output string Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file). 33 | -R, --recursive Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory. 34 | --show-managed-fields If true, keep the managedFields when printing objects in JSON or YAML format. 35 | --template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview]. 36 | ``` 37 | 38 | ### Options inherited from parent commands 39 | 40 | ``` 41 | --as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace. 42 | --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. 43 | --as-uid string UID to impersonate for the operation. 44 | --cache-dir string Default cache directory (default "$HOME/.kube/cache") 45 | --certificate-authority string Path to a cert file for the certificate authority 46 | --client-certificate string Path to a client certificate file for TLS 47 | --client-key string Path to a client key file for TLS 48 | --cluster string The name of the kubeconfig cluster to use 49 | --context string The name of the kubeconfig context to use 50 | --disable-compression If true, opt-out of response compression for all requests to the server 51 | --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure 52 | --kubeconfig string Path to the kubeconfig file to use for CLI requests. 53 | --match-server-version Require server version to match client version 54 | -n, --namespace string If present, the namespace scope for this CLI request 55 | --password string Password for basic authentication to the API server 56 | --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none") 57 | --profile-output string Name of the file to write the profile to (default "profile.pprof") 58 | --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") 59 | -s, --server string The address and port of the Kubernetes API server 60 | --tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used 61 | --token string Bearer token for authentication to the API server 62 | --user string The name of the kubeconfig user to use 63 | --username string Username for basic authentication to the API server 64 | --warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code 65 | ``` 66 | 67 | ### SEE ALSO 68 | 69 | * [kubectl-kruise rollout](kubectl-kruise_rollout.md) - Manage the rollout of a resource 70 | 71 | ###### Auto generated by spf13/cobra on 12-Mar-2025 72 | -------------------------------------------------------------------------------- /docs/kubectl-kruise_rollout_status.md: -------------------------------------------------------------------------------- 1 | ## kubectl-kruise rollout status 2 | 3 | Show the status of the rollout 4 | 5 | ### Synopsis 6 | 7 | Show the status of the rollout. 8 | 9 | By default 'rollout status' will watch the status of the latest rollout until it's done. If you don't want to wait for the rollout to finish then you can use --watch=false. Note that if a new rollout starts in-between, then 'rollout status' will continue watching the latest revision. If you want to pin to a specific revision and abort if it is rolled over by another revision, use --revision=N where N is the revision you need to watch for. 10 | 11 | ``` 12 | kubectl-kruise rollout status (TYPE NAME | TYPE/NAME) [flags] 13 | ``` 14 | 15 | ### Examples 16 | 17 | ``` 18 | # Watch the rollout status of a deployment 19 | kubectl-kruise rollout status deployment/nginx 20 | 21 | # Watch the rollout status of a cloneset 22 | kubectl-kruise rollout status cloneset/nginx 23 | 24 | # Watch the rollout status of a advanced statefulset 25 | kubectl-kruise rollout status asts/nginx 26 | ``` 27 | 28 | ### Options 29 | 30 | ``` 31 | -d, --detail Show the detail status of the rollout. 32 | -f, --filename strings Filename, directory, or URL to files identifying the resource to get from a server. 33 | -h, --help help for status 34 | -k, --kustomize string Process the kustomization directory. This flag can't be used together with -f or -R. 35 | -R, --recursive Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory. 36 | --revision int Pin to a specific revision for showing its status. Defaults to 0 (last revision). 37 | --timeout duration The length of time to wait before ending watch, zero means never. Any other values should contain a corresponding time unit (e.g. 1s, 2m, 3h). 38 | -w, --watch Watch the status of the rollout until it's done. (default true) 39 | ``` 40 | 41 | ### Options inherited from parent commands 42 | 43 | ``` 44 | --as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace. 45 | --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. 46 | --as-uid string UID to impersonate for the operation. 47 | --cache-dir string Default cache directory (default "$HOME/.kube/cache") 48 | --certificate-authority string Path to a cert file for the certificate authority 49 | --client-certificate string Path to a client certificate file for TLS 50 | --client-key string Path to a client key file for TLS 51 | --cluster string The name of the kubeconfig cluster to use 52 | --context string The name of the kubeconfig context to use 53 | --disable-compression If true, opt-out of response compression for all requests to the server 54 | --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure 55 | --kubeconfig string Path to the kubeconfig file to use for CLI requests. 56 | --match-server-version Require server version to match client version 57 | -n, --namespace string If present, the namespace scope for this CLI request 58 | --password string Password for basic authentication to the API server 59 | --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none") 60 | --profile-output string Name of the file to write the profile to (default "profile.pprof") 61 | --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") 62 | -s, --server string The address and port of the Kubernetes API server 63 | --tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used 64 | --token string Bearer token for authentication to the API server 65 | --user string The name of the kubeconfig user to use 66 | --username string Username for basic authentication to the API server 67 | --warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code 68 | ``` 69 | 70 | ### SEE ALSO 71 | 72 | * [kubectl-kruise rollout](kubectl-kruise_rollout.md) - Manage the rollout of a resource 73 | 74 | ###### Auto generated by spf13/cobra on 12-Mar-2025 75 | -------------------------------------------------------------------------------- /docs/kubectl-kruise_scaledown.md: -------------------------------------------------------------------------------- 1 | ## kubectl-kruise scaledown 2 | 3 | Scaledown a cloneset with selective Pods 4 | 5 | ### Synopsis 6 | 7 | Scaledown a cloneset with selective Pods 8 | 9 | ``` 10 | kubectl-kruise scaledown [CLONESET] --pods [POD1,POD2] -n [NAMESPACE] 11 | ``` 12 | 13 | ### Examples 14 | 15 | ``` 16 | 17 | # Scale down 2 with selective pods 18 | kubectl-kruise scaledown CloneSet cloneset-demo --pods pod-1, pod-2 -n default 19 | 20 | ``` 21 | 22 | ### Options 23 | 24 | ``` 25 | -h, --help help for scaledown 26 | --pods string Name of the pods to delete 27 | ``` 28 | 29 | ### Options inherited from parent commands 30 | 31 | ``` 32 | --as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace. 33 | --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. 34 | --as-uid string UID to impersonate for the operation. 35 | --cache-dir string Default cache directory (default "$HOME/.kube/cache") 36 | --certificate-authority string Path to a cert file for the certificate authority 37 | --client-certificate string Path to a client certificate file for TLS 38 | --client-key string Path to a client key file for TLS 39 | --cluster string The name of the kubeconfig cluster to use 40 | --context string The name of the kubeconfig context to use 41 | --disable-compression If true, opt-out of response compression for all requests to the server 42 | --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure 43 | --kubeconfig string Path to the kubeconfig file to use for CLI requests. 44 | --match-server-version Require server version to match client version 45 | -n, --namespace string If present, the namespace scope for this CLI request 46 | --password string Password for basic authentication to the API server 47 | --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none") 48 | --profile-output string Name of the file to write the profile to (default "profile.pprof") 49 | --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") 50 | -s, --server string The address and port of the Kubernetes API server 51 | --tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used 52 | --token string Bearer token for authentication to the API server 53 | --user string The name of the kubeconfig user to use 54 | --username string Username for basic authentication to the API server 55 | --warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code 56 | ``` 57 | 58 | ### SEE ALSO 59 | 60 | * [kubectl-kruise](kubectl-kruise.md) - kubectl-kruise controls the OpenKruise CRs 61 | 62 | ###### Auto generated by spf13/cobra on 12-Mar-2025 63 | -------------------------------------------------------------------------------- /docs/kubectl-kruise_set.md: -------------------------------------------------------------------------------- 1 | ## kubectl-kruise set 2 | 3 | Set specific features on objects 4 | 5 | ### Synopsis 6 | 7 | Configure application resources 8 | 9 | These commands help you make changes to existing application resources. 10 | 11 | ``` 12 | kubectl-kruise set SUBCOMMAND 13 | ``` 14 | 15 | ### Options 16 | 17 | ``` 18 | -h, --help help for set 19 | ``` 20 | 21 | ### Options inherited from parent commands 22 | 23 | ``` 24 | --as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace. 25 | --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. 26 | --as-uid string UID to impersonate for the operation. 27 | --cache-dir string Default cache directory (default "$HOME/.kube/cache") 28 | --certificate-authority string Path to a cert file for the certificate authority 29 | --client-certificate string Path to a client certificate file for TLS 30 | --client-key string Path to a client key file for TLS 31 | --cluster string The name of the kubeconfig cluster to use 32 | --context string The name of the kubeconfig context to use 33 | --disable-compression If true, opt-out of response compression for all requests to the server 34 | --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure 35 | --kubeconfig string Path to the kubeconfig file to use for CLI requests. 36 | --match-server-version Require server version to match client version 37 | -n, --namespace string If present, the namespace scope for this CLI request 38 | --password string Password for basic authentication to the API server 39 | --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none") 40 | --profile-output string Name of the file to write the profile to (default "profile.pprof") 41 | --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") 42 | -s, --server string The address and port of the Kubernetes API server 43 | --tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used 44 | --token string Bearer token for authentication to the API server 45 | --user string The name of the kubeconfig user to use 46 | --username string Username for basic authentication to the API server 47 | --warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code 48 | ``` 49 | 50 | ### SEE ALSO 51 | 52 | * [kubectl-kruise](kubectl-kruise.md) - kubectl-kruise controls the OpenKruise CRs 53 | * [kubectl-kruise set env](kubectl-kruise_set_env.md) - Update environment variables on a pod template 54 | * [kubectl-kruise set image](kubectl-kruise_set_image.md) - Update image of a pod template 55 | * [kubectl-kruise set resources](kubectl-kruise_set_resources.md) - Update resource requests/limits on objects with pod templates 56 | * [kubectl-kruise set selector](kubectl-kruise_set_selector.md) - Set the selector on a resource 57 | * [kubectl-kruise set serviceaccount](kubectl-kruise_set_serviceaccount.md) - Update ServiceAccount of a resource 58 | * [kubectl-kruise set subject](kubectl-kruise_set_subject.md) - Update User, Group or ServiceAccount in a RoleBinding/ClusterRoleBinding 59 | 60 | ###### Auto generated by spf13/cobra on 12-Mar-2025 61 | -------------------------------------------------------------------------------- /docs/yaml/kubectl-kruise.yaml: -------------------------------------------------------------------------------- 1 | name: kubectl-kruise 2 | synopsis: kubectl-kruise controls the OpenKruise CRs 3 | description: |- 4 | kubectl-kruise controls the OpenKruise manager. 5 | 6 | Find more information at: https://openkruise.io/ 7 | usage: kubectl-kruise [flags] 8 | options: 9 | - name: as 10 | usage: | 11 | Username to impersonate for the operation. User could be a regular user or a service account in a namespace. 12 | - name: as-group 13 | default_value: '[]' 14 | usage: | 15 | Group to impersonate for the operation, this flag can be repeated to specify multiple groups. 16 | - name: as-uid 17 | usage: UID to impersonate for the operation. 18 | - name: cache-dir 19 | default_value: $HOME/.kube/cache 20 | usage: Default cache directory 21 | - name: certificate-authority 22 | usage: Path to a cert file for the certificate authority 23 | - name: client-certificate 24 | usage: Path to a client certificate file for TLS 25 | - name: client-key 26 | usage: Path to a client key file for TLS 27 | - name: cluster 28 | usage: The name of the kubeconfig cluster to use 29 | - name: context 30 | usage: The name of the kubeconfig context to use 31 | - name: disable-compression 32 | default_value: "false" 33 | usage: | 34 | If true, opt-out of response compression for all requests to the server 35 | - name: help 36 | shorthand: h 37 | default_value: "false" 38 | usage: help for kubectl-kruise 39 | - name: insecure-skip-tls-verify 40 | default_value: "false" 41 | usage: | 42 | If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure 43 | - name: kubeconfig 44 | usage: Path to the kubeconfig file to use for CLI requests. 45 | - name: match-server-version 46 | default_value: "false" 47 | usage: Require server version to match client version 48 | - name: namespace 49 | shorthand: "n" 50 | usage: If present, the namespace scope for this CLI request 51 | - name: password 52 | usage: Password for basic authentication to the API server 53 | - name: profile 54 | default_value: none 55 | usage: | 56 | Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) 57 | - name: profile-output 58 | default_value: profile.pprof 59 | usage: Name of the file to write the profile to 60 | - name: request-timeout 61 | default_value: "0" 62 | usage: | 63 | The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. 64 | - name: server 65 | shorthand: s 66 | usage: The address and port of the Kubernetes API server 67 | - name: tls-server-name 68 | usage: | 69 | Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used 70 | - name: token 71 | usage: Bearer token for authentication to the API server 72 | - name: user 73 | usage: The name of the kubeconfig user to use 74 | - name: username 75 | usage: Username for basic authentication to the API server 76 | - name: warnings-as-errors 77 | default_value: "false" 78 | usage: | 79 | Treat warnings received from the server as errors and exit with a non-zero exit code 80 | see_also: 81 | - kubectl-kruise create - Create a resource from a file or from stdin. 82 | - kubectl-kruise describe - Show details of a specific resource or group of resources 83 | - kubectl-kruise expose - Take a workload(e.g. deployment, cloneset), service or pod and expose it as a new Kubernetes Service 84 | - kubectl-kruise migrate - Migrate from K8s original workloads to Kruise workloads 85 | - kubectl-kruise rollout - Manage the rollout of a resource 86 | - kubectl-kruise scaledown - Scaledown a cloneset with selective Pods 87 | - kubectl-kruise set - Set specific features on objects 88 | -------------------------------------------------------------------------------- /docs/yaml/kubectl-kruise_describe.yaml: -------------------------------------------------------------------------------- 1 | name: kubectl-kruise describe 2 | synopsis: Show details of a specific resource or group of resources 3 | description: Show details of a rollout. 4 | usage: kubectl-kruise describe SUBCOMMAND 5 | options: 6 | - name: help 7 | shorthand: h 8 | default_value: "false" 9 | usage: help for describe 10 | inherited_options: 11 | - name: as 12 | usage: | 13 | Username to impersonate for the operation. User could be a regular user or a service account in a namespace. 14 | - name: as-group 15 | default_value: '[]' 16 | usage: | 17 | Group to impersonate for the operation, this flag can be repeated to specify multiple groups. 18 | - name: as-uid 19 | usage: UID to impersonate for the operation. 20 | - name: cache-dir 21 | default_value: $HOME/.kube/cache 22 | usage: Default cache directory 23 | - name: certificate-authority 24 | usage: Path to a cert file for the certificate authority 25 | - name: client-certificate 26 | usage: Path to a client certificate file for TLS 27 | - name: client-key 28 | usage: Path to a client key file for TLS 29 | - name: cluster 30 | usage: The name of the kubeconfig cluster to use 31 | - name: context 32 | usage: The name of the kubeconfig context to use 33 | - name: disable-compression 34 | default_value: "false" 35 | usage: | 36 | If true, opt-out of response compression for all requests to the server 37 | - name: insecure-skip-tls-verify 38 | default_value: "false" 39 | usage: | 40 | If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure 41 | - name: kubeconfig 42 | usage: Path to the kubeconfig file to use for CLI requests. 43 | - name: match-server-version 44 | default_value: "false" 45 | usage: Require server version to match client version 46 | - name: namespace 47 | shorthand: "n" 48 | usage: If present, the namespace scope for this CLI request 49 | - name: password 50 | usage: Password for basic authentication to the API server 51 | - name: profile 52 | default_value: none 53 | usage: | 54 | Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) 55 | - name: profile-output 56 | default_value: profile.pprof 57 | usage: Name of the file to write the profile to 58 | - name: request-timeout 59 | default_value: "0" 60 | usage: | 61 | The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. 62 | - name: server 63 | shorthand: s 64 | usage: The address and port of the Kubernetes API server 65 | - name: tls-server-name 66 | usage: | 67 | Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used 68 | - name: token 69 | usage: Bearer token for authentication to the API server 70 | - name: user 71 | usage: The name of the kubeconfig user to use 72 | - name: username 73 | usage: Username for basic authentication to the API server 74 | - name: warnings-as-errors 75 | default_value: "false" 76 | usage: | 77 | Treat warnings received from the server as errors and exit with a non-zero exit code 78 | example: |4- 79 | # Describe the rollout named rollout-demo 80 | kubectl-kruise describe rollout rollout-demo 81 | see_also: 82 | - kubectl-kruise - kubectl-kruise controls the OpenKruise CRs 83 | - kubectl-kruise describe rollout - Get details about a rollout 84 | -------------------------------------------------------------------------------- /docs/yaml/kubectl-kruise_describe_rollout.yaml: -------------------------------------------------------------------------------- 1 | name: kubectl-kruise describe rollout 2 | synopsis: Get details about a rollout 3 | description: Get details about and visual representation of a rollout. 4 | usage: kubectl-kruise describe rollout SUBCOMMAND 5 | options: 6 | - name: all 7 | default_value: "false" 8 | usage: Show all pods in the rollout 9 | - name: help 10 | shorthand: h 11 | default_value: "false" 12 | usage: help for rollout 13 | - name: no-color 14 | default_value: "false" 15 | usage: If true, print output without color 16 | - name: timeout 17 | default_value: "0" 18 | usage: Timeout after specified seconds 19 | - name: watch 20 | shorthand: w 21 | default_value: "false" 22 | usage: Watch for changes to the rollout 23 | inherited_options: 24 | - name: as 25 | usage: | 26 | Username to impersonate for the operation. User could be a regular user or a service account in a namespace. 27 | - name: as-group 28 | default_value: '[]' 29 | usage: | 30 | Group to impersonate for the operation, this flag can be repeated to specify multiple groups. 31 | - name: as-uid 32 | usage: UID to impersonate for the operation. 33 | - name: cache-dir 34 | default_value: $HOME/.kube/cache 35 | usage: Default cache directory 36 | - name: certificate-authority 37 | usage: Path to a cert file for the certificate authority 38 | - name: client-certificate 39 | usage: Path to a client certificate file for TLS 40 | - name: client-key 41 | usage: Path to a client key file for TLS 42 | - name: cluster 43 | usage: The name of the kubeconfig cluster to use 44 | - name: context 45 | usage: The name of the kubeconfig context to use 46 | - name: disable-compression 47 | default_value: "false" 48 | usage: | 49 | If true, opt-out of response compression for all requests to the server 50 | - name: insecure-skip-tls-verify 51 | default_value: "false" 52 | usage: | 53 | If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure 54 | - name: kubeconfig 55 | usage: Path to the kubeconfig file to use for CLI requests. 56 | - name: match-server-version 57 | default_value: "false" 58 | usage: Require server version to match client version 59 | - name: namespace 60 | shorthand: "n" 61 | usage: If present, the namespace scope for this CLI request 62 | - name: password 63 | usage: Password for basic authentication to the API server 64 | - name: profile 65 | default_value: none 66 | usage: | 67 | Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) 68 | - name: profile-output 69 | default_value: profile.pprof 70 | usage: Name of the file to write the profile to 71 | - name: request-timeout 72 | default_value: "0" 73 | usage: | 74 | The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. 75 | - name: server 76 | shorthand: s 77 | usage: The address and port of the Kubernetes API server 78 | - name: tls-server-name 79 | usage: | 80 | Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used 81 | - name: token 82 | usage: Bearer token for authentication to the API server 83 | - name: user 84 | usage: The name of the kubeconfig user to use 85 | - name: username 86 | usage: Username for basic authentication to the API server 87 | - name: warnings-as-errors 88 | default_value: "false" 89 | usage: | 90 | Treat warnings received from the server as errors and exit with a non-zero exit code 91 | example: " # Describe the rollout named rollout-demo within namespace default\n kubectl-kruise describe rollout rollout-demo/default\n \n # Watch for changes to the rollout named rollout-demo\n kubectl-kruise describe rollout rollout-demo/default -w" 92 | see_also: 93 | - kubectl-kruise describe - Show details of a specific resource or group of resources 94 | -------------------------------------------------------------------------------- /docs/yaml/kubectl-kruise_rollout.yaml: -------------------------------------------------------------------------------- 1 | name: kubectl-kruise rollout 2 | synopsis: Manage the rollout of a resource 3 | description: "Manage the rollout of a resource.\n \n Valid resource types include:\n\n * deployments\n * daemonsets\n * statefulsets\n * clonesets\n * statefulsets.apps.kruise.io\n * daemonsets.apps.kruise.io\n * rollouts.rollouts.kruise.io" 4 | usage: kubectl-kruise rollout SUBCOMMAND 5 | options: 6 | - name: help 7 | shorthand: h 8 | default_value: "false" 9 | usage: help for rollout 10 | inherited_options: 11 | - name: as 12 | usage: | 13 | Username to impersonate for the operation. User could be a regular user or a service account in a namespace. 14 | - name: as-group 15 | default_value: '[]' 16 | usage: | 17 | Group to impersonate for the operation, this flag can be repeated to specify multiple groups. 18 | - name: as-uid 19 | usage: UID to impersonate for the operation. 20 | - name: cache-dir 21 | default_value: $HOME/.kube/cache 22 | usage: Default cache directory 23 | - name: certificate-authority 24 | usage: Path to a cert file for the certificate authority 25 | - name: client-certificate 26 | usage: Path to a client certificate file for TLS 27 | - name: client-key 28 | usage: Path to a client key file for TLS 29 | - name: cluster 30 | usage: The name of the kubeconfig cluster to use 31 | - name: context 32 | usage: The name of the kubeconfig context to use 33 | - name: disable-compression 34 | default_value: "false" 35 | usage: | 36 | If true, opt-out of response compression for all requests to the server 37 | - name: insecure-skip-tls-verify 38 | default_value: "false" 39 | usage: | 40 | If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure 41 | - name: kubeconfig 42 | usage: Path to the kubeconfig file to use for CLI requests. 43 | - name: match-server-version 44 | default_value: "false" 45 | usage: Require server version to match client version 46 | - name: namespace 47 | shorthand: "n" 48 | usage: If present, the namespace scope for this CLI request 49 | - name: password 50 | usage: Password for basic authentication to the API server 51 | - name: profile 52 | default_value: none 53 | usage: | 54 | Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) 55 | - name: profile-output 56 | default_value: profile.pprof 57 | usage: Name of the file to write the profile to 58 | - name: request-timeout 59 | default_value: "0" 60 | usage: | 61 | The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. 62 | - name: server 63 | shorthand: s 64 | usage: The address and port of the Kubernetes API server 65 | - name: tls-server-name 66 | usage: | 67 | Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used 68 | - name: token 69 | usage: Bearer token for authentication to the API server 70 | - name: user 71 | usage: The name of the kubeconfig user to use 72 | - name: username 73 | usage: Username for basic authentication to the API server 74 | - name: warnings-as-errors 75 | default_value: "false" 76 | usage: | 77 | Treat warnings received from the server as errors and exit with a non-zero exit code 78 | example: " # Rollback to the previous cloneset\n kubectl-kruise rollout undo cloneset/abc\n \n # Check the rollout status of a daemonset\n kubectl-kruise rollout status daemonset/foo" 79 | see_also: 80 | - kubectl-kruise - kubectl-kruise controls the OpenKruise CRs 81 | - kubectl-kruise rollout approve - Approve a resource 82 | - kubectl-kruise rollout history - View rollout history 83 | - kubectl-kruise rollout pause - Mark the provided resource as paused 84 | - kubectl-kruise rollout restart - Restart a resource 85 | - kubectl-kruise rollout resume - Resume a paused resource 86 | - kubectl-kruise rollout status - Show the status of the rollout 87 | - kubectl-kruise rollout undo - Undo a previous rollout 88 | -------------------------------------------------------------------------------- /docs/yaml/kubectl-kruise_scaledown.yaml: -------------------------------------------------------------------------------- 1 | name: kubectl-kruise scaledown 2 | synopsis: Scaledown a cloneset with selective Pods 3 | description: Scaledown a cloneset with selective Pods 4 | usage: kubectl-kruise scaledown [CLONESET] --pods [POD1,POD2] -n [NAMESPACE] 5 | options: 6 | - name: help 7 | shorthand: h 8 | default_value: "false" 9 | usage: help for scaledown 10 | - name: pods 11 | usage: Name of the pods to delete 12 | inherited_options: 13 | - name: as 14 | usage: | 15 | Username to impersonate for the operation. User could be a regular user or a service account in a namespace. 16 | - name: as-group 17 | default_value: '[]' 18 | usage: | 19 | Group to impersonate for the operation, this flag can be repeated to specify multiple groups. 20 | - name: as-uid 21 | usage: UID to impersonate for the operation. 22 | - name: cache-dir 23 | default_value: $HOME/.kube/cache 24 | usage: Default cache directory 25 | - name: certificate-authority 26 | usage: Path to a cert file for the certificate authority 27 | - name: client-certificate 28 | usage: Path to a client certificate file for TLS 29 | - name: client-key 30 | usage: Path to a client key file for TLS 31 | - name: cluster 32 | usage: The name of the kubeconfig cluster to use 33 | - name: context 34 | usage: The name of the kubeconfig context to use 35 | - name: disable-compression 36 | default_value: "false" 37 | usage: | 38 | If true, opt-out of response compression for all requests to the server 39 | - name: insecure-skip-tls-verify 40 | default_value: "false" 41 | usage: | 42 | If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure 43 | - name: kubeconfig 44 | usage: Path to the kubeconfig file to use for CLI requests. 45 | - name: match-server-version 46 | default_value: "false" 47 | usage: Require server version to match client version 48 | - name: namespace 49 | shorthand: "n" 50 | usage: If present, the namespace scope for this CLI request 51 | - name: password 52 | usage: Password for basic authentication to the API server 53 | - name: profile 54 | default_value: none 55 | usage: | 56 | Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) 57 | - name: profile-output 58 | default_value: profile.pprof 59 | usage: Name of the file to write the profile to 60 | - name: request-timeout 61 | default_value: "0" 62 | usage: | 63 | The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. 64 | - name: server 65 | shorthand: s 66 | usage: The address and port of the Kubernetes API server 67 | - name: tls-server-name 68 | usage: | 69 | Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used 70 | - name: token 71 | usage: Bearer token for authentication to the API server 72 | - name: user 73 | usage: The name of the kubeconfig user to use 74 | - name: username 75 | usage: Username for basic authentication to the API server 76 | - name: warnings-as-errors 77 | default_value: "false" 78 | usage: | 79 | Treat warnings received from the server as errors and exit with a non-zero exit code 80 | example: |4 81 | # Scale down 2 with selective pods 82 | kubectl-kruise scaledown CloneSet cloneset-demo --pods pod-1, pod-2 -n default 83 | see_also: 84 | - kubectl-kruise - kubectl-kruise controls the OpenKruise CRs 85 | -------------------------------------------------------------------------------- /docs/yaml/kubectl-kruise_set.yaml: -------------------------------------------------------------------------------- 1 | name: kubectl-kruise set 2 | synopsis: Set specific features on objects 3 | description: |- 4 | Configure application resources 5 | 6 | These commands help you make changes to existing application resources. 7 | usage: kubectl-kruise set SUBCOMMAND 8 | options: 9 | - name: help 10 | shorthand: h 11 | default_value: "false" 12 | usage: help for set 13 | inherited_options: 14 | - name: as 15 | usage: | 16 | Username to impersonate for the operation. User could be a regular user or a service account in a namespace. 17 | - name: as-group 18 | default_value: '[]' 19 | usage: | 20 | Group to impersonate for the operation, this flag can be repeated to specify multiple groups. 21 | - name: as-uid 22 | usage: UID to impersonate for the operation. 23 | - name: cache-dir 24 | default_value: $HOME/.kube/cache 25 | usage: Default cache directory 26 | - name: certificate-authority 27 | usage: Path to a cert file for the certificate authority 28 | - name: client-certificate 29 | usage: Path to a client certificate file for TLS 30 | - name: client-key 31 | usage: Path to a client key file for TLS 32 | - name: cluster 33 | usage: The name of the kubeconfig cluster to use 34 | - name: context 35 | usage: The name of the kubeconfig context to use 36 | - name: disable-compression 37 | default_value: "false" 38 | usage: | 39 | If true, opt-out of response compression for all requests to the server 40 | - name: insecure-skip-tls-verify 41 | default_value: "false" 42 | usage: | 43 | If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure 44 | - name: kubeconfig 45 | usage: Path to the kubeconfig file to use for CLI requests. 46 | - name: match-server-version 47 | default_value: "false" 48 | usage: Require server version to match client version 49 | - name: namespace 50 | shorthand: "n" 51 | usage: If present, the namespace scope for this CLI request 52 | - name: password 53 | usage: Password for basic authentication to the API server 54 | - name: profile 55 | default_value: none 56 | usage: | 57 | Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) 58 | - name: profile-output 59 | default_value: profile.pprof 60 | usage: Name of the file to write the profile to 61 | - name: request-timeout 62 | default_value: "0" 63 | usage: | 64 | The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. 65 | - name: server 66 | shorthand: s 67 | usage: The address and port of the Kubernetes API server 68 | - name: tls-server-name 69 | usage: | 70 | Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used 71 | - name: token 72 | usage: Bearer token for authentication to the API server 73 | - name: user 74 | usage: The name of the kubeconfig user to use 75 | - name: username 76 | usage: Username for basic authentication to the API server 77 | - name: warnings-as-errors 78 | default_value: "false" 79 | usage: | 80 | Treat warnings received from the server as errors and exit with a non-zero exit code 81 | see_also: 82 | - kubectl-kruise - kubectl-kruise controls the OpenKruise CRs 83 | - kubectl-kruise set env - Update environment variables on a pod template 84 | - kubectl-kruise set image - Update image of a pod template 85 | - kubectl-kruise set resources - Update resource requests/limits on objects with pod templates 86 | - kubectl-kruise set selector - Set the selector on a resource 87 | - kubectl-kruise set serviceaccount - Update ServiceAccount of a resource 88 | - kubectl-kruise set subject - Update User, Group or ServiceAccount in a RoleBinding/ClusterRoleBinding 89 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/openkruise/kruise-tools 2 | 3 | go 1.22.0 4 | 5 | toolchain go1.22.4 6 | 7 | require ( 8 | github.com/go-errors/errors v1.4.2 9 | github.com/lithammer/dedent v1.1.0 10 | github.com/moby/term v0.0.0-20221205130635-1aeaba878587 11 | github.com/openkruise/kruise-api v1.8.0 12 | github.com/openkruise/kruise-rollout-api v0.6.0 13 | github.com/spf13/cobra v1.8.1 14 | github.com/spf13/pflag v1.0.5 15 | github.com/stretchr/testify v1.9.0 16 | k8s.io/api v0.30.11 17 | k8s.io/apimachinery v0.30.11 18 | k8s.io/cli-runtime v0.30.11 19 | k8s.io/client-go v0.30.11 20 | k8s.io/component-base v0.30.11 21 | k8s.io/klog/v2 v2.120.1 22 | k8s.io/kubectl v0.30.11 23 | k8s.io/utils v0.0.0-20230726121419-3b25d923346b 24 | sigs.k8s.io/controller-runtime v0.18.6 25 | sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 26 | sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 27 | ) 28 | 29 | require ( 30 | github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect 31 | github.com/MakeNowJust/heredoc v1.0.0 // indirect 32 | github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect 33 | github.com/chai2010/gettext-go v1.0.2 // indirect 34 | github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect 35 | github.com/davecgh/go-spew v1.1.1 // indirect 36 | github.com/emicklei/go-restful/v3 v3.11.0 // indirect 37 | github.com/evanphx/json-patch v5.6.0+incompatible // indirect 38 | github.com/evanphx/json-patch/v5 v5.9.0 // indirect 39 | github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect 40 | github.com/fatih/camelcase v1.0.0 // indirect 41 | github.com/fvbommel/sortorder v1.1.0 // indirect 42 | github.com/go-logr/logr v1.4.2 // indirect 43 | github.com/go-openapi/jsonpointer v0.19.6 // indirect 44 | github.com/go-openapi/jsonreference v0.20.2 // indirect 45 | github.com/go-openapi/swag v0.22.3 // indirect 46 | github.com/gogo/protobuf v1.3.2 // indirect 47 | github.com/golang/protobuf v1.5.4 // indirect 48 | github.com/google/btree v1.0.1 // indirect 49 | github.com/google/gnostic-models v0.6.8 // indirect 50 | github.com/google/go-cmp v0.6.0 // indirect 51 | github.com/google/gofuzz v1.2.0 // indirect 52 | github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect 53 | github.com/google/uuid v1.6.0 // indirect 54 | github.com/gorilla/websocket v1.5.0 // indirect 55 | github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect 56 | github.com/imdario/mergo v0.3.12 // indirect 57 | github.com/inconshreveable/mousetrap v1.1.0 // indirect 58 | github.com/jonboulle/clockwork v0.2.2 // indirect 59 | github.com/josharian/intern v1.0.0 // indirect 60 | github.com/json-iterator/go v1.1.12 // indirect 61 | github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect 62 | github.com/mailru/easyjson v0.7.7 // indirect 63 | github.com/mitchellh/go-wordwrap v1.0.1 // indirect 64 | github.com/moby/spdystream v0.2.0 // indirect 65 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 66 | github.com/modern-go/reflect2 v1.0.2 // indirect 67 | github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect 68 | github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect 69 | github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect 70 | github.com/peterbourgon/diskv v2.0.1+incompatible // indirect 71 | github.com/pkg/errors v0.9.1 // indirect 72 | github.com/pmezard/go-difflib v1.0.0 // indirect 73 | github.com/russross/blackfriday/v2 v2.1.0 // indirect 74 | github.com/xlab/treeprint v1.2.0 // indirect 75 | go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect 76 | golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect 77 | golang.org/x/net v0.38.0 // indirect 78 | golang.org/x/oauth2 v0.17.0 // indirect 79 | golang.org/x/sync v0.12.0 // indirect 80 | golang.org/x/sys v0.31.0 // indirect 81 | golang.org/x/term v0.30.0 // indirect 82 | golang.org/x/text v0.23.0 // indirect 83 | golang.org/x/time v0.3.0 // indirect 84 | google.golang.org/appengine v1.6.8 // indirect 85 | google.golang.org/protobuf v1.33.0 // indirect 86 | gopkg.in/inf.v0 v0.9.1 // indirect 87 | gopkg.in/yaml.v2 v2.4.0 // indirect 88 | gopkg.in/yaml.v3 v3.0.1 // indirect 89 | k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect 90 | sigs.k8s.io/gateway-api v0.7.1 // indirect 91 | sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect 92 | sigs.k8s.io/kustomize/kustomize/v5 v5.0.4-0.20230601165947-6ce0bf390ce3 // indirect 93 | sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect 94 | sigs.k8s.io/yaml v1.4.0 // indirect 95 | ) 96 | -------------------------------------------------------------------------------- /pkg/api/api.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 The Kruise Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package api 18 | 19 | import ( 20 | kruiseappsv1alpha1 "github.com/openkruise/kruise-api/apps/v1alpha1" 21 | kruiseappsv1beta1 "github.com/openkruise/kruise-api/apps/v1beta1" 22 | kruisepolicyv1alpha1 "github.com/openkruise/kruise-api/policy/v1alpha1" 23 | kruiserolloutsv1alpha1 "github.com/openkruise/kruise-rollout-api/rollouts/v1alpha1" 24 | kruiserolloutsv1beta1 "github.com/openkruise/kruise-rollout-api/rollouts/v1beta1" 25 | apps "k8s.io/api/apps/v1" 26 | "k8s.io/apimachinery/pkg/runtime" 27 | "k8s.io/apimachinery/pkg/runtime/schema" 28 | "k8s.io/apimachinery/pkg/types" 29 | clientgoscheme "k8s.io/client-go/kubernetes/scheme" 30 | "k8s.io/kubectl/pkg/scheme" 31 | ) 32 | 33 | var ( 34 | DeploymentKind = apps.SchemeGroupVersion.WithKind("Deployment") 35 | CloneSetKind = kruiseappsv1alpha1.SchemeGroupVersion.WithKind("CloneSet") 36 | ) 37 | 38 | var Scheme = scheme.Scheme 39 | 40 | func init() { 41 | _ = clientgoscheme.AddToScheme(Scheme) 42 | _ = kruiseappsv1alpha1.AddToScheme(Scheme) 43 | _ = kruiseappsv1beta1.AddToScheme(Scheme) 44 | _ = kruiserolloutsv1alpha1.AddToScheme(Scheme) 45 | _ = kruiserolloutsv1beta1.AddToScheme(Scheme) 46 | _ = kruisepolicyv1alpha1.AddToScheme(Scheme) 47 | } 48 | 49 | func GetScheme() *runtime.Scheme { 50 | return Scheme 51 | } 52 | 53 | type ResourceRef struct { 54 | // API version of the object. 55 | APIVersion string 56 | // Kind of the object. 57 | Kind string 58 | // Namespace of the object. 59 | Namespace string 60 | // Name of the object. 61 | Name string 62 | } 63 | 64 | func (rf *ResourceRef) GetGroupVersionKind() schema.GroupVersionKind { 65 | return schema.FromAPIVersionAndKind(rf.APIVersion, rf.Kind) 66 | } 67 | 68 | func (rf *ResourceRef) GetNamespacedName() types.NamespacedName { 69 | return types.NamespacedName{Namespace: rf.Namespace, Name: rf.Name} 70 | } 71 | 72 | func NewDeploymentRef(namespace, name string) ResourceRef { 73 | return ResourceRef{ 74 | APIVersion: DeploymentKind.GroupVersion().String(), 75 | Kind: DeploymentKind.Kind, 76 | Namespace: namespace, 77 | Name: name, 78 | } 79 | } 80 | 81 | func NewCloneSetRef(namespace, name string) ResourceRef { 82 | return ResourceRef{ 83 | APIVersion: CloneSetKind.GroupVersion().String(), 84 | Kind: CloneSetKind.Kind, 85 | Namespace: namespace, 86 | Name: name, 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /pkg/cmd/alpha.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 The Kruise Authors. 3 | Copyright 2017 The Kubernetes Authors. 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | */ 17 | 18 | package cmd 19 | 20 | import ( 21 | "github.com/spf13/cobra" 22 | 23 | "k8s.io/cli-runtime/pkg/genericclioptions" 24 | cmdutil "k8s.io/kubectl/pkg/cmd/util" 25 | "k8s.io/kubectl/pkg/util/i18n" 26 | "k8s.io/kubectl/pkg/util/templates" 27 | ) 28 | 29 | // NewCmdAlpha creates a command that acts as an alternate root command for features in alpha 30 | func NewCmdAlpha(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command { 31 | cmd := &cobra.Command{ 32 | Use: "alpha", 33 | Short: i18n.T("Commands for features in alpha"), 34 | Long: templates.LongDesc(i18n.T("These commands correspond to alpha features that are not enabled in Kubernetes clusters by default.")), 35 | } 36 | 37 | // Alpha commands should be added here. As features graduate from alpha they should move 38 | // from here to the CommandGroups defined by NewKubeletCommand() in cmd.go. 39 | 40 | // NewKubeletCommand() will hide the alpha command if it has no subcommands. Overriding 41 | // the help function ensures a reasonable message if someone types the hidden command anyway. 42 | if !cmd.HasAvailableSubCommands() { 43 | cmd.SetHelpFunc(func(*cobra.Command, []string) { 44 | cmd.Println(i18n.T("No alpha commands are available in this version of kubectl")) 45 | }) 46 | } 47 | 48 | return cmd 49 | } 50 | -------------------------------------------------------------------------------- /pkg/cmd/auto_completion.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | 7 | "github.com/spf13/cobra" 8 | ) 9 | 10 | func NewAutoCompleteCommand() *cobra.Command { 11 | var completionCmd = &cobra.Command{ 12 | Use: "completion [bash|zsh|fish|powershell]", 13 | Short: "Generate completion script", 14 | Long: `To load completions: 15 | 16 | Bash: 17 | $ source <(kubectl-kruise completion bash) 18 | 19 | Zsh: 20 | # If shell completion is not already enabled in your environment, 21 | # you will need to enable it. You can execute the following once: 22 | $ echo "autoload -U compinit; compinit" >> ~/.zshrc 23 | 24 | # To load completions for each session, execute once: 25 | $ kubectl-kruise completion zsh > "${fpath[1]}/_kubectl-kruise" 26 | 27 | Fish: 28 | $ kubectl-kruise completion fish | source 29 | 30 | PowerShell: 31 | PS> kubectl-kruise completion powershell | Out-String | Invoke-Expression 32 | `, 33 | RunE: func(cmd *cobra.Command, args []string) error { 34 | switch args[0] { 35 | case "bash": 36 | return cmd.Root().GenBashCompletion(os.Stdout) 37 | case "zsh": 38 | return cmd.Root().GenZshCompletion(os.Stdout) 39 | case "fish": 40 | return cmd.Root().GenFishCompletion(os.Stdout, true) 41 | case "powershell": 42 | return cmd.Root().GenPowerShellCompletion(os.Stdout) 43 | default: 44 | return fmt.Errorf("unsupported shell type %q", args[0]) 45 | } 46 | }, 47 | } 48 | return completionCmd 49 | } 50 | -------------------------------------------------------------------------------- /pkg/cmd/describe/describe.go: -------------------------------------------------------------------------------- 1 | package describe 2 | 3 | /* 4 | Copyright 2021 The Kruise Authors. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | 19 | import ( 20 | "github.com/spf13/cobra" 21 | "k8s.io/cli-runtime/pkg/genericclioptions" 22 | cmdutil "k8s.io/kubectl/pkg/cmd/util" 23 | "k8s.io/kubectl/pkg/util/i18n" 24 | "k8s.io/kubectl/pkg/util/templates" 25 | ) 26 | 27 | var ( 28 | describeLong = templates.LongDesc(i18n.T(` 29 | Show details of a rollout.`)) 30 | 31 | describeExample = templates.Examples(` 32 | # Describe the rollout named rollout-demo 33 | kubectl-kruise describe rollout rollout-demo`) 34 | ) 35 | 36 | // NewCmdRollout returns a Command instance for 'rollout' sub command 37 | func NewCmdDescibe(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command { 38 | cmd := &cobra.Command{ 39 | Use: "describe SUBCOMMAND", 40 | DisableFlagsInUseLine: true, 41 | Short: i18n.T("Show details of a specific resource or group of resources"), 42 | Long: describeLong, 43 | Example: describeExample, 44 | Run: cmdutil.DefaultSubCommandRun(streams.Out), 45 | } 46 | // subcommands 47 | cmd.AddCommand(NewCmdDescribeRollout(f, streams)) 48 | 49 | return cmd 50 | } 51 | -------------------------------------------------------------------------------- /pkg/cmd/generate-docs.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 The Kruise Authors. 3 | Copyright 2017 The Kubernetes Authors. 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | */ 17 | 18 | package cmd 19 | 20 | import ( 21 | "fmt" 22 | "os" 23 | "path/filepath" 24 | 25 | "github.com/spf13/cobra" 26 | "github.com/spf13/cobra/doc" 27 | "k8s.io/cli-runtime/pkg/genericclioptions" 28 | cmdutil "k8s.io/kubectl/pkg/cmd/util" 29 | ) 30 | 31 | var ( 32 | defaultDocDir = "docs" 33 | yamlDir = "yaml" 34 | ) 35 | 36 | func NewCmdGenerateDocs(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command { 37 | cmd := &cobra.Command{ 38 | Use: "generate-docs", 39 | Short: "Generate documentation for kruise", 40 | Long: "Generate documentation for kruise", 41 | Run: func(cmd *cobra.Command, args []string) { 42 | cmdutil.CheckErr(generateDocs(cmd)) 43 | }, 44 | Hidden: true, 45 | } 46 | 47 | cmd.Flags().String("directory", "", "The directory to write the generated docs to") 48 | return cmd 49 | 50 | } 51 | 52 | func generateDocs(cmd *cobra.Command) error { 53 | directory, err := cmd.Flags().GetString("directory") 54 | if err != nil { 55 | return err 56 | } 57 | if directory == "" { 58 | directory = defaultDocDir 59 | } 60 | // Remove the commands from the root command tree 61 | removeCmds(cmd.Root(), []string{"exec", "apply", "wait", "diff", "options", "help", "api-resources", "api-versions", "patch", "plugin", "scale", "replace", "options", "kustomize", "version", "config", "completion"}) 62 | 63 | err = os.MkdirAll(directory, os.ModePerm) 64 | if err != nil { 65 | return err 66 | } 67 | err = os.MkdirAll(filepath.Join(directory, yamlDir), os.ModePerm) 68 | if err != nil { 69 | return err 70 | } 71 | err = doc.GenMarkdownTree(cmd.Root(), directory) 72 | if err != nil { 73 | return err 74 | } 75 | err = doc.GenYamlTree(cmd.Root(), filepath.Join(directory, yamlDir)) 76 | if err != nil { 77 | return err 78 | } 79 | fmt.Println("documentation generated successfully") 80 | return nil 81 | } 82 | 83 | func removeCmds(rootCmd *cobra.Command, cmdsToRemove []string) { 84 | // Keep track of command names to detect duplicates 85 | encountered := make(map[string]bool) 86 | 87 | for _, cmdName := range cmdsToRemove { 88 | for _, cmd := range rootCmd.Commands() { 89 | if cmd.Name() == cmdName { 90 | rootCmd.RemoveCommand(cmd) 91 | } 92 | } 93 | } 94 | 95 | // Remove duplicates 96 | var uniqueCmds []*cobra.Command 97 | for _, cmd := range rootCmd.Commands() { 98 | if encountered[cmd.Name()] { 99 | continue 100 | } 101 | encountered[cmd.Name()] = true 102 | uniqueCmds = append(uniqueCmds, cmd) 103 | } 104 | rootCmd.ResetCommands() 105 | rootCmd.AddCommand(uniqueCmds...) 106 | } 107 | -------------------------------------------------------------------------------- /pkg/cmd/migrate/migrate_cloneset.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 The Kruise Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package migrate 18 | 19 | import ( 20 | "fmt" 21 | "time" 22 | 23 | internalcmdutil "github.com/openkruise/kruise-tools/pkg/cmd/util" 24 | "github.com/openkruise/kruise-tools/pkg/creation" 25 | clonesetcreation "github.com/openkruise/kruise-tools/pkg/creation/cloneset" 26 | "github.com/openkruise/kruise-tools/pkg/migration" 27 | clonesetmigration "github.com/openkruise/kruise-tools/pkg/migration/cloneset" 28 | "github.com/spf13/cobra" 29 | cmdutil "k8s.io/kubectl/pkg/cmd/util" 30 | ) 31 | 32 | func (o *migrateOptions) migrateCloneSet(f cmdutil.Factory, cmd *cobra.Command) error { 33 | cfg, err := f.ToRESTConfig() 34 | if err != nil { 35 | return err 36 | } 37 | 38 | if o.IsCreate { 39 | 40 | ctrl, err := clonesetcreation.NewControl(cfg) 41 | if err != nil { 42 | return err 43 | } 44 | 45 | opts := creation.Options{CopyReplicas: o.IsCopy} 46 | if err := ctrl.Create(o.SrcRef, o.DstRef, opts); err != nil { 47 | return err 48 | } 49 | 50 | internalcmdutil.Print(fmt.Sprintf("Successfully created from %s/%s to %s/%s", o.From, o.SrcName, o.To, o.DstName)) 51 | 52 | } else { 53 | 54 | stopChan := make(chan struct{}) 55 | ctrl, err := clonesetmigration.NewControl(cfg, stopChan) 56 | if err != nil { 57 | return err 58 | } 59 | 60 | opts := migration.Options{} 61 | if o.Replicas >= 0 { 62 | opts.Replicas = &o.Replicas 63 | } 64 | if o.MaxSurge >= 1 { 65 | opts.MaxSurge = &o.MaxSurge 66 | } 67 | if o.TimeoutSeconds > 0 { 68 | opts.TimeoutSeconds = &o.TimeoutSeconds 69 | } 70 | 71 | oldResult, err := ctrl.Submit(o.SrcRef, o.DstRef, opts) 72 | if err != nil { 73 | return err 74 | } 75 | 76 | for { 77 | time.Sleep(time.Second) 78 | newResult, err := ctrl.Query(oldResult.ID) 79 | if err != nil { 80 | return err 81 | } 82 | 83 | if newResult.SrcMigratedReplicas != oldResult.SrcMigratedReplicas || newResult.DstMigratedReplicas != oldResult.DstMigratedReplicas { 84 | internalcmdutil.Print(fmt.Sprintf("Migration progress: %s/%s scale in %d, %s/%s scale out %d", 85 | o.From, o.SrcName, newResult.SrcMigratedReplicas, o.To, o.DstName, newResult.DstMigratedReplicas)) 86 | } 87 | 88 | switch newResult.State { 89 | case migration.MigrateSucceeded: 90 | internalcmdutil.Print(fmt.Sprintf("Successfully migrated %v replicas from %s/%s to %s/%s", 91 | newResult.DstMigratedReplicas, o.From, o.SrcName, o.To, o.DstName)) 92 | return nil 93 | case migration.MigrateFailed: 94 | return fmt.Errorf("failed to migrate: %v", newResult.Message) 95 | } 96 | 97 | oldResult = newResult 98 | } 99 | } 100 | 101 | return nil 102 | } 103 | -------------------------------------------------------------------------------- /pkg/cmd/profiling.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 The Kruise Authors. 3 | Copyright 2017 The Kubernetes Authors. 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | */ 17 | 18 | package cmd 19 | 20 | import ( 21 | "fmt" 22 | "os" 23 | "os/signal" 24 | "runtime" 25 | "runtime/pprof" 26 | 27 | "github.com/spf13/pflag" 28 | ) 29 | 30 | var ( 31 | profileName string 32 | profileOutput string 33 | ) 34 | 35 | func addProfilingFlags(flags *pflag.FlagSet) { 36 | flags.StringVar(&profileName, "profile", "none", "Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex)") 37 | flags.StringVar(&profileOutput, "profile-output", "profile.pprof", "Name of the file to write the profile to") 38 | } 39 | 40 | func initProfiling() error { 41 | switch profileName { 42 | case "none": 43 | return nil 44 | case "cpu": 45 | f, err := os.Create(profileOutput) 46 | if err != nil { 47 | return err 48 | } 49 | err = pprof.StartCPUProfile(f) 50 | if err != nil { 51 | return err 52 | } 53 | // Block and mutex profiles need a call to Set{Block,Mutex}ProfileRate to 54 | // output anything. We choose to sample all events. 55 | case "block": 56 | runtime.SetBlockProfileRate(1) 57 | case "mutex": 58 | runtime.SetMutexProfileFraction(1) 59 | default: 60 | // Check the profile name is valid. 61 | if profile := pprof.Lookup(profileName); profile == nil { 62 | return fmt.Errorf("unknown profile '%s'", profileName) 63 | } 64 | } 65 | 66 | // If the command is interrupted before the end (ctrl-c), flush the 67 | // profiling files 68 | c := make(chan os.Signal, 1) 69 | signal.Notify(c, os.Interrupt) 70 | go func() { 71 | <-c 72 | flushProfiling() 73 | os.Exit(0) 74 | }() 75 | 76 | return nil 77 | } 78 | 79 | func flushProfiling() error { 80 | switch profileName { 81 | case "none": 82 | return nil 83 | case "cpu": 84 | pprof.StopCPUProfile() 85 | case "heap": 86 | runtime.GC() 87 | fallthrough 88 | default: 89 | profile := pprof.Lookup(profileName) 90 | if profile == nil { 91 | return nil 92 | } 93 | f, err := os.Create(profileOutput) 94 | if err != nil { 95 | return err 96 | } 97 | profile.WriteTo(f, 0) 98 | } 99 | 100 | return nil 101 | } 102 | -------------------------------------------------------------------------------- /pkg/cmd/rollout/rollout.go: -------------------------------------------------------------------------------- 1 | package rollout 2 | 3 | /* 4 | Copyright 2021 The Kruise Authors. 5 | Copyright 2016 The Kubernetes Authors. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | import ( 21 | "github.com/lithammer/dedent" 22 | "github.com/spf13/cobra" 23 | "k8s.io/cli-runtime/pkg/genericclioptions" 24 | cmdutil "k8s.io/kubectl/pkg/cmd/util" 25 | "k8s.io/kubectl/pkg/util/i18n" 26 | "k8s.io/kubectl/pkg/util/templates" 27 | ) 28 | 29 | var ( 30 | rolloutLong = templates.LongDesc(i18n.T(` 31 | Manage the rollout of a resource.`) + rolloutValidResources) 32 | 33 | rolloutExample = templates.Examples(` 34 | # Rollback to the previous cloneset 35 | kubectl-kruise rollout undo cloneset/abc 36 | 37 | # Check the rollout status of a daemonset 38 | kubectl-kruise rollout status daemonset/foo`) 39 | 40 | rolloutValidResources = dedent.Dedent(` 41 | 42 | Valid resource types include: 43 | 44 | * deployments 45 | * daemonsets 46 | * statefulsets 47 | * clonesets 48 | * statefulsets.apps.kruise.io 49 | * daemonsets.apps.kruise.io 50 | * rollouts.rollouts.kruise.io 51 | `) 52 | ) 53 | 54 | // NewCmdRollout returns a Command instance for 'rollout' sub command 55 | func NewCmdRollout(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command { 56 | cmd := &cobra.Command{ 57 | Use: "rollout SUBCOMMAND", 58 | DisableFlagsInUseLine: true, 59 | Short: i18n.T("Manage the rollout of a resource"), 60 | Long: rolloutLong, 61 | Example: rolloutExample, 62 | Run: cmdutil.DefaultSubCommandRun(streams.Out), 63 | } 64 | // subcommands 65 | cmd.AddCommand(NewCmdRolloutHistory(f, streams)) 66 | cmd.AddCommand(NewCmdRolloutPause(f, streams)) 67 | cmd.AddCommand(NewCmdRolloutResume(f, streams)) 68 | cmd.AddCommand(NewCmdRolloutUndo(f, streams)) 69 | cmd.AddCommand(NewCmdRolloutStatus(f, streams)) 70 | cmd.AddCommand(NewCmdRolloutRestart(f, streams)) 71 | cmd.AddCommand(NewCmdRolloutApprove(f, streams)) 72 | 73 | return cmd 74 | } 75 | -------------------------------------------------------------------------------- /pkg/cmd/scaledown/scaledown.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 The Kruise Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package scaledown 18 | 19 | import ( 20 | "fmt" 21 | 22 | kruiseappsv1alpha1 "github.com/openkruise/kruise-api/apps/v1alpha1" 23 | internalapi "github.com/openkruise/kruise-tools/pkg/api" 24 | 25 | "github.com/spf13/cobra" 26 | "k8s.io/cli-runtime/pkg/genericclioptions" 27 | "k8s.io/cli-runtime/pkg/printers" 28 | "k8s.io/cli-runtime/pkg/resource" 29 | cmdutil "k8s.io/kubectl/pkg/cmd/util" 30 | "k8s.io/kubectl/pkg/scheme" 31 | ) 32 | 33 | type ScaleDownOptions struct { 34 | Resources []string 35 | Namespace string 36 | EnforceNamespace bool 37 | Pods string 38 | Builder func() *resource.Builder 39 | 40 | PrintFlags *genericclioptions.PrintFlags 41 | PrintObj printers.ResourcePrinterFunc 42 | resource.FilenameOptions 43 | genericclioptions.IOStreams 44 | } 45 | 46 | func newScaleDownOptions(ioStreams genericclioptions.IOStreams) *ScaleDownOptions { 47 | return &ScaleDownOptions{ 48 | PrintFlags: genericclioptions.NewPrintFlags("selective pod deletion").WithTypeSetter(scheme.Scheme), 49 | IOStreams: ioStreams, 50 | } 51 | } 52 | 53 | func NewCmdScaleDown(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { 54 | o := newScaleDownOptions(ioStreams) 55 | 56 | cmd := &cobra.Command{ 57 | Use: "scaledown [CLONESET] --pods [POD1,POD2] -n [NAMESPACE]", 58 | DisableFlagsInUseLine: true, 59 | Short: "Scaledown a cloneset with selective Pods", 60 | Long: "Scaledown a cloneset with selective Pods", 61 | Example: ` 62 | # Scale down 2 with selective pods 63 | kubectl-kruise scaledown CloneSet cloneset-demo --pods pod-1, pod-2 -n default 64 | `, 65 | Run: func(cmd *cobra.Command, args []string) { 66 | cmdutil.CheckErr(o.Complete(f, cmd, args)) 67 | cmdutil.CheckErr(o.Run(f, cmd)) 68 | }, 69 | } 70 | 71 | cmd.Flags().StringVar(&o.Pods, "pods", "", "Name of the pods to delete") 72 | 73 | return cmd 74 | } 75 | 76 | func (o *ScaleDownOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { 77 | namespace, explicitNamespace, err := f.ToRawKubeConfigLoader().Namespace() 78 | if err != nil { 79 | return err 80 | } 81 | o.Namespace = namespace 82 | o.EnforceNamespace = explicitNamespace 83 | o.Resources = args 84 | o.Builder = f.NewBuilder 85 | 86 | printer, err := o.PrintFlags.ToPrinter() 87 | if err != nil { 88 | return err 89 | } 90 | o.PrintObj = printer.PrintObj 91 | if len(o.Pods) == 0 { 92 | return fmt.Errorf("must specify one pod name") 93 | } 94 | 95 | return nil 96 | } 97 | 98 | func (o *ScaleDownOptions) Run(f cmdutil.Factory, cmd *cobra.Command) error { 99 | b := o.Builder(). 100 | WithScheme(internalapi.GetScheme(), scheme.Scheme.PrioritizedVersionsAllGroups()...). 101 | NamespaceParam(o.Namespace).DefaultNamespace(). 102 | FilenameParam(o.EnforceNamespace, &o.FilenameOptions). 103 | ResourceTypeOrNameArgs(true, o.Resources...). 104 | ContinueOnError(). 105 | Latest(). 106 | Flatten() 107 | 108 | infos, err := b.Do().Infos() 109 | if err != nil { 110 | return err 111 | } 112 | if len(infos) == 0 { 113 | return nil 114 | } 115 | 116 | switch infos[0].Object.(type) { 117 | case *kruiseappsv1alpha1.CloneSet: 118 | err = o.ScaleDownCloneSet(infos[0]) 119 | if err != nil { 120 | return err 121 | } 122 | 123 | default: 124 | return fmt.Errorf("currently only supported CloneSet selective pods deletion") 125 | } 126 | 127 | return nil 128 | } 129 | -------------------------------------------------------------------------------- /pkg/cmd/scaledown/scaledown_cloneset.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 The Kruise Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package scaledown 18 | 19 | import ( 20 | "errors" 21 | "fmt" 22 | "strings" 23 | 24 | kruiseappsv1alpha1 "github.com/openkruise/kruise-api/apps/v1alpha1" 25 | "k8s.io/cli-runtime/pkg/resource" 26 | ) 27 | 28 | func (o *ScaleDownOptions) ScaleDownCloneSet(info *resource.Info) error { 29 | cloneSetName := info.Name 30 | obj, err := resource. 31 | NewHelper(info.Client, info.Mapping). 32 | Get(info.Namespace, info.Name) 33 | if err != nil { 34 | return err 35 | } 36 | res := obj.(*kruiseappsv1alpha1.CloneSet) 37 | 38 | podsSlc := strings.Split(o.Pods, ",") 39 | afterReplicas := *res.Spec.Replicas - int32(len(podsSlc)) 40 | res.Spec.ScaleStrategy.PodsToDelete = append(res.Spec.ScaleStrategy.PodsToDelete, podsSlc...) 41 | res.Spec.Replicas = &afterReplicas 42 | 43 | _, err = resource. 44 | NewHelper(info.Client, info.Mapping). 45 | Replace(info.Namespace, info.Name, true, res) 46 | if err != nil { 47 | fmt.Fprintf(o.Out, "%s delete pods %s failed\n", cloneSetName, podsSlc) 48 | return fmt.Errorf("scaledown cloneset %s failed, error is %v", res.Name, err) 49 | } 50 | 51 | fmt.Fprintf(o.Out, "# %s delete pods %s successfully\n", cloneSetName, podsSlc) 52 | if err := o.PrintObj(res, o.Out); err != nil { 53 | return errors.New(err.Error()) 54 | } 55 | 56 | return nil 57 | } 58 | -------------------------------------------------------------------------------- /pkg/cmd/set/env/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Package env provides functions to incorporate environment variables into set env. 18 | package env 19 | -------------------------------------------------------------------------------- /pkg/cmd/set/env/env_parse_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package env 18 | 19 | import ( 20 | "fmt" 21 | "io" 22 | "strings" 23 | ) 24 | 25 | func ExampleIsEnvironmentArgument_true() { 26 | test := "returns=true" 27 | fmt.Println(IsEnvironmentArgument(test)) 28 | // Output: true 29 | } 30 | 31 | func ExampleIsEnvironmentArgument_false() { 32 | test := "returnsfalse" 33 | fmt.Println(IsEnvironmentArgument(test)) 34 | // Output: false 35 | } 36 | 37 | func ExampleIsValidEnvironmentArgument_true() { 38 | test := "wordcharacters=true" 39 | fmt.Println(IsValidEnvironmentArgument(test)) 40 | // Output: true 41 | } 42 | 43 | func ExampleIsValidEnvironmentArgument_false() { 44 | test := "not$word^characters=test" 45 | fmt.Println(IsValidEnvironmentArgument(test)) 46 | // Output: false 47 | } 48 | 49 | func ExampleSplitEnvironmentFromResources() { 50 | args := []string{`resource`, "ENV\\=ARG", `ONE\=MORE`, `DASH-`} 51 | fmt.Println(SplitEnvironmentFromResources(args)) 52 | // Output: [resource] [ENV\=ARG ONE\=MORE DASH-] true 53 | } 54 | 55 | func ExampleParseEnv_good() { 56 | r := strings.NewReader("FROM=READER") 57 | ss := []string{"ENV=VARIABLE", "AND=ANOTHER", "REMOVE-", "-"} 58 | fmt.Println(ParseEnv(ss, r)) 59 | // Output: 60 | // [{ENV VARIABLE nil} {AND ANOTHER nil} {FROM READER nil}] [REMOVE] 61 | } 62 | 63 | func ExampleParseEnv_bad() { 64 | var r io.Reader 65 | bad := []string{"This not in the key=value format."} 66 | fmt.Println(ParseEnv(bad, r)) 67 | // Output: 68 | // [] [] environment variables must be of the form key=value and can only contain letters, numbers, and underscores 69 | } 70 | -------------------------------------------------------------------------------- /pkg/cmd/set/set.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package set 18 | 19 | import ( 20 | "github.com/spf13/cobra" 21 | "k8s.io/cli-runtime/pkg/genericclioptions" 22 | cmdutil "k8s.io/kubectl/pkg/cmd/util" 23 | "k8s.io/kubectl/pkg/util/i18n" 24 | "k8s.io/kubectl/pkg/util/templates" 25 | ) 26 | 27 | var ( 28 | setLong = templates.LongDesc(` 29 | Configure application resources 30 | 31 | These commands help you make changes to existing application resources.`) 32 | ) 33 | 34 | // NewCmdSet returns an initialized Command instance for 'set' sub command 35 | func NewCmdSet(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command { 36 | cmd := &cobra.Command{ 37 | Use: "set SUBCOMMAND", 38 | DisableFlagsInUseLine: true, 39 | Short: i18n.T("Set specific features on objects"), 40 | Long: setLong, 41 | Run: cmdutil.DefaultSubCommandRun(streams.ErrOut), 42 | } 43 | 44 | // add subcommands 45 | cmd.AddCommand(NewCmdImage(f, streams)) 46 | cmd.AddCommand(NewCmdResources(f, streams)) 47 | cmd.AddCommand(NewCmdSelector(f, streams)) 48 | cmd.AddCommand(NewCmdSubject(f, streams)) 49 | cmd.AddCommand(NewCmdServiceAccount(f, streams)) 50 | cmd.AddCommand(NewCmdEnv(f, streams)) 51 | 52 | return cmd 53 | } 54 | -------------------------------------------------------------------------------- /pkg/cmd/set/set_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package set 18 | 19 | import ( 20 | "testing" 21 | 22 | "github.com/spf13/cobra" 23 | 24 | "k8s.io/cli-runtime/pkg/genericclioptions" 25 | clientcmdutil "k8s.io/kubectl/pkg/cmd/util" 26 | ) 27 | 28 | func TestLocalAndDryRunFlags(t *testing.T) { 29 | f := clientcmdutil.NewFactory(genericclioptions.NewTestConfigFlags()) 30 | setCmd := NewCmdSet(f, genericclioptions.NewTestIOStreamsDiscard()) 31 | ensureLocalAndDryRunFlagsOnChildren(t, setCmd, "") 32 | } 33 | 34 | func ensureLocalAndDryRunFlagsOnChildren(t *testing.T, c *cobra.Command, prefix string) { 35 | for _, cmd := range c.Commands() { 36 | name := prefix + cmd.Name() 37 | if localFlag := cmd.Flag("local"); localFlag == nil { 38 | t.Errorf("Command %s does not implement the --local flag", name) 39 | } 40 | if dryRunFlag := cmd.Flag("dry-run"); dryRunFlag == nil { 41 | t.Errorf("Command %s does not implement the --dry-run flag", name) 42 | } 43 | ensureLocalAndDryRunFlagsOnChildren(t, cmd, name+".") 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /pkg/cmd/util/cmd.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 The Kruise Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package util 18 | 19 | import "io" 20 | 21 | // IOStreams provides the standard names for iostreams. This is useful for embedding and for unit testing. 22 | // Inconsistent and different names make it hard to read and review code 23 | type IOStreams struct { 24 | // In think, os.Stdin 25 | In io.Reader 26 | // Out think, os.Stdout 27 | Out io.Writer 28 | // ErrOut think, os.Stderr 29 | ErrOut io.Writer 30 | } 31 | -------------------------------------------------------------------------------- /pkg/cmd/util/factory.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 The Kruise Authors. 3 | Copyright 2016 The Kubernetes Authors. 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | Unless required by applicable law or agreed to in writing, software 9 | distributed under the License is distributed on an "AS IS" BASIS, 10 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | See the License for the specific language governing permissions and 12 | limitations under the License. 13 | */ 14 | 15 | package util 16 | 17 | import ( 18 | "k8s.io/apimachinery/pkg/api/meta" 19 | "k8s.io/cli-runtime/pkg/genericclioptions" 20 | "k8s.io/cli-runtime/pkg/resource" 21 | "k8s.io/client-go/discovery" 22 | "k8s.io/client-go/dynamic" 23 | "k8s.io/client-go/kubernetes" 24 | restclient "k8s.io/client-go/rest" 25 | "k8s.io/kubectl/pkg/util/openapi" 26 | "k8s.io/kubectl/pkg/validation" 27 | ) 28 | 29 | type Factory interface { 30 | genericclioptions.RESTClientGetter 31 | 32 | // DynamicClient returns a dynamic client ready for use 33 | DynamicClient() (dynamic.Interface, error) 34 | 35 | // KubernetesClientSet gives you back an external clientset 36 | KubernetesClientSet() (*kubernetes.Clientset, error) 37 | 38 | // RESTClient Returns a RESTClient for accessing Kubernetes resources or an error. 39 | RESTClient() (*restclient.RESTClient, error) 40 | 41 | // NewBuilder returns an object that assists in loading objects from both disk and the server 42 | // and which implements the common patterns for CLI interactions with generic resources. 43 | NewBuilder() *resource.Builder 44 | 45 | // ClientForMapping Returns a RESTClient for working with the specified RESTMapping or an error. This is intended 46 | // for working with arbitrary resources and is not guaranteed to point to a Kubernetes APIServer. 47 | ClientForMapping(mapping *meta.RESTMapping) (resource.RESTClient, error) 48 | 49 | // UnstructuredClientForMapping Returns a RESTClient for working with Unstructured objects. 50 | UnstructuredClientForMapping(mapping *meta.RESTMapping) (resource.RESTClient, error) 51 | 52 | // Validator Returns a schema that can validate objects stored on disk. 53 | Validator(validate bool) (validation.Schema, error) 54 | // OpenAPISchema returns the parsed openapi schema definition 55 | OpenAPISchema() (openapi.Resources, error) 56 | // OpenAPIGetter returns a getter for the openapi schema document 57 | OpenAPIGetter() discovery.OpenAPISchemaInterface 58 | } 59 | -------------------------------------------------------------------------------- /pkg/cmd/util/factory_client_access.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // this file contains factories with no other dependencies 18 | 19 | package util 20 | 21 | import ( 22 | corev1 "k8s.io/api/core/v1" 23 | "k8s.io/apimachinery/pkg/api/meta" 24 | "k8s.io/cli-runtime/pkg/genericclioptions" 25 | "k8s.io/cli-runtime/pkg/resource" 26 | "k8s.io/client-go/discovery" 27 | "k8s.io/client-go/dynamic" 28 | "k8s.io/client-go/kubernetes" 29 | restclient "k8s.io/client-go/rest" 30 | "k8s.io/client-go/tools/clientcmd" 31 | ) 32 | 33 | type factoryImpl struct { 34 | clientGetter genericclioptions.RESTClientGetter 35 | } 36 | 37 | func NewFactory(clientGetter genericclioptions.RESTClientGetter) *factoryImpl { 38 | if clientGetter == nil { 39 | panic("attempt to instantiate client_access_factory with nil clientGetter") 40 | } 41 | 42 | f := &factoryImpl{ 43 | clientGetter: clientGetter, 44 | } 45 | 46 | return f 47 | } 48 | 49 | func (f *factoryImpl) KubernetesClientSet() (*kubernetes.Clientset, error) { 50 | clientConfig, err := f.ToRESTConfig() 51 | if err != nil { 52 | return nil, err 53 | } 54 | return kubernetes.NewForConfig(clientConfig) 55 | } 56 | 57 | func (f *factoryImpl) DynamicClient() (dynamic.Interface, error) { 58 | clientConfig, err := f.ToRESTConfig() 59 | if err != nil { 60 | return nil, err 61 | } 62 | return dynamic.NewForConfig(clientConfig) 63 | } 64 | 65 | // NewBuilder returns a new resource builder for structured api objects. 66 | func (f *factoryImpl) NewBuilder() *resource.Builder { 67 | return resource.NewBuilder(f.clientGetter) 68 | } 69 | 70 | func (f *factoryImpl) RESTClient() (*restclient.RESTClient, error) { 71 | clientConfig, err := f.ToRESTConfig() 72 | if err != nil { 73 | return nil, err 74 | } 75 | 76 | err = restclient.SetKubernetesDefaults(clientConfig) 77 | if err != nil { 78 | return nil, err 79 | } 80 | return restclient.RESTClientFor(clientConfig) 81 | } 82 | 83 | func (f *factoryImpl) ClientForMapping(mapping *meta.RESTMapping) (resource.RESTClient, error) { 84 | cfg, err := f.clientGetter.ToRESTConfig() 85 | if err != nil { 86 | return nil, err 87 | } 88 | if err := restclient.SetKubernetesDefaults(cfg); err != nil { 89 | return nil, err 90 | } 91 | gvk := mapping.GroupVersionKind 92 | switch gvk.Group { 93 | case corev1.GroupName: 94 | cfg.APIPath = "/api" 95 | default: 96 | cfg.APIPath = "/apis" 97 | } 98 | gv := gvk.GroupVersion() 99 | cfg.GroupVersion = &gv 100 | return restclient.RESTClientFor(cfg) 101 | } 102 | 103 | func (f *factoryImpl) UnstructuredClientForMapping(mapping *meta.RESTMapping) (resource.RESTClient, error) { 104 | cfg, err := f.clientGetter.ToRESTConfig() 105 | if err != nil { 106 | return nil, err 107 | } 108 | if err := restclient.SetKubernetesDefaults(cfg); err != nil { 109 | return nil, err 110 | } 111 | cfg.APIPath = "/apis" 112 | if mapping.GroupVersionKind.Group == corev1.GroupName { 113 | cfg.APIPath = "/api" 114 | } 115 | gv := mapping.GroupVersionKind.GroupVersion() 116 | cfg.ContentConfig = resource.UnstructuredPlusDefaultContentConfig() 117 | cfg.GroupVersion = &gv 118 | return restclient.RESTClientFor(cfg) 119 | } 120 | 121 | func (f *factoryImpl) ToRESTConfig() (*restclient.Config, error) { 122 | return f.clientGetter.ToRESTConfig() 123 | } 124 | 125 | func (f *factoryImpl) ToRESTMapper() (meta.RESTMapper, error) { 126 | return f.clientGetter.ToRESTMapper() 127 | } 128 | 129 | func (f *factoryImpl) ToDiscoveryClient() (discovery.CachedDiscoveryInterface, error) { 130 | return f.clientGetter.ToDiscoveryClient() 131 | } 132 | 133 | func (f *factoryImpl) ToRawKubeConfigLoader() clientcmd.ClientConfig { 134 | return f.clientGetter.ToRawKubeConfigLoader() 135 | } 136 | -------------------------------------------------------------------------------- /pkg/cmd/util/helpers.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 The Kruise Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package util 18 | 19 | import ( 20 | "context" 21 | "fmt" 22 | "os" 23 | "strings" 24 | 25 | "github.com/spf13/cobra" 26 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 27 | "k8s.io/apimachinery/pkg/runtime" 28 | "k8s.io/apimachinery/pkg/types" 29 | "k8s.io/cli-runtime/pkg/resource" 30 | "k8s.io/klog/v2" 31 | ) 32 | 33 | const ( 34 | DefaultErrorExitCode = 1 35 | ) 36 | 37 | func Print(msg string) { 38 | if klog.V(2).Enabled() { 39 | klog.FatalDepth(2, msg) 40 | } 41 | if len(msg) > 0 { 42 | // add newline if needed 43 | if !strings.HasSuffix(msg, "\n") { 44 | msg += "\n" 45 | } 46 | fmt.Fprint(os.Stderr, msg) 47 | } 48 | } 49 | 50 | func fatal(msg string, code int) { 51 | if klog.V(2).Enabled() { 52 | klog.FatalDepth(2, msg) 53 | } 54 | if len(msg) > 0 { 55 | // add newline if needed 56 | if !strings.HasSuffix(msg, "\n") { 57 | msg += "\n" 58 | } 59 | fmt.Fprint(os.Stderr, msg) 60 | } 61 | os.Exit(code) 62 | } 63 | 64 | func CheckErr(err error) { 65 | if err == nil { 66 | return 67 | } 68 | msg := err.Error() 69 | if !strings.HasPrefix(msg, "error: ") { 70 | msg = fmt.Sprintf("error: %s", msg) 71 | } 72 | fatal(msg, DefaultErrorExitCode) 73 | } 74 | 75 | func AddFieldManagerFlagVar(cmd *cobra.Command, p *string, defaultFieldManager string) { 76 | cmd.Flags().StringVar(p, "field-manager", defaultFieldManager, "Name of the manager used to track field ownership.") 77 | } 78 | 79 | func PatchSubResource(RESTClient resource.RESTClient, resource, subResource, namespace, name string, namespaceScoped bool, pt types.PatchType, data []byte, options *metav1.PatchOptions) (runtime.Object, error) { 80 | if options == nil { 81 | options = &metav1.PatchOptions{} 82 | } 83 | return RESTClient.Patch(pt). 84 | NamespaceIfScoped(namespace, namespaceScoped). 85 | Resource(resource). 86 | SubResource(subResource). 87 | Name(name). 88 | VersionedParams(options, metav1.ParameterCodec). 89 | Body(data). 90 | Do(context.TODO()). 91 | Get() 92 | } 93 | -------------------------------------------------------------------------------- /pkg/cmd/util/sidecar_set.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "encoding/json" 5 | 6 | corev1 "k8s.io/api/core/v1" 7 | ) 8 | 9 | const ( 10 | // SidecarSetWorkingHotUpgradeContainer record which hot upgrade container is working currently 11 | SidecarSetWorkingHotUpgradeContainer = "kruise.io/sidecarset-working-hotupgrade-container" 12 | ) 13 | 14 | func GetPodHotUpgradeInfoInAnnotations(pod *corev1.Pod) map[string]string { 15 | hotUpgradeWorkContainer := make(map[string]string) 16 | currentStr, ok := pod.Annotations[SidecarSetWorkingHotUpgradeContainer] 17 | if !ok { 18 | //klog.V(6).Infof("Pod(%s.%s) annotations(%s) Not Found", pod.Namespace, pod.Name, SidecarSetWorkingHotUpgradeContainer) 19 | return hotUpgradeWorkContainer 20 | } 21 | if err := json.Unmarshal([]byte(currentStr), &hotUpgradeWorkContainer); err != nil { 22 | //klog.Errorf("Parse Pod(%s.%s) annotations(%s) Value(%s) failed: %s", pod.Namespace, pod.Name, 23 | // SidecarSetWorkingHotUpgradeContainer, currentStr, err.Error()) 24 | return hotUpgradeWorkContainer 25 | } 26 | return hotUpgradeWorkContainer 27 | } 28 | -------------------------------------------------------------------------------- /pkg/conversion/cloneset_convertion.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 The Kruise Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package conversion 18 | 19 | import ( 20 | appsv1alpha1 "github.com/openkruise/kruise-api/apps/v1alpha1" 21 | apps "k8s.io/api/apps/v1" 22 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 23 | ) 24 | 25 | // Convert Deployment to CloneSet 26 | func DeploymentToCloneSet(deploy *apps.Deployment, dstCloneSetName string) *appsv1alpha1.CloneSet { 27 | // Deep copy first 28 | from := deploy.DeepCopy() 29 | 30 | cs := &appsv1alpha1.CloneSet{ 31 | ObjectMeta: metav1.ObjectMeta{ 32 | Namespace: from.Namespace, 33 | Name: dstCloneSetName, 34 | Labels: from.Labels, 35 | Annotations: from.Annotations, 36 | Finalizers: from.Finalizers, 37 | }, 38 | Spec: appsv1alpha1.CloneSetSpec{ 39 | Replicas: from.Spec.Replicas, 40 | Selector: from.Spec.Selector, 41 | Template: from.Spec.Template, 42 | RevisionHistoryLimit: from.Spec.RevisionHistoryLimit, 43 | MinReadySeconds: from.Spec.MinReadySeconds, 44 | UpdateStrategy: appsv1alpha1.CloneSetUpdateStrategy{ 45 | Type: appsv1alpha1.RecreateCloneSetUpdateStrategyType, 46 | Paused: deploy.Spec.Paused, 47 | }, 48 | }, 49 | } 50 | 51 | if from.Spec.Strategy.RollingUpdate != nil { 52 | if from.Spec.Strategy.RollingUpdate.MaxUnavailable != nil { 53 | cs.Spec.UpdateStrategy.MaxUnavailable = from.Spec.Strategy.RollingUpdate.MaxUnavailable 54 | } 55 | if from.Spec.Strategy.RollingUpdate.MaxSurge != nil { 56 | cs.Spec.UpdateStrategy.MaxSurge = from.Spec.Strategy.RollingUpdate.MaxSurge 57 | } 58 | } 59 | return cs 60 | } 61 | -------------------------------------------------------------------------------- /pkg/creation/api.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 The Kruise Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package creation 18 | 19 | import "github.com/openkruise/kruise-tools/pkg/api" 20 | 21 | type Control interface { 22 | Create(src api.ResourceRef, dst api.ResourceRef, opts Options) error 23 | } 24 | 25 | type Options struct { 26 | CopyReplicas bool 27 | } 28 | -------------------------------------------------------------------------------- /pkg/creation/cloneset/cloneset_creation.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 The Kruise Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package cloneset 18 | 19 | import ( 20 | "context" 21 | "fmt" 22 | 23 | appsv1alpha1 "github.com/openkruise/kruise-api/apps/v1alpha1" 24 | "github.com/openkruise/kruise-tools/pkg/api" 25 | "github.com/openkruise/kruise-tools/pkg/conversion" 26 | "github.com/openkruise/kruise-tools/pkg/creation" 27 | 28 | apps "k8s.io/api/apps/v1" 29 | "k8s.io/apimachinery/pkg/api/errors" 30 | "k8s.io/client-go/rest" 31 | "sigs.k8s.io/controller-runtime/pkg/client" 32 | "sigs.k8s.io/controller-runtime/pkg/client/apiutil" 33 | ) 34 | 35 | type control struct { 36 | client client.Client 37 | } 38 | 39 | func NewControl(cfg *rest.Config) (creation.Control, error) { 40 | scheme := api.GetScheme() 41 | c, err := rest.HTTPClientFor(cfg) 42 | if err != nil { 43 | return nil, err 44 | } 45 | mapper, err := apiutil.NewDynamicRESTMapper(cfg, c) 46 | if err != nil { 47 | return nil, err 48 | } 49 | 50 | ctrl := &control{} 51 | if ctrl.client, err = client.New(cfg, client.Options{Scheme: scheme, Mapper: mapper}); err != nil { 52 | return nil, err 53 | } 54 | 55 | return ctrl, nil 56 | } 57 | 58 | func (c *control) Create(src api.ResourceRef, dst api.ResourceRef, opts creation.Options) error { 59 | if src.GetGroupVersionKind() != api.DeploymentKind { 60 | return fmt.Errorf("invalid src type, currently only support %v", api.DeploymentKind.String()) 61 | } else if dst.GetGroupVersionKind() != api.CloneSetKind { 62 | return fmt.Errorf("invalid dst type, must be %v", api.CloneSetKind.String()) 63 | } 64 | 65 | if err := c.ensureCloneSetNotExists(dst); err != nil { 66 | return err 67 | } 68 | srcDeployment, err := c.getDeployment(src) 69 | if err != nil { 70 | return err 71 | } 72 | 73 | dstCloneSet := conversion.DeploymentToCloneSet(srcDeployment, dst.Name) 74 | return c.client.Create(context.TODO(), dstCloneSet) 75 | } 76 | 77 | func (c *control) getDeployment(ref api.ResourceRef) (*apps.Deployment, error) { 78 | d := &apps.Deployment{} 79 | if err := c.client.Get(context.TODO(), ref.GetNamespacedName(), d); err != nil { 80 | return nil, fmt.Errorf("failed to get %v: %v", ref, err) 81 | } 82 | return d, nil 83 | } 84 | 85 | func (c *control) ensureCloneSetNotExists(ref api.ResourceRef) error { 86 | cs := &appsv1alpha1.CloneSet{} 87 | if err := c.client.Get(context.TODO(), ref.GetNamespacedName(), cs); err == nil { 88 | return fmt.Errorf("cloneset %v already exists", ref.GetNamespacedName()) 89 | } else if !errors.IsNotFound(err) { 90 | return fmt.Errorf("failed to get %v: %v", ref, err) 91 | } 92 | return nil 93 | } 94 | -------------------------------------------------------------------------------- /pkg/internal/apps/kind_visitor.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 The Kruise Authors. 3 | Copyright 2017 The Kubernetes Authors. 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | */ 17 | 18 | package apps 19 | 20 | import ( 21 | "fmt" 22 | 23 | "k8s.io/apimachinery/pkg/runtime/schema" 24 | ) 25 | 26 | // KindVisitor is used with GroupKindElement to call a particular function depending on the 27 | // Kind of a schema.GroupKind 28 | type KindVisitor interface { 29 | VisitDaemonSet(kind GroupKindElement) 30 | VisitDeployment(kind GroupKindElement) 31 | VisitJob(kind GroupKindElement) 32 | VisitPod(kind GroupKindElement) 33 | VisitReplicaSet(kind GroupKindElement) 34 | VisitReplicationController(kind GroupKindElement) 35 | VisitStatefulSet(kind GroupKindElement) 36 | VisitCronJob(kind GroupKindElement) 37 | VisitCloneSet(kind GroupKindElement) 38 | VisitAdvancedStatefulSet(kind GroupKindElement) 39 | VisitAdvancedDaemonSet(kind GroupKindElement) 40 | VisitRollout(kind GroupKindElement) 41 | } 42 | 43 | // GroupKindElement defines a Kubernetes API group elem 44 | type GroupKindElement schema.GroupKind 45 | 46 | // Accept calls the Visit method on visitor that corresponds to elem's Kind 47 | func (elem GroupKindElement) Accept(visitor KindVisitor) error { 48 | switch { 49 | case elem.GroupMatch("apps", "extensions") && elem.Kind == "DaemonSet": 50 | visitor.VisitDaemonSet(elem) 51 | case elem.GroupMatch("apps", "extensions") && elem.Kind == "Deployment": 52 | visitor.VisitDeployment(elem) 53 | case elem.GroupMatch("batch") && elem.Kind == "Job": 54 | visitor.VisitJob(elem) 55 | case elem.GroupMatch("", "core") && elem.Kind == "Pod": 56 | visitor.VisitPod(elem) 57 | case elem.GroupMatch("apps", "extensions") && elem.Kind == "ReplicaSet": 58 | visitor.VisitReplicaSet(elem) 59 | case elem.GroupMatch("", "core") && elem.Kind == "ReplicationController": 60 | visitor.VisitReplicationController(elem) 61 | case elem.GroupMatch("apps") && elem.Kind == "StatefulSet": 62 | visitor.VisitStatefulSet(elem) 63 | case elem.GroupMatch("batch") && elem.Kind == "CronJob": 64 | visitor.VisitCronJob(elem) 65 | case elem.GroupMatch("apps.kruise.io") && elem.Kind == "CloneSet": 66 | visitor.VisitCloneSet(elem) 67 | case elem.GroupMatch("apps.kruise.io") && elem.Kind == "StatefulSet": 68 | visitor.VisitAdvancedStatefulSet(elem) 69 | case elem.GroupMatch("apps.kruise.io") && elem.Kind == "DaemonSet": 70 | visitor.VisitAdvancedDaemonSet(elem) 71 | case elem.GroupMatch("rollouts.kruise.io") && elem.Kind == "Rollout": 72 | visitor.VisitRollout(elem) 73 | default: 74 | return fmt.Errorf("no visitor method exists for %v", elem) 75 | } 76 | return nil 77 | } 78 | 79 | // GroupMatch returns true if and only if elem's group matches one 80 | // of the group arguments 81 | func (elem GroupKindElement) GroupMatch(groups ...string) bool { 82 | for _, g := range groups { 83 | if elem.Group == g { 84 | return true 85 | } 86 | } 87 | return false 88 | } 89 | -------------------------------------------------------------------------------- /pkg/internal/polymorphichelpers/attachablepodforobject.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package polymorphichelpers 18 | 19 | import ( 20 | "fmt" 21 | "sort" 22 | "time" 23 | 24 | corev1 "k8s.io/api/core/v1" 25 | "k8s.io/apimachinery/pkg/runtime" 26 | "k8s.io/cli-runtime/pkg/genericclioptions" 27 | corev1client "k8s.io/client-go/kubernetes/typed/core/v1" 28 | "k8s.io/kubectl/pkg/util/podutils" 29 | ) 30 | 31 | // attachablePodForObject returns the pod to which to attach given an object. 32 | func attachablePodForObject(restClientGetter genericclioptions.RESTClientGetter, object runtime.Object, timeout time.Duration) (*corev1.Pod, error) { 33 | switch t := object.(type) { 34 | case *corev1.Pod: 35 | return t, nil 36 | } 37 | 38 | clientConfig, err := restClientGetter.ToRESTConfig() 39 | if err != nil { 40 | return nil, err 41 | } 42 | clientset, err := corev1client.NewForConfig(clientConfig) 43 | if err != nil { 44 | return nil, err 45 | } 46 | 47 | namespace, selector, err := SelectorsForObject(object) 48 | if err != nil { 49 | return nil, fmt.Errorf("cannot attach to %T: %v", object, err) 50 | } 51 | sortBy := func(pods []*corev1.Pod) sort.Interface { return sort.Reverse(podutils.ActivePods(pods)) } 52 | pod, _, err := GetFirstPod(clientset, namespace, selector.String(), timeout, sortBy) 53 | return pod, err 54 | } 55 | -------------------------------------------------------------------------------- /pkg/internal/polymorphichelpers/canbeexposed.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package polymorphichelpers 18 | 19 | import ( 20 | "fmt" 21 | 22 | kruiseappsv1alpha1 "github.com/openkruise/kruise-api/apps/v1alpha1" 23 | appsv1 "k8s.io/api/apps/v1" 24 | corev1 "k8s.io/api/core/v1" 25 | extensionsv1beta1 "k8s.io/api/extensions/v1beta1" 26 | "k8s.io/apimachinery/pkg/runtime/schema" 27 | ) 28 | 29 | // Check whether the kind of resources could be exposed 30 | func canBeExposed(kind schema.GroupKind) error { 31 | switch kind { 32 | case 33 | corev1.SchemeGroupVersion.WithKind("ReplicationController").GroupKind(), 34 | corev1.SchemeGroupVersion.WithKind("Service").GroupKind(), 35 | corev1.SchemeGroupVersion.WithKind("Pod").GroupKind(), 36 | appsv1.SchemeGroupVersion.WithKind("Deployment").GroupKind(), 37 | appsv1.SchemeGroupVersion.WithKind("ReplicaSet").GroupKind(), 38 | extensionsv1beta1.SchemeGroupVersion.WithKind("Deployment").GroupKind(), 39 | kruiseappsv1alpha1.SchemeGroupVersion.WithKind("CloneSet").GroupKind(), 40 | extensionsv1beta1.SchemeGroupVersion.WithKind("ReplicaSet").GroupKind(): 41 | 42 | // nothing to do here 43 | default: 44 | return fmt.Errorf("cannot expose a %s", kind) 45 | } 46 | return nil 47 | } 48 | -------------------------------------------------------------------------------- /pkg/internal/polymorphichelpers/describe_rollout.go: -------------------------------------------------------------------------------- 1 | package polymorphichelpers 2 | 3 | import ( 4 | rolloutschema "github.com/openkruise/kruise-rollout-api/rollouts/v1beta1" 5 | "k8s.io/apimachinery/pkg/runtime" 6 | ) 7 | 8 | type RolloutViewer func(obj runtime.Unstructured) (*rolloutschema.Rollout, error) 9 | -------------------------------------------------------------------------------- /pkg/internal/polymorphichelpers/getviewer.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2024 The Kruise Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package polymorphichelpers 18 | 19 | import ( 20 | "fmt" 21 | 22 | kruiseappsv1alpha1 "github.com/openkruise/kruise-api/apps/v1alpha1" 23 | kruiseappsv1beta1 "github.com/openkruise/kruise-api/apps/v1beta1" 24 | kruisepolicyv1alpha1 "github.com/openkruise/kruise-api/policy/v1alpha1" 25 | rolloutv1alpha1 "github.com/openkruise/kruise-rollout-api/rollouts/v1alpha1" 26 | rolloutv1beta1 "github.com/openkruise/kruise-rollout-api/rollouts/v1beta1" 27 | "k8s.io/apimachinery/pkg/runtime" 28 | "k8s.io/cli-runtime/pkg/printers" 29 | ) 30 | 31 | // getViewer returns a printer for Kruise resources 32 | func getViewer(obj runtime.Object) (interface{}, error) { 33 | switch obj.(type) { 34 | case *kruiseappsv1alpha1.CloneSet, 35 | *kruiseappsv1beta1.StatefulSet, 36 | *kruiseappsv1alpha1.DaemonSet, 37 | *rolloutv1beta1.Rollout, 38 | *rolloutv1alpha1.Rollout, 39 | *kruiseappsv1alpha1.BroadcastJob, 40 | *kruiseappsv1alpha1.ContainerRecreateRequest, 41 | *kruiseappsv1alpha1.AdvancedCronJob, 42 | *kruiseappsv1alpha1.ResourceDistribution, 43 | *kruiseappsv1alpha1.UnitedDeployment, 44 | *kruiseappsv1alpha1.SidecarSet, 45 | *kruiseappsv1alpha1.PodProbeMarker, 46 | *kruiseappsv1alpha1.ImagePullJob, 47 | *kruisepolicyv1alpha1.PodUnavailableBudget: 48 | return printers.NewTablePrinter(printers.PrintOptions{ 49 | WithKind: true, 50 | WithNamespace: true, 51 | }), nil 52 | default: 53 | return nil, fmt.Errorf("no viewer has been implemented for %T", obj) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /pkg/internal/polymorphichelpers/historyviewer.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package polymorphichelpers 18 | 19 | import ( 20 | kruiseclientsets "github.com/openkruise/kruise-api/client/clientset/versioned" 21 | "k8s.io/apimachinery/pkg/api/meta" 22 | "k8s.io/cli-runtime/pkg/genericclioptions" 23 | "k8s.io/client-go/kubernetes" 24 | ) 25 | 26 | // historyViewer Returns a HistoryViewer for viewing change history 27 | func historyViewer(restClientGetter genericclioptions.RESTClientGetter, mapping *meta.RESTMapping) (HistoryViewer, error) { 28 | clientConfig, err := restClientGetter.ToRESTConfig() 29 | if err != nil { 30 | return nil, err 31 | } 32 | 33 | external, err := kubernetes.NewForConfig(clientConfig) 34 | if err != nil { 35 | return nil, err 36 | } 37 | 38 | kruiseExternal, err := kruiseclientsets.NewForConfig(clientConfig) 39 | if err != nil { 40 | return nil, err 41 | } 42 | 43 | return HistoryViewerFor(mapping.GroupVersionKind.GroupKind(), external, kruiseExternal) 44 | } 45 | -------------------------------------------------------------------------------- /pkg/internal/polymorphichelpers/objectapprover.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 The Kruise Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package polymorphichelpers 18 | 19 | import ( 20 | "errors" 21 | "fmt" 22 | 23 | rolloutsapiv1alpha1 "github.com/openkruise/kruise-rollout-api/rollouts/v1alpha1" 24 | rolloutsapiv1beta1 "github.com/openkruise/kruise-rollout-api/rollouts/v1beta1" 25 | "k8s.io/apimachinery/pkg/runtime" 26 | "k8s.io/kubectl/pkg/scheme" 27 | ) 28 | 29 | // defaultObjectApprover currently only support Kruise Rollout. 30 | func defaultObjectApprover(obj runtime.Object) ([]byte, error) { 31 | switch obj := obj.(type) { 32 | case *rolloutsapiv1alpha1.Rollout: 33 | if obj.Status.CanaryStatus == nil || obj.Status.CanaryStatus.CurrentStepState != rolloutsapiv1alpha1.CanaryStepStatePaused { 34 | return nil, errors.New("does not allow to approve, because current canary state is not 'StepPaused'") 35 | } 36 | obj.Status.CanaryStatus.CurrentStepState = rolloutsapiv1alpha1.CanaryStepStateReady 37 | return runtime.Encode(scheme.Codecs.LegacyCodec(rolloutsapiv1alpha1.GroupVersion), obj) 38 | case *rolloutsapiv1beta1.Rollout: 39 | switch { 40 | case obj.Status.CanaryStatus != nil: 41 | if obj.Status.CanaryStatus.CurrentStepState != rolloutsapiv1beta1.CanaryStepStatePaused { 42 | return nil, fmt.Errorf("does not allow to approve, because current canary state is not '%s'", rolloutsapiv1beta1.CanaryStepStatePaused) 43 | } 44 | obj.Status.CanaryStatus.CurrentStepState = rolloutsapiv1beta1.CanaryStepStateReady 45 | case obj.Status.BlueGreenStatus != nil: 46 | if obj.Status.BlueGreenStatus.CurrentStepState != rolloutsapiv1beta1.CanaryStepStatePaused { 47 | return nil, fmt.Errorf("does not allow to approve, because current blue-green state is not '%s'", rolloutsapiv1beta1.CanaryStepStatePaused) 48 | } 49 | obj.Status.BlueGreenStatus.CurrentStepState = rolloutsapiv1beta1.CanaryStepStateReady 50 | default: 51 | return nil, fmt.Errorf("no need to approve: not in canary or blue-green progress") 52 | } 53 | return runtime.Encode(scheme.Codecs.LegacyCodec(rolloutsapiv1beta1.GroupVersion), obj) 54 | 55 | default: 56 | return nil, fmt.Errorf("approving is not supported") 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /pkg/internal/polymorphichelpers/objectpauser.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 The Kruise Authors. 3 | Copyright 2018 The Kubernetes Authors. 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | */ 17 | 18 | package polymorphichelpers 19 | 20 | import ( 21 | "errors" 22 | "fmt" 23 | 24 | kruiseappsv1alpha1 "github.com/openkruise/kruise-api/apps/v1alpha1" 25 | rolloutsapi "github.com/openkruise/kruise-rollout-api/rollouts/v1beta1" 26 | appsv1 "k8s.io/api/apps/v1" 27 | appsv1beta1 "k8s.io/api/apps/v1beta1" 28 | appsv1beta2 "k8s.io/api/apps/v1beta2" 29 | extensionsv1beta1 "k8s.io/api/extensions/v1beta1" 30 | "k8s.io/apimachinery/pkg/runtime" 31 | "k8s.io/kubectl/pkg/scheme" 32 | ) 33 | 34 | // Currently supports Deployments, CloneSet and Kruise Rollout. 35 | func defaultObjectPauser(obj runtime.Object) ([]byte, error) { 36 | switch obj := obj.(type) { 37 | case *extensionsv1beta1.Deployment: 38 | if obj.Spec.Paused { 39 | return nil, errors.New("is already paused") 40 | } 41 | obj.Spec.Paused = true 42 | return runtime.Encode(scheme.Codecs.LegacyCodec(extensionsv1beta1.SchemeGroupVersion), obj) 43 | 44 | case *appsv1.Deployment: 45 | if obj.Spec.Paused { 46 | return nil, errors.New("is already paused") 47 | } 48 | obj.Spec.Paused = true 49 | return runtime.Encode(scheme.Codecs.LegacyCodec(appsv1.SchemeGroupVersion), obj) 50 | 51 | case *appsv1beta2.Deployment: 52 | if obj.Spec.Paused { 53 | return nil, errors.New("is already paused") 54 | } 55 | obj.Spec.Paused = true 56 | return runtime.Encode(scheme.Codecs.LegacyCodec(appsv1beta2.SchemeGroupVersion), obj) 57 | 58 | case *appsv1beta1.Deployment: 59 | if obj.Spec.Paused { 60 | return nil, errors.New("is already paused") 61 | } 62 | obj.Spec.Paused = true 63 | return runtime.Encode(scheme.Codecs.LegacyCodec(appsv1beta1.SchemeGroupVersion), obj) 64 | 65 | case *kruiseappsv1alpha1.CloneSet: 66 | if obj.Spec.UpdateStrategy.Paused { 67 | return nil, errors.New("is already paused") 68 | } 69 | obj.Spec.UpdateStrategy.Paused = true 70 | return runtime.Encode(scheme.Codecs.LegacyCodec(kruiseappsv1alpha1.SchemeGroupVersion), obj) 71 | 72 | case *rolloutsapi.Rollout: 73 | if obj.Spec.Strategy.Paused { 74 | return nil, errors.New("is already paused") 75 | } 76 | obj.Spec.Strategy.Paused = true 77 | return runtime.Encode(scheme.Codecs.LegacyCodec(rolloutsapi.SchemeGroupVersion), obj) 78 | 79 | default: 80 | return nil, fmt.Errorf("pausing is not supported") 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /pkg/internal/polymorphichelpers/objectresumer.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 The Kruise Authors. 3 | Copyright 2018 The Kubernetes Authors. 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | */ 17 | 18 | package polymorphichelpers 19 | 20 | import ( 21 | "errors" 22 | "fmt" 23 | 24 | kruiseappsv1alpha1 "github.com/openkruise/kruise-api/apps/v1alpha1" 25 | rolloutsapi "github.com/openkruise/kruise-rollout-api/rollouts/v1beta1" 26 | appsv1 "k8s.io/api/apps/v1" 27 | appsv1beta1 "k8s.io/api/apps/v1beta1" 28 | appsv1beta2 "k8s.io/api/apps/v1beta2" 29 | extensionsv1beta1 "k8s.io/api/extensions/v1beta1" 30 | "k8s.io/apimachinery/pkg/runtime" 31 | "k8s.io/kubectl/pkg/scheme" 32 | ) 33 | 34 | // Currently supports Deployments, CloneSet and Kruise Rollout. 35 | func defaultObjectResumer(obj runtime.Object) ([]byte, error) { 36 | switch obj := obj.(type) { 37 | case *extensionsv1beta1.Deployment: 38 | if !obj.Spec.Paused { 39 | return nil, errors.New("is not paused") 40 | } 41 | obj.Spec.Paused = false 42 | return runtime.Encode(scheme.Codecs.LegacyCodec(extensionsv1beta1.SchemeGroupVersion), obj) 43 | 44 | case *appsv1.Deployment: 45 | if !obj.Spec.Paused { 46 | return nil, errors.New("is not paused") 47 | } 48 | obj.Spec.Paused = false 49 | return runtime.Encode(scheme.Codecs.LegacyCodec(appsv1.SchemeGroupVersion), obj) 50 | 51 | case *appsv1beta2.Deployment: 52 | if !obj.Spec.Paused { 53 | return nil, errors.New("is not paused") 54 | } 55 | obj.Spec.Paused = false 56 | return runtime.Encode(scheme.Codecs.LegacyCodec(appsv1beta2.SchemeGroupVersion), obj) 57 | 58 | case *appsv1beta1.Deployment: 59 | if !obj.Spec.Paused { 60 | return nil, errors.New("is not paused") 61 | } 62 | obj.Spec.Paused = false 63 | return runtime.Encode(scheme.Codecs.LegacyCodec(appsv1beta1.SchemeGroupVersion), obj) 64 | 65 | case *kruiseappsv1alpha1.CloneSet: 66 | if !obj.Spec.UpdateStrategy.Paused { 67 | return nil, errors.New("is not paused") 68 | } 69 | obj.Spec.UpdateStrategy.Paused = false 70 | return runtime.Encode(scheme.Codecs.LegacyCodec(kruiseappsv1alpha1.SchemeGroupVersion), obj) 71 | 72 | case *rolloutsapi.Rollout: 73 | if !obj.Spec.Strategy.Paused { 74 | return nil, errors.New("is not paused") 75 | } 76 | obj.Spec.Strategy.Paused = false 77 | return runtime.Encode(scheme.Codecs.LegacyCodec(rolloutsapi.SchemeGroupVersion), obj) 78 | 79 | default: 80 | return nil, fmt.Errorf("resuming is not supported") 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /pkg/internal/polymorphichelpers/portsforobject.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package polymorphichelpers 18 | 19 | import ( 20 | "fmt" 21 | "strconv" 22 | 23 | appsv1 "k8s.io/api/apps/v1" 24 | appsv1beta1 "k8s.io/api/apps/v1beta1" 25 | appsv1beta2 "k8s.io/api/apps/v1beta2" 26 | corev1 "k8s.io/api/core/v1" 27 | extensionsv1beta1 "k8s.io/api/extensions/v1beta1" 28 | "k8s.io/apimachinery/pkg/runtime" 29 | ) 30 | 31 | func portsForObject(object runtime.Object) ([]string, error) { 32 | switch t := object.(type) { 33 | case *corev1.ReplicationController: 34 | return getPorts(t.Spec.Template.Spec), nil 35 | 36 | case *corev1.Pod: 37 | return getPorts(t.Spec), nil 38 | 39 | case *corev1.Service: 40 | return getServicePorts(t.Spec), nil 41 | 42 | case *extensionsv1beta1.Deployment: 43 | return getPorts(t.Spec.Template.Spec), nil 44 | case *appsv1.Deployment: 45 | return getPorts(t.Spec.Template.Spec), nil 46 | case *appsv1beta2.Deployment: 47 | return getPorts(t.Spec.Template.Spec), nil 48 | case *appsv1beta1.Deployment: 49 | return getPorts(t.Spec.Template.Spec), nil 50 | 51 | case *extensionsv1beta1.ReplicaSet: 52 | return getPorts(t.Spec.Template.Spec), nil 53 | case *appsv1.ReplicaSet: 54 | return getPorts(t.Spec.Template.Spec), nil 55 | case *appsv1beta2.ReplicaSet: 56 | return getPorts(t.Spec.Template.Spec), nil 57 | default: 58 | return nil, fmt.Errorf("cannot extract ports from %T", object) 59 | } 60 | } 61 | 62 | func getPorts(spec corev1.PodSpec) []string { 63 | result := []string{} 64 | for _, container := range spec.Containers { 65 | for _, port := range container.Ports { 66 | result = append(result, strconv.Itoa(int(port.ContainerPort))) 67 | } 68 | } 69 | return result 70 | } 71 | 72 | func getServicePorts(spec corev1.ServiceSpec) []string { 73 | result := []string{} 74 | for _, servicePort := range spec.Ports { 75 | result = append(result, strconv.Itoa(int(servicePort.Port))) 76 | } 77 | return result 78 | } 79 | -------------------------------------------------------------------------------- /pkg/internal/polymorphichelpers/protocolsforobject.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 The Kruise Authors. 3 | Copyright 2018 The Kubernetes Authors. 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | */ 17 | 18 | package polymorphichelpers 19 | 20 | import ( 21 | "fmt" 22 | "strconv" 23 | 24 | kruiseappsv1alpha1 "github.com/openkruise/kruise-api/apps/v1alpha1" 25 | appsv1 "k8s.io/api/apps/v1" 26 | appsv1beta1 "k8s.io/api/apps/v1beta1" 27 | appsv1beta2 "k8s.io/api/apps/v1beta2" 28 | corev1 "k8s.io/api/core/v1" 29 | extensionsv1beta1 "k8s.io/api/extensions/v1beta1" 30 | "k8s.io/apimachinery/pkg/runtime" 31 | ) 32 | 33 | func protocolsForObject(object runtime.Object) (map[string]string, error) { 34 | // TODO: replace with a swagger schema based approach (identify pod selector via schema introspection) 35 | switch t := object.(type) { 36 | case *corev1.ReplicationController: 37 | return getProtocols(t.Spec.Template.Spec), nil 38 | 39 | case *corev1.Pod: 40 | return getProtocols(t.Spec), nil 41 | 42 | case *corev1.Service: 43 | return getServiceProtocols(t.Spec), nil 44 | 45 | case *extensionsv1beta1.Deployment: 46 | return getProtocols(t.Spec.Template.Spec), nil 47 | case *appsv1.Deployment: 48 | return getProtocols(t.Spec.Template.Spec), nil 49 | case *appsv1beta2.Deployment: 50 | return getProtocols(t.Spec.Template.Spec), nil 51 | case *appsv1beta1.Deployment: 52 | return getProtocols(t.Spec.Template.Spec), nil 53 | 54 | case *extensionsv1beta1.ReplicaSet: 55 | return getProtocols(t.Spec.Template.Spec), nil 56 | case *appsv1.ReplicaSet: 57 | return getProtocols(t.Spec.Template.Spec), nil 58 | case *appsv1beta2.ReplicaSet: 59 | return getProtocols(t.Spec.Template.Spec), nil 60 | 61 | case *kruiseappsv1alpha1.CloneSet: 62 | return getProtocols(t.Spec.Template.Spec), nil 63 | 64 | default: 65 | return nil, fmt.Errorf("cannot extract protocols from %T", object) 66 | } 67 | } 68 | 69 | func getProtocols(spec corev1.PodSpec) map[string]string { 70 | result := make(map[string]string) 71 | for _, container := range spec.Containers { 72 | for _, port := range container.Ports { 73 | // Empty protocol must be defaulted (TCP) 74 | if len(port.Protocol) == 0 { 75 | port.Protocol = corev1.ProtocolTCP 76 | } 77 | result[strconv.Itoa(int(port.ContainerPort))] = string(port.Protocol) 78 | } 79 | } 80 | return result 81 | } 82 | 83 | // Extracts the protocols exposed by a service from the given service spec. 84 | func getServiceProtocols(spec corev1.ServiceSpec) map[string]string { 85 | result := make(map[string]string) 86 | for _, servicePort := range spec.Ports { 87 | // Empty protocol must be defaulted (TCP) 88 | if len(servicePort.Protocol) == 0 { 89 | servicePort.Protocol = corev1.ProtocolTCP 90 | } 91 | result[strconv.Itoa(int(servicePort.Port))] = string(servicePort.Protocol) 92 | } 93 | return result 94 | } 95 | -------------------------------------------------------------------------------- /pkg/internal/polymorphichelpers/rollbacker.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package polymorphichelpers 18 | 19 | import ( 20 | kruiseclientsets "github.com/openkruise/kruise-api/client/clientset/versioned" 21 | "k8s.io/apimachinery/pkg/api/meta" 22 | "k8s.io/cli-runtime/pkg/genericclioptions" 23 | "k8s.io/client-go/kubernetes" 24 | ) 25 | 26 | // Returns a Rollbacker for changing the rollback version of the specified RESTMapping type or an error 27 | func rollbacker(restClientGetter genericclioptions.RESTClientGetter, mapping *meta.RESTMapping) (Rollbacker, error) { 28 | clientConfig, err := restClientGetter.ToRESTConfig() 29 | if err != nil { 30 | return nil, err 31 | } 32 | external, err := kubernetes.NewForConfig(clientConfig) 33 | if err != nil { 34 | return nil, err 35 | } 36 | kruiseExternal, err := kruiseclientsets.NewForConfig(clientConfig) 37 | if err != nil { 38 | return nil, err 39 | } 40 | 41 | return RollbackerFor(mapping.GroupVersionKind.GroupKind(), external, kruiseExternal) 42 | } 43 | -------------------------------------------------------------------------------- /pkg/internal/polymorphichelpers/rollout_utils.go: -------------------------------------------------------------------------------- 1 | package polymorphichelpers 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | kruiseappsv1alpha1 "github.com/openkruise/kruise-api/apps/v1alpha1" 8 | corev1 "k8s.io/api/core/v1" 9 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 10 | "k8s.io/apimachinery/pkg/labels" 11 | intstrutil "k8s.io/apimachinery/pkg/util/intstr" 12 | "k8s.io/client-go/kubernetes" 13 | "k8s.io/utils/integer" 14 | ) 15 | 16 | func getPodsByLabelSelector(client kubernetes.Interface, ns string, labelSelector *metav1.LabelSelector) ([]*corev1.Pod, error) { 17 | var podsList []*corev1.Pod 18 | pods, err := client.CoreV1().Pods(ns).List(context.TODO(), metav1.ListOptions{LabelSelector: labels.Set(labelSelector.MatchLabels).String()}) 19 | if err != nil { 20 | return nil, err 21 | } 22 | 23 | for i := range pods.Items { 24 | podsList = append(podsList, &pods.Items[i]) 25 | } 26 | 27 | return podsList, nil 28 | } 29 | 30 | func filterOldNewReadyPodsFromCloneSet(client kubernetes.Interface, clone *kruiseappsv1alpha1.CloneSet) (oldPods []*corev1.Pod, 31 | newNotReadyPods []*corev1.Pod, updatedReadyPods []*corev1.Pod, err error) { 32 | pods, err := getPodsByLabelSelector(client, clone.Namespace, clone.Spec.Selector) 33 | if err != nil { 34 | return 35 | } 36 | 37 | for i := range pods { 38 | if podRevision, ok := pods[i].GetLabels()["controller-revision-hash"]; ok { 39 | if podRevision == clone.Status.UpdateRevision { 40 | if podReady(pods[i]) { 41 | updatedReadyPods = append(updatedReadyPods, pods[i]) 42 | } else { 43 | newNotReadyPods = append(newNotReadyPods, pods[i]) 44 | } 45 | } else { 46 | oldPods = append(oldPods, pods[i]) 47 | } 48 | } 49 | } 50 | return 51 | } 52 | func podReady(p *corev1.Pod) bool { 53 | cs := p.Status.Conditions 54 | for _, c := range cs { 55 | if c.Type == corev1.PodReady { 56 | return c.Status == corev1.ConditionTrue 57 | } 58 | } 59 | return false 60 | } 61 | 62 | func generatePodsInfoForCloneSet(client kubernetes.Interface, clone *kruiseappsv1alpha1.CloneSet) string { 63 | var notReadyPodsSlice, ReadyPodsSlice []string 64 | _, notReadyNewPods, readyNewPods, err := filterOldNewReadyPodsFromCloneSet(client, clone) 65 | if err != nil { 66 | return "" 67 | } 68 | for i := range notReadyNewPods { 69 | notReadyPodsSlice = append(notReadyPodsSlice, notReadyNewPods[i].Name) 70 | } 71 | for j := range readyNewPods { 72 | ReadyPodsSlice = append(ReadyPodsSlice, readyNewPods[j].Name) 73 | } 74 | 75 | return fmt.Sprintf("Updated ready pods: %v\nUpdated not ready pods: %v\n", ReadyPodsSlice, notReadyPodsSlice) 76 | } 77 | 78 | // CalculatePartitionReplicas returns absolute value of partition for workload. This func can solve some 79 | // corner cases about percentage-type partition, such as: 80 | // - if partition > "0%" and replicas > 0, we will ensure at least 1 old pod is reserved. 81 | // - if partition < "100%" and replicas > 1, we will ensure at least 1 pod is upgraded. 82 | func CalculatePartitionReplicas(partition *intstrutil.IntOrString, replicasPointer *int32) (int, error) { 83 | if partition == nil { 84 | return 0, nil 85 | } 86 | 87 | replicas := 1 88 | if replicasPointer != nil { 89 | replicas = int(*replicasPointer) 90 | } 91 | 92 | // 'roundUp=true' will ensure at least 1 old pod is reserved if partition > "0%" and replicas > 0. 93 | pValue, err := intstrutil.GetScaledValueFromIntOrPercent(partition, replicas, true) 94 | if err != nil { 95 | return pValue, err 96 | } 97 | 98 | // if partition < "100%" and replicas > 1, we will ensure at least 1 pod is upgraded. 99 | if replicas > 1 && pValue == replicas && partition.Type == intstrutil.String && partition.StrVal != "100%" { 100 | pValue = replicas - 1 101 | } 102 | 103 | pValue = integer.IntMax(integer.IntMin(pValue, replicas), 0) 104 | return pValue, nil 105 | } 106 | -------------------------------------------------------------------------------- /pkg/internal/polymorphichelpers/rolloutviewer.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package polymorphichelpers 18 | 19 | import ( 20 | "fmt" 21 | 22 | "k8s.io/apimachinery/pkg/runtime" 23 | 24 | rolloutv1alpha1 "github.com/openkruise/kruise-rollout-api/rollouts/v1alpha1" 25 | rolloutv1beta1 "github.com/openkruise/kruise-rollout-api/rollouts/v1beta1" 26 | ) 27 | 28 | // statusViewer returns a StatusViewer for printing rollout status. 29 | func rolloutViewer(obj runtime.Object) (interface{}, error) { 30 | if rollout, ok := obj.(*rolloutv1beta1.Rollout); ok { 31 | return rollout, nil 32 | } 33 | if rollout, ok := obj.(*rolloutv1alpha1.Rollout); ok { 34 | return rollout, nil 35 | } 36 | 37 | return nil, fmt.Errorf("unknown rollout type: %T", obj) 38 | } 39 | -------------------------------------------------------------------------------- /pkg/internal/polymorphichelpers/statusviewer.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package polymorphichelpers 18 | 19 | import ( 20 | "k8s.io/apimachinery/pkg/api/meta" 21 | ) 22 | 23 | // statusViewer returns a StatusViewer for printing rollout status. 24 | func statusViewer(mapping *meta.RESTMapping) (StatusViewer, error) { 25 | return StatusViewerFor(mapping.GroupVersionKind.GroupKind()) 26 | } 27 | -------------------------------------------------------------------------------- /pkg/internal/polymorphichelpers/steps.go: -------------------------------------------------------------------------------- 1 | package polymorphichelpers 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/openkruise/kruise-rollout-api/rollouts/v1beta1" 7 | "k8s.io/apimachinery/pkg/runtime" 8 | "k8s.io/apimachinery/pkg/util/intstr" 9 | "k8s.io/klog/v2" 10 | "k8s.io/kubectl/pkg/scheme" 11 | ) 12 | 13 | func defaultRolloutRollbackGetter(targetStep int32) func(runtime.Object) ([]byte, error) { 14 | return func(obj runtime.Object) ([]byte, error) { 15 | switch rollout := obj.(type) { 16 | case *v1beta1.Rollout: 17 | steps := rollout.Spec.Strategy.GetSteps() 18 | curStep := rollout.Status.CurrentStepIndex 19 | if len(steps) < int(curStep) { 20 | return nil, fmt.Errorf("has %d steps, but current step is too large %d", len(steps), curStep) 21 | } 22 | if curStep <= 1 { 23 | return nil, fmt.Errorf("already at the first step") 24 | } 25 | if targetStep == -1 { 26 | s, err := findPreviousStepWithNoTrafficAndMostReplicas(steps, rollout.Status.CurrentStepIndex) 27 | if err != nil { 28 | return nil, err 29 | } 30 | targetStep = s 31 | } 32 | if targetStep >= rollout.Status.CurrentStepIndex { 33 | return nil, fmt.Errorf("specified step %d is not a previous step (current step is %d)", targetStep, rollout.Status.CurrentStepIndex) 34 | } 35 | style := rollout.Spec.Strategy.GetRollingStyle() 36 | switch style { 37 | case v1beta1.BlueGreenRollingStyle: 38 | rollout.Status.BlueGreenStatus.NextStepIndex = targetStep 39 | default: 40 | // canary and partition 41 | rollout.Status.CanaryStatus.NextStepIndex = targetStep 42 | } 43 | return runtime.Encode(scheme.Codecs.LegacyCodec(v1beta1.GroupVersion), rollout) 44 | default: 45 | return nil, fmt.Errorf("rollback is not supported on given object") 46 | } 47 | } 48 | } 49 | 50 | func findPreviousStepWithNoTrafficAndMostReplicas(steps []v1beta1.CanaryStep, curStep int32) (int32, error) { 51 | maxReplicas := 0 52 | var targetStep int32 = -1 53 | for i := curStep - 2; i >= 0; i-- { 54 | step := steps[i] 55 | if hasTraffic(step) { 56 | klog.V(5).InfoS("has traffic", "step", i+1) 57 | continue 58 | } 59 | replicas, _ := intstr.GetScaledValueFromIntOrPercent(step.Replicas, 100, true) 60 | klog.V(5).InfoS("replicas percent", "percent", replicas, "step", i+1, "obj", step) 61 | if replicas > maxReplicas { 62 | maxReplicas = replicas 63 | targetStep = i + 1 64 | } 65 | } 66 | if targetStep == -1 { 67 | return 0, fmt.Errorf("no previous step with no traffic found") 68 | } 69 | return targetStep, nil 70 | } 71 | 72 | func hasTraffic(step v1beta1.CanaryStep) bool { 73 | if step.Traffic == nil { 74 | return false 75 | } 76 | is := intstr.FromString(*step.Traffic) 77 | trafficPercent, _ := intstr.GetScaledValueFromIntOrPercent(&is, 100, true) 78 | return trafficPercent != 0 79 | } 80 | -------------------------------------------------------------------------------- /pkg/internal/polymorphichelpers/updatepodspec.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package polymorphichelpers 18 | 19 | import ( 20 | "fmt" 21 | 22 | kruiseappsv1alpha1 "github.com/openkruise/kruise-api/apps/v1alpha1" 23 | kruiseappsv1beta1 "github.com/openkruise/kruise-api/apps/v1beta1" 24 | appsv1 "k8s.io/api/apps/v1" 25 | appsv1beta1 "k8s.io/api/apps/v1beta1" 26 | appsv1beta2 "k8s.io/api/apps/v1beta2" 27 | batchv1 "k8s.io/api/batch/v1" 28 | batchv1beta1 "k8s.io/api/batch/v1beta1" 29 | v1 "k8s.io/api/core/v1" 30 | extensionsv1beta1 "k8s.io/api/extensions/v1beta1" 31 | "k8s.io/apimachinery/pkg/runtime" 32 | ) 33 | 34 | func updatePodSpecForObject(obj runtime.Object, fn func(*v1.PodSpec) error) (bool, error) { 35 | switch t := obj.(type) { 36 | 37 | case *kruiseappsv1alpha1.CloneSet: 38 | return true, fn(&t.Spec.Template.Spec) 39 | case *kruiseappsv1beta1.StatefulSet: 40 | return true, fn(&t.Spec.Template.Spec) 41 | case *kruiseappsv1alpha1.DaemonSet: 42 | return true, fn(&t.Spec.Template.Spec) 43 | case *kruiseappsv1alpha1.SidecarSet: 44 | // Because the fn function requires passing v1.PodSpec as a parameter, 45 | // but kruiseappsv1alpha1.SidecarSet only has kruiseappsv1alpha1.SidecarContainer, 46 | // and their types do not match. 47 | // Therefore, passing nil as a placeholder here. 48 | return true, fn(nil) 49 | case *v1.Pod: 50 | return true, fn(&t.Spec) 51 | // ReplicationController 52 | case *v1.ReplicationController: 53 | if t.Spec.Template == nil { 54 | t.Spec.Template = &v1.PodTemplateSpec{} 55 | } 56 | return true, fn(&t.Spec.Template.Spec) 57 | 58 | // Deployment 59 | case *extensionsv1beta1.Deployment: 60 | return true, fn(&t.Spec.Template.Spec) 61 | case *appsv1beta1.Deployment: 62 | return true, fn(&t.Spec.Template.Spec) 63 | case *appsv1beta2.Deployment: 64 | return true, fn(&t.Spec.Template.Spec) 65 | case *appsv1.Deployment: 66 | return true, fn(&t.Spec.Template.Spec) 67 | 68 | // DaemonSet 69 | case *extensionsv1beta1.DaemonSet: 70 | return true, fn(&t.Spec.Template.Spec) 71 | case *appsv1beta2.DaemonSet: 72 | return true, fn(&t.Spec.Template.Spec) 73 | case *appsv1.DaemonSet: 74 | return true, fn(&t.Spec.Template.Spec) 75 | 76 | // ReplicaSet 77 | case *extensionsv1beta1.ReplicaSet: 78 | return true, fn(&t.Spec.Template.Spec) 79 | case *appsv1beta2.ReplicaSet: 80 | return true, fn(&t.Spec.Template.Spec) 81 | case *appsv1.ReplicaSet: 82 | return true, fn(&t.Spec.Template.Spec) 83 | 84 | // StatefulSet 85 | case *appsv1beta1.StatefulSet: 86 | return true, fn(&t.Spec.Template.Spec) 87 | case *appsv1beta2.StatefulSet: 88 | return true, fn(&t.Spec.Template.Spec) 89 | case *appsv1.StatefulSet: 90 | return true, fn(&t.Spec.Template.Spec) 91 | 92 | // Job 93 | case *batchv1.Job: 94 | return true, fn(&t.Spec.Template.Spec) 95 | 96 | // CronJob 97 | case *batchv1beta1.CronJob: 98 | return true, fn(&t.Spec.JobTemplate.Spec.Template.Spec) 99 | 100 | default: 101 | return false, fmt.Errorf("the object is not a pod or does not have a pod template: %T", t) 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /pkg/migration/api.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 The Kruise Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package migration 18 | 19 | import ( 20 | "github.com/openkruise/kruise-tools/pkg/api" 21 | 22 | "k8s.io/apimachinery/pkg/types" 23 | ) 24 | 25 | type Control interface { 26 | Submit(src api.ResourceRef, dst api.ResourceRef, opts Options) (Result, error) 27 | Query(ID types.UID) (Result, error) 28 | } 29 | 30 | type Options struct { 31 | // Specify Replicas that should be migrated. 32 | // Default to migrate all replicas 33 | Replicas *int32 34 | // The maximum number of pods that can be scheduled above the desired number of pods. 35 | // This can not be 0 if MaxUnavailable is 0. 36 | // Defaults to 1. 37 | MaxSurge *int32 38 | // TimeoutSeconds indicates the timeout seconds that migration exceeded. 39 | // Defaults to no limited. 40 | TimeoutSeconds *int32 41 | } 42 | 43 | type Result struct { 44 | ID types.UID 45 | State MigrateState 46 | Message string 47 | 48 | SrcMigratedReplicas int32 49 | DstMigratedReplicas int32 50 | } 51 | 52 | type MigrateState string 53 | 54 | const ( 55 | MigrateExecuting MigrateState = "Executing" 56 | MigrateSucceeded MigrateState = "Succeeded" 57 | MigrateFailed MigrateState = "Failed" 58 | ) 59 | -------------------------------------------------------------------------------- /pkg/migration/cloneset/event_handlers.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 The Kruise Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package cloneset 18 | 19 | import ( 20 | appsv1alpha1 "github.com/openkruise/kruise-api/apps/v1alpha1" 21 | "github.com/openkruise/kruise-tools/pkg/api" 22 | 23 | apps "k8s.io/api/apps/v1" 24 | toolscache "k8s.io/client-go/tools/cache" 25 | ) 26 | 27 | type cloneSetHandler struct { 28 | ctrl *control 29 | } 30 | 31 | var _ toolscache.ResourceEventHandler = &cloneSetHandler{} 32 | 33 | func (ch *cloneSetHandler) OnAdd(obj interface{}, isInInitialList bool) { 34 | d, ok := obj.(*appsv1alpha1.CloneSet) 35 | if !ok { 36 | return 37 | } 38 | ref := api.ResourceRef{ 39 | APIVersion: api.CloneSetKind.GroupVersion().String(), 40 | Kind: api.CloneSetKind.Kind, 41 | Namespace: d.Namespace, 42 | Name: d.Name, 43 | } 44 | 45 | ch.ctrl.RLock() 46 | defer ch.ctrl.RUnlock() 47 | if task, ok := ch.ctrl.executingTasks[ref]; ok { 48 | ch.ctrl.queue.Add(task.ID) 49 | } 50 | } 51 | 52 | func (ch *cloneSetHandler) OnUpdate(oldObj interface{}, newObj interface{}) { 53 | d, ok := newObj.(*appsv1alpha1.CloneSet) 54 | if !ok { 55 | return 56 | } 57 | 58 | ref := api.ResourceRef{ 59 | APIVersion: api.CloneSetKind.GroupVersion().String(), 60 | Kind: api.CloneSetKind.Kind, 61 | Namespace: d.Namespace, 62 | Name: d.Name, 63 | } 64 | 65 | ch.ctrl.RLock() 66 | defer ch.ctrl.RUnlock() 67 | if task, ok := ch.ctrl.executingTasks[ref]; ok { 68 | ch.ctrl.queue.Add(task.ID) 69 | } 70 | } 71 | 72 | func (ch *cloneSetHandler) OnDelete(obj interface{}) { 73 | d, ok := obj.(*appsv1alpha1.CloneSet) 74 | if !ok { 75 | return 76 | } 77 | ref := api.ResourceRef{ 78 | APIVersion: api.CloneSetKind.GroupVersion().String(), 79 | Kind: api.CloneSetKind.Kind, 80 | Namespace: d.Namespace, 81 | Name: d.Name, 82 | } 83 | 84 | ch.ctrl.RLock() 85 | defer ch.ctrl.RUnlock() 86 | if task, ok := ch.ctrl.executingTasks[ref]; ok { 87 | ch.ctrl.queue.Add(task.ID) 88 | } 89 | } 90 | 91 | type deploymentHandler struct { 92 | ctrl *control 93 | } 94 | 95 | var _ toolscache.ResourceEventHandler = &deploymentHandler{} 96 | 97 | func (dh *deploymentHandler) OnAdd(obj interface{}, isInInitialList bool) { 98 | d, ok := obj.(*apps.Deployment) 99 | if !ok { 100 | return 101 | } 102 | ref := api.ResourceRef{ 103 | APIVersion: api.DeploymentKind.GroupVersion().String(), 104 | Kind: api.DeploymentKind.Kind, 105 | Namespace: d.Namespace, 106 | Name: d.Name, 107 | } 108 | 109 | dh.ctrl.RLock() 110 | defer dh.ctrl.RUnlock() 111 | if task, ok := dh.ctrl.executingTasks[ref]; ok { 112 | dh.ctrl.queue.Add(task.ID) 113 | } 114 | } 115 | 116 | func (dh *deploymentHandler) OnUpdate(oldObj interface{}, newObj interface{}) { 117 | d, ok := newObj.(*apps.Deployment) 118 | if !ok { 119 | return 120 | } 121 | 122 | ref := api.ResourceRef{ 123 | APIVersion: api.DeploymentKind.GroupVersion().String(), 124 | Kind: api.DeploymentKind.Kind, 125 | Namespace: d.Namespace, 126 | Name: d.Name, 127 | } 128 | 129 | dh.ctrl.RLock() 130 | defer dh.ctrl.RUnlock() 131 | if task, ok := dh.ctrl.executingTasks[ref]; ok { 132 | dh.ctrl.queue.Add(task.ID) 133 | } 134 | } 135 | 136 | func (dh *deploymentHandler) OnDelete(obj interface{}) { 137 | d, ok := obj.(*apps.Deployment) 138 | if !ok { 139 | return 140 | } 141 | ref := api.ResourceRef{ 142 | APIVersion: api.DeploymentKind.GroupVersion().String(), 143 | Kind: api.DeploymentKind.Kind, 144 | Namespace: d.Namespace, 145 | Name: d.Name, 146 | } 147 | 148 | dh.ctrl.RLock() 149 | defer dh.ctrl.RUnlock() 150 | if task, ok := dh.ctrl.executingTasks[ref]; ok { 151 | dh.ctrl.queue.Add(task.ID) 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /pkg/utils/logs/logs.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 The Kruise Authors. 3 | Copyright 2014 The Kubernetes Authors. 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | */ 17 | 18 | package logs 19 | 20 | import ( 21 | "flag" 22 | "log" 23 | "time" 24 | 25 | "k8s.io/apimachinery/pkg/util/wait" 26 | "k8s.io/klog/v2" 27 | ) 28 | 29 | func init() { 30 | klog.InitFlags(flag.CommandLine) 31 | flag.Set("logtostderr", "true") 32 | } 33 | 34 | // KlogWriter serves as a bridge between the standard log package and the glog package. 35 | type KlogWriter struct{} 36 | 37 | // Write implements the io.Writer interface. 38 | func (writer KlogWriter) Write(data []byte) (n int, err error) { 39 | klog.InfoDepth(1, string(data)) 40 | return len(data), nil 41 | } 42 | 43 | // InitLogs initializes logs the way we want for kubernetes. 44 | func InitLogs() { 45 | log.SetOutput(KlogWriter{}) 46 | log.SetFlags(0) 47 | // The default glog flush interval is one second. 48 | go wait.Until(klog.Flush, time.Second, wait.NeverStop) 49 | } 50 | 51 | // FlushLogs flushes logs immediately. 52 | func FlushLogs() { 53 | klog.Flush() 54 | } 55 | 56 | // NewLogger creates a new log.Logger which sends logs to klog.Info. 57 | func NewLogger(prefix string) *log.Logger { 58 | return log.New(KlogWriter{}, prefix, 0) 59 | } 60 | -------------------------------------------------------------------------------- /pkg/utils/math.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 The Kruise Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package utils 18 | 19 | func Int32Min(a int32, items ...int32) int32 { 20 | min := a 21 | for _, i := range items { 22 | if min > i { 23 | min = i 24 | } 25 | } 26 | return min 27 | } 28 | -------------------------------------------------------------------------------- /pkg/utils/misc.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "strings" 5 | 6 | appsv1 "k8s.io/api/apps/v1" 7 | ) 8 | 9 | const InRolloutProgressingAnnotation = "rollouts.kruise.io/in-progressing" 10 | const DeploymentStrategyAnnotation = "rollouts.kruise.io/deployment-strategy" 11 | 12 | func IsKruiseRolloutsAnnotation(s *string) bool { 13 | if s == nil { 14 | return false 15 | } 16 | const prefix = "rollouts.kruise.io/" 17 | return strings.Contains(*s, prefix) 18 | } 19 | 20 | func InCanaryProgress(deployment *appsv1.Deployment) bool { 21 | if !deployment.Spec.Paused { 22 | return false 23 | } 24 | //if deployment has InRolloutProgressingAnnotation, it is under kruise-rollout control 25 | if _, ok := deployment.Annotations[InRolloutProgressingAnnotation]; !ok { 26 | return false 27 | } 28 | // only if deployment strategy is 'partition', webhook would add DeploymentStrategyAnnotation 29 | if _, ok := deployment.Annotations[DeploymentStrategyAnnotation]; ok { 30 | return false 31 | } 32 | return true 33 | } 34 | -------------------------------------------------------------------------------- /pkg/version/version.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 The Kruise Authors. 3 | Copyright 2019 The Kubernetes Authors. 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | */ 17 | 18 | package version 19 | 20 | import ( 21 | "fmt" 22 | "runtime/debug" 23 | ) 24 | 25 | // Version returns the version of the main module 26 | func Version() string { 27 | info, ok := debug.ReadBuildInfo() 28 | if !ok { 29 | // binary has not been built with module support 30 | return "(unknown)" 31 | } 32 | return info.Main.Version 33 | } 34 | 35 | // Print prints the main module version on stdout. 36 | // 37 | // Print will display either: 38 | // 39 | // - "Version: v0.2.1" when the program has been compiled with: 40 | // 41 | // $ go get github.com/controller-tools/cmd/controller-gen@v0.2.1 42 | // 43 | // Note: go modules requires the usage of semver compatible tags starting with 44 | // 'v' to have nice human-readable versions. 45 | // 46 | // - "Version: (devel)" when the program is compiled from a local git checkout. 47 | // 48 | // - "Version: (unknown)" when not using go modules. 49 | func Print() { 50 | fmt.Printf("Version: %s\n", Version()) 51 | } 52 | -------------------------------------------------------------------------------- /testdata/apply/cm.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | items: 3 | - kind: ConfigMap 4 | apiVersion: v1 5 | metadata: 6 | name: test0 7 | data: 8 | key1: apple 9 | - kind: ConfigMap 10 | apiVersion: v1 11 | metadata: 12 | name: test1 13 | data: 14 | key2: apple 15 | kind: ConfigMapList 16 | metadata: {} 17 | -------------------------------------------------------------------------------- /testdata/apply/deploy-clientside.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: nginx-deployment 5 | labels: 6 | name: nginx 7 | spec: 8 | selector: 9 | matchLabels: 10 | name: nginx 11 | strategy: 12 | type: Recreate 13 | rollingUpdate: null 14 | template: 15 | metadata: 16 | labels: 17 | name: nginx 18 | spec: 19 | containers: 20 | - name: nginx 21 | image: nginx 22 | -------------------------------------------------------------------------------- /testdata/apply/deploy-serverside.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | annotations: 5 | deployment.kubernetes.io/revision: "1" 6 | kubectl.kubernetes.io/last-applied-configuration: '{"kind":"Deployment","apiVersion":"apps/v1","metadata":{"name":"nginx-deployment","creationTimestamp":null,"labels":{"name":"nginx"}},"spec":{"selector":{"matchLabels":{"name":"nginx"}},"template":{"metadata":{"creationTimestamp":null,"labels":{"name":"nginx"}},"spec":{"containers":[{"name":"nginx","image":"nginx","resources":{}}]}},"strategy":{}},"status":{}}' 7 | creationTimestamp: "2016-10-24T22:15:06Z" 8 | generation: 6 9 | labels: 10 | name: nginx 11 | name: nginx-deployment 12 | namespace: test 13 | resourceVersion: "355959" 14 | selfLink: /apis/extensions/v1beta1/namespaces/test/deployments/nginx-deployment 15 | uid: 51ac266e-9a37-11e6-8738-0800270c4edc 16 | spec: 17 | replicas: 1 18 | selector: 19 | matchLabels: 20 | name: nginx 21 | strategy: 22 | rollingUpdate: 23 | maxSurge: 1 24 | maxUnavailable: 1 25 | type: RollingUpdate 26 | template: 27 | metadata: 28 | creationTimestamp: null 29 | labels: 30 | name: nginx 31 | spec: 32 | containers: 33 | - image: nginx 34 | imagePullPolicy: Always 35 | name: nginx 36 | resources: {} 37 | terminationMessagePath: /dev/termination-log 38 | dnsPolicy: ClusterFirst 39 | restartPolicy: Always 40 | securityContext: {} 41 | terminationGracePeriodSeconds: 30 42 | status: 43 | availableReplicas: 1 44 | observedGeneration: 6 45 | replicas: 1 46 | updatedReplicas: 1 47 | -------------------------------------------------------------------------------- /testdata/apply/patch.json: -------------------------------------------------------------------------------- 1 | {"apiVersion":"v1","kind":"ReplicationController","metadata":{"labels":{"name":"test-rc"},"name":"test-rc","namespace":"test"},"spec":{"replicas":1,"template":{"metadata":{"labels":{"name":"test-rc"}},"spec":{"containers":[{"image":"nginx","name":"test-rc","ports":[{"containerPort":80}]}]}}}} 2 | -------------------------------------------------------------------------------- /testdata/apply/rc-args.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ReplicationController 3 | metadata: 4 | name: test-rc 5 | labels: 6 | name: test-rc 7 | spec: 8 | replicas: 1 9 | template: 10 | metadata: 11 | labels: 12 | name: test-rc 13 | spec: 14 | containers: 15 | - name: test-rc 16 | image: nginx 17 | args: 18 | - -random_flag=%s@domain.com 19 | ports: 20 | - containerPort: 80 21 | -------------------------------------------------------------------------------- /testdata/apply/rc-lastapplied-args.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ReplicationController 3 | metadata: 4 | annotations: 5 | kubectl.kubernetes.io/last-applied-configuration: | 6 | {"args":"-random_flag=%s@domain.com"} 7 | name: test-rc 8 | labels: 9 | name: test-rc 10 | spec: 11 | replicas: 1 12 | template: 13 | metadata: 14 | labels: 15 | name: test-rc 16 | spec: 17 | containers: 18 | - name: test-rc 19 | image: nginx 20 | args: 21 | - -random_flag=%s@domain.com 22 | ports: 23 | - containerPort: 80 24 | -------------------------------------------------------------------------------- /testdata/apply/rc-lastapplied.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ReplicationController 3 | metadata: 4 | annotations: 5 | kubectl.kubernetes.io/last-applied-configuration: | 6 | {"test":1234} 7 | name: test-rc 8 | labels: 9 | name: test-rc 10 | spec: 11 | replicas: 1 12 | template: 13 | metadata: 14 | labels: 15 | name: test-rc 16 | spec: 17 | containers: 18 | - name: test-rc 19 | image: nginx 20 | ports: 21 | - containerPort: 80 22 | -------------------------------------------------------------------------------- /testdata/apply/rc-no-annotation.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ReplicationController 3 | metadata: 4 | name: no-annotation 5 | labels: 6 | name: no-annotation 7 | spec: 8 | replicas: 1 9 | template: 10 | metadata: 11 | labels: 12 | name: no-annotation 13 | spec: 14 | containers: 15 | - name: no-annotation 16 | image: nginx 17 | ports: 18 | - containerPort: 80 19 | -------------------------------------------------------------------------------- /testdata/apply/rc-noexist.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ReplicationController 3 | metadata: 4 | name: no-exist 5 | labels: 6 | name: no-exist 7 | spec: 8 | replicas: 1 9 | template: 10 | metadata: 11 | labels: 12 | name: no-exist 13 | spec: 14 | containers: 15 | - name: no-exist 16 | image: nginx 17 | ports: 18 | - containerPort: 80 19 | -------------------------------------------------------------------------------- /testdata/apply/rc-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: List 3 | items: 4 | - apiVersion: v1 5 | kind: Service 6 | metadata: 7 | name: test-service 8 | labels: 9 | name: test-service 10 | spec: 11 | ports: 12 | - port: 80 13 | selector: 14 | name: test-rc 15 | - apiVersion: v1 16 | kind: ReplicationController 17 | metadata: 18 | name: test-rc 19 | labels: 20 | name: test-rc 21 | spec: 22 | replicas: 1 23 | template: 24 | metadata: 25 | labels: 26 | name: test-rc 27 | spec: 28 | containers: 29 | - name: test-rc 30 | image: nginx 31 | ports: 32 | - containerPort: 80 33 | -------------------------------------------------------------------------------- /testdata/apply/rc.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "kind": "ReplicationController", 4 | "metadata": { 5 | "name": "test-rc", 6 | "labels": { 7 | "name": "test-rc" 8 | } 9 | }, 10 | "spec": { 11 | "replicas": 1, 12 | "template": { 13 | "metadata": { 14 | "labels": { 15 | "name": "test-rc" 16 | } 17 | }, 18 | "spec": { 19 | "containers": [ 20 | { 21 | "name": "test-rc", 22 | "image": "nginx", 23 | "ports": [ 24 | { 25 | "containerPort": 80 26 | } 27 | ] 28 | } 29 | ] 30 | } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /testdata/apply/rc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ReplicationController 3 | metadata: 4 | name: test-rc 5 | namespace: test 6 | labels: 7 | name: test-rc 8 | spec: 9 | replicas: 1 10 | template: 11 | metadata: 12 | labels: 13 | name: test-rc 14 | spec: 15 | containers: 16 | - name: test-rc 17 | image: nginx 18 | ports: 19 | - containerPort: 80 20 | -------------------------------------------------------------------------------- /testdata/apply/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: test-service 5 | labels: 6 | name: test-service 7 | spec: 8 | ports: 9 | - port: 80 10 | selector: 11 | name: test-rc 12 | -------------------------------------------------------------------------------- /testdata/apply/testdir/rc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ReplicationController 3 | metadata: 4 | name: test-rc 5 | labels: 6 | name: test-rc 7 | spec: 8 | replicas: 1 9 | template: 10 | metadata: 11 | labels: 12 | name: test-rc 13 | spec: 14 | containers: 15 | - name: test-rc 16 | image: nginx 17 | ports: 18 | - containerPort: 80 19 | -------------------------------------------------------------------------------- /testdata/apply/testdir/rc1.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ReplicationController 3 | metadata: 4 | name: test-rc 5 | labels: 6 | name: test-rc 7 | spec: 8 | replicas: 1 9 | template: 10 | metadata: 11 | labels: 12 | name: test-rc 13 | spec: 14 | containers: 15 | - name: test-rc 16 | image: nginx 17 | ports: 18 | - containerPort: 80 19 | -------------------------------------------------------------------------------- /testdata/apply/widget-clientside.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: "unit-test.test.com/v1" 2 | kind: Widget 3 | metadata: 4 | name: "widget" 5 | namespace: "test" 6 | labels: 7 | foo: bar 8 | key: "value" -------------------------------------------------------------------------------- /testdata/apply/widget-serverside.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: "unit-test.test.com/v1" 2 | kind: Widget 3 | metadata: 4 | name: "widget" 5 | namespace: "test" 6 | annotations: 7 | "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"unit-test.test.com/v1\",\"key\":\"value\",\"kind\":\"Widget\",\"metadata\":{\"annotations\":{},\"labels\":{\"foo\":\"bar\"},\"name\":\"widget\",\"namespace\":\"test\"}}\n" 8 | labels: 9 | foo: bar 10 | key: "value" -------------------------------------------------------------------------------- /testdata/controller.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ReplicationController 3 | metadata: 4 | name: cassandra 5 | # The labels will be applied automatically 6 | # from the labels in the pod template, if not set 7 | # labels: 8 | # app: cassandra 9 | spec: 10 | replicas: 2 11 | # The selector will be applied automatically 12 | # from the labels in the pod template, if not set. 13 | # selector: 14 | # app: cassandra 15 | template: 16 | metadata: 17 | labels: 18 | app: cassandra 19 | spec: 20 | containers: 21 | - command: 22 | - /run.sh 23 | resources: 24 | limits: 25 | cpu: 0.5 26 | env: 27 | - name: MAX_HEAP_SIZE 28 | value: 512M 29 | - name: HEAP_NEWSIZE 30 | value: 100M 31 | - name: CASSANDRA_SEED_PROVIDER 32 | value: "io.k8s.cassandra.KubernetesSeedProvider" 33 | - name: POD_NAMESPACE 34 | valueFrom: 35 | fieldRef: 36 | fieldPath: metadata.namespace 37 | - name: POD_IP 38 | valueFrom: 39 | fieldRef: 40 | fieldPath: status.podIP 41 | image: gcr.io/google-samples/cassandra:v13 42 | name: cassandra 43 | ports: 44 | - containerPort: 7000 45 | name: intra-node 46 | - containerPort: 7001 47 | name: tls-intra-node 48 | - containerPort: 7199 49 | name: jmx 50 | - containerPort: 9042 51 | name: cql 52 | volumeMounts: 53 | - mountPath: /cassandra_data 54 | name: data 55 | volumes: 56 | - name: data 57 | emptyDir: {} 58 | 59 | -------------------------------------------------------------------------------- /testdata/frontend-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: frontend 5 | labels: 6 | app: guestbook 7 | tier: frontend 8 | spec: 9 | # if your cluster supports it, uncomment the following to automatically create 10 | # an external load-balanced IP for the frontend service. 11 | # type: LoadBalancer 12 | ports: 13 | - port: 80 14 | selector: 15 | app: guestbook 16 | tier: frontend 17 | -------------------------------------------------------------------------------- /testdata/redis-master-controller.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ReplicationController 3 | metadata: 4 | name: redis-master 5 | labels: 6 | app: redis 7 | role: master 8 | tier: backend 9 | spec: 10 | replicas: 1 11 | template: 12 | metadata: 13 | labels: 14 | app: redis 15 | role: master 16 | tier: backend 17 | spec: 18 | containers: 19 | - name: master 20 | image: docker.io/library/redis:5.0.5-alpine 21 | resources: 22 | requests: 23 | cpu: 100m 24 | memory: 100Mi 25 | ports: 26 | - containerPort: 6379 27 | -------------------------------------------------------------------------------- /testdata/redis-master-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: redis-master 5 | labels: 6 | app: redis 7 | role: master 8 | tier: backend 9 | spec: 10 | ports: 11 | - port: 6379 12 | targetPort: 6379 13 | selector: 14 | app: redis 15 | role: master 16 | tier: backend 17 | -------------------------------------------------------------------------------- /testdata/replace/legacy/frontend-controller.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ReplicationController 3 | metadata: 4 | name: frontend 5 | spec: 6 | replicas: 3 7 | template: 8 | metadata: 9 | labels: 10 | app: guestbook 11 | tier: frontend 12 | spec: 13 | containers: 14 | - name: php-redis 15 | image: gcr.io/google_samples/gb-frontend:v4 16 | resources: 17 | requests: 18 | cpu: 100m 19 | memory: 100Mi 20 | env: 21 | - name: GET_HOSTS_FROM 22 | value: dns 23 | # If your cluster config does not include a dns service, then to 24 | # instead access environment variables to find service host 25 | # info, comment out the 'value: dns' line above, and uncomment the 26 | # line below: 27 | # value: env 28 | ports: 29 | - containerPort: 80 30 | -------------------------------------------------------------------------------- /testdata/replace/legacy/redis-master-controller.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ReplicationController 3 | metadata: 4 | name: redis-master 5 | labels: 6 | app: redis 7 | role: master 8 | tier: backend 9 | spec: 10 | replicas: 1 11 | template: 12 | metadata: 13 | labels: 14 | app: redis 15 | role: master 16 | tier: backend 17 | spec: 18 | containers: 19 | - name: master 20 | image: docker.io/library/redis:5.0.5-alpine 21 | resources: 22 | requests: 23 | cpu: 100m 24 | memory: 100Mi 25 | ports: 26 | - containerPort: 6379 27 | -------------------------------------------------------------------------------- /testdata/replace/legacy/redis-slave-controller.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ReplicationController 3 | metadata: 4 | name: redis-slave 5 | labels: 6 | app: redis 7 | role: slave 8 | tier: backend 9 | spec: 10 | replicas: 2 11 | template: 12 | metadata: 13 | labels: 14 | app: redis 15 | role: slave 16 | tier: backend 17 | spec: 18 | containers: 19 | - name: slave 20 | image: docker.io/library/redis:5.0.5-alpine 21 | # We are only implementing the dns option of: 22 | # https://github.com/kubernetes/examples/blob/97c7ed0eb6555a4b667d2877f965d392e00abc45/guestbook/redis-slave/run.sh 23 | command: [ "redis-server", "--slaveof", "redis-master", "6379" ] 24 | resources: 25 | requests: 26 | cpu: 100m 27 | memory: 100Mi 28 | env: 29 | - name: GET_HOSTS_FROM 30 | value: dns 31 | # If your cluster config does not include a dns service, then to 32 | # instead access an environment variable to find the master 33 | # service's host, comment out the 'value: dns' line above, and 34 | # uncomment the line below: 35 | # value: env 36 | ports: 37 | - containerPort: 6379 38 | -------------------------------------------------------------------------------- /testdata/set/daemon.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: DaemonSet 3 | metadata: 4 | name: prometheus-node-exporter 5 | spec: 6 | selector: 7 | matchLabels: 8 | daemon: prom-node-exp 9 | template: 10 | metadata: 11 | name: prometheus-node-exporter 12 | labels: 13 | daemon: prom-node-exp 14 | spec: 15 | containers: 16 | - name: c 17 | image: prom/prometheus 18 | ports: 19 | - containerPort: 9090 20 | hostPort: 9090 21 | name: serverport 22 | -------------------------------------------------------------------------------- /testdata/set/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: nginx-deployment 5 | labels: 6 | name: nginx-deployment 7 | spec: 8 | replicas: 3 9 | selector: 10 | matchLabels: 11 | name: nginx 12 | template: 13 | metadata: 14 | labels: 15 | name: nginx 16 | spec: 17 | containers: 18 | - name: nginx 19 | image: nginx 20 | ports: 21 | - containerPort: 80 22 | -------------------------------------------------------------------------------- /testdata/set/job.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: Job 3 | metadata: 4 | name: pi 5 | spec: 6 | template: 7 | metadata: 8 | name: pi 9 | spec: 10 | containers: 11 | - name: pi 12 | image: perl 13 | command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] 14 | restartPolicy: Never 15 | 16 | -------------------------------------------------------------------------------- /testdata/set/multi-resource-yaml.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ReplicationController 3 | metadata: 4 | name: first-rc 5 | spec: 6 | replicas: 1 7 | selector: 8 | app: mock 9 | template: 10 | metadata: 11 | labels: 12 | app: mock 13 | spec: 14 | containers: 15 | - name: mock-container 16 | image: registry.k8s.io/pause:3.2 17 | --- 18 | apiVersion: v1 19 | kind: ReplicationController 20 | metadata: 21 | name: second-rc 22 | spec: 23 | replicas: 1 24 | selector: 25 | app: mock 26 | template: 27 | metadata: 28 | labels: 29 | app: mock 30 | spec: 31 | containers: 32 | - name: mock-container 33 | image: registry.k8s.io/pause:3.2 34 | -------------------------------------------------------------------------------- /testdata/set/namespaced-resource.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ReplicationController 3 | metadata: 4 | name: namespaced-rc 5 | namespace: existing-ns 6 | spec: 7 | replicas: 1 8 | selector: 9 | app: mock 10 | template: 11 | metadata: 12 | labels: 13 | app: mock 14 | spec: 15 | containers: 16 | - name: mock-container 17 | image: registry.k8s.io/pause:3.2 18 | -------------------------------------------------------------------------------- /testdata/set/redis-slave.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: ReplicaSet 3 | metadata: 4 | name: redis-slave 5 | labels: 6 | app: redis 7 | role: slave 8 | tier: backend 9 | spec: 10 | # this replicas value is default 11 | # modify it according to your case 12 | replicas: 2 13 | selector: 14 | matchLabels: 15 | app: redis 16 | role: slave 17 | tier: backend 18 | template: 19 | metadata: 20 | labels: 21 | app: redis 22 | role: slave 23 | tier: backend 24 | spec: 25 | containers: 26 | - name: slave 27 | image: docker.io/library/redis:5.0.5-alpine 28 | # We are only implementing the dns option of: 29 | # https://github.com/kubernetes/examples/blob/97c7ed0eb6555a4b667d2877f965d392e00abc45/guestbook/redis-slave/run.sh 30 | command: [ "redis-server", "--slaveof", "redis-master", "6379" ] 31 | resources: 32 | requests: 33 | cpu: 100m 34 | memory: 100Mi 35 | env: 36 | - name: GET_HOSTS_FROM 37 | value: dns 38 | # If your cluster config does not include a dns service, then to 39 | # instead access an environment variable to find the master 40 | # service's host, comment out the 'value: dns' line above, and 41 | # uncomment the line below. 42 | # value: env 43 | ports: 44 | - containerPort: 6379 45 | -------------------------------------------------------------------------------- /testdata/set/replication.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ReplicationController 3 | metadata: 4 | name: nginx 5 | spec: 6 | replicas: 3 7 | selector: 8 | app: nginx 9 | template: 10 | metadata: 11 | name: nginx 12 | labels: 13 | app: nginx 14 | spec: 15 | containers: 16 | - name: nginx 17 | image: nginx 18 | ports: 19 | - containerPort: 80 20 | -------------------------------------------------------------------------------- /version.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | 4 | if [[ -n ${GIT_COMMIT-} ]] || GIT_COMMIT=$(git rev-parse "HEAD^{commit}" 2>/dev/null); then 5 | if [[ -z ${GIT_TREE_STATE-} ]]; then 6 | # Check if the tree is dirty. default to dirty 7 | if git_status=$(git status --porcelain 2>/dev/null) && [[ -z ${git_status} ]]; then 8 | GIT_TREE_STATE="clean" 9 | else 10 | GIT_TREE_STATE="dirty" 11 | fi 12 | fi 13 | 14 | # Use git describe to find the version based on tags. 15 | if [[ -n ${GIT_VERSION-} ]] || GIT_VERSION=$(git describe --tags --abbrev=14 "${GIT_COMMIT}^{commit}" 2>/dev/null); then 16 | # This translates the "git describe" to an actual semver.org 17 | # compatible semantic version that looks something like this: 18 | # v1.0.0-beta.0.10+4c183422345d8f 19 | # 20 | # downstream consumers are expecting it there. 21 | DASHES_IN_VERSION=$(echo "${GIT_VERSION}" | sed "s/[^-]//g") 22 | if [[ "${DASHES_IN_VERSION}" == "---" ]] ; then 23 | # We have distance to subversion (v1.1.0-subversion-1-gCommitHash) 24 | GIT_VERSION=$(echo "${GIT_VERSION}" | sed "s/-\([0-9]\{1,\}\)-g\([0-9a-f]\{14\}\)$/.\1\+\2/") 25 | elif [[ "${DASHES_IN_VERSION}" == "--" ]] ; then 26 | # We have distance to base tag (v1.1.0-1-gCommitHash) 27 | GIT_VERSION=$(echo "${GIT_VERSION}" | sed "s/-g\([0-9a-f]\{14\}\)$/+\1/") 28 | fi 29 | if [[ "${GIT_TREE_STATE}" == "dirty" ]]; then 30 | # git describe --dirty only considers changes to existing files, but 31 | # that is problematic since new untracked .go files affect the build, 32 | # so use our idea of "dirty" from git status instead. 33 | GIT_VERSION+="-dirty" 34 | fi 35 | 36 | # Try to match the "git describe" output to a regex to try to extract 37 | # the "major" and "minor" versions and whether this is the exact tagged 38 | # version or whether the tree is between two tagged versions. 39 | if [[ "${GIT_VERSION}" =~ ^v([0-9]+)\.([0-9]+)(\.[0-9]+)?([-].*)?([+].*)?$ ]]; then 40 | GIT_MAJOR=${BASH_REMATCH[1]} 41 | GIT_MINOR=${BASH_REMATCH[2]} 42 | if [[ -n "${BASH_REMATCH[4]}" ]]; then 43 | GIT_MINOR+="+" 44 | fi 45 | fi 46 | 47 | # If GIT_VERSION is not a valid Semantic Version, then refuse to build. 48 | if ! [[ "${GIT_VERSION}" =~ ^v([0-9]+)\.([0-9]+)(\.[0-9]+)?(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?$ ]]; then 49 | echo "GIT_VERSION should be a valid Semantic Version. Current value: ${GIT_VERSION}" 50 | echo "Please see more details here: https://semver.org" 51 | exit 1 52 | fi 53 | fi 54 | fi 55 | 56 | function add_ldflag() { 57 | local key=${1} 58 | local val=${2} 59 | ldflags+=( 60 | "-X 'k8s.io/component-base/version.${key}=${val}'" 61 | ) 62 | } 63 | 64 | SOURCE_DATE_EPOCH=$(git show -s --format=format:%ct HEAD) 65 | add_ldflag "buildDate" "$(date ${SOURCE_DATE_EPOCH:+"--date=@${SOURCE_DATE_EPOCH}"} -u +'%Y-%m-%dT%H:%M:%SZ')" 66 | 67 | add_ldflag "gitCommit" "${GIT_COMMIT}" 68 | add_ldflag "gitTreeState" "${GIT_TREE_STATE}" 69 | add_ldflag "gitVersion" "${GIT_VERSION}" 70 | add_ldflag "gitMajor" "${GIT_MAJOR}" 71 | add_ldflag "gitMinor" "${GIT_MINOR}" 72 | 73 | # The -ldflags parameter takes a single string, so join the output. 74 | echo "${ldflags[*]-}" 75 | --------------------------------------------------------------------------------