Imported Upstream version 1.7.0
[platform/upstream/augeas.git] / lenses / systemd.aug
1 (*
2 Module: Systemd
3   Parses systemd unit files.
4
5 Author: Dominic Cleal <dcleal@redhat.com>
6
7 About: Reference
8   This lens tries to keep as close as possible to systemd.unit(5) and
9   systemd.service(5) etc where possible.
10
11 About: License
12   This file is licenced under the LGPL v2+, like the rest of Augeas.
13
14 About: Lens Usage
15   To be documented
16
17 About: Configuration files
18   This lens applies to /lib/systemd/system/* and /etc/systemd/system/*.
19   See <filter>.
20 *)
21
22 module Systemd =
23 autoload xfm
24
25 (************************************************************************
26  * Group:                 USEFUL PRIMITIVES
27  *************************************************************************)
28
29 (* View: eol *)
30 let eol = Util.eol
31
32 (* View: eol_comment
33    An <IniFile.comment> entry for standalone comment lines (; or #) *)
34 let comment     = IniFile.comment IniFile.comment_re "#"
35
36 (* View: eol_comment
37    An <IniFile.comment> entry for end of line comments (# only) *)
38 let eol_comment = IniFile.comment "#" "#"
39
40 (* View: sep
41    An <IniFile.sep> entry *)
42 let sep        = IniFile.sep "=" "="
43
44 (* Variable: entry_single_kw *)
45 let entry_single_kw  = "Description"
46
47 (* Variable: entry_command_kw *)
48 let entry_command_kw = /Exec[A-Za-z][A-Za-z0-9._-]+/
49
50 (* Variable: entry_env_kw *)
51 let entry_env_kw     = "Environment"
52
53 (* Variable: entry_multi_kw *)
54 let entry_multi_kw   =
55      let forbidden = entry_single_kw | entry_command_kw | entry_env_kw
56   in /[A-Za-z][A-Za-z0-9._-]+/ - forbidden
57
58 (* Variable: value_single_re *)
59 let value_single_re  = /[^# \t\n\\][^#\n\\]*[^# \t\n\\]|[^# \t\n\\]/
60
61 (* View: sto_value_single
62    Support multiline values with a backslash *)
63 let sto_value_single = Util.del_opt_ws ""
64                        . store (value_single_re
65                                 . (/\\\\\n/ . value_single_re)*)
66
67 (* View: sto_value *)
68 let sto_value = store /[^# \t\n]*[^# \t\n\\]/
69
70 (* Variable: value_sep
71    Multi-value entries separated by whitespace or backslash and newline *)
72 let value_sep = del /[ \t]+|[ \t]*\\\\[ \t]*\n[ \t]*/ " "
73
74 (* Variable: value_cmd_re
75    Don't parse @ and - prefix flags *)
76 let value_cmd_re = /[^#@ \t\n\\-][^#@ \t\n\\-][^# \t\n\\]*/
77
78 (* Variable: env_key *)
79 let env_key = /[A-Za-z0-9_]+(\[[0-9]+\])?/
80
81 (************************************************************************
82  * Group:                 ENTRIES
83  *************************************************************************)
84
85 (*
86 Supported entry features, selected by key names:
87   * multi-value space separated attrs (the default)
88   * single-value attrs (Description)
89   * systemd.service: Exec* attrs with flags, command and arguments
90   * systemd.service: Environment NAME=arg
91 *)
92
93 (* View: entry_fn
94    Prototype for our various key=value lines, with optional comment *)
95 let entry_fn (kw:regexp) (val:lens) =
96     [ key kw . sep . val . (eol_comment|eol) ]
97
98 (* View: entry_value
99    Store a value that doesn't contain spaces *)
100 let entry_value  = [ label "value" . sto_value ]
101
102 (* View: entry_single
103    Entry that takes a single value containing spaces *)
104 let entry_single = entry_fn entry_single_kw
105                      [ label "value" . sto_value_single ]?
106
107 (* View: entry_command
108    Entry that takes a space separated set of values (the default) *)
109 let entry_multi  = entry_fn entry_multi_kw
110                      ( Util.del_opt_ws ""
111                        . Build.opt_list entry_value value_sep )?
112
113 (* View: entry_command_flags
114    Exec* flags "@" and "-".  Order is important, see systemd.service(8) *)
115 let entry_command_flags =
116      let exit  = [ label "ignoreexit" . Util.del_str "-" ]
117   in let arg0  = [ label "arg0" . Util.del_str "@" ]
118   in exit? . arg0?
119
120 (* View: entry_command
121    Entry that takes a command, arguments and the optional prefix flags *)
122 let entry_command =
123      let cmd  = [ label "command" . store value_cmd_re ]
124   in let arg  = [ seq "args" . sto_value ]
125   in let args = [ counter "args" . label "arguments"
126                 . (value_sep . arg)+ ]
127   in entry_fn entry_command_kw ( entry_command_flags . cmd . args? )?
128
129 (* View: entry_env
130    Entry that takes a space separated set of ENV=value key/value pairs *)
131 let entry_env =
132      let envkv (env_val:lens) = key env_key . Util.del_str "=" . env_val
133      (* bare has no spaces, and is optionally quoted *)
134   in let bare = Quote.do_quote_opt (envkv (store /[^#'" \t\n]*[^#'" \t\n\\]/)?)
135   in let bare_dqval = envkv (store /"[^#" \t\n]*[^#" \t\n\\]"/)
136   in let bare_sqval = envkv (store /'[^#' \t\n]*[^#' \t\n\\]'/)
137      (* quoted has at least one space, and must be quoted *)
138   in let quoted = Quote.do_quote (envkv (store /[^#"'\n]*[ \t]+[^#"'\n]*/))
139   in let envkv_quoted = [ bare ] | [ bare_dqval ] | [ bare_sqval ] | [ quoted ]
140   in entry_fn entry_env_kw ( Build.opt_list envkv_quoted value_sep )
141
142
143 (************************************************************************
144  * Group:                 LENS
145  *************************************************************************)
146
147 (* View: entry
148    An <IniFile.entry> *)
149 let entry   = entry_single | entry_multi | entry_command | entry_env | comment
150
151 (* View: include
152    Includes another file at this position *)
153 let include = [ key ".include" . Util.del_ws_spc . sto_value
154                 . (eol_comment|eol) ]
155
156 (* View: title
157    An <IniFile.title> *)
158 let title   = IniFile.title IniFile.record_re
159
160 (* View: record
161    An <IniFile.record> *)
162 let record = IniFile.record title (entry|include)
163
164 (* View: lns
165    An <IniFile.lns> *)
166 let lns    = IniFile.lns record (comment|include)
167
168 (* View: filter *)
169 let filter = incl "/lib/systemd/system/*"
170            . incl "/lib/systemd/system/*/*"
171            . incl "/etc/systemd/system/*"
172            . incl "/etc/systemd/system/*/*"
173            . incl "/etc/sysconfig/*.systemd"
174            . Util.stdexcl
175
176 let xfm = transform lns filter