Skip to content

Commit

Permalink
new: add host bind mounts
Browse files Browse the repository at this point in the history
Signed-off-by: Valentin Lab <[email protected]>
  • Loading branch information
vaab committed Oct 6, 2024
1 parent 293ef59 commit 50fd1df
Show file tree
Hide file tree
Showing 6 changed files with 710 additions and 616 deletions.
18 changes: 18 additions & 0 deletions client/llb/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ type mount struct {
cacheSharing CacheMountSharingMode
noOutput bool
contentCache MountContentCache
hostPath string
}

type ExecOp struct {
Expand Down Expand Up @@ -371,6 +372,10 @@ func (e *ExecOp) Marshal(ctx context.Context, c *Constraints) (digest.Digest, []
Output: int64(outputIndex),
Selector: m.selector,
}
if m.hostPath != "" {
pm.MountType = pb.MountType_HOST_BIND
pm.HostPath = m.hostPath
}
if m.cacheID != "" {
pm.MountType = pb.MountType_CACHE
pm.CacheOpt = &pb.CacheOpt{
Expand Down Expand Up @@ -505,6 +510,19 @@ func (e ExecState) AddMount(target string, source State, opt ...MountOption) Sta
return source.WithOutput(e.exec.AddMount(target, source.Output(), opt...))
}

func AddHostBindMount(dest string, hostPath string, opts ...MountOption) RunOption {
return runOptionFunc(func(ei *ExecInfo) {
mountOpts := append(opts, func(m *mount) {
m.target = dest
m.hostPath = hostPath
m.noOutput = true
m.source = nil
m.output = nil
})
ei.Mounts = append(ei.Mounts, MountInfo{dest, nil, mountOpts})
})
}

func (e ExecState) GetMount(target string) State {
return NewState(e.exec.GetMount(target))
}
Expand Down
10 changes: 10 additions & 0 deletions frontend/gateway/container/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,16 @@ func PrepareMounts(ctx context.Context, mm *mounts.MountManager, cm cache.Manage
if mountable == nil {
continue
}
case opspb.MountType_HOST_BIND:
mountable, err = mm.MountableHostBind(ctx, m, g)
if err != nil {
return p, err
}
if mountable == nil {
continue // or handle error if necessary
}
// Since this is a direct host mount, we may not need to handle outputs or cache.
// Proceed to add this mountable to the list of mounts.

default:
return p, errors.Errorf("mount type %s not implemented", m.MountType)
Expand Down
52 changes: 52 additions & 0 deletions solver/llbsolver/mounts/mount.go
Original file line number Diff line number Diff line change
Expand Up @@ -582,3 +582,55 @@ func (md CacheRefMetadata) setCacheDirIndex(id string) error {
func (md CacheRefMetadata) ClearCacheDirIndex() error {
return md.ClearValueAndIndex(keyCacheDir, cacheDirIndex)
}

func (mm *MountManager) MountableHostBind(ctx context.Context, m *pb.Mount, g session.Group) (cache.Mountable, error) {
return mm.getHostBindMountable(ctx, m, g)
}

func (mm *MountManager) getHostBindMountable(ctx context.Context, m *pb.Mount, g session.Group) (cache.Mountable, error) {
if m.HostPath == "" {
return nil, errors.Errorf("hostPath must be specified for HOST_BIND mount")
}
return &hostBindMount{
hostPath: m.HostPath,
readonly: m.Readonly,
}, nil
}

type hostBindMount struct {
hostPath string
readonly bool
}

func (hbm *hostBindMount) Mount(ctx context.Context, readonly bool, g session.Group) (snapshot.Mountable, error) {
return &hostBindMountInstance{
hostPath: hbm.hostPath,
readonly: hbm.readonly || readonly,
}, nil
}

type hostBindMountInstance struct {
hostPath string
readonly bool
}

func (hbm *hostBindMountInstance) Mount() ([]mount.Mount, func() error, error) {
options := []string{"rbind"}
if hbm.readonly {
options = append(options, "ro")
}

return []mount.Mount{
{
Type: "bind",
Source: hbm.hostPath,
Options: options,
},
}, func() error { return nil }, nil

}

// Implement IdentityMapping method
func (hbm *hostBindMountInstance) IdentityMapping() *idtools.IdentityMapping {
return nil
}
2 changes: 1 addition & 1 deletion solver/llbsolver/ops/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ func (e *ExecOp) getMountDeps() ([]dep, error) {
deps := make([]dep, e.numInputs)
for _, m := range e.op.Mounts {
switch m.MountType {
case pb.MountType_SECRET, pb.MountType_SSH, pb.MountType_TMPFS:
case pb.MountType_SECRET, pb.MountType_SSH, pb.MountType_TMPFS, pb.MountType_HOST_BIND:
continue
}

Expand Down
Loading

0 comments on commit 50fd1df

Please sign in to comment.