mirror of https://github.com/k3s-io/k3s
Allow kubectl patcher to patch specific version
Give a new "ResourceVersion" option to the patch so that the patch can be forced against a specific version. Also there is no way to customize how many retries the patcher should do on conflicts, so also add a "Retries" option that let's one customize it.pull/58/head
parent
7c4d097faf
commit
89daa462ff
|
@ -17,6 +17,7 @@ limitations under the License.
|
||||||
package apply
|
package apply
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -436,6 +437,7 @@ func (o *ApplyOptions) Run() error {
|
||||||
GracePeriod: o.DeleteOptions.GracePeriod,
|
GracePeriod: o.DeleteOptions.GracePeriod,
|
||||||
ServerDryRun: o.ServerDryRun,
|
ServerDryRun: o.ServerDryRun,
|
||||||
OpenapiSchema: openapiSchema,
|
OpenapiSchema: openapiSchema,
|
||||||
|
Retries: maxPatchRetry,
|
||||||
}
|
}
|
||||||
|
|
||||||
patchBytes, patchedObject, err := patcher.Patch(info.Object, modified, info.Source, info.Namespace, info.Name, o.ErrOut)
|
patchBytes, patchedObject, err := patcher.Patch(info.Object, modified, info.Source, info.Namespace, info.Name, o.ErrOut)
|
||||||
|
@ -699,6 +701,12 @@ type Patcher struct {
|
||||||
GracePeriod int
|
GracePeriod int
|
||||||
ServerDryRun bool
|
ServerDryRun bool
|
||||||
|
|
||||||
|
// If set, forces the patch against a specific resourceVersion
|
||||||
|
ResourceVersion *string
|
||||||
|
|
||||||
|
// Number of retries to make if the patch fails with conflict
|
||||||
|
Retries int
|
||||||
|
|
||||||
OpenapiSchema openapi.Resources
|
OpenapiSchema openapi.Resources
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -741,6 +749,22 @@ func (v *DryRunVerifier) HasSupport(gvk schema.GroupVersionKind) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func addResourceVersion(patch []byte, rv string) ([]byte, error) {
|
||||||
|
var patchMap map[string]interface{}
|
||||||
|
err := json.Unmarshal(patch, &patchMap)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
u := unstructured.Unstructured{Object: patchMap}
|
||||||
|
a, err := meta.Accessor(&u)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
a.SetResourceVersion(rv)
|
||||||
|
|
||||||
|
return json.Marshal(patchMap)
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Patcher) patchSimple(obj runtime.Object, modified []byte, source, namespace, name string, errOut io.Writer) ([]byte, runtime.Object, error) {
|
func (p *Patcher) patchSimple(obj runtime.Object, modified []byte, source, namespace, name string, errOut io.Writer) ([]byte, runtime.Object, error) {
|
||||||
// Serialize the current configuration of the object from the server.
|
// Serialize the current configuration of the object from the server.
|
||||||
current, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj)
|
current, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj)
|
||||||
|
@ -812,6 +836,13 @@ func (p *Patcher) patchSimple(obj runtime.Object, modified []byte, source, names
|
||||||
return patch, obj, nil
|
return patch, obj, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if p.ResourceVersion != nil {
|
||||||
|
patch, err = addResourceVersion(patch, *p.ResourceVersion)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, cmdutil.AddSourceToErr("Failed to insert resourceVersion in patch", source, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
options := metav1.UpdateOptions{}
|
options := metav1.UpdateOptions{}
|
||||||
if p.ServerDryRun {
|
if p.ServerDryRun {
|
||||||
options.DryRun = []string{metav1.DryRunAll}
|
options.DryRun = []string{metav1.DryRunAll}
|
||||||
|
@ -824,7 +855,10 @@ func (p *Patcher) patchSimple(obj runtime.Object, modified []byte, source, names
|
||||||
func (p *Patcher) Patch(current runtime.Object, modified []byte, source, namespace, name string, errOut io.Writer) ([]byte, runtime.Object, error) {
|
func (p *Patcher) Patch(current runtime.Object, modified []byte, source, namespace, name string, errOut io.Writer) ([]byte, runtime.Object, error) {
|
||||||
var getErr error
|
var getErr error
|
||||||
patchBytes, patchObject, err := p.patchSimple(current, modified, source, namespace, name, errOut)
|
patchBytes, patchObject, err := p.patchSimple(current, modified, source, namespace, name, errOut)
|
||||||
for i := 1; i <= maxPatchRetry && errors.IsConflict(err); i++ {
|
if p.Retries == 0 {
|
||||||
|
p.Retries = maxPatchRetry
|
||||||
|
}
|
||||||
|
for i := 1; i <= p.Retries && errors.IsConflict(err); i++ {
|
||||||
if i > triesBeforeBackOff {
|
if i > triesBeforeBackOff {
|
||||||
p.BackOff.Sleep(backOffPeriod)
|
p.BackOff.Sleep(backOffPeriod)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue