9af4f26d43
Co-authored-by: paul cannon <thepaul@users.noreply.github.com> Co-authored-by: Kaloyan Raev <kaloyan-raev@users.noreply.github.com>
148 lines
4.2 KiB
Go
148 lines
4.2 KiB
Go
// Copyright (C) 2019 Storj Labs, Inc.
|
|
// See LICENSE for copying information.
|
|
|
|
package uplink
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
"time"
|
|
|
|
"github.com/zeebo/errs"
|
|
|
|
"storj.io/storj/pkg/metainfo/kvmetainfo"
|
|
"storj.io/storj/pkg/storage/streams"
|
|
"storj.io/storj/pkg/storj"
|
|
"storj.io/storj/pkg/stream"
|
|
)
|
|
|
|
// Bucket represents operations you can perform on a bucket
|
|
type Bucket struct {
|
|
storj.Bucket
|
|
Config BucketConfig
|
|
|
|
metainfo *kvmetainfo.DB
|
|
streams streams.Store
|
|
pathCipher storj.Cipher
|
|
}
|
|
|
|
// OpenObject returns an Object handle, if authorized.
|
|
func (b *Bucket) OpenObject(ctx context.Context, path storj.Path) (o *Object, err error) {
|
|
defer mon.Task()(&ctx)(&err)
|
|
|
|
info, err := b.metainfo.GetObject(ctx, b.Name, path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &Object{
|
|
Meta: ObjectMeta{
|
|
Bucket: info.Bucket.Name,
|
|
Path: info.Path,
|
|
IsPrefix: info.IsPrefix,
|
|
ContentType: info.ContentType,
|
|
Metadata: info.Metadata,
|
|
Created: info.Created,
|
|
Modified: info.Modified,
|
|
Expires: info.Expires,
|
|
Size: info.Size,
|
|
Checksum: info.Checksum,
|
|
Volatile: struct {
|
|
EncryptionParameters storj.EncryptionParameters
|
|
RedundancyScheme storj.RedundancyScheme
|
|
}{
|
|
EncryptionParameters: info.ToEncryptionParameters(),
|
|
RedundancyScheme: info.RedundancyScheme,
|
|
},
|
|
},
|
|
metainfo: b.metainfo,
|
|
streams: b.streams,
|
|
}, nil
|
|
}
|
|
|
|
// UploadOptions controls options about uploading a new Object, if authorized.
|
|
type UploadOptions struct {
|
|
// ContentType, if set, gives a MIME content-type for the Object.
|
|
ContentType string
|
|
// Metadata contains additional information about an Object. It can
|
|
// hold arbitrary textual fields and can be retrieved together with the
|
|
// Object. Field names can be at most 1024 bytes long. Field values are
|
|
// not individually limited in size, but the total of all metadata
|
|
// (fields and values) can not exceed 4 kiB.
|
|
Metadata map[string]string
|
|
// Expires is the time at which the new Object can expire (be deleted
|
|
// automatically from storage nodes).
|
|
Expires time.Time
|
|
|
|
// Volatile groups config values that are likely to change semantics
|
|
// or go away entirely between releases. Be careful when using them!
|
|
Volatile struct {
|
|
// EncryptionParameters determines the cipher suite to use for
|
|
// the Object's data encryption. If not set, the Bucket's
|
|
// defaults will be used.
|
|
EncryptionParameters storj.EncryptionParameters
|
|
|
|
// RedundancyScheme determines the Reed-Solomon and/or Forward
|
|
// Error Correction encoding parameters to be used for this
|
|
// Object.
|
|
RedundancyScheme storj.RedundancyScheme
|
|
}
|
|
}
|
|
|
|
// UploadObject uploads a new object, if authorized.
|
|
func (b *Bucket) UploadObject(ctx context.Context, path storj.Path, data io.Reader, opts *UploadOptions) (err error) {
|
|
defer mon.Task()(&ctx)(&err)
|
|
|
|
if opts == nil {
|
|
opts = &UploadOptions{}
|
|
}
|
|
|
|
createInfo := storj.CreateObject{
|
|
ContentType: opts.ContentType,
|
|
Metadata: opts.Metadata,
|
|
Expires: opts.Expires,
|
|
RedundancyScheme: opts.Volatile.RedundancyScheme,
|
|
EncryptionScheme: opts.Volatile.EncryptionParameters.ToEncryptionScheme(),
|
|
}
|
|
|
|
obj, err := b.metainfo.CreateObject(ctx, b.Name, path, &createInfo)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
mutableStream, err := obj.CreateStream(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
upload := stream.NewUpload(ctx, mutableStream, b.streams)
|
|
|
|
_, err = io.Copy(upload, data)
|
|
|
|
return errs.Combine(err, upload.Close())
|
|
}
|
|
|
|
// DeleteObject removes an object, if authorized.
|
|
func (b *Bucket) DeleteObject(ctx context.Context, path storj.Path) (err error) {
|
|
defer mon.Task()(&ctx)(&err)
|
|
return b.metainfo.DeleteObject(ctx, b.Bucket.Name, path)
|
|
}
|
|
|
|
// ListOptions controls options for the ListObjects() call.
|
|
type ListOptions = storj.ListOptions
|
|
|
|
// ListObjects lists objects a user is authorized to see.
|
|
// TODO(paul): should probably have a ListOptions defined in this package, for consistency's sake
|
|
func (b *Bucket) ListObjects(ctx context.Context, cfg *ListOptions) (list storj.ObjectList, err error) {
|
|
defer mon.Task()(&ctx)(&err)
|
|
if cfg == nil {
|
|
cfg = &storj.ListOptions{}
|
|
}
|
|
return b.metainfo.ListObjects(ctx, b.Bucket.Name, *cfg)
|
|
}
|
|
|
|
// Close closes the Bucket session.
|
|
func (b *Bucket) Close() error {
|
|
return nil
|
|
}
|