Skip to content

Commit

Permalink
config: convert ZoneConfig to the new format
Browse files Browse the repository at this point in the history
Converts ZoneConfig to the new format specified in the expressive ZoneConfig
RFC.  This is intermediate work on cockroachdb#4868.
https://github.com/cockroachdb/cockroach/blob/develop/docs/RFCS/expressive_zone_config.md

- Allocator and StorePool use []config.Constraint instead of roachpb.Attributes
  since the new type allows for different types of constraint.
- Adds a `ZoneConfigLegacy` struct for upgrades to the new format.
- Adds a `ZoneConfigHuman` struct for easier specification on the command line.
  • Loading branch information
d4l3k committed Aug 29, 2016
1 parent aeca0e0 commit c19f31b
Show file tree
Hide file tree
Showing 27 changed files with 1,254 additions and 337 deletions.
24 changes: 12 additions & 12 deletions cli/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -503,41 +503,41 @@ func Example_zone() {
// .default
// zone set system --file=./testdata/zone_attrs.yaml
// INSERT 1
// replicas:
// - attrs: [us-east-1a, ssd]
// range_min_bytes: 1048576
// range_max_bytes: 67108864
// gc:
// ttlseconds: 86400
// num_replicas: 1
// constraints: [us-east-1a, ssd]
// zone ls
// .default
// system
// zone get system.nonexistent
// system.nonexistent not found
// zone get system.lease
// system
// replicas:
// - attrs: [us-east-1a, ssd]
// range_min_bytes: 1048576
// range_max_bytes: 67108864
// gc:
// ttlseconds: 86400
// num_replicas: 1
// constraints: [us-east-1a, ssd]
// zone set system --file=./testdata/zone_range_max_bytes.yaml
// UPDATE 1
// replicas:
// - attrs: [us-east-1a, ssd]
// range_min_bytes: 1048576
// range_max_bytes: 134217728
// gc:
// ttlseconds: 86400
// num_replicas: 1
// constraints: [us-east-1a, ssd]
// zone get system
// system
// replicas:
// - attrs: [us-east-1a, ssd]
// range_min_bytes: 1048576
// range_max_bytes: 134217728
// gc:
// ttlseconds: 86400
// num_replicas: 1
// constraints: [us-east-1a, ssd]
// zone rm system
// DELETE 1
// zone ls
Expand All @@ -546,20 +546,20 @@ func Example_zone() {
// unable to remove .default
// zone set .default --file=./testdata/zone_range_max_bytes.yaml
// UPDATE 1
// replicas:
// - attrs: []
// range_min_bytes: 1048576
// range_max_bytes: 134217728
// gc:
// ttlseconds: 86400
// num_replicas: 1
// constraints: []
// zone get system
// .default
// replicas:
// - attrs: []
// range_min_bytes: 1048576
// range_max_bytes: 134217728
// gc:
// ttlseconds: 86400
// num_replicas: 1
// constraints: []
}

func Example_sql() {
Expand Down
4 changes: 2 additions & 2 deletions cli/testdata/zone_attrs.yaml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
replicas:
- attrs: [us-east-1a,ssd]
num_replicas: 1
constraints: [us-east-1a,ssd]
6 changes: 1 addition & 5 deletions cli/zone.go
Original file line number Diff line number Diff line change
Expand Up @@ -461,9 +461,8 @@ func runSetZone(cmd *cobra.Command, args []string) error {
// Convert it to proto and marshal it again to put into the table. This is a
// bit more tedious than taking protos directly, but yaml is a more widely
// understood format.
origReplicaAttrs := zone.ReplicaAttrs
zone.ReplicaAttrs = nil
// Read zoneConfig file to conf.

var conf []byte
if zoneConfig == "-" {
conf, err = ioutil.ReadAll(os.Stdin)
Expand All @@ -476,9 +475,6 @@ func runSetZone(cmd *cobra.Command, args []string) error {
if err := yaml.Unmarshal(conf, &zone); err != nil {
return fmt.Errorf("unable to parse zoneConfig file: %s", err)
}
if zone.ReplicaAttrs == nil {
zone.ReplicaAttrs = origReplicaAttrs
}

if err := zone.Validate(); err != nil {
return err
Expand Down
78 changes: 72 additions & 6 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ import (
"crypto/sha1"
"fmt"
"sort"
"strings"

yaml "gopkg.in/yaml.v2"

"golang.org/x/net/context"

Expand All @@ -44,11 +47,7 @@ var (
// defaultZoneConfig is the default zone configuration used when no custom
// config has been specified.
defaultZoneConfig = ZoneConfig{
ReplicaAttrs: []roachpb.Attributes{
{},
{},
{},
},
NumReplicas: 3,
RangeMinBytes: 1 << 20,
RangeMaxBytes: 64 << 20,
GC: GCPolicy{
Expand All @@ -66,6 +65,73 @@ var (
testingLargestIDHook func(uint32) uint32
)

func (c Constraint) String() string {
var str string
switch c.Type {
case Constraint_REQUIRED:
str += "+"
case Constraint_PROHIBITED:
str += "-"
}
if len(c.Key) > 0 {
str += c.Key + "="
}
str += c.Value
return str
}

// FromString populates the constraint from the constraint shorthand notation.
func (c *Constraint) FromString(short string) error {
switch short[0] {
case '+':
c.Type = Constraint_REQUIRED
short = short[1:]
case '-':
c.Type = Constraint_PROHIBITED
short = short[1:]
default:
c.Type = Constraint_POSITIVE
}
parts := strings.Split(short, "=")
if len(parts) == 1 {
c.Value = parts[0]
} else if len(parts) == 2 {
c.Key = parts[0]
c.Value = parts[1]
} else {
return errors.Errorf("constraint needs to be in the form \"(key=)value\", not %q", short)
}
return nil
}

var _ yaml.Marshaler = Constraints{}
var _ yaml.Unmarshaler = &Constraints{}

// MarshalYAML implements yaml.Marshaler.
func (c Constraints) MarshalYAML() (interface{}, error) {
short := make([]string, len(c.Constraints))
for i, c := range c.Constraints {
short[i] = c.String()
}
return short, nil
}

// UnmarshalYAML implements yaml.Unmarshaler.
func (c *Constraints) UnmarshalYAML(unmarshal func(interface{}) error) error {
var shortConstraints []string
if err := unmarshal(&shortConstraints); err != nil {
return err
}
constraints := make([]Constraint, len(shortConstraints))
for i, short := range shortConstraints {
if err := constraints[i].FromString(short); err != nil {
return err
}
}
c.Constraints = constraints
return nil
}

// DefaultZoneConfig is the default zone configuration used when no custom
// config has been specified.
func DefaultZoneConfig() ZoneConfig {
Expand All @@ -92,7 +158,7 @@ func TestingSetDefaultZoneConfig(cfg ZoneConfig) func() {
// Validate verifies some ZoneConfig fields.
// This should be used to validate user input when setting a new zone config.
func (z ZoneConfig) Validate() error {
switch len(z.ReplicaAttrs) {
switch z.NumReplicas {
case 0:
return fmt.Errorf("attributes for at least one replica must be specified in zone config")
case 2:
Expand Down
Loading

0 comments on commit c19f31b

Please sign in to comment.