mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-07-09 21:17:09 +08:00
162
vendor/github.com/moby/buildkit/util/apicaps/caps.go
generated
vendored
Normal file
162
vendor/github.com/moby/buildkit/util/apicaps/caps.go
generated
vendored
Normal file
@ -0,0 +1,162 @@
|
||||
package apicaps
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
pb "github.com/moby/buildkit/util/apicaps/pb"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type PBCap = pb.APICap
|
||||
|
||||
// ExportedProduct is the name of the product using this package.
|
||||
// Users vendoring this library may override it to provide better versioning hints
|
||||
// for their users (or set it with a flag to buildkitd).
|
||||
var ExportedProduct string
|
||||
|
||||
// CapStatus defines the stability properties of a capability
|
||||
type CapStatus int
|
||||
|
||||
const (
|
||||
// CapStatusStable refers to a capability that should never be changed in
|
||||
// backwards incompatible manner unless there is a serious security issue.
|
||||
CapStatusStable CapStatus = iota
|
||||
// CapStatusExperimental refers to a capability that may be removed in the future.
|
||||
// If incompatible changes are made the previous ID is disabled and new is added.
|
||||
CapStatusExperimental
|
||||
// CapStatusPrerelease is same as CapStatusExperimental that can be used for new
|
||||
// features before they move to stable.
|
||||
CapStatusPrerelease
|
||||
)
|
||||
|
||||
// CapID is type for capability identifier
|
||||
type CapID string
|
||||
|
||||
// Cap describes an API feature
|
||||
type Cap struct {
|
||||
ID CapID
|
||||
Name string // readable name, may contain spaces but keep in one sentence
|
||||
Status CapStatus
|
||||
Enabled bool
|
||||
Deprecated bool
|
||||
SupportedHint map[string]string
|
||||
DisabledReason string
|
||||
DisabledReasonMsg string
|
||||
DisabledAlternative string
|
||||
}
|
||||
|
||||
// CapList is a collection of capability definitions
|
||||
type CapList struct {
|
||||
m map[CapID]Cap
|
||||
}
|
||||
|
||||
// Init initializes definition for a new capability.
|
||||
// Not safe to be called concurrently with other methods.
|
||||
func (l *CapList) Init(cc ...Cap) {
|
||||
if l.m == nil {
|
||||
l.m = make(map[CapID]Cap, len(cc))
|
||||
}
|
||||
for _, c := range cc {
|
||||
l.m[c.ID] = c
|
||||
}
|
||||
}
|
||||
|
||||
// All reports the configuration of all known capabilities
|
||||
func (l *CapList) All() []pb.APICap {
|
||||
out := make([]pb.APICap, 0, len(l.m))
|
||||
for _, c := range l.m {
|
||||
out = append(out, pb.APICap{
|
||||
ID: string(c.ID),
|
||||
Enabled: c.Enabled,
|
||||
Deprecated: c.Deprecated,
|
||||
DisabledReason: c.DisabledReason,
|
||||
DisabledReasonMsg: c.DisabledReasonMsg,
|
||||
DisabledAlternative: c.DisabledAlternative,
|
||||
})
|
||||
}
|
||||
sort.Slice(out, func(i, j int) bool {
|
||||
return out[i].ID < out[j].ID
|
||||
})
|
||||
return out
|
||||
}
|
||||
|
||||
// CapSet returns a CapSet for an capability configuration
|
||||
func (l *CapList) CapSet(caps []pb.APICap) CapSet {
|
||||
m := make(map[string]*pb.APICap, len(caps))
|
||||
for _, c := range caps {
|
||||
if c.ID != "" {
|
||||
c := c // capture loop iterator
|
||||
m[c.ID] = &c
|
||||
}
|
||||
}
|
||||
return CapSet{
|
||||
list: l,
|
||||
set: m,
|
||||
}
|
||||
}
|
||||
|
||||
// CapSet is a configuration for detecting supported capabilities
|
||||
type CapSet struct {
|
||||
list *CapList
|
||||
set map[string]*pb.APICap
|
||||
}
|
||||
|
||||
// Supports returns an error if capability is not supported
|
||||
func (s *CapSet) Supports(id CapID) error {
|
||||
err := &CapError{ID: id}
|
||||
c, ok := s.list.m[id]
|
||||
if !ok {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
err.Definition = &c
|
||||
state, ok := s.set[string(id)]
|
||||
if !ok {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
err.State = state
|
||||
if !state.Enabled {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CapError is an error for unsupported capability
|
||||
type CapError struct {
|
||||
ID CapID
|
||||
Definition *Cap
|
||||
State *pb.APICap
|
||||
}
|
||||
|
||||
func (e CapError) Error() string {
|
||||
if e.Definition == nil {
|
||||
return fmt.Sprintf("unknown API capability %s", e.ID)
|
||||
}
|
||||
typ := ""
|
||||
if e.Definition.Status == CapStatusExperimental {
|
||||
typ = "experimental "
|
||||
}
|
||||
if e.Definition.Status == CapStatusPrerelease {
|
||||
typ = "prerelease "
|
||||
}
|
||||
name := ""
|
||||
if e.Definition.Name != "" {
|
||||
name = "(" + e.Definition.Name + ")"
|
||||
}
|
||||
b := &strings.Builder{}
|
||||
fmt.Fprintf(b, "requested %sfeature %s %s", typ, e.ID, name)
|
||||
if e.State == nil {
|
||||
fmt.Fprint(b, " is not supported by build server")
|
||||
if hint, ok := e.Definition.SupportedHint[ExportedProduct]; ok {
|
||||
fmt.Fprintf(b, " (added in %s)", hint)
|
||||
}
|
||||
fmt.Fprintf(b, ", please update %s", ExportedProduct)
|
||||
} else {
|
||||
fmt.Fprint(b, " has been disabled on the build server")
|
||||
if e.State.DisabledReasonMsg != "" {
|
||||
fmt.Fprintf(b, ": %s", e.State.DisabledReasonMsg)
|
||||
}
|
||||
}
|
||||
return b.String()
|
||||
}
|
Reference in New Issue
Block a user