diff --git a/.cargo/config b/.cargo/config index 0dd2f79f..56956048 100644 --- a/.cargo/config +++ b/.cargo/config @@ -1,2 +1,2 @@ [target.x86_64-unknown-linux-musl] -linker = "musl-gcc" +linker = "x86_64-unknown-linux-musl-gcc" diff --git a/.dockerignore b/.dockerignore index 1e107f52..b7265688 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1 +1 @@ -examples +examples \ No newline at end of file diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml new file mode 100644 index 00000000..c2256e91 --- /dev/null +++ b/.github/workflows/pipeline.yml @@ -0,0 +1,32 @@ +name: Rust + +on: + push: + branches: [ $default-branch, dev ] + pull_request: + branches: [ $default-branch ] + +env: + CARGO_TERM_COLOR: always + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v1 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: us-east-1 + + - name: Login to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v1 + + - name: Build + run: DOCKER_BUILDKIT=1 docker build -f Dockerfile.x86 -t aws-lambda-adapter:latest . diff --git a/Cargo.lock b/Cargo.lock index 819dd9ba..1ec18bff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -433,9 +433,9 @@ dependencies = [ [[package]] name = "lambda_http" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b38af2eeca21a34121eb9bc714d05483b6b869533beb3ae4d82d7ca29c41fd54" +checksum = "f10599c844cf7584c0dfbf6030df7c174cd5c91f2515412f8875de2a0f2b3fc5" dependencies = [ "base64", "http", @@ -447,9 +447,9 @@ dependencies = [ [[package]] name = "lambda_runtime" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db78b8997843bbb30fdf81ebb9fed56ded699d6226781ec8e2ddd980d3bd3591" +checksum = "17ed88d8421123f9546cbd0c4235386803859c4a20b80a6eb613a652b486df8e" dependencies = [ "async-stream", "bytes", @@ -613,18 +613,18 @@ checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" [[package]] name = "openssl-src" -version = "111.15.0+1.1.1k" +version = "111.16.0+1.1.1l" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a5f6ae2ac04393b217ea9f700cd04fa9bf3d93fae2872069f3d15d908af70a" +checksum = "7ab2173f69416cf3ec12debb5823d244127d23a9b127d5a5189aa97c5fa2859f" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.61" +version = "0.9.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "313752393519e876837e09e1fa183ddef0be7735868dced3196f4472d536277f" +checksum = "1996d2d305e561b70d1ee0c53f1542833f4e1ac6ce9a6708b6ff2738ca67dc82" dependencies = [ "autocfg", "cc", diff --git a/Cargo.toml b/Cargo.toml index 463ec95d..61702fdd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ log = "0.4.14" env_logger = "0.8.3" tokio = { version = "1.4", features = ["macros", "io-util", "sync", "rt-multi-thread", "process"] } tokio-retry = "0.3" -lambda_http = "0.4.0" +lambda_http = "0.4.1" reqwest = { version = "0.11", features = ["json"] } http = "0.2.4" openssl-sys = "0.9.61" diff --git a/Dockerfile.mac b/Dockerfile.mac new file mode 100644 index 00000000..013bbb32 --- /dev/null +++ b/Dockerfile.mac @@ -0,0 +1,2 @@ +FROM scratch +COPY target/x86_64-unknown-linux-musl/release/bootstrap /opt/bootstrap \ No newline at end of file diff --git a/Dockerfile b/Dockerfile.x86 similarity index 54% rename from Dockerfile rename to Dockerfile.x86 index 8ec6b5ff..7836f0f3 100644 --- a/Dockerfile +++ b/Dockerfile.x86 @@ -3,11 +3,12 @@ RUN rpm --rebuilddb && yum install -y yum-plugin-ovl openssl-devel RUN yum groupinstall -y "Development tools" RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y RUN source $HOME/.cargo/env && rustup target add x86_64-unknown-linux-musl -RUN curl -o /etc/yum.repos.d/ngompa-musl-libc-epel-7.repo https://copr.fedorainfracloud.org/coprs/ngompa/musl-libc/repo/epel-7/ngompa-musl-libc-epel-7.repo -RUN yum install -y musl-devel musl-gcc +RUN curl -o /musl-1.2.2.tar.gz https://musl.libc.org/releases/musl-1.2.2.tar.gz \ + && tar zxf /musl-1.2.2.tar.gz && cd musl-1.2.2/ \ + && ./configure && make install && ln -s /usr/local/musl/bin/musl-gcc /usr/local/bin/x86_64-unknown-linux-musl-gcc WORKDIR /app ADD . /app -RUN source $HOME/.cargo/env && cargo build --release --target=x86_64-unknown-linux-musl --features vendored +RUN source $HOME/.cargo/env && CC=x86_64-unknown-linux-musl-gcc cargo build --release --target=x86_64-unknown-linux-musl --features vendored FROM scratch AS package-stage COPY --from=build-stage /app/target/x86_64-unknown-linux-musl/release/bootstrap /opt/bootstrap diff --git a/Makefile b/Makefile index 4476015e..3ecfb4ee 100644 --- a/Makefile +++ b/Makefile @@ -2,5 +2,10 @@ clean: rm -rf target build: - aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/awsguru - DOCKER_BUILDKIT=1 docker build -t aws-lambda-adapter:latest . + aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws + DOCKER_BUILDKIT=1 docker build -f Dockerfile.x86 -t aws-lambda-adapter:latest . + +build-mac: + CC=x86_64-unknown-linux-musl-gcc cargo build --release --target=x86_64-unknown-linux-musl --features vendored + aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws + DOCKER_BUILDKIT=1 docker build -f Dockerfile.mac -t aws-lambda-adapter:latest . \ No newline at end of file diff --git a/README.md b/README.md index 8ad072a2..0ddbbd10 100644 --- a/README.md +++ b/README.md @@ -19,22 +19,64 @@ It will start lambda runtime client after receiving 200 response from the applic ## How to build it? AWS Lambda Adapter is written in Rust and based on [AWS Lambda Rust Runtime](https://github.com/awslabs/aws-lambda-rust-runtime). -You can use GNU Make to compile it as static linked binary and package into a docker image. We provide a [Dockerfile](Dockerfile) including all the required rust toolchain and dependencies. -You need to install [AWS CLI](https://aws.amazon.com/cli/) and [Docker](https://www.docker.com/get-started) to run the build. +AWS Lambda executes functions in x86_64 Amazon Linux Environment. We need to cross compile the adapter to that environment. + +### Compiling on macOS + +First, install [rustup](https://rustup.rs/) if you haven't done it already. Then, add the `x86_64-unknown-linux-musl` target: + +```shell +$ rustup target add x86_64-unknown-linux-musl +``` + +And we have to install macOS cross-compiler toolchains. `messense/homebrew-macos-cross-toolchains` can be used on both Intel chip and Apple M1 chip. + +```shell +$ brew tap messense/macos-cross-toolchains +$ brew install x86_64-unknown-linux-musl +``` + +And we need to inform Cargo that our project uses the newly-installed linker when building for the `x86_64-unknown-linux-musl` platform. +Create a new directory called `.cargo` in your project folder and a new file called `config` inside the new folder. + +```shell +$ mkdir .cargo +$ echo '[target.x86_64-unknown-linux-musl] +linker = "x86_64-unknown-linux-musl-gcc"' > .cargo/config +``` + +Now we can cross compile AWS Lambda Adapter. + +```shell +$ CC=x86_64-unknown-linux-musl-gcc cargo build --release --target=x86_64-unknown-linux-musl --features vendored +``` + +Lambda Adapter binary will be placed at `target/x86_64-unkonw-linux-musl/release/bootstrap`. + +Finally, run the following command to package lambda adapter into a docker image named "aws-lambda-adapter:latest". + +```shell +$ aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws +$ DOCKER_BUILDKIT=1 docker build -f Dockerfile.mac -t aws-lambda-adapter:latest . +``` + +### Compiling with Docker +On x86_64 Windows, Linux and macOS, you can run one command to compile Lambda Adapter with docker. ```shell -make build +$ make build ``` -This will create a docker image called "aws-lambda-adapter:latest". In this docker image, AWS Lambda Adapter is packaged as a file "/opt/bootstrap". + +Once the build completes, it creates a docker image called "aws-lambda-adapter:latest". AWS Lambda Adapter binary is packaged as '/opt/bootstrap' inside the docker image. ## How to use it? -To use it, copy the bootstrap binary from "aws-lambda-adapter:latest" to your container, and use it as ENTRYPOINT. +To use it, copy the bootstrap binary to your container, and use it as ENTRYPOINT. Below is an example Dockerfile for packaging a nodejs application. ```dockerfile FROM public.ecr.aws/lambda/nodejs:14 -COPY --from=aws-lambda-adapter:latest /opt/bootstrap /opt/bootstrap +COPY --from=aws-lambda-adapter:latest /opt/bootstrap ENTRYPOINT ["/opt/bootstrap"] EXPOSE 8080 WORKDIR "/var/task" diff --git a/examples/expressjs/app/Dockerfile b/examples/expressjs/app/Dockerfile index 0e442d45..1eaabccf 100644 --- a/examples/expressjs/app/Dockerfile +++ b/examples/expressjs/app/Dockerfile @@ -3,7 +3,6 @@ COPY --from=aws-lambda-adapter:latest /opt/bootstrap /opt/bootstrap ENTRYPOINT ["/opt/bootstrap"] EXPOSE 8080 WORKDIR "/var/task" -ADD extensions/ /opt ADD src/package.json /var/task/package.json ADD src/package-lock.json /var/task/package-lock.json RUN npm install --production diff --git a/examples/expressjs/app/extensions/cloudwatch/cloudwatch_lambda_agent.toml b/examples/expressjs/app/extensions/cloudwatch/cloudwatch_lambda_agent.toml deleted file mode 100644 index d793e3db..00000000 --- a/examples/expressjs/app/extensions/cloudwatch/cloudwatch_lambda_agent.toml +++ /dev/null @@ -1,31 +0,0 @@ -request_buffer_size = 20 -stack_size_bytes = 1049000 # 1 MiB # TODO: validate this is not unnecessarily large -share_telemetry = true - -[outputs] - request_buffer_recv_timeout_millis = 100 - event_sink_recv_timeout_millis = 100 - - [outputs.backoff_strategy] - initial_interval = 50 - randomization_factor = 0.2 - multiplier = 1.5 - max_interval_millis = 2000 - max_elapsed_time_millis = 2000 - -[rapid] -register_path = "/2020-01-01/extension/register" -next_event_path = "/2020-01-01/extension/event/next" -init_error_path = "/2020-01-01/extension/init/error" -exit_error_path = "/2020-01-01/extension/exit/error" -logs_subscribe_path = "/2020-08-15/logs" -retry_interval = 200 - -[inputs] -sample_interval = 50 - -[logs] -logging_port = 3000 -# functions are limited to 5 layers and so we do not expect -# more than 5 ports being opened for this purpose -max_logging_port = 3010 \ No newline at end of file diff --git a/examples/expressjs/app/extensions/cloudwatch/manifest.json b/examples/expressjs/app/extensions/cloudwatch/manifest.json deleted file mode 100644 index de90c8bd..00000000 --- a/examples/expressjs/app/extensions/cloudwatch/manifest.json +++ /dev/null @@ -1 +0,0 @@ -{ "sha": "abc89e196583edd9dd738734659beb378336b05c2a263bc34f188e64ad09814c", "rev": "41fae653dbbfd01f3716cfaf4cffa46f45e80ffa", "version": "1.0.98.0" } diff --git a/examples/expressjs/app/extensions/extensions/cloudwatch_lambda_agent b/examples/expressjs/app/extensions/extensions/cloudwatch_lambda_agent deleted file mode 100755 index c2819deb..00000000 Binary files a/examples/expressjs/app/extensions/extensions/cloudwatch_lambda_agent and /dev/null differ diff --git a/examples/expressjs/app/extensions/preview-extensions-ggqizro707 b/examples/expressjs/app/extensions/preview-extensions-ggqizro707 deleted file mode 100644 index e69de29b..00000000 diff --git a/examples/nginx/app/Dockerfile b/examples/nginx/app/Dockerfile index da16ab1a..48b84d1e 100644 --- a/examples/nginx/app/Dockerfile +++ b/examples/nginx/app/Dockerfile @@ -3,6 +3,5 @@ WORKDIR "/tmp" COPY --from=aws-lambda-adapter:latest /opt/bootstrap /opt/bootstrap ADD config/ /etc/nginx/ ADD images/ /usr/share/nginx/html/images -ADD extensions/ /opt ENTRYPOINT ["/opt/bootstrap"] CMD ["nginx", "-g", "daemon off;"] diff --git a/examples/nginx/app/extensions/cloudwatch/cloudwatch_lambda_agent.toml b/examples/nginx/app/extensions/cloudwatch/cloudwatch_lambda_agent.toml deleted file mode 100644 index d793e3db..00000000 --- a/examples/nginx/app/extensions/cloudwatch/cloudwatch_lambda_agent.toml +++ /dev/null @@ -1,31 +0,0 @@ -request_buffer_size = 20 -stack_size_bytes = 1049000 # 1 MiB # TODO: validate this is not unnecessarily large -share_telemetry = true - -[outputs] - request_buffer_recv_timeout_millis = 100 - event_sink_recv_timeout_millis = 100 - - [outputs.backoff_strategy] - initial_interval = 50 - randomization_factor = 0.2 - multiplier = 1.5 - max_interval_millis = 2000 - max_elapsed_time_millis = 2000 - -[rapid] -register_path = "/2020-01-01/extension/register" -next_event_path = "/2020-01-01/extension/event/next" -init_error_path = "/2020-01-01/extension/init/error" -exit_error_path = "/2020-01-01/extension/exit/error" -logs_subscribe_path = "/2020-08-15/logs" -retry_interval = 200 - -[inputs] -sample_interval = 50 - -[logs] -logging_port = 3000 -# functions are limited to 5 layers and so we do not expect -# more than 5 ports being opened for this purpose -max_logging_port = 3010 \ No newline at end of file diff --git a/examples/nginx/app/extensions/cloudwatch/manifest.json b/examples/nginx/app/extensions/cloudwatch/manifest.json deleted file mode 100644 index de90c8bd..00000000 --- a/examples/nginx/app/extensions/cloudwatch/manifest.json +++ /dev/null @@ -1 +0,0 @@ -{ "sha": "abc89e196583edd9dd738734659beb378336b05c2a263bc34f188e64ad09814c", "rev": "41fae653dbbfd01f3716cfaf4cffa46f45e80ffa", "version": "1.0.98.0" } diff --git a/examples/nginx/app/extensions/extensions/cloudwatch_lambda_agent b/examples/nginx/app/extensions/extensions/cloudwatch_lambda_agent deleted file mode 100755 index c2819deb..00000000 Binary files a/examples/nginx/app/extensions/extensions/cloudwatch_lambda_agent and /dev/null differ diff --git a/examples/nginx/app/extensions/preview-extensions-ggqizro707 b/examples/nginx/app/extensions/preview-extensions-ggqizro707 deleted file mode 100644 index e69de29b..00000000 diff --git a/examples/springboot/app/Dockerfile b/examples/springboot/app/Dockerfile index b14eb73f..011e1201 100644 --- a/examples/springboot/app/Dockerfile +++ b/examples/springboot/app/Dockerfile @@ -9,6 +9,5 @@ COPY --from=aws-lambda-adapter:latest /opt/bootstrap /opt/bootstrap ENTRYPOINT ["/opt/bootstrap"] EXPOSE 8080 WORKDIR /opt -ADD extensions/ /opt COPY --from=build-image /task/target/petstore-0.0.1-SNAPSHOT.jar /opt CMD ["java", "-jar", "petstore-0.0.1-SNAPSHOT.jar"] diff --git a/examples/springboot/app/extensions/cloudwatch/cloudwatch_lambda_agent.toml b/examples/springboot/app/extensions/cloudwatch/cloudwatch_lambda_agent.toml deleted file mode 100644 index d793e3db..00000000 --- a/examples/springboot/app/extensions/cloudwatch/cloudwatch_lambda_agent.toml +++ /dev/null @@ -1,31 +0,0 @@ -request_buffer_size = 20 -stack_size_bytes = 1049000 # 1 MiB # TODO: validate this is not unnecessarily large -share_telemetry = true - -[outputs] - request_buffer_recv_timeout_millis = 100 - event_sink_recv_timeout_millis = 100 - - [outputs.backoff_strategy] - initial_interval = 50 - randomization_factor = 0.2 - multiplier = 1.5 - max_interval_millis = 2000 - max_elapsed_time_millis = 2000 - -[rapid] -register_path = "/2020-01-01/extension/register" -next_event_path = "/2020-01-01/extension/event/next" -init_error_path = "/2020-01-01/extension/init/error" -exit_error_path = "/2020-01-01/extension/exit/error" -logs_subscribe_path = "/2020-08-15/logs" -retry_interval = 200 - -[inputs] -sample_interval = 50 - -[logs] -logging_port = 3000 -# functions are limited to 5 layers and so we do not expect -# more than 5 ports being opened for this purpose -max_logging_port = 3010 \ No newline at end of file diff --git a/examples/springboot/app/extensions/cloudwatch/manifest.json b/examples/springboot/app/extensions/cloudwatch/manifest.json deleted file mode 100644 index de90c8bd..00000000 --- a/examples/springboot/app/extensions/cloudwatch/manifest.json +++ /dev/null @@ -1 +0,0 @@ -{ "sha": "abc89e196583edd9dd738734659beb378336b05c2a263bc34f188e64ad09814c", "rev": "41fae653dbbfd01f3716cfaf4cffa46f45e80ffa", "version": "1.0.98.0" } diff --git a/examples/springboot/app/extensions/extensions/cloudwatch_lambda_agent b/examples/springboot/app/extensions/extensions/cloudwatch_lambda_agent deleted file mode 100755 index c2819deb..00000000 Binary files a/examples/springboot/app/extensions/extensions/cloudwatch_lambda_agent and /dev/null differ diff --git a/examples/springboot/app/extensions/preview-extensions-ggqizro707 b/examples/springboot/app/extensions/preview-extensions-ggqizro707 deleted file mode 100644 index e69de29b..00000000