minio: Add config-folder option.

Fixes #997
This commit is contained in:
Harshavardhana
2015-12-06 14:31:20 -08:00
parent a97c4ebce3
commit 836f5204af
19 changed files with 149 additions and 202 deletions

View File

@@ -102,7 +102,7 @@ func Init() error {
// Lookup returns matching content-type for known types of file extensions.
func Lookup(extension string) (contentType string, e error) {
if !isInitialized {
return "", errors.New("contentdb is not initialized.")
return "", errors.New("contentdb is not initialized")
}
return extDB[extension], e

View File

@@ -184,8 +184,8 @@ type bintree struct {
}
var _bintree = &bintree{nil, map[string]*bintree{
"db": &bintree{nil, map[string]*bintree{
"db.json": &bintree{dbDbJSON, map[string]*bintree{}},
"db": {nil, map[string]*bintree{
"db.json": {dbDbJSON, map[string]*bintree{}},
}},
}}

View File

@@ -17,52 +17,22 @@
package fs
import (
"os"
"os/user"
"path/filepath"
"runtime"
"strconv"
"github.com/minio/minio-xl/pkg/probe"
"github.com/minio/minio-xl/pkg/quick"
"github.com/minio/minio/pkg/user"
)
// Workaround for docker images with fully static binary and 32bit linux operating systems.
// For static binaries NSS library will not be a part of the static binary hence user.Current() fails.
// For 32bit linux CGO is not enabled so it will not provide linux specific codebase.
func userCurrent() (*user.User, *probe.Error) {
if os.Getenv("DOCKERIMAGE") == "1" {
wd, err := os.Getwd()
if err != nil {
return nil, probe.NewError(err)
}
return &user.User{Uid: "0", Gid: "0", Username: "root", Name: "root", HomeDir: wd}, nil
}
if runtime.GOARCH == "386" && runtime.GOOS == "linux" {
return &user.User{
Uid: strconv.Itoa(os.Getuid()),
Gid: strconv.Itoa(os.Getgid()),
Username: os.Getenv("USER"),
Name: os.Getenv("USER"),
HomeDir: os.Getenv("HOME"),
}, nil
}
user, err := user.Current()
if err != nil {
return nil, probe.NewError(err)
}
return user, nil
}
func getFSBucketsConfigPath() (string, *probe.Error) {
if customBucketsConfigPath != "" {
return customBucketsConfigPath, nil
}
u, err := userCurrent()
if err != nil {
return "", err.Trace()
homeDir, e := user.HomeDir()
if e != nil {
return "", probe.NewError(e)
}
fsBucketsConfigPath := filepath.Join(u.HomeDir, ".minio", "buckets.json")
fsBucketsConfigPath := filepath.Join(homeDir, ".minio", "$buckets.json")
return fsBucketsConfigPath, nil
}
@@ -70,29 +40,29 @@ func getFSMultipartsSessionConfigPath() (string, *probe.Error) {
if customMultipartsConfigPath != "" {
return customMultipartsConfigPath, nil
}
u, err := userCurrent()
if err != nil {
return "", err.Trace()
homeDir, e := user.HomeDir()
if e != nil {
return "", probe.NewError(e)
}
fsMultipartsConfigPath := filepath.Join(u.HomeDir, ".minio", "multiparts-session.json")
fsMultipartsConfigPath := filepath.Join(homeDir, ".minio", "$multiparts-session.json")
return fsMultipartsConfigPath, nil
}
// internal variable only accessed via get/set methods
var customMultipartsConfigPath, customBucketsConfigPath string
// SetFSBucketsConfigPath - set custom fs buckets config path
func SetFSBucketsConfigPath(configPath string) {
// setFSBucketsConfigPath - set custom fs buckets config path
func setFSBucketsConfigPath(configPath string) {
customBucketsConfigPath = configPath
}
// SetFSMultipartsConfigPath - set custom multiparts session config path
func SetFSMultipartsConfigPath(configPath string) {
func setFSMultipartsConfigPath(configPath string) {
customMultipartsConfigPath = configPath
}
// SaveMultipartsSession - save multiparts
func SaveMultipartsSession(multiparts *Multiparts) *probe.Error {
// saveMultipartsSession - save multiparts
func saveMultipartsSession(multiparts *Multiparts) *probe.Error {
fsMultipartsConfigPath, err := getFSMultipartsSessionConfigPath()
if err != nil {
return err.Trace()
@@ -107,8 +77,8 @@ func SaveMultipartsSession(multiparts *Multiparts) *probe.Error {
return nil
}
// SaveBucketsMetadata - save metadata of all buckets
func SaveBucketsMetadata(buckets *Buckets) *probe.Error {
// saveBucketsMetadata - save metadata of all buckets
func saveBucketsMetadata(buckets *Buckets) *probe.Error {
fsBucketsConfigPath, err := getFSBucketsConfigPath()
if err != nil {
return err.Trace()

View File

@@ -54,7 +54,7 @@ func (fs Filesystem) DeleteBucket(bucket string) *probe.Error {
return probe.NewError(err)
}
delete(fs.buckets.Metadata, bucket)
if err := SaveBucketsMetadata(fs.buckets); err != nil {
if err := saveBucketsMetadata(fs.buckets); err != nil {
return err.Trace(bucket)
}
return nil
@@ -147,7 +147,7 @@ func (fs Filesystem) MakeBucket(bucket, acl string) *probe.Error {
bucketMetadata.Created = fi.ModTime()
bucketMetadata.ACL = BucketACL(acl)
fs.buckets.Metadata[bucket] = bucketMetadata
if err := SaveBucketsMetadata(fs.buckets); err != nil {
if err := saveBucketsMetadata(fs.buckets); err != nil {
return err.Trace(bucket)
}
return nil
@@ -211,7 +211,7 @@ func (fs Filesystem) SetBucketMetadata(bucket string, metadata map[string]string
}
bucketMetadata.ACL = BucketACL(acl)
fs.buckets.Metadata[bucket] = bucketMetadata
if err := SaveBucketsMetadata(fs.buckets); err != nil {
if err := saveBucketsMetadata(fs.buckets); err != nil {
return err.Trace(bucket)
}
return nil

View File

@@ -201,7 +201,7 @@ func (fs Filesystem) NewMultipartUpload(bucket, object string) (string, *probe.E
if err != nil {
return "", probe.NewError(err)
}
if err := SaveMultipartsSession(fs.multiparts); err != nil {
if err := saveMultipartsSession(fs.multiparts); err != nil {
return "", err.Trace()
}
return uploadID, nil
@@ -419,7 +419,7 @@ func (fs Filesystem) CompleteMultipartUpload(bucket, object, uploadID string, da
file.CloseAndPurge()
return ObjectMetadata{}, probe.NewError(err)
}
if err := SaveMultipartsSession(fs.multiparts); err != nil {
if err := saveMultipartsSession(fs.multiparts); err != nil {
file.CloseAndPurge()
return ObjectMetadata{}, err.Trace()
}

View File

@@ -18,6 +18,7 @@ package fs
import (
"os"
"path/filepath"
"sync"
"time"
@@ -54,7 +55,10 @@ type Multiparts struct {
}
// New instantiate a new donut
func New() (Filesystem, *probe.Error) {
func New(rootPath string) (Filesystem, *probe.Error) {
setFSBucketsConfigPath(filepath.Join(rootPath, "$buckets.json"))
setFSMultipartsConfigPath(filepath.Join(rootPath, "$multiparts-session.json"))
var err *probe.Error
// load multiparts session from disk
var multiparts *Multiparts
@@ -65,7 +69,7 @@ func New() (Filesystem, *probe.Error) {
Version: "1",
ActiveSession: make(map[string]*MultipartSession),
}
if err := SaveMultipartsSession(multiparts); err != nil {
if err := saveMultipartsSession(multiparts); err != nil {
return Filesystem{}, err.Trace()
}
} else {
@@ -80,7 +84,7 @@ func New() (Filesystem, *probe.Error) {
Version: "1",
Metadata: make(map[string]*BucketMetadata),
}
if err := SaveBucketsMetadata(buckets); err != nil {
if err := saveBucketsMetadata(buckets); err != nil {
return Filesystem{}, err.Trace()
}
} else {
@@ -88,18 +92,12 @@ func New() (Filesystem, *probe.Error) {
}
}
a := Filesystem{lock: new(sync.Mutex)}
a.path = rootPath
a.multiparts = multiparts
a.buckets = buckets
return a, nil
}
// SetRootPath - set root path
func (fs *Filesystem) SetRootPath(path string) {
fs.lock.Lock()
defer fs.lock.Unlock()
fs.path = path
}
// SetMinFreeDisk - set min free disk
func (fs *Filesystem) SetMinFreeDisk(minFreeDisk int64) {
fs.lock.Lock()

View File

@@ -19,7 +19,6 @@ package fs
import (
"io/ioutil"
"os"
"path/filepath"
"testing"
. "gopkg.in/check.v1"
@@ -34,15 +33,10 @@ var _ = Suite(&MySuite{})
func (s *MySuite) TestAPISuite(c *C) {
var storageList []string
create := func() Filesystem {
configPath, err := ioutil.TempDir(os.TempDir(), "minio-")
c.Check(err, IsNil)
path, err := ioutil.TempDir(os.TempDir(), "minio-")
c.Check(err, IsNil)
SetFSMultipartsConfigPath(filepath.Join(configPath, "multiparts-session.json"))
SetFSBucketsConfigPath(filepath.Join(configPath, "buckets.json"))
storageList = append(storageList, path)
store, perr := New()
store.SetRootPath(path)
store, perr := New(path)
store.SetMinFreeDisk(0)
c.Check(perr, IsNil)
return store

49
pkg/user/user.go Normal file
View File

@@ -0,0 +1,49 @@
package user
import (
"os"
"os/user"
"runtime"
"strconv"
)
// Current is a portable implementation to determine the current user.
// Golang's user.Current does not work reliably under docker or 32bit linux
//
// Two issues this code handles :-
//
// Docker Container - For static binaries NSS library will not be a part of the static binary hence user.Current() fails.
// Linux Intel 32 bit - CGO is not enabled so it will not link with NSS library.
//
func Current() (*user.User, error) {
if os.Getenv("DOCKERIMAGE") == "1" {
wd, err := os.Getwd()
if err != nil {
return nil, err
}
return &user.User{Uid: "0", Gid: "0", Username: "root", Name: "root", HomeDir: wd}, nil
}
if runtime.GOARCH == "386" && runtime.GOOS == "linux" {
return &user.User{
Uid: strconv.Itoa(os.Getuid()),
Gid: strconv.Itoa(os.Getgid()),
Username: os.Getenv("USER"),
Name: os.Getenv("USER"),
HomeDir: os.Getenv("HOME"),
}, nil
}
user, e := user.Current()
if e != nil {
return nil, e
}
return user, nil
}
// HomeDir - return current home directory.
func HomeDir() (string, error) {
user, err := Current()
if err != nil {
return "", err
}
return user.HomeDir, nil
}