parent
6be5a2fb7e
commit
aabfd541e1
@ -1 +0,0 @@ |
||||
donut |
@ -1,171 +0,0 @@ |
||||
/* |
||||
* Minio Cloud Storage, (C) 2015 Minio, Inc. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package main |
||||
|
||||
import ( |
||||
"fmt" |
||||
"os" |
||||
"sync" |
||||
|
||||
"path/filepath" |
||||
) |
||||
|
||||
type logLevel int |
||||
|
||||
const ( |
||||
levelUnknown logLevel = iota |
||||
levelPrint |
||||
levelDebug |
||||
levelInfo |
||||
levelError |
||||
levelFatal |
||||
) |
||||
|
||||
var ( |
||||
mutex = &sync.RWMutex{} |
||||
|
||||
// Fatal prints a error message and exits
|
||||
Fatal = func(a ...interface{}) { privatePrint(levelFatal, a...) } |
||||
// Fatalln prints a error message with a new line and exits
|
||||
Fatalln = func(a ...interface{}) { privatePrintln(levelFatal, a...) } |
||||
// Fatalf prints a error message with formatting and exits
|
||||
Fatalf = func(f string, a ...interface{}) { privatePrintf(levelFatal, f, a...) } |
||||
|
||||
// Error prints a error message
|
||||
Error = func(a ...interface{}) { privatePrint(levelError, a...) } |
||||
// Errorln prints a error message with a new line
|
||||
Errorln = func(a ...interface{}) { privatePrintln(levelError, a...) } |
||||
// Errorf prints a error message with formatting
|
||||
Errorf = func(f string, a ...interface{}) { privatePrintf(levelError, f, a...) } |
||||
|
||||
// Info prints a informational message
|
||||
Info = func(a ...interface{}) { privatePrint(levelInfo, a...) } |
||||
// Infoln prints a informational message with a new line
|
||||
Infoln = func(a ...interface{}) { privatePrintln(levelInfo, a...) } |
||||
// Infof prints a informational message with formatting
|
||||
Infof = func(f string, a ...interface{}) { privatePrintf(levelInfo, f, a...) } |
||||
|
||||
// Debug prints a debug message
|
||||
Debug = func(a ...interface{}) { privatePrint(levelDebug, a...) } |
||||
// Debugln prints a debug message with a new line
|
||||
Debugln = func(a ...interface{}) { privatePrintln(levelDebug, a...) } |
||||
// Debugf prints a debug message with formatting
|
||||
Debugf = func(f string, a ...interface{}) { privatePrintf(levelDebug, f, a...) } |
||||
|
||||
// Print prints a debug message
|
||||
Print = func(a ...interface{}) { privatePrint(levelPrint, a...) } |
||||
// Println prints a debug message with a new line
|
||||
Println = func(a ...interface{}) { privatePrintln(levelPrint, a...) } |
||||
// Printf prints a debug message with formatting
|
||||
Printf = func(f string, a ...interface{}) { privatePrintf(levelPrint, f, a...) } |
||||
) |
||||
|
||||
var ( |
||||
// print prints a message prefixed with message type and program name
|
||||
privatePrint = func(l logLevel, a ...interface{}) { |
||||
switch l { |
||||
case levelDebug: |
||||
mutex.Lock() |
||||
fmt.Fprint(os.Stderr, ProgramName()+": <DEBUG> ") |
||||
fmt.Fprint(os.Stderr, a...) |
||||
mutex.Unlock() |
||||
case levelInfo: |
||||
mutex.Lock() |
||||
fmt.Print(ProgramName() + ": <INFO> ") |
||||
fmt.Print(a...) |
||||
mutex.Unlock() |
||||
case levelError: |
||||
mutex.Lock() |
||||
fmt.Fprint(os.Stderr, ProgramName()+": <ERROR> ") |
||||
fmt.Fprint(os.Stderr, a...) |
||||
mutex.Unlock() |
||||
case levelFatal: |
||||
mutex.Lock() |
||||
fmt.Fprint(os.Stderr, ProgramName()+": <FATAL> ") |
||||
fmt.Fprint(os.Stderr, a...) |
||||
mutex.Unlock() |
||||
os.Exit(1) |
||||
default: |
||||
fmt.Print(a...) |
||||
} |
||||
} |
||||
|
||||
// println - same as print with a new line
|
||||
privatePrintln = func(l logLevel, a ...interface{}) { |
||||
switch l { |
||||
case levelDebug: |
||||
mutex.Lock() |
||||
fmt.Fprint(os.Stderr, ProgramName()+": <DEBUG> ") |
||||
fmt.Fprintln(os.Stderr, a...) |
||||
mutex.Unlock() |
||||
case levelInfo: |
||||
mutex.Lock() |
||||
fmt.Print(ProgramName() + ": <INFO> ") |
||||
fmt.Println(a...) |
||||
mutex.Unlock() |
||||
case levelError: |
||||
mutex.Lock() |
||||
fmt.Fprint(os.Stderr, ProgramName()+": <ERROR> ") |
||||
fmt.Fprintln(os.Stderr, a...) |
||||
mutex.Unlock() |
||||
case levelFatal: |
||||
mutex.Lock() |
||||
fmt.Fprint(os.Stderr, ProgramName()+": <FATAL> ") |
||||
fmt.Fprintln(os.Stderr, a...) |
||||
mutex.Unlock() |
||||
os.Exit(1) |
||||
default: |
||||
fmt.Print(a...) |
||||
} |
||||
} |
||||
|
||||
// printf - same as print, but takes a format specifier
|
||||
privatePrintf = func(l logLevel, f string, a ...interface{}) { |
||||
switch l { |
||||
case levelDebug: |
||||
mutex.Lock() |
||||
fmt.Fprint(os.Stderr, ProgramName()+": <DEBUG> ") |
||||
fmt.Fprintf(os.Stderr, f, a...) |
||||
mutex.Unlock() |
||||
case levelInfo: |
||||
mutex.Lock() |
||||
fmt.Print(ProgramName() + ": <INFO> ") |
||||
fmt.Printf(f, a...) |
||||
mutex.Unlock() |
||||
case levelError: |
||||
mutex.Lock() |
||||
fmt.Fprint(os.Stderr, ProgramName()+": <ERROR> ") |
||||
fmt.Fprintf(os.Stderr, f, a...) |
||||
mutex.Unlock() |
||||
|
||||
case levelFatal: |
||||
mutex.Lock() |
||||
fmt.Fprint(os.Stderr, ProgramName()+": <FATAL> ") |
||||
fmt.Fprintf(os.Stderr, f, a...) |
||||
mutex.Unlock() |
||||
os.Exit(1) |
||||
default: |
||||
fmt.Printf(f, a...) |
||||
} |
||||
} |
||||
) |
||||
|
||||
// ProgramName - return the name of the executable program
|
||||
func ProgramName() string { |
||||
_, progName := filepath.Split(os.Args[0]) |
||||
return progName |
||||
} |
@ -1,190 +0,0 @@ |
||||
/* |
||||
* Minio Cloud Storage, (C) 2015 Minio, Inc. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package main |
||||
|
||||
import ( |
||||
"fmt" |
||||
"os" |
||||
"os/user" |
||||
"path/filepath" |
||||
"runtime" |
||||
"strconv" |
||||
"time" |
||||
|
||||
"github.com/dustin/go-humanize" |
||||
"github.com/minio/cli" |
||||
"github.com/minio/minio/pkg/donut" |
||||
"github.com/minio/minio/pkg/iodine" |
||||
) |
||||
|
||||
var globalDebugFlag = false |
||||
|
||||
var flags = []cli.Flag{ |
||||
cli.BoolFlag{ |
||||
Name: "debug", |
||||
Usage: "print debug information", |
||||
}, |
||||
} |
||||
var commands = []cli.Command{ |
||||
{ |
||||
Name: "make", |
||||
Description: "make a donut", |
||||
Action: runMkdonut, |
||||
CustomHelpTemplate: `NAME: |
||||
donut {{.Name}} - {{.Description}} |
||||
|
||||
USAGE: |
||||
donut {{.Name}} DONUTNAME [DISKS...] |
||||
|
||||
EXAMPLES: |
||||
1. Make a donut with 4 exports |
||||
$ donut {{.Name}} mongodb-backup /mnt/export1 /mnt/export2 /mnt/export3 /mnt/export4 |
||||
|
||||
2. Make a donut with 16 exports |
||||
$ donut {{.Name}} operational-data /mnt/export1 /mnt/export2 /mnt/export3 /mnt/export4 /mnt/export5 \
|
||||
/mnt/export6 /mnt/export7 /mnt/export8 /mnt/export9 /mnt/export10 /mnt/export11 \
|
||||
/mnt/export12 /mnt/export13 /mnt/export14 /mnt/export15 /mnt/export16 |
||||
`, |
||||
}, |
||||
} |
||||
|
||||
func init() { |
||||
// Check for the environment early on and gracefuly report.
|
||||
_, err := user.Current() |
||||
if err != nil { |
||||
Fatalf("Unable to obtain user's home directory. \nError: %s\n", err) |
||||
} |
||||
} |
||||
|
||||
// Tries to get os/arch/platform specific information
|
||||
// Returns a map of current os/arch/platform/memstats
|
||||
func getSystemData() map[string]string { |
||||
host, err := os.Hostname() |
||||
if err != nil { |
||||
host = "" |
||||
} |
||||
memstats := &runtime.MemStats{} |
||||
runtime.ReadMemStats(memstats) |
||||
mem := fmt.Sprintf("Used: %s | Allocated: %s | Used-Heap: %s | Allocated-Heap: %s", |
||||
humanize.Bytes(memstats.Alloc), |
||||
humanize.Bytes(memstats.TotalAlloc), |
||||
humanize.Bytes(memstats.HeapAlloc), |
||||
humanize.Bytes(memstats.HeapSys)) |
||||
platform := fmt.Sprintf("Host: %s | OS: %s | Arch: %s", |
||||
host, |
||||
runtime.GOOS, |
||||
runtime.GOARCH) |
||||
goruntime := fmt.Sprintf("Version: %s | CPUs: %s", runtime.Version(), strconv.Itoa(runtime.NumCPU())) |
||||
return map[string]string{ |
||||
"PLATFORM": platform, |
||||
"RUNTIME": goruntime, |
||||
"MEM": mem, |
||||
} |
||||
} |
||||
|
||||
func runMkdonut(c *cli.Context) { |
||||
if !c.Args().Present() || c.Args().First() == "help" { |
||||
cli.ShowCommandHelpAndExit(c, "make", 1) |
||||
} |
||||
donutName := c.Args().First() |
||||
if c.Args().First() != "" { |
||||
if !donut.IsValidDonut(donutName) { |
||||
Fatalf("Invalid donutname %s\n", donutName) |
||||
} |
||||
} |
||||
var disks []string |
||||
for _, disk := range c.Args().Tail() { |
||||
if _, err := isUsable(disk); err != nil { |
||||
Fatalln(err) |
||||
} |
||||
disks = append(disks, disk) |
||||
} |
||||
for _, disk := range disks { |
||||
if err := os.MkdirAll(filepath.Join(disk, donutName), 0700); err != nil { |
||||
Fatalln(err) |
||||
} |
||||
} |
||||
|
||||
hostname, err := os.Hostname() |
||||
if err != nil { |
||||
Fatalln(err) |
||||
} |
||||
donutConfig := &donut.Config{} |
||||
donutConfig.Version = "0.0.1" |
||||
donutConfig.DonutName = donutName |
||||
donutConfig.NodeDiskMap = make(map[string][]string) |
||||
// keep it in exact order as it was specified, do not try to sort disks
|
||||
donutConfig.NodeDiskMap[hostname] = disks |
||||
// default cache is unlimited
|
||||
donutConfig.MaxSize = 512000000 |
||||
|
||||
if err := donut.SaveConfig(donutConfig); err != nil { |
||||
Fatalln(err) |
||||
} |
||||
|
||||
Infoln("Success!") |
||||
} |
||||
|
||||
func main() { |
||||
// set up iodine
|
||||
iodine.SetGlobalState("mkdonut.version", Version) |
||||
iodine.SetGlobalState("mkdonut.starttime", time.Now().Format(time.RFC3339)) |
||||
|
||||
// set up go max processes
|
||||
runtime.GOMAXPROCS(runtime.NumCPU()) |
||||
|
||||
// set up app
|
||||
app := cli.NewApp() |
||||
app.Name = "donut" |
||||
app.Version = getVersion() |
||||
app.Compiled = getVersion() |
||||
app.Author = "Minio.io" |
||||
app.Usage = "Donut maker" |
||||
app.Commands = commands |
||||
app.Flags = flags |
||||
app.Before = func(c *cli.Context) error { |
||||
globalDebugFlag = c.GlobalBool("debug") |
||||
return nil |
||||
} |
||||
app.ExtraInfo = func() map[string]string { |
||||
if globalDebugFlag { |
||||
return getSystemData() |
||||
} |
||||
return make(map[string]string) |
||||
} |
||||
app.CustomAppHelpTemplate = `NAME: |
||||
{{.Name}} - {{.Usage}} |
||||
|
||||
USAGE: |
||||
{{.Name}} {{if .Flags}}[global flags] {{end}}command{{if .Flags}} [command flags]{{end}} [arguments...] |
||||
|
||||
COMMANDS: |
||||
{{range .Commands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}} |
||||
{{end}}{{if .Flags}} |
||||
GLOBAL FLAGS: |
||||
{{range .Flags}}{{.}} |
||||
{{end}}{{end}} |
||||
VERSION: |
||||
{{if .Compiled}} |
||||
{{.Compiled}}{{end}} |
||||
{{range $key, $value := ExtraInfo}} |
||||
{{$key}}: |
||||
{{$value}} |
||||
{{end}} |
||||
` |
||||
app.RunAndExitOnError() |
||||
} |
@ -1,121 +0,0 @@ |
||||
// +build ignore
|
||||
|
||||
/* |
||||
* Makefile alternative for Minio Cloud Storage, (C) 2015 Minio, Inc. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package main |
||||
|
||||
import ( |
||||
"bytes" |
||||
"flag" |
||||
"fmt" |
||||
"os" |
||||
"os/exec" |
||||
"text/template" |
||||
"time" |
||||
) |
||||
|
||||
type Version struct { |
||||
Date string |
||||
} |
||||
|
||||
func writeVersion(version Version) error { |
||||
var versionTemplate = `// -------- DO NOT EDIT --------
|
||||
// this is an autogenerated file
|
||||
|
||||
package main |
||||
|
||||
import ( |
||||
"net/http" |
||||
"time" |
||||
) |
||||
|
||||
// Version autogenerated
|
||||
var Version = {{if .Date}}"{{.Date}}"{{else}}""{{end}} |
||||
|
||||
// getVersion -
|
||||
func getVersion() string { |
||||
t, _ := time.Parse(time.RFC3339Nano, Version) |
||||
if t.IsZero() { |
||||
return "" |
||||
} |
||||
return t.Format(http.TimeFormat) |
||||
} |
||||
` |
||||
t := template.Must(template.New("version").Parse(versionTemplate)) |
||||
versionFile, err := os.OpenFile("version.go", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
defer versionFile.Close() |
||||
err = t.Execute(versionFile, version) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
type command struct { |
||||
cmd *exec.Cmd |
||||
stderr *bytes.Buffer |
||||
stdout *bytes.Buffer |
||||
} |
||||
|
||||
func (c command) runCommand() error { |
||||
c.cmd.Stdout = c.stdout |
||||
c.cmd.Stderr = c.stderr |
||||
return c.cmd.Run() |
||||
} |
||||
func (c command) String() string { |
||||
message := c.stderr.String() |
||||
message += c.stdout.String() |
||||
return message |
||||
} |
||||
|
||||
func runDonutInstall() { |
||||
donutInstall := command{exec.Command("godep", "go", "install", "-a", "github.com/minio/minio/cmd/donut"), &bytes.Buffer{}, &bytes.Buffer{}} |
||||
donutInstallErr := donutInstall.runCommand() |
||||
if donutInstallErr != nil { |
||||
fmt.Println(donutInstall) |
||||
os.Exit(1) |
||||
} |
||||
fmt.Print(donutInstall) |
||||
} |
||||
|
||||
func runDonutRelease() { |
||||
t := time.Now().UTC() |
||||
date := t.Format(time.RFC3339Nano) |
||||
version := Version{Date: date} |
||||
err := writeVersion(version) |
||||
if err != nil { |
||||
fmt.Print(err) |
||||
os.Exit(1) |
||||
} |
||||
} |
||||
|
||||
func main() { |
||||
releaseFlag := flag.Bool("release", false, "make a release") |
||||
installFlag := flag.Bool("install", false, "install donut") |
||||
|
||||
flag.Parse() |
||||
|
||||
if *releaseFlag { |
||||
runDonutRelease() |
||||
} |
||||
if *installFlag { |
||||
runDonutInstall() |
||||
} |
||||
} |
@ -1,21 +0,0 @@ |
||||
// -------- DO NOT EDIT --------
|
||||
// this is an autogenerated file
|
||||
|
||||
package main |
||||
|
||||
import ( |
||||
"net/http" |
||||
"time" |
||||
) |
||||
|
||||
// Version autogenerated
|
||||
var Version = "2015-07-13T01:59:53.151205631Z" |
||||
|
||||
// getVersion -
|
||||
func getVersion() string { |
||||
t, _ := time.Parse(time.RFC3339Nano, Version) |
||||
if t.IsZero() { |
||||
return "" |
||||
} |
||||
return t.Format(http.TimeFormat) |
||||
} |
Loading…
Reference in new issue