vendor: github.com/moby/buildkit@master ed6dc749ce40b9fdc308676d10343fd00f56c717
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
This commit is contained in:
@@ -29,8 +29,8 @@ require (
|
||||
github.com/hashicorp/hcl/v2 v2.24.0
|
||||
github.com/in-toto/in-toto-golang v0.9.0
|
||||
github.com/mitchellh/hashstructure/v2 v2.0.2
|
||||
github.com/moby/buildkit v0.26.2
|
||||
github.com/moby/go-archive v0.1.0
|
||||
github.com/moby/buildkit v0.26.1-0.20260106154623-ed6dc749ce40 // v0.27.0-dev
|
||||
github.com/moby/go-archive v0.2.0
|
||||
github.com/moby/moby/api v1.52.0
|
||||
github.com/moby/moby/client v0.2.1
|
||||
github.com/moby/sys/atomicwriter v0.1.0
|
||||
@@ -47,7 +47,7 @@ require (
|
||||
github.com/spf13/cobra v1.10.2
|
||||
github.com/spf13/pflag v1.0.10
|
||||
github.com/stretchr/testify v1.11.1
|
||||
github.com/tonistiigi/fsutil v0.0.0-20250605211040-586307ad452f
|
||||
github.com/tonistiigi/fsutil v0.0.0-20251211185533-a2aa163d723f
|
||||
github.com/tonistiigi/go-csvvalue v0.0.0-20240814133006-030d3b2625d0
|
||||
github.com/tonistiigi/jaeger-ui-rest v0.0.0-20250408171107-3dd17559e117
|
||||
github.com/zclconf/go-cty v1.17.0
|
||||
|
||||
@@ -210,12 +210,12 @@ github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQ
|
||||
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
|
||||
github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4=
|
||||
github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE=
|
||||
github.com/moby/buildkit v0.26.2 h1:EIh5j0gzRsCZmQzvgNNWzSDbuKqwUIiBH7ssqLv8RU8=
|
||||
github.com/moby/buildkit v0.26.2/go.mod h1:ylDa7IqzVJgLdi/wO7H1qLREFQpmhFbw2fbn4yoTw40=
|
||||
github.com/moby/buildkit v0.26.1-0.20260106154623-ed6dc749ce40 h1:h45o8dTo7Cq1Su49bs9VHP83Fdp3olgMfgo3tZULXUw=
|
||||
github.com/moby/buildkit v0.26.1-0.20260106154623-ed6dc749ce40/go.mod h1:LtUhyzVLAD0ilniDZRbghEyRq9CgZAY7ywMXlVo9MBI=
|
||||
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
|
||||
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
|
||||
github.com/moby/go-archive v0.1.0 h1:Kk/5rdW/g+H8NHdJW2gsXyZ7UnzvJNOy6VKJqueWdcQ=
|
||||
github.com/moby/go-archive v0.1.0/go.mod h1:G9B+YoujNohJmrIYFBpSd54GTUB4lt9S+xVQvsJyFuo=
|
||||
github.com/moby/go-archive v0.2.0 h1:zg5QDUM2mi0JIM9fdQZWC7U8+2ZfixfTYoHL7rWUcP8=
|
||||
github.com/moby/go-archive v0.2.0/go.mod h1:mNeivT14o8xU+5q1YnNrkQVpK+dnNe/K6fHqnTg4qPU=
|
||||
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
|
||||
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
|
||||
github.com/moby/moby/api v1.52.0 h1:00BtlJY4MXkkt84WhUZPRqt5TvPbgig2FZvTbe3igYg=
|
||||
@@ -319,8 +319,8 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/tonistiigi/dchapes-mode v0.0.0-20250318174251-73d941a28323 h1:r0p7fK56l8WPequOaR3i9LBqfPtEdXIQbUTzT55iqT4=
|
||||
github.com/tonistiigi/dchapes-mode v0.0.0-20250318174251-73d941a28323/go.mod h1:3Iuxbr0P7D3zUzBMAZB+ois3h/et0shEz0qApgHYGpY=
|
||||
github.com/tonistiigi/fsutil v0.0.0-20250605211040-586307ad452f h1:MoxeMfHAe5Qj/ySSBfL8A7l1V+hxuluj8owsIEEZipI=
|
||||
github.com/tonistiigi/fsutil v0.0.0-20250605211040-586307ad452f/go.mod h1:BKdcez7BiVtBvIcef90ZPc6ebqIWr4JWD7+EvLm6J98=
|
||||
github.com/tonistiigi/fsutil v0.0.0-20251211185533-a2aa163d723f h1:Z4NEQ86qFl1mHuCu9gwcE+EYCwDKfXAYXZbdIXyxmEA=
|
||||
github.com/tonistiigi/fsutil v0.0.0-20251211185533-a2aa163d723f/go.mod h1:BKdcez7BiVtBvIcef90ZPc6ebqIWr4JWD7+EvLm6J98=
|
||||
github.com/tonistiigi/go-csvvalue v0.0.0-20240814133006-030d3b2625d0 h1:2f304B10LaZdB8kkVEaoXvAMVan2tl9AiK4G0odjQtE=
|
||||
github.com/tonistiigi/go-csvvalue v0.0.0-20240814133006-030d3b2625d0/go.mod h1:278M4p8WsNh3n4a1eqiFcV2FGk7wE5fwUpUom9mK9lE=
|
||||
github.com/tonistiigi/jaeger-ui-rest v0.0.0-20250408171107-3dd17559e117 h1:XFwyh2JZwR5aiKLXHX2C1n0v5F11dCJpyGL1W/Cpl3U=
|
||||
|
||||
+27
-2
@@ -236,6 +236,9 @@ func (c *Client) solve(ctx context.Context, def *llb.Definition, runGateway runG
|
||||
frontendAttrs := maps.Clone(opt.FrontendAttrs)
|
||||
maps.Copy(frontendAttrs, cacheOpt.frontendAttrs)
|
||||
|
||||
const statusInactivityTimeout = 5 * time.Second
|
||||
statusActivity := make(chan struct{}, 1)
|
||||
|
||||
solveCtx, cancelSolve := context.WithCancelCause(ctx)
|
||||
var res *SolveResponse
|
||||
eg.Go(func() error {
|
||||
@@ -244,8 +247,21 @@ func (c *Client) solve(ctx context.Context, def *llb.Definition, runGateway runG
|
||||
|
||||
defer func() { // make sure the Status ends cleanly on build errors
|
||||
go func() {
|
||||
<-time.After(3 * time.Second)
|
||||
cancelStatus(errors.WithStack(context.Canceled))
|
||||
// Start inactivity monitoring after solve completes
|
||||
statusInactivityTimer := time.NewTimer(statusInactivityTimeout)
|
||||
defer statusInactivityTimer.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-statusContext.Done():
|
||||
return
|
||||
case <-statusActivity:
|
||||
// Reset timer on activity
|
||||
statusInactivityTimer.Reset(statusInactivityTimeout)
|
||||
case <-statusInactivityTimer.C:
|
||||
cancelStatus(errors.WithStack(context.Canceled))
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
if !opt.SessionPreInitialized {
|
||||
bklog.G(ctx).Debugf("stopping session")
|
||||
@@ -345,8 +361,17 @@ func (c *Client) solve(ctx context.Context, def *llb.Definition, runGateway runG
|
||||
if errors.Is(err, io.EOF) {
|
||||
return nil
|
||||
}
|
||||
// Ignore context canceled, triggered after inactivity timeout
|
||||
if errors.Is(err, context.Canceled) || statusContext.Err() != nil {
|
||||
return nil
|
||||
}
|
||||
return errors.Wrap(err, "failed to receive status")
|
||||
}
|
||||
// Signal activity (non-blocking)
|
||||
select {
|
||||
case statusActivity <- struct{}{}:
|
||||
default:
|
||||
}
|
||||
if statusChan != nil {
|
||||
statusChan <- NewSolveStatus(resp)
|
||||
}
|
||||
|
||||
+56
-5
@@ -2,6 +2,7 @@ package linter
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"maps"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -19,7 +20,7 @@ type Config struct {
|
||||
}
|
||||
|
||||
type Linter struct {
|
||||
CalledRules []string
|
||||
CalledRules *[]string
|
||||
ExperimentalAll bool
|
||||
ExperimentalRules map[string]struct{}
|
||||
ReturnAsError bool
|
||||
@@ -32,7 +33,7 @@ func New(config *Config) *Linter {
|
||||
toret := &Linter{
|
||||
SkippedRules: map[string]struct{}{},
|
||||
ExperimentalRules: map[string]struct{}{},
|
||||
CalledRules: []string{},
|
||||
CalledRules: new([]string),
|
||||
Warn: config.Warn,
|
||||
}
|
||||
toret.SkipAll = config.SkipAll
|
||||
@@ -65,20 +66,70 @@ func (lc *Linter) Run(rule LinterRuleI, location []parser.Range, txt ...string)
|
||||
}
|
||||
}
|
||||
|
||||
lc.CalledRules = append(lc.CalledRules, rulename)
|
||||
*lc.CalledRules = append(*lc.CalledRules, rulename)
|
||||
rule.Run(lc.Warn, location, txt...)
|
||||
}
|
||||
|
||||
func (lc *Linter) WithMergedConfig(other *Config) *Linter {
|
||||
cloned := *lc
|
||||
if other.ExperimentalAll {
|
||||
cloned.ExperimentalAll = true
|
||||
}
|
||||
|
||||
if len(other.ExperimentalRules) > 0 {
|
||||
cloned.ExperimentalRules = maps.Clone(cloned.ExperimentalRules)
|
||||
for _, rulename := range other.ExperimentalRules {
|
||||
cloned.ExperimentalRules[rulename] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
if other.SkipAll {
|
||||
cloned.SkipAll = true
|
||||
}
|
||||
|
||||
if len(other.SkipRules) > 0 {
|
||||
cloned.SkippedRules = maps.Clone(cloned.SkippedRules)
|
||||
for _, rulename := range other.SkipRules {
|
||||
cloned.SkippedRules[rulename] = struct{}{}
|
||||
}
|
||||
}
|
||||
return &cloned
|
||||
}
|
||||
|
||||
func (lc *Linter) WithMergedConfigFromComments(comments []string) *Linter {
|
||||
if comments == nil {
|
||||
return lc
|
||||
}
|
||||
|
||||
for _, comment := range comments {
|
||||
p := parser.DirectiveParser{}
|
||||
p.SetComment("")
|
||||
|
||||
d, _ := p.ParseLine([]byte(comment))
|
||||
if d == nil || d.Name != "check" {
|
||||
continue
|
||||
}
|
||||
|
||||
v, _, _ := strings.Cut(d.Value, " ")
|
||||
lintConfig, err := ParseLintOptions(v)
|
||||
if err != nil {
|
||||
return lc
|
||||
}
|
||||
return lc.WithMergedConfig(lintConfig)
|
||||
}
|
||||
return lc
|
||||
}
|
||||
|
||||
func (lc *Linter) Error() error {
|
||||
if lc == nil || !lc.ReturnAsError {
|
||||
return nil
|
||||
}
|
||||
if len(lc.CalledRules) == 0 {
|
||||
if len(*lc.CalledRules) == 0 {
|
||||
return nil
|
||||
}
|
||||
var rules []string
|
||||
uniqueRules := map[string]struct{}{}
|
||||
for _, r := range lc.CalledRules {
|
||||
for _, r := range *lc.CalledRules {
|
||||
uniqueRules[r] = struct{}{}
|
||||
}
|
||||
for r := range uniqueRules {
|
||||
|
||||
+23
-11
@@ -4,9 +4,10 @@ import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"unicode"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
@@ -32,14 +33,18 @@ type Directive struct {
|
||||
// DirectiveParser is a parser for Dockerfile directives that enforces the
|
||||
// quirks of the directive parser.
|
||||
type DirectiveParser struct {
|
||||
line int
|
||||
regexp *regexp.Regexp
|
||||
seen map[string]struct{}
|
||||
done bool
|
||||
line int
|
||||
comment *string
|
||||
seen map[string]struct{}
|
||||
done bool
|
||||
}
|
||||
|
||||
func (d *DirectiveParser) setComment(comment string) {
|
||||
d.regexp = regexp.MustCompile(fmt.Sprintf(`^%s\s*([a-zA-Z][a-zA-Z0-9]*)\s*=\s*(.+?)\s*$`, comment))
|
||||
var directiveRegexp = sync.OnceValue(func() *regexp.Regexp {
|
||||
return regexp.MustCompile(`^([a-zA-Z][a-zA-Z0-9]*)\s*=\s*(.+?)\s*$`)
|
||||
})
|
||||
|
||||
func (d *DirectiveParser) SetComment(comment string) {
|
||||
d.comment = &comment
|
||||
}
|
||||
|
||||
func (d *DirectiveParser) ParseLine(line []byte) (*Directive, error) {
|
||||
@@ -47,11 +52,18 @@ func (d *DirectiveParser) ParseLine(line []byte) (*Directive, error) {
|
||||
if d.done {
|
||||
return nil, nil
|
||||
}
|
||||
if d.regexp == nil {
|
||||
d.setComment("#")
|
||||
if d.comment == nil {
|
||||
d.SetComment("#")
|
||||
}
|
||||
|
||||
match := d.regexp.FindSubmatch(line)
|
||||
line, ok := bytes.CutPrefix(line, []byte(*d.comment))
|
||||
if !ok {
|
||||
d.done = true
|
||||
return nil, nil
|
||||
}
|
||||
line = bytes.TrimLeftFunc(line, unicode.IsSpace)
|
||||
|
||||
match := directiveRegexp().FindSubmatch(line)
|
||||
if len(match) == 0 {
|
||||
d.done = true
|
||||
return nil, nil
|
||||
@@ -142,7 +154,7 @@ func parseDirective(key string, dt []byte, anyFormat bool) (string, string, []Ra
|
||||
|
||||
// use directive with different comment prefix, and search for //key=
|
||||
directiveParser = DirectiveParser{line: line}
|
||||
directiveParser.setComment("//")
|
||||
directiveParser.SetComment("//")
|
||||
if syntax, cmdline, loc, ok := detectDirectiveFromParser(key, dt, directiveParser); ok {
|
||||
return syntax, cmdline, loc, true
|
||||
}
|
||||
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
package authprovider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/docker/cli/cli/config/configfile"
|
||||
"github.com/docker/cli/cli/config/types"
|
||||
)
|
||||
|
||||
func LoadAuthConfig(config *configfile.ConfigFile) AuthConfigProvider {
|
||||
acp := &authConfigProvider{
|
||||
config: config,
|
||||
authConfigCache: map[string]authConfigCacheEntry{},
|
||||
}
|
||||
return acp.load
|
||||
}
|
||||
|
||||
type authConfigProvider struct {
|
||||
config *configfile.ConfigFile
|
||||
authConfigCache map[string]authConfigCacheEntry
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
func (ap *authConfigProvider) load(ctx context.Context, host string, scopes []string, cacheExpireCheck ExpireCachedAuthCheck) (types.AuthConfig, error) {
|
||||
ap.mu.Lock()
|
||||
defer ap.mu.Unlock()
|
||||
|
||||
entry, exists := ap.authConfigCache[host]
|
||||
if exists && (cacheExpireCheck == nil || !cacheExpireCheck(entry.Created, host)) {
|
||||
return *entry.Auth, nil
|
||||
}
|
||||
|
||||
hostKey := host
|
||||
if host == DockerHubRegistryHost {
|
||||
hostKey = DockerHubConfigfileKey
|
||||
}
|
||||
|
||||
ac, err := ap.config.GetAuthConfig(hostKey)
|
||||
if err != nil {
|
||||
return types.AuthConfig{}, err
|
||||
}
|
||||
|
||||
entry = authConfigCacheEntry{
|
||||
Created: time.Now(),
|
||||
Auth: &ac,
|
||||
}
|
||||
|
||||
ap.authConfigCache[host] = entry
|
||||
|
||||
return ac, nil
|
||||
}
|
||||
|
||||
type authConfigCacheEntry struct {
|
||||
Created time.Time
|
||||
Auth *types.AuthConfig
|
||||
}
|
||||
+44
-61
@@ -19,7 +19,6 @@ import (
|
||||
authutil "github.com/containerd/containerd/v2/core/remotes/docker/auth"
|
||||
remoteserrors "github.com/containerd/containerd/v2/core/remotes/errors"
|
||||
"github.com/docker/cli/cli/config"
|
||||
"github.com/docker/cli/cli/config/configfile"
|
||||
"github.com/docker/cli/cli/config/types"
|
||||
cleanhttp "github.com/hashicorp/go-cleanhttp"
|
||||
"github.com/moby/buildkit/session"
|
||||
@@ -36,13 +35,17 @@ import (
|
||||
|
||||
const (
|
||||
defaultExpiration = 60
|
||||
dockerHubConfigfileKey = "https://index.docker.io/v1/"
|
||||
dockerHubRegistryHost = "registry-1.docker.io"
|
||||
DockerHubConfigfileKey = "https://index.docker.io/v1/"
|
||||
DockerHubRegistryHost = "registry-1.docker.io"
|
||||
)
|
||||
|
||||
type AuthConfigProvider func(ctx context.Context, host string, scope []string, cacheCheck ExpireCachedAuthCheck) (types.AuthConfig, error)
|
||||
|
||||
type ExpireCachedAuthCheck func(created time.Time, serverURL string) bool
|
||||
|
||||
type DockerAuthProviderConfig struct {
|
||||
// ConfigFile is the docker config file
|
||||
ConfigFile *configfile.ConfigFile
|
||||
// AuthConfigProvider is a function that provides auth config for a given host and scope
|
||||
AuthConfigProvider AuthConfigProvider
|
||||
// TLSConfigs is a map of host to TLS config
|
||||
TLSConfigs map[string]*AuthTLSConfig
|
||||
// ExpireCachedAuth is a function that returns true auth config should be refreshed
|
||||
@@ -50,12 +53,7 @@ type DockerAuthProviderConfig struct {
|
||||
// If nil then the cached result will expire after 4 minutes and 50 seconds.
|
||||
// The function is called with the time the cached auth config was created
|
||||
// and the server URL the auth config is for.
|
||||
ExpireCachedAuth func(created time.Time, serverURL string) bool
|
||||
}
|
||||
|
||||
type authConfigCacheEntry struct {
|
||||
Created time.Time
|
||||
Auth *types.AuthConfig
|
||||
ExpireCachedAuth ExpireCachedAuthCheck
|
||||
}
|
||||
|
||||
func NewDockerAuthProvider(cfg DockerAuthProviderConfig) session.Attachable {
|
||||
@@ -66,23 +64,21 @@ func NewDockerAuthProvider(cfg DockerAuthProviderConfig) session.Attachable {
|
||||
}
|
||||
}
|
||||
return &authProvider{
|
||||
authConfigCache: map[string]authConfigCacheEntry{},
|
||||
expireAc: cfg.ExpireCachedAuth,
|
||||
config: cfg.ConfigFile,
|
||||
seeds: &tokenSeeds{dir: config.Dir()},
|
||||
loggerCache: map[string]struct{}{},
|
||||
tlsConfigs: cfg.TLSConfigs,
|
||||
expireAc: cfg.ExpireCachedAuth,
|
||||
provider: cfg.AuthConfigProvider,
|
||||
seeds: &tokenSeeds{dir: config.Dir()},
|
||||
loggerCache: map[string]struct{}{},
|
||||
tlsConfigs: cfg.TLSConfigs,
|
||||
}
|
||||
}
|
||||
|
||||
type authProvider struct {
|
||||
authConfigCache map[string]authConfigCacheEntry
|
||||
expireAc func(time.Time, string) bool
|
||||
config *configfile.ConfigFile
|
||||
seeds *tokenSeeds
|
||||
logger progresswriter.Logger
|
||||
loggerCache map[string]struct{}
|
||||
tlsConfigs map[string]*AuthTLSConfig
|
||||
expireAc func(time.Time, string) bool
|
||||
provider AuthConfigProvider
|
||||
seeds *tokenSeeds
|
||||
logger progresswriter.Logger
|
||||
loggerCache map[string]struct{}
|
||||
tlsConfigs map[string]*AuthTLSConfig
|
||||
|
||||
// The need for this mutex is not well understood.
|
||||
// Without it, the docker cli on OS X hangs when
|
||||
@@ -102,7 +98,7 @@ func (ap *authProvider) Register(server *grpc.Server) {
|
||||
}
|
||||
|
||||
func (ap *authProvider) FetchToken(ctx context.Context, req *auth.FetchTokenRequest) (rr *auth.FetchTokenResponse, err error) {
|
||||
ac, err := ap.getAuthConfig(ctx, req.Host)
|
||||
ac, err := ap.getAuthConfig(ctx, req.Host, req.Scopes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -112,11 +108,7 @@ func (ap *authProvider) FetchToken(ctx context.Context, req *auth.FetchTokenRequ
|
||||
return toTokenResponse(ac.RegistryToken, time.Time{}, 0), nil
|
||||
}
|
||||
|
||||
creds, err := ap.credentials(ctx, req.Host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
creds := toCredentials(*ac)
|
||||
to := authutil.TokenOptions{
|
||||
Realm: req.Realm,
|
||||
Service: req.Service,
|
||||
@@ -215,11 +207,7 @@ func (ap *authProvider) tlsConfig(host string) (*tls.Config, error) {
|
||||
return tc, nil
|
||||
}
|
||||
|
||||
func (ap *authProvider) credentials(ctx context.Context, host string) (*auth.CredentialsResponse, error) {
|
||||
ac, err := ap.getAuthConfig(ctx, host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
func toCredentials(ac types.AuthConfig) *auth.CredentialsResponse {
|
||||
res := &auth.CredentialsResponse{}
|
||||
if ac.IdentityToken != "" {
|
||||
res.Secret = ac.IdentityToken
|
||||
@@ -227,12 +215,16 @@ func (ap *authProvider) credentials(ctx context.Context, host string) (*auth.Cre
|
||||
res.Username = ac.Username
|
||||
res.Secret = ac.Password
|
||||
}
|
||||
return res, nil
|
||||
return res
|
||||
}
|
||||
|
||||
func (ap *authProvider) Credentials(ctx context.Context, req *auth.CredentialsRequest) (*auth.CredentialsResponse, error) {
|
||||
resp, err := ap.credentials(ctx, req.Host)
|
||||
if err != nil || resp.Secret != "" {
|
||||
ac, err := ap.getAuthConfig(ctx, req.Host, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp := toCredentials(*ac)
|
||||
if resp.Secret != "" {
|
||||
ap.mu.Lock()
|
||||
defer ap.mu.Unlock()
|
||||
_, ok := ap.loggerCache[req.Host]
|
||||
@@ -267,33 +259,22 @@ func (ap *authProvider) VerifyTokenAuthority(ctx context.Context, req *auth.Veri
|
||||
return &auth.VerifyTokenAuthorityResponse{Signed: sign.Sign(nil, req.Payload, priv)}, nil
|
||||
}
|
||||
|
||||
func (ap *authProvider) getAuthConfig(ctx context.Context, host string) (*types.AuthConfig, error) {
|
||||
func (ap *authProvider) getAuthConfig(ctx context.Context, host string, scopes []string) (*types.AuthConfig, error) {
|
||||
ap.mu.Lock()
|
||||
defer ap.mu.Unlock()
|
||||
|
||||
if host == dockerHubRegistryHost {
|
||||
host = dockerHubConfigfileKey
|
||||
var ac types.AuthConfig
|
||||
if ap.provider != nil {
|
||||
span, _ := tracing.StartSpan(ctx, fmt.Sprintf("load credentials for %s", host))
|
||||
res, err := ap.provider(ctx, host, scopes, ap.expireAc)
|
||||
tracing.FinishWithError(span, err)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ac = res
|
||||
}
|
||||
|
||||
entry, exists := ap.authConfigCache[host]
|
||||
if exists && !ap.expireAc(entry.Created, host) {
|
||||
return entry.Auth, nil
|
||||
}
|
||||
|
||||
span, _ := tracing.StartSpan(ctx, fmt.Sprintf("load credentials for %s", host))
|
||||
ac, err := ap.config.GetAuthConfig(host)
|
||||
tracing.FinishWithError(span, err)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
entry = authConfigCacheEntry{
|
||||
Created: time.Now(),
|
||||
Auth: &ac,
|
||||
}
|
||||
|
||||
ap.authConfigCache[host] = entry
|
||||
|
||||
return entry.Auth, nil
|
||||
return &ac, nil
|
||||
}
|
||||
|
||||
func (ap *authProvider) getAuthorityKey(ctx context.Context, host string, salt []byte) (ed25519.PrivateKey, error) {
|
||||
@@ -301,10 +282,12 @@ func (ap *authProvider) getAuthorityKey(ctx context.Context, host string, salt [
|
||||
return nil, status.Errorf(codes.Unavailable, "client side tokens disabled")
|
||||
}
|
||||
|
||||
creds, err := ap.credentials(ctx, host)
|
||||
ac, err := ap.getAuthConfig(ctx, host, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
creds := toCredentials(*ac)
|
||||
seed, err := ap.seeds.getSeed(host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
+7
@@ -95,7 +95,14 @@ func (b *buffer) Writer(ctx context.Context, opts ...content.WriterOpt) (content
|
||||
}
|
||||
}
|
||||
b.mu.Lock()
|
||||
if wOpts.Desc.Digest != "" {
|
||||
if _, ok := b.buffers[wOpts.Desc.Digest]; ok {
|
||||
b.mu.Unlock()
|
||||
return nil, errors.Wrapf(cerrdefs.ErrAlreadyExists, "content %v already exists", wOpts.Desc.Digest)
|
||||
}
|
||||
}
|
||||
if _, ok := b.refs[wOpts.Ref]; ok {
|
||||
b.mu.Unlock()
|
||||
return nil, errors.Wrapf(cerrdefs.ErrUnavailable, "ref %s locked", wOpts.Ref)
|
||||
}
|
||||
b.mu.Unlock()
|
||||
|
||||
+229
@@ -0,0 +1,229 @@
|
||||
package contentutil
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/containerd/containerd/v2/core/content"
|
||||
"github.com/containerd/containerd/v2/core/remotes"
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
ocispecs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
func ReferrersProviderWithBuffer(p ReferrersProvider, buffer Buffer, name string) *ReferrersProviderBuffer {
|
||||
return &ReferrersProviderBuffer{
|
||||
p: p,
|
||||
cache: buffer,
|
||||
name: name,
|
||||
}
|
||||
}
|
||||
|
||||
var _ ReferrersProvider = &ReferrersProviderBuffer{}
|
||||
|
||||
type ReferrersProviderBuffer struct {
|
||||
p ReferrersProvider
|
||||
cache Buffer
|
||||
name string
|
||||
|
||||
mu sync.Mutex
|
||||
blobs map[digest.Digest]ocispecs.Descriptor
|
||||
refs map[digest.Digest][]ocispecs.Descriptor
|
||||
}
|
||||
|
||||
func (p *ReferrersProviderBuffer) ReaderAt(ctx context.Context, desc ocispecs.Descriptor) (content.ReaderAt, error) {
|
||||
cw, err := content.OpenWriter(ctx, p.cache, content.WithDescriptor(desc), content.WithRef(desc.Digest.String()))
|
||||
if err != nil {
|
||||
if cerrdefs.IsAlreadyExists(err) {
|
||||
ra, err := p.cache.ReaderAt(ctx, desc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.mu.Lock()
|
||||
if p.blobs == nil {
|
||||
p.blobs = make(map[digest.Digest]ocispecs.Descriptor)
|
||||
}
|
||||
p.blobs[desc.Digest] = desc
|
||||
p.mu.Unlock()
|
||||
return ra, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
ra, err := p.p.ReaderAt(ctx, desc)
|
||||
if err != nil {
|
||||
cw.Close()
|
||||
return nil, err
|
||||
}
|
||||
if err := content.CopyReaderAt(cw, ra, ra.Size()); err != nil {
|
||||
cw.Close()
|
||||
return nil, err
|
||||
}
|
||||
if err := cw.Commit(ctx, desc.Size, desc.Digest); err != nil {
|
||||
cw.Close()
|
||||
return nil, err
|
||||
}
|
||||
ra, err = p.cache.ReaderAt(ctx, desc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.mu.Lock()
|
||||
if p.blobs == nil {
|
||||
p.blobs = make(map[digest.Digest]ocispecs.Descriptor)
|
||||
}
|
||||
p.blobs[desc.Digest] = desc
|
||||
p.mu.Unlock()
|
||||
return ra, nil
|
||||
}
|
||||
|
||||
func (p *ReferrersProviderBuffer) FetchReferrers(ctx context.Context, dgst digest.Digest, opts ...remotes.FetchReferrersOpt) ([]ocispecs.Descriptor, error) {
|
||||
cfg := remotes.FetchReferrersConfig{}
|
||||
for _, o := range opts {
|
||||
if err := o(ctx, &cfg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
info, err := p.cache.Info(ctx, dgst)
|
||||
if err == nil && len(info.Labels) != 0 {
|
||||
refs := []ocispecs.Descriptor{}
|
||||
for l, v := range info.Labels {
|
||||
if !strings.HasPrefix(l, "containerd.io/gc.ref.content.buildkit.refs.") {
|
||||
continue
|
||||
}
|
||||
dgst, err := digest.Parse(v)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
dt, err := content.ReadBlob(ctx, p.cache, ocispecs.Descriptor{Digest: dgst})
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
desc := ocispecs.Descriptor{
|
||||
Digest: dgst,
|
||||
Size: int64(len(dt)),
|
||||
ArtifactType: readArtifactType(dt),
|
||||
}
|
||||
refs = append(refs, desc)
|
||||
}
|
||||
refs = filterRefs(refs, &cfg)
|
||||
if len(refs) > 0 {
|
||||
return refs, nil
|
||||
}
|
||||
v, ok := info.Labels["buildkit/refs.null"]
|
||||
if ok {
|
||||
for name := range strings.SplitSeq(v, ",") {
|
||||
if name == p.name {
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
refs, err := p.p.FetchReferrers(ctx, dgst, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
refs = filterRefs(refs, &cfg)
|
||||
p.mu.Lock()
|
||||
if p.refs == nil {
|
||||
p.refs = make(map[digest.Digest][]ocispecs.Descriptor)
|
||||
}
|
||||
p.refs[dgst] = append(p.refs[dgst], refs...)
|
||||
p.mu.Unlock()
|
||||
|
||||
return refs, nil
|
||||
}
|
||||
|
||||
func (p *ReferrersProviderBuffer) SetGCLabels(ctx context.Context, root ocispecs.Descriptor) error {
|
||||
labels := map[string]string{}
|
||||
fieldpaths := []string{}
|
||||
|
||||
p.mu.Lock()
|
||||
for _, desc := range p.blobs {
|
||||
shaPrefix := desc.Digest.Hex()[:12]
|
||||
key := "containerd.io/gc.ref.content.buildkit." + shaPrefix
|
||||
labels[key] = desc.Digest.String()
|
||||
fieldpaths = append(fieldpaths, "labels."+key)
|
||||
}
|
||||
p.mu.Unlock()
|
||||
|
||||
_, err := p.cache.Update(ctx, content.Info{
|
||||
Digest: root.Digest,
|
||||
Labels: labels,
|
||||
}, fieldpaths...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for dgst, refs := range p.refs {
|
||||
info, err := p.cache.Info(ctx, dgst)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
labels := map[string]string{}
|
||||
fieldpaths := []string{}
|
||||
for _, ref := range refs {
|
||||
shaPrefix := ref.Digest.Hex()[:12]
|
||||
key := "containerd.io/gc.ref.content.buildkit.refs." + shaPrefix
|
||||
labels[key] = ref.Digest.String()
|
||||
fieldpaths = append(fieldpaths, "labels."+key)
|
||||
}
|
||||
if len(refs) == 0 {
|
||||
key := "buildkit/refs.null"
|
||||
labels[key] = addName(info.Labels[key], p.name)
|
||||
fieldpaths = append(fieldpaths, "labels."+key)
|
||||
}
|
||||
if len(labels) == 0 {
|
||||
continue
|
||||
}
|
||||
_, err = p.cache.Update(ctx, content.Info{
|
||||
Digest: dgst,
|
||||
Labels: labels,
|
||||
}, fieldpaths...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func filterRefs(refs []ocispecs.Descriptor, cfg *remotes.FetchReferrersConfig) []ocispecs.Descriptor {
|
||||
if len(cfg.ArtifactTypes) == 0 {
|
||||
return refs
|
||||
}
|
||||
out := []ocispecs.Descriptor{}
|
||||
for _, ref := range refs {
|
||||
if slices.Contains(cfg.ArtifactTypes, ref.ArtifactType) {
|
||||
out = append(out, ref)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func addName(existing, name string) string {
|
||||
if existing == "" {
|
||||
return name
|
||||
}
|
||||
m := map[string]struct{}{}
|
||||
for n := range strings.SplitSeq(existing, ",") {
|
||||
m[n] = struct{}{}
|
||||
}
|
||||
m[name] = struct{}{}
|
||||
var names []string
|
||||
for n := range m {
|
||||
names = append(names, n)
|
||||
}
|
||||
slices.Sort(names)
|
||||
return strings.Join(names, ",")
|
||||
}
|
||||
|
||||
func readArtifactType(dt []byte) string {
|
||||
var mfst ocispecs.Manifest
|
||||
if err := json.Unmarshal(dt, &mfst); err != nil {
|
||||
return ""
|
||||
}
|
||||
return mfst.ArtifactType
|
||||
}
|
||||
+1
-1
@@ -12,7 +12,7 @@ import (
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.opentelemetry.io/otel/sdk"
|
||||
"go.opentelemetry.io/otel/sdk/resource"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.26.0"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
+2
-3
@@ -11,10 +11,9 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace"
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
"go.opentelemetry.io/otel/propagation"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.26.0"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
"go.opentelemetry.io/otel/trace/noop"
|
||||
)
|
||||
@@ -43,7 +42,7 @@ func FinishWithError(span trace.Span, err error) {
|
||||
if err != nil {
|
||||
span.RecordError(err)
|
||||
if hasStacktrace(err) {
|
||||
span.SetAttributes(attribute.String(string(semconv.ExceptionStacktraceKey), fmt.Sprintf("%+v", stack.Formatter(err))))
|
||||
span.SetAttributes(semconv.ExceptionStacktrace(fmt.Sprintf("%+v", stack.Formatter(err))))
|
||||
}
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
}
|
||||
|
||||
-40
@@ -36,10 +36,6 @@ import (
|
||||
const ImpliedDirectoryMode = 0o755
|
||||
|
||||
type (
|
||||
// Compression is the state represents if compressed or not.
|
||||
//
|
||||
// Deprecated: use [compression.Compression].
|
||||
Compression = compression.Compression
|
||||
// WhiteoutFormat is the format of whiteouts unpacked
|
||||
WhiteoutFormat int
|
||||
|
||||
@@ -95,14 +91,6 @@ func NewDefaultArchiver() *Archiver {
|
||||
// in order for the test to pass.
|
||||
type breakoutError error
|
||||
|
||||
const (
|
||||
Uncompressed = compression.None // Deprecated: use [compression.None].
|
||||
Bzip2 = compression.Bzip2 // Deprecated: use [compression.Bzip2].
|
||||
Gzip = compression.Gzip // Deprecated: use [compression.Gzip].
|
||||
Xz = compression.Xz // Deprecated: use [compression.Xz].
|
||||
Zstd = compression.Zstd // Deprecated: use [compression.Zstd].
|
||||
)
|
||||
|
||||
const (
|
||||
AUFSWhiteoutFormat WhiteoutFormat = 0 // AUFSWhiteoutFormat is the default format for whiteouts
|
||||
OverlayWhiteoutFormat WhiteoutFormat = 1 // OverlayWhiteoutFormat formats whiteout according to the overlay standard.
|
||||
@@ -126,27 +114,6 @@ func IsArchivePath(path string) bool {
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// DetectCompression detects the compression algorithm of the source.
|
||||
//
|
||||
// Deprecated: use [compression.Detect].
|
||||
func DetectCompression(source []byte) compression.Compression {
|
||||
return compression.Detect(source)
|
||||
}
|
||||
|
||||
// DecompressStream decompresses the archive and returns a ReaderCloser with the decompressed archive.
|
||||
//
|
||||
// Deprecated: use [compression.DecompressStream].
|
||||
func DecompressStream(archive io.Reader) (io.ReadCloser, error) {
|
||||
return compression.DecompressStream(archive)
|
||||
}
|
||||
|
||||
// CompressStream compresses the dest with specified compression algorithm.
|
||||
//
|
||||
// Deprecated: use [compression.CompressStream].
|
||||
func CompressStream(dest io.Writer, comp compression.Compression) (io.WriteCloser, error) {
|
||||
return compression.CompressStream(dest, comp)
|
||||
}
|
||||
|
||||
// TarModifierFunc is a function that can be passed to ReplaceFileTarWrapper to
|
||||
// modify the contents or header of an entry in the archive. If the file already
|
||||
// exists in the archive the TarModifierFunc will be called with the Header and
|
||||
@@ -235,13 +202,6 @@ func ReplaceFileTarWrapper(inputTarStream io.ReadCloser, mods map[string]TarModi
|
||||
return pipeReader
|
||||
}
|
||||
|
||||
// FileInfoHeaderNoLookups creates a partially-populated tar.Header from fi.
|
||||
//
|
||||
// Deprecated: use [tarheader.FileInfoHeaderNoLookups].
|
||||
func FileInfoHeaderNoLookups(fi os.FileInfo, link string) (*tar.Header, error) {
|
||||
return tarheader.FileInfoHeaderNoLookups(fi, link)
|
||||
}
|
||||
|
||||
// FileInfoHeader creates a populated Header from fi.
|
||||
//
|
||||
// Compared to the archive/tar package, this function fills in less information
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
//go:build !linux && !windows
|
||||
//go:build darwin || freebsd || netbsd
|
||||
|
||||
package archive
|
||||
|
||||
|
||||
+52
-10
@@ -111,6 +111,7 @@ func Copy(ctx context.Context, srcRoot, src, dstRoot, dst string, opts ...Opt) e
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.testHookLstat = ci.testHookLstat
|
||||
srcs := []string{src}
|
||||
|
||||
if ci.AllowWildcards {
|
||||
@@ -206,6 +207,9 @@ type CopyInfo struct {
|
||||
// replace any existing symlink or file)
|
||||
AlwaysReplaceExistingDestPaths bool
|
||||
ChangeFunc fsutil.ChangeFunc
|
||||
|
||||
// testHookLstat is called before each os.Lstat if non-nil (for testing only)
|
||||
testHookLstat func(path string)
|
||||
}
|
||||
|
||||
type Opt func(*CopyInfo)
|
||||
@@ -272,6 +276,7 @@ type copier struct {
|
||||
changefn fsutil.ChangeFunc
|
||||
root string
|
||||
alwaysReplaceExistingDestPaths bool
|
||||
testHookLstat func(string)
|
||||
}
|
||||
|
||||
type parentDir struct {
|
||||
@@ -317,6 +322,7 @@ func newCopier(root string, chown Chowner, tm *time.Time, mode *int, modeSet *mo
|
||||
excludePatternMatcher: excludePatternMatcher,
|
||||
changefn: changeFunc,
|
||||
alwaysReplaceExistingDestPaths: alwaysReplaceExistingDestPaths,
|
||||
testHookLstat: nil,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -328,16 +334,10 @@ func (c *copier) copy(ctx context.Context, src, srcComponents, target string, ov
|
||||
default:
|
||||
}
|
||||
|
||||
fi, err := os.Lstat(src)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to stat %s", src)
|
||||
}
|
||||
targetFi, err := os.Lstat(target)
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return errors.Wrapf(err, "failed to stat %s", src)
|
||||
}
|
||||
|
||||
// Check exclude patterns BEFORE calling os.Lstat to avoid permission errors
|
||||
// on inaccessible files/directories (e.g., protected Windows system folders)
|
||||
include := true
|
||||
excluded := false
|
||||
var (
|
||||
includeMatchInfo patternmatcher.MatchInfo
|
||||
excludeMatchInfo patternmatcher.MatchInfo
|
||||
@@ -345,6 +345,7 @@ func (c *copier) copy(ctx context.Context, src, srcComponents, target string, ov
|
||||
if srcComponents != "" {
|
||||
matchesIncludePattern := false
|
||||
matchesExcludePattern := false
|
||||
var err error
|
||||
matchesIncludePattern, includeMatchInfo, err = c.include(srcComponents, parentIncludeMatchInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -357,7 +358,40 @@ func (c *copier) copy(ctx context.Context, src, srcComponents, target string, ov
|
||||
}
|
||||
if matchesExcludePattern {
|
||||
include = false
|
||||
excluded = true
|
||||
}
|
||||
|
||||
// Optimization: Skip os.Lstat() for excluded paths when safe to do so.
|
||||
// We can skip Lstat if:
|
||||
// 1. The path is explicitly excluded
|
||||
// 2. There are no include patterns (no need to check children)
|
||||
// 3. There are no negation patterns in excludes (no exceptions to exclusions)
|
||||
//
|
||||
// This prevents "Access is denied" errors on Windows protected folders
|
||||
// like "System Volume Information" and "WcSandboxState".
|
||||
canSkip := !include && c.includePatternMatcher == nil &&
|
||||
(c.excludePatternMatcher == nil || !c.excludePatternMatcher.Exclusions())
|
||||
if canSkip {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
if c.testHookLstat != nil {
|
||||
c.testHookLstat(src)
|
||||
}
|
||||
fi, err := os.Lstat(src)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to stat %s", src)
|
||||
}
|
||||
|
||||
// After Lstat, if this item is excluded and is NOT a directory, skip it
|
||||
if !include && !fi.IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
targetFi, err := os.Lstat(target)
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return errors.Wrapf(err, "failed to stat %s", target)
|
||||
}
|
||||
|
||||
if include {
|
||||
@@ -388,7 +422,7 @@ func (c *copier) copy(ctx context.Context, src, srcComponents, target string, ov
|
||||
case fi.IsDir():
|
||||
if created, err := c.copyDirectory(
|
||||
ctx, src, srcComponents, target, fi, overwriteTargetMetadata,
|
||||
include, includeMatchInfo, excludeMatchInfo,
|
||||
include, excluded, includeMatchInfo, excludeMatchInfo,
|
||||
); err != nil {
|
||||
return err
|
||||
} else if !overwriteTargetMetadata {
|
||||
@@ -539,6 +573,7 @@ func (c *copier) copyDirectory(
|
||||
stat os.FileInfo,
|
||||
overwriteTargetMetadata bool,
|
||||
include bool,
|
||||
excluded bool,
|
||||
includeMatchInfo patternmatcher.MatchInfo,
|
||||
excludeMatchInfo patternmatcher.MatchInfo,
|
||||
) (bool, error) {
|
||||
@@ -577,6 +612,13 @@ func (c *copier) copyDirectory(
|
||||
c.parentDirs = c.parentDirs[:len(c.parentDirs)-1]
|
||||
}()
|
||||
|
||||
// Skip reading directory contents if explicitly excluded AND no negation patterns exist.
|
||||
// If negation patterns exist (e.g., "!bar/baz"), we must traverse excluded directories
|
||||
// to find children that might be un-excluded by the negation.
|
||||
if excluded && (c.excludePatternMatcher == nil || !c.excludePatternMatcher.Exclusions()) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
fis, err := os.ReadDir(src)
|
||||
if err != nil {
|
||||
return false, errors.Wrapf(err, "failed to read %s", src)
|
||||
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
# Semconv v1.26.0
|
||||
|
||||
[](https://pkg.go.dev/go.opentelemetry.io/otel/semconv/v1.26.0)
|
||||
-8996
File diff suppressed because it is too large
Load Diff
-9
@@ -1,9 +0,0 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package semconv implements OpenTelemetry semantic conventions.
|
||||
//
|
||||
// OpenTelemetry semantic conventions are agreed standardized naming
|
||||
// patterns for OpenTelemetry things. This package represents the v1.26.0
|
||||
// version of the OpenTelemetry semantic conventions.
|
||||
package semconv // import "go.opentelemetry.io/otel/semconv/v1.26.0"
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package semconv // import "go.opentelemetry.io/otel/semconv/v1.26.0"
|
||||
|
||||
const (
|
||||
// ExceptionEventName is the name of the Span event representing an exception.
|
||||
ExceptionEventName = "exception"
|
||||
)
|
||||
-1307
File diff suppressed because it is too large
Load Diff
-9
@@ -1,9 +0,0 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package semconv // import "go.opentelemetry.io/otel/semconv/v1.26.0"
|
||||
|
||||
// SchemaURL is the schema URL that matches the version of the semantic conventions
|
||||
// that this package defines. Semconv packages starting from v1.4.0 must declare
|
||||
// non-empty schema URL in the form https://opentelemetry.io/schemas/<version>
|
||||
const SchemaURL = "https://opentelemetry.io/schemas/1.26.0"
|
||||
Vendored
+3
-4
@@ -421,7 +421,7 @@ github.com/mitchellh/go-wordwrap
|
||||
# github.com/mitchellh/hashstructure/v2 v2.0.2
|
||||
## explicit; go 1.14
|
||||
github.com/mitchellh/hashstructure/v2
|
||||
# github.com/moby/buildkit v0.26.2
|
||||
# github.com/moby/buildkit v0.26.1-0.20260106154623-ed6dc749ce40
|
||||
## explicit; go 1.24.3
|
||||
github.com/moby/buildkit/api/services/control
|
||||
github.com/moby/buildkit/api/types
|
||||
@@ -514,7 +514,7 @@ github.com/moby/buildkit/version
|
||||
# github.com/moby/docker-image-spec v1.3.1
|
||||
## explicit; go 1.18
|
||||
github.com/moby/docker-image-spec/specs-go/v1
|
||||
# github.com/moby/go-archive v0.1.0
|
||||
# github.com/moby/go-archive v0.2.0
|
||||
## explicit; go 1.23.0
|
||||
github.com/moby/go-archive
|
||||
github.com/moby/go-archive/compression
|
||||
@@ -670,7 +670,7 @@ github.com/stretchr/testify/require
|
||||
# github.com/tonistiigi/dchapes-mode v0.0.0-20250318174251-73d941a28323
|
||||
## explicit; go 1.21
|
||||
github.com/tonistiigi/dchapes-mode
|
||||
# github.com/tonistiigi/fsutil v0.0.0-20250605211040-586307ad452f
|
||||
# github.com/tonistiigi/fsutil v0.0.0-20251211185533-a2aa163d723f
|
||||
## explicit; go 1.21
|
||||
github.com/tonistiigi/fsutil
|
||||
github.com/tonistiigi/fsutil/copy
|
||||
@@ -732,7 +732,6 @@ go.opentelemetry.io/otel/codes
|
||||
go.opentelemetry.io/otel/internal/baggage
|
||||
go.opentelemetry.io/otel/internal/global
|
||||
go.opentelemetry.io/otel/propagation
|
||||
go.opentelemetry.io/otel/semconv/v1.26.0
|
||||
go.opentelemetry.io/otel/semconv/v1.37.0
|
||||
go.opentelemetry.io/otel/semconv/v1.37.0/httpconv
|
||||
go.opentelemetry.io/otel/semconv/v1.37.0/otelconv
|
||||
|
||||
Reference in New Issue
Block a user