Skip to content

Commit 4b2aead

Browse files
committed
feat: add musl build to python autoinstrumentation
1 parent 1ebbc2e commit 4b2aead

File tree

11 files changed

+249
-26
lines changed

11 files changed

+249
-26
lines changed

README.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -250,8 +250,13 @@ instrumentation.opentelemetry.io/inject-nodejs: "true"
250250
```
251251

252252
Python:
253+
Python auto-instrumentation also honors an annotation that will be used to set Python runtime C library implementation.
254+
Currently, two C library implementations are supported: `linux-x64` and `linux-musl-x64`.
255+
By default `linux-x64` is used.
253256
```bash
254-
instrumentation.opentelemetry.io/inject-python: "true"
257+
instrumentation.opentelemetry.io/inject-: "true"
258+
instrumentation.opentelemetry.io/otel-python-auto-runtime: "linux-x64" # for Linux glibc based images, this is default value and can be omitted
259+
instrumentation.opentelemetry.io/otel-python-auto-runtime: "linux-musl-x64" # for Linux musl based images
255260
```
256261

257262
.NET:

autoinstrumentation/python/Dockerfile

+12-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
# - Grant the necessary access to `/autoinstrumentation` directory. `chmod -R go+r /autoinstrumentation`
1010
# - For auto-instrumentation by container injection, the Linux command cp is
1111
# used and must be availabe in the image.
12+
# - Please note that we build twice. First time for environments with libc and second time with musl C implementations
1213
FROM python:3.11 AS build
1314

1415
WORKDIR /operator-build
@@ -17,8 +18,18 @@ ADD requirements.txt .
1718

1819
RUN mkdir workspace && pip install --target workspace -r requirements.txt
1920

21+
FROM python:3.11-alpine AS build-musl
22+
23+
WORKDIR /operator-build
24+
25+
ADD requirements.txt .
26+
27+
RUN apk add --update --no-cache gcc musl-dev linux-headers
28+
RUN mkdir workspace && pip install --target workspace -r requirements.txt
29+
2030
FROM busybox
2131

22-
COPY --from=build /operator-build/workspace /autoinstrumentation
32+
COPY --from=build /operator-build/workspace /autoinstrumentation/linux-x64
33+
COPY --from=build-musl /operator-build/workspace /autoinstrumentation/linux-musl-x64
2334

2435
RUN chmod -R go+r /autoinstrumentation

pkg/instrumentation/annotation.go

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ const (
2929
annotationInjectNodeJS = "instrumentation.opentelemetry.io/inject-nodejs"
3030
annotationInjectNodeJSContainersName = "instrumentation.opentelemetry.io/nodejs-container-names"
3131
annotationInjectPython = "instrumentation.opentelemetry.io/inject-python"
32+
annotationPythonRuntime = "instrumentation.opentelemetry.io/otel-python-auto-runtime"
3233
annotationInjectPythonContainersName = "instrumentation.opentelemetry.io/python-container-names"
3334
annotationInjectDotNet = "instrumentation.opentelemetry.io/inject-dotnet"
3435
annotationDotNetRuntime = "instrumentation.opentelemetry.io/otel-dotnet-auto-runtime"

pkg/instrumentation/podmutator.go

+1
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ func (pm *instPodMutator) Mutate(ctx context.Context, ns corev1.Namespace, pod c
252252
}
253253
if featuregate.EnablePythonAutoInstrumentationSupport.IsEnabled() || inst == nil {
254254
insts.Python.Instrumentation = inst
255+
insts.Python.AdditionalAnnotations = map[string]string{annotationPythonRuntime: annotationValue(ns.ObjectMeta, pod.ObjectMeta, annotationPythonRuntime)}
255256
} else {
256257
logger.Error(nil, "support for Python auto instrumentation is not enabled")
257258
pm.Recorder.Event(pod.DeepCopy(), "Warning", "InstrumentationRequestRejected", "support for Python auto instrumentation is not enabled")

pkg/instrumentation/podmutator_test.go

+7-7
Original file line numberDiff line numberDiff line change
@@ -1205,7 +1205,7 @@ func TestMutatePod(t *testing.T) {
12051205
},
12061206
{
12071207
Name: "PYTHONPATH",
1208-
Value: fmt.Sprintf("%s:%s", pythonPathPrefix, pythonPathSuffix),
1208+
Value: fmt.Sprintf("%s:%s", pythonPathGlibcPrefix, pythonPathGlibcSuffix),
12091209
},
12101210
{
12111211
Name: "OTEL_EXPORTER_OTLP_TRACES_PROTOCOL",
@@ -1393,7 +1393,7 @@ func TestMutatePod(t *testing.T) {
13931393
},
13941394
{
13951395
Name: "PYTHONPATH",
1396-
Value: fmt.Sprintf("%s:%s", pythonPathPrefix, pythonPathSuffix),
1396+
Value: fmt.Sprintf("%s:%s", pythonPathGlibcPrefix, pythonPathGlibcSuffix),
13971397
},
13981398
{
13991399
Name: "OTEL_EXPORTER_OTLP_TRACES_PROTOCOL",
@@ -1472,7 +1472,7 @@ func TestMutatePod(t *testing.T) {
14721472
},
14731473
{
14741474
Name: "PYTHONPATH",
1475-
Value: fmt.Sprintf("%s:%s", pythonPathPrefix, pythonPathSuffix),
1475+
Value: fmt.Sprintf("%s:%s", pythonPathGlibcPrefix, pythonPathGlibcSuffix),
14761476
},
14771477
{
14781478
Name: "OTEL_EXPORTER_OTLP_TRACES_PROTOCOL",
@@ -3743,7 +3743,7 @@ func TestMutatePod(t *testing.T) {
37433743
},
37443744
{
37453745
Name: "PYTHONPATH",
3746-
Value: fmt.Sprintf("%s:%s", pythonPathPrefix, pythonPathSuffix),
3746+
Value: fmt.Sprintf("%s:%s", pythonPathGlibcPrefix, pythonPathGlibcSuffix),
37473747
},
37483748
{
37493749
Name: "OTEL_TRACES_EXPORTER",
@@ -3806,7 +3806,7 @@ func TestMutatePod(t *testing.T) {
38063806
},
38073807
{
38083808
Name: "PYTHONPATH",
3809-
Value: fmt.Sprintf("%s:%s", pythonPathPrefix, pythonPathSuffix),
3809+
Value: fmt.Sprintf("%s:%s", pythonPathGlibcPrefix, pythonPathGlibcSuffix),
38103810
},
38113811
{
38123812
Name: "OTEL_TRACES_EXPORTER",
@@ -4401,7 +4401,7 @@ func TestMutatePod(t *testing.T) {
44014401
},
44024402
{
44034403
Name: "PYTHONPATH",
4404-
Value: fmt.Sprintf("%s:%s", pythonPathPrefix, pythonPathSuffix),
4404+
Value: fmt.Sprintf("%s:%s", pythonPathGlibcPrefix, pythonPathGlibcSuffix),
44054405
},
44064406
{
44074407
Name: "OTEL_TRACES_EXPORTER",
@@ -4464,7 +4464,7 @@ func TestMutatePod(t *testing.T) {
44644464
},
44654465
{
44664466
Name: "PYTHONPATH",
4467-
Value: fmt.Sprintf("%s:%s", pythonPathPrefix, pythonPathSuffix),
4467+
Value: fmt.Sprintf("%s:%s", pythonPathGlibcPrefix, pythonPathGlibcSuffix),
44684468
},
44694469
{
44704470
Name: "OTEL_TRACES_EXPORTER",

pkg/instrumentation/python.go

+23-3
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,21 @@ const (
2828
envOtelMetricsExporter = "OTEL_METRICS_EXPORTER"
2929
envOtelExporterOTLPTracesProtocol = "OTEL_EXPORTER_OTLP_TRACES_PROTOCOL"
3030
envOtelExporterOTLPMetricsProtocol = "OTEL_EXPORTER_OTLP_METRICS_PROTOCOL"
31-
pythonPathPrefix = "/otel-auto-instrumentation-python/opentelemetry/instrumentation/auto_instrumentation"
32-
pythonPathSuffix = "/otel-auto-instrumentation-python"
31+
pythonPathGlibcPrefix = "/otel-auto-instrumentation-python/linux-x64/opentelemetry/instrumentation/auto_instrumentation"
32+
pythonPathGlibcSuffix = "/otel-auto-instrumentation-python/linux-x64"
33+
pythonPathMuslPrefix = "/otel-auto-instrumentation-python/linux-musl-x64/opentelemetry/instrumentation/auto_instrumentation"
34+
pythonPathMuslSuffix = "/otel-auto-instrumentation-python/linux-musl-x64"
3335
pythonInstrMountPath = "/otel-auto-instrumentation-python"
3436
pythonVolumeName = volumeName + "-python"
3537
pythonInitContainerName = initContainerName + "-python"
3638
)
3739

38-
func injectPythonSDK(pythonSpec v1alpha1.Python, pod corev1.Pod, index int) (corev1.Pod, error) {
40+
const (
41+
pythonRuntimeLinuxGlibc = "linux-x64"
42+
pythonRuntimeLinuxMusl = "linux-musl-x64"
43+
)
44+
45+
func injectPythonSDK(pythonSpec v1alpha1.Python, pod corev1.Pod, index int, runtime string) (corev1.Pod, error) {
3946
// caller checks if there is at least one container.
4047
container := &pod.Spec.Containers[index]
4148

@@ -44,6 +51,19 @@ func injectPythonSDK(pythonSpec v1alpha1.Python, pod corev1.Pod, index int) (cor
4451
return pod, err
4552
}
4653

54+
pythonPathPrefix := ""
55+
pythonPathSuffix := ""
56+
switch runtime {
57+
case "", pythonRuntimeLinuxGlibc:
58+
pythonPathPrefix = pythonPathGlibcPrefix
59+
pythonPathSuffix = pythonPathGlibcSuffix
60+
case pythonRuntimeLinuxMusl:
61+
pythonPathPrefix = pythonPathMuslPrefix
62+
pythonPathSuffix = pythonPathMuslSuffix
63+
default:
64+
return pod, fmt.Errorf("provided instrumentation.opentelemetry.io/otel-python-auto-runtime annotation value '%s' is not supported", runtime)
65+
}
66+
4767
// inject Python instrumentation spec env vars.
4868
for _, env := range pythonSpec.Env {
4969
idx := getIndexOfEnv(container.Env, env.Name)

0 commit comments

Comments
 (0)