| #!/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) |