Left: | ||
Right: |
OLD | NEW |
---|---|
(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 } | |
OLD | NEW |