Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

S3FS storage driver #397

Closed
wants to merge 1 commit into from
Closed

Conversation

alexey-mr
Copy link

@alexey-mr alexey-mr commented Jan 23, 2017

This is the draft implementation, or proof-of-concent (POC), of the s3fs storage driver that enables the mounting of S3 buckets via FUSE.

Restrictions

The current implementation has the following restrictions:

  • The driver does not support volume creation
  • The driver does not support volume removal

Next Steps

  • Add more options in mounting (e.g. region, now it uses default one)
  • Add ability to mount a sub-path in bucket (bucket:/somepath). In that case volumes are inside of a bucket (allowed in config), e.g. bucket:/volume1, bucket:/volume2, etc. Create|remove volume operations could just create|remove appropriate 'path' in S3 (say, via creation of a hidden object, e.g. bucket:/volume1/.volume1)
  • Add buckets management via S3 rest api (create|remove in volume create|remove operation). But it is discussable - because buckets are limited resource in S3. Probably it is not to do it until it is requested by someone.

"github.com/codedellemc/libstorage/drivers/storage/s3fs"
)

func Supported(ctx types.Context) (bool, error) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exported function Supported should have comment or be unexported

"github.com/codedellemc/libstorage/drivers/storage/s3fs"
)

func Supported(ctx types.Context) (bool, error) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exported function Supported should have comment or be unexported

// Name is the provider's name.
Name = "s3fs"

// Name of the cmd utility

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment on exported const CmdName should be of the form "CmdName ..."

// Name is the provider's name.
Name = "s3fs"

// Name of the cmd utility

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment on exported const CmdName should be of the form "CmdName ..."

return isDeviceUriSupported(d.name, device)
}

func (d *s3fsDriver) getBucketFromUri(uri string) string {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

func getBucketFromUri should be getBucketFromURI

return isDeviceUriSupported(d.name, device)
}

func (d *s3fsDriver) getBucketFromUri(uri string) string {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

func getBucketFromUri should be getBucketFromURI

if mp == mountPoint {
// bucket is mounted to the required target => ok
return nil
} else {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if block ends with a return statement, so drop this else and outdent its block

if mp == mountPoint {
// bucket is mounted to the required target => ok
return nil
} else {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if block ends with a return statement, so drop this else and outdent its block

const (
Name = "s3fs"
s3fsCmdName = "s3fs"
s3fsUriPrefix = Name + "://"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const s3fsUriPrefix should be s3fsURIPrefix

const (
Name = "s3fs"
s3fsCmdName = "s3fs"
s3fsUriPrefix = Name + "://"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const s3fsUriPrefix should be s3fsURIPrefix

)

const (
Name = "s3fs"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exported const Name should have comment (or a comment on this block) or be unexported

)

const (
Name = "s3fs"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exported const Name should have comment (or a comment on this block) or be unexported

return strings.Split(device, ":")[0]
}

func makeDeviceUri(driver, device string) string {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

func makeDeviceUri should be makeDeviceURI

return strings.Split(device, ":")[0]
}

func makeDeviceUri(driver, device string) string {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

func makeDeviceUri should be makeDeviceURI

return strings.TrimPrefix(device, fmt.Sprintf("%s://", name))
}

func getNameFromDeviceUri(device string) string {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

func getNameFromDeviceUri should be getNameFromDeviceURI

return strings.TrimPrefix(device, fmt.Sprintf("%s://", name))
}

func getNameFromDeviceUri(device string) string {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

func getNameFromDeviceUri should be getNameFromDeviceURI

return strings.HasPrefix(device, fmt.Sprintf("%s://", name))
}

func getPathFromDeviceUri(name, device string) string {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

func getPathFromDeviceUri should be getPathFromDeviceURI

return strings.HasPrefix(device, fmt.Sprintf("%s://", name))
}

func getPathFromDeviceUri(name, device string) string {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

func getPathFromDeviceUri should be getPathFromDeviceURI

}

// Help functions to operate with device uri
func isDeviceUriSupported(name, device string) bool {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

func isDeviceUriSupported should be isDeviceURISupported

}

// Help functions to operate with device uri
func isDeviceUriSupported(name, device string) bool {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

func isDeviceUriSupported should be isDeviceURISupported

"github.com/codedellemc/libstorage/api/types"
)

// Function to construct new MountDriver objects

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment on exported type NewMountDriver should be of the form "NewMountDriver ..." (with optional leading article)

"github.com/codedellemc/libstorage/api/types"
)

// Function to construct new MountDriver objects

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment on exported type NewMountDriver should be of the form "NewMountDriver ..." (with optional leading article)

@codecov-io
Copy link

codecov-io commented Jan 23, 2017

Codecov Report

Merging #397 into master will not impact coverage.

@@           Coverage Diff           @@
##           master     #397   +/-   ##
=======================================
  Coverage   30.47%   30.47%           
=======================================
  Files          29       29           
  Lines        1739     1739           
=======================================
  Hits          530      530           
  Misses       1151     1151           
  Partials       58       58

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d6d9f13...ba2a8a3. Read the comment docs.

@CLAassistant
Copy link

CLAassistant commented Jan 23, 2017

CLA assistant check
All committers have signed the CLA.

@akutz akutz changed the title S3FS fuse support WiP - S3FS fuse support Jan 24, 2017
@akutz akutz added the s3fs label Jan 24, 2017
@akutz akutz self-assigned this Jan 24, 2017
@akutz
Copy link
Collaborator

akutz commented Jan 24, 2017

Hi @alexey-mr,

Thank you for this PR. I like the idea of a mount driver; in fact it's been something we've discussed a few times internally due to other driver requirements. Two notes about the way that it's been implemented in this PR:

  1. A mount driver should not require its own registry implementation -- it should reuse the central registry.
  2. I do not think this should be a driver at all, rather a new function of the executor.

If it's okay with you, I'd like to go ahead and rewrite the new mount driver for the s3fs driver as part of the executor logic. You're free to do so as well, but I also do not mind.

Thoughts so far?

Beyond my comments on the mount driver, I am currently reviewing the rest of the code in the PR. My only other immediate note is that I would like to see the PR's commits squashed and rebased. Thank you.

// so, it is workaround to patch Source info
// Another option - use moinPoint to filter mounts into
// the integration driver logic and remove this patching
d.patchMounts(ctx, &mounts)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @codenrhoden,

Can you please take a look at the suggested PatchMountInfo function as well as the implementation of it in this PR and tell me if I'm crazy, but I think we should take the other option @alexey-mr suggests and relocate this to the integration driver here.

If I'm following all of the code correctly, it appears that the patching/lookup should really be occurring in the LocalDevices function of the executor so that the Libstorage-Localdevices map is initialized properly when sent to the server and thus the returned volumes have the mappings correctly set. That would mean the correct device name and source should be set when used in the integration driver.

Thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@akutz I agree that the patching should happen in the executors LocalDevices(). I am not following, however, what would need to be added to the integration driver that is related to this... I feel like I should see it, but I don't.

With your work to add mount/unmount functionality capability to the executors, what would need to be added to the integration driver? I'm assuming a check to see if the volume we are working with needs to be mounted via executor, or one of our existing "standard" mount functions, but is there anything else related to the patching of mount info?

@akutz akutz changed the title WiP - S3FS fuse support S3FS storage driver Jan 26, 2017
return buckets, nil
}

func Mount(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exported function Mount should have comment or be unexported

return nil, err
}
var buckets []string
for b, _ := range bucketsMap {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should omit 2nd value from range; this loop is equivalent to for b := range ...

s3fs allows to mount S3 buckets via FUSE.
It can't create new buckets, so this first impl of
the s3fs storage driver doesn't create/remove volumes actually.
It uses list of buckets that could be used for mounting
from config file. These buckets are returned as volumes and
are available for mount/unmount operations.
@alexey-mr
Copy link
Author

Hi @akutz, I reworked it according updated executor's interface. Now patching of mountinfo.Source is moved in LocalDevices of s3fs executor... But if I understand correctly somethingelse should be done additionally to make it work, because Mounts() (in integration driver) doesnt call LocalDevices from storage driver executors.

@akutz
Copy link
Collaborator

akutz commented Feb 7, 2017

Hi @alexey-mr,

Thank you again for your work on this. In light of recent changes and in order to close this out, I'm taking ownership of it at #409. Thank you again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants