Skip to content

Commit 5e5e43d

Browse files
authored
[Feature] Fix numactl options (#1432)
1 parent ff34073 commit 5e5e43d

File tree

9 files changed

+231
-22
lines changed

9 files changed

+231
-22
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- (Improvement) Allow tcp:// and ssl:// protocols in endpoints for members
66
- (Maintenance) Reorganize package imports / move common code to separate repos
77
- (Maintenance) Remove support for RELATED_IMAGE_UBI, RELATED_IMAGE_DATABASE and RELATED_IMAGE_METRICSEXPORTER env vars
8+
- (Bugfix) Fix numactl options
89

910
## [1.2.33](https://github.com/arangodb/kube-arangodb/tree/1.2.33) (2023-09-27)
1011
- (Maintenance) Bump golang.org/x/net to v0.13.0

pkg/deployment/deployment_core_test.go

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,190 @@ func TestEnsurePod_ArangoDB_Core(t *testing.T) {
8888
},
8989
},
9090
},
91+
{
92+
Name: "Agent Pod with numactl",
93+
ArangoDeployment: &api.ArangoDeployment{
94+
Spec: api.DeploymentSpec{
95+
Image: util.NewType[string](testImage),
96+
Authentication: noAuthentication,
97+
TLS: noTLS,
98+
ImagePullPolicy: util.NewType[core.PullPolicy](core.PullAlways),
99+
100+
Agents: api.ServerGroupSpec{
101+
Numactl: &api.ServerGroupSpecNumactl{
102+
Enabled: util.NewType(true),
103+
},
104+
},
105+
},
106+
},
107+
Helper: func(t *testing.T, deployment *Deployment, testCase *testCaseStruct) {
108+
deployment.currentObjectStatus = &api.DeploymentStatus{
109+
Members: api.DeploymentStatusMembers{
110+
Agents: api.MemberStatusList{
111+
firstAgentStatus,
112+
},
113+
},
114+
Images: createTestImages(false),
115+
}
116+
testCase.createTestPodData(deployment, api.ServerGroupAgents, firstAgentStatus)
117+
},
118+
ExpectedEvent: "member agent is created",
119+
ExpectedPod: core.Pod{
120+
Spec: core.PodSpec{
121+
Volumes: []core.Volume{
122+
k8sutil.CreateVolumeEmptyDir(shared.ArangodVolumeName),
123+
},
124+
Containers: []core.Container{
125+
{
126+
Name: shared.ServerContainerName,
127+
Image: testImage,
128+
Command: util.List[string]{api.ServerGroupSpecNumactlPathDefault}.
129+
Append(createTestCommandForAgent(firstAgentStatus.ID, false, false, false)...).
130+
List(),
131+
Ports: createTestPorts(api.ServerGroupAgents),
132+
VolumeMounts: []core.VolumeMount{
133+
k8sutil.ArangodVolumeMount(),
134+
},
135+
Resources: emptyResources,
136+
LivenessProbe: createTestLivenessProbe(httpProbe, false, "", shared.ServerPortName),
137+
ImagePullPolicy: core.PullAlways,
138+
SecurityContext: securityContext.NewSecurityContext(),
139+
},
140+
},
141+
RestartPolicy: core.RestartPolicyNever,
142+
TerminationGracePeriodSeconds: &defaultAgentTerminationTimeout,
143+
Hostname: testDeploymentName + "-" + api.ServerGroupAgentsString + "-" + firstAgentStatus.ID,
144+
Subdomain: testDeploymentName + "-int",
145+
Affinity: k8sutil.CreateAffinity(testDeploymentName, api.ServerGroupAgentsString,
146+
false, ""),
147+
},
148+
},
149+
},
150+
{
151+
Name: "Agent Pod with numactl with opts and override",
152+
ArangoDeployment: &api.ArangoDeployment{
153+
Spec: api.DeploymentSpec{
154+
Image: util.NewType[string](testImage),
155+
Authentication: noAuthentication,
156+
TLS: noTLS,
157+
ImagePullPolicy: util.NewType[core.PullPolicy](core.PullAlways),
158+
159+
Agents: api.ServerGroupSpec{
160+
Numactl: &api.ServerGroupSpecNumactl{
161+
Enabled: util.NewType(true),
162+
Args: []string{
163+
"--example=all",
164+
},
165+
Path: util.NewType("numactl-random-version"),
166+
},
167+
},
168+
},
169+
},
170+
Helper: func(t *testing.T, deployment *Deployment, testCase *testCaseStruct) {
171+
deployment.currentObjectStatus = &api.DeploymentStatus{
172+
Members: api.DeploymentStatusMembers{
173+
Agents: api.MemberStatusList{
174+
firstAgentStatus,
175+
},
176+
},
177+
Images: createTestImages(false),
178+
}
179+
testCase.createTestPodData(deployment, api.ServerGroupAgents, firstAgentStatus)
180+
},
181+
ExpectedEvent: "member agent is created",
182+
ExpectedPod: core.Pod{
183+
Spec: core.PodSpec{
184+
Volumes: []core.Volume{
185+
k8sutil.CreateVolumeEmptyDir(shared.ArangodVolumeName),
186+
},
187+
Containers: []core.Container{
188+
{
189+
Name: shared.ServerContainerName,
190+
Image: testImage,
191+
Command: util.List[string]{"numactl-random-version", "--example=all"}.
192+
Append(createTestCommandForAgent(firstAgentStatus.ID, false, false, false)...).
193+
List(),
194+
Ports: createTestPorts(api.ServerGroupAgents),
195+
VolumeMounts: []core.VolumeMount{
196+
k8sutil.ArangodVolumeMount(),
197+
},
198+
Resources: emptyResources,
199+
LivenessProbe: createTestLivenessProbe(httpProbe, false, "", shared.ServerPortName),
200+
ImagePullPolicy: core.PullAlways,
201+
SecurityContext: securityContext.NewSecurityContext(),
202+
},
203+
},
204+
RestartPolicy: core.RestartPolicyNever,
205+
TerminationGracePeriodSeconds: &defaultAgentTerminationTimeout,
206+
Hostname: testDeploymentName + "-" + api.ServerGroupAgentsString + "-" + firstAgentStatus.ID,
207+
Subdomain: testDeploymentName + "-int",
208+
Affinity: k8sutil.CreateAffinity(testDeploymentName, api.ServerGroupAgentsString,
209+
false, ""),
210+
},
211+
},
212+
},
213+
{
214+
Name: "Agent Pod with numactl with opts",
215+
ArangoDeployment: &api.ArangoDeployment{
216+
Spec: api.DeploymentSpec{
217+
Image: util.NewType[string](testImage),
218+
Authentication: noAuthentication,
219+
TLS: noTLS,
220+
ImagePullPolicy: util.NewType[core.PullPolicy](core.PullAlways),
221+
222+
Agents: api.ServerGroupSpec{
223+
Numactl: &api.ServerGroupSpecNumactl{
224+
Enabled: util.NewType(true),
225+
Args: []string{
226+
"--example=all",
227+
},
228+
},
229+
},
230+
},
231+
},
232+
Helper: func(t *testing.T, deployment *Deployment, testCase *testCaseStruct) {
233+
deployment.currentObjectStatus = &api.DeploymentStatus{
234+
Members: api.DeploymentStatusMembers{
235+
Agents: api.MemberStatusList{
236+
firstAgentStatus,
237+
},
238+
},
239+
Images: createTestImages(false),
240+
}
241+
testCase.createTestPodData(deployment, api.ServerGroupAgents, firstAgentStatus)
242+
},
243+
ExpectedEvent: "member agent is created",
244+
ExpectedPod: core.Pod{
245+
Spec: core.PodSpec{
246+
Volumes: []core.Volume{
247+
k8sutil.CreateVolumeEmptyDir(shared.ArangodVolumeName),
248+
},
249+
Containers: []core.Container{
250+
{
251+
Name: shared.ServerContainerName,
252+
Image: testImage,
253+
Command: util.List[string]{api.ServerGroupSpecNumactlPathDefault, "--example=all"}.
254+
Append(createTestCommandForAgent(firstAgentStatus.ID, false, false, false)...).
255+
List(),
256+
Ports: createTestPorts(api.ServerGroupAgents),
257+
VolumeMounts: []core.VolumeMount{
258+
k8sutil.ArangodVolumeMount(),
259+
},
260+
Resources: emptyResources,
261+
LivenessProbe: createTestLivenessProbe(httpProbe, false, "", shared.ServerPortName),
262+
ImagePullPolicy: core.PullAlways,
263+
SecurityContext: securityContext.NewSecurityContext(),
264+
},
265+
},
266+
RestartPolicy: core.RestartPolicyNever,
267+
TerminationGracePeriodSeconds: &defaultAgentTerminationTimeout,
268+
Hostname: testDeploymentName + "-" + api.ServerGroupAgentsString + "-" + firstAgentStatus.ID,
269+
Subdomain: testDeploymentName + "-int",
270+
Affinity: k8sutil.CreateAffinity(testDeploymentName, api.ServerGroupAgentsString,
271+
false, ""),
272+
},
273+
},
274+
},
91275
{
92276
Name: "Agent Pod with image pull policy",
93277
ArangoDeployment: &api.ArangoDeployment{

pkg/deployment/images.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -393,8 +393,8 @@ func (i *ImageUpdatePod) ApplyPodSpec(p *core.PodSpec) error {
393393
return nil
394394
}
395395

396-
func (a *ContainerIdentity) GetArgs() ([]string, error) {
397-
return nil, nil
396+
func (a *ContainerIdentity) GetCommand() ([]string, error) {
397+
return []string{a.GetExecutor()}, nil
398398
}
399399

400400
// GetEnvs returns environment variables for identity containers.
@@ -449,8 +449,8 @@ func (a *ContainerIdentity) GetVolumeMounts() []core.VolumeMount {
449449
return nil
450450
}
451451

452-
// GetArgs returns the list of arguments for the ArangoD container identification.
453-
func (a *ArangoDIdentity) GetArgs() ([]string, error) {
452+
// GetCommand returns the command for the ArangoD container identification.
453+
func (a *ArangoDIdentity) GetCommand() ([]string, error) {
454454
options := k8sutil.CreateOptionPairs(64)
455455
options.Add("--server.authentication", "false")
456456
options.Addf("--server.endpoint", "tcp://%s:%d", a.ipAddress, shared.ArangoPort)
@@ -460,7 +460,7 @@ func (a *ArangoDIdentity) GetArgs() ([]string, error) {
460460
// Security
461461
options.Merge(pod.Security().Args(a.input))
462462

463-
return options.Copy().Sort().AsArgs(), nil
463+
return options.Copy().Sort().AsArgsWithCommand(a.GetExecutor()), nil
464464
}
465465

466466
// GetEnvs returns environment variables for Arango identity containers.

pkg/deployment/resources/pod_creator_arangod.go

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -121,22 +121,23 @@ func (a *ArangoDContainer) GetPorts() []core.ContainerPort {
121121
return ports
122122
}
123123

124-
func (a *ArangoDContainer) GetArgs() ([]string, error) {
124+
func (a *ArangoDContainer) GetCommand() ([]string, error) {
125+
cmd := make([]string, 0, 128)
126+
127+
if args := createArangodNumactl(a.groupSpec); len(args) > 0 {
128+
cmd = append(cmd, args...)
129+
}
130+
131+
cmd = append(cmd, a.GetExecutor())
132+
125133
args, err := createArangodArgs(a.cachedStatus, a.input)
126134
if err != nil {
127135
return nil, err
128136
}
129137

130-
if nmargs := createArangodNumactl(a.groupSpec); len(nmargs) > 0 {
131-
vs := make([]string, len(args)+len(nmargs))
132-
133-
copy(vs, nmargs)
134-
copy(vs[len(nmargs):], args)
135-
136-
return vs, nil
137-
}
138+
cmd = append(cmd, args...)
138139

139-
return args, nil
140+
return cmd, nil
140141
}
141142

142143
func (a *ArangoDContainer) GetName() string {

pkg/deployment/resources/pod_creator_sync.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,11 @@ type MemberSyncPod struct {
8282
cachedStatus interfaces.Inspector
8383
}
8484

85-
func (a *ArangoSyncContainer) GetArgs() ([]string, error) {
86-
return createArangoSyncArgs(a.apiObject, a.spec, a.group, a.groupSpec, a.memberStatus), nil
85+
func (a *ArangoSyncContainer) GetCommand() ([]string, error) {
86+
cmd := make([]string, 0, 128)
87+
cmd = append(cmd, a.GetExecutor())
88+
cmd = append(cmd, createArangoSyncArgs(a.apiObject, a.spec, a.group, a.groupSpec, a.memberStatus)...)
89+
return cmd, nil
8790
}
8891

8992
func (a *ArangoSyncContainer) GetName() string {

pkg/util/k8sutil/interfaces/pod_creator.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// DISCLAIMER
33
//
4-
// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany
4+
// Copyright 2016-2023 ArangoDB GmbH, Cologne, Germany
55
//
66
// Licensed under the Apache License, Version 2.0 (the "License");
77
// you may not use this file except in compliance with the License.
@@ -65,7 +65,7 @@ type PodCreator interface {
6565
}
6666

6767
type ContainerCreator interface {
68-
GetArgs() ([]string, error)
68+
GetCommand() ([]string, error)
6969
GetName() string
7070
GetExecutor() string
7171
GetProbes() (*core.Probe, *core.Probe, *core.Probe, error)

pkg/util/k8sutil/pair.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// DISCLAIMER
33
//
4-
// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany
4+
// Copyright 2016-2023 ArangoDB GmbH, Cologne, Germany
55
//
66
// Licensed under the Apache License, Version 2.0 (the "License");
77
// you may not use this file except in compliance with the License.
@@ -126,6 +126,18 @@ func (o OptionPairs) Sort() OptionPairs {
126126
return o
127127
}
128128

129+
func (o OptionPairs) AsArgsWithCommand(command string) []string {
130+
s := make([]string, len(o)+1)
131+
132+
s[0] = command
133+
134+
for id, pair := range o {
135+
s[id+1] = pair.String()
136+
}
137+
138+
return s
139+
}
140+
129141
func (o OptionPairs) AsArgs() []string {
130142
s := make([]string, len(o))
131143

pkg/util/k8sutil/pods.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,7 @@ func NewContainer(containerCreator interfaces.ContainerCreator) (core.Container,
545545
return core.Container{}, err
546546
}
547547

548-
args, err := containerCreator.GetArgs()
548+
cmd, err := containerCreator.GetCommand()
549549
if err != nil {
550550
return core.Container{}, err
551551
}
@@ -554,7 +554,7 @@ func NewContainer(containerCreator interfaces.ContainerCreator) (core.Container,
554554
return core.Container{
555555
Name: containerCreator.GetName(),
556556
Image: containerCreator.GetImage(),
557-
Command: append([]string{containerCreator.GetExecutor()}, args...),
557+
Command: cmd,
558558
Ports: containerCreator.GetPorts(),
559559
Env: env,
560560
EnvFrom: envFrom,

pkg/util/list.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,14 @@ func (l List[T]) Count(fn func(T) bool) int {
4141
return len(l.Filter(fn))
4242
}
4343

44+
func (l List[T]) Append(items ...T) List[T] {
45+
return append(l, items...)
46+
}
47+
48+
func (l List[T]) List() []T {
49+
return l
50+
}
51+
4452
func (l List[T]) Sort(fn func(T, T) bool) List[T] {
4553
clone := l
4654
sort.Slice(clone, func(i, j int) bool {

0 commit comments

Comments
 (0)