mirror of
https://github.com/grafana/grafana.git
synced 2025-08-01 01:41:50 +08:00
142 lines
4.4 KiB
Go
142 lines
4.4 KiB
Go
package pipelines
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log"
|
|
"strings"
|
|
|
|
"dagger.io/dagger"
|
|
"github.com/grafana/grafana/pkg/build/daggerbuild/containers"
|
|
"github.com/grafana/grafana/pkg/build/daggerbuild/docker"
|
|
"golang.org/x/sync/errgroup"
|
|
"golang.org/x/sync/semaphore"
|
|
)
|
|
|
|
func ImageManifest(tag string) string {
|
|
log.Println(tag)
|
|
log.Println(tag)
|
|
log.Println(tag)
|
|
log.Println(tag)
|
|
manifest := strings.ReplaceAll(tag, "-image-tags", "")
|
|
lastDash := strings.LastIndex(manifest, "-")
|
|
return manifest[:lastDash]
|
|
}
|
|
|
|
func LatestManifest(tag string) string {
|
|
suffix := ""
|
|
if strings.Contains(tag, "ubuntu") {
|
|
suffix = "-ubuntu"
|
|
}
|
|
|
|
manifest := strings.ReplaceAll(tag, "-image-tags", "")
|
|
manifestImage := strings.Split(manifest, ":")[0]
|
|
return strings.Join([]string{manifestImage, fmt.Sprintf("latest%s", suffix)}, ":")
|
|
}
|
|
|
|
// PublishDocker is a pipeline that uses a grafana.docker.tar.gz as input and publishes a Docker image to a container registry or repository.
|
|
// Grafana's Dockerfile should support supplying a tar.gz using a --build-arg.
|
|
func PublishDocker(ctx context.Context, d *dagger.Client, args PipelineArgs) error {
|
|
opts := args.DockerOpts
|
|
packages, err := containers.GetPackages(ctx, d, args.PackageInputOpts, args.GCPOpts)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var (
|
|
wg = &errgroup.Group{}
|
|
sm = semaphore.NewWeighted(args.ConcurrencyOpts.Parallel)
|
|
)
|
|
|
|
manifestTags := make(map[string][]string)
|
|
for i, name := range args.PackageInputOpts.Packages {
|
|
// For each package we retrieve the tags grafana-image-tags and grafana-oss-image-tags, or grafana-enterprise-image-tags
|
|
format := opts.TagFormat
|
|
if strings.Contains(name, "ubuntu") {
|
|
format = opts.UbuntuTagFormat
|
|
}
|
|
|
|
tarOpts := TarOptsFromFileName(name)
|
|
|
|
tags, err := docker.Tags(opts.Org, opts.Registry, []string{opts.Repository}, format, tarOpts.NameOpts())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
log.Println(tags)
|
|
for _, tag := range tags {
|
|
// For each tag we publish an image and add the tag to the list of tags for a specific manifest
|
|
// Since each package has a maximum of 2 tags, this for loop will only run twice on a worst case scenario
|
|
manifest := ImageManifest(tag)
|
|
manifestTags[manifest] = append(manifestTags[manifest], tag)
|
|
|
|
if opts.Latest {
|
|
manifest := LatestManifest(tag)
|
|
manifestTags[manifest] = append(manifestTags[manifest], tag)
|
|
}
|
|
|
|
wg.Go(PublishPackageImageFunc(ctx, sm, d, packages[i], tag, opts))
|
|
}
|
|
}
|
|
|
|
if err := wg.Wait(); err != nil {
|
|
// Wait for all images to be published
|
|
return err
|
|
}
|
|
|
|
for manifest, tags := range manifestTags {
|
|
// Publish each manifest
|
|
wg.Go(PublishDockerManifestFunc(ctx, sm, d, manifest, tags, opts))
|
|
}
|
|
|
|
return wg.Wait()
|
|
}
|
|
|
|
func PublishPackageImageFunc(ctx context.Context, sm *semaphore.Weighted, d *dagger.Client, pkg *dagger.File, tag string, opts *docker.DockerOpts) func() error {
|
|
return func() error {
|
|
log.Printf("[%s] Attempting to publish image", tag)
|
|
log.Printf("[%s] Acquiring semaphore", tag)
|
|
if err := sm.Acquire(ctx, 1); err != nil {
|
|
return fmt.Errorf("failed to acquire semaphore: %w", err)
|
|
}
|
|
defer sm.Release(1)
|
|
log.Printf("[%s] Acquired semaphore", tag)
|
|
|
|
log.Printf("[%s] Publishing image", tag)
|
|
out, err := docker.PublishPackageImage(ctx, d, pkg, tag, opts.Username, opts.Password, opts.Registry)
|
|
if err != nil {
|
|
return fmt.Errorf("[%s] error: %w", tag, err)
|
|
}
|
|
log.Printf("[%s] Done publishing image", tag)
|
|
|
|
if _, err := fmt.Fprintln(Stdout, out); err != nil {
|
|
return fmt.Errorf("error writing to stdout: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func PublishDockerManifestFunc(ctx context.Context, sm *semaphore.Weighted, d *dagger.Client, manifest string, tags []string, opts *docker.DockerOpts) func() error {
|
|
return func() error {
|
|
log.Printf("[%s] Attempting to publish manifest", manifest)
|
|
log.Printf("[%s] Acquiring semaphore", manifest)
|
|
if err := sm.Acquire(ctx, 1); err != nil {
|
|
return fmt.Errorf("failed to acquire semaphore: %w", err)
|
|
}
|
|
defer sm.Release(1)
|
|
log.Printf("[%s] Acquired semaphore", manifest)
|
|
|
|
log.Printf("[%s] Publishing manifest", manifest)
|
|
out, err := docker.PublishManifest(ctx, d, manifest, tags, opts.Username, opts.Password, opts.Registry)
|
|
if err != nil {
|
|
return fmt.Errorf("[%s] error: %w", manifest, err)
|
|
}
|
|
log.Printf("[%s] Done publishing manifest", manifest)
|
|
|
|
if _, err := fmt.Fprintln(Stdout, out); err != nil {
|
|
return fmt.Errorf("error writing to stdout: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
}
|