diff --git a/main.go b/main.go index 6929c2f17..7bcd538fd 100644 --- a/main.go +++ b/main.go @@ -11,7 +11,8 @@ func parseInput(c *cli.Context) { tls := c.Bool("tls") certFile := c.String("cert") keyFile := c.String("key") - server.Start(":8080", tls, certFile, keyFile) + inmemory := c.Bool("inmemory") + server.Start(":8080", tls, certFile, keyFile, inmemory) } func main() { @@ -33,6 +34,10 @@ func main() { Value: "", Usage: "key file path", }, + cli.BoolFlag{ + Name: "inmemory", + Usage: "in memory storage", + }, } app.Flags = flags app.Action = parseInput diff --git a/pkg/server/server.go b/pkg/server/server.go index 7444f3500..b797f1c27 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -18,15 +18,19 @@ package server import ( "log" + "os" + "os/user" + "path" "reflect" "github.com/minio-io/minio/pkg/httpserver" mstorage "github.com/minio-io/minio/pkg/storage" + "github.com/minio-io/minio/pkg/storage/fs" "github.com/minio-io/minio/pkg/storage/inmemory" "github.com/minio-io/minio/pkg/webapi/minioapi" ) -func Start(hostname string, tls bool, certFile, keyFile string) { +func Start(hostname string, tls bool, certFile, keyFile string, inMemoryStorage bool) { var ctrlChans []chan<- string var statusChans []<-chan error @@ -44,9 +48,26 @@ func Start(hostname string, tls bool, certFile, keyFile string) { srv.KeyFile = keyFile } - ctrlChan, statusChan, storage = inmemory.Start() - ctrlChans = append(ctrlChans, ctrlChan) - statusChans = append(statusChans, statusChan) + if inMemoryStorage { + ctrlChan, statusChan, storage = inmemory.Start() + ctrlChans = append(ctrlChans, ctrlChan) + statusChans = append(statusChans, statusChan) + } else { + currentUser, err := user.Current() + if err != nil { + log.Fatal(err) + } + rootPath := path.Join(currentUser.HomeDir, "minio-storage") + _, err = os.Stat(rootPath) + if os.IsNotExist(err) { + err = os.Mkdir(rootPath, 0700) + } else if err != nil { + log.Fatal("Could not create $HOME/minio-storage", err) + } + ctrlChan, statusChan, storage = fs.Start(rootPath) + ctrlChans = append(ctrlChans, ctrlChan) + statusChans = append(statusChans, statusChan) + } ctrlChan, statusChan = httpserver.Start(minioapi.HttpHandler(storage), srv) ctrlChans = append(ctrlChans, ctrlChan) diff --git a/pkg/storage/fs/fs.go b/pkg/storage/fs/fs.go index 3b3af4a8b..1f3eb7ef8 100644 --- a/pkg/storage/fs/fs.go +++ b/pkg/storage/fs/fs.go @@ -176,6 +176,13 @@ func (storage *storage) StoreObject(bucket string, key string, data io.Reader) e // get object path objectPath := path.Join(storage.root, bucket, key) + objectDir := path.Dir(objectPath) + if _, err := os.Stat(objectDir); os.IsNotExist(err) { + err = os.MkdirAll(objectDir, 0700) + if err != nil { + return mstorage.EmbedError(bucket, key, err) + } + } // check if object exists if _, err := os.Stat(objectPath); !os.IsNotExist(err) { diff --git a/pkg/storage/storage_api_suite.go b/pkg/storage/storage_api_suite.go index b593b80f8..e36cd148b 100644 --- a/pkg/storage/storage_api_suite.go +++ b/pkg/storage/storage_api_suite.go @@ -15,6 +15,7 @@ func APITestSuite(c *C, create func() Storage) { testObjectOverwriteFails(c, create) testNonExistantBucketOperations(c, create) testBucketRecreateFails(c, create) + testPutObjectInSubdir(c, create) } func testCreateBucket(c *C, create func() Storage) { @@ -142,3 +143,16 @@ func testBucketRecreateFails(c *C, create func() Storage) { err = storage.StoreBucket("string") c.Assert(err, Not(IsNil)) } + +func testPutObjectInSubdir(c *C, create func() Storage) { + storage := create() + err := storage.StoreBucket("bucket") + c.Assert(err, IsNil) + err = storage.StoreObject("bucket", "dir1/dir2/object", bytes.NewBufferString("hello world")) + c.Assert(err, IsNil) + var bytesBuffer bytes.Buffer + length, err := storage.CopyObjectToWriter(&bytesBuffer, "bucket", "dir1/dir2/object") + c.Assert(len(bytesBuffer.Bytes()), Equals, len("hello world")) + c.Assert(int64(len(bytesBuffer.Bytes())), Equals, length) + c.Assert(err, IsNil) +}