kvm2: base image cache with a streamed upload and the pool-space precheck
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -7,13 +7,16 @@ package kvm2
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/log"
|
||||
|
||||
"gitea.home.hrajfrisbee.cz/kacerr/egress-proxies-operator/internal/provider"
|
||||
"gitea.home.hrajfrisbee.cz/kacerr/egress-proxies-operator/internal/tracing"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -25,10 +28,33 @@ const (
|
||||
// Provider is one configured kvm2 entry: a set of hosts sharing one SSH key
|
||||
// and one image and machine-type catalogue.
|
||||
type Provider struct {
|
||||
name string
|
||||
cfg provider.KVMConfig
|
||||
now func() time.Time
|
||||
hosts *hostTable
|
||||
name string
|
||||
cfg provider.KVMConfig
|
||||
now func() time.Time
|
||||
hosts *hostTable
|
||||
http *http.Client
|
||||
budgets budgets
|
||||
tracing []tracing.Option
|
||||
|
||||
// imageLocks serialises image fetches per (host, volume), spec entry 19.
|
||||
imageMu sync.Mutex
|
||||
imageLocks map[string]chan struct{}
|
||||
}
|
||||
|
||||
// providerOption adjusts what newProvider builds; tests inject an HTTP
|
||||
// client bound to a test server, a span recorder and shorter budgets.
|
||||
type providerOption func(*Provider)
|
||||
|
||||
func withHTTPClient(c *http.Client) providerOption {
|
||||
return func(p *Provider) { p.http = c }
|
||||
}
|
||||
|
||||
func withBudgets(b budgets) providerOption {
|
||||
return func(p *Provider) { p.budgets = b }
|
||||
}
|
||||
|
||||
func withTracing(opts ...tracing.Option) providerOption {
|
||||
return func(p *Provider) { p.tracing = opts }
|
||||
}
|
||||
|
||||
var _ provider.Provider = (*Provider)(nil)
|
||||
@@ -59,9 +85,26 @@ func New(ctx context.Context, pc provider.ProviderConfig) (provider.Provider, er
|
||||
}
|
||||
|
||||
// newProvider is the constructor tests use: d hands out the backends, the
|
||||
// production one being newLibvirtDialer.
|
||||
func newProvider(name string, cfg provider.KVMConfig, d dialer) *Provider {
|
||||
return &Provider{name: name, cfg: withDefaults(cfg), now: time.Now, hosts: newHostTable(d)}
|
||||
// production one being newLibvirtDialer. Without options the image
|
||||
// downloads use http.DefaultClient (system CA roots, no client timeout: the
|
||||
// per-request ctx carries the transfer budget) and the default budgets.
|
||||
func newProvider(name string, cfg provider.KVMConfig, d dialer, opts ...providerOption) *Provider {
|
||||
p := &Provider{
|
||||
name: name,
|
||||
cfg: withDefaults(cfg),
|
||||
now: time.Now,
|
||||
hosts: newHostTable(d),
|
||||
http: http.DefaultClient,
|
||||
budgets: defaultBudgets,
|
||||
imageLocks: make(map[string]chan struct{}),
|
||||
}
|
||||
for _, opt := range opts {
|
||||
opt(p)
|
||||
}
|
||||
if p.http == nil {
|
||||
p.http = http.DefaultClient
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// withDefaults returns cfg with every optional field filled in, so the rest
|
||||
|
||||
Reference in New Issue
Block a user