mirror of
https://github.com/minio/minio.git
synced 2025-11-25 20:16:10 -05:00
Migrate to external Donut package
This commit is contained in:
@@ -1,196 +0,0 @@
|
||||
package donut
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/minio-io/iodine"
|
||||
)
|
||||
|
||||
type donut struct {
|
||||
buckets map[string]Bucket
|
||||
nodes map[string]Node
|
||||
}
|
||||
|
||||
// NewDonut - instantiate new donut driver
|
||||
func NewDonut(root string) (Donut, error) {
|
||||
nodes := make(map[string]Node)
|
||||
nodes["localhost"] = &localDirectoryNode{root: root}
|
||||
driver := &donut{
|
||||
buckets: make(map[string]Bucket),
|
||||
nodes: nodes,
|
||||
}
|
||||
for nodeID, node := range nodes {
|
||||
bucketIDs, err := node.GetBuckets()
|
||||
if err != nil {
|
||||
return nil, iodine.New(err, map[string]string{"root": root})
|
||||
}
|
||||
for _, bucketID := range bucketIDs {
|
||||
tokens := strings.Split(bucketID, ":")
|
||||
if _, ok := driver.buckets[tokens[0]]; !ok {
|
||||
bucket := donutBucket{
|
||||
nodes: make([]string, 16),
|
||||
}
|
||||
// TODO catch errors
|
||||
driver.buckets[tokens[0]] = bucket
|
||||
}
|
||||
if err = driver.buckets[tokens[0]].AddNode(nodeID, bucketID); err != nil {
|
||||
return nil, iodine.New(err, map[string]string{"root": root})
|
||||
}
|
||||
}
|
||||
}
|
||||
return driver, nil
|
||||
}
|
||||
|
||||
// CreateBucket - create a new bucket
|
||||
func (d donut) CreateBucket(bucketName string) error {
|
||||
if _, ok := d.buckets[bucketName]; ok == false {
|
||||
bucketName = strings.TrimSpace(bucketName)
|
||||
if bucketName == "" {
|
||||
return iodine.New(errors.New("Cannot create bucket with no name"), map[string]string{"bucket": bucketName})
|
||||
}
|
||||
// assign nodes
|
||||
// TODO assign other nodes
|
||||
nodes := make([]string, 16)
|
||||
for i := 0; i < 16; i++ {
|
||||
nodes[i] = "localhost"
|
||||
if node, ok := d.nodes["localhost"]; ok {
|
||||
err := node.CreateBucket(bucketName + ":0:" + strconv.Itoa(i))
|
||||
if err != nil {
|
||||
return iodine.New(err, map[string]string{"node": nodes[i], "bucket": bucketName})
|
||||
}
|
||||
}
|
||||
}
|
||||
bucket := donutBucket{
|
||||
nodes: nodes,
|
||||
}
|
||||
d.buckets[bucketName] = bucket
|
||||
return nil
|
||||
}
|
||||
return iodine.New(errors.New("Bucket exists"), map[string]string{"bucket": bucketName})
|
||||
}
|
||||
|
||||
// ListBuckets - list all buckets
|
||||
func (d donut) ListBuckets() ([]string, error) {
|
||||
var buckets []string
|
||||
for bucket := range d.buckets {
|
||||
buckets = append(buckets, bucket)
|
||||
}
|
||||
sort.Strings(buckets)
|
||||
return buckets, nil
|
||||
}
|
||||
|
||||
// GetObjectWriter - get a new writer interface for a new object
|
||||
func (d donut) GetObjectWriter(bucketName, objectName string) (ObjectWriter, error) {
|
||||
if bucket, ok := d.buckets[bucketName]; ok == true {
|
||||
writers := make([]Writer, 16)
|
||||
nodes, err := bucket.GetNodes()
|
||||
if err != nil {
|
||||
return nil, iodine.New(err, map[string]string{"bucket": bucketName, "object": objectName})
|
||||
}
|
||||
for i, nodeID := range nodes {
|
||||
if node, ok := d.nodes[nodeID]; ok == true {
|
||||
bucketID := bucketName + ":0:" + strconv.Itoa(i)
|
||||
writer, err := node.GetWriter(bucketID, objectName)
|
||||
if err != nil {
|
||||
for _, writerToClose := range writers {
|
||||
if writerToClose != nil {
|
||||
writerToClose.CloseWithError(iodine.New(err, nil))
|
||||
}
|
||||
}
|
||||
return nil, iodine.New(err, map[string]string{"bucketid": bucketID})
|
||||
}
|
||||
writers[i] = writer
|
||||
}
|
||||
}
|
||||
return newErasureWriter(writers), nil
|
||||
}
|
||||
return nil, iodine.New(errors.New("Bucket not found"), map[string]string{"bucket": bucketName})
|
||||
}
|
||||
|
||||
// GetObjectReader - get a new reader interface for a new object
|
||||
func (d donut) GetObjectReader(bucketName, objectName string) (io.ReadCloser, error) {
|
||||
errParams := map[string]string{"bucket": bucketName, "object": objectName}
|
||||
r, w := io.Pipe()
|
||||
if bucket, ok := d.buckets[bucketName]; ok == true {
|
||||
readers := make([]io.ReadCloser, 16)
|
||||
nodes, err := bucket.GetNodes()
|
||||
if err != nil {
|
||||
return nil, iodine.New(err, errParams)
|
||||
}
|
||||
var metadata map[string]string
|
||||
for i, nodeID := range nodes {
|
||||
if node, ok := d.nodes[nodeID]; ok == true {
|
||||
bucketID := bucketName + ":0:" + strconv.Itoa(i)
|
||||
reader, err := node.GetReader(bucketID, objectName)
|
||||
if err != nil {
|
||||
errParams["node"] = nodeID
|
||||
return nil, iodine.New(err, errParams)
|
||||
}
|
||||
readers[i] = reader
|
||||
if metadata == nil {
|
||||
metadata, err = node.GetDonutMetadata(bucketID, objectName)
|
||||
if err != nil {
|
||||
errParams["node"] = nodeID
|
||||
return nil, iodine.New(err, errParams)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
go erasureReader(readers, metadata, w)
|
||||
return r, nil
|
||||
}
|
||||
return nil, iodine.New(errors.New("Bucket not found"), errParams)
|
||||
}
|
||||
|
||||
// GetObjectMetadata returns metadata for a given object in a bucket
|
||||
func (d donut) GetObjectMetadata(bucketName, object string) (map[string]string, error) {
|
||||
errParams := map[string]string{"bucket": bucketName, "object": object}
|
||||
if bucket, ok := d.buckets[bucketName]; ok {
|
||||
nodes, err := bucket.GetNodes()
|
||||
if err != nil {
|
||||
return nil, iodine.New(err, errParams)
|
||||
}
|
||||
if node, ok := d.nodes[nodes[0]]; ok {
|
||||
bucketID := bucketName + ":0:0"
|
||||
metadata, err := node.GetMetadata(bucketID, object)
|
||||
if err != nil {
|
||||
errParams["bucketID"] = bucketID
|
||||
return nil, iodine.New(err, errParams)
|
||||
}
|
||||
donutMetadata, err := node.GetDonutMetadata(bucketID, object)
|
||||
if err != nil {
|
||||
errParams["bucketID"] = bucketID
|
||||
return nil, iodine.New(err, errParams)
|
||||
}
|
||||
metadata["sys.created"] = donutMetadata["created"]
|
||||
metadata["sys.md5"] = donutMetadata["md5"]
|
||||
metadata["sys.size"] = donutMetadata["size"]
|
||||
return metadata, nil
|
||||
}
|
||||
errParams["node"] = nodes[0]
|
||||
return nil, iodine.New(errors.New("Cannot connect to node: "+nodes[0]), errParams)
|
||||
}
|
||||
return nil, errors.New("Bucket not found")
|
||||
}
|
||||
|
||||
// ListObjects - list all the available objects in a bucket
|
||||
func (d donut) ListObjects(bucketName string) ([]string, error) {
|
||||
errParams := map[string]string{"bucket": bucketName}
|
||||
if bucket, ok := d.buckets[bucketName]; ok {
|
||||
nodes, err := bucket.GetNodes()
|
||||
if err != nil {
|
||||
return nil, iodine.New(err, errParams)
|
||||
}
|
||||
if node, ok := d.nodes[nodes[0]]; ok {
|
||||
bucketID := bucketName + ":0:0"
|
||||
objects, err := node.ListObjects(bucketID)
|
||||
errParams["bucketID"] = bucketID
|
||||
return objects, iodine.New(err, errParams)
|
||||
}
|
||||
}
|
||||
return nil, iodine.New(errors.New("Bucket not found"), errParams)
|
||||
}
|
||||
Reference in New Issue
Block a user