|
|
|
@ -17,15 +17,94 @@ |
|
|
|
|
package donut |
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
|
"encoding/json" |
|
|
|
|
"errors" |
|
|
|
|
"fmt" |
|
|
|
|
"io" |
|
|
|
|
"os" |
|
|
|
|
"path" |
|
|
|
|
"strings" |
|
|
|
|
|
|
|
|
|
"github.com/minio-io/minio/pkg/iodine" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
// TODO we have to store the acl's
|
|
|
|
|
/// This file contains all the internal functions used by Object interface
|
|
|
|
|
|
|
|
|
|
// getDiskWriters -
|
|
|
|
|
func (d donut) getBucketMetadataWriters() ([]io.WriteCloser, error) { |
|
|
|
|
var writers []io.WriteCloser |
|
|
|
|
for _, node := range d.nodes { |
|
|
|
|
disks, err := node.ListDisks() |
|
|
|
|
if err != nil { |
|
|
|
|
return nil, iodine.New(err, nil) |
|
|
|
|
} |
|
|
|
|
writers = make([]io.WriteCloser, len(disks)) |
|
|
|
|
for _, disk := range disks { |
|
|
|
|
bucketMetaDataWriter, err := disk.MakeFile(path.Join(d.name, bucketMetadataConfig)) |
|
|
|
|
if err != nil { |
|
|
|
|
return nil, iodine.New(err, nil) |
|
|
|
|
} |
|
|
|
|
writers[disk.GetOrder()] = bucketMetaDataWriter |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return writers, nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (d donut) getBucketMetadataReaders() ([]io.ReadCloser, error) { |
|
|
|
|
var readers []io.ReadCloser |
|
|
|
|
for _, node := range d.nodes { |
|
|
|
|
disks, err := node.ListDisks() |
|
|
|
|
if err != nil { |
|
|
|
|
return nil, iodine.New(err, nil) |
|
|
|
|
} |
|
|
|
|
readers = make([]io.ReadCloser, len(disks)) |
|
|
|
|
for _, disk := range disks { |
|
|
|
|
bucketMetaDataReader, err := disk.OpenFile(path.Join(d.name, bucketMetadataConfig)) |
|
|
|
|
if err != nil { |
|
|
|
|
return nil, iodine.New(err, nil) |
|
|
|
|
} |
|
|
|
|
readers[disk.GetOrder()] = bucketMetaDataReader |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return readers, nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
func (d donut) setDonutBucketMetadata(metadata map[string]map[string]string) error { |
|
|
|
|
writers, err := d.getBucketMetadataWriters() |
|
|
|
|
if err != nil { |
|
|
|
|
return iodine.New(err, nil) |
|
|
|
|
} |
|
|
|
|
for _, writer := range writers { |
|
|
|
|
defer writer.Close() |
|
|
|
|
} |
|
|
|
|
for _, writer := range writers { |
|
|
|
|
jenc := json.NewEncoder(writer) |
|
|
|
|
if err := jenc.Encode(metadata); err != nil { |
|
|
|
|
return iodine.New(err, nil) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (d donut) getDonutBucketMetadata() (map[string]map[string]string, error) { |
|
|
|
|
metadata := make(map[string]map[string]string) |
|
|
|
|
readers, err := d.getBucketMetadataReaders() |
|
|
|
|
if err != nil { |
|
|
|
|
return nil, iodine.New(err, nil) |
|
|
|
|
} |
|
|
|
|
for _, reader := range readers { |
|
|
|
|
defer reader.Close() |
|
|
|
|
} |
|
|
|
|
for _, reader := range readers { |
|
|
|
|
jenc := json.NewDecoder(reader) |
|
|
|
|
if err := jenc.Decode(&metadata); err != nil { |
|
|
|
|
return nil, iodine.New(err, nil) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return metadata, nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (d donut) makeDonutBucket(bucketName, acl string) error { |
|
|
|
|
err := d.getDonutBuckets() |
|
|
|
|
if err != nil { |
|
|
|
@ -34,7 +113,7 @@ func (d donut) makeDonutBucket(bucketName, acl string) error { |
|
|
|
|
if _, ok := d.buckets[bucketName]; ok { |
|
|
|
|
return iodine.New(errors.New("bucket exists"), nil) |
|
|
|
|
} |
|
|
|
|
bucket, err := NewBucket(bucketName, acl, d.name, d.nodes) |
|
|
|
|
bucket, bucketMetadata, err := NewBucket(bucketName, acl, d.name, d.nodes) |
|
|
|
|
if err != nil { |
|
|
|
|
return iodine.New(err, nil) |
|
|
|
|
} |
|
|
|
@ -54,6 +133,25 @@ func (d donut) makeDonutBucket(bucketName, acl string) error { |
|
|
|
|
} |
|
|
|
|
nodeNumber = nodeNumber + 1 |
|
|
|
|
} |
|
|
|
|
metadata, err := d.getDonutBucketMetadata() |
|
|
|
|
if err != nil { |
|
|
|
|
err = iodine.ToError(err) |
|
|
|
|
if os.IsNotExist(err) { |
|
|
|
|
metadata := make(map[string]map[string]string) |
|
|
|
|
metadata[bucketName] = bucketMetadata |
|
|
|
|
err = d.setDonutBucketMetadata(metadata) |
|
|
|
|
if err != nil { |
|
|
|
|
return iodine.New(err, nil) |
|
|
|
|
} |
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
return iodine.New(err, nil) |
|
|
|
|
} |
|
|
|
|
metadata[bucketName] = bucketMetadata |
|
|
|
|
err = d.setDonutBucketMetadata(metadata) |
|
|
|
|
if err != nil { |
|
|
|
|
return iodine.New(err, nil) |
|
|
|
|
} |
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -75,7 +173,7 @@ func (d donut) getDonutBuckets() error { |
|
|
|
|
} |
|
|
|
|
bucketName := splitDir[0] |
|
|
|
|
// we dont need this NewBucket once we cache from makeDonutBucket()
|
|
|
|
|
bucket, err := NewBucket(bucketName, "private", d.name, d.nodes) |
|
|
|
|
bucket, _, err := NewBucket(bucketName, "private", d.name, d.nodes) |
|
|
|
|
if err != nil { |
|
|
|
|
return iodine.New(err, nil) |
|
|
|
|
} |
|
|
|
|