From 0bd4a502a8ff924c0be60b47a3ae85684f086b13 Mon Sep 17 00:00:00 2001 From: Vadim Bauer Date: Fri, 15 Nov 2024 09:58:10 -0700 Subject: [PATCH 1/6] init version of daggerization of harbor. --- .dagger/.gitattributes | 4 + .dagger/.gitignore | 4 + .dagger/go.mod | 50 +++++++++++++ .dagger/go.sum | 83 +++++++++++++++++++++ .dagger/main.go | 164 +++++++++++++++++++++++++++++++++++++++++ .gitignore | 2 + .golangci.yaml | 17 +++++ dagger.json | 6 ++ 8 files changed, 330 insertions(+) create mode 100644 .dagger/.gitattributes create mode 100644 .dagger/.gitignore create mode 100644 .dagger/go.mod create mode 100644 .dagger/go.sum create mode 100644 .dagger/main.go create mode 100644 .golangci.yaml create mode 100644 dagger.json diff --git a/.dagger/.gitattributes b/.dagger/.gitattributes new file mode 100644 index 00000000000..3a454933cbe --- /dev/null +++ b/.dagger/.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/.dagger/.gitignore b/.dagger/.gitignore new file mode 100644 index 00000000000..7ebabcc1426 --- /dev/null +++ b/.dagger/.gitignore @@ -0,0 +1,4 @@ +/dagger.gen.go +/internal/dagger +/internal/querybuilder +/internal/telemetry diff --git a/.dagger/go.mod b/.dagger/go.mod new file mode 100644 index 00000000000..5500608f28d --- /dev/null +++ b/.dagger/go.mod @@ -0,0 +1,50 @@ +module dagger/harbor + +go 1.23.2 + +require ( + github.com/99designs/gqlgen v0.17.55 + github.com/Khan/genqlient v0.7.0 + github.com/vektah/gqlparser/v2 v2.5.17 + go.opentelemetry.io/otel v1.27.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/otlpmetric/otlpmetricgrpc v1.27.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.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/metric v1.27.0 + go.opentelemetry.io/otel/sdk v1.27.0 + go.opentelemetry.io/otel/sdk/log v0.3.0 + go.opentelemetry.io/otel/sdk/metric v1.27.0 + go.opentelemetry.io/otel/trace v1.27.0 + go.opentelemetry.io/proto/otlp v1.3.1 + golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa + golang.org/x/sync v0.8.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.22.0 // indirect + github.com/sosodev/duration v1.3.1 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect + golang.org/x/net v0.29.0 // indirect + golang.org/x/sys v0.26.0 // indirect + golang.org/x/text v0.18.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect + google.golang.org/protobuf v1.34.2 // indirect +) + +replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 + +replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 + +replace go.opentelemetry.io/otel/log => go.opentelemetry.io/otel/log v0.3.0 + +replace go.opentelemetry.io/otel/sdk/log => go.opentelemetry.io/otel/sdk/log v0.3.0 diff --git a/.dagger/go.sum b/.dagger/go.sum new file mode 100644 index 00000000000..c52dd24bd0b --- /dev/null +++ b/.dagger/go.sum @@ -0,0 +1,83 @@ +github.com/99designs/gqlgen v0.17.55 h1:3vzrNWYyzSZjGDFo68e5j9sSauLxfKvLp+6ioRokVtM= +github.com/99designs/gqlgen v0.17.55/go.mod h1:3Bq768f8hgVPGZxL8aY9MaYmbxa6llPM/qu1IGH1EJo= +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.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.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= +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.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +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/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.17 h1:9At7WblLV7/36nulgekUgIaqHZWn5hxqluxrxGUhOmI= +github.com/vektah/gqlparser/v2 v2.5.17/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/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/otlpmetric/otlpmetricgrpc v1.27.0 h1:bFgvUr3/O4PHj3VQcFEuYKvRZJX1SJDQ+11JXuSB3/w= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0/go.mod h1:xJntEd2KL6Qdg5lwp97HMLQDVeAhrYxmzFseAMDPQ8I= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 h1:CIHWikMsN3wO+wq1Tp5VGdVRTcON+DmOJSfDjXypKOc= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0/go.mod h1:TNupZ6cxqyFEpLXAZW7On+mLFL0/g0TE3unIYL91xWc= +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/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/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/sdk/metric v1.27.0 h1:5uGNOlpXi+Hbo/DRoI31BSb1v+OGcpv2NemcCrOL8gI= +go.opentelemetry.io/otel/sdk/metric v1.27.0/go.mod h1:we7jJVrYN2kh3mVBlswtPU22K0SA+769l93J6bsyvqw= +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/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/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= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= +google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +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/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/.dagger/main.go b/.dagger/main.go new file mode 100644 index 00000000000..bbe10557dba --- /dev/null +++ b/.dagger/main.go @@ -0,0 +1,164 @@ +package main + +import ( + "context" + "dagger/harbor/internal/dagger" + "fmt" + "log" + "strings" +) + +const ( + GOLANGCILINT_VERSION = "v1.61.0" + GO_VERSION = "latest" + SYFT_VERSION = "v1.9.0" + GORELEASER_VERSION = "v2.3.2" +) + +var ( + SupportedPlatforms = []string{"linux/arm64", "linux/amd64"} + packages = []string{"core", "jobservice", "registryctl", "cmd/exporter", "cmd/standalone-db-migrator"} + //packages = []string{"core", "jobservice"} +) + +type BuildMetadata struct { + Package string + BinaryPath string + Container *dagger.Container + Platform string +} + +func New( + // Local or remote directory with source code, defaults to "./" + // +optional + // +defaultPath="./" + source *dagger.Directory, +) *Harbor { + return &Harbor{Source: source} +} + +type Harbor struct { + Source *dagger.Directory +} + +func (m *Harbor) BuildAllImages(ctx context.Context) []*dagger.Container { + var buildImages []*dagger.Container + for _, platform := range SupportedPlatforms { + for _, pkg := range packages { + image := m.BuildImage(ctx, platform, pkg) + buildImages = append(buildImages, image) + } + // build portal + } + return buildImages +} + +func (m *Harbor) buildAllImages(ctx context.Context) []*BuildMetadata { + var buildMetadata []*BuildMetadata + for _, platform := range SupportedPlatforms { + for _, pkg := range packages { + image := m.buildImage(ctx, platform, pkg) + buildImages = append(buildImages, image) + } + // build portal + } + return buildImages +} + +func (m *Harbor) BuildImage(ctx context.Context, platform string, pkg string) *dagger.Container { + bc := m.buildBinary(ctx, platform, pkg) + img := dag.Container(dagger.ContainerOpts{Platform: dagger.Platform(platform)}). + WithFile("/"+pkg, bc.Container.File(bc.BinaryPath)). + WithEntrypoint([]string{"/" + pkg}) + return img +} + +func (m *Harbor) BuildAllBinaries(ctx context.Context) *dagger.Directory { + output := dag.Directory() + builds := m.buildAllBinaries(ctx) + for _, build := range builds { + output = output.WithFile(build.BinaryPath, build.Container.File(build.BinaryPath)) + } + return output + +} + +func (m *Harbor) buildAllBinaries(ctx context.Context) []*BuildMetadata { + var buildContainers []*BuildMetadata + for _, platform := range SupportedPlatforms { + for _, pkg := range packages { + buildContainer := m.buildBinary(ctx, platform, pkg) + buildContainers = append(buildContainers, buildContainer) + } + // build portal + } + return buildContainers +} + +func (m *Harbor) BuildBinary(ctx context.Context, platform string, pkg string) *dagger.File { + build := m.buildBinary(ctx, platform, pkg) + return build.Container.File(build.BinaryPath) +} + +func (m *Harbor) buildBinary(ctx context.Context, platform string, pkg string) *BuildMetadata { + + os, arch, err := parsePlatform(platform) + if err != nil { + log.Fatalf("Error parsing platform: %v", err) + } + + outputPath := fmt.Sprintf("bin/%s/%s", platform, pkg) + src := fmt.Sprintf("%s/main.go", pkg) + builder := dag.Container(). + From("golang:latest"). + WithMountedCache("/go/pkg/mod", dag.CacheVolume("go-mod-"+GO_VERSION)). + WithEnvVariable("GOMODCACHE", "/go/pkg/mod"). + WithMountedCache("/go/build-cache", dag.CacheVolume("go-build-"+GO_VERSION)). + WithEnvVariable("GOCACHE", "/go/build-cache"). + WithMountedDirectory("/harbor", m.Source). // Ensure the source directory with go.mod is mounted + WithWorkdir("/harbor/src/"). + WithEnvVariable("GOOS", os). + WithEnvVariable("GOARCH", arch). + WithEnvVariable("CGO_ENABLED", "0"). + WithExec([]string{"go", "build", "-o", outputPath, "-ldflags", "-extldflags=-static -s -w", src}) + + return &BuildMetadata{ + Package: pkg, + BinaryPath: outputPath, + Container: builder, + Platform: platform, + } +} + +func (m *Harbor) buildPortal(ctx context.Context, platform string, pkg string) *dagger.Directory { + fmt.Println("🛠️ Building Harbor Core...") + // Define the path for the binary output + os, arch, err := parsePlatform(platform) + + if err != nil { + log.Fatalf("Error parsing platform: %v", err) + } + + outputPath := fmt.Sprintf("bin/%s/%s", platform, pkg) + src := fmt.Sprintf("src/%s/main.go", pkg) + builder := dag.Container(). + From("golang:latest"). + WithMountedCache("/go/pkg/mod", dag.CacheVolume("go-mod-"+GO_VERSION)). + WithEnvVariable("GOMODCACHE", "/go/pkg/mod"). + WithMountedCache("/go/build-cache", dag.CacheVolume("go-build-"+GO_VERSION)). + WithEnvVariable("GOCACHE", "/go/build-cache"). + WithMountedDirectory("/harbor", m.Source). // Ensure the source directory with go.mod is mounted + WithWorkdir("/harbor"). + WithEnvVariable("GOOS", os). + WithEnvVariable("GOARCH", arch). + WithExec([]string{"go", "build", "-o", outputPath, src}) + return builder.Directory(outputPath) +} + +func parsePlatform(platform string) (string, string, error) { + parts := strings.Split(platform, "/") + if len(parts) != 2 { + return "", "", fmt.Errorf("invalid platform format: %s. Should be os/arch. E.g. darwin/amd64", platform) + } + return parts[0], parts[1], nil +} diff --git a/.gitignore b/.gitignore index f2b08ad4aa9..3624ca1c6b8 100644 --- a/.gitignore +++ b/.gitignore @@ -58,3 +58,5 @@ src/server/v2.0/restapi/ harborclient/ openapi-generator-cli.jar + +bin/ diff --git a/.golangci.yaml b/.golangci.yaml new file mode 100644 index 00000000000..c35d551a9e3 --- /dev/null +++ b/.golangci.yaml @@ -0,0 +1,17 @@ +run: + timeout: 3m +linters: + enable: + # Default linters are already enabled, these are the additional ones + - typecheck + - gofmt + - gosec + - nilnil + # - wrapcheck + # - gocritic + # - revive #, enable once current issues are resolved +issues: + exclude-dirs: + - .dagger/internal + exclude-files: + - ^.*\\.gen\\.go$ diff --git a/dagger.json b/dagger.json new file mode 100644 index 00000000000..4afd4263526 --- /dev/null +++ b/dagger.json @@ -0,0 +1,6 @@ +{ + "name": "harbor", + "sdk": "go", + "source": ".dagger", + "engineVersion": "v0.13.6" +} From 2d56ca2e183bc8c3c47965e02fdc8a586a439b0a Mon Sep 17 00:00:00 2001 From: Vadim Bauer Date: Thu, 21 Nov 2024 08:44:57 +0100 Subject: [PATCH 2/6] impl. build all containers --- .dagger/main.go | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/.dagger/main.go b/.dagger/main.go index bbe10557dba..15964498c58 100644 --- a/.dagger/main.go +++ b/.dagger/main.go @@ -42,35 +42,42 @@ type Harbor struct { } func (m *Harbor) BuildAllImages(ctx context.Context) []*dagger.Container { - var buildImages []*dagger.Container - for _, platform := range SupportedPlatforms { - for _, pkg := range packages { - image := m.BuildImage(ctx, platform, pkg) - buildImages = append(buildImages, image) - } - // build portal + metdata := m.buildAllImages(ctx) + images := make([]*dagger.Container, len(metdata)) + for i, meta := range metdata { + images[i] = meta.Container } - return buildImages + return images } func (m *Harbor) buildAllImages(ctx context.Context) []*BuildMetadata { var buildMetadata []*BuildMetadata for _, platform := range SupportedPlatforms { for _, pkg := range packages { - image := m.buildImage(ctx, platform, pkg) - buildImages = append(buildImages, image) + img := m.BuildImage(ctx, platform, pkg) + buildMetadata = append(buildMetadata, &BuildMetadata{ + Package: pkg, + BinaryPath: fmt.Sprintf("bin/%s/%s", platform, pkg), + Container: img, + Platform: platform, + }) } // build portal } - return buildImages + return buildMetadata } func (m *Harbor) BuildImage(ctx context.Context, platform string, pkg string) *dagger.Container { - bc := m.buildBinary(ctx, platform, pkg) + return m.buildImage(ctx, platform, pkg).Container +} + +func (m *Harbor) buildImage(ctx context.Context, platform string, pkg string) *BuildMetadata { + build := m.buildBinary(ctx, platform, pkg) img := dag.Container(dagger.ContainerOpts{Platform: dagger.Platform(platform)}). - WithFile("/"+pkg, bc.Container.File(bc.BinaryPath)). + WithFile("/"+pkg, build.Container.File(build.BinaryPath)). WithEntrypoint([]string{"/" + pkg}) - return img + build.Container = img + return build } func (m *Harbor) BuildAllBinaries(ctx context.Context) *dagger.Directory { From e11e143396273368c116e8aa10c328c285b20add Mon Sep 17 00:00:00 2001 From: Vadim Bauer Date: Fri, 22 Nov 2024 17:33:24 +0100 Subject: [PATCH 3/6] export all images --- .dagger/main.go | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/.dagger/main.go b/.dagger/main.go index 15964498c58..4a9ad6a56a0 100644 --- a/.dagger/main.go +++ b/.dagger/main.go @@ -29,9 +29,9 @@ type BuildMetadata struct { } func New( - // Local or remote directory with source code, defaults to "./" - // +optional - // +defaultPath="./" +// Local or remote directory with source code, defaults to "./" +// +optional +// +defaultPath="./" source *dagger.Directory, ) *Harbor { return &Harbor{Source: source} @@ -41,6 +41,19 @@ type Harbor struct { Source *dagger.Directory } +func (m *Harbor) ExportAllImages(ctx context.Context) (string, error) { + metdata := m.buildAllImages(ctx) + for _, meta := range metdata { + export, err := meta.Container.Export(ctx, fmt.Sprintf("bin/container/%s/%s.tgz", meta.Platform, meta.Package)) + export, err := meta.Container.AsTarball(ctx, fmt.Sprintf("bin/container/%s/%s.tgz", meta.Platform, meta.Package)) + println(export) + if err != nil { + return "", err + } + } + return "bin/container", nil +} + func (m *Harbor) BuildAllImages(ctx context.Context) []*dagger.Container { metdata := m.buildAllImages(ctx) images := make([]*dagger.Container, len(metdata)) From ca8d7f1a4de28c9dd0dea481ad56b3613f058075 Mon Sep 17 00:00:00 2001 From: Vadim Bauer Date: Sat, 30 Nov 2024 13:20:56 +0100 Subject: [PATCH 4/6] push all images to registry. verified harbor core image is working as expected --- .dagger/main.go | 150 +++++++++++++++++++++++++++++++++++------------ dagger.json | 4 +- src/core/main.go | 1 + src/go.mod | 11 ++-- src/go.sum | 7 +-- 5 files changed, 125 insertions(+), 48 deletions(-) diff --git a/.dagger/main.go b/.dagger/main.go index 4a9ad6a56a0..b373d2e8d75 100644 --- a/.dagger/main.go +++ b/.dagger/main.go @@ -15,23 +15,25 @@ const ( GORELEASER_VERSION = "v2.3.2" ) +type Package string +type Platform string + var ( - SupportedPlatforms = []string{"linux/arm64", "linux/amd64"} - packages = []string{"core", "jobservice", "registryctl", "cmd/exporter", "cmd/standalone-db-migrator"} + targetPlatforms = []Platform{"linux/arm64", "linux/amd64"} + packages = []Package{"core", "jobservice", "registryctl", "cmd/exporter", "cmd/standalone-db-migrator"} //packages = []string{"core", "jobservice"} ) type BuildMetadata struct { - Package string + Package Package BinaryPath string Container *dagger.Container - Platform string + Platform Platform } func New( -// Local or remote directory with source code, defaults to "./" -// +optional -// +defaultPath="./" + // +optional + // +defaultPath="./" source *dagger.Directory, ) *Harbor { return &Harbor{Source: source} @@ -41,17 +43,90 @@ type Harbor struct { Source *dagger.Directory } -func (m *Harbor) ExportAllImages(ctx context.Context) (string, error) { - metdata := m.buildAllImages(ctx) - for _, meta := range metdata { - export, err := meta.Container.Export(ctx, fmt.Sprintf("bin/container/%s/%s.tgz", meta.Platform, meta.Package)) - export, err := meta.Container.AsTarball(ctx, fmt.Sprintf("bin/container/%s/%s.tgz", meta.Platform, meta.Package)) - println(export) +func (m *Harbor) PublishImageAllImages( + ctx context.Context, + registry, registryUsername string, + imageTags []string, + registryPassword *dagger.Secret) string { + + allImages := m.buildAllImages(ctx) + + for i, tag := range imageTags { + imageTags[i] = strings.TrimSpace(tag) + if strings.HasPrefix(imageTags[i], "v") { + imageTags[i] = strings.TrimPrefix(imageTags[i], "v") + } + } + fmt.Printf("provided tags: %s\n", imageTags) + + platformVariantsContainer := make(map[Package][]*dagger.Container) + for _, meta := range allImages { + platformVariantsContainer[meta.Package] = append(platformVariantsContainer[meta.Package], meta.Container) + } + + for pkg, imgs := range platformVariantsContainer { + for _, imageTag := range imageTags { + _, err := dag.Container().WithRegistryAuth(registry, registryUsername, registryPassword).Publish(ctx, + fmt.Sprintf("%s/%s/%s:%s", registry, "harbor", pkg, imageTag), + dagger.ContainerPublishOpts{PlatformVariants: imgs}, + ) + if err != nil { + panic(err) + } + } + } + return "allImageAddrs" +} + +func (m *Harbor) PublishImage( + ctx context.Context, + registry, registryUsername string, + imageTags []string, + registryPassword *dagger.Secret) []string { + + releaseImages := []*dagger.Container{} + + for i, tag := range imageTags { + imageTags[i] = strings.TrimSpace(tag) + if strings.HasPrefix(imageTags[i], "v") { + imageTags[i] = strings.TrimPrefix(imageTags[i], "v") + } + } + fmt.Printf("provided tags: %s\n", imageTags) + + for _, platform := range targetPlatforms { + for _, pkg := range packages { + build := m.buildImage(ctx, platform, pkg) + if strings.HasPrefix(string(platform), "linux") { + releaseImages = append(releaseImages, build.Container) + } + } + } + + imageAddrs := []string{} + for _, imageTag := range imageTags { + addr, err := dag.Container().WithRegistryAuth(registry, registryUsername, registryPassword). + Publish(ctx, + fmt.Sprintf("%s/%s/harbor-cli:%s", registry, "harbor-cli", imageTag), + dagger.ContainerPublishOpts{PlatformVariants: releaseImages}, + ) + if err != nil { - return "", err + panic(err) } + fmt.Printf("Published image address: %s\n", addr) + imageAddrs = append(imageAddrs, addr) + } + return imageAddrs +} + +func (m *Harbor) ExportAllImages(ctx context.Context) *dagger.Directory { + metdata := m.buildAllImages(ctx) + artifacts := dag.Directory() + for _, meta := range metdata { + artifacts = artifacts.WithFile(fmt.Sprintf("containers/%s/%s.tgz", meta.Platform, meta.Package), meta.Container.AsTarball()) } - return "bin/container", nil + return artifacts } func (m *Harbor) BuildAllImages(ctx context.Context) []*dagger.Container { @@ -65,7 +140,7 @@ func (m *Harbor) BuildAllImages(ctx context.Context) []*dagger.Container { func (m *Harbor) buildAllImages(ctx context.Context) []*BuildMetadata { var buildMetadata []*BuildMetadata - for _, platform := range SupportedPlatforms { + for _, platform := range targetPlatforms { for _, pkg := range packages { img := m.BuildImage(ctx, platform, pkg) buildMetadata = append(buildMetadata, &BuildMetadata{ @@ -75,22 +150,26 @@ func (m *Harbor) buildAllImages(ctx context.Context) []*BuildMetadata { Platform: platform, }) } - // build portal } return buildMetadata } -func (m *Harbor) BuildImage(ctx context.Context, platform string, pkg string) *dagger.Container { - return m.buildImage(ctx, platform, pkg).Container +func (m *Harbor) BuildImage(ctx context.Context, platform Platform, pkg Package) *dagger.Container { + buildMtd := m.buildImage(ctx, platform, pkg) + if pkg == "core" { + buildMtd.Container = buildMtd.Container.WithDirectory("/migrations", m.Source.Directory("make/migrations")) + } + return buildMtd.Container + } -func (m *Harbor) buildImage(ctx context.Context, platform string, pkg string) *BuildMetadata { - build := m.buildBinary(ctx, platform, pkg) - img := dag.Container(dagger.ContainerOpts{Platform: dagger.Platform(platform)}). - WithFile("/"+pkg, build.Container.File(build.BinaryPath)). - WithEntrypoint([]string{"/" + pkg}) - build.Container = img - return build +func (m *Harbor) buildImage(ctx context.Context, platform Platform, pkg Package) *BuildMetadata { + buildMtd := m.buildBinary(ctx, platform, pkg) + img := dag.Container(dagger.ContainerOpts{Platform: dagger.Platform(string(platform))}). + WithFile("/"+string(pkg), buildMtd.Container.File(buildMtd.BinaryPath)). + WithEntrypoint([]string{"/" + string(pkg)}) + buildMtd.Container = img + return buildMtd } func (m *Harbor) BuildAllBinaries(ctx context.Context) *dagger.Directory { @@ -100,29 +179,27 @@ func (m *Harbor) BuildAllBinaries(ctx context.Context) *dagger.Directory { output = output.WithFile(build.BinaryPath, build.Container.File(build.BinaryPath)) } return output - } func (m *Harbor) buildAllBinaries(ctx context.Context) []*BuildMetadata { var buildContainers []*BuildMetadata - for _, platform := range SupportedPlatforms { + for _, platform := range targetPlatforms { for _, pkg := range packages { buildContainer := m.buildBinary(ctx, platform, pkg) buildContainers = append(buildContainers, buildContainer) } - // build portal } return buildContainers } -func (m *Harbor) BuildBinary(ctx context.Context, platform string, pkg string) *dagger.File { +func (m *Harbor) BuildBinary(ctx context.Context, platform Platform, pkg Package) *dagger.File { build := m.buildBinary(ctx, platform, pkg) return build.Container.File(build.BinaryPath) } -func (m *Harbor) buildBinary(ctx context.Context, platform string, pkg string) *BuildMetadata { +func (m *Harbor) buildBinary(ctx context.Context, platform Platform, pkg Package) *BuildMetadata { - os, arch, err := parsePlatform(platform) + os, arch, err := parsePlatform(string(platform)) if err != nil { log.Fatalf("Error parsing platform: %v", err) } @@ -135,7 +212,7 @@ func (m *Harbor) buildBinary(ctx context.Context, platform string, pkg string) * WithEnvVariable("GOMODCACHE", "/go/pkg/mod"). WithMountedCache("/go/build-cache", dag.CacheVolume("go-build-"+GO_VERSION)). WithEnvVariable("GOCACHE", "/go/build-cache"). - WithMountedDirectory("/harbor", m.Source). // Ensure the source directory with go.mod is mounted + WithMountedDirectory("/harbor", m.Source). WithWorkdir("/harbor/src/"). WithEnvVariable("GOOS", os). WithEnvVariable("GOARCH", arch). @@ -150,10 +227,9 @@ func (m *Harbor) buildBinary(ctx context.Context, platform string, pkg string) * } } -func (m *Harbor) buildPortal(ctx context.Context, platform string, pkg string) *dagger.Directory { +func (m *Harbor) buildPortal(ctx context.Context, platform Platform, pkg Package) *dagger.Directory { fmt.Println("🛠️ Building Harbor Core...") - // Define the path for the binary output - os, arch, err := parsePlatform(platform) + os, arch, err := parsePlatform(string(platform)) if err != nil { log.Fatalf("Error parsing platform: %v", err) @@ -167,7 +243,7 @@ func (m *Harbor) buildPortal(ctx context.Context, platform string, pkg string) * WithEnvVariable("GOMODCACHE", "/go/pkg/mod"). WithMountedCache("/go/build-cache", dag.CacheVolume("go-build-"+GO_VERSION)). WithEnvVariable("GOCACHE", "/go/build-cache"). - WithMountedDirectory("/harbor", m.Source). // Ensure the source directory with go.mod is mounted + WithMountedDirectory("/harbor", m.Source). WithWorkdir("/harbor"). WithEnvVariable("GOOS", os). WithEnvVariable("GOARCH", arch). diff --git a/dagger.json b/dagger.json index 4afd4263526..6c1a89943e5 100644 --- a/dagger.json +++ b/dagger.json @@ -1,6 +1,6 @@ { "name": "harbor", + "engineVersion": "v0.14.0", "sdk": "go", - "source": ".dagger", - "engineVersion": "v0.13.6" + "source": ".dagger" } diff --git a/src/core/main.go b/src/core/main.go index f0bc9656452..6e614446c26 100644 --- a/src/core/main.go +++ b/src/core/main.go @@ -75,6 +75,7 @@ import ( pkguser "github.com/goharbor/harbor/src/pkg/user" "github.com/goharbor/harbor/src/pkg/version" "github.com/goharbor/harbor/src/server" + _ "golang.org/x/crypto/x509roots/fallback" ) const ( diff --git a/src/go.mod b/src/go.mod index 0d720e2872a..b36cff139a8 100644 --- a/src/go.mod +++ b/src/go.mod @@ -21,12 +21,12 @@ require ( github.com/go-asn1-ber/asn1-ber v1.5.7 github.com/go-ldap/ldap/v3 v3.4.6 github.com/go-openapi/errors v0.22.0 - github.com/go-openapi/loads v0.22.0 // indirect + github.com/go-openapi/loads v0.22.0 github.com/go-openapi/runtime v0.28.0 - github.com/go-openapi/spec v0.21.0 // indirect + github.com/go-openapi/spec v0.21.0 github.com/go-openapi/strfmt v0.23.0 github.com/go-openapi/swag v0.23.0 - github.com/go-openapi/validate v0.24.0 // indirect + github.com/go-openapi/validate v0.24.0 github.com/go-redis/redis/v8 v8.11.4 github.com/gocarina/gocsv v0.0.0-20210516172204-ca9e8a8ddea8 github.com/gocraft/work v0.5.1 @@ -78,7 +78,10 @@ require ( sigs.k8s.io/yaml v1.4.0 ) -require github.com/prometheus/client_model v0.6.1 +require ( + github.com/prometheus/client_model v0.6.1 + golang.org/x/crypto/x509roots/fallback v0.0.0-20241127184453-8c4e668694cc +) require ( cloud.google.com/go/compute/metadata v0.3.0 // indirect diff --git a/src/go.sum b/src/go.sum index 7c8df2472a6..bcd19178103 100644 --- a/src/go.sum +++ b/src/go.sum @@ -53,17 +53,13 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= -github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190726115642-cd293c93fd97 h1:bNE5ID4C3YOkROfvBjXJUG53gyb+8az3TQN02LqnGBk= -github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190726115642-cd293c93fd97/go.mod h1:myCDvQSzCW+wB1WAlocEru4wMGJxy+vlxHdhegi1CDQ= github.com/aliyun/alibaba-cloud-sdk-go v1.61.1193 h1:C5LuIDWuQlugv30EBsSLKFF6jdtrqoVH84nYCdVYTC4= github.com/aliyun/alibaba-cloud-sdk-go v1.61.1193/go.mod h1:pUKYbK5JQ+1Dfxk80P0qxGqe5dkxDoabbZS7zOcouyA= -github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= -github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc= github.com/beego/beego/v2 v2.2.1 h1:5RatpEOKnw6sm76hj6lQvEFi4Tco+E21VQomnVB7NsA= github.com/beego/beego/v2 v2.2.1/go.mod h1:X4hHhM2AXn0hN2tbyz5X/PD7v5JUdE4IihZApiljpNA= github.com/beego/i18n v0.0.0-20140604031826-e87155e8f0c0 h1:fQaDnUQvBXHHQdGBu9hz8nPznB4BeiPQokvmQVjmNEw= @@ -605,6 +601,8 @@ golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/crypto/x509roots/fallback v0.0.0-20241127184453-8c4e668694cc h1:N2DXFnxni8U4KZ7CcK6kicRat3uowReUjOJxwYTxQv8= +golang.org/x/crypto/x509roots/fallback v0.0.0-20241127184453-8c4e668694cc/go.mod h1:kNa9WdvYnzFwC79zRpLRMJbdEFlhyM5RPFBBZp/wWH8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= @@ -711,7 +709,6 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= From 48612c78e535f4956c6ed8162f2f752db1fd6708 Mon Sep 17 00:00:00 2001 From: Vadim Bauer Date: Sat, 7 Dec 2024 14:04:12 +0100 Subject: [PATCH 5/6] sign image and push and sign all images. --- .dagger/main.go | 86 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 81 insertions(+), 5 deletions(-) diff --git a/.dagger/main.go b/.dagger/main.go index b373d2e8d75..e9d2e0f7e5e 100644 --- a/.dagger/main.go +++ b/.dagger/main.go @@ -43,11 +43,81 @@ type Harbor struct { Source *dagger.Directory } -func (m *Harbor) PublishImageAllImages( +func (m *Harbor) PublishAndSignAllImages( + ctx context.Context, + registry string, + registryUsername string, + registryPassword *dagger.Secret, + imageTags []string, + // +optional + githubToken *dagger.Secret, + // +optional + actionsIdTokenRequestToken *dagger.Secret, + // +optional + actionsIdTokenRequestUrl string, +) (string, error) { + + imageAddrs := m.PublishAllImages(ctx, registry, registryUsername, imageTags, registryPassword) + _, err := m.Sign( + ctx, + githubToken, + actionsIdTokenRequestUrl, + actionsIdTokenRequestToken, + registryUsername, + registryPassword, + imageAddrs[0], + ) + if err != nil { + return "", fmt.Errorf("failed to sign image: %w", err) + } + + fmt.Printf("Signed image: %s\n", imageAddrs) + return imageAddrs[0], nil +} + +// Sign signs a container image using Cosign, works also with GitHub Actions +func (m *Harbor) Sign(ctx context.Context, + // +optional + githubToken *dagger.Secret, + // +optional + actionsIdTokenRequestUrl string, + // +optional + actionsIdTokenRequestToken *dagger.Secret, + registryUsername string, + registryPassword *dagger.Secret, + imageAddr string, +) (string, error) { + + registryPasswordPlain, _ := registryPassword.Plaintext(ctx) + + cosing_ctr := dag.Container().From("cgr.dev/chainguard/cosign") + + // If githubToken is provided, use it to sign the image. (GitHub Actions) use case + if githubToken != nil { + if actionsIdTokenRequestUrl == "" || actionsIdTokenRequestToken == nil { + return "", fmt.Errorf("actionsIdTokenRequestUrl (exist=%s) and actionsIdTokenRequestToken (exist=%t) must be provided when githubToken is provided", actionsIdTokenRequestUrl, actionsIdTokenRequestToken != nil) + } + fmt.Printf("Setting the ENV Vars GITHUB_TOKEN, ACTIONS_ID_TOKEN_REQUEST_URL, ACTIONS_ID_TOKEN_REQUEST_TOKEN to sign with GitHub Token") + cosing_ctr = cosing_ctr.WithSecretVariable("GITHUB_TOKEN", githubToken). + WithEnvVariable("ACTIONS_ID_TOKEN_REQUEST_URL", actionsIdTokenRequestUrl). + WithSecretVariable("ACTIONS_ID_TOKEN_REQUEST_TOKEN", actionsIdTokenRequestToken) + } + + return cosing_ctr.WithSecretVariable("REGISTRY_PASSWORD", registryPassword). + WithExec([]string{"cosign", "env"}). + WithExec([]string{"cosign", "sign", "--yes", "--recursive", + "--registry-username", registryUsername, + "--registry-password", registryPasswordPlain, + imageAddr, + "--timeout", "1m", + }).Stdout(ctx) +} + +func (m *Harbor) PublishAllImages( ctx context.Context, registry, registryUsername string, imageTags []string, - registryPassword *dagger.Secret) string { + registryPassword *dagger.Secret) []string { allImages := m.buildAllImages(ctx) @@ -64,18 +134,24 @@ func (m *Harbor) PublishImageAllImages( platformVariantsContainer[meta.Package] = append(platformVariantsContainer[meta.Package], meta.Container) } + var imageAddresses []string for pkg, imgs := range platformVariantsContainer { for _, imageTag := range imageTags { - _, err := dag.Container().WithRegistryAuth(registry, registryUsername, registryPassword).Publish(ctx, + container := dag.Container().WithRegistryAuth(registry, registryUsername, registryPassword) + imgAddress, err := container.Publish(ctx, fmt.Sprintf("%s/%s/%s:%s", registry, "harbor", pkg, imageTag), dagger.ContainerPublishOpts{PlatformVariants: imgs}, ) if err != nil { - panic(err) + fmt.Printf("Failed to publish image: %s/%s/%s:%s\n", registry, "harbor", pkg, imageTag) + fmt.Printf("Error: %s\n", err) + continue } + imageAddresses = append(imageAddresses, imgAddress) + fmt.Printf("Published image: %s\n", imgAddress) } } - return "allImageAddrs" + return imageAddresses } func (m *Harbor) PublishImage( From 9e5aa41ca74317fa4e9a109613e5941553a08f6c Mon Sep 17 00:00:00 2001 From: Vadim Bauer Date: Mon, 9 Dec 2024 16:08:20 +0100 Subject: [PATCH 6/6] lint reporter --- .dagger/main.go | 25 +++++++++++++++++++++++++ src/core/main.go | 3 ++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/.dagger/main.go b/.dagger/main.go index e9d2e0f7e5e..ff60af01372 100644 --- a/.dagger/main.go +++ b/.dagger/main.go @@ -43,6 +43,31 @@ type Harbor struct { Source *dagger.Directory } +// LintReport Executes the Linter and writes the linting results to a file golangci-linter-report.sarif +func (m *Harbor) LintReport(ctx context.Context) (string, error) { + report := "golangci-lint-report.sarif" + output, _ := m.Source.File(report).Name(ctx) + return m.linter(ctx).WithExec([]string{"golangci-lint", "run", + "--out-format", "sarif:" + report, + "--issues-exit-code", "0"}).File(report).Export(ctx, report) +} + +// Lint Run the linter golangci-linter +func (m *Harbor) Lint(ctx context.Context) (string, error) { + return m.linter(ctx).WithExec([]string{"golangci-lint", "run"}).Stderr(ctx) +} + +func (m *Harbor) linter(ctx context.Context) *dagger.Container { + fmt.Printf("👀 Running linter") + linter := dag.Container(). + From("golangci/golangci-lint:"+GOLANGCILINT_VERSION+"-alpine"). + WithMountedCache("/lint-cache", dag.CacheVolume("/lint-cache")). + WithEnvVariable("GOLANGCI_LINT_CACHE", "/lint-cache"). + WithMountedDirectory("/harbor", m.Source). + WithWorkdir("/harbor/src/") + return linter +} + func (m *Harbor) PublishAndSignAllImages( ctx context.Context, registry string, diff --git a/src/core/main.go b/src/core/main.go index 6e614446c26..3a5bbeb1d62 100644 --- a/src/core/main.go +++ b/src/core/main.go @@ -28,6 +28,8 @@ import ( "github.com/beego/beego/v2/server/web" + _ "golang.org/x/crypto/x509roots/fallback" + "github.com/goharbor/harbor/src/common/dao" common_http "github.com/goharbor/harbor/src/common/http" configCtl "github.com/goharbor/harbor/src/controller/config" @@ -75,7 +77,6 @@ import ( pkguser "github.com/goharbor/harbor/src/pkg/user" "github.com/goharbor/harbor/src/pkg/version" "github.com/goharbor/harbor/src/server" - _ "golang.org/x/crypto/x509roots/fallback" ) const (