From 1d64e4b6c185a833d9b78583c2d652de3e0fdc64 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Mon, 6 Jul 2015 10:35:23 -0700 Subject: [PATCH] Add Donut rpc service for sending changes to configuration files --- commands.go | 8 ++++++- pkg/controller/client.go | 27 +++++++++++++++++++++++ pkg/donut/config.go | 1 + pkg/donut/disk/disk.go | 10 ++++----- pkg/server/api/api.go | 5 ++++- pkg/server/router.go | 1 + pkg/server/rpc/{setdonut.go => donut.go} | 28 +++++++++++++++++++----- 7 files changed, 67 insertions(+), 13 deletions(-) rename pkg/server/rpc/{setdonut.go => donut.go} (64%) diff --git a/commands.go b/commands.go index ba7bd8560..73f0f4912 100644 --- a/commands.go +++ b/commands.go @@ -106,7 +106,7 @@ 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" { + if len(c.Args()) <= 2 || c.Args().First() == "help" { cli.ShowCommandHelpAndExit(c, "controller", 1) // last argument is exit code } switch c.Args().First() { @@ -122,5 +122,11 @@ func runController(c *cli.Context) { Fatalln(err) } Println(string(memstats)) + case "donut": + hostname, _ := os.Hostname() + err := controller.SetDonut(c.Args().Tail().First(), hostname, c.Args().Tail().Tail()) + if err != nil { + Fatalln(err) + } } } diff --git a/pkg/controller/client.go b/pkg/controller/client.go index 88bcd98ec..7f91a661c 100644 --- a/pkg/controller/client.go +++ b/pkg/controller/client.go @@ -69,4 +69,31 @@ func GetMemStats(url string) ([]byte, error) { return json.MarshalIndent(reply, "", "\t") } +// SetDonut - set donut config +func SetDonut(url, hostname string, disks []string) error { + op := RPCOps{ + Method: "Donut.Set", + Request: rpc.DonutArgs{ + Hostname: hostname, + Disks: disks, + Name: "default", + MaxSize: 512000000, + }, + } + req, err := NewRequest(url, op, http.DefaultTransport) + if err != nil { + return iodine.New(err, nil) + } + resp, err := req.Do() + if err != nil { + return iodine.New(err, nil) + } + defer resp.Body.Close() + var reply rpc.Reply + if err := jsonrpc.DecodeClientResponse(resp.Body, &reply); err != nil { + return iodine.New(err, nil) + } + return reply.Error +} + // Add more functions here for many replies diff --git a/pkg/donut/config.go b/pkg/donut/config.go index 60cccc372..a9bcbf749 100644 --- a/pkg/donut/config.go +++ b/pkg/donut/config.go @@ -34,6 +34,7 @@ func getDonutConfigPath() (string, error) { return donutConfigPath, nil } +// NOTE - this is not to be used outside Donut package, this is primarily intended for testing purposes only var customConfigPath string // SaveConfig save donut config diff --git a/pkg/donut/disk/disk.go b/pkg/donut/disk/disk.go index 326777de8..ad7ecdbb5 100644 --- a/pkg/donut/disk/disk.go +++ b/pkg/donut/disk/disk.go @@ -38,11 +38,6 @@ func New(diskPath string) (Disk, error) { if diskPath == "" { return Disk{}, iodine.New(InvalidArgument{}, nil) } - s := syscall.Statfs_t{} - err := syscall.Statfs(diskPath, &s) - if err != nil { - return Disk{}, iodine.New(err, nil) - } st, err := os.Stat(diskPath) if err != nil { return Disk{}, iodine.New(err, nil) @@ -50,6 +45,11 @@ func New(diskPath string) (Disk, error) { if !st.IsDir() { return Disk{}, iodine.New(syscall.ENOTDIR, nil) } + s := syscall.Statfs_t{} + err = syscall.Statfs(diskPath, &s) + if err != nil { + return Disk{}, iodine.New(err, nil) + } disk := Disk{ path: diskPath, fsInfo: make(map[string]string), diff --git a/pkg/server/api/api.go b/pkg/server/api/api.go index c20176cb6..389ce63e8 100644 --- a/pkg/server/api/api.go +++ b/pkg/server/api/api.go @@ -32,7 +32,10 @@ type Minio struct { // New instantiate a new minio API func New() Minio { // ignore errors for now - d, _ := donut.New() + d, err := donut.New() + if err != nil { + panic(err) + } return Minio{ OP: make(chan Operation), Donut: d, diff --git a/pkg/server/router.go b/pkg/server/router.go index 8ecebee12..7fa25b542 100644 --- a/pkg/server/router.go +++ b/pkg/server/router.go @@ -115,6 +115,7 @@ func getRPCHandler() http.Handler { s.RegisterService(new(rpc.VersionService), "Version") s.RegisterService(new(rpc.SysInfoService), "SysInfo") s.RegisterService(new(rpc.DiskInfoService), "DiskInfo") + s.RegisterService(new(rpc.DonutService), "Donut") // Add new services here return registerRPC(router.NewRouter(), s) } diff --git a/pkg/server/rpc/setdonut.go b/pkg/server/rpc/donut.go similarity index 64% rename from pkg/server/rpc/setdonut.go rename to pkg/server/rpc/donut.go index 2017613e6..4754955ce 100644 --- a/pkg/server/rpc/setdonut.go +++ b/pkg/server/rpc/donut.go @@ -16,16 +16,22 @@ package rpc -import "net/http" +import ( + "net/http" + + "github.com/minio/minio/pkg/donut" + "github.com/minio/minio/pkg/iodine" +) // DonutService donut service type DonutService struct{} // DonutArgs collections of disks and name to initialize donut type DonutArgs struct { - MaxSize int64 - Name string - Disks []string + Name string + MaxSize uint64 + Hostname string + Disks []string } // Reply reply for successful or failed Set operation @@ -34,11 +40,21 @@ type Reply struct { Error error `json:"error"` } -func setDonutArgs(args *DonutArgs, reply *Reply) error { +func setDonut(args *DonutArgs, reply *Reply) error { + conf := &donut.Config{Version: "0.0.1"} + conf.DonutName = args.Name + conf.MaxSize = args.MaxSize + conf.NodeDiskMap = make(map[string][]string) + conf.NodeDiskMap[args.Hostname] = args.Disks + if err := donut.SaveConfig(conf); err != nil { + return iodine.New(err, nil) + } + reply.Message = "success" + reply.Error = nil return nil } // Set method func (s *DonutService) Set(r *http.Request, args *DonutArgs, reply *Reply) error { - return setDonutArgs(args, reply) + return setDonut(args, reply) }