Merge ~vlgrevtsev/ntp-charm:lp1835766 into ntp-charm:master

Proposed by Vladimir Grevtsev
Status: Merged
Approved by: Haw Loeung
Approved revision: 54ea9fed2dede66bb06cbc4be12b2c764cfe2fde
Merged at revision: b120456b0b3370d44877993c06fbbc200b3f6e37
Proposed branch: ~vlgrevtsev/ntp-charm:lp1835766
Merge into: ntp-charm:master
Diff against target: 46 lines (+26/-0)
2 files modified
config.yaml (+6/-0)
reactive/ntp.py (+20/-0)
Reviewer Review Type Date Requested Status
Haw Loeung Approve
Stuart Bishop (community) Approve
Canonical IS Reviewers Pending
Review via email: mp+369879@code.launchpad.net

Commit message

Added option to ensure all source NTP servers provided via config are being tested - and error raised, if some of them are not reachable.

To post a comment you must log in.
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

This merge proposal is being monitored by mergebot. Change the status to Approved to merge.

Revision history for this message
Stuart Bishop (stub) wrote :

Looks good to me. 'blocked' is probably the right status to notify users with, but I could also argue 'waiting' since in many cases the issue will resolve itself rather than needing user intervention.

The subprocess call needs to be tweaked before landing to avoid the need for shell=True, which avoids potential problems if the server address needs shell character escaping (probably trusted and fine, but if shell=False nobody has to trace things back to confirm that).

Still needs a peer review by someone more familiar with NTP before landing, but I suspect it will be no problem since the new behavior is optional.

review: Approve
Revision history for this message
Vladimir Grevtsev (vlgrevtsev) wrote :

@Stuart, thanks for comment re "shell=True" - I fixed that and updated a review.

Revision history for this message
Haw Loeung (hloeung) wrote :

There's nothing to install the 'ntpdate' package, from universe.

Also, there's code in the ntpmon layer which this charm pulls in and does all the reach-ability checks. Maybe you could import and use that rather than ntpdate?

Revision history for this message
Tom Haddon (mthaddon) wrote :

> There's nothing to install the 'ntpdate' package, from universe.

I've tested this on an LXC on trusty:

$ apt-cache policy ntpdate
ntpdate:
  Installed: 1:4.2.6.p5+dfsg-3ubuntu2.14.04.13
  Candidate: 1:4.2.6.p5+dfsg-3ubuntu2.14.04.13
  Version table:
 *** 1:4.2.6.p5+dfsg-3ubuntu2.14.04.13 0
        500 http://archive.ubuntu.com/ubuntu/ trusty-updates/main amd64 Packages
        500 http://security.ubuntu.com/ubuntu/ trusty-security/main amd64 Packages
        100 /var/lib/dpkg/status
     1:4.2.6.p5+dfsg-3ubuntu2 0
        500 http://archive.ubuntu.com/ubuntu/ trusty/main amd64 Packages

And on an LXC on xenial:

$ apt-cache policy ntpdate
ntpdate:
  Installed: (none)
  Candidate: 1:4.2.8p4+dfsg-3ubuntu5.9
  Version table:
     1:4.2.8p4+dfsg-3ubuntu5.9 500
        500 http://archive.ubuntu.com/ubuntu xenial-updates/main amd64 Packages
        500 http://security.ubuntu.com/ubuntu xenial-security/main amd64 Packages
     1:4.2.8p4+dfsg-3ubuntu5 500
        500 http://archive.ubuntu.com/ubuntu xenial/main amd64 Packages

And on LXC in bionic:

$ apt-cache policy ntpdate
ntpdate:
  Installed: (none)
  Candidate: 1:4.2.8p10+dfsg-5ubuntu7.1
  Version table:
     1:4.2.8p10+dfsg-5ubuntu7.1 500
        500 http://archive.ubuntu.com/ubuntu bionic-updates/universe amd64 Packages
        500 http://security.ubuntu.com/ubuntu bionic-security/universe amd64 Packages
     1:4.2.8p10+dfsg-5ubuntu7 500
        500 http://archive.ubuntu.com/ubuntu bionic/universe amd64 Packages

So it seems like configuring universe would be needed if we're on bionic, just to clarify.

Revision history for this message
Vladimir Grevtsev (vlgrevtsev) wrote :

Well, the charm itself is installing ntpdate tool:

https://git.launchpad.net/ntp-charm/tree/lib/ntp_scoring.py#n27
https://git.launchpad.net/ntp-charm/tree/reactive/ntp.py#n108

I did a test deployment with Juju and MAAS provider and charm has installed an ntpdate package itself without any manual intervention (however, it was not present before charm installation began): https://pastebin.canonical.com/p/2mJ9J7fwGq/

So is there any reason we still can't use ntpdate, as proposed?

Revision history for this message
Haw Loeung (hloeung) wrote :

Ah, I didn't realise that we're already pulling in 'ntpdate' and using it - although it is to be deprecated because the code hasn't really been updated[1]. We certainly want to fix that, but that can happen in future changes.

[1]http://support.ntp.org/bin/view/Dev/DeprecatingNtpdate

Revision history for this message
Haw Loeung (hloeung) :
review: Approve
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

Change successfully merged at revision b120456b0b3370d44877993c06fbbc200b3f6e37

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/config.yaml b/config.yaml
2index f7574a6..bb07365 100644
3--- a/config.yaml
4+++ b/config.yaml
5@@ -1,4 +1,10 @@
6 options:
7+ verify_ntp_servers:
8+ default: false
9+ type: boolean
10+ description: >
11+ If configured to True, charm will automatically try to verify that
12+ given NTP servers are accessible and raise an error, if they aren't.
13 source:
14 default: ""
15 type: string
16diff --git a/reactive/ntp.py b/reactive/ntp.py
17index 9476fd2..6b8f082 100755
18--- a/reactive/ntp.py
19+++ b/reactive/ntp.py
20@@ -296,6 +296,26 @@ def assess_status():
21 hookenv.application_version_set(version)
22
23 status = []
24+ if hookenv.config('verify_ntp_servers'):
25+ failed_servers = []
26+ if hookenv.config('source'):
27+ for server in hookenv.config('source').split():
28+ try:
29+ subprocess.check_call(
30+ ["ntpdate", "-qd", server],
31+ stderr=subprocess.DEVNULL,
32+ )
33+ except subprocess.CalledProcessError:
34+ failed_servers.append(server)
35+ continue
36+
37+ if failed_servers:
38+ _servers = '; '.join(failed_servers)
39+ hookenv.status_set(
40+ 'blocked',
41+ 'NTP servers are not reachable: %s' % _servers
42+ )
43+ return
44
45 # service status
46 if host.service_running(implementation.service_name()):

Subscribers

People subscribed via source and target branches