Skip to content

Commit

Permalink
chore(ci): build and publish operator and lam image with dagger (#1206)
Browse files Browse the repository at this point in the history
  • Loading branch information
emosbaugh authored Sep 20, 2024
1 parent acc9ea2 commit 1bb52ef
Show file tree
Hide file tree
Showing 14 changed files with 496 additions and 180 deletions.
5 changes: 3 additions & 2 deletions common.mk
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ else
GOBIN=$(shell go env GOBIN)
endif

image-tag = $(shell echo "$1" | sed 's/+/-/')

.PHONY: print-%
print-%:
@echo -n $($*)
Expand Down Expand Up @@ -90,13 +92,12 @@ apko-print-pkg-version: apko-template check-env-PACKAGE_NAME
head -n1

.PHONY: apko-output-image
apko-output-image:
apko-output-image: check-env-IMAGE
@digest=$$(cut -s -d'@' -f2 build/digest); \
if [ -z "$$digest" ]; then \
echo "error: no image digest found" >&2; \
exit 1; \
fi ; \
mkdir -p build; \
echo "$(IMAGE)@$$digest" > build/image

.PHONY: melange-build
Expand Down
111 changes: 111 additions & 0 deletions dagger/chainguard.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package main

import (
"fmt"

"dagger/embedded-cluster/internal/dagger"
)

type chainguard struct{}

func (m *chainguard) melangeBuildGo(
src *dagger.Directory,
melangeFile *dagger.File,
// +default="amd64,arm64"
arch string,
// +default="latest"
imageTag string,
) *dagger.Container {

keygen := m.melangeKeygen(imageTag)

c := dag.Container().
From(fmt.Sprintf("cgr.dev/chainguard/melange:%s", imageTag)).
WithDirectory("/workspace", src).
WithFile("/workspace/melange.yaml", melangeFile).
WithFile("/workspace/melange.rsa", keygen.File("/workspace/melange.rsa")).
WithMountedCache("/go/pkg/mod", dag.CacheVolume("go-mod")).
WithWorkdir("/workspace").
WithExec(
[]string{
"melange", "build", "melange.yaml",
"--signing-key", "melange.rsa",
"--cache-dir", "/go/pkg/mod",
"--arch", arch,
"--out-dir", "build/packages/",
},
dagger.ContainerWithExecOpts{
ExperimentalPrivilegedNesting: true,
InsecureRootCapabilities: true,
},
)

// for output
c = c.WithFile("/workspace/build/melange.rsa.pub", keygen.File("/workspace/melange.rsa.pub"))

return c
}

func (m *chainguard) melangeKeygen(
// +default="latest"
imageTag string,
) *dagger.Container {
keygen := dag.Container().
From(fmt.Sprintf("cgr.dev/chainguard/melange:%s", imageTag)).
WithWorkdir("/workspace").
WithExec([]string{"melange", "keygen"})

return keygen
}

func (m *chainguard) apkoBuild(
src *dagger.Directory,
apkoFile *dagger.File,
image string,
// +default="amd64,arm64"
arch string,
// +default="latest"
imageTag string,
) *dagger.Container {

c := dag.Container().
From(fmt.Sprintf("cgr.dev/chainguard/apko:%s", imageTag)).
WithDirectory("/workspace", src).
WithFile("/workspace/apko.yaml", apkoFile).
WithWorkdir("/workspace").
WithExec(
[]string{
"apko", "build", "apko.yaml", image, "apko.tar",
"--cache-dir", "/go/pkg/mod",
"--arch", arch,
},
)

return c
}

func (m *chainguard) apkoPublish(
src *dagger.Directory,
apkoFile *dagger.File,
image string,
// +default="amd64,arm64"
arch string,
// +default="latest"
imageTag string,
) *dagger.Container {

c := dag.Container().
From(fmt.Sprintf("cgr.dev/chainguard/apko:%s", imageTag)).
WithDirectory("/workspace", src).
WithFile("/workspace/apko.yaml", apkoFile).
WithWorkdir("/workspace").
WithExec(
[]string{
"apko", "publish", "apko.yaml", image,
"--cache-dir", "/go/pkg/mod",
"--arch", arch,
},
)

return c
}
14 changes: 8 additions & 6 deletions dagger/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,33 @@ 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.27.0
go.opentelemetry.io/otel v1.30.0
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0
go.opentelemetry.io/otel/log v0.3.0
go.opentelemetry.io/otel/sdk v1.27.0
go.opentelemetry.io/otel/sdk v1.30.0
go.opentelemetry.io/otel/sdk/log v0.3.0
go.opentelemetry.io/otel/trace v1.27.0
go.opentelemetry.io/otel/trace v1.30.0
go.opentelemetry.io/proto/otlp v1.3.1
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56
golang.org/x/sync v0.8.0
google.golang.org/grpc v1.66.1
)

require (
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // 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.22.0 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // 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.27.0 // indirect
go.opentelemetry.io/otel/metric v1.27.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect
go.opentelemetry.io/otel/metric v1.30.0 // indirect
golang.org/x/net v0.29.0 // indirect
golang.org/x/sys v0.25.0 // indirect
golang.org/x/text v0.18.0 // indirect
Expand Down
30 changes: 16 additions & 14 deletions dagger/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo
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/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/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=
Expand All @@ -23,8 +24,9 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1
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/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/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=
Expand All @@ -35,34 +37,34 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT
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.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg=
go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ=
go.opentelemetry.io/otel v1.30.0 h1:F2t8sK4qf1fAmY9ua4ohFS/K+FUuOPemHUIXHtktrts=
go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc=
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 h1:oM0GTNKGlc5qHctWeIGTVyda4iFFalOzMZ3Ehj5rwB4=
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88/go.mod h1:JGG8ebaMO5nXOPnvKEl+DiA4MGwFjCbjsxT1WHIEBPY=
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 h1:ccBrA8nCY5mM0y5uO7FT0ze4S0TuFcWdDB2FxGMTjkI=
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0/go.mod h1:/9pb6634zi2Lk8LYg9Q0X8Ar6jka4dkFOylBLbVQPCE=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s=
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.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0/go.mod h1:MOiCmryaYtc+V0Ei+Tx9o5S1ZjA7kzLucuVuyzBZloQ=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 h1:QY7/0NeRPKlzusf40ZE4t1VlMKbqSNT7cJRYzWuja0s=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0/go.mod h1:HVkSiDhTM9BoUJU8qE6j2eSWLLXvi1USXjyd2BXT8PY=
go.opentelemetry.io/otel/log v0.3.0 h1:kJRFkpUFYtny37NQzL386WbznUByZx186DpEMKhEGZs=
go.opentelemetry.io/otel/log v0.3.0/go.mod h1:ziCwqZr9soYDwGNbIL+6kAvQC+ANvjgG367HVcyR/ys=
go.opentelemetry.io/otel/metric v1.27.0 h1:hvj3vdEKyeCi4YaYfNjv2NUje8FqKqUY8IlF0FxV/ik=
go.opentelemetry.io/otel/metric v1.27.0/go.mod h1:mVFgmRlhljgBiuk/MP/oKylr4hs85GZAylncepAX/ak=
go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kTWmI=
go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A=
go.opentelemetry.io/otel/metric v1.30.0 h1:4xNulvn9gjzo4hjg+wzIKG7iNFEaBMX00Qd4QIZs7+w=
go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ=
go.opentelemetry.io/otel/sdk v1.30.0 h1:cHdik6irO49R5IysVhdn8oaiR9m8XluDaJAs4DfOrYE=
go.opentelemetry.io/otel/sdk v1.30.0/go.mod h1:p14X4Ok8S+sygzblytT1nqG98QG2KYKv++HE0LY/mhg=
go.opentelemetry.io/otel/sdk/log v0.3.0 h1:GEjJ8iftz2l+XO1GF2856r7yYVh74URiF9JMcAacr5U=
go.opentelemetry.io/otel/sdk/log v0.3.0/go.mod h1:BwCxtmux6ACLuys1wlbc0+vGBd+xytjmjajwqqIul2g=
go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw=
go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4=
go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8dQ9wmc=
go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o=
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-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ=
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
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.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
Expand Down
140 changes: 140 additions & 0 deletions dagger/localartifactmirror.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
package main

import (
"context"
"fmt"
"strings"

"dagger/embedded-cluster/internal/dagger"
)

// Builds the local artifact mirror image with APKO.
func (m *EmbeddedCluster) BuildLocalArtifactMirrorImage(
// Source directory to use for the build.
// +defaultPath="/"
src *dagger.Directory,
// Repository to use for the image.
// +default="replicated/embedded-cluster-local-artifact-mirror"
repo string,
// Version to use for the package.
ecVersion string,
// Architectures to build for.
// +default="amd64,arm64"
arch string,
) *dagger.File {

tag := strings.Replace(ecVersion, "+", "-", -1)
image := fmt.Sprintf("%s:%s", repo, tag)

apkoFile := m.apkoTemplateLocalArtifactMirror(src, ecVersion)

pkgBuild := m.BuildLocalArtifactMirrorPackage(src, ecVersion, arch)

dir := dag.Directory().
WithFile("melange.rsa.pub", pkgBuild.File("melange.rsa.pub")).
WithDirectory("packages", pkgBuild.Directory("packages"))

build := m.apkoBuild(
dir,
apkoFile,
image,
arch,
APKOImageVersion,
)

return build.File("apko.tar")
}

// Builds and publishes the local artifact mirror image with APKO.
func (m *EmbeddedCluster) PublishLocalArtifactMirrorImage(
ctx context.Context,
// Source directory to use for the build.
// +defaultPath="/"
src *dagger.Directory,
// Repository to use for the image.
// +default="replicated/embedded-cluster-local-artifact-mirror"
repo string,
// Version to use for the package.
ecVersion string,
// Architectures to build for.
// +default="amd64,arm64"
arch string,
) (string, error) {

tag := strings.Replace(ecVersion, "+", "-", -1)
image := fmt.Sprintf("%s:%s", repo, tag)

apkoFile := m.apkoTemplateLocalArtifactMirror(src, ecVersion)

pkgBuild := m.BuildLocalArtifactMirrorPackage(src, ecVersion, arch)

dir := dag.Directory().
WithFile("melange.rsa.pub", pkgBuild.File("melange.rsa.pub")).
WithDirectory("packages", pkgBuild.Directory("packages"))

publish := m.apkoPublish(
dir,
apkoFile,
image,
arch,
APKOImageVersion,
)

return publish.Stdout(ctx)
}

// Builds the local artifact mirror package with Melange.
func (m *EmbeddedCluster) BuildLocalArtifactMirrorPackage(
// Source directory to use for the build.
// +defaultPath="/"
src *dagger.Directory,
// Version to use for the package.
ecVersion string,
// Architectures to build for.
// +default="amd64,arm64"
arch string,
) *dagger.Directory {

melangeFile := m.melangeTemplateLocalArtifactMirror(src, ecVersion)

dir := dag.Directory().
WithDirectory("local-artifact-mirror", src.Directory("local-artifact-mirror")).
WithDirectory("cmd", src.Directory("cmd"))

build := m.melangeBuildGo(
directoryWithCommonGoFiles(dir, src),
melangeFile,
arch,
MelangeImageVersion,
)

return build.Directory("build")
}

func (m *EmbeddedCluster) apkoTemplateLocalArtifactMirror(
src *dagger.Directory,
ecVersion string,
) *dagger.File {
return m.renderTemplate(
src.Directory("local-artifact-mirror/deploy"),
map[string]string{
"PACKAGE_VERSION": ecVersion,
},
"apko.tmpl.yaml",
"apko.yaml",
)
}

func (m *EmbeddedCluster) melangeTemplateLocalArtifactMirror(
src *dagger.Directory,
ecVersion string,
) *dagger.File {
return m.renderTemplate(
src.Directory("local-artifact-mirror/deploy"),
map[string]string{
"PACKAGE_VERSION": ecVersion,
},
"melange.tmpl.yaml",
"melange.yaml",
)
}
Loading

0 comments on commit 1bb52ef

Please sign in to comment.