diff --git a/.github/workflows/image-build.yaml b/.github/workflows/image-build.yaml index f25d0b1fc..d462c9d51 100644 --- a/.github/workflows/image-build.yaml +++ b/.github/workflows/image-build.yaml @@ -10,6 +10,26 @@ on: # yamllint disable-line rule:truthy paths: [.github/workflows/image-build.yaml] jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Build bpfman binary + run: cargo build -p bpfman --verbose + + - name: archive bpfman binary + run: | + cd target/debug + tar -czvf bpfman.tar.gz bpfman + + - name: Archive bpfman Binaries + uses: actions/upload-artifact@v4 + with: + name: bpfman + path: | + ./target/debug/bpfman.tar.gz + build-and-push-images: permissions: contents: read @@ -204,14 +224,6 @@ jobs: username: ${{ secrets.BPFMAN_USERSPACE_USERNAME }} password: ${{ secrets.BPFMAN_USERSPACE_ROBOT_TOKEN }} - - name: Login to quay.io/bpfman-bytecode - uses: redhat-actions/podman-login@v1 - if: ${{ github.event_name == 'push' && matrix.image.repository == 'bpfman-bytecode' }} - with: - registry: ${{ matrix.image.registry }} - username: ${{ secrets.BPFMAN_BYTECODE_USERNAME }} - password: ${{ secrets.BPFMAN_BYTECODE_ROBOT_TOKEN }} - - name: Extract metadata (tags, labels) for image id: meta uses: docker/metadata-action@v5.5.1 @@ -256,6 +268,7 @@ jobs: done build-and-push-bytecode-images: + needs: [build] permissions: contents: read packages: write @@ -271,313 +284,9 @@ jobs: bpf_build_wrapper: go repository: bpfman-bytecode image: go-xdp-counter - context: ./examples/go-xdp-counter - dockerfile: ./Containerfile.bytecode - build_args: | - PROGRAM_NAME=go-xdp-counter - BPF_FUNCTION_NAME=xdp_stats - PROGRAM_TYPE=xdp - BYTECODE_FILENAME=bpf_bpfel.o - tags: | - type=ref,event=branch - type=ref,event=tag - type=ref,event=pr - type=sha,format=long - # set latest tag for default branch - type=raw,value=latest,enable={{is_default_branch}} - - - registry: quay.io - build_language: go - bpf_build_wrapper: go - repository: bpfman-bytecode - image: go-tc-counter - context: ./examples/go-tc-counter - dockerfile: ./Containerfile.bytecode - build_args: | - PROGRAM_NAME=go-tc-counter - BPF_FUNCTION_NAME=stats - PROGRAM_TYPE=tc - BYTECODE_FILENAME=bpf_bpfel.o - tags: | - type=ref,event=branch - type=ref,event=tag - type=ref,event=pr - type=sha,format=long - # set latest tag for default branch - type=raw,value=latest,enable={{is_default_branch}} - - - registry: quay.io - build_language: go - bpf_build_wrapper: go - repository: bpfman-bytecode - image: go-tracepoint-counter - context: ./examples/go-tracepoint-counter - dockerfile: ./Containerfile.bytecode - build_args: | - PROGRAM_NAME=go-tracepoint-counter - BPF_FUNCTION_NAME=tracepoint_kill_recorder - PROGRAM_TYPE=tracepoint - BYTECODE_FILENAME=bpf_bpfel.o - tags: | - type=ref,event=branch - type=ref,event=tag - type=ref,event=pr - type=sha,format=long - # set latest tag for default branch - type=raw,value=latest,enable={{is_default_branch}} - - - registry: quay.io - build_language: go - bpf_build_wrapper: go - repository: bpfman-bytecode - image: go-kprobe-counter - context: ./examples/go-kprobe-counter - dockerfile: ./Containerfile.bytecode - build_args: | - PROGRAM_NAME=kprobe_counter - BPF_FUNCTION_NAME=kprobe_counter - PROGRAM_TYPE=kprobe - BYTECODE_FILENAME=bpf_bpfel.o - tags: | - type=ref,event=branch - type=ref,event=tag - type=ref,event=pr - type=sha,format=long - # set latest tag for default branch - type=raw,value=latest,enable={{is_default_branch}} - - - registry: quay.io - build_language: go - bpf_build_wrapper: go - repository: bpfman-bytecode - image: go-uprobe-counter - context: ./examples/go-uprobe-counter - dockerfile: ./Containerfile.bytecode - build_args: | - PROGRAM_NAME=uprobe_counter - BPF_FUNCTION_NAME=uprobe_counter - PROGRAM_TYPE=uprobe - BYTECODE_FILENAME=bpf_bpfel.o - tags: | - type=ref,event=branch - type=ref,event=tag - type=ref,event=pr - type=sha,format=long - # set latest tag for default branch - type=raw,value=latest,enable={{is_default_branch}} - - - registry: quay.io - build_language: go - bpf_build_wrapper: go - repository: bpfman-bytecode - image: go-uretprobe-counter - context: ./examples/go-uretprobe-counter - dockerfile: ./Containerfile.bytecode - build_args: | - PROGRAM_NAME=uretprobe_counter - BPF_FUNCTION_NAME=uretprobe_counter - PROGRAM_TYPE=uretprobe - BYTECODE_FILENAME=bpf_x86_bpfel.o - tags: | - type=ref,event=branch - type=ref,event=tag - type=ref,event=pr - type=sha,format=long - # set latest tag for default branch - type=raw,value=latest,enable={{is_default_branch}} - - - registry: quay.io - build_language: rust - bpf_build_wrapper: rust - repository: bpfman-bytecode - image: xdp_pass - context: ./tests/integration-test/bpf/.output - dockerfile: ./Containerfile.bytecode - build_args: | - PROGRAM_NAME=xdp_pass - BPF_FUNCTION_NAME=pass - PROGRAM_TYPE=xdp - BYTECODE_FILENAME=xdp_pass.bpf.o - tags: | - type=ref,event=branch - type=ref,event=tag - type=ref,event=pr - type=sha,format=long - # set latest tag for default branch - type=raw,value=latest,enable={{is_default_branch}} - - - registry: quay.io - build_language: rust - bpf_build_wrapper: rust - repository: bpfman-bytecode - image: xdp_pass_private - context: ./tests/integration-test/bpf/.output - dockerfile: ./Containerfile.bytecode - build_args: | - PROGRAM_NAME=xdp_pass_private - BPF_FUNCTION_NAME=pass - PROGRAM_TYPE=xdp - BYTECODE_FILENAME=xdp_pass.bpf.o - tags: | - type=ref,event=branch - type=ref,event=tag - type=ref,event=pr - type=sha,format=long - # set latest tag for default branch - type=raw,value=latest,enable={{is_default_branch}} - - - registry: quay.io - build_language: rust - bpf_build_wrapper: rust - repository: bpfman-bytecode - image: tc_pass - context: ./tests/integration-test/bpf/.output - dockerfile: ./Containerfile.bytecode - build_args: | - PROGRAM_NAME=tc_pass - BPF_FUNCTION_NAME=pass - PROGRAM_TYPE=tc - BYTECODE_FILENAME=tc_pass.bpf.o - tags: | - type=ref,event=branch - type=ref,event=tag - type=ref,event=pr - type=sha,format=long - # set latest tag for default branch - type=raw,value=latest,enable={{is_default_branch}} - - - registry: quay.io - build_language: rust - bpf_build_wrapper: rust - repository: bpfman-bytecode - image: tracepoint - context: ./tests/integration-test/bpf/.output - dockerfile: ./Containerfile.bytecode - build_args: | - PROGRAM_NAME=tracepoint - BPF_FUNCTION_NAME=enter_openat - PROGRAM_TYPE=tracepoint - BYTECODE_FILENAME=tp_openat.bpf.o - tags: | - type=ref,event=branch - type=ref,event=tag - type=ref,event=pr - type=sha,format=long - # set latest tag for default branch - type=raw,value=latest,enable={{is_default_branch}} - - - registry: quay.io - build_language: rust - bpf_build_wrapper: rust - repository: bpfman-bytecode - image: uprobe - context: ./tests/integration-test/bpf/.output - dockerfile: ./Containerfile.bytecode - build_args: | - PROGRAM_NAME=uprobe - BPF_FUNCTION_NAME=my_uprobe - PROGRAM_TYPE=uprobe - BYTECODE_FILENAME=uprobe.bpf.o - tags: | - type=ref,event=branch - type=ref,event=tag - type=ref,event=pr - type=sha,format=long - # set latest tag for default branch - type=raw,value=latest,enable={{is_default_branch}} - - - registry: quay.io - build_language: rust - bpf_build_wrapper: rust - repository: bpfman-bytecode - image: uretprobe - context: ./tests/integration-test/bpf/.output - dockerfile: ./Containerfile.bytecode - build_args: | - PROGRAM_NAME=uretprobe - BPF_FUNCTION_NAME=my_uretprobe - PROGRAM_TYPE=uretprobe - BYTECODE_FILENAME=uprobe.bpf.o - tags: | - type=ref,event=branch - type=ref,event=tag - type=ref,event=pr - type=sha,format=long - # set latest tag for default branch - type=raw,value=latest,enable={{is_default_branch}} - - - registry: quay.io - build_language: rust - bpf_build_wrapper: rust - repository: bpfman-bytecode - image: kprobe - context: ./tests/integration-test/bpf/.output - dockerfile: ./Containerfile.bytecode - build_args: | - PROGRAM_NAME=kprobe - BPF_FUNCTION_NAME=my_kprobe - PROGRAM_TYPE=kprobe - BYTECODE_FILENAME=kprobe.bpf.o - tags: | - type=ref,event=branch - type=ref,event=tag - type=ref,event=pr - type=sha,format=long - # set latest tag for default branch - type=raw,value=latest,enable={{is_default_branch}} - - - registry: quay.io - build_language: rust - bpf_build_wrapper: rust - repository: bpfman-bytecode - image: kretprobe - context: ./tests/integration-test/bpf/.output - dockerfile: ./Containerfile.bytecode - build_args: | - PROGRAM_NAME=kretprobe - BPF_FUNCTION_NAME=my_kretprobe - PROGRAM_TYPE=kretprobe - BYTECODE_FILENAME=kprobe.bpf.o - tags: | - type=ref,event=branch - type=ref,event=tag - type=ref,event=pr - type=sha,format=long - # set latest tag for default branch - type=raw,value=latest,enable={{is_default_branch}} - - - registry: quay.io - build_language: rust - bpf_build_wrapper: rust - repository: bpfman-bytecode - image: fentry - context: ./tests/integration-test/bpf/.output - dockerfile: ./Containerfile.bytecode - build_args: | - PROGRAM_NAME=do_unlinkat - BPF_FUNCTION_NAME=test_fentry - PROGRAM_TYPE=fentry - BYTECODE_FILENAME=fentry.bpf.o - tags: | - type=ref,event=branch - type=ref,event=tag - type=ref,event=pr - type=sha,format=long - # set latest tag for default branch - type=raw,value=latest,enable={{is_default_branch}} - - - registry: quay.io - build_language: rust - bpf_build_wrapper: rust - repository: bpfman-bytecode - image: fexit - context: ./tests/integration-test/bpf/.output + context: . dockerfile: ./Containerfile.bytecode - build_args: | - PROGRAM_NAME=do_unlinkat - BPF_FUNCTION_NAME=test_fexit - PROGRAM_TYPE=fexit - BYTECODE_FILENAME=fentry.bpf.o + bytecode_path: ./examples/go-xdp-counter/bpf_bpfel.o tags: | type=ref,event=branch type=ref,event=tag @@ -586,38 +295,338 @@ jobs: # set latest tag for default branch type=raw,value=latest,enable={{is_default_branch}} - - registry: quay.io - build_language: rust - bpf_build_wrapper: rust - repository: bpfman - image: xdp-dispatcher - context: . - dockerfile: ./Containerfile.xdp_dispatcher_v1 - tags: | - type=sha,format=long - type=raw,value=v1,enable=true - - - registry: quay.io - build_language: rust - bpf_build_wrapper: rust - repository: bpfman - image: xdp-dispatcher - context: . - dockerfile: ./Containerfile.xdp_dispatcher_v2 - tags: | - type=sha,format=long - type=raw,value=v2,enable=true - - - registry: quay.io - build_language: rust - bpf_build_wrapper: rust - repository: bpfman - image: tc-dispatcher - context: . - dockerfile: ./Containerfile.tc_dispatcher - tags: | - type=sha,format=long - type=raw,value=v1,enable=true + # - registry: quay.io + # build_language: go + # bpf_build_wrapper: go + # repository: bpfman-bytecode + # image: go-tc-counter + # context: ./examples/go-tc-counter + # dockerfile: ./Containerfile.bytecode + # build_args: | + # PROGRAM_NAME=go-tc-counter + # BPF_FUNCTION_NAME=stats + # PROGRAM_TYPE=tc + # BYTECODE_FILENAME=bpf_bpfel.o + # tags: | + # type=ref,event=branch + # type=ref,event=tag + # type=ref,event=pr + # type=sha,format=long + # # set latest tag for default branch + # type=raw,value=latest,enable={{is_default_branch}} + + # - registry: quay.io + # build_language: go + # bpf_build_wrapper: go + # repository: bpfman-bytecode + # image: go-tracepoint-counter + # context: ./examples/go-tracepoint-counter + # dockerfile: ./Containerfile.bytecode + # build_args: | + # PROGRAM_NAME=go-tracepoint-counter + # BPF_FUNCTION_NAME=tracepoint_kill_recorder + # PROGRAM_TYPE=tracepoint + # BYTECODE_FILENAME=bpf_bpfel.o + # tags: | + # type=ref,event=branch + # type=ref,event=tag + # type=ref,event=pr + # type=sha,format=long + # # set latest tag for default branch + # type=raw,value=latest,enable={{is_default_branch}} + + # - registry: quay.io + # build_language: go + # bpf_build_wrapper: go + # repository: bpfman-bytecode + # image: go-kprobe-counter + # context: ./examples/go-kprobe-counter + # dockerfile: ./Containerfile.bytecode + # build_args: | + # PROGRAM_NAME=kprobe_counter + # BPF_FUNCTION_NAME=kprobe_counter + # PROGRAM_TYPE=kprobe + # BYTECODE_FILENAME=bpf_bpfel.o + # tags: | + # type=ref,event=branch + # type=ref,event=tag + # type=ref,event=pr + # type=sha,format=long + # # set latest tag for default branch + # type=raw,value=latest,enable={{is_default_branch}} + + # - registry: quay.io + # build_language: go + # bpf_build_wrapper: go + # repository: bpfman-bytecode + # image: go-uprobe-counter + # context: ./examples/go-uprobe-counter + # dockerfile: ./Containerfile.bytecode + # build_args: | + # PROGRAM_NAME=uprobe_counter + # BPF_FUNCTION_NAME=uprobe_counter + # PROGRAM_TYPE=uprobe + # BYTECODE_FILENAME=bpf_bpfel.o + # tags: | + # type=ref,event=branch + # type=ref,event=tag + # type=ref,event=pr + # type=sha,format=long + # # set latest tag for default branch + # type=raw,value=latest,enable={{is_default_branch}} + + # - registry: quay.io + # build_language: go + # bpf_build_wrapper: go + # repository: bpfman-bytecode + # image: go-uretprobe-counter + # context: ./examples/go-uretprobe-counter + # dockerfile: ./Containerfile.bytecode + # build_args: | + # PROGRAM_NAME=uretprobe_counter + # BPF_FUNCTION_NAME=uretprobe_counter + # PROGRAM_TYPE=uretprobe + # BYTECODE_FILENAME=bpf_x86_bpfel.o + # tags: | + # type=ref,event=branch + # type=ref,event=tag + # type=ref,event=pr + # type=sha,format=long + # # set latest tag for default branch + # type=raw,value=latest,enable={{is_default_branch}} + + # - registry: quay.io + # build_language: rust + # bpf_build_wrapper: rust + # repository: bpfman-bytecode + # image: xdp_pass + # context: ./tests/integration-test/bpf/.output + # dockerfile: ./Containerfile.bytecode + # build_args: | + # PROGRAM_NAME=xdp_pass + # BPF_FUNCTION_NAME=pass + # PROGRAM_TYPE=xdp + # BYTECODE_FILENAME=xdp_pass.bpf.o + # tags: | + # type=ref,event=branch + # type=ref,event=tag + # type=ref,event=pr + # type=sha,format=long + # # set latest tag for default branch + # type=raw,value=latest,enable={{is_default_branch}} + + # - registry: quay.io + # build_language: rust + # bpf_build_wrapper: rust + # repository: bpfman-bytecode + # image: xdp_pass_private + # context: ./tests/integration-test/bpf/.output + # dockerfile: ./Containerfile.bytecode + # build_args: | + # PROGRAM_NAME=xdp_pass_private + # BPF_FUNCTION_NAME=pass + # PROGRAM_TYPE=xdp + # BYTECODE_FILENAME=xdp_pass.bpf.o + # tags: | + # type=ref,event=branch + # type=ref,event=tag + # type=ref,event=pr + # type=sha,format=long + # # set latest tag for default branch + # type=raw,value=latest,enable={{is_default_branch}} + + # - registry: quay.io + # build_language: rust + # bpf_build_wrapper: rust + # repository: bpfman-bytecode + # image: tc_pass + # context: ./tests/integration-test/bpf/.output + # dockerfile: ./Containerfile.bytecode + # build_args: | + # PROGRAM_NAME=tc_pass + # BPF_FUNCTION_NAME=pass + # PROGRAM_TYPE=tc + # BYTECODE_FILENAME=tc_pass.bpf.o + # tags: | + # type=ref,event=branch + # type=ref,event=tag + # type=ref,event=pr + # type=sha,format=long + # # set latest tag for default branch + # type=raw,value=latest,enable={{is_default_branch}} + + # - registry: quay.io + # build_language: rust + # bpf_build_wrapper: rust + # repository: bpfman-bytecode + # image: tracepoint + # context: ./tests/integration-test/bpf/.output + # dockerfile: ./Containerfile.bytecode + # build_args: | + # PROGRAM_NAME=tracepoint + # BPF_FUNCTION_NAME=enter_openat + # PROGRAM_TYPE=tracepoint + # BYTECODE_FILENAME=tp_openat.bpf.o + # tags: | + # type=ref,event=branch + # type=ref,event=tag + # type=ref,event=pr + # type=sha,format=long + # # set latest tag for default branch + # type=raw,value=latest,enable={{is_default_branch}} + + # - registry: quay.io + # build_language: rust + # bpf_build_wrapper: rust + # repository: bpfman-bytecode + # image: uprobe + # context: ./tests/integration-test/bpf/.output + # dockerfile: ./Containerfile.bytecode + # build_args: | + # PROGRAM_NAME=uprobe + # BPF_FUNCTION_NAME=my_uprobe + # PROGRAM_TYPE=uprobe + # BYTECODE_FILENAME=uprobe.bpf.o + # tags: | + # type=ref,event=branch + # type=ref,event=tag + # type=ref,event=pr + # type=sha,format=long + # # set latest tag for default branch + # type=raw,value=latest,enable={{is_default_branch}} + + # - registry: quay.io + # build_language: rust + # bpf_build_wrapper: rust + # repository: bpfman-bytecode + # image: uretprobe + # context: ./tests/integration-test/bpf/.output + # dockerfile: ./Containerfile.bytecode + # build_args: | + # PROGRAM_NAME=uretprobe + # BPF_FUNCTION_NAME=my_uretprobe + # PROGRAM_TYPE=uretprobe + # BYTECODE_FILENAME=uprobe.bpf.o + # tags: | + # type=ref,event=branch + # type=ref,event=tag + # type=ref,event=pr + # type=sha,format=long + # # set latest tag for default branch + # type=raw,value=latest,enable={{is_default_branch}} + + # - registry: quay.io + # build_language: rust + # bpf_build_wrapper: rust + # repository: bpfman-bytecode + # image: kprobe + # context: ./tests/integration-test/bpf/.output + # dockerfile: ./Containerfile.bytecode + # build_args: | + # PROGRAM_NAME=kprobe + # BPF_FUNCTION_NAME=my_kprobe + # PROGRAM_TYPE=kprobe + # BYTECODE_FILENAME=kprobe.bpf.o + # tags: | + # type=ref,event=branch + # type=ref,event=tag + # type=ref,event=pr + # type=sha,format=long + # # set latest tag for default branch + # type=raw,value=latest,enable={{is_default_branch}} + + # - registry: quay.io + # build_language: rust + # bpf_build_wrapper: rust + # repository: bpfman-bytecode + # image: kretprobe + # context: ./tests/integration-test/bpf/.output + # dockerfile: ./Containerfile.bytecode + # build_args: | + # PROGRAM_NAME=kretprobe + # BPF_FUNCTION_NAME=my_kretprobe + # PROGRAM_TYPE=kretprobe + # BYTECODE_FILENAME=kprobe.bpf.o + # tags: | + # type=ref,event=branch + # type=ref,event=tag + # type=ref,event=pr + # type=sha,format=long + # # set latest tag for default branch + # type=raw,value=latest,enable={{is_default_branch}} + + # - registry: quay.io + # build_language: rust + # bpf_build_wrapper: rust + # repository: bpfman-bytecode + # image: fentry + # context: ./tests/integration-test/bpf/.output + # dockerfile: ./Containerfile.bytecode + # build_args: | + # PROGRAM_NAME=do_unlinkat + # BPF_FUNCTION_NAME=test_fentry + # PROGRAM_TYPE=fentry + # BYTECODE_FILENAME=fentry.bpf.o + # tags: | + # type=ref,event=branch + # type=ref,event=tag + # type=ref,event=pr + # type=sha,format=long + # # set latest tag for default branch + # type=raw,value=latest,enable={{is_default_branch}} + + # - registry: quay.io + # build_language: rust + # bpf_build_wrapper: rust + # repository: bpfman-bytecode + # image: fexit + # context: ./tests/integration-test/bpf/.output + # dockerfile: ./Containerfile.bytecode + # build_args: | + # PROGRAM_NAME=do_unlinkat + # BPF_FUNCTION_NAME=test_fexit + # PROGRAM_TYPE=fexit + # BYTECODE_FILENAME=fentry.bpf.o + # tags: | + # type=ref,event=branch + # type=ref,event=tag + # type=ref,event=pr + # type=sha,format=long + # # set latest tag for default branch + # type=raw,value=latest,enable={{is_default_branch}} + + # - registry: quay.io + # build_language: rust + # bpf_build_wrapper: rust + # repository: bpfman + # image: xdp-dispatcher + # context: . + # dockerfile: ./Containerfile.xdp_dispatcher_v1 + # tags: | + # type=sha,format=long + # type=raw,value=v1,enable=true + + # - registry: quay.io + # build_language: rust + # bpf_build_wrapper: rust + # repository: bpfman + # image: xdp-dispatcher + # context: . + # dockerfile: ./Containerfile.xdp_dispatcher_v2 + # tags: | + # type=sha,format=long + # type=raw,value=v2,enable=true + + # - registry: quay.io + # build_language: rust + # bpf_build_wrapper: rust + # repository: bpfman + # image: tc-dispatcher + # context: . + # dockerfile: ./Containerfile.tc_dispatcher + # tags: | + # type=sha,format=long + # type=raw,value=v1,enable=true name: Build eBPF Image (${{ matrix.image.image }}) steps: @@ -663,22 +672,15 @@ jobs: if: ${{ matrix.image.bpf_build_wrapper == 'go' }} run: | cd examples && make generate - - - name: Login to quay.io/bpfman - uses: redhat-actions/podman-login@v1 - if: ${{ github.event_name == 'push' && matrix.image.repository == 'bpfman'}} + + - name: Download bpfman binary + uses: actions/download-artifact@v4 with: - registry: ${{ matrix.image.registry }} - username: ${{ secrets.BPFMAN_USERNAME }} - password: ${{ secrets.BPFMAN_ROBOT_TOKEN }} + name: bpfman - - name: Login to quay.io/bpfman-userspace - uses: redhat-actions/podman-login@v1 - if: ${{ github.event_name == 'push' && matrix.image.repository == 'bpfman-userspace'}} - with: - registry: ${{ matrix.image.registry }} - username: ${{ secrets.BPFMAN_USERSPACE_USERNAME }} - password: ${{ secrets.BPFMAN_USERSPACE_ROBOT_TOKEN }} + - name: Unpack binary and put bpfman in path + run: | + tar -C /usr/local/bin -xzvf bpfman.tar.gz - name: Login to quay.io/bpfman-bytecode uses: redhat-actions/podman-login@v1 @@ -695,6 +697,11 @@ jobs: images: ${{ matrix.image.registry }}/${{ matrix.image.repository }}/${{ matrix.image.image }} tags: ${{ matrix.image.tags }} + - name: Generate build args + id: build-tags + run: | + echo "BUILD_ARGS=$(bpfman image generate-build-args -b ${{ matrix.image.bytecode_path }})" + - name: Build image id: build-image uses: redhat-actions/buildah-build@v2 @@ -703,7 +710,9 @@ jobs: tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} containerfiles: ${{ matrix.image.dockerfile }} - build-args: ${{ matrix.image.build_args }} + build-args: format('{0}\n{1}\n{2}', matrix.image.build_args, 'BYTECODE_FILE=${{ matrix.image.bytecode_path }}', ${{ env.BUILD_ARGS }}) + + '${{ matrix.image.build_args }}/nBYTECODE_FILE=${{ matrix.image.bytecode_path }}' context: ${{ matrix.image.context }} - name: Push to registry diff --git a/Cargo.lock b/Cargo.lock index 0342b229b..5e4d15211 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,9 +14,9 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" dependencies = [ "gimli", ] @@ -133,9 +133,9 @@ dependencies = [ [[package]] name = "anstyle-query" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" +checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" dependencies = [ "windows-sys 0.52.0", ] @@ -185,7 +185,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.66", ] [[package]] @@ -207,7 +207,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.66", ] [[package]] @@ -218,7 +218,7 @@ checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.66", ] [[package]] @@ -240,7 +240,7 @@ dependencies = [ "futures-util", "http 0.2.12", "http-body 0.4.6", - "hyper 0.14.28", + "hyper 0.14.29", "itoa", "matchit", "memchr", @@ -249,7 +249,7 @@ dependencies = [ "pin-project-lite", "rustversion", "serde", - "sync_wrapper", + "sync_wrapper 0.1.2", "tower", "tower-layer", "tower-service", @@ -305,16 +305,16 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.71" +version = "0.3.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" dependencies = [ "addr2line", "cc", "cfg-if", "libc", "miniz_oxide", - "object 0.32.2", + "object 0.36.0", "rustc-demangle", ] @@ -419,6 +419,7 @@ dependencies = [ "assert_matches", "async-trait", "aya", + "aya-obj", "base16ct", "base64 0.22.1", "bpfman-csi", @@ -434,7 +435,7 @@ dependencies = [ "log", "netlink-packet-route", "nix 0.28.0", - "object 0.35.0", + "object 0.32.2", "oci-distribution", "rand", "rtnetlink", @@ -650,9 +651,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.98" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" +checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" [[package]] name = "cesu8" @@ -738,14 +739,14 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.66", ] [[package]] name = "clap_lex" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" [[package]] name = "clap_mangen" @@ -871,7 +872,7 @@ dependencies = [ "bitflags 2.5.0", "crossterm_winapi", "libc", - "parking_lot 0.12.2", + "parking_lot 0.12.3", "winapi", ] @@ -947,7 +948,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.66", ] [[package]] @@ -995,7 +996,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.65", + "syn 2.0.66", ] [[package]] @@ -1017,7 +1018,7 @@ checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" dependencies = [ "darling_core 0.20.9", "quote", - "syn 2.0.65", + "syn 2.0.66", ] [[package]] @@ -1053,7 +1054,7 @@ checksum = "5fe87ce4529967e0ba1dcf8450bab64d97dfd5010a6256187ffe2e43e6f0e049" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.66", ] [[package]] @@ -1109,7 +1110,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.66", ] [[package]] @@ -1214,7 +1215,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.66", ] [[package]] @@ -1405,7 +1406,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.66", ] [[package]] @@ -1473,9 +1474,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" [[package]] name = "glob" @@ -1611,7 +1612,7 @@ dependencies = [ "ipconfig", "lru-cache", "once_cell", - "parking_lot 0.12.2", + "parking_lot 0.12.3", "rand", "resolv-conf", "smallvec", @@ -1712,12 +1713,12 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", - "futures-core", + "futures-util", "http 1.1.0", "http-body 1.0.0", "pin-project-lite", @@ -1725,9 +1726,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" [[package]] name = "httpdate" @@ -1737,9 +1738,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "0.14.28" +version = "0.14.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +checksum = "f361cde2f109281a220d4307746cdfd5ee3f410da58a70377762396775634b33" dependencies = [ "bytes", "futures-channel", @@ -1786,7 +1787,7 @@ checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", "http 0.2.12", - "hyper 0.14.28", + "hyper 0.14.29", "rustls", "tokio", "tokio-rustls", @@ -1798,7 +1799,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" dependencies = [ - "hyper 0.14.28", + "hyper 0.14.29", "pin-project-lite", "tokio", "tokio-io-timeout", @@ -1811,7 +1812,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", - "hyper 0.14.28", + "hyper 0.14.29", "native-tls", "tokio", "tokio-native-tls", @@ -1835,9 +1836,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" +checksum = "7b875924a60b96e5d7b9ae7b066540b1dd1cbd90d1828f54c92e02a283351c56" dependencies = [ "bytes", "futures-channel", @@ -1991,7 +1992,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.66", ] [[package]] @@ -2084,7 +2085,7 @@ name = "integration-test-macros" version = "0.4.1" dependencies = [ "quote", - "syn 2.0.65", + "syn 2.0.66", ] [[package]] @@ -2186,9 +2187,9 @@ dependencies = [ [[package]] name = "json-syntax" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe45447363747ecc18deb478f945df8482edafbae21e51bdc73eab76883c6a5" +checksum = "ed6de1df37a464e0d1958ea233f2abe64b07558f27e718e2fcda04547dc7ae03" dependencies = [ "decoded-char", "hashbrown 0.12.3", @@ -2332,9 +2333,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.16" +version = "1.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e143b5e666b2695d28f6bca6497720813f699c9602dd7f5cac91008b8ada7f9" +checksum = "c15da26e5af7e25c90b37a2d75cdbf940cf4a55316de9d84c679c9b8bfabf82e" dependencies = [ "cc", "pkg-config", @@ -2428,9 +2429,9 @@ checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" [[package]] name = "memchr" -version = "2.7.2" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memoffset" @@ -2491,11 +2492,10 @@ checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03" [[package]] name = "native-tls" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" dependencies = [ - "lazy_static", "libc", "log", "openssl", @@ -2731,9 +2731,9 @@ dependencies = [ [[package]] name = "object" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8ec7ab813848ba4522158d5517a6093db1ded27575b070f4177b8d12b41db5e" +checksum = "576dfe1fc8f9df304abb159d767a29d0476f7750fbf8aa7ad07816004a207434" dependencies = [ "memchr", ] @@ -2841,7 +2841,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.66", ] [[package]] @@ -2988,9 +2988,9 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core 0.9.10", @@ -3018,7 +3018,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.1", + "redox_syscall 0.5.2", "smallvec", "windows-targets 0.52.5", ] @@ -3102,7 +3102,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.66", ] [[package]] @@ -3224,7 +3224,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ "proc-macro2", - "syn 2.0.65", + "syn 2.0.66", ] [[package]] @@ -3262,9 +3262,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.83" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43" +checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" dependencies = [ "unicode-ident", ] @@ -3296,7 +3296,7 @@ dependencies = [ "prost", "prost-types", "regex", - "syn 2.0.65", + "syn 2.0.66", "tempfile", ] @@ -3310,7 +3310,7 @@ dependencies = [ "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.66", ] [[package]] @@ -3406,9 +3406,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" dependencies = [ "bitflags 2.5.0", ] @@ -3427,9 +3427,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", @@ -3438,9 +3438,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "reqwest" @@ -3457,7 +3457,7 @@ dependencies = [ "hickory-resolver", "http 0.2.12", "http-body 0.4.6", - "hyper 0.14.28", + "hyper 0.14.29", "hyper-rustls", "hyper-tls 0.5.0", "ipnet", @@ -3473,7 +3473,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", - "sync_wrapper", + "sync_wrapper 0.1.2", "system-configuration", "tokio", "tokio-native-tls", @@ -3491,9 +3491,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.4" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" +checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37" dependencies = [ "base64 0.22.1", "bytes", @@ -3518,7 +3518,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", - "sync_wrapper", + "sync_wrapper 1.0.1", "tokio", "tokio-native-tls", "tower-service", @@ -3914,7 +3914,7 @@ checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.66", ] [[package]] @@ -3955,7 +3955,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.66", ] [[package]] @@ -4006,7 +4006,7 @@ dependencies = [ "darling 0.20.9", "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.66", ] [[package]] @@ -4090,7 +4090,7 @@ dependencies = [ "pkcs8", "rand", "regex", - "reqwest 0.12.4", + "reqwest 0.12.5", "rsa", "rustls-webpki 0.102.4", "scrypt", @@ -4167,9 +4167,9 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "snafu" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75976f4748ab44f6e5332102be424e7c2dc18daeaf7e725f2040c3ebb133512e" +checksum = "418b8136fec49956eba89be7da2847ec1909df92a9ae4178b5ff0ff092c8d95e" dependencies = [ "futures-core", "pin-project", @@ -4178,14 +4178,14 @@ dependencies = [ [[package]] name = "snafu-derive" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4b19911debfb8c2fb1107bc6cb2d61868aaf53a988449213959bb1b5b1ed95f" +checksum = "1a4812a669da00d17d8266a0439eddcacbc88b17f732f927e52eeb9d196f7fb5" dependencies = [ - "heck 0.4.1", + "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.66", ] [[package]] @@ -4252,15 +4252,15 @@ checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" [[package]] name = "strum_macros" -version = "0.26.2" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ - "heck 0.4.1", + "heck 0.5.0", "proc-macro2", "quote", "rustversion", - "syn 2.0.65", + "syn 2.0.66", ] [[package]] @@ -4282,9 +4282,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.65" +version = "2.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2863d96a84c6439701d7a38f9de935ec562c8832cc55d1dde0f513b52fad106" +checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" dependencies = [ "proc-macro2", "quote", @@ -4297,6 +4297,12 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +[[package]] +name = "sync_wrapper" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" + [[package]] name = "synstructure" version = "0.13.1" @@ -4305,7 +4311,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.66", ] [[package]] @@ -4384,7 +4390,7 @@ checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.66", ] [[package]] @@ -4461,7 +4467,7 @@ checksum = "8d9ef545650e79f30233c0003bcc2504d7efac6dad25fca40744de773fe2049c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.66", ] [[package]] @@ -4475,7 +4481,7 @@ dependencies = [ "libc", "mio", "num_cpus", - "parking_lot 0.12.2", + "parking_lot 0.12.3", "pin-project-lite", "signal-hook-registry", "socket2", @@ -4501,7 +4507,7 @@ checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.66", ] [[package]] @@ -4597,7 +4603,7 @@ dependencies = [ "h2", "http 0.2.12", "http-body 0.4.6", - "hyper 0.14.28", + "hyper 0.14.29", "hyper-timeout", "percent-encoding", "pin-project", @@ -4620,7 +4626,7 @@ dependencies = [ "proc-macro2", "prost-build", "quote", - "syn 2.0.65", + "syn 2.0.66", ] [[package]] @@ -4709,7 +4715,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.66", ] [[package]] @@ -4771,9 +4777,9 @@ dependencies = [ [[package]] name = "unicode-width" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" [[package]] name = "universal-hash" @@ -4839,9 +4845,9 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" @@ -4925,7 +4931,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.66", "wasm-bindgen-shared", ] @@ -4959,7 +4965,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.66", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -5269,9 +5275,9 @@ checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "winnow" -version = "0.6.8" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c52e9c97a68071b23e836c9380edae937f17b9c4667bd021973efc689f618d" +checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1" dependencies = [ "memchr", ] @@ -5364,7 +5370,7 @@ checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.66", "synstructure", ] @@ -5385,7 +5391,7 @@ checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.66", ] [[package]] @@ -5405,15 +5411,15 @@ checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.66", "synstructure", ] [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" dependencies = [ "zeroize_derive", ] @@ -5426,7 +5432,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.66", ] [[package]] @@ -5448,5 +5454,5 @@ checksum = "97cf56601ee5052b4417d90c8755c6683473c926039908196cf35d99f893ebe7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.66", ] diff --git a/Cargo.toml b/Cargo.toml index 57822d9c9..9e3886817 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,7 +54,7 @@ netlink-packet-core = { version = "^0.7", default-features = false } netlink-packet-route = { version = "^0.19", default-features = false } netlink-sys = { version = "^0.8", default-features = false } nix = { version = "0.28", default-features = false } -object = { version = "0.35.0", default-features = false } +object = { version = "0.32.2", default-features = false } oci-distribution = { version = "0.10", default-features = false } opentelemetry = { version = "0.22.0", default-features = false } opentelemetry-otlp = { version = "0.15.0", default-features = false } @@ -89,7 +89,7 @@ tonic-build = { version = "0.11.0", default-features = false } tower = { version = "0.4.13", default-features = false } url = { version = "2.5.1", default-features = false } users = { version = "0.11.0", default-features = false } - +aya-obj = { version = "0.1.0", default-features = false } [workspace.metadata.vendor-filter] platforms = [ diff --git a/Containerfile.bytecode b/Containerfile.bytecode index 063748c07..350e61545 100644 --- a/Containerfile.bytecode +++ b/Containerfile.bytecode @@ -1,13 +1,10 @@ FROM scratch -ARG PROGRAM_NAME -ARG BPF_FUNCTION_NAME -ARG EL_BYTECODE_FILE -ARG EB_BYTECODE_FILE +ARG BYTECODE_FILE +ARG PROGRAMS +ARG MAPS -COPY $EL_BYTECODE_FILE / -COPY $EB_BYTECODE_FILE / -LABEL io.ebpf.filename_eb $EB_BYTECODE_FILE -LABEL io.ebpf.filename_el $EB_BYTECODE_FILE -LABEL io.ebpf.program_name $PROGRAM_NAME -LABEL io.ebpf.bpf_function_name $BPF_FUNCTION_NAME +LABEL "io.ebpf.programs"=$PROGRAMS +LABEL "io.ebpf.maps"=$MAPS + +COPY $BYTECODE_FILE / diff --git a/bpfman/Cargo.toml b/bpfman/Cargo.toml index 4333fc2fd..e3f856cdb 100644 --- a/bpfman/Cargo.toml +++ b/bpfman/Cargo.toml @@ -75,6 +75,7 @@ toml = { workspace = true, features = ["parse"] } tonic = { workspace = true, features = ["transport"] } tower = { workspace = true } url = { workspace = true } +aya-obj = { workspace = true } [dev-dependencies] assert_matches = { workspace = true } diff --git a/bpfman/src/bin/cli/args.rs b/bpfman/src/bin/cli/args.rs index 0f0f7448b..8d4dcdbe6 100644 --- a/bpfman/src/bin/cli/args.rs +++ b/bpfman/src/bin/cli/args.rs @@ -1,6 +1,8 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright Authors of bpfman +use std::{io::ErrorKind, path::PathBuf, str::FromStr}; + use bpfman::types::ProgramType; use clap::{Args, Parser, Subcommand}; use hex::FromHex; @@ -310,6 +312,101 @@ pub(crate) struct GetArgs { pub(crate) enum ImageSubCommand { /// Pull an eBPF bytecode image from a remote registry. Pull(PullBytecodeArgs), + /// Build an eBPF bytecode image from local bytecode objects. + Build(BuildBytecodeArgs), + /// Generate the OCI image labels for a given bytecode file. + GenerateBuildArgs(GenerateArgs), +} + +// Targets understood by bpf2go. +// +// Targets without a Linux string can't be used directly and are only included +// for the generic bpf, bpfel, bpfeb targets. +// +// See https://go.dev/doc/install/source#environment for valid GOARCHes when +// GOOS=linux. +// var targetByGoArch = map[goarch]target{ +// "386": {"bpfel", "x86"}, +// "amd64": {"bpfel", "x86"}, +// "arm": {"bpfel", "arm"}, +// "arm64": {"bpfel", "arm64"}, +// "loong64": {"bpfel", "loongarch"}, +// "mips": {"bpfeb", "mips"}, +// "mipsle": {"bpfel", ""}, +// "mips64": {"bpfeb", ""}, +// "mips64le": {"bpfel", ""}, +// "ppc64": {"bpfeb", "powerpc"}, +// "ppc64le": {"bpfel", "powerpc"}, +// "riscv64": {"bpfel", "riscv"}, +// "s390x": {"bpfeb", "s390"}, +// } + +#[derive(Debug, Clone)] +pub(crate) enum GoArch { + X386, + Amd64, + Arm, + Arm64, + Loong64, + Mips, + Mipsle, + Mips64, + Mips64le, + Ppc64, + Ppc64le, + Riscv64, + S390x, +} + +impl FromStr for GoArch { + type Err = std::io::Error; + + fn from_str(s: &str) -> Result { + match s { + "386" => Ok(GoArch::X386), + "amd64" => Ok(GoArch::Amd64), + "arm" => Ok(GoArch::Arm), + "arm64" => Ok(GoArch::Arm64), + "loong64" => Ok(GoArch::Loong64), + "mips" => Ok(GoArch::Mips), + "mipsle" => Ok(GoArch::Mipsle), + "mips64" => Ok(GoArch::Mips64), + "mips64le" => Ok(GoArch::Mips64le), + "ppc64" => Ok(GoArch::Ppc64), + "ppc64le" => Ok(GoArch::Ppc64le), + "riscv64" => Ok(GoArch::Riscv64), + "s390x" => Ok(GoArch::S390x), + _ => Err(std::io::Error::new(ErrorKind::InvalidInput, "not a valid bytecode arch, please refer to https://go.dev/doc/install/source#environment for valid GOARCHes when GOOS=linux.")), + } + } +} + +#[derive(Args, Debug)] +#[command(disable_version_flag = true)] +pub(crate) struct BuildBytecodeArgs { + /// Required: Dockerfile to use for building the image. + /// Example: --file Containerfile.bytecode + #[clap(short, long, verbatim_doc_comment)] + pub(crate) bytecode_file: PathBuf, + + /// Required: Name and optionally a tag in the name:tag format. + /// Example: --tag quay.io/bpfman-bytecode/xdp_pass:latest + #[clap(short, long, verbatim_doc_comment)] + pub(crate) tag: String, + + /// Required: Dockerfile to use for building the image. + /// Example: --file Containerfile.bytecode + #[clap(short = 'f', long, verbatim_doc_comment)] + pub(crate) container_file: PathBuf, +} + +#[derive(Args, Debug)] +#[command(disable_version_flag = true)] +pub(crate) struct GenerateArgs { + /// Required: Dockerfile to use for building the image. + /// Example: --file Containerfile.bytecode + #[clap(short, long, verbatim_doc_comment)] + pub(crate) bytecode_file: PathBuf, } #[derive(Args, Debug)] diff --git a/bpfman/src/bin/cli/image.rs b/bpfman/src/bin/cli/image.rs index 3b2de6cf9..60f94c5cb 100644 --- a/bpfman/src/bin/cli/image.rs +++ b/bpfman/src/bin/cli/image.rs @@ -1,18 +1,25 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright Authors of bpfman +use anyhow::{anyhow, Context, Result}; +use aya_obj::Object; use base64::{engine::general_purpose, Engine}; use bpfman::{ pull_bytecode, - types::{BytecodeImage, ImagePullPolicy}, + types::{BytecodeImage, ImagePullPolicy, MapType, ProgramType}, }; +use log::debug; +use object::Endianness; +use std::{collections::HashMap, env, fs, path::Path, process::Command}; -use crate::args::{ImageSubCommand, PullBytecodeArgs}; +use crate::args::{BuildBytecodeArgs, GenerateArgs, ImageSubCommand, PullBytecodeArgs}; impl ImageSubCommand { pub(crate) async fn execute(&self) -> anyhow::Result<()> { match self { ImageSubCommand::Pull(args) => execute_pull(args).await, + ImageSubCommand::Build(args) => execute_build(args).await, + ImageSubCommand::GenerateBuildArgs(args) => execute_build_args(args).await, } } } @@ -47,3 +54,170 @@ pub(crate) async fn execute_pull(args: &PullBytecodeArgs) -> anyhow::Result<()> Ok(()) } + +pub(crate) async fn execute_build(args: &BuildBytecodeArgs) -> anyhow::Result<()> { + // parse program data from bytecode file + let (prog_labels, map_labels) = + build_image_labels(&args.bytecode_file, Some(Endianness::default()))?; + debug!( + "Bytecode: {} contains the following. \n + programs: {prog_labels}\n + maps: {map_labels}", + args.bytecode_file.display() + ); + let container_tool = ContainerRuntime::new()?; + container_tool.build_image( + &args.tag, + &args.bytecode_file, + &args.container_file, + prog_labels, + map_labels, + )?; + + Ok(()) +} + +pub(crate) async fn execute_build_args(args: &GenerateArgs) -> anyhow::Result<()> { + // parse program data from bytecode file + let (prog_labels, map_labels) = + build_image_labels(&args.bytecode_file, Some(Endianness::default()))?; + debug!( + "Bytecode: {} contains the following. \n + programs: {prog_labels}\n + maps: {map_labels}", + args.bytecode_file.display() + ); + + println!("PROGRAMS={}", prog_labels); + println!("MAPS={}", map_labels); + + Ok(()) +} + +enum ContainerRuntime { + Docker, + Podman, +} + +impl ContainerRuntime { + // Default to using docker if it's available. + fn new() -> Result { + if Command::new("docker") + .arg("version") + .output() + .is_ok_and(|o| o.status.success()) + { + debug!("using docker for container runtime"); + Ok(ContainerRuntime::Docker) + } else if Command::new("podman") + .arg("version") + .output() + .is_ok_and(|o| o.status.success()) + { + debug!("using podman for container runtime"); + Ok(ContainerRuntime::Podman) + } else { + Err(anyhow!( + "No container runtime found. Please install either docker or podman." + )) + } + } + + fn command(&self) -> Command { + match self { + ContainerRuntime::Docker => Command::new("docker"), + ContainerRuntime::Podman => Command::new("podman"), + } + } + + fn build_image( + &self, + image_tag: &str, + bc_file: &Path, + container_file: &Path, + program_labels: String, + map_labels: String, + ) -> anyhow::Result<()> { + let mut command = self.command(); + command.arg("build"); + command.arg("-t").arg(image_tag); + command.arg("-f").arg(container_file); + + command + .arg("--build-arg") + .arg(format! {"PROGRAMS={}",program_labels}); + command + .arg("--build-arg") + .arg(format! {"MAPS={}",map_labels}); + + let current_dir = env::current_dir()?; + + let build_arg = format!("BYTECODE_FILE={}", bc_file.display()); + command.arg("--build-arg").arg(build_arg); + command.arg(current_dir.as_os_str().to_str().unwrap_or(".")); + + debug!( + "Building bytecode images with command: {} {}", + command.get_program().to_string_lossy(), + command + .get_args() + .map(|arg| arg.to_string_lossy().into_owned()) + .collect::>() + .join(" ") + ); + + let output = command.output()?; + if !output.status.success() { + return Err(anyhow!( + "Failed to build image: {}", + String::from_utf8(output.stderr)? + )); + } + + Ok(()) + } +} + +fn build_image_labels( + file: &Path, + expected_endianness: Option, +) -> Result<(String, String), anyhow::Error> { + let bc_content = fs::read(file).context("cannot find bytecode")?; + let bc = Object::parse(&bc_content)?; + + if expected_endianness.is_some_and(|e| e != bc.endianness) { + return Err(anyhow!( + "Bytcode: {file:?} doesn't match expected endianness {expected_endianness:?}" + )); + } + + if bc.programs.is_empty() { + return Err(anyhow!("No programs found in bytecode: {file:?}")); + } + + let program_labels: HashMap = bc + .programs + .into_iter() + .map(|(k, v)| { + let prog_type = ProgramType::from(v.section); + (k, prog_type.to_string()) + }) + .collect(); + + let map_labels: HashMap = bc + .maps + .into_iter() + .filter_map(|(name, v)| { + if !(name.contains(".rodata") || name.contains(".bss") || name.contains(".data")) { + let map_type = MapType::from(v.map_type()); + Some((name, map_type.to_string())) + } else { + None + } + }) + .collect(); + Ok(( + serde_json::to_string(&program_labels)?, + serde_json::to_string(&map_labels)?, + )) +} diff --git a/bpfman/src/errors.rs b/bpfman/src/errors.rs index 97c55ae6d..9bdf6c85c 100644 --- a/bpfman/src/errors.rs +++ b/bpfman/src/errors.rs @@ -40,6 +40,12 @@ pub enum BpfmanError { image_prog_name: String, provided_prog_name: String, }, + #[error("Program {expected_prog_name} not found in bytecode image {bytecode_image} with program names {program_names:?}")] + ProgramNotFoundInBytecode { + bytecode_image: String, + expected_prog_name: String, + program_names: Vec, + }, #[error("Unable to delete program {0}")] BpfmanProgramDeleteError(#[source] anyhow::Error), #[error(transparent)] @@ -69,6 +75,8 @@ pub enum BpfmanError { pub enum ParseError { #[error("{program} is not a valid program type")] InvalidProgramType { program: String }, + #[error("{map} is not a valid map type")] + InvalidMapType { map: String }, #[error("{proceedon} is not a valid proceed-on value")] InvalidProceedOn { proceedon: String }, #[error("not a valid direction: {direction}")] diff --git a/bpfman/src/multiprog/tc.rs b/bpfman/src/multiprog/tc.rs index ca1c540a4..ce89ee90d 100644 --- a/bpfman/src/multiprog/tc.rs +++ b/bpfman/src/multiprog/tc.rs @@ -36,6 +36,7 @@ use crate::{ const DEFAULT_PRIORITY: u32 = 50; // Default priority for user programs in the dispatcher const TC_DISPATCHER_PRIORITY: u16 = 50; // Default TC priority for TC Dispatcher +const TC_DISPATCHER_PROGRAM_NAME: &str = "tc_dispatcher"; /// These constants define the key of SLED DB const REVISION: &str = "revision"; @@ -127,7 +128,7 @@ impl TcDispatcher { None, ); - let (path, bpf_function_name) = image_manager + let (path, bpf_program_names) = image_manager .get_image( root_db, &image.image_url, @@ -137,14 +138,24 @@ impl TcDispatcher { ) .await?; + if !bpf_program_names.contains(&TC_DISPATCHER_PROGRAM_NAME.to_string()) { + return Err(BpfmanError::ProgramNotFoundInBytecode { + bytecode_image: image.image_url, + expected_prog_name: TC_DISPATCHER_PROGRAM_NAME.to_string(), + program_names: bpf_program_names, + }); + } + let program_bytes = image_manager.get_bytecode_from_image_store(root_db, path)?; let mut loader = BpfLoader::new() .set_global("CONFIG", &config, true) .load(&program_bytes)?; - let dispatcher: &mut SchedClassifier = - loader.program_mut(&bpf_function_name).unwrap().try_into()?; + let dispatcher: &mut SchedClassifier = loader + .program_mut(TC_DISPATCHER_PROGRAM_NAME) + .unwrap() + .try_into()?; dispatcher.load()?; @@ -157,7 +168,7 @@ impl TcDispatcher { self.loader = Some(loader); self.set_num_extensions(extensions.len())?; - self.set_program_name(&bpf_function_name)?; + self.set_program_name(TC_DISPATCHER_PROGRAM_NAME)?; self.attach_extensions(&mut extensions)?; self.attach(root_db, old_dispatcher).await?; diff --git a/bpfman/src/multiprog/xdp.rs b/bpfman/src/multiprog/xdp.rs index dddcf654b..8b780a241 100644 --- a/bpfman/src/multiprog/xdp.rs +++ b/bpfman/src/multiprog/xdp.rs @@ -29,6 +29,7 @@ use crate::{ }; pub(crate) const DEFAULT_PRIORITY: u32 = 50; +const XDP_DISPATCHER_PROGRAM_NAME: &str = "xdp_dispatcher"; /// These constants define the key of SLED DB const REVISION: &str = "revision"; @@ -123,7 +124,7 @@ impl XdpDispatcher { None, ); - let (path, bpf_function_name) = image_manager + let (path, bpf_program_names) = image_manager .get_image( root_db, &image.image_url.clone(), @@ -133,13 +134,24 @@ impl XdpDispatcher { ) .await?; + if !bpf_program_names.contains(&XDP_DISPATCHER_PROGRAM_NAME.to_string()) { + return Err(BpfmanError::ProgramNotFoundInBytecode { + bytecode_image: image.image_url, + expected_prog_name: XDP_DISPATCHER_PROGRAM_NAME.to_string(), + program_names: bpf_program_names, + }); + } + let program_bytes = image_manager.get_bytecode_from_image_store(root_db, path)?; let mut loader = BpfLoader::new() .set_global("conf", &config, true) .load(&program_bytes)?; - let dispatcher: &mut Xdp = loader.program_mut(&bpf_function_name).unwrap().try_into()?; + let dispatcher: &mut Xdp = loader + .program_mut(XDP_DISPATCHER_PROGRAM_NAME) + .unwrap() + .try_into()?; dispatcher.load()?; @@ -148,7 +160,7 @@ impl XdpDispatcher { self.loader = Some(loader); self.set_num_extensions(extensions.len())?; - self.set_program_name(&bpf_function_name)?; + self.set_program_name(XDP_DISPATCHER_PROGRAM_NAME)?; self.attach_extensions(&mut extensions)?; self.attach()?; diff --git a/bpfman/src/oci_utils/image_manager.rs b/bpfman/src/oci_utils/image_manager.rs index 92312dd74..d54e79414 100644 --- a/bpfman/src/oci_utils/image_manager.rs +++ b/bpfman/src/oci_utils/image_manager.rs @@ -1,10 +1,15 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright Authors of bpfman -use std::io::{copy, Read}; +use std::{ + collections::HashMap, + io::{copy, Read}, +}; + +use anyhow::anyhow; use flate2::read::GzDecoder; -use log::{debug, trace, warn}; +use log::{debug, trace}; use object::{Endianness, Object}; use oci_distribution::{ client::{ClientConfig, ClientProtocol}, @@ -22,24 +27,39 @@ use tar::Archive; use crate::{ oci_utils::{cosign::CosignVerifier, ImageError}, types::ImagePullPolicy, - utils::{bytes_to_usize, sled_get, sled_insert}, + utils::{sled_get, sled_insert}, }; -#[derive(Deserialize)] -#[allow(dead_code)] +const OCI_PROGRAMS_LABEL: &str = "io.ebpf.programs"; +const OCI_MAPS_LABEL: &str = "io.ebpf.maps"; + +#[derive(Debug)] pub struct ContainerImageMetadata { + pub programs: HashMap, + pub maps: HashMap, +} + +impl From for ContainerImageMetadata { + fn from(value: ContainerImageMetadataV1) -> Self { + let mut programs = HashMap::new(); + programs.insert(value.bpf_function_name, value.program_type); + ContainerImageMetadata { + programs, + maps: HashMap::new(), + } + } +} + +#[derive(Deserialize)] +pub struct ContainerImageMetadataV1 { #[serde(rename(deserialize = "io.ebpf.program_name"))] - pub name: Option, + pub name: String, #[serde(rename(deserialize = "io.ebpf.bpf_function_name"))] pub bpf_function_name: String, #[serde(rename(deserialize = "io.ebpf.program_type"))] - pub program_type: Option, + pub program_type: String, #[serde(rename(deserialize = "io.ebpf.filename"))] - pub filename: Option, - #[serde(rename(deserialize = "io.ebpf.filename_eb"))] - pub eb_file: Option, - #[serde(rename(deserialize = "io.ebpf.filename_eb"))] - pub el_file: Option, + pub filename: String, } pub struct ImageManager { @@ -68,7 +88,7 @@ impl ImageManager { pull_policy: ImagePullPolicy, username: Option, password: Option, - ) -> Result<(String, String), ImageError> { + ) -> Result<(String, Vec), ImageError> { // The reference created here is created using the krustlet oci-distribution // crate. It currently contains many defaults more of which can be seen // here: https://github.com/krustlet/oci-distribution/blob/main/src/reference.rs#L58 @@ -108,7 +128,10 @@ impl ImageManager { } }; - Ok((image_content_key.to_string(), image_meta.bpf_function_name)) + Ok(( + image_content_key.to_string(), + image_meta.programs.into_keys().collect(), + )) } fn get_auth_for_registry( @@ -153,14 +176,8 @@ impl ImageManager { let image_manifest_json = serde_json::to_string(&image_manifest) .map_err(|e| ImageError::ByteCodeImageProcessFailure(e.into()))?; - // inset and flush to disk to avoid races across threads on write. - root_db - .insert(image_manifest_key, image_manifest_json.as_str()) - .map_err(|e| { - ImageError::DatabaseError("failed to write to db".to_string(), e.to_string()) - })?; - root_db.flush().map_err(|e| { - ImageError::DatabaseError("failed to flush db".to_string(), e.to_string()) + sled_insert(root_db, &image_manifest_key, image_manifest_json.as_bytes()).map_err(|e| { + ImageError::DatabaseError("failed to write to db".to_string(), e.to_string()) })?; let config_sha = &image_manifest @@ -175,10 +192,35 @@ impl ImageManager { .map_err(|e| ImageError::ByteCodeImageProcessFailure(e.into()))?; trace!("Raw container image config {}", image_config); - // Deserialize image metadata(labels) from json config - let image_labels: ContainerImageMetadata = - serde_json::from_str(&image_config["config"]["Labels"].to_string()) - .map_err(|e| ImageError::ByteCodeImageProcessFailure(e.into()))?; + let labels_map = image_config["config"]["Labels"].as_object().ok_or( + ImageError::ByteCodeImageProcessFailure(anyhow!("Labels not found")), + )?; + + // The values of the Labels `io.ebpf.maps` and `io.ebpf.programs` are in JSON format try and + // parse those, if that fails fallback to the V1 version of the metadata spec, + // if that fails error out. + let image_labels = match ( + labels_map.get(OCI_MAPS_LABEL), + labels_map.get(OCI_PROGRAMS_LABEL), + ) { + (Some(maps), Some(programs)) => ContainerImageMetadata { + maps: serde_json::from_str::>(maps.as_str().unwrap()) + .map_err(|e| ImageError::ByteCodeImageProcessFailure(e.into()))?, + programs: serde_json::from_str::>( + programs.as_str().unwrap(), + ) + .map_err(|e| ImageError::ByteCodeImageProcessFailure(e.into()))?, + }, + _ => { + // Try to deserialize from older version of metadata + match serde_json::from_str::( + &image_config["config"]["Labels"].to_string(), + ) { + Ok(labels) => labels.into(), + Err(e) => return Err(ImageError::ByteCodeImageProcessFailure(e.into())), + } + } + }; root_db .insert(image_config_path, config_contents.as_str()) @@ -189,7 +231,7 @@ impl ImageManager { ImageError::DatabaseError("failed to flush db".to_string(), e.to_string()) })?; - let layers = self + let image_content = self .client .pull( &image, @@ -201,63 +243,34 @@ impl ImageManager { ) .await .map_err(ImageError::BytecodeImagePullFailure)? - .layers; - - // Support legacy bytecode images where there was only one layer (build machine endian), - // Otherwise make sure to store only the correct endian target for the system - let mut layer_index = 0; - let image_content = if layers.len() == 1 { - warn!("Bytecode image is using legacy format (single layer) please package both little and big endian images in the future."); - layer_index = 0; - Ok(layers[layer_index].data.clone()) - } else if layers.len() == 2 { - let image_content_1 = get_bytecode_from_gzip(layers[0].data.clone()); - let image_content_2 = get_bytecode_from_gzip(layers[1].data.clone()); - - let obj_1_endianness = object::read::File::parse(image_content_1.as_slice()) - .map_err(|e| ImageError::BytecodeImageExtractFailure(e.to_string()))? - .endianness(); - let obj_2_endianness = object::read::File::parse(image_content_2.as_slice()) - .map_err(|e| ImageError::BytecodeImageExtractFailure(e.to_string()))? - .endianness(); - - if obj_1_endianness == obj_2_endianness { - return Err(ImageError::BytecodeImageExtractFailure( - "image bytecode variants are same endianness".to_string(), - )); - } - - if Endianness::default() == obj_1_endianness { - layer_index = 0; - } else { - layer_index = 1; - }; - - Ok(layers[layer_index].data.clone()) - } else { - Err(ImageError::BytecodeImageExtractFailure( - "failed to parse bytecode image with {layers.len()} layers".to_string(), - )) - }?; + .layers + .into_iter() + .next() + .map(|layer| layer.data) + .ok_or(ImageError::BytecodeImageExtractFailure( + "No data in bytecode image layer".to_string(), + ))?; - debug!("Layer index {layer_index} matches host endian"); + // Make sure endian target matches that of the system before storing + let unzipped_content = get_bytecode_from_gzip(image_content.clone()); + let obj_endianness = object::read::File::parse(unzipped_content.as_slice()) + .map_err(|e| ImageError::BytecodeImageExtractFailure(e.to_string()))? + .endianness(); + let host_endianness = Endianness::default(); + + if host_endianness != obj_endianness { + return Err(ImageError::BytecodeImageExtractFailure( + format!("image bytecode endianness: {obj_endianness:?} does not match host {host_endianness:?}"), + )); + }; - let bytecode_sha = image_manifest.layers[layer_index] + let bytecode_sha = image_manifest.layers[0] .digest .split(':') .collect::>()[1]; let bytecode_path = base_key.to_string() + bytecode_sha; - sled_insert( - root_db, - &format!("{base_key}_layer_index"), - &layer_index.to_ne_bytes(), - ) - .map_err(|e| { - ImageError::DatabaseError("failed to write to db".to_string(), e.to_string()) - })?; - sled_insert(root_db, &bytecode_path, &image_content).map_err(|e| { ImageError::DatabaseError("failed to write to db".to_string(), e.to_string()) })?; @@ -270,22 +283,11 @@ impl ImageManager { root_db: &Db, base_key: String, ) -> Result, ImageError> { - let layer_index = sled_get(root_db, &format!("{base_key}_layer_index")) - .map(bytes_to_usize) - .map_err(|e| { - ImageError::DatabaseError("failed to read db".to_string(), e.to_string()) - })?; - - debug! {"Layer index {layer_index} on get_bytecode_from_image_store"}; - let manifest = serde_json::from_str::( std::str::from_utf8( - &root_db - .get(base_key.clone() + "manifest.json") - .map_err(|e| { - ImageError::DatabaseError("failed to read db".to_string(), e.to_string()) - })? - .expect("Image manifest is empty"), + &sled_get(root_db, &(base_key.clone() + "manifest.json")).map_err(|e| { + ImageError::DatabaseError("failed to read db".to_string(), e.to_string()) + })?, ) .unwrap(), ) @@ -296,7 +298,7 @@ impl ImageManager { ) })?; - let bytecode_sha = &manifest.layers[layer_index].digest; + let bytecode_sha = &manifest.layers[0].digest; let bytecode_key = base_key + bytecode_sha.clone().split(':').collect::>()[1]; debug!( @@ -304,16 +306,12 @@ impl ImageManager { bytecode_key ); - let f = root_db - .get(bytecode_key.clone()) - .map_err(|e| ImageError::DatabaseError("failed to read db".to_string(), e.to_string()))? - .ok_or(ImageError::DatabaseError( - "key does not exist in db".to_string(), - String::new(), - ))?; + let f = sled_get(root_db, &bytecode_key).map_err(|e| { + ImageError::DatabaseError("failed to read db".to_string(), e.to_string()) + })?; let mut hasher = Sha256::new(); - copy(&mut f.as_ref(), &mut hasher).expect("cannot copy bytecode to hasher"); + copy(&mut f.as_slice(), &mut hasher).expect("cannot copy bytecode to hasher"); let hash = hasher.finalize(); let expected_sha = "sha256:".to_owned() + &base16ct::lower::encode_string(&hash); @@ -325,22 +323,19 @@ impl ImageManager { panic!("Bpf Bytecode has been compromised") } - Ok(get_bytecode_from_gzip(f.as_ref().to_vec())) + Ok(get_bytecode_from_gzip(f)) } fn load_image_meta( &self, root_db: &Db, image_content_key: &str, - ) -> Result { + ) -> Result { let manifest = serde_json::from_str::( std::str::from_utf8( - &root_db - .get(image_content_key.to_string() + "manifest.json") - .map_err(|e| { - ImageError::DatabaseError("failed to read db".to_string(), e.to_string()) - })? - .expect("Image manifest is empty"), + &sled_get(root_db, &(image_content_key.to_string() + "manifest.json")).map_err( + |e| ImageError::DatabaseError("failed to read db".to_string(), e.to_string()), + )?, ) .unwrap(), ) @@ -355,12 +350,12 @@ impl ImageManager { let image_config_key = image_content_key.to_string() + config_sha; - let db_content = &root_db - .get(image_config_key) - .map_err(|e| ImageError::DatabaseError("failed to read db".to_string(), e.to_string()))? - .expect("Image manifest is empty"); + let db_content = sled_get(root_db, &image_config_key).map_err(|e| { + ImageError::DatabaseError("failed to read db".to_string(), e.to_string()) + })?; - let file_content = std::str::from_utf8(db_content)?; + let file_content = std::str::from_utf8(&db_content) + .map_err(|e| ImageError::ByteCodeImageProcessFailure(e.into()))?; let image_config: Value = serde_json::from_str(file_content).expect("cannot parse image config from database"); @@ -369,9 +364,34 @@ impl ImageManager { &image_config["config"]["Labels"].to_string() ); - Ok(serde_json::from_str::( - &image_config["config"]["Labels"].to_string(), - )?) + let labels_map = image_config["config"]["Labels"].as_object().ok_or( + ImageError::ByteCodeImageProcessFailure(anyhow!("Labels not found")), + )?; + + Ok( + match ( + labels_map.get(OCI_MAPS_LABEL), + labels_map.get(OCI_PROGRAMS_LABEL), + ) { + (Some(maps), Some(programs)) => ContainerImageMetadata { + maps: serde_json::from_str::>(maps.as_str().unwrap()) + .map_err(|e| ImageError::ByteCodeImageProcessFailure(e.into()))?, + programs: serde_json::from_str::>( + programs.as_str().unwrap(), + ) + .map_err(|e| ImageError::ByteCodeImageProcessFailure(e.into()))?, + }, + _ => { + // Try to deserialize from older version of metadata + match serde_json::from_str::( + &image_config["config"]["Labels"].to_string(), + ) { + Ok(labels) => labels.into(), + Err(e) => return Err(ImageError::ByteCodeImageProcessFailure(e.into())), + } + } + }, + ) } } @@ -429,7 +449,7 @@ mod tests { let (image_content_key, _) = mgr .get_image( &root_db, - "quay.io/bpfman-bytecode/xdp_pass:latest", + "quay.io/bpfman-bytecode/go-xdp-counter-legacy-labels:latest", ImagePullPolicy::Always, None, None, @@ -437,9 +457,6 @@ mod tests { .await .expect("failed to pull bytecode"); - // Assert that an manifest, config, layer_index and bytecode key were formed for image. - assert!(root_db.scan_prefix(image_content_key.clone()).count() == 4); - let program_bytes = mgr .get_bytecode_from_image_store(&root_db, image_content_key) .expect("failed to get bytecode from image store"); @@ -458,7 +475,7 @@ mod tests { let (image_content_key, _) = mgr .get_image( &root_db, - "quay.io/bpfman-bytecode/go_xdp_counter_multi:latest", + "quay.io/bpfman-bytecode/go-xdp-counter:latest", ImagePullPolicy::Always, None, None, @@ -466,9 +483,6 @@ mod tests { .await .expect("failed to pull bytecode"); - // Assert that an manifest, config, layer_index and bytecode key were formed for image. - assert!(root_db.scan_prefix(image_content_key.clone()).count() == 4); - let program_bytes = mgr .get_bytecode_from_image_store(&root_db, image_content_key) .expect("failed to get bytecode from image store"); @@ -533,9 +547,6 @@ mod tests { .await .expect("failed to pull bytecode"); - // Assert that an manifest, config, layer_index and bytecode key were formed for image. - assert!(root_db.scan_prefix(image_content_key.clone()).count() == 4); - let program_bytes = mgr .get_bytecode_from_image_store(&root_db, image_content_key) .expect("failed to get bytecode from image store"); diff --git a/bpfman/src/types.rs b/bpfman/src/types.rs index e70a77c5b..e1573e4c9 100644 --- a/bpfman/src/types.rs +++ b/bpfman/src/types.rs @@ -224,11 +224,11 @@ impl Location { &self, root_db: &Db, image_manager: &mut ImageManager, - ) -> Result<(Vec, String), BpfmanError> { + ) -> Result<(Vec, Vec), BpfmanError> { match self { - Location::File(l) => Ok((crate::utils::read(l)?, "".to_owned())), + Location::File(l) => Ok((crate::utils::read(l)?, Vec::new())), Location::Image(l) => { - let (path, bpf_function_name) = image_manager + let (path, bpf_function_names) = image_manager .get_image( root_db, &l.image_url, @@ -239,7 +239,7 @@ impl Location { .await?; let bytecode = image_manager.get_bytecode_from_image_store(root_db, path)?; - Ok((bytecode, bpf_function_name)) + Ok((bytecode, bpf_function_names)) } } } @@ -625,14 +625,14 @@ impl ProgramData { // always use the provided program name. let provided_name = self.get_name()?.clone(); - if provided_name.is_empty() { - self.set_name(&s)?; - } else if s != provided_name { - debug!( - "Bytecode image bpf function name: {} isn't equal to the provided bpf function name: {}", - s, - provided_name - ); + if s.contains(&provided_name) { + self.set_name(&provided_name)?; + } else { + return Err(BpfmanError::ProgramNotFoundInBytecode { + bytecode_image: l.image_url, + expected_prog_name: provided_name, + program_names: s, + }); } } Location::File(l) => { @@ -1530,6 +1530,134 @@ impl Program { } } +/// MapType must match the the bpf_prog_type enum defined in the linux kernel. +/// https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/bpf.h#L964 +#[derive(Debug)] +pub enum MapType { + Unspec, + Hash, + Array, + ProgArray, + PerfEventArray, + PerCpuHash, + PerCpuArray, + StackTrace, + CgroupArray, + LruHash, + LruPerCpuHash, + LpmTrie, + ArrayOfMaps, + HashOfMaps, + Devmap, + Sockmap, + Cpumap, + Xskmap, + Sockhash, + CgroupStorage, + ReuseportSockarray, + PerCpuCgroupStorage, + Queue, + Stack, + SkStorage, + DevmapHash, + StructOps, + Ringbuf, + InodeStorage, + TaskStorage, + BloomFilter, + UserRingbuf, + CgrpStorage, + Arena, +} + +/// This function is only used in the oci-utils for taking an object +/// file parsed by aya-obj, pulling out the maps included in it, and +/// presenting it in a user frendly manner, it will panic if it's called +/// with a non-checked integer, only use where pre-processing has occured. +impl From for MapType { + fn from(value: u32) -> Self { + match value { + 0 => MapType::Unspec, + 1 => MapType::Hash, + 2 => MapType::Array, + 3 => MapType::ProgArray, + 4 => MapType::PerfEventArray, + 5 => MapType::PerCpuHash, + 6 => MapType::PerCpuArray, + 7 => MapType::StackTrace, + 8 => MapType::CgroupArray, + 9 => MapType::LruHash, + 10 => MapType::LruPerCpuHash, + 11 => MapType::LpmTrie, + 12 => MapType::ArrayOfMaps, + 13 => MapType::HashOfMaps, + 14 => MapType::Devmap, + 15 => MapType::Sockmap, + 16 => MapType::Cpumap, + 17 => MapType::Xskmap, + 18 => MapType::Sockhash, + 20 => MapType::ReuseportSockarray, + 22 => MapType::Queue, + 23 => MapType::Stack, + 24 => MapType::SkStorage, + 25 => MapType::DevmapHash, + 26 => MapType::StructOps, + 27 => MapType::Ringbuf, + 28 => MapType::InodeStorage, + 29 => MapType::TaskStorage, + 30 => MapType::BloomFilter, + 31 => MapType::UserRingbuf, + 32 => MapType::CgrpStorage, + 33 => MapType::Arena, + v => panic!("Unknown map type {v}"), + } + } +} + +impl std::fmt::Display for MapType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let v = match self { + MapType::Unspec => "unspec", + MapType::Hash => "hash", + MapType::Array => "array", + MapType::ProgArray => "prog_array", + MapType::PerfEventArray => "perf_event_array", + MapType::PerCpuHash => "per_cpu_hash", + MapType::PerCpuArray => "per_cpu_array", + MapType::StackTrace => "stack_trace", + MapType::CgroupArray => "cgroup_array", + MapType::LruHash => "lru_hash", + MapType::LruPerCpuHash => "lru_per_cpu_hash", + MapType::LpmTrie => "lpm_trie", + MapType::ArrayOfMaps => "array_of_maps", + MapType::HashOfMaps => "hash_of_maps", + MapType::Devmap => "devmap", + MapType::Sockmap => "sockmap", + MapType::Cpumap => "cpumap", + MapType::Xskmap => "xskmap", + MapType::Sockhash => "sockhash", + MapType::CgroupStorage => "cgroup_storage", + MapType::ReuseportSockarray => "reuseport_sockarray", + MapType::PerCpuCgroupStorage => "per_cpu_cgroup_storage", + MapType::Queue => "queue", + MapType::Stack => "stack", + MapType::SkStorage => "sk_storage", + MapType::DevmapHash => "devmap_hash", + MapType::StructOps => "struct_ops", + MapType::Ringbuf => "ringbuf", + MapType::InodeStorage => "inode_storage", + MapType::TaskStorage => "task_storage", + MapType::BloomFilter => "bloom_filter", + MapType::UserRingbuf => "user_ringbuf", + MapType::CgrpStorage => "cgrp_storage", + MapType::Arena => "arena", + }; + write!(f, "{}", v) + } +} + +/// ProgramType must match the the bpf_prog_type enum defined in the linux kernel. +/// https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/bpf.h#L1024 #[derive(ValueEnum, Copy, Clone, Debug, Eq, PartialEq, Deserialize, Serialize)] pub enum ProgramType { Unspec, @@ -1566,6 +1694,42 @@ pub enum ProgramType { Syscall, } +impl From for ProgramType { + fn from(value: aya_obj::ProgramSection) -> Self { + match value { + aya_obj::ProgramSection::KRetProbe => ProgramType::Probe, + aya_obj::ProgramSection::KProbe => ProgramType::Probe, + aya_obj::ProgramSection::UProbe { .. } => ProgramType::Probe, + aya_obj::ProgramSection::URetProbe { .. } => ProgramType::Probe, + aya_obj::ProgramSection::TracePoint => ProgramType::Tracepoint, + aya_obj::ProgramSection::SocketFilter => ProgramType::SocketFilter, + aya_obj::ProgramSection::Xdp { .. } => ProgramType::Xdp, + aya_obj::ProgramSection::SkMsg => ProgramType::SkMsg, + aya_obj::ProgramSection::SkSkbStreamParser => ProgramType::SkSkb, + aya_obj::ProgramSection::SkSkbStreamVerdict => ProgramType::SkSkb, + aya_obj::ProgramSection::SockOps => ProgramType::SockOps, + aya_obj::ProgramSection::SchedClassifier => ProgramType::Tc, + aya_obj::ProgramSection::CgroupSkb => ProgramType::CgroupSkb, + aya_obj::ProgramSection::CgroupSkbIngress => ProgramType::CgroupSkb, + aya_obj::ProgramSection::CgroupSkbEgress => ProgramType::CgroupSkb, + aya_obj::ProgramSection::CgroupSockAddr { .. } => ProgramType::CgroupSockAddr, + aya_obj::ProgramSection::CgroupSysctl => ProgramType::CgroupSysctl, + aya_obj::ProgramSection::CgroupSockopt { .. } => ProgramType::CgroupSockopt, + aya_obj::ProgramSection::LircMode2 => ProgramType::LircMode2, + aya_obj::ProgramSection::PerfEvent => ProgramType::PerfEvent, + aya_obj::ProgramSection::RawTracePoint => ProgramType::RawTracepoint, + aya_obj::ProgramSection::Lsm { .. } => ProgramType::Lsm, + aya_obj::ProgramSection::BtfTracePoint => ProgramType::Tracepoint, + aya_obj::ProgramSection::FEntry { .. } => ProgramType::Tracing, + aya_obj::ProgramSection::FExit { .. } => ProgramType::Tracing, + aya_obj::ProgramSection::Extension => ProgramType::Ext, + aya_obj::ProgramSection::SkLookup => ProgramType::SkLookup, + aya_obj::ProgramSection::CgroupSock { .. } => ProgramType::CgroupSock, + aya_obj::ProgramSection::CgroupDevice { .. } => ProgramType::CgroupDevice, + } + } +} + impl TryFrom for ProgramType { type Error = ParseError; diff --git a/docs/developer-guide/shipping-bytecode.md b/docs/developer-guide/shipping-bytecode.md index 6c3064647..714a07018 100644 --- a/docs/developer-guide/shipping-bytecode.md +++ b/docs/developer-guide/shipping-bytecode.md @@ -36,35 +36,34 @@ a `.o` extension) placed at the root of the layer `./`. To provide relevant metadata regarding the bytecode to any consumers, some relevant labels **MUST** be defined on the image. -These labels are defined as follows: +These labels are dynamic and defined as follows: -- `io.ebpf.program_type`: The eBPF program type (i.e `xdp`,`tc`, `sockops`, ...). +- `io.ebpf.programs`: A label which defines The eBPF programs stored in the bytecode image. + the value of the label is a list which must contain a valid JSON object with + Key's specifying the program name, and values specifying the program type i.e: + "{ "pass" : "xdp" , "counter" : "tc", ...}". -- `io.ebpf.filename`: The Filename of the bytecode stored in the image. - -- `io.ebpf.program_name`: The name of the eBPF Program represented in the bytecode. - -- `io.ebpf.bpf_function_name`: The name of the function that is the entry point for the BPF program. +- `io.ebpf.maps`: A label which defines The eBPF maps stored in the bytecode image. + the value of the label is a list which must contain a valid JSON object with + Key's specifying the map name, and values specifying the map type i.e: + "{ "xdp_stats_map" : "per_cpu_array", ...}". ### Building a Backwards compatible OCI compliant image +Bpfman does not provide wrappers around compilers like clang since many eBPF +libraries (i.e aya, libbpf, cilium-ebpf) already do so, meaning users are expected +to pass in the correct ebpf program bytecode for the appropriate platform. However, +bpfman does provide a few image builder commands to make this whole process easier. + An Example Containerfile can be found at `/packaging/container/deployment/Containerfile.bytecode` -To use the provided templated Containerfile simply run a `docker build` command -like the following: +#### Host Platform Image Build -```bash -docker build \ - --build-arg PROGRAM_NAME=xdp_pass \ - --build-arg BPF_FUNCTION_NAME=pass \ - --build-arg PROGRAM_TYPE=xdp \ - --build-arg BYTECODE_FILENAME=pass.bpf.o \ - --build-arg KERNEL_COMPILE_VER=$(uname -r) \ - -f Containerfile.bytecode \ - /home//bytecode -t quay.io//xdp_pass:latest +```console +bpfman image build -b ./examples/go-xdp-counter/bpf_bpfel.o -f Containerfile.bytecode --tag quay.io//go-xdp-counter ``` -Where `/home//bytecode` is the directory the bytecode object file is located. +Where `./examples/go-xdp-counter/bpf_bpfel.o` is the directory the bytecode object file is located. Users can also use `skopeo` to ensure the image follows the backwards compatible version of the spec: @@ -73,26 +72,31 @@ backwards compatible version of the spec: configuration layer (`application/vnd.oci.image.config.v1+json`) of the image. ```bash -skopeo inspect docker://quay.io/astoycos/xdp_pass:latest +skopeo inspect docker://quay.io/astoycos/go-xdp-counter { - "Name": "quay.io//xdp_pass", - "Digest": "sha256:db1f7dd03f9fba0913e07493238fcfaf0bf08de37b8e992cc5902775dfb9086a", + "Name": "quay.io/astoycos/go-xdp-counter", + "Digest": "sha256:e8377e94c56272937689af88a1a6231d4d594f83218b5cda839eaeeea70a30d3", "RepoTags": [ "latest" ], - "Created": "2022-08-14T14:27:20.147468277Z", + "Created": "2024-05-30T09:17:15.327378016-04:00", "DockerVersion": "", "Labels": { - "io.buildah.version": "1.26.1", - "io.ebpf.filename": "pass.bpf.o", - "io.ebpf.program_name": "xdp_counter", - "io.ebpf.program_type": "xdp", - "io.ebpf.bpf_function_name": "pass" + "io.ebpf.maps": "{\"xdp_stats_map\":\"per_cpu_array\"}", + "io.ebpf.programs": "{\"xdp_stats\":\"xdp\"}" }, "Architecture": "amd64", "Os": "linux", "Layers": [ - "sha256:5f6dae6f567601fdad15a936d844baac1f30c31bd3df8df0c5b5429f3e048000" + "sha256:c0d921d3f0d077da7cdfba8c0240fb513789e7698cdf326f80f30f388c084cff" + ], + "LayersData": [ + { + "MIMEType": "application/vnd.docker.image.rootfs.diff.tar.gzip", + "Digest": "sha256:c0d921d3f0d077da7cdfba8c0240fb513789e7698cdf326f80f30f388c084cff", + "Size": 2656, + "Annotations": null + } ], "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" @@ -100,17 +104,10 @@ skopeo inspect docker://quay.io/astoycos/xdp_pass:latest } ``` -- `skopeo inspect --raw` will show the correct layer type is used in the image. - -```bash -skopeo inspect --raw docker://quay.io/astoycos/xdp_pass:latest -{"schemaVersion":2,"mediaType":"application/vnd.oci.image.manifest.v1+json","config":{"mediaType":"application/vnd.oci.image.config.v1+json","digest":"sha256:ff4108b8405a877b2df3e06f9287c509b9d62d6c241c9a5213d81a9abee80361","size":2385},"layers":[{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:5f6dae6f567601fdad15a936d844baac1f30c31bd3df8df0c5b5429f3e048000","size":1539}],"annotations":{"org.opencontainers.image.base.digest":"sha256:86b59a6cf7046c624c47e40a5618b383d763be712df2c0e7aaf9391c2c9ef559","org.opencontainers.image.base.name":""}} -``` - ## Custom OCI compatible spec This variant of the eBPF bytecode image spec uses custom OCI medium types to represent eBPF bytecode as container images. Many toolchains and registries may not support this yet. -TODO(astoycos) +TODO diff --git a/examples/build-bytecode-images.sh b/examples/build-bytecode-images.sh index b10a08023..9bf99bd5b 100755 --- a/examples/build-bytecode-images.sh +++ b/examples/build-bytecode-images.sh @@ -1,49 +1,33 @@ #!/bin/bash -docker build \ - --build-arg PROGRAM_NAME=xdp_counter \ - --build-arg BPF_FUNCTION_NAME=xdp_stats \ - --build-arg PROGRAM_TYPE=xdp \ - --build-arg BYTECODE_FILENAME=bpf_bpfel.o \ - -f ../Containerfile.bytecode \ - ./go-xdp-counter -t ${IMAGE_XDP_BC} +export RUST_LOG=debug -docker build \ - --build-arg PROGRAM_NAME=tc_counter \ - --build-arg BPF_FUNCTION_NAME=stats \ - --build-arg PROGRAM_TYPE=tc \ - --build-arg BYTECODE_FILENAME=bpf_bpfel.o \ - -f ../Containerfile.bytecode \ - ./go-tc-counter -t $IMAGE_TC_BC +../target/debug/bpfman image build \ + -b ./go-xdp-counter/bpf_bpfel.o \ + -f ../Containerfile.bytecode \ + --tag ${IMAGE_XDP_BC} -docker build \ - --build-arg PROGRAM_NAME=tracepoint_counter \ - --build-arg BPF_FUNCTION_NAME=tracepoint_kill_recorder \ - --build-arg PROGRAM_TYPE=tracepoint \ - --build-arg BYTECODE_FILENAME=bpf_bpfel.o \ - -f ../Containerfile.bytecode \ - ./go-tracepoint-counter -t $IMAGE_TP_BC +../target/debug/bpfman image build \ + -b ./go-tc-counter/bpf_bpfel.o \ + -f ../Containerfile.bytecode \ + --tag ${IMAGE_TC_BC} -docker build \ - --build-arg PROGRAM_NAME=kprobe_counter \ - --build-arg BPF_FUNCTION_NAME=kprobe_counter \ - --build-arg PROGRAM_TYPE=kprobe \ - --build-arg BYTECODE_FILENAME=bpf_bpfel.o \ - -f ../Containerfile.bytecode \ - ./go-kprobe-counter -t $IMAGE_KP_BC +../target/debug/bpfman image build \ +-b ./go-tracepoint-counter/bpf_bpfel.o \ +-f ../Containerfile.bytecode \ +--tag ${IMAGE_TP_BC} -docker build \ - --build-arg PROGRAM_NAME=uprobe_counter \ - --build-arg BPF_FUNCTION_NAME=uprobe_counter \ - --build-arg PROGRAM_TYPE=uprobe \ - --build-arg BYTECODE_FILENAME=bpf_bpfel.o \ - -f ../Containerfile.bytecode \ - ./go-uprobe-counter -t $IMAGE_UP_BC +../target/debug/bpfman image build \ + -b ./go-kprobe-counter/bpf_bpfel.o \ + -f ../Containerfile.bytecode \ + --tag ${IMAGE_KP_BC} -docker build \ - --build-arg PROGRAM_NAME=uretprobe_counter \ - --build-arg BPF_FUNCTION_NAME=uretprobe_counter \ - --build-arg PROGRAM_TYPE=uretprobe \ - --build-arg BYTECODE_FILENAME=bpf_x86_bpfel.o \ - -f ../Containerfile.bytecode \ - ./go-uretprobe-counter -t $IMAGE_URP_BC +../target/debug/bpfman image build \ + -b ./go-uprobe-counter/bpf_bpfel.o \ + -f ../Containerfile.bytecode \ + --tag ${IMAGE_UP_BC} + +../target/debug/bpfman image build \ + -b ./go-uretprobe-counter/bpf_x86_bpfel.o \ + -f ../Containerfile.bytecode \ + --tag ${IMAGE_URP_BC}