diff --git a/commands.go b/commands.go index 2cae91df6..26a52bdce 100644 --- a/commands.go +++ b/commands.go @@ -4,6 +4,7 @@ import ( "os/user" "github.com/minio/cli" + "github.com/minio/minio/pkg/controller" "github.com/minio/minio/pkg/server" "github.com/minio/minio/pkg/server/api" ) @@ -41,8 +42,11 @@ USAGE: minio {{.Name}} EXAMPLES: - 1. Start in controller mode - $ minio {{.Name}} + 1. Get disks from controller + $ minio {{.Name}} disks http://localhost:9001/rpc + + 2. Get memstats from controller + $ minio {{.Name}} mem http://localhost:9001/rpc `, } @@ -79,4 +83,21 @@ func runController(c *cli.Context) { if err != nil { Fatalf("Unable to determine current user. Reason: %s\n", err) } + if len(c.Args()) != 2 || c.Args().First() == "help" { + cli.ShowCommandHelpAndExit(c, "controller", 1) // last argument is exit code + } + switch c.Args().First() { + case "disks": + disks, err := controller.GetDisks(c.Args().Tail().First()) + if err != nil { + Fatalln(err) + } + Println(disks) + case "mem": + memstats, err := controller.GetMemStats(c.Args().Tail().First()) + if err != nil { + Fatalln(err) + } + Println(string(memstats)) + } } diff --git a/console.go b/console.go index 9a6af599c..49daec834 100644 --- a/console.go +++ b/console.go @@ -28,6 +28,7 @@ type logLevel int const ( levelUnknown logLevel = iota + levelPrint levelDebug levelInfo levelError @@ -64,6 +65,13 @@ var ( 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 ( diff --git a/pkg/controller/client.go b/pkg/controller/client.go new file mode 100644 index 000000000..88bcd98ec --- /dev/null +++ b/pkg/controller/client.go @@ -0,0 +1,72 @@ +/* + * Minimalist Object 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 controller + +import ( + "encoding/json" + "net/http" + + jsonrpc "github.com/gorilla/rpc/v2/json" + "github.com/minio/minio/pkg/iodine" + "github.com/minio/minio/pkg/server/rpc" +) + +// GetDisks get disks info of the server at given url +func GetDisks(url string) ([]string, error) { + op := RPCOps{ + Method: "DiskInfo.Get", + Request: rpc.Args{Request: ""}, + } + req, err := NewRequest(url, op, http.DefaultTransport) + if err != nil { + return nil, iodine.New(err, nil) + } + resp, err := req.Do() + if err != nil { + return nil, iodine.New(err, nil) + } + defer resp.Body.Close() + var reply rpc.DiskInfoReply + if err := jsonrpc.DecodeClientResponse(resp.Body, &reply); err != nil { + return nil, iodine.New(err, nil) + } + return reply.Disks, nil +} + +// GetMemStats get system info of the server at given url +func GetMemStats(url string) ([]byte, error) { + op := RPCOps{ + Method: "SysInfo.Get", + Request: rpc.Args{Request: ""}, + } + req, err := NewRequest(url, op, http.DefaultTransport) + if err != nil { + return nil, iodine.New(err, nil) + } + resp, err := req.Do() + if err != nil { + return nil, iodine.New(err, nil) + } + defer resp.Body.Close() + var reply rpc.SysInfoReply + if err := jsonrpc.DecodeClientResponse(resp.Body, &reply); err != nil { + return nil, iodine.New(err, nil) + } + return json.MarshalIndent(reply, "", "\t") +} + +// Add more functions here for many replies diff --git a/pkg/controller/rpc.go b/pkg/controller/rpc.go new file mode 100644 index 000000000..51934826f --- /dev/null +++ b/pkg/controller/rpc.go @@ -0,0 +1,66 @@ +/* + * Minimalist Object 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 controller + +import ( + "bytes" + "net/http" + + "github.com/gorilla/rpc/v2/json" + "github.com/minio/minio/pkg/iodine" +) + +// RPCOps RPC operation +type RPCOps struct { + Method string + Request interface{} +} + +// RPCRequest rpc client request +type RPCRequest struct { + req *http.Request + transport http.RoundTripper +} + +// NewRequest initiate a new client RPC request +func NewRequest(url string, op RPCOps, transport http.RoundTripper) (*RPCRequest, error) { + params, err := json.EncodeClientRequest(op.Method, op.Request) + if err != nil { + return nil, iodine.New(err, nil) + } + req, err := http.NewRequest("POST", url, bytes.NewReader(params)) + if err != nil { + return nil, iodine.New(err, nil) + } + rpcReq := &RPCRequest{} + rpcReq.req = req + rpcReq.req.Header.Set("Content-Type", "application/json") + if transport == nil { + transport = http.DefaultTransport + } + rpcReq.transport = transport + return rpcReq, nil +} + +// Do - make a http connection +func (r RPCRequest) Do() (*http.Response, error) { + resp, err := r.transport.RoundTrip(r.req) + if err != nil { + return nil, iodine.New(err, nil) + } + return resp, nil +} diff --git a/pkg/server/router.go b/pkg/server/router.go index 21339e7c6..8ecebee12 100644 --- a/pkg/server/router.go +++ b/pkg/server/router.go @@ -24,11 +24,6 @@ import ( "github.com/minio/minio/pkg/server/rpc" ) -// Get api -func getAPI() api.Minio { - return api.New() -} - // registerAPI - register all the object API handlers to their respective paths func registerAPI(mux *router.Router, a api.Minio) http.Handler { mux.HandleFunc("/", a.ListBucketsHandler).Methods("GET") @@ -107,7 +102,7 @@ func registerRPC(mux *router.Router, s *rpc.Server) http.Handler { // getAPIHandler api handler func getAPIHandler(conf api.Config) (http.Handler, api.Minio) { mux := router.NewRouter() - minioAPI := getAPI() + minioAPI := api.New() apiHandler := registerAPI(mux, minioAPI) apiHandler = registerCustomMiddleware(apiHandler, conf) return apiHandler, minioAPI