From 8f2722a5dc0bf47fa5512f522da943e8e044d576 Mon Sep 17 00:00:00 2001 From: Yann Soubeyrand Date: Fri, 19 Jul 2024 17:39:28 +0200 Subject: [PATCH] ci: build multi-platform container images --- .gitattributes | 4 + .github/workflows/build.yaml | 79 +++++++++++++++--- .gitignore | 5 +- dagger.json | 18 ++++- go.mod | 39 ++++++++- go.sum | 87 ++++++++++++++++++++ main.go | 151 ++++++++++++++++++++++++++++++----- 7 files changed, 347 insertions(+), 36 deletions(-) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..3a45493 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,4 @@ +/dagger.gen.go linguist-generated +/internal/dagger/** linguist-generated +/internal/querybuilder/** linguist-generated +/internal/telemetry/** linguist-generated diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 9981c4a..0ea53f1 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -1,33 +1,92 @@ --- -name: "Build" +name: "Build and publish" on: push: tags: - "*" -permissions: - contents: "read" - id-token: "write" - packages: "write" - jobs: - image: - name: "Container Image" - runs-on: "ubuntu-latest" + build: + name: "Build" + runs-on: "ubuntu-22.04" + + permissions: + contents: "read" + packages: "write" + + strategy: + matrix: + images: + - arch: "amd64" + - arch: "arm64" + + fail-fast: true + steps: - name: "Checkout repository" id: "checkout" uses: "actions/checkout@v4" + - name: "Set up Dagger" id: "setup-dagger" uses: "camptocamp/setup-dagger@v1" with: cloud-token: "${{ secrets.DAGGER_CLOUD_TOKEN }}" + + - name: "Login to GitHub Container Registry" + id: "login-registry" + uses: "docker/login-action@v3" + with: + registry: "ghcr.io" + username: "${{ github.actor }}" + password: "${{ secrets.GITHUB_TOKEN }}" + - name: "Build container image" id: "build-image" run: | - dagger call publish --registry 'ghcr.io' --username '${{ github.actor }}' --password '${{ github.token }}' --repository '${{ github.repository_owner }}/varnish' --tag '${{ github.ref_name }}' + echo "$(dagger call container --platform '${{ matrix.images.arch }}' publish --address "ghcr.io/${{ github.repository_owner }}/varnish:${{ github.ref_name }}-${{ matrix.images.arch }}")" > ref + + - name: "Upload reference" + id: "upload-reference" + uses: "actions/upload-artifact@v4" + with: + name: "ref-${{ matrix.images.arch }}" + path: "ref" + if-no-files-found: error + retention-days: 1 + + publish: + name: "Publish" + runs-on: "ubuntu-22.04" + needs: "build" + + permissions: + packages: "write" + + steps: + - name: "Login to GitHub Container Registry" + id: "login-registry" + uses: "docker/login-action@v3" + with: + registry: "ghcr.io" + username: "${{ github.actor }}" + password: "${{ secrets.GITHUB_TOKEN }}" + + - name: "Download references" + id: "download-references" + uses: "actions/download-artifact@v4" + with: + pattern: "ref-*" + merge-multiple: true + + - name: "Publish manifest" + id: "publish-manifest" + run: | + address='ghcr.io/${{ github.repository_owner }}/varnish:${{ github.ref_name }}' + docker manifest create "$address" $(cat ref-*) + docker manifest push "$address" + - name: "Delete old container images" id: "delete-old-images" uses: "actions/delete-package-versions@v5" diff --git a/.gitignore b/.gitignore index d10f24a..7ebabcc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /dagger.gen.go -/internal/querybuilder/ -/querybuilder/ +/internal/dagger +/internal/querybuilder +/internal/telemetry diff --git a/dagger.json b/dagger.json index 3f08c15..2ca3faf 100644 --- a/dagger.json +++ b/dagger.json @@ -1,4 +1,20 @@ { "name": "varnish", - "sdk": "go" + "sdk": "go", + "dependencies": [ + { + "name": "golang", + "source": "github.com/camptocamp/daggerverse/golang@16a6c4a8c337532d2c8a5dd8bb2969aedb3cb845" + }, + { + "name": "jq", + "source": "github.com/camptocamp/daggerverse/jq@b8db11532e3745f05cb0346325f0bf0f0bd51eb4" + }, + { + "name": "redhat", + "source": "github.com/camptocamp/daggerverse/redhat@f21280f6ba7a0d17c20b88776affcf8fba5cfd87" + } + ], + "source": ".", + "engineVersion": "v0.12.0" } diff --git a/go.mod b/go.mod index d337dcb..24effc4 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,40 @@ -module github.com/camptocamp/docker-varnish +module varnish go 1.21.3 + +require ( + github.com/99designs/gqlgen v0.17.49 + github.com/Khan/genqlient v0.7.0 + github.com/vektah/gqlparser/v2 v2.5.16 + go.opentelemetry.io/otel v1.28.0 + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240722072124-4c7f2bf5e845 + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.4.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0 + go.opentelemetry.io/otel/log v0.4.0 + go.opentelemetry.io/otel/sdk v1.28.0 + go.opentelemetry.io/otel/sdk/log v0.4.0 + go.opentelemetry.io/otel/trace v1.28.0 + go.opentelemetry.io/proto/otlp v1.3.1 + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 + golang.org/x/sync v0.7.0 + google.golang.org/grpc v1.65.0 +) + +require ( + github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect + github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect + github.com/sosodev/duration v1.3.1 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect + go.opentelemetry.io/otel/metric v1.28.0 // indirect + golang.org/x/net v0.27.0 // indirect + golang.org/x/sys v0.22.0 // indirect + golang.org/x/text v0.16.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect + google.golang.org/protobuf v1.34.2 // indirect +) diff --git a/go.sum b/go.sum index e69de29..2058cae 100644 --- a/go.sum +++ b/go.sum @@ -0,0 +1,87 @@ +github.com/99designs/gqlgen v0.17.49 h1:b3hNGexHd33fBSAd4NDT/c3NCcQzcAVkknhN9ym36YQ= +github.com/99designs/gqlgen v0.17.49/go.mod h1:tC8YFVZMed81x7UJ7ORUwXF4Kn6SXuucFqQBhN8+BU0= +github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= +github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/sosodev/duration v1.3.1 h1:qtHBDMQ6lvMQsL15g4aopM4HEfOaYuhWBw3NPTtlqq4= +github.com/sosodev/duration v1.3.1/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/vektah/gqlparser/v2 v2.5.16 h1:1gcmLTvs3JLKXckwCwlUagVn/IlV2bwqle0vJ0vy5p8= +github.com/vektah/gqlparser/v2 v2.5.16/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= +go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= +go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240722072124-4c7f2bf5e845 h1:TrOO1do62NoaHl6MVPH/Kfwt/c6C1Cr9cYJCSWZJ+t8= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240722072124-4c7f2bf5e845/go.mod h1:rW8ltr6KoR3Rrl0/qiEnuUBXPYME0z5YCwO2pKsmOpc= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.4.0 h1:zBPZAISA9NOc5cE8zydqDiS0itvg/P/0Hn9m72a5gvM= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.4.0/go.mod h1:gcj2fFjEsqpV3fXuzAA+0Ze1p2/4MJ4T7d77AmkvueQ= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 h1:R3X6ZXmNPRR8ul6i3WgFURCHzaXjHdm0karRG/+dj3s= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0/go.mod h1:QWFXnDavXWwMx2EEcZsf3yxgEKAqsxQ+Syjp+seyInw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0 h1:j9+03ymgYhPKmeXGk5Zu+cIZOlVzd9Zv7QIiyItjFBU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0/go.mod h1:Y5+XiUG4Emn1hTfciPzGPJaSI+RpDts6BnCIir0SLqk= +go.opentelemetry.io/otel/log v0.4.0 h1:/vZ+3Utqh18e8TPjuc3ecg284078KWrR8BRz+PQAj3o= +go.opentelemetry.io/otel/log v0.4.0/go.mod h1:DhGnQvky7pHy82MIRV43iXh3FlKN8UUKftn0KbLOq6I= +go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= +go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= +go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= +go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= +go.opentelemetry.io/otel/sdk/log v0.4.0 h1:1mMI22L82zLqf6KtkjrRy5BbagOTWdJsqMY/HSqILAA= +go.opentelemetry.io/otel/sdk/log v0.4.0/go.mod h1:AYJ9FVF0hNOgAVzUG/ybg/QttnXhUePWAupmCqtdESo= +go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= +go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= +go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= +go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY= +google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d h1:JU0iKnSg02Gmb5ZdV8nYsKEKsP6o/FGVWTrw4i1DA9A= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index 7b945a1..5f96592 100644 --- a/main.go +++ b/main.go @@ -2,37 +2,144 @@ package main import ( "context" + "fmt" + "strings" + "time" + "varnish/internal/dagger" ) const ( - version = "7.5.0" - prometheusExporterVersion = "1.6.1" - jqVersion = "1.7.1" + // Varnish container registry + ImageRegistry string = "docker.io" + // Varnish container repository + ImageRepository string = "library/varnish" + // Varnish container tag + ImageTag string = "7.5.0" + // Varnish container digest + ImageDigest string = "sha256:ca2fcecb439f71a3546d025c65857591281a1596c44e8cb816905aa4d1864b61" + + // Varnish Prometheus exporter version + PrometheusExporterVersion string = "1.6.1" + + // jq version + JqVersion string = "1.7.1" ) +// Varnish type Varnish struct{} -func (v *Varnish) Container() *Container { - binaryFileOpts := ContainerWithFileOpts{ - Owner: "root:root", - Permissions: 0755, +// Get a Varnish container +func (varnish *Varnish) Container( + ctx context.Context, + // Platform to get container for + // +optional + platform dagger.Platform, +) (*dagger.Container, error) { + prometheusExporter, err := varnish.PrometheusExporter(PrometheusExporterVersion).Overlay(ctx, platform, "") + + if err != nil { + return nil, fmt.Errorf("failed to get Prometheus Exporter overlay: %s", err) + } + + jq := dag.Jq(JqVersion).Overlay(dagger.JqOverlayOpts{Platform: platform}) + configurationLoaderScript := dag.CurrentModule().Source().File("varnish-configuration-loader") + + container := dag.Container(dagger.ContainerOpts{Platform: platform}). + From(ImageRegistry+"/"+ImageRepository+":"+ImageTag+"@"+ImageDigest). + WithDirectory("/", prometheusExporter). + WithDirectory("/", jq). + WithFile("/usr/local/bin/varnish-configuration-loader", configurationLoaderScript, dagger.ContainerWithFileOpts{ + Owner: "root:root", + Permissions: 0755, + }) + + return container, nil +} + +// Varnish Prometheus Exporter +type VarnishPrometheusExporter struct { + // +private + Version string +} + +// Varnish Prometheus Exporter constructor +func (*Varnish) PrometheusExporter( + // Varnish Prometheus exporter version to get + version string, +) *VarnishPrometheusExporter { + prometheusExporter := &VarnishPrometheusExporter{ + Version: version, + } + + return prometheusExporter +} + +// Get Varnish Prometheus Exporter executable binary +func (prometheusExporter *VarnishPrometheusExporter) Binary( + ctx context.Context, + // Platform to get Varnish Prometheus exporter for + // +optional + platform dagger.Platform, +) (*dagger.File, error) { + if platform == "" { + defaultPlatform, err := dag.DefaultPlatform(ctx) + + if err != nil { + return nil, fmt.Errorf("failed to get platform: %s", err) + } + + platform = defaultPlatform + } + + platformElements := strings.Split(string(platform), "/") + + os := platformElements[0] + arch := platformElements[1] + + source := dag.Git("https://github.com/jonnenauha/prometheus_varnish_exporter.git"). + Tag(prometheusExporter.Version) + + commit, err := source.Commit(ctx) + + if err != nil { + return nil, fmt.Errorf("failed to get commit hash: %s", err) } - exporter := dag.Container(). - From("registry.access.redhat.com/ubi9/ubi"). - WithWorkdir("/home"). - WithEntrypoint([]string{"bash", "-c"}). - WithFile("prometheus-exporter.tar.gz", dag.HTTP("https://github.com/jonnenauha/prometheus_varnish_exporter/releases/download/"+prometheusExporterVersion+"/prometheus_varnish_exporter-"+prometheusExporterVersion+".linux-amd64.tar.gz")). - WithExec([]string{"tar -xzvf prometheus-exporter.tar.gz"}). - File("prometheus_varnish_exporter-" + prometheusExporterVersion + ".linux-amd64/prometheus_varnish_exporter") - - return dag.Container(). - From("docker.io/varnish:"+version). - WithFile("/usr/local/bin/prometheus_varnish_exporter", exporter, binaryFileOpts). - WithFile("/usr/local/bin/jq", dag.HTTP("https://github.com/jqlang/jq/releases/download/jq-"+jqVersion+"/jq-linux-amd64"), binaryFileOpts). - WithFile("/usr/local/bin/varnish-configuration-loader", dag.CurrentModule().Source().File("varnish-configuration-loader"), binaryFileOpts) + binary := dag.Golang(). + RedhatContainer(). + WithEnvVariable("GOOS", os). + WithEnvVariable("GOARCH", arch). + WithMountedDirectory(".", source.Tree()). + WithExec([]string{"go", "build", "-ldflags", fmt.Sprintf("-X 'main.Version=%s' -X 'main.VersionHash=%s' -X 'main.VersionDate=%s'", prometheusExporter.Version, commit, time.Now().Format(time.DateTime))}). + File("prometheus_varnish_exporter") + + return binary, nil } -func (v *Varnish) Publish(ctx context.Context, registry string, username string, password string, repository string, tag string) (string, error) { - return v.Container().WithRegistryAuth(registry, username, dag.SetSecret("registry-password", password)).Publish(ctx, registry+"/"+repository+":"+tag) +// Get a root filesystem overlay with Varnish Prometheus Exporter +func (prometheusExporter *VarnishPrometheusExporter) Overlay( + ctx context.Context, + // Platform to get Varnish Prometheus Exporter for + // +optional + platform dagger.Platform, + // Filesystem prefix under which to install Varnish Prometheus Exporter + // +optional + prefix string, +) (*dagger.Directory, error) { + if prefix == "" { + prefix = "/usr/local" + } + + binary, err := prometheusExporter.Binary(ctx, platform) + + if err != nil { + return nil, fmt.Errorf("failed to get Varnish Prometheus Exporter binary: %s", err) + } + + overlay := dag.Directory(). + WithDirectory(prefix, dag.Directory(). + WithFile("bin/prometheus-exporter", binary), + ) + + return overlay, nil }