Imported Upstream version 1.3.0
[platform/upstream/augeas.git] / lenses / grub.aug
1 (*
2 Module: Grub
3   Parses grub configuration
4
5 Author: David Lutterkort <lutter@redhat.com>
6
7 About: License
8    This file is licenced under the LGPL v2+, like the rest of Augeas.
9
10 About: Lens Usage
11    To be documented
12 *)
13
14 module Grub =
15   autoload xfm
16
17     (* This only covers the most basic grub directives. Needs to be *)
18     (* expanded to cover more (and more esoteric) directives        *)
19     (* It is good enough to handle the grub.conf on my Fedora 8 box *)
20
21
22 (************************************************************************
23  * Group:                 USEFUL PRIMITIVES
24  *************************************************************************)
25
26     (* View: value_to_eol *)
27     let value_to_eol = store /[^= \t\n][^\n]*[^= \t\n]|[^= \t\n]/
28
29     (* View: eol *)
30     let eol = Util.eol
31
32     (* View: del_to_eol *)
33     let del_to_eol = del /[^ \t\n]*/ ""
34
35     (* View: spc *)
36     let spc = Util.del_ws_spc
37
38     (* View: opt_ws *)
39     let opt_ws = Util.del_opt_ws ""
40
41     (* View: dels *)
42     let dels (s:string) = Util.del_str s
43
44     (* View: eq *)
45     let eq = dels "="
46
47     (* View: switch *)
48     let switch (n:regexp) = dels "--" . key n
49
50     (* View: switch_arg *)
51     let switch_arg (n:regexp) = switch n . eq . store Rx.no_spaces
52
53     (* View: value_sep *)
54     let value_sep (dflt:string) = del /[ \t]*[ \t=][ \t]*/ dflt
55
56     (* View: comment_re *)
57     let comment_re = /([^ \t\n].*[^ \t\n]|[^ \t\n])/
58                        - /# ## (Start|End) Default Options ##/
59
60     (* View: comment *)
61     let comment    =
62         [ Util.indent . label "#comment" . del /#[ \t]*/ "# "
63             . store comment_re . eol ]
64
65     (* View: empty *)
66     let empty   = Util.empty
67
68 (************************************************************************
69  * Group:                 USEFUL FUNCTIONS
70  *************************************************************************)
71
72     (* View: command *)
73     let command (kw:regexp) (indent:string) =
74       Util.del_opt_ws indent . key kw
75
76     (* View: kw_arg *)
77     let kw_arg (kw:regexp) (indent:string) (dflt_sep:string) =
78       [ command kw indent . value_sep dflt_sep . value_to_eol . eol ]
79
80     (* View: kw_boot_arg *)
81     let kw_boot_arg (kw:regexp) = kw_arg kw "\t" " "
82
83     (* View: kw_menu_arg *)
84     let kw_menu_arg (kw:regexp) = kw_arg kw "" " "
85
86     (* View: password_arg *)
87     let password_arg = [ key "password" .
88       (spc . [ switch "md5" ])? .
89       (spc . [ switch "encrypted" ])? .
90       spc . store (/[^ \t\n]+/ - /--[^ \t\n]+/) .
91       (spc . [ label "file" . store /[^ \t\n]+/ ])? .
92       eol ]
93
94     (* View: kw_pres *)
95     let kw_pres (kw:string) = [ opt_ws . key kw . del_to_eol . eol ]
96
97 (************************************************************************
98  * Group:                 BOOT ENTRIES
99  *************************************************************************)
100
101     (* View: device
102      *  This is a shell-only directive in upstream grub; the grub versions
103      *  in at least Fedora/RHEL use this to find devices for UEFI boot *)
104     let device =
105       [ command "device" "" . Sep.space . store /\([A-Za-z0-9_.-]+\)/ . spc .
106         [ label "file" . value_to_eol ] . Util.eol ]
107
108     (* View: color *)
109     let color =
110       (* Should we nail it down to exactly the color names that *)
111       (* grub supports ? *)
112       let color_name = store /[A-Za-z-]+/ in
113       let color_spec =
114         [ label "foreground" . color_name] .
115         dels "/" .
116         [ label "background" . color_name ] in
117       [ opt_ws . key "color" .
118         spc . [ label "normal" . color_spec ] .
119         (spc . [ label "highlight" . color_spec ])? .
120         eol ]
121
122     (* View: serial *)
123     let serial =
124       [ command "serial" "" .
125         [ spc . switch_arg /unit|port|speed|word|parity|stop|device/ ]* .
126         eol ]
127
128     (* View: terminal *)
129     let terminal =
130       [ command "terminal" "" .
131           ([ spc . switch /dumb|no-echo|no-edit|silent/ ]
132           |[ spc . switch_arg /timeout|lines/ ])* .
133           [ spc . key /console|serial|hercules/ ]* . eol ]
134
135     (* View: setkey *)
136     let setkey = [ command "setkey" "" .
137       ( spc . [ label "to" . store Rx.no_spaces ] .
138         spc . [ label "from" . store Rx.no_spaces ] )? .
139       eol ]
140
141     (* View: menu_setting *)
142     let menu_setting = kw_menu_arg "default"
143                      | kw_menu_arg "fallback"
144                      | kw_pres "hiddenmenu"
145                      | kw_menu_arg "timeout"
146                      | kw_menu_arg "splashimage"
147                      | kw_menu_arg "gfxmenu"
148                      | kw_menu_arg "foreground"
149                      | kw_menu_arg "background"
150                      | kw_menu_arg "verbose"
151                      | serial
152                      | terminal
153                      | password_arg
154                      | color
155                      | device
156                      | setkey
157
158     (* View: title *)
159     let title = del /title[ \t=]+/ "title " . value_to_eol . eol
160
161     (* View: multiboot_arg
162      *  Permits a second form for Solaris multiboot kernels that
163      *  take a path (with a slash) as their first arg, e.g.
164      *  /boot/multiboot kernel/unix another=arg *)
165     let multiboot_arg = [ label "@path" .
166                           store (Rx.word . "/" . Rx.no_spaces) ]
167
168     (* View: kernel_args
169         Parse the file name and args on a kernel or module line. *)
170     let kernel_args =
171       let arg = /[A-Za-z0-9_.$-]+/ - /type|no-mem-option/  in
172       store /(\([a-z0-9,]+\))?\/[^ \t\n]*/ .
173             (spc . multiboot_arg)? .
174             (spc . [ key arg . (eq. store /([^ \t\n])*/)?])* . eol
175
176     (* View: module_line
177         Solaris extension adds module$ and kernel$ for variable interpolation *)
178     let module_line =
179       [ command /module\$?/ "\t" . spc . kernel_args ]
180
181     (* View: map_line *)
182     let map_line =
183       [ command "map" "\t" . spc .
184            [ label "from" . store /[()A-za-z0-9]+/ ] . spc .
185            [ label "to" . store /[()A-za-z0-9]+/ ] . eol ]
186
187     (* View: kernel *)
188     let kernel =
189         [ command /kernel\$?/ "\t" .
190           (spc .
191              ([switch "type" . eq . store /[a-z]+/]
192              |[switch "no-mem-option"]))* .
193           spc . kernel_args ]
194
195     (* View: chainloader *)
196     let chainloader =
197       [ command "chainloader" "\t" .
198           [ spc . switch "force" ]? . spc . store Rx.no_spaces . eol ]
199
200     (* View: savedefault *)
201     let savedefault =
202       [ command "savedefault" "\t" . (spc . store Rx.integer)? . eol ]
203
204     (* View: configfile *)
205     let configfile =
206       [ command "configfile" "\t" . spc . store Rx.no_spaces . eol ]
207
208     (* View: boot_setting
209         <boot> entries *)
210     let boot_setting =
211           let boot_arg_re = "root" | "initrd" | "rootnoverify" | "uuid"
212                           | "findroot" | "bootfs" (* Solaris extensions *)
213        in kw_boot_arg boot_arg_re
214         | kernel
215         | chainloader
216         | kw_pres "quiet"  (* Seems to be a Ubuntu extension *)
217         | savedefault
218         | configfile
219         | module_line
220         | map_line
221         | kw_pres "lock"
222         | kw_pres "makeactive"
223
224     (* View: boot *)
225     let boot =
226       let line = ((boot_setting|comment)* . boot_setting)? in
227       [ label "title" . title . line ]
228
229 (************************************************************************
230  * Group:                 DEBIAN-SPECIFIC SECTIONS
231  *************************************************************************)
232
233     (* View: debian_header
234         Header for a <debian>-specific section *)
235     let debian_header  = "## ## Start Default Options ##\n"
236
237     (* View: debian_footer
238         Footer for a <debian>-specific section *)
239     let debian_footer  = "## ## End Default Options ##\n"
240
241     (* View: debian_comment_re *)
242     let debian_comment_re = /([^ \t\n].*[^ \t\n]|[^ \t\n])/
243                             - "## End Default Options ##"
244
245     (* View: debian_comment
246         A comment entry inside a <debian>-specific section *)
247     let debian_comment =
248         [ Util.indent . label "#comment" . del /##[ \t]*/ "## "
249             . store debian_comment_re . eol ]
250
251     (* View: debian_setting_re *)
252     let debian_setting_re = "kopt"
253                           | "groot"
254                           | "alternative"
255                           | "lockalternative"
256                           | "defoptions"
257                           | "lockold"
258                           | "xenhopt"
259                           | "xenkopt"
260                           | "altoptions"
261                           | "howmany"
262                           | "memtest86"
263                           | "updatedefaultentry"
264                           | "savedefault"
265                           | "indomU"
266
267     (* View: debian_entry *)
268     let debian_entry   = [ Util.del_str "#" . Util.indent
269                          . key debian_setting_re . del /[ \t]*=/ "="
270                          . value_to_eol? . eol ]
271
272     (* View: debian
273         A debian-specific section, made of <debian_entry> lines *)
274     let debian         = [ label "debian"
275                     . del debian_header debian_header
276                     . (debian_comment|empty|debian_entry)*
277                     . del debian_footer debian_footer ]
278
279 (************************************************************************
280  * Group:                 LENS AND FILTER
281  *************************************************************************)
282
283     (* View: lns *)
284     let lns = (comment | empty | menu_setting | boot | debian)*
285
286     (* View: filter *)
287     let filter = incl "/boot/grub/grub.conf"
288                . incl "/boot/grub/menu.lst"
289                . incl "/etc/grub.conf"
290
291     let xfm = transform lns filter