[augeas-devel] Hash-like entries across multiple lines

Raphaël Pinson raphink at gmail.com
Mon Aug 25 08:38:30 UTC 2008


On Mon, Aug 25, 2008 at 10:22 AM, Free Ekanayaka <free at 64studio.com> wrote:

> Hi,
>
> I am working on a lens to parse /etc/dhclient.conf (you find the
> current code below), and I would like to parse a sequence of
> statements like:
>
> send fqdn.fqdn \"grosse.fugue.com.\";
> send fqdn.encoded on;
>
> into a tree like:
>
> { "send"
>     { "fqdn.fqdn" = "\"grosse.fugue.com.\"" }
>     { "fqdn.encoded" = "on" } }
>
> Note that the two statements could also be in different positions in
> the file, not only one right after the other, for example:
>
> send fqdn.fqdn \"grosse.fugue.com.\";
> some statement;
> more statements at will;
> send fqdn.encoded on;
>
> So the problem I am facing is how to add subnodes to a tree node which
> was created before. I'm not sure if this is possible/acceptable..
>


No, this is not possible. It's ok though, because it will lead to a tree
like

/send/fqdn.fqdn = "\"grosse.fugue.com.\""
/send/fqdn.encoded = "on"

Xpath should allow to parse this easily (as if it was only one node) imo.



================================ dhclient.aug
> =================================
>
> (* Intefraces module for Augeas
>  Author: Free Ekanayaka <free at 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 splitted across several lines, rather than
> merged
>  in a single one.
>
> *)
>
> module Dhclient =
>
>   autoload xfm
>
> (************************************************************************
>  *                           USEFUL PRIMITIVES
>  *************************************************************************)
>
> let eol     = Util.eol
> let spc     = Util.del_ws_spc
> let comment = Util.comment
> let empty   = Util.empty
>
> (* Define basic types *)
> let comma  = del /[ \t\n]*,[ \t\n]*/ ","
> let scolon = del /[ \t]*;/ ";"
> let word   = /[A-Za-z0-9_.-]+(\[[0-9]+\])?/
> let value  = store /[^\\#,; \t\n]+/
> let sep    = del /[ \t\n]*/ " "
> let indent = del /\n?[ \t]/ " "
>
> (************************************************************************
>  *                          ARRAY STATEMENTS
>  *************************************************************************)
>
> let array (t:string) = del t t . label t . indent .
>     [ sep   . seq t . value ] .
>     [ comma . seq t . value ]* .
>     scolon . (eol|comment)
> let a_statement_key  = /request|require/
> let a_statement = (
>     [ array "request" ] |
>     [ array "require" ] )
>
> (************************************************************************
>  *                          HASH STATEMENTS
>  *************************************************************************)
>
> let hash (t:string) =
>     del t t . label t .
>     indent .
>     [ sep . key word . indent . sep . value ]
> let h_statement_key  = /send/
> let h_statement = (
>     [ hash "send" . scolon . (eol|comment) ] )
>
> (************************************************************************
>  *                         SIMPLE STATEMENTS
>  *************************************************************************)
>
> let s_statement_key  = word - (a_statement_key | h_statement_key)
> let s_statement = [
>     key s_statement_key .
>     indent . sep .
>     value .
>     scolon . (eol|comment) ]
>
> let statement = (a_statement|s_statement |h_statement )
>
> let lns = (empty | comment | statement)*
>
> let filter = incl "/etc/dhcp3/dhclient.conf"
>            . Util.stdexcl
>
> let xfm = transform lns filter
>
> ========================= test_dhclient.aug ===============================
>
> module Test_dhclient =
>
>    let conf ="# Sample dhclient.conf
> #
>
> # Protocol timing
> timeout 3; # Expect a fast server
> retry
>      10;
>
> # Lease requirements and requests
> request
>        subnet-mask,
>  broadcast-address,
>        ntp-servers;
> require subnet-mask, domain-name-servers; # We want these
>
> # Dynamic DNS
> send
>        fqdn.fqdn
>          \"grosse.fugue.com.\";
> send fqdn.encoded on;
> "
>
>    test Dhclient.lns get conf =
>        { "#comment" = "Sample dhclient.conf" }
>        {}
>        {}
>        { "#comment" = "Protocol timing" }
>        { "timeout" = "3"
>           { "#comment" = "Expect a fast server" } }
>        { "retry" = "10" }
>        {}
>        { "#comment" = "Lease requirements and requests" }
>        { "request"
>           { "1" = "subnet-mask" }
>           { "2" = "broadcast-address" }
>           { "3" = "ntp-servers" } }
>        { "require"
>           { "1" = "subnet-mask" }
>           { "2" = "domain-name-servers" }
>           { "#comment" = "We want these" } }
>        {}
>        { "#comment" = "Dynamic DNS" }
>        { "send"
>           { "fqdn.fqdn" = "\"grosse.fugue.com.\"" } }
>        { "send"
>           { "fqdn.encoded" = "on" } }
>




Nice. This doesn't seem to support all dhclient conf options though. In my
dhclient.conf, I have stuff like

alias {
  interface "eth0";
  fixed-address 192.5.5.213;
  option subnet-mask 255.255.255.255;
}

lease {
  interface "eth0";
  fixed-address 192.33.137.200;
  medium "link0 link1";
  option host-name "andare.swiftmedia.com";
  option subnet-mask 255.255.255.0;
  option broadcast-address 192.33.137.255;
  option routers 192.33.137.250;
  option domain-name-servers 127.0.0.1;
  renew 2 2000/1/12 00:00:01;
  rebind 2 2000/1/12 00:00:01;
  expire 2 2000/1/12 00:00:01;
}




Ciao


Raphaël
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listman.redhat.com/archives/augeas-devel/attachments/20080825/cbe3d5e6/attachment.htm>


More information about the augeas-devel mailing list