report_start_task() {
- local id="$SNF_IMAGE_HOSTNAME"
- local type="ganeti-start-task"
- local timestamp=$(date +%s)
+ local type="start-task"
+ local timestamp=$(date +%s.%N)
local name="${PROGNAME}"
report="{\"id\":\"$id\","
report+="\"type\":\"$type\"," \
- report+="\"timestamp\":$(date +%s)," \
+ report+="\"timestamp\":$(date +%s.%N)," \
report+="\"name\":\"$name\"}"
echo "$report" > "$MONITOR"
report_end_task() {
- local id="$SNF_IMAGE_HOSTNAME"
- local type="ganeti-end-task"
- local timestam=$(date +%s)
+ local type="end-task"
+ local timestam=$(date +%s.%N)
local name=${PROGNAME}
local warnings=$(json_list WARNINGS[@])
}
report_error() {
- local id="$SNF_IMAGE_HOSTNAME"
local type="ganeti-error"
- local timestamp=$(date +%s)
+ local timestamp=$(date +%s.%N)
local location="${PROGNAME}"
local errors=$(json_list ERRORS[@])
local warnings=$(json_list WARNINGS[@])
rc=$?
if [ $rc -eq 0 ]; then
- report_end_task
+ report_end_task
else
report_error
fi
report="{\"id\":\"$id\","
report+="\"type\":\"$type\"," \
- report+="\"timestamp\":$(date +%s)," \
+ report+="\"timestamp\":$(date +%s.%N)," \
report+="\"location\":\"$location\"," \
report+="\"messages\":$msg," \
report+="\"stderr\":\"$stderr\"}"
mv -f "$tmp_cache" "$HELPER_CACHE_FILE"
}
-cleanup() {
- # Carefull this should be the first command in the function. We want to
- # store the last exit code to see if cleanup was triggered by an abnormal
- # termination of the script.
- local rc=$?
- local err_file=$1
+report_and_cleanup(){
+
+ local err_file="$1"
+
+ report_error "$err_file"
+ cleanup
+}
+cleanup() {
# if something fails here, it souldn't call cleanup again...
trap - EXIT
- if [ $rc -ne 0 -a -f "$err_file" ]; then
- report_error "$err_file"
- fi
-
if [ ${#CLEANUP[*]} -gt 0 ]; then
LAST_ELEMENT=$((${#CLEANUP[*]}-1))
REVERSE_INDEXES=$(seq ${LAST_ELEMENT} -1 0)
"%prog runs 'command' with the specified arguments, monitoring the " \
"number of bytes read by it. 'command' is assumed to be " \
"A program used to install the OS for a Ganeti instance. %prog " \
- "periodically issues notifications of type 'ganeti-copy-progress'."
+ "periodically issues notifications of type 'copy-progress'."
parser = OptionParser(**kw)
parser.disable_interspersed_args()
help="The expected number of bytes to be read, " \
"used to compute input progress",
default=None)
- parser.add_option("-i", "--instance-name", dest="instance_name",
- default=None, metavar="GANETI_INSTANCE",
- help="The Ganeti instance name to be used in AMQP " \
- "notifications")
parser.add_option("-o", "--output", dest="output", default=None,
metavar="FILE",
help="Write output notifications to this file")
(opts, args) = parser.parse_args(args)
- if opts.instance_name is None:
- sys.stderr.write("Fatal: Option '-i' is mandatory.\n")
- parser.print_help()
- sys.exit(1)
if opts.read_bytes is None:
sys.stderr.write("Fatal: Option '-r' is mandatory.\n")
def send_message(to, message):
- message['timestamp'] = int(time.time())
+ message['timestamp'] = time.time()
to.write("%s\n" % json.dumps(message))
to.flush()
(sys.argv[0], pid, iofname))
message = {}
- message['id'] = opts.instance_name
- message['type'] = 'ganeti-copy-progress'
+ message['type'] = 'copy-progress'
message['total'] = opts.read_bytes
while True:
return 1
else:
message['position'] = message['total']
- message['rprogress'] = float(100)
+ message['progress'] = float(100)
send_message(out, message)
return 0
for l in iof.readlines():
if l.startswith("rchar:"):
message['position'] = int(l.split(': ')[1])
- message['rprogress'] = float(100) if opts.read_bytes == 0 \
+ message['progress'] = float(100) if opts.read_bytes == 0 \
else float("%2.2f" % (
message['position'] * 100.0 / message['total']))
send_message(out, message)
add_cleanup rm -f "$monitor_pipe"
if [ -n "$PROGRESS_MONITOR" ]; then
- { cat "$monitor_pipe" | tee >( $PROGRESS_MONITOR ) ; } &
+ { sleep 1; tee >( $PROGRESS_MONITOR ) < "$monitor_pipe" ; } &
+ monitor_pid="$!"
else
cat "$monitor_pipe" &
+ monitor_pid="$!"
fi
# Create file descriptor to monitor_pipe
eval "exec ${MONITOR_FD}>${monitor_pipe}"
add_cleanup close_fd ${MONITOR_FD}
-trap "cleanup $(printf "%q" "$stderr")" EXIT
+# Ignore sigpipe signals. If progress monitor is dead and snf-image-host tries
+# to output something to the opened pipe, then a sigpipe signal will be raised.
+# If I do not catch this, the program will terminate.
+trap "" SIGPIPE
+
+trap "report_and_cleanup $(printf "%q" "$stderr")" EXIT
ganeti_os_main
;;
esac
-monitor="./copy-monitor.py -o $(printf "%q" "$monitor_pipe") \
- -i $(printf "%q" "$INSTANCE_NAME") -r $image_size"
+monitor="./copy-monitor.py -o $(printf "%q" "$monitor_pipe") -r $image_size"
if [ "$BACKEND_TYPE" = "local" ]; then
# dd the dump to its new home :-)
# Deploying an image file on a target block device is a streaming copy
exit 1
fi
+# Do not report errors after this. If the result is not "SUCCESS" then the
+# helper VM should have reported the error.
+trap cleanup EXIT
+
# Read the first line. This will remove \r and \n chars
result=$(sed 's|\r||g' "$result_file" | head -1)