Skip to content

Commit 9a65f7d

Browse files
authored
[Feature] Multi-arch image discovery (#930)
1 parent ac35fd7 commit 9a65f7d

File tree

15 files changed

+250
-52
lines changed

15 files changed

+250
-52
lines changed

pkg/apis/deployment/v1/architecture.go

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"runtime"
2525

2626
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
27+
2728
"github.com/pkg/errors"
2829
core "k8s.io/api/core/v1"
2930
)
@@ -39,10 +40,6 @@ func (a ArangoDeploymentArchitecture) GetDefault() ArangoDeploymentArchitectureT
3940
}
4041

4142
func (a ArangoDeploymentArchitecture) Validate() error {
42-
if len(a) > 1 {
43-
return errors.Errorf("Only one architecture type is supported currently")
44-
}
45-
4643
for id := range a {
4744
if err := a[id].Validate(); err != nil {
4845
return errors.WithStack(errors.Wrapf(err, "%d", id))
@@ -52,18 +49,6 @@ func (a ArangoDeploymentArchitecture) Validate() error {
5249
return nil
5350
}
5451

55-
func (a ArangoDeploymentArchitecture) AsNodeSelectorRequirement() core.NodeSelectorTerm {
56-
return core.NodeSelectorTerm{
57-
MatchExpressions: []core.NodeSelectorRequirement{
58-
{
59-
Key: k8sutil.NodeArchAffinityLabel,
60-
Operator: "In",
61-
Values: []string{string(a.GetDefault())},
62-
},
63-
},
64-
}
65-
}
66-
6752
type ArangoDeploymentArchitectureType string
6853

6954
const (
@@ -87,3 +72,42 @@ func (a ArangoDeploymentArchitectureType) Validate() error {
8772
return errors.Errorf("Unknown architecture type %s", q)
8873
}
8974
}
75+
76+
func (a ArangoDeploymentArchitectureType) AsNodeSelectorRequirement() core.NodeSelectorTerm {
77+
return core.NodeSelectorTerm{
78+
MatchExpressions: []core.NodeSelectorRequirement{
79+
{
80+
Key: k8sutil.NodeArchAffinityLabel,
81+
Operator: "In",
82+
Values: []string{string(a)},
83+
},
84+
},
85+
}
86+
}
87+
88+
func GetArchsFromNodeSelector(selectors []core.NodeSelectorTerm) map[ArangoDeploymentArchitectureType]bool {
89+
result := make(map[ArangoDeploymentArchitectureType]bool)
90+
for _, selector := range selectors {
91+
if selector.MatchExpressions != nil {
92+
for _, req := range selector.MatchExpressions {
93+
if req.Key == k8sutil.NodeArchAffinityLabel || req.Key == k8sutil.NodeArchAffinityLabelBeta {
94+
for _, arch := range req.Values {
95+
result[ArangoDeploymentArchitectureType(arch)] = true
96+
}
97+
}
98+
}
99+
}
100+
}
101+
return result
102+
}
103+
104+
func (a *ArangoDeploymentArchitectureType) Equal(other *ArangoDeploymentArchitectureType) bool {
105+
if a == nil && other == nil {
106+
return true
107+
} else if a == nil || other == nil {
108+
return false
109+
} else if a == other {
110+
return true
111+
}
112+
return false
113+
}

pkg/apis/deployment/v1/member_status.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ type MemberStatus struct {
7676
Image *ImageInfo `json:"image,omitempty"`
7777
// OldImage holds old image defails
7878
OldImage *ImageInfo `json:"old-image,omitempty"`
79+
// Architecture defines Image architecture type
80+
Architecture *ArangoDeploymentArchitectureType `json:"architecture,omitempty"`
7981
// Upgrade define if upgrade should be enforced during next execution
8082
Upgrade bool `json:"upgrade,omitempty"`
8183
// Endpoint definition how member should be reachable
@@ -105,6 +107,7 @@ func (s MemberStatus) Equal(other MemberStatus) bool {
105107
s.ImageID == other.ImageID &&
106108
s.Image.Equal(other.Image) &&
107109
s.OldImage.Equal(other.OldImage) &&
110+
s.Architecture.Equal(other.Architecture) &&
108111
s.Upgrade == other.Upgrade &&
109112
util.CompareStringPointers(s.Endpoint, other.Endpoint)
110113
}

pkg/apis/deployment/v1/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/apis/deployment/v2alpha1/architecture.go

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"runtime"
2525

2626
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
27+
2728
"github.com/pkg/errors"
2829
core "k8s.io/api/core/v1"
2930
)
@@ -39,10 +40,6 @@ func (a ArangoDeploymentArchitecture) GetDefault() ArangoDeploymentArchitectureT
3940
}
4041

4142
func (a ArangoDeploymentArchitecture) Validate() error {
42-
if len(a) > 1 {
43-
return errors.Errorf("Only one architecture type is supported currently")
44-
}
45-
4643
for id := range a {
4744
if err := a[id].Validate(); err != nil {
4845
return errors.WithStack(errors.Wrapf(err, "%d", id))
@@ -52,18 +49,6 @@ func (a ArangoDeploymentArchitecture) Validate() error {
5249
return nil
5350
}
5451

55-
func (a ArangoDeploymentArchitecture) AsNodeSelectorRequirement() core.NodeSelectorTerm {
56-
return core.NodeSelectorTerm{
57-
MatchExpressions: []core.NodeSelectorRequirement{
58-
{
59-
Key: k8sutil.NodeArchAffinityLabel,
60-
Operator: "In",
61-
Values: []string{string(a.GetDefault())},
62-
},
63-
},
64-
}
65-
}
66-
6752
type ArangoDeploymentArchitectureType string
6853

6954
const (
@@ -87,3 +72,42 @@ func (a ArangoDeploymentArchitectureType) Validate() error {
8772
return errors.Errorf("Unknown architecture type %s", q)
8873
}
8974
}
75+
76+
func (a ArangoDeploymentArchitectureType) AsNodeSelectorRequirement() core.NodeSelectorTerm {
77+
return core.NodeSelectorTerm{
78+
MatchExpressions: []core.NodeSelectorRequirement{
79+
{
80+
Key: k8sutil.NodeArchAffinityLabel,
81+
Operator: "In",
82+
Values: []string{string(a)},
83+
},
84+
},
85+
}
86+
}
87+
88+
func GetArchsFromNodeSelector(selectors []core.NodeSelectorTerm) map[ArangoDeploymentArchitectureType]bool {
89+
result := make(map[ArangoDeploymentArchitectureType]bool)
90+
for _, selector := range selectors {
91+
if selector.MatchExpressions != nil {
92+
for _, req := range selector.MatchExpressions {
93+
if req.Key == k8sutil.NodeArchAffinityLabel || req.Key == k8sutil.NodeArchAffinityLabelBeta {
94+
for _, arch := range req.Values {
95+
result[ArangoDeploymentArchitectureType(arch)] = true
96+
}
97+
}
98+
}
99+
}
100+
}
101+
return result
102+
}
103+
104+
func (a *ArangoDeploymentArchitectureType) Equal(other *ArangoDeploymentArchitectureType) bool {
105+
if a == nil && other == nil {
106+
return true
107+
} else if a == nil || other == nil {
108+
return false
109+
} else if a == other {
110+
return true
111+
}
112+
return false
113+
}

pkg/apis/deployment/v2alpha1/member_status.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ type MemberStatus struct {
7676
Image *ImageInfo `json:"image,omitempty"`
7777
// OldImage holds old image defails
7878
OldImage *ImageInfo `json:"old-image,omitempty"`
79+
// Architecture defines Image architecture type
80+
Architecture *ArangoDeploymentArchitectureType `json:"architecture,omitempty"`
7981
// Upgrade define if upgrade should be enforced during next execution
8082
Upgrade bool `json:"upgrade,omitempty"`
8183
// Endpoint definition how member should be reachable
@@ -105,6 +107,7 @@ func (s MemberStatus) Equal(other MemberStatus) bool {
105107
s.ImageID == other.ImageID &&
106108
s.Image.Equal(other.Image) &&
107109
s.OldImage.Equal(other.OldImage) &&
110+
s.Architecture.Equal(other.Architecture) &&
108111
s.Upgrade == other.Upgrade &&
109112
util.CompareStringPointers(s.Endpoint, other.Endpoint)
110113
}

pkg/apis/deployment/v2alpha1/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/deployment/deployment_definitions_test.go

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,34 +41,42 @@ var (
4141
"test": "test",
4242
}
4343

44+
arch = api.ArangoDeploymentArchitectureDefault
45+
4446
firstAgentStatus = api.MemberStatus{
45-
ID: "agent1",
46-
Phase: api.MemberPhaseNone,
47+
ID: "agent1",
48+
Phase: api.MemberPhaseNone,
49+
Architecture: &arch,
4750
}
4851

4952
firstCoordinatorStatus = api.MemberStatus{
50-
ID: "coordinator1",
51-
Phase: api.MemberPhaseNone,
53+
ID: "coordinator1",
54+
Phase: api.MemberPhaseNone,
55+
Architecture: &arch,
5256
}
5357

5458
singleStatus = api.MemberStatus{
55-
ID: "single1",
56-
Phase: api.MemberPhaseNone,
59+
ID: "single1",
60+
Phase: api.MemberPhaseNone,
61+
Architecture: &arch,
5762
}
5863

5964
firstSyncMaster = api.MemberStatus{
60-
ID: "syncMaster1",
61-
Phase: api.MemberPhaseNone,
65+
ID: "syncMaster1",
66+
Phase: api.MemberPhaseNone,
67+
Architecture: &arch,
6268
}
6369

6470
firstSyncWorker = api.MemberStatus{
65-
ID: "syncWorker1",
66-
Phase: api.MemberPhaseNone,
71+
ID: "syncWorker1",
72+
Phase: api.MemberPhaseNone,
73+
Architecture: &arch,
6774
}
6875

6976
firstDBServerStatus = api.MemberStatus{
70-
ID: "DBserver1",
71-
Phase: api.MemberPhaseNone,
77+
ID: "DBserver1",
78+
Phase: api.MemberPhaseNone,
79+
Architecture: &arch,
7280
}
7381

7482
noAuthentication = api.AuthenticationSpec{

pkg/deployment/images.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,8 +354,9 @@ func (i *ImageUpdatePod) GetPodAffinity() *core.PodAffinity {
354354

355355
func (i *ImageUpdatePod) GetNodeAffinity() *core.NodeAffinity {
356356
a := core.NodeAffinity{}
357+
arch := i.spec.Architecture.GetDefault()
357358

358-
pod.AppendArchSelector(&a, i.spec.Architecture)
359+
pod.AppendArchSelector(&a, &arch)
359360

360361
pod.MergeNodeAffinity(&a, i.spec.ID.Get().NodeAffinity)
361362

pkg/deployment/members.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ func renderMember(log zerolog.Logger, status *api.DeploymentStatus, group api.Se
132132
}
133133
deploymentName := apiObject.GetName()
134134
role := group.AsRole()
135+
arch := apiObject.Spec.Architecture.GetDefault()
135136

136137
switch group {
137138
case api.ServerGroupSingle:
@@ -144,6 +145,7 @@ func renderMember(log zerolog.Logger, status *api.DeploymentStatus, group api.Se
144145
PersistentVolumeClaimName: k8sutil.CreatePersistentVolumeClaimName(deploymentName, role, id),
145146
PodName: "",
146147
Image: apiObject.Status.CurrentImage,
148+
Architecture: &arch,
147149
}, nil
148150
case api.ServerGroupAgents:
149151
log.Debug().Str("id", id).Msg("Adding agent")
@@ -155,6 +157,7 @@ func renderMember(log zerolog.Logger, status *api.DeploymentStatus, group api.Se
155157
PersistentVolumeClaimName: k8sutil.CreatePersistentVolumeClaimName(deploymentName, role, id),
156158
PodName: "",
157159
Image: apiObject.Status.CurrentImage,
160+
Architecture: &arch,
158161
}, nil
159162
case api.ServerGroupDBServers:
160163
log.Debug().Str("id", id).Msg("Adding dbserver")
@@ -166,6 +169,7 @@ func renderMember(log zerolog.Logger, status *api.DeploymentStatus, group api.Se
166169
PersistentVolumeClaimName: k8sutil.CreatePersistentVolumeClaimName(deploymentName, role, id),
167170
PodName: "",
168171
Image: apiObject.Status.CurrentImage,
172+
Architecture: &arch,
169173
}, nil
170174
case api.ServerGroupCoordinators:
171175
log.Debug().Str("id", id).Msg("Adding coordinator")
@@ -177,6 +181,7 @@ func renderMember(log zerolog.Logger, status *api.DeploymentStatus, group api.Se
177181
PersistentVolumeClaimName: "",
178182
PodName: "",
179183
Image: apiObject.Status.CurrentImage,
184+
Architecture: &arch,
180185
}, nil
181186
case api.ServerGroupSyncMasters:
182187
log.Debug().Str("id", id).Msg("Adding syncmaster")
@@ -188,6 +193,7 @@ func renderMember(log zerolog.Logger, status *api.DeploymentStatus, group api.Se
188193
PersistentVolumeClaimName: "",
189194
PodName: "",
190195
Image: apiObject.Status.CurrentImage,
196+
Architecture: &arch,
191197
}, nil
192198
case api.ServerGroupSyncWorkers:
193199
log.Debug().Str("id", id).Msg("Adding syncworker")
@@ -199,6 +205,7 @@ func renderMember(log zerolog.Logger, status *api.DeploymentStatus, group api.Se
199205
PersistentVolumeClaimName: "",
200206
PodName: "",
201207
Image: apiObject.Status.CurrentImage,
208+
Architecture: &arch,
202209
}, nil
203210
default:
204211
return nil, errors.WithStack(errors.Newf("Unknown server group %d", group))

pkg/deployment/pod/affinity.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func AppendPodAntiAffinityDefault(p interfaces.PodCreator, a *core.PodAntiAffini
5050
}
5151
}
5252

53-
func AppendArchSelector(a *core.NodeAffinity, arch api.ArangoDeploymentArchitecture) {
53+
func AppendArchSelector(a *core.NodeAffinity, arch *api.ArangoDeploymentArchitectureType) {
5454
if a.RequiredDuringSchedulingIgnoredDuringExecution == nil {
5555
a.RequiredDuringSchedulingIgnoredDuringExecution = &core.NodeSelector{}
5656
}

0 commit comments

Comments
 (0)