File: manager.go

package info (click to toggle)
singularity-container 4.1.5%2Bds4-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 43,876 kB
  • sloc: asm: 14,840; sh: 3,190; ansic: 1,751; awk: 414; makefile: 413; python: 99
file content (85 lines) | stat: -rw-r--r-- 2,505 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package source

import (
	"context"
	"strings"
	"sync"

	"github.com/moby/buildkit/cache"
	"github.com/moby/buildkit/session"
	"github.com/moby/buildkit/solver"
	"github.com/moby/buildkit/solver/pb"
	"github.com/pkg/errors"
)

// Source implementations provide "root" vertices in the graph that can be
// constructed from a URI-like string and arbitrary attrs.
type Source interface {
	// Schemes returns a list of SourceOp identifier schemes that this source
	// should match.
	Schemes() []string

	// Identifier constructs an Identifier from the given scheme, ref, and attrs,
	// all of which come from a SourceOp.
	Identifier(scheme, ref string, attrs map[string]string, platform *pb.Platform) (Identifier, error)

	// Resolve constructs an instance of the source from an Identifier.
	Resolve(ctx context.Context, id Identifier, sm *session.Manager, vtx solver.Vertex) (SourceInstance, error)
}

// SourceInstance represents a cacheable vertex created by a Source.
type SourceInstance interface {
	// CacheKey returns the cache key for the instance.
	CacheKey(ctx context.Context, g session.Group, index int) (key, pin string, opts solver.CacheOpts, done bool, err error)

	// Snapshot creates a cache ref for the instance. May return a nil ref if source points to empty content, e.g. image without any layers.
	Snapshot(ctx context.Context, g session.Group) (cache.ImmutableRef, error)
}

type Manager struct {
	mu      sync.Mutex
	schemes map[string]Source
}

func NewManager() (*Manager, error) {
	return &Manager{
		schemes: make(map[string]Source),
	}, nil
}

func (sm *Manager) Register(src Source) {
	sm.mu.Lock()
	for _, scheme := range src.Schemes() {
		sm.schemes[scheme] = src
	}
	sm.mu.Unlock()
}

func (sm *Manager) Identifier(op *pb.Op_Source, platform *pb.Platform) (Identifier, error) {
	scheme, ref, ok := strings.Cut(op.Source.Identifier, "://")
	if !ok {
		return nil, errors.Wrapf(errInvalid, "failed to parse %s", op.Source.Identifier)
	}

	sm.mu.Lock()
	source, found := sm.schemes[scheme]
	sm.mu.Unlock()

	if !found {
		return nil, errors.Wrapf(errNotFound, "unknown scheme %s", scheme)
	}

	return source.Identifier(scheme, ref, op.Source.Attrs, platform)
}

func (sm *Manager) Resolve(ctx context.Context, id Identifier, sessM *session.Manager, vtx solver.Vertex) (SourceInstance, error) {
	sm.mu.Lock()
	src, ok := sm.schemes[id.Scheme()]
	sm.mu.Unlock()

	if !ok {
		return nil, errors.Errorf("no handler for %s", id.Scheme())
	}

	return src.Resolve(ctx, id, sessM, vtx)
}