Skip to content

Commit a6648d8

Browse files
authored
Merge branch 'rust-serverless:master' into master
2 parents 9bd4d6d + 7f24954 commit a6648d8

File tree

3 files changed

+107
-78
lines changed

3 files changed

+107
-78
lines changed

README.md

Lines changed: 30 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
# AWS Lambda [Rust](https://www.rust-lang.org/) docker builder 🐑 🦀 🐳 [![Build Status](https://github.com/rust-serverless/lambda-rust/workflows/Main/badge.svg)](https://github.com/rust-serverless/lambda-rust/actions)
22

3-
43
## 🤔 about
54

6-
This docker image extends AWS Lambda `provided.al2 runtime environment, and installs [rustup](https://rustup.rs/) and the *stable* rust toolchain.
5+
This docker image extends AWS Lambda `provided.al2` runtime environment, and installs [rustup](https://rustup.rs/) and the *stable* rust toolchain.
76

87
This provides a build environment, consistent with your target execution environment for predictable results.
98

@@ -24,7 +23,7 @@ The default docker entrypoint will build a packaged release optimized version of
2423
isolate the lambda specific build artifacts from your host-local build artifacts.
2524

2625
> **⚠️ Note:** you can switch from the `release` profile to a custom profile like `dev` by providing a `PROFILE` environment variable set to the name of the desired profile. i.e. `-e PROFILE=dev` in your docker run
27-
26+
>
2827
> **⚠️ Note:** you can include debug symbols in optimized release build binaries by setting `DEBUGINFO`. By default, debug symbols will be stripped from the release binary and set aside in a separate .debug file.
2928
3029
You will want to volume mount `/code` to the directory containing your cargo project.
@@ -40,15 +39,16 @@ A typical docker run might look like the following.
4039

4140
```sh
4241
$ docker run --rm \
43-
-u $(id -u):$(id -g) \
42+
-u "$(id -u)":"$(id -g)" \
4443
-v ${PWD}:/code \
4544
-v ${HOME}/.cargo/registry:/cargo/registry \
4645
-v ${HOME}/.cargo/git:/cargo/git \
4746
rustserverless/lambda-rust
4847
```
48+
4949
> 💡 The -v (volume mount) flags for `/cargo/{registry,git}` are optional but when supplied, provides a much faster turn around when doing iterative development
5050
51-
Note that `-u $(id -u):$(id -g)` argument is crucial for the container to produce artifacts
51+
Note that `-u "$(id -u)":$(id -g)` argument is crucial for the container to produce artifacts
5252
owned by the current host user, otherwise you won't be able to `rm -rf target/lambda`
5353
or run `cargo update`, because the container will write artifacts owned by `root` docker user
5454
to `target/lambda` and `./cargo/{registry,git}` dirs which will break your dev and/or ci environment.
@@ -86,8 +86,9 @@ $ docker run --rm \
8686

8787
## ⚓ using hooks
8888

89-
If you want to customize certain parts of the build process, you can leverage hooks that this image provides.
90-
Hooks are just shell scripts that are invoked in a specific order, so you can customize the process as you wish. The following hooks exist:
89+
You can leverage hooks provided in the image to customize certain parts of the build process.
90+
Hooks are shell scripts that are invoked if they exist, so you can customize the process. The following hooks exist:
91+
9192
* `install`: run before `cargo build` - useful for installing native dependencies on the lambda environment
9293
* `build`: run after `cargo build`, but before packaging the executable into a zip - useful when modifying the executable after compilation
9394
* `package`: run after packaging the executable into a zip - useful for adding extra files into the zip file
@@ -121,56 +122,33 @@ docker run \
121122
-v ${HOME}/.cargo/git:/cargo/git \
122123
rustserverless/lambda-rust
123124

124-
# start a one-off docker container replicating the "provided.al2" lambda runtime
125-
# awaiting an event to be provided via stdin
126-
$ docker run \
127-
-i -e DOCKER_LAMBDA_USE_STDIN=1 \
128-
--rm \
129-
-v ${PWD}/target/lambda/release/output/{your-binary-name}:/var/task:ro,delegated \
130-
public.ecr.aws/lambda/provided:al2
131-
132-
# provide an event payload via stdin (typically a json blob)
125+
# Build a container with your binary as the runtime
133126

134-
# Ctrl-D to yield control back to your function
135-
```
127+
$ docker build -t mylambda -f- . <<EOF
128+
FROM public.ecr.aws/lambda/provided:al2
129+
COPY bootstrap /var/runtime
130+
CMD [ "function.handler" ]
131+
EOF
136132

137-
You may find the one-off container less than ideal if you wish to trigger your lambda multiple times. For these cases try using the "stay open" mode of execution.
138-
139-
```sh
140-
# start a long running docker container replicating the "provided" lambda runtime
141-
# listening on port 9001
142-
$ unzip -o \
143-
target/lambda/release/{your-binary-name}.zip \
144-
-d /tmp/lambda && \
145-
docker run \
146-
--rm \
147-
-v /tmp/lambda:/var/task:ro,delegated \
148-
-e DOCKER_LAMBDA_STAY_OPEN=1 \
149-
-p 9001:9001 \
150-
public.ecr.aws/lambda/provided:al2
151-
```
133+
# start a container based on your image
134+
$ docker run \
135+
--name lambda \
136+
--rm \
137+
-p 9000:8080 \
138+
-d mylambda
152139

153-
In a separate terminal, you can invoke your function with `curl`
140+
# provide an event payload (in event.json" by http POST to the container
154141

155-
The `-d` flag is a means of providing your function's input.
142+
$ curl -X POST \
143+
-H "Content-Type: application/json" \
144+
-d "@event.json" \
145+
"http://localhost:9000/2015-03-31/functions/function/invocations"
156146

157-
```sh
158-
$ curl -d '{}' \
159-
http://localhost:9001/2015-03-31/functions/myfunction/invocations
147+
# Stop the container
148+
$ docker container stop lambda
160149
```
161150

162-
You can also use the `aws` cli to invoke your function locally. The `--payload` is a means of providing your function's input.
163-
164-
```sh
165-
$ aws lambda invoke \
166-
--endpoint http://localhost:9001 \
167-
--cli-binary-format raw-in-base64-out \
168-
--no-sign-request \
169-
--function-name myfunction \
170-
--payload '{}' out.json \
171-
&& cat out.json \
172-
&& rm -f out.json
173-
```
151+
You may submit multiple events to the same container.
174152

175153
## 🤸🤸 usage via cargo aws-lambda subcommand
176154

@@ -184,17 +162,17 @@ $ cargo install cargo-aws-lambda
184162
```
185163

186164
To compile and deploy in your project directory
165+
187166
```sh
188167
$ cargo aws-lambda {your aws function's full ARN} {your-binary-name}
189168
```
190169
191170
To list all options
171+
192172
```sh
193173
$ cargo aws-lambda --help
194174
```
195175
196176
More instructions can be found [here](https://github.com/vvilhonen/cargo-aws-lambda).
197177
198-
199178
Doug Tangren ([softprops](https://github.com/softprops)) 2020, Alexander Zaitsev ([zamazan4ik](https://github.com/zamazan4ik)) 2021
200-

latest.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ source /cargo/env
88

99
rustup toolchain install stable --profile=minimal
1010
STABLE=$(rustup check | grep stable | grep -E "[0-9]+\.[0-9]+\.[0-9]+" -o)
11-
DEFAULT=$(rustup show | grep -m 1 default | grep -E "[0-9]+\.[0-9]+\.[0-9]+" -o)
11+
DEFAULT=$(rustup show | grep -m 1 rustc | grep -E "[0-9]+\.[0-9]+\.[0-9]+" -o)
1212

1313
if [ "${STABLE}" == "${DEFAULT}" ]; then exit 0
1414
else exit 1
1515
fi
16+

tests/test.sh

Lines changed: 75 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
# Directory of the integration test
44
HERE="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
5-
# Root directory of the repository
6-
DIST=$(cd "$HERE"/..; pwd)
75
: "${IMAGE:=rustserverless/lambda-rust}"
86

97
source "${HERE}"/bashtest.sh
@@ -12,12 +10,12 @@ source "${HERE}"/bashtest.sh
1210
package_bin() {
1311
rm -rf target/lambda/release > /dev/null 2>&1
1412
docker run --rm \
15-
-u $(id -u):$(id -g) \
13+
-u "$(id -u)":"$(id -g)" \
1614
-e BIN="$1" \
1715
-v "${PWD}":/code \
1816
-v "${HOME}"/.cargo/registry:/cargo/registry \
1917
-v "${HOME}"/.cargo/git:/cargo/git \
20-
${IMAGE} && \
18+
"${IMAGE}" && \
2119
ls target/lambda/release/"${1}".zip > /dev/null 2>&1 &&
2220
ls target/lambda/release/output/"${1}"/bootstrap 2>&1 &&
2321
ls target/lambda/release/output/"${1}"/bootstrap.debug 2>&1
@@ -27,11 +25,11 @@ package_bin() {
2725
package_all() {
2826
rm -rf target/lambda/release > /dev/null 2>&1
2927
docker run --rm \
30-
-u $(id -u):$(id -g) \
28+
-u "$(id -u)":"$(id -g)" \
3129
-v "${PWD}":/code \
3230
-v "${HOME}"/.cargo/registry:/cargo/registry \
3331
-v "${HOME}"/.cargo/git:/cargo/git \
34-
${IMAGE} && \
32+
"${IMAGE}" && \
3533
ls target/lambda/release/"${1}".zip > /dev/null 2>&1 &&
3634
ls target/lambda/release/output/"${1}"/bootstrap 2>&1 &&
3735
ls target/lambda/release/output/"${1}"/bootstrap.debug 2>&1
@@ -41,13 +39,13 @@ package_all() {
4139
compile_without_packaging() {
4240
rm -rf target/lambda/release > /dev/null 2>&1
4341
docker run --rm \
44-
-u $(id -u):$(id -g) \
42+
-u "$(id -u)":"$(id -g)" \
4543
-e PACKAGE=false \
4644
-v "${PWD}":/code \
4745
-v "${HOME}"/.cargo/registry:/cargo/registry \
4846
-v "${HOME}"/.cargo/git:/cargo/git \
49-
${IMAGE} &&
50-
!(ls target/lambda/release/"${1}".zip > /dev/null 2>&1) &&
47+
"${IMAGE}" &&
48+
! (ls target/lambda/release/"${1}".zip > /dev/null 2>&1) &&
5149
ls target/lambda/release/output/"${1}"/bootstrap 2>&1 &&
5250
ls target/lambda/release/output/"${1}"/bootstrap.debug 2>&1
5351
}
@@ -56,19 +54,82 @@ compile_without_packaging() {
5654
package_all_dev_profile() {
5755
rm -rf target/lambda/debug > /dev/null 2>&1
5856
docker run --rm \
59-
-u $(id -u):$(id -g) \
57+
-u "$(id -u)":"$(id -g)" \
6058
-e PROFILE=dev \
6159
-v "${PWD}":/code \
6260
-v "${HOME}"/.cargo/registry:/cargo/registry \
6361
-v "${HOME}"/.cargo/git:/cargo/git \
64-
${IMAGE} && \
62+
"${IMAGE}" && \
6563
ls target/lambda/debug/"${1}".zip > /dev/null 2>&1 &&
6664
ls target/lambda/release/output/"${1}"/bootstrap 2>&1 &&
6765
ls target/lambda/release/output/"${1}"/bootstrap.debug 2>&1
6866
}
6967

68+
verify_packaged_application() {
69+
LAMBDA_RUNTIME_DIR="/var/runtime"
70+
LAMBDA_TASK_DIR="/var/task"
71+
HOOKS="test-func-with-hooks"
72+
TRY=1
73+
MAX_TRY=10
74+
TRIES_EXCEEDED=10
75+
SLEEP=1
76+
PACKAGE="${1}"
77+
PROJECT="${2}"
78+
TSFRACTION=$(date +%M%S)
79+
80+
clean_up() {
81+
docker container stop lamb > /dev/null 2>&1
82+
rm -f bootstrap > /dev/null 2>&1
83+
rm -f output.log > /dev/null 2>&1
84+
}
85+
86+
clean_up
87+
rm -f test-out.log > /dev/null 2>&1
88+
89+
unzip -o \
90+
target/lambda/release/"${PACKAGE}".zip
91+
92+
if [ "$PROJECT" = "${HOOKS}" ]; then
93+
docker build -t mylambda:"${TSFRACTION}" -f- . <<EOF
94+
FROM public.ecr.aws/lambda/provided:al2
95+
COPY bootstrap ${LAMBDA_RUNTIME_DIR}
96+
COPY output.log ${LAMBDA_TASK_DIR}
97+
CMD [ "function.handler" ]
98+
EOF
99+
else
100+
docker build -t mylambda:"${TSFRACTION}" -f- . <<EOF
101+
FROM public.ecr.aws/lambda/provided:al2
102+
COPY bootstrap ${LAMBDA_RUNTIME_DIR}
103+
CMD [ "function.handler" ]
104+
EOF
105+
fi
106+
# rm -f bootstrap > /dev/null 2>&1
107+
docker run \
108+
--name lamb \
109+
--rm \
110+
-p 9000:8080 \
111+
-d mylambda:"${TSFRACTION}"
112+
113+
until curl -X POST \
114+
-H "Content-Type: application/json" \
115+
-d "@test-event.json" \
116+
"http://localhost:9000/2015-03-31/functions/function/invocations" | \
117+
grep -v RequestId | \
118+
grep -v '^\W*$' > test-out.log; do
119+
>&2 echo "waiting for service to spin up"
120+
sleep ${SLEEP}
121+
if [ ${TRY} = ${MAX_TRY} ]; then
122+
exit ${TRIES_EXCEEDED}
123+
else
124+
TRY=$((TRY + 1))
125+
fi
126+
done
127+
128+
clean_up
129+
}
130+
70131
for project in test-func test-multi-func test-func-with-hooks; do
71-
cd "${HERE}"/"${project}"
132+
cd "${HERE}"/"${project}" || exit 2
72133
echo "👩‍🔬 Running tests for $project with image $IMAGE"
73134

74135
if [[ "$project" == test-multi-func ]]; then
@@ -86,19 +147,8 @@ for project in test-func test-multi-func test-func-with-hooks; do
86147

87148
assert "it packages all bins" package_all "${bin_name}"
88149

89-
# verify packaged artifact by invoking it using the lambdaci "provided.al2" docker image
90-
rm -f output.log > /dev/null 2>&1
91-
rm -f test-out.log > /dev/null 2>&1
92-
rm -rf /tmp/lambda > /dev/null 2>&1
93-
unzip -o \
94-
target/lambda/release/"${bin_name}".zip \
95-
-d /tmp/lambda > /dev/null 2>&1 && \
96-
docker run \
97-
-i -e DOCKER_LAMBDA_USE_STDIN=1 \
98-
--rm \
99-
-v /tmp/lambda:/var/task \
100-
lambci/lambda:provided.al2 < test-event.json | grep -v RequestId | grep -v '^\W*$' > test-out.log
101-
150+
# verify packaged artifact by invoking it using the aws lambda "provided.al2" docker image
151+
verify_packaged_application "${bin_name}" "${project}"
102152
assert "when invoked, it produces expected output" diff expected-output.json test-out.log
103153
done
104154

0 commit comments

Comments
 (0)