Added progress reporter playbook 54/754/1
authorJyrki Aaltonen <jyrki.aaltonen@nokia.com>
Mon, 13 May 2019 10:34:31 +0000 (13:34 +0300)
committerJyrki Aaltonen <jyrki.aaltonen@nokia.com>
Mon, 20 May 2019 13:23:45 +0000 (16:23 +0300)
Change-Id: Ie2d313c1bd4145f7d48e23d07dc91e3a2b1caa85
Signed-off-by: Jyrki Aaltonen <jyrki.aaltonen@nokia.com>
infra-ansible.spec
playbooks/report-installation-progress [new file with mode: 0755]
playbooks/report-installation-success.sh [new file with mode: 0644]
playbooks/report_installation_progress.yml [new file with mode: 0644]
systemd/finalize-bootstrap.sh
systemd/report-installation-success.service [new file with mode: 0644]

index 42c045e..144eb76 100644 (file)
@@ -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 (executable)
index 0000000..7da8164
--- /dev/null
@@ -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 (file)
index 0000000..75c6c74
--- /dev/null
@@ -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 (file)
index 0000000..bdecbd6
--- /dev/null
@@ -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
index f2b12bc..019338e 100644 (file)
@@ -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 (file)
index 0000000..d668630
--- /dev/null
@@ -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