Skip to content

Commit 9de974f

Browse files
authored
Merge changes for v1.11 release
Merge changes for v1.11 release
2 parents 5a79e1e + c1cf0c5 commit 9de974f

File tree

125 files changed

+6917
-2772
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

125 files changed

+6917
-2772
lines changed

README.md

+65-39
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
## AWS Lambda Runtime Interface Emulator
2+
![GitHub release (latest by date)](https://img.shields.io/github/v/release/aws/aws-lambda-runtime-interface-emulator)
3+
![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/aws/aws-lambda-runtime-interface-emulator)
4+
![GitHub](https://img.shields.io/github/license/aws/aws-lambda-runtime-interface-emulator)
25

3-
![Apache-2.0](https://img.shields.io/npm/l/aws-sam-local.svg)
46

57
The Lambda Runtime Interface Emulator is a proxy for Lambda’s Runtime and Extensions APIs, which allows customers to
68
locally test their Lambda function packaged as a container image. It is a lightweight web-server that converts
@@ -12,6 +14,21 @@ requests instead of the JSON events required for deployment to Lambda. This comp
1214
Lambda’s orchestrator, or security and authentication configurations. You can get started by downloading and installing it on your local machine. When the Lambda Runtime API emulator is executed, a `/2015-03-31/functions/function/invocations` endpoint will be stood up within the container that you post data to it in order to invoke your function for testing.
1315

1416

17+
## Content
18+
* [Installing](#installing)
19+
* [Getting started](#getting-started)
20+
* [Test an image with RIE included in the image](#test-an-image-with-rie-included-in-the-image)
21+
* [To test your Lambda function with the emulator](#to-test-your-lambda-function-with-the-emulator)
22+
* [Build RIE into your base image](#build-rie-into-your-base-image)
23+
* [To build the emulator into your image](#to-build-the-emulator-into-your-image)
24+
* [Test an image without adding RIE to the image](#test-an-image-without-adding-rie-to-the-image)
25+
* [To test an image without adding RIE to the image](#to-test-an-image-without-adding-rie-to-the-image)
26+
* [How to configure](#how-to-configure)
27+
* [Level of support](#level-of-support)
28+
* [Security](#security)
29+
* [License](#license)
30+
31+
1532
## Installing
1633

1734
Instructions for installing AWS Lambda Runtime Interface Emulator for your platform
@@ -26,26 +43,26 @@ Instructions for installing AWS Lambda Runtime Interface Emulator for your platf
2643

2744
## Getting started
2845

29-
There are a few ways you use the Runtime Interface Emulator (RIE) to locally test your function depending on the base image used.
46+
There are a few ways you use the Runtime Interface Emulator (RIE) to locally test your function depending on the base image used.
3047

3148

3249
### Test an image with RIE included in the image
3350

34-
The AWS base images for Lambda include the runtime interface emulator. You can also follow these steps if you built the RIE into your alternative base image.
51+
The AWS base images for Lambda include the runtime interface emulator. You can also follow these steps if you built the RIE into your alternative base image.
3552

3653
#### To test your Lambda function with the emulator
3754

38-
1. Build your image locally using the docker build command.
55+
1. Build your image locally using the docker build command.
3956

4057
`docker build -t myfunction:latest .`
4158

42-
2. Run your container image locally using the docker run command.
59+
2. Run your container image locally using the docker run command.
4360

4461
`docker run -p 9000:8080 myfunction:latest`
4562

46-
This command runs the image as a container and starts up an endpoint locally at `localhost:9000/2015-03-31/functions/function/invocations`.
63+
This command runs the image as a container and starts up an endpoint locally at `localhost:9000/2015-03-31/functions/function/invocations`.
4764

48-
3. Post an event to the following endpoint using a curl command:
65+
3. Post an event to the following endpoint using a curl command:
4966

5067
`curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'`
5168

@@ -59,10 +76,11 @@ You can build RIE into a base image. Download the RIE from GitHub to your local
5976

6077
1. Create a script and save it in your project directory. Set execution permissions for the script file.
6178

62-
The script checks for the presence of the `AWS_LAMBDA_RUNTIME_API` environment variable, which indicates the presence of the runtime API. If the runtime API is present, the script runs [the runtime interface client](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-images.html#runtimes-api-client). Otherwise, the script runs the runtime interface emulator.
79+
The script checks for the presence of the `AWS_LAMBDA_RUNTIME_API` environment variable, which indicates the presence of the runtime API. If the runtime API is present, the script runs [the runtime interface client](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-images.html#runtimes-api-client). Otherwise, the script runs the runtime interface emulator.
6380

64-
The following example shows a typical script for a Node.js function.
65-
```
81+
The following example shows a typical script for a Node.js function.
82+
83+
```sh
6684
#!/bin/sh
6785
if [ -z "${AWS_LAMBDA_RUNTIME_API}" ]; then
6886
exec /usr/local/bin/aws-lambda-rie /usr/bin/npx aws-lambda-ric
@@ -71,74 +89,83 @@ The following example shows a typical script for a Node.js function.
7189
fi
7290
```
7391

74-
2. Download the [runtime interface emulator](https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest) for your target architecture (`aws-lambda-rie` for x86\_64 or `aws-lambda-rie-arm64` for arm64) from GitHub into your project directory.
92+
2. Download the [runtime interface emulator](https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest) for your target architecture (`aws-lambda-rie` for x86\_64 or `aws-lambda-rie-arm64` for arm64) from GitHub into your project directory.
7593

7694
3. Install the emulator package and change `ENTRYPOINT` to run the new script by adding the following lines to your Dockerfile:
7795

78-
To use the default x86\_64 architecture
79-
```
96+
To use the default x86\_64 architecture
97+
98+
```dockerfile
8099
ADD aws-lambda-rie /usr/local/bin/aws-lambda-rie
81100
ENTRYPOINT [ "/entry_script.sh" ]
82101
```
83102

84-
To use the arm64 architecture:
85-
```
103+
To use the arm64 architecture:
104+
105+
```dockerfile
86106
ADD aws-lambda-rie-arm64 /usr/local/bin/aws-lambda-rie
87107
ENTRYPOINT [ "/entry_script.sh" ]
88108
```
89109

90110
4. Build your image locally using the docker build command.
91-
```
111+
112+
```sh
92113
docker build -t myfunction:latest .
93114
```
94115

95116
5. Run your image locally using the docker run command.
96-
```
117+
118+
```sh
97119
docker run -p 9000:8080 myfunction:latest
98120
```
99121

100122
### Test an image without adding RIE to the image
101123

102124
You install the runtime interface emulator to your local machine. When you run the container image, you set the entry point to be the emulator.
103-
*To test an image without adding RIE to the image *
125+
126+
#### To test an image without adding RIE to the image
104127

105128
1. From your project directory, run the following command to download the RIE (x86-64 architecture) from GitHub and install it on your local machine.
106129

107-
```
130+
```sh
108131
mkdir -p ~/.aws-lambda-rie && curl -Lo ~/.aws-lambda-rie/aws-lambda-rie \
109132
https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie \
110133
&& chmod +x ~/.aws-lambda-rie/aws-lambda-rie
111-
```
134+
```
135+
136+
To download the RIE for arm64 architecture, use the previous command with a different GitHub download url.
112137

113-
To download the RIE for arm64 architecture, use the previous command with a different GitHub download url.
114138
```
115139
https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie-arm64 \
116140
```
117141

118-
2. Run your Lambda image function using the docker run command.
119-
```
120-
docker run -d -v ~/.aws-lambda-rie:/aws-lambda -p 9000:8080 myfunction:latest
121-
--entrypoint /aws-lambda/aws-lambda-rie <image entrypoint> <(optional) image command>`
142+
2. Run your Lambda image function using the docker run command.
143+
144+
```sh
145+
docker run -d -v ~/.aws-lambda-rie:/aws-lambda -p 9000:8080 myfunction:latest \
146+
--entrypoint /aws-lambda/aws-lambda-rie <image entrypoint> <(optional) image command>
122147
```
123148

124-
This runs the image as a container and starts up an endpoint locally at `localhost:9000/2015-03-31/functions/function/invocations`.
149+
This runs the image as a container and starts up an endpoint locally at `localhost:9000/2015-03-31/functions/function/invocations`.
125150

126-
3. Post an event to the following endpoint using a curl command:
151+
3. Post an event to the following endpoint using a curl command:
127152

128-
`curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'`
153+
```sh
154+
curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
155+
```
129156

130157
This command invokes the function running in the container image and returns a response.
131158

132-
## How to configure
159+
## How to configure
133160

134-
`aws-lambda-rie` can be configured through Environment Variables within the local running Image.
161+
`aws-lambda-rie` can be configured through Environment Variables within the local running Image.
135162
You can configure your credentials by setting:
136163
* `AWS_ACCESS_KEY_ID`
137164
* `AWS_SECRET_ACCESS_KEY`
138165
* `AWS_SESSION_TOKEN`
139166
* `AWS_REGION`
140167

141-
You can configure timeout by setting AWS_LAMBDA_FUNCTION_TIMEOUT to the number of seconds you want your function to timeout in.
168+
You can configure timeout by setting `AWS_LAMBDA_FUNCTION_TIMEOUT` to the number of seconds you want your function to timeout in.
142169

143170
The rest of these Environment Variables can be set to match AWS Lambda's environment but are not required.
144171
* `AWS_LAMBDA_FUNCTION_VERSION`
@@ -147,17 +174,16 @@ The rest of these Environment Variables can be set to match AWS Lambda's environ
147174
148175
## Level of support
149176
150-
You can use the emulator to test if your function code is compatible with the Lambda environment, executes successfully
151-
and provides the expected output. For example, you can mock test events from different event sources. You can also use
152-
it to test extensions and agents built into the container image against the Lambda Extensions API. This component
153-
does *not *emulate* *the orchestration behavior of AWS Lambda. For example, Lambda has a network and security
154-
configurations that will not be emulated by this component.
155-
177+
You can use the emulator to test if your function code is compatible with the Lambda environment, executes successfully
178+
and provides the expected output. For example, you can mock test events from different event sources. You can also use
179+
it to test extensions and agents built into the container image against the Lambda Extensions API. This component
180+
does _not_ emulate the orchestration behavior of AWS Lambda. For example, Lambda has a network and security
181+
configurations that will not be emulated by this component.
156182
157183
* You can use the emulator to test if your function code is compatible with the Lambda environment, runs successfully and provides the expected output.
158184
* You can also use it to test extensions and agents built into the container image against the Lambda Extensions API.
159-
* This component does _not_ emulate Lambda’s orchestration, or security and authentication configurations.
160-
* The component does _not_ support X-ray and other Lambda integrations locally.
185+
* This component does _not_ emulate Lambda’s orchestration, or security and authentication configurations.
186+
* The component does _not_ support X-ray and other Lambda integrations locally.
161187
* The component supports only Linux, for x86-64 and arm64 architectures.
162188
163189
## Security

cmd/aws-lambda-rie/handlers.go

+25-6
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ import (
1414
"strings"
1515
"time"
1616

17+
"go.amzn.com/lambda/core/statejson"
1718
"go.amzn.com/lambda/interop"
1819
"go.amzn.com/lambda/rapidcore"
20+
"go.amzn.com/lambda/rapidcore/env"
1921

2022
"github.com/google/uuid"
2123

@@ -27,6 +29,19 @@ type Sandbox interface {
2729
Invoke(responseWriter http.ResponseWriter, invoke *interop.Invoke) error
2830
}
2931

32+
type InteropServer interface {
33+
Init(i *interop.Init, invokeTimeoutMs int64) error
34+
AwaitInitialized() error
35+
FastInvoke(w http.ResponseWriter, i *interop.Invoke, direct bool) error
36+
Reserve(id string, traceID, lambdaSegmentID string) (*rapidcore.ReserveResponse, error)
37+
Reset(reason string, timeoutMs int64) (*statejson.ResetDescription, error)
38+
AwaitRelease() (*statejson.InternalStateDescription, error)
39+
Shutdown(shutdown *interop.Shutdown) *statejson.InternalStateDescription
40+
InternalState() (*statejson.InternalStateDescription, error)
41+
CurrentToken() *interop.Token
42+
Restore(restore *interop.Restore) error
43+
}
44+
3045
var initDone bool
3146

3247
func GetenvWithDefault(key string, defaultValue string) string {
@@ -57,7 +72,7 @@ func printEndReports(invokeId string, initDuration string, memorySize string, in
5772
invokeId, invokeDuration, math.Ceil(invokeDuration), memorySize, memorySize)
5873
}
5974

60-
func InvokeHandler(w http.ResponseWriter, r *http.Request, sandbox Sandbox) {
75+
func InvokeHandler(w http.ResponseWriter, r *http.Request, sandbox Sandbox, bs interop.Bootstrap) {
6176
log.Debugf("invoke: -> %s %s %v", r.Method, r.URL, r.Header)
6277
bodyBytes, err := ioutil.ReadAll(r.Body)
6378
if err != nil {
@@ -80,7 +95,7 @@ func InvokeHandler(w http.ResponseWriter, r *http.Request, sandbox Sandbox) {
8095

8196
if !initDone {
8297

83-
initStart, initEnd := InitHandler(sandbox, functionVersion, timeout)
98+
initStart, initEnd := InitHandler(sandbox, functionVersion, timeout, bs)
8499

85100
// Calculate InitDuration
86101
initTimeMS := math.Min(float64(initEnd.Sub(initStart).Nanoseconds()),
@@ -99,7 +114,6 @@ func InvokeHandler(w http.ResponseWriter, r *http.Request, sandbox Sandbox) {
99114
TraceID: r.Header.Get("X-Amzn-Trace-Id"),
100115
LambdaSegmentID: r.Header.Get("X-Amzn-Segment-Id"),
101116
Payload: bytes.NewReader(bodyBytes),
102-
CorrelationID: "invokeCorrelationID",
103117
}
104118
fmt.Println("START RequestId: " + invokePayload.ID + " Version: " + functionVersion)
105119

@@ -166,7 +180,7 @@ func InvokeHandler(w http.ResponseWriter, r *http.Request, sandbox Sandbox) {
166180
w.Write(invokeResp.Body)
167181
}
168182

169-
func InitHandler(sandbox Sandbox, functionVersion string, timeout int64) (time.Time, time.Time) {
183+
func InitHandler(sandbox Sandbox, functionVersion string, timeout int64, bs interop.Bootstrap) (time.Time, time.Time) {
170184
additionalFunctionEnvironmentVariables := map[string]string{}
171185

172186
// Add default Env Vars if they were not defined. This is a required otherwise 1p Python2.7, Python3.6, and
@@ -189,15 +203,20 @@ func InitHandler(sandbox Sandbox, functionVersion string, timeout int64) (time.T
189203
// pass to rapid
190204
sandbox.Init(&interop.Init{
191205
Handler: GetenvWithDefault("AWS_LAMBDA_FUNCTION_HANDLER", os.Getenv("_HANDLER")),
192-
CorrelationID: "initCorrelationID",
193206
AwsKey: os.Getenv("AWS_ACCESS_KEY_ID"),
194207
AwsSecret: os.Getenv("AWS_SECRET_ACCESS_KEY"),
195208
AwsSession: os.Getenv("AWS_SESSION_TOKEN"),
196209
XRayDaemonAddress: "0.0.0.0:0", // TODO
197210
FunctionName: GetenvWithDefault("AWS_LAMBDA_FUNCTION_NAME", "test_function"),
198211
FunctionVersion: functionVersion,
199-
212+
RuntimeInfo: interop.RuntimeInfo{
213+
ImageJSON: "{}",
214+
Arn: "",
215+
Version: ""},
200216
CustomerEnvironmentVariables: additionalFunctionEnvironmentVariables,
217+
SandboxType: interop.SandboxClassic,
218+
Bootstrap: bs,
219+
EnvironmentVariables: env.NewEnvironment(),
201220
}, timeout*1000)
202221
initEnd := time.Now()
203222
return initStart, initEnd

cmd/aws-lambda-rie/http.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,18 @@ import (
77
"net/http"
88

99
log "github.com/sirupsen/logrus"
10+
"go.amzn.com/lambda/interop"
11+
"go.amzn.com/lambda/rapidcore"
1012
)
1113

12-
func startHTTPServer(ipport string, sandbox Sandbox) {
14+
func startHTTPServer(ipport string, sandbox *rapidcore.SandboxBuilder, bs interop.Bootstrap) {
1315
srv := &http.Server{
1416
Addr: ipport,
1517
}
1618

1719
// Pass a channel
1820
http.HandleFunc("/2015-03-31/functions/function/invocations", func(w http.ResponseWriter, r *http.Request) {
19-
InvokeHandler(w, r, sandbox)
21+
InvokeHandler(w, r, sandbox.LambdaInvokeAPI(), bs)
2022
})
2123

2224
// go routine (main thread waits)

0 commit comments

Comments
 (0)