allow dynamic LocalDir access

Changes the filesync attachable to accept an interface instead of a
static allowlist of dirs. This way a single session can support syncing
directories not known ahead of time.

Signed-off-by: Alex Suraci <suraci.alex@gmail.com>
This commit is contained in:
Alex Suraci
2022-10-26 18:31:14 -04:00
parent 46f6f51822
commit 3548517cf2
3 changed files with 23 additions and 15 deletions

View File

@@ -355,7 +355,7 @@ func (c *Client) solve(ctx context.Context, def *llb.Definition, runGateway runG
return res, nil
}
func prepareSyncedDirs(def *llb.Definition, localDirs map[string]string) ([]filesync.SyncedDir, error) {
func prepareSyncedDirs(def *llb.Definition, localDirs map[string]string) (filesync.StaticDirSource, error) {
for _, d := range localDirs {
fi, err := os.Stat(d)
if err != nil {
@@ -371,10 +371,10 @@ func prepareSyncedDirs(def *llb.Definition, localDirs map[string]string) ([]file
return fsutil.MapResultKeep
}
dirs := make([]filesync.SyncedDir, 0, len(localDirs))
dirs := make(filesync.StaticDirSource, len(localDirs))
if def == nil {
for name, d := range localDirs {
dirs = append(dirs, filesync.SyncedDir{Name: name, Dir: d, Map: resetUIDAndGID})
dirs[name] = filesync.SyncedDir{Dir: d, Map: resetUIDAndGID}
}
} else {
for _, dt := range def.Def {
@@ -389,7 +389,7 @@ func prepareSyncedDirs(def *llb.Definition, localDirs map[string]string) ([]file
if !ok {
return nil, errors.Errorf("local directory %s not enabled", name)
}
dirs = append(dirs, filesync.SyncedDir{Name: name, Dir: d, Map: resetUIDAndGID})
dirs[name] = filesync.SyncedDir{Dir: d, Map: resetUIDAndGID}
}
}
}

View File

@@ -27,27 +27,35 @@ const (
)
type fsSyncProvider struct {
dirs map[string]SyncedDir
dirs DirSource
p progressCb
doneCh chan error
}
type SyncedDir struct {
Name string
Dir string
Excludes []string
Map func(string, *fstypes.Stat) fsutil.MapResult
}
type DirSource interface {
LookupDir(string) (SyncedDir, bool)
}
type StaticDirSource map[string]SyncedDir
var _ DirSource = StaticDirSource{}
func (dirs StaticDirSource) LookupDir(name string) (SyncedDir, bool) {
dir, found := dirs[name]
return dir, found
}
// NewFSSyncProvider creates a new provider for sending files from client
func NewFSSyncProvider(dirs []SyncedDir) session.Attachable {
p := &fsSyncProvider{
dirs: map[string]SyncedDir{},
func NewFSSyncProvider(dirs DirSource) session.Attachable {
return &fsSyncProvider{
dirs: dirs,
}
for _, d := range dirs {
p.dirs[d.Name] = d
}
return p
}
func (sp *fsSyncProvider) Register(server *grpc.Server) {
@@ -81,7 +89,7 @@ func (sp *fsSyncProvider) handle(method string, stream grpc.ServerStream) (retEr
dirName = name[0]
}
dir, ok := sp.dirs[dirName]
dir, ok := sp.dirs.LookupDir(dirName)
if !ok {
return InvalidSessionError{status.Errorf(codes.NotFound, "no access allowed to dir %q", dirName)}
}

View File

@@ -32,7 +32,7 @@ func TestFileSyncIncludePatterns(t *testing.T) {
m, err := session.NewManager()
require.NoError(t, err)
fs := NewFSSyncProvider([]SyncedDir{{Name: "test0", Dir: tmpDir}})
fs := NewFSSyncProvider(StaticDirSource{"test0": {Dir: tmpDir}})
s.Allow(fs)
dialer := session.Dialer(testutil.TestStream(testutil.Handler(m.HandleConn)))