#!/usr/bin/python3 # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. from subprocess import * import sys import logging LOG_FILE='/var/log/cloudstack/agent/rolling-maintenance.log' AVOID_MAINTENANCE_EXIT_STATUS=70 logging.basicConfig(filename=LOG_FILE, filemode='a', format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s', datefmt='%H:%M:%S', level=logging.INFO) logger = logging.getLogger('rolling-maintenance') def execute_script(stage, script, payload, timeout): logger.info("Executing script: %s for stage: %s" % (script, stage)) try: command = "timeout %s %s " % (str(timeout), script) if payload: logger.info("Adding payload: %s" % payload) command += " " + payload pout = Popen(command, shell=True, stdout=PIPE, stderr=PIPE) exitStatus = pout.wait() stdout, stderr = pout.communicate() success = True if exitStatus == 0 or exitStatus == AVOID_MAINTENANCE_EXIT_STATUS else False avoid_maintenance = True if exitStatus == AVOID_MAINTENANCE_EXIT_STATUS else False return {"success": success, "message": stdout.decode('utf-8').strip(), "avoidmaintenance": avoid_maintenance} except Exception as e: logger.error("Error in stage %s: %s" % (script, e)) sys.exit(1) if __name__ == '__main__': try: logger.info(sys.argv) if len(sys.argv) < 2: logger.error("Arguments missing") sys.exit(0) args = sys.argv[1] params = args.split(',') if len(params) < 5: logger.error("Wrong number of parameters received, STAGE,SCRIPT,TIMEOUT,RESULTS_FILE,OUTPUT_FILE" "[,PAYLOAD] expected") sys.exit(0) stage = params[0] script = params[1] timeout = params[2] results_file_path = params[3] output_file_path = params[4] payload = params[5] if len(params) > 5 else None logger.info("Received parameters: stage: %s, script: %s, timeout: %s, results_file: %s, output_file: %s " "and payload: %s" % (stage, script, timeout, results_file_path, output_file_path, payload)) results = execute_script(stage, script, payload, timeout) # Persist results and output on a file output_file = open(output_file_path, "w+") output_file.write(results['message']) output_file.close() results_file = open(results_file_path, "w+") results_file.write("%s,%s,%s" % (stage, str(results['success']), str(results['avoidmaintenance']))) results_file.close() msg = "Successful execution of %s" if results['success'] else "Script execution failed: %s" logger.info(results['message']) logger.info(msg % script) except Exception as e: logger.error("Unexpected error on systemd service: %s" % e) sys.exit(1)