Skip to content

Commit

Permalink
temp
Browse files Browse the repository at this point in the history
  • Loading branch information
gargnitingoogle committed Jun 11, 2024
1 parent 153e2f6 commit d655104
Show file tree
Hide file tree
Showing 12 changed files with 42 additions and 128 deletions.
25 changes: 10 additions & 15 deletions docs/semantics.md
Original file line number Diff line number Diff line change
Expand Up @@ -378,25 +378,20 @@ Not all of the usual file system features are supported. Most prominently:
- Modification times are not tracked for any inodes except for files.
- No other times besides modification time are tracked. For example, ctime and atime are not tracked (but will be set to something reasonable). Requests to change them will appear to succeed, but the results are unspecified.

**Unsupported GCS object names**
**Unsupported object names**

GCS objects having following constraints in their name
are not accessible through GCSFuse.
Cloud Storage objects having following constraints in their name
are not accessible through Cloud Storage Fuse.

1. Names `.`, `..`, or `'' (empty-name)`, Or
1. Names beginning with `./`, `../`, or`/`, Or
1. Names containing `/./`, `/../` or `//`, or
`\0` (null-character).
1. `''` (empty-name), Or
1. Names beginning with `/`, Or
1. Names containing `//`.

The above restricted GCS objects cannot be accessed
The above objects cannot be accessed
through Cloud Storage Fuse, as these names have
special meanings in linux-based filesystems.
For example, a file/directory with path `a/./b`
is treated the same as `a/b`. Similar special
meanings exist for `a/../b` and `a//b`.
For example, a file/directory with path `a//b`
is treated the same as `a/b`.

The null-character (`\0`) is an unsupported character
in linux-based filesystems.

Any GCS objects having such names are invisible to
Any objects having such names are invisible to
(or in other words, ignored by) Cloud Storage Fuse mounts.
8 changes: 0 additions & 8 deletions internal/fs/fs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,14 +172,6 @@ func (t *fsTest) SetUpTestSuite() {

mfs, err = fuse.Mount(mntDir, server, &mountCfg)
AssertEq(nil, err)

if t.serverCfg.MountConfig != nil {
mountConfig := t.serverCfg.MountConfig
if mountConfig.LogConfig.FilePath != "" {
err = logger.InitLogFile(mountConfig.LogConfig)
AssertEq(nil, err)
}
}
}

func (t *fsTest) TearDownTestSuite() {
Expand Down
46 changes: 6 additions & 40 deletions internal/fs/implicit_dirs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import (
"syscall"
"time"

"github.com/googlecloudplatform/gcsfuse/v2/internal/config"
"github.com/googlecloudplatform/gcsfuse/v2/internal/storage/gcs"
"github.com/jacobsa/fuse/fusetesting"
. "github.com/jacobsa/oglematchers"
Expand All @@ -51,22 +50,6 @@ func init() {
func (t *ImplicitDirsTest) SetUpTestSuite() {
t.serverCfg.ImplicitDirectories = true

logfile := "/tmp/gcsfuse_logs.txt"
logConfig := config.LogConfig{
Severity: "TRACE",
Format: "text",
FilePath: logfile,
LogRotateConfig: config.LogRotateConfig{
MaxFileSizeMB: 100000,
Compress: false,
BackupFileCount: 100,
},
}
if t.serverCfg.MountConfig == nil {
t.serverCfg.MountConfig = config.NewMountConfig()
}
t.serverCfg.MountConfig.LogConfig = logConfig

t.fsTest.SetUpTestSuite()
}

Expand Down Expand Up @@ -607,15 +590,9 @@ func (t *ImplicitDirsTest) UnsupportedDirNames() {
map[string]string{
"foo//bar": "", // unsupported
"foo/1": "", // supported
// "foo/./bar": "", // unsupported
// "foo/../bar": "", // unsupported
// "foo/\000/bar": "", // unsupported
"/bar": "", // unsupported
// "./bar": "", // unsupported
// "../bar": "", // unsupported
// "\000/bar": "", // unsupported
"a/2": "", // supported
"a//3": "", // unsupported
"/bar": "", // unsupported
"a/2": "", // supported
"a//3": "", // unsupported
}))

// Statting the mount directory should return a directory entry.
Expand Down Expand Up @@ -658,21 +635,16 @@ func (t *ImplicitDirsTest) UnsupportedDirNames() {
// Create objects in implicit directories with
// unsupported names such as ., .., /, \0 and
// test that stat and ReadDirPicky on the different directories.
func (t *ImplicitDirsTest) UnsupportedDirNames_WalkDirPath() {
func (t *ImplicitDirsTest) UnsupportedDirNames_WalkDir() {
// Set up contents.
AssertEq(
nil,
t.createObjects(
map[string]string{
"a/b": "", // supported
//"foo/c": "", // supported
"a/b": "", // supported
"foo/c/d": "", // supported
"foo//e": "", // unsupported
//"foo/./f": "", // unsupported
// "foo/../g": "", // unsupported
"/h": "", // unsupported
// "./i": "", // unsupported
// "../j": "", // unsupported
"/h": "", // unsupported
}))

expectedWalkedEntries := []struct {
Expand Down Expand Up @@ -707,8 +679,6 @@ func (t *ImplicitDirsTest) UnsupportedDirNames_WalkDirPath() {

maxIters := 100
AssertEq(nil, filepath.WalkDir(mntDir, func(path string, d fs.DirEntry, err error) error {
//defer fmt.Printf("... exiting WalkFn(%q)\n", path)
//fmt.Printf("WalkFn(path=%q,d=%q,isDir=%v,err=%v) ...\n", path, d.Name(), d.IsDir(), err)
maxIters--

if err != nil {
Expand All @@ -719,10 +689,6 @@ func (t *ImplicitDirsTest) UnsupportedDirNames_WalkDirPath() {
return fmt.Errorf("walk went too deep")
}

// if d.Name() == "foo" {
// return filepath.SkipDir
// }

foundMatchingExpectedWalkingEntry := false
for i := range expectedWalkedEntries {
expectedWalkedEntry := &expectedWalkedEntries[i]
Expand Down
18 changes: 6 additions & 12 deletions internal/storage/bucket_handle.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
"github.com/googlecloudplatform/gcsfuse/v2/internal/storage/gcs"
"github.com/googlecloudplatform/gcsfuse/v2/internal/storage/storageutil"
"github.com/googlecloudplatform/gcsfuse/v2/internal/util"

"google.golang.org/api/googleapi"
"google.golang.org/api/iterator"
)
Expand Down Expand Up @@ -297,17 +298,13 @@ func (b *bucketHandle) ListObjects(ctx context.Context, req *gcs.ListObjectsRequ
IncludeFoldersAsPrefixes: req.IncludeFoldersAsPrefixes,
//MaxResults: , (Field not present in storage.Query of Go Storage Library but present in ListObjectsQuery in Jacobsa code.)
}

logger.Debugf("Calling GCS ListObjects for %#v", query)

itr := b.bucket.Objects(ctx, query) // Returning iterator to the list of objects.
pi := itr.PageInfo()
pi.MaxSize = req.MaxResults
pi.Token = req.ContinuationToken
var list gcs.Listing

// Iterating through all the objects in the bucket and one by one adding them to the list.
iter := 0
for {
var attrs *storage.ObjectAttrs

Expand All @@ -321,20 +318,17 @@ func (b *bucketHandle) ListObjects(ctx context.Context, req *gcs.ListObjectsRequ
return
}

logger.Debugf("ListObjects.response[#%d] = Prefix=\"%s\", Name=\"%s\"", iter, attrs.Prefix, attrs.Name)
iter++

// Prefix attribute will be set for the objects returned as part of Prefix[] array in list response.
// https://github.com/GoogleCloudPlatform/gcsfuse/blob/master/vendor/cloud.google.com/go/storage/storage.go#L1304
// https://github.com/GoogleCloudPlatform/gcsfuse/blob/master/vendor/cloud.google.com/go/storage/http_client.go#L370
if attrs.Prefix != "" {
if util.IsUnsupportedObjectName(attrs.Prefix) {
// Do not list unsupported directories such as '.', '..',
// '/', and '\0' as prefixes, which become implicit directories,
// Do not list unsupported directories such as those including
// '/' as prefix, which become implicit directories,
// unless there are explicit GCS objects corresponding to them.
// Unix environments see these directories
// as having special meanings e.g. a/b/../ is treated as a/, similarly,
// a/./ as a/, a//b/ as a/b/. 'a/\00/b' is not a valid substring file/directory
// as having special meanings e.g. a//b is treated as a/b.
// a/b/ is not a valid substring file/directory
// in any unix file/directory name. GCSFuse simulates the same behvaiour
// by ignoring the GCS objects which have these specially reserved/unsupported unix names/substrings.
logger.Warnf("Ignoring unsupported object-prefix: \"%s\"", attrs.Prefix)
Expand All @@ -343,7 +337,7 @@ func (b *bucketHandle) ListObjects(ctx context.Context, req *gcs.ListObjectsRequ
}
} else {
if util.IsUnsupportedObjectName(attrs.Name) {
// For GCS objects, which have the unsupported substrings i.e. //, /./, /../, \0'
// For GCS objects, which have the unsupported substrings i.e. //
// in their names, should be warned against as they can not be properly
// mapped by GCSFuse, as these are either specially reserved/unsupported
// names in unix environments.
Expand Down
33 changes: 12 additions & 21 deletions internal/storage/bucket_handle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ var ContentDisposition string = "ContentDisposition"
// https://github.com/GoogleCloudPlatform/gcsfuse/blob/master/vendor/github.com/fsouza/fake-gcs-server/fakestorage/object.go#L515

// objectsToObjectNames is a helper function which returns
// a list of string containing the names of all the
// a list of strings containing the names of all the
// GCS objects in the passed list.
// For nil objects, name is returned as nil.
// For nil objects, name is returned as <nil>.
func objectsToObjectNames(objects []*gcs.Object) (objectNames []string) {
objectNames = make([]string, len(objects))
for i, object := range objects {
Expand Down Expand Up @@ -449,19 +449,14 @@ func (testSuite *BucketHandleTest) TestListObjectMethodWithPrefixObjectExist() {
Delimiter: "/",
IncludeTrailingDelimiter: true,
ContinuationToken: "ContinuationToken",
MaxResults: 15,
MaxResults: 7,
ProjectionVal: 0,
})

assert.Nil(testSuite.T(), err)
assert.Equal(testSuite.T(), 4, len(obj.Objects))
assert.Equal(testSuite.T(), 1, len(obj.CollapsedRuns))
assert.Equal(testSuite.T(), TestObjectRootFolderName, obj.Objects[0].Name)
assert.Equal(testSuite.T(), TestObjectSubRootFolderName, obj.Objects[1].Name)
assert.Equal(testSuite.T(), TestObjectName, obj.Objects[2].Name)
assert.Equal(testSuite.T(), TestGzipObjectName, obj.Objects[3].Name)
assert.ElementsMatch(testSuite.T(), []string{TestObjectRootFolderName, TestObjectSubRootFolderName, TestObjectName, TestGzipObjectName}, objectsToObjectNames(obj.Objects))
assert.Equal(testSuite.T(), TestObjectGeneration, obj.Objects[0].Generation)
assert.Equal(testSuite.T(), TestObjectSubRootFolderName, obj.CollapsedRuns[0])
assert.ElementsMatch(testSuite.T(), []string{TestObjectSubRootFolderName}, (obj.CollapsedRuns))
}

func (testSuite *BucketHandleTest) TestListObjectMethodWithPrefixObjectDoesNotExist() {
Expand All @@ -471,7 +466,7 @@ func (testSuite *BucketHandleTest) TestListObjectMethodWithPrefixObjectDoesNotEx
Delimiter: "/",
IncludeTrailingDelimiter: true,
ContinuationToken: "ContinuationToken",
MaxResults: 15,
MaxResults: 7,
ProjectionVal: 0,
})

Expand All @@ -487,17 +482,13 @@ func (testSuite *BucketHandleTest) TestListObjectMethodWithIncludeTrailingDelimi
Delimiter: "/",
IncludeTrailingDelimiter: false,
ContinuationToken: "ContinuationToken",
MaxResults: 15,
MaxResults: 7,
ProjectionVal: 0,
})

assert.Nil(testSuite.T(), err)
assert.Equal(testSuite.T(), 3, len(obj.Objects))
assert.Equal(testSuite.T(), 1, len(obj.CollapsedRuns))
assert.Equal(testSuite.T(), TestObjectRootFolderName, obj.Objects[0].Name)
assert.Equal(testSuite.T(), TestObjectName, obj.Objects[1].Name)
assert.Equal(testSuite.T(), TestGzipObjectName, obj.Objects[2].Name)
assert.Equal(testSuite.T(), TestObjectSubRootFolderName, obj.CollapsedRuns[0])
assert.ElementsMatch(testSuite.T(), []string{TestObjectRootFolderName, TestObjectName, TestGzipObjectName}, objectsToObjectNames(obj.Objects))
assert.ElementsMatch(testSuite.T(), []string{TestObjectSubRootFolderName}, obj.CollapsedRuns)
}

// If Delimiter is empty, all the objects will appear with same prefix.
Expand All @@ -508,7 +499,7 @@ func (testSuite *BucketHandleTest) TestListObjectMethodWithEmptyDelimiter() {
Delimiter: "",
IncludeTrailingDelimiter: true,
ContinuationToken: "ContinuationToken",
MaxResults: 15,
MaxResults: 7,
ProjectionVal: 0,
})

Expand All @@ -527,7 +518,7 @@ func (testSuite *BucketHandleTest) TestListObjectMethodForMaxResult() {
Delimiter: "",
IncludeTrailingDelimiter: false,
ContinuationToken: "",
MaxResults: 15,
MaxResults: 5,
ProjectionVal: 0,
})

Expand All @@ -550,7 +541,7 @@ func (testSuite *BucketHandleTest) TestListObjectMethodForMaxResult() {
// only 1 object and 1 collapsedRuns would have been returned if
// IncludeTrailingDelimiter = false and 3 objects and 1 collapsedRuns if
// IncludeTrailingDelimiter = true.
// This is because fake storage doesn't support pagination and hence maxResults
// This is because fake storage doesn'testSuite support pagination and hence maxResults
// has no affect.
assert.Nil(testSuite.T(), err2)
assert.ElementsMatch(testSuite.T(), []string{TestObjectRootFolderName, TestGzipObjectName, TestObjectName}, objectsToObjectNames(collapsedListOfObjects.Objects))
Expand Down
5 changes: 0 additions & 5 deletions internal/storage/fake/bucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -449,8 +449,6 @@ func (b *bucket) ListObjects(
b.mu.Lock()
defer b.mu.Unlock()

//b.printAllObjectNames()

// Set up the result object.
listing = new(gcs.Listing)

Expand Down Expand Up @@ -525,9 +523,6 @@ func (b *bucket) ListObjects(

// Save the result, but only if it's not a duplicate.
resultPrefix := name[:resultPrefixLimit]

//fmt.Printf("\t\t\tresultPrefix: \"%s\"\n", resultPrefix)

if len(listing.CollapsedRuns) == 0 ||
listing.CollapsedRuns[len(listing.CollapsedRuns)-1] != resultPrefix {
listing.CollapsedRuns = append(listing.CollapsedRuns, resultPrefix)
Expand Down
2 changes: 1 addition & 1 deletion internal/storage/fake/testing/bucket_tests.go
Original file line number Diff line number Diff line change
Expand Up @@ -4459,7 +4459,7 @@ func (t *cancellationTest) ReadObject() {
ExpectLt(time.Since(before), 50*time.Millisecond)
}

func (t *cancellationTest) TestListForUnsupportedNames() {
func (t *listTest) TestListForUnsupportedNames() {
// Create several objects.
AssertEq(
nil,
Expand Down
3 changes: 1 addition & 2 deletions internal/storage/fake_storage_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ const TestObjectRootFolderName string = "gcsfuse/"
const TestObjectName string = "gcsfuse/default.txt"
const TestObjectSubRootFolderName string = "gcsfuse/SubFolder/"
const TestSubObjectName string = "gcsfuse/SubFolder/default.txt"

const TestObjectInUnsupportedFolderName string = "gcsfuse//default.txt"
const TestObjectInUnsupportedFolderName string = "gcsfuse//fileInUnsupportedDirName"
const ContentInTestObject string = "Hello GCSFuse!!!"
const ContentInTestSubObject string = "Hello GCSFuse From SubObject!!!"
const TestObjectGeneration int64 = 780
Expand Down
4 changes: 2 additions & 2 deletions internal/util/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,11 +285,11 @@ func (ts *UtilTest) TestIsUnsupportedObjectName() {
isUnsupported bool
}{
{
name: "abc",
name: "foo",
isUnsupported: false,
},
{
name: "abc.txt",
name: "foo/bar",
isUnsupported: false,
},
{
Expand Down
4 changes: 0 additions & 4 deletions tools/integration_tests/implicit_dir/list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ func TestListImplicitObjectsFromBucket(t *testing.T) {
// testBucket/dirForImplicitDirTests/explicitDirectory/fileInExplicitDir2 -- File
// testBucket/dirForImplicitDirTests/.. -- Dir
// testBucket/dirForImplicitDirTests/../fileInUnsupportedImplicitDir1 -- File
// testBucket/dirForImplicitDirTests/. -- Dir
// testBucket/dirForImplicitDirTests/./fileInUnsupportedImplicitDir2 -- File
// testBucket/dirForImplicitDirTests// -- Dir
// testBucket/dirForImplicitDirTests//fileInUnsupportedImplicitDir3 -- File

implicit_and_explicit_dir_setup.CreateImplicitDirectoryStructure(DirForImplicitDirTests)
implicit_and_explicit_dir_setup.CreateExplicitDirectoryStructure(DirForImplicitDirTests, t)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,8 @@ const FirstFileInExplicitDirectory = "fileInExplicitDir1"
const SecondFileInExplicitDirectory = "fileInExplicitDir2"
const FileInImplicitDirectory = "fileInImplicitDir1"
const FileInImplicitSubDirectory = "fileInImplicitDir2"
const UnsupportedImplicitDirectory1 = ".."
const UnsupportedImplicitDirectory1 = "/"
const FileInUnsupportedImplicitDirectory1 = "fileInUnsupportedImplicitDir1"
const UnsupportedImplicitDirectory2 = "."
const FileInUnsupportedImplicitDirectory2 = "fileInUnsupportedImplicitDir2"
const UnsupportedImplicitDirectory3 = "/"
const FileInUnsupportedImplicitDirectory3 = "fileInUnsupportedImplicitDir3"

func RunTestsForImplicitDirAndExplicitDir(flags [][]string, m *testing.M) int {
setup.ExitWithFailureIfBothTestBucketAndMountedDirectoryFlagsAreNotSet()
Expand Down Expand Up @@ -93,10 +89,6 @@ func CreateUnsupportedImplicitDirectoryStructure(testDir string) {
// Unsupported Implicit Directory Structure
// testBucket/testDir/../ -- Dir
// testBucket/testDir/../fileInUnsupportedImplicitDir1 -- File
// testBucket/testDir/. -- Dir
// testBucket/testDir/./fileInUnsupportedImplicitDir2 -- File
// testBucket/testDir// -- Dir
// testBucket/testDir//fileInUnsupportedImplicitDir3 -- File

// Create implicit directory in bucket for testing.
setup.RunScriptForTestData("../util/setup/implicit_and_explicit_dir_setup/testdata/create_objects_in_unsupported_directories.sh", path.Join(setup.TestBucket(), testDir))
Expand Down
Loading

0 comments on commit d655104

Please sign in to comment.