[augeas-devel] Less-stuffed interfaces lens

Matt Palmer matt at anchor.net.au
Mon May 11 04:05:08 UTC 2009


Solved my earlier problem of not being able to write a simple
/etc/network/interfaces file, by fixing the lens.  I also went and fixed the
lens for several incompatibilities with the file format specification, made
generic allow-* work, and wrote a test to make sure that the lens can
actually write something.

I've attached both the lens and it's test spec, since it's a bit much to
paste.


-- 
Matt Palmer - Systems Administrator

A view into the Anchor Engineroom: http://anchor.com.au/blog/
Web Hosting Knowledgebase: http://anchor.com.au/wiki/

Anchor Systems Pty Ltd - Hosting Heavyweights
W: http://www.anchor.com.u - E: support at anchor.com.au
Phone: 1300 883 979 - Fax: 02 8296 5199
-------------- next part --------------
(* Intefraces module for Augeas
 Author: Free Ekanayaka <free at 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 reseverved words *)
let stanza_word = /(iface|auto|allow-[a-z-]+|mapping)/

(* Define additional lines for multi-line stanzas *)
let stanza_option = [  del /[ \t]*/ "   " 
                     . key  ( /[a-z_-]+/ - stanza_word )
                     . sep_spc
                     . sto_to_eol ]

(************************************************************************
 *                              AUTO
 *************************************************************************)

let array (r:regexp) (t:string) =  del r t . label t . counter t
   . [ sep_spc . seq t . sto_to_spc ]+
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 iface   = [ stanza_id    "iface"
              . stanza_param "family"
              . stanza_param "method"
              . eol
              . (stanza_option|comment|empty)* ]

(************************************************************************
 *                              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 a iface or mapping block *)

let stanza_single = (auto|allow) . (comment|empty)*
let stanza_multi  = iface|mapping

(************************************************************************
 *                              LENS & FILTER
 *************************************************************************)

   let lns = (comment|empty)* . (stanza_multi | stanza_single)*

   let filter = incl "/etc/network/interfaces"
              . Util.stdexcl

   let xfm = transform lns filter

-------------- next part --------------
module Test_interfaces = 

    let conf ="# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
# The loopback network interface

auto lo eth0 #foo
allow-hotplug eth1

iface lo inet \
 loopback

mapping eth0
	script /usr/local/sbin/map-scheme
map HOME eth0-home
     map \
 WORK eth0-work

iface eth0-home inet static

address 192.168.1.1
     netmask 255.255.255.0
     bridge_maxwait 0
#        up flush-mail
    down Mambo #5

iface eth0-work inet dhcp

allow-auto eth1
iface eth1 inet dhcp

mapping eth1
	# I like mapping ...
        # ... and I like comments

	script\
 /usr/local/sbin/map-scheme
"

    test Interfaces.lns get conf =
        { "#comment" = "This file describes the network interfaces available on your system"}
        { "#comment" = "and how to activate them. For more information, see interfaces(5)." }
        { "#comment" = "The loopback network interface" }
        {}
        { "auto"
            { "1" = "lo" }
            { "2" = "eth0" }
            { "3" = "#foo" } }
        { "allow-hotplug" { "1" = "eth1" } }
        { "iface" = "lo"
            { "family" = "inet"}
            { "method" = "loopback"} {} }
        { "mapping" = "eth0"
            { "script" = "/usr/local/sbin/map-scheme"}
            { "map" = "HOME eth0-home"}
            { "map" = "WORK eth0-work"} 
            {} }
        { "iface" = "eth0-home"
            { "family" = "inet"}
            { "method" = "static"}
            {}
            { "address" = "192.168.1.1" }
            { "netmask" = "255.255.255.0" }
            { "bridge_maxwait" = "0" }
            { "#comment" = "up flush-mail" }
            { "down" = "Mambo #5" }
            {} }
        { "iface" = "eth0-work"
            { "family" = "inet"}
            { "method" = "dhcp"}
            {} }
        { "auto"
            { "1" = "eth1" } }
        { "iface" = "eth1"
            { "family" = "inet"}
            { "method" = "dhcp"}
	    {} }
        { "mapping" = "eth1"
            { "#comment" = "I like mapping ..." }
            { "#comment" = "... and I like comments" }
            {}
            { "script" = "/usr/local/sbin/map-scheme"} }

test Interfaces.lns put "" after
	set "/iface[1]" "eth0";
	set "/iface[1]/family" "inet";
	set "/iface[1]/method" "dhcp"
= "iface eth0 inet dhcp\n"



More information about the augeas-devel mailing list