Skip to content

Commit 4c95dda

Browse files
authored
Merge pull request #5048 from ricardomaraschini/backport-helm-timeout-change
[Backport release-1.30] chore(backport): make helm timeout backward compatible
2 parents 9fc4bfe + a55e5d6 commit 4c95dda

File tree

6 files changed

+92
-7
lines changed

6 files changed

+92
-7
lines changed

pkg/apis/k0s/v1beta1/extensions.go

+36-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ limitations under the License.
1717
package v1beta1
1818

1919
import (
20+
"encoding/json"
2021
"errors"
22+
"time"
2123

2224
"helm.sh/helm/v3/pkg/chartutil"
2325
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -97,14 +99,47 @@ type Chart struct {
9799
TargetNS string `json:"namespace"`
98100
// Timeout specifies the timeout for how long to wait for the chart installation to finish.
99101
// 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".
100-
Timeout metav1.Duration `json:"timeout"`
102+
// +kubebuilder:validation:XIntOrString
103+
Timeout BackwardCompatibleDuration `json:"timeout,omitempty"`
101104
// ForceUpgrade when set to false, disables the use of the "--force" flag when upgrading the the chart (default: true).
102105
// +kubebuilder:default=true
103106
// +optional
104107
ForceUpgrade *bool `json:"forceUpgrade,omitempty"`
105108
Order int `json:"order"`
106109
}
107110

111+
// BackwardCompatibleDuration is a metav1.Duration with a different JSON
112+
// unmarshaler. The unmashaler accepts its value as either a string (e.g.
113+
// 10m15s) or as an integer 64. If the value is of type integer then, for
114+
// backward compatibility, it is interpreted as nano seconds.
115+
type BackwardCompatibleDuration metav1.Duration
116+
117+
// MarshalJSON marshals the BackwardCompatibleDuration to JSON.
118+
func (b BackwardCompatibleDuration) MarshalJSON() ([]byte, error) {
119+
return json.Marshal(b.Duration.String())
120+
}
121+
122+
// UnmarshalJSON attempts unmarshals the provided value into a
123+
// BackwardCompatibleDuration. This function attempts to unmarshal it as a
124+
// string first and if that fails it attempts to parse it as an integer.
125+
func (b *BackwardCompatibleDuration) UnmarshalJSON(data []byte) error {
126+
var duration metav1.Duration
127+
ustrerr := duration.UnmarshalJSON(data)
128+
if ustrerr == nil {
129+
*b = BackwardCompatibleDuration(duration)
130+
return nil
131+
}
132+
133+
var integer int64
134+
if err := json.Unmarshal(data, &integer); err != nil {
135+
// we return the error from the first unmarshal attempt.
136+
return ustrerr
137+
}
138+
metadur := metav1.Duration{Duration: time.Duration(integer)}
139+
*b = BackwardCompatibleDuration(metadur)
140+
return nil
141+
}
142+
108143
// Validate performs validation
109144
func (c Chart) Validate() error {
110145
if c.Name == "" {

pkg/apis/k0s/v1beta1/extenstions_test.go

+31-3
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,34 @@ func TestValidation(t *testing.T) {
8686
})
8787
}
8888

89+
func TestIntegerTimeoutParsing(t *testing.T) {
90+
yaml := `
91+
apiVersion: k0s.k0sproject.io/v1beta1
92+
kind: ClusterConfig
93+
metadata:
94+
name: foobar
95+
spec:
96+
extensions:
97+
helm:
98+
charts:
99+
- name: prometheus-stack
100+
chartname: prometheus-community/prometheus
101+
version: "14.6.1"
102+
timeout: 60000000000
103+
`
104+
105+
c, err := ConfigFromString(yaml)
106+
require := require.New(t)
107+
108+
require.NoError(err)
109+
110+
chart := c.Spec.Extensions.Helm.Charts[0]
111+
expectedDuration := BackwardCompatibleDuration(
112+
metav1.Duration{Duration: time.Minute},
113+
)
114+
require.Equal(expectedDuration, chart.Timeout)
115+
}
116+
89117
func TestDurationParsing(t *testing.T) {
90118
yaml := `
91119
apiVersion: k0s.k0sproject.io/v1beta1
@@ -108,8 +136,8 @@ spec:
108136
require.NoError(err)
109137

110138
chart := c.Spec.Extensions.Helm.Charts[0]
111-
expectedDuration := metav1.Duration{
112-
Duration: 20 * time.Minute,
113-
}
139+
expectedDuration := BackwardCompatibleDuration(
140+
metav1.Duration{Duration: 20 * time.Minute},
141+
)
114142
require.Equal(expectedDuration, chart.Timeout)
115143
}

pkg/apis/k0s/v1beta1/zz_generated.deepcopy.go

+15
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/component/controller/extensions_controller.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,9 @@ func addOpenEBSHelmExtension(helmSpec *k0sv1beta1.HelmExtensions, storageExtensi
159159
TargetNS: "openebs",
160160
Version: constant.OpenEBSVersion,
161161
Values: values,
162-
Timeout: metav1.Duration{Duration: time.Duration(time.Minute * 30)}, // it takes a while to install openebs
162+
Timeout: k0sv1beta1.BackwardCompatibleDuration(
163+
metav1.Duration{Duration: time.Duration(time.Minute * 30)}, // it takes a while to install openebs
164+
),
163165
})
164166
return helmSpec, nil
165167
}

pkg/component/controller/extensions_controller_test.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,9 @@ func TestExtensionsController_writeChartManifestFile(t *testing.T) {
251251
Version: "0.0.1",
252252
Values: "values",
253253
TargetNS: "default",
254-
Timeout: metav1.Duration{Duration: 5 * time.Minute},
254+
Timeout: k0sv1beta1.BackwardCompatibleDuration(
255+
metav1.Duration{Duration: 5 * time.Minute},
256+
),
255257
},
256258
fileName: "0_helm_extension_release.yaml",
257259
},
@@ -282,8 +284,10 @@ spec:
282284
Version: "0.0.1",
283285
Values: "values",
284286
TargetNS: "default",
285-
Timeout: metav1.Duration{Duration: 5 * time.Minute},
286287
ForceUpgrade: ptr.To(false),
288+
Timeout: k0sv1beta1.BackwardCompatibleDuration(
289+
metav1.Duration{Duration: 5 * time.Minute},
290+
),
287291
},
288292
fileName: "0_helm_extension_release.yaml",
289293
},

static/_crds/v1beta1/k0s.k0sproject.io_clusterconfigs.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ spec:
117117
Timeout specifies the timeout for how long to wait for the chart installation to finish.
118118
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".
119119
type: string
120+
x-kubernetes-int-or-string: true
120121
values:
121122
type: string
122123
version:

0 commit comments

Comments
 (0)