diff --git a/Makefile b/Makefile index 867c9fdf3..740ce7dea 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -all: getdeps install +all: install checkdeps: @echo "Checking deps:" diff --git a/commands.go b/commands.go index 4673185d9..58979aabe 100644 --- a/commands.go +++ b/commands.go @@ -16,181 +16,12 @@ package main -import ( - "os" - "path/filepath" +import "github.com/minio/minio/internal/github.com/minio/cli" - "github.com/minio/minio/internal/github.com/minio/cli" - "github.com/minio/minio/pkg/controller" - "github.com/minio/minio/pkg/donut" - "github.com/minio/minio/pkg/server" - "github.com/minio/minio/pkg/server/api" -) +// Collection of minio commands currently supported are +var commands = []cli.Command{} -var commands = []cli.Command{ - serverCmd, - controllerCmd, - donutCmd, -} - -var serverCmd = cli.Command{ - Name: "server", - Description: "Server mode", - Action: runServer, - CustomHelpTemplate: `NAME: - minio {{.Name}} - {{.Description}} - -USAGE: - minio {{.Name}} - -EXAMPLES: - 1. Start in server mode - $ minio {{.Name}} - -`, -} - -var controllerCmd = cli.Command{ - Name: "controller", - Description: "Control mode", - Action: runController, - CustomHelpTemplate: `NAME: - minio {{.Name}} - {{.Description}} - -USAGE: - minio {{.Name}} - -EXAMPLES: - 1. Get disks from controller - $ minio {{.Name}} disks http://localhost:9001/rpc - - 2. Get memstats from controller - $ minio {{.Name}} mem http://localhost:9001/rpc - -`, -} - -var donutSubCommands = []cli.Command{ - { - Name: "make", - Description: "make a donut", - Action: runMkdonut, - CustomHelpTemplate: `NAME: - minio donut {{.Name}} - {{.Description}} - -USAGE: - minio donut {{.Name}} DONUTNAME [DISKS...] - -EXAMPLES: - 1. Make a donut with 4 exports - $ minio donut {{.Name}} mongodb-backup /mnt/export1 /mnt/export2 /mnt/export3 /mnt/export4 - - 2. Make a donut with 16 exports - $ minio 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 -`, - }, -} - -var donutCmd = cli.Command{ - Name: "donut", - Description: "Donut maker", - Subcommands: donutSubCommands, -} - -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 getServerConfig(c *cli.Context) api.Config { - certFile := c.GlobalString("cert") - keyFile := c.GlobalString("key") - if (certFile != "" && keyFile == "") || (certFile == "" && keyFile != "") { - Fatalln("Both certificate and key are required to enable https.") - } - tls := (certFile != "" && keyFile != "") - return api.Config{ - Address: c.GlobalString("address"), - TLS: tls, - CertFile: certFile, - KeyFile: keyFile, - RateLimit: c.GlobalInt("ratelimit"), - } -} - -func runServer(c *cli.Context) { - if c.Args().Present() { - cli.ShowCommandHelpAndExit(c, "server", 1) - } - apiServerConfig := getServerConfig(c) - err := server.StartServices(apiServerConfig) - if err != nil { - Fatalln(err) - } -} - -func runController(c *cli.Context) { - if len(c.Args()) < 2 || c.Args().First() == "help" { - cli.ShowCommandHelpAndExit(c, "controller", 1) // last argument is exit code - } - switch c.Args().First() { - case "mem": - memstats, err := controller.GetMemStats(c.Args().Tail().First()) - if err != nil { - Fatalln(err) - } - Println(string(memstats)) - case "sysinfo": - sysinfo, err := controller.GetSysInfo(c.Args().Tail().First()) - if err != nil { - Fatalln(err) - } - Println(string(sysinfo)) - case "auth": - keys, err := controller.GetAuthKeys(c.Args().Tail().First()) - if err != nil { - Fatalln(err) - } - Println(string(keys)) - } +// registerCommand registers a cli command +func registerCommand(command cli.Command) { + commands = append(commands, command) } diff --git a/console.go b/console.go index c3caedddd..5f640061a 100644 --- a/console.go +++ b/console.go @@ -129,7 +129,7 @@ var ( mutex.Unlock() os.Exit(1) default: - fmt.Print(a...) + fmt.Println(a...) } } diff --git a/controller-main.go b/controller-main.go new file mode 100644 index 000000000..f7efb65c0 --- /dev/null +++ b/controller-main.go @@ -0,0 +1,74 @@ +/* + * 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 ( + "github.com/minio/minio/internal/github.com/minio/cli" + "github.com/minio/minio/pkg/controller" +) + +var controllerCmd = cli.Command{ + Name: "controller", + Usage: "Get|Set server configuration", + Action: controllerMain, + CustomHelpTemplate: `NAME: + minio {{.Name}} - {{.Description}} + +USAGE: + minio {{.Name}} [get|set] [INFOTYPE] [SERVERURL] + +EXAMPLES: + 1. Get disks from controller + $ minio {{.Name}} get disks http://localhost:9001/rpc + + 2. Get memstats from controller + $ minio {{.Name}} get mem http://localhost:9001/rpc + +`, +} + +func controllerMain(c *cli.Context) { + if len(c.Args()) < 2 || c.Args().First() == "help" { + cli.ShowCommandHelpAndExit(c, "controller", 1) // last argument is exit code + } + if c.Args().First() == "get" { + newArgs := c.Args().Tail() + switch newArgs.First() { + case "mem": + memstats, err := controller.GetMemStats(newArgs.Tail().First()) + if err != nil { + Fatalln(err) + } + Println(string(memstats)) + case "sysinfo": + sysinfo, err := controller.GetSysInfo(newArgs.Tail().First()) + if err != nil { + Fatalln(err) + } + Println(string(sysinfo)) + case "auth": + keys, err := controller.GetAuthKeys(newArgs.Tail().First()) + if err != nil { + Fatalln(err) + } + Println(string(keys)) + } + } + if c.Args().First() == "set" { + Fatalln("Not supported yet") + } +} diff --git a/donut-main.go b/donut-main.go new file mode 100644 index 000000000..48380e1a1 --- /dev/null +++ b/donut-main.go @@ -0,0 +1,99 @@ +/* + * 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 ( + "os" + "path/filepath" + + "github.com/minio/minio/internal/github.com/minio/cli" + "github.com/minio/minio/pkg/donut" +) + +var ( + donutSubCommands = []cli.Command{ + { + Name: "make", + Description: "make a donut", + Action: makeDonutMain, + CustomHelpTemplate: `NAME: + minio donut {{.Name}} - {{.Description}} + +USAGE: + minio donut {{.Name}} DONUTNAME [DISKS...] + +EXAMPLES: + 1. Make a donut with 4 exports + $ minio donut {{.Name}} mongodb-backup /mnt/export1 /mnt/export2 /mnt/export3 /mnt/export4 + + 2. Make a donut with 16 exports + $ minio 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 +`, + }, + } + + donutCmd = cli.Command{ + Name: "donut", + Usage: "Create and manage a donut configuration", + Subcommands: donutSubCommands, + } +) + +func makeDonutMain(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!") +} diff --git a/flags.go b/flags.go new file mode 100644 index 000000000..ae6ad2872 --- /dev/null +++ b/flags.go @@ -0,0 +1,63 @@ +/* + * 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 "github.com/minio/minio/internal/github.com/minio/cli" + +// Collection of minio flags currently supported +var flags = []cli.Flag{} + +var ( + addressFlag = cli.StringFlag{ + Name: "address", + Value: ":9000", + Usage: "ADDRESS:PORT for cloud storage access", + } + + addressMgmtFlag = cli.StringFlag{ + Name: "address-mgmt", + Hide: true, + Value: ":9001", + Usage: "ADDRESS:PORT for management console access", + } + + ratelimitFlag = cli.IntFlag{ + Name: "ratelimit", + Value: 16, + Usage: "Limit for total concurrent requests: [DEFAULT: 16]", + } + + certFlag = cli.StringFlag{ + Name: "cert", + Usage: "Provide your domain certificate", + } + + keyFlag = cli.StringFlag{ + Name: "key", + Usage: "Provide your domain private key", + } + + debugFlag = cli.BoolFlag{ + Name: "debug", + Usage: "print debug information", + } +) + +// registerFlag registers a cli flag +func registerFlag(flag cli.Flag) { + flags = append(flags, flag) +} diff --git a/genversion.go b/genversion.go index 39f0de5b2..c72ff10d1 100644 --- a/genversion.go +++ b/genversion.go @@ -20,6 +20,7 @@ package main import ( "fmt" + "net/http" "os" "text/template" "time" @@ -27,37 +28,16 @@ import ( type Version struct { Date string - Tag string } func writeVersion(version Version) error { var versionTemplate = `// -------- DO NOT EDIT -------- -// this is an autogenerated file +// This file is autogenerated by genversion.go during the release process. package main -import ( - "net/http" - "time" -) - // Version autogenerated -var Version = {{if .Date}}"{{.Date}}"{{else}}""{{end}} - -// Tag is of following format -// -// RELEASE.[WeekDay]-[Month]-[Day]-[Hour]-[Min]-[Sec]-GMT-[Year] -// -var Tag = {{if .Tag}}"{{.Tag}}"{{else}}""{{end}} - -// getVersion - -func getVersion() string { - t, _ := time.Parse(time.RFC3339Nano, Version) - if t.IsZero() { - return "" - } - return t.Format(http.TimeFormat) -} +const Version = {{if .Date}}"{{.Date}}"{{else}}""{{end}} ` t := template.Must(template.New("version").Parse(versionTemplate)) versionFile, err := os.OpenFile("version.go", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) @@ -72,9 +52,13 @@ func getVersion() string { return nil } -func main() { +func genVersion() { t := time.Now().UTC() date := t.Format(time.RFC3339Nano) + // Tag is of following format + // + // RELEASE.[WeekDay]-[Month]-[Day]-[Hour]-[Min]-[Sec]-GMT-[Year] + // tag := fmt.Sprintf( "RELEASE.%s-%s-%02d-%02d-%02d-%02d-GMT-%d", t.Weekday().String()[0:3], @@ -83,12 +67,18 @@ func main() { t.Hour(), t.Minute(), t.Second(), - t.Year(), - ) - version := Version{Date: date, Tag: tag} + t.Year()) + fmt.Println("Release-Tag: " + tag) + fmt.Println("Release-Version: " + t.Format(http.TimeFormat)) + version := Version{Date: date} err := writeVersion(version) if err != nil { fmt.Print(err) os.Exit(1) } + fmt.Println("Successfully generated ‘version.go’") +} + +func main() { + genVersion() } diff --git a/main.go b/main.go index f82bfe815..025b11894 100644 --- a/main.go +++ b/main.go @@ -18,10 +18,12 @@ package main import ( "fmt" + "net/http" "os" "os/user" "runtime" "strconv" + "time" "github.com/minio/minio/internal/github.com/dustin/go-humanize" "github.com/minio/minio/internal/github.com/minio/cli" @@ -29,37 +31,6 @@ import ( var globalDebugFlag = false -var flags = []cli.Flag{ - cli.StringFlag{ - Name: "address", - Value: ":9000", - Usage: "ADDRESS:PORT for cloud storage access", - }, - cli.StringFlag{ - Name: "address-mgmt", - Hide: true, - Value: ":9001", - Usage: "ADDRESS:PORT for management console access", - }, - cli.IntFlag{ - Name: "ratelimit", - Value: 16, - Usage: "Limit for total concurrent requests: [DEFAULT: 16]", - }, - cli.StringFlag{ - Name: "cert", - Usage: "Provide your domain certificate", - }, - cli.StringFlag{ - Name: "key", - Usage: "Provide your domain private key", - }, - cli.BoolFlag{ - Name: "debug", - Usage: "print debug information", - }, -} - func init() { // Check for the environment early on and gracefuly report. _, err := user.Current() @@ -100,29 +71,39 @@ func init() { } } -func main() { - // set up go max processes - runtime.GOMAXPROCS(runtime.NumCPU()) +// getFormattedVersion - +func getFormattedVersion() string { + t, _ := time.Parse(time.RFC3339Nano, Version) + if t.IsZero() { + return "" + } + return t.Format(http.TimeFormat) +} + +func registerApp() *cli.App { + // register all commands + registerCommand(donutCmd) + registerCommand(serverCmd) + registerCommand(controllerCmd) + registerCommand(versionCmd) + + // register all flags + registerFlag(addressFlag) + registerFlag(addressMgmtFlag) + registerFlag(ratelimitFlag) + registerFlag(certFlag) + registerFlag(keyFlag) + registerFlag(debugFlag) // set up app app := cli.NewApp() app.Name = "minio" - app.Version = getVersion() - app.Compiled = getVersion() + // hide --version flag, version is a command + app.HideVersion = true app.Author = "Minio.io" app.Usage = "Minio Cloud Storage" app.Flags = flags app.Commands = commands - 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}} @@ -137,8 +118,9 @@ GLOBAL FLAGS: {{range .Flags}}{{.}} {{end}}{{end}} VERSION: - {{if .Compiled}} - {{.Compiled}}{{end}} + +` + getFormattedVersion() + + ` {{range $key, $value := ExtraInfo}} {{$key}}: {{$value}} @@ -149,5 +131,26 @@ VERSION: Fatalf("Command not found: ‘%s’\n", command) } + return app +} + +func registerBefore(c *cli.Context) error { + globalDebugFlag = c.GlobalBool("debug") + return nil +} + +func main() { + // set up go max processes + runtime.GOMAXPROCS(runtime.NumCPU()) + + app := registerApp() + app.Before = registerBefore + app.ExtraInfo = func() map[string]string { + if globalDebugFlag { + return getSystemData() + } + return make(map[string]string) + } + app.RunAndExitOnError() } diff --git a/server-main.go b/server-main.go new file mode 100644 index 000000000..ef77ad966 --- /dev/null +++ b/server-main.go @@ -0,0 +1,67 @@ +/* + * 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 ( + "github.com/minio/minio/internal/github.com/minio/cli" + "github.com/minio/minio/pkg/server" + "github.com/minio/minio/pkg/server/api" +) + +var serverCmd = cli.Command{ + Name: "server", + Usage: "Start minio server", + Action: serverMain, + CustomHelpTemplate: `NAME: + minio {{.Name}} - {{.Description}} + +USAGE: + minio {{.Name}} + +EXAMPLES: + 1. Start minio server + $ minio {{.Name}} + +`, +} + +func getServerConfig(c *cli.Context) api.Config { + certFile := c.GlobalString("cert") + keyFile := c.GlobalString("key") + if (certFile != "" && keyFile == "") || (certFile == "" && keyFile != "") { + Fatalln("Both certificate and key are required to enable https.") + } + tls := (certFile != "" && keyFile != "") + return api.Config{ + Address: c.GlobalString("address"), + TLS: tls, + CertFile: certFile, + KeyFile: keyFile, + RateLimit: c.GlobalInt("ratelimit"), + } +} + +func serverMain(c *cli.Context) { + if c.Args().Present() { + cli.ShowCommandHelpAndExit(c, "server", 1) + } + apiServerConfig := getServerConfig(c) + err := server.StartServices(apiServerConfig) + if err != nil { + Fatalln(err) + } +} diff --git a/version-main.go b/version-main.go new file mode 100644 index 000000000..219e0ee53 --- /dev/null +++ b/version-main.go @@ -0,0 +1,48 @@ +/* + * 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 ( + "net/http" + "time" + + "github.com/minio/minio/internal/github.com/minio/cli" +) + +var versionCmd = cli.Command{ + Name: "version", + Usage: "Print version", + Action: mainVersion, + CustomHelpTemplate: `NAME: + mc {{.Name}} - {{.Usage}} + +USAGE: + mc {{.Name}} {{if .Description}} + +EXAMPLES: + +`, +} + +func mainVersion(ctxx *cli.Context) { + t, _ := time.Parse(time.RFC3339Nano, Version) + if t.IsZero() { + Println("") + return + } + Println(t.Format(http.TimeFormat)) +} diff --git a/version.go b/version.go index e73f9d3c1..1d646b9f1 100644 --- a/version.go +++ b/version.go @@ -1,29 +1,7 @@ // -------- DO NOT EDIT -------- -// this is an autogenerated file +// This file is autogenerated by genversion.go during the release process. package main -import ( - "net/http" - "time" -) - // Version autogenerated -var Version = "2015-06-17T03:17:23.789648634Z" - -// Tag is of following format -// -// [[STRING]-[EPOCH] -// -// STRING is release string of your choice. -// EPOCH is unix seconds since Jan 1, 1970 UTC. -var Tag = "release-1434511043" - -// getVersion - -func getVersion() string { - t, _ := time.Parse(time.RFC3339Nano, Version) - if t.IsZero() { - return "" - } - return t.Format(http.TimeFormat) -} +const Version = "2015-08-14T03:23:47.250240049Z"