From 972df96690f76f42d4351686c75bc8e5d1b2cb31 Mon Sep 17 00:00:00 2001 From: Jyrki Aaltonen Date: Mon, 13 May 2019 13:34:31 +0300 Subject: [PATCH] Added progress reporter playbook Change-Id: Ie2d313c1bd4145f7d48e23d07dc91e3a2b1caa85 Signed-off-by: Jyrki Aaltonen --- infra-ansible.spec | 3 + playbooks/report-installation-progress | 163 ++++++++++++++++++++++++++++ playbooks/report-installation-success.sh | 33 ++++++ playbooks/report_installation_progress.yml | 23 ++++ systemd/finalize-bootstrap.sh | 3 + systemd/report-installation-success.service | 23 ++++ 6 files changed, 248 insertions(+) create mode 100755 playbooks/report-installation-progress create mode 100644 playbooks/report-installation-success.sh create mode 100644 playbooks/report_installation_progress.yml create mode 100644 systemd/report-installation-success.service diff --git a/infra-ansible.spec b/infra-ansible.spec index 42c045e..144eb76 100644 --- a/infra-ansible.spec +++ b/infra-ansible.spec @@ -123,6 +123,7 @@ ln -sf /opt/config-encoder-macros %{buildroot}%{_roles_path}/access-management/t mkdir -p %{buildroot}/usr/lib/systemd/system/ cp systemd/finalize-bootstrap.service %{buildroot}/usr/lib/systemd/system/ cp systemd/sriov.service %{buildroot}/usr/lib/systemd/system +cp systemd/report-installation-success.service %{buildroot}/usr/lib/systemd/system mkdir -p %{buildroot}/opt/ansible-change_kernel_cmdline/ cp systemd/finalize-bootstrap.sh %{buildroot}/opt/ansible-change_kernel_cmdline/ @@ -131,6 +132,8 @@ mkdir -p %{buildroot}/opt/sriov cp systemd/sriov.sh %{buildroot}/opt/sriov %files +%attr(0755,root,root) %{_playbooks_path}/report-installation-progress +%attr(0755,root,root) %{_playbooks_path}/report-installation-success.sh %defattr(0644,root,root,0755) /root/dev_tools %{_playbooks_path}/* diff --git a/playbooks/report-installation-progress b/playbooks/report-installation-progress new file mode 100755 index 0000000..7da8164 --- /dev/null +++ b/playbooks/report-installation-progress @@ -0,0 +1,163 @@ +#! /usr/bin/python + +# Copyright 2019 Nokia +# +# Licensed 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 __future__ import print_function +import sys +import argparse +import logging + +import requests + +class ProgressReporter(object): + CALLBACK_URL_PATH = '/etc/userconfig/callback_url' + DEFAULT_CLIENT_CERT = '/etc/userconfig/clientcert.pem' + DEFAULT_CLIENT_KEY = '/etc/userconfig/clientkey.pem' + + def __init__(self): + self._prog = 'progress-reporter' + self._callback_url = None + self._verbose = None + self._status = None + self._percentage = None + self._description = None + self._client_cert_path = ProgressReporter.DEFAULT_CLIENT_CERT + self._client_key_path = ProgressReporter.DEFAULT_CLIENT_KEY + + def __call__(self, args): + parser = argparse.ArgumentParser(description='Progress Reporter', + prog=self._prog) + + parser.add_argument('--callback-url', + dest='callback_url', + metavar='CALLBACK-URL', + required=False, + help='The URL for the report callback', + action='store') + + parser.add_argument('--client-cert-path', + dest='client_cert_path', + metavar='CLIENT-CERT-PATH', + required=False, + help='The path to client cert file', + action='store') + + parser.add_argument('--client-key-path', + dest='client_key_path', + metavar='CLIENT-KEY-PATH', + required=False, + help='The path to client key file', + action='store') + + parser.add_argument('--status', + dest='status', + metavar='STATUS', + required=True, + help='The status of the progress, should be: ongoing or failed or success', + action='store') + + parser.add_argument('--description', + dest='description', + metavar='DESCRIPTION', + required=True, + help='The description of the progress', + action='store') + + parser.add_argument('--percentage', + dest='percentage', + metavar='PERCENTAGE', + required=False, + help='The percentage of the progress', + action='store') + + parser.add_argument('--verbose', + required=False, + default=False, + action='store_true') + + args = parser.parse_args(args) + + self.process(args) + + def _set_callback_url(self): + try: + with open(ProgressReporter.CALLBACK_URL_PATH) as cf: + self._callback_url = cf.readline().strip() + except IOError: + logging.debug('No callback URL found') + + def _send_progress(self): + if self._callback_url: + request_data = {'status': self._status, 'description': self._description} + if self._percentage: + request_data['percentage'] = self._percentage + + cert_tuple = None + if self._client_cert_path: + cert_tuple = (self._client_cert_path, self._client_key_path) + + response = None + try: + response = requests.post(self._callback_url, json=request_data, cert=cert_tuple, verify=False) + if response.status_code != requests.codes.ok: + logging.debug('Failed to send progress: %s (%s)', str(response.reason), str(response.status_code)) + raise Exception('Failed') + except Exception as ex: + logging.debug('Failed to send progress: %s', str(ex)) + raise Exception('Failed') + + return True + + def process(self, args): + log_level = logging.INFO + if args.verbose: + log_level = logging.DEBUG + + logging.basicConfig(level=log_level, format='%(asctime)s %(message)s') + + self._callback_url = args.callback_url + if not self._callback_url: + self._set_callback_url() + + if args.client_cert_path: + self._client_cert_path = args.client_cert_path + + if args.client_key_path: + self._client_key_path = args.client_key_path + + self._verbose = args.verbose + self._status = args.status + self._percentage = args.percentage + self._description = args.description + + logging.debug('callback_url = %s', self._callback_url) + logging.debug('client_cert_path = %s', self._client_cert_path) + logging.debug('client_key_path = %s', self._client_key_path) + logging.info('status=%s, percentage=%s, description=%s', self._status, self._percentage, self._description) + + self._send_progress() + +def main(): + try: + reporter = ProgressReporter() + args = sys.argv[1:] + reporter(args) + except Exception as exp: + logging.error('Failed with error: %s', str(exp)) + return 1 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/playbooks/report-installation-success.sh b/playbooks/report-installation-success.sh new file mode 100644 index 0000000..75c6c74 --- /dev/null +++ b/playbooks/report-installation-success.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# Copyright 2019 Nokia + +# Licensed 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. + +MAX_TRIES=5 +COUNT=0 +while [ $COUNT -lt $MAX_TRIES ]; do + if [ "$_INSTALLATION_SUCCESS" == "success" ]; then + /opt/openstack-ansible/playbooks/report-installation-progress --status completed --description "Installation complete" --percentage 100 + else + /opt/openstack-ansible/playbooks/report-installation-progress --status failed --description "Installation failed" + fi + + if [ "$?" -eq 0 ]; then + exit 0 + fi + sleep 10 + let COUNT=COUNT+1 +done + +exit 1 diff --git a/playbooks/report_installation_progress.yml b/playbooks/report_installation_progress.yml new file mode 100644 index 0000000..bdecbd6 --- /dev/null +++ b/playbooks/report_installation_progress.yml @@ -0,0 +1,23 @@ +# Copyright 2019 Nokia + +# Licensed 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. + +--- +- name: Report installation progress + hosts: [ management ] + gather_facts: False + tasks: + - name: Report installation progress + shell: "/opt/openstack-ansible/playbooks/report-installation-progress --status ongoing --description \"Working on: {{ installation_progress_phase }} {{ installation_progress_playbook }}\" --percentage {{ installation_progress }}" + ignore_errors: yes + when: inventory_hostname == installation_controller diff --git a/systemd/finalize-bootstrap.sh b/systemd/finalize-bootstrap.sh index f2b12bc..019338e 100644 --- a/systemd/finalize-bootstrap.sh +++ b/systemd/finalize-bootstrap.sh @@ -26,8 +26,11 @@ if [ ! -f /etc/performance-nodes/dpdk.enabled ] then if has_kernel_parameters_changed; then + systemctl set-environment _INSTALLATION_SUCCESS='failed' log_installation_failure else + systemctl set-environment _INSTALLATION_SUCCESS='success' log_installation_success fi + systemctl start report-installation-success.service --no-block fi diff --git a/systemd/report-installation-success.service b/systemd/report-installation-success.service new file mode 100644 index 0000000..d668630 --- /dev/null +++ b/systemd/report-installation-success.service @@ -0,0 +1,23 @@ +# Copyright 2019 Nokia + +# Licensed 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. + +[Unit] +Description=report installation success +After=network.target +Wants=network.target + +[Service] +Type=oneshot +RemainAfterExit=True +ExecStart=/opt/openstack-ansible/playbooks/report-installation-success.sh -- 2.16.6