feat: runtime manager
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
// Package engineimage resolves the Docker reference Lobby publishes on
|
||||
// `runtime:start_jobs`. The reference is built from a configurable
|
||||
// template that must contain the literal `{engine_version}` placeholder
|
||||
// and a per-game `target_engine_version`.
|
||||
//
|
||||
// The resolver intentionally performs only template substitution and a
|
||||
// non-empty-version guard. Semver validation of the engine version
|
||||
// itself lives in `lobby/internal/domain/game` and runs at game-record
|
||||
// construction time; by the time `startgame.Service.Handle` reads the
|
||||
// record the version is already validated.
|
||||
package engineimage
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// VersionPlaceholder is the literal token a template must contain. The
|
||||
// resolver substitutes it with the per-game engine version verbatim.
|
||||
const VersionPlaceholder = "{engine_version}"
|
||||
|
||||
// Resolver substitutes a per-game engine version into a pre-validated
|
||||
// template. The template is validated once at construction so per-game
|
||||
// `Resolve` calls remain pure string substitution.
|
||||
type Resolver struct {
|
||||
template string
|
||||
}
|
||||
|
||||
// NewResolver returns a Resolver that uses template for every Resolve
|
||||
// call. It returns an error if template is empty or does not contain
|
||||
// VersionPlaceholder.
|
||||
func NewResolver(template string) (*Resolver, error) {
|
||||
trimmed := strings.TrimSpace(template)
|
||||
if trimmed == "" {
|
||||
return nil, errors.New("engine image resolver: template must not be empty")
|
||||
}
|
||||
if !strings.Contains(trimmed, VersionPlaceholder) {
|
||||
return nil, fmt.Errorf(
|
||||
"engine image resolver: template %q must contain placeholder %q",
|
||||
template, VersionPlaceholder,
|
||||
)
|
||||
}
|
||||
return &Resolver{template: trimmed}, nil
|
||||
}
|
||||
|
||||
// Template returns the validated template string the resolver was
|
||||
// constructed with. The accessor is intended for diagnostics and tests.
|
||||
func (resolver *Resolver) Template() string {
|
||||
if resolver == nil {
|
||||
return ""
|
||||
}
|
||||
return resolver.template
|
||||
}
|
||||
|
||||
// Resolve substitutes VersionPlaceholder in the validated template with
|
||||
// version. It returns an error when version is empty or whitespace.
|
||||
func (resolver *Resolver) Resolve(version string) (string, error) {
|
||||
if resolver == nil {
|
||||
return "", errors.New("engine image resolver: nil resolver")
|
||||
}
|
||||
if strings.TrimSpace(version) == "" {
|
||||
return "", errors.New("engine image resolver: engine version must not be empty")
|
||||
}
|
||||
return strings.ReplaceAll(resolver.template, VersionPlaceholder, version), nil
|
||||
}
|
||||
Reference in New Issue
Block a user