Beispiel #1
0
// Stat retrieves the FileInfo for the given path, including the current size
// in bytes and the creation time.
func (d *driver) Stat(ctx context.Context, path string) (storagedriver.FileInfo, error) {
	listResponse, err := d.Bucket.List(d.s3Path(path), "", "", 1)
	if err != nil {
		return nil, err
	}

	fi := storagedriver.FileInfoFields{
		Path: path,
	}

	if len(listResponse.Contents) == 1 {
		if listResponse.Contents[0].Key != d.s3Path(path) {
			fi.IsDir = true
		} else {
			fi.IsDir = false
			fi.Size = listResponse.Contents[0].Size

			timestamp, err := time.Parse(time.RFC3339Nano, listResponse.Contents[0].LastModified)
			if err != nil {
				return nil, err
			}
			fi.ModTime = timestamp
		}
	} else if len(listResponse.CommonPrefixes) == 1 {
		fi.IsDir = true
	} else {
		return nil, storagedriver.PathNotFoundError{Path: path}
	}

	return storagedriver.FileInfoInternal{FileInfoFields: fi}, nil
}
Beispiel #2
0
// Stat retrieves the FileInfo for the given path, including the current size
// in bytes and the creation time.
func (d *driver) Stat(ctx context.Context, path string) (storagedriver.FileInfo, error) {
	resp, err := d.S3.ListObjects(&s3.ListObjectsInput{
		Bucket:  aws.String(d.Bucket),
		Prefix:  aws.String(d.s3Path(path)),
		MaxKeys: aws.Int64(1),
	})
	if err != nil {
		return nil, err
	}

	fi := storagedriver.FileInfoFields{
		Path: path,
	}

	if len(resp.Contents) == 1 {
		if *resp.Contents[0].Key != d.s3Path(path) {
			fi.IsDir = true
		} else {
			fi.IsDir = false
			fi.Size = *resp.Contents[0].Size
			fi.ModTime = *resp.Contents[0].LastModified
		}
	} else if len(resp.CommonPrefixes) == 1 {
		fi.IsDir = true
	} else {
		return nil, storagedriver.PathNotFoundError{Path: path}
	}

	return storagedriver.FileInfoInternal{FileInfoFields: fi}, nil
}
Beispiel #3
0
// Stat retrieves the FileInfo for the given path, including the current
// size in bytes and the creation time.
func (d *driver) Stat(ctx context.Context, path string) (storagedriver.FileInfo, error) {

	items, _, _, err := d.bucket.List(ctx, d.getKey(path), "", "", 1)
	if err != nil {
		if err != io.EOF {
			return nil, err
		}
		err = nil
	}

	if len(items) == 0 {
		return nil, storagedriver.PathNotFoundError{Path: path}
	}

	item := items[0]

	fi := storagedriver.FileInfoFields{
		Path: path,
	}

	if d.getKey(path) != item.Key {
		fi.IsDir = true
	}

	if !fi.IsDir {
		fi.Size = item.Fsize
		fi.ModTime = time.Unix(0, item.PutTime*100)
	}

	return storagedriver.FileInfoInternal{FileInfoFields: fi}, nil
}
Beispiel #4
0
// Stat retrieves the FileInfo for the given path, including the current size
// in bytes and the creation time.
func (d *driver) Stat(ctx context.Context, path string) (storagedriver.FileInfo, error) {
	swiftPath := d.swiftPath(path)
	opts := &swift.ObjectsOpts{
		Prefix:    swiftPath,
		Delimiter: '/',
	}

	objects, err := d.Conn.ObjectsAll(d.Container, opts)
	if err != nil {
		if err == swift.ContainerNotFound {
			return nil, storagedriver.PathNotFoundError{Path: path}
		}
		return nil, err
	}

	fi := storagedriver.FileInfoFields{
		Path: strings.TrimPrefix(strings.TrimSuffix(swiftPath, "/"), d.swiftPath("/")),
	}

	for _, obj := range objects {
		if obj.PseudoDirectory && obj.Name == swiftPath+"/" {
			fi.IsDir = true
			return storagedriver.FileInfoInternal{FileInfoFields: fi}, nil
		} else if obj.Name == swiftPath {
			// The file exists. But on Swift 1.12, the 'bytes' field is always 0 so
			// we need to do a separate HEAD request.
			break
		}
	}

	//Don't trust an empty `objects` slice. A container listing can be
	//outdated. For files, we can make a HEAD request on the object which
	//reports existence (at least) much more reliably.
	info, _, err := d.Conn.Object(d.Container, swiftPath)
	if err != nil {
		if err == swift.ObjectNotFound {
			return nil, storagedriver.PathNotFoundError{Path: path}
		}
		return nil, err
	}
	fi.IsDir = false
	fi.Size = info.Bytes
	fi.ModTime = info.LastModified
	return storagedriver.FileInfoInternal{FileInfoFields: fi}, nil
}
Beispiel #5
0
// Stat retrieves the FileInfo for the given path, including the current size
// in bytes and the creation time.
func (d *driver) Stat(ctx context.Context, path string) (storagedriver.FileInfo, error) {
	swiftPath := d.swiftPath(path)
	opts := &swift.ObjectsOpts{
		Prefix:    swiftPath,
		Delimiter: '/',
	}

	objects, err := d.Conn.ObjectsAll(d.Container, opts)
	if err != nil {
		if err == swift.ContainerNotFound {
			return nil, storagedriver.PathNotFoundError{Path: path}
		}
		return nil, err
	}

	fi := storagedriver.FileInfoFields{
		Path: strings.TrimPrefix(strings.TrimSuffix(swiftPath, "/"), d.swiftPath("/")),
	}

	for _, obj := range objects {
		if obj.PseudoDirectory && obj.Name == swiftPath+"/" {
			fi.IsDir = true
			return storagedriver.FileInfoInternal{FileInfoFields: fi}, nil
		} else if obj.Name == swiftPath {
			// On Swift 1.12, the 'bytes' field is always 0
			// so we need to do a second HEAD request
			info, _, err := d.Conn.Object(d.Container, swiftPath)
			if err != nil {
				if err == swift.ObjectNotFound {
					return nil, storagedriver.PathNotFoundError{Path: path}
				}
				return nil, err
			}
			fi.IsDir = false
			fi.Size = info.Bytes
			fi.ModTime = info.LastModified
			return storagedriver.FileInfoInternal{FileInfoFields: fi}, nil
		}
	}

	return nil, storagedriver.PathNotFoundError{Path: path}
}
Beispiel #6
0
// Stat retrieves the FileInfo for the given path, including the current size
func (d *driver) Stat(ctx context.Context, path string) (storagedriver.FileInfo, error) {
	fi := storagedriver.FileInfoFields{
		Path: path,
	}

	res, err := d.Client.ListObjects(d.bucketName, nil, nil, nil, path)
	if err != nil {
		return nil, storagedriver.PathNotFoundError{Path: path}
	}

	if len(res.Contents) < 1 {
		return nil, storagedriver.PathNotFoundError{Path: path}
	} else if len(res.Contents) > 1 {
		fi.IsDir = true
	} else {
		fi.IsDir = false
		fi.Size = res.Contents[0].Size
		//fi.Size, _ = strconv.ParseInt(res1["Size"], 10, 64)
	}
	return storagedriver.FileInfoInternal{FileInfoFields: fi}, nil
}
Beispiel #7
0
// Stat retrieves the FileInfo for the given path, including the current size
// in bytes and the creation time.
func (d *driver) Stat(ctx context.Context, path string) (storagedriver.FileInfo, error) {
	swiftPath := d.swiftPath(path)
	opts := &swift.ObjectsOpts{
		Prefix:    swiftPath,
		Delimiter: '/',
	}

	objects, err := d.Conn.ObjectsAll(d.Container, opts)
	if err != nil {
		if err == swift.ContainerNotFound {
			return nil, storagedriver.PathNotFoundError{Path: path}
		}
		return nil, err
	}

	fi := storagedriver.FileInfoFields{
		Path: strings.TrimPrefix(strings.TrimSuffix(swiftPath, "/"), d.swiftPath("/")),
	}

	for _, obj := range objects {
		if obj.PseudoDirectory && obj.Name == swiftPath+"/" {
			fi.IsDir = true
			return storagedriver.FileInfoInternal{FileInfoFields: fi}, nil
		} else if obj.Name == swiftPath {
			// The file exists. But on Swift 1.12, the 'bytes' field is always 0 so
			// we need to do a separate HEAD request.
			break
		}
	}

	//Don't trust an empty `objects` slice. A container listing can be
	//outdated. For files, we can make a HEAD request on the object which
	//reports existence (at least) much more reliably.
	waitingTime := readAfterWriteWait
	endTime := time.Now().Add(readAfterWriteTimeout)

	for {
		info, headers, err := d.Conn.Object(d.Container, swiftPath)
		if err != nil {
			if err == swift.ObjectNotFound {
				return nil, storagedriver.PathNotFoundError{Path: path}
			}
			return nil, err
		}

		//if this is a DLO and it is clear that segments are still missing,
		//wait until they show up
		_, isDLO := headers["X-Object-Manifest"]
		if isDLO && info.Bytes == 0 {
			if time.Now().Add(waitingTime).After(endTime) {
				return nil, fmt.Errorf("Timeout expired while waiting for segments of %s to show up", path)
			}
			time.Sleep(waitingTime)
			waitingTime *= 2
			continue
		}

		//otherwise, accept the result
		fi.IsDir = false
		fi.Size = info.Bytes
		fi.ModTime = info.LastModified
		return storagedriver.FileInfoInternal{FileInfoFields: fi}, nil
	}
}