mirror of
https://github.com/moby/buildkit.git
synced 2026-06-30 19:57:39 +00:00
source: add local file source fundamentals
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
This commit is contained in:
@@ -15,6 +15,7 @@ var (
|
||||
const (
|
||||
DockerImageScheme = "docker-image"
|
||||
GitScheme = "git"
|
||||
LocalScheme = "local"
|
||||
)
|
||||
|
||||
type Identifier interface {
|
||||
@@ -33,6 +34,8 @@ func FromString(s string) (Identifier, error) {
|
||||
return NewImageIdentifier(parts[1])
|
||||
case GitScheme:
|
||||
return NewGitIdentifier(parts[1])
|
||||
case LocalScheme:
|
||||
return NewLocalIdentifier(parts[1])
|
||||
default:
|
||||
return nil, errors.Wrapf(errNotFound, "unknown schema %s", parts[0])
|
||||
}
|
||||
@@ -54,6 +57,19 @@ func NewImageIdentifier(str string) (*ImageIdentifier, error) {
|
||||
return &ImageIdentifier{Reference: ref}, nil
|
||||
}
|
||||
|
||||
func (i *ImageIdentifier) ID() string {
|
||||
func (_ *ImageIdentifier) ID() string {
|
||||
return DockerImageScheme
|
||||
}
|
||||
|
||||
type LocalIdentifier struct {
|
||||
Name string
|
||||
SessionID string
|
||||
}
|
||||
|
||||
func NewLocalIdentifier(str string) (*LocalIdentifier, error) {
|
||||
return &LocalIdentifier{Name: str}, nil
|
||||
}
|
||||
|
||||
func (_ *LocalIdentifier) ID() string {
|
||||
return LocalScheme
|
||||
}
|
||||
|
||||
138
source/local/local.go
Normal file
138
source/local/local.go
Normal file
@@ -0,0 +1,138 @@
|
||||
package local
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/moby/buildkit/cache"
|
||||
"github.com/moby/buildkit/session"
|
||||
"github.com/moby/buildkit/session/filesync"
|
||||
"github.com/moby/buildkit/snapshot"
|
||||
"github.com/moby/buildkit/source"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
type Opt struct {
|
||||
SessionManager *session.Manager
|
||||
CacheAccessor cache.Accessor
|
||||
}
|
||||
|
||||
func NewSource(opt Opt) (source.Source, error) {
|
||||
ls := &localSource{
|
||||
sm: opt.SessionManager,
|
||||
cm: opt.CacheAccessor,
|
||||
}
|
||||
return ls, nil
|
||||
}
|
||||
|
||||
type localSource struct {
|
||||
sm *session.Manager
|
||||
cm cache.Accessor
|
||||
}
|
||||
|
||||
func (ls *localSource) ID() string {
|
||||
return source.LocalScheme
|
||||
}
|
||||
|
||||
func (ls *localSource) Resolve(ctx context.Context, id source.Identifier) (source.SourceInstance, error) {
|
||||
localIdentifier, ok := id.(*source.LocalIdentifier)
|
||||
if !ok {
|
||||
return nil, errors.Errorf("invalid local identifier %v", id)
|
||||
}
|
||||
|
||||
return &localSourceHandler{
|
||||
src: *localIdentifier,
|
||||
localSource: ls,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type localSourceHandler struct {
|
||||
src source.LocalIdentifier
|
||||
*localSource
|
||||
}
|
||||
|
||||
func (ls *localSourceHandler) CacheKey(ctx context.Context) (string, error) {
|
||||
sessionID := ls.src.SessionID
|
||||
|
||||
if sessionID == "" {
|
||||
uuid := session.FromContext(ctx)
|
||||
if uuid == "" {
|
||||
return "", errors.New("could not access local files without session")
|
||||
}
|
||||
sessionID = uuid
|
||||
}
|
||||
|
||||
return "session:" + ls.src.Name + ":" + sessionID, nil
|
||||
}
|
||||
|
||||
func (ls *localSourceHandler) Snapshot(ctx context.Context) (out cache.ImmutableRef, retErr error) {
|
||||
|
||||
uuid := session.FromContext(ctx)
|
||||
if uuid == "" {
|
||||
return nil, errors.New("could not access local files without session")
|
||||
}
|
||||
|
||||
timeoutCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
caller, err := ls.sm.Get(timeoutCtx, uuid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mutable, err := ls.cm.New(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if retErr != nil && mutable != nil {
|
||||
s, err := mutable.Freeze()
|
||||
if err == nil {
|
||||
go s.Release(context.TODO())
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
mount, err := mutable.Mount(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
lm := snapshot.LocalMounter(mount)
|
||||
|
||||
dest, err := lm.Mount()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if retErr != nil && lm != nil {
|
||||
lm.Unmount()
|
||||
}
|
||||
}()
|
||||
|
||||
opt := filesync.FSSendRequestOpt{
|
||||
IncludePatterns: nil,
|
||||
OverrideExcludes: false,
|
||||
DestDir: dest,
|
||||
CacheUpdater: nil,
|
||||
}
|
||||
|
||||
if err := filesync.FSSync(ctx, caller, opt); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := lm.Unmount(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lm = nil
|
||||
|
||||
snap, err := mutable.ReleaseAndCommit(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mutable = nil
|
||||
|
||||
return snap, err
|
||||
}
|
||||
Reference in New Issue
Block a user