~jamesodhunt/ubuntu/vivid/upstart/bug-1447756

« back to all changes in this revision

Viewing changes to scripts/init-checkconf.sh

  • Committer: James Hunt
  • Date: 2011-12-14 14:09:46 UTC
  • mfrom: (1185.1.14 upstream)
  • Revision ID: james.hunt@ubuntu.com-20111214140946-omh0ikuf6utjdm1o
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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}")"