create history for the overcloud deploy command
Add a history directory in user $HOME for tracking all the calls of the openstack overcloud deploy command passed by the users. Each deploy command run by a user is now track in an history file under $HOME/.tripleo directory. It allow to retrieve all the previous calls from the openstack overcloud deploy command, the environment files used and the templates directories used, for analysis, debugging or tracking. See https://bugs.launchpad.net/tripleo/+bug/1673700 It will be very usefull for post deployment user experience and for customer debuging. This review aim to be backport for old releases support. I will implement a mistral workflow in a follow up review for Pike, as suggested by D0ugal (D Matthews) Change-Id: Ibf7dd4a7b0036b6f2a0809d0448a05665c809167 Closes-Bug: #1673700
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
---
|
||||
fixes:
|
||||
- Each deploy command run by a user is now track in an history file under
|
||||
$HOME/.tripleo directory. It allow to retrieve all the previous calls from
|
||||
the openstack overcloud deploy command, the environment files used and the
|
||||
templates directories used, for analysis, debugging or tracking. See
|
||||
https://bugs.launchpad.net/tripleo/+bug/1673700
|
@@ -15,9 +15,12 @@
|
||||
|
||||
from uuid import uuid4
|
||||
|
||||
import argparse
|
||||
import mock
|
||||
from mock import call
|
||||
import os.path
|
||||
import tempfile
|
||||
|
||||
from unittest import TestCase
|
||||
import yaml
|
||||
|
||||
@@ -712,3 +715,45 @@ class TestBracketIPV6(TestCase):
|
||||
def test_already_bracketed(self):
|
||||
result = utils.bracket_ipv6('[::1]')
|
||||
self.assertEqual('[::1]', result)
|
||||
|
||||
|
||||
class TestStoreCliParam(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.args = argparse.ArgumentParser()
|
||||
|
||||
@mock.patch('os.mkdir')
|
||||
@mock.patch('os.path.exists')
|
||||
def test_fail_to_create_file(self, mock_exists, mock_mkdir):
|
||||
mock_exists.return_value = False
|
||||
mock_mkdir.side_effect = OSError()
|
||||
self.assertRaises(OSError, utils.store_cli_param, self.args)
|
||||
|
||||
@mock.patch('os.path.isdir')
|
||||
@mock.patch('os.path.exists')
|
||||
def test_exists_but_not_dir(self, mock_exists, mock_isdir):
|
||||
mock_exists.return_value = True
|
||||
mock_isdir.return_value = False
|
||||
self.assertRaises(exceptions.InvalidConfiguration,
|
||||
utils.store_cli_param,
|
||||
self.args)
|
||||
|
||||
@mock.patch('six.moves.builtins.open')
|
||||
@mock.patch('os.path.isdir')
|
||||
@mock.patch('os.path.exists')
|
||||
def test_write_cli_param(self, mock_exists, mock_isdir, mock_open):
|
||||
history_path = os.path.join(os.path.expanduser("~"), '.tripleo')
|
||||
mock_exists.return_value = True
|
||||
mock_isdir.return_value = True
|
||||
utils.store_cli_param(self.args)
|
||||
expected_call = [call("%s/history" % history_path, 'a')]
|
||||
mock_open.assert_has_calls(expected_call)
|
||||
|
||||
@mock.patch('six.moves.builtins.open')
|
||||
@mock.patch('os.path.isdir')
|
||||
@mock.patch('os.path.exists')
|
||||
def test_fail_to_write_data(self, mock_exists, mock_isdir, mock_open):
|
||||
mock_exists.return_value = True
|
||||
mock_isdir.return_value = True
|
||||
mock_open.side_effect = IOError()
|
||||
self.assertRaises(IOError, utils.store_cli_param, self.args)
|
||||
|
@@ -15,6 +15,7 @@
|
||||
|
||||
from __future__ import print_function
|
||||
import csv
|
||||
import datetime
|
||||
import hashlib
|
||||
import json
|
||||
import logging
|
||||
@@ -77,6 +78,35 @@ def write_overcloudrc(stack_name, overcloudrcs, config_directory='.'):
|
||||
os.chmod(rcv3path, 0o600)
|
||||
|
||||
|
||||
def store_cli_param(parsed_args):
|
||||
"""write the cli parameters into an history file"""
|
||||
|
||||
history_path = os.path.join(os.path.expanduser("~"), '.tripleo')
|
||||
if not os.path.exists(history_path):
|
||||
try:
|
||||
os.mkdir(history_path)
|
||||
except OSError as e:
|
||||
messages = "Unable to create TripleO history directory: "
|
||||
"{0}, {1}".format(history_path, e)
|
||||
raise OSError(messages)
|
||||
if os.path.isdir(history_path):
|
||||
try:
|
||||
with open(os.path.join(history_path,
|
||||
'history'), 'a') as history:
|
||||
args = parsed_args.__dict__.copy()
|
||||
used_args = ', '.join('%s=%s' % (key, value)
|
||||
for key, value in args.items())
|
||||
history.write(' '.join([str(datetime.datetime.now()),
|
||||
used_args]))
|
||||
except IOError as e:
|
||||
messages = "Unable to write into TripleO history file: "
|
||||
"{0}, {1}".format(history_path, e)
|
||||
raise IOError(messages)
|
||||
else:
|
||||
raise exceptions.InvalidConfiguration("Target path %s is not a "
|
||||
"directory" % history_path)
|
||||
|
||||
|
||||
def create_tempest_deployer_input(config_name='tempest-deployer-input.conf'):
|
||||
config = configparser.ConfigParser()
|
||||
|
||||
|
@@ -812,6 +812,7 @@ class DeployOvercloud(command.Command):
|
||||
sc_logger.setLevel(logging.CRITICAL)
|
||||
|
||||
self._validate_args(parsed_args)
|
||||
utils.store_cli_param(parsed_args)
|
||||
|
||||
stack = utils.get_stack(self.orchestration_client, parsed_args.stack)
|
||||
|
||||
|
Reference in New Issue
Block a user