feat: runtime manager
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
package patchruntime
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/distribution/reference"
|
||||
"golang.org/x/mod/semver"
|
||||
)
|
||||
|
||||
// errImageRefNoTag reports that an image reference does not declare a
|
||||
// tag. The patch service maps it to `image_ref_not_semver` because a
|
||||
// digest-only or tagless reference cannot carry a semver-comparable
|
||||
// version.
|
||||
var errImageRefNoTag = errors.New("image reference is missing a tag")
|
||||
|
||||
// extractSemverTag returns the canonical semver string ("v1.4.7") for
|
||||
// imageRef, ready to feed into golang.org/x/mod/semver. The leading "v"
|
||||
// is added when the underlying tag omits it.
|
||||
//
|
||||
// Errors returned by this function are pre-formatted for inclusion in
|
||||
// the patch service's `image_ref_not_semver` failure message.
|
||||
func extractSemverTag(imageRef string) (string, error) {
|
||||
parsed, err := reference.ParseNormalizedNamed(imageRef)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("parse image reference %q: %w", imageRef, err)
|
||||
}
|
||||
tagged, ok := parsed.(reference.NamedTagged)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("%w: %q", errImageRefNoTag, imageRef)
|
||||
}
|
||||
tag := strings.TrimSpace(tagged.Tag())
|
||||
if tag == "" {
|
||||
return "", fmt.Errorf("%w: %q", errImageRefNoTag, imageRef)
|
||||
}
|
||||
candidate := tag
|
||||
if !strings.HasPrefix(candidate, "v") {
|
||||
candidate = "v" + candidate
|
||||
}
|
||||
if !semver.IsValid(candidate) {
|
||||
return "", fmt.Errorf("tag %q on image reference %q is not a valid semver", tag, imageRef)
|
||||
}
|
||||
return candidate, nil
|
||||
}
|
||||
|
||||
// samePatchSeries reports whether two canonical semver strings (with
|
||||
// the leading "v") share their major and minor components. The third
|
||||
// component (patch) and any pre-release / build metadata are ignored.
|
||||
func samePatchSeries(currentSemver, newSemver string) bool {
|
||||
return semver.MajorMinor(currentSemver) == semver.MajorMinor(newSemver)
|
||||
}
|
||||
Reference in New Issue
Block a user