diff --git a/cli/src/alluxio.org/cli/cmd/quorum/elect.go b/cli/src/alluxio.org/cli/cmd/quorum/elect.go new file mode 100644 index 000000000000..001e2b87d3f4 --- /dev/null +++ b/cli/src/alluxio.org/cli/cmd/quorum/elect.go @@ -0,0 +1,62 @@ +/* + * The Alluxio Open Foundation licenses this work under the Apache License, version 2.0 + * (the "License"). You may not use this work except in compliance with the License, which is + * available at www.apache.org/licenses/LICENSE-2.0 + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied, as more fully set forth in the License. + * + * See the NOTICE file distributed with this work for information regarding copyright ownership. + */ + +package quorum + +import ( + "github.com/palantir/stacktrace" + "github.com/spf13/cobra" + + "alluxio.org/cli/env" +) + +var Elect = &ElectCommand{ + QuorumCommand: &QuorumCommand{ + BaseJavaCommand: &env.BaseJavaCommand{ + CommandName: "elect", + JavaClassName: "alluxio.cli.fsadmin.FileSystemAdminShell", + Parameters: []string{"journal", "quorum", "elect"}, + }, + allowedDomains: []string{domainMaster}, + }, +} + +type ElectCommand struct { + *QuorumCommand + + serverAddress string +} + +func (c *ElectCommand) ToCommand() *cobra.Command { + cmd := c.Base().InitRunJavaClassCmd(&cobra.Command{ + Use: Elect.CommandName, + Short: "Transfers leadership of the quorum to the specified server", + RunE: func(cmd *cobra.Command, args []string) error { + return c.Run(nil) + }, + }) + + const address = "address" + cmd.Flags().StringVar(&c.serverAddress, address, "", "Address of new leader server in the format :") + if err := cmd.MarkFlagRequired(address); err != nil { + panic(err) + } + return cmd +} + +func (c *ElectCommand) Run(_ []string) error { + if err := checkDomain(c.QuorumCommand.domain, c.QuorumCommand.allowedDomains...); err != nil { + return stacktrace.Propagate(err, "error checking domain %v", c.QuorumCommand.domain) + } + // TODO: ignore the domain flag for now since elect command can only operate on MASTER + // java command needs to be updated such that it can accept the domain flag + return c.Base().Run([]string{"-address", c.serverAddress}) +} diff --git a/cli/src/alluxio.org/cli/cmd/quorum/info.go b/cli/src/alluxio.org/cli/cmd/quorum/info.go new file mode 100644 index 000000000000..7c0c71091f01 --- /dev/null +++ b/cli/src/alluxio.org/cli/cmd/quorum/info.go @@ -0,0 +1,48 @@ +/* + * The Alluxio Open Foundation licenses this work under the Apache License, version 2.0 + * (the "License"). You may not use this work except in compliance with the License, which is + * available at www.apache.org/licenses/LICENSE-2.0 + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied, as more fully set forth in the License. + * + * See the NOTICE file distributed with this work for information regarding copyright ownership. + */ + +package quorum + +import ( + "github.com/spf13/cobra" + + "alluxio.org/cli/env" +) + +var Info = &InfoCommand{ + QuorumCommand: &QuorumCommand{ + BaseJavaCommand: &env.BaseJavaCommand{ + CommandName: "info", + JavaClassName: "alluxio.cli.fsadmin.FileSystemAdminShell", + Parameters: []string{"journal", "quorum", "info"}, + }, + allowedDomains: []string{domainJobMaster, domainMaster}, + }, +} + +type InfoCommand struct { + *QuorumCommand +} + +func (c *InfoCommand) ToCommand() *cobra.Command { + cmd := c.QuorumCommand.InitQuorumCmd(c.Base().InitRunJavaClassCmd(&cobra.Command{ + Use: Info.CommandName, + Short: "Shows quorum information", + RunE: func(cmd *cobra.Command, args []string) error { + return c.Run(nil) + }, + })) + return cmd +} + +func (c *InfoCommand) Run(_ []string) error { + return c.QuorumCommand.Run(nil) +} diff --git a/cli/src/alluxio.org/cli/cmd/quorum/quorum.go b/cli/src/alluxio.org/cli/cmd/quorum/quorum.go new file mode 100644 index 000000000000..9593642a5eb4 --- /dev/null +++ b/cli/src/alluxio.org/cli/cmd/quorum/quorum.go @@ -0,0 +1,78 @@ +/* + * The Alluxio Open Foundation licenses this work under the Apache License, version 2.0 + * (the "License"). You may not use this work except in compliance with the License, which is + * available at www.apache.org/licenses/LICENSE-2.0 + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied, as more fully set forth in the License. + * + * See the NOTICE file distributed with this work for information regarding copyright ownership. + */ + +package quorum + +import ( + "fmt" + "strings" + + "github.com/palantir/stacktrace" + "github.com/spf13/cobra" + + "alluxio.org/cli/env" +) + +var ( + Service = &env.Service{ + Name: "quorum", + Description: "Manage the high availability server quorum, such as electing a new leader", + Commands: []env.Command{ + Elect, + Info, + Remove, + }, + } +) + +const ( + domainJobMaster = "JOB_MASTER" + domainMaster = "MASTER" +) + +type QuorumCommand struct { + *env.BaseJavaCommand + + allowedDomains []string + domain string +} + +func (c *QuorumCommand) Base() *env.BaseJavaCommand { + return c.BaseJavaCommand +} + +func (c *QuorumCommand) InitQuorumCmd(cmd *cobra.Command) *cobra.Command { + const domain = "domain" + cmd.Flags().StringVar(&c.domain, domain, "", fmt.Sprintf("Quorum domain to operate on, must be one of %v", strings.Join(c.allowedDomains, ", "))) + if err := cmd.MarkFlagRequired(domain); err != nil { + panic(err) + } + return cmd +} + +func (c *QuorumCommand) Run(args []string) error { + if err := checkDomain(c.domain, c.allowedDomains...); err != nil { + return stacktrace.Propagate(err, "error checking domain %v", c.domain) + } + var javaArgs []string + javaArgs = append(javaArgs, args...) + javaArgs = append(javaArgs, "-domain", c.domain) + return c.Base().Run(javaArgs) +} + +func checkDomain(domain string, allowedDomains ...string) error { + for _, d := range allowedDomains { + if domain == d { + return nil + } + } + return stacktrace.NewError("domain is %v but must be one of %v", domain, strings.Join(allowedDomains, ",")) +} diff --git a/cli/src/alluxio.org/cli/cmd/quorum/remove.go b/cli/src/alluxio.org/cli/cmd/quorum/remove.go new file mode 100644 index 000000000000..76b84f6addf8 --- /dev/null +++ b/cli/src/alluxio.org/cli/cmd/quorum/remove.go @@ -0,0 +1,55 @@ +/* + * The Alluxio Open Foundation licenses this work under the Apache License, version 2.0 + * (the "License"). You may not use this work except in compliance with the License, which is + * available at www.apache.org/licenses/LICENSE-2.0 + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied, as more fully set forth in the License. + * + * See the NOTICE file distributed with this work for information regarding copyright ownership. + */ + +package quorum + +import ( + "github.com/spf13/cobra" + + "alluxio.org/cli/env" +) + +var Remove = &RemoveCommand{ + QuorumCommand: &QuorumCommand{ + BaseJavaCommand: &env.BaseJavaCommand{ + CommandName: "remove", + JavaClassName: "alluxio.cli.fsadmin.FileSystemAdminShell", + Parameters: []string{"journal", "quorum", "remove"}, + }, + allowedDomains: []string{domainJobMaster, domainMaster}, + }, +} + +type RemoveCommand struct { + *QuorumCommand + + serverAddress string +} + +func (c *RemoveCommand) ToCommand() *cobra.Command { + cmd := c.QuorumCommand.InitQuorumCmd(c.Base().InitRunJavaClassCmd(&cobra.Command{ + Use: Remove.CommandName, + Short: "Removes the specified server from the quorum", + RunE: func(cmd *cobra.Command, args []string) error { + return c.Run(nil) + }, + })) + const address = "address" + cmd.Flags().StringVar(&c.serverAddress, address, "", "Address of server in the format :") + if err := cmd.MarkFlagRequired(address); err != nil { + panic(err) + } + return cmd +} + +func (c *RemoveCommand) Run(_ []string) error { + return c.QuorumCommand.Run([]string{"-address", c.serverAddress}) +} diff --git a/cli/src/alluxio.org/cli/main.go b/cli/src/alluxio.org/cli/main.go index ef831b5d2fa5..c733c1bac3ed 100644 --- a/cli/src/alluxio.org/cli/main.go +++ b/cli/src/alluxio.org/cli/main.go @@ -18,6 +18,7 @@ import ( "alluxio.org/cli/cmd/info" "alluxio.org/cli/cmd/journal" "alluxio.org/cli/cmd/process" + "alluxio.org/cli/cmd/quorum" "alluxio.org/cli/env" "alluxio.org/cli/launch" "alluxio.org/cli/processes" @@ -36,9 +37,10 @@ func main() { for _, c := range []*env.Service{ conf.Service, + info.Service, journal.Service, process.Service, - info.Service, + quorum.Service, } { env.RegisterService(c) }