Bump Sharp.Augeas

This commit is contained in:
code liturgy 2022-12-04 23:07:41 +00:00
parent a8c22a0e94
commit ce13a75aaa
601 changed files with 69014 additions and 9 deletions

View File

@ -26,8 +26,6 @@ EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeLiturgy.Views", "CodeLiturgy.Views\CodeLiturgy.Views.csproj", "{59714691-B930-416E-9B93-D91BAE37318F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sharp.Augeas.Test", "include\Sharp.Augeas\Sharp.Augeas.Test\Sharp.Augeas.Test.csproj", "{03308684-19AC-454B-8CD3-AB1C26B8BBBF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sharp.Augeas", "include\Sharp.Augeas\Sharp.Augeas\Sharp.Augeas.csproj", "{25840113-CFD7-4B72-B096-E3EAA4A811DB}"
EndProject
Global
@ -60,10 +58,6 @@ Global
{59714691-B930-416E-9B93-D91BAE37318F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{59714691-B930-416E-9B93-D91BAE37318F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{59714691-B930-416E-9B93-D91BAE37318F}.Release|Any CPU.Build.0 = Release|Any CPU
{03308684-19AC-454B-8CD3-AB1C26B8BBBF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{03308684-19AC-454B-8CD3-AB1C26B8BBBF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{03308684-19AC-454B-8CD3-AB1C26B8BBBF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{03308684-19AC-454B-8CD3-AB1C26B8BBBF}.Release|Any CPU.Build.0 = Release|Any CPU
{25840113-CFD7-4B72-B096-E3EAA4A811DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{25840113-CFD7-4B72-B096-E3EAA4A811DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{25840113-CFD7-4B72-B096-E3EAA4A811DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -76,7 +70,6 @@ Global
{30637214-EDE9-4C2E-BFD6-E4B163FA308B} = {A1606EEC-6AC5-4779-B140-F57089F5A05F}
{08F4484E-5FD8-4590-A8D7-12FBE47120C8} = {A1606EEC-6AC5-4779-B140-F57089F5A05F}
{BBF5E860-A880-450B-B6C9-EF92F6421B3D} = {A1606EEC-6AC5-4779-B140-F57089F5A05F}
{03308684-19AC-454B-8CD3-AB1C26B8BBBF} = {A1606EEC-6AC5-4779-B140-F57089F5A05F}
{25840113-CFD7-4B72-B096-E3EAA4A811DB} = {A1606EEC-6AC5-4779-B140-F57089F5A05F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution

View File

@ -0,0 +1,15 @@
using Sharp.Augeas;
namespace CodeLiturgy.Views.Augeas;
public static class AugeasExtensions
{
public static AugSettings GetSettings()
{
// if DEBUG we use this
var rootDir = Environment.CurrentDirectory + "/root";
var lensDir = Environment.CurrentDirectory + "/lens";
return new AugSettings(rootDir, lensDir);
}
}

View File

@ -0,0 +1,34 @@
using Sharp.Augeas;
namespace CodeLiturgy.Views.Augeas
{
public class AugeasManager
{
private readonly Sharp.Augeas.Augeas _augeas;
private AugSettings _augSettings;
public AugeasManager()
{
_augeas = new Sharp.Augeas.Augeas(AugeasExtensions.GetSettings());
}
public string GetPreview()
{
var preview = _augeas.GetPreview("/files/etc/apache2/sites-available/example.com.conf");
return preview;
}
public List<string> GetApacheAvailableConfigurations()
{
DirectoryInfo d = new DirectoryInfo(_augSettings.); //Assuming Test is your Folder
FileInfo[] Files = d.GetFiles("*.txt"); //Getting Text files
string str = "";
foreach(FileInfo file in Files )
{
str = str + ", " +
}
}
}

View File

@ -0,0 +1,128 @@
(*
Module: Access
Parses /etc/security/access.conf
Author: Lorenzo Dalrio <lorenzo.dalrio@gmail.com>
About: Reference
Some examples of valid entries can be found in access.conf or "man access.conf"
About: License
This file is licensed under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
Sample usage of this lens in augtool
* Add a rule to permit login of all users from local sources (tty's, X, cron)
> set /files/etc/security/access.conf[0] +
> set /files/etc/security/access.conf[0]/user ALL
> set /files/etc/security/access.conf[0]/origin LOCAL
About: Configuration files
This lens applies to /etc/security/access.conf. See <filter>.
About: Examples
The <Test_Access> file contains various examples and tests.
*)
module Access =
autoload xfm
(* Group: Comments and empty lines *)
(* Variable: comment *)
let comment = Util.comment
(* Variable: empty *)
let empty = Util.empty
(* Group: Useful primitives *)
(* Variable: colon
* this is the standard field separator " : "
*)
let colon = del (Rx.opt_space . ":" . Rx.opt_space) " : "
(************************************************************************
* Group: ENTRY LINE
*************************************************************************)
(* View: access
* Allow (+) or deny (-) access
*)
let access = label "access" . store /[+-]/
(* Variable: identifier_re
Regex for user/group identifiers *)
let identifier_re = /[A-Za-z0-9_.\\-]+/
(* View: user_re
* Regex for user/netgroup fields
*)
let user_re = identifier_re - /[Ee][Xx][Cc][Ee][Pp][Tt]/
(* View: user
* user can be a username, username@hostname or a group
*)
let user = [ label "user"
. ( store user_re
| store Rx.word . Util.del_str "@"
. [ label "host" . store Rx.word ] ) ]
(* View: group
* Format is (GROUP)
*)
let group = [ label "group"
. Util.del_str "(" . store identifier_re . Util.del_str ")" ]
(* View: netgroup
* Format is @NETGROUP[@@NISDOMAIN]
*)
let netgroup =
[ label "netgroup" . Util.del_str "@" . store user_re
. [ label "nisdomain" . Util.del_str "@@" . store Rx.word ]? ]
(* View: user_list
* A list of users or netgroups to apply the rule to
*)
let user_list = Build.opt_list (user|group|netgroup) Sep.space
(* View: origin_list
* origin_list can be a single ipaddr/originname/domain/fqdn or a list of those values
*)
let origin_list =
let origin_re = Rx.no_spaces - /[Ee][Xx][Cc][Ee][Pp][Tt]/
in Build.opt_list [ label "origin" . store origin_re ] Sep.space
(* View: except
* The except operator makes it possible to write very compact rules.
*)
let except (lns:lens) = [ label "except" . Sep.space
. del /[Ee][Xx][Cc][Ee][Pp][Tt]/ "EXCEPT"
. Sep.space . lns ]
(* View: entry
* A valid entry line
* Definition:
* > entry ::= access ':' user ':' origin_list
*)
let entry = [ access . colon
. user_list
. (except user_list)?
. colon
. origin_list
. (except origin_list)?
. Util.eol ]
(************************************************************************
* Group: LENS & FILTER
*************************************************************************)
(* View: lns
The access.conf lens, any amount of
* <empty> lines
* <comments>
* <entry>
*)
let lns = (comment|empty|entry) *
(* Variable: filter *)
let filter = incl "/etc/security/access.conf"
(* xfm *)
let xfm = transform lns filter

View File

@ -0,0 +1,61 @@
(*
Module: ActiveMQ_Conf
ActiveMQ / FuseMQ conf module for Augeas
Author: Brian Redbeard <redbeard@dead-city.org>
About: Reference
This lens ensures that conf files included in ActiveMQ /FuseMQ are properly
handled by Augeas.
About: License
This file is licensed under the LGPL License.
About: Lens Usage
Sample usage of this lens in augtool:
* Get your current setup
> print /files/etc/activemq.conf
...
* Change ActiveMQ Home
> set /files/etc/activemq.conf/ACTIVEMQ_HOME /usr/share/activemq
Saving your file:
> save
About: Configuration files
This lens applies to relevant conf files located in /etc/activemq/ and
the file /etc/activemq.conf . See <filter>.
*)
module ActiveMQ_Conf =
autoload xfm
(* Variable: blank_val *)
let blank_val = del /^\z/
(* View: entry *)
let entry =
Build.key_value_line Rx.word Sep.space_equal Quote.any_opt
(* View: empty_entry *)
let empty_entry = Build.key_value_line Rx.word Sep.equal Quote.dquote_opt_nil
(* View: lns *)
let lns = (Util.empty | Util.comment | entry | empty_entry )*
(* Variable: filter *)
let filter = incl "/etc/activemq.conf"
. incl "/etc/activemq/*"
. excl "/etc/activemq/*.xml"
. excl "/etc/activemq/jmx.*"
. excl "/etc/activemq/jetty-realm.properties"
. excl "/etc/activemq/*.ts"
. excl "/etc/activemq/*.ks"
. excl "/etc/activemq/*.cert"
. Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,41 @@
(*
Module: ActiveMQ_XML
ActiveMQ / FuseMQ XML module for Augeas
Author: Brian Redbeard <redbeard@dead-city.org>
About: Reference
This lens ensures that XML files included in ActiveMQ / FuseMQ are properly
handled by Augeas.
About: License
This file is licensed under the LGPL License.
About: Lens Usage
Sample usage of this lens in augtool:
* Get your current setup
> print /files/etc/activemq/activemq.xml
...
* Change OpenShift domain
> set /files/etc/openshift/broker.conf/CLOUD_DOMAIN ose.example.com
Saving your file:
> save
About: Configuration files
This lens applies to relevant XML files located in /etc/activemq/ . See <filter>.
*)
module ActiveMQ_XML =
autoload xfm
let lns = Xml.lns
let filter = (incl "/etc/activemq/*.xml")
. Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,60 @@
(*
Module: AFS_cellalias
Parses AFS configuration file CellAlias
Author: Pat Riehecky <riehecky@fnal.gov>
About: Reference
This lens is targeted at the OpenAFS CellAlias file
About: Lens Usage
Sample usage of this lens in augtool
* Add a CellAlias for fnal.gov/files to fnal-files
> set /files/usr/vice/etc/CellAlias/target[99] fnal.gov/files
> set /files/usr/vice/etc/CellAlias/target[99]/linkname fnal-files
About: License
This file is licensed under the LGPL v2+, like the rest of Augeas.
*)
module AFS_cellalias =
autoload xfm
(************************************************************************
* Group: USEFUL PRIMITIVES
*************************************************************************)
(* Group: Comments and empty lines *)
(* View: eol *)
let eol = Util.eol
(* View: comment *)
let comment = Util.comment
(* View: empty *)
let empty = Util.empty
(* Group: separators *)
(* View: space
* Separation between key and value
*)
let space = Util.del_ws_spc
let target = /[^ \t\n#]+/
let linkname = Rx.word
(************************************************************************
* Group: ENTRIES
*************************************************************************)
(* View: entry *)
let entry = [ label "target" . store target . space . [ label "linkname" . store linkname . eol ] ]
(* View: lns *)
let lns = (empty | comment | entry)*
let xfm = transform lns (incl "/usr/vice/etc/CellAlias")
(* Local Variables: *)
(* mode: caml *)
(* End: *)

View File

@ -0,0 +1,89 @@
(*
Module: Aliases
Parses /etc/aliases
Author: David Lutterkort <lutter@redhat.com>
About: Reference
This lens tries to keep as close as possible to `man 5 aliases` where possible.
About: License
This file is licenced under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
See <lns>.
About: Configuration files
This lens applies to /etc/aliases.
About: Examples
The <Test_Aliases> file contains various examples and tests.
*)
module Aliases =
autoload xfm
(************************************************************************
* Group: USEFUL PRIMITIVES
*************************************************************************)
(* Group: basic tokens *)
(* Variable: word *)
let word = /[^|", \t\n]+/
(* Variable: name *)
let name = /([^ \t\n#:|@]+|"[^"|\n]*")/ (* " make emacs calm down *)
(* Variable: command
* a command can contain spaces, if enclosed in double quotes, the case
* without spaces is taken care with <word>
*)
let command = /(\|([^", \t\n]+|"[^"\n]+"))|("\|[^"\n]+")/
(* Group: Comments and empty lines *)
(* View: eol *)
let eol = Util.eol
(* View: comment *)
let comment = Util.comment
(* View: empty *)
let empty = Util.empty
(* Group: separators *)
(* View: colon
* Separation between the alias and it's destinations
*)
let colon = del /[ \t]*:[ \t]*/ ":\t"
(* View: comma
* Separation between multiple destinations
*)
let comma = del /[ \t]*,[ \t]*(\n[ \t]+)?/ ", "
(* Group: alias *)
(* View: destination
* Can be either a word (no spaces included) or a command with spaces
*)
let destination = ( word | command )
(* View: value_list
* List of destinations
*)
let value_list = Build.opt_list ([ label "value" . store destination]) comma
(* View: alias
* a name with one or more destinations
*)
let alias = [ seq "alias" .
[ label "name" . store name ] . colon .
value_list
] . eol
(* View: lns *)
let lns = (comment | empty | alias)*
let xfm = transform lns (incl "/etc/aliases")
(* Local Variables: *)
(* mode: caml *)
(* End: *)

View File

@ -0,0 +1,30 @@
(*
Module: Anaconda
Parses Anaconda's user interaction configuration files.
Author: Pino Toscano <ptoscano@redhat.com>
About: Reference
https://anaconda-installer.readthedocs.io/en/latest/user-interaction-config-file-spec.html
About: Configuration file
This lens applies to /etc/sysconfig/anaconda.
About: License
This file is licensed under the LGPL v2+, like the rest of Augeas.
*)
module Anaconda =
autoload xfm
let comment = IniFile.comment "#" "#"
let sep = IniFile.sep "=" "="
let entry = IniFile.entry IniFile.entry_re sep comment
let title = IniFile.title IniFile.record_re
let record = IniFile.record title entry
let lns = IniFile.lns record comment
let filter = incl "/etc/sysconfig/anaconda"
let xfm = transform lns filter

View File

@ -0,0 +1,87 @@
(*
Module: Anacron
Parses /etc/anacrontab
Author: Raphael Pinson <raphink@gmail.com>
About: Reference
This lens tries to keep as close as possible to `man 5 anacrontab` where
possible.
About: License
This file is licensed under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
About: Configuration files
This lens applies to /etc/anacrontab. See <filter>.
About: Examples
The <Test_Anacron> file contains various examples and tests.
*)
module Anacron =
autoload xfm
(************************************************************************
* Group: ENTRIES
*************************************************************************)
(************************************************************************
* View: shellvar
* A shell variable in crontab
*************************************************************************)
let shellvar = Cron.shellvar
(* View: period *)
let period = [ label "period" . store Rx.integer ]
(* Variable: period_name_re
The valid values for <period_name>. Currently only "monthly" *)
let period_name_re = "monthly"
(************************************************************************
* View: period_name
* In the format "@keyword"
*************************************************************************)
let period_name = [ label "period_name" . Util.del_str "@"
. store period_name_re ]
(************************************************************************
* View: delay
* The delay for an <entry>
*************************************************************************)
let delay = [ label "delay" . store Rx.integer ]
(************************************************************************
* View: job_identifier
* The job_identifier for an <entry>
*************************************************************************)
let job_identifier = [ label "job-identifier" . store Rx.word ]
(************************************************************************
* View: entry
* An anacrontab entry
*************************************************************************)
let entry = [ label "entry" . Util.indent
. ( period | period_name )
. Sep.space . delay
. Sep.space . job_identifier
. Sep.space . store Rx.space_in . Util.eol ]
(*
* View: lns
* The anacron lens
*)
let lns = ( Util.empty | Util.comment | shellvar | entry )*
(* Variable: filter *)
let filter = incl "/etc/anacrontab"
let xfm = transform lns filter

View File

@ -0,0 +1,59 @@
(*
Module: Approx
Parses /etc/approx/approx.conf
Author: David Lutterkort <lutter@redhat.com>
About: Reference
This lens tries to keep as close as possible to `man 5 approx.conf` where possible.
About: License
This file is licenced under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
See <lns>.
About: Configuration files
This lens applies to /etc/approx/approx.conf.
About: Examples
The <Test_Approx> file contains various examples and tests.
*)
module Approx =
autoload xfm
(* Variable: eol
An <Util.eol> *)
let eol = Util.eol
(* Variable: indent
An <Util.indent> *)
let indent = Util.indent
(* Variable: key_re *)
let key_re = /\$?[A-Za-z0-9_.-]+/
(* Variable: sep *)
let sep = /[ \t]+/
(* Variable: value_re *)
let value_re = /[^ \t\n](.*[^ \t\n])?/
(* View: comment *)
let comment = [ indent . label "#comment" . del /[#;][ \t]*/ "# "
. store /([^ \t\n].*[^ \t\n]|[^ \t\n])/ . eol ]
(* View: empty
An <Util.empty> *)
let empty = Util.empty
(* View: kv *)
let kv = [ indent . key key_re . del sep " " . store value_re . eol ]
(* View: lns *)
let lns = (empty | comment | kv) *
(* View: filter *)
let filter = incl "/etc/approx/approx.conf"
let xfm = transform lns filter

View File

@ -0,0 +1,47 @@
(*
Module: Apt_Update_Manager
Parses files in /etc/update-manager
Author: Raphael Pinson <raphael.pinson@camptocamp.com>
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 files in /etc/update-manager. See <filter>.
About: Examples
The <Test_Apt_Update_Manager> file contains various examples and tests.
*)
module Apt_Update_Manager =
autoload xfm
(* View: comment *)
let comment = IniFile.comment IniFile.comment_re IniFile.comment_default
(* View: sep *)
let sep = IniFile.sep IniFile.sep_re IniFile.sep_default
(* View: title *)
let title = IniFile.title Rx.word
(* View: entry *)
let entry = IniFile.entry Rx.word sep comment
(* View: record *)
let record = IniFile.record title entry
(* View: lns *)
let lns = IniFile.lns record comment
(* Variable: filter *)
let filter = incl "/etc/update-manager/meta-release"
. incl "/etc/update-manager/release-upgrades"
. incl "/etc/update-manager/release-upgrades.d/*"
. Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,25 @@
(* Module: AptCacherNGSecurity
Lens for config files like the one found in
/etc/apt-cacher-ng/security.conf
About: License
Copyright 2013 Erik B. Andersen; this file is licenced under the LGPL v2+.
*)
module AptCacherNGSecurity =
autoload xfm
(* Define a Username/PW pair *)
let authpair = [ key /[^ \t:\/]*/ . del /:/ ":" . store /[^: \t\n]*/ ]
(* Define a record. So far as I can tell, the only auth level supported is Admin *)
let record = [ key "AdminAuth". del /[ \t]*:[ \t]*/ ": ". authpair . Util.del_str "\n"]
(* Define the basic lens *)
let lns = ( record | Util.empty | Util.comment )*
let filter = incl "/etc/apt-cacher-ng/security.conf"
. Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,151 @@
(*
Module: AptConf
Parses /etc/apt/apt.conf and /etc/apt/apt.conf.d/*
Author: Raphael Pinson <raphink@gmail.com>
About: Reference
This lens tries to keep as close as possible to `man 5 apt.conf`
where possible.
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/apt/apt.conf and /etc/apt/apt.conf.d/*.
See <filter>.
*)
module AptConf =
autoload xfm
(************************************************************************
* Group: USEFUL PRIMITIVES
*************************************************************************)
(* View: eol
And <Util.eol> end of line *)
let eol = Util.eol
(* View: empty
A C-style empty line *)
let empty = Util.empty_any
(* View: indent
An indentation *)
let indent = Util.indent
(* View: comment_simple
A one-line comment, C-style *)
let comment_simple = Util.comment_c_style_or_hash
(* View: comment_multi
A multiline comment, C-style *)
let comment_multi = Util.comment_multiline
(* View: comment
A comment, either <comment_simple> or <comment_multi> *)
let comment = comment_simple | comment_multi
(************************************************************************
* Group: ENTRIES
*************************************************************************)
(* View: name_re
Regex for entry names *)
let name_re = /[A-Za-z][A-Za-z-]*/
(* View: name_re_colons
Regex for entry names with colons *)
let name_re_colons = /[A-Za-z][A-Za-z:-]*/
(* View: entry
An apt.conf entry, recursive
WARNING:
This lens exploits a put ambiguity
since apt.conf allows for both
APT { Clean-Installed { "true" } }
and APT::Clean-Installed "true";
but we're choosing to map them the same way
The recursive lens doesn't seem
to care and defaults to the first
item in the union.
This is why the APT { Clean-Installed { "true"; } }
form is listed first, since it supports
all subnodes (which Dpkg::Conf) doesn't.
Exchanging these two expressions in the union
makes tests fails since the tree cannot
be mapped back.
This situation results in existing
configuration being modified when the
associated tree is modified. For example,
changing the value of
APT::Clean-Installed "true"; to "false"
results in
APT { Clean-Installed "false"; }
(see unit tests)
*)
let rec entry_noeol =
let value =
Util.del_str "\"" . store /[^"\n]+/
. del /";?/ "\";" in
let opt_eol = del /[ \t\n]*/ "\n" in
let long_eol = del /[ \t]*\n+/ "\n" in
let list_elem = [ opt_eol . label "@elem" . value ] in
let eol_comment = del /([ \t\n]*\n)?/ "" . comment in
[ key name_re . Sep.space . value ]
| [ key name_re . del /[ \t\n]*\{/ " {" .
( (opt_eol . entry_noeol) |
list_elem |
eol_comment
)* .
del /[ \t\n]*\};?/ "\n};" ]
| [ key name_re . Util.del_str "::" . entry_noeol ]
let entry = indent . entry_noeol . eol
(* View: include
A file inclusion
/!\ The manpage is not clear on the syntax *)
let include =
[ indent . key "#include" . Sep.space
. store Rx.fspath . eol ]
(* View: clear
A list of variables to clear
/!\ The manpage is not clear on the syntax *)
let clear =
let name = [ label "name" . store name_re_colons ] in
[ indent . key "#clear" . Sep.space
. Build.opt_list name Sep.space
. eol ]
(************************************************************************
* Group: LENS AND FILTER
*************************************************************************)
(* View: lns
The apt.conf lens *)
let lns = (empty|comment|entry|include|clear)*
(* View: filter *)
let filter = incl "/etc/apt/apt.conf"
. incl "/etc/apt/apt.conf.d/*"
. Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,69 @@
(*
Module: AptPreferences
Apt/preferences module for Augeas
Author: Raphael Pinson <raphael.pinson@camptocamp.com>
*)
module AptPreferences =
autoload xfm
(************************************************************************
* Group: Entries
************************************************************************)
(* View: colon *)
let colon = del /:[ \t]*/ ": "
(* View: pin_gen
A generic pin
Parameters:
lbl:string - the label *)
let pin_gen (lbl:string) = store lbl
. [ label lbl . Sep.space . store Rx.no_spaces ]
(* View: pin_keys *)
let pin_keys =
let space_in = store /[^, \r\t\n][^,\n]*[^, \r\t\n]|[^, \t\n\r]/
in Build.key_value /[aclnov]/ Sep.equal space_in
(* View: pin_options *)
let pin_options =
let comma = Util.delim ","
in store "release" . Sep.space
. Build.opt_list pin_keys comma
(* View: version_pin *)
let version_pin = pin_gen "version"
(* View: origin_pin *)
let origin_pin = pin_gen "origin"
(* View: pin *)
let pin =
let pin_value = pin_options | version_pin | origin_pin
in Build.key_value_line "Pin" colon pin_value
(* View: entries *)
let entries = Build.key_value_line ("Explanation"|"Package"|"Pin-Priority")
colon (store Rx.space_in)
| pin
| Util.comment
(* View: record *)
let record = [ seq "record" . entries+ ]
(************************************************************************
* Group: Lens
************************************************************************)
(* View: lns *)
let lns = Util.empty* . (Build.opt_list record Util.eol+ . Util.empty*)?
(* View: filter *)
let filter = incl "/etc/apt/preferences"
. incl "/etc/apt/preferences.d/*"
. Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,70 @@
(*
Module: Aptsources
Parsing /etc/apt/sources.list
*)
module Aptsources =
autoload xfm
(************************************************************************
* Group: Utility variables/functions
************************************************************************)
(* View: sep_ws *)
let sep_ws = Sep.space
(* View: eol *)
let eol = Util.del_str "\n"
(* View: comment *)
let comment = Util.comment
(* View: empty *)
let empty = Util.empty
(* View: word *)
let word = /[^][# \n\t]+/
(* View: uri *)
let uri =
let protocol = /[a-z+]+:/
in let path = /\/[^] \t]*/
in let path_brack = /\[[^]]+\]\/?/
in protocol? . path
| protocol . path_brack
(************************************************************************
* Group: Keywords
************************************************************************)
(* View: record *)
let record =
let option_sep = [ label "operation" . store /[+-]/]? . Sep.equal
in let option = Build.key_value /arch|trusted/ option_sep (store Rx.word)
in let options = [ label "options"
. Util.del_str "[" . Sep.opt_space
. Build.opt_list option Sep.space
. Sep.opt_space . Util.del_str "]"
. sep_ws ]
in [ Util.indent . seq "source"
. [ label "type" . store word ] . sep_ws
. options?
. [ label "uri" . store uri ] . sep_ws
. [ label "distribution" . store word ]
. [ label "component" . sep_ws . store word ]*
. del /[ \t]*(#.*)?/ ""
. eol ]
(************************************************************************
* Group: Lens
************************************************************************)
(* View: lns *)
let lns = ( comment | empty | record ) *
(* View: filter *)
let filter = (incl "/etc/apt/sources.list")
. (incl "/etc/apt/sources.list.d/*")
. Util.stdexcl
let xfm = transform lns filter
(* Local Variables: *)
(* mode: caml *)
(* End: *)

View File

@ -0,0 +1,39 @@
(* Authinfo2 module for Augeas *)
(* Author: Nicolas Gif <ngf18490@pm.me> *)
(* Heavily based on DPUT module by Raphael Pinson *)
(* <raphink@gmail.com> *)
(* *)
module Authinfo2 =
autoload xfm
(************************************************************************
* INI File settings
*************************************************************************)
let comment = IniFile.comment IniFile.comment_re "#"
let sep = IniFile.sep IniFile.sep_re ":"
(************************************************************************
* ENTRY
*************************************************************************)
let entry =
IniFile.entry_generic_nocomment (key IniFile.entry_re) sep IniFile.comment_re comment
(************************************************************************
* TITLE & RECORD
*************************************************************************)
let title = IniFile.title IniFile.record_re
let record = IniFile.record title entry
(************************************************************************
* LENS & FILTER
*************************************************************************)
let lns = IniFile.lns record comment
let filter = (incl (Sys.getenv("HOME") . "/.s3ql/authinfo2"))
let xfm = transform lns filter

View File

@ -0,0 +1,72 @@
(*
Module: Authorized_Keys
Parses SSH authorized_keys
Author: Raphael Pinson <raphael.pinson@camptocamp.com>
About: Reference
This lens tries to keep as close as possible to `man 5 authorized_keys` where possible.
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 SSH authorized_keys. See <filter>.
About: Examples
The <Test_Authorized_Keys> file contains various examples and tests.
*)
module Authorized_Keys =
autoload xfm
(* View: option
A key option *)
let option =
let kv_re = "command" | "environment" | "from"
| "permitopen" | "principals" | "tunnel"
in let flag_re = "cert-authority" | "no-agent-forwarding"
| "no-port-forwarding" | "no-pty" | "no-user-rc"
| "no-X11-forwarding"
in let option_value = Util.del_str "\""
. store /((\\\\")?[^\\\n"]*)+/
. Util.del_str "\""
in Build.key_value kv_re Sep.equal option_value
| Build.flag flag_re
(* View: key_options
A list of key <option>s *)
let key_options = [ label "options" . Build.opt_list option Sep.comma ]
(* View: key_type *)
let key_type =
let key_type_re = /ecdsa-sha2-nistp[0-9]+/ | /ssh-[a-z0-9]+/
in [ label "type" . store key_type_re ]
(* View: key_comment *)
let key_comment = [ label "comment" . store Rx.space_in ]
(* View: authorized_key *)
let authorized_key =
[ label "key"
. (key_options . Sep.space)?
. key_type . Sep.space
. store Rx.no_spaces
. (Sep.space . key_comment)?
. Util.eol ]
(* View: lns
The authorized_keys lens
*)
let lns = ( Util.empty | Util.comment | authorized_key)*
(* Variable: filter *)
let filter = incl (Sys.getenv("HOME") . "/.ssh/authorized_keys")
let xfm = transform lns filter

View File

@ -0,0 +1,85 @@
(*
Module: AuthselectPam
Parses /etc/authselect/custom/*/*-auth and
/etc/authselect/custom/*/postlogin files
Author: Heston Snodgrass <heston.snodgrass@puppet.com> based on pam.aug by David Lutterkort <lutter@redhat.com>
About: Reference
This lens tries to keep as close as possible to `man pam.conf` where
possible. This lens supports authselect templating syntax as
can be found in `man authselect-profiles`.
About: Licence
This file is licensed under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
About: Configuration files
This lens also autoloads /etc/authselect/custom/*/*-auth and
/etc/authselect/custom/*/postlogin because these files are PAM template
files on machines that have authselect custom profiles.
*)
module AuthselectPam =
autoload xfm
(* The Pam space does not work for certain parts of the authselect syntax so we need our own whitespace *)
let reg_ws = del /([ \t])/ " "
(* This is close the the same as argument from pam.aug, but curly braces are accounted for *)
let argument = /(\[[^]{}#\n]+\]|[^[{#\n \t\\][^#\n \t\\]*)/
(* The various types of conditional statements that can exist in authselect PAM files *)
let authselect_conditional_type = /(continue if|stop if|include if|exclude if|imply|if)/
(* Basic logical operators supported by authselect templates *)
let authselect_logic_stmt = [ reg_ws . key /(and|or|not)/ ]
(* authselect features inside conditional templates *)
let authselect_feature = [ label "feature" . Quote.do_dquote (store /([a-z0-9-]+)/) ]
(* authselect templates can substitute text if a condition is met. *)
(* The sytax for this is `<conditional>:<what to sub on true>|<what to sub on false>` *)
(* Both result forms are optional *)
let authselect_on_true = [ label "on_true" . Util.del_str ":" . store /([^#{}:|\n\\]+)/ ]
let authselect_on_false = [ label "on_false" . Util.del_str "|" . store /([^#{}:|\n\\]+)/ ]
(* Features in conditionals can be grouped together so that logical operations can be resolved for the entire group *)
let authselect_feature_group = [ label "feature_group" . Util.del_str "(" .
authselect_feature . authselect_logic_stmt .
reg_ws . authselect_feature . (authselect_logic_stmt . reg_ws . authselect_feature)* .
Util.del_str ")" ]
(* Represents a single, full authselect conditional template *)
let authselect_conditional = [ Pam.space .
Util.del_str "{" .
label "authselect_conditional" . store authselect_conditional_type .
authselect_logic_stmt* .
( reg_ws . authselect_feature | reg_ws . authselect_feature_group) .
authselect_on_true? .
authselect_on_false? .
Util.del_str "}" ]
(* Shared with PamConf *)
let record = [ label "optional" . del "-" "-" ]? .
[ label "type" . store Pam.types ] .
Pam.space .
[ label "control" . store Pam.control] .
Pam.space .
[ label "module" . store Pam.word ] .
(authselect_conditional | [ Pam.space . label "argument" . store argument ])* .
Pam.comment_or_eol
let record_svc = [ seq "record" . Pam.indent . record ]
let lns = ( Pam.empty | Pam.comment | Pam.include | record_svc ) *
let filter = incl "/etc/authselect/custom/*/*-auth"
. incl "/etc/authselect/custom/*/postlogin"
. Util.stdexcl
let xfm = transform lns filter
(* Local Variables: *)
(* mode: caml *)
(* End: *)

View File

@ -0,0 +1,125 @@
(*
Module: Automaster
Parses autofs' auto.master files
Author: Dominic Cleal <dcleal@redhat.com>
About: Reference
See auto.master(5)
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/auto.master, auto_master and /etc/auto.master.d/*
files.
About: Examples
The <Test_Automaster> file contains various examples and tests.
*)
module Automaster =
autoload xfm
(************************************************************************
* Group: USEFUL PRIMITIVES
*************************************************************************)
(* View: eol *)
let eol = Util.eol
(* View: empty *)
let empty = Util.empty
(* View: comment *)
let comment = Util.comment
(* View mount *)
let mount = /[^+ \t\n#]+/
(* View: type
yp, file, dir etc but not ldap *)
let type = Rx.word - /ldap/
(* View: format
sun, hesoid *)
let format = Rx.word
(* View: name *)
let name = /[^: \t\n]+/
(* View: host *)
let host = /[^:# \n\t]+/
(* View: dn *)
let dn = /[^:# \n\t]+/
(* An option label can't contain comma, comment, equals, or space *)
let optlabel = /[^,#= \n\t]+/
let spec = /[^,# \n\t][^ \n\t]*/
(* View: optsep *)
let optsep = del /[ \t,]+/ ","
(************************************************************************
* Group: ENTRIES
*************************************************************************)
(* View: map_format *)
let map_format = [ label "format" . store format ]
(* View: map_type *)
let map_type = [ label "type" . store type ]
(* View: map_name *)
let map_name = [ label "map" . store name ]
(* View: map_generic
Used for all except LDAP maps which are parsed further *)
let map_generic = ( map_type . ( Sep.comma . map_format )? . Sep.colon )?
. map_name
(* View: map_ldap_name
Split up host:dc=foo into host/map nodes *)
let map_ldap_name = ( [ label "host" . store host ] . Sep.colon )?
. [ label "map" . store dn ]
(* View: map_ldap *)
let map_ldap = [ label "type" . store "ldap" ]
. ( Sep.comma . map_format )? . Sep.colon
. map_ldap_name
(* View: comma_spc_sep_list
Parses options either for filesystems or autofs *)
let comma_spc_sep_list (l:string) =
let value = [ label "value" . Util.del_str "=" . store Rx.neg1 ] in
let lns = [ label l . store optlabel . value? ] in
Build.opt_list lns optsep
(* View: map_mount
Mountpoint and whitespace, followed by the map info *)
let map_mount = [ seq "map" . store mount . Util.del_ws_tab
. ( map_generic | map_ldap )
. ( Util.del_ws_spc . comma_spc_sep_list "opt" )?
. Util.eol ]
(* map_master
"+" to include more master entries and optional whitespace *)
let map_master = [ seq "map" . store "+" . Util.del_opt_ws ""
. ( map_generic | map_ldap )
. ( Util.del_ws_spc . comma_spc_sep_list "opt" )?
. Util.eol ]
(* View: lns *)
let lns = ( empty | comment | map_mount | map_master ) *
(* Variable: filter *)
let filter = incl "/etc/auto.master"
. incl "/etc/auto_master"
. incl "/etc/auto.master.d/*"
. Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,131 @@
(*
Module: Automounter
Parses automounter file based maps
Author: Dominic Cleal <dcleal@redhat.com>
About: Reference
See autofs(5)
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/auto.*, auto_*, excluding known scripts.
About: Examples
The <Test_Automounter> file contains various examples and tests.
*)
module Automounter =
autoload xfm
(************************************************************************
* Group: USEFUL PRIMITIVES
*************************************************************************)
(* View: eol *)
let eol = Util.eol
(* View: empty *)
let empty = Util.empty
(* View: comment *)
let comment = Util.comment
(* View: path *)
let path = /[^-+#: \t\n][^#: \t\n]*/
(* View: hostname *)
let hostname = /[^-:#\(\), \n\t][^:#\(\), \n\t]*/
(* An option label can't contain comma, comment, equals, or space *)
let optlabel = /[^,#:\(\)= \n\t]+/
let spec = /[^,#:\(\)= \n\t][^ \n\t]*/
(* View: weight *)
let weight = Rx.integer
(* View: map_name *)
let map_name = /[^: \t\n]+/
(* View: entry_multimount_sep
Separator for multimount entries, permits line spanning with "\" *)
let entry_multimount_sep = del /[ \t]+(\\\\[ \t]*\n[ \t]+)?/ " "
(************************************************************************
* Group: ENTRIES
*************************************************************************)
(* View: entry_key
Key for a map entry *)
let entry_mkey = store path
(* View: entry_path
Path component of an entry location *)
let entry_path = [ label "path" . store path ]
(* View: entry_host
Host component with optional weight of an entry location *)
let entry_host = [ label "host" . store hostname
. ( Util.del_str "(" . [ label "weight"
. store weight ] . Util.del_str ")" )? ]
(* View: comma_sep_list
Parses options for filesystems *)
let comma_sep_list (l:string) =
let value = [ label "value" . Util.del_str "=" . store Rx.neg1 ] in
let lns = [ label l . store optlabel . value? ] in
Build.opt_list lns Sep.comma
(* View: entry_options *)
let entry_options = Util.del_str "-" . comma_sep_list "opt" . Util.del_ws_tab
(* View: entry_location
A single location with one or more hosts, and one path *)
let entry_location = ( entry_host . ( Sep.comma . entry_host )* )?
. Sep.colon . entry_path
(* View: entry_locations
Multiple locations (each with one or more hosts), separated by spaces *)
let entry_locations = [ label "location" . counter "location"
. [ seq "location" . entry_location ]
. ( [ Util.del_ws_spc . seq "location" . entry_location ] )* ]
(* View: entry_multimount
Parses one of many mountpoints given for a multimount line *)
let entry_multimount = entry_mkey . Util.del_ws_tab . entry_options? . entry_locations
(* View: entry_multimounts
Parses multiple mountpoints given on an entry line *)
let entry_multimounts = [ label "mount" . counter "mount"
. [ seq "mount" . entry_multimount ]
. ( [ entry_multimount_sep . seq "mount" . entry_multimount ] )* ]
(* View: entry
A single map entry from start to finish, including multi-mounts *)
let entry = [ seq "entry" . entry_mkey . Util.del_ws_tab . entry_options?
. ( entry_locations | entry_multimounts ) . Util.eol ]
(* View: include
An include line starting with a "+" and a map name *)
let include = [ seq "entry" . store "+" . Util.del_opt_ws ""
. [ label "map" . store map_name ] . Util.eol ]
(* View: lns *)
let lns = ( empty | comment | entry | include ) *
(* Variable: filter
Exclude scripts/executable maps from here *)
let filter = incl "/etc/auto.*"
. incl "/etc/auto_*"
. excl "/etc/auto.master"
. excl "/etc/auto_master"
. excl "/etc/auto.net"
. excl "/etc/auto.smb"
. Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,45 @@
(*
Module: Avahi
Avahi module for Augeas
Author: Athir Nuaimi <athir@nuaimi.com>
avahi-daemon.conf is a standard INI File.
*)
module Avahi =
autoload xfm
(************************************************************************
* Group: INI File settings
* avahi-daemon.conf only supports "# as commentary and "=" as separator
*************************************************************************)
(* View: comment *)
let comment = IniFile.comment "#" "#"
(* View: sep *)
let sep = IniFile.sep "=" "="
(************************************************************************
* Group: Entry
*************************************************************************)
(* View: entry *)
let entry = IniFile.indented_entry IniFile.entry_re sep comment
(************************************************************************
* Group: Record
*************************************************************************)
(* View: title *)
let title = IniFile.indented_title IniFile.record_re
(* View: record *)
let record = IniFile.record title entry
(************************************************************************
* Group: Lens and filter
*************************************************************************)
(* View: lns *)
let lns = IniFile.lns record comment
(* View: filter *)
let filter = (incl "/etc/avahi/avahi-daemon.conf")
let xfm = transform lns filter

View File

@ -0,0 +1,40 @@
(*
Module: BackupPCHosts
Parses /etc/backuppc/hosts
About: Reference
This lens tries to keep as close as possible to `man backuppc` where possible.
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/backuppc/hosts. See <filter>.
*)
module BackupPCHosts =
autoload xfm
(* View: word *)
let word = /[^#, \n\t\/]+/
(* View: record *)
let record =
let moreusers = Build.opt_list [ label "moreusers" . store word ] Sep.comma in
[ seq "host"
. [ label "host" . store word ] . Util.del_ws_tab
. [ label "dhcp" . store word ] . Util.del_ws_tab
. [ label "user" . store word ]
. (Util.del_ws_tab . moreusers)?
. (Util.comment|Util.eol) ]
(* View: lns *)
let lns = ( Util.empty | Util.comment | record ) *
(* View: filter *)
let filter = incl "/etc/backuppc/hosts"
let xfm = transform lns filter

View File

@ -0,0 +1,130 @@
(* BB-hosts module for Augeas *)
(* Author: Raphael Pinson <raphink@gmail.com> *)
(* *)
(* Supported : *)
(* *)
(* Todo : *)
(* *)
module BBhosts =
autoload xfm
(* Define useful shortcuts *)
let eol = Util.eol
let eol_no_spc = Util.del_str "\n"
let sep_spc = Sep.space
let sep_opt_spc = Sep.opt_space
let word = store /[^|;# \n\t]+/
let value_to_eol = store /[^ \t][^\n]+/
let ip = store Rx.ipv4
let url = store /https?:[^# \n\t]+/
let word_cont = store /[^;# \n\t]+/
(* Define comments and empty lines *)
let comment = Util.comment
let empty = Util.empty
(* Define host *)
let host_ip = [ label "ip" . ip ]
let host_fqdn = [ label "fqdn" . sep_spc . word ]
let host_test_url = [ label "url" . url ]
let host_test_cont (kw:string) = [ store /!?/ . key kw .
(Util.del_str ";" .
[ label "url" . word_cont ] .
(Util.del_str ";" . [ label "keyword" . word ])?
)?
]
(* DOWNTIME=[columns:]day:starttime:endtime:cause[,day:starttime:endtime:cause] *)
let host_test_downtime =
let probe = [ label "probe" . store (Rx.word | "*") ]
in let probes = Build.opt_list probe Sep.comma
in let day = [ label "day" . store (Rx.word | "*") ]
in let starttime = [ label "starttime" . store Rx.integer ]
in let endtime = [ label "endtime" . store Rx.integer ]
in let cause = [ label "cause" . Util.del_str "\"" . store /[^"]*/ . Util.del_str "\"" ]
in [ key "DOWNTIME" . Sep.equal
. (probes . Sep.colon)?
. day . Sep.colon
. starttime . Sep.colon
. endtime . Sep.colon
. cause
]
let host_test_flag_value = [ label "value" . Util.del_str ":"
. store Rx.word ]
let host_test_flag (kw:regexp) = [ store /!?/ . key kw
. host_test_flag_value? ]
let host_test = host_test_cont "cont"
| host_test_cont "contInsecure"
| host_test_cont "dns"
| host_test_flag "BBDISPLAY"
| host_test_flag "BBNET"
| host_test_flag "BBPAGER"
| host_test_flag "CDB"
| host_test_flag "GTM"
| host_test_flag "XYMON"
| host_test_flag "ajp13"
| host_test_flag "bbd"
| host_test_flag "clamd"
| host_test_flag "cupsd"
| host_test_flag "front"
| host_test_flag /ftps?/
| host_test_flag /imap[2-4s]?/
| host_test_flag /ldaps?/
| host_test_flag /nntps?/
| host_test_flag "noconn"
| host_test_flag "nocont"
| host_test_flag "noping"
| host_test_flag "notrends"
| host_test_flag "oratns"
| host_test_flag /pop-?[2-3]?s?/
| host_test_flag "qmqp"
| host_test_flag "qmtp"
| host_test_flag "rsync"
| host_test_flag /smtps?/
| host_test_flag "spamd"
| host_test_flag /ssh[1-2]?/
| host_test_flag /telnets?/
| host_test_flag "vnc"
| host_test_url
| host_test_downtime
let host_test_list = Build.opt_list host_test sep_spc
let host_opts = [ label "probes" . sep_spc . Util.del_str "#" . (sep_opt_spc . host_test_list)? ]
let host = [ label "host" . host_ip . host_fqdn . host_opts . eol ]
(* Define group-compress and group-only *)
let group_compress = [ key /group(-compress)?/ . (sep_spc . value_to_eol)? . eol_no_spc .
( comment | empty | host)*
]
let group_only_col = [ label "col" . word ]
let group_only_cols = sep_spc . group_only_col . ( Util.del_str "|" . group_only_col )*
let group_only = [ key "group-only" . group_only_cols . sep_spc . value_to_eol . eol_no_spc .
( comment | empty | host)*
]
(* Define page *)
let page_title = [ label "title" . sep_spc . value_to_eol ]
let page = [ key "page" . sep_spc . word . page_title? . eol_no_spc .
( comment | empty | host )* . ( group_compress | group_only )*
]
(* Define lens *)
let lns = (comment | empty)* . page*
let filter = incl "/etc/bb/bb-hosts"
let xfm = transform lns filter

View File

@ -0,0 +1,130 @@
(*
Module: BootConf
Parses (Open)BSD-stype /etc/boot.conf
Author: Jasper Lievisse Adriaanse <jasper@jasper.la>
About: Reference
This lens is used to parse the second-stage bootstrap configuration
file, /etc/boot.conf as found on OpenBSD. The format is largely MI,
with MD parts included:
http://www.openbsd.org/cgi-bin/man.cgi?query=boot.conf&arch=i386
About: Usage Example
To be documented
About: License
This file is licensed under the LGPL v2+, like the rest of Augeas.
About: Configuration files
This lens applies to /etc/boot.conf.
See <filter>.
*)
module BootConf =
autoload xfm
(************************************************************************
* Utility variables/functions
************************************************************************)
(* View: comment *)
let comment = Util.comment
(* View: empty *)
let empty = Util.empty
(* View: eol *)
let eol = Util.eol
(* View: fspath *)
let fspath = Rx.fspath
(* View: space *)
let space = Sep.space
(* View: word *)
let word = Rx.word
(************************************************************************
* View: key_opt_value_line
* A subnode with a keyword, an optional part consisting of a separator
* and a storing lens, and an end of line
*
* Parameters:
* kw:regexp - the pattern to match as key
* sto:lens - the storing lens
************************************************************************)
let key_opt_value_line (kw:regexp) (sto:lens) =
[ key kw . (space . sto)? . eol ]
(************************************************************************
* Commands
************************************************************************)
(* View: single_command
single command such as 'help' or 'time' *)
let single_command =
let line_re = /help|time|reboot/
in [ Util.indent . key line_re . eol ]
(* View: ls
ls [directory] *)
let ls = Build.key_value_line
"ls" space (store fspath)
let set_cmd = "addr"
| "debug"
| "device"
| "howto"
| "image"
| "timeout"
| "tty"
(* View: set
set [varname [value]] *)
let set = Build.key_value
"set" space
(key_opt_value_line set_cmd (store Rx.space_in))
(* View: stty
stty [device [speed]] *)
let stty =
let device = [ label "device" . store fspath ]
in let speed = [ label "speed" . store Rx.integer ]
in key_opt_value_line "stty" (device . (space . speed)?)
(* View: echo
echo [args] *)
let echo = Build.key_value_line
"echo" space (store word)
(* View: boot
boot [image [-acds]]
XXX: the last arguments are not always needed, so make them optional *)
let boot =
let image = [ label "image" . store fspath ]
in let arg = [ label "arg" . store word ]
in Build.key_value_line "boot" space (image . space . arg)
(* View: machine
machine [command] *)
let machine =
let machine_entry = Build.key_value ("comaddr"|"memory")
space (store word)
| Build.flag ("diskinfo"|"regs")
in Build.key_value_line
"machine" space
(Build.opt_list
machine_entry
space)
(************************************************************************
* Lens
************************************************************************)
(* View: command *)
let command = boot | echo | ls | machine | set | stty
(* View: lns *)
let lns = ( empty | comment | command | single_command )*
(* Variable: filter *)
let filter = (incl "/etc/boot.conf")
let xfm = transform lns filter

View File

@ -0,0 +1,420 @@
(*
Module: Build
Generic functions to build lenses
Author: Raphael Pinson <raphink@gmail.com>
About: License
This file is licensed under the LGPL v2+, like the rest of Augeas.
About: Reference
This file provides generic functions to build Augeas lenses
*)
module Build =
let eol = Util.eol
(************************************************************************
* Group: GENERIC CONSTRUCTIONS
************************************************************************)
(************************************************************************
* View: brackets
* Put a lens inside brackets
*
* Parameters:
* l:lens - the left bracket lens
* r: lens - the right bracket lens
* lns:lens - the lens to put inside brackets
************************************************************************)
let brackets (l:lens) (r:lens) (lns:lens) = l . lns . r
(************************************************************************
* Group: LIST CONSTRUCTIONS
************************************************************************)
(************************************************************************
* View: list
* Build a list of identical lenses separated with a given separator
* (at least 2 elements)
*
* Parameters:
* lns:lens - the lens to repeat in the list
* sep:lens - the separator lens, which can be taken from the <Sep> module
************************************************************************)
let list (lns:lens) (sep:lens) = lns . ( sep . lns )+
(************************************************************************
* View: opt_list
* Same as <list>, but there might be only one element in the list
*
* Parameters:
* lns:lens - the lens to repeat in the list
* sep:lens - the separator lens, which can be taken from the <Sep> module
************************************************************************)
let opt_list (lns:lens) (sep:lens) = lns . ( sep . lns )*
(************************************************************************
* Group: LABEL OPERATIONS
************************************************************************)
(************************************************************************
* View: xchg
* Replace a pattern with a different label in the tree,
* thus emulating a key but allowing to replace the keyword
* with a different value than matched
*
* Parameters:
* m:regexp - the pattern to match
* d:string - the default value when a node in created
* l:string - the label to apply for such nodes
************************************************************************)
let xchg (m:regexp) (d:string) (l:string) = del m d . label l
(************************************************************************
* View: xchgs
* Same as <xchg>, but the pattern is the default string
*
* Parameters:
* m:string - the string to replace, also used as default
* l:string - the label to apply for such nodes
************************************************************************)
let xchgs (m:string) (l:string) = xchg m m l
(************************************************************************
* Group: SUBNODE CONSTRUCTIONS
************************************************************************)
(************************************************************************
* View: key_value_line
* A subnode with a keyword, a separator and a storing lens,
* and an end of line
*
* Parameters:
* kw:regexp - the pattern to match as key
* sep:lens - the separator lens, which can be taken from the <Sep> module
* sto:lens - the storing lens
************************************************************************)
let key_value_line (kw:regexp) (sep:lens) (sto:lens) =
[ key kw . sep . sto . eol ]
(************************************************************************
* View: key_value_line_comment
* Same as <key_value_line>, but allows to have a comment in the end of a line
* and an end of line
*
* Parameters:
* kw:regexp - the pattern to match as key
* sep:lens - the separator lens, which can be taken from the <Sep> module
* sto:lens - the storing lens
* comment:lens - the comment lens, which can be taken from <Util>
************************************************************************)
let key_value_line_comment (kw:regexp) (sep:lens) (sto:lens) (comment:lens) =
[ key kw . sep . sto . (eol|comment) ]
(************************************************************************
* View: key_value
* Same as <key_value_line>, but does not end with an end of line
*
* Parameters:
* kw:regexp - the pattern to match as key
* sep:lens - the separator lens, which can be taken from the <Sep> module
* sto:lens - the storing lens
************************************************************************)
let key_value (kw: regexp) (sep:lens) (sto:lens) =
[ key kw . sep . sto ]
(************************************************************************
* View: key_ws_value
*
* Store a key/value pair where key and value are separated by whitespace
* and the value goes to the end of the line. Leading and trailing
* whitespace is stripped from the value. The end of line is consumed by
* this lens
*
* Parameters:
* kw:regexp - the pattern to match as key
************************************************************************)
let key_ws_value (kw:regexp) =
key_value_line kw Util.del_ws_spc (store Rx.space_in)
(************************************************************************
* View: flag
* A simple flag subnode, consisting of a single key
*
* Parameters:
* kw:regexp - the pattern to match as key
************************************************************************)
let flag (kw:regexp) = [ key kw ]
(************************************************************************
* View: flag_line
* A simple flag line, consisting of a single key
*
* Parameters:
* kw:regexp - the pattern to match as key
************************************************************************)
let flag_line (kw:regexp) = [ key kw . eol ]
(************************************************************************
* Group: BLOCK CONSTRUCTIONS
************************************************************************)
(************************************************************************
* View: block_generic
* A block enclosed in brackets
*
* Parameters:
* entry:lens - the entry to be stored inside the block.
* This entry should include <Util.empty>
* or its equivalent if necessary.
* entry_noindent:lens - the entry to be stored inside the block,
* without indentation.
* This entry should not include <Util.empty>
* entry_noeol:lens - the entry to be stored inside the block,
* without eol.
* This entry should not include <Util.empty>
* entry_noindent_noeol:lens - the entry to be stored inside the block,
* without indentation or eol.
* This entry should not include <Util.empty>
* comment:lens - the comment lens used in the block
* comment_noindent:lens - the comment lens used in the block,
* without indentation.
* ldelim_re:regexp - regexp for the left delimiter
* rdelim_re:regexp - regexp for the right delimiter
* ldelim_default:string - default value for the left delimiter
* rdelim_default:string - default value for the right delimiter
************************************************************************)
let block_generic
(entry:lens) (entry_noindent:lens)
(entry_noeol:lens) (entry_noindent_noeol:lens)
(comment:lens) (comment_noindent:lens)
(ldelim_re:regexp) (rdelim_re:regexp)
(ldelim_default:string) (rdelim_default:string) =
let block_single = entry_noindent_noeol | comment_noindent
in let block_start = entry_noindent | comment_noindent
in let block_middle = (entry | comment)*
in let block_end = entry_noeol | comment
in del ldelim_re ldelim_default
. ( ( block_start . block_middle . block_end )
| block_single )
. del rdelim_re rdelim_default
(************************************************************************
* View: block_setdefault
* A block enclosed in brackets
*
* Parameters:
* entry:lens - the entry to be stored inside the block.
* This entry should not include <Util.empty>,
* <Util.comment> or <Util.comment_noindent>,
* should not be indented or finish with an eol.
* ldelim_re:regexp - regexp for the left delimiter
* rdelim_re:regexp - regexp for the left delimiter
* ldelim_default:string - default value for the left delimiter
* rdelim_default:string - default value for the right delimiter
************************************************************************)
let block_setdelim (entry:lens)
(ldelim_re:regexp)
(rdelim_re:regexp)
(ldelim_default:string)
(rdelim_default:string) =
block_generic (Util.empty | Util.indent . entry . eol)
(entry . eol) (Util.indent . entry) entry
Util.comment Util.comment_noindent
ldelim_re rdelim_re
ldelim_default rdelim_default
(* Variable: block_ldelim_re *)
let block_ldelim_re = /[ \t\n]+\{[ \t\n]*/
(* Variable: block_rdelim_re *)
let block_rdelim_re = /[ \t\n]*\}/
(* Variable: block_ldelim_default *)
let block_ldelim_default = " {\n"
(* Variable: block_rdelim_default *)
let block_rdelim_default = "}"
(************************************************************************
* View: block
* A block enclosed in brackets
*
* Parameters:
* entry:lens - the entry to be stored inside the block.
* This entry should not include <Util.empty>,
* <Util.comment> or <Util.comment_noindent>,
* should not be indented or finish with an eol.
************************************************************************)
let block (entry:lens) = block_setdelim entry
block_ldelim_re block_rdelim_re
block_ldelim_default block_rdelim_default
(* Variable: block_ldelim_newlines_re *)
let block_ldelim_newlines_re = /[ \t\n]*\{([ \t\n]*\n)?/
(* Variable: block_rdelim_newlines_re *)
let block_rdelim_newlines_re = /[ \t]*\}/
(* Variable: block_ldelim_newlines_default *)
let block_ldelim_newlines_default = "\n{\n"
(* Variable: block_rdelim_newlines_default *)
let block_rdelim_newlines_default = "}"
(************************************************************************
* View: block_newline
* A block enclosed in brackets, with newlines forced
* and indentation defaulting to a tab.
*
* Parameters:
* entry:lens - the entry to be stored inside the block.
* This entry should not include <Util.empty>,
* <Util.comment> or <Util.comment_noindent>,
* should be indented and finish with an eol.
************************************************************************)
let block_newlines (entry:lens) (comment:lens) =
del block_ldelim_newlines_re block_ldelim_newlines_default
. ((entry | comment) . (Util.empty | entry | comment)*)?
. del block_rdelim_newlines_re block_rdelim_newlines_default
(************************************************************************
* View: block_newlines_spc
* A block enclosed in brackets, with newlines forced
* and indentation defaulting to a tab. The opening brace
* must be preceded by whitespace
*
* Parameters:
* entry:lens - the entry to be stored inside the block.
* This entry should not include <Util.empty>,
* <Util.comment> or <Util.comment_noindent>,
* should be indented and finish with an eol.
************************************************************************)
let block_newlines_spc (entry:lens) (comment:lens) =
del (/[ \t\n]/ . block_ldelim_newlines_re) block_ldelim_newlines_default
. ((entry | comment) . (Util.empty | entry | comment)*)?
. del block_rdelim_newlines_re block_rdelim_newlines_default
(************************************************************************
* View: named_block
* A named <block> enclosed in brackets
*
* Parameters:
* kw:regexp - the regexp for the block name
* entry:lens - the entry to be stored inside the block
* this entry should not include <Util.empty>
************************************************************************)
let named_block (kw:regexp) (entry:lens) = [ key kw . block entry . eol ]
(************************************************************************
* Group: COMBINATORICS
************************************************************************)
(************************************************************************
* View: combine_two_ord
* Combine two lenses, ensuring first lens is first
*
* Parameters:
* a:lens - the first lens
* b:lens - the second lens
************************************************************************)
let combine_two_ord (a:lens) (b:lens) = a . b
(************************************************************************
* View: combine_two
* Combine two lenses
*
* Parameters:
* a:lens - the first lens
* b:lens - the second lens
************************************************************************)
let combine_two (a:lens) (b:lens) =
combine_two_ord a b | combine_two_ord b a
(************************************************************************
* View: combine_two_opt_ord
* Combine two lenses optionally, ensuring first lens is first
* (a, and optionally b)
*
* Parameters:
* a:lens - the first lens
* b:lens - the second lens
************************************************************************)
let combine_two_opt_ord (a:lens) (b:lens) = a . b?
(************************************************************************
* View: combine_two_opt
* Combine two lenses optionally
* (either a, b, or both, in any order)
*
* Parameters:
* a:lens - the first lens
* b:lens - the second lens
************************************************************************)
let combine_two_opt (a:lens) (b:lens) =
combine_two_opt_ord a b | combine_two_opt_ord b a
(************************************************************************
* View: combine_three_ord
* Combine three lenses, ensuring first lens is first
* (a followed by either b, c, in any order)
*
* Parameters:
* a:lens - the first lens
* b:lens - the second lens
* c:lens - the third lens
************************************************************************)
let combine_three_ord (a:lens) (b:lens) (c:lens) =
combine_two_ord a (combine_two b c)
(************************************************************************
* View: combine_three
* Combine three lenses
*
* Parameters:
* a:lens - the first lens
* b:lens - the second lens
* c:lens - the third lens
************************************************************************)
let combine_three (a:lens) (b:lens) (c:lens) =
combine_three_ord a b c
| combine_three_ord b a c
| combine_three_ord c b a
(************************************************************************
* View: combine_three_opt_ord
* Combine three lenses optionally, ensuring first lens is first
* (a followed by either b, c, or any of them, in any order)
*
* Parameters:
* a:lens - the first lens
* b:lens - the second lens
* c:lens - the third lens
************************************************************************)
let combine_three_opt_ord (a:lens) (b:lens) (c:lens) =
combine_two_opt_ord a (combine_two_opt b c)
(************************************************************************
* View: combine_three_opt
* Combine three lenses optionally
* (either a, b, c, or any of them, in any order)
*
* Parameters:
* a:lens - the first lens
* b:lens - the second lens
* c:lens - the third lens
************************************************************************)
let combine_three_opt (a:lens) (b:lens) (c:lens) =
combine_three_opt_ord a b c
| combine_three_opt_ord b a c
| combine_three_opt_ord c b a

View File

@ -0,0 +1,89 @@
(*
Module: Cachefilesd
Parses /etc/cachefilesd.conf
Author: Pat Riehecky <riehecky@fnal.gov>
About: Reference
This lens tries to keep as close as possible to `man 5 cachefilesd.conf` where possible.
About: License
This file is licenced under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
See <lns>.
About: Configuration files
This lens applies to /etc/cachefilesd.conf.
About: Examples
The <Test_Cachefilesd> file contains various examples and tests.
*)
module Cachefilesd =
autoload xfm
(************************************************************************
* Group: USEFUL PRIMITIVES
*************************************************************************)
(* Group: Comments and empty lines *)
(* View: eol *)
let eol = Util.eol
(* View: comment *)
let comment = Util.comment
(* View: empty *)
let empty = Util.empty
(* Group: separators *)
(* View: space
* Separation between key and value
*)
let space = Util.del_ws_spc
(* View: colon
* Separation between selinux attributes
*)
let colon = Sep.colon
(* Group: entries *)
(* View: entry_key
* The key for an entry in the config file
*)
let entry_key = Rx.word
(* View: entry_value
* The value for an entry may contain all sorts of things
*)
let entry_value = /[A-Za-z0-9_.-:%]+/
(* View: nocull
* The nocull key has different syntax than the rest
*)
let nocull = /nocull/i
(* Group: config *)
(* View: cacheconfig
* This is a simple "key value" setup
*)
let cacheconfig = [ key (entry_key - nocull) . space
. store entry_value . eol ]
(* View: nocull
* This is a either present, and therefore active or missing and
* not active
*)
let nocull_entry = [ key nocull . eol ]
(* View: lns *)
let lns = (empty | comment | cacheconfig | nocull_entry)*
let xfm = transform lns (incl "/etc/cachefilesd.conf")
(* Local Variables: *)
(* mode: caml *)
(* End: *)

View File

@ -0,0 +1,54 @@
(*
Module: Carbon
Parses Carbon's configuration files
Author: Marc Fournier <marc.fournier@camptocamp.com>
About: Reference
This lens is based on the conf/*.conf.example files from the Carbon
package.
About: Configuration files
This lens applies to most files in /etc/carbon/. See <filter>.
NB: whitelist.conf and blacklist.conf use a different syntax. This lens
doesn't support them.
About: Usage Example
(start code)
$ augtool
augtool> ls /files/etc/carbon/carbon.conf/
cache/ = (none)
relay/ = (none)
aggregator/ = (none)
augtool> get /files/etc/carbon/carbon.conf/cache/ENABLE_UDP_LISTENER
/files/etc/carbon/carbon.conf/cache/ENABLE_UDP_LISTENER = False
augtool> set /files/etc/carbon/carbon.conf/cache/ENABLE_UDP_LISTENER True
augtool> save
Saved 1 file(s)
(end code)
The <Test_Carbon> file also contains various examples.
About: License
This file is licensed under the LGPL v2+, like the rest of Augeas.
*)
module Carbon =
autoload xfm
let comment = IniFile.comment "#" "#"
let sep = IniFile.sep "=" "="
let entry = IniFile.entry IniFile.entry_re sep comment
let title = IniFile.title IniFile.record_re
let record = IniFile.record title entry
let lns = IniFile.lns record comment
let filter = incl "/etc/carbon/carbon.conf"
. incl "/etc/carbon/relay-rules.conf"
. incl "/etc/carbon/rewrite-rules.conf"
. incl "/etc/carbon/storage-aggregation.conf"
. incl "/etc/carbon/storage-schemas.conf"
let xfm = transform lns filter

View File

@ -0,0 +1,26 @@
(* Ceph module for Augeas
Author: Pavel Chechetin <pchechetin@mirantis.com>
ceph.conf is a standard INI File with whitespaces in the title.
*)
module Ceph =
autoload xfm
let comment = IniFile.comment IniFile.comment_re IniFile.comment_default
let sep = IniFile.sep IniFile.sep_re IniFile.sep_default
let entry_re = /[A-Za-z0-9_.-][A-Za-z0-9 _.-]*[A-Za-z0-9_.-]/
let entry = IniFile.indented_entry entry_re sep comment
let title = IniFile.indented_title IniFile.record_re
let record = IniFile.record title entry
let lns = IniFile.lns record comment
let filter = (incl "/etc/ceph/ceph.conf")
. (incl (Sys.getenv("HOME") . "/.ceph/config"))
let xfm = transform lns filter

View File

@ -0,0 +1,120 @@
(*
Module: cgconfig
Parses /etc/cgconfig.conf
Author:
Ivana Hutarova Varekova <varekova@redhat.com>
Raphael Pinson <raphink@gmail.com>
About: Licence
This file is licensed under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
Sample usage of this lens in augtool
* print all mounted cgroups
print /files/etc/cgconfig.conf/mount
About: Configuration files
This lens applies to /etc/cgconfig.conf. See <filter>.
*)
module Cgconfig =
autoload xfm
let indent = Util.indent
let eol = Util.eol
let comment = Util.comment
let empty = Util.empty
let id = /[a-zA-Z0-9_\/.-]+/
let name = /[^#= \n\t{}\/]+/
let cont_name = /(cpuacct|cpu|devices|ns|cpuset|memory|freezer|net_cls|blkio|hugetlb|perf_event)/
let role_name = /(admin|task)/
let id_name = /(uid|gid|fperm|dperm)/
let address = /[^#; \n\t{}]+/
let qaddress = address|/"[^#;"\n\t{}]+"/
let lbracket = del /[ \t\n]*\{/ " {"
let rbracket = del /[ \t]*\}/ "}"
let eq = indent . Util.del_str "=" . indent
(******************************************
* Function to deal with abc=def; entries
******************************************)
let key_value (key_rx:regexp) (val_rx:regexp) =
[ indent . key key_rx . eq . store val_rx
. indent . Util.del_str ";" ]
(* Function to deal with bracketted entries *)
let brack_entry_base (lnsa:lens) (lnsb:lens) =
[ indent . lnsa . lbracket . lnsb . rbracket ]
let brack_entry_key (kw:regexp) (lns:lens) =
let lnsa = key kw in
brack_entry_base lnsa lns
let brack_entry (kw:regexp) (lns:lens) =
let full_lns = (lns | comment | empty)* in
brack_entry_key kw full_lns
(******************************************
* control groups
******************************************)
let permission_setting = key_value id_name address
(* task setting *)
let t_info = brack_entry "task" permission_setting
(* admin setting *)
let a_info = brack_entry "admin" permission_setting
(* permissions setting *)
let perm_info =
let ce = (comment|empty)* in
let perm_info_lns = ce .
((t_info . ce . (a_info . ce)?)
|(a_info . ce . (t_info . ce)?))? in
brack_entry_key "perm" perm_info_lns
let variable_setting = key_value name qaddress
(* controllers setting *)
let controller_info =
let lnsa = label "controller" . store cont_name in
let lnsb = ( variable_setting | comment | empty ) * in
brack_entry_base lnsa lnsb
(* group { ... } *)
let group_data =
let lnsa = key "group" . Util.del_ws_spc . store id in
let lnsb = ( perm_info | controller_info | comment | empty )* in
brack_entry_base lnsa lnsb
(*************************************************
* mount point
*************************************************)
(* controller = mount_point; *)
let mount_point = key_value name address
(* mount { .... } *)
let mount_data = brack_entry "mount" mount_point
(****************************************************
* namespace
****************************************************)
(* controller = cgroup; *)
let namespace_instance = key_value name address
(* namespace { .... } *)
let namespace = brack_entry "namespace" namespace_instance
let lns = ( comment | empty | mount_data | group_data | namespace )*
let xfm = transform lns (incl "/etc/cgconfig.conf")

View File

@ -0,0 +1,85 @@
(*
Module: cgrules
Parses /etc/cgrules.conf
Author:
Raphael Pinson <raphink@gmail.com>
Ivana Hutarova Varekova <varekova@redhat.com>
About: Licence
This file is licensed under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
Sample usage of this lens in augtool:
About: Configuration files
This lens applies to /etc/cgconfig.conf. See <filter>.
*)
module Cgrules =
autoload xfm
(************************************************************************
* Group: USEFUL PRIMITIVES
*************************************************************************)
(* Group: Separators *)
(* Variable: ws *)
let ws = del /[ \t]+/ " "
(* Group: Comments and empty lines *)
(* Variable: eol *)
let eol = Util.eol
(* Variable: comment *)
let comment = Util.comment
(* Variable: empty *)
let empty = Util.empty
(* Group: Generic primitive definitions *)
(* Variable: name *)
let name = /[^@%# \t\n][^ \t\n]*/
(* Variable: ctrl_key *)
let ctrl_key = /[^ \t\n\/]+/
(* Variable: ctrl_value *)
let ctrl_value = /[^ \t\n]+/
(************************************************************************
* Group: CONTROLLER
*************************************************************************)
(* Variable: controller *)
let controller = ws . [ key ctrl_key . ws . store ctrl_value ]
let more_controller = Util.del_str "%" . controller . eol
(************************************************************************
* Group: RECORDS
*************************************************************************)
let generic_record (lbl:string) (lns:lens) =
[ label lbl . lns
. controller . eol
. more_controller* ]
(* Variable: user_record *)
let user_record = generic_record "user" (store name)
(* Variable: group_record *)
let group_record = generic_record "group" (Util.del_str "@" . store name)
(************************************************************************
* Group: LENS & FILTER
*************************************************************************)
(* View: lns
The main lens, any amount of
* <empty> lines
* <comment>
* <user_record>
* <group_record>
*)
let lns = ( empty | comment | user_record | group_record )*
let xfm = transform lns (incl "/etc/cgrules.conf")

View File

@ -0,0 +1,155 @@
(*
Module: Channels
Parses channels.conf files
Author: Raphael Pinson <raphink@gmail.com>
About: Reference
See http://linuxtv.org/vdrwiki/index.php/Syntax_of_channels.conf
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 channels.conf files.
About: Examples
The <Test_Channels> file contains various examples and tests.
*)
module Channels =
(************************************************************************
* Group: USEFUL PRIMITIVES
*************************************************************************)
(* View: eol *)
let eol = Util.eol
(* View: comment *)
let comment = Util.comment_generic /;[ \t]*/ "; "
(* View: equal *)
let equal = Sep.equal
(* View: colon *)
let colon = Sep.colon
(* View: comma *)
let comma = Sep.comma
(* View: semicol *)
let semicol = Util.del_str ";"
(* View: plus *)
let plus = Util.del_str "+"
(* View: arroba *)
let arroba = Util.del_str "@"
(* View: no_colon *)
let no_colon = /[^: \t\n][^:\n]*[^: \t\n]|[^:\n]/
(* View: no_semicolon *)
let no_semicolon = /[^;\n]+/
(************************************************************************
* Group: FUNCTIONS
*************************************************************************)
(* View: field
A generic field *)
let field (name:string) (sto:regexp) = [ label name . store sto ]
(* View: field_no_colon
A <field> storing <no_colon> *)
let field_no_colon (name:string) = field name no_colon
(* View: field_int
A <field> storing <Rx.integer> *)
let field_int (name:string) = field name Rx.integer
(* View: field_word
A <field> storing <Rx.word> *)
let field_word (name:string) = field name Rx.word
(************************************************************************
* Group: ENTRIES
*************************************************************************)
(* View: vpid *)
let vpid =
let codec =
[ equal . label "codec" . store Rx.integer ]
in let vpid_entry (lbl:string) =
[ label lbl . store Rx.integer . codec? ]
in vpid_entry "vpid"
. ( plus . vpid_entry "vpid_pcr" )?
(* View: langs *)
let langs =
let lang =
[ label "lang" . store Rx.word ]
in Build.opt_list lang plus
(* View: apid *)
let apid =
let codec =
[ arroba . label "codec" . store Rx.integer ]
in let options =
equal . ( (langs . codec?) | codec )
in let apid_entry (lbl:string) =
[ label lbl . store Rx.integer . options? ]
in Build.opt_list (apid_entry "apid") comma
. ( semicol
. Build.opt_list (apid_entry "apid_dolby") comma )?
(* View: tpid *)
let tpid =
let tpid_bylang =
[ label "tpid_bylang" . store Rx.integer
. (equal . langs)? ]
in field_int "tpid"
. ( semicol . Build.opt_list tpid_bylang comma )?
(* View: caid *)
let caid =
let caid_entry =
[ label "caid" . store Rx.word ]
in Build.opt_list caid_entry comma
(* View: entry *)
let entry = [ label "entry" . store no_semicolon
. (semicol . field_no_colon "provider")? . colon
. field_int "frequency" . colon
. field_word "parameter" . colon
. field_word "signal_source" . colon
. field_int "symbol_rate" . colon
. vpid . colon
. apid . colon
. tpid . colon
. caid . colon
. field_int "sid" . colon
. field_int "nid" . colon
. field_int "tid" . colon
. field_int "rid" . eol ]
(* View: entry_or_comment *)
let entry_or_comment = entry | comment
(* View: group *)
let group =
[ Util.del_str ":" . label "group"
. store no_colon . eol
. entry_or_comment* ]
(* View: lns *)
let lns = entry_or_comment* . group*

View File

@ -0,0 +1,408 @@
(*
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: 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.relinteger
(* Variable: decimal *)
let decimal = Rx.reldecimal
(* Variable: ip *)
let ip = Rx.ip
(* Variable: path *)
let path = Rx.fspath
(************************************************************************
* Group: Create required expressions
************************************************************************)
(* Variable: number *)
let number = integer | decimal | decimal . /[eE]/ . integer
(* 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/Pool options with values
*)
let cmd_options = "asymmetry"
| "filter"
| "key"
| /maxdelay((dev)?ratio)?/
| /(min|max)poll/
| /(min|max)samples/
| "maxsources"
| "mindelay"
| "offset"
| "polltarget"
| "port"
| "presend"
| "version"
(* Variable: cmd_flags
Server/Peer/Pool options without values
*)
let cmd_flags = "auto_offline"|"iburst"|"noselect"|"offline"|"prefer"
|"require"|"trust"|"xleave"|"burst"|"nts"
(* Variable: ntp_source
Server/Peer/Pool key names
*)
let ntp_source = "server"|"peer"|"pool"
(* Variable: allowdeny_types
Key names for access configuration
*)
let allowdeny_types = "allow"|"deny"|"cmdallow"|"cmddeny"
(* Variable: hwtimestamp_options
HW timestamping options with values
*)
let hwtimestamp_options = "minpoll"|"precision"|"rxcomp"|"txcomp"
|"minsamples"|"maxsamples"|"rxfilter"
(* Variable: hwtimestamp_flags
HW timestamping options without values
*)
let hwtimestamp_flags = "nocrossts"
(* Variable: local_options
local options with values
*)
let local_options = "stratum"|"distance"
(* Variable: local_flags
local options without values
*)
let local_flags = "orphan"
(* Variable: ratelimit_options
Rate limiting options with values
*)
let ratelimit_options = "interval"|"burst"|"leak"
(* Variable: refclock_options
refclock options with values
*)
let refclock_options = "refid"|"lock"|"poll"|"dpoll"|"filter"|"rate"
|"minsamples"|"maxsamples"|"offset"|"delay"
|"precision"|"maxdispersion"|"stratum"|"width"
(* Variable: refclock_flags
refclock options without values
*)
let refclock_flags = "noselect"|"pps"|"prefer"|"require"|"tai"|"trust"
(* Variable: flags
Options without values
*)
let flags = "dumponexit"
| "generatecommandkey"
| "lock_all"
| "manual"
| "noclientlog"
| "nosystemcert"
| "rtconutc"
| "rtcsync"
(* Variable: log_flags
log has a specific options list
*)
let log_flags = "measurements"|"rawmeasurements"|"refclocks"|"rtc"
|"statistics"|"tempcomp"|"tracking"
(* Variable: simple_keys
Options with single values
*)
let simple_keys = "acquisitionport" | "authselectmode" | "bindacqaddress"
| "bindaddress" | "bindcmdaddress" | "bindacqdevice"
| "bindcmddevice" | "binddevice" | "clientloglimit"
| "clockprecision" | "combinelimit" | "commandkey"
| "cmdport" | "corrtimeratio" | "driftfile"
| "dscp"
| "dumpdir" | "hwclockfile" | "include" | "keyfile"
| "leapsecmode" | "leapsectz" | "linux_freq_scale"
| "linux_hz" | "logbanner" | "logchange" | "logdir"
| "maxclockerror" | "maxdistance" | "maxdrift"
| "maxjitter" | "maxsamples" | "maxslewrate"
| "maxntsconnections"
| "maxupdateskew" | "minsamples" | "minsources"
| "nocerttimecheck" | "ntsdumpdir" | "ntsntpserver"
| "ntsport" | "ntsprocesses" | "ntsrefresh" | "ntsrotate"
| "ntsservercert" | "ntsserverkey" | "ntstrustedcerts"
| "ntpsigndsocket" | "pidfile"
| "port" | "reselectdist" | "rtcautotrim" | "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 number ]
(* 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
options without any arguments
*)
let all_flags = [ Util.indent . key flags . eol ]
(* View: kv
options with only one arg can be directly mapped to key = value
*)
let kv = [ Util.indent . key simple_keys . space . (store no_space) . eol ]
(* Property: Options with multiple values
Each of these gets their own parsing block
- server|peer|pool <address> <options>
- allow|deny|cmdallow|cmddeny [all] [<address[/subnet]>]
- log <options>
- broadcast <interval> <address> <optional port>
- fallbackdrift <min> <max>
- hwtimestamp <interface> <options>
- initstepslew <threshold> <addr> <optional extra addrs>
- local <options>
- mailonchange <emailaddress> <threshold>
- makestep <threshold> <limit>
- maxchange <threshold> <delay> <limit>
- ratelimit|cmdratelimit|ntsratelimit <options>
- refclock <driver> <parameter> <options>
- smoothtime <maxfreq> <maxwander> <options>
- tempcomp <sensorfile> <interval> (<t0> <k0> <k1> <k2> | <pointfile> )
- confdir|sourcedir <directories>
*)
(* View: host_list
Find all NTP sources and their flags/options
*)
let host_list = [ Util.indent . key ntp_source
. space . store address_re
. ( host_flags | host_options )*
. eol ]
(* View: allowdeny
allow/deny/cmdallow/cmddeny has a specific syntax
*)
let allowdeny = [ Util.indent . key allowdeny_types
. [ space . key "all" ]?
. ( space . store ( no_space - "all" ) )?
. 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: bcast
confdir and sourcedir have specific syntax
*)
let dir_list = [ Util.indent . key /(conf|source)dir/
. [ label "directory" . space . store no_space ]+
. 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: hwtimestamp
hwtimestamp has specific syntax
*)
let hwtimestamp = [ Util.indent . key "hwtimestamp"
. space . [ label "interface" . store no_space ]
. ( space . ( [ key hwtimestamp_flags ]
| [ key hwtimestamp_options . space
. store no_space ] )
)*
. 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 local_flags ]
| [ key local_options . space . store no_space ] )
)*
. 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 ]
(* View: ratelimit
ratelimit/cmdratelimit has specific syntax
*)
let ratelimit = [ Util.indent . key /(cmd|nts)?ratelimit/
. [ space . key ratelimit_options
. space . store no_space ]*
. eol ]
(* View: refclock
refclock has specific syntax
*)
let refclock = [ Util.indent . key "refclock"
. space
. [ label "driver" . store word ]
. space
. [ label "parameter" . store no_space ]
. ( space . ( [ key refclock_flags ]
| [ key refclock_options . space . store no_space ] )
)*
. eol ]
(* View: smoothtime
smoothtime has specific syntax
*)
let smoothtime = [ Util.indent . key "smoothtime"
. space
. [ label "maxfreq" . store number ]
. space
. [ label "maxwander" . store number ]
. ( space . [ key "leaponly" ] )?
. eol ]
(* View: tempcomp
tempcomp has specific syntax
*)
let tempcomp = [ Util.indent . key "tempcomp"
. space
. [ label "sensorfile" . store path ]
. space
. [ label "interval" . store number ]
. space
. ( [ label "t0" . store number ] . space
. [ label "k0" . store number ] . space
. [ label "k1" . store number ] . space
. [ label "k2" . store number ]
| [ label "pointfile" . store path ] )
. eol ]
(************************************************************************
* Group: Final lense summary
************************************************************************)
(* View: settings
* All supported chrony settings
*)
let settings = host_list | allowdeny | log_list | bcast | fdrift | istepslew
| local | email | makestep | maxchange | refclock | smoothtime
| dir_list | hwtimestamp | ratelimit | tempcomp | 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

View File

@ -0,0 +1,55 @@
(*
Module: ClamAV
Parses ClamAV clamd and freshclam configuration files.
Author: Andrew Colin Kissa <andrew@topdog.za.net>
Baruwa Enterprise Edition http://www.baruwa.com
About: License
This file is licensed under the LGPL v2+.
About: Configuration files
This lens applies to /etc/clamd.conf, /etc/freshclam.conf and files in
/etc/clamd.d. See <filter>.
*)
module Clamav =
autoload xfm
(************************************************************************
* Group: USEFUL PRIMITIVES
************************************************************************)
let word = /[A-Za-z][A-Za-z0-9]+/
let comment = Util.comment
let some_value = Sep.space . store Rx.space_in
(************************************************************************
* Group: Entry
************************************************************************)
let example_entry = [ key "Example" . Util.eol ]
let clamd_entry = [ key word . some_value . Util.eol ]
(******************************************************************
* Group: LENS AND FILTER
******************************************************************)
(************************************************************************
* View: Lns
************************************************************************)
let lns = (Util.empty | example_entry | clamd_entry | comment )*
(* Variable: filter *)
let filter = (incl "/etc/clamd.conf")
. (incl "/etc/freshclam.conf")
. (incl "/etc/clamd.d/*.conf")
. (incl "/etc/clamav/clamd.conf")
. (incl "/etc/clamav/freshclam.conf")
. (incl "/etc/clamav/clamd.d/*.conf")
let xfm = transform lns filter

View File

@ -0,0 +1,21 @@
(*
Module: Cmdline
Parses /proc/cmdline and /etc/kernel/cmdline
Author: Thomas Weißschuh <thomas.weissschuh@amadeus.com>
About: License
This file is licensed under the LGPL v2+, like the rest of Augeas.
*)
module Cmdline =
autoload xfm
let entry = [ key Rx.word . Util.del_str "=" . store Rx.no_spaces ] | [ key Rx.word ]
let lns = (Build.opt_list entry Sep.space)? . del /\n?/ ""
let filter = incl "/etc/kernel/cmdline"
. incl "/proc/cmdline"
let xfm = transform lns filter

View File

@ -0,0 +1,17 @@
module CobblerModules =
autoload xfm
let comment = IniFile.comment "#" "#"
let sep = IniFile.sep "=" "="
let entry = IniFile.entry IniFile.entry_re sep comment
let title = IniFile.indented_title IniFile.record_re
let record = IniFile.record title entry
let lns = IniFile.lns record comment
let filter = (incl "/etc/cobbler/modules.conf")
let xfm = transform lns filter

View File

@ -0,0 +1,72 @@
(*
Parse the /etc/cobbler/settings file which is in
YAML 1.0 format.
The lens can handle the following constructs
* key: value
* key: "value"
* key: 'value'
* key: [value1, value2]
* key:
- value1
- value2
* key:
key2: value1
key3: value2
Author: Bryan Kearney
About: License
This file is licensed under the LGPL v2+, like the rest of Augeas.
*)
module CobblerSettings =
autoload xfm
let kw = /[a-zA-Z0-9_]+/
(* TODO Would be better if this stripped off the "" and '' characters *)
let kv = /([^]['", \t\n#:@-]+|"[^"\n]*"|'[^'\n]*')/
let lbr = del /\[/ "["
let rbr = del /\]/ "]"
let colon = del /[ \t]*:[ \t]*/ ": "
let dash = del /-[ \t]*/ "- "
(* let comma = del /,[ \t]*(\n[ \t]+)?/ ", " *)
let comma = del /[ \t]*,[ \t]*/ ", "
let eol_only = del /\n/ "\n"
(* TODO Would be better to make items a child of a document *)
let docmarker = /-{3}/
let eol = Util.eol
let comment = Util.comment
let empty = Util.empty
let indent = del /[ \t]+/ "\t"
let ws = del /[ \t]*/ " "
let value_list = Build.opt_list [label "item" . store kv] comma
let setting = [key kw . colon . store kv] . eol
let simple_setting_suffix = store kv . eol
let setting_list_suffix = [label "sequence" . lbr . ws . (value_list . ws)? . rbr ] . eol
let indendented_setting_list_suffix = eol_only . (indent . setting)+
let indented_list_suffix = [label "list" . eol_only . ([ label "value" . indent . dash . store kv] . eol)+]
(* Break out setting because of a current bug in augeas *)
let nested_setting = [key kw . colon . (
(* simple_setting_suffix | *)
setting_list_suffix |
indendented_setting_list_suffix |
indented_list_suffix
)
]
let document = [label "---" . store docmarker] . eol
let lns = (document | comment | empty | setting | nested_setting )*
let xfm = transform lns (incl "/etc/cobbler/settings")
(* Local Variables: *)
(* mode: caml *)
(* End: *)

View File

@ -0,0 +1,36 @@
(*
Module: Collectd
Parses collectd configuration files
Author: Raphael Pinson <raphink@gmail.com>
About: Reference
This lens tries to keep as close as possible to `man 5 collectd.conf` where possible.
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 collectd configuration files. See <filter>.
About: Examples
The <Test_Collectd> file contains various examples and tests.
*)
module Collectd =
autoload xfm
(* View: lns
Collectd is essentially Httpd-compliant configuration files *)
let lns = Httpd.lns
(* Variable: filter *)
let filter = incl "/etc/collectd.conf"
. incl "/etc/collectd/*.conf"
. incl "/usr/share/doc/collectd/examples/collection3/etc/collection.conf"
let xfm = transform lns filter

View File

@ -0,0 +1,39 @@
(*
Module: CPanel
Parses cpanel.config
Author: Raphael Pinson <raphink@gmail.com>
About: Reference
This lens parses cpanel.config files
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 cpanel.config files. See <filter>.
About: Examples
The <Test_CPanel> file contains various examples and tests.
*)
module CPanel =
autoload xfm
(* View: kv
A key-value pair, supporting flags and empty values *)
let kv = [ key /[A-Za-z0-9:_.-]+/
. (Sep.equal . store (Rx.space_in?))?
. Util.eol ]
(* View: lns
The <CPanel> lens *)
let lns = (Util.comment | Util.empty | kv)*
(* View: filter *)
let filter = incl "/var/cpanel/cpanel.config"
let xfm = transform lns filter

View File

@ -0,0 +1,155 @@
(*
Module: Cron
Parses /etc/cron.d/*, /etc/crontab
Author: Raphael Pinson <raphink@gmail.com>
About: Reference
This lens tries to keep as close as possible to `man 5 crontab` where
possible.
About: License
This file is licensed under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
Sample usage of this lens in augtool
* Get the entry that launches '/usr/bin/ls'
> match '/files/etc/crontab/entry[. = "/usr/bin/ls"]'
About: Configuration files
This lens applies to /etc/cron.d/* and /etc/crontab. See <filter>.
*)
module Cron =
autoload xfm
(************************************************************************
* Group: USEFUL PRIMITIVES
*************************************************************************)
(* Group: Generic primitives *)
(* Variable: eol *)
let eol = Util.eol
(* Variable: indent *)
let indent = Util.indent
(* Variable: comment *)
let comment = Util.comment
(* Variable: empty *)
let empty = Util.empty
(* Variable: num *)
let num = /[0-9*][0-9\/,*-]*/
(* Variable: alpha *)
let alpha = /[A-Za-z]{3}/
(* Variable: alphanum *)
let alphanum = (num|alpha) . ("-" . (num|alpha))?
(* Variable: entry_prefix *)
let entry_prefix = /-/
(* Group: Separators *)
(* Variable: sep_spc *)
let sep_spc = Util.del_ws_spc
(* Variable: sep_eq *)
let sep_eq = Util.del_str "="
(************************************************************************
* Group: ENTRIES
*************************************************************************)
(************************************************************************
* View: shellvar
* A shell variable in crontab
*************************************************************************)
let shellvar =
let key_re = /[A-Za-z1-9_-]+(\[[0-9]+\])?/ - "entry" in
let sto_to_eol = store /[^\n]*[^ \t\n]/ in
[ key key_re . sep_eq . sto_to_eol . eol ]
(* View: - prefix of an entry *)
let prefix = [ label "prefix" . store entry_prefix ]
(* View: minute *)
let minute = [ label "minute" . store num ]
(* View: hour *)
let hour = [ label "hour" . store num ]
(* View: dayofmonth *)
let dayofmonth = [ label "dayofmonth" . store num ]
(* View: month *)
let month = [ label "month" . store alphanum ]
(* View: dayofweek *)
let dayofweek = [ label "dayofweek" . store alphanum ]
(* View: user *)
let user = [ label "user" . store Rx.word ]
(************************************************************************
* View: time
* Time in the format "minute hour dayofmonth month dayofweek"
*************************************************************************)
let time = [ label "time" .
minute . sep_spc . hour . sep_spc . dayofmonth
. sep_spc . month . sep_spc . dayofweek ]
(* Variable: the valid values for schedules *)
let schedule_re = "reboot" | "yearly" | "annually" | "monthly"
| "weekly" | "daily" | "midnight" | "hourly"
(************************************************************************
* View: schedule
* Time in the format "@keyword"
*************************************************************************)
let schedule = [ label "schedule" . Util.del_str "@"
. store schedule_re ]
(************************************************************************
* View: entry
* A crontab entry
*************************************************************************)
let entry = [ label "entry" . indent
. prefix?
. ( time | schedule )
. sep_spc . user
. sep_spc . store Rx.space_in . eol ]
(*
* View: lns
* The cron lens
*)
let lns = ( empty | comment | shellvar | entry )*
(* Variable: filter *)
let filter =
incl "/etc/cron.d/*" .
incl "/etc/crontab" .
incl "/etc/crontabs/*" .
excl "/etc/cron.d/at.allow" .
excl "/etc/cron.d/at.deny" .
excl "/etc/cron.d/cron.allow" .
excl "/etc/cron.d/cron.deny" .
Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,46 @@
(*
Module: Cron_User
Parses /var/spool/cron/*
Author: David Lutterkort <lutter@watzmann.net>
About: Reference
This lens parses the user crontab files in /var/spool/cron. It produces
almost the same tree as the Cron.lns, except that it never contains a user
field.
About: License
This file is licensed under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
Sample usage of this lens in augtool
* Get the entry that launches '/usr/bin/ls'
> match '/files/var/spool/cron/foo/entry[. = "/usr/bin/ls"]'
About: Configuration files
This lens applies to /var/spool/cron*. See <filter>.
*)
module Cron_User =
autoload xfm
(************************************************************************
* View: entry
* A crontab entry for a user's crontab
*************************************************************************)
let entry = [ label "entry" . Cron.indent
. Cron.prefix?
. ( Cron.time | Cron.schedule )
. Cron.sep_spc . store Rx.space_in . Cron.eol ]
(*
* View: lns
* The cron_user lens. Almost identical to Cron.lns
*)
let lns = ( Cron.empty | Cron.comment | Cron.shellvar | entry )*
let filter =
incl "/var/spool/cron/*" .
Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,108 @@
(*
Module: Crypttab
Parses /etc/crypttab from the cryptsetup package.
Author: Frédéric Lespez <frederic.lespez@free.fr>
About: Reference
This lens tries to keep as close as possible to `man crypttab` where possible.
About: License
This file is licensed under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
Sample usage of this lens in augtool
* Create a new entry for an encrypted block devices
> ins 01 after /files/etc/crypttab/*[last()]
> set /files/etc/crypttab/01/target crypt_sda2
> set /files/etc/crypttab/01/device /dev/sda2
> set /files/etc/crypttab/01/password /dev/random
> set /files/etc/crypttab/01/opt swap
* Print the entry applying to the "/dev/sda2" device
> print /files/etc/crypttab/01
* Remove the entry applying to the "/dev/sda2" device
> rm /files/etc/crypttab/*[device="/dev/sda2"]
About: Configuration files
This lens applies to /etc/crypttab. See <filter>.
*)
module Crypttab =
autoload xfm
(************************************************************************
* Group: USEFUL PRIMITIVES
*************************************************************************)
(* Group: Separators *)
(* Variable: sep_tab *)
let sep_tab = Sep.tab
(* Variable: comma *)
let comma = Sep.comma
(* Group: Generic primitives *)
(* Variable: eol *)
let eol = Util.eol
(* Variable: comment *)
let comment = Util.comment
(* Variable: empty *)
let empty = Util.empty
(* Variable: word *)
let word = Rx.word
(* Variable: optval *)
let optval = /[A-Za-z0-9\/_.:-]+/
(* Variable: target *)
let target = Rx.device_name
(* Variable: fspath *)
let fspath = Rx.fspath
(* Variable: uuid *)
let uuid = /UUID=[0-9a-f-]+/
(************************************************************************
* Group: ENTRIES
*************************************************************************)
(************************************************************************
* View: comma_sep_list
* A comma separated list of options (opt=value or opt)
*************************************************************************)
let comma_sep_list (l:string) =
let value = [ label "value" . Util.del_str "=" . store optval ] in
let lns = [ label l . store word . value? ] in
Build.opt_list lns comma
(************************************************************************
* View: record
* A crypttab record
*************************************************************************)
let record = [ seq "entry" .
[ label "target" . store target ] . sep_tab .
[ label "device" . store (fspath|uuid) ] .
(sep_tab . [ label "password" . store fspath ] .
( sep_tab . comma_sep_list "opt")? )?
. eol ]
(*
* View: lns
* The crypttab lens
*)
let lns = ( empty | comment | record ) *
(* Variable: filter *)
let filter = (incl "/etc/crypttab")
let xfm = transform lns filter
(* coding: utf-8 *)

View File

@ -0,0 +1,51 @@
(*
Module: CSV
Generic CSV lens collection
Author: Raphael Pinson <raphael.pinson@camptocamp.com>
About: Reference
https://tools.ietf.org/html/rfc4180
About: License
This file is licenced under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
To be documented
About: Configuration files
About: Examples
The <Test_CSV> file contains various examples and tests.
Caveats:
No support for files without an ending CRLF
*)
module CSV =
(* View: eol *)
let eol = Util.del_str "\n"
(* View: comment *)
let comment = Util.comment
| [ del /#[ \t]*\r?\n/ "#\n" ]
(* View: entry
An entry of fields, quoted or not *)
let entry (sep_str:string) =
let field = [ seq "field" . store (/[^"#\r\n]/ - sep_str)* ]
| [ seq "field" . store /("[^"#]*")+/ ]
in let sep = Util.del_str sep_str
in [ seq "entry" . counter "field" . Build.opt_list field sep . eol ]
(* View: lns
The generic lens, taking the separator as a parameter *)
let lns_generic (sep:string) = (comment | entry sep)*
(* View: lns
The comma-separated value lens *)
let lns = lns_generic ","
(* View: lns_semicol
A semicolon-separated value lens *)
let lns_semicol = lns_generic ";"

View File

@ -0,0 +1,27 @@
(*
Module: Cups
Parses cups configuration files
Author: Raphael Pinson <raphink@gmail.com>
About: License
This file is licenced under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
To be documented
About: Examples
The <Test_Cups> file contains various examples and tests.
*)
module Cups =
autoload xfm
(* View: lns *)
let lns = Httpd.lns
(* Variable: filter *)
let filter = incl "/etc/cups/*.conf"
let xfm = transform lns filter

View File

@ -0,0 +1,49 @@
(*
Cyrus_Imapd module for Augeas
Author: Free Ekanayaka <free@64studio.com>
*)
module Cyrus_Imapd =
autoload xfm
(************************************************************************
* USEFUL PRIMITIVES
*************************************************************************)
let eol = Util.eol
let indent = del /[ \t]*(\n[ \t]+)?/ " "
let comment = Util.comment
let empty = Util.empty
let eq = del /[ \t]*:/ ":"
let word = /[A-Za-z0-9_.-]+/
(* The value of a parameter, after the '=' sign. Postfix allows that
* lines are continued by starting continuation lines with spaces.
* The definition needs to make sure we don't add indented comment lines
* into values *)
let value =
let chr = /[^# \t\n]/ in
let any = /.*/ in
let line = (chr . any* . chr | chr) in
let lines = line . (/\n[ \t]+/ . line)* in
store lines
(************************************************************************
* ENTRIES
*************************************************************************)
let entry = [ key word . eq . (indent . value)? . eol ]
(************************************************************************
* LENS
*************************************************************************)
let lns = (comment|empty|entry) *
let filter = (incl "/etc/imapd.conf")
. (incl "/etc/imap/*.conf")
. Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,29 @@
(* Darkice module for Augeas
Author: Free Ekanayaka <free@64studio.com>
Reference: man 5 darkice.cfg
*)
module Darkice =
autoload xfm
(************************************************************************
* INI File settings
*************************************************************************)
let comment = IniFile.comment IniFile.comment_re IniFile.comment_default
let sep = IniFile.sep IniFile.sep_re IniFile.sep_default
let entry_re = ( /[A-Za-z0-9][A-Za-z0-9._-]*/ )
let entry = IniFile.entry entry_re sep comment
let title = IniFile.title_label "target" IniFile.record_label_re
let record = IniFile.record title entry
let lns = IniFile.lns record comment
let filter = (incl "/etc/darkice.cfg")
let xfm = transform lns filter

View File

@ -0,0 +1,131 @@
(*
Module: debctrl
Parses ./debian/control
Author:
Dominique Dumont domi.dumont@free.fr or dominique.dumont@hp.com
About: Reference
http://augeas.net/page/Create_a_lens_from_bottom_to_top
http://www.debian.org/doc/debian-policy/ch-controlfields.html
About: License
This file is licensed under the LGPL v2+.
About: Lens Usage
Since control file is not a system configuration file, you will have
to use augtool -r option to point to 'debian' directory.
Run augtool:
$ augtool -r debian
Sample usage of this lens in augtool:
* Get the value stored in control file
> print /files/control
...
Saving your file:
> save
*)
module Debctrl =
autoload xfm
let eol = Util.eol
let del_ws_spc = del /[\t ]*/ " "
let hardeol = del /\n/ "\n"
let del_opt_ws = del /[\t ]*/ ""
let colon = del /:[ \t]*/ ": "
let simple_entry (k:regexp) =
let value = store /[^ \t][^\n]+/ in
[ key k . colon . value . hardeol ]
let cont_line = del /\n[ \t]+/ "\n "
let comma = del /,[ \t]*/ ", "
let sep_comma_with_nl = del /[ \t\n]*,[ \t\n]*/ ",\n "
(*= del_opt_ws . cont_line* . comma . cont_line**)
let email = store ( /([A-Za-z]+ )+<[^\n>]+>/ | /[^\n,\t<> ]+/ )
let multi_line_array_entry (k:regexp) (v:lens) =
[ key k . colon . [ counter "array" . seq "array" . v ] .
[ seq "array" . sep_comma_with_nl . v ]* . hardeol ]
(* dependency stuff *)
let version_depends =
[ label "version"
. [ del / *\( */ " ( " . label "relation" . store /[<>=]+/ ]
. [ del_ws_spc . label "number"
. store ( /[a-zA-Z0-9_.-]+/ | /\$\{[a-zA-Z0-9:]+\}/ )
. del / *\)/ " )" ]
]
let arch_depends =
[ label "arch"
. [ del / *\[ */ " [ " . label "prefix" . store /!?/ ]
. [ label "name" . store /[a-zA-Z0-9_.-]+/ . del / *\]/ " ]" ] ]
let package_depends
= [ key ( /[a-zA-Z0-9_-]+/ | /\$\{[a-zA-Z0-9:]+\}/ )
. ( version_depends | arch_depends ) * ]
let dependency = [ label "or" . package_depends ]
. [ label "or" . del / *\| */ " | "
. package_depends ] *
let dependency_list (field:regexp) =
[ key field . colon . [ label "and" . dependency ]
. [ label "and" . sep_comma_with_nl . dependency ]*
. eol ]
(* source package *)
let uploaders =
multi_line_array_entry /Uploaders/ email
let simple_src_keyword = "Source" | "Section" | "Priority"
| "Standards\-Version" | "Homepage" | /Vcs\-Svn/ | /Vcs\-Browser/
| "Maintainer" | "DM-Upload-Allowed" | /XS?-Python-Version/
let depend_src_keywords = /Build\-Depends/ | /Build\-Depends\-Indep/
let src_entries = ( simple_entry simple_src_keyword
| uploaders
| dependency_list depend_src_keywords ) *
(* package paragraph *)
let multi_line_entry (k:string) =
let line = /.*[^ \t\n].*/ in
[ label k . del / / " " . store line . hardeol ] *
let description
= [ key "Description" . colon
. [ label "summary" . store /[a-zA-Z][^\n]+/ . hardeol ]
. multi_line_entry "text" ]
(* binary package *)
let simple_bin_keywords = "Package" | "Architecture" | "Section"
| "Priority" | "Essential" | "Homepage" | "XB-Python-Version"
let depend_bin_keywords = "Depends" | "Recommends" | "Suggests" | "Provides"
let bin_entries = ( simple_entry simple_bin_keywords
| dependency_list depend_bin_keywords
) + . description
(* The whole stuff *)
let lns = [ label "srcpkg" . src_entries ]
. [ label "binpkg" . hardeol+ . bin_entries ]+
. eol*
(* lens must be used with AUG_ROOT set to debian package source directory *)
let xfm = transform lns (incl "/control")

View File

@ -0,0 +1,53 @@
(*
Module: Desktop
Desktop module for Augeas (.desktop files)
Author: Raphael Pinson <raphink@gmail.com>
About: Lens Usage
This lens is made to provide a lens for .desktop files for augeas
Reference: Freedesktop.org
http://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html
About: License
This file is licenced under the LGPL v2+, like the rest of Augeas.
*)
module Desktop =
(* We don't load this lens by default
Since a lot of desktop files contain unicode characters
which we can't parse *)
(* autoload xfm *)
(* Comments can be only of # type *)
let comment = IniFile.comment "#" "#"
(* TITLE
* These represents sections of a desktop file
* Example : [DesktopEntry]
*)
let title = IniFile.title IniFile.record_re
let sep = IniFile.sep "=" "="
let setting = /[A-Za-z0-9_.-]+([][@A-Za-z0-9_.-]+)?/
(* Variable: sto_to_comment
Store until comment *)
let sto_to_comment = Sep.opt_space . store /[^# \t\r\n][^#\r\n]*[^# \t\r\n]|[^# \t\r\n]/
(* Entries can have comments at their end and so they are modified to represent as such *)
let entry = [ key setting . sep . sto_to_comment? . (comment|IniFile.eol) ] | comment
let record = IniFile.record title entry
let lns = IniFile.lns record comment
let filter = ( incl "/usr/share/applications/*.desktop"
. incl "/usr/share/applications/screensavers/*.desktop" )
let xfm = transform lns filter

View File

@ -0,0 +1,24 @@
module DevfsRules =
autoload xfm
let comment = IniFile.comment IniFile.comment_re "#"
let eol = Util.eol
let line_re = /[^][#; \t\n][^#;\n]*[^#; \t\n]/
let entry = [ seq "entry" . store line_re . (eol | comment) ]
let title = Util.del_str "["
. key Rx.word . [ label "id" . Sep.equal . store Rx.integer ]
. Util.del_str "]" . eol
. counter "entry"
let record = IniFile.record title (entry | comment)
let lns = IniFile.lns record comment
let filter = incl "/etc/defaults/devfs.rules"
. incl "/etc/devfs.rules"
let xfm = transform lns filter

View File

@ -0,0 +1,28 @@
(* Parsing grub's device.map *)
module Device_map =
autoload xfm
let sep_tab = Sep.tab
let eol = Util.eol
let fspath = Rx.fspath
let del_str = Util.del_str
let comment = Util.comment
let empty = Util.empty
let dev_name = /(h|f|c)d[0-9]+(,[0-9a-zA-Z]+){0,2}/
let dev_hex = Rx.hex
let dev_dec = /[0-9]+/
let device = del_str "(" . key ( dev_name | dev_hex | dev_dec ) . del_str ")"
let map = [ device . sep_tab . store fspath . eol ]
let lns = ( empty | comment | map ) *
let xfm = transform lns (incl "/boot/*/device.map")
(* Local Variables: *)
(* mode: caml *)
(* End: *)

View File

@ -0,0 +1,184 @@
(* Intefraces module for Augeas
Author: Free Ekanayaka <free@64studio.com>
Reference: man dhclient.conf
The only difference with the reference syntax is that this lens assumes
that statements end with a new line, while the reference syntax allows
new statements to be started right after the trailing ";" of the
previous statement. This should not be a problem in real-life
configuration files as statements get usually split across several
lines, rather than merged in a single one.
*)
module Dhclient =
autoload xfm
(************************************************************************
* USEFUL PRIMITIVES
*************************************************************************)
let eol = Util.eol
let comment = Util.comment
let comment_or_eol = Util.comment_or_eol
let empty = Util.empty
(* Define separators *)
let sep_spc = del /[ \t\n]+/ " "
let sep_scl = del /[ \t]*;/ ";"
let sep_obr = del /[ \t\n]*\{\n]*/ " {\n"
let sep_cbr = del /[ \t\n]*\}/ " }"
let sep_com = del /[ \t\n]*,[ \t\n]*/ ","
let sep_slh = del "\/" "/"
let sep_col = del ":" ":"
let sep_eq = del /[ \t]*=[ \t]*/ "="
(* Define basic types *)
let word = /[A-Za-z0-9_.-]+(\[[0-9]+\])?/
(* Define fields *)
(* TODO: there could be a " " in the middle of a value ... *)
let sto_to_spc = store /[^\\#,;{}" \t\n]+|"[^\\#"\n]+"/
let sto_to_spc_noeval = store /[^=\\#,;{}" \t\n]|[^=\\#,;{}" \t\n][^\\#,;{}" \t\n]*|"[^\\#"\n]+"/
let sto_to_scl = store /[^ \t\n][^;\n]+[^ \t]|[^ \t;\n]+/
let rfc_code = [ key "code" . sep_spc . store word ]
. sep_eq
. [ label "value" . sto_to_scl ]
let eval = [ label "#eval" . Sep.equal . sep_spc . sto_to_scl ]
let sto_number = store /[0-9][0-9]*/
(************************************************************************
* SIMPLE STATEMENTS
*************************************************************************)
let stmt_simple_re = "timeout"
| "retry"
| "select-timeout"
| "reboot"
| "backoff-cutoff"
| "initial-interval"
| "do-forward-updates"
| "reject"
let stmt_simple = [ key stmt_simple_re
. sep_spc
. sto_to_spc
. sep_scl
. comment_or_eol ]
(************************************************************************
* ARRAY STATEMENTS
*************************************************************************)
(* TODO: the array could also be empty, like in the request statement *)
let stmt_array_re = "media"
| "request"
| "require"
let stmt_array = [ key stmt_array_re
. sep_spc
. counter "stmt_array"
. [ seq "stmt_array" . sto_to_spc ]
. [ sep_com . seq "stmt_array" . sto_to_spc ]*
. sep_scl . comment_or_eol ]
(************************************************************************
* HASH STATEMENTS
*************************************************************************)
let stmt_hash_re = "send"
| "option"
let stmt_args = ( [ key word . sep_spc . sto_to_spc_noeval ]
| [ key word . sep_spc . (rfc_code|eval) ] )
. sep_scl
. comment_or_eol
let stmt_hash = [ key stmt_hash_re
. sep_spc
. stmt_args ]
let stmt_opt_mod_re = "append"
| "prepend"
| "default"
| "supersede"
let stmt_opt_mod = [ key stmt_opt_mod_re
. sep_spc
. stmt_args ]
(************************************************************************
* BLOCK STATEMENTS
*************************************************************************)
let stmt_block_re = "interface"
| "lease"
| "alias"
let stmt_block_opt_re = "interface"
| "script"
| "bootp"
| "fixed-address"
| "filename"
| "server-name"
| "medium"
| "vendor option space"
(* TODO: some options could take no argument like bootp *)
let stmt_block_opt = [ key stmt_block_opt_re
. sep_spc
. sto_to_spc
. sep_scl
. comment_or_eol ]
let stmt_block_date_re
= "renew"
| "rebind"
| "expire"
let stmt_block_date = [ key stmt_block_date_re
. [ sep_spc . label "weekday" . sto_number ]
. [ sep_spc . label "year" . sto_number ]
. [ sep_slh . label "month" . sto_number ]
. [ sep_slh . label "day" . sto_number ]
. [ sep_spc . label "hour" . sto_number ]
. [ sep_col . label "minute" . sto_number ]
. [ sep_col . label "second" . sto_number ]
. sep_scl
. comment_or_eol ]
let stmt_block_arg = sep_spc . sto_to_spc
let stmt_block_entry = sep_spc
. ( stmt_array
| stmt_hash
| stmt_opt_mod
| stmt_block_opt
| stmt_block_date )
let stmt_block = [ key stmt_block_re
. stmt_block_arg?
. sep_obr
. stmt_block_entry+
. sep_cbr
. comment_or_eol ]
(************************************************************************
* LENS & FILTER
*************************************************************************)
let statement = (stmt_simple|stmt_opt_mod|stmt_array|stmt_hash|stmt_block)
let lns = ( empty
| comment
| statement )*
let filter = incl "/etc/dhcp3/dhclient.conf"
. incl "/etc/dhcp/dhclient.conf"
. incl "/etc/dhclient.conf"
let xfm = transform lns filter

View File

@ -0,0 +1,518 @@
(*
Module: Dhcpd
BIND dhcp 3 server configuration module for Augeas
Author: Francis Giraldeau <francis.giraldeau@usherbrooke.ca>
About: Reference
Reference: manual of dhcpd.conf and dhcp-eval
Follow dhclient module for tree structure
About: License
This file is licensed under the GPL.
About: Lens Usage
Sample usage of this lens in augtool
Directive without argument.
Set this dhcpd server authoritative on the domain.
> clear /files/etc/dhcp3/dhcpd.conf/authoritative
Directives with integer or string argument.
Set max-lease-time to one hour:
> set /files/etc/dhcp3/dhcpd.conf/max-lease-time 3600
Options are declared as a list, even for single values.
Set the domain of the network:
> set /files/etc/dhcp3/dhcpd.conf/option/domain-name/arg example.org
Set two name server:
> set /files/etc/dhcp3/dhcpd.conf/option/domain-name-servers/arg[1] foo.example.org
> set /files/etc/dhcp3/dhcpd.conf/option/domain-name-servers/arg[2] bar.example.org
Create the subnet 172.16.0.1 with 10 addresses:
> clear /files/etc/dhcp3/dhcpd.conf/subnet[last() + 1]
> set /files/etc/dhcp3/dhcpd.conf/subnet[last()]/network 172.16.0.0
> set /files/etc/dhcp3/dhcpd.conf/subnet[last()]/netmask 255.255.255.0
> set /files/etc/dhcp3/dhcpd.conf/subnet[last()]/range/from 172.16.0.10
> set /files/etc/dhcp3/dhcpd.conf/subnet[last()]/range/to 172.16.0.20
Create a new group "foo" with one static host. Nodes type and address are ordered.
> ins group after /files/etc/dhcp3/dhcpd.conf/subnet[network='172.16.0.0']/*[last()]
> set /files/etc/dhcp3/dhcpd.conf/subnet[network='172.16.0.0']/group[last()]/host foo
> set /files/etc/dhcp3/dhcpd.conf/subnet[network='172.16.0.0']/group[host='foo']/host/hardware/type "ethernet"
> set /files/etc/dhcp3/dhcpd.conf/subnet[network='172.16.0.0']/group[host='foo']/host/hardware/address "00:00:00:aa:bb:cc"
> set /files/etc/dhcp3/dhcpd.conf/subnet[network='172.16.0.0']/group[host='foo']/host/fixed-address 172.16.0.100
About: Configuration files
This lens applies to /etc/dhcpd3/dhcpd.conf. See <filter>.
*)
module Dhcpd =
autoload xfm
(************************************************************************
* USEFUL PRIMITIVES
*************************************************************************)
let dels (s:string) = del s s
let eol = Util.eol
let comment = Util.comment
let empty = Util.empty
let indent = Util.indent
let eos = comment?
(* Define separators *)
let sep_spc = del /[ \t]+/ " "
let sep_osp = del /[ \t]*/ ""
let sep_scl = del /[ \t]*;([ \t]*\n)*/ ";\n"
let sep_obr = del /[ \t\n]*\{([ \t]*\n)*/ " {\n"
let sep_cbr = del /[ \t]*\}([ \t]*\n)*/ "}\n"
let sep_com = del /[ \t\n]*,[ \t\n]*/ ", "
let sep_slh = del "\/" "/"
let sep_col = del ":" ":"
let sep_eq = del /[ \t\n]*=[ \t\n]*/ "="
let scl = del ";" ";"
(* Define basic types *)
let word = /[A-Za-z0-9_.-]+(\[[0-9]+\])?/
let ip = Rx.ipv4
(* Define fields *)
(* adapted from sysconfig.aug *)
(* Chars allowed in a bare string *)
let bchar = /[^ \t\n"'\\{}#,()\/]|\\\\./
let qchar = /["']/ (* " *)
(* We split the handling of right hand sides into a few cases:
* bare - strings that contain no spaces, optionally enclosed in
* single or double quotes
* dquot - strings that contain at least one space, apostrophe or slash
* which must be enclosed in double quotes
* squot - strings that contain an unescaped double quote
*)
let bare = del qchar? "" . store (bchar+) . del qchar? ""
let quote = Quote.do_quote (store (bchar* . /[ \t'\/]/ . bchar*)+)
let dquote = Quote.do_dquote (store (bchar+))
(* these two are for special cases. bare_to_scl is for any bareword that is
* space or semicolon terminated. dquote_any allows almost any character in
* between the quotes. *)
let bare_to_scl = Quote.do_dquote_opt (store /[^" \t\n;]+/)
let dquote_any = Quote.do_dquote (store /[^"\n]*[ \t]+[^"\n]*/)
let sto_to_spc = store /[^\\#,;\{\}" \t\n]+|"[^\\#"\n]+"/
let sto_to_scl = store /[^ \t;][^;\n=]+[^ \t;]|[^ \t;=]+/
let sto_number = store /[0-9][0-9]*/
(************************************************************************
* NO ARG STATEMENTS
*************************************************************************)
let stmt_noarg_re = "authoritative"
| "primary"
| "secondary"
let stmt_noarg = [ indent
. key stmt_noarg_re
. sep_scl
. eos ]
(************************************************************************
* INT ARG STATEMENTS
*************************************************************************)
let stmt_integer_re = "default-lease-time"
| "max-lease-time"
| "min-lease-time"
| /lease[ ]+limit/
| "port"
| /peer[ ]+port/
| "max-response-delay"
| "max-unacked-updates"
| "mclt"
| "split"
| /load[ ]+balance[ ]+max[ ]+seconds/
| "max-lease-misbalance"
| "max-lease-ownership"
| "min-balance"
| "max-balance"
| "adaptive-lease-time-threshold"
| "dynamic-bootp-lease-length"
| "local-port"
| "min-sec"
| "omapi-port"
| "ping-timeout"
| "remote-port"
let stmt_integer = [ indent
. key stmt_integer_re
. sep_spc
. sto_number
. sep_scl
. eos ]
(************************************************************************
* STRING ARG STATEMENTS
*************************************************************************)
let stmt_string_re = "ddns-update-style"
| "ddns-updates"
| "ddns-hostname"
| "ddns-domainname"
| "ddns-rev-domainname"
| "log-facility"
| "server-name"
| "fixed-address"
| /failover[ ]+peer/
| "use-host-decl-names"
| "next-server"
| "address"
| /peer[ ]+address/
| "type"
| "file"
| "algorithm"
| "secret"
| "key"
| "include"
| "hba"
| "boot-unknown-clients"
| "db-time-format"
| "do-forward-updates"
| "dynamic-bootp-lease-cutoff"
| "get-lease-hostnames"
| "infinite-is-reserved"
| "lease-file-name"
| "local-address"
| "one-lease-per-client"
| "pid-file-name"
| "ping-check"
| "server-identifier"
| "site-option-space"
| "stash-agent-options"
| "update-conflict-detection"
| "update-optimization"
| "update-static-leases"
| "use-host-decl-names"
| "use-lease-addr-for-default-route"
| "vendor-option-space"
| "primary"
| "omapi-key"
let stmt_string_tpl (kw:regexp) (l:lens) = [ indent
. key kw
. sep_spc
. l
. sep_scl
. eos ]
let stmt_string = stmt_string_tpl stmt_string_re bare
| stmt_string_tpl stmt_string_re quote
| stmt_string_tpl "filename" dquote
(************************************************************************
* RANGE STATEMENTS
*************************************************************************)
let stmt_range = [ indent
. key "range"
. sep_spc
. [ label "flag" . store /dynamic-bootp/ . sep_spc ]?
. [ label "from" . store ip . sep_spc ]?
. [ label "to" . store ip ]
. sep_scl
. eos ]
(************************************************************************
* HARDWARE STATEMENTS
*************************************************************************)
let stmt_hardware = [ indent
. key "hardware"
. sep_spc
. [ label "type" . store /ethernet|tokenring|fddi/ ]
. sep_spc
. [ label "address" . store /[a-fA-F0-9:-]+/ ]
. sep_scl
. eos ]
(************************************************************************
* SET STATEMENTS
*************************************************************************)
let stmt_set = [ indent
. key "set"
. sep_spc
. store word
. sep_spc
. Sep.equal
. sep_spc
. [ label "value" . sto_to_scl ]
. sep_scl
. eos ]
(************************************************************************
* OPTION STATEMENTS
*************************************************************************)
(* The general case is considering options as a list *)
let stmt_option_value = /((array of[ \t]+)?(((un)?signed[ \t]+)?integer (8|16|32)|string|ip6?-address|boolean|domain-list|text)|encapsulate [A-Za-z0-9_.-]+)/
let stmt_option_list = ([ label "arg" . bare ] | [ label "arg" . quote ])
. ( sep_com . ([ label "arg" . bare ] | [ label "arg" . quote ]))*
let del_trail_spc = del /[ \t\n]*/ ""
let stmt_record = counter "record" . Util.del_str "{"
. sep_spc
. ([seq "record" . store stmt_option_value . sep_com]*
. [seq "record" . store stmt_option_value . del_trail_spc])?
. Util.del_str "}"
let stmt_option_code = [ label "label" . store word . sep_spc ]
. [ key "code" . sep_spc . store word ]
. sep_eq
. ([ label "type" . store stmt_option_value ]
|[ label "record" . stmt_record ])
let stmt_option_basic = [ key word . sep_spc . stmt_option_list ]
let stmt_option_extra = [ key word . sep_spc . store /true|false/ . sep_spc . stmt_option_list ]
let stmt_option_body = stmt_option_basic | stmt_option_extra
let stmt_option1 = [ indent
. key "option"
. sep_spc
. stmt_option_body
. sep_scl
. eos ]
let stmt_option2 = [ indent
. dels "option" . label "rfc-code"
. sep_spc
. stmt_option_code
. sep_scl
. eos ]
let stmt_option = stmt_option1 | stmt_option2
(************************************************************************
* SUBCLASS STATEMENTS
*************************************************************************)
(* this statement is not well documented in the manual dhcpd.conf
we support basic use case *)
let stmt_subclass = [ indent . key "subclass" . sep_spc
. ( [ label "name" . bare_to_scl ]|[ label "name" . dquote_any ] )
. sep_spc
. ( [ label "value" . bare_to_scl ]|[ label "value" . dquote_any ] )
. sep_scl
. eos ]
(************************************************************************
* ALLOW/DENY STATEMENTS
*************************************************************************)
(* We have to use special key for allow/deny members of
to avoid ambiguity in the put direction *)
let allow_deny_re = /unknown(-|[ ]+)clients/
| /known(-|[ ]+)clients/
| /all[ ]+clients/
| /dynamic[ ]+bootp[ ]+clients/
| /authenticated[ ]+clients/
| /unauthenticated[ ]+clients/
| "bootp"
| "booting"
| "duplicates"
| "declines"
| "client-updates"
| "leasequery"
let stmt_secu_re = "allow"
| "deny"
let del_allow = del /allow[ ]+members[ ]+of/ "allow members of"
let del_deny = del /deny[ \t]+members[ \t]+of/ "deny members of"
(* bare is anything but whitespace, quote marks or semicolon.
* technically this should be locked down to mostly alphanumerics, but the
* idea right now is just to make things work. Also ideally I would use
* dquote_space but I had a whale of a time with it. It doesn't like
* semicolon termination and my attempts to fix that led me to 3 hours of
* frustration and back to this :)
*)
let stmt_secu_tpl (l:lens) (s:string) =
[ indent . l . sep_spc . label s . bare_to_scl . sep_scl . eos ] |
[ indent . l . sep_spc . label s . dquote_any . sep_scl . eos ]
let stmt_secu = [ indent . key stmt_secu_re . sep_spc .
store allow_deny_re . sep_scl . eos ] |
stmt_secu_tpl del_allow "allow-members-of" |
stmt_secu_tpl del_deny "deny-members-of"
(************************************************************************
* MATCH STATEMENTS
*************************************************************************)
let sto_com = /[^ \t\n,\(\)][^,\(\)]*[^ \t\n,\(\)]|[^ \t\n,\(\)]+/ | word . /[ \t]*\([^)]*\)/
(* this is already the most complicated part of this module and it's about to
* get worse. match statements can be way more complicated than this
*
* examples:
* using or:
* match if ((option vendor-class-identifier="Banana Bready") or (option vendor-class-identifier="Cherry Sunfire"));
* unneeded parenthesis:
* match if (option vendor-class-identifier="Hello");
*
* and of course the fact that the above two rules used one of infinately
* many potential options instead of a builtin function.
*)
(* sto_com doesn't support quoted strings as arguments. It also doesn't
support single arguments (needs to match a comma) It will need to be
updated for lcase, ucase and log to be workable.
it also doesn't support no arguments, so gethostbyname() doesn't work.
option and config-option are considered operators. They should be matched
in stmt_entry but also available under "match if" and "if" conditionals
leased-address, host-decl-name, both take no args and return a value. We
might need to treat them as variable names in the parser.
things like this may be near-impossible to parse even with recursion
because we have no way of knowing when or if a subfunction takes arguments
set ClientMac = binary-to-ascii(16, 8, ":", substring(hardware, 1, 6));
even if we could parse it, they could get arbitrarily complicated like:
binary-to-ascii(16, 8, ":", substring(hardware, 1, 6) and substring(hardware, 2, 3));
so at some point we may need to programmatically knock it off and tell
people to put weird stuff in an include file that augeas doesn't parse.
the other option is to change the API to not parse the if statement at all,
just pull in the conditional as a string.
*)
let fct_re = "substring" | "binary-to-ascii" | "suffix" | "lcase" | "ucase"
| "gethostbyname" | "packet"
| "concat" | "reverse" | "encode-int"
| "extract-int" | "lease-time" | "client-state" | "exists" | "known" | "static"
| "pick-first-value" | "log" | "execute"
(* not needs to be different because it's a negation of whatever happens next *)
let op_re = "~="|"="|"~~"|"and"|"or"
let fct_args = [ label "args" . dels "(" . sep_osp .
([ label "arg" . store sto_com ] . [ label "arg" . sep_com . store sto_com ]+) .
sep_osp . dels ")" ]
let stmt_match_ifopt = [ dels "if" . sep_spc . key "option" . sep_spc . store word .
sep_eq . ([ label "value" . bare_to_scl ]|[ label "value" . dquote_any ]) ]
let stmt_match_func = [ store fct_re . sep_osp . label "function" . fct_args ] .
sep_eq . ([ label "value" . bare_to_scl ]|[ label "value" . dquote_any ])
let stmt_match_pfv = [ label "function" . store "pick-first-value" . sep_spc .
dels "(" . sep_osp .
[ label "args" .
[ label "arg" . store sto_com ] .
[ sep_com . label "arg" . store sto_com ]+ ] .
dels ")" ]
let stmt_match_tpl (l:lens) = [ indent . key "match" . sep_spc . l . sep_scl . eos ]
let stmt_match = stmt_match_tpl (dels "if" . sep_spc . stmt_match_func | stmt_match_pfv | stmt_match_ifopt)
(************************************************************************
* BLOCK STATEMENTS
*************************************************************************)
(* Blocks doesn't support comments at the end of the closing bracket *)
let stmt_entry = stmt_secu
| stmt_option
| stmt_hardware
| stmt_range
| stmt_string
| stmt_integer
| stmt_noarg
| stmt_match
| stmt_subclass
| stmt_set
| empty
| comment
let stmt_block_noarg_re = "pool" | "group"
let stmt_block_noarg (body:lens)
= [ indent
. key stmt_block_noarg_re
. sep_obr
. body*
. sep_cbr ]
let stmt_block_arg_re = "host"
| "class"
| "shared-network"
| /failover[ ]+peer/
| "zone"
| "group"
| "on"
let stmt_block_arg (body:lens)
= ([ indent . key stmt_block_arg_re . sep_spc . dquote_any . sep_obr . body* . sep_cbr ]
|[ indent . key stmt_block_arg_re . sep_spc . bare_to_scl . sep_obr . body* . sep_cbr ]
|[ indent . del /key/ "key" . label "key_block" . sep_spc . dquote_any . sep_obr . body* . sep_cbr . del /(;([ \t]*\n)*)?/ "" ]
|[ indent . del /key/ "key" . label "key_block" . sep_spc . bare_to_scl . sep_obr . body* . sep_cbr . del /(;([ \t]*\n)*)?/ "" ])
let stmt_block_subnet (body:lens)
= [ indent
. key "subnet"
. sep_spc
. [ label "network" . store ip ]
. sep_spc
. [ key "netmask" . sep_spc . store ip ]
. sep_obr
. body*
. sep_cbr ]
let conditional (body:lens) =
let condition = /[^{ \r\t\n][^{\n]*[^{ \r\t\n]|[^{ \t\n\r]/
in let elsif = [ indent
. Build.xchgs "elsif" "@elsif"
. sep_spc
. store condition
. sep_obr
. body*
. sep_cbr ]
in let else = [ indent
. Build.xchgs "else" "@else"
. sep_obr
. body*
. sep_cbr ]
in [ indent
. Build.xchgs "if" "@if"
. sep_spc
. store condition
. sep_obr
. body*
. sep_cbr
. elsif*
. else? ]
let all_block (body:lens) =
let lns1 = stmt_block_subnet body in
let lns2 = stmt_block_arg body in
let lns3 = stmt_block_noarg body in
let lns4 = conditional body in
(lns1 | lns2 | lns3 | lns4 | stmt_entry)
let rec lns_staging = stmt_entry|all_block lns_staging
let lns = (lns_staging)*
let filter = incl "/etc/dhcp3/dhcpd.conf"
. incl "/etc/dhcp/dhcpd.conf"
. incl "/etc/dhcpd.conf"
let xfm = transform lns filter

View File

@ -0,0 +1,113 @@
(*
Module: Dns_Zone
Lens for parsing DNS zone files
Authors:
Kaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>
About: Reference
RFC 1035, RFC 2782, RFC 3403
About: License
This file is licensed under the LGPL v2+
*)
module Dns_Zone =
autoload xfm
let eol = del /([ \t\n]*(;[^\n]*)?\n)+/ "\n"
let opt_eol = del /([ \t\n]*(;[^\n]*)?\n)*/ ""
let ws = del /[ \t]+|(([ \t\n]*;[^\n]*)?\n)+[ \t]*/ " "
let opt_ws = del /(([ \t\n]*;[^\n]*)?\n)*[ \t]*/ ""
let token = /([^ \t\n";()\\]|\\\\.)+|"([^"\\]|\\\\.)*"/
let control = [ key /\$[^ \t\n\/]+/
. Util.del_ws_tab
. store token
. eol ]
let labeled_token (lbl:string) (re:regexp) (sep:lens) =
[ label lbl . store re . sep ]
let regexp_token (lbl:string) (re:regexp) =
labeled_token lbl re Util.del_ws_tab
let type_token (re:regexp) = regexp_token "type" re
let simple_token (lbl:string) = regexp_token lbl token
let enclosed_token (lbl:string) = labeled_token lbl token ws
let last_token (lbl:string) = labeled_token lbl token eol
let class_re = /IN/
let ttl = regexp_token "ttl" /[0-9]+[DHMWdhmw]?/
let class = regexp_token "class" class_re
let rr =
let simple_type = /[A-Z]+/ - class_re - /MX|NAPTR|SOA|SRV/
in type_token simple_type . last_token "rdata"
let mx = type_token "MX"
. simple_token "priority"
. last_token "exchange"
let naptr = type_token "NAPTR"
. simple_token "order"
. simple_token "preference"
. simple_token "flags"
. simple_token "service"
. simple_token "regexp"
. last_token "replacement"
let soa = type_token "SOA"
. simple_token "mname"
. simple_token "rname"
. Util.del_str "("
. opt_ws
. enclosed_token "serial"
. enclosed_token "refresh"
. enclosed_token "retry"
. enclosed_token "expiry"
. labeled_token "minimum" token opt_ws
. Util.del_str ")"
. eol
let srv = type_token "SRV"
. simple_token "priority"
. simple_token "weight"
. simple_token "port"
. last_token "target"
let record = seq "owner"
. ((ttl? . class?) | (class . ttl))
. (rr|mx|naptr|soa|srv)
let ws_record = [ Util.del_ws_tab . record ]
let records (k:regexp) = [ key k . counter "owner" . ws_record+ ]
let any_record_block = records /[^ \t\n;\/$][^ \t\n;\/]*/
let non_root_records = records /@[^ \t\n;\/]+|[^ \t\n;\/$@][^ \t\n;\/]*/
let root_records = [ del /@?/ "@"
. Util.del_ws_tab
. label "@"
. counter "owner"
. [ record ]
. ws_record* ]
let lns = opt_eol
. control*
. ( (root_records|non_root_records)
. (control|any_record_block)* )?
let filter = incl "/var/bind/pri/*.zone"
let xfm = transform Dns_Zone.lns filter

View File

@ -0,0 +1,62 @@
(* Dnsmasq module for Augeas
Author: Free Ekanayaka <free@64studio.com>
Reference: man dnsmasq (8)
"Format is one option per line, legal options are the same
as the long options legal on the command line. See
"/usr/sbin/dnsmasq --help" or "man 8 dnsmasq" for details."
*)
module Dnsmasq =
autoload xfm
(************************************************************************
* USEFUL PRIMITIVES
*************************************************************************)
let eol = Util.eol
let spc = Util.del_ws_spc
let comment = Util.comment
let empty = Util.empty
let sep_eq = Sep.equal
let sto_to_eol = store /([^ \t\n].*[^ \t\n]|[^ \t\n])/
let slash = Util.del_str "/"
let sto_no_slash = store /([^\/ \t\n]+)/
let domains = slash . [ label "domain" . sto_no_slash . slash ]+
(************************************************************************
* SIMPLE ENTRIES
*************************************************************************)
let entry_re = Rx.word - /(address|server)/
let entry = [ key entry_re . (sep_eq . sto_to_eol)? . eol ]
(************************************************************************
* STRUCTURED ENTRIES
*************************************************************************)
let address = [ key "address" . sep_eq . domains . sto_no_slash . eol ]
let server =
let port = [ Build.xchgs "#" "port" . store Rx.integer ]
in let source = [ Build.xchgs "@" "source" . store /[^#\/ \t\n]+/ . port? ]
in let srv_spec = store /(#|([^#@\/ \t\n]+))/ . port? . source?
in [ key "server" . sep_eq . domains? . srv_spec? . eol ]
(************************************************************************
* LENS
*************************************************************************)
let lns = (comment|empty|address|server|entry) *
let filter = incl "/etc/dnsmasq.conf"
. incl "/etc/dnsmasq.d/*"
. excl ".*"
. Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,135 @@
(*
Module: Dovecot
Parses dovecot configuration files.
Author: Serge Smetana <serge.smetana@gmail.com>
Acunote http://www.acunote.com
Pluron, Inc. http://pluron.com
About: License
This file is licensed under the LGPL v2+.
About: Configuration files
This lens applies to /etc/dovecot/dovecot.conf and files in
/etc/dovecot/conf.d/. See <filter>.
About: Examples
The <Test_Dovecot> file contains various examples and tests.
About: TODO
Support for multiline values like queries in dict-sql.conf
*)
module Dovecot =
autoload xfm
(******************************************************************
* Group: USEFUL PRIMITIVES
******************************************************************)
(* View: indent *)
let indent = Util.indent
(* View: eol *)
let eol = Util.eol
(* View: empty
Map empty lines. *)
let empty = Util.empty
(* View: comment
Map comments in "#comment" nodes. *)
let comment = Util.comment
(* View: eq *)
let eq = del /[ \t]*=/ " ="
(* Variable: any *)
let any = Rx.no_spaces
(* Variable: value
Match any value after " =".
Should not start and end with spaces. May contain spaces inside *)
let value = any . (Rx.space . any)*
(* View: command_start *)
let command_start = Util.del_str "!"
(******************************************************************
* Group: ENTRIES
******************************************************************)
(* Variable: commands *)
let commands = /include|include_try/
(* Variable: block_names *)
let block_names = /dict|userdb|passdb|protocol|service|plugin|namespace|map|fields|unix_listener|fifo_listener|inet_listener/
(* Variable: keys
Match any possible key except commands and block names. *)
let keys = Rx.word - (commands | block_names)
(* View: entry
Map simple "key = value" entries including "key =" entries with empty value. *)
let entry = [ indent . key keys. eq . (Sep.opt_space . store value)? . eol ]
(* View: command
Map commands started with "!". *)
let command = [ command_start . key commands . Sep.space . store Rx.fspath . eol ]
(*
View: dquote_spaces
Make double quotes mandatory if value contains spaces,
and optional if value doesn't contain spaces.
Based off Quote.dquote_spaces
Parameters:
lns1:lens - the lens before
lns2:lens - the lens after
*)
let dquote_spaces (lns1:lens) (lns2:lens) =
(* bare has no spaces, and is optionally quoted *)
let bare = Quote.do_dquote_opt (store /[^" \t\n]+/)
(* quoted has at least one space, and must be quoted *)
in let quoted = Quote.do_dquote (store /[^"\n]*[ \t]+[^"\n]*/)
in [ lns1 . bare . lns2 ] | [ lns1 . quoted . lns2 ]
let mailbox = indent
. dquote_spaces
(key /mailbox/ . Sep.space)
(Build.block_newlines_spc entry comment . eol)
let block_ldelim_newlines_re = /[ \t]+\{([ \t\n]*\n)?/
let block_newlines (entry:lens) (comment:lens) =
let indent = del Rx.opt_space "\t"
in del block_ldelim_newlines_re Build.block_ldelim_default
. ((entry | comment) . (Util.empty | entry | comment)*)?
. del Build.block_rdelim_newlines_re Build.block_rdelim_newlines_default
(* View: block
Map block enclosed in brackets recursively.
Block may be indented and have optional argument.
Block body may have entries, comments, empty lines, and nested blocks recursively. *)
let rec block = [ indent . key block_names . (Sep.space . Quote.do_dquote_opt (store /!?[\/A-Za-z0-9_-]+/))? . block_newlines (entry|block|mailbox) comment . eol ]
(******************************************************************
* Group: LENS AND FILTER
******************************************************************)
(* View: lns
The Dovecot lens *)
let lns = (comment|empty|entry|command|block)*
(* Variable: filter *)
let filter = incl "/etc/dovecot/dovecot.conf"
. (incl "/etc/dovecot/conf.d/*.conf")
. incl "/usr/local/etc/dovecot/dovecot.conf"
. (incl "/usr/local/etc/dovecot/conf.d/*.conf")
. Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,91 @@
(*
Module: Dpkg
Parses /etc/dpkg/dpkg.cfg
Author: Robin Lee Powell <rlpowell@digitalkingdom.org>
About: License
This file, and the attendant test_dpgk.aug, are explicitly
placed in the public domain.
About: Description
dpkg.cfg is a simple list of options, the same ones as the
command line options, with or without a value.
The tree is a list of either comments or option/value pairs by
name. Use "set" to set an option with a value, and "clear" for a
bare option.
About: Usage Example
(start code)
$ augtool -n
augtool> ls /files/etc/dpkg/dpkg.cfg
#comment[1] = dpkg configuration file
#comment[2] = This file can contain default options for dpkg. All command-line
#comment[3] = options are allowed. Values can be specified by putting them after
#comment[4] = the option, separated by whitespace and/or an `=' sign.
#comment[5] = Do not enable debsig-verify by default; since the distribution is not using
#comment[6] = embedded signatures, debsig-verify would reject all packages.
no-debsig = (none)
#comment[7] = Log status changes and actions to a file.
log = /var/log/dpkg.log
augtool> get /files/etc/dpkg/dpkg.cfg/no-debsig
/files/etc/dpkg/dpkg.cfg/no-debsig (none)
augtool> get /files/etc/dpkg/dpkg.cfg/log
/files/etc/dpkg/dpkg.cfg/log = /var/log/dpkg.log
augtool> clear /files/etc/dpkg/dpkg.cfg/testopt
augtool> set /files/etc/dpkg/dpkg.cfg/testopt2 test
augtool> save
Saved 1 file(s)
augtool>
$ cat /etc/dpkg/dpkg.cfg.augnew
# dpkg configuration file
#
# This file can contain default options for dpkg. All command-line
# options are allowed. Values can be specified by putting them after
# the option, separated by whitespace and/or an `=' sign.
#
# Do not enable debsig-verify by default; since the distribution is not using
# embedded signatures, debsig-verify would reject all packages.
no-debsig
# Log status changes and actions to a file.
log /var/log/dpkg.log
testopt
testopt2 test
(end code)
*)
module Dpkg =
autoload xfm
let sep_tab = Util.del_ws_tab
let sep_spc = Util.del_ws_spc
let eol = del /[ \t]*\n/ "\n"
let comment = Util.comment
let empty = Util.empty
let word = /[^,# \n\t]+/
let keyword = /[^,# \n\t\/]+/
(* View: record
Keyword, followed by optional whitespace and value, followed
by EOL.
The actual file specification doesn't require EOL, but the
likelihood of the file not having one is pretty slim, and
this way things we add have EOL.
*)
let record = [ key keyword . (sep_spc . store word)? . eol ]
(* View: lns
Any number of empty lines, comments, and records.
*)
let lns = ( empty | comment | record ) *
let xfm = transform lns (incl "/etc/dpkg/dpkg.cfg")

View File

@ -0,0 +1,68 @@
(* Dput module for Augeas
Author: Raphael Pinson <raphink@gmail.com>
Reference: dput uses Python's ConfigParser:
http://docs.python.org/lib/module-ConfigParser.html
*)
module Dput =
autoload xfm
(************************************************************************
* INI File settings
*************************************************************************)
let comment = IniFile.comment IniFile.comment_re IniFile.comment_default
let sep = IniFile.sep IniFile.sep_re IniFile.sep_default
let setting = "allow_dcut"
| "allow_non-us_software"
| "allow_unsigned_uploads"
| "check_version"
| "default_host_main"
| "default_host_non-us"
| "fqdn"
| "hash"
| "incoming"
| "login"
| "method"
| "passive_ftp"
| "post_upload_command"
| "pre_upload_command"
| "progress_indicator"
| "run_dinstall"
| "run_lintian"
| "scp_compress"
| "ssh_config_options"
| "allowed_distributions"
(************************************************************************
* "name: value" entries, with continuations in the style of RFC 822;
* "name=value" is also accepted
* leading whitespace is removed from values
*************************************************************************)
let entry = IniFile.entry setting sep comment
(************************************************************************
* sections, led by a "[section]" header
* We can't use titles as node names here since they could contain "/"
* We remove #comment from possible keys
* since it is used as label for comments
* We also remove / as first character
* because augeas doesn't like '/' keys (although it is legal in INI Files)
*************************************************************************)
let title = IniFile.title_label "target" IniFile.record_label_re
let record = IniFile.record title entry
let lns = IniFile.lns record comment
let filter = (incl "/etc/dput.cf")
. (incl (Sys.getenv("HOME") . "/.dput.cf"))
let xfm = transform lns filter

View File

@ -0,0 +1,196 @@
(*
Module: Erlang
Parses Erlang configuration files
Author: Raphael Pinson <raphael.pinson@camptocamp.com>
About: Reference
This lens tries to keep as close as possible to `http://www.erlang.org/doc/man/config.html` where possible.
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 Erlang configuration files. See <filter>.
About: Examples
The <Test_Erlang> file contains various examples and tests.
*)
module Erlang =
(* Group: Spacing Functions *)
(* View: space *)
let space = del /[ \t\n]*/ ""
(* View: lspace
Add spaces to the left of char *)
let lspace (char:string) = del (/[ \t\n]*/ . char) char
(* View: rspace
Add spaces to the right of char *)
let rspace (char:string) = del (char . /[ \t\n]*/ ) char
(* View: lrspace
Add spaces to the left or right of char *)
let lrspace (char:string) = del (/[ \t\n]*/ . char . /[ \t\n]*/ ) char
(* Group: Separators *)
(* Variable: lbrace
Left square bracket *)
let lbrace = "{"
(* Variable: rbrace
Right square bracket *)
let rbrace = "}"
(* Variable: lbrack
Left curly brackets *)
let lbrack = "["
(* Variable: rbrack
Right curly brackets *)
let rbrack = "]"
(* Variable: lglob
Left glob separator *)
let lglob = "<<\""
(* Variable: rglob
Right glob separator *)
let rglob = "\">>"
(* Variable: comma *)
let comma = ","
(* Group: Value types *)
(* View: opt_list
An optional list of elements, in square brackets *)
let opt_list (lns:lens) = rspace lbrack
. (Build.opt_list lns (lrspace comma) . space)?
. Util.del_str rbrack
(* View: integer
Store a <Rx.integer> *)
let integer = store Rx.integer
(* View: decimal
Store a decimal value *)
let decimal = store /[0-9]+(.[0-9]+)?/
(* View: quoted
Store a quoted value *)
let quoted = Quote.do_quote (store /[^,\n}{]+/)
(* View: bare
Store a bare <Rx.word> *)
let bare = store Rx.word
(* View: boolean
Store a boolean value *)
let boolean = store /true|false/
(* View: path
Store a path (<quoted>) *)
let path = quoted
(* View: glob
Store a glob *)
let glob = Util.del_str lglob . store /[^\n"]+/ . Util.del_str rglob
(* View: make_value
Make a "value" subnode for arrays/tuples *)
let make_value (lns:lens) = [ label "value" . lns ]
(* Group: Store types *)
(* View: value
A single value *)
let value (kw:regexp) (sto:lens) =
[ rspace lbrace
. key kw
. lrspace comma
. sto
. lspace rbrace ]
(* View: tuple
A tuple of values *)
let tuple (one:lens) (two:lens) =
[ rspace lbrace
. label "tuple"
. [ label "value" . one ]
. lrspace comma
. [ label "value" . two ]
. lspace rbrace ]
(* View: tuple3
A tuple of 3 values *)
let tuple3 (one:lens) (two:lens) (three:lens) =
[ rspace lbrace
. label "tuple"
. [ label "value" . one ]
. lrspace comma
. [ label "value" . two ]
. lrspace comma
. [ label "value" . three ]
. lspace rbrace ]
(* View: list
A list of lenses *)
let list (kw:regexp) (lns:lens) =
[ rspace lbrace
. key kw
. lrspace comma
. opt_list lns
. lspace rbrace ]
(* View: value_list
A <list> of seq entries *)
let value_list (kw:regexp) (sto:lens) =
list kw (make_value sto)
(* View: application *)
let application (name:regexp) (parameter:lens) =
list name parameter
(* View: kernel_parameters
Config parameters accepted for kernel app *)
let kernel_parameters =
value "browser_cmd" path
| value "dist_auto_connect" (store /never|once/)
| value "error_logger" (store /tty|false|silent/)
| value "net_setuptime" integer
| value "net_ticktime" integer
| value "shutdown_timeout" integer
| value "sync_nodes_timeout" integer
| value "start_dist_ac" boolean
| value "start_boot_server" boolean
| value "start_disk_log" boolean
| value "start_pg2" boolean
| value "start_timer" boolean
(* View: kernel
Core Erlang kernel app configuration *)
let kernel = application "kernel" kernel_parameters
(* View: comment *)
let comment = Util.comment_generic /%[ \t]*/ "% "
(* View: config
A top-level config *)
let config (app:lens) =
(Util.empty | comment)*
. rspace lbrack
. Build.opt_list (kernel | app) (lrspace comma)
. lrspace rbrack
. Util.del_str "." . Util.eol
. (Util.empty | comment)*

View File

@ -0,0 +1,25 @@
(* Parsing /etc/ethers *)
module Ethers =
autoload xfm
let sep_tab = Util.del_ws_tab
let eol = del /[ \t]*\n/ "\n"
let indent = del /[ \t]*/ ""
let comment = Util.comment
let empty = [ del /[ \t]*#?[ \t]*\n/ "\n" ]
let word = /[^# \n\t]+/
let address =
let hex = /[0-9a-fA-F][0-9a-fA-F]?/ in
hex . ":" . hex . ":" . hex . ":" . hex . ":" . hex . ":" . hex
let record = [ seq "ether" . indent .
[ label "mac" . store address ] . sep_tab .
[ label "ip" . store word ] . eol ]
let lns = ( empty | comment | record ) *
let xfm = transform lns (incl "/etc/ethers")

View File

@ -0,0 +1,98 @@
(* Lens for Linux syntax of NFS exports(5) *)
(*
Module: Exports
Parses /etc/exports
Author: David Lutterkort <lutter@redhat.com>
About: Description
/etc/exports contains lines associating a directory with one or
more hosts, and NFS options for each host.
About: Usage Example
(start code)
$ augtool
augtool> ls /files/etc/exports/
comment[1] = /etc/exports: the access control list for filesystems which may be exported
comment[2] = to NFS clients. See exports(5).
comment[3] = sample /etc/exports file
dir[1]/ = /
dir[2]/ = /projects
dir[3]/ = /usr
dir[4]/ = /home/joe
augtool> ls /files/etc/exports/dir[1]
client[1]/ = master
client[2]/ = trusty
(end code)
The corresponding line in the file is:
(start code)
/ master(rw) trusty(rw,no_root_squash)
(end code)
Digging further:
(start code)
augtool> ls /files/etc/exports/dir[1]/client[1]
option = rw
To add a new entry, you'd do something like this:
(end code)
(start code)
augtool> set /files/etc/exports/dir[10000] /foo
augtool> set /files/etc/exports/dir[last()]/client[1] weeble
augtool> set /files/etc/exports/dir[last()]/client[1]/option[1] ro
augtool> set /files/etc/exports/dir[last()]/client[1]/option[2] all_squash
augtool> save
Saved 1 file(s)
(end code)
Which creates the line:
(start code)
/foo weeble(ro,all_squash)
(end code)
About: Limitations
This lens cannot handle options without a host, as with the last
example line in "man 5 exports":
/pub (ro,insecure,all_squash)
In this case, though, you can just do:
/pub *(ro,insecure,all_squash)
It also can't handle whitespace before the directory name.
*)
module Exports =
autoload xfm
let client_re = /[][a-zA-Z0-9.@*?\/:-]+/
let eol = Util.eol
let lbracket = Util.del_str "("
let rbracket = Util.del_str ")"
let sep_com = Sep.comma
let sep_spc = Sep.space
let option = [ label "option" . store /[^,)]*/ ]
let client = [ label "client" . store client_re .
( Build.brackets lbracket rbracket
( Build.opt_list option sep_com ) )? ]
let entry = [ label "dir" . store /[^ \t\n#]*/
. sep_spc . Build.opt_list client sep_spc . eol ]
let lns = (Util.empty | Util.comment | entry)*
let xfm = transform lns (incl "/etc/exports")

View File

@ -0,0 +1,286 @@
(*
Module: FAI_DiskConfig
Parses disk_config files for FAI
Author: Raphael Pinson <raphink@gmail.com>
About: Reference
This lens tries to keep as close as possible to the FAI wiki where possible:
http://wiki.fai-project.org/wiki/Setup-storage#New_configuration_file_syntax
About: License
This file is licensed under the LGPL v2+, like the rest of Augeas.
About: Examples
The <Test_FAI_DiskConfig> file contains various examples and tests.
*)
module FAI_DiskConfig =
(* autoload xfm *)
(************************************************************************
* Group: USEFUL PRIMITIVES
*************************************************************************)
(* Group: Generic primitives *)
(* Variable: eol *)
let eol = Util.eol
(* Variable: space *)
let space = Sep.space
(* Variable: empty *)
let empty = Util.empty
(* Variable: comment *)
let comment = Util.comment
(* Variable: tag
A generic tag beginning with a colon *)
let tag (re:regexp) = [ Util.del_str ":" . key re ]
(* Variable: generic_opt
A generic key/value option *)
let generic_opt (type:string) (kw:regexp) =
[ key type . Util.del_str ":" . store kw ]
(* Variable: generic_opt_list
A generic key/list option *)
let generic_opt_list (type:string) (kw:regexp) =
[ key type . Util.del_str ":" . counter "locallist"
. Build.opt_list [seq "locallist" . store kw] Sep.comma ]
(************************************************************************
* Group: RECORDS
*************************************************************************)
(* Group: volume *)
(* Variable: mountpoint_kw *)
let mountpoint_kw = "-" (* do not mount *)
| "swap" (* swap space *)
(* fully qualified path; if :encrypt is given, the partition
* will be encrypted, the key is generated automatically *)
| /\/[^: \t\n]*/
(* Variable: encrypt
encrypt tag *)
let encrypt = tag "encrypt"
(* Variable: mountpoint *)
let mountpoint = [ label "mountpoint" . store mountpoint_kw
(* encrypt is only for the fspath, but we parse it anyway *)
. encrypt?]
(* Variable: resize
resize tag *)
let resize = tag "resize"
(* Variable: size_kw
Regexps for size *)
let size_kw = /[0-9]+[kMGTP%]?(-([0-9]+[kMGTP%]?)?)?/
| /-[0-9]+[kMGTP%]?/
(* Variable: size *)
let size = [ label "size" . store size_kw . resize? ]
(* Variable: filesystem_kw
Regexps for filesystem *)
let filesystem_kw = "-"
| "swap"
(* NOTE: Restraining this regexp would improve perfs *)
| (Rx.no_spaces - ("-" | "swap")) (* mkfs.xxx must exist *)
(* Variable: filesystem *)
let filesystem = [ label "filesystem" . store filesystem_kw ]
(* Variable: mount_option_value *)
let mount_option_value = [ label "value" . Util.del_str "="
. store /[^,= \t\n]+/ ]
(* Variable: mount_option
Counting options *)
let mount_option = [ seq "mount_option"
. store /[^,= \t\n]+/
. mount_option_value? ]
(* Variable: mount_options
An array of <mount_option>s *)
let mount_options = [ label "mount_options"
. counter "mount_option"
. Build.opt_list mount_option Sep.comma ]
(* Variable: fs_option *)
let fs_option =
[ key /createopts|tuneopts/
. Util.del_str "=\"" . store /[^"\n]*/ . Util.del_str "\"" ]
(* Variable: fs_options
An array of <fs_option>s *)
let fs_options =
(* options to append to mkfs.xxx and to the filesystem-specific
* tuning tool *)
[ label "fs_options" . Build.opt_list fs_option Sep.space ]
(* Variable: volume_full *)
let volume_full (type:lens) (third_field:lens) =
[ type . space
. mountpoint .space
(* The third field changes depending on types *)
. third_field . space
. filesystem . space
. mount_options
. (space . fs_options)?
. eol ]
(* Variable: name
LVM volume group name *)
let name = [ label "name" . store /[^\/ \t\n]+/ ]
(* Variable: partition
An optional partition number for <disk> *)
let partition = [ label "partition" . Util.del_str "." . store /[0-9]+/ ]
(* Variable: disk *)
let disk = [ label "disk" . store /[^., \t\n]+/ . partition? ]
(* Variable: vg_option
An option for <volume_vg> *)
let vg_option =
[ key "pvcreateopts"
. Util.del_str "=\"" . store /[^"\n]*/ . Util.del_str "\"" ]
(* Variable: volume_vg *)
let volume_vg = [ key "vg"
. space . name
. space . disk
. (space . vg_option)?
. eol ]
(* Variable: spare_missing *)
let spare_missing = tag /spare|missing/
(* Variable: disk_with_opt
A <disk> with a spare/missing option for raids *)
let disk_with_opt = [ label "disk" . store /[^:., \t\n]+/ . partition?
. spare_missing* ]
(* Variable: disk_list
A list of <disk_with_opt>s *)
let disk_list = Build.opt_list disk_with_opt Sep.comma
(* Variable: type_label_lv *)
let type_label_lv = label "lv"
. [ label "vg" . store (/[^# \t\n-]+/ - "raw") ]
. Util.del_str "-"
. [ label "name" . store /[^ \t\n]+/ ]
(* Variable: volume_tmpfs *)
let volume_tmpfs =
[ key "tmpfs" . space
. mountpoint .space
. size . space
. mount_options
. (space . fs_options)?
. eol ]
(* Variable: volume_lvm *)
let volume_lvm = volume_full type_label_lv size (* lvm logical volume: vg name and lv name *)
| volume_vg
(* Variable: volume_raid *)
let volume_raid = volume_full (key /raid[0156]/) disk_list (* raid level *)
(* Variable: device *)
let device = [ label "device" . store Rx.fspath ]
(* Variable: volume_cryptsetup *)
let volume_cryptsetup = volume_full (key ("swap"|"tmp"|"luks")) device
(* Variable: volume *)
let volume = volume_full (key "primary") size (* for physical disks only *)
| volume_full (key "logical") size (* for physical disks only *)
| volume_full (key "raw-disk") size
(* Variable: volume_or_comment
A succesion of <volume>s and <comment>s *)
let volume_or_comment (vol:lens) =
(vol|empty|comment)* . vol
(* Variable: disk_config_entry *)
let disk_config_entry (kw:regexp) (opt:lens) (vol:lens) =
[ key "disk_config" . space . store kw
. (space . opt)* . eol
. (volume_or_comment vol)? ]
(* Variable: lvmoption *)
let lvmoption =
(* preserve partitions -- always *)
generic_opt "preserve_always" /[^\/, \t\n-]+-[^\/, \t\n-]+(,[^\/, \t\n-]+-[^\/, \t\n-]+)*/
(* preserve partitions -- unless the system is installed
* for the first time *)
| generic_opt "preserve_reinstall" /[^\/, \t\n-]+-[^\/, \t\n-]+(,[^\/, \t\n-]+-[^\/, \t\n-]+)*/
(* attempt to resize partitions *)
| generic_opt "resize" /[^\/, \t\n-]+-[^\/, \t\n-]+(,[^\/, \t\n-]+-[^\/, \t\n-]+)*/
(* when creating the fstab, the key used for defining the device
* may be the device (/dev/xxx), a label given using -L, or the uuid *)
| generic_opt "fstabkey" /device|label|uuid/
(* Variable: raidoption *)
let raidoption =
(* preserve partitions -- always *)
generic_opt_list "preserve_always" (Rx.integer | "all")
(* preserve partitions -- unless the system is installed
* for the first time *)
| generic_opt_list "preserve_reinstall" Rx.integer
(* when creating the fstab, the key used for defining the device
* may be the device (/dev/xxx), a label given using -L, or the uuid *)
| generic_opt "fstabkey" /device|label|uuid/
(* Variable: option *)
let option =
(* preserve partitions -- always *)
generic_opt_list "preserve_always" (Rx.integer | "all")
(* preserve partitions -- unless the system is installed
for the first time *)
| generic_opt_list "preserve_reinstall" Rx.integer
(* attempt to resize partitions *)
| generic_opt_list "resize" Rx.integer
(* write a disklabel - default is msdos *)
| generic_opt "disklabel" /msdos|gpt/
(* mark a partition bootable, default is / *)
| generic_opt "bootable" Rx.integer
(* do not assume the disk to be a physical device, use with xen *)
| [ key "virtual" ]
(* when creating the fstab, the key used for defining the device
* may be the device (/dev/xxx), a label given using -L, or the uuid *)
| generic_opt "fstabkey" /device|label|uuid/
| generic_opt_list "always_format" Rx.integer
| generic_opt "sameas" Rx.fspath
let cryptoption =
[ key "randinit" ]
(* Variable: disk_config *)
let disk_config =
let excludes = "lvm" | "raid" | "end" | /disk[0-9]+/
| "cryptsetup" | "tmpfs" in
let other_label = Rx.fspath - excludes in
disk_config_entry "lvm" lvmoption volume_lvm
| disk_config_entry "raid" raidoption volume_raid
| disk_config_entry "tmpfs" option volume_tmpfs
| disk_config_entry "end" option volume (* there shouldn't be an option here *)
| disk_config_entry /disk[0-9]+/ option volume
| disk_config_entry "cryptsetup" cryptoption volume_cryptsetup
| disk_config_entry other_label option volume
(* Variable: lns
The disk_config lens *)
let lns = (disk_config|comment|empty)*
(* let xfm = transform lns Util.stdexcl *)

View File

@ -0,0 +1,47 @@
(* Fail2ban module for Augeas *)
(* Author: Nicolas Gif <ngf18490@pm.me> *)
(* Heavily based on DPUT module by Raphael Pinson *)
(* <raphink@gmail.com> *)
(* *)
module Fail2ban =
autoload xfm
(************************************************************************
* INI File settings
*************************************************************************)
let comment = IniFile.comment IniFile.comment_re IniFile.comment_default
let sep = IniFile.sep IniFile.sep_re IniFile.sep_default
(************************************************************************
* "name: value" entries, with continuations in the style of RFC 822;
* "name=value" is also accepted
* leading whitespace is removed from values
*************************************************************************)
let entry = IniFile.entry IniFile.entry_re sep comment
(************************************************************************
* sections, led by a "[section]" header
* We can't use titles as node names here since they could contain "/"
* We remove #comment from possible keys
* since it is used as label for comments
* We also remove / as first character
* because augeas doesn't like '/' keys (although it is legal in INI Files)
*************************************************************************)
let title = IniFile.title IniFile.record_re
let record = IniFile.record title entry
let lns = IniFile.lns record comment
let filter = (incl "/etc/fail2ban/fail2ban.conf")
. (incl "/etc/fail2ban/jail.conf")
. (incl "/etc/fail2ban/jail.local")
. (incl "/etc/fail2ban/fail2ban.d/*.conf")
. (incl "/etc/fail2ban/jail.d/*.conf")
let xfm = transform lns filter

View File

@ -0,0 +1,37 @@
(*
Module: Fonts
Parses the /etc/fonts directory
Author: Raphael Pinson <raphink@gmail.com>
About: Reference
This lens tries to keep as close as possible to `man 5 fonts-conf` where possible.
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 files in the /etc/fonts directory. See <filter>.
About: Examples
The <Test_Fonts> file contains various examples and tests.
*)
module Fonts =
autoload xfm
(* View: lns *)
let lns = Xml.lns
(* Variable: filter *)
let filter = incl "/etc/fonts/fonts.conf"
. incl "/etc/fonts/conf.avail/*"
. incl "/etc/fonts/conf.d/*"
. excl "/etc/fonts/*/README"
. Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,43 @@
(* Parsing /etc/fstab *)
module Fstab =
autoload xfm
let sep_tab = Sep.tab
let sep_spc = Sep.space
let comma = Sep.comma
let eol = Util.eol
let comment = Util.comment
let empty = Util.empty
let file = /[^# \t\n]+/
(* An option label can't contain comma, comment, equals, or space *)
let optlabel = /[^,#= \n\t]+/
let spec = /[^,# \n\t][^ \n\t]*/
let comma_sep_list (l:string) =
let value = [ label "value" . Util.del_str "=" . ( store Rx.neg1 )? ] in
let lns = [ label l . store optlabel . value? ] in
Build.opt_list lns comma
let record = [ seq "mntent" .
Util.indent .
[ label "spec" . store spec ] . sep_tab .
[ label "file" . store file ] . sep_tab .
comma_sep_list "vfstype" .
(sep_tab . comma_sep_list "opt" .
(sep_tab . [ label "dump" . store /[0-9]+/ ] .
( sep_spc . [ label "passno" . store /[0-9]+/ ])? )? )?
. Util.comment_or_eol ]
let lns = ( empty | comment | record ) *
let filter = incl "/etc/fstab"
. incl "/etc/mtab"
let xfm = transform lns filter
(* Local Variables: *)
(* mode: caml *)
(* End: *)

View File

@ -0,0 +1,45 @@
(*
Module: Fuse
Parses /etc/fuse.conf
Author: Raphael Pinson <raphink@gmail.com>
About: Reference
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/fuse.conf. See <filter>.
About: Examples
The <Test_Fuse> file contains various examples and tests.
*)
module Fuse =
autoload xfm
(* Variable: equal *)
let equal = del /[ \t]*=[ \t]*/ " = "
(* View: mount_max *)
let mount_max = Build.key_value_line "mount_max" equal (store Rx.integer)
(* View: user_allow_other *)
let user_allow_other = Build.flag_line "user_allow_other"
(* View: lns
The fuse.conf lens
*)
let lns = ( Util.empty | Util.comment | mount_max | user_allow_other )*
(* Variable: filter *)
let filter = incl "/etc/fuse.conf"
let xfm = transform lns filter

View File

@ -0,0 +1,48 @@
(* Gdm module for Augeas *)
(* Author: Free Ekanayaka <freek@64studio.com> *)
(* *)
module Gdm =
autoload xfm
(************************************************************************
* INI File settings
*************************************************************************)
let comment = IniFile.comment IniFile.comment_re IniFile.comment_default
let sep = IniFile.sep IniFile.sep_re IniFile.sep_default
let empty = IniFile.empty
(************************************************************************
* ENTRY
* Entry keywords can be bare digits as well (the [server] section)
*************************************************************************)
let entry_re = ( /[A-Za-z0-9][A-Za-z0-9._-]*/ )
let entry = IniFile.entry entry_re sep comment
(************************************************************************
* TITLE
*
* We use IniFile.title_label because there can be entries
* outside of sections whose labels would conflict with section names
*************************************************************************)
let title = IniFile.title ( IniFile.record_re - ".anon" )
let record = IniFile.record title entry
let record_anon = [ label ".anon" . ( entry | empty )+ ]
(************************************************************************
* LENS & FILTER
* There can be entries before any section
* IniFile.entry includes comment management, so we just pass entry to lns
*************************************************************************)
let lns = record_anon? . record*
let filter = (incl "/etc/gdm/gdm.conf*")
. (incl "/etc/gdm/custom.conf")
. Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,49 @@
(*
Module: Getcap
Parses generic termcap-style capability databases
Author: Matt Dainty <matt@bodgit-n-scarper.com>
About: Reference
- man 3 getcap
- man 5 login.conf
- man 5 printcap
Each line represents a record consisting of a number of ':'-separated fields
the first of which is the name or identifier for the record. The name can
optionally be split by '|' and each subsequent value is considered an alias
of the first. Records can be split across multiple lines with '\'.
See also the Rtadvd and Termcap modules which contain slightly more specific
grammars.
*)
module Getcap =
autoload xfm
(* Comments cannot have any leading characters *)
let comment = Util.comment_generic /#[ \t]*/ "# "
let nfield = /[^#:\\\\\t\n|][^:\\\\\t\n|]*/
(* field must not contain ':' *)
let cfield = /[a-zA-Z0-9-]+([%^$#\\]?@|[%^$#\\=]([^:\\\\^]|\\\\[0-7]{1,3}|\\\\[bBcCeEfFnNrRtT\\^]|\^.)*)?/
let csep = del /:([ \t]*\\\\\n[ \t]*:)?/ ":\\\n\t:"
let nsep = Util.del_str "|"
let name = [ label "name" . store nfield ]
let capability (re:regexp) = [ label "capability" . store re ]
let record (re:regexp) = [ label "record" . name . ( nsep . name )* . ( csep . capability re )* . Sep.colon . Util.eol ]
let lns = ( Util.empty | comment | record cfield )*
let filter = incl "/etc/login.conf"
. incl "/etc/printcap"
. Util.stdexcl
let xfm = transform lns filter
(* Local Variables: *)
(* mode: caml *)
(* End: *)

View File

@ -0,0 +1,59 @@
(* Group module for Augeas
Author: Free Ekanayaka <free@64studio.com>
Reference: man 5 group
*)
module Group =
autoload xfm
(************************************************************************
* USEFUL PRIMITIVES
*************************************************************************)
let eol = Util.eol
let comment = Util.comment
let empty = Util.empty
let dels = Util.del_str
let colon = Sep.colon
let comma = Sep.comma
let sto_to_spc = store Rx.space_in
let sto_to_col = Passwd.sto_to_col
let word = Rx.word
let password = /[A-Za-z0-9_.!*-]*/
let integer = Rx.integer
(************************************************************************
* ENTRIES
*************************************************************************)
let user = [ label "user" . store word ]
let user_list = Build.opt_list user comma
let params = [ label "password" . store password . colon ]
. [ label "gid" . store integer . colon ]
. user_list?
let entry = Build.key_value_line word colon params
let nisdefault =
let overrides =
colon
. [ label "password" . store password? . colon ]
. [ label "gid" . store integer? . colon ]
. user_list? in
[ dels "+" . label "@nisdefault" . overrides? . eol ]
(************************************************************************
* LENS
*************************************************************************)
let lns = (comment|empty|entry|nisdefault) *
let filter = incl "/etc/group"
let xfm = transform lns filter

View File

@ -0,0 +1,337 @@
(*
Module: Grub
Parses grub configuration
Author: David Lutterkort <lutter@redhat.com>
About: License
This file is licenced under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
To be documented
*)
module Grub =
autoload xfm
(* This only covers the most basic grub directives. Needs to be *)
(* expanded to cover more (and more esoteric) directives *)
(* It is good enough to handle the grub.conf on my Fedora 8 box *)
(************************************************************************
* Group: USEFUL PRIMITIVES
*************************************************************************)
(* View: value_to_eol *)
let value_to_eol = store /[^= \t\n][^\n]*[^= \t\n]|[^= \t\n]/
(* View: eol *)
let eol = Util.eol
(* View: spc *)
let spc = Util.del_ws_spc
(* View: opt_ws *)
let opt_ws = Util.del_opt_ws ""
(* View: dels *)
let dels (s:string) = Util.del_str s
(* View: eq *)
let eq = dels "="
(* View: switch *)
let switch (n:regexp) = dels "--" . key n
(* View: switch_arg *)
let switch_arg (n:regexp) = switch n . eq . store Rx.no_spaces
(* View: value_sep *)
let value_sep (dflt:string) = del /[ \t]*[ \t=][ \t]*/ dflt
(* View: comment_re *)
let comment_re = /([^ \t\n].*[^ \t\n]|[^ \t\n])/
- /# ## (Start|End) Default Options ##/
(* View: comment *)
let comment =
[ Util.indent . label "#comment" . del /#[ \t]*/ "# "
. store comment_re . eol ]
(* View: empty *)
let empty = Util.empty
(************************************************************************
* Group: USEFUL FUNCTIONS
*************************************************************************)
(* View: command *)
let command (kw:regexp) (indent:string) =
Util.del_opt_ws indent . key kw
(* View: kw_arg *)
let kw_arg (kw:regexp) (indent:string) (dflt_sep:string) =
[ command kw indent . value_sep dflt_sep . value_to_eol . eol ]
(* View: kw_boot_arg *)
let kw_boot_arg (kw:regexp) = kw_arg kw "\t" " "
(* View: kw_menu_arg *)
let kw_menu_arg (kw:regexp) = kw_arg kw "" " "
(* View: password_arg *)
let password_arg = [ command "password" "" .
(spc . [ switch "md5" ])? .
(spc . [ switch "encrypted" ])? .
spc . store (/[^ \t\n]+/ - /--[^ \t\n]+/) .
(spc . [ label "file" . store /[^ \t\n]+/ ])? .
eol ]
(* View: kw_pres *)
let kw_pres (kw:string) = [ opt_ws . key kw . eol ]
(* View: error
* Parse a line that looks almost like a valid setting, but isn't,
* into an '#error' node. Any line that starts with letters, but not
* anything matching kw, is considered an error line.
*
* Parameters:
* kw:regexp - the valid keywords that are _not_ considered an
* error
*)
let error (kw:regexp) =
let not_kw = /[a-zA-Z]+/ - kw in
[ label "#error" . Util.del_opt_ws "\t"
. store (not_kw . /([^a-zA-Z\n].*[^ \t\n])?/) . eol ]
(************************************************************************
* Group: BOOT ENTRIES
*************************************************************************)
(* View: device
* This is a shell-only directive in upstream grub; the grub versions
* in at least Fedora/RHEL use this to find devices for UEFI boot *)
let device =
[ command "device" "" . Sep.space . store /\([A-Za-z0-9_.-]+\)/ . spc .
[ label "file" . value_to_eol ] . Util.eol ]
(* View: color *)
let color =
(* Should we nail it down to exactly the color names that *)
(* grub supports ? *)
let color_name = store /[A-Za-z-]+/ in
let color_spec =
[ label "foreground" . color_name] .
dels "/" .
[ label "background" . color_name ] in
[ opt_ws . key "color" .
spc . [ label "normal" . color_spec ] .
(spc . [ label "highlight" . color_spec ])? .
eol ]
(* View: serial *)
let serial =
[ command "serial" "" .
[ spc . switch_arg /unit|port|speed|word|parity|stop|device/ ]* .
eol ]
(* View: terminal *)
let terminal =
[ command "terminal" "" .
([ spc . switch /dumb|no-echo|no-edit|silent/ ]
|[ spc . switch_arg /timeout|lines/ ])* .
[ spc . key /console|serial|hercules/ ]* . eol ]
(* View: setkey *)
let setkey = [ command "setkey" "" .
( spc . [ label "to" . store Rx.no_spaces ] .
spc . [ label "from" . store Rx.no_spaces ] )? .
eol ]
(* View: menu_entry *)
let menu_entry = kw_menu_arg "default"
| kw_menu_arg "fallback"
| kw_pres "hiddenmenu"
| kw_menu_arg "timeout"
| kw_menu_arg "splashimage"
| kw_menu_arg "gfxmenu"
| kw_menu_arg "foreground"
| kw_menu_arg "background"
| kw_menu_arg "verbose"
| kw_menu_arg "boot" (* only for CLI, ignored in conf *)
| serial
| terminal
| password_arg
| color
| device
| setkey
(* View: menu_error
* Accept lines not matching menu_entry and stuff them into
* '#error' nodes
*)
let menu_error =
let kw = /default|fallback|hiddenmenu|timeout|splashimage|gfxmenu/
|/foreground|background|verbose|boot|password|title/
|/serial|setkey|terminal|color|device/ in
error kw
(* View: menu_setting
* a valid menu setting or a line that looks like one but is an #error
*)
let menu_setting = menu_entry | menu_error
(* View: title *)
let title = del /title[ \t=]+/ "title " . value_to_eol . eol
(* View: multiboot_arg
* Permits a second form for Solaris multiboot kernels that
* take a path (with a slash) as their first arg, e.g.
* /boot/multiboot kernel/unix another=arg *)
let multiboot_arg = [ label "@path" .
store (Rx.word . "/" . Rx.no_spaces) ]
(* View: kernel_args
Parse the file name and args on a kernel or module line. *)
let kernel_args =
let arg = /[A-Za-z0-9_.$\+-]+/ - /type|no-mem-option/ in
store /(\([a-z0-9,]+\))?\/[^ \t\n]*/ .
(spc . multiboot_arg)? .
(spc . [ key arg . (eq. store /([^ \t\n])*/)?])* . eol
(* View: module_line
Solaris extension adds module$ and kernel$ for variable interpolation *)
let module_line =
[ command /module\$?/ "\t" . spc . kernel_args ]
(* View: map_line *)
let map_line =
[ command "map" "\t" . spc .
[ label "from" . store /[()A-za-z0-9]+/ ] . spc .
[ label "to" . store /[()A-za-z0-9]+/ ] . eol ]
(* View: kernel *)
let kernel =
[ command /kernel\$?/ "\t" .
(spc .
([switch "type" . eq . store /[a-z]+/]
|[switch "no-mem-option"]))* .
spc . kernel_args ]
(* View: chainloader *)
let chainloader =
[ command "chainloader" "\t" .
[ spc . switch "force" ]? . spc . store Rx.no_spaces . eol ]
(* View: savedefault *)
let savedefault =
[ command "savedefault" "\t" . (spc . store Rx.integer)? . eol ]
(* View: configfile *)
let configfile =
[ command "configfile" "\t" . spc . store Rx.no_spaces . eol ]
(* View: boot_entry
<boot> entries *)
let boot_entry =
let boot_arg_re = "root" | "initrd" | "rootnoverify" | "uuid"
| "findroot" | "bootfs" (* Solaris extensions *)
in kw_boot_arg boot_arg_re
| kernel
| chainloader
| kw_pres "quiet" (* Seems to be a Ubuntu extension *)
| savedefault
| configfile
| module_line
| map_line
| kw_pres "lock"
| kw_pres "makeactive"
| password_arg
(* View: boot_error
* Accept lines not matching boot_entry and stuff them into
* '#error' nodes
*)
let boot_error =
let kw = /lock|uuid|password|root|initrd|rootnoverify|findroot|bootfs/
|/configfile|chainloader|title|boot|quiet|kernel|module/
|/makeactive|savedefault|map/ in
error kw
(* View: boot_setting
* a valid boot setting or a line that looks like one but is an #error
*)
let boot_setting = boot_entry | boot_error
(* View: boot *)
let boot =
let line = ((boot_setting|comment)* . boot_setting)? in
[ label "title" . title . line ]
(************************************************************************
* Group: DEBIAN-SPECIFIC SECTIONS
*************************************************************************)
(* View: debian_header
Header for a <debian>-specific section *)
let debian_header = "## ## Start Default Options ##\n"
(* View: debian_footer
Footer for a <debian>-specific section *)
let debian_footer = "## ## End Default Options ##\n"
(* View: debian_comment_re *)
let debian_comment_re = /([^ \t\n].*[^ \t\n]|[^ \t\n])/
- "## End Default Options ##"
(* View: debian_comment
A comment entry inside a <debian>-specific section *)
let debian_comment =
[ Util.indent . label "#comment" . del /##[ \t]*/ "## "
. store debian_comment_re . eol ]
(* View: debian_setting_re *)
let debian_setting_re = "kopt"
| "groot"
| "alternative"
| "lockalternative"
| "defoptions"
| "lockold"
| "xenhopt"
| "xenkopt"
| "altoptions"
| "howmany"
| "memtest86"
| "updatedefaultentry"
| "savedefault"
| "indomU"
(* View: debian_entry *)
let debian_entry = [ Util.del_str "#" . Util.indent
. key debian_setting_re . del /[ \t]*=/ "="
. value_to_eol? . eol ]
(* View: debian
A debian-specific section, made of <debian_entry> lines *)
let debian = [ label "debian"
. del debian_header debian_header
. (debian_comment|empty|debian_entry)*
. del debian_footer debian_footer ]
(************************************************************************
* Group: LENS AND FILTER
*************************************************************************)
(* View: lns *)
let lns = (comment | empty | menu_setting | debian)*
. (boot . (comment | empty | boot)*)?
(* View: filter *)
let filter = incl "/boot/grub/grub.conf"
. incl "/boot/grub/menu.lst"
. incl "/etc/grub.conf"
. incl "/boot/efi/EFI/*/grub.conf"
let xfm = transform lns filter

View File

@ -0,0 +1,19 @@
(* Parsing /boot/grub/grubenv *)
module GrubEnv =
autoload xfm
let eol = Util.del_str "\n"
let comment = Util.comment
let eq = Util.del_str "="
let value = /[^\\\n]*(\\\\(\\\\|\n)[^\\\n]*)*/
let word = /[A-Za-z_][A-Za-z0-9_]*/
let record = [ seq "target" .
[ label "name" . store word ] . eq .
[ label "value" . store value ] . eol ]
let lns = ( comment | record ) *
let xfm = transform lns (incl "/boot/grub/grubenv" . incl "/boot/grub2/grubenv")

View File

@ -0,0 +1,80 @@
(*
Module: Gshadow
Parses /etc/gshadow
Author: Lorenzo M. Catucci <catucci@ccd.uniroma2.it>
Original Author: Free Ekanayaka <free@64studio.com>
About: Reference
- man 5 gshadow
About: License
This file is licensed under the LGPL v2+, like the rest of Augeas.
About:
Each line in the gshadow files represents the additional shadow-defined
attributes for the corresponding group, as defined in the group file.
*)
module Gshadow =
autoload xfm
(************************************************************************
* USEFUL PRIMITIVES
*************************************************************************)
let eol = Util.eol
let comment = Util.comment
let empty = Util.empty
let colon = Sep.colon
let comma = Sep.comma
let sto_to_spc = store Rx.space_in
let word = Rx.word
let password = /[A-Za-z0-9_.!*-]*/
let integer = Rx.integer
(************************************************************************
* Group: ENTRIES
*************************************************************************)
(* View: member *)
let member = [ label "member" . store word ]
(* View: member_list
the member list is a comma separated list of
users allowed to chgrp to the group without
being prompted for the group's password *)
let member_list = Build.opt_list member comma
(* View: admin *)
let admin = [ label "admin" . store word ]
(* View: admin_list
the admin_list is a comma separated list of
users allowed to change the group's password
and the member_list *)
let admin_list = Build.opt_list admin comma
(* View: params *)
let params = [ label "password" . store password . colon ]
. admin_list? . colon
. member_list?
let entry = Build.key_value_line word colon params
(************************************************************************
* LENS
*************************************************************************)
let lns = (comment|empty|entry) *
let filter
= incl "/etc/gshadow"
. Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,36 @@
(*
Module: GtkBookmarks
Parses $HOME/.gtk-bookmarks
Author: Raphael Pinson <raphael.pinson@camptocamp.com>
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 $HOME/.gtk-bookmarks. See <filter>.
About: Examples
The <Test_GtkBookmarks> file contains various examples and tests.
*)
module GtkBookmarks =
autoload xfm
(* View: empty
Comment are not allowed, even empty comments *)
let empty = Util.empty_generic Rx.opt_space
(* View: entry *)
let entry = [ label "bookmark" . store Rx.no_spaces
. (Sep.space . [ label "label" . store Rx.space_in ])?
. Util.eol ]
(* View: lns *)
let lns = (empty | entry)*
(* View: xfm *)
let xfm = transform lns (incl (Sys.getenv("HOME") . "/.gtk-bookmarks"))

View File

@ -0,0 +1,71 @@
(*
Module: Host_Conf
Parses /etc/host.conf
Author: Raphael Pinson <raphink@gmail.com>
About: Reference
This lens tries to keep as close as possible to `man 5 host.conf` where possible.
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/host.conf. See <filter>.
*)
module Host_Conf =
autoload xfm
(************************************************************************
* Group: ENTRY TYPES
*************************************************************************)
(* View: sto_bool
Store a boolean value *)
let sto_bool = store ("on"|"off")
(* View: sto_bool_warn
Store a boolean value *)
let sto_bool_warn = store ("on"|"off"|"warn"|"nowarn")
(* View: bool
A boolean switch *)
let bool (kw:regexp) = Build.key_value_line kw Sep.space sto_bool
(* View: bool_warn
A boolean switch with extended values *)
let bool_warn (kw:regexp) = Build.key_value_line kw Sep.space sto_bool_warn
(* View: list
A list of items *)
let list (kw:regexp) (elem:string) =
let list_elems = Build.opt_list [seq elem . store Rx.word] (Sep.comma . Sep.opt_space) in
Build.key_value_line kw Sep.space list_elems
(* View: trim *)
let trim =
let trim_list = Build.opt_list [seq "trim" . store Rx.word] (del /[:;,]/ ":") in
Build.key_value_line "trim" Sep.space trim_list
(* View: entry *)
let entry = bool ("multi"|"nospoof"|"spoofalert"|"reorder")
| bool_warn "spoof"
| list "order" "order"
| trim
(************************************************************************
* Group: LENS AND FILTER
*************************************************************************)
(* View: lns *)
let lns = ( Util.empty | Util.comment | entry )*
(* View: filter *)
let filter = incl "/etc/host.conf"
let xfm = transform lns filter

View File

@ -0,0 +1,22 @@
(*
Module: Hostname
Parses /etc/hostname and /etc/mailname
Author: Raphael Pinson <raphink@gmail.com>
About: License
This file is licenced under the LGPL v2+, like the rest of Augeas.
*)
module Hostname =
autoload xfm
(* View: lns *)
let lns = [ label "hostname" . store Rx.word . Util.eol ] | Util.empty
(* View: filter *)
let filter = incl "/etc/hostname"
. incl "/etc/mailname"
let xfm = transform lns filter

View File

@ -0,0 +1,15 @@
(* Parsing /etc/hosts *)
module Hosts =
autoload xfm
let word = /[^# \n\t]+/
let record = [ seq "host" . Util.indent .
[ label "ipaddr" . store word ] . Sep.tab .
[ label "canonical" . store word ] .
[ label "alias" . Sep.space . store word ]*
. Util.comment_or_eol ]
let lns = ( Util.empty | Util.comment | record ) *
let xfm = transform lns (incl "/etc/hosts")

View File

@ -0,0 +1,152 @@
(*
Module: Hosts_Access
Parses /etc/hosts.{allow,deny}
Author: Raphael Pinson <raphink@gmail.com>
About: Reference
This lens tries to keep as close as possible to `man 5 hosts_access` and `man 5 hosts_options` where possible.
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/hosts.{allow,deny}. See <filter>.
*)
module Hosts_Access =
autoload xfm
(************************************************************************
* Group: USEFUL PRIMITIVES
*************************************************************************)
(* View: colon *)
let colon = del /[ \t]*(\\\\[ \t]*\n[ \t]+)?:[ \t]*(\\\\[ \t]*\n[ \t]+)?/ ": "
(* Variable: comma_sep *)
let comma_sep = /([ \t]|(\\\\\n))*,([ \t]|(\\\\\n))*/
(* Variable: ws_sep *)
let ws_sep = / +/
(* View: list_sep *)
let list_sep = del ( comma_sep | ws_sep ) ", "
(* View: list_item *)
let list_item = store ( Rx.word - /EXCEPT/i )
(* View: client_host_item
Allows @ for netgroups, supports [ipv6] syntax *)
let client_host_item =
let client_hostname_rx = /[A-Za-z0-9_.@?*-][A-Za-z0-9_.?*-]*/ in
let client_ipv6_rx = "[" . /[A-Za-z0-9:?*%]+/ . "]" in
let client_host_rx = client_hostname_rx | client_ipv6_rx in
let netmask = [ Util.del_str "/" . label "netmask" . store Rx.word ] in
store ( client_host_rx - /EXCEPT/i ) . netmask?
(* View: client_file_item *)
let client_file_item =
let client_file_rx = /\/[^ \t\n,:]+/ in
store ( client_file_rx - /EXCEPT/i )
(* Variable: option_kw
Since either an option or a shell command can be given, use an explicit list
of known options to avoid misinterpreting a command as an option *)
let option_kw = "severity"
| "spawn"
| "twist"
| "keepalive"
| "linger"
| "rfc931"
| "banners"
| "nice"
| "setenv"
| "umask"
| "user"
| /allow/i
| /deny/i
(* Variable: shell_command_rx *)
let shell_command_rx = /[^ \t\n:][^\n]*[^ \t\n]|[^ \t\n:\\\\]/
- ( option_kw . /.*/ )
(* View: sto_to_colon
Allows escaped colon sequences *)
let sto_to_colon = store /[^ \t\n:=][^\n:]*((\\\\:|\\\\[ \t]*\n[ \t]+)[^\n:]*)*[^ \\\t\n:]|[^ \t\n:\\\\]/
(* View: except
* The except operator makes it possible to write very compact rules.
*)
let except (lns:lens) = [ label "except" . Sep.space
. del /except/i "EXCEPT"
. Sep.space . lns ]
(************************************************************************
* Group: ENTRY TYPES
*************************************************************************)
(* View: daemon *)
let daemon =
let host = [ label "host"
. Util.del_str "@"
. list_item ] in
[ label "process"
. list_item
. host? ]
(* View: daemon_list
A list of <daemon>s *)
let daemon_list = Build.opt_list daemon list_sep
(* View: client *)
let client =
let user = [ label "user"
. list_item
. Util.del_str "@" ] in
[ label "client"
. user?
. client_host_item ]
(* View: client_file *)
let client_file = [ label "file" . client_file_item ]
(* View: client_list
A list of <client>s *)
let client_list = Build.opt_list ( client | client_file ) list_sep
(* View: option
Optional extensions defined in hosts_options(5) *)
let option = [ key option_kw
. ( del /([ \t]*=[ \t]*|[ \t]+)/ " " . sto_to_colon )? ]
(* View: shell_command *)
let shell_command = [ label "shell_command"
. store shell_command_rx ]
(* View: entry *)
let entry = [ seq "line"
. daemon_list
. (except daemon_list)?
. colon
. client_list
. (except client_list)?
. ( (colon . option)+ | (colon . shell_command)? )
. Util.eol ]
(************************************************************************
* Group: LENS AND FILTER
*************************************************************************)
(* View: lns *)
let lns = (Util.empty | Util.comment | entry)*
(* View: filter *)
let filter = incl "/etc/hosts.allow"
. incl "/etc/hosts.deny"
let xfm = transform lns filter

View File

@ -0,0 +1,41 @@
(*
Module: Htpasswd
Parses htpasswd and rsyncd.secrets files
Author: Marc Fournier <marc.fournier@camptocamp.com>
About: Reference
This lens is based on examples in htpasswd(1) and rsyncd.conf(5)
About: Usage Example
(start code)
augtool> set /augeas/load/Htpasswd/lens "Htpasswd.lns"
augtool> set /augeas/load/Htpasswd/incl "/var/www/.htpasswd"
augtool> load
augtool> get /files/var/www/.htpasswd/foo
/files/var/www/.htpasswd/foo = $apr1$e2WS6ARQ$lYhqy9CLmwlxR/07TLR46.
augtool> set /files/var/www/.htpasswd/foo bar
augtool> save
Saved 1 file(s)
$ cat /var/www/.htpasswd
foo:bar
(end code)
About: License
This file is licensed under the LGPL v2+, like the rest of Augeas.
*)
module Htpasswd =
autoload xfm
let entry = Build.key_value_line Rx.word Sep.colon (store Rx.space_in)
let lns = (Util.empty | Util.comment | entry)*
let filter = incl "/etc/httpd/htpasswd"
. incl "/etc/apache2/htpasswd"
. incl "/etc/rsyncd.secrets"
let xfm = transform lns filter

View File

@ -0,0 +1,206 @@
(* Apache HTTPD lens for Augeas
Authors:
David Lutterkort <lutter@redhat.com>
Francis Giraldeau <francis.giraldeau@usherbrooke.ca>
Raphael Pinson <raphink@gmail.com>
About: Reference
Online Apache configuration manual: http://httpd.apache.org/docs/trunk/
About: License
This file is licensed under the LGPL v2+.
About: Lens Usage
Sample usage of this lens in augtool
Apache configuration is represented by two main structures, nested sections
and directives. Sections are used as labels, while directives are kept as a
value. Sections and directives can have positional arguments inside values
of "arg" nodes. Arguments of sections must be the firsts child of the
section node.
This lens doesn't support automatic string quoting. Hence, the string must
be quoted when containing a space.
Create a new VirtualHost section with one directive:
> clear /files/etc/apache2/sites-available/foo/VirtualHost
> set /files/etc/apache2/sites-available/foo/VirtualHost/arg "172.16.0.1:80"
> set /files/etc/apache2/sites-available/foo/VirtualHost/directive "ServerAdmin"
> set /files/etc/apache2/sites-available/foo/VirtualHost/*[self::directive="ServerAdmin"]/arg "admin@example.com"
About: Configuration files
This lens applies to files in /etc/httpd and /etc/apache2. See <filter>.
*)
module Httpd =
autoload xfm
(******************************************************************
* Utilities lens
*****************************************************************)
let dels (s:string) = del s s
(* The continuation sequence that indicates that we should consider the
* next line part of the current line *)
let cont = /\\\\\r?\n/
(* Whitespace within a line: space, tab, and the continuation sequence *)
let ws = /[ \t]/ | cont
(* Any possible character - '.' does not match \n *)
let any = /(.|\n)/
(* Any character preceded by a backslash *)
let esc_any = /\\\\(.|\n)/
(* Newline sequence - both for Unix and DOS newlines *)
let nl = /\r?\n/
(* Whitespace at the end of a line *)
let eol = del (ws* . nl) "\n"
(* deal with continuation lines *)
let sep_spc = del ws+ " "
let sep_osp = del ws* ""
let sep_eq = del (ws* . "=" . ws*) "="
let nmtoken = /[a-zA-Z:_][a-zA-Z0-9:_.-]*/
let word = /[a-z][a-z0-9._-]*/i
(* A complete line that is either just whitespace or a comment that only
* contains whitespace *)
let empty = [ del (ws* . /#?/ . ws* . nl) "\n" ]
let indent = Util.indent
(* A comment that is not just whitespace. We define it in terms of the
* things that are not allowed as part of such a comment:
* 1) Starts with whitespace
* 2) Ends with whitespace, a backslash or \r
* 3) Unescaped newlines
*)
let comment =
let comment_start = del (ws* . "#" . ws* ) "# " in
let unesc_eol = /[^\]?/ . nl in
let w = /[^\t\n\r \\]/ in
let r = /[\r\\]/ in
let s = /[\t\r ]/ in
(*
* we'd like to write
* let b = /\\\\/ in
* let t = /[\t\n\r ]/ in
* let x = b . (t? . (s|w)* ) in
* but the definition of b depends on commit 244c0edd in 1.9.0 and
* would make the lens unusable with versions before 1.9.0. So we write
* x out which works in older versions, too
*)
let x = /\\\\[\t\n\r ]?[^\n\\]*/ in
let line = ((r . s* . w|w|r) . (s|w)* . x*|(r.s* )?).w.(s*.w)* in
[ label "#comment" . comment_start . store line . eol ]
(* borrowed from shellvars.aug *)
let char_arg_sec = /([^\\ '"\t\r\n>]|[^ '"\t\r\n>]+[^\\ \t\r\n>])|\\\\"|\\\\'|\\\\ /
let char_arg_wl = /([^\\ '"},\t\r\n]|[^ '"},\t\r\n]+[^\\ '"},\t\r\n])/
let dquot =
let no_dquot = /[^"\\\r\n]/
in /"/ . (no_dquot|esc_any)* . /"/
let dquot_msg =
let no_dquot = /([^ \t"\\\r\n]|[^"\\\r\n]+[^ \t"\\\r\n])/
in /"/ . (no_dquot|esc_any)* . no_dquot
let squot =
let no_squot = /[^'\\\r\n]/
in /'/ . (no_squot|esc_any)* . /'/
let comp = /[<>=]?=/
(******************************************************************
* Attributes
*****************************************************************)
(* The arguments for a directive come in two flavors: quoted with single or
* double quotes, or bare. Bare arguments may not start with a single or
* double quote; since we also treat "word lists" special, i.e. lists
* enclosed in curly braces, bare arguments may not start with those,
* either.
*
* Bare arguments may not contain unescaped spaces, but we allow escaping
* with '\\'. Quoted arguments can contain anything, though the quote must
* be escaped with '\\'.
*)
let bare = /([^{"' \t\n\r]|\\\\.)([^ \t\n\r]|\\\\.)*[^ \t\n\r\\]|[^{"' \t\n\r\\]/
let arg_quoted = [ label "arg" . store (dquot|squot) ]
let arg_bare = [ label "arg" . store bare ]
(* message argument starts with " but ends at EOL *)
let arg_dir_msg = [ label "arg" . store dquot_msg ]
let arg_wl = [ label "arg" . store (char_arg_wl+|dquot|squot) ]
(* comma-separated wordlist as permitted in the SSLRequire directive *)
let arg_wordlist =
let wl_start = dels "{" in
let wl_end = dels "}" in
let wl_sep = del /[ \t]*,[ \t]*/ ", "
in [ label "wordlist" . wl_start . arg_wl . (wl_sep . arg_wl)* . wl_end ]
let argv (l:lens) = l . (sep_spc . l)*
(* the arguments of a directive. We use this once we have parsed the name
* of the directive, and the space right after it. When dir_args is used,
* we also know that we have at least one argument. We need to be careful
* with the spacing between arguments: quoted arguments and word lists do
* not need to have space between them, but bare arguments do.
*
* Apache apparently is also happy if the last argument starts with a double
* quote, but has no corresponding closing duoble quote, which is what
* arg_dir_msg handles
*)
let dir_args =
let arg_nospc = arg_quoted|arg_wordlist in
(arg_bare . sep_spc | arg_nospc . sep_osp)* . (arg_bare|arg_nospc|arg_dir_msg)
let directive =
[ indent . label "directive" . store word . (sep_spc . dir_args)? . eol ]
let arg_sec = [ label "arg" . store (char_arg_sec+|comp|dquot|squot) ]
let section (body:lens) =
(* opt_eol includes empty lines *)
let opt_eol = del /([ \t]*#?[ \t]*\r?\n)*/ "\n" in
let inner = (sep_spc . argv arg_sec)? . sep_osp .
dels ">" . opt_eol . ((body|comment) . (body|empty|comment)*)? .
indent . dels "</" in
let kword = key (word - /perl/i) in
let dword = del (word - /perl/i) "a" in
[ indent . dels "<" . square kword inner dword . del />[ \t\n\r]*/ ">\n" ]
let perl_section = [ indent . label "Perl" . del /<perl>/i "<Perl>"
. store /[^<]*/
. del /<\/perl>/i "</Perl>" . eol ]
let rec content = section (content|directive)
| perl_section
let lns = (content|directive|comment|empty)*
let filter = (incl "/etc/apache2/apache2.conf") .
(incl "/etc/apache2/httpd.conf") .
(incl "/etc/apache2/ports.conf") .
(incl "/etc/apache2/conf.d/*") .
(incl "/etc/apache2/conf-available/*.conf") .
(incl "/etc/apache2/mods-available/*") .
(incl "/etc/apache2/sites-available/*") .
(incl "/etc/apache2/vhosts.d/*.conf") .
(incl "/etc/httpd/conf.d/*.conf") .
(incl "/etc/httpd/httpd.conf") .
(incl "/etc/httpd/conf/httpd.conf") .
(incl "/etc/httpd/conf.modules.d/*.conf") .
Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,185 @@
(* inetd.conf lens definition for Augeas
Auther: Matt Palmer <mpalmer@hezmatt.org>
Copyright (C) 2009 Matt Palmer, All Rights Reserved
This program is free software: you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License version 2.1 as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
Public License for more details.
You should have received a copy of the GNU General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>.
This lens parses /etc/inetd.conf. The current format is based on the
syntax documented in the inetd manpage shipped with Debian's openbsd-inetd
package version 0.20080125-2. Apologies if your inetd.conf doesn't follow
the same format.
Each top-level entry will have a key being that of the service name (the
first column in the service definition, which is the name or number of the
port that the service should listen on). The attributes for the service all
sit under that. In regular Augeas style, the order of the attributes
matter, and attempts to set things in a different order will fail miserably.
The defined attribute names (and the order in which they must appear) are as
follows (with mandatory parameters indicated by [*]):
address -- a sequence of IP addresses or hostnames on which this service
should listen.
socket[*] -- The type of the socket that will be created (either stream or
dgram, although the lens doesn't constrain the possibilities here)
protocol[*] -- The socket protocol. I believe that the usual possibilities
are "tcp", "udp", or "unix", but no restriction is made on what you
can actually put here.
sndbuf -- Specify a non-default size for the send buffer of the connection.
rcvbuf -- Specify a non-default size for the receive buffer of the connection.
wait[*] -- Whether to wait for new connections ("wait"), or just terminate
immediately ("nowait").
max -- The maximum number of times that a service can be invoked in one minute.
user[*] -- The user to run the service as.
group -- A group to set the running service to, rather than the primary
group of the previously specified user.
command[*] -- What program to run.
arguments -- A sequence of arguments to pass to the command.
In addition to this straightforward tree, inetd has the ability to set
"default" listen addresses; this is a little used feature which nonetheless
comes in handy sometimes. The key for entries of this type is "address"
, and the subtree should be a sequence of addresses. "*" can
always be used to return the default behaviour of listening on INADDR_ANY.
*)
module Inetd =
autoload xfm
(***************************
* PRIMITIVES
***************************)
(* Store whitespace *)
let wsp = del /[ \t]+/ " "
let sep = del /[ \t]+/ " "
let owsp(t:string) = del /[ \t]*/ t
(* It's the end of the line as we know it... doo, doo, dooooo *)
let eol = Util.eol
(* In the beginning, the earth was without form, and void *)
let empty = Util.empty
let comment = Util.comment
let del_str = Util.del_str
let address = [ seq "addrseq" . store /([a-zA-Z0-9.-]+|\[[A-Za-z0-9:?*%]+\]|\*)/ ]
let address_list = ( counter "addrseq" . (address . del_str ",")* . address )
let argument = [ seq "argseq" . store /[^ \t\n]+/ ]
let argument_list = ( counter "argseq" . [ label "arguments" . (argument . wsp)* . argument ] )
(***************************
* ELEMENTS
***************************)
let service (l:string) = ( label l . [label "address" . address_list . del_str ":" ]? . store /[^ \t\n\/:#]+/ )
let socket = [ label "socket" . store /[^ \t\n#]+/ ]
let protocol = ( [ label "protocol" . store /[^ \t\n,#]+/ ]
. [ del_str "," . key /sndbuf/ . del_str "=" . store /[^ \t\n,]+/ ]?
. [ del_str "," . key /rcvbuf/ . del_str "=" . store /[^ \t\n,]+/ ]?
)
let wait = ( [ label "wait" . store /(wait|nowait)/ ]
. [ del_str "." . label "max" . store /[0-9]+/ ]?
)
let usergroup = ( [ label "user" . store /[^ \t\n:.]+/ ]
. [ del /[:.]/ ":" . label "group" . store /[^ \t\n:.]+/ ]?
)
let command = ( [ label "command" . store /[^ \t\n]+/ ]
. (wsp . argument_list)?
)
(***************************
* SERVICE LINES
***************************)
let service_line = [ service "service"
. sep
. socket
. sep
. protocol
. sep
. wait
. sep
. usergroup
. sep
. command
. eol
]
(***************************
* RPC LINES
***************************)
let rpc_service = service "rpc_service" . Util.del_str "/"
. [ label "version" . store Rx.integer ]
let rpc_endpoint = [ label "endpoint-type" . store Rx.word ]
let rpc_protocol = Util.del_str "rpc/"
. (Build.opt_list
[label "protocol" . store /[^ \t\n,#]+/ ]
Sep.comma)
let rpc_line = [ rpc_service
. sep
. rpc_endpoint
. sep
. rpc_protocol
. sep
. wait
. sep
. usergroup
. sep
. command
. eol
]
(***************************
* DEFAULT LISTEN ADDRESSES
***************************)
let default_listen_address = [ label "address"
. address_list
. del_str ":"
. eol
]
(***********************
* LENS / FILTER
***********************)
let lns = (comment|empty|service_line|rpc_line|default_listen_address)*
let filter = incl "/etc/inetd.conf"
let xfm = transform lns filter

View File

@ -0,0 +1,555 @@
(*
Module: IniFile
Generic module to create INI files lenses
Author: Raphael Pinson <raphink@gmail.com>
About: License
This file is licensed under the LGPL v2+, like the rest of Augeas.
About: TODO
Things to add in the future
- Support double quotes in value
About: Lens usage
This lens is made to provide generic primitives to construct INI File lenses.
See <Puppet>, <PHP>, <MySQL> or <Dput> for examples of real life lenses using it.
About: Examples
The <Test_IniFile> file contains various examples and tests.
*)
module IniFile =
(************************************************************************
* Group: USEFUL PRIMITIVES
*************************************************************************)
(* Group: Internal primitives *)
(*
Variable: eol
End of line, inherited from <Util.eol>
*)
let eol = Util.doseol
(* Group: Separators *)
(*
Variable: sep
Generic separator
Parameters:
pat:regexp - the pattern to delete
default:string - the default string to use
*)
let sep (pat:regexp) (default:string)
= Sep.opt_space . del pat default
(*
Variable: sep_noindent
Generic separator, no indentation
Parameters:
pat:regexp - the pattern to delete
default:string - the default string to use
*)
let sep_noindent (pat:regexp) (default:string)
= del pat default
(*
Variable: sep_re
The default regexp for a separator
*)
let sep_re = /[=:]/
(*
Variable: sep_default
The default separator value
*)
let sep_default = "="
(* Group: Stores *)
(*
Variable: sto_to_eol
Store until end of line
*)
let sto_to_eol = Sep.opt_space . store Rx.space_in
(*
Variable: to_comment_re
Regex until comment
*)
let to_comment_re = /[^";# \t\n][^";#\n]*[^";# \t\n]|[^";# \t\n]/
(*
Variable: sto_to_comment
Store until comment
*)
let sto_to_comment = Sep.opt_space . store to_comment_re
(*
Variable: sto_multiline
Store multiline values
*)
let sto_multiline = Sep.opt_space
. store (to_comment_re
. (/[ \t]*\n/ . Rx.space . to_comment_re)*)
(*
Variable: sto_multiline_nocomment
Store multiline values without an end-of-line comment
*)
let sto_multiline_nocomment = Sep.opt_space
. store (Rx.space_in . (/[ \t]*\n/ . Rx.space . Rx.space_in)*)
(* Group: Define comment and defaults *)
(*
View: comment_noindent
Map comments into "#comment" nodes,
no indentation allowed
Parameters:
pat:regexp - pattern to delete before commented data
default:string - default pattern before commented data
Sample Usage:
(start code)
let comment = IniFile.comment_noindent "#" "#"
let comment = IniFile.comment_noindent IniFile.comment_re IniFile.comment_default
(end code)
*)
let comment_noindent (pat:regexp) (default:string) =
Util.comment_generic_seteol (pat . Rx.opt_space) default eol
(*
View: comment
Map comments into "#comment" nodes
Parameters:
pat:regexp - pattern to delete before commented data
default:string - default pattern before commented data
Sample Usage:
(start code)
let comment = IniFile.comment "#" "#"
let comment = IniFile.comment IniFile.comment_re IniFile.comment_default
(end code)
*)
let comment (pat:regexp) (default:string) =
Util.comment_generic_seteol (Rx.opt_space . pat . Rx.opt_space) default eol
(*
Variable: comment_re
Default regexp for <comment> pattern
*)
let comment_re = /[;#]/
(*
Variable: comment_default
Default value for <comment> pattern
*)
let comment_default = ";"
(*
View: empty_generic
Empty line, including empty comments
Parameters:
indent:regexp - the indentation regexp
comment_re:regexp - the comment separator regexp
*)
let empty_generic (indent:regexp) (comment_re:regexp) =
Util.empty_generic_dos (indent . comment_re? . Rx.opt_space)
(*
View: empty
Empty line
*)
let empty = empty_generic Rx.opt_space comment_re
(*
View: empty_noindent
Empty line, without indentation
*)
let empty_noindent = empty_generic "" comment_re
(************************************************************************
* Group: ENTRY
*************************************************************************)
(* Group: entry includes comments *)
(*
View: entry_generic_nocomment
A very generic INI File entry, not including comments
It allows to set the key lens (to set indentation
or subnodes linked to the key) as well as the comment
separator regexp, used to tune the store regexps.
Parameters:
kw:lens - lens to match the key, including optional indentation
sep:lens - lens to use as key/value separator
comment_re:regexp - comment separator regexp
comment:lens - lens to use as comment
Sample Usage:
> let entry = IniFile.entry_generic (key "setting") sep IniFile.comment_re comment
*)
let entry_generic_nocomment (kw:lens) (sep:lens)
(comment_re:regexp) (comment:lens) =
let bare_re_noquot = (/[^" \t\r\n]/ - comment_re)
in let bare_re = (/[^\r\n]/ - comment_re)+
in let no_quot = /[^"\r\n]*/
in let bare = Quote.do_dquote_opt_nil (store (bare_re_noquot . (bare_re* . bare_re_noquot)?))
in let quoted = Quote.do_dquote (store (no_quot . comment_re+ . no_quot))
in [ kw . sep . (Sep.opt_space . bare)? . (comment|eol) ]
| [ kw . sep . Sep.opt_space . quoted . (comment|eol) ]
(*
View: entry_generic
A very generic INI File entry
It allows to set the key lens (to set indentation
or subnodes linked to the key) as well as the comment
separator regexp, used to tune the store regexps.
Parameters:
kw:lens - lens to match the key, including optional indentation
sep:lens - lens to use as key/value separator
comment_re:regexp - comment separator regexp
comment:lens - lens to use as comment
Sample Usage:
> let entry = IniFile.entry_generic (key "setting") sep IniFile.comment_re comment
*)
let entry_generic (kw:lens) (sep:lens) (comment_re:regexp) (comment:lens) =
entry_generic_nocomment kw sep comment_re comment | comment
(*
View: entry
Generic INI File entry
Parameters:
kw:regexp - keyword regexp for the label
sep:lens - lens to use as key/value separator
comment:lens - lens to use as comment
Sample Usage:
> let entry = IniFile.entry setting sep comment
*)
let entry (kw:regexp) (sep:lens) (comment:lens) =
entry_generic (key kw) sep comment_re comment
(*
View: indented_entry
Generic INI File entry that might be indented with an arbitrary
amount of whitespace
Parameters:
kw:regexp - keyword regexp for the label
sep:lens - lens to use as key/value separator
comment:lens - lens to use as comment
Sample Usage:
> let entry = IniFile.indented_entry setting sep comment
*)
let indented_entry (kw:regexp) (sep:lens) (comment:lens) =
entry_generic (Util.indent . key kw) sep comment_re comment
(*
View: entry_multiline_generic
A very generic multiline INI File entry
It allows to set the key lens (to set indentation
or subnodes linked to the key) as well as the comment
separator regexp, used to tune the store regexps.
Parameters:
kw:lens - lens to match the key, including optional indentation
sep:lens - lens to use as key/value separator
comment_re:regexp - comment separator regexp
comment:lens - lens to use as comment
eol:lens - lens for end of line
Sample Usage:
> let entry = IniFile.entry_generic (key "setting") sep IniFile.comment_re comment comment_or_eol
*)
let entry_multiline_generic (kw:lens) (sep:lens) (comment_re:regexp)
(comment:lens) (eol:lens) =
let newline = /\r?\n[ \t]+/
in let bare =
let word_re_noquot = (/[^" \t\r\n]/ - comment_re)+
in let word_re = (/[^\r\n]/ - comment_re)+
in let base_re = (word_re_noquot . (word_re* . word_re_noquot)?)
in let sto_re = base_re . (newline . base_re)*
| (newline . base_re)+
in Quote.do_dquote_opt_nil (store sto_re)
in let quoted =
let no_quot = /[^"\r\n]*/
in let base_re = (no_quot . comment_re+ . no_quot)
in let sto_re = base_re . (newline . base_re)*
| (newline . base_re)+
in Quote.do_dquote (store sto_re)
in [ kw . sep . (Sep.opt_space . bare)? . eol ]
| [ kw . sep . Sep.opt_space . quoted . eol ]
| comment
(*
View: entry_multiline
Generic multiline INI File entry
Parameters:
kw:regexp - keyword regexp for the label
sep:lens - lens to use as key/value separator
comment:lens - lens to use as comment
*)
let entry_multiline (kw:regexp) (sep:lens) (comment:lens) =
entry_multiline_generic (key kw) sep comment_re comment (comment|eol)
(*
View: entry_multiline_nocomment
Generic multiline INI File entry without an end-of-line comment
Parameters:
kw:regexp - keyword regexp for the label
sep:lens - lens to use as key/value separator
comment:lens - lens to use as comment
*)
let entry_multiline_nocomment (kw:regexp) (sep:lens) (comment:lens) =
entry_multiline_generic (key kw) sep comment_re comment eol
(*
View: entry_list
Generic INI File list entry
Parameters:
kw:regexp - keyword regexp for the label
sep:lens - lens to use as key/value separator
sto:regexp - store regexp for the values
list_sep:lens - lens to use as list separator
comment:lens - lens to use as comment
*)
let entry_list (kw:regexp) (sep:lens) (sto:regexp) (list_sep:lens) (comment:lens) =
let list = counter "elem"
. Build.opt_list [ seq "elem" . store sto ] list_sep
in Build.key_value_line_comment kw sep (Sep.opt_space . list) comment
(*
View: entry_list_nocomment
Generic INI File list entry without an end-of-line comment
Parameters:
kw:regexp - keyword regexp for the label
sep:lens - lens to use as key/value separator
sto:regexp - store regexp for the values
list_sep:lens - lens to use as list separator
*)
let entry_list_nocomment (kw:regexp) (sep:lens) (sto:regexp) (list_sep:lens) =
let list = counter "elem"
. Build.opt_list [ seq "elem" . store sto ] list_sep
in Build.key_value_line kw sep (Sep.opt_space . list)
(*
Variable: entry_re
Default regexp for <entry> keyword
*)
let entry_re = ( /[A-Za-z][A-Za-z0-9._-]*/ )
(************************************************************************
* Group: RECORD
*************************************************************************)
(* Group: Title definition *)
(*
View: title
Title for <record>. This maps the title of a record as a node in the abstract tree.
Parameters:
kw:regexp - keyword regexp for the label
Sample Usage:
> let title = IniFile.title IniFile.record_re
*)
let title (kw:regexp)
= Util.del_str "[" . key kw
. Util.del_str "]". eol
(*
View: indented_title
Title for <record>. This maps the title of a record as a node in the abstract tree. The title may be indented with arbitrary amounts of whitespace
Parameters:
kw:regexp - keyword regexp for the label
Sample Usage:
> let title = IniFile.title IniFile.record_re
*)
let indented_title (kw:regexp)
= Util.indent . title kw
(*
View: title_label
Title for <record>. This maps the title of a record as a value in the abstract tree.
Parameters:
name:string - name for the title label
kw:regexp - keyword regexp for the label
Sample Usage:
> let title = IniFile.title_label "target" IniFile.record_label_re
*)
let title_label (name:string) (kw:regexp)
= label name
. Util.del_str "[" . store kw
. Util.del_str "]". eol
(*
View: indented_title_label
Title for <record>. This maps the title of a record as a value in the abstract tree. The title may be indented with arbitrary amounts of whitespace
Parameters:
name:string - name for the title label
kw:regexp - keyword regexp for the label
Sample Usage:
> let title = IniFile.title_label "target" IniFile.record_label_re
*)
let indented_title_label (name:string) (kw:regexp)
= Util.indent . title_label name kw
(*
Variable: record_re
Default regexp for <title> keyword pattern
*)
let record_re = ( /[^]\r\n\/]+/ - /#comment/ )
(*
Variable: record_label_re
Default regexp for <title_label> keyword pattern
*)
let record_label_re = /[^]\r\n]+/
(* Group: Record definition *)
(*
View: record_noempty
INI File Record with no empty lines allowed.
Parameters:
title:lens - lens to use for title. Use either <title> or <title_label>.
entry:lens - lens to use for entries in the record. See <entry>.
*)
let record_noempty (title:lens) (entry:lens)
= [ title
. entry* ]
(*
View: record
Generic INI File record
Parameters:
title:lens - lens to use for title. Use either <title> or <title_label>.
entry:lens - lens to use for entries in the record. See <entry>.
Sample Usage:
> let record = IniFile.record title entry
*)
let record (title:lens) (entry:lens)
= record_noempty title ( entry | empty )
(************************************************************************
* Group: GENERIC LENSES
*************************************************************************)
(*
Group: Lens definition
View: lns_noempty
Generic INI File lens with no empty lines
Parameters:
record:lens - record lens to use. See <record_noempty>.
comment:lens - comment lens to use. See <comment>.
Sample Usage:
> let lns = IniFile.lns_noempty record comment
*)
let lns_noempty (record:lens) (comment:lens)
= comment* . record*
(*
View: lns
Generic INI File lens
Parameters:
record:lens - record lens to use. See <record>.
comment:lens - comment lens to use. See <comment>.
Sample Usage:
> let lns = IniFile.lns record comment
*)
let lns (record:lens) (comment:lens)
= lns_noempty record (comment|empty)
(************************************************************************
* Group: READY-TO-USE LENSES
*************************************************************************)
let record_anon (entry:lens) = [ label "section" . value ".anon" . ( entry | empty )+ ]
(*
View: lns_loose
A loose, ready-to-use lens, featuring:
- sections as values (to allow '/' in names)
- support empty lines and comments
- support for [#;] as comment, defaulting to ";"
- .anon sections
- don't allow multiline values
- allow indented titles
- allow indented entries
*)
let lns_loose =
let l_comment = comment comment_re comment_default
in let l_sep = sep sep_re sep_default
in let l_entry = indented_entry entry_re l_sep l_comment
in let l_title = indented_title_label "section" (record_label_re - ".anon")
in let l_record = record l_title l_entry
in (record_anon l_entry)? . l_record*
(*
View: lns_loose_multiline
A loose, ready-to-use lens, featuring:
- sections as values (to allow '/' in names)
- support empty lines and comments
- support for [#;] as comment, defaulting to ";"
- .anon sections
- allow multiline values
*)
let lns_loose_multiline =
let l_comment = comment comment_re comment_default
in let l_sep = sep sep_re sep_default
in let l_entry = entry_multiline entry_re l_sep l_comment
in let l_title = title_label "section" (record_label_re - ".anon")
in let l_record = record l_title l_entry
in (record_anon l_entry)? . l_record*

View File

@ -0,0 +1,31 @@
(* Parsing /etc/inittab *)
module Inittab =
autoload xfm
let sep = Util.del_str ":"
let eol = Util.del_str "\n"
let id = /[^\/#:\n]{1,4}/
let value = /[^#:\n]*/
let comment = Util.comment|Util.empty
let record =
let field (name:string) = [ label name . store value ] in
let process = [ label "process" . store /[^#\n]*/ ] in
let eolcomment =
[ label "#comment" . del /#[ \t]*/ "# "
. store /([^ \t\n].*[^ \t\n]|[^ \t\n]?)/ ] in
[ key id . sep .
field "runlevels" . sep .
field "action" . sep .
process . eolcomment? . eol ]
let lns = ( comment | record ) *
let xfm = transform lns (incl "/etc/inittab")
(* Local Variables: *)
(* mode: caml *)
(* End: *)

View File

@ -0,0 +1,59 @@
(*
Module: Inputrc
Parses /etc/inputrc
Author: Raphael Pinson <raphink@gmail.com>
About: Reference
This lens tries to keep as close as possible to `man 3 readline` where possible.
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/inputrc. See <filter>.
About: Examples
The <Test_Inputrc> file contains various examples and tests.
*)
module Inputrc =
autoload xfm
(* View: entry
An inputrc mapping entry *)
let entry =
let mapping = [ label "mapping" . store /[A-Za-z0-9_."\*\/+\,\\-]+/ ]
in [ label "entry"
. Util.del_str "\"" . store /[^" \t\n]+/
. Util.del_str "\":" . Sep.space
. mapping
. Util.eol ]
(* View: variable
An inputrc variable declaration *)
let variable = [ Util.del_str "set" . Sep.space
. key (Rx.word - "entry") . Sep.space
. store Rx.word . Util.eol ]
(* View: condition
An "if" declaration, recursive *)
let rec condition = [ Util.del_str "$if" . label "@if"
. Sep.space . store Rx.space_in . Util.eol
. (Util.empty | Util.comment | condition | variable | entry)*
. [ Util.del_str "$else" . label "@else" . Util.eol
. (Util.empty | Util.comment | condition | variable | entry)* ] ?
. Util.del_str "$endif" . Util.eol ]
(* View: lns
The inputrc lens *)
let lns = (Util.empty | Util.comment | condition | variable | entry)*
(* Variable: filter *)
let filter = incl "/etc/inputrc"
let xfm = transform lns filter

View File

@ -0,0 +1,131 @@
(* Interfaces module for Augeas
Author: Free Ekanayaka <free@64studio.com>
Reference: man interfaces
*)
module Interfaces =
autoload xfm
(************************************************************************
* USEFUL PRIMITIVES
*************************************************************************)
let eol = Util.eol
(* Define separators *)
(* a line can be extended across multiple lines by making the last *)
(* character a backslash *)
let sep_spc = del /([ \t]+|[ \t]*\\\\\n[ \t]*)/ " "
(* Define fields *)
let sto_to_eol = store /([^\\ \t\n].*[^\\ \t\n]|[^\\ \t\n])/ . eol
let sto_to_spc = store /[^\\ \t\n]+/
(* Define comments and empty lines *)
(* note that the comment definition from Util does not support *)
(* splitting lines with a backlash *)
let comment = Util.comment
let empty = Util.empty
(* Define tree stanza_ids *)
let stanza_id (t:string) = key t . sep_spc . sto_to_spc
let stanza_param (l:string) = [ sep_spc . label l . sto_to_spc ]
(* Define reserved words and multi-value options *)
let stanza_word =
/(source(-directory)?|iface|auto|allow-[a-z-]+|mapping|bond-slaves|bridge-ports)/
(* Define stanza option indentation *)
let stanza_indent = del /[ \t]*/ " "
(* Define additional lines for multi-line stanzas *)
let stanza_option = [ stanza_indent
. key ( /[a-z0-9_-]+/ - stanza_word )
. sep_spc
. sto_to_eol ]
(* Define space-separated array *)
let array (r:regexp) (t:string) = del r t . label t . counter t
. [ sep_spc . seq t . sto_to_spc ]+
(************************************************************************
* AUTO
*************************************************************************)
let auto = [ array /(allow-)?auto/ "auto" . eol ]
(************************************************************************
* GENERIC ALLOW
*************************************************************************)
let allow = [ key ( /allow-[a-z-]+/ - "allow-auto" )
. counter "allow_seq"
. [ sep_spc . seq "allow_seq" . sto_to_spc ]+
. eol ]
(************************************************************************
* MAPPING
*************************************************************************)
let mapping = [ stanza_id "mapping"
. eol
. (stanza_option|comment|empty)+ ]
(************************************************************************
* IFACE
*************************************************************************)
let multi_option (t:string) = [ stanza_indent . array t t . eol ]
let iface = [ Util.indent
. stanza_id "iface"
. stanza_param "family"
. stanza_param "method"
. eol
. ( stanza_option
| multi_option "bond-slaves"
| multi_option "bridge-ports"
| comment
| empty )* ]
(************************************************************************
* SOURCE
*************************************************************************)
let source = [ key "source" . sep_spc . sto_to_eol ]
(************************************************************************
* SOURCE-DIRECTORY
*************************************************************************)
let source_directory = [ key "source-directory" . sep_spc . sto_to_eol ]
(************************************************************************
* STANZAS
*************************************************************************)
(* The auto and hotplug stanzas always consist of one line only, while
iface and mapping can spand along more lines. Comment nodes are
inserted in the tree as direct children of the root node only when they
come after an auto or hotplug stanza, otherwise they are considered part
of an iface or mapping block *)
let stanza_single = (auto|allow|source|source_directory) . (comment|empty)*
let stanza_multi = iface|mapping
(************************************************************************
* LENS & FILTER
*************************************************************************)
let lns = (comment|empty)* . (stanza_multi | stanza_single)*
let filter = (incl "/etc/network/interfaces")
. (incl "/etc/network/interfaces.d/*")
. Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,10 @@
module IPRoute2 =
autoload xfm
let empty = [ del /[ \t]*#?[ \t]*\n/ "\n" ]
let id = Rx.hex | Rx.integer
let record = [ key id . del /[ \t]+/ "\t" . store /[a-zA-Z0-9\/-]+/ . Util.comment_or_eol ]
let lns = ( empty | Util.comment | record ) *
let xfm = transform lns (incl "/etc/iproute2/*" . Util.stdexcl)

View File

@ -0,0 +1,87 @@
module Iptables =
autoload xfm
(*
Module: Iptables
Parse the iptables file format as produced by iptables-save. The
resulting tree is fairly simple; in particular a rule is simply
a long list of options/switches and their values (if any)
This lens should be considered experimental
*)
let comment = Util.comment
let empty = Util.empty
let eol = Util.eol
let spc = Util.del_ws_spc
let dels = Util.del_str
let chain_name = store /[A-Za-z0-9_-]+/
let chain =
let policy = [ label "policy" . store /ACCEPT|DROP|REJECT|-/ ] in
let counters_eol = del /[ \t]*(\[[0-9:]+\])?[ \t]*\n/ "\n" in
[ label "chain" .
dels ":" . chain_name . spc . policy . counters_eol ]
let param (long:string) (short:string) =
[ label long .
spc . del (/--/ . long | /-/ . short) ("-" . short) . spc .
store /(![ \t]*)?[^ \t\n!-][^ \t\n]*/ ]
(* A negatable parameter, which can either be FTW
! --param arg
or
--param ! arg
*)
let neg_param (long:string) (short:string) =
[ label long .
[ spc . dels "!" . label "not" ]? .
spc . del (/--/ . long | /-/ . short) ("-" . short) . spc .
store /(![ \t]*)?[^ \t\n!-][^ \t\n]*/ ]
let tcp_flags =
let flags = /SYN|ACK|FIN|RST|URG|PSH|ALL|NONE/ in
let flag_list (name:string) =
Build.opt_list [label name . store flags] (dels ",") in
[ label "tcp-flags" .
spc . dels "--tcp-flags" .
spc . flag_list "mask" . spc . flag_list "set" ]
(* misses --set-counters *)
let ipt_match =
let any_key = /[a-zA-Z-][a-zA-Z0-9-]+/ -
/protocol|source|destination|jump|goto|in-interface|out-interface|fragment|match|tcp-flags/ in
let any_val = /([^" \t\n!-][^ \t\n]*)|"([^"\\\n]|\\\\.)*"/ in
let any_param =
[ [ spc . dels "!" . label "not" ]? .
spc . dels "--" . key any_key . (spc . store any_val)? ] in
(neg_param "protocol" "p"
|neg_param "source" "s"
|neg_param "destination" "d"
|param "jump" "j"
|param "goto" "g"
|neg_param "in-interface" "i"
|neg_param "out-interface" "o"
|neg_param "fragment" "f"
|param "match" "m"
|tcp_flags
|any_param)*
let chain_action (n:string) (o:string) =
[ label n .
del (/--/ . n | o) o .
spc . chain_name . ipt_match . eol ]
let table_rule = chain_action "append" "-A"
| chain_action "insert" "-I"
| empty
let table = [ del /\*/ "*" . label "table" . store /[a-z]+/ . eol .
(chain|comment|table_rule)* .
dels "COMMIT" . eol ]
let lns = (comment|empty|table)*
let xfm = transform lns (incl "/etc/sysconfig/iptables"
. incl "/etc/sysconfig/iptables.save"
. incl "/etc/iptables-save")

View File

@ -0,0 +1,28 @@
(*
Module: Iscsid
Parses iscsid configuration file
Author: Joey Boggs <jboggs@redhat.com>
About: Reference
This lens is targeted at /etc/iscsi/iscsid.conf
*)
module Iscsid =
autoload xfm
let filter = incl "/etc/iscsi/iscsid.conf"
let eol = Util.eol
let indent = Util.indent
let key_re = /[][A-Za-z0-9_.-]+/
let eq = del /[ \t]*=[ \t]*/ " = "
let value_re = /[^ \t\n](.*[^ \t\n])?/
let comment = [ indent . label "#comment" . del /[#;][ \t]*/ "# "
. store /([^ \t\n].*[^ \t\n]|[^ \t\n])/ . eol ]
let empty = Util.empty
let kv = [ indent . key key_re . eq . store value_re . eol ]
let lns = (empty | comment | kv) *
let xfm = transform lns filter

View File

@ -0,0 +1,36 @@
(* Module Jaas *)
(* Original Author: Simon Vocella <voxsim@gmail.com> *)
(* Updated by: Steve Shipway <steve@steveshipway.org> *)
(* Changes: allow comments within Modules, allow optionless flags, *)
(* allow options without linebreaks, allow naked true/false options *)
(* Trailing ';' terminator should not be included in option value *)
(* Note: requires latest Util.aug for multiline comments to work *)
module Jaas =
autoload xfm
let space_equal = del (/[ \t]*/ . "=" . /[ \t]*/) (" = ")
let lbrace = del (/[ \t\n]*\{[ \t]*\n/) " {\n"
let rbrace = del (/[ \t]*}[ \t]*;/) " };"
let word = /[A-Za-z0-9_.-]+/
let wsnl = del (/[ \t\n]+/) ("\n")
let endflag = del ( /[ \t]*;/ ) ( ";" )
let value_re =
let value_squote = /'[^\n']*'/
in let value_dquote = /"[^\n"]*"/
in let value_tf = /(true|false)/
in value_squote | value_dquote | value_tf
let moduleOption = [ wsnl . key word . space_equal . (store value_re) ]
let moduleSuffix = ( moduleOption | Util.eol . Util.comment_c_style | Util.comment_multiline )
let flag = [ Util.del_ws_spc . label "flag" . (store word) . moduleSuffix* . endflag ]
let loginModuleClass = [( Util.del_opt_ws "" . label "loginModuleClass" . (store word) . flag ) ]
let content = (Util.empty | Util.comment_c_style | Util.comment_multiline | loginModuleClass)*
let loginModule = [Util.del_opt_ws "" . label "login" . (store word . lbrace) . (content . rbrace)]
let lns = (Util.empty | Util.comment_c_style | Util.comment_multiline | loginModule)*
let filter = incl "/opt/shibboleth-idp/conf/login.config"
let xfm = transform lns filter

View File

@ -0,0 +1,56 @@
(*
Module: JettyRealm
JettyRealm Properties for Augeas
Author: Brian Redbeard <redbeard@dead-city.org>
About: Reference
This lens ensures that properties files for JettyRealms are properly
handled by Augeas.
About: License
This file is licensed under the LGPL License.
About: Lens Usage
Sample usage of this lens in augtool:
* Create a new user
> ins user after /files/etc/activemq/jetty-realm.properties/user
> set /files/etc/activemq/jetty-realm.properties/user[last()]/username redbeard
> set /files/etc/activemq/jetty-realm.properties/user[last()]/password testing
> set /files/etc/activemq/jetty-realm.properties/user[last()]/realm admin
...
* Delete the user named sample_user
> rm /files/etc/activemq/jetty-realm.properties/user[*][username = "sample_user"]
Saving your file:
> save
About: Configuration files
This lens applies to jetty-realm.properties files. See <filter>.
*)
module JettyRealm =
autoload xfm
(* View: comma_sep *)
let comma_sep = del /,[ \t]*/ ", "
(* View: realm_entry *)
let realm_entry = [ label "user" .
[ label "username" . store Rx.word ] . del /[ \t]*:[ \t]*/ ": " .
[ label "password" . store Rx.word ] .
[ label "realm" . comma_sep . store Rx.word ]* .
Util.eol ]
(* View: lns *)
let lns = ( Util.comment | Util.empty | realm_entry )*
(* Variable: filter *)
let filter = incl "/etc/activemq/jetty-realm.properties"
let xfm = transform lns filter

View File

@ -0,0 +1,58 @@
(*
Module: JMXAccess
JMXAccess module for Augeas
Author: Brian Redbeard <redbeard@dead-city.org>
About: Reference
This lens ensures that files included in JMXAccess are properly
handled by Augeas.
About: License
This file is licensed under the LGPL License.
About: Lens Usage
Sample usage of this lens in augtool:
* Create a new user
> ins user after /files/etc/activemq/jmx.access
> set /files/etc/activemq/jmx.password/user[last()]/username redbeard
> set /files/etc/activemq/jmx.password/user[last()]/access readonly
...
* Delete the user named sample_user
> rm /files/etc/activemq/jmx.password/user[*][username = "sample_user"]
Saving your file:
> save
About: Configuration files
This lens applies to relevant conf files located in /etc/activemq/
The following views correspond to the related files:
* access_entry:
/etc/activemq/jmx.access
See <filter>.
*)
module JMXAccess =
autoload xfm
(* View: access_entry *)
let access_entry = [ label "user" .
[ label "username" . store Rx.word ] . Sep.space .
[ label "access" . store /(readonly|readwrite)/i ] . Util.eol ]
(* View: lns *)
let lns = ( Util.comment | Util.empty | access_entry )*
(* Variable: filter *)
let filter = incl "/etc/activemq/jmx.access"
let xfm = transform lns filter

View File

@ -0,0 +1,56 @@
(*
Module: JMXPassword
JMXPassword for Augeas
Author: Brian Redbeard <redbeard@dead-city.org>
About: Reference
This lens ensures that files included in JMXPassword are properly
handled by Augeas.
About: License
This file is licensed under the LGPL License.
About: Lens Usage
Sample usage of this lens in augtool:
* Create a new user
> ins user after /files/etc/activemq/jmx.password
> set /files/etc/activemq/jmx.password/user[last()]/username redbeard
> set /files/etc/activemq/jmx.password/user[last()]/password testing
...
* Delete the user named sample_user
> rm /files/etc/activemq/jmx.password/user[*][username = "sample_user"]
Saving your file:
> save
About: Configuration files
This lens applies to relevant conf files located in /etc/activemq/
The following views correspond to the related files:
* pass_entry:
/etc/activemq/jmx.password
See <filter>.
*)
module JMXPassword =
autoload xfm
(* View: pass_entry *)
let pass_entry = [ label "user" .
[ label "username" . store Rx.word ] . Sep.space .
[ label "password" . store Rx.no_spaces ] . Util.eol ]
(* View: lns *)
let lns = ( Util.comment | Util.empty | pass_entry )*
(* Variable: filter *)
let filter = incl "/etc/activemq/jmx.password"
let xfm = transform lns filter

View File

@ -0,0 +1,50 @@
module Json =
(* A generic lens for Json files *)
(* Based on the following grammar from http://www.json.org/ *)
(* Object ::= '{'Members ? '}' *)
(* Members ::= Pair+ *)
(* Pair ::= String ':' Value *)
(* Array ::= '[' Elements ']' *)
(* Elements ::= Value ( "," Value )* *)
(* Value ::= String | Number | Object | Array | "true" | "false" | "null" *)
(* String ::= "\"" Char* "\"" *)
(* Number ::= /-?[0-9]+(\.[0-9]+)?([eE][+-]?[0-9]+)?/ *)
let ws = del /[ \t\n]*/ ""
let comment = Util.empty_c_style | Util.comment_c_style | Util.comment_multiline
let comments = comment* . Sep.opt_space
let comma = Util.del_str "," . comments
let colon = Util.del_str ":" . comments
let lbrace = Util.del_str "{" . comments
let rbrace = Util.del_str "}"
let lbrack = Util.del_str "[" . comments
let rbrack = Util.del_str "]"
(* This follows the definition of 'string' at https://www.json.org/
It's a little wider than what's allowed there as it would accept
nonsensical \u escapes *)
let str_store = Quote.dquote . store /([^\\"]|\\\\["\/bfnrtu\\])*/ . Quote.dquote
let number = [ label "number" . store /-?[0-9]+(\.[0-9]+)?([eE][+-]?[0-9]+)?/
. comments ]
let str = [ label "string" . str_store . comments ]
let const (r:regexp) = [ label "const" . store r . comments ]
let fix_value (value:lens) =
let array = [ label "array" . lbrack
. ( ( Build.opt_list value comma . rbrack . comments )
| (rbrack . ws) ) ]
in let pair = [ label "entry" . str_store . ws . colon . value ]
in let obj = [ label "dict" . lbrace
. ( ( Build.opt_list pair comma. rbrace . comments )
| (rbrace . ws ) ) ]
in (str | number | obj | array | const /true|false|null/)
(* Process arbitrarily deeply nested JSON objects *)
let rec rlns = fix_value rlns
let lns = comments . rlns

View File

@ -0,0 +1,83 @@
(*
Module: Kdump
Parses /etc/kdump.conf
Author: Roman Rakus <rrakus@redhat.com>
About: References
manual page kdump.conf(5)
About: License
This file is licenced under the LGPL v2+, like the rest of Augeas.
About: Configuration files
This lens applies to /etc/kdump.conf. See <filter>.
*)
module Kdump =
autoload xfm
(************************************************************************
* Group: USEFUL PRIMITIVES
*************************************************************************)
let empty = Util.empty
let comment = Util.comment
let value_to_eol = store /[^ \t\n#][^\n#]*[^ \t\n#]|[^ \t\n#]/
let int_to_eol = store Rx.integer
let delimiter = Util.del_ws_spc
let eol = Util.eol
let value_to_spc = store Rx.neg1
let key_to_space = key /[A-Za-z0-9_.\$-]+/
let eq = Sep.equal
(************************************************************************
* Group: ENTRY TYPES
*************************************************************************)
let list (kw:string) = counter kw
. Build.key_value_line_comment kw delimiter
(Build.opt_list [ seq kw . value_to_spc ] delimiter)
comment
let mdl_key_value = [ delimiter . key_to_space . ( eq . value_to_spc)? ]
let mdl_options = [ key_to_space . mdl_key_value+ ]
let mod_options = [ key "options" . delimiter . mdl_options . (comment|eol) ]
(************************************************************************
* Group: ENTRIES
*************************************************************************)
(* Got from mount(8) *)
let fs_types = "adfs" | "affs" | "autofs" | "cifs" | "coda" | "coherent"
| "cramfs" | "debugfs" | "devpts" | "efs" | "ext" | "ext2"
| "ext3" | "ext4" | "hfs" | "hfsplus" | "hpfs" | "iso9660"
| "jfs" | "minix" | "msdos" | "ncpfs" | "nfs" | "nfs4" | "ntfs"
| "proc" | "qnx4" | "ramfs" | "reiserfs" | "romfs" | "squashfs"
| "smbfs" | "sysv" | "tmpfs" | "ubifs" | "udf" | "ufs" | "umsdos"
| "usbfs" | "vfat" | "xenix" | "xfs" | "xiafs"
let simple_kws = "raw" | "net" | "path" | "core_collector" | "kdump_post"
| "kdump_pre" | "default" | "ssh" | "sshkey" | "dracut_args"
| "fence_kdump_args"
let int_kws = "force_rebuild" | "override_resettable" | "debug_mem_level"
| "link_delay" | "disk_timeout"
let option = Build.key_value_line_comment ( simple_kws | fs_types )
delimiter value_to_eol comment
| Build.key_value_line_comment int_kws delimiter int_to_eol comment
| list "extra_bins"
| list "extra_modules"
| list "blacklist"
| list "fence_kdump_nodes"
| mod_options
(* View: lns
The options lens
*)
let lns = ( empty | comment | option )*
let filter = incl "/etc/kdump.conf"
let xfm = transform lns filter

View File

@ -0,0 +1,348 @@
(*
Module: Keepalived
Parses /etc/keepalived/keepalived.conf
Author: Raphael Pinson <raphink@gmail.com>
About: Reference
This lens tries to keep as close as possible to `man 5 keepalived.conf` where possible.
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/keepalived/keepalived.conf. See <filter>.
About: Examples
The <Test_Keepalived> file contains various examples and tests.
*)
module Keepalived =
autoload xfm
(************************************************************************
* Group: USEFUL PRIMITIVES
*************************************************************************)
(* Group: Comments and empty lines *)
(* View: indent *)
let indent = Util.indent
(* View: eol *)
let eol = Util.eol
(* View: opt_eol *)
let opt_eol = del /[ \t]*\n?/ " "
(* View: sep_spc *)
let sep_spc = Sep.space
(* View: comment
Map comments in "#comment" nodes *)
let comment = Util.comment_generic /[ \t]*[#!][ \t]*/ "# "
(* View: comment_eol
Map comments at eol *)
let comment_eol = Util.comment_generic /[ \t]*[#!][ \t]*/ " # "
(* View: comment_or_eol
A <comment_eol> or <eol> *)
let comment_or_eol = comment_eol | (del /[ \t]*[#!]?\n/ "\n")
(* View: empty
Map empty lines *)
let empty = Util.empty
(* View: sto_email_addr *)
let sto_email_addr = store Rx.email_addr
(* Variable: word *)
let word = Rx.word
(* Variable: word_slash *)
let word_slash = word | "/"
(* View: sto_word *)
let sto_word = store word
(* View: sto_num *)
let sto_num = store Rx.relinteger
(* View: sto_ipv6 *)
let sto_ipv6 = store Rx.ipv6
(* View: sto_to_eol *)
let sto_to_eol = store /[^#! \t\n][^#!\n]*[^#! \t\n]|[^#! \t\n]/
(* View: field *)
let field (kw:regexp) (sto:lens) = indent . Build.key_value_line_comment kw sep_spc sto comment_eol
(* View: flag
A single word *)
let flag (kw:regexp) = [ indent . key kw . comment_or_eol ]
(* View: ip_port
An IP <space> port pair *)
let ip_port = [ label "ip" . sto_word ] . sep_spc . [ label "port" . sto_num ]
(* View: lens_block
A generic block with a title lens.
The definition is very similar to Build.block_newlines
but uses a different type of <comment>. *)
let lens_block (title:lens) (sto:lens) =
[ indent . title
. Build.block_newlines sto comment . eol ]
(* View: block
A simple block with just a block title *)
let block (kw:regexp) (sto:lens) = lens_block (key kw) sto
(* View: named_block
A block with a block title and name *)
let named_block (kw:string) (sto:lens) = lens_block (key kw . sep_spc . sto_word) sto
(* View: named_block_arg_title
A title lens for named_block_arg *)
let named_block_arg_title (kw:string) (name:string) (arg:string) =
key kw . sep_spc
. [ label name . sto_word ]
. sep_spc
. [ label arg . sto_word ]
(* View: named_block_arg
A block with a block title, a name and an argument *)
let named_block_arg (kw:string) (name:string) (arg:string) (sto:lens) =
lens_block (named_block_arg_title kw name arg) sto
(************************************************************************
* Group: GLOBAL CONFIGURATION
*************************************************************************)
(* View: email
A simple email address entry *)
let email = [ indent . label "email" . sto_email_addr . comment_or_eol ]
(* View: global_defs_field
Possible fields in the global_defs block *)
let global_defs_field =
let word_re = "smtp_server"|"lvs_id"|"router_id"|"vrrp_mcast_group4"
in let ipv6_re = "vrrp_mcast_group6"
in let num_re = "smtp_connect_timeout"
in block "notification_email" email
| field "notification_email_from" sto_email_addr
| field word_re sto_word
| field num_re sto_num
| field ipv6_re sto_ipv6
(* View: global_defs
A global_defs block *)
let global_defs = block "global_defs" global_defs_field
(* View: prefixlen
A prefix for IP addresses *)
let prefixlen = [ label "prefixlen" . Util.del_str "/" . sto_num ]
(* View: ipaddr
An IP address or range with an optional mask *)
let ipaddr = label "ipaddr" . store /[0-9.-]+/ . prefixlen?
(* View: ipdev
A device for IP addresses *)
let ipdev = [ key "dev" . sep_spc . sto_word ]
(* View: static_ipaddress_field
The whole string is fed to ip addr add.
You can truncate the string anywhere you like and let ip addr add use defaults for the rest of the string.
To be refined with fields according to `ip addr help`.
*)
let static_ipaddress_field = [ indent . ipaddr
. (sep_spc . ipdev)?
. comment_or_eol ]
(* View: static_routes_field
src $SRC_IP to $DST_IP dev $SRC_DEVICE
*)
let static_routes_field = [ indent . label "route"
. [ key "src" . sto_word ] . sep_spc
. [ key "to" . sto_word ] . sep_spc
. [ key "dev" . sto_word ] . comment_or_eol ]
(* View: static_routes *)
let static_routes = block "static_ipaddress" static_ipaddress_field
| block "static_routes" static_routes_field
(* View: global_conf
A global configuration entry *)
let global_conf = global_defs | static_routes
(************************************************************************
* Group: VRRP CONFIGURATION
*************************************************************************)
(*View: vrrp_sync_group_field *)
let vrrp_sync_group_field =
let to_eol_re = /notify(_master|_backup|_fault)?/
in let flag_re = "smtp_alert"
in field to_eol_re sto_to_eol
| flag flag_re
| block "group" [ indent . key word . comment_or_eol ]
(* View: vrrp_sync_group *)
let vrrp_sync_group = named_block "vrrp_sync_group" vrrp_sync_group_field
(* View: vrrp_instance_field *)
let vrrp_instance_field =
let word_re = "state" | "interface" | "lvs_sync_daemon_interface"
in let num_re = "virtual_router_id" | "priority" | "advert_int" | /garp_master_(delay|repeat|refresh|refresh_repeat)/
in let to_eol_re = /notify(_master|_backup|_fault)?/ | /(mcast|unicast)_src_ip/
in let flag_re = "smtp_alert" | "nopreempt" | "ha_suspend" | "debug" | "use_vmac" | "vmac_xmit_base" | "native_ipv6" | "dont_track_primary" | "preempt_delay"
in field word_re sto_word
| field num_re sto_num
| field to_eol_re sto_to_eol
| flag flag_re
| block "authentication" (
field /auth_(type|pass)/ sto_word
)
| block "virtual_ipaddress" static_ipaddress_field
| block /track_(interface|script)/ ( flag word )
| block "unicast_peer" static_ipaddress_field
(* View: vrrp_instance *)
let vrrp_instance = named_block "vrrp_instance" vrrp_instance_field
(* View: vrrp_script_field *)
let vrrp_script_field =
let num_re = "interval" | "weight" | "fall" | "raise"
in let to_eol_re = "script"
in field to_eol_re sto_to_eol
| field num_re sto_num
(* View: vrrp_script *)
let vrrp_script = named_block "vrrp_script" vrrp_script_field
(* View: vrrpd_conf
contains subblocks of VRRP synchronization group(s) and VRRP instance(s) *)
let vrrpd_conf = vrrp_sync_group | vrrp_instance | vrrp_script
(************************************************************************
* Group: REAL SERVER CHECKS CONFIGURATION
*************************************************************************)
(* View: tcp_check_field *)
let tcp_check_field =
let word_re = "bindto"
in let num_re = /connect_(timeout|port)/
in field word_re sto_word
| field num_re sto_num
(* View: misc_check_field *)
let misc_check_field =
let flag_re = "misc_dynamic"
in let num_re = "misc_timeout"
in let to_eol_re = "misc_path"
in field num_re sto_num
| flag flag_re
| field to_eol_re sto_to_eol
(* View: smtp_host_check_field *)
let smtp_host_check_field =
let word_re = "connect_ip" | "bindto"
in let num_re = "connect_port"
in field word_re sto_word
| field num_re sto_num
(* View: smtp_check_field *)
let smtp_check_field =
let word_re = "connect_ip" | "bindto"
in let num_re = "connect_timeout" | "retry" | "delay_before_retry"
in let to_eol_re = "helo_name"
in field word_re sto_word
| field num_re sto_num
| field to_eol_re sto_to_eol
| block "host" smtp_host_check_field
(* View: http_url_check_field *)
let http_url_check_field =
let word_re = "digest"
in let num_re = "status_code"
in let to_eol_re = "path"
in field word_re sto_word
| field num_re sto_num
| field to_eol_re sto_to_eol
(* View: http_check_field *)
let http_check_field =
let num_re = /connect_(timeout|port)/ | "nb_get_retry" | "delay_before_retry"
in field num_re sto_num
| block "url" http_url_check_field
(* View: real_server_field *)
let real_server_field =
let num_re = "weight"
in let flag_re = "inhibit_on_failure"
in let to_eol_re = /notify_(up|down)/
in field num_re sto_num
| flag flag_re
| field to_eol_re sto_to_eol
| block "TCP_CHECK" tcp_check_field
| block "MISC_CHECK" misc_check_field
| block "SMTP_CHECK" smtp_check_field
| block /(HTTP|SSL)_GET/ http_check_field
(************************************************************************
* Group: LVS CONFIGURATION
*************************************************************************)
(* View: virtual_server_field *)
let virtual_server_field =
let num_re = "delay_loop" | "persistence_timeout" | "quorum" | "hysteresis"
in let word_re = /lb_(algo|kind)/ | "nat_mask" | "protocol" | "persistence_granularity"
| "virtualhost"
in let flag_re = "ops" | "ha_suspend" | "alpha" | "omega"
in let to_eol_re = /quorum_(up|down)/
in let ip_port_re = "sorry_server"
in field num_re sto_num
| field word_re sto_word
| flag flag_re
| field to_eol_re sto_to_eol
| field ip_port_re ip_port
| named_block_arg "real_server" "ip" "port" real_server_field
(* View: virtual_server *)
let virtual_server = named_block_arg "virtual_server" "ip" "port" virtual_server_field
(* View: virtual_server_group_field *)
let virtual_server_group_field = [ indent . label "vip"
. [ ipaddr ]
. sep_spc
. [ label "port" . sto_num ]
. comment_or_eol ]
(* View: virtual_server_group *)
let virtual_server_group = named_block "virtual_server_group" virtual_server_group_field
(* View: lvs_conf
contains subblocks of Virtual server group(s) and Virtual server(s) *)
let lvs_conf = virtual_server | virtual_server_group
(* View: lns
The keepalived lens
*)
let lns = ( empty | comment | global_conf | vrrpd_conf | lvs_conf )*
(* Variable: filter *)
let filter = incl "/etc/keepalived/keepalived.conf"
let xfm = transform lns filter

View File

@ -0,0 +1,70 @@
(*
Module: Known_Hosts
Parses SSH known_hosts files
Author: Raphaël Pinson <raphink@gmail.com>
About: Reference
This lens manages OpenSSH's known_hosts files. See `man 8 sshd` for reference.
About: License
This file is licenced under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
Sample usage of this lens in augtool:
* Get a key by name from ssh_known_hosts
> print /files/etc/ssh_known_hosts/*[.="foo.example.com"]
...
* Change a host's key
> set /files/etc/ssh_known_hosts/*[.="foo.example.com"]/key "newkey"
About: Configuration files
This lens applies to SSH known_hosts files. See <filter>.
*)
module Known_Hosts =
autoload xfm
(* View: marker
The marker is optional, but if it is present then it must be one of
“@cert-authority”, to indicate that the line contains a certification
authority (CA) key, or “@revoked”, to indicate that the key contained
on the line is revoked and must not ever be accepted.
Only one marker should be used on a key line.
*)
let marker = [ key /@(revoked|cert-authority)/ . Sep.space ]
(* View: type
Bits, exponent, and modulus are taken directly from the RSA host key;
they can be obtained, for example, from /etc/ssh/ssh_host_key.pub.
The optional comment field continues to the end of the line, and is not used.
*)
let type = [ label "type" . store Rx.neg1 ]
(* View: entry
A known_hosts entry *)
let entry =
let alias = [ label "alias" . store Rx.neg1 ]
in let key = [ label "key" . store Rx.neg1 ]
in [ Util.indent . seq "entry" . marker?
. store Rx.neg1
. (Sep.comma . Build.opt_list alias Sep.comma)?
. Sep.space . type . Sep.space . key
. Util.comment_or_eol ]
(* View: lns
The known_hosts lens *)
let lns = (Util.empty | Util.comment | entry)*
(* Variable: filter *)
let filter = incl "/etc/ssh/ssh_known_hosts"
. incl (Sys.getenv("HOME") . "/.ssh/known_hosts")
let xfm = transform lns filter

View File

@ -0,0 +1,40 @@
(*
Module: Koji
Parses koji config files
Author: Pat Riehecky <riehecky@fnal.gov>
About: Reference
This lens tries to keep as close as possible to koji config syntax
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/koji.conf
/etc/kojid/kojid.conf
/etc/koji-hub/hub.conf
/etc/kojira/kojira.conf
/etc/kojiweb/web.conf
/etc/koji-shadow/koji-shadow.conf
See <filter>.
*)
module Koji =
autoload xfm
let lns = IniFile.lns_loose_multiline
let filter = incl "/etc/koji.conf"
. incl "/etc/kojid/kojid.conf"
. incl "/etc/koji-hub/hub.conf"
. incl "/etc/kojira/kojira.conf"
. incl "/etc/kojiweb/web.conf"
. incl "/etc/koji-shadow/koji-shadow.conf"
let xfm = transform lns filter

View File

@ -0,0 +1,182 @@
module Krb5 =
autoload xfm
let comment = Inifile.comment IniFile.comment_re "#"
let empty = Inifile.empty
let eol = Inifile.eol
let dels = Util.del_str
let indent = del /[ \t]*/ ""
let comma_or_space_sep = del /[ \t,]{1,}/ " "
let eq = del /[ \t]*=[ \t]*/ " = "
let eq_openbr = del /[ \t]*=[ \t\n]*\{[ \t]*\n/ " = {\n"
let closebr = del /[ \t]*\}/ "}"
(* These two regexps for realms and apps are not entirely true
- strictly speaking, there's no requirement that a realm is all upper case
and an application only uses lowercase. But it's what's used in practice.
Without that distinction we couldn't distinguish between applications
and realms in the [appdefaults] section.
*)
let include_re = /include(dir)?/
let realm_re = /[A-Z0-9][.a-zA-Z0-9-]*/
let realm_anycase_re = /[A-Za-z0-9][.a-zA-Z0-9-]*/
let app_re = /[a-z][a-zA-Z0-9_]*/
let name_re = /[.a-zA-Z0-9_-]+/ - include_re
let value_br = store /[^;# \t\r\n{}]+/
let value = store /[^;# \t\r\n]+/
let entry (kw:regexp) (sep:lens) (value:lens) (comment:lens)
= [ indent . key kw . sep . value . (comment|eol) ] | comment
let subsec_entry (kw:regexp) (sep:lens) (comment:lens)
= ( entry kw sep value_br comment ) | empty
let simple_section (n:string) (k:regexp) =
let title = Inifile.indented_title n in
let entry = entry k eq value comment in
Inifile.record title entry
let record (t:string) (e:lens) =
let title = Inifile.indented_title t in
Inifile.record title e
let v4_name_convert (subsec:lens) = [ indent . key "v4_name_convert" .
eq_openbr . subsec* . closebr . eol ]
(*
For the enctypes this appears to be a list of the valid entries:
c4-hmac arcfour-hmac aes128-cts rc4-hmac
arcfour-hmac-md5 des3-cbc-sha1 des-cbc-md5 des-cbc-crc
*)
let enctype_re = /[a-zA-Z0-9-]{3,}/
let enctypes = /permitted_enctypes|default_tgs_enctypes|default_tkt_enctypes/i
(* An #eol label prevents ambiguity between "k = v1 v2" and "k = v1\n k = v2" *)
let enctype_list (nr:regexp) (ns:string) =
indent . del nr ns . eq
. Build.opt_list [ label ns . store enctype_re ] comma_or_space_sep
. (comment|eol) . [ label "#eol" ]
let libdefaults =
let option = entry (name_re - ("v4_name_convert" |enctypes)) eq value comment in
let enctype_lists = enctype_list /permitted_enctypes/i "permitted_enctypes"
| enctype_list /default_tgs_enctypes/i "default_tgs_enctypes"
| enctype_list /default_tkt_enctypes/i "default_tkt_enctypes" in
let subsec = [ indent . key /host|plain/ . eq_openbr .
(subsec_entry name_re eq comment)* . closebr . eol ] in
record "libdefaults" (option|enctype_lists|v4_name_convert subsec)
let login =
let keys = /krb[45]_get_tickets|krb4_convert|krb_run_aklog/
|/aklog_path|accept_passwd/ in
simple_section "login" keys
let appdefaults =
let option = entry (name_re - ("realm" | "application")) eq value_br comment in
let realm = [ indent . label "realm" . store realm_re .
eq_openbr . (option|empty)* . closebr . eol ] in
let app = [ indent . label "application" . store app_re .
eq_openbr . (realm|option|empty)* . closebr . eol] in
record "appdefaults" (option|realm|app)
let realms =
let simple_option = /kdc|admin_server|database_module|default_domain/
|/v4_realm|auth_to_local(_names)?|master_kdc|kpasswd_server/
|/admin_server|ticket_lifetime|pkinit_(anchors|identities|identity|pool)/
|/krb524_server/ in
let subsec_option = /v4_instance_convert/ in
let option = subsec_entry simple_option eq comment in
let subsec = [ indent . key subsec_option . eq_openbr .
(subsec_entry name_re eq comment)* . closebr . eol ] in
let v4subsec = [ indent . key /host|plain/ . eq_openbr .
(subsec_entry name_re eq comment)* . closebr . eol ] in
let realm = [ indent . label "realm" . store realm_anycase_re .
eq_openbr . (option|subsec|(v4_name_convert v4subsec))* .
closebr . eol ] in
record "realms" (realm|comment)
let domain_realm =
simple_section "domain_realm" name_re
let logging =
let keys = /kdc|admin_server|default/ in
let xchg (m:regexp) (d:string) (l:string) =
del m d . label l in
let xchgs (m:string) (l:string) = xchg m m l in
let dest =
[ xchg /FILE[=:]/ "FILE=" "file" . value ]
|[ xchgs "STDERR" "stderr" ]
|[ xchgs "CONSOLE" "console" ]
|[ xchgs "DEVICE=" "device" . value ]
|[ xchgs "SYSLOG" "syslog" .
([ xchgs ":" "severity" . store /[A-Za-z0-9]+/ ].
[ xchgs ":" "facility" . store /[A-Za-z0-9]+/ ]?)? ] in
let entry = [ indent . key keys . eq . dest . (comment|eol) ] | comment in
record "logging" entry
let capaths =
let realm = [ indent . key realm_re .
eq_openbr .
(entry realm_re eq value_br comment)* . closebr . eol ] in
record "capaths" (realm|comment)
let dbdefaults =
let keys = /database_module|ldap_kerberos_container_dn|ldap_kdc_dn/
|/ldap_kadmind_dn|ldap_service_password_file|ldap_servers/
|/ldap_conns_per_server/ in
simple_section "dbdefaults" keys
let dbmodules =
let subsec_key = /database_name|db_library|disable_last_success/
|/disable_lockout|ldap_conns_per_server|ldap_(kdc|kadmind)_dn/
|/ldap_(kdc|kadmind)_sasl_mech|ldap_(kdc|kadmind)_sasl_authcid/
|/ldap_(kdc|kadmind)_sasl_authzid|ldap_(kdc|kadmind)_sasl_realm/
|/ldap_kerberos_container_dn|ldap_servers/
|/ldap_service_password_file|mapsize|max_readers|nosync/
|/unlockiter/ in
let subsec_option = subsec_entry subsec_key eq comment in
let key = /db_module_dir/ in
let option = entry key eq value comment in
let realm = [ indent . label "realm" . store realm_re .
eq_openbr . (subsec_option)* . closebr . eol ] in
record "dbmodules" (option|realm)
(* This section is not documented in the krb5.conf manpage,
but the Fermi example uses it. *)
let instance_mapping =
let value = dels "\"" . store /[^;# \t\r\n{}]*/ . dels "\"" in
let map_node = label "mapping" . store /[a-zA-Z0-9\/*]+/ in
let mapping = [ indent . map_node . eq .
[ label "value" . value ] . (comment|eol) ] in
let instance = [ indent . key name_re .
eq_openbr . (mapping|comment)* . closebr . eol ] in
record "instancemapping" instance
let kdc =
simple_section "kdc" /profile/
let pam =
simple_section "pam" name_re
let plugins =
let interface_option = subsec_entry name_re eq comment in
let interface = [ indent . key name_re .
eq_openbr . (interface_option)* . closebr . eol ] in
record "plugins" (interface|comment)
let includes = Build.key_value_line include_re Sep.space (store Rx.fspath)
let include_lines = includes . (comment|empty)*
let lns = (comment|empty)* .
(libdefaults|login|appdefaults|realms|domain_realm
|logging|capaths|dbdefaults|dbmodules|instance_mapping|kdc|pam|include_lines
|plugins)*
let filter = (incl "/etc/krb5.conf.d/*.conf")
. (incl "/etc/krb5.conf")
let xfm = transform lns filter

View File

@ -0,0 +1,227 @@
(*
Module: Ldif
Parses the LDAP Data Interchange Format (LDIF)
Author: Dominic Cleal <dcleal@redhat.com>
About: Reference
This lens tries to keep as close as possible to RFC2849
<http://tools.ietf.org/html/rfc2849>
and OpenLDAP's ldif(5)
About: Licence
This file is licensed under the LGPLv2+, like the rest of Augeas.
*)
module Ldif =
autoload xfm
(************************************************************************
* Group: USEFUL PRIMITIVES
************************************************************************)
(* View: comment *)
let comment = Util.comment_generic /#[ \t]*/ "# "
(* View: empty
Map empty lines, including empty comments *)
let empty = [ del /#?[ \t]*\n/ "\n" ]
(* View: eol
Only eol, don't include whitespace *)
let eol = Util.del_str "\n"
(* View: sep_colon
The separator for attributes and values *)
let sep_colon = del /:[ \t]*/ ": "
(* View: sep_base64
The separator for attributes and base64 encoded values *)
let sep_base64 = del /::[ \t]*/ ":: "
(* View: sep_url
The separator for attributes and URL-sourced values *)
let sep_url = del /:<[ \t]*/ ":< "
(* Variable: ldapoid_re
Format of an LDAP OID from RFC 2251 *)
let ldapoid_re = /[0-9][0-9\.]*/
(* View: sep_modspec
Separator between modify operations *)
let sep_modspec = Util.del_str "-" . eol
(************************************************************************
* Group: BASIC ATTRIBUTES
************************************************************************)
(* Different types of values, all permitting continuation where the next line
begins with whitespace *)
let attr_safe_string =
let line = /[^ \t\n:<][^\n]*/
in let lines = line . (/\n[ \t]+[^ \t\n][^\n]*/)*
in sep_colon . store lines
let attr_base64_string =
let line = /[a-zA-Z0-9=+]+/
in let lines = line . (/\n[ \t]+/ . line)*
in sep_base64 . [ label "@base64" . store lines ]
let attr_url_string =
let line = /[^ \t\n][^\n]*/
in let lines = line . (/\n[ \t]+/ . line)*
in sep_url . [ label "@url" . store lines ]
let attr_intflag = sep_colon . store /0|1/
(* View: attr_version
version-spec = "version:" FILL version-number *)
let attr_version = Build.key_value_line "version" sep_colon (store /[0-9]+/)
(* View: attr_dn
dn-spec = "dn:" (FILL distinguishedName /
":" FILL base64-distinguishedName) *)
let attr_dn = del /dn/i "dn"
. ( attr_safe_string | attr_base64_string )
. eol
(* View: attr_type
AttributeType = ldap-oid / (ALPHA *(attr-type-chars)) *)
let attr_type = ldapoid_re | /[a-zA-Z][a-zA-Z0-9-]*/
- /dn/i
- /changeType/i
- /include/i
(* View: attr_option
options = option / (option ";" options) *)
let attr_option = Util.del_str ";"
. [ label "@option" . store /[a-zA-Z0-9-]+/ ]
(* View: attr_description
Attribute name, possibly with options *)
let attr_description = key attr_type . attr_option*
(* View: attr_val_spec
Generic attribute with a value *)
let attr_val_spec = [ attr_description
. ( attr_safe_string
| attr_base64_string
| attr_url_string )
. eol ]
(* View: attr_changetype
Parameters:
t:regexp - value of changeType *)
let attr_changetype (t:regexp) =
key /changeType/i . sep_colon . store t . eol
(* View: attr_modspec *)
let attr_modspec = key /add|delete|replace/ . sep_colon . store attr_type
. attr_option* . eol
(* View: attr_dn_value
Parses an attribute line with a DN on the RHS
Parameters:
k:regexp - match attribute name as key *)
let attr_dn_value (k:regexp) =
[ key k . ( attr_safe_string | attr_base64_string ) . eol ]
(* View: sep_line *)
let sep_line = empty | comment
(* View: attr_include
OpenLDAP extension, must be separated by blank lines *)
let attr_include = eol . [ key "include" . sep_colon
. store /[^ \t\n][^\n]*/ . eol . comment* . eol ]
(* View: sep_record *)
let sep_record = ( sep_line | attr_include )*
(************************************************************************
* Group: LDIF CONTENT RECORDS
************************************************************************)
(* View: ldif_attrval_record
ldif-attrval-record = dn-spec SEP 1*attrval-spec *)
let ldif_attrval_record = [ seq "record"
. attr_dn
. ( sep_line* . attr_val_spec )+ ]
(* View: ldif_content
ldif-content = version-spec 1*(1*SEP ldif-attrval-record) *)
let ldif_content = [ label "@content"
. ( sep_record . attr_version )?
. ( sep_record . ldif_attrval_record )+
. sep_record ]
(************************************************************************
* Group: LDIF CHANGE RECORDS
************************************************************************)
(* View: change_add
change-add = "add" SEP 1*attrval-spec *)
let change_add = [ attr_changetype "add" ] . ( sep_line* . attr_val_spec )+
(* View: change_delete
change-delete = "add" SEP 1*attrval-spec *)
let change_delete = [ attr_changetype "delete" ]
(* View: change_modspec
change-modspec = add/delete/replace: AttributeDesc SEP *attrval-spec "-" *)
let change_modspec = attr_modspec . ( sep_line* . attr_val_spec )*
(* View: change_modify
change-modify = "modify" SEP *mod-spec *)
let change_modify = [ attr_changetype "modify" ]
. ( sep_line* . [ change_modspec
. sep_line* . sep_modspec ] )+
(* View: change_modrdn
("modrdn" / "moddn") SEP newrdn/newsuperior/deleteoldrdn *)
let change_modrdn =
let attr_deleteoldrdn = [ key "deleteoldrdn" . attr_intflag . eol ]
in let attrs_modrdn = attr_dn_value "newrdn"
| attr_dn_value "newsuperior"
| attr_deleteoldrdn
in [ attr_changetype /modr?dn/ ]
. ( sep_line | attrs_modrdn )* . attrs_modrdn
(* View: change_record
changerecord = "changetype:" FILL (changeadd/delete/modify/moddn) *)
let change_record = ( change_add | change_delete | change_modify
| change_modrdn)
(* View: change_control
"control:" FILL ldap-oid 0*1(1*SPACE ("true" / "false")) 0*1(value-spec) *)
let change_control =
let attr_criticality = [ Util.del_ws_spc . label "criticality"
. store /true|false/ ]
in let attr_ctrlvalue = [ label "value" . (attr_safe_string
| attr_base64_string
| attr_url_string ) ]
in [ key "control" . sep_colon . store ldapoid_re
. attr_criticality? . attr_ctrlvalue? . eol ]
(* View: ldif_change_record
ldif-change-record = dn-spec SEP *control changerecord *)
let ldif_change_record = [ seq "record" . attr_dn
. ( ( sep_line | change_control )* . change_control )?
. sep_line* . change_record ]
(* View: ldif_changes
ldif-changes = version-spec 1*(1*SEP ldif-change-record) *)
let ldif_changes = [ label "@changes"
. ( sep_record . attr_version )?
. ( sep_record . ldif_change_record )+
. sep_record ]
(************************************************************************
* Group: LENS
************************************************************************)
(* View: lns *)
let lns = sep_record | ldif_content | ldif_changes
let filter = incl "/etc/openldap/schema/*.ldif"
let xfm = transform lns filter

View File

@ -0,0 +1,44 @@
(*
Module: Keepalived
Parses /etc/ld.so.conf and /etc/ld.so.conf.d/*
Author: Raphael Pinson <raphink@gmail.com>
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/ld.so.conf and /etc/ld.so.conf.d/*. See <filter>.
About: Examples
The <Test_Ldso> file contains various examples and tests.
*)
module LdSo =
autoload xfm
(* View: path *)
let path = [ label "path" . store /[^# \t\n][^ \t\n]*/ . Util.eol ]
(* View: include *)
let include = Build.key_value_line "include" Sep.space (store Rx.fspath)
(* View: hwcap *)
let hwcap =
let hwcap_val = [ label "bit" . store Rx.integer ] . Sep.space .
[ label "name" . store Rx.word ]
in Build.key_value_line "hwcap" Sep.space hwcap_val
(* View: lns *)
let lns = (Util.empty | Util.comment | path | include | hwcap)*
(* Variable: filter *)
let filter = incl "/etc/ld.so.conf"
. incl "/etc/ld.so.conf.d/*"
. Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,56 @@
(*
Module: Lightdm
Lightdm module for Augeas for which parses /etc/lightdm/*.conf files which
are standard INI file format.
Author: David Salmen <dsalmen@dsalmen.com>
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/lightdm/*.conf. See <filter>.
About: Tests
The tests/test_lightdm.aug file contains unit tests.
*)
module Lightdm =
autoload xfm
(************************************************************************
* INI File settings
*
* lightdm.conf only supports "# as commentary and "=" as separator
*************************************************************************)
let comment = IniFile.comment "#" "#"
let sep = IniFile.sep "=" "="
(************************************************************************
* ENTRY
* lightdm.conf uses standard INI File entries
*************************************************************************)
let entry = IniFile.indented_entry IniFile.entry_re sep comment
(************************************************************************
* RECORD
* lightdm.conf uses standard INI File records
*************************************************************************)
let title = IniFile.indented_title IniFile.record_re
let record = IniFile.record title entry
(************************************************************************
* LENS & FILTER
* lightdm.conf uses standard INI File records
*************************************************************************)
let lns = IniFile.lns record comment
let filter = (incl "/etc/lightdm/*.conf")
let xfm = transform lns filter

View File

@ -0,0 +1,71 @@
(* Limits module for Augeas
Author: Free Ekanayaka <free@64studio.com>
Reference: /etc/security/limits.conf
*)
module Limits =
autoload xfm
(************************************************************************
* USEFUL PRIMITIVES
*************************************************************************)
let eol = Util.eol
let comment_or_eol = Util.comment_or_eol
let spc = Util.del_ws_spc
let comment = Util.comment
let empty = Util.empty
let sto_to_eol = store /([^ \t\n].*[^ \t\n]|[^ \t\n])/
(************************************************************************
* ENTRIES
*************************************************************************)
let domain = label "domain" . store /[%@]?[A-Za-z0-9_.:-]+|\*/
let type_re = "soft"
| "hard"
| "-"
let type = [ label "type" . store type_re ]
let item_re = "core"
| "data"
| "fsize"
| "memlock"
| "nofile"
| "rss"
| "stack"
| "cpu"
| "nproc"
| "as"
| "maxlogins"
| "maxsyslogins"
| "priority"
| "locks"
| "sigpending"
| "msgqueue"
| "nice"
| "rtprio"
| "chroot"
let item = [ label "item" . store item_re ]
let value = [ label "value" . store /[A-Za-z0-9_.\/-]+/ ]
let entry = [ domain . spc
. type . spc
. item . spc
. value . comment_or_eol ]
(************************************************************************
* LENS
*************************************************************************)
let lns = (comment|empty|entry) *
let filter = incl "/etc/security/limits.conf"
. incl "/etc/security/limits.d/*.conf"
let xfm = transform lns filter

Some files were not shown because too many files have changed in this diff Show More