29
29
panic("state: illegal relation")
32
// zkTopology is used to marshal and unmarshal the content
32
// topoTopology is used to marshal and unmarshal the content
33
33
// of the /topology node in ZooKeeper.
34
type zkTopology struct {
34
type topoTopology struct {
36
Machines map[string]*zkMachine
37
Services map[string]*zkService
36
Machines map[string]*topoMachine
37
Services map[string]*topoService
38
38
UnitSequence map[string]int "unit-sequence"
39
Relations map[string]*zkRelation
42
// zkMachine represents the machine data within the /topology
44
type zkMachine struct {
47
// zkService represents the service data within the /topology
49
type zkService struct {
39
Relations map[string]*topoRelation
42
// topoMachine represents the machine data within the /topology
44
type topoMachine struct {
47
// topoService represents the service data within the /topology
49
type topoService struct {
51
Units map[string]*zkUnit
51
Units map[string]*topoUnit
54
// zkUnit represents the unit data within the /topology
54
// topoUnit represents the unit data within the /topology
55
55
// node in ZooKeeper.
56
type topoUnit struct {
61
// zkRelation represents the relation data within the
61
// topoRelation represents the relation data within the
62
62
// /topology node in ZooKeeper.
63
type zkRelation struct {
63
type topoRelation struct {
65
65
Scope RelationScope
66
Services map[RelationRole]*zkRelationService
66
Services map[RelationRole]*topoRelationService
69
// zkRelationService represents the data of one
69
// topoRelationService represents the data of one
70
70
// service of a relation within the /topology
71
71
// node in ZooKeeper.
72
type zkRelationService struct {
72
type topoRelationService struct {
74
74
RelationName string "relation-name"
77
77
// check verifies that r is a proper relation.
78
func (r *zkRelation) check() error {
78
func (r *topoRelation) check() error {
79
79
if len(r.Interface) == 0 {
80
80
return fmt.Errorf("relation interface is empty")
145
145
// AddMachine adds a new machine to the topology.
146
146
func (t *topology) AddMachine(key string) error {
147
147
if t.topology.Machines == nil {
148
t.topology.Machines = make(map[string]*zkMachine)
148
t.topology.Machines = make(map[string]*topoMachine)
149
149
} else if t.HasMachine(key) {
150
150
return fmt.Errorf("attempted to add duplicated machine %q", key)
152
t.topology.Machines[key] = &zkMachine{}
152
t.topology.Machines[key] = &topoMachine{}
201
201
// AddService adds a new service to the topology.
202
202
func (t *topology) AddService(key, name string) error {
203
203
if t.topology.Services == nil {
204
t.topology.Services = make(map[string]*zkService)
204
t.topology.Services = make(map[string]*topoService)
206
206
if t.HasService(key) {
207
207
return fmt.Errorf("attempted to add duplicated service %q", key)
209
209
if _, err := t.ServiceKey(name); err == nil {
210
210
return fmt.Errorf("service name %q already in use", name)
212
t.topology.Services[key] = &zkService{
212
t.topology.Services[key] = &topoService{
214
Units: make(map[string]*zkUnit),
214
Units: make(map[string]*topoUnit),
216
216
if t.topology.UnitSequence == nil {
217
217
t.topology.UnitSequence = make(map[string]int)
294
294
// Add unit and increase sequence number.
295
295
svc := t.topology.Services[serviceKey]
296
296
sequenceNo := t.topology.UnitSequence[svc.Name]
297
svc.Units[unitKey] = &zkUnit{Sequence: sequenceNo}
297
svc.Units[unitKey] = &topoUnit{Sequence: sequenceNo}
298
298
t.topology.UnitSequence[svc.Name] += 1
299
299
return sequenceNo, nil
400
400
// Relation returns the relation with key from the topology.
401
func (t *topology) Relation(key string) (*zkRelation, error) {
401
func (t *topology) Relation(key string) (*topoRelation, error) {
402
402
if t.topology.Relations == nil || t.topology.Relations[key] == nil {
403
403
return nil, fmt.Errorf("relation %q does not exist", key)
408
408
// AddRelation adds a new relation with the given key and relation data.
409
func (t *topology) AddRelation(relationKey string, relation *zkRelation) error {
409
func (t *topology) AddRelation(relationKey string, relation *topoRelation) error {
410
410
if t.topology.Relations == nil {
411
t.topology.Relations = make(map[string]*zkRelation)
411
t.topology.Relations = make(map[string]*topoRelation)
413
413
_, ok := t.topology.Relations[relationKey]
452
452
// RelationsForService returns all relations that the service
453
453
// with serviceKey is part of.
454
func (t *topology) RelationsForService(serviceKey string) (map[string]*zkRelation, error) {
454
func (t *topology) RelationsForService(serviceKey string) (map[string]*topoRelation, error) {
455
455
if err := t.assertService(serviceKey); err != nil {
458
relations := make(map[string]*zkRelation)
458
relations := make(map[string]*topoRelation)
459
459
for relationKey, relation := range t.topology.Relations {
460
460
for _, service := range relation.Services {
461
461
if service.Service == serviceKey {
540
540
// parseTopology returns the topology represented by yaml.
541
541
func parseTopology(yaml string) (*topology, error) {
542
t := &topology{topology: &zkTopology{Version: topologyVersion}}
542
t := &topology{topology: &topoTopology{Version: topologyVersion}}
543
543
if err := goyaml.Unmarshal([]byte(yaml), t.topology); err != nil {
559
559
func retryTopologyChange(zk *zookeeper.Conn, f func(t *topology) error) error {
560
560
change := func(yaml string, stat *zookeeper.Stat) (string, error) {
562
it := &topology{topology: &zkTopology{Version: 1}}
562
it := &topology{topology: &topoTopology{Version: 1}}
564
564
if it, err = parseTopology(yaml); err != nil {