diff --git a/.github/workflows/build-mlconnector.yml b/.github/workflows/build-mlconnector.yml new file mode 100644 index 0000000..8ea1196 --- /dev/null +++ b/.github/workflows/build-mlconnector.yml @@ -0,0 +1,179 @@ +name: Build agent containers + +on: + workflow_call: + inputs: + agent: + default: 'node' + required: false + type: string + registry: + default: 'harbor.nbfc.io' + required: false + type: string + workflow_dispatch: + inputs: + agent: + default: 'node' + required: false + type: string + registry: + default: 'harbor.nbfc.io' + required: false + type: string + +env: + REGISTRY: ${{ github.event.inputs.registry || 'harbor.nbfc.io' }} + REGISTRY_IMAGE: ${{ github.event.inputs.registry || 'harbor.nbfc.io' }}/mlsysops/mlconnector + RUNNER_ARCH_MAP: '[{"amd64":"x86_64", "arm64":"aarch64", "arm":"armv7l"}]' + +jobs: + build: + name: Build Docker Image + runs-on: ${{ format('{0}-{1}', 'base-dind-2204', matrix.arch) }} + strategy: + matrix: + arch: ["arm64", "amd64"] + fail-fast: false + outputs: + digest-amd64: ${{ steps.set-outputs.outputs.digest-amd64 }} + digest-arm64: ${{ steps.set-outputs.outputs.digest-arm64 }} + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Login to registry ${{ env.REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ secrets.HARBOR_USER }} + password: ${{ secrets.HARBOR_SECRET }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY_IMAGE }} + tags: | + type=sha,prefix=${{ matrix.arch }}- + type=ref,event=branch,prefix=${{ matrix.arch }}- + + - name: Build and push ${{ matrix.arch }} image + id: build-and-push + uses: docker/build-push-action@v6 + with: + context: ./mlconnector/src + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + platforms: linux/${{ matrix.arch }} + push: true + file: ./mlconnector/src/Dockerfile + provenance: false + build-args: | + ARCHTAG=${{ fromJson(env.RUNNER_ARCH_MAP)[0][matrix.arch] }} + BRANCH=${{ github.event.ref_name || github.ref_name }} + + - name: Set ${{ matrix.arch }} digest output + id: set-outputs + run: | + # Workaround for https://github.com/actions/runner/issues/2499 + echo "digest-${{ matrix.arch }}=${{ steps.build-and-push.outputs.digest }}" \ + >> "$GITHUB_OUTPUT" + shell: bash + + create-manifest: + name: Create Merged Docker Image Manifest + needs: [build] + runs-on: 'base-dind-2204-amd64' + outputs: + digest-merged: ${{ steps.inspect.outputs.digest-merged }} + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Login to registry ${{ inputs.REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ secrets.HARBOR_USER }} + password: ${{ secrets.HARBOR_SECRET }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY_IMAGE }} + tags: | + type=sha + type=ref,event=branch + type=raw,value=latest + + - name: Create and push manifest + run: | + docker buildx imagetools create \ + $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< \ + "$DOCKER_METADATA_OUTPUT_JSON") \ + ${{ env.REGISTRY_IMAGE }}@${{ needs.build.outputs.digest-amd64 }} \ + ${{ env.REGISTRY_IMAGE }}@${{ needs.build.outputs.digest-arm64 }} + shell: bash + + - name: Inspect merged image + id: inspect + run: | + docker buildx imagetools inspect \ + ${{ env.REGISTRY_IMAGE }}:${{ steps.meta.outputs.version }} + digest=$(docker buildx imagetools inspect \ + ${{ env.REGISTRY_IMAGE }}:${{ steps.meta.outputs.version }} \ + --format '{{json .Manifest}}' | jq -r '.digest') + if [[ -z "${digest}" ]]; then + echo "Could not get merged image digest" + exit 1 + fi + echo "digest-merged=${digest}" >> "$GITHUB_OUTPUT" + shell: bash + + sign: + name: Sign Docker Images + needs: [build, create-manifest] + runs-on: 'base-dind-2204-amd64' + permissions: + contents: read + id-token: write + + steps: + - name: Install Cosign + uses: sigstore/cosign-installer@v3 + + - name: Verify Cosign installation + run: cosign version + + - name: Login to registry ${{ env.REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ secrets.HARBOR_USER }} + password: ${{ secrets.HARBOR_SECRET }} + + - name: Sign published Docker images + env: + DIGESTS: >- + ${{ needs.create-manifest.outputs.digest-merged }} + ${{ needs.build.outputs.digest-amd64 }} + ${{ needs.build.outputs.digest-arm64 }} + run: | + for digest in ${DIGESTS}; do + cosign sign --yes ${{ env.REGISTRY_IMAGE }}@${digest} \ + -a "repo=${{ github.repository }}" \ + -a "workflow=${{ github.workflow }}" \ + -a "ref=${{ github.sha }}" \ + -a "author=Nubificus LTD" + done + shell: bash diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f44d517..c596d70 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -68,6 +68,14 @@ jobs: uses: ./.github/workflows/build-northbound-api.yml secrets: inherit + build-mlconnector: + name: Build MLConnector container Image + if: | + contains(github.event.pull_request.labels.*.name, 'ok-to-test') && + !contains(github.event.pull_request.labels.*.name, 'skip-build-containers') + uses: ./.github/workflows/build-mlconnector.yml + secrets: inherit + build-test-app: #needs: [build-agent-pkg] name: Build testing application containers diff --git a/.github/workflows/ci_manual.yml b/.github/workflows/ci_manual.yml index 612dac6..e1fbd3c 100644 --- a/.github/workflows/ci_manual.yml +++ b/.github/workflows/ci_manual.yml @@ -50,6 +50,14 @@ jobs: uses: ./.github/workflows/build-northbound-api.yml secrets: inherit + build-mlconnector: + name: Build MLConnector container Image + if: | + contains(github.event.pull_request.labels.*.name, 'ok-to-test') && + !contains(github.event.pull_request.labels.*.name, 'skip-build-containers') + uses: ./.github/workflows/build-mlconnector.yml + secrets: inherit + build-test-app: #needs: [build-agent-pkg] name: Build testing application containers diff --git a/mlconnector/docker-compose.yaml b/mlconnector/docker-compose.yaml index 0d901c6..fbd3b48 100644 --- a/mlconnector/docker-compose.yaml +++ b/mlconnector/docker-compose.yaml @@ -64,7 +64,6 @@ services: # - api_network app: - #image: registry.mlsysops.eu/usecases/augmenta-demo-testbed/side-api:0.0.1 build: ./src container_name: api env_file: diff --git a/northbound-api/mlsysops-test-app-description.yaml b/northbound-api/mlsysops-test-app-description.yaml index ea08a13..bab88aa 100644 --- a/northbound-api/mlsysops-test-app-description.yaml +++ b/northbound-api/mlsysops-test-app-description.yaml @@ -2,14 +2,19 @@ MLSysOpsApp: name: test-application cluster_placement: cluster_id: - - mls04 + - mls01 components: - metadata: name: server-app uid: server-app-v1 node_placement: +<<<<<<<< HEAD:northbound-api/mlsysops-test-app-description.yaml node: mls04 restart_policy: on_failure +======== + node: mls01 + restart_policy: OnFailure +>>>>>>>> e3625f0 (feat: Fix various errors with CLI, agents and NB API):mlsysops-cli/mlsysops-test-app-description.yaml containers: - image: harbor.nbfc.io/mlsysops/test-app:latest image_pull_policy: IfNotPresent @@ -37,7 +42,7 @@ MLSysOpsApp: - metadata: name: client-app uid: client-app-v1 - restart_policy: on_failure + restart_policy: OnFailure containers: - image: harbor.nbfc.io/mlsysops/test-app:latest image_pull_policy: IfNotPresent