Merge lp:~bcsaller/pyjuju/subordinate-ports into lp:pyjuju

Proposed by Benjamin Saller
Status: Merged
Approved by: Kapil Thangavelu
Approved revision: 548
Merged at revision: 555
Proposed branch: lp:~bcsaller/pyjuju/subordinate-ports
Merge into: lp:pyjuju
Diff against target: 217 lines (+142/-1)
5 files modified
examples/precise/recorder/hooks/install (+3/-0)
juju/hooks/protocol.py (+15/-0)
juju/hooks/tests/test_communications.py (+3/-0)
juju/hooks/tests/test_invoker.py (+84/-1)
juju/state/tests/test_service.py (+37/-0)
To merge this branch: bzr merge lp:~bcsaller/pyjuju/subordinate-ports
Reviewer Review Type Date Requested Status
Juju Engineering Pending
Review via email: mp+111534@code.launchpad.net

Description of the change

Subordinate port open/close support

Subordinates will open ports in their container. They will report open ports on the container and in the subordinate.

https://codereview.appspot.com/6324045/

To post a comment you must log in.
Revision history for this message
Benjamin Saller (bcsaller) wrote :

Reviewers: mp+111534_code.launchpad.net,

Message:
Please take a look.

Description:
Subordinate port open/close support

Subordinates will open ports in their container. They will report open
ports on the container and in the subordinate.

https://code.launchpad.net/~bcsaller/juju/subordinate-ports/+merge/111534

(do not edit description out of merge proposal)

Please review this at https://codereview.appspot.com/6324045/

Affected files:
   A [revision details]
   A examples/precise/recorder/hooks/install
   M juju/charm/tests/repository/series/logging/hooks/install
   M juju/hooks/protocol.py
   M juju/hooks/tests/test_communications.py
   M juju/hooks/tests/test_invoker.py
   M juju/state/tests/test_firewall.py
   M juju/state/tests/test_service.py

Revision history for this message
Kapil Thangavelu (hazmat) wrote :

is it nesc/valuable to record the open port against both the subordinate and the primary

Revision history for this message
Benjamin Saller (bcsaller) wrote :

nesc, no, valuable, I think so. It has to be on the principal for this
to work the way its set up, recording it on the subordinate I think is
more clean that issuing commands to the subordinate and not seeing any
change in status for that service. The fact that the subordinate makes
a change somewhere else as well in status is more understandable than
not seeing it.

It might be possible to record the change in the sub and open it on
the principal but not record it there but that seemed like a recipe
for unintended consequences.

On Tue, Jun 26, 2012 at 9:35 AM, Kapil Thangavelu
<email address hidden> wrote:
> is it nesc/valuable to record the open port against both the subordinate and the primary
> --
> https://code.launchpad.net/~bcsaller/juju/subordinate-ports/+merge/111534
> You are the owner of lp:~bcsaller/juju/subordinate-ports.

Revision history for this message
Kapil Thangavelu (hazmat) wrote :

while the implementation LGTM, the tests need fixing.

https://codereview.appspot.com/6324045/diff/1/juju/hooks/tests/test_invoker.py
File juju/hooks/tests/test_invoker.py (right):

https://codereview.appspot.com/6324045/diff/1/juju/hooks/tests/test_invoker.py#newcode37
juju/hooks/tests/test_invoker.py:37: self._invokers = {} # client_id ->
Invoker
pep8 need an extra space before comment

https://codereview.appspot.com/6324045/diff/1/juju/hooks/tests/test_invoker.py#newcode1519
juju/hooks/tests/test_invoker.py:1519: (yield
unit_state.get_open_ports()),
This test never verifies the implementation, namely that the container
ports are open.

https://codereview.appspot.com/6324045/diff/1/juju/hooks/tests/test_invoker.py#newcode1560
juju/hooks/tests/test_invoker.py:1560: "closed 80/tcp"])
pep8 need an extra blank line after this test

https://codereview.appspot.com/6324045/diff/1/juju/state/tests/test_firewall.py
File juju/state/tests/test_firewall.py (right):

https://codereview.appspot.com/6324045/diff/1/juju/state/tests/test_firewall.py#newcode192
juju/state/tests/test_firewall.py:192: """
this test also seems superfluous. the only impl file being modified by
the branch is the invoker, yet we have tests in numerous state test
files verifying what has already been verified by other tests in those
files

https://codereview.appspot.com/6324045/diff/1/juju/state/tests/test_service.py
File juju/state/tests/test_service.py (right):

https://codereview.appspot.com/6324045/diff/1/juju/state/tests/test_service.py#newcode176
juju/state/tests/test_service.py:176: m1 = yield
self.machine_state_manager.add_machine_state(
machine creation and assignment is superflous

https://codereview.appspot.com/6324045/diff/1/juju/state/tests/test_service.py#newcode2771
juju/state/tests/test_service.py:2771: def
test_get_open_ports_subordiate(self):
typo in test name

https://codereview.appspot.com/6324045/diff/1/juju/state/tests/test_service.py#newcode2810
juju/state/tests/test_service.py:2810: self.assertEqual(
how is this entire test not entirely superfluous?

https://codereview.appspot.com/6324045/

Revision history for this message
Benjamin Saller (bcsaller) wrote :

https://codereview.appspot.com/6324045/diff/1/juju/hooks/tests/test_invoker.py
File juju/hooks/tests/test_invoker.py (right):

https://codereview.appspot.com/6324045/diff/1/juju/hooks/tests/test_invoker.py#newcode1519
juju/hooks/tests/test_invoker.py:1519: (yield
unit_state.get_open_ports()),
On 2012/07/01 02:32:22, hazmat wrote:
> This test never verifies the implementation, namely that the container
ports are
> open.

Right you are, thanks

https://codereview.appspot.com/6324045/diff/1/juju/state/tests/test_firewall.py
File juju/state/tests/test_firewall.py (right):

https://codereview.appspot.com/6324045/diff/1/juju/state/tests/test_firewall.py#newcode192
juju/state/tests/test_firewall.py:192: """
fair enough, removed

On 2012/07/01 02:32:22, hazmat wrote:
> this test also seems superfluous. the only impl file being modified by
the
> branch is the invoker, yet we have tests in numerous state test files
verifying
> what has already been verified by other tests in those files

https://codereview.appspot.com/6324045/diff/1/juju/state/tests/test_service.py
File juju/state/tests/test_service.py (right):

https://codereview.appspot.com/6324045/diff/1/juju/state/tests/test_service.py#newcode2810
juju/state/tests/test_service.py:2810: self.assertEqual(
On 2012/07/01 02:32:22, hazmat wrote:
> how is this entire test not entirely superfluous?

removed

https://codereview.appspot.com/6324045/

Revision history for this message
Kapil Thangavelu (hazmat) wrote :

can you merge/resolve with trunk, there's a conflict.
thanks,
-k

On Mon, Jul 2, 2012 at 6:31 PM, Benjamin Saller <email address hidden> wrote:

>
>
> https://codereview.appspot.com/6324045/diff/1/juju/hooks/tests/test_invoker.py
> File juju/hooks/tests/test_invoker.py (right):
>
>
> https://codereview.appspot.com/6324045/diff/1/juju/hooks/tests/test_invoker.py#newcode1519
> juju/hooks/tests/test_invoker.py:1519: (yield
> unit_state.get_open_ports()),
> On 2012/07/01 02:32:22, hazmat wrote:
> > This test never verifies the implementation, namely that the container
> ports are
> > open.
>
> Right you are, thanks
>
>
> https://codereview.appspot.com/6324045/diff/1/juju/state/tests/test_firewall.py
> File juju/state/tests/test_firewall.py (right):
>
>
> https://codereview.appspot.com/6324045/diff/1/juju/state/tests/test_firewall.py#newcode192
> juju/state/tests/test_firewall.py:192: """
> fair enough, removed
>
> On 2012/07/01 02:32:22, hazmat wrote:
> > this test also seems superfluous. the only impl file being modified by
> the
> > branch is the invoker, yet we have tests in numerous state test files
> verifying
> > what has already been verified by other tests in those files
>
>
> https://codereview.appspot.com/6324045/diff/1/juju/state/tests/test_service.py
> File juju/state/tests/test_service.py (right):
>
>
> https://codereview.appspot.com/6324045/diff/1/juju/state/tests/test_service.py#newcode2810
> juju/state/tests/test_service.py:2810: self.assertEqual(
> On 2012/07/01 02:32:22, hazmat wrote:
> > how is this entire test not entirely superfluous?
>
> removed
>
> https://codereview.appspot.com/6324045/
>
> --
> https://code.launchpad.net/~bcsaller/juju/subordinate-ports/+merge/111534
> You are subscribed to branch lp:juju.
>

548. By Benjamin Saller

merge trunk

Revision history for this message
Kapil Thangavelu (hazmat) wrote :

needs to be lbox reproposed when making a modification for inline changes..
 just doing this one by hand...

nice catch re. test_invoker yield exe.ended

test_open_and_close_ports

- there are four open port calls and one close here, please ditch two of
the open ports, its repetitive, executing a process (slow), and not adding
any value.

setup_subordinate_defaults isn't used and should get yanked, additionally
it still has all the unesc. machine stuff. these sort of methods (excessive
default setup) cause slow tests, ie. almost every slow unit test we have
uses the status base setup even then though most check only a fraction of
it.

LGTM, with the above minors please merge.

-k

On Mon, Jul 2, 2012 at 7:34 PM, Kapil Thangavelu <
<email address hidden>> wrote:

> can you merge/resolve with trunk, there's a conflict.
> thanks,
> -k
>
> On Mon, Jul 2, 2012 at 6:31 PM, Benjamin Saller <email address hidden>
> wrote:
>
> >
> >
> >
> https://codereview.appspot.com/6324045/diff/1/juju/hooks/tests/test_invoker.py
> > File juju/hooks/tests/test_invoker.py (right):
> >
> >
> >
> https://codereview.appspot.com/6324045/diff/1/juju/hooks/tests/test_invoker.py#newcode1519
> > juju/hooks/tests/test_invoker.py:1519: (yield
> > unit_state.get_open_ports()),
> > On 2012/07/01 02:32:22, hazmat wrote:
> > > This test never verifies the implementation, namely that the container
> > ports are
> > > open.
> >
> > Right you are, thanks
> >
> >
> >
> https://codereview.appspot.com/6324045/diff/1/juju/state/tests/test_firewall.py
> > File juju/state/tests/test_firewall.py (right):
> >
> >
> >
> https://codereview.appspot.com/6324045/diff/1/juju/state/tests/test_firewall.py#newcode192
> > juju/state/tests/test_firewall.py:192: """
> > fair enough, removed
> >
> > On 2012/07/01 02:32:22, hazmat wrote:
> > > this test also seems superfluous. the only impl file being modified by
> > the
> > > branch is the invoker, yet we have tests in numerous state test files
> > verifying
> > > what has already been verified by other tests in those files
> >
> >
> >
> https://codereview.appspot.com/6324045/diff/1/juju/state/tests/test_service.py
> > File juju/state/tests/test_service.py (right):
> >
> >
> >
> https://codereview.appspot.com/6324045/diff/1/juju/state/tests/test_service.py#newcode2810
> > juju/state/tests/test_service.py:2810: self.assertEqual(
> > On 2012/07/01 02:32:22, hazmat wrote:
> > > how is this entire test not entirely superfluous?
> >
> > removed
> >
> > https://codereview.appspot.com/6324045/
> >
> > --
> >
> https://code.launchpad.net/~bcsaller/juju/subordinate-ports/+merge/111534
> > You are subscribed to branch lp:juju.
> >
>
> --
> https://code.launchpad.net/~bcsaller/juju/subordinate-ports/+merge/111534
> You are subscribed to branch lp:juju.
>

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'examples/precise/recorder/hooks/install'
--- examples/precise/recorder/hooks/install 1970-01-01 00:00:00 +0000
+++ examples/precise/recorder/hooks/install 2012-07-03 00:41:21 +0000
@@ -0,0 +1,3 @@
1#!/bin/bash
2# for testing
3open-port 8080
0\ No newline at end of file4\ No newline at end of file
15
=== modified file 'juju/charm/tests/repository/series/logging/hooks/install' (properties changed: -x to +x)
=== modified file 'juju/hooks/protocol.py'
--- juju/hooks/protocol.py 2012-06-14 14:33:22 +0000
+++ juju/hooks/protocol.py 2012-07-03 00:41:21 +0000
@@ -328,6 +328,14 @@
328 """328 """
329 context = self.factory.get_context(client_id)329 context = self.factory.get_context(client_id)
330 service_unit_state = yield context.get_local_unit_state()330 service_unit_state = yield context.get_local_unit_state()
331 container = yield service_unit_state.get_container()
332 if container:
333 # also open the port on the container
334 # we still do subordinate unit below to ease
335 # status reporting
336 yield container.open_port(port, proto)
337
338
331 yield service_unit_state.open_port(port, proto)339 yield service_unit_state.open_port(port, proto)
332 yield self.factory.log(logging.DEBUG, "opened %s/%s" % (port, proto))340 yield self.factory.log(logging.DEBUG, "opened %s/%s" % (port, proto))
333 defer.returnValue({})341 defer.returnValue({})
@@ -348,6 +356,13 @@
348 """356 """
349 context = self.factory.get_context(client_id)357 context = self.factory.get_context(client_id)
350 service_unit_state = yield context.get_local_unit_state()358 service_unit_state = yield context.get_local_unit_state()
359 container = yield service_unit_state.get_container()
360 if container:
361 # also close the port on the container
362 # we still do subordinate unit below to ease
363 # status reporting
364 yield container.close_port(port, proto)
365
351 yield service_unit_state.close_port(port, proto)366 yield service_unit_state.close_port(port, proto)
352 yield self.factory.log(logging.DEBUG, "closed %s/%s" % (port, proto))367 yield self.factory.log(logging.DEBUG, "closed %s/%s" % (port, proto))
353 defer.returnValue({})368 defer.returnValue({})
354369
=== modified file 'juju/hooks/tests/test_communications.py'
--- juju/hooks/tests/test_communications.py 2012-06-06 23:00:51 +0000
+++ juju/hooks/tests/test_communications.py 2012-07-03 00:41:21 +0000
@@ -54,6 +54,9 @@
54 self.ports = set()54 self.ports = set()
55 self.config = {}55 self.config = {}
5656
57 def get_container(self):
58 return None
59
57 def open_port(self, port, proto):60 def open_port(self, port, proto):
58 self.ports.add((port, proto))61 self.ports.add((port, proto))
5962
6063
=== modified file 'juju/hooks/tests/test_invoker.py'
--- juju/hooks/tests/test_invoker.py 2012-07-01 18:38:54 +0000
+++ juju/hooks/tests/test_invoker.py 2012-07-03 00:41:21 +0000
@@ -1477,13 +1477,15 @@
14771477
1478 mu1, mu2 = my_units1478 mu1, mu2 = my_units
1479 lu1, lu2 = log_units1479 lu1, lu2 = log_units
1480 self.mysql_units = my_units
1481 self.log_units = log_units
14801482
1481 mystate = pick_attr(service_states, relation_role="server")1483 mystate = pick_attr(service_states, relation_role="server")
1482 logstate = pick_attr(service_states, relation_role="client")1484 logstate = pick_attr(service_states, relation_role="client")
14831485
1484 yield mystate.add_unit_state(mu1)1486 yield mystate.add_unit_state(mu1)
1485 self.relation = yield logstate.add_unit_state(lu1)1487 self.relation = yield logstate.add_unit_state(lu1)
1486 # add the second container (1488 # add the second container
1487 yield mystate.add_unit_state(mu2)1489 yield mystate.add_unit_state(mu2)
1488 self.relation2 = yield logstate.add_unit_state(lu2)1490 self.relation2 = yield logstate.add_unit_state(lu2)
14891491
@@ -1509,11 +1511,92 @@
1509 "--format=smart"))1511 "--format=smart"))
1510 self.assertEqual(result, 0)1512 self.assertEqual(result, 0)
1511 # verify that we see the proper unit1513 # verify that we see the proper unit
1514 yield exe.ended
1512 self.assertIn("mysql/1", self.log.getvalue())1515 self.assertIn("mysql/1", self.log.getvalue())
1513 # we don't see units in the other container1516 # we don't see units in the other container
1514 self.assertNotIn("mysql/0", self.log.getvalue())1517 self.assertNotIn("mysql/0", self.log.getvalue())
15151518
15161519
1520 @defer.inlineCallbacks
1521 def test_open_and_close_ports(self):
1522 """Verify that port hook commands run and changes are immediate."""
1523 unit_state = self.log_units[0]
1524 container_state = self.mysql_units[0]
1525
1526 self.assertEqual((yield unit_state.get_open_ports()), [])
1527
1528 exe = yield self.ua.get_invoker(
1529 "database:42", "add", "logging/0", self.relation)
1530 result = yield exe(self.create_hook("open-port", "80"))
1531 self.assertEqual(result, 0)
1532 self.assertEqual(
1533 (yield unit_state.get_open_ports()),
1534 [{"port": 80, "proto": "tcp"}])
1535 self.assertEqual(
1536 (yield container_state.get_open_ports()),
1537 [{"port": 80, "proto": "tcp"}])
1538
1539 result = yield exe(self.create_hook("open-port", "53/udp"))
1540 self.assertEqual(result, 0)
1541 self.assertEqual(
1542 (yield unit_state.get_open_ports()),
1543 [{"port": 80, "proto": "tcp"},
1544 {"port": 53, "proto": "udp"}])
1545 self.assertEqual(
1546 (yield container_state.get_open_ports()),
1547 [{"port": 80, "proto": "tcp"},
1548 {"port": 53, "proto": "udp"}])
1549
1550 result = yield exe(self.create_hook("open-port", "53/tcp"))
1551 self.assertEqual(result, 0)
1552 self.assertEqual(
1553 (yield unit_state.get_open_ports()),
1554 [{"port": 80, "proto": "tcp"},
1555 {"port": 53, "proto": "udp"},
1556 {"port": 53, "proto": "tcp"}])
1557 self.assertEqual(
1558 (yield container_state.get_open_ports()),
1559 [{"port": 80, "proto": "tcp"},
1560 {"port": 53, "proto": "udp"},
1561 {"port": 53, "proto": "tcp"}])
1562
1563 result = yield exe(self.create_hook("open-port", "443/tcp"))
1564 self.assertEqual(result, 0)
1565 self.assertEqual(
1566 (yield unit_state.get_open_ports()),
1567 [{"port": 80, "proto": "tcp"},
1568 {"port": 53, "proto": "udp"},
1569 {"port": 53, "proto": "tcp"},
1570 {"port": 443, "proto": "tcp"}])
1571 self.assertEqual(
1572 (yield container_state.get_open_ports()),
1573 [{"port": 80, "proto": "tcp"},
1574 {"port": 53, "proto": "udp"},
1575 {"port": 53, "proto": "tcp"},
1576 {"port": 443, "proto": "tcp"}])
1577
1578 result = yield exe(self.create_hook("close-port", "80/tcp"))
1579 self.assertEqual(result, 0)
1580 self.assertEqual(
1581 (yield unit_state.get_open_ports()),
1582 [{"port": 53, "proto": "udp"},
1583 {"port": 53, "proto": "tcp"},
1584 {"port": 443, "proto": "tcp"}])
1585 self.assertEqual(
1586 (yield container_state.get_open_ports()),
1587 [{"port": 53, "proto": "udp"},
1588 {"port": 53, "proto": "tcp"},
1589 {"port": 443, "proto": "tcp"}])
1590
1591 yield exe.ended
1592 self.assertLogLines(
1593 self.log.getvalue(), [
1594 "opened 80/tcp",
1595 "opened 53/udp",
1596 "opened 443/tcp",
1597 "closed 80/tcp"])
1598
1599
1517def capture_separate_log(name, level):1600def capture_separate_log(name, level):
1518 """Support the separate capture of logging at different log levels.1601 """Support the separate capture of logging at different log levels.
15191602
15201603
=== modified file 'juju/state/tests/test_service.py'
--- juju/state/tests/test_service.py 2012-04-11 19:38:41 +0000
+++ juju/state/tests/test_service.py 2012-07-03 00:41:21 +0000
@@ -159,6 +159,43 @@
159 unit_state = yield service_state.add_unit_state()159 unit_state = yield service_state.add_unit_state()
160 returnValue(unit_state)160 returnValue(unit_state)
161161
162 @inlineCallbacks
163 def setup_subordinate_defaults(self):
164 mysql_ep = RelationEndpoint("mysql", "juju-info", "juju-info",
165 "server", "global")
166 logging_ep = RelationEndpoint("logging", "juju-info", "juju-info",
167 "client", "container")
168
169 logging_charm_state = yield self.get_subordinate_charm()
170 self.assertTrue(logging_charm_state.is_subordinate())
171 log_state = yield self.service_state_manager.add_service_state(
172 "logging", logging_charm_state, dummy_constraints)
173 mysql_state = yield self.service_state_manager.add_service_state(
174 "mysql", self.charm_state, dummy_constraints)
175
176 m1 = yield self.machine_state_manager.add_machine_state(
177 series_constraints)
178 m2 = yield self.machine_state_manager.add_machine_state(
179 series_constraints)
180
181 relation_state, service_states = (yield
182 self.relation_state_manager.add_relation_state(
183 mysql_ep, logging_ep))
184
185 unit_state1 = yield mysql_state.add_unit_state()
186 yield unit_state1.assign_to_machine(m1)
187 unit_state0 = yield log_state.add_unit_state(
188 container=unit_state1)
189
190 unit_state3 = yield mysql_state.add_unit_state()
191 yield unit_state3.assign_to_machine(m2)
192 unit_state2 = yield log_state.add_unit_state(
193 container=unit_state3)
194
195 returnValue([service_states, relation_state,
196 [(unit_state0, unit_state1),
197 (unit_state2, unit_state3)]])
198
162199
163class ServiceStateManagerTest(ServiceStateManagerTestBase):200class ServiceStateManagerTest(ServiceStateManagerTestBase):
164201

Subscribers

People subscribed via source and target branches

to status/vote changes: