Skip to content

Commit

Permalink
wip: fix azure storage path to use leading slash
Browse files Browse the repository at this point in the history
  • Loading branch information
flavianmissi committed Feb 8, 2024
1 parent c7be7b4 commit fd7983d
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 16 deletions.
40 changes: 25 additions & 15 deletions registry/storage/driver/azure/azure.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ func (d *driver) Reader(ctx context.Context, path string, offset int64) (io.Read
// at the location designated by "path" after the call to Commit.
func (d *driver) Writer(ctx context.Context, path string, append bool) (storagedriver.FileWriter, error) {
blobName := d.blobName(path)
fmt.Println("Writer blobName:", blobName)
blobRef := d.client.NewBlobClient(blobName)

props, err := blobRef.GetProperties(ctx, nil)
Expand Down Expand Up @@ -258,6 +259,7 @@ func (d *driver) Stat(ctx context.Context, path string) (storagedriver.FileInfo,
// List returns a list of the objects that are direct descendants of the given
// path.
func (d *driver) List(ctx context.Context, path string) ([]string, error) {
// the base storage driver errors if the given path is ""
if path == "/" {
path = ""
}
Expand Down Expand Up @@ -372,18 +374,23 @@ func (d *driver) Walk(ctx context.Context, path string, f storagedriver.WalkFn)
// Example: direct descendants of "/" in {"/foo", "/bar/1", "/bar/2"} is
// {"/foo", "/bar"} and direct descendants of "bar" is {"/bar/1", "/bar/2"}
func directDescendants(blobs []string, prefix string) []string {
if !strings.HasPrefix(prefix, "/") { // add trailing '/'
if !strings.HasPrefix(prefix, "/") { // add leading '/'
prefix = "/" + prefix
}
if !strings.HasSuffix(prefix, "/") { // containerify the path
prefix += "/"
}

out := make(map[string]bool)
// fmt.Println("directDescendants: prefix is:", prefix)
for _, b := range blobs {
// fmt.Println("directDescendants: analyzing blob", b)
if strings.HasPrefix(b, prefix) {
// fmt.Println("blob", b, "has prefix", prefix)
rel := b[len(prefix):]
c := strings.Count(rel, "/")
// fmt.Println("rel is", rel)
// fmt.Println("c is", c)
if c == 0 {
out[b] = true
} else {
Expand All @@ -400,24 +407,15 @@ func directDescendants(blobs []string, prefix string) []string {
}

func (d *driver) listBlobs(ctx context.Context, virtPath string) ([]string, error) {
// we want the path to end in a "/" (not sure why), so if it's not empty
// and it doesn't already end in one, add it.
if virtPath != "" && !strings.HasSuffix(virtPath, "/") { // containerify the path
virtPath += "/"
}

// we will replace the root directory prefix before returning blob names
blobPrefix := d.blobName("")

// This is to cover for the cases when the rootDirectory of the driver is either "" or "/".
// In those cases, there is no root prefix to replace and we must actually add a "/" to all
// results in order to keep them as valid paths as recognized by storagedriver.PathRegexp
prefix := ""
if blobPrefix == "" {
prefix = "/"
}

out := []string{}

listPrefix := d.blobName(virtPath)

pager := d.client.NewListBlobsFlatPager(&container.ListBlobsFlatOptions{
Prefix: &listPrefix,
})
Expand All @@ -431,10 +429,20 @@ func (d *driver) listBlobs(ctx context.Context, virtPath string) ([]string, erro
return nil, fmt.Errorf("required blob property Name is missing while listing blobs under: %s", listPrefix)
}
name := *blob.Name
out = append(out, strings.Replace(name, blobPrefix, prefix, 1))

// This is to cover for the cases when the rootDirectory of the driver is either "" or "/".
// In those cases, there is no root prefix to replace and we must actually add a "/" to all
// results in order to keep them as valid paths as recognized by storagedriver.PathRegexp
if !strings.HasPrefix(name, "/") { // add leading '/'
name = "/" + name
}
out = append(out, name)
}
}

// fmt.Println("listBlob out's len is:", len(out))
// fmt.Println("listBlob out[0] is:", out[0])

return out, nil
}

Expand All @@ -446,7 +454,9 @@ func (d *driver) blobName(path string) string {
return path
}

return strings.TrimLeft(strings.TrimRight(d.rootDirectory, "/")+path, "/")
trimmedRoot := strings.TrimRight(d.rootDirectory, "/")
trimmedPath := strings.TrimLeft(path, "/")
return trimmedRoot + "/" + trimmedPath
}

func is404(err error) bool {
Expand Down
58 changes: 58 additions & 0 deletions registry/storage/driver/azure/azure_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,64 @@ func randStringRunes(n int) string {
return string(b)
}

func writeBlob(ctx context.Context, driver storagedriver.StorageDriver, contents, path string, append_ bool) error {
writer, err := driver.Writer(ctx, path, append_)
if err != nil {
return fmt.Errorf("unexpected error from driver.Writer: %v", err)
}
_, err = writer.Write([]byte(contents))
if err != nil {
return fmt.Errorf("writer.Write: unexpected error: %v", err)
}

err = writer.Commit()
if err != nil {
return fmt.Errorf("writer.Commit: unexpected error: %v", err)
}
err = writer.Close()
if err != nil {
return fmt.Errorf("writer.Close: unexpected error: %v", err)
}
return nil
}

func TestListBlobs(t *testing.T) {
driver, err := azureDriverConstructor()
if err != nil {
t.Fatalf("unexpected error creating azure driver: %v", err)
}

contents := randStringRunes(4 * 1024 * 1024)
path := "/file"
ctx := context.Background()

defer driver.Delete(ctx, path)
if err := writeBlob(ctx, driver, contents, path, false); err != nil {
t.Fatal(err)
}

blobNames, err := driver.List(ctx, "/")
if err != nil {
t.Fatalf("driver.List: unexpected error: %v", err)
}

if len(blobNames) == 0 {
t.Fatalf("blob %q was not listed! driver.List returned 0 blobs!", path)
}

found := false
for _, blobName := range blobNames {
if blobName == path {
found = true
break
}
fmt.Println("TestListBlobs blobName", blobName, "did not match path", path)
}
if !found {
t.Fatalf("blob %q was not listed!", path)
}
}

func TestCommitAfterMove(t *testing.T) {
driver, err := azureDriverConstructor()
if err != nil {
Expand Down

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

0 comments on commit fd7983d

Please sign in to comment.