mirror of
https://github.com/siderolabs/image-factory.git
synced 2025-09-21 13:51:08 +02:00
Add fallback to direct asset download in case of S3 issues. Signed-off-by: Mateusz Urbanek <mateusz.urbanek@siderolabs.com>
117 lines
3.0 KiB
Go
117 lines
3.0 KiB
Go
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
// Package schematic implements schematic factory: storing image schematics.
|
|
package schematic
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
"go.uber.org/zap"
|
|
|
|
"github.com/siderolabs/image-factory/internal/schematic/storage"
|
|
"github.com/siderolabs/image-factory/pkg/schematic"
|
|
)
|
|
|
|
// Factory is the schematic factory.
|
|
type Factory struct {
|
|
storage storage.Storage
|
|
metricGet prometheus.Counter
|
|
metricCreate prometheus.Counter
|
|
metricDuplicate prometheus.Counter
|
|
logger *zap.Logger
|
|
options Options
|
|
}
|
|
|
|
// Options for the schematic factory.
|
|
type Options struct {
|
|
MetricsNamespace string
|
|
}
|
|
|
|
// NewFactory creates a new schematic factory.
|
|
func NewFactory(logger *zap.Logger, storage storage.Storage, options Options) *Factory {
|
|
return &Factory{
|
|
options: options,
|
|
storage: storage,
|
|
logger: logger.With(zap.String("factory", "schematic")),
|
|
|
|
metricGet: prometheus.NewCounter(prometheus.CounterOpts{
|
|
Name: "image_factory_schematic_get_total",
|
|
Help: "Number of times schematics were retrieved.",
|
|
Namespace: options.MetricsNamespace,
|
|
}),
|
|
metricCreate: prometheus.NewCounter(prometheus.CounterOpts{
|
|
Name: "image_factory_schematic_create_total",
|
|
Help: "Number of new schematics created.",
|
|
Namespace: options.MetricsNamespace,
|
|
}),
|
|
metricDuplicate: prometheus.NewCounter(prometheus.CounterOpts{
|
|
Name: "image_factory_schematic_duplicate_create_total",
|
|
Help: "Number of new schematics which were created as duplicate.",
|
|
Namespace: options.MetricsNamespace,
|
|
}),
|
|
}
|
|
}
|
|
|
|
// Put stores the schematic.
|
|
//
|
|
// If the schematic already exists, Put does nothing.
|
|
func (s *Factory) Put(ctx context.Context, cfg *schematic.Schematic) (string, error) {
|
|
id, err := cfg.ID()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
if err = s.storage.Head(ctx, id); err == nil {
|
|
s.logger.Info("schematic already exists", zap.String("id", id))
|
|
|
|
s.metricDuplicate.Inc()
|
|
|
|
return id, nil
|
|
}
|
|
|
|
data, err := cfg.Marshal()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
err = s.storage.Put(ctx, id, data)
|
|
if err == nil {
|
|
s.metricCreate.Inc()
|
|
|
|
s.logger.Info("schematic created", zap.String("id", id), zap.Any("customization", cfg.Customization))
|
|
}
|
|
|
|
return id, err
|
|
}
|
|
|
|
// Get retrieves the stored schematic.
|
|
func (s *Factory) Get(ctx context.Context, id string) (*schematic.Schematic, error) {
|
|
data, err := s.storage.Get(ctx, id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
s.metricGet.Inc()
|
|
|
|
return schematic.Unmarshal(data)
|
|
}
|
|
|
|
// Describe implements prom.Collector interface.
|
|
func (s *Factory) Describe(ch chan<- *prometheus.Desc) {
|
|
prometheus.DescribeByCollect(s, ch)
|
|
}
|
|
|
|
// Collect implements prom.Collector interface.
|
|
func (s *Factory) Collect(ch chan<- prometheus.Metric) {
|
|
s.metricCreate.Collect(ch)
|
|
s.metricGet.Collect(ch)
|
|
s.metricDuplicate.Collect(ch)
|
|
|
|
s.storage.Collect(ch)
|
|
}
|
|
|
|
var _ prometheus.Collector = &Factory{}
|