Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backport release-1.30] chore(backport): make helm timeout backward compatible #5048

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 36 additions & 1 deletion pkg/apis/k0s/v1beta1/extensions.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ limitations under the License.
package v1beta1

import (
"encoding/json"
"errors"
"time"

"helm.sh/helm/v3/pkg/chartutil"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -97,14 +99,47 @@ type Chart struct {
TargetNS string `json:"namespace"`
// Timeout specifies the timeout for how long to wait for the chart installation to finish.
// A duration string is a sequence of decimal numbers, each with optional fraction and a unit suffix, such as "300ms" or "2h45m". Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
Timeout metav1.Duration `json:"timeout"`
// +kubebuilder:validation:XIntOrString
Timeout BackwardCompatibleDuration `json:"timeout,omitempty"`
// ForceUpgrade when set to false, disables the use of the "--force" flag when upgrading the the chart (default: true).
// +kubebuilder:default=true
// +optional
ForceUpgrade *bool `json:"forceUpgrade,omitempty"`
Order int `json:"order"`
}

// BackwardCompatibleDuration is a metav1.Duration with a different JSON
// unmarshaler. The unmashaler accepts its value as either a string (e.g.
// 10m15s) or as an integer 64. If the value is of type integer then, for
// backward compatibility, it is interpreted as nano seconds.
type BackwardCompatibleDuration metav1.Duration

// MarshalJSON marshals the BackwardCompatibleDuration to JSON.
func (b BackwardCompatibleDuration) MarshalJSON() ([]byte, error) {
return json.Marshal(b.Duration.String())
}

// UnmarshalJSON attempts unmarshals the provided value into a
// BackwardCompatibleDuration. This function attempts to unmarshal it as a
// string first and if that fails it attempts to parse it as an integer.
func (b *BackwardCompatibleDuration) UnmarshalJSON(data []byte) error {
var duration metav1.Duration
ustrerr := duration.UnmarshalJSON(data)
if ustrerr == nil {
*b = BackwardCompatibleDuration(duration)
return nil
}

var integer int64
if err := json.Unmarshal(data, &integer); err != nil {
// we return the error from the first unmarshal attempt.
return ustrerr
}
metadur := metav1.Duration{Duration: time.Duration(integer)}
*b = BackwardCompatibleDuration(metadur)
return nil
}

// Validate performs validation
func (c Chart) Validate() error {
if c.Name == "" {
Expand Down
34 changes: 31 additions & 3 deletions pkg/apis/k0s/v1beta1/extenstions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,34 @@ func TestValidation(t *testing.T) {
})
}

func TestIntegerTimeoutParsing(t *testing.T) {
yaml := `
apiVersion: k0s.k0sproject.io/v1beta1
kind: ClusterConfig
metadata:
name: foobar
spec:
extensions:
helm:
charts:
- name: prometheus-stack
chartname: prometheus-community/prometheus
version: "14.6.1"
timeout: 60000000000
`

c, err := ConfigFromString(yaml)
require := require.New(t)

require.NoError(err)

chart := c.Spec.Extensions.Helm.Charts[0]
expectedDuration := BackwardCompatibleDuration(
metav1.Duration{Duration: time.Minute},
)
require.Equal(expectedDuration, chart.Timeout)
}

func TestDurationParsing(t *testing.T) {
yaml := `
apiVersion: k0s.k0sproject.io/v1beta1
Expand All @@ -108,8 +136,8 @@ spec:
require.NoError(err)

chart := c.Spec.Extensions.Helm.Charts[0]
expectedDuration := metav1.Duration{
Duration: 20 * time.Minute,
}
expectedDuration := BackwardCompatibleDuration(
metav1.Duration{Duration: 20 * time.Minute},
)
require.Equal(expectedDuration, chart.Timeout)
}
15 changes: 15 additions & 0 deletions pkg/apis/k0s/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion pkg/component/controller/extensions_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,9 @@ func addOpenEBSHelmExtension(helmSpec *k0sv1beta1.HelmExtensions, storageExtensi
TargetNS: "openebs",
Version: constant.OpenEBSVersion,
Values: values,
Timeout: metav1.Duration{Duration: time.Duration(time.Minute * 30)}, // it takes a while to install openebs
Timeout: k0sv1beta1.BackwardCompatibleDuration(
metav1.Duration{Duration: time.Duration(time.Minute * 30)}, // it takes a while to install openebs
),
})
return helmSpec, nil
}
Expand Down
8 changes: 6 additions & 2 deletions pkg/component/controller/extensions_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,9 @@ func TestExtensionsController_writeChartManifestFile(t *testing.T) {
Version: "0.0.1",
Values: "values",
TargetNS: "default",
Timeout: metav1.Duration{Duration: 5 * time.Minute},
Timeout: k0sv1beta1.BackwardCompatibleDuration(
metav1.Duration{Duration: 5 * time.Minute},
),
},
fileName: "0_helm_extension_release.yaml",
},
Expand Down Expand Up @@ -282,8 +284,10 @@ spec:
Version: "0.0.1",
Values: "values",
TargetNS: "default",
Timeout: metav1.Duration{Duration: 5 * time.Minute},
ForceUpgrade: ptr.To(false),
Timeout: k0sv1beta1.BackwardCompatibleDuration(
metav1.Duration{Duration: 5 * time.Minute},
),
},
fileName: "0_helm_extension_release.yaml",
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ spec:
Timeout specifies the timeout for how long to wait for the chart installation to finish.
A duration string is a sequence of decimal numbers, each with optional fraction and a unit suffix, such as "300ms" or "2h45m". Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
type: string
x-kubernetes-int-or-string: true
values:
type: string
version:
Expand Down
Loading