Merge lp:~brad-marshall/charms/trusty/ntp/add-auto-peers into lp:charms/trusty/ntp

Proposed by Brad Marshall
Status: Merged
Merged at revision: 19
Proposed branch: lp:~brad-marshall/charms/trusty/ntp/add-auto-peers
Merge into: lp:charms/trusty/ntp
Diff against target: 265 lines (+89/-19)
6 files modified
README.md (+12/-3)
config.yaml (+13/-1)
hooks/ntp_hooks.py (+33/-3)
metadata.yaml (+3/-0)
templates/ntp.conf (+5/-0)
tests/10-deploy-test.py (+23/-12)
To merge this branch: bzr merge lp:~brad-marshall/charms/trusty/ntp/add-auto-peers
Reviewer Review Type Date Requested Status
Charles Butler (community) Approve
Adam Israel (community) Approve
Whit Morriss (community) Needs Fixing
Cory Johns (community) Needs Fixing
Marco Ceppi (community) Needs Fixing
Review via email: mp+253132@code.launchpad.net

Description of the change

Add auto_peers and peers option to manage setting peers both manually and automatically between subordinates. Added a use_iburst option to speed up the initial sync period.

To post a comment you must log in.
Revision history for this message
Mick Gregg (macgreagoir) wrote :

Tested successfully in BootStack Staging environment.

Revision history for this message
Marco Ceppi (marcoceppi) wrote :

This has conflicts with a upstream as it is. Could you please correct these and move merge back in to a "Needs Review" state. Otherwise, LGTM

review: Needs Fixing
Revision history for this message
Brad Marshall (brad-marshall) wrote :

Ah, yes - it conflicts with my other ntp change I got merged. I'll fix that now.

Revision history for this message
Cory Johns (johnsca) wrote :

Brad,

This change looks mostly good, and the merge conflict has been resolved. However, I have two items that I think should be addressed before I can give my +1:

  * Missing default value for nagios_servicegroups option (seems like it was missed / removed in the conflict resolution)

  * A test case for the auto-peering should be added (maybe just a couple of lines could be added to 10-deploy-test.py?)

I'm also a little confused about the purpose of the "total_sources" option? Is it really useful to have an option whose only effect is to create a log message? Is there more behavior that will be coming to this option?

review: Needs Fixing
Revision history for this message
Brad Marshall (brad-marshall) wrote :

Ok, I've fixed the nagios_servicegroup issue, added a test for the peers and removed the total_source line - I was going to do a nagios test but ran out of time to get it sorted correctly. I'll add it back later if I get the chance.

Revision history for this message
Brad Marshall (brad-marshall) wrote :

Somehow I've managed to lose my nrpe changes in this from my other MP, I'll fix that up before resubmitting it.

Revision history for this message
Brad Marshall (brad-marshall) wrote :

This should be ready for review now - once this lands I'll look at doing similar for ntpmaster.

Revision history for this message
Whit Morriss (whitmo) wrote :

LGTM once you add this test fix. Looks like a minor typo that didn't get pushed.

https://code.launchpad.net/~whitmo/charms/trusty/ntp/test-fix/+merge/254802

Merges cleanly, all tests pass.

review: Needs Fixing
37. By Brad Marshall

[bradm] Fixed unit name on the test

Revision history for this message
Brad Marshall (brad-marshall) wrote :

Thanks for catching that, I must have missed pushing up my latest rev somehow. All merged, ready for review.

Revision history for this message
Adam Israel (aisrael) wrote :

Hi Brad,

I had the chance to review your latest revision, and everything passes cleanly for me. +1

review: Approve
Revision history for this message
Charles Butler (lazypower) wrote :

There's one fix I'd like to comment on with this branch.

It appears there's a bug in the setup routine that isn't installing amulet for the python version under test.

http://reports.vapour.ws/charm-test-details/charm-bundle-test-parent-214

I've pulled the tests and run them manually and while the dependency is present, I was unable to get a successful test run:

Traceback (most recent call last):
  File "/tmp/bundletester-s0XPw7/ntp/tests/10-deploy-test.py", line 98, in <module>
    configuration_file.index(ubuntu_0_public_address)

This returned on all tested substrates.

Once this is fixed up I'll be happy to approve and merge.

Thanks for all the hard work already @brad-marshall, I look forward to ack'ing this MP soon.

review: Needs Fixing
Revision history for this message
Charles Butler (lazypower) wrote :

I circled back and cleaned up the tests to pass.

Thanks for the contribution! Make sure that you backport the changes from tests/10-deploy-test.py into your branch before making the next revision or it will collide with whats currently included in TRUNK.

+1 LGTM. Thank you for taking the time to submit this fix for the charm store. We appreciate your work. I've merged this branch and it should be available in the charm store after the next ingestion.

If you have any questions/comments/concerns about the review contact us in #juju on irc.freenode.net or email the mailing list <email address hidden>, or ask a question tagged with "juju" on http://askubuntu.com.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'README.md'
--- README.md 2013-08-29 13:50:54 +0000
+++ README.md 2015-04-01 00:26:30 +0000
@@ -27,11 +27,20 @@
2727
28 juju set ntp source=myatomiclock.local.net28 juju set ntp source=myatomiclock.local.net
2929
30You can also specify multiple sources:30You can also specify multiple sources and peers:
3131
32 juju set ntp source="mac1.local.net mac2.local.net mac3.local.net"32 juju set ntp source="mac1.local.net mac2.local.net mac3.local.net"
3333 juju set ntp peers="mac1.local.net mac2.local.net mac3.local.net"
34Sources should be space separated.34
35Sources and peers should be space separated.
36
37When you need a set of services to keep close time to each other, it may
38be useful to have them automatically peer with each other. This means
39any set of services that use the same ntp subordinate will peer together.
40
41 juju set ntp auto_peers=true
42
43This will add all the hosts as peers to each other.
3544
36Mastered45Mastered
37========46========
3847
=== modified file 'config.yaml'
--- config.yaml 2015-03-23 00:39:09 +0000
+++ config.yaml 2015-04-01 00:26:30 +0000
@@ -3,6 +3,10 @@
3 default: ""3 default: ""
4 type: string4 type: string
5 description: Space separated list of NTP servers to use as source for time.5 description: Space separated list of NTP servers to use as source for time.
6 peers:
7 default: ""
8 type: string
9 description: Space separated list of NTP servers to use as peers for time.
6 nagios_context:10 nagios_context:
7 default: "juju"11 default: "juju"
8 type: string12 type: string
@@ -13,7 +17,7 @@
13 juju-myservice-017 juju-myservice-0
14 If you're running multiple environments with the same services in them18 If you're running multiple environments with the same services in them
15 this allows you to differentiate between them.19 this allows you to differentiate between them.
16 nagios_servicegroups:20 nagios_servicegroups:
17 default: ""21 default: ""
18 type: string22 type: string
19 description: |23 description: |
@@ -25,3 +29,11 @@
25 description: |29 description: |
26 A space-seperated list of nagios ntpmon checks to enable.30 A space-seperated list of nagios ntpmon checks to enable.
27 If left empty, no ntpmon checks will be used.31 If left empty, no ntpmon checks will be used.
32 auto_peers:
33 default: false
34 type: boolean
35 description: Will ntp auto peer between the environment
36 use_iburst:
37 default: false
38 type: boolean
39 description: Use iburst for all servers, not just ntpmaster
2840
=== added symlink 'hooks/ntp-peers-relation-changed'
=== target is u'ntp_hooks.py'
=== added symlink 'hooks/ntp-peers-relation-joined'
=== target is u'ntp_hooks.py'
=== modified file 'hooks/ntp_hooks.py'
--- hooks/ntp_hooks.py 2015-03-23 00:51:20 +0000
+++ hooks/ntp_hooks.py 2015-04-01 00:26:30 +0000
@@ -19,6 +19,17 @@
19hooks = hookenv.Hooks()19hooks = hookenv.Hooks()
2020
2121
22def get_peer_nodes():
23 hosts = []
24 hosts.append(hookenv.unit_get('private-address'))
25 for relid in hookenv.relation_ids('ntp-peers'):
26 for unit in hookenv.related_units(relid):
27 hosts.append(hookenv.relation_get('private-address',
28 unit, relid))
29 hosts.sort()
30 return hosts
31
32
22@hooks.hook('install')33@hooks.hook('install')
23def install():34def install():
24 fetch.apt_update(fatal=True)35 fetch.apt_update(fatal=True)
@@ -30,27 +41,46 @@
30@hooks.hook('config-changed')41@hooks.hook('config-changed')
31@hooks.hook('master-relation-changed')42@hooks.hook('master-relation-changed')
32@hooks.hook('master-relation-departed')43@hooks.hook('master-relation-departed')
44@hooks.hook('ntp-peers-relation-joined',
45 'ntp-peers-relation-changed')
33@host.restart_on_change({NTP_CONF: ['ntp']})46@host.restart_on_change({NTP_CONF: ['ntp']})
34def write_config():47def write_config():
48 use_iburst = hookenv.config('use_iburst')
35 source = hookenv.config('source')49 source = hookenv.config('source')
36 remote_sources = []50 remote_sources = []
37 if source:51 if source:
38 for s in source.split(" "):52 for s in source.split(" "):
39 if len(s) > 0:53 if len(s) > 0:
40 remote_sources.append({'name': s})54 if use_iburst:
55 remote_sources.append({'name': '%s iburst' % s})
56 else:
57 remote_sources.append({'name': s})
41 for relid in hookenv.relation_ids('master'):58 for relid in hookenv.relation_ids('master'):
42 for unit in hookenv.related_units(relid=relid):59 for unit in hookenv.related_units(relid=relid):
43 u_addr = hookenv.relation_get(attribute='private-address',60 u_addr = hookenv.relation_get(attribute='private-address',
44 unit=unit, rid=relid)61 unit=unit, rid=relid)
45 remote_sources.append({'name': '%s iburst' % u_addr})62 remote_sources.append({'name': '%s iburst' % u_addr})
4663
64 auto_peers = hookenv.config('auto_peers')
65 peers = hookenv.config('peers')
66 remote_peers = []
67 if peers:
68 for p in peers.split(" "):
69 if len(p) > 0:
70 remote_peers.append(p)
71 if hookenv.relation_ids('ntp-peers'):
72 if auto_peers:
73 for rp in get_peer_nodes():
74 remote_peers.append(rp)
75
47 if len(remote_sources) == 0:76 if len(remote_sources) == 0:
48 shutil.copy(NTP_CONF_ORIG, NTP_CONF)77 shutil.copy(NTP_CONF_ORIG, NTP_CONF)
49 else:78 else:
50 with open(NTP_CONF, "w") as ntpconf:79 with open(NTP_CONF, "w") as ntpconf:
51 ntpconf.write(render(os.path.basename(NTP_CONF),80 ntpconf.write(render(os.path.basename(NTP_CONF),
52 {'servers': remote_sources}))81 {'servers': remote_sources,
5382 'peers': remote_peers,
83 'use_iburst': use_iburst}))
54 update_nrpe_config()84 update_nrpe_config()
5585
5686
5787
=== modified file 'metadata.yaml'
--- metadata.yaml 2015-03-17 04:10:30 +0000
+++ metadata.yaml 2015-04-01 00:26:30 +0000
@@ -22,3 +22,6 @@
22 scope: container22 scope: container
23 master:23 master:
24 interface: ntp24 interface: ntp
25peers:
26 ntp-peers:
27 interface: ntp
2528
=== modified file 'templates/ntp.conf'
--- templates/ntp.conf 2013-07-15 14:26:04 +0000
+++ templates/ntp.conf 2015-04-01 00:26:30 +0000
@@ -8,6 +8,11 @@
8restrict -6 default kod notrap nomodify nopeer noquery8restrict -6 default kod notrap nomodify nopeer noquery
9restrict 127.0.0.19restrict 127.0.0.1
10restrict ::110restrict ::1
11{% for peer in peers %}restrict {{ peer }} kod notrap nomodify
12{% endfor %}
11# SERVERS13# SERVERS
12{% for server in servers %}server {{ server.name }}14{% for server in servers %}server {{ server.name }}
13{% endfor %}15{% endfor %}
16# PEERS
17{% for peer in peers %}peer {{ peer }} {% if use_iburst %}iburst{% endif %}
18{% endfor %}
1419
=== modified file 'tests/10-deploy-test.py'
--- tests/10-deploy-test.py 2014-06-18 18:11:00 +0000
+++ tests/10-deploy-test.py 2015-04-01 00:26:30 +0000
@@ -5,35 +5,36 @@
5import amulet5import amulet
66
7# The number of seconds to wait for Juju to set up the environment.7# The number of seconds to wait for Juju to set up the environment.
8seconds = 9008seconds = 9600
9ntp_server_0 = 'ntp.your.org'9ntp_server_0 = 'ntp.your.org'
10ntp_server_1 = 'us.pool.ntp.org'10ntp_server_1 = 'us.pool.ntp.org'
11ntp_server_2 = 'tock.mtnlion.com'11ntp_server_2 = 'tock.mtnlion.com'
1212
13# The ntp configuration to test.13# The ntp configuration to test.
14ntp_configuration = {14ntp_configuration = {
15 'source': ntp_server_0 + ' ' + ntp_server_1 + ' ' + ntp_server_215 'source': ntp_server_0 + ' ' + ntp_server_1 + ' ' + ntp_server_2,
16 'auto_peers': True
16}17}
1718
18d = amulet.Deployment()19d = amulet.Deployment(series='trusty', juju_deployer='juju-deployer -d -v')
19# Add the ntp charm to the deployment.20# Add the ntp charm to the deployment.
20d.add('ntp')21d.add('ntp')
21# Add the ntpmaster charm to the deployment.22# Add the ntpmaster charm to the deployment.
22d.add('ntpmaster')23d.add('ntpmaster')
23# Add the ubuntu charm to the deployment.24# Add the ubuntu charm to the deployment.
24d.add('ubuntu')25d.add('ubuntu', units=2)
25# Configure the ntp charm.26# Configure the ntp charm.
26d.configure('ntp', ntp_configuration)27d.configure('ntp', ntp_configuration)
2728
29# Relate the ntp and the ubuntu charm.
30d.relate('ntp:juju-info', 'ubuntu:juju-info')
28# Relate the ntp and ntpmaster charms.31# Relate the ntp and ntpmaster charms.
29d.relate('ntp:master', 'ntpmaster:master')32d.relate('ntp:master', 'ntpmaster:master')
30# Relate the ntp and the ubuntu charm.
31d.relate('ntp:juju-info', 'ubuntu:juju-info')
3233
33# Deploy the environment and wait for it to setup.34# Deploy the environment and wait for it to setup.
34try:35try:
35 d.setup(timeout=seconds)36 d.setup(timeout=seconds)
36 d.sentry.wait(seconds)37 d.sentry.wait(timeout=seconds)
37except amulet.helpers.TimeoutError:38except amulet.helpers.TimeoutError:
38 message = 'The environment did not setup in %d seconds.' % seconds39 message = 'The environment did not setup in %d seconds.' % seconds
39 # The SKIP status enables skip or fail the test based on configuration.40 # The SKIP status enables skip or fail the test based on configuration.
@@ -48,7 +49,8 @@
48ntpmaster_unit = d.sentry.unit['ntpmaster/0']49ntpmaster_unit = d.sentry.unit['ntpmaster/0']
4950
50# Get the sentry unit for ubuntu.51# Get the sentry unit for ubuntu.
51ubuntu_unit = d.sentry.unit['ubuntu/0']52ubuntu_unit_0 = d.sentry.unit['ubuntu/0']
53ubuntu_unit_1 = d.sentry.unit['ubuntu/1']
5254
53# Get the public address for the system running the ntmpmaster charm.55# Get the public address for the system running the ntmpmaster charm.
54master_public_address = ntpmaster_unit.info['public-address']56master_public_address = ntpmaster_unit.info['public-address']
@@ -59,22 +61,27 @@
59master_private_address = master_relation['private-address']61master_private_address = master_relation['private-address']
60print('ntpmaster private address ' + master_private_address)62print('ntpmaster private address ' + master_private_address)
6163
64ubuntu_0_public_address = ubuntu_unit_0.info['public-address']
65print('ubuntu/0 public address ' + ubuntu_0_public_address)
66ubuntu_1_public_address = ubuntu_unit_1.info['public-address']
67print('ubuntu/1 public address ' + ubuntu_1_public_address)
68
62# Create a command to check the ntp service.69# Create a command to check the ntp service.
63command = 'sudo service ntp status'70command = 'sudo service ntp status'
64print(command)71print(command)
65# Run the command to see if apache2 is running.72# Run the command to see if ntp is running.
66output, code = ubuntu_unit.run(command)73output, code = ubuntu_unit_0.run(command)
67print(output)74print(output)
68if code != 0 or output.find('NTP server is running') == -1:75if code != 0 or output.find('NTP server is running') == -1:
69 message = 'The NTP service is not running on the ubuntu unit.'76 message = 'The NTP service is not running on the ubuntu unit.'
70 print(message)77 print(message)
71 amulet.raise_status(amulet.FAIL, msg=message)78 amulet.raise_status(amulet.FAIL, msg=message)
7279
73# The ubuntu cloud image does not have ntp installed by default, 80# The ubuntu cloud image does not have ntp installed by default,
74# and therefore does not have the /etc/ntp.conf file.81# and therefore does not have the /etc/ntp.conf file.
7582
76# Read in the ntp configuration file from the ubuntu unit.83# Read in the ntp configuration file from the ubuntu unit.
77configuration_file = ubuntu_unit.file_contents('/etc/ntp.conf')84configuration_file = ubuntu_unit_0.file_contents('/etc/ntp.conf')
78# This call will fail with an IO exception if the file does not exist.85# This call will fail with an IO exception if the file does not exist.
7986
80# Search for ntp server 0 in the config file, raise an exception if not found.87# Search for ntp server 0 in the config file, raise an exception if not found.
@@ -87,4 +94,8 @@
87# Search for the ntpmaster IP address in the config file, added by relation.94# Search for the ntpmaster IP address in the config file, added by relation.
88configuration_file.index(master_private_address)95configuration_file.index(master_private_address)
8996
97# Search for ubuntu/[01] in the config file, raise an exception if not found.
98configuration_file.index(ubuntu_0_public_address)
99configuration_file.index(ubuntu_1_public_address)
100
90print('The ntp deploy test completed successfully.')101print('The ntp deploy test completed successfully.')

Subscribers

People subscribed via source and target branches

to all changes: