Skip to content

Commit f88f047

Browse files
committed
Sort env-vars by string name
This issue fixes the non-determinism observed by @LucasRoesler and @bmcstdio which caused Function Pods to be re-created due to the order of environment variables changing in the Deployment and PodSpec. Ref: #484 Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
1 parent 0a45df7 commit f88f047

File tree

3 files changed

+70
-3
lines changed

3 files changed

+70
-3
lines changed

handlers/deploy.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"log"
1111
"net/http"
1212
"regexp"
13+
"sort"
1314
"strconv"
1415
"strings"
1516

@@ -292,6 +293,10 @@ func buildEnvVars(request *types.FunctionDeployment) []corev1.EnvVar {
292293
})
293294
}
294295

296+
sort.SliceStable(envVars, func(i, j int) bool {
297+
return strings.Compare(envVars[i].Name, envVars[j].Name) == -1
298+
})
299+
295300
return envVars
296301
}
297302

handlers/deploy_test.go

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
package handlers
22

33
import (
4+
"testing"
5+
46
"github.com/openfaas/faas-netes/k8s"
7+
types "github.com/openfaas/faas-provider/types"
58
"k8s.io/client-go/kubernetes/fake"
6-
"testing"
79

8-
"github.com/openfaas/faas/gateway/requests"
910
apiv1 "k8s.io/api/core/v1"
1011
)
1112

@@ -91,3 +92,64 @@ func Test_SetNonRootUser(t *testing.T) {
9192
}
9293

9394
}
95+
96+
func Test_buildEnvVars_TwoSortedKeys(t *testing.T) {
97+
firstKey := "first"
98+
lastKey := "last"
99+
100+
inputEnvs := map[string]string{
101+
lastKey: "",
102+
firstKey: "",
103+
}
104+
105+
function := types.FunctionDeployment{
106+
EnvVars: inputEnvs,
107+
}
108+
109+
coreEnvs := buildEnvVars(&function)
110+
111+
if coreEnvs[0].Name != firstKey {
112+
t.Errorf("first want: %s, got: %s", firstKey, coreEnvs[0].Name)
113+
t.Fail()
114+
}
115+
}
116+
117+
func Test_buildEnvVars_FourSortedKeys(t *testing.T) {
118+
firstKey := "alex"
119+
secondKey := "elliot"
120+
thirdKey := "stefan"
121+
lastKey := "zane"
122+
123+
inputEnvs := map[string]string{
124+
lastKey: "",
125+
firstKey: "",
126+
thirdKey: "",
127+
secondKey: "",
128+
}
129+
130+
function := types.FunctionDeployment{
131+
EnvVars: inputEnvs,
132+
}
133+
134+
coreEnvs := buildEnvVars(&function)
135+
136+
if coreEnvs[0].Name != firstKey {
137+
t.Errorf("first want: %s, got: %s", firstKey, coreEnvs[0].Name)
138+
t.Fail()
139+
}
140+
141+
if coreEnvs[1].Name != secondKey {
142+
t.Errorf("second want: %s, got: %s", secondKey, coreEnvs[1].Name)
143+
t.Fail()
144+
}
145+
146+
if coreEnvs[2].Name != thirdKey {
147+
t.Errorf("third want: %s, got: %s", thirdKey, coreEnvs[2].Name)
148+
t.Fail()
149+
}
150+
151+
if coreEnvs[3].Name != lastKey {
152+
t.Errorf("last want: %s, got: %s", lastKey, coreEnvs[3].Name)
153+
t.Fail()
154+
}
155+
}

handlers/secrets_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import (
66
"net/http"
77
"testing"
88

9-
"github.com/openfaas/faas/gateway/requests"
9+
types "github.com/openfaas/faas-provider/types"
1010
appsv1 "k8s.io/api/apps/v1beta2"
1111
apiv1 "k8s.io/api/core/v1"
1212
k8serrors "k8s.io/apimachinery/pkg/api/errors"

0 commit comments

Comments
 (0)