mirror of
https://github.com/minio/minio.git
synced 2025-01-11 15:03:22 -05:00
parent
a20ccb1e83
commit
434423de89
23
config.go
23
config.go
@ -86,26 +86,3 @@ func getConfigFile() (string, error) {
|
||||
}
|
||||
return filepath.Join(configPath, globalMinioConfigFile), nil
|
||||
}
|
||||
|
||||
// isFormatConfigFileExists - returns true if format config file exists.
|
||||
func isFormatConfigFileExists() bool {
|
||||
st, err := os.Stat(mustGetFormatConfigFile())
|
||||
return (err == nil && st.Mode().IsRegular())
|
||||
}
|
||||
|
||||
// mustGetFormatConfigFile must get format config file.
|
||||
func mustGetFormatConfigFile() string {
|
||||
configFile, err := getFormatConfigFile()
|
||||
fatalIf(err, "Unable to get format config file.", nil)
|
||||
|
||||
return configFile
|
||||
}
|
||||
|
||||
// getFormatConfigFile get format config file.
|
||||
func getFormatConfigFile() (string, error) {
|
||||
configPath, err := getConfigPath()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return filepath.Join(configPath, globalMinioFormatConfigFile), nil
|
||||
}
|
||||
|
@ -16,7 +16,10 @@
|
||||
|
||||
package main
|
||||
|
||||
import "github.com/minio/minio/pkg/quick"
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type fsFormat struct {
|
||||
Version string `json:"version"`
|
||||
@ -28,84 +31,72 @@ type xlFormat struct {
|
||||
}
|
||||
|
||||
type formatConfigV1 struct {
|
||||
// must have "Version" to "quick" to work
|
||||
Version string `json:"version"`
|
||||
Format string `json:"format"`
|
||||
FS fsFormat `json:"fs,omitempty"`
|
||||
XL xlFormat `json:"xl,omitempty"`
|
||||
Version string `json:"version"`
|
||||
Format string `json:"format"`
|
||||
FS *fsFormat `json:"fs,omitempty"`
|
||||
XL *xlFormat `json:"xl,omitempty"`
|
||||
}
|
||||
|
||||
func (f formatConfigV1) Save() error {
|
||||
configFile, err := getFormatConfigFile()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// FIXME: currently we don't check single exportPath which uses FS layer.
|
||||
|
||||
// initialize quick.
|
||||
qc, err := quick.New(&f)
|
||||
// loadFormatXL - load XL format.json.
|
||||
func loadFormatXL(storage StorageAPI) (xl *xlFormat, err error) {
|
||||
offset := int64(0)
|
||||
r, err := storage.ReadFile(minioMetaBucket, formatConfigFile, offset)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Save config file.
|
||||
return qc.Save(configFile)
|
||||
decoder := json.NewDecoder(r)
|
||||
formatXL := formatConfigV1{}
|
||||
err = decoder.Decode(&formatXL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = r.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if formatXL.Version != "1" {
|
||||
return nil, fmt.Errorf("Unsupported version of backend format [%s] found.", formatXL.Version)
|
||||
}
|
||||
if formatXL.Format != "xl" {
|
||||
return nil, fmt.Errorf("Unsupported backend format [%s] found.", formatXL.Format)
|
||||
}
|
||||
return formatXL.XL, nil
|
||||
}
|
||||
|
||||
func (f *formatConfigV1) Load() error {
|
||||
configFile, err := getFormatConfigFile()
|
||||
// checkFormat - validates if format.json file exists.
|
||||
func checkFormat(storage StorageAPI) error {
|
||||
_, err := storage.StatFile(minioMetaBucket, formatConfigFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f.Version = globalMinioConfigVersion
|
||||
qc, err := quick.New(f)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := qc.Load(configFile); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// saveFormatFS - save FS format configuration
|
||||
func saveFormatFS(fs fsFormat) error {
|
||||
config := formatConfigV1{Version: globalMinioConfigVersion, Format: "fs", FS: fs}
|
||||
return config.Save()
|
||||
}
|
||||
|
||||
// saveFormatXL - save XL format configuration
|
||||
func saveFormatXL(xl xlFormat) error {
|
||||
config := formatConfigV1{Version: globalMinioConfigVersion, Format: "xl", XL: xl}
|
||||
return config.Save()
|
||||
}
|
||||
|
||||
// getSavedFormatConfig - get saved format configuration
|
||||
func getSavedFormatConfig() (formatConfigV1, error) {
|
||||
config := formatConfigV1{Version: globalMinioConfigVersion}
|
||||
|
||||
if err := config.Load(); err != nil {
|
||||
return config, err
|
||||
}
|
||||
|
||||
return config, nil
|
||||
}
|
||||
|
||||
// getFormatFS - get saved FS format configuration
|
||||
func getFormatFS() (fsFormat, error) {
|
||||
config, err := getSavedFormatConfig()
|
||||
func saveFormatXL(storage StorageAPI, xl *xlFormat) error {
|
||||
w, err := storage.CreateFile(minioMetaBucket, formatConfigFile)
|
||||
if err != nil {
|
||||
return fsFormat{}, err
|
||||
return err
|
||||
}
|
||||
return config.FS, nil
|
||||
}
|
||||
|
||||
// getFormatXL - get saved XL format configuration
|
||||
func getFormatXL() (xlFormat, error) {
|
||||
config, err := getSavedFormatConfig()
|
||||
formatXL := formatConfigV1{
|
||||
Version: "1",
|
||||
Format: "xl",
|
||||
XL: xl,
|
||||
}
|
||||
encoder := json.NewEncoder(w)
|
||||
err = encoder.Encode(&formatXL)
|
||||
if err != nil {
|
||||
return xlFormat{}, err
|
||||
if clErr := safeCloseAndRemove(w); clErr != nil {
|
||||
return clErr
|
||||
}
|
||||
return err
|
||||
}
|
||||
return config.XL, nil
|
||||
if err = w.Close(); err != nil {
|
||||
if clErr := safeCloseAndRemove(w); clErr != nil {
|
||||
return clErr
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
13
globals.go
13
globals.go
@ -29,13 +29,12 @@ const (
|
||||
|
||||
// minio configuration related constants.
|
||||
const (
|
||||
globalMinioConfigVersion = "4"
|
||||
globalMinioConfigDir = ".minio"
|
||||
globalMinioCertsDir = ".minio/certs"
|
||||
globalMinioCertFile = "public.crt"
|
||||
globalMinioKeyFile = "private.key"
|
||||
globalMinioConfigFile = "config.json"
|
||||
globalMinioFormatConfigFile = "format.json"
|
||||
globalMinioConfigVersion = "4"
|
||||
globalMinioConfigDir = ".minio"
|
||||
globalMinioCertsDir = ".minio/certs"
|
||||
globalMinioCertFile = "public.crt"
|
||||
globalMinioKeyFile = "private.key"
|
||||
globalMinioConfigFile = "config.json"
|
||||
)
|
||||
|
||||
var (
|
||||
|
22
routers.go
22
routers.go
@ -17,9 +17,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
|
||||
router "github.com/gorilla/mux"
|
||||
)
|
||||
@ -38,26 +36,6 @@ func newObjectLayer(exportPaths ...string) (ObjectLayer, error) {
|
||||
|
||||
// configureServer handler returns final handler for the http server.
|
||||
func configureServerHandler(srvCmdConfig serverCmdConfig) http.Handler {
|
||||
// FIXME: currently we don't check single exportPath which uses FS layer.
|
||||
if len(srvCmdConfig.exportPaths) > 1 {
|
||||
if isFormatConfigFileExists() {
|
||||
format, err := getFormatXL()
|
||||
if err != nil {
|
||||
fatalIf(err, "Failed to read format.json", nil)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(format.Disks, srvCmdConfig.exportPaths) {
|
||||
err = fmt.Errorf("Number of export paths from command-line did not match the backend configuration. Backend is configured with [%s] exports.", format.Disks)
|
||||
fatalIf(err, "", nil)
|
||||
}
|
||||
} else {
|
||||
// First run: save disk configuration
|
||||
if err := saveFormatXL(xlFormat{Version: "1", Disks: srvCmdConfig.exportPaths}); err != nil {
|
||||
fatalIf(err, "Unable to save 'format.json'", nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
objAPI, err := newObjectLayer(srvCmdConfig.exportPaths...)
|
||||
fatalIf(err, "Initializing object layer failed.", nil)
|
||||
|
||||
|
@ -18,6 +18,7 @@ package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@ -29,6 +30,7 @@ import (
|
||||
const (
|
||||
multipartSuffix = ".minio.multipart"
|
||||
multipartMetaFile = "00000" + multipartSuffix
|
||||
formatConfigFile = "format.json"
|
||||
)
|
||||
|
||||
// xlObjects - Implements fs object layer.
|
||||
@ -43,11 +45,37 @@ func isLeafDirectory(disk StorageAPI, volume, leafPath string) bool {
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// isValidFormat - validates input arguments with backend 'format.json'
|
||||
func isValidFormat(storage StorageAPI, exportPaths ...string) bool {
|
||||
// Load saved XL format.json and validate.
|
||||
xl, err := loadFormatXL(storage)
|
||||
if err != nil {
|
||||
log.Errorf("loadFormatXL failed with %s", err)
|
||||
return false
|
||||
}
|
||||
if xl.Version != "1" {
|
||||
log.Errorf("Unsupported XL backend format found [%s]", xl.Version)
|
||||
return false
|
||||
}
|
||||
if len(exportPaths) != len(xl.Disks) {
|
||||
log.Errorf("Number of disks %d passed at the command-line did not match the backend format %d", len(exportPaths), len(xl.Disks))
|
||||
return false
|
||||
}
|
||||
for index, disk := range xl.Disks {
|
||||
if exportPaths[index] != disk {
|
||||
log.Errorf("Invalid order of disks detected %s. Required order is %s.", exportPaths, xl.Disks)
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// FIXME: constructor should return a pointer.
|
||||
// newXLObjects - initialize new xl object layer.
|
||||
func newXLObjects(exportPaths ...string) (ObjectLayer, error) {
|
||||
storage, err := newXL(exportPaths...)
|
||||
if err != nil {
|
||||
log.Errorf("newXL failed with %s", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -55,6 +83,30 @@ func newXLObjects(exportPaths ...string) (ObjectLayer, error) {
|
||||
// cleaning up tmp files etc.
|
||||
initObjectLayer(storage)
|
||||
|
||||
err = checkFormat(storage)
|
||||
if err != nil {
|
||||
if err == errFileNotFound {
|
||||
// Save new XL format.
|
||||
errSave := saveFormatXL(storage, &xlFormat{
|
||||
Version: "1",
|
||||
Disks: exportPaths,
|
||||
})
|
||||
if errSave != nil {
|
||||
log.Errorf("saveFormatXL failed with %s", errSave)
|
||||
return nil, errSave
|
||||
}
|
||||
} else {
|
||||
log.Errorf("Unable to check backend format %s", err)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Validate if format exists and input arguments are validated
|
||||
// with backend format.
|
||||
if !isValidFormat(storage, exportPaths...) {
|
||||
return nil, fmt.Errorf("Command-line arguments %s is not valid.", exportPaths)
|
||||
}
|
||||
|
||||
// Return successfully initialized object layer.
|
||||
return xlObjects{
|
||||
storage: storage,
|
||||
|
Loading…
Reference in New Issue
Block a user