Skip to content

Commit 85fe4aa

Browse files
authored
fix: ruby injector (#247)
* fix ruby injector * add test case
1 parent e3dd6f0 commit 85fe4aa

File tree

2 files changed

+55
-2
lines changed

2 files changed

+55
-2
lines changed

internal/apm/ruby.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package apm
1717

1818
import (
1919
"context"
20+
"strings"
2021

2122
corev1 "k8s.io/api/core/v1"
2223

@@ -85,7 +86,9 @@ func (i *RubyInjector) Inject(ctx context.Context, inst current.Instrumentation,
8586
Value: rubyOptRequire,
8687
})
8788
} else if idx > -1 {
88-
container.Env[idx].Value = container.Env[idx].Value + envRubyOpt
89+
if !strings.Contains(" "+container.Env[idx].Value+" ", " "+rubyOptRequire+" ") {
90+
container.Env[idx].Value = container.Env[idx].Value + " " + rubyOptRequire
91+
}
8992
}
9093

9194
if isContainerVolumeMissing(container, volumeName) {

internal/apm/ruby_test.go

+51-1
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,62 @@ func TestRubyInjector_Inject(t *testing.T) {
9595
}},
9696
inst: current.Instrumentation{Spec: current.InstrumentationSpec{Agent: current.Agent{Language: "ruby"}, LicenseKeySecret: "newrelic-key-secret"}},
9797
},
98+
{
99+
name: "a container, instrumentation, existing RUBYOPT",
100+
pod: corev1.Pod{Spec: corev1.PodSpec{Containers: []corev1.Container{
101+
{
102+
Name: "test",
103+
Env: []corev1.EnvVar{
104+
{
105+
Name: "RUBYOPT",
106+
Value: "-r fakelib",
107+
},
108+
},
109+
},
110+
}}},
111+
expectedPod: corev1.Pod{
112+
ObjectMeta: metav1.ObjectMeta{
113+
Labels: map[string]string{
114+
DescK8sAgentOperatorVersionLabelName: version.Get().Operator,
115+
},
116+
Annotations: map[string]string{
117+
"newrelic.com/instrumentation-versions": `{"/":"/0"}`,
118+
},
119+
}, Spec: corev1.PodSpec{
120+
Containers: []corev1.Container{{
121+
Name: "test",
122+
Env: []corev1.EnvVar{
123+
{Name: "RUBYOPT", Value: "-r fakelib -r /newrelic-instrumentation/lib/boot/strap"},
124+
{Name: "NEW_RELIC_APP_NAME", Value: "test"},
125+
{Name: "NEW_RELIC_LABELS", Value: "operator:auto-injection"},
126+
{Name: "NEW_RELIC_K8S_OPERATOR_ENABLED", Value: "true"},
127+
{Name: "NEW_RELIC_LICENSE_KEY", ValueFrom: &corev1.EnvVarSource{SecretKeyRef: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "newrelic-key-secret"}, Key: "new_relic_license_key", Optional: &vtrue}}},
128+
},
129+
VolumeMounts: []corev1.VolumeMount{{Name: "newrelic-instrumentation", MountPath: "/newrelic-instrumentation"}},
130+
}},
131+
InitContainers: []corev1.Container{{
132+
Name: "newrelic-instrumentation-ruby",
133+
Command: []string{"cp", "-a", "/instrumentation/.", "/newrelic-instrumentation/"},
134+
VolumeMounts: []corev1.VolumeMount{{Name: "newrelic-instrumentation", MountPath: "/newrelic-instrumentation"}},
135+
}},
136+
Volumes: []corev1.Volume{{Name: "newrelic-instrumentation", VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}}}},
137+
}},
138+
inst: current.Instrumentation{Spec: current.InstrumentationSpec{Agent: current.Agent{Language: "ruby"}, LicenseKeySecret: "newrelic-key-secret"}},
139+
},
98140
}
99141
for _, test := range tests {
100142
t.Run(test.name, func(t *testing.T) {
101143
ctx := context.Background()
102144
i := &RubyInjector{}
103-
actualPod, err := i.Inject(ctx, test.inst, test.ns, test.pod)
145+
// inject multiple times to assert that it's idempotent
146+
var err error
147+
var actualPod corev1.Pod
148+
for ic := 0; ic < 3; ic++ {
149+
actualPod, err = i.Inject(ctx, test.inst, test.ns, test.pod)
150+
if err != nil {
151+
break
152+
}
153+
}
104154
errStr := ""
105155
if err != nil {
106156
errStr = err.Error()

0 commit comments

Comments
 (0)