diff --git a/cmd/torusctl/init.go b/cmd/torusctl/init.go index a06069d..44a63e8 100644 --- a/cmd/torusctl/init.go +++ b/cmd/torusctl/init.go @@ -16,11 +16,12 @@ import ( ) var ( - blockSize uint64 - blockSizeStr string - blockSpec string - noMakeRing bool - metaView bool + blockSize uint64 + blockSizeStr string + blockSpec string + metaView bool + initRingType string + initRepFactor int ) var initCommand = &cobra.Command{ @@ -33,8 +34,9 @@ var initCommand = &cobra.Command{ func init() { initCommand.Flags().StringVarP(&blockSizeStr, "block-size", "", "512KiB", "size of all data blocks in this storage cluster") initCommand.Flags().StringVarP(&blockSpec, "block-spec", "", "crc", "default replication/error correction applied to blocks in this storage cluster") - initCommand.Flags().BoolVar(&noMakeRing, "no-ring", false, "do not create the default ring as part of init") initCommand.Flags().BoolVar(&metaView, "view", false, "view metadata configured in this storage cluster") + initCommand.Flags().StringVar(&initRingType, "type", "ketama", "type of ring to create (empty, single, mod or ketama)") + initCommand.Flags().IntVarP(&initRepFactor, "replication", "r", 2, "number of replicas") } func initPreRun(cmd *cobra.Command, args []string) { @@ -62,15 +64,34 @@ func initAction(cmd *cobra.Command, args []string) { die("error parsing block-spec: %v", err) } - cfg := flagconfig.BuildConfigFromFlags() - ringType := ring.Ketama - if noMakeRing { + var ringType torus.RingType + switch initRingType { + case "empty": + if initRepFactor != 0 { + die(`invalid number of replicas for empty ring. Use "--replication=0"`) + } ringType = ring.Empty + case "single": + die(`Currently single ring type is not supported by init. Use torusctl ring manual-change after adding one node."`) + /* + if initRepFactor != 1 { + die(`invalid number of replicas for single ring. Use "--replication=1"`) + } + iRingType = ring.Single + */ + case "mod": + ringType = ring.Mod + case "ketama": + ringType = ring.Ketama + default: + die(`invalid ring type %s (try "empty", "mod", "single" or "ketama")`, initRingType) } - err = torus.InitMDS("etcd", cfg, md, ringType) + cfg := flagconfig.BuildConfigFromFlags() + err = torus.InitMDS("etcd", cfg, md, ringType, initRepFactor) if err != nil { die("error writing metadata: %v", err) } + } func viewMetadata() { diff --git a/cmd/torusd/main.go b/cmd/torusd/main.go index 75b2681..f360279 100644 --- a/cmd/torusd/main.go +++ b/cmd/torusd/main.go @@ -157,7 +157,7 @@ func runServer(cmd *cobra.Command, args []string) { err = torus.InitMDS("etcd", cfg, torus.GlobalMetadata{ BlockSize: 512 * 1024, DefaultBlockSpec: blockset.MustParseBlockLayerSpec("crc,base"), - }, ring.Ketama) + }, ring.Ketama, 2) if err != nil { if err == torus.ErrExists { fmt.Println("debug-init: Already exists") diff --git a/metadata.go b/metadata.go index bb7b031..5d8c551 100644 --- a/metadata.go +++ b/metadata.go @@ -99,7 +99,7 @@ func CreateMetadataService(name string, cfg Config) (MetadataService, error) { } // InitMDSFunc is the signature of a function which preformats a metadata service. -type InitMDSFunc func(cfg Config, gmd GlobalMetadata, ringType RingType) error +type InitMDSFunc func(cfg Config, gmd GlobalMetadata, ringType RingType, repFactor int) error var initMDSFuncs map[string]InitMDSFunc @@ -118,9 +118,9 @@ func RegisterMetadataInit(name string, newFunc InitMDSFunc) { } // InitMDS calls the specific init function provided by a metadata package. -func InitMDS(name string, cfg Config, gmd GlobalMetadata, ringType RingType) error { +func InitMDS(name string, cfg Config, gmd GlobalMetadata, ringType RingType, repFactor int) error { clog.Debugf("running InitMDS for service type: %s", name) - return initMDSFuncs[name](cfg, gmd, ringType) + return initMDSFuncs[name](cfg, gmd, ringType, repFactor) } type WipeMDSFunc func(cfg Config) error diff --git a/metadata/etcd/global_funcs.go b/metadata/etcd/global_funcs.go index 86cd52c..ea9f6c9 100644 --- a/metadata/etcd/global_funcs.go +++ b/metadata/etcd/global_funcs.go @@ -11,7 +11,7 @@ import ( "golang.org/x/net/context" ) -func initEtcdMetadata(cfg torus.Config, gmd torus.GlobalMetadata, ringType torus.RingType) error { +func initEtcdMetadata(cfg torus.Config, gmd torus.GlobalMetadata, ringType torus.RingType, repFactor int) error { gmdbytes, err := json.Marshal(gmd) if err != nil { return err @@ -19,7 +19,7 @@ func initEtcdMetadata(cfg torus.Config, gmd torus.GlobalMetadata, ringType torus emptyRing, err := ring.CreateRing(&models.Ring{ Type: uint32(ringType), Version: 1, - ReplicationFactor: 2, + ReplicationFactor: uint32(repFactor), }) if err != nil { return err