-
Notifications
You must be signed in to change notification settings - Fork 89
/
bootstrap
executable file
·90 lines (81 loc) · 3.27 KB
/
bootstrap
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#!/bin/bash
set -uo pipefail
# Constants
RUNTIME_PATH="2018-06-01/runtime"
mkdir -p /tmp/.aws
touch /tmp/.aws/config
export HOME="/tmp"
export AWS_CONFIG_FILE="/tmp/.aws/config"
# Send initialization error to Lambda API
sendInitError () {
ERROR_MESSAGE=$1
ERROR_TYPE=$2
ERROR="{\"errorMessage\": \"$ERROR_MESSAGE\", \"errorType\": \"$ERROR_TYPE\"}"
curl -sS -X POST -d "$ERROR" "http://${AWS_LAMBDA_RUNTIME_API}/${RUNTIME_PATH}/init/error" > /dev/null
}
# Send runtime error to Lambda API
sendRuntimeError () {
REQUEST_ID=$1
ERROR_MESSAGE=$2
ERROR_TYPE=$3
STACK_TRACE=$4
ERROR="{\"errorMessage\": \"$ERROR_MESSAGE\", \"errorType\": \"$ERROR_TYPE\", \"stackTrace\": \"$STACK_TRACE\"}"
curl -sS -X POST -d "$ERROR" "http://${AWS_LAMBDA_RUNTIME_API}/${RUNTIME_PATH}/invocation/${REQUEST_ID}/error" > /dev/null
}
# Send successful response to Lambda API
sendResponse () {
REQUEST_ID=$1
REQUEST_RESPONSE_FILE=$2
cat $REQUEST_RESPONSE_FILE | curl -sS -X POST -d @- "http://${AWS_LAMBDA_RUNTIME_API}/${RUNTIME_PATH}/invocation/${REQUEST_ID}/response" > /dev/null
}
# Make sure handler file exists
if [[ ! -f $LAMBDA_TASK_ROOT/"$(echo $_HANDLER | cut -d. -f1).sh" ]]; then
sendInitError "Failed to load handler '$(echo $_HANDLER | cut -d. -f2)' from module '$(echo $_HANDLER | cut -d. -f1)'. File '$(echo $_HANDLER | cut -d. -f1).sh' does not exist." "InvalidHandlerException"
exit 1
fi
# Initialization
SOURCE_RESPONSE="$(mktemp)"
source $LAMBDA_TASK_ROOT/"$(echo $_HANDLER | cut -d. -f1).sh" > $SOURCE_RESPONSE 2>&1
if [[ $? -eq "0" ]]; then
rm -f -- "$SOURCE_RESPONSE"
else
sendInitError "Failed to source file '$(echo $_HANDLER | cut -d. -f1).sh'. $(cat $SOURCE_RESPONSE)" "InvalidHandlerException"
exit 1
fi
# Make sure handler function exists
type "$(echo $_HANDLER | cut -d. -f2)" > /dev/null 2>&1
if [[ ! $? -eq "0" ]]; then
sendInitError "Failed to load handler '$(echo $_HANDLER | cut -d. -f2)' from module '$(echo $_HANDLER | cut -d. -f1)'. Function '$(echo $_HANDLER | cut -d. -f2)' does not exist." "InvalidHandlerException"
exit 1
fi
# Processing
while true
do
HEADERS="/tmp/headers-$(date +'%s')"
RESPONSE="/tmp/response-$(date +'%s')"
touch $HEADERS
touch $RESPONSE
EVENT_DATA=$(curl -sS -LD "$HEADERS" -X GET "http://${AWS_LAMBDA_RUNTIME_API}/${RUNTIME_PATH}/invocation/next")
REQUEST_ID=$(grep -Fi Lambda-Runtime-Aws-Request-Id "$HEADERS" | tr -d '[:space:]' | cut -d: -f2)
# Export some additional context
export AWS_LAMBDA_REQUEST_ID=$REQUEST_ID
export AWS_LAMBDA_DEADLINE_MS=$(grep -Fi Lambda-Runtime-Deadline-Ms "$HEADERS" | tr -d '[:space:]' | cut -d: -f2)
export AWS_LAMBDA_FUNCTION_ARN=$(grep -Fi Lambda-Runtime-Invoked-Function-Arn "$HEADERS" | cut -d" " -f2)
export AWS_LAMBDA_TRACE_ID=$(grep -Fi Lambda-Runtime-Trace-Id "$HEADERS" | tr -d '[:space:]' | cut -d: -f2)
# Execute the user function
$(echo "$_HANDLER" | cut -d. -f2) "$EVENT_DATA" >&1 2> $RESPONSE | cat
EXIT_CODE=$?
# Respond to Lambda API
if [[ $EXIT_CODE -eq "0" ]]; then
sendResponse "$REQUEST_ID" "$RESPONSE"
else
# Log error to stdout as well
cat $RESPONSE
sendRuntimeError "$REQUEST_ID" "Exited with code $EXIT_CODE" "RuntimeErrorException" "$(cat $RESPONSE)"
fi
# Clean up
rm -f -- "$HEADERS"
rm -f -- "$RESPONSE"
unset HEADERS
unset RESPONSE
done