[augeas-devel] Syslinux config file lens

Matthew Palmer matt at anchor.net.au
Thu Aug 13 01:30:31 UTC 2009


On Tue, Aug 04, 2009 at 03:57:32PM -0700, David Lutterkort wrote:
> On Sat, 2009-08-01 at 10:56 +1000, Matthew Palmer wrote:
> > 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.
> 
> Very nice. A few questions:
> 
> Do you insist on GPL for these files ? Augeas is licensed under LGPLv2+.
> I don't think there are any practical differences for a lens, but there
> has been some confusion in the past about lenses under GPL, which I'd
> like to avoid.

I really don't like the LGPL (and think it would have been better if the
whole of Augeas were released under the GPL) but in the interests of keeping
things comprehensible, I'll keep everything LGPL.

> In syslinux.aug:
> 
> >         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 ]
> >                            ....
> 
> How about

[far neater version]

Definitely.

> That should be deleted.

Whups, that's what insufficient QA does to you.

New version attached.

- Matt
-------------- 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 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 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 opt (canon:string) (re:regexp) = [ del re canon . label canon . option_value ]

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