Finally got it doing everything I want!  Basically, this lens just manages
the configuration for the syslinux family of bootloaders.  I personally only
use it for our boot servers' pxelinux configs, but the Internets assure me
that the format is the same for all of them.

Share and enjoy!


-- 
Windows is too dangerous to be left to Windows admins.
                -- James Riden, ASR
(* syslinux (and all other *linux boot loaders) lens definition for Augeas
   Author: Matt Palmer <[email protected]>

   Copyright (C) 2009 Matt Palmer, All Rights Reserved
   Copyright (C) 2009 Anchor Systems Pty Ltd, All Rights Reserved

   This program is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License version 2 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 is designed to parse a pxelinux/isolinux/syslinux/<foo>linux boot
loaderconfig file (such as "default", "isolinux.cfg", or
"01-00-00-12-34-56-78").

These files typically contain a series of simple key/value pairs, each on their
own line, with the key and value separated by whitespace, like so:

---8<---
prompt 1
timeout 600
default foo
--->8---

This lens turns those into simple key/value pairs in the tree:

set /prompt 1
set /timeout 600
set /default foo

There is one exception to this simple key/value rule, and that is the
"append" option, which gives default append options to be used for all boot
configurations.  Because the append parameter is a key/value store of it's
own, we represent it a bit differently. This string:

append initrd=/initrd.img ramdisk_size=15240 rw --

is translated like this in the tree:

set /append[1] initrd=/initrd.img
set /append[2] ramdisk_size=15240
set /append[3] rw
set /append[4] --

The reason why this is an array of options rather than some sort of
key/value list of it's own is that appended options can have slashes in them
(think "preseed/file=/preseed.cfg"), and Augeas doesn't like slashes in it's
keys.  So, sorry 'bout that, but it's an array of options all the way, I'm
afraid.

Apart from setting configurations globally, you also provide boot
configurations, which are the different names you can type at the <foo>linux
prompt to choose between, say, normal install, expert install, and a rescue
environment.  These look like this in the file:

label xyzzy
        kernel vmlinuz-xyzzy
        append initrd=initrd-xyzzy vga=normal --

This gets turned into this in the tree:

set /label[0] xyzzy
set /label[0]/kernel vmlinuz-xyzzy
set /label[0]/append[1] initrd=initrd-xyzzy
set /label[0]/append[2] vga=normal
set /label[0]/append[3] --

Effectively, the same key/value association (with the special handling for
"append") happens inside each boot label, just as it does at the top level. 
Hopefully this makes for consistent usage and minimal confusion.

Comments in <foo>linux config files are hash ('#') prefixed, and continue to
end-of-line. These are represented with "#comment" tags in the tree, as per
standard convention.

*)

module Syslinux =
        autoload xfm

        (* Store whitespace *)
        let wsp = del /[ \t]+/ " "
        
        let indent = del /[ \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

        (***************************
         * GENERIC OPTION HANDLING
         ***************************)

        let option_value = wsp . store /[^ \t\n][^\n]*/ . del /\n/ "\n"

        let global_option = [ del /[Ii][Nn][Cc][Ll][Uu][Dd][Ee]/ "include" . 
label "include" . option_value ]
                           |[ del /[Kk][Ee][Rr][Nn][Ee][Ll]/ "kernel" . label 
"kernel" . option_value ]
                           |[ del /[Ll][Ii][Nn][Uu][Xx]/ "linux" . label 
"linux" . option_value ]
                           |[ del /[Bb][Oo][Oo][Tt]/ "boot" . label "boot" . 
option_value ]
                           |[ del /[Bb][Ss][Ss]/ "bss" . label "bss" . 
option_value ]
                           |[ del /[Pp][Xx][Ee]/ "pxe" . label "pxe" . 
option_value ]
                           |[ del /[Ff][Dd][Ii][Mm][Aa][Gg][Ee]/ "fdimage" . 
label "fdimage" . option_value ]
                           |[ del /[Cc][Oo][Mm][Bb][Oo][Oo][Tt]/ "comboot" . 
label "comboot" . option_value ]
                           |[ del /[Cc][Oo][Mm]32/ "com32" . label "com32" . 
option_value ]
                           |[ del /[Cc][Oo][Nn][Ff][ii][Gg]/ "config" . label 
"config" . option_value ]
                           |[ del /[Ii][Pp][Aa][Pp][Pp][Ee][Nn][Dd]/ "ipappend" 
. label "ipappend" . option_value ]
                           |[ del /[Ll][Oo][Cc][Aa][Ll][Bb][Oo][Oo][Tt]/ 
"localboot" . label "localboot" . option_value ]
                           |[ del /[Ii][Nn][Ii][Tt][Rr][Dd]/ "initrd" . label 
"initrd" . option_value ]
                           |[ del /[Dd][Ee][Ff][Aa][Uu][Ll][Tt]/ "default" . 
label "default" . option_value ]
                           |[ del /[Uu][Ii]/ "ui" . label "ui" . option_value ]
                           |[ del /[Pp][Rr][Oo][Mm][Pp][Tt]/ "prompt" . label 
"prompt" . option_value ]
                           |[ del /[Nn][Oo][Ee][Ss][Cc][Aa][Pp][Ee]/ "noescape" 
. label "noescape" . option_value ]
                           |[ del /[Nn][Oo][Cc][Oo][Mm][Pp][Ll][Ee][Tt][Ee]/ 
"nocomplete" . label "nocomplete" . option_value ]
                           |[ del /[Ii][Mm][Pp][Ll][Ii][Cc][Ii][Tt]/ "implicit" 
. label "implicit" . option_value ]
                           |[ del 
/[Aa][Ll][Ll][Oo][Ww][Oo][Pp][Tt][Ii][Oo][Nn][Ss]/ "allowoptions" . label 
"allowoptions" . option_value ]
                           |[ del /[Tt][Ii][Mm][Ee][Oo][Uu][Tt]/ "timeout" . 
label "timeout" . option_value ]
                           |[ del 
/[Tt][Oo][Tt][Aa][Ll][Tt][Ii][Mm][Ee][Oo][Uu][Tt]/ "totaltimeout" . label 
"totaltimeout" . option_value ]
                           |[ del /[Oo][Nn][Tt][Ii][Mm][Ee][Oo][Uu][Tt]/ 
"ontimeout" . label "ontimeout" . option_value ]
                           |[ del /[Oo][Nn][Ee][Rr][Rr][Oo][Rr]/ "onerror" . 
label "onerror" . option_value ]
                           |[ del /[Ss][Ee][Rr][Ii][Aa][Ll]/ "serial" . label 
"serial" . option_value ]
                           |[ del /[Cc][Oo][Nn][Ss][Oo][Ll][Ee]/ "console" . 
label "console" . option_value ]
                           |[ del /[Ff][Oo][Nn][Tt]/ "font" . label "font" . 
option_value ]
                           |[ del /[Kk][Bb][Dd][Mm][Aa][Pp]/ "kbdmap" . label 
"kbdmap" . option_value ]
                           |[ del /[Ss][Aa][Yy]/ "say" . label "say" . 
option_value ]
                           |[ del /[Dd][Ii][Ss][Pp][Ll][Aa][Yy]/ "display" . 
label "display" . option_value ]
                           |[ key /F(1[12]?|[2-9])/ . option_value ]
        
(*      let global_option = [ valid_option   key ( /[^ \t\n\/#]+/ - 
/([Aa][Pp][Pp][Ee][Nn][Dd]|[Ll][Aa][Bb][Ee][Ll])/ )
                              . wsp
                              . store /[^ \t\n].*/
                              . del /\n/ "\n"
                            ]
*)

        (***************************
         * APPEND OPTION HANDLING
         ***************************)
        
        let append_opt = [ seq "append_seq" . wsp . store /[^ \t\n]+/ ]
        
        let global_append = [ del /[Aa][Pp][Pp][Ee][Nn][Dd]/ "append"
                              . label "append"
                              . counter "append_seq"
                              . append_opt+
                              . eol
                            ]

        (***********************
         * LABEL
         ***********************)

        let label_line = del /[Ll][Aa][Bb][Ee][Ll]/ "label" . label "label" . 
wsp . store /[^ \t\n]+/ . eol
        let label_option = indent . global_option
        let label_append = indent . global_append
                
        let label = [ label_line
                      . (label_option|label_append)*
                    ]

        (***********************
         * LENS / FILTER
         ***********************)

        let lns = (comment|empty|global_option|global_append|label)*
        
        let filter = (incl "/tftpboot/pxelinux.cfg/default")
                     . (incl 
"/tftpboot/pxelinux.cfg/[0-9a-f][0-9a-f]-[0-9a-f][0-9a-f]-[0-9a-f][0-9a-f]-[0-9a-f][0-9a-f]-[0-9a-f][0-9a-f]-[0-9a-f][0-9a-f]")
                     . Util.stdexcl
                     
        let xfm = transform lns filter
module Test_syslinux =

        (* The standard "parse a bucket of text" test *)
        let conf = "# Blah di blah comment

prompt 1
timeout 600
default local
display welcome.msg
F1 help.msg
F2 opts.msg
F3 images.msg

label mem
        kernel memtest

LABEL local
        localboot 0x80

LABEL burn
        kernel vmlinuz-rhel
        append initrd=initrd.img-rhel text ks=/kickstart.ks

label lenny64
        kernel vmlinuz-lenny64
        append vga=normal initrd=initrd.img-lenny64 
preseed/url=http://localhost/preseed.cfg --
"

        test Syslinux.lns get conf =
                { "#comment" = "Blah di blah comment" }
                {}
                { "prompt" = "1" }
                { "timeout" = "600" }
                { "default" = "local" }
                { "display" = "welcome.msg" }
                { "F1" = "help.msg" }
                { "F2" = "opts.msg" }
                { "F3" = "images.msg" }
                {}
                { "label" = "mem"
                        { "kernel" = "memtest" }
                }
                {}
                { "label" = "local"
                        { "localboot" = "0x80" }
                }
                {}
                { "label" = "burn"
                        { "kernel" = "vmlinuz-rhel" }
                        { "append"
                                { "1" = "initrd=initrd.img-rhel" }
                                { "2" = "text" }
                                { "3" = "ks=/kickstart.ks" }
                        }
                }
                {}
                { "label" = "lenny64"
                        { "kernel" = "vmlinuz-lenny64" }
                        { "append"
                                { "1" = "vga=normal" }
                                { "2" = "initrd=initrd.img-lenny64" }
                                { "3" = 
"preseed/url=http://localhost/preseed.cfg"; }
                                { "4" = "--" }
                        }
                }

(**************************************************************************)

        (* Test new file creation *)
        
        test Syslinux.lns put "" after
                set "/default" "mem";
                set "/prompt" "1";
                set "/timeout" "600";
                set "/label[1]" "mem";
                set "/label[1]/kernel" "memtest";
                set "/label[2]" "lenny64";
                set "/label[2]/kernel" "vmlinuz-lenny64";
                set "/label[2]/append/1" "vga=normal";
                set "/label[2]/append/2" "initrd=initrd.img-lenny64";
                set "/label[2]/append/3" 
"preseed/url=http://172.1.7.2/preseed.cfg";;
                set "/label[2]/append/4" "--"
        = "default mem
prompt 1
timeout 600
label mem
        kernel memtest
label lenny64
        kernel vmlinuz-lenny64
        append vga=normal initrd=initrd.img-lenny64 
preseed/url=http://172.1.7.2/preseed.cfg --
"
_______________________________________________
augeas-devel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/augeas-devel

Reply via email to