From f6d87cb468845c498e42e7285099d5b295ee936b Mon Sep 17 00:00:00 2001
From: Pat Riehecky <riehecky@fnal.gov>
Date: Wed, 12 Feb 2014 11:43:16 -0600
Subject: [PATCH] Added chrony lense
(cherry picked from commit 319e30fcbea54aadc97430809cea6fb7b398b4b6)
---
doc/naturaldocs/conf/lenses/Menu.txt | 2 +
lenses/chrony.aug | 266 +++++++++++++++++++++++++++++++++++
lenses/tests/test_chrony.aug | 143 +++++++++++++++++++
tests/Makefile.am | 1 +
4 files changed, 412 insertions(+)
create mode 100644 lenses/chrony.aug
create mode 100644 lenses/tests/test_chrony.aug
diff --git a/doc/naturaldocs/conf/lenses/Menu.txt b/doc/naturaldocs/conf/lenses/Menu.txt
index a6fa0f0..34e0bf6 100644
--- a/doc/naturaldocs/conf/lenses/Menu.txt
+++ b/doc/naturaldocs/conf/lenses/Menu.txt
@@ -74,6 +74,7 @@ Group: Specific Modules {
File: Cgconfig (no auto-title, cgconfig.aug)
File: Cgrules (no auto-title, cgrules.aug)
File: Channels (channels.aug)
+ File: Chrony (chrony.aug)
File: Collectd (collectd.aug)
File: Cron (cron.aug)
File: Crypttab (crypttab.aug)
@@ -191,6 +192,7 @@ Group: Tests and Examples {
File: Test_Build (tests/test_build.aug)
File: Test_Carbon (tests/test_carbon.aug)
File: Test_Channels (tests/test_channels.aug)
+ File: Test_Chrony (tests/test_chrony.aug)
File: Test_Collectd (tests/test_collectd.aug)
File: Test_Cups (tests/test_cups.aug)
File: Test_Dovecot (tests/test_dovecot.aug)
diff --git a/lenses/chrony.aug b/lenses/chrony.aug
new file mode 100644
index 0000000..ede2c94
--- /dev/null
+++ b/lenses/chrony.aug
@@ -0,0 +1,266 @@
+(*
+Module: Chrony
+ Parses the chrony config file
+
+Author: Pat Riehecky <riehecky@fnal.gov>
+
+About: Reference
+ This lens tries to keep as close as possible to chrony config syntax
+
+ See http://chrony.tuxfamily.org/manual.html#Configuration-file
+
+About: Limitations
+ Does not (currently) support
+ - include
+ - manual
+ - refclock
+ - tempcomp
+
+About: License
+ This file is licenced under the LGPL v2+, like the rest of Augeas.
+
+About: Lens Usage
+ To be documented
+
+About: Configuration files
+ This lens applies to /etc/chrony.conf
+
+ See <filter>.
+*)
+
+module Chrony =
+ autoload xfm
+
+(************************************************************************
+ * Group: Import provided expressions
+ ************************************************************************)
+ (* View: empty *)
+ let empty = Util.empty
+
+ (* View: eol *)
+ let eol = Util.eol
+
+ (* View: space *)
+ let space = Sep.space
+
+ (* Variable: email_addr *)
+ let email_addr = Rx.email_addr
+
+ (* Variable: word *)
+ let word = Rx.word
+
+ (* Variable: integer *)
+ let integer = Rx.integer
+
+ (* Variable: decimal *)
+ let decimal = Rx.decimal
+
+ (* Variable: ip *)
+ let ip = Rx.ip
+
+(************************************************************************
+ * Group: Create required expressions
+ ************************************************************************)
+ (* Variable: number *)
+ let number = integer | decimal
+
+ (* Variable: address_re *)
+ let address_re = Rx.ip | Rx.hostname
+
+ (*
+ View: comment
+ from 4.2.1 of the upstream doc
+ Chrony comments start with: ! ; # or % and must be on their own line
+ *)
+ let comment = Util.comment_generic /[ \t]*[!;#%][ \t]*/ "# "
+
+ (* Variable: no_space
+ No spaces or comment characters
+ *)
+ let no_space = /[^ \t\r\n!;#%]+/
+
+ (* Variable: cmd_options
+ Server/Peer options with values
+ *)
+ let cmd_options = "key"
+ | /maxdelay((dev)?ratio)?/
+ | /(min|max)poll/
+ | "polltarget"
+ | "port"
+ | "presend"
+
+ (* Variable: cmd_flags
+ Server/Peer options without values
+ *)
+ let cmd_flags = "auto_offline"|"iburst"|"noselect"|"offline"|"prefer"
+
+ (* Variable: server_peer
+ Server/Peer key names
+ *)
+ let server_peer = "server"|"peer"
+
+ (* Variable: flags
+ Options without values
+ *)
+ let flags = "dumponexit"
+ | "generatecommandkey"
+ | "lock_all"
+ | "noclientlog"
+ | "rtconutc"
+ | "rtcsync"
+
+ (* Variable: log_flags
+ log has a specific options list
+ *)
+ let log_flags = /measurments|statistics|tracking|rtc|refclocks|tempcomp/
+
+ (* Variable: simple_keys
+ Options with single values
+ *)
+ let simple_keys = "acquisitionport" | "allow" | "bindaddress"
+ | "bindcmdaddress" | "cmdallow" | "cmddeny"
+ | "combinelimit" | "commandkey" | "cmdport"
+ | "corrtimeratio" | "deny" | "driftfile"
+ | "dumpdir" | "keyfile" | "leapsectz" | "linux_hz"
+ | "linux_freq_scale" | "logbanner" | "logchange"
+ | "logdir" | "maxclockerror" | "maxsamples"
+ | "maxupdateskew" | "minsamples" | "clientloglimit"
+ | "pidfile" | "port" | "reselectdist" | "rtcdevice"
+ | "rtcfile" | "sched_priority" | "stratumweight" | "user"
+
+(************************************************************************
+ * Group: Make some sub-lenses for use in later lenses
+ ************************************************************************)
+ (* View: host_flags *)
+ let host_flags = [ space . key cmd_flags ]
+ (* View: host_options *)
+ let host_options = [ space . key cmd_options . space . store integer ]
+ (* View: log_flag_list *)
+ let log_flag_list = [ space . key log_flags ]
+ (* View: store_address *)
+ let store_address = [ label "address" . store address_re ]
+
+(************************************************************************
+ * Group: Lenses for parsing out sections
+ ************************************************************************)
+ (* View: all_flags
+ match all flags using Build.flag_line
+ *)
+ let all_flags = Build.flag_line flags
+
+ (* View: kv
+ options with only one arg can be directly mapped to key = value
+ *)
+ let kv = Build.key_value_line_comment simple_keys space (store no_space) comment
+
+ (* Property: Options with multiple values
+
+ Each of these gets their own parsing block
+ - server|peer <address> <options>
+ - log <options>
+ - broadcast <interval> <address> <optional port>
+ - fallbackdrift <min> <max>
+ - initstepslew <threshold> <addr> <optional extra addrs>
+ - local stratum <int>
+ - mailonchange <emailaddress> <threshold>
+ - makestep <threshold> <limit>
+ - maxchange <threshold> <delay> <limit>
+ *)
+
+ (* View: host_list
+ Find all ntp servers/peers and their flags/options
+ *)
+ let host_list = [ Util.indent . key server_peer
+ . space . store address_re
+ . ( host_flags | host_options )*
+ . eol ]
+
+ (* View: log_list
+ log has a specific options list
+ *)
+ let log_list = [ Util.indent . key "log" . log_flag_list+ . eol ]
+
+ (* View: bcast
+ broadcast has specific syntax
+ *)
+ let bcast = [ Util.indent . key "broadcast"
+ . space . [ label "interval" . store integer ]
+ . space . store_address
+ . ( space . [ label "port" . store integer] | eol) ]
+
+ (* View: fdrift
+ fallbackdrift has specific syntax
+ *)
+ let fdrift = [ Util.indent . key "fallbackdrift"
+ . space . [ label "min" . store integer ]
+ . space . [ label "max" . store integer ]
+ . eol ]
+
+ (* View: istepslew
+ initstepslew has specific syntax
+ *)
+ let istepslew = [ Util.indent . key "initstepslew"
+ . space . [ label "threshold" . store number ]
+ . ( space . store_address )+
+ . eol ]
+
+ (* View: local
+ local has specific syntax
+ *)
+ let local = [ Util.indent . key "local" . space
+ . [ key "stratum" . space . store integer ]
+ . eol ]
+
+ (* View: email
+ mailonchange has specific syntax
+ *)
+ let email = [ Util.indent . key "mailonchange" . space
+ . [ label "emailaddress" . store email_addr ]
+ . space
+ . [ label "threshold" . store number ]
+ . eol ]
+
+ (* View: makestep
+ makestep has specific syntax
+ *)
+ let makestep = [ Util.indent . key "makestep"
+ . space
+ . [ label "threshold" . store number ]
+ . space
+ . [ label "limit" . store integer ]
+ . eol ]
+
+ (* View: maxchange
+ maxchange has specific syntax
+ *)
+ let maxchange = [ Util.indent . key "maxchange"
+ . space
+ . [ label "threshold" . store number ]
+ . space
+ . [ label "delay" . store integer ]
+ . space
+ . [ label "limit" . store integer ]
+ . eol ]
+
+(************************************************************************
+ * Group: Final lense summary
+ ************************************************************************)
+(* View: settings
+ * All supported chrony settings
+ *)
+let settings = host_list | log_list | bcast | fdrift | istepslew
+ | local | email | makestep | maxchange | kv | all_flags
+
+(*
+ * View: lns
+ * The crony lens
+ *)
+let lns = ( empty | comment | settings )*
+
+(* View: filter
+ * The files parsed by default
+ *)
+let filter = incl "/etc/chrony.conf"
+
+let xfm = transform lns filter
+
diff --git a/lenses/tests/test_chrony.aug b/lenses/tests/test_chrony.aug
new file mode 100644
index 0000000..4917358
--- /dev/null
+++ b/lenses/tests/test_chrony.aug
@@ -0,0 +1,143 @@
+(*
+Module: Test_Chrony
+ Provides unit tests and examples for the <Chrony> lens.
+*)
+
+module Test_Chrony =
+
+ let exampleconf = "# Comment
+#Comment
+! Comment
+!Comment
+; Comment
+;Comment
+% Comment
+%Comment
+
+server ntp1.example.com
+server ntp2.example.com iburst
+server ntp3.example.com presend 2
+server ntp4.example.com offline polltarget 4
+server ntp5.example.com maxdelay 2 offline
+server ntp6.example.com maxdelay 2 iburst presend 2
+server ntp7.example.com iburst presend 2 offline
+peer ntpc1.example.com
+stratumweight 0
+driftfile /var/lib/chrony/drift
+rtcsync
+makestep 10 3
+bindcmdaddress 127.0.0.1
+bindcmdaddress ::1
+local stratum 10
+keyfile /etc/chrony.keys
+commandkey 1
+generatecommandkey
+noclientlog
+logchange 0.5
+logdir /var/log/chrony
+log rtc
+leapsectz right/UTC
+broadcast 10 192.168.1.255
+broadcast 10 192.168.100.255 123
+fallbackdrift 16 19
+mailonchange root@localhost 0.5
+maxchange 1000 1 2
+initstepslew 30 foo.bar.com
+initstepslew 30 foo.bar.com baz.quz.com
+"
+
+ test Chrony.lns get exampleconf =
+ { "#comment" = "Comment" }
+ { "#comment" = "Comment" }
+ { "#comment" = "Comment" }
+ { "#comment" = "Comment" }
+ { "#comment" = "Comment" }
+ { "#comment" = "Comment" }
+ { "#comment" = "Comment" }
+ { "#comment" = "Comment" }
+ { }
+ { "server" = "ntp1.example.com" }
+ { "server" = "ntp2.example.com"
+ { "iburst" }
+ }
+ { "server" = "ntp3.example.com"
+ { "presend" = "2" }
+ }
+ { "server" = "ntp4.example.com"
+ { "offline" }
+ { "polltarget" = "4" }
+ }
+ { "server" = "ntp5.example.com"
+ { "maxdelay" = "2" }
+ { "offline" }
+ }
+ { "server" = "ntp6.example.com"
+ { "maxdelay" = "2" }
+ { "iburst" }
+ { "presend" = "2" }
+ }
+ { "server" = "ntp7.example.com"
+ { "iburst" }
+ { "presend" = "2" }
+ { "offline" }
+ }
+ { "peer" = "ntpc1.example.com" }
+ { "stratumweight" = "0" }
+ { "driftfile" = "/var/lib/chrony/drift" }
+ { "rtcsync" }
+ { "makestep"
+ { "threshold" = "10" }
+ { "limit" = "3" }
+ }
+ { "bindcmdaddress" = "127.0.0.1" }
+ { "bindcmdaddress" = "::1" }
+ { "local"
+ { "stratum" = "10" }
+ }
+ { "keyfile" = "/etc/chrony.keys" }
+ { "commandkey" = "1" }
+ { "generatecommandkey" }
+ { "noclientlog" }
+ { "logchange" = "0.5" }
+ { "logdir" = "/var/log/chrony" }
+ { "log"
+ { "rtc" }
+ }
+ { "leapsectz" = "right/UTC" }
+ { "broadcast"
+ { "interval" = "10" }
+ { "address" = "192.168.1.255" }
+ }
+ { "broadcast"
+ { "interval" = "10" }
+ { "address" = "192.168.100.255" }
+ { "port" = "123" }
+ }
+ { }
+ { "fallbackdrift"
+ { "min" = "16" }
+ { "max" = "19" }
+ }
+ { "mailonchange"
+ { "emailaddress" = "root@localhost" }
+ { "threshold" = "0.5" }
+ }
+ { "maxchange"
+ { "threshold" = "1000" }
+ { "delay" = "1" }
+ { "limit" = "2" }
+ }
+ { "initstepslew"
+ { "threshold" = "30" }
+ { "address" = "foo.bar.com" }
+ }
+ { "initstepslew"
+ { "threshold" = "30" }
+ { "address" = "foo.bar.com" }
+ { "address" = "baz.quz.com" }
+ }
+
+
+(* Local Variables: *)
+(* mode: caml *)
+(* End: *)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 180a19d..1b79629 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -41,6 +41,7 @@ lens_tests = \
lens-cgconfig.sh \
lens-cgrules.sh \
lens-channels.sh \
+ lens-chrony.sh \
lens-cobblersettings.sh \
lens-cobblermodules.sh \
lens-collectd.sh \