ce7cb702218693d08ea6d83464d2457c9250027c

This commit is contained in:
ms2k 2026-11-12 20:46:28 +09:00
commit 34c5f8963c

View file

@ -0,0 +1,87 @@
package main
import (
"context"
"errors"
"fmt"
"log/slog"
"os"
"os/signal"
"syscall"
"time"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/rest"
)
func main() {
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
defer stop()
if err := run(ctx, os.Args[1:]); err != nil && !errors.Is(err, context.Canceled) {
slog.Error("image mirror", "error", err)
os.Exit(1)
}
}
func run(ctx context.Context, arguments []string) error {
if len(arguments) != 1 {
return errors.New("expected one command: run")
}
if arguments[0] != "run" {
return fmt.Errorf("unknown command %q", arguments[0])
}
clientConfig, err := rest.InClusterConfig()
if err != nil {
return fmt.Errorf("load Kubernetes configuration: %w", err)
}
client, err := dynamic.NewForConfig(clientConfig)
if err != nil {
return fmt.Errorf("create Kubernetes client: %w", err)
}
config, err := loadConfig()
if err != nil {
return err
}
registry, err := loadRegistry()
if err != nil {
return err
}
return (&controller{client: client, registry: registry, config: config}).run(ctx)
}
func loadConfig() (controllerConfig, error) {
namespace := os.Getenv("POD_NAMESPACE")
if namespace == "" {
return controllerConfig{}, errors.New("POD_NAMESPACE is required")
}
pollInterval, err := durationEnv("POLL_INTERVAL", 20*time.Second)
if err != nil {
return controllerConfig{}, err
}
return controllerConfig{
namespace: namespace,
pollInterval: pollInterval,
prepareTemplate: valueOrDefault("PREPARE_TEMPLATE", "image-prepare"),
promotionTemplate: valueOrDefault("PROMOTION_TEMPLATE", "image-promote"),
cleanupTemplate: valueOrDefault("CLEANUP_TEMPLATE", "image-cleanup"),
}, nil
}
func durationEnv(name string, fallback time.Duration) (time.Duration, error) {
value := os.Getenv(name)
if value == "" {
return fallback, nil
}
duration, err := time.ParseDuration(value)
if err != nil || duration <= 0 {
return 0, fmt.Errorf("%s must be a positive duration", name)
}
return duration, nil
}
func valueOrDefault(name, fallback string) string {
if value := os.Getenv(name); value != "" {
return value
}
return fallback
}