Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add multi and arm dockerfiles #265

Merged
merged 6 commits into from
Mar 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,3 @@ target/
devops/
docs/
tools/

Cargo.lock

**/Dockerfile
**/Dockerfile.**
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ ARG CHARIOTT_UID=10001
RUN apt update && apt upgrade -y
RUN apt install -y cmake protobuf-compiler

WORKDIR /sdv

COPY ./ .

# Check that CHARIOTT_UID argument is valid.
RUN /sdv/container/scripts/argument_sanitizer.sh \
--arg-value "${CHARIOTT_UID}" \
--regex "^[0-9]+$" || \
( echo "Argument sanitizer failed for ARG 'CHARIOTT_UID'"; exit 1 )

# unprivileged identity to run Chariott Service Discovery as
RUN adduser \
--disabled-password \
Expand All @@ -27,10 +37,6 @@ RUN adduser \
--uid "${CHARIOTT_UID}" \
chariott

WORKDIR /sdv

COPY ./ .

RUN rustup target add x86_64-unknown-linux-musl

RUN cargo build --release --target=x86_64-unknown-linux-musl -p service_discovery
Expand Down
62 changes: 62 additions & 0 deletions Dockerfile.service_discovery.arm64
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
# SPDX-License-Identifier: MIT

ARG RUST_VERSION=1.70

FROM docker.io/library/rust:${RUST_VERSION} AS builder

# Dockerfile for building Eclipse Chariott Service Discovery container
#
# This Dockerfile utilizes a two step build process. It builds Chariott
# Service Discovery with statically linked dependencies (using musl)
# for an arm64 architecture.

# Chariott user id
ARG CHARIOTT_UID=10001

RUN apt update && apt upgrade -y
RUN apt install -y cmake protobuf-compiler gcc-aarch64-linux-gnu

WORKDIR /sdv

COPY ./ .

# Check that UID argument is valid.
RUN /sdv/container/scripts/argument_sanitizer.sh \
--arg-value "${UID}" \
--regex "^[0-9]+$" || \
( echo "Argument sanitizer failed for ARG 'UID'"; exit 1 )

# unprivileged identity to run Chariott Service Discovery as
RUN adduser \
--disabled-password \
--gecos "" \
--home "/nonexistent" \
--shell "/sbin/nologin" \
--no-create-home \
--uid "${CHARIOTT_UID}" \
chariott

RUN rustup target add aarch64-unknown-linux-musl

RUN cargo build --release --target=aarch64-unknown-linux-musl -p service_discovery

####################################################################################################
## Final image
####################################################################################################
FROM arm64v8/alpine:latest

# Import Chariott user and group from builder.
COPY --from=builder /etc/passwd /etc/passwd
COPY --from=builder /etc/group /etc/group

WORKDIR /sdv

# Copy our build
COPY --from=builder /sdv/target/aarch64-unknown-linux-musl/release/service_discovery /sdv/service_discovery

# Use the unprivileged chariott user during execution.
USER chariott:chariott

CMD ["./service_discovery"]
81 changes: 81 additions & 0 deletions Dockerfile.service_discovery.multi
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
# SPDX-License-Identifier: MIT

ARG RUST_VERSION=1.70

FROM --platform=$BUILDPLATFORM docker.io/library/rust:${RUST_VERSION} AS builder
ladatz marked this conversation as resolved.
Show resolved Hide resolved

# Dockerfile for building Eclipse Chariott Service Discovery container
ladatz marked this conversation as resolved.
Show resolved Hide resolved
#
# This Dockerfile utilizes a two step build process. It builds Chariott
# Service Discovery with statically linked dependencies (using musl)
# for a x86_64 and aarch64 architecture, based on the TARGETARCH.

# Target architecture to cross-compile
ARG TARGETARCH
ladatz marked this conversation as resolved.
Show resolved Hide resolved

# Chariott user id
ARG CHARIOTT_UID=10001

RUN apt update && apt upgrade -y
RUN apt install -y cmake protobuf-compiler

WORKDIR /sdv

COPY ./ .

# Check that CHARIOTT_UID argument is valid.
RUN /sdv/container/scripts/argument_sanitizer.sh \
--arg-value "${CHARIOTT_UID}" \
--regex "^[0-9]+$" || \
( echo "Argument sanitizer failed for ARG 'CHARIOTT_UID'"; exit 1 )

# unprivileged identity to run Chariott Service Discovery as
RUN adduser \
--disabled-password \
--gecos "" \
--home "/nonexistent" \
--shell "/sbin/nologin" \
--no-create-home \
--uid "${CHARIOTT_UID}" \
chariott

# Check that TARGETARCH argument is valid.
RUN /sdv/container/scripts/argument_sanitizer.sh \
--arg-value "${TARGETARCH}" \
--regex "^[a-zA-Z_0-9-]+$" || \
( echo "Argument sanitizer failed for ARG 'TARGETARCH'"; exit 1 )

# Based on the target architecture, add the appropriate build target and build service.
RUN if [ "$TARGETARCH" = "amd64" ]; then \
CARGOARCH="x86_64-unknown-linux-musl"; \
elif [ "$TARGETARCH" = "arm64" ]; then \
apt install -y gcc-aarch64-linux-gnu; \
CARGOARCH="aarch64-unknown-linux-musl"; \
else \
echo "Unsupported cross-compile architecture"; \
exit 1; \
fi; \
rustup target add ${CARGOARCH}; \
cargo build --release --target=${CARGOARCH} -p service_discovery; \
mkdir -p /sdv/release && cp /sdv/target/${CARGOARCH}/release/service_discovery /sdv/release/service_discovery

####################################################################################################
## Final image
####################################################################################################
FROM --platform=$TARGETPLATFORM alpine:latest

# Import Chariott user and group from builder.
COPY --from=builder /etc/passwd /etc/passwd
COPY --from=builder /etc/group /etc/group

WORKDIR /sdv

# Copy our build
COPY --from=builder /sdv/release/service_discovery /sdv/service_discovery

# Use the unprivileged chariott user during execution.
USER chariott:chariott

CMD ["./service_discovery"]
138 changes: 138 additions & 0 deletions container/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
## Containers

This repository provides several Dockerfiles to enable building of OCI container images. This
document has instructions for building and running the provided Dockerfiles in
[Docker](#docker-containers) and [Podman](#podman-containers). Refer to the
[Dockerfiles](#dockerfiles) section to select the appropriate Dockerfile.

### Dockerfiles

#### Service Discovery

- [Dockerfile.service_discovery.amd64](../Dockerfile.service_discovery.amd64) - Dockerfile used to build the `Service Discovery Service` for the
x86-64 architecture.
- [Dockerfile.service_discovery.arm64](../Dockerfile.service_discovery.arm64) - Dockerfile used to build the `Service Discovery Service` for the
aarch64 architecture.
- [Dockerfile.service_discovery.multi](../Dockerfile.service_discovery.multi) - Dockerfile used to build the `Service Discovery Service` for multiple architectures based on the TARGETARCH argument.

#### Intent Brokering

- [Dockerfile.intent_brokering.amd64](../Dockerfile.intent_brokering.amd64) - Dockerfile used to build the `Intent Brokering Service` for the
x86-64 architecture.
- [Dockerfile.intent_brokering.arm64](../Dockerfile.intent_brokering.arm64) - Dockerfile used to build the `Intent Brokering Service` for the
aarch64 architecture.

### Docker Containers

#### Prequisites

[Install Docker](https://docs.docker.com/engine/install/)

#### Running in Docker

To run the service in a Docker container:

1. Run the following command in the project root directory to build the docker container from the
Dockerfile:

```shell
docker build -t <image_name> -f <Dockerfile> .
```

For example, to build an image for the `service_discovery` component:

```shell
docker build -t service_discovery -f Dockerfile.service_discovery.amd64 .
```

Or to build a multi-platform image for the `service_discovery` component and push it to a
container registry:
You must first create a new builder using the docker-container driver, which gives you access
to more complex features like multi-platform build. See more information here:
[multi-platform builds.](https://docs.docker.com/build/building/multi-platform/#cross-compilation)

```shell
docker buildx create --name multibuilder --driver docker-container --use
docker buildx build --platform=linux/amd64,linux/arm64 -f Dockerfile.service_discovery.multi -t <container_registry>/service_discovery_multi --push .
```

1. Once the container has been built, start the container in interactive mode with the following
command in the project root directory:

```shell
docker run --name <container_name> --network=host -it --rm <image_name>
```

For example, to run the `service_discovery` image built in step 1:

```shell
docker run --name service_discovery --network=host -it --rm service_discovery
```

>Note: A custom network is recommended when using a container for anything but testing.

1. To detach from the container, enter:

<kbd>Ctrl</kbd> + <kbd>p</kbd>, <kbd>Ctrl</kbd> + <kbd>q</kbd>

1. To stop the container, enter:

```shell
docker stop <container_name>
```

For example, to stop the `service_discovery` container started in step 2:

```shell
docker stop service_discovery
```

### Podman Containers

#### Prequisites

[Install Podman](https://podman.io/docs/installation)

#### Running in Podman

To run the service in a Podman container:

1. Run the following command in the project root directory to build the podman container from the
Dockerfile:

```shell
podman build -t <image_name> -f <Dockerfile> .
```

For example, to build an image for the `service_discovery` component:

```shell
podman build -t service_discovery -f Dockerfile.amd64 .
```

1. Once the container has been built, start the container with the following command in the project
root directory:

```shell
podman run --network=host <image_name>
```

For example, to run the `service_discovery` image built in step 1:

```shell
podman run --network=host service_discovery
```

>Note: A custom network is recommended when using a container for anything but testing.

1. To stop the container, run:

```shell
podman ps -f ancestor=<image_name> --format="{{.Names}}" | xargs podman stop
```

For example, to stop the `service_discovery` container started in step 2:

```shell
podman ps -f ancestor=localhost/service_discovery:latest --format="{{.Names}}" | xargs podman stop
```
61 changes: 61 additions & 0 deletions container/scripts/argument_sanitizer.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/bin/bash

# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
# SPDX-License-Identifier: MIT

# Exits immediately on failure.
set -eu

# Function to display usage information
usage() {
echo "Usage: $0 [-a|--arg-value] <ARGUMENT_VALUE> [-r|--regex] <ACCEPTED_REGEX>"
echo "Example:"
echo " $0 -a \"\${APP_NAME}\" -r \"^[a-zA-Z_0-9-]+$\""
}

# Parse command line arguments
while [[ $# -gt 0 ]]
do
key="$1"

case $key in
-a|--arg-value)
arg_value="$2"
shift # past argument
shift # past value
;;
-r|--regex)
regex="$2"
shift # past argument
shift # past value
;;
-h|--help)
usage
exit 0
;;
*)
echo "Unknown argument: $key"
usage
exit 1
esac
done

# Check if all required arguments have been set
if [[ -z "${arg_value}" || -z "${regex}" ]]; then
echo "Error: Missing required arguments:"
[[ -z "${arg_value}" ]] && echo " -a|--arg-value"
[[ -z "${regex}" ]] && echo " -r|--regex"
echo -e "\n"
usage
exit 1
fi

sanitized=$(echo "${arg_value}" | tr -dc "${regex}");
[ "$sanitized" = "${arg_value}" ] || {
echo "ARG is invalid. ARG='${arg_value}' sanitized='${sanitized}'";
exit 1
}

echo -e "\nARG with value '${arg_value}' is sanitized"
exit 0
Loading