Skip to content

Commit

Permalink
add loopback attach support (#39)
Browse files Browse the repository at this point in the history
  • Loading branch information
jlowellwofford authored Jul 24, 2021
1 parent 65b06eb commit f8c1504
Show file tree
Hide file tree
Showing 7 changed files with 557 additions and 2 deletions.
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/kraken-hpc/imageapi
go 1.15

require (
github.com/u-root/u-root v7.0.0+incompatible
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect
github.com/bensallen/rbd v0.0.0-20210224155049-baf486eceefa
github.com/go-openapi/errors v0.20.0
Expand All @@ -24,3 +25,5 @@ require (
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987 // indirect
)

replace github.com/u-root/u-root v7.0.0+incompatible => github.com/u-root/u-root v1.0.1-0.20201119150355-04f343dd1922
125 changes: 125 additions & 0 deletions go.sum

Large diffs are not rendered by default.

96 changes: 96 additions & 0 deletions internal/api/attach_loopback.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package api

// API operations on rbd maps

import (
"os"
"path"

"github.com/kraken-hpc/imageapi/models"
"github.com/sirupsen/logrus"
"github.com/u-root/u-root/pkg/mount/loop"
)

func init() {
AttachDrivers[models.AttachKindLoopback] = &AttachDriverLoopback{}
}

type AttachDriverLoopback struct {
log *logrus.Entry
}

func (a *AttachDriverLoopback) Init(log *logrus.Entry) {
a.log = log
a.log.Trace("initialized")
}

func (a *AttachDriverLoopback) Attach(att *Attach) (ret *Attach, err error) {
// sanity check
l := a.log.WithField("operation", "attach")
if att.Loopback == nil {
l.Trace("attempted to attach loopback with no loopback definition")
return nil, ERRINVALDAT
}
l = l.WithFields(logrus.Fields{
"path": att.Loopback.Path,
"base": att.Loopback.Base,
})

base := "/"
if *att.Loopback.Base == models.MountBindBaseMount {
if att.Loopback.Mount == nil {
l.Debug("bind mount called with mount base but no mount definition")
return nil, ERRINVALDAT
}
m, err := API.Mounts.GetOrMount((*Mount)(att.Loopback.Mount))
if err != nil {
l.Error("base mount failed to GetOrMount")
return nil, ERRFAIL
}
att.Loopback.Mount = (*models.Mount)(m)
defer func() {
if err != nil {
API.Store.RefAdd(att.Loopback.Mount.ID, -1)
}
}()
base = att.Loopback.Mount.Mountpoint
}
fullPath := path.Join(base, *att.Loopback.Path)
l.WithField("fullPath", fullPath)
info, err := os.Stat(fullPath)
if err != nil {
l.Debug("loopback attach called on file that doesn't exist")
return nil, ERRINVALDAT
}
if !info.Mode().IsRegular() {
l.Debug("loopback attach call on a non-regular file")
return nil, ERRINVALDAT
}

att.DeviceFile, err = loop.FindDevice()
if err != nil {
l.WithError(err).Error("failed to acquire loopback device")
return nil, ERRFAIL
}
if err = loop.SetFile(att.DeviceFile, fullPath); err != nil {
l.WithError(err).Debug("failed to assign file to loopback device")
return nil, ERRFAIL
}

l.Info("successfully mapped")
return att, err
}

func (a *AttachDriverLoopback) Detach(att *Attach) (ret *Attach, err error) {
l := a.log.WithFields(logrus.Fields{
"operation": "unmap",
"id": att.ID,
"path": att.Loopback.Path,
"base": att.Loopback.Base,
})
if err = loop.ClearFile(att.DeviceFile); err != nil {
l.Debug("failed to clear loopback association")
return nil, ERRFAIL
}
return att, nil
}
42 changes: 42 additions & 0 deletions models/attach.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

182 changes: 182 additions & 0 deletions models/attach_loopback.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit f8c1504

Please sign in to comment.