Compare commits

..

1 Commits

Author SHA1 Message Date
Kubernetes Publisher 5388930266 Update dependencies to v0.35.0-alpha.0 tag 2025-08-07 00:12:43 +00:00
23 changed files with 186 additions and 407 deletions

View File

@ -1,8 +1,3 @@
> ⚠️ **This is an automatically published [staged repository](https://git.k8s.io/kubernetes/staging#external-repository-staging-area) for Kubernetes**.
> Pull requests, should be made to the main Kubernetes repository: [https://github.com/kubernetes/kubernetes](https://github.com/kubernetes/kubernetes).
> This repository is read-only for importing, and not used for direct contributions.
> See [CONTRIBUTING.md](./CONTRIBUTING.md) for more details.
# Kubectl # Kubectl
![kubectl logo](./images/kubectl-logo-medium.png) ![kubectl logo](./images/kubectl-logo-medium.png)

33
go.mod
View File

@ -27,17 +27,17 @@ require (
github.com/spf13/pflag v1.0.6 github.com/spf13/pflag v1.0.6
github.com/stretchr/testify v1.10.0 github.com/stretchr/testify v1.10.0
go.yaml.in/yaml/v2 v2.4.2 go.yaml.in/yaml/v2 v2.4.2
golang.org/x/sys v0.33.0 golang.org/x/sys v0.31.0
gopkg.in/evanphx/json-patch.v4 v4.13.0 gopkg.in/evanphx/json-patch.v4 v4.12.0
k8s.io/api v0.0.0-20250830163657-b903cd06836a k8s.io/api v0.35.0-alpha.0
k8s.io/apimachinery v0.0.0-20250830163350-eb2c6e0d1ec4 k8s.io/apimachinery v0.35.0-alpha.0
k8s.io/cli-runtime v0.0.0-20250830171832-3e7914c55f7e k8s.io/cli-runtime v0.35.0-alpha.0
k8s.io/client-go v0.0.0-20250830164107-2a8d855d0d97 k8s.io/client-go v0.35.0-alpha.0
k8s.io/component-base v0.0.0-20250830165319-75dce96cfea7 k8s.io/component-base v0.35.0-alpha.0
k8s.io/component-helpers v0.0.0-20250830165448-f84446610ecc k8s.io/component-helpers v0.35.0-alpha.0
k8s.io/klog/v2 v2.130.1 k8s.io/klog/v2 v2.130.1
k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b
k8s.io/metrics v0.0.0-20250830171643-3daf20f585bd k8s.io/metrics v0.35.0-alpha.0
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 k8s.io/utils v0.0.0-20250604170112-4c0f3b243397
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8
sigs.k8s.io/kustomize/kustomize/v5 v5.7.1 sigs.k8s.io/kustomize/kustomize/v5 v5.7.1
@ -54,7 +54,7 @@ require (
github.com/emicklei/go-restful/v3 v3.12.2 // indirect github.com/emicklei/go-restful/v3 v3.12.2 // indirect
github.com/fxamacker/cbor/v2 v2.9.0 // indirect github.com/fxamacker/cbor/v2 v2.9.0 // indirect
github.com/go-errors/errors v1.4.2 // indirect github.com/go-errors/errors v1.4.2 // indirect
github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/logr v1.4.2 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/swag v0.23.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
@ -76,18 +76,19 @@ require (
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/x448/float16 v0.8.4 // indirect github.com/x448/float16 v0.8.4 // indirect
github.com/xlab/treeprint v1.2.0 // indirect github.com/xlab/treeprint v1.2.0 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/net v0.40.0 // indirect golang.org/x/net v0.38.0 // indirect
golang.org/x/oauth2 v0.30.0 // indirect golang.org/x/oauth2 v0.27.0 // indirect
golang.org/x/sync v0.14.0 // indirect golang.org/x/sync v0.12.0 // indirect
golang.org/x/term v0.32.0 // indirect golang.org/x/term v0.30.0 // indirect
golang.org/x/text v0.25.0 // indirect golang.org/x/text v0.23.0 // indirect
golang.org/x/time v0.9.0 // indirect golang.org/x/time v0.9.0 // indirect
golang.org/x/tools v0.26.0 // indirect golang.org/x/tools v0.26.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect google.golang.org/protobuf v1.36.5 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
sigs.k8s.io/kustomize/api v0.20.1 // indirect sigs.k8s.io/kustomize/api v0.20.1 // indirect

66
go.sum
View File

@ -27,8 +27,8 @@ github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sa
github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
@ -105,6 +105,8 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
@ -151,27 +153,27 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M=
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg= golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ= golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@ -184,36 +186,36 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4=
gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
k8s.io/api v0.0.0-20250830163657-b903cd06836a h1:qS+abmAu2zbGFkbN1vA7LKS07jsXBN1BvTFXFvaGOLI= k8s.io/api v0.35.0-alpha.0 h1:3rghgVk/GvRexcSajck/2xpUwz91B+ZzHGz7qB/jG5o=
k8s.io/api v0.0.0-20250830163657-b903cd06836a/go.mod h1:/IpJMZ4ur2JBuX+kkBc115bnq09sFfUnbuFNrdEe5yc= k8s.io/api v0.35.0-alpha.0/go.mod h1:y19WmC73yDyEO1leoE2dp5eTkP+Lidi/Y49aiL1iQAw=
k8s.io/apimachinery v0.0.0-20250830163350-eb2c6e0d1ec4 h1:ObQoOWhkcPbMnU7PIHT2pkO2wK66CcBn6vD+77CidHM= k8s.io/apimachinery v0.35.0-alpha.0 h1:FrJ3gqYFPIldvKa2KHzmT0lL0gqcRr1GiS6thHvdSGM=
k8s.io/apimachinery v0.0.0-20250830163350-eb2c6e0d1ec4/go.mod h1:fDax9lidUgmNSmBlzUrSISURQmHpeyamBbKX9jGbJ3g= k8s.io/apimachinery v0.35.0-alpha.0/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
k8s.io/cli-runtime v0.0.0-20250830171832-3e7914c55f7e h1:dovWIA2PM0UrJrZdUBV8uy5pExliSBXSFeL0bI6IX6E= k8s.io/cli-runtime v0.35.0-alpha.0 h1:/v7towpkwNCL/Jd/1o9vaOX8GYmAcqxxvOI3a9jq6ms=
k8s.io/cli-runtime v0.0.0-20250830171832-3e7914c55f7e/go.mod h1:/yp9r2rD6AV7MYM/gmb55/6LttRuURzjhgqbfiFQ0Rg= k8s.io/cli-runtime v0.35.0-alpha.0/go.mod h1:10xf4YueIlNnvy4VLCdm1rpKrta9oLir8FccSttSwbE=
k8s.io/client-go v0.0.0-20250830164107-2a8d855d0d97 h1:6ks7Y8CNm05xZ6eyE0db5IDP54PIyRM3aZhpflG55hI= k8s.io/client-go v0.35.0-alpha.0 h1:7GJHPneJbBH/c6dmlWrE8ziwZcGcrpBaRiMH3ugW9S0=
k8s.io/client-go v0.0.0-20250830164107-2a8d855d0d97/go.mod h1:xTpANYjBhGsmpO7Gdw8kMt3yQfciVwyRhbqcq77qwyI= k8s.io/client-go v0.35.0-alpha.0/go.mod h1:6Xh99xpoAzHua3e4q0DOkuOPa4flj8h/uHpa259RKbw=
k8s.io/component-base v0.0.0-20250830165319-75dce96cfea7 h1:JQ/dO+EIXNQ+y3Vlez6PC6r7T+0JvNQWrBx6CD3jKls= k8s.io/component-base v0.35.0-alpha.0 h1:SlkxlHeclVHFlkO8keGc0OFmqVpnt6uZnNxlOEgtZKs=
k8s.io/component-base v0.0.0-20250830165319-75dce96cfea7/go.mod h1:ZZMk2BFRSF/kI9Y5qKmvTk4SJM654XsQ5eJ9cP7mrhw= k8s.io/component-base v0.35.0-alpha.0/go.mod h1:r7SSCr6rm5A2R4zVfy3o1rmg9ngSJ2D8zQRA42are74=
k8s.io/component-helpers v0.0.0-20250830165448-f84446610ecc h1:hEo6RVciD0e0QvtMBgwG9a7fFWb/vkx0Jvw/iQ5i+lQ= k8s.io/component-helpers v0.35.0-alpha.0 h1:e4V2YTqJcWo8ZNWbqiIwx5ACcsfO4LMGTOyJAqAipYE=
k8s.io/component-helpers v0.0.0-20250830165448-f84446610ecc/go.mod h1:TmnJ20kJrkgbEqHgHoUxoTksgIUJNCWtv/QM+yBqCF0= k8s.io/component-helpers v0.35.0-alpha.0/go.mod h1:SupfPkTyG8u3sMaRU4QTQCf0JDPPMBsPxJw6vsLoJnY=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b h1:MloQ9/bdJyIu9lb1PzujOPolHyvO06MXG5TUIj2mNAA= k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b h1:MloQ9/bdJyIu9lb1PzujOPolHyvO06MXG5TUIj2mNAA=
k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts= k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts=
k8s.io/metrics v0.0.0-20250830171643-3daf20f585bd h1:GNGeQ8o/xw8TwhavcXmWrGKHd0ez5TRx8qRqyncbFH4= k8s.io/metrics v0.35.0-alpha.0 h1:sUCq98tDisGoUWFOQK4xK9hxHu2QcZOozktQG08b5gk=
k8s.io/metrics v0.0.0-20250830171643-3daf20f585bd/go.mod h1:OYYW2zJf2TAQHmxQwQgSsP/i40dCZig4RQkw3o3vFPE= k8s.io/metrics v0.35.0-alpha.0/go.mod h1:Mb/8cTTMirlc7HZrq0hjbIftbvTroDfbYZVq3C+hb+0=
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y=
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=

View File

@ -18,7 +18,6 @@ package apiresources
import ( import (
"encoding/json" "encoding/json"
"strings"
"testing" "testing"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -58,8 +57,8 @@ See 'kubectl api-resources -h' for help and examples`
if err == nil { if err == nil {
t.Fatalf("An error was expected but not returned") t.Fatalf("An error was expected but not returned")
} }
expectedError = `unable to match a printer suitable for the output format "foo", allowed formats are:` expectedError = `unable to match a printer suitable for the output format "foo", allowed formats are: json,name,wide,yaml`
if !strings.HasPrefix(err.Error(), expectedError) { if err.Error() != expectedError {
t.Fatalf("Unexpected error: %v\n expected: %v", err, expectedError) t.Fatalf("Unexpected error: %v\n expected: %v", err, expectedError)
} }
} }

View File

@ -42,7 +42,6 @@ import (
"k8s.io/kubectl/pkg/util/completion" "k8s.io/kubectl/pkg/util/completion"
"k8s.io/kubectl/pkg/util/i18n" "k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/templates" "k8s.io/kubectl/pkg/util/templates"
"k8s.io/kubectl/pkg/util/term"
) )
var ( var (
@ -301,9 +300,7 @@ func (o *AttachOptions) Run() error {
sizePlusOne.Height++ sizePlusOne.Height++
// this call spawns a goroutine to monitor/update the terminal size // this call spawns a goroutine to monitor/update the terminal size
sizeQueue = &terminalSizeQueueAdapter{ sizeQueue = t.MonitorSize(&sizePlusOne, size)
delegate: t.MonitorSize(&sizePlusOne, size),
}
} }
o.DisableStderr = true o.DisableStderr = true
@ -360,18 +357,3 @@ func (o *AttachOptions) reattachMessage(containerName string, rawTTY bool) strin
} }
return fmt.Sprintf("Session ended, resume using '%s %s -c %s -i -t' command when the pod is running", o.CommandName, o.Pod.Name, containerName) return fmt.Sprintf("Session ended, resume using '%s %s -c %s -i -t' command when the pod is running", o.CommandName, o.Pod.Name, containerName)
} }
type terminalSizeQueueAdapter struct {
delegate term.TerminalSizeQueue
}
func (a *terminalSizeQueueAdapter) Next() *remotecommand.TerminalSize {
next := a.delegate.Next()
if next == nil {
return nil
}
return &remotecommand.TerminalSize{
Width: next.Width,
Height: next.Height,
}
}

View File

@ -22,7 +22,6 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/klog/v2" "k8s.io/klog/v2"
rbacv1 "k8s.io/api/rbac/v1" rbacv1 "k8s.io/api/rbac/v1"
@ -34,7 +33,6 @@ import (
"k8s.io/cli-runtime/pkg/resource" "k8s.io/cli-runtime/pkg/resource"
corev1client "k8s.io/client-go/kubernetes/typed/core/v1" corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
rbacv1client "k8s.io/client-go/kubernetes/typed/rbac/v1" rbacv1client "k8s.io/client-go/kubernetes/typed/rbac/v1"
"k8s.io/client-go/util/retry"
"k8s.io/component-helpers/auth/rbac/reconciliation" "k8s.io/component-helpers/auth/rbac/reconciliation"
cmdutil "k8s.io/kubectl/pkg/cmd/util" cmdutil "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/scheme" "k8s.io/kubectl/pkg/scheme"
@ -199,9 +197,6 @@ func (o *ReconcileOptions) Validate() error {
// RunReconcile performs the execution // RunReconcile performs the execution
func (o *ReconcileOptions) RunReconcile() error { func (o *ReconcileOptions) RunReconcile() error {
// conflictBackoff retries up to 3 times on conflict, with no delay
conflictBackoff := wait.Backoff{Steps: 3}
return o.Visitor.Visit(func(info *resource.Info, err error) error { return o.Visitor.Visit(func(info *resource.Info, err error) error {
if err != nil { if err != nil {
return err return err
@ -218,14 +213,7 @@ func (o *ReconcileOptions) RunReconcile() error {
Client: o.RBACClient, Client: o.RBACClient,
}, },
} }
var ( result, err := reconcileOptions.Run()
result *reconciliation.ReconcileClusterRoleResult
err error
)
retry.RetryOnConflict(conflictBackoff, func() error {
result, err = reconcileOptions.Run()
return err
})
if err != nil { if err != nil {
return err return err
} }
@ -240,14 +228,7 @@ func (o *ReconcileOptions) RunReconcile() error {
Client: o.RBACClient.ClusterRoles(), Client: o.RBACClient.ClusterRoles(),
}, },
} }
var ( result, err := reconcileOptions.Run()
result *reconciliation.ReconcileClusterRoleResult
err error
)
retry.RetryOnConflict(conflictBackoff, func() error {
result, err = reconcileOptions.Run()
return err
})
if err != nil { if err != nil {
return err return err
} }
@ -263,14 +244,10 @@ func (o *ReconcileOptions) RunReconcile() error {
NamespaceClient: o.NamespaceClient.Namespaces(), NamespaceClient: o.NamespaceClient.Namespaces(),
}, },
} }
var ( result, err := reconcileOptions.Run()
result *reconciliation.ReconcileClusterRoleBindingResult if err != nil {
err error
)
retry.RetryOnConflict(conflictBackoff, func() error {
result, err = reconcileOptions.Run()
return err return err
}) }
o.printResults(result.RoleBinding.GetObject(), result.MissingSubjects, result.ExtraSubjects, nil, nil, result.Operation, result.Protected) o.printResults(result.RoleBinding.GetObject(), result.MissingSubjects, result.ExtraSubjects, nil, nil, result.Operation, result.Protected)
case *rbacv1.ClusterRoleBinding: case *rbacv1.ClusterRoleBinding:
@ -282,14 +259,10 @@ func (o *ReconcileOptions) RunReconcile() error {
Client: o.RBACClient.ClusterRoleBindings(), Client: o.RBACClient.ClusterRoleBindings(),
}, },
} }
var ( result, err := reconcileOptions.Run()
result *reconciliation.ReconcileClusterRoleBindingResult if err != nil {
err error
)
retry.RetryOnConflict(conflictBackoff, func() error {
result, err = reconcileOptions.Run()
return err return err
}) }
o.printResults(result.RoleBinding.GetObject(), result.MissingSubjects, result.ExtraSubjects, nil, nil, result.Operation, result.Protected) o.printResults(result.RoleBinding.GetObject(), result.MissingSubjects, result.ExtraSubjects, nil, nil, result.Operation, result.Protected)
case *rbacv1beta1.Role, case *rbacv1beta1.Role,

View File

@ -129,8 +129,7 @@ func NewCmdConfigSetCredentials(out io.Writer, configAccess clientcmd.ConfigAcce
} }
// NewCmdConfigSetAuthInfo returns a Command instance for 'config set-credentials' sub command // NewCmdConfigSetAuthInfo returns a Command instance for 'config set-credentials' sub command
// // DEPRECATED: Use NewCmdConfigSetCredentials instead
// Deprecated: Use NewCmdConfigSetCredentials instead
func NewCmdConfigSetAuthInfo(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command { func NewCmdConfigSetAuthInfo(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command {
return NewCmdConfigSetCredentials(out, configAccess) return NewCmdConfigSetCredentials(out, configAccess)
} }

View File

@ -106,7 +106,7 @@ func NewCmdCreateJob(f cmdutil.Factory, ioStreams genericiooptions.IOStreams) *c
cmdutil.AddValidateFlags(cmd) cmdutil.AddValidateFlags(cmd)
cmdutil.AddDryRunFlag(cmd) cmdutil.AddDryRunFlag(cmd)
cmd.Flags().StringVar(&o.Image, "image", o.Image, "Image name to run.") cmd.Flags().StringVar(&o.Image, "image", o.Image, "Image name to run.")
cmd.Flags().StringVar(&o.From, "from", o.From, "The name of the resource to create a Job from (only CronJob is supported).") cmd.Flags().StringVar(&o.From, "from", o.From, "The name of the resource to create a Job from (only cronjob is supported).")
cmdutil.AddFieldManagerFlagVar(cmd, &o.FieldManager, "kubectl-create") cmdutil.AddFieldManagerFlagVar(cmd, &o.FieldManager, "kubectl-create")
return cmd return cmd
} }

View File

@ -19,7 +19,6 @@ package drain
import ( import (
"errors" "errors"
"fmt" "fmt"
"time"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -152,11 +151,10 @@ func NewDrainCmdOptions(f cmdutil.Factory, ioStreams genericiooptions.IOStreams)
PrintFlags: genericclioptions.NewPrintFlags("drained").WithTypeSetter(scheme.Scheme), PrintFlags: genericclioptions.NewPrintFlags("drained").WithTypeSetter(scheme.Scheme),
IOStreams: ioStreams, IOStreams: ioStreams,
drainer: &drain.Helper{ drainer: &drain.Helper{
GracePeriodSeconds: -1, GracePeriodSeconds: -1,
EvictErrorRetryDelay: 5 * time.Second, Out: ioStreams.Out,
Out: ioStreams.Out, ErrOut: ioStreams.ErrOut,
ErrOut: ioStreams.ErrOut, ChunkSize: cmdutil.DefaultChunkSize,
ChunkSize: cmdutil.DefaultChunkSize,
}, },
} }
o.drainer.OnPodDeletionOrEvictionFinished = o.onPodDeletionOrEvictionFinished o.drainer.OnPodDeletionOrEvictionFinished = o.onPodDeletionOrEvictionFinished

View File

@ -366,9 +366,7 @@ func (p *ExecOptions) Run() error {
var sizeQueue remotecommand.TerminalSizeQueue var sizeQueue remotecommand.TerminalSizeQueue
if t.Raw { if t.Raw {
// this call spawns a goroutine to monitor/update the terminal size // this call spawns a goroutine to monitor/update the terminal size
sizeQueue = &terminalSizeQueueAdapter{ sizeQueue = t.MonitorSize(t.GetSize())
delegate: t.MonitorSize(t.GetSize()),
}
// unset p.Err if it was previously set because both stdout and stderr go over p.Out when tty is // unset p.Err if it was previously set because both stdout and stderr go over p.Out when tty is
// true // true
@ -405,18 +403,3 @@ func (p *ExecOptions) Run() error {
return nil return nil
} }
type terminalSizeQueueAdapter struct {
delegate term.TerminalSizeQueue
}
func (a *terminalSizeQueueAdapter) Next() *remotecommand.TerminalSize {
next := a.delegate.Next()
if next == nil {
return nil
}
return &remotecommand.TerminalSize{
Width: next.Width,
Height: next.Height,
}
}

View File

@ -206,7 +206,7 @@ func (flags *ExposeServiceFlags) AddFlags(cmd *cobra.Command) {
cmd.Flags().StringVar(&flags.Port, "port", flags.Port, i18n.T("The port that the service should serve on. Copied from the resource being exposed, if unspecified")) cmd.Flags().StringVar(&flags.Port, "port", flags.Port, i18n.T("The port that the service should serve on. Copied from the resource being exposed, if unspecified"))
cmd.Flags().StringVar(&flags.Type, "type", flags.Type, i18n.T("Type for this service: ClusterIP, NodePort, LoadBalancer, or ExternalName. Default is 'ClusterIP'.")) cmd.Flags().StringVar(&flags.Type, "type", flags.Type, i18n.T("Type for this service: ClusterIP, NodePort, LoadBalancer, or ExternalName. Default is 'ClusterIP'."))
cmd.Flags().StringVar(&flags.LoadBalancerIP, "load-balancer-ip", flags.LoadBalancerIP, i18n.T("IP to assign to the LoadBalancer. If empty, an ephemeral IP will be created and used (cloud-provider specific).")) cmd.Flags().StringVar(&flags.LoadBalancerIP, "load-balancer-ip", flags.LoadBalancerIP, i18n.T("IP to assign to the LoadBalancer. If empty, an ephemeral IP will be created and used (cloud-provider specific)."))
cmd.Flags().StringVar(&flags.Selector, "selector", flags.Selector, i18n.T("A label selector to use for this service. Only equality-based selector requirements are supported. If empty (the default) infer the selector from the resource being exposed.")) cmd.Flags().StringVar(&flags.Selector, "selector", flags.Selector, i18n.T("A label selector to use for this service. Only equality-based selector requirements are supported. If empty (the default) infer the selector from the replication controller or replica set.)"))
cmd.Flags().StringVarP(&flags.Labels, "labels", "l", flags.Labels, "Labels to apply to the service created by this call.") cmd.Flags().StringVarP(&flags.Labels, "labels", "l", flags.Labels, "Labels to apply to the service created by this call.")
cmd.Flags().StringVar(&flags.TargetPort, "target-port", flags.TargetPort, i18n.T("Name or number for the port on the container that the service should direct traffic to. Optional.")) cmd.Flags().StringVar(&flags.TargetPort, "target-port", flags.TargetPort, i18n.T("Name or number for the port on the container that the service should direct traffic to. Optional."))
cmd.Flags().StringVar(&flags.ExternalIP, "external-ip", flags.ExternalIP, i18n.T("Additional external IP address (not managed by Kubernetes) to accept for the service. If this IP is routed to a node, the service can be accessed by this IP in addition to its generated service IP.")) cmd.Flags().StringVar(&flags.ExternalIP, "external-ip", flags.ExternalIP, i18n.T("Additional external IP address (not managed by Kubernetes) to accept for the service. If this IP is routed to a node, the service can be accessed by this IP in addition to its generated service IP."))

View File

@ -74,7 +74,7 @@ var (
selectorExample = templates.Examples(` selectorExample = templates.Examples(`
# Set the labels and selector before creating a deployment/service pair # Set the labels and selector before creating a deployment/service pair
kubectl create service clusterip my-svc --clusterip="None" -o yaml --dry-run=client | kubectl set selector --local -f - 'environment=qa' -o yaml | kubectl create -f - kubectl create service clusterip my-svc --clusterip="None" -o yaml --dry-run=client | kubectl set selector --local -f - 'environment=qa' -o yaml | kubectl create -f -
kubectl create deployment my-dep --image=nginx -o yaml --dry-run=client | kubectl label --local -f - environment=qa -o yaml | kubectl create -f -`) kubectl create deployment my-dep -o yaml --dry-run=client | kubectl label --local -f - environment=qa -o yaml | kubectl create -f -`)
) )
// NewSelectorOptions returns an initialized SelectorOptions instance // NewSelectorOptions returns an initialized SelectorOptions instance

View File

@ -46,7 +46,7 @@ import (
var ( var (
waitLong = templates.LongDesc(i18n.T(` waitLong = templates.LongDesc(i18n.T(`
Wait for a specific condition on one or many resources. Experimental: Wait for a specific condition on one or many resources.
The command takes multiple resources and waits until the specified condition The command takes multiple resources and waits until the specified condition
is seen in the Status field of every given resource. is seen in the Status field of every given resource.

View File

@ -3445,15 +3445,61 @@ func (d *ServiceAccountDescriber) Describe(namespace, name string, describerSett
return "", err return "", err
} }
tokens := []corev1.Secret{}
// missingSecrets is the set of all secrets present in the
// serviceAccount but not present in the set of existing secrets.
missingSecrets := sets.New[string]()
secrets := corev1.SecretList{}
err = runtimeresource.FollowContinue(&metav1.ListOptions{Limit: describerSettings.ChunkSize},
func(options metav1.ListOptions) (runtime.Object, error) {
newList, err := d.CoreV1().Secrets(namespace).List(context.TODO(), options)
if err != nil {
return nil, runtimeresource.EnhanceListError(err, options, corev1.ResourceSecrets.String())
}
secrets.Items = append(secrets.Items, newList.Items...)
return newList, nil
})
// errors are tolerated here in order to describe the serviceAccount with all
// of the secrets that it references, even if those secrets cannot be fetched.
if err == nil {
// existingSecrets is the set of all secrets remaining on a
// service account that are not present in the "tokens" slice.
existingSecrets := sets.New[string]()
for _, s := range secrets.Items {
if s.Type == corev1.SecretTypeServiceAccountToken {
name := s.Annotations[corev1.ServiceAccountNameKey]
uid := s.Annotations[corev1.ServiceAccountUIDKey]
if name == serviceAccount.Name && uid == string(serviceAccount.UID) {
tokens = append(tokens, s)
}
}
existingSecrets.Insert(s.Name)
}
for _, s := range serviceAccount.Secrets {
if !existingSecrets.Has(s.Name) {
missingSecrets.Insert(s.Name)
}
}
for _, s := range serviceAccount.ImagePullSecrets {
if !existingSecrets.Has(s.Name) {
missingSecrets.Insert(s.Name)
}
}
}
var events *corev1.EventList var events *corev1.EventList
if describerSettings.ShowEvents { if describerSettings.ShowEvents {
events, _ = searchEvents(d.CoreV1(), serviceAccount, describerSettings.ChunkSize) events, _ = searchEvents(d.CoreV1(), serviceAccount, describerSettings.ChunkSize)
} }
return describeServiceAccount(serviceAccount, events) return describeServiceAccount(serviceAccount, tokens, missingSecrets, events)
} }
func describeServiceAccount(serviceAccount *corev1.ServiceAccount, events *corev1.EventList) (string, error) { func describeServiceAccount(serviceAccount *corev1.ServiceAccount, tokens []corev1.Secret, missingSecrets sets.Set[string], events *corev1.EventList) (string, error) {
return tabbedString(func(out io.Writer) error { return tabbedString(func(out io.Writer) error {
w := NewPrefixWriter(out) w := NewPrefixWriter(out)
w.Write(LEVEL_0, "Name:\t%s\n", serviceAccount.Name) w.Write(LEVEL_0, "Name:\t%s\n", serviceAccount.Name)
@ -3464,16 +3510,28 @@ func describeServiceAccount(serviceAccount *corev1.ServiceAccount, events *corev
var ( var (
emptyHeader = " " emptyHeader = " "
pullHeader = "Image pull secrets:" pullHeader = "Image pull secrets:"
mountHeader = "Mountable secrets: "
tokenHeader = "Tokens: "
pullSecretNames = []string{} pullSecretNames = []string{}
mountSecretNames = []string{}
tokenSecretNames = []string{}
) )
for _, s := range serviceAccount.ImagePullSecrets { for _, s := range serviceAccount.ImagePullSecrets {
pullSecretNames = append(pullSecretNames, s.Name) pullSecretNames = append(pullSecretNames, s.Name)
} }
for _, s := range serviceAccount.Secrets {
mountSecretNames = append(mountSecretNames, s.Name)
}
for _, s := range tokens {
tokenSecretNames = append(tokenSecretNames, s.Name)
}
types := map[string][]string{ types := map[string][]string{
pullHeader: pullSecretNames, pullHeader: pullSecretNames,
mountHeader: mountSecretNames,
tokenHeader: tokenSecretNames,
} }
for _, header := range sets.List(sets.KeySet(types)) { for _, header := range sets.List(sets.KeySet(types)) {
names := types[header] names := types[header]
@ -3482,7 +3540,11 @@ func describeServiceAccount(serviceAccount *corev1.ServiceAccount, events *corev
} else { } else {
prefix := header prefix := header
for _, name := range names { for _, name := range names {
w.Write(LEVEL_0, "%s\t%s\n", prefix, name) if missingSecrets.Has(name) {
w.Write(LEVEL_0, "%s\t%s (not found)\n", prefix, name)
} else {
w.Write(LEVEL_0, "%s\t%s\n", prefix, name)
}
prefix = emptyHeader prefix = emptyHeader
} }
} }

View File

@ -6238,7 +6238,9 @@ func TestDescribeServiceAccount(t *testing.T) {
Namespace: foo Namespace: foo
Labels: <none> Labels: <none>
Annotations: <none> Annotations: <none>
Image pull secrets: test-local-ref Image pull secrets: test-local-ref (not found)
Mountable secrets: test-objectref (not found)
Tokens: <none>
Events: <none>` + "\n" Events: <none>` + "\n"
if out != expectedOut { if out != expectedOut {
t.Errorf("expected : %q\n but got output:\n %q", expectedOut, out) t.Errorf("expected : %q\n but got output:\n %q", expectedOut, out)

View File

@ -74,9 +74,6 @@ type Helper struct {
// won't drain otherwise // won't drain otherwise
SkipWaitForDeleteTimeoutSeconds int SkipWaitForDeleteTimeoutSeconds int
// EvictErrorRetryDelay is used to control the retry delay after a pod eviction error
EvictErrorRetryDelay time.Duration
// AdditionalFilters are applied sequentially after base drain filters to // AdditionalFilters are applied sequentially after base drain filters to
// exclude pods using custom logic. Any filter that returns PodDeleteStatus // exclude pods using custom logic. Any filter that returns PodDeleteStatus
// with Delete == false will immediately stop execution of further filters. // with Delete == false will immediately stop execution of further filters.
@ -281,27 +278,37 @@ func (d *Helper) evictPods(pods []corev1.Pod, evictionGroupVersion schema.GroupV
defer cancel() defer cancel()
for _, pod := range pods { for _, pod := range pods {
go func(pod corev1.Pod, returnCh chan error) { go func(pod corev1.Pod, returnCh chan error) {
activePod := pod refreshPod := false
for { for {
switch d.DryRunStrategy { switch d.DryRunStrategy {
case cmdutil.DryRunServer: case cmdutil.DryRunServer:
//nolint:errcheck fmt.Fprintf(d.Out, "evicting pod %s/%s (server dry run)\n", pod.Namespace, pod.Name)
fmt.Fprintf(d.Out, "evicting pod %s/%s (server dry run)\n", activePod.Namespace, activePod.Name)
default: default:
if d.OnPodDeletionOrEvictionStarted != nil { if d.OnPodDeletionOrEvictionStarted != nil {
d.OnPodDeletionOrEvictionStarted(&activePod, true) d.OnPodDeletionOrEvictionStarted(&pod, true)
} }
//nolint:errcheck fmt.Fprintf(d.Out, "evicting pod %s/%s\n", pod.Namespace, pod.Name)
fmt.Fprintf(d.Out, "evicting pod %s/%s\n", activePod.Namespace, activePod.Name)
} }
select { select {
case <-ctx.Done(): case <-ctx.Done():
// return here or we'll leak a goroutine. // return here or we'll leak a goroutine.
returnCh <- fmt.Errorf("error when evicting pods/%q -n %q: global timeout reached: %v", activePod.Name, activePod.Namespace, globalTimeout) returnCh <- fmt.Errorf("error when evicting pods/%q -n %q: global timeout reached: %v", pod.Name, pod.Namespace, globalTimeout)
return return
default: default:
} }
// Create a temporary pod so we don't mutate the pod in the loop.
activePod := pod
if refreshPod {
freshPod, err := getPodFn(pod.Namespace, pod.Name)
// We ignore errors and let eviction sort it out with
// the original pod.
if err == nil {
activePod = *freshPod
}
refreshPod = false
}
err := d.EvictPod(activePod, evictionGroupVersion) err := d.EvictPod(activePod, evictionGroupVersion)
if err == nil { if err == nil {
break break
@ -309,9 +316,8 @@ func (d *Helper) evictPods(pods []corev1.Pod, evictionGroupVersion schema.GroupV
returnCh <- nil returnCh <- nil
return return
} else if apierrors.IsTooManyRequests(err) { } else if apierrors.IsTooManyRequests(err) {
//nolint:errcheck fmt.Fprintf(d.ErrOut, "error when evicting pods/%q -n %q (will retry after 5s): %v\n", activePod.Name, activePod.Namespace, err)
fmt.Fprintf(d.ErrOut, "error when evicting pods/%q -n %q (will retry after %v): %v\n", activePod.Name, activePod.Namespace, d.EvictErrorRetryDelay, err) time.Sleep(5 * time.Second)
time.Sleep(d.EvictErrorRetryDelay)
} else if !activePod.ObjectMeta.DeletionTimestamp.IsZero() && apierrors.IsForbidden(err) && apierrors.HasStatusCause(err, corev1.NamespaceTerminatingCause) { } else if !activePod.ObjectMeta.DeletionTimestamp.IsZero() && apierrors.IsForbidden(err) && apierrors.HasStatusCause(err, corev1.NamespaceTerminatingCause) {
// an eviction request in a deleting namespace will throw a forbidden error, // an eviction request in a deleting namespace will throw a forbidden error,
// if the pod is already marked deleted, we can ignore this error, an eviction // if the pod is already marked deleted, we can ignore this error, an eviction
@ -320,19 +326,12 @@ func (d *Helper) evictPods(pods []corev1.Pod, evictionGroupVersion schema.GroupV
} else if apierrors.IsForbidden(err) && apierrors.HasStatusCause(err, corev1.NamespaceTerminatingCause) { } else if apierrors.IsForbidden(err) && apierrors.HasStatusCause(err, corev1.NamespaceTerminatingCause) {
// an eviction request in a deleting namespace will throw a forbidden error, // an eviction request in a deleting namespace will throw a forbidden error,
// if the pod is not marked deleted, we retry until it is. // if the pod is not marked deleted, we retry until it is.
//nolint:errcheck fmt.Fprintf(d.ErrOut, "error when evicting pod %q from terminating namespace %q (will retry after 5s): %v\n", activePod.Name, activePod.Namespace, err)
fmt.Fprintf(d.ErrOut, "error when evicting pod %q from terminating namespace %q (will retry after %v): %v\n", activePod.Name, activePod.Namespace, d.EvictErrorRetryDelay, err) time.Sleep(5 * time.Second)
time.Sleep(d.EvictErrorRetryDelay)
} else { } else {
returnCh <- fmt.Errorf("error when evicting pods/%q -n %q: %v", activePod.Name, activePod.Namespace, err) returnCh <- fmt.Errorf("error when evicting pods/%q -n %q: %v", activePod.Name, activePod.Namespace, err)
return return
} }
freshPod, err := getPodFn(activePod.Namespace, activePod.Name)
// we ignore errors and let eviction sort it out with the original pod.
if err == nil {
activePod = *freshPod
}
} }
if d.DryRunStrategy == cmdutil.DryRunServer { if d.DryRunStrategy == cmdutil.DryRunServer {
returnCh <- nil returnCh <- nil
@ -340,7 +339,7 @@ func (d *Helper) evictPods(pods []corev1.Pod, evictionGroupVersion schema.GroupV
} }
params := waitForDeleteParams{ params := waitForDeleteParams{
ctx: ctx, ctx: ctx,
pods: []corev1.Pod{activePod}, pods: []corev1.Pod{pod},
interval: 1 * time.Second, interval: 1 * time.Second,
timeout: time.Duration(math.MaxInt64), timeout: time.Duration(math.MaxInt64),
usingEviction: true, usingEviction: true,

View File

@ -529,110 +529,3 @@ func TestFilterPods(t *testing.T) {
}) })
} }
} }
func TestEvictDuringNamespaceTerminating(t *testing.T) {
testPodUID := types.UID("test-uid")
testPodName := "test-pod"
testNamespace := "default"
retryDelay := 5 * time.Millisecond
globalTimeout := 2 * retryDelay
tests := []struct {
description string
refresh bool
err error
}{
{
description: "Pod refreshed after NamespaceTerminating error",
refresh: true,
err: nil,
},
{
description: "Pod not refreshed after NamespaceTerminating error",
refresh: false,
err: fmt.Errorf("error when evicting pods/%q -n %q: global timeout reached: %v", testPodName, testNamespace, globalTimeout),
},
}
for _, test := range tests {
t.Run(test.description, func(t *testing.T) {
var retry bool
initialPod := &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: testPodName,
Namespace: testNamespace,
UID: testPodUID,
},
}
// pod with DeletionTimestamp, indicating deletion in progress
deletedPod := &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: testPodName,
Namespace: testNamespace,
UID: testPodUID,
DeletionTimestamp: &metav1.Time{Time: time.Now()},
},
}
evictPods := []corev1.Pod{*initialPod}
k := fake.NewClientset(initialPod)
addEvictionSupport(t, k, "v1")
// mock eviction to return NamespaceTerminating error
k.PrependReactor("create", "pods", func(action ktest.Action) (bool, runtime.Object, error) {
if action.GetSubresource() != "eviction" {
return false, nil, nil
}
err := apierrors.NewForbidden(
schema.GroupResource{Resource: "pods"},
testPodName,
errors.New("namespace is terminating"),
)
err.ErrStatus.Details.Causes = append(err.ErrStatus.Details.Causes, metav1.StatusCause{
Type: corev1.NamespaceTerminatingCause,
})
return true, nil, err
})
k.PrependReactor("get", "pods", func(action ktest.Action) (bool, runtime.Object, error) {
if !test.refresh {
// for non-refresh test, always return the initial pod
return true, initialPod, nil
}
if retry {
// second call, pod is deleted
return true, nil, apierrors.NewNotFound(schema.GroupResource{Resource: "pods"}, testPodName)
}
// first call, pod is being deleted
retry = true
return true, deletedPod, nil
})
h := &Helper{
Client: k,
DisableEviction: false,
Out: os.Stdout,
ErrOut: os.Stderr,
Timeout: globalTimeout,
EvictErrorRetryDelay: retryDelay,
}
err := h.DeleteOrEvictPods(evictPods)
if test.err == nil && err != nil {
t.Errorf("expected no error, got: %v", err)
} else if test.err != nil && (err == nil || err.Error() != test.err.Error()) {
t.Errorf("%s: unexpected eviction; actual %v; expected %v", test.description, err, test.err)
}
})
}
}

View File

@ -319,18 +319,16 @@ func compGetResourceList(restClientGetter genericclioptions.RESTClientGetter, cm
streams := genericiooptions.IOStreams{In: os.Stdin, Out: buf, ErrOut: io.Discard} streams := genericiooptions.IOStreams{In: os.Stdin, Out: buf, ErrOut: io.Discard}
o := apiresources.NewAPIResourceOptions(streams) o := apiresources.NewAPIResourceOptions(streams)
o.Complete(restClientGetter, cmd, nil)
// Get the list of resources // Get the list of resources
o.PrintFlags.OutputFormat = ptr.To("name") o.PrintFlags.OutputFormat = ptr.To("name")
o.Cached = true o.Cached = true
o.Verbs = []string{"get"} o.Verbs = []string{"get"}
// TODO:Should set --request-timeout=5s // TODO:Should set --request-timeout=5s
if err := o.Complete(restClientGetter, cmd, nil); err != nil {
return []string{}
}
// Ignore errors as the output may still be valid // Ignore errors as the output may still be valid
_ = o.RunAPIResources() o.RunAPIResources()
// Resources can be a comma-separated list. The last element is then // Resources can be a comma-separated list. The last element is then
// the one we should complete. For example if toComplete=="pods,secre" // the one we should complete. For example if toComplete=="pods,secre"

View File

@ -492,101 +492,6 @@ func TestResourceAndPortCompletionFunc(t *testing.T) {
} }
} }
func TestResourceTypeAndNameCompletionFuncResourceList(t *testing.T) {
// Set up a fake discovery client with some API resources
dc := cmdtesting.NewFakeCachedDiscoveryClient()
dc.PreferredResources = []*metav1.APIResourceList{
{
GroupVersion: "v1",
APIResources: []metav1.APIResource{
{
Name: "pods",
Namespaced: true,
Kind: "Pod",
Verbs: []string{"get", "list"},
},
{
Name: "services",
Namespaced: true,
Kind: "Service",
Verbs: []string{"get", "list"},
},
{
Name: "secrets",
Namespaced: true,
Kind: "Secret",
Verbs: []string{"get", "list"},
},
},
},
{
GroupVersion: "apps/v1",
APIResources: []metav1.APIResource{
{
Name: "deployments",
Namespaced: true,
Kind: "Deployment",
Verbs: []string{"get", "list"},
},
},
},
}
testCases := []struct {
name string
args []string
toComplete string
expectedComps []string
expectedDirective cobra.ShellCompDirective
}{
{
name: "complete resources starting with 's'",
args: []string{},
toComplete: "s",
expectedComps: []string{"secrets", "services"},
expectedDirective: cobra.ShellCompDirectiveNoFileComp,
},
{
name: "complete resources starting with 'p'",
args: []string{},
toComplete: "p",
expectedComps: []string{"pods"},
expectedDirective: cobra.ShellCompDirectiveNoFileComp,
},
{
name: "complete resources starting with 'd'",
args: []string{},
toComplete: "d",
expectedComps: []string{"deployments.apps"},
expectedDirective: cobra.ShellCompDirectiveNoFileComp,
},
{
name: "complete all resources with empty string",
args: []string{},
toComplete: "",
expectedComps: []string{"deployments.apps", "pods", "secrets", "services"},
expectedDirective: cobra.ShellCompDirectiveNoFileComp,
},
{
name: "no matches",
args: []string{},
toComplete: "xyz",
expectedComps: []string{},
expectedDirective: cobra.ShellCompDirectiveNoFileComp,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
tf, cmd := prepareCompletionTest()
tf.WithDiscoveryClient(dc)
compFunc := ResourceTypeAndNameCompletionFunc(tf)
comps, directive := compFunc(cmd, tc.args, tc.toComplete)
checkCompletion(t, comps, tc.expectedComps, directive, tc.expectedDirective)
})
}
}
func setMockFactory(config api.Config) { func setMockFactory(config api.Config) {
clientConfig := clientcmd.NewDefaultClientConfig(config, nil) clientConfig := clientcmd.NewDefaultClientConfig(config, nil)
testFactory := cmdtesting.NewTestFactory().WithClientConfig(clientConfig) testFactory := cmdtesting.NewTestFactory().WithClientConfig(clientConfig)

View File

@ -21,28 +21,12 @@ import (
"github.com/moby/term" "github.com/moby/term"
"k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/client-go/tools/remotecommand"
) )
// TerminalSize represents the width and height of a terminal.
// It is the same as staging/src/k8s.io/client-go/tools/remotecommand.TerminalSize.
// Copied to decouple the packages. Terminal-related package should not depend on API client and vice versa.
type TerminalSize struct {
Width uint16
Height uint16
}
// TerminalSizeQueue is capable of returning terminal resize events as they occur.
// It is the same as staging/src/k8s.io/client-go/tools/remotecommand.TerminalSizeQueue.
// Copied to decouple the packages. Terminal-related package should not depend on API client and vice versa.
type TerminalSizeQueue interface {
// Next returns the new terminal size after the terminal has been resized. It returns nil when
// monitoring has been stopped.
Next() *TerminalSize
}
// GetSize returns the current size of the user's terminal. If it isn't a terminal, // GetSize returns the current size of the user's terminal. If it isn't a terminal,
// nil is returned. // nil is returned.
func (t TTY) GetSize() *TerminalSize { func (t TTY) GetSize() *remotecommand.TerminalSize {
outFd, isTerminal := term.GetFdInfo(t.Out) outFd, isTerminal := term.GetFdInfo(t.Out)
if !isTerminal { if !isTerminal {
return nil return nil
@ -51,19 +35,19 @@ func (t TTY) GetSize() *TerminalSize {
} }
// GetSize returns the current size of the terminal associated with fd. // GetSize returns the current size of the terminal associated with fd.
func GetSize(fd uintptr) *TerminalSize { func GetSize(fd uintptr) *remotecommand.TerminalSize {
winsize, err := term.GetWinsize(fd) winsize, err := term.GetWinsize(fd)
if err != nil { if err != nil {
runtime.HandleError(fmt.Errorf("unable to get terminal size: %v", err)) runtime.HandleError(fmt.Errorf("unable to get terminal size: %v", err))
return nil return nil
} }
return &TerminalSize{Width: winsize.Width, Height: winsize.Height} return &remotecommand.TerminalSize{Width: winsize.Width, Height: winsize.Height}
} }
// MonitorSize monitors the terminal's size. It returns a TerminalSizeQueue primed with // MonitorSize monitors the terminal's size. It returns a TerminalSizeQueue primed with
// initialSizes, or nil if there's no TTY present. // initialSizes, or nil if there's no TTY present.
func (t *TTY) MonitorSize(initialSizes ...*TerminalSize) TerminalSizeQueue { func (t *TTY) MonitorSize(initialSizes ...*remotecommand.TerminalSize) remotecommand.TerminalSizeQueue {
outFd, isTerminal := term.GetFdInfo(t.Out) outFd, isTerminal := term.GetFdInfo(t.Out)
if !isTerminal { if !isTerminal {
return nil return nil
@ -73,7 +57,7 @@ func (t *TTY) MonitorSize(initialSizes ...*TerminalSize) TerminalSizeQueue {
t: *t, t: *t,
// make it buffered so we can send the initial terminal sizes without blocking, prior to starting // make it buffered so we can send the initial terminal sizes without blocking, prior to starting
// the streaming below // the streaming below
resizeChan: make(chan TerminalSize, len(initialSizes)), resizeChan: make(chan remotecommand.TerminalSize, len(initialSizes)),
stopResizing: make(chan struct{}), stopResizing: make(chan struct{}),
} }
@ -86,16 +70,16 @@ func (t *TTY) MonitorSize(initialSizes ...*TerminalSize) TerminalSizeQueue {
type sizeQueue struct { type sizeQueue struct {
t TTY t TTY
// resizeChan receives a Size each time the user's terminal is resized. // resizeChan receives a Size each time the user's terminal is resized.
resizeChan chan TerminalSize resizeChan chan remotecommand.TerminalSize
stopResizing chan struct{} stopResizing chan struct{}
} }
// make sure sizeQueue implements the TerminalSizeQueue interface // make sure sizeQueue implements the resize.TerminalSizeQueue interface
var _ TerminalSizeQueue = &sizeQueue{} var _ remotecommand.TerminalSizeQueue = &sizeQueue{}
// monitorSize primes resizeChan with initialSizes and then monitors for resize events. With each // monitorSize primes resizeChan with initialSizes and then monitors for resize events. With each
// new event, it sends the current terminal size to resizeChan. // new event, it sends the current terminal size to resizeChan.
func (s *sizeQueue) monitorSize(outFd uintptr, initialSizes ...*TerminalSize) { func (s *sizeQueue) monitorSize(outFd uintptr, initialSizes ...*remotecommand.TerminalSize) {
// send the initial sizes // send the initial sizes
for i := range initialSizes { for i := range initialSizes {
if initialSizes[i] != nil { if initialSizes[i] != nil {
@ -103,7 +87,7 @@ func (s *sizeQueue) monitorSize(outFd uintptr, initialSizes ...*TerminalSize) {
} }
} }
resizeEvents := make(chan TerminalSize, 1) resizeEvents := make(chan remotecommand.TerminalSize, 1)
monitorResizeEvents(outFd, resizeEvents, s.stopResizing) monitorResizeEvents(outFd, resizeEvents, s.stopResizing)
@ -134,7 +118,7 @@ func (s *sizeQueue) monitorSize(outFd uintptr, initialSizes ...*TerminalSize) {
// Next returns the new terminal size after the terminal has been resized. It returns nil when // Next returns the new terminal size after the terminal has been resized. It returns nil when
// monitoring has been stopped. // monitoring has been stopped.
func (s *sizeQueue) Next() *TerminalSize { func (s *sizeQueue) Next() *remotecommand.TerminalSize {
size, ok := <-s.resizeChan size, ok := <-s.resizeChan
if !ok { if !ok {
return nil return nil

View File

@ -25,12 +25,13 @@ import (
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
"k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/client-go/tools/remotecommand"
) )
// monitorResizeEvents spawns a goroutine that waits for SIGWINCH signals (these indicate the // monitorResizeEvents spawns a goroutine that waits for SIGWINCH signals (these indicate the
// terminal has resized). After receiving a SIGWINCH, this gets the terminal size and tries to send // terminal has resized). After receiving a SIGWINCH, this gets the terminal size and tries to send
// it to the resizeEvents channel. The goroutine stops when the stop channel is closed. // it to the resizeEvents channel. The goroutine stops when the stop channel is closed.
func monitorResizeEvents(fd uintptr, resizeEvents chan<- TerminalSize, stop chan struct{}) { func monitorResizeEvents(fd uintptr, resizeEvents chan<- remotecommand.TerminalSize, stop chan struct{}) {
go func() { go func() {
defer runtime.HandleCrash() defer runtime.HandleCrash()

View File

@ -20,12 +20,13 @@ import (
"time" "time"
"k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/client-go/tools/remotecommand"
) )
// monitorResizeEvents spawns a goroutine that periodically gets the terminal size and tries to send // monitorResizeEvents spawns a goroutine that periodically gets the terminal size and tries to send
// it to the resizeEvents channel if the size has changed. The goroutine stops when the stop channel // it to the resizeEvents channel if the size has changed. The goroutine stops when the stop channel
// is closed. // is closed.
func monitorResizeEvents(fd uintptr, resizeEvents chan<- TerminalSize, stop chan struct{}) { func monitorResizeEvents(fd uintptr, resizeEvents chan<- remotecommand.TerminalSize, stop chan struct{}) {
go func() { go func() {
defer runtime.HandleCrash() defer runtime.HandleCrash()

View File

@ -23,6 +23,8 @@ import (
wordwrap "github.com/mitchellh/go-wordwrap" wordwrap "github.com/mitchellh/go-wordwrap"
"github.com/moby/term" "github.com/moby/term"
"k8s.io/client-go/tools/remotecommand"
) )
type wordWrapWriter struct { type wordWrapWriter struct {
@ -68,7 +70,7 @@ func NewWordWrapWriter(w io.Writer, limit uint) io.Writer {
} }
} }
func getTerminalLimitWidth(terminalSize *TerminalSize) uint { func getTerminalLimitWidth(terminalSize *remotecommand.TerminalSize) uint {
var limit uint var limit uint
switch { switch {
case terminalSize.Width >= 120: case terminalSize.Width >= 120: