Skip to content

Commit 73e8378

Browse files
authored
Keep dots in Build IDs and format Worker Deployment names <k8s-namespace>/<twd-name> (#133)
<!--- Note to EXTERNAL Contributors --> <!-- Thanks for opening a PR! If it is a significant code change, please **make sure there is an open issue** for this. We work best with you when we have accepted the idea first before you code. --> <!--- For ALL Contributors 👇 --> ## What was changed Keep dots in Build IDs and format Worker Deployment names `<k8s-namespace>/<twd-name>` ## Why? Dots are allowed in pod names and its nice to maintain the semantic version appearance of an image. Namespace first means the same alphabetization as `kubectl list --all-namespaces`. Namespace first is more expected for a slash delimiter that implies hierarchy ## Checklist <!--- add/delete as needed ---> 1. Closes <!-- add issue number here --> 2. How was this tested: Unit tests and functional tests 3. Any docs updates needed? <!--- update README if applicable or point out where to update docs.temporal.io -->
1 parent 51d025a commit 73e8378

File tree

3 files changed

+40
-52
lines changed

3 files changed

+40
-52
lines changed

internal/k8s/deployments.go

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,11 @@ import (
2626
const (
2727
DeployOwnerKey = ".metadata.controller"
2828
// BuildIDLabel is the label that identifies the build ID for a deployment
29-
BuildIDLabel = "temporal.io/build-id"
30-
DeploymentNameSeparator = "/" // TODO(carlydf): change this to "." once the server accepts `.` in deployment names
31-
VersionIDSeparator = "." // TODO(carlydf): change this to ":"
32-
K8sResourceNameSeparator = "-"
33-
MaxBuildIdLen = 63
34-
ConnectionSpecHashAnnotation = "temporal.io/connection-spec-hash"
29+
BuildIDLabel = "temporal.io/build-id"
30+
WorkerDeploymentNameSeparator = "/"
31+
K8sResourceNameSeparator = "-"
32+
MaxBuildIdLen = 63
33+
ConnectionSpecHashAnnotation = "temporal.io/connection-spec-hash"
3534
)
3635

3736
// DeploymentState represents the Kubernetes state of all deployments for a temporal worker deployment
@@ -111,11 +110,6 @@ func NewObjectRef(obj client.Object) *corev1.ObjectReference {
111110
}
112111
}
113112

114-
// ComputeVersionID generates a version ID from the worker deployment spec
115-
func ComputeVersionID(w *temporaliov1alpha1.TemporalWorkerDeployment) string {
116-
return ComputeWorkerDeploymentName(w) + VersionIDSeparator + ComputeBuildID(w)
117-
}
118-
119113
func ComputeBuildID(w *temporaliov1alpha1.TemporalWorkerDeployment) string {
120114
if containers := w.Spec.Template.Spec.Containers; len(containers) > 0 {
121115
if img := containers[0].Image; img != "" {
@@ -131,7 +125,7 @@ func ComputeBuildID(w *temporaliov1alpha1.TemporalWorkerDeployment) string {
131125
// ComputeWorkerDeploymentName generates the base worker deployment name
132126
func ComputeWorkerDeploymentName(w *temporaliov1alpha1.TemporalWorkerDeployment) string {
133127
// Use the name and namespace to form the worker deployment name
134-
return w.GetName() + DeploymentNameSeparator + w.GetNamespace()
128+
return w.GetNamespace() + WorkerDeploymentNameSeparator + w.GetName()
135129
}
136130

137131
// ComputeVersionedDeploymentName generates a name for a versioned deployment
@@ -162,8 +156,8 @@ func CleanAndTruncateString(s string, n int) string {
162156
if len(s) > n && n > 0 {
163157
s = s[:n]
164158
}
165-
// Keep only letters, numbers, and dashes
166-
re := regexp.MustCompile(`[^a-zA-Z0-9-]+`)
159+
// Keep only letters, numbers, dashes, and dots
160+
re := regexp.MustCompile(`[^a-zA-Z0-9-.]+`)
167161
return re.ReplaceAllString(s, K8sResourceNameSeparator)
168162
}
169163

internal/k8s/deployments_test.go

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ func TestGenerateBuildID(t *testing.T) {
235235
twd2 := testhelpers.MakeTWD("", "", 1, pod2, nil, nil, nil)
236236
return twd1, twd2
237237
},
238-
expectedPrefix: "my-test-image",
238+
expectedPrefix: "my.test-image",
239239
expectedHashLen: 4,
240240
expectEquality: false, // should be different
241241
},
@@ -248,7 +248,7 @@ func TestGenerateBuildID(t *testing.T) {
248248
twd2 := testhelpers.MakeTWD("", "", 2, pod, nil, nil, nil)
249249
return twd1, twd2
250250
},
251-
expectedPrefix: "my-test-image",
251+
expectedPrefix: "my.test-image",
252252
expectedHashLen: 4,
253253
expectEquality: true, // should be the same
254254
},
@@ -334,7 +334,7 @@ func TestGenerateBuildID(t *testing.T) {
334334
twd := testhelpers.MakeTWDWithImage("", "", illegalCharsImg)
335335
return twd, nil // only check 1 result, no need to compare
336336
},
337-
expectedPrefix: "this-is-my-weird-image",
337+
expectedPrefix: "this.is.my-weird-image",
338338
expectedHashLen: 4,
339339
expectEquality: false,
340340
},
@@ -450,15 +450,9 @@ func TestComputeWorkerDeploymentName_Integration_WithVersionedName(t *testing.T)
450450
versionedName := k8s.ComputeVersionedDeploymentName(workerDeploymentName, buildID)
451451

452452
// Verify the expected formats
453-
assert.Equal(t, "hello-world"+k8s.DeploymentNameSeparator+"demo", workerDeploymentName)
454-
assert.True(t, strings.HasPrefix(versionedName, "hello-world"+k8s.DeploymentNameSeparator+"demo-"))
455-
assert.True(t, strings.Contains(versionedName, "v1-0-0"), "versioned name should contain cleaned image tag")
456-
457-
// Verify the version ID combines worker deployment name and build ID
458-
versionID := k8s.ComputeVersionID(twd)
459-
expectedVersionID := workerDeploymentName + k8s.VersionIDSeparator + buildID
460-
assert.Equal(t, expectedVersionID, versionID)
461-
assert.Equal(t, "hello-world"+k8s.DeploymentNameSeparator+"demo"+k8s.VersionIDSeparator+"v1-0-0-dd84", versionID)
453+
assert.Equal(t, "demo"+k8s.WorkerDeploymentNameSeparator+"hello-world", workerDeploymentName)
454+
assert.True(t, strings.HasPrefix(versionedName, "demo"+k8s.WorkerDeploymentNameSeparator+"hello-world-"))
455+
assert.True(t, strings.Contains(versionedName, "v1.0.0"), "versioned name should contain cleaned image tag")
462456
}
463457

464458
// TestNewDeploymentWithPodAnnotations tests that every new pod created has a connection spec hash annotation

internal/tests/internal/integration_test.go

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -47,53 +47,53 @@ func TestIntegration(t *testing.T) {
4747
WithInput(
4848
testhelpers.NewTemporalWorkerDeploymentBuilder().
4949
WithManualStrategy().
50-
WithTargetTemplate("v1"),
50+
WithTargetTemplate("v1.0"),
5151
).
5252
WithWaitTime(5 * time.Second). // wait before checking to confirm no change
5353
WithExpectedStatus(
5454
testhelpers.NewStatusBuilder().
55-
WithTargetVersion("v1", temporaliov1alpha1.VersionStatusInactive, -1, true, false),
55+
WithTargetVersion("v1.0", temporaliov1alpha1.VersionStatusInactive, -1, true, false),
5656
),
5757
"all-at-once-rollout-2-replicas": testhelpers.NewTestCase().
5858
WithInput(
5959
testhelpers.NewTemporalWorkerDeploymentBuilder().
6060
WithAllAtOnceStrategy().
6161
WithReplicas(2).
62-
WithTargetTemplate("v1"),
62+
WithTargetTemplate("v1.0"),
6363
).
6464
WithExpectedStatus(
6565
testhelpers.NewStatusBuilder().
66-
WithTargetVersion("v1", temporaliov1alpha1.VersionStatusCurrent, -1, true, false).
67-
WithCurrentVersion("v1", true, false),
66+
WithTargetVersion("v1.0", temporaliov1alpha1.VersionStatusCurrent, -1, true, false).
67+
WithCurrentVersion("v1.0", true, false),
6868
),
6969
"progressive-rollout-no-unversioned-pollers-expect-all-at-once": testhelpers.NewTestCase().
7070
WithInput(
7171
testhelpers.NewTemporalWorkerDeploymentBuilder().
7272
WithProgressiveStrategy(testhelpers.ProgressiveStep(5, time.Hour)).
73-
WithTargetTemplate("v1"),
73+
WithTargetTemplate("v1.0"),
7474
).
7575
WithExpectedStatus(
7676
testhelpers.NewStatusBuilder().
77-
WithTargetVersion("v1", temporaliov1alpha1.VersionStatusCurrent, -1, true, false).
78-
WithCurrentVersion("v1", true, false),
77+
WithTargetVersion("v1.0", temporaliov1alpha1.VersionStatusCurrent, -1, true, false).
78+
WithCurrentVersion("v1.0", true, false),
7979
),
8080
//// TODO(carlydf): this won't work until the controller detects unversioned pollers
8181
// "progressive-rollout-yes-unversioned-pollers-expect-first-step": testhelpers.NewTestCase().
8282
// WithInput(
8383
// testhelpers.NewTemporalWorkerDeploymentBuilder().
8484
// WithProgressiveStrategy(testhelpers.ProgressiveStep(5, time.Hour)).
85-
// WithTargetTemplate("v1"),
85+
// WithTargetTemplate("v1.0"),
8686
// ).
8787
// WithSetupFunction(setupUnversionedPoller).
8888
// WithExpectedStatus(
8989
// testhelpers.NewStatusBuilder().
90-
// WithTargetVersion("v1", temporaliov1alpha1.VersionStatusRamping, 5, true, false),
90+
// WithTargetVersion("v1.0", temporaliov1alpha1.VersionStatusRamping, 5, true, false),
9191
// ),
9292
"nth-progressive-rollout-expect-first-step": testhelpers.NewTestCase().
9393
WithInput(
9494
testhelpers.NewTemporalWorkerDeploymentBuilder().
9595
WithProgressiveStrategy(testhelpers.ProgressiveStep(5, time.Hour)).
96-
WithTargetTemplate("v1").
96+
WithTargetTemplate("v1.0").
9797
WithStatus(
9898
testhelpers.NewStatusBuilder().
9999
WithTargetVersion("v0", temporaliov1alpha1.VersionStatusCurrent, -1, true, true).
@@ -105,14 +105,14 @@ func TestIntegration(t *testing.T) {
105105
).
106106
WithExpectedStatus(
107107
testhelpers.NewStatusBuilder().
108-
WithTargetVersion("v1", temporaliov1alpha1.VersionStatusRamping, 5, true, false),
108+
WithTargetVersion("v1.0", temporaliov1alpha1.VersionStatusRamping, 5, true, false),
109109
),
110110
"nth-progressive-rollout-with-success-gate": testhelpers.NewTestCase().
111111
WithInput(
112112
testhelpers.NewTemporalWorkerDeploymentBuilder().
113113
WithProgressiveStrategy(testhelpers.ProgressiveStep(5, time.Hour)).
114114
WithGate(true).
115-
WithTargetTemplate("v1").
115+
WithTargetTemplate("v1.0").
116116
WithStatus(
117117
testhelpers.NewStatusBuilder().
118118
WithTargetVersion("v0", temporaliov1alpha1.VersionStatusCurrent, -1, true, true).
@@ -124,14 +124,14 @@ func TestIntegration(t *testing.T) {
124124
).
125125
WithExpectedStatus(
126126
testhelpers.NewStatusBuilder().
127-
WithTargetVersion("v1", temporaliov1alpha1.VersionStatusRamping, 5, true, false),
127+
WithTargetVersion("v1.0", temporaliov1alpha1.VersionStatusRamping, 5, true, false),
128128
),
129129
"nth-progressive-rollout-with-failed-gate": testhelpers.NewTestCase().
130130
WithInput(
131131
testhelpers.NewTemporalWorkerDeploymentBuilder().
132132
WithProgressiveStrategy(testhelpers.ProgressiveStep(5, time.Hour)).
133133
WithGate(false).
134-
WithTargetTemplate("v1").
134+
WithTargetTemplate("v1.0").
135135
WithStatus(
136136
testhelpers.NewStatusBuilder().
137137
WithTargetVersion("v0", temporaliov1alpha1.VersionStatusCurrent, -1, true, true).
@@ -144,52 +144,52 @@ func TestIntegration(t *testing.T) {
144144
WithWaitTime(5 * time.Second).
145145
WithExpectedStatus(
146146
testhelpers.NewStatusBuilder().
147-
WithTargetVersion("v1", temporaliov1alpha1.VersionStatusInactive, -1, true, false).
147+
WithTargetVersion("v1.0", temporaliov1alpha1.VersionStatusInactive, -1, true, false).
148148
WithCurrentVersion("v0", true, true),
149149
),
150150
"failed-gate-is-not-scaled-down-while-target": testhelpers.NewTestCase().
151151
WithInput(
152152
testhelpers.NewTemporalWorkerDeploymentBuilder().
153153
WithAllAtOnceStrategy().
154154
WithGate(false).
155-
WithTargetTemplate("v1"),
155+
WithTargetTemplate("v1.0"),
156156
).
157157
WithWaitTime(5 * time.Second).
158158
WithExpectedStatus(
159159
testhelpers.NewStatusBuilder().
160-
WithTargetVersion("v1", temporaliov1alpha1.VersionStatusInactive, -1, true, false),
160+
WithTargetVersion("v1.0", temporaliov1alpha1.VersionStatusInactive, -1, true, false),
161161
),
162162
"failed-gate-is-scaled-down-when-deprecated": testhelpers.NewTestCase().
163163
WithInput(
164164
testhelpers.NewTemporalWorkerDeploymentBuilder().
165165
WithAllAtOnceStrategy().
166-
WithTargetTemplate("v2").
166+
WithTargetTemplate("v2.0").
167167
WithStatus(
168168
testhelpers.NewStatusBuilder().
169-
WithTargetVersion("v1", temporaliov1alpha1.VersionStatusInactive, -1, true, true).
169+
WithTargetVersion("v1.0", temporaliov1alpha1.VersionStatusInactive, -1, true, true).
170170
WithDeprecatedVersions(
171171
testhelpers.NewDeprecatedVersionInfo("v0", temporaliov1alpha1.VersionStatusDrained, true, true, true),
172172
),
173173
),
174174
).
175175
WithExistingDeployments(
176176
testhelpers.NewDeploymentInfo("v0", 1),
177-
testhelpers.NewDeploymentInfo("v1", 1),
177+
testhelpers.NewDeploymentInfo("v1.0", 1),
178178
).
179179
WithWaitTime(5*time.Second).
180180
WithExpectedStatus(
181181
testhelpers.NewStatusBuilder().
182-
WithTargetVersion("v2", temporaliov1alpha1.VersionStatusCurrent, -1, true, false).
183-
WithCurrentVersion("v2", true, false).
182+
WithTargetVersion("v2.0", temporaliov1alpha1.VersionStatusCurrent, -1, true, false).
183+
WithCurrentVersion("v2.0", true, false).
184184
WithDeprecatedVersions(
185185
testhelpers.NewDeprecatedVersionInfo("v0", temporaliov1alpha1.VersionStatusDrained, true, false, true),
186-
testhelpers.NewDeprecatedVersionInfo("v1", temporaliov1alpha1.VersionStatusInactive, true, false, true),
186+
testhelpers.NewDeprecatedVersionInfo("v1.0", temporaliov1alpha1.VersionStatusInactive, true, false, true),
187187
),
188188
).
189189
WithExpectedDeployments( // note: right now this is only checked for deprecated versions, TODO(carlydf) add for non-deprecated too
190190
testhelpers.NewDeploymentInfo("v0", 1),
191-
testhelpers.NewDeploymentInfo("v1", 0),
192-
testhelpers.NewDeploymentInfo("v2", 1),
191+
testhelpers.NewDeploymentInfo("v1.0", 0),
192+
testhelpers.NewDeploymentInfo("v2.0", 1),
193193
),
194194
"nth-rollout-blocked-by-modifier": testhelpers.NewTestCase().
195195
WithInput(

0 commit comments

Comments
 (0)