Skip to content

Commit

Permalink
feat: Allow copa to use buildkit from dockerd (#233)
Browse files Browse the repository at this point in the history
Co-authored-by: Sertaç Özercan <852750+sozercan@users.noreply.github.com>
  • Loading branch information
cpuguy83 and sozercan authored Aug 15, 2023
1 parent 6e08cb6 commit 3dec6b7
Show file tree
Hide file tree
Showing 22 changed files with 843 additions and 62 deletions.
71 changes: 21 additions & 50 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,26 +79,32 @@ jobs:
name: copa_edge_linux_amd64.tar.gz
path: dist/linux_amd64/release/copa_edge_linux_amd64.tar.gz
- name: Load test cases for patch testing
id: load-tests
id: load-test-envs-matrix
shell: bash
run: |
json="$(cat .github/workflows/test-images.json)"
json="${json//[$'\n'$'\r']/''}"
echo "include=$json" >> $GITHUB_OUTPUT
run: echo "buildkitenvs=$(.github/workflows/scripts/buildkit-env-matrix.sh)" | tee -a "${GITHUB_OUTPUT}"
outputs:
include: ${{ steps.load-tests.outputs.include }}
buildkitenvs: ${{ steps.load-test-envs-matrix.outputs.buildkitenvs }}

test-patch:
needs: build
name: Test patch ${{ matrix.image }}:${{ matrix.tag }}
name: Test patch ${{ matrix.buildkit_mode }}
runs-on: ubuntu-latest
timeout-minutes: 10
timeout-minutes: 30
permissions: read-all
strategy:
fail-fast: false
matrix:
include: ${{ fromJson(needs.build.outputs.include) }}
buildkit_mode: ${{fromJson(needs.build.outputs.buildkitenvs)}}
steps:
- name: Download copa from build artifacts
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
with:
name: copa_edge_linux_amd64.tar.gz
- name: Check out code
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Install required tools
shell: bash
run: .github/workflows/scripts/download-tooling.sh
- name: Download copa from build artifacts
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
with:
Expand All @@ -108,48 +114,13 @@ jobs:
run: |
tar xzf copa_edge_linux_amd64.tar.gz
./copa --version
- name: Install required tools
shell: bash
run: |
curl -sfL https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_Linux-64bit.deb -o trivy.deb \
&& sudo dpkg -i trivy.deb \
&& rm trivy.deb
curl -sfL https://github.com/moby/buildkit/releases/download/v${BUILDKIT_VERSION}/buildkit-v${BUILDKIT_VERSION}.linux-amd64.tar.gz -o buildkit.tar.gz \
&& sudo tar -zxvf buildkit.tar.gz -C /usr/local/ \
&& rm buildkit.tar.gz
- name: Create Trivy ignore policy
shell: bash
run: |
cat <<EOF >>trivy_ignore.rego
package trivy
import data.lib.trivy
default ignore = false
ignore_vulnerability_ids := {
# centos 7.6.1810
# bind-license package version "9.11.4-26.P2.el7_9.14" does not exist
"CVE-2023-2828"
}
ignore {
input.VulnerabilityID == ignore_vulnerability_ids[_]
}
EOF
- name: Set up QEMU
uses: docker/setup-qemu-action@2b82ce82d56a2a04d2637cd93a637ae1b359c0a7 # v2.2.0
- name: Run functional test
shell: bash
run: |
echo "[INFO]: Patching ${{ matrix.distro }} image with: ${{ matrix.description }}"
echo "[INFO]: Scanning image with trivy ..."
trivy image --vuln-type os --ignore-unfixed --scanners vuln -f json -o scan.json "${{ matrix.image }}:${{ matrix.tag }}@${{ matrix.digest }}" --exit-on-eol 1 --ignore-policy trivy_ignore.rego
echo "[INFO]: Start buildkitd in the background ..."
docker run --net=host --detach --rm --privileged -p 127.0.0.1:8888:8888/tcp --name buildkitd --entrypoint buildkitd moby/buildkit:v${{ env.BUILDKIT_VERSION }} --addr tcp://0.0.0.0:8888
echo "[INFO]: Run copa on target ..."
./copa patch -i "${{ matrix.image }}:${{ matrix.tag }}@${{ matrix.digest }}" -r scan.json -t "${{ matrix.tag }}-patched" -a tcp://127.0.0.1:8888 --timeout 10m
set -eu -o pipefail
. .github/workflows/scripts/buildkitenvs/${{ matrix.buildkit_mode}}
go test -v ./integration --addr="${COPA_BUILDKIT_ADDR}" --copa="$(pwd)/copa"
echo "[INFO]: Rescanning patched image with same vuln DB ..."
trivy image --vuln-type os --ignore-unfixed --skip-db-update --scanners vuln "${{ matrix.image }}:${{ matrix.tag }}-patched" --exit-code 1 --exit-on-eol 1 --ignore-policy trivy_ignore.rego
17 changes: 17 additions & 0 deletions .github/workflows/scripts/buildkit-env-matrix.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/usr/bin/env bash

set -eu -o pipefail

SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"

# Collect all the modes into a bash array
modes=()
for i in ${SCRIPT_DIR}/buildkitenvs/*; do
base="${i##*/}"
for j in "${i}"/*; do
modes+=(${base}/${j##*/})
done
done

# Convert bash array to json
jq -c --null-input '$ARGS.positional' --args -- "${modes[@]}"
5 changes: 5 additions & 0 deletions .github/workflows/scripts/buildkitenvs/buildx/default
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env sh

docker buildx create --use
docker buildx inspect --bootstrap
export COPA_BUILDKIT_ADDR="buildx://"
5 changes: 5 additions & 0 deletions .github/workflows/scripts/buildkitenvs/buildx/named
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env sh

docker buildx create --name testpatch
docker buildx inspect --bootstrap testpatch
export COPA_BUILDKIT_ADDR="buildx://testpatch"
24 changes: 24 additions & 0 deletions .github/workflows/scripts/buildkitenvs/direct/tcp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env sh


: "${BUILDKIT_PORT:=30321}"
: "${BUILDKIT_VERSION=0.12.0}"

_buildkit_direct_tcp_id="$(docker run --detach --rm --privileged -p 127.0.0.1::${BUILDKIT_PORT}/tcp --entrypoint buildkitd "moby/buildkit:v$BUILDKIT_VERSION" --addr tcp://0.0.0.0:${BUILDKIT_PORT})"
_buildkitd_tcp_addr="$(docker port ${_buildkit_direct_tcp_id} ${BUILDKIT_PORT})"
export COPA_BUILDKIT_ADDR="tcp://${_buildkitd_tcp_addr}"

_cleanup() {
docker rm -f "${_buildkit_direct_tcp_id}"
}

trap '_cleanup' EXIT

_check_buildkitd_tcp() {
buildctl --addr ${COPA_BUILDKIT_ADDR} debug info
}

echo "[INFO] Wait for buildkitd to be ready @ ${COPA_BUILDKIT_ADDR}"
while ! _check_buildkitd_tcp; do
sleep 1
done
31 changes: 31 additions & 0 deletions .github/workflows/scripts/buildkitenvs/docker/custom-unix
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/env sh

# dockerd requires containerd snapshotter support to be enabled otherwise required features for buildkit are disabled.
docker build -t dind -<<EOF
FROM docker:24.0-dind
RUN mkdir -p /etc/docker && echo '{"features": { "containerd-snapshotter": true }}' > /etc/docker/daemon.json
ENTRYPOINT ["dockerd"]
EOF

: "${DOCKER_DIND_VOLUME:="copa-docker-dind"}"

sock_dir="$(mktemp -d)"

docker_custom_unix_id="$(docker run -d --privileged --mount=type=bind,source="${sock_dir}",target=/run --mount=type=volume,source="${DOCKER_DIND_VOLUME}",target=/var/lib/docker dind --group "$(id -g)")"

_cleanup() {
docker rm -f "$docker_custom_unix_id"
sudo rm -rf "${sock_dir}"
}

trap '_cleanup' EXIT

_check_docker_dind() {
docker -H "unix://${sock_dir}/docker.sock" info
}

while ! _check_docker_dind; do
check_docker_dind || sleep 1
done

export COPA_BUILDKIT_ADDR="docker://unix://${sock_dir}/docker.sock"
11 changes: 11 additions & 0 deletions .github/workflows/scripts/download-tooling.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env bash

set -eu -o pipefail

curl -sfL https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_Linux-64bit.deb -o trivy.deb
sudo dpkg -i trivy.deb
rm trivy.deb

curl -sfL https://github.com/moby/buildkit/releases/download/v${BUILDKIT_VERSION}/buildkit-v${BUILDKIT_VERSION}.linux-amd64.tar.gz -o buildkit.tar.gz
sudo tar -zxvf buildkit.tar.gz -C /usr/local/
rm buildkit.tar.gz
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ require (
github.com/aquasecurity/trivy v0.44.1
github.com/containerd/console v1.0.3
github.com/containerd/containerd v1.7.3
github.com/cpuguy83/dockercfg v0.3.1
github.com/distribution/distribution v2.8.2+incompatible
github.com/docker/cli v24.0.5+incompatible
github.com/google/go-containerregistry v0.16.1
Expand All @@ -34,6 +35,7 @@ require (
github.com/containerd/continuity v0.4.1 // indirect
github.com/containerd/ttrpc v1.2.2 // indirect
github.com/containerd/typeurl/v2 v2.1.1 // indirect
github.com/cpuguy83/go-docker v0.1.2
github.com/cyphar/filepath-securejoin v0.2.3 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/docker/distribution v2.8.2+incompatible // indirect
Expand Down Expand Up @@ -94,7 +96,7 @@ require (
golang.org/x/tools v0.10.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
google.golang.org/grpc v1.55.0 // indirect
google.golang.org/grpc v1.55.0
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
Expand Down
6 changes: 5 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ github.com/containerd/ttrpc v1.2.2 h1:9vqZr0pxwOF5koz6N0N3kJ0zDHokrcPxIR/ZR2YFtO
github.com/containerd/ttrpc v1.2.2/go.mod h1:sIT6l32Ph/H9cvnJsfXM5drIVzTr5A2flTf1G5tYZak=
github.com/containerd/typeurl/v2 v2.1.1 h1:3Q4Pt7i8nYwy2KmQWIw2+1hTvwTE/6w9FqcttATPO/4=
github.com/containerd/typeurl/v2 v2.1.1/go.mod h1:IDp2JFvbwZ31H8dQbEIY7sDl2L3o3HZj1hsSQlywkQ0=
github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E=
github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc=
github.com/cpuguy83/go-docker v0.1.2 h1:bHyfwV+yMw+IP2iL/0T5WU/g7Bpj+yhdlwoe6LEwA+A=
github.com/cpuguy83/go-docker v0.1.2/go.mod h1:tZURUlegjsgYPhkfkuPCeVrp1ocirH4P1yUexBpP25g=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI=
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
Expand Down Expand Up @@ -725,7 +729,7 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
gotest.tools/v3 v3.3.0 h1:MfDY1b1/0xN1CyMlQDac0ziEy9zJQd9CXBRRDHw2jJo=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
Expand Down
File renamed without changes.
11 changes: 11 additions & 0 deletions integration/fixtures/trivy_ignore.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package trivy

import data.lib.trivy

default ignore = false

ignore_vulnerability_ids := {
# centos 7.6.1810
# bind-license package version "9.11.4-26.P2.el7_9.14" does not exist
"CVE-2023-2828"
}
25 changes: 25 additions & 0 deletions integration/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package integration

import (
"flag"
"os"
"testing"
)

var (
buildkitAddr string
copaPath string
)

func TestMain(m *testing.M) {
flag.StringVar(&buildkitAddr, "addr", "", "buildkit address to pass through to copa binary")
flag.StringVar(&copaPath, "copa", "./copa", "path to copa binary")
flag.Parse()

if copaPath == "" {
panic("missing --copa")
}

ec := m.Run()
os.Exit(ec)
}
Loading

0 comments on commit 3dec6b7

Please sign in to comment.