From 3fbc1a56ef3a7d56e9e4200f29bc116331d225d0 Mon Sep 17 00:00:00 2001
From: devkelley <105753233+devkelley@users.noreply.github.com>
Date: Thu, 7 Dec 2023 14:07:30 -0800
Subject: [PATCH] Update Ibeji Dockerfiles (#81)
* Remove Containerize feature and add aarch64 targets
* Updated Dockerfiles for amd64 and arm64
* Update README's to reflect container changes
* Fix link and linting
* make optional args more concise
* remove unused comment
---
.cargo/config.toml | 3 +
.github/workflows/check-spelling.yml | 1 -
Dockerfile => Dockerfile.amd64 | 53 +++-
Dockerfile.integrated => Dockerfile.arm64 | 63 +++--
README.md | 5 +-
container/.accepted_words.txt | 5 +
container/README.md | 228 +++++++++++++++---
container/config/docker.env | 9 -
container/config/podman.env | 9 -
container/scripts/argument_sanitizer.sh | 61 +++++
container/scripts/container_startup.sh | 16 ++
core/common/Cargo.toml | 3 -
core/common/src/utils.rs | 41 +---
core/invehicle-digital-twin/Cargo.toml | 3 +-
core/invehicle-digital-twin/src/main.rs | 8 +-
core/module/managed_subscribe/Cargo.toml | 3 -
.../src/managed_subscribe_interceptor.rs | 4 +-
...file.consumer => Dockerfile.samples.amd64} | 46 ++--
...file.provider => Dockerfile.samples.arm64} | 56 +++--
samples/common/.cargo/config.toml | 3 +
samples/common/Cargo.toml | 5 +-
samples/common/src/utils.rs | 46 +---
samples/container/.accepted_words.txt | 93 -------
samples/container/README.md | 157 ------------
samples/container/config/docker.env | 9 -
samples/container/config/podman.env | 9 -
samples/managed_subscribe/Cargo.toml | 5 +-
.../managed_subscribe/consumer/src/main.rs | 4 +-
.../provider/src/provider_impl.rs | 5 +-
samples/property/Cargo.toml | 5 +-
samples/property/provider/src/main.rs | 8 +-
samples/streaming/.cargo/config.toml | 3 +
samples/streaming/Cargo.toml | 4 +
33 files changed, 475 insertions(+), 498 deletions(-)
create mode 100644 .cargo/config.toml
rename Dockerfile => Dockerfile.amd64 (64%)
rename Dockerfile.integrated => Dockerfile.arm64 (55%)
delete mode 100644 container/config/docker.env
delete mode 100644 container/config/podman.env
create mode 100755 container/scripts/argument_sanitizer.sh
create mode 100755 container/scripts/container_startup.sh
rename samples/{Dockerfile.consumer => Dockerfile.samples.amd64} (75%)
rename samples/{Dockerfile.provider => Dockerfile.samples.arm64} (64%)
create mode 100644 samples/common/.cargo/config.toml
delete mode 100644 samples/container/.accepted_words.txt
delete mode 100644 samples/container/README.md
delete mode 100644 samples/container/config/docker.env
delete mode 100644 samples/container/config/podman.env
create mode 100644 samples/streaming/.cargo/config.toml
diff --git a/.cargo/config.toml b/.cargo/config.toml
new file mode 100644
index 00000000..c3b54de3
--- /dev/null
+++ b/.cargo/config.toml
@@ -0,0 +1,3 @@
+[target.aarch64-unknown-linux-gnu]
+linker = "aarch64-linux-gnu-gcc"
+rustflags = [ "-C", "target-feature=+crt-static", "-C", "link-arg=-lgcc" ]
diff --git a/.github/workflows/check-spelling.yml b/.github/workflows/check-spelling.yml
index 086c23a8..61768720 100644
--- a/.github/workflows/check-spelling.yml
+++ b/.github/workflows/check-spelling.yml
@@ -21,6 +21,5 @@ jobs:
./tools/check_spelling.sh ./core/common/README.md
./tools/check_spelling.sh ./dtdl-parser/README.md
./tools/check_spelling.sh ./docs/design/README.md
- ./tools/check_spelling.sh ./samples/container/README.md
./tools/check_spelling.sh ./samples/managed_subscribe/README.md
shell: bash
diff --git a/Dockerfile b/Dockerfile.amd64
similarity index 64%
rename from Dockerfile
rename to Dockerfile.amd64
index 41e3848c..d5740afc 100644
--- a/Dockerfile
+++ b/Dockerfile.amd64
@@ -10,24 +10,37 @@
# Create a stage for building the application.
ARG RUST_VERSION=1.72.1
-FROM docker.io/library/rust:${RUST_VERSION}-slim-bullseye AS build
ARG APP_NAME=invehicle-digital-twin
+ARG FEATURES=""
+ARG UID=10001
+
+FROM docker.io/library/rust:${RUST_VERSION}-slim-bullseye AS build
+ARG APP_NAME
+ARG FEATURES
WORKDIR /sdv
COPY ./ .
+# Check that APP_NAME argument is valid.
+RUN /sdv/container/scripts/argument_sanitizer.sh \
+ --arg-value "${APP_NAME}" \
+ --regex "^[a-zA-Z_0-9-]+$" || \
+ ( echo "Argument sanitizer failed for ARG 'APP_NAME'"; exit 1 )
+
+# Check that FEATURES argument is valid if the argument is not empty.
+# The regex checks if there is one or more features separated by a single space.
+RUN if [ -n "${FEATURES}" ]; then \
+ /sdv/container/scripts/argument_sanitizer.sh \
+ --arg-value "${FEATURES}" \
+ --regex "^[a-zA-Z_0-9-]+(?: [a-zA-Z_0-9-]+)*$" || \
+ ( echo "Argument sanitizer failed for ARG 'FEATURES'"; exit 1 ) \
+ fi
+
# Add Build dependencies.
RUN apt update && apt upgrade -y && apt install -y protobuf-compiler
-# Check that APP_NAME argument is valid.
-RUN sanitized=$(echo "${APP_NAME}" | tr -dc '^[a-zA-Z_0-9-]+$'); \
-[ "$sanitized" = "${APP_NAME}" ] || { \
- echo "ARG 'APP_NAME' is invalid. APP_NAME='${APP_NAME}' sanitized='${sanitized}'"; \
- exit 1; \
-}
-
-# Build the application with the 'containerize' feature.
-RUN cargo build --release -p "${APP_NAME}" --features "containerize"
+# Build the application (with features if provided).
+RUN cargo build --release -p "${APP_NAME}" --features "${FEATURES}"
# Copy the built application to working directory.
RUN cp ./target/release/"${APP_NAME}" /sdv/service
@@ -44,6 +57,16 @@ RUN cp ./target/release/"${APP_NAME}" /sdv/service
# reproducability is important, consider using a digest
# (e.g., debian@sha256:ac707220fbd7b67fc19b112cee8170b41a9e97f703f588b2cdbbcdcecdd8af57).
FROM docker.io/library/debian:bullseye-slim AS final
+ARG UID
+
+# Copy container scripts.
+COPY ./container/scripts/*.sh /sdv/scripts/
+
+# Check that UID argument is valid.
+RUN /sdv/scripts/argument_sanitizer.sh \
+ --arg-value "${UID}" \
+ --regex "^[0-9]+$" || \
+ ( echo "Argument sanitizer failed for ARG 'UID'"; exit 1 )
# Create a non-privileged user that the app will run under.
# See https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user
@@ -56,6 +79,14 @@ RUN adduser \
--no-create-home \
--uid "${UID}" \
appuser
+
+# Create and add user ownership to config directory.
+RUN mkdir -p /sdv/config
+RUN chown appuser /sdv/config
+
+# Create mnt directory to copy override configs into.
+RUN mkdir -p /mnt/config
+
USER appuser
WORKDIR /sdv
@@ -73,4 +104,4 @@ COPY --from=build /sdv/container/config/standalone/ /sdv/config
EXPOSE 5010
# What the container should run when it is started.
-CMD ["/sdv/service"]
+CMD ["/sdv/scripts/container_startup.sh"]
diff --git a/Dockerfile.integrated b/Dockerfile.arm64
similarity index 55%
rename from Dockerfile.integrated
rename to Dockerfile.arm64
index 05c335f3..244b4e97 100644
--- a/Dockerfile.integrated
+++ b/Dockerfile.arm64
@@ -10,27 +10,44 @@
# Create a stage for building the application.
ARG RUST_VERSION=1.72.1
-FROM docker.io/library/rust:${RUST_VERSION}-slim-bullseye AS build
ARG APP_NAME=invehicle-digital-twin
+ARG FEATURES=""
+ARG UID=10001
+
+FROM docker.io/library/rust:${RUST_VERSION}-slim-bullseye AS build
+ARG APP_NAME
+ARG FEATURES
WORKDIR /sdv
COPY ./ .
+# Check that APP_NAME argument is valid.
+RUN /sdv/container/scripts/argument_sanitizer.sh \
+ --arg-value "${APP_NAME}" \
+ --regex "^[a-zA-Z_0-9-]+$" || \
+ ( echo "Argument sanitizer failed for ARG 'APP_NAME'"; exit 1 )
+
+# Check that FEATURES argument is valid if the argument is not empty.
+# The regex checks if there is one or more features separated by a single space.
+RUN if [ -n "${FEATURES}" ]; then \
+ /sdv/container/scripts/argument_sanitizer.sh \
+ --arg-value "${FEATURES}" \
+ --regex "^[a-zA-Z_0-9-]+(?: [a-zA-Z_0-9-]+)*$" || \
+ ( echo "Argument sanitizer failed for ARG 'FEATURES'"; exit 1 ) \
+ fi
+
# Add Build dependencies.
-RUN apt update && apt upgrade -y && apt install -y protobuf-compiler
+RUN apt update && apt upgrade -y && apt install -y \
+ protobuf-compiler \
+ gcc-aarch64-linux-gnu
-# Check that APP_NAME argument is valid.
-RUN sanitized=$(echo "${APP_NAME}" | tr -dc '^[a-zA-Z_0-9-]+$'); \
-[ "$sanitized" = "${APP_NAME}" ] || { \
- echo "ARG 'APP_NAME' is invalid. APP_NAME='${APP_NAME}' sanitized='${sanitized}'"; \
- exit 1; \
-}
+RUN rustup target add aarch64-unknown-linux-gnu
-# Build the application with the 'containerize' feature.
-RUN cargo build --release -p "${APP_NAME}" --features "containerize managed_subscribe"
+# Build the application (with features if provided).
+RUN cargo build --release --target=aarch64-unknown-linux-gnu -p "${APP_NAME}" --features "${FEATURES}"
# Copy the built application to working directory.
-RUN cp ./target/release/"${APP_NAME}" /sdv/service
+RUN cp ./target/aarch64-unknown-linux-gnu/release/"${APP_NAME}" /sdv/service
################################################################################
# Create a new stage for running the application that contains the minimal
@@ -43,7 +60,17 @@ RUN cp ./target/release/"${APP_NAME}" /sdv/service
# most recent version of that tag when you build your Dockerfile. If
# reproducability is important, consider using a digest
# (e.g., debian@sha256:ac707220fbd7b67fc19b112cee8170b41a9e97f703f588b2cdbbcdcecdd8af57).
-FROM docker.io/library/debian:bullseye-slim AS final
+FROM docker.io/arm64v8/debian:bullseye-slim AS final
+ARG UID
+
+# Copy container scripts.
+COPY ./container/scripts/*.sh /sdv/scripts/
+
+# Check that UID argument is valid.
+RUN /sdv/scripts/argument_sanitizer.sh \
+ --arg-value "${UID}" \
+ --regex "^[0-9]+$" || \
+ ( echo "Argument sanitizer failed for ARG 'UID'"; exit 1 )
# Create a non-privileged user that the app will run under.
# See https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user
@@ -56,6 +83,14 @@ RUN adduser \
--no-create-home \
--uid "${UID}" \
appuser
+
+# Create and add user ownership to config directory.
+RUN mkdir -p /sdv/config
+RUN chown appuser /sdv/config
+
+# Create mnt directory to copy override configs into.
+RUN mkdir -p /mnt/config
+
USER appuser
WORKDIR /sdv
@@ -67,10 +102,10 @@ ENV IBEJI_HOME=/sdv/config
COPY --from=build /sdv/service /sdv/
# Copy configuration for service.
-COPY --from=build /sdv/container/config/integrated/ /sdv/config
+COPY --from=build /sdv/container/config/standalone/ /sdv/config
# Expose the port that the application listens on.
EXPOSE 5010
# What the container should run when it is started.
-CMD ["/sdv/service"]
+CMD ["/sdv/scripts/container_startup.sh"]
diff --git a/README.md b/README.md
index 75ce3775..1f8e0d5b 100644
--- a/README.md
+++ b/README.md
@@ -310,9 +310,8 @@ rather than having it statically provided in their respective config file, then
## Running in a Container
-To run the In-Vehicle Digital Twin Service in a container, please refer to [Ibeji Containerization](./container/README.md).
-
-To run the samples in a container, please refer to [Samples Containerization](./samples/container/README.md).
+Please refer to [Ibeji Containers](./container/README.md#ibeji-containers) for information on how
+build and run the In-Vehicle Digital Twin Service or the Sample Applications in a container.
## Trademarks
diff --git a/container/.accepted_words.txt b/container/.accepted_words.txt
index 4e86eebb..5158ffe4 100644
--- a/container/.accepted_words.txt
+++ b/container/.accepted_words.txt
@@ -1,5 +1,9 @@
+aarch
Agemo
agemo
+amd
+APP
+arg
br
build
cargo
@@ -54,6 +58,7 @@ loopback
md
microsoft
minimalistic
+mnt
mosquitto
Mosquitto
mqtt
diff --git a/container/README.md b/container/README.md
index 06d9363e..a2fe9716 100644
--- a/container/README.md
+++ b/container/README.md
@@ -1,119 +1,271 @@
-# Ibeji Containerization
+# Ibeji Containers
-This document covers how to containerize the In-Vehicle Digital Twin Service. To run the samples as
-a container please refer to [Samples Containerization](../samples/container/README.md).
+This document covers how to containerize the services provided in this repository.
-## Running the In-Vehicle Digital Twin Service in a Container
+## Dockerfile Selection
-Below are the steps for running the service in a container. Note that the configuration files used
-by the containerized service are cloned from [/container/config](./config/) defined in the
-project's root.
+### In-Vehicle Digital Twin Service
-### Dockerfile
+To containerize the [In-Vehicle Digital Twin Service](../core/invehicle-digital-twin/) use one of
+the following dockerfiles:
-There are currently two dockerfiles provided in the root directory of the project that can be built:
+- [Dockerfile.amd64](../Dockerfile.amd64) - For x86-64 architecture.
+- [Dockerfile.arm64](../Dockerfile.arm64) - For aarch64 architecture.
-- Dockerfile - A standalone version of the In-Vehicle Digital Twin Service
-- Dockerfile.integrated - A version of the In-Vehicle Digital Twin Service that communicates with
-the [Chariott Service](https://github.com/eclipse-chariott/chariott) and the
-[Agemo Service](https://github.com/eclipse-chariott/Agemo).
+### Sample Applications
-### Docker
+To containerize one of the [Ibeji Sample Applications](../samples/) use one of the following
+dockerfiles:
-#### Prerequisites
+- [./samples/Dockerfile.samples.amd64](../samples/Dockerfile.samples.amd64) - For x86-64
+architecture.
+- [./samples/Dockerfile.samples.arm64](../samples/Dockerfile.samples.arm64) - For aarch64
+architecture.
+
+## Configuration Defaults
+
+### In-Vehicle Digital Twin Service
+
+This repository provides default configuration files for the In-Vehicle Digital Twin Service
+running in [Standalone](../container/config/standalone/) and
+[Integrated](../container/config/integrated) modes.
+
+>Note: Integrated mode runs the In-Vehicle Digital Twin Service with the
+[Chariott Service](https://github.com/eclipse-chariott/chariott) and the
+[Agemo Service](https://github.com/eclipse-chariott/Agemo). Other combinations may require config
+changes.
+
+### Sample Applications
+
+For the samples, this repository provides
+default configuration files for the [Property Provider](../samples/container/config/provider/) and
+[Property Consumer](../samples/container/config/consumer/) samples.
+
+>Note: Other samples may need config changes (see
+[Running the Samples](../README.md#running-the-samples) for config changes).
+
+## Docker Containers
+
+### Prerequisites
[Install Docker](https://docs.docker.com/engine/install/)
-#### Running in Docker
+### Running in Docker
To run the service in a Docker container:
-1. Run the following command in the project's root directory to build the docker container from the
+>Note: Before running any of the following commands, replace all placeholders (wrapped with `<>`).
+
+1. Run the following command in the project root directory to build the docker container from the
Dockerfile:
```shell
- docker build -t invehicle_digital_twin -f Dockerfile .
+ docker build -t -f [--build-arg=APP_NAME=] [--build-arg=FEATURES=""] .
+ ```
+
+ >Note: The `FEATURES` build arg only applies to the dockerfiles for In-Vehicle Digital Twin Service.
+
+ For example, to build an image for the `invehicle-digital-twin` project in `Standalone` mode:
+
+ ```shell
+ docker build -t invehicle_digital_twin -f Dockerfile.amd64 .
+ ```
+
+ Or to build an image for the `invehicle-digital-twin` project with the `Managed Subscribe`
+ module:
+
+ ```shell
+ docker build -t invehicle_digital_twin -f Dockerfile.amd64 --build-arg=FEATURES="managed_subscribe" .
+ ```
+
+ >Note: Modules for Ibeji are enabled via the `--features` flag. The `FEATURES` build arg passes
+ one or more features to the cargo build argument. If you want to add multiple features, add
+ each feature followed by a space e.g. `"module_1 module_2"`.
+
+ Or to build an image for the `property-provider` sample for aarch64:
+
+ ```shell
+ docker build -t property_provider -f ./samples/Dockerfile.samples.arm64 --build-arg=APP_NAME=property-provider .
```
+ >Note: The build arg `APP_NAME` needs to be passed in for all sample applications to build the
+ correct sample.
+
1. Once the container has been built, start the container in interactive mode with the following
-command in the project's root directory:
+command in the project root directory:
+
+ ```shell
+ docker run --name --network=host -it --rm
+ ```
+
+ >Note: Most images built will require configuration overrides. See
+ [Running in Docker with overridden configuration](#running-in-docker-with-overridden-configuration)
+ for more details.
+
+ For example, to run the `invehicle_digital_twin` standalone image built in step 1:
```shell
- docker run --name invehicle_digital_twin -p 5010:5010 --env-file=./container/config/docker.env --add-host=host.docker.internal:host-gateway -it --rm invehicle_digital_twin
+ docker run --name invehicle_digital_twin --network=host -it --rm invehicle_digital_twin
```
+ >Note: A custom network is recommended when using a container for anything but testing.
+
1. To detach from the container, enter:
Ctrl + p, Ctrl + q
1. To stop the container, enter:
+ ```shell
+ docker stop
+ ```
+
+ For example, to stop the `invehicle_digital_twin` container started in step 2:
+
```shell
docker stop invehicle_digital_twin
```
-#### Running in Docker with overridden configuration
+### Running in Docker with overridden configuration
Follow the steps in [Running in Docker](#running-in-docker) to build the container.
1. To run the container with overridden configuration, create your config file and set an
-environment variable called IBEJI_HOME to the absolute path of the directory containing the
-config file:
+environment variable called CONFIG_HOME to the path to the config file:
```shell
- export IBEJI_HOME={absolute path of the directory containing the config file}
+ export CONFIG_HOME={path to directory containing config file}
```
+ For example, to set the configuration for the
+ [Property Provider](../samples/property/provider/) sample, run:
+
+ ```shell
+ export CONFIG_HOME={path-to-repo-root}/samples/container/config/provider
+ ```
+
+ >Note: See [Configuration Defaults](#configuration-defaults) for more information. If running
+ a sample other than the `Property` sample you will need to create your own configuration files.
+
1. Then run the container with the following command:
```shell
- docker run -v ${IBEJI_HOME}:/sdv/config --name invehicle_digital_twin -p 5010:5010 --env-file=./container/config/docker.env --add-host=host.docker.internal:host-gateway -it --rm invehicle_digital_twin
+ docker run -v ${CONFIG_HOME}:/mnt/config --name --network=host -it --rm
```
-### Podman
+ For example, to run the `property_provider` image with overridden configuration:
-#### Prerequisites
+ ```shell
+ docker run -v ${CONFIG_HOME}:/mnt/config --name property_provider --network=host -it --rm property_provider
+ ```
+
+## Podman
+
+### Prerequisites
[Install Podman](https://podman.io/docs/installation)
-#### Running in Podman
+### Running in Podman
To run the service in a Podman container:
-1. Run the following command in the project's root directory to build the podman container from the
+>Note: Before running any of the following commands, replace all placeholders (wrapped with `<>`).
+
+1. Run the following command in the project root directory to build the podman container from the
Dockerfile:
```shell
- podman build -t invehicle_digital_twin:latest -f Dockerfile .
+ podman build -t -f [--build-arg=APP_NAME=] [--build-arg=FEATURES=""] .
+ ```
+
+ >Note: The `FEATURES` build arg only applies to the dockerfiles for In-Vehicle Digital Twin Service.
+
+ For example, to build an image for the `invehicle-digital-twin` project in `Standalone` mode:
+
+ ```shell
+ podman build -t invehicle_digital_twin -f Dockerfile.amd64 .
```
-1. Once the container has been built, start the container with the following command in the
-project's root directory:
+ Or to build an image for the `invehicle-digital-twin` project with the `Managed Subscribe`
+ module:
+
+ ```shell
+ podman build -t invehicle_digital_twin -f Dockerfile.amd64 --build-arg=FEATURES="managed_subscribe" .
+ ```
+
+ >Note: Modules for Ibeji are enabled via the `--features` flag. The `FEATURES` build arg passes
+ one or more features to the cargo build argument. If you want to add multiple features, add
+ each feature followed by a space e.g. `"module_1 module_2"`.
+
+ Or to build an image for the `property-provider` sample for aarch64:
+
+ ```shell
+ podman build -t property_provider -f ./samples/Dockerfile.samples.arm64 --build-arg=APP_NAME=property-provider .
+ ```
+
+ >Note: The build arg `APP_NAME` needs to be passed in for all sample applications to build the
+ correct sample.
+
+1. Once the container has been built, start the container with the following command in the project
+root directory:
```shell
- podman run -p 5010:5010 --env-file=./container/config/podman.env --network=slirp4netns:allow_host_loopback=true localhost/invehicle_digital_twin
+ podman run --network=host
```
+ >Note: Most images built will require configuration overrides. See
+ [Running in Podman with overridden configuration](#running-in-podman-with-overridden-configuration)
+ for more details.
+
+ For example, to run the `invehicle_digital_twin` image built in step 1:
+
+ ```shell
+ podman run --network=host invehicle_digital_twin
+ ```
+
+ >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= --format="{{.Names}}" | xargs podman stop
+ ```
+
+ For example, to stop the `invehicle_digital_twin` container started in step 2:
+
```shell
podman ps -f ancestor=localhost/invehicle_digital_twin:latest --format="{{.Names}}" | xargs podman stop
```
-#### Running in Podman with overridden configuration
+### Running in Podman with overridden configuration
Follow the steps in [Running in Podman](#running-in-podman) to build the container.
1. To run the container with overridden configuration, create your config file and set an
-environment variable called IBEJI_HOME to the absolute path of the directory containing the
-config file:
+environment variable called CONFIG_HOME to the path to the config file:
```shell
- export IBEJI_HOME={absolute path of the directory containing the config file}
+ export CONFIG_HOME={path to directory containing config file}
```
+ For example, to set the configuration for the
+ [Property Provider](../samples/property/provider/) sample, run:
+
+ ```shell
+ export CONFIG_HOME={path-to-repo-root}/samples/container/config/provider
+ ```
+
+ >Note: See [Configuration Defaults](#configuration-defaults) for more information. If running
+ a sample other than the `Property` sample you will need to create your own configuration files.
+
1. Then run the container with the following command:
```shell
- podman run --mount=type=bind,src=${IBEJI_HOME},dst=/sdv/config,ro=true -p 5010:5010 --env-file=./container/config/podman.env --network=slirp4netns:allow_host_loopback=true localhost/invehicle_digital_twin:latest
+ podman run --mount=type=bind,src=${CONFIG_HOME},dst=/mnt/config,ro=true --network=host
+ ```
+
+ For example, to run the `property_provider` image with overridden configuration:
+
+ ```shell
+ podman run --mount=type=bind,src=${CONFIG_HOME},dst=/mnt/config,ro=true --network=host property_provider
```
diff --git a/container/config/docker.env b/container/config/docker.env
deleted file mode 100644
index 56bafc6e..00000000
--- a/container/config/docker.env
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright (c) Microsoft Corporation.
-# Licensed under the MIT license.
-# SPDX-License-Identifier: MIT
-
-# DNS name used by the container to communicate with host.
-HOST_GATEWAY=host.docker.internal
-
-# Alias for localhost to be replaced by HOST_GATEWAY if run in a container.
-LOCALHOST_ALIAS=0.0.0.0
diff --git a/container/config/podman.env b/container/config/podman.env
deleted file mode 100644
index 1abc4a35..00000000
--- a/container/config/podman.env
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright (c) Microsoft Corporation.
-# Licensed under the MIT license.
-# SPDX-License-Identifier: MIT
-
-# DNS name used by the container to communicate with host.
-HOST_GATEWAY=host.containers.internal
-
-# Alias for localhost to be replaced by HOST_GATEWAY if run in a container.
-LOCALHOST_ALIAS=0.0.0.0
diff --git a/container/scripts/argument_sanitizer.sh b/container/scripts/argument_sanitizer.sh
new file mode 100755
index 00000000..d31613d4
--- /dev/null
+++ b/container/scripts/argument_sanitizer.sh
@@ -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] [-r|--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
\ No newline at end of file
diff --git a/container/scripts/container_startup.sh b/container/scripts/container_startup.sh
new file mode 100755
index 00000000..c5f6350a
--- /dev/null
+++ b/container/scripts/container_startup.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+# Copyright (c) Microsoft Corporation.
+# Licensed under the MIT license.
+# SPDX-License-Identifier: MIT
+
+# Exits immediately on failure.
+set -e
+
+# Copy any configuration files present to service configuration.
+# If there is a configuration file with the same name at `/sdv/config` this will overwrite
+# that file with the mounted configuration file.
+cp -rf /mnt/config /sdv
+
+# Start the Ibeji service.
+/sdv/service
\ No newline at end of file
diff --git a/core/common/Cargo.toml b/core/common/Cargo.toml
index 8fa85569..e226d4b7 100644
--- a/core/common/Cargo.toml
+++ b/core/common/Cargo.toml
@@ -35,6 +35,3 @@ url = { workspace = true }
[build-dependencies]
tonic-build = { workspace = true }
-
-[features]
-containerize = []
diff --git a/core/common/src/utils.rs b/core/common/src/utils.rs
index ab732d06..7acfdc03 100644
--- a/core/common/src/utils.rs
+++ b/core/common/src/utils.rs
@@ -116,10 +116,9 @@ pub async fn discover_service_using_chariott(
expected_communication_kind: &str,
expected_communication_reference: &str,
) -> Result {
- let uri = get_uri(chariott_uri)?;
-
- let mut client =
- ServiceRegistryClient::connect(uri).await.map_err(|e| Status::internal(e.to_string()))?;
+ let mut client = ServiceRegistryClient::connect(chariott_uri.to_owned())
+ .await
+ .map_err(|e| Status::internal(e.to_string()))?;
let request = Request::new(DiscoverRequest {
namespace: namespace.to_string(),
@@ -183,39 +182,7 @@ pub async fn get_service_uri(
}
};
- let uri = get_uri(&result)?;
-
- Ok(uri)
-}
-
-/// If feature 'containerize' is set, will modify a localhost uri to point to container's localhost
-/// DNS alias. Otherwise, returns the uri as a String.
-///
-/// # Arguments
-/// * `uri` - The uri to potentially modify.
-pub fn get_uri(uri: &str) -> Result {
- #[cfg(feature = "containerize")]
- let uri = {
- // Container env variable names.
- let host_gateway_env_var: &str = "HOST_GATEWAY";
- let host_alias_env_var: &str = "LOCALHOST_ALIAS";
-
- // Return an error if container env variables are not set.
- let host_gateway = env::var(host_gateway_env_var).map_err(|err| {
- Status::failed_precondition(format!(
- "Unable to get environment var '{host_gateway_env_var}' with error: {err}"
- ))
- })?;
- let host_alias = env::var(host_alias_env_var).map_err(|err| {
- Status::failed_precondition(format!(
- "Unable to get environment var '{host_alias_env_var}' with error: {err}"
- ))
- })?;
-
- uri.replace(&host_alias, &host_gateway)
- };
-
- Ok(uri.to_string())
+ Ok(result)
}
#[cfg(test)]
diff --git a/core/invehicle-digital-twin/Cargo.toml b/core/invehicle-digital-twin/Cargo.toml
index 79509142..213a8bd3 100644
--- a/core/invehicle-digital-twin/Cargo.toml
+++ b/core/invehicle-digital-twin/Cargo.toml
@@ -39,5 +39,4 @@ tonic-build = { workspace = true }
[features]
managed_subscribe = ["dep:managed_subscribe"]
-containerize = ["common/containerize"]
-tokio_console = ["dep:tokio-console-subscriber", "tokio/tracing"]
\ No newline at end of file
+tokio_console = ["dep:tokio-console-subscriber", "tokio/tracing"]
diff --git a/core/invehicle-digital-twin/src/main.rs b/core/invehicle-digital-twin/src/main.rs
index 1949c858..bf6f38ed 100644
--- a/core/invehicle-digital-twin/src/main.rs
+++ b/core/invehicle-digital-twin/src/main.rs
@@ -5,7 +5,6 @@
// Module references behind feature flags. Add any necessary module references here.
// Start: Module references.
-use common::utils;
#[cfg(feature = "managed_subscribe")]
use managed_subscribe::managed_subscribe_module::ManagedSubscribeModule;
@@ -55,10 +54,9 @@ async fn register_invehicle_digital_twin_service_with_chariott(
chariott_uri: &str,
invehicle_digital_twin_uri: &str,
) -> Result<(), Status> {
- let uri = utils::get_uri(chariott_uri)?;
-
- let mut client =
- ServiceRegistryClient::connect(uri).await.map_err(|e| Status::internal(e.to_string()))?;
+ let mut client = ServiceRegistryClient::connect(chariott_uri.to_owned())
+ .await
+ .map_err(|e| Status::internal(e.to_string()))?;
let service = Some(ServiceMetadata {
namespace: INVEHICLE_DIGITAL_TWIN_SERVICE_NAMESPACE.to_string(),
diff --git a/core/module/managed_subscribe/Cargo.toml b/core/module/managed_subscribe/Cargo.toml
index 81b63cc2..184a9758 100644
--- a/core/module/managed_subscribe/Cargo.toml
+++ b/core/module/managed_subscribe/Cargo.toml
@@ -27,6 +27,3 @@ yaml-rust = { workspace = true }
[build-dependencies]
tonic-build = { workspace = true }
-
-[features]
-containerize = ["common/containerize"]
diff --git a/core/module/managed_subscribe/src/managed_subscribe_interceptor.rs b/core/module/managed_subscribe/src/managed_subscribe_interceptor.rs
index 21edf3cd..3efbc1d2 100644
--- a/core/module/managed_subscribe/src/managed_subscribe_interceptor.rs
+++ b/core/module/managed_subscribe/src/managed_subscribe_interceptor.rs
@@ -9,7 +9,7 @@ use parking_lot::RwLock;
use prost::Message;
use std::{collections::HashMap, error::Error, sync::Arc};
-use common::{grpc_interceptor::GrpcInterceptor, utils};
+use common::grpc_interceptor::GrpcInterceptor;
use crate::managed_subscribe_store::{CallbackInfo, EntityMetadata, ManagedSubscribeStore};
@@ -77,7 +77,7 @@ impl GrpcInterceptor for ManagedSubscribeInterceptor {
for endpoint in &mut endpoints {
if endpoint.operations.contains(&Self::MANAGED_SUBSCRIBE_OPERATION.to_string()) {
- let entity_callback = utils::get_uri(&endpoint.uri)?;
+ let entity_callback = endpoint.uri.clone();
let callback_protocol = endpoint.protocol.clone();
// Set endpoint information to the managed subscribe module.
diff --git a/samples/Dockerfile.consumer b/samples/Dockerfile.samples.amd64
similarity index 75%
rename from samples/Dockerfile.consumer
rename to samples/Dockerfile.samples.amd64
index 425a1b30..0b5def23 100644
--- a/samples/Dockerfile.consumer
+++ b/samples/Dockerfile.samples.amd64
@@ -10,12 +10,21 @@
# Create a stage for building the application.
ARG RUST_VERSION=1.72.1
-FROM docker.io/library/rust:${RUST_VERSION}-slim-bullseye AS build
ARG APP_NAME=property-consumer
+ARG UID=10001
+
+FROM docker.io/library/rust:${RUST_VERSION}-slim-bullseye AS build
+ARG APP_NAME
WORKDIR /sdv
COPY ./ .
+# Check that APP_NAME argument is valid.
+RUN /sdv/container/scripts/argument_sanitizer.sh \
+ --arg-value "${APP_NAME}" \
+ --regex "^[a-zA-Z_0-9-]+$" || \
+ ( echo "Argument sanitizer failed for ARG 'APP_NAME'"; exit 1 )
+
# Add Build dependencies.
RUN apt update && apt upgrade -y && apt install -y \
cmake \
@@ -24,15 +33,8 @@ RUN apt update && apt upgrade -y && apt install -y \
pkg-config \
protobuf-compiler
-# Check that APP_NAME argument is valid.
-RUN sanitized=$(echo "${APP_NAME}" | tr -dc '^[a-zA-Z_0-9-]+$'); \
-[ "$sanitized" = "${APP_NAME}" ] || { \
- echo "ARG 'APP_NAME' is invalid. APP_NAME='${APP_NAME}' sanitized='${sanitized}'"; \
- exit 1; \
-}
-
-# Build the application with the 'containerize' feature.
-RUN cargo build --release --bin "${APP_NAME}" --features "containerize"
+# Build the application.
+RUN cargo build --release --bin "${APP_NAME}"
# Copy the built application to working directory.
RUN cp ./target/release/"${APP_NAME}" /sdv/service
@@ -49,12 +51,21 @@ RUN cp ./target/release/"${APP_NAME}" /sdv/service
# reproducability is important, consider using a digest
# (e.g., debian@sha256:ac707220fbd7b67fc19b112cee8170b41a9e97f703f588b2cdbbcdcecdd8af57).
FROM docker.io/library/debian:bullseye-slim AS final
+ARG UID
+
+# Copy container scripts.
+COPY ./container/scripts/*.sh /sdv/scripts/
+
+# Check that UID argument is valid.
+RUN /sdv/scripts/argument_sanitizer.sh \
+ --arg-value "${UID}" \
+ --regex "^[0-9]+$" || \
+ ( echo "Argument sanitizer failed for ARG 'UID'"; exit 1 )
RUN apt update && apt upgrade -y && apt install -y libsdl2-dev
# Create a non-privileged user that the app will run under.
# See https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user
-ARG UID=10001
RUN adduser \
--disabled-password \
--gecos "" \
@@ -63,6 +74,14 @@ RUN adduser \
--no-create-home \
--uid "${UID}" \
appuser
+
+# Create and add user ownership to config directory.
+RUN mkdir -p /sdv/config
+RUN chown appuser /sdv/config
+
+# Create mnt directory to copy override configs into.
+RUN mkdir -p /mnt/config
+
USER appuser
WORKDIR /sdv
@@ -76,8 +95,5 @@ COPY --from=build /sdv/service /sdv/
# Copy configuration for service.
COPY --from=build /sdv/samples/container/config/consumer/ /sdv/config
-# Expose the port that the application listens on.
-EXPOSE 6010
-
# What the container should run when it is started.
-CMD ["/sdv/service"]
+CMD ["/sdv/scripts/container_startup.sh"]
diff --git a/samples/Dockerfile.provider b/samples/Dockerfile.samples.arm64
similarity index 64%
rename from samples/Dockerfile.provider
rename to samples/Dockerfile.samples.arm64
index 34cad0ca..cc108117 100644
--- a/samples/Dockerfile.provider
+++ b/samples/Dockerfile.samples.arm64
@@ -10,32 +10,38 @@
# Create a stage for building the application.
ARG RUST_VERSION=1.72.1
+ARG APP_NAME=property-consumer
+ARG UID=10001
+
FROM docker.io/library/rust:${RUST_VERSION}-slim-bullseye AS build
-ARG APP_NAME=property-provider
+ARG APP_NAME
WORKDIR /sdv
COPY ./ .
+# Check that APP_NAME argument is valid.
+RUN /sdv/container/scripts/argument_sanitizer.sh \
+ --arg-value "${APP_NAME}" \
+ --regex "^[a-zA-Z_0-9-]+$" || \
+ ( echo "Argument sanitizer failed for ARG 'APP_NAME'"; exit 1 )
+
# Add Build dependencies.
RUN apt update && apt upgrade -y && apt install -y \
cmake \
libsdl2-dev \
libssl-dev \
pkg-config \
- protobuf-compiler
+ protobuf-compiler \
+ gcc-aarch64-linux-gnu \
+ g++-aarch64-linux-gnu
-# Check that APP_NAME argument is valid.
-RUN sanitized=$(echo "${APP_NAME}" | tr -dc '^[a-zA-Z_0-9-]+$'); \
-[ "$sanitized" = "${APP_NAME}" ] || { \
- echo "ARG 'APP_NAME' is invalid. APP_NAME='${APP_NAME}' sanitized='${sanitized}'"; \
- exit 1; \
-}
+RUN rustup target add aarch64-unknown-linux-gnu
-# Build the application with the 'containerize' feature.
-RUN cargo build --release --bin "${APP_NAME}" --features "containerize"
+# Build the application.
+RUN cargo build --release --target=aarch64-unknown-linux-gnu --bin "${APP_NAME}"
# Copy the built application to working directory.
-RUN cp ./target/release/"${APP_NAME}" /sdv/service
+RUN cp ./target/aarch64-unknown-linux-gnu/release/"${APP_NAME}" /sdv/service
################################################################################
# Create a new stage for running the application that contains the minimal
@@ -48,13 +54,20 @@ RUN cp ./target/release/"${APP_NAME}" /sdv/service
# most recent version of that tag when you build your Dockerfile. If
# reproducability is important, consider using a digest
# (e.g., debian@sha256:ac707220fbd7b67fc19b112cee8170b41a9e97f703f588b2cdbbcdcecdd8af57).
-FROM docker.io/library/debian:bullseye-slim AS final
+FROM docker.io/arm64v8/debian:bullseye-slim AS final
+ARG UID
+
+# Copy container scripts.
+COPY ./container/scripts/*.sh /sdv/scripts/
-RUN apt update && apt upgrade -y && apt install -y libsdl2-dev
+# Check that UID argument is valid.
+RUN /sdv/scripts/argument_sanitizer.sh \
+ --arg-value "${UID}" \
+ --regex "^[0-9]+$" || \
+ ( echo "Argument sanitizer failed for ARG 'UID'"; exit 1 )
# Create a non-privileged user that the app will run under.
# See https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user
-ARG UID=10001
RUN adduser \
--disabled-password \
--gecos "" \
@@ -63,6 +76,14 @@ RUN adduser \
--no-create-home \
--uid "${UID}" \
appuser
+
+# Create and add user ownership to config directory.
+RUN mkdir -p /sdv/config
+RUN chown appuser /sdv/config
+
+# Create mnt directory to copy override configs into.
+RUN mkdir -p /mnt/config
+
USER appuser
WORKDIR /sdv
@@ -74,10 +95,7 @@ ENV IBEJI_HOME=/sdv/config
COPY --from=build /sdv/service /sdv/
# Copy configuration for service.
-COPY --from=build /sdv/samples/container/config/provider/ /sdv/config
-
-# Expose the port that the application listens on.
-EXPOSE 4010
+COPY --from=build /sdv/samples/container/config/consumer/ /sdv/config
# What the container should run when it is started.
-CMD ["/sdv/service"]
+CMD ["/sdv/scripts/container_startup.sh"]
diff --git a/samples/common/.cargo/config.toml b/samples/common/.cargo/config.toml
new file mode 100644
index 00000000..47b518be
--- /dev/null
+++ b/samples/common/.cargo/config.toml
@@ -0,0 +1,3 @@
+[target.aarch64-unknown-linux-gnu]
+linker = "aarch64-linux-gnu-g++"
+rustflags = [ "-C", "target-feature=+crt-static", "-C", "link-arg=-lg++" ]
diff --git a/samples/common/Cargo.toml b/samples/common/Cargo.toml
index dc5b7659..e398c20b 100644
--- a/samples/common/Cargo.toml
+++ b/samples/common/Cargo.toml
@@ -20,5 +20,6 @@ tokio = { workspace = true }
tonic = { workspace = true }
yaml-rust = { workspace = true }
-[features]
-containerize = []
+# If built for aarch64, enable the 'vendored-ssl' feature.
+[target.'cfg(target_arch = "aarch64")'.dependencies]
+sdl2 = { workspace = true, features = [ "bundled", "static-link" ] }
diff --git a/samples/common/src/utils.rs b/samples/common/src/utils.rs
index 0b4ee2f5..f8497f4f 100644
--- a/samples/common/src/utils.rs
+++ b/samples/common/src/utils.rs
@@ -129,15 +129,12 @@ pub async fn discover_digital_twin_provider_using_ibeji(
})
.cloned()
{
- Some(mut result) => {
+ Some(result) => {
info!(
"Found a matching endpoint for entity id {entity_id} that has URI {}",
result.uri
);
- result.uri = get_uri(&result.uri)
- .map_err(|err| format!("Failed to get provider URI due to error: {err}"))?;
-
Ok(result)
}
None => Err("Did not find an endpoint that met our requirements".to_string()),
@@ -161,10 +158,9 @@ pub async fn discover_service_using_chariott(
communication_kind: &str,
communication_reference: &str,
) -> Result {
- let uri = get_uri(chariott_uri)?;
-
- let mut client =
- ServiceRegistryClient::connect(uri).await.map_err(|e| Status::internal(e.to_string()))?;
+ let mut client = ServiceRegistryClient::connect(chariott_uri.to_owned())
+ .await
+ .map_err(|e| Status::internal(e.to_string()))?;
let request = Request::new(DiscoverRequest {
namespace: namespace.to_string(),
@@ -233,39 +229,7 @@ pub async fn retrieve_invehicle_digital_twin_uri(
}
};
- get_uri(&result).map_err(|err| {
- format!("Failed to retrieve the in-vehicle digital twin service's URI due to error: {err}")
- })
-}
-
-/// If the 'containerize' feature is set, this function will modify the localhost URI to point to
-/// the container's localhost DNS alias. Otherwise, returns the URI as a string.
-///
-/// # Arguments
-/// * `uri` - The uri to potentially modify.
-pub fn get_uri(uri: &str) -> Result {
- #[cfg(feature = "containerize")]
- let uri = {
- // Container env variable names.
- let host_gateway_env_var: &str = "HOST_GATEWAY";
- let host_alias_env_var: &str = "LOCALHOST_ALIAS";
-
- // Return an error if container env variables are not set.
- let host_gateway = std::env::var(host_gateway_env_var).map_err(|err| {
- Status::failed_precondition(format!(
- "Unable to get environment var '{host_gateway_env_var}' with error: {err}"
- ))
- })?;
- let host_alias = std::env::var(host_alias_env_var).map_err(|err| {
- Status::failed_precondition(format!(
- "Unable to get environment var '{host_alias_env_var}' with error: {err}"
- ))
- })?;
-
- uri.replace(&host_alias, &host_gateway)
- };
-
- Ok(uri.to_string())
+ Ok(result)
}
#[cfg(test)]
diff --git a/samples/container/.accepted_words.txt b/samples/container/.accepted_words.txt
deleted file mode 100644
index 49d4301f..00000000
--- a/samples/container/.accepted_words.txt
+++ /dev/null
@@ -1,93 +0,0 @@
-Agemo
-agemo
-APP
-arg
-br
-build
-cargo
-cd
-CHARIOTT
-Chariott
-Chariott's
-chariott
-com
-config
-containerize
-containerized
-Containerization
-Ctrl
-dev
-digitaltwins
-dir
-Dockerfile
-dockerfile
-dockerfiles
-dotnet
-dst
-dt
-dtdl
-DTDL
-en
-env
-fontconfig
-gcc
-gcc's
-github
-hardcheese
-haudebourg
-https
-ibeji
-Ibeji
-Ibeji's
-intellectualproperty
-invehicle
-io
-iot
-js
-json
-JSON
-kbd
-ld
-LD
-libfontconfig
-libsdl
-localhost
-loopback
-md
-microsoft
-minimalistic
-mosquitto
-Mosquitto
-mqtt
-MQTT
-netns
-opendigitaltwins
-plugandplay
-Podman
-podman
-protobuf
-Protobuf
-ps
-repo
-Repo
-rm
-ro
-rustup
-sdk
-sdl
-SDL
-sdv
-slirp
-snapd
-src
-standalone
-sudo
-timothee
-toml
-Tonic
-toolchain
-uri
-URI
-www
-xargs
-yaml
diff --git a/samples/container/README.md b/samples/container/README.md
deleted file mode 100644
index f3467046..00000000
--- a/samples/container/README.md
+++ /dev/null
@@ -1,157 +0,0 @@
-# Samples Containerization
-
-This document covers how to containerize the samples for Ibeji. To run the in-vehicle digital twin
-service as a container or to get more in depth instruction for building and running a container
-please refer to [Ibeji Containerization](../../container/README.md).
-
-## Running the Samples in a Container
-
-Below are the steps for running the sample providers and consumers in a container. Note that the
-configuration files used by the containerized sample are cloned from
-[/samples/container/config](./config/) defined in the project's root.
-
-### Provider
-
-Provider containers utilize the dockerfile [Dockerfile.provider](../Dockerfile.provider).
-
-#### Build
-
-By default, the sample provider built in the Dockerfile is the
-[property-provider](../property/provider/). To change the provider the container builds, use
-the following argument:
-
- Docker
-
- ```shell
- --build-arg APP_NAME={name of the provider}
- ```
-
- For example:
-
- ```shell
- docker build -t provider -f ./samples/Dockerfile.provider . --build-arg APP_NAME=managed-subscribe-provider
- ```
-
- Podman
-
- ```shell
- --build-arg=APP_NAME={name of the provider}
- ```
-
- For example:
-
- ```shell
- podman build -t provider:latest -f ./samples/Dockerfile.provider . --build-arg=APP_NAME=managed-subscribe-provider
- ```
-
-#### Run
-
-If you selected a different provider than the default provider built in the dockerfile, you may
-need to override the configuration file [provider_settings.yaml](./config/provider/provider_settings.yaml).
-To override the configuration of a provider container, follow the below steps after you have built
-the container:
-
- Docker
-
- 1. To run the container with overridden configuration, create your config file and set an
- environment variable called IBEJI_HOME to the absolute path of the directory containing the
- config file:
-
- ```shell
- export IBEJI_HOME={absolute path of the directory containing the config file}
- ```
-
- 1. Then run the container from the project's root with the following command:
-
- ```shell
- docker run -v ${IBEJI_HOME}:/sdv/config --name provider -p 5010:5010 --env-file=./samples/container/config/docker.env --add-host=host.docker.internal:host-gateway -it --rm invehicle_digital_twin
- ```
-
- Podman
-
- 1. To run the container with overridden configuration, create your config file and set an
- environment variable called IBEJI_HOME to the absolute path of the directory containing the
- config file:
-
- ```shell
- export IBEJI_HOME={absolute path of the directory containing the config file}
- ```
-
- 1. Then run the container from the project's root with the following command:
-
- ```shell
- podman run --mount=type=bind,src=${IBEJI_HOME},dst=/sdv/config,ro=true -p 5010:5010 --env-file=./samples/container/config/podman.env --network=slirp4netns:allow_host_loopback=true localhost/provider:latest
- ```
-
-### Consumer
-
-Consumer containers utilize the dockerfile [Dockerfile.consumer](../Dockerfile.consumer).
-
-#### Build
-
-By default, the sample consumer built in the Dockerfile is the
-[property-consumer](../property/consumer/). To change the consumer the container builds, use
-the following argument:
-
- Docker
-
- ```shell
- --build-arg APP_NAME={name of the consumer}
- ```
-
- For example:
-
- ```shell
- docker build -t consumer -f ./samples/Dockerfile.consumer . --build-arg APP_NAME=managed-subscribe-consumer
- ```
-
- Podman
-
- ```shell
- --build-arg=APP_NAME={name of the consumer}
- ```
-
- For example:
-
- ```shell
- podman build -t consumer:latest -f ./samples/Dockerfile.consumer . --build-arg=APP_NAME=managed-subscribe-consumer
- ```
-
-#### Run
-
-If you selected a different consumer than the default consumer built in the dockerfile, you may
-need to override the configuration file [consumer_settings.yaml](./config/consumer/consumer_settings.yaml).
-To override the configuration of a consumer container, follow the below steps after you have built
-the container:
-
- Docker
-
- 1. To run the container with overridden configuration, create your config file and set an
- environment variable called IBEJI_HOME to the absolute path of the directory containing the
- config file:
-
- ```shell
- export IBEJI_HOME={absolute path of the directory containing the config file}
- ```
-
- 1. Then run the container from the project's root with the following command:
-
- ```shell
- docker run -v ${IBEJI_HOME}:/sdv/config --name consumer -p 5010:5010 --env-file=./samples/container/config/docker.env --add-host=host.docker.internal:host-gateway -it --rm invehicle_digital_twin
- ```
-
- Podman
-
- 1. To run the container with overridden configuration, create your config file and set an
- environment variable called IBEJI_HOME to the absolute path of the directory containing the
- config file:
-
- ```shell
- export IBEJI_HOME={absolute path of the directory containing the config file}
- ```
-
- 1. Then run the container from the project's root with the following command:
-
- ```shell
- podman run --mount=type=bind,src=${IBEJI_HOME},dst=/sdv/config,ro=true -p 5010:5010 --env-file=./samples/container/config/podman.env --network=slirp4netns:allow_host_loopback=true localhost/consumer:latest
- ```
diff --git a/samples/container/config/docker.env b/samples/container/config/docker.env
deleted file mode 100644
index 56bafc6e..00000000
--- a/samples/container/config/docker.env
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright (c) Microsoft Corporation.
-# Licensed under the MIT license.
-# SPDX-License-Identifier: MIT
-
-# DNS name used by the container to communicate with host.
-HOST_GATEWAY=host.docker.internal
-
-# Alias for localhost to be replaced by HOST_GATEWAY if run in a container.
-LOCALHOST_ALIAS=0.0.0.0
diff --git a/samples/container/config/podman.env b/samples/container/config/podman.env
deleted file mode 100644
index 1abc4a35..00000000
--- a/samples/container/config/podman.env
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright (c) Microsoft Corporation.
-# Licensed under the MIT license.
-# SPDX-License-Identifier: MIT
-
-# DNS name used by the container to communicate with host.
-HOST_GATEWAY=host.containers.internal
-
-# Alias for localhost to be replaced by HOST_GATEWAY if run in a container.
-LOCALHOST_ALIAS=0.0.0.0
diff --git a/samples/managed_subscribe/Cargo.toml b/samples/managed_subscribe/Cargo.toml
index f82adb36..63ed3e7d 100644
--- a/samples/managed_subscribe/Cargo.toml
+++ b/samples/managed_subscribe/Cargo.toml
@@ -39,5 +39,6 @@ path = "provider/src/main.rs"
name = "managed-subscribe-consumer"
path = "consumer/src/main.rs"
-[features]
-containerize = ["samples-common/containerize"]
+# If built for aarch64, enable the 'vendored-ssl' feature.
+[target.'cfg(target_arch = "aarch64")'.dependencies]
+paho-mqtt = { workspace = true, features = ["vendored-ssl"] }
diff --git a/samples/managed_subscribe/consumer/src/main.rs b/samples/managed_subscribe/consumer/src/main.rs
index e8ec255d..44b467a5 100644
--- a/samples/managed_subscribe/consumer/src/main.rs
+++ b/samples/managed_subscribe/consumer/src/main.rs
@@ -11,7 +11,7 @@ use paho_mqtt as mqtt;
use samples_common::constants::{constraint_type, digital_twin_operation, digital_twin_protocol};
use samples_common::consumer_config;
use samples_common::utils::{
- discover_digital_twin_provider_using_ibeji, get_uri, retrieve_invehicle_digital_twin_uri,
+ discover_digital_twin_provider_using_ibeji, retrieve_invehicle_digital_twin_uri,
};
use samples_protobuf_data_access::module::managed_subscribe::v1::managed_subscribe_client::ManagedSubscribeClient;
use samples_protobuf_data_access::module::managed_subscribe::v1::{
@@ -180,7 +180,7 @@ async fn main() -> Result<(), Box> {
.await?;
// Deconstruct subscription information.
- let broker_uri = get_uri(&subscription_info.uri)?;
+ let broker_uri = subscription_info.uri;
let topic = subscription_info.context;
info!("The broker URI for the AmbientAirTemperature property's provider is {broker_uri}");
diff --git a/samples/managed_subscribe/provider/src/provider_impl.rs b/samples/managed_subscribe/provider/src/provider_impl.rs
index 9fe889a4..a0151042 100644
--- a/samples/managed_subscribe/provider/src/provider_impl.rs
+++ b/samples/managed_subscribe/provider/src/provider_impl.rs
@@ -16,7 +16,6 @@ use log::{debug, info, warn};
use paho_mqtt as mqtt;
use parking_lot::RwLock;
use samples_common::constants::constraint_type;
-use samples_common::utils;
use serde_derive::{Deserialize, Serialize};
use strum_macros::{Display, EnumString};
use tokio::sync::{mpsc, watch};
@@ -131,9 +130,7 @@ impl ProviderImpl {
let min_interval_ms = self.min_interval_ms;
// This should not be empty.
- let mut subscription_info = payload.subscription_info.unwrap();
-
- subscription_info.uri = utils::get_uri(&subscription_info.uri).unwrap();
+ let subscription_info = payload.subscription_info.unwrap();
// Create stop publish channel.
let (sender, mut reciever) = mpsc::channel(10);
diff --git a/samples/property/Cargo.toml b/samples/property/Cargo.toml
index e24508d1..fe7b9743 100644
--- a/samples/property/Cargo.toml
+++ b/samples/property/Cargo.toml
@@ -37,5 +37,6 @@ path = "provider/src/main.rs"
name = "property-consumer"
path = "consumer/src/main.rs"
-[features]
-containerize = ["samples-common/containerize"]
+# If built for aarch64, enable the 'vendored-ssl' feature.
+[target.'cfg(target_arch = "aarch64")'.dependencies]
+paho-mqtt = { workspace = true, features = ["vendored-ssl"] }
diff --git a/samples/property/provider/src/main.rs b/samples/property/provider/src/main.rs
index 0808174a..21f9c052 100644
--- a/samples/property/provider/src/main.rs
+++ b/samples/property/provider/src/main.rs
@@ -8,9 +8,7 @@ use log::{debug, info, warn, LevelFilter};
use paho_mqtt as mqtt;
use samples_common::constants::{digital_twin_operation, digital_twin_protocol};
use samples_common::provider_config;
-use samples_common::utils::{
- get_uri, retrieve_invehicle_digital_twin_uri, retry_async_based_on_status,
-};
+use samples_common::utils::{retrieve_invehicle_digital_twin_uri, retry_async_based_on_status};
use samples_protobuf_data_access::invehicle_digital_twin::v1::invehicle_digital_twin_client::InvehicleDigitalTwinClient;
use samples_protobuf_data_access::invehicle_digital_twin::v1::{
EndpointInfo, EntityAccessInfo, RegisterRequest,
@@ -209,9 +207,7 @@ async fn main() -> Result<(), Box> {
})
.await?;
- let stream_uri = get_uri(&broker_uri)?;
-
- start_ambient_air_temperature_data_stream(stream_uri, topic);
+ start_ambient_air_temperature_data_stream(broker_uri, topic);
signal::ctrl_c().await.expect("Failed to listen for control-c event");
diff --git a/samples/streaming/.cargo/config.toml b/samples/streaming/.cargo/config.toml
new file mode 100644
index 00000000..47b518be
--- /dev/null
+++ b/samples/streaming/.cargo/config.toml
@@ -0,0 +1,3 @@
+[target.aarch64-unknown-linux-gnu]
+linker = "aarch64-linux-gnu-g++"
+rustflags = [ "-C", "target-feature=+crt-static", "-C", "link-arg=-lg++" ]
diff --git a/samples/streaming/Cargo.toml b/samples/streaming/Cargo.toml
index 1a1b8b41..431917a8 100644
--- a/samples/streaming/Cargo.toml
+++ b/samples/streaming/Cargo.toml
@@ -45,3 +45,7 @@ path = "provider/src/main.rs"
[[bin]]
name = "streaming-consumer"
path = "consumer/src/main.rs"
+
+# If built for aarch64, enable the 'vendored-ssl' feature.
+[target.'cfg(target_arch = "aarch64")'.dependencies]
+sdl2 = { workspace = true, features = [ "bundled", "static-link" ] }