Tizen 2.0 Release
[pkgs/o/oma-ds-service.git] / bin / init-checkconf
1 #!/bin/bash
2 #---------------------------------------------------------------------
3 # Script to determine if specified config file is valid or not.
4 # By default, two checks are performed:
5 #
6 #   - Ensure Upstart can parse overall file successfully
7 #   - Ensure all script sections are parseable by shell
8 #
9 #---------------------------------------------------------------------
10 #
11 # Copyright (C) 2011 Canonical Ltd.
12 #
13 # Author: James Hunt <james.hunt@canonical.com>
14 #
15 # This program is free software: you can redistribute it and/or modify
16 # it under the terms of the GNU General Public License as published by
17 # the Free Software Foundation, version 3 of the License.
18 #
19 # This program is distributed in the hope that it will be useful,
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 # GNU General Public License for more details.
23 #
24 # You should have received a copy of the GNU General Public License
25 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
26 #
27 #---------------------------------------------------------------------
28
29 script_name=${0##*/}
30 confdir=$(mktemp -d /tmp/${script_name}.XXXXXXXXXX)
31 upstart_path=/sbin/init
32 initctl_path=/sbin/initctl
33 debug_enabled=n
34 file_valid=n
35 running=n
36 check_scripts=y
37
38 cleanup()
39 {
40   if [ ! -z "$upstart_pid" ]
41   then
42     debug "stopping secondary Upstart (running with PID $upstart_pid)"
43     kill -0 "$upstart_pid" >/dev/null 2>&1 && \
44     kill -9 "$upstart_pid" >/dev/null 2>&1
45   fi
46
47   [ -d "$confdir" ] && rm -rf "$confdir"
48   [ $file_valid = y ] && exit 0
49   exit 1
50 }
51
52 usage()
53 {
54 cat <<EOT
55 Description: Determine if specified Upstart (init(8)) job configuration
56              file is valid.
57
58 Usage: $script_name [options] -f <conf_file>
59        $script_name [options]    <conf_file>
60
61 Options:
62
63  -d, --debug           : Show some debug output.
64  -f <file>,            : Job configuration file to check.
65  --file=<file>           (no default).
66  -i <path>,            : Specify path to initctl binary
67  --initctl-path=<path>   (default=$initctl_path).
68  -s, --noscript        : Do not check script sections.
69  -x <path>             : Specify path to init daemon binary
70  --upstart-path=<path>   (default=$upstart_path).
71  -h, --help            : Show this help.
72
73 EOT
74 }
75
76 debug()
77 {
78   msg="$*"
79   [ $debug_enabled = y ] && echo "DEBUG: $msg"
80 }
81
82 error()
83 {
84   msg="$*"
85   printf "ERROR: %s\n" "$msg" >&2
86 }
87
88 die()
89 {
90   error "$*"
91   exit 1
92 }
93
94 # Return 0 if Upstart is running on the D-Bus session bus, else 1.
95 upstart_running()
96 {
97   dbus-send --session --print-reply \
98     --dest='com.ubuntu.Upstart' /com/ubuntu/Upstart \
99     org.freedesktop.DBus.Properties.GetAll \
100     string:'com.ubuntu.Upstart0_6' >/dev/null 2>&1
101 }
102
103 trap cleanup EXIT INT TERM
104
105 args=$(getopt \
106   -n "$script_name" \
107   -a \
108   --options="df:hi:sx:" \
109   --longoptions="debug file: help initctl-path: noscript upstart-path:" \
110   -- "$@")
111
112 eval set -- "$args"
113 [ $? -ne 0 ] && { usage; exit 1; }
114 [ $# -eq 0 ] && { usage; exit 0; }
115
116 while [ $# -gt 0 ]
117 do
118     case "$1" in
119       -d|--debug)
120         debug_enabled=y
121         ;;
122
123       -f|--file)
124         file="$2"
125         shift
126         ;;
127
128       -h|--help)
129         usage
130         exit 0
131         ;;
132
133       -i|--initctl-path)
134         initctl_path="$2"
135         shift
136         ;;
137
138       -s|--noscript)
139         check_scripts=n
140         ;;
141
142       -x|--upstart-path)
143         upstart_path="$2"
144         shift
145         ;;
146
147       --)
148         shift
149         break
150         ;;
151     esac
152     shift
153 done
154
155 [ -z "$file" ] && file="$1"
156
157 # safety first
158 [ "$(id -u)" -eq 0 ] && die "cannot run as root"
159
160 [   -z "$file" ] && die "must specify configuration file"
161 [ ! -f "$file" ] && die "file $file does not exist"
162
163 debug "upstart_path=$upstart_path"
164 debug "initctl_path=$initctl_path"
165
166 for cmd in "$upstart_path" "$initctl_path"
167 do
168   [ -f "$cmd" ] || die "Path $cmd does not exist"
169   [ -x "$cmd" ] || die "File $cmd not executable"
170   "$cmd" --help | grep -q -- --session || die "version of $cmd too old"
171 done
172
173 # this is the only safe way to run another instance of Upstart
174 "$upstart_path" --help|grep -q -- --no-startup-event || die "$upstart_path too old"
175
176 debug "confdir=$confdir"
177 debug "file=$file"
178
179 filename=$(basename $file)
180
181 echo "$filename" | egrep -q '\.conf$' || die "file must end in .conf"
182
183 job="${filename%.conf}"
184
185 cp "$file" "$confdir"
186 debug "job=$job"
187
188 upstart_running
189 [ $? -eq 0 ] && die "Another instance of this program is already running"
190 debug "ok - no other running instances detected"
191
192 upstart_out="$(mktemp --tmpdir "${script_name}-upstart-output.XXXXXXXXXX")"
193 debug "upstart_out=$upstart_out"
194
195 upstart_cmd=$(printf \
196    "%s --session --no-sessions --no-startup-event --verbose --confdir %s" \
197   "$upstart_path" \
198   "$confdir")
199 debug "upstart_cmd=$upstart_cmd"
200
201 nohup $upstart_cmd >"$upstart_out" 2>&1 &
202 upstart_pid=$!
203
204 # Stop the shell outputting a message when Upstart is killed.
205 # We handle this ourselves in cleanup().
206 disown 
207
208 # wait for Upstart to initialize
209 for i in $(seq 1 5)
210 do
211   debug "Waiting for Upstart to reply over D-Bus (attempt $i)"
212   upstart_running
213   if [ $? -eq 0 ]
214   then
215     running=y
216     break
217   fi
218   sleep 1
219 done
220
221 [ $running = n ] && die "failed to ask Upstart to check conf file"
222
223 debug "Secondary Upstart ($upstart_cmd) running with PID $upstart_pid"
224
225 if [ "$check_scripts" = y ]
226 then
227   for section in pre-start post-start script pre-stop post-stop
228   do
229     if egrep -q "\<${section}\>" "$file"
230     then
231       cmd='sed -n "/^ *${section}/,/^ *end script/p" $file | /bin/sh -n 2>&1'
232       errors=$(eval "$cmd")
233       [ $? -ne 0 ] && \
234         die "$(printf "File $file: shell syntax invalid in $section section:\n${errors}")"
235     fi
236   done
237 fi
238
239 "$initctl_path" --session list|grep -q "^${job}"
240 if [ $? -eq 0 ]
241 then
242   file_valid=y
243   echo "File $file: syntax ok"
244   exit 0
245 fi
246
247 errors=$(grep "$job" "$upstart_out"|sed "s,${confdir}/,,g")
248 die "$(printf "File $file: syntax invalid:\n${errors}")"