diff --git a/.github/workflows/flex-build-push.yml b/.github/workflows/flex-build-push.yml new file mode 100644 index 0000000..eaecdae --- /dev/null +++ b/.github/workflows/flex-build-push.yml @@ -0,0 +1,58 @@ +--- +name: Build & Push Flex Docker Container + +on: + push: + branches: [main] + tags: ["v*.*.*"] + pull_request: + types: [opened, synchronize, reopened] + +permissions: + contents: read + +env: + REGISTRY: ghcr.io + +jobs: + build-push-flex: + runs-on: [ubuntu-latest] + permissions: + contents: write + packages: write + pull-requests: write + steps: + - uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5.5.1 + id: metadata + env: + DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index + with: + images: ${{ env.REGISTRY }}/${{ github.repository }}-flex + # Generate Docker tags based on the following events/attributes + tags: | + type=raw,value=latest,enable={{is_default_branch}} + type=ref,event=pr + type=semver,pattern={{raw}} + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + - uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db # v3.6.1 + - uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + with: + persist-credentials: false + submodules: true + - uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85 # v6.7.0 + with: + file: Dockerfile.flex + tags: ${{ steps.metadata.outputs.tags }} + labels: ${{ steps.metadata.outputs.labels }} + annotations: ${{ steps.metadata.outputs.annotations }} + sbom: true + provenance: true + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/Dockerfile.flex b/Dockerfile.flex index 9287315..bee1710 100644 --- a/Dockerfile.flex +++ b/Dockerfile.flex @@ -10,11 +10,21 @@ COPY . /workspace RUN cmake --preset flex \ && cmake --build --preset flex +RUN apt-get update && apt-get install -y --no-install-recommends net-tools + FROM scratch +HEALTHCHECK --interval=5s --retries=100 CMD netstat -ltn | grep -c ":1234"; if [ 0 != $? ]; then exit 1; fi; + WORKDIR /flex COPY --from=builder /workspace/build/flex/postmaster/flex/postmaster.flex /flex/ COPY --from=builder /lib/x86_64-linux-gnu/libc.so.6 /lib/x86_64-linux-gnu/libc.so.6 +COPY --from=builder /bin/sh /bin/sh +COPY --from=builder /usr/bin/netstat /usr/bin/netstat +COPY --from=builder /usr/bin/grep /usr/bin/grep +COPY --from=builder /lib/x86_64-linux-gnu/libselinux.so.1 /lib/x86_64-linux-gnu/libselinux.so.1 +COPY --from=builder /lib/x86_64-linux-gnu/libpcre2-8.so.0 /lib/x86_64-linux-gnu/libpcre2-8.so.0 +COPY --from=builder /lib64/ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2 ENTRYPOINT ["/flex/postmaster.flex"] CMD ["--help"] diff --git a/postmaster/flex/Main.cpp b/postmaster/flex/Main.cpp index 368d682..a39c64f 100644 --- a/postmaster/flex/Main.cpp +++ b/postmaster/flex/Main.cpp @@ -11,6 +11,16 @@ #include "services/network_instantiations/NetworkAdapter.hpp" #include "services/tracer/GlobalTracer.hpp" #include "services/tracer/TracerOnIoOutputInfrastructure.hpp" +#include + +std::string Env(const char* name) +{ + auto result = std::getenv(name); + if (result != nullptr) + return result; + else + return ""; +} int main(int argc, const char* argv[], const char* env[]) { @@ -24,7 +34,17 @@ int main(int argc, const char* argv[], const char* env[]) try { - parser.ParseCLI(argc, argv); + std::string firmwareArg = Env("POSTMASTER_FIRMWARE"); + std::string urlArg = Env("POSTMASTER_IP"); + std::string passwordArg = Env("POSTMASTER_PASSWORD"); + + if (firmwareArg.empty() && urlArg.empty()) + { + parser.ParseCLI(argc, argv); + firmwareArg = args::get(firmwareArgument); + urlArg = args::get(urlArgument); + passwordArg = args::get(passwordArgument); + } static hal::TimerServiceGeneric timerService; static hal::SynchronousRandomDataGeneratorGeneric randomDataGenerator; @@ -32,17 +52,17 @@ int main(int argc, const char* argv[], const char* env[]) static main_::NetworkAdapter network; static hal::FileSystemGeneric fileSystem; - static auto firmware = firmwareArgument ? fileSystem.ReadBinaryFile(args::get(firmwareArgument)) : std::vector{}; + static auto firmware = !firmwareArg.empty() ? fileSystem.ReadBinaryFile(firmwareArg) : std::vector{}; static services::HttpClientConnectorWithNameResolverImpl<> connector(network.ConnectionFactoryWithNameResolver()); - static infra::BoundedString::WithStorage<512> httpUrl{ args::get(urlArgument) }; - static infra::BoundedString::WithStorage<512> webSocketUrl{ args::get(urlArgument) }; - static application::EchoWebSocketClientFactory webSocketFactory(webSocketUrl, 80, network.ConnectionFactory(), tracer.tracer); + static infra::BoundedString::WithStorage<512> httpUrl{ urlArg }; + static infra::BoundedString::WithStorage<512> webSocketUrl{ urlArg }; + static application::EchoWebSocketClientFactory webSocketFactory(webSocketUrl, services::PortFromUrl(webSocketUrl).ValueOr(80), network.ConnectionFactory(), tracer.tracer); static services::HttpClientWebSocketInitiation webSocketInitiation(webSocketFactory, connector, webSocketFactory, randomDataGenerator, services::noAutoConnect); - static application::HttpClientAuthenticationDigest::WithMaxHeaders<10> clientAuthentication{ args::get(passwordArgument), randomDataGenerator }; + static application::HttpClientAuthenticationDigest::WithMaxHeaders<10> clientAuthentication{ passwordArg, randomDataGenerator }; static services::HttpClientAuthenticationConnector clientAuthenticationConnector{ connector, clientAuthentication }; - static application::FlexHttpClient httpClient(httpUrl, 80, clientAuthenticationConnector, firmware, webSocketInitiation, tracer.tracer); + static application::FlexHttpClient httpClient(httpUrl, services::PortFromUrl(httpUrl).ValueOr(80), clientAuthenticationConnector, firmware, webSocketInitiation, tracer.tracer); network.ExecuteUntil([&]() {