Skip to content

Commit 86c04d2

Browse files
authored
Merge branch 'main' into avara1986-patch-1
2 parents dd5c44c + c43d2b2 commit 86c04d2

File tree

6 files changed

+111
-38
lines changed

6 files changed

+111
-38
lines changed

Dockerfile

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,22 @@ RUN rm -rf ./python/lib/$runtime/site-packages/ddtrace/appsec/_iast
3737
RUN rm -rf ./python/lib/$runtime/site-packages/ddtrace/appsec/sca
3838
RUN rm -rf ./python/lib/$runtime/site-packages/ddtrace/appsec/_shared
3939
RUN rm -rf ./python/lib/$runtime/site-packages/ddtrace/internal/test_visibility
40+
41+
# CI Visibility paths/integrations
42+
RUN rm -rf \
43+
./python/lib/$runtime/site-packages/ddtrace/contrib/coverage/ \
44+
./python/lib/$runtime/site-packages/ddtrace/contrib/pytest/ \
45+
./python/lib/$runtime/site-packages/ddtrace/contrib/pytest_bdd/ \
46+
./python/lib/$runtime/site-packages/ddtrace/contrib/pytest_benchmark/ \
47+
./python/lib/$runtime/site-packages/ddtrace/contrib/selenium/ \
48+
./python/lib/$runtime/site-packages/ddtrace/contrib/unittest/ \
49+
./python/lib/$runtime/site-packages/ddtrace/ext/ci_visibility \
50+
./python/lib/$runtime/site-packages/ddtrace/ext/test_visibility \
51+
./python/lib/$runtime/site-packages/ddtrace/internal/ci_visibility \
52+
./python/lib/$runtime/site-packages/ddtrace/internal/coverage \
53+
./python/lib/$runtime/site-packages/ddtrace/internal/test_visibility \
54+
./python/lib/$runtime/site-packages/ddtrace/testing/
55+
4056
# Dogshell
4157
RUN rm -rf ./python/lib/$runtime/site-packages/datadog/dogshell
4258
RUN rm -rf ./python/lib/$runtime/site-packages/bin/dog*
@@ -64,10 +80,18 @@ RUN rm -rf \
6480
# https://docs.python.org/3.11/using/cmdline.html#cmdoption-O
6581
# https://docs.python.org/3/using/cmdline.html#envvar-PYTHONNODEBUGRANGES
6682
RUN PYTHONNODEBUGRANGES=1 python -OO -m compileall -b ./python/lib/$runtime/site-packages
67-
# remove all .py files except ddtrace/contrib/*/patch.py which are necessary
68-
# for ddtrace.patch to discover instrumationation packages.
69-
RUN find ./python/lib/$runtime/site-packages -name \*.py | grep -v ddtrace/contrib | xargs rm -rf
70-
RUN find ./python/lib/$runtime/site-packages/ddtrace/contrib -name \*.py | grep -v patch.py | xargs rm -rf
83+
# remove all .py files
84+
# DEV: ddtrace>=4.7.0rc3 checks for .pyc files in addition to .py files for instrumentation
85+
# discovery (DataDog/dd-trace-py#17196), so we can safely remove all .py files.
86+
# For older versions, we need to keep patch.py files for instrumentation discovery.
87+
RUN pip install --quiet packaging && \
88+
DDTRACE_VERSION=$(grep "^Version:" ./python/lib/$runtime/site-packages/ddtrace-*.dist-info/METADATA | awk '{print $2}') && \
89+
if python -c "from packaging.version import Version; exit(0 if Version('$DDTRACE_VERSION') >= Version('4.7.0rc3') else 1)"; then \
90+
find ./python/lib/$runtime/site-packages -name \*.py | xargs rm -rf; \
91+
else \
92+
find ./python/lib/$runtime/site-packages -name \*.py | grep -v ddtrace/contrib | xargs rm -rf && \
93+
find ./python/lib/$runtime/site-packages/ddtrace/contrib -name \*.py | grep -v patch.py | xargs rm -rf; \
94+
fi
7195
RUN find ./python/lib/$runtime/site-packages -name __pycache__ -type d -exec rm -r {} \+
7296

7397
# When building ddtrace from branch, remove extra source files. These are

ci/get_secrets.sh

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,11 @@ fi
2121

2222
printf "Getting AWS External ID...\n"
2323

24-
EXTERNAL_ID=$(aws ssm get-parameter \
25-
--region us-east-1 \
26-
--name "ci.datadog-lambda-python.$EXTERNAL_ID_NAME" \
27-
--with-decryption \
28-
--query "Parameter.Value" \
29-
--out text)
24+
EXTERNAL_ID=$(vault kv get -field="$EXTERNAL_ID_NAME" kv/k8s/gitlab-runner/datadog-lambda-python/secrets)
3025

3126
printf "Getting DD API KEY...\n"
3227

33-
export DD_API_KEY=$(aws ssm get-parameter \
34-
--region us-east-1 \
35-
--name ci.datadog-lambda-python.dd-api-key \
36-
--with-decryption \
37-
--query "Parameter.Value" \
38-
--out text)
28+
export DD_API_KEY=$(vault kv get -field=dd-api-key kv/k8s/gitlab-runner/datadog-lambda-python/secrets)
3929

4030
printf "Assuming role...\n"
4131

datadog_lambda/durable.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,17 @@ def extract_durable_function_tags(event):
4141
if not parsed:
4242
logger.error("Failed to parse DurableExecutionArn: %s", durable_execution_arn)
4343
return {}
44-
4544
execution_name, execution_id = parsed
45+
# Use the number of operations to determine if it's the first invocation. This is
46+
# what the durable execution SDK does to determine the replay status.
47+
operations = event.get("InitialExecutionState", {}).get("Operations", [])
48+
is_first_invocation = len(operations) == 1
4649
return {
47-
"durable_function_execution_name": execution_name,
48-
"durable_function_execution_id": execution_id,
50+
"aws_lambda.durable_function.execution_name": execution_name,
51+
"aws_lambda.durable_function.execution_id": execution_id,
52+
"aws_lambda.durable_function.first_invocation": str(
53+
is_first_invocation
54+
).lower(),
4955
}
5056

5157

scripts/build_layers.sh

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -91,29 +91,49 @@ trap cleanup EXIT
9191
# Helper: replace the multi-line ddtrace dependency in pyproject.toml.
9292
# Uses perl instead of sed -z for macOS/Linux portability.
9393
replace_ddtrace_dep() {
94+
echo "Replacing dep with $1"
9495
perl -i -0777 -pe "s|ddtrace = \[[^\]]*\]|$1|gs" pyproject.toml
9596
}
9697

9798
function make_path_absolute {
9899
echo "$(cd "$(dirname "$1")"; pwd)/$(basename "$1")"
99100
}
100101

101-
function docker_build_zip {
102-
# Args: [python version] [zip destination]
102+
function search_wheel {
103+
# Args: [wheel base name] [index]
103104

104-
destination=$(make_path_absolute $2)
105-
arch=$3
105+
WHEEL_BASENAME=$1
106+
INDEX=$2
107+
108+
SEARCH_PATTERN="${WHEEL_BASENAME}-[^\"]*${PY_TAG}[^\"]*${PLATFORM}[^\"]*\.whl"
109+
INDEX_URL="${S3_BASE}/index-${INDEX}.html"
110+
echo "Searching for wheel ${SEARCH_PATTERN}"
111+
export WHEEL_FILE=$(curl -sSfL ${INDEX_URL} | grep -o "$SEARCH_PATTERN" | head -n 1)
112+
if [ ! -z "${WHEEL_FILE}" ]; then
113+
curl -sSfL "${S3_BASE}/${WHEEL_FILE}" -o "${WHEEL_FILE}"
114+
echo "Using S3 wheel: ${WHEEL_FILE}"
115+
replace_ddtrace_dep "${WHEEL_BASENAME} = { file = \"${WHEEL_FILE}\" }"
116+
fi
117+
}
118+
119+
function find_and_spec_wheel {
120+
# Args: [python version] [wheel base name] [index]
121+
122+
arch=$2
123+
wheel_basename=$3
124+
index=$4
106125

107126
# Restore pyproject.toml to a clean state for each build iteration
108127
cp pyproject.toml.bak pyproject.toml
109128

110129
# Replace ddtrace source if necessary
111130
if [ -n "$DD_TRACE_COMMIT" ]; then
112-
replace_ddtrace_dep "ddtrace = { git = \"https://github.com/DataDog/dd-trace-py.git\", rev = \"$DD_TRACE_COMMIT\" }"
131+
replace_ddtrace_dep "${wheel_basename} = { git = \"https://github.com/DataDog/dd-trace-py.git\", rev = \"$DD_TRACE_COMMIT\" }"
113132
elif [ -n "$DD_TRACE_COMMIT_BRANCH" ]; then
114-
replace_ddtrace_dep "ddtrace = { git = \"https://github.com/DataDog/dd-trace-py.git\", branch = \"$DD_TRACE_COMMIT_BRANCH\" }"
133+
replace_ddtrace_dep "${wheel_basename} = { git = \"https://github.com/DataDog/dd-trace-py.git\", branch = \"$DD_TRACE_COMMIT_BRANCH\" }"
115134
elif [ -n "$DD_TRACE_WHEEL" ]; then
116-
replace_ddtrace_dep "ddtrace = { file = \"$DD_TRACE_WHEEL\" }"
135+
wheel_basename=$(sed 's/^.*\///' <<< ${DD_TRACE_WHEEL%%-*})
136+
replace_ddtrace_dep "${wheel_basename} = { file = \"$DD_TRACE_WHEEL\" }"
117137
elif [ -n "$UPSTREAM_PIPELINE_ID" ]; then
118138
S3_BASE="https://dd-trace-py-builds.s3.amazonaws.com/${UPSTREAM_PIPELINE_ID}"
119139
if [ "${arch}" = "amd64" ]; then
@@ -122,18 +142,19 @@ function docker_build_zip {
122142
PLATFORM="manylinux2014_aarch64"
123143
fi
124144
PY_TAG="cp$(echo "$1" | tr -d '.')"
125-
WHEEL_FILE=$(curl -sSfL "${S3_BASE}/index-manylinux2014.html" \
126-
| grep -o "ddtrace-[^\"]*${PY_TAG}[^\"]*${PLATFORM}[^\"]*\.whl" \
127-
| head -n 1)
145+
search_wheel ${wheel_basename} ${index}
128146
if [ -z "${WHEEL_FILE}" ]; then
129147
echo "No S3 wheel found for ${PY_TAG} ${PLATFORM}, using default pyproject.toml version"
130-
else
131-
curl -sSfL "${S3_BASE}/${WHEEL_FILE}" -o "${WHEEL_FILE}"
132-
echo "Using S3 wheel: ${WHEEL_FILE}"
133-
replace_ddtrace_dep "ddtrace = { file = \"${WHEEL_FILE}\" }"
148+
return 1
134149
fi
135150
fi
151+
}
152+
153+
function docker_build_zip {
154+
# Args: [python version] [zip destination]
136155

156+
destination=$(make_path_absolute $2)
157+
arch=$3
137158
# Install datadogpy in a docker container to avoid the mess from switching
138159
# between different python runtimes.
139160
temp_dir=$(mktemp -d)
@@ -159,6 +180,14 @@ do
159180
for architecture in "${ARCHS[@]}"
160181
do
161182
echo "Building layer for Python ${python_version} arch=${architecture}"
183+
set +e
184+
find_and_spec_wheel ${python_version} ${architecture} "ddtrace_serverless" "serverless"
185+
FAILURE=$?
186+
if [ $FAILURE != 0 ]; then
187+
echo "Attempting layer build again with package ddtrace"
188+
find_and_spec_wheel ${python_version} ${architecture} "ddtrace" "manylinux2014"
189+
fi
190+
set -e
162191
docker_build_zip ${python_version} $LAYER_DIR/${LAYER_FILES_PREFIX}-${architecture}-${python_version}.zip ${architecture}
163192
done
164193
done

scripts/check_layer_size.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
# Compares layer size to threshold, and fails if below that threshold
99

1010
set -e
11-
MAX_LAYER_COMPRESSED_SIZE_KB=$(expr 9 \* 1024) # 9216 KB
11+
MAX_LAYER_COMPRESSED_SIZE_KB=$(expr 9 \* 1024 + 15) # 9231 KB
1212
MAX_LAYER_UNCOMPRESSED_SIZE_KB=$(expr 25 \* 1024) # 25600 KB
1313

1414

tests/test_durable.py

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,18 +46,42 @@ def test_works_with_numeric_version_qualifier(self):
4646

4747

4848
class TestExtractDurableFunctionTags(unittest.TestCase):
49-
def test_extracts_tags_from_event_with_durable_execution_arn(self):
49+
def test_sets_first_invocation_true_when_only_execution_operation(self):
50+
# One operation (the current EXECUTION operation itself) → not replaying → first invocation
5051
event = {
5152
"DurableExecutionArn": "arn:aws:lambda:us-east-1:123456789012:function:my-func:1/durable-execution/my-execution/550e8400-e29b-41d4-a716-446655440004",
5253
"CheckpointToken": "some-token",
53-
"InitialExecutionState": {"Operations": []},
54+
"InitialExecutionState": {"Operations": [{"OperationType": "EXECUTION"}]},
5455
}
5556
result = extract_durable_function_tags(event)
5657
self.assertEqual(
5758
result,
5859
{
59-
"durable_function_execution_name": "my-execution",
60-
"durable_function_execution_id": "550e8400-e29b-41d4-a716-446655440004",
60+
"aws_lambda.durable_function.execution_name": "my-execution",
61+
"aws_lambda.durable_function.execution_id": "550e8400-e29b-41d4-a716-446655440004",
62+
"aws_lambda.durable_function.first_invocation": "true",
63+
},
64+
)
65+
66+
def test_sets_first_invocation_false_when_multiple_operations(self):
67+
# More than one operation → replaying → not first invocation
68+
event = {
69+
"DurableExecutionArn": "arn:aws:lambda:us-east-1:123456789012:function:my-func:1/durable-execution/my-execution/550e8400-e29b-41d4-a716-446655440004",
70+
"CheckpointToken": "some-token",
71+
"InitialExecutionState": {
72+
"Operations": [
73+
{"OperationType": "EXECUTION"},
74+
{"OperationType": "STEP"},
75+
]
76+
},
77+
}
78+
result = extract_durable_function_tags(event)
79+
self.assertEqual(
80+
result,
81+
{
82+
"aws_lambda.durable_function.execution_name": "my-execution",
83+
"aws_lambda.durable_function.execution_id": "550e8400-e29b-41d4-a716-446655440004",
84+
"aws_lambda.durable_function.first_invocation": "false",
6185
},
6286
)
6387

0 commit comments

Comments
 (0)