Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(559)

Side by Side Diff: worker/firewaller/firewaller.go

Issue 6374069: worker: started implementation of the firewaller (Closed)
Patch Set: Created 11 years, 8 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 package firewaller
2
3 import (
4 "launchpad.net/juju-core/environs"
5 "launchpad.net/juju-core/log"
6 "launchpad.net/juju-core/state"
7 "launchpad.net/tomb"
8 )
9
10 // Firewaller manages the opening and closing of ports.
11 type Firewaller struct {
12 st *state.State
13 info *state.Info
14 environ environs.Environ
15 tomb tomb.Tomb
16 environWatcher *state.ConfigWatcher
fwereade 2012/07/16 23:23:59 Shouldn't be a field, only used inside loop(). Al
TheMue 2012/07/17 15:42:03 Done.
17 machinesWatcher *state.MachinesWatcher
fwereade 2012/07/16 23:23:59 Shouldn't be a field, only used inside loop().
TheMue 2012/07/17 15:42:03 Done.
18 machines map[int]*machine
19 machineUnitsChanges chan *machineUnitsChange
20 }
21
22 // NewFirewaller returns a new Firewaller.
23 func NewFirewaller(info *state.Info) (*Firewaller, error) {
24 st, err := state.Open(info)
25 if err != nil {
26 return nil, err
27 }
28 fw := &Firewaller{
29 st: st,
30 info: info,
31 machinesWatcher: st.WatchMachines(),
32 machines: make(map[int]*machine),
33 machineUnitsChanges: make(chan *machineUnitsChange),
34 }
35 go fw.loop()
36 return fw, nil
37 }
38
39 func (fw *Firewaller) loop() {
40 defer fw.tomb.Done()
41 defer fw.st.Close()
42 // Get environment first.
rog 2012/07/16 16:40:46 defer watcher.Stop(fw.machineUnitsChanges, &fw.tom
fwereade 2012/07/16 23:23:59 defer close(fw.machineUnitsChanges) defer watcher.
TheMue 2012/07/17 15:42:03 Done.
43 fw.environWatcher = fw.st.WatchEnvironConfig()
rog 2012/07/16 16:40:46 defer watcher.Stop(fw.environWatcher, &fw.tomb)
TheMue 2012/07/17 15:42:03 Removed environWatcher.
44 for {
45 select {
46 case <-fw.tomb.Dying():
47 return
48 case config, ok := <-fw.environWatcher.Changes():
49 if !ok {
50 err := fw.environWatcher.Stop()
51 if err != nil {
52 fw.tomb.Kill(err)
53 }
fwereade 2012/07/16 23:23:59 fw.tomb.Kill(watcher.MustErr(fw.environWatcher))
TheMue 2012/07/17 15:42:03 Removed.
54 return
rog 2012/07/16 16:40:46 this isn't killing the machines watcher
TheMue 2012/07/17 15:42:03 Removed environWatcher.
55 }
56 var err error
57 fw.environ, err = environs.NewEnviron(config.Map())
58 if err != nil {
59 log.Printf("firewaller: loaded invalid environme nt configuration: %v", err)
60 continue
61 }
62 log.Printf("firewaller: loaded new environment configura tion")
63 case change, ok := <-fw.machinesWatcher.Changes():
64 if !ok {
65 err := fw.machinesWatcher.Stop()
66 if err != nil {
67 fw.tomb.Kill(err)
68 }
fwereade 2012/07/16 23:23:59 watcher.MustErr, as above.
TheMue 2012/07/17 15:42:03 Done.
69 return
rog 2012/07/16 16:40:46 this isn't killing the environs watcher
TheMue 2012/07/17 15:42:03 Removed environWatcher.
70 }
71 for _, removedMachine := range change.Removed {
72 m, ok := fw.machines[removedMachine.Id()]
73 if !ok {
74 // TODO(mue) Error handling in
75 // case of not managed machine?
fwereade 2012/07/16 23:23:59 Feels like a panic situation to me.
TheMue 2012/07/17 15:42:03 Done.
76 }
77 m.watcher.Stop()
fwereade 2012/07/16 23:39:52 Don't we need to wait until the *machine* has fini
78 delete(fw.machines, removedMachine.Id())
79 }
80 for _, addedMachine := range change.Added {
81 m := &machine{
82 id: addedMachine.Id(),
83 watcher: addedMachine.WatchUnits(),
84 ports: make(map[state.Port]*unit),
85 }
86 fw.machines[addedMachine.Id()] = m
fwereade 2012/07/16 23:23:59 go machine.loop() In fact, plausibly, m := newMac
TheMue 2012/07/17 15:42:03 Yep, had forgotten. But I added it next branch. Bu
87 log.Debugf("Added machine %v", m.id)
88 }
89 case <-fw.machineUnitsChanges:
90 // TODO(mue) fill with life.
rog 2012/07/16 16:40:46 i like the image :-)
TheMue 2012/07/17 15:42:03 Hehe, step by step.
91 }
92 }
93 }
94
95 // Wait waits for the Firewaller to exit.
96 func (fw *Firewaller) Wait() error {
97 return fw.tomb.Wait()
98 }
99
100 // Stop stops the Firewaller and returns any error encountered while stopping.
101 func (fw *Firewaller) Stop() error {
102 fw.tomb.Kill(nil)
103 return fw.tomb.Wait()
104 }
105
106 type machine struct {
107 id int
108 watcher *state.MachineUnitsWatcher
109 ports map[state.Port]*unit
110 }
111
112 type machineUnitsChange struct {
113 machine *machine
114 change *state.MachineUnitsChange
115 }
116
117 func (m *machine) loop(fw *Firewaller) {
118 defer m.watcher.Stop()
119 for {
120 select {
121 case <-fw.tomb.Dying():
122 return
123 case change, ok := <-m.watcher.Changes():
124 select {
125 case fw.machineUnitsChanges <- &machineUnitsChange{m, ch ange}:
126 case <-fw.tomb.Dying():
127 return
128 }
129 if !ok {
fwereade 2012/07/16 23:23:59 fw.tomb.Kill(watcher.MustErr(m.watcher))?
fwereade 2012/07/16 23:39:52 Feels a bit over-familiar, but better than droppin
TheMue 2012/07/17 15:42:03 Done.
130 return
131 }
132 }
133 }
134 }
135
136 type service struct {
137 exposed bool
138 }
139
140 type unit struct {
141 svc *service
142 id string
143 ports []state.Port
144 }
OLDNEW

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b