[augeas-devel] Syslinux config file lens
Matthew Palmer
matt at anchor.net.au
Sat Aug 1 00:56:05 UTC 2009
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
-------------- next part --------------
(* syslinux (and all other *linux boot loaders) lens definition for Augeas
Author: Matt Palmer <mpalmer at hezmatt.org>
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
-------------- next part --------------
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 --
"
More information about the augeas-devel
mailing list