Remove the logging to Swift custom Mistral actions
In I0419ca070553ad7261cda947c2d246a44df5580d the workflow was removed, this change removes the related custom actions that are now unused. Change-Id: I4e73402a2bb2feec2e8fde0ab134317d31be5df9
This commit is contained in:
parent
525a48b972
commit
5566697549
@ -132,9 +132,6 @@ mistral.actions =
|
||||
tripleo.plan.update_roles = tripleo_common.actions.plan:UpdateRolesAction
|
||||
tripleo.plan.validate_roles = tripleo_common.actions.plan:ValidateRolesDataAction
|
||||
tripleo.plan.remove_noop_deploystep = tripleo_common.actions.plan:RemoveNoopDeployStepAction
|
||||
tripleo.logging_to_swift.format_messages = tripleo_common.actions.logging_to_swift:FormatMessagesAction
|
||||
tripleo.logging_to_swift.publish_ui_log_to_swift = tripleo_common.actions.logging_to_swift:PublishUILogToSwiftAction
|
||||
tripleo.logging_to_swift.prepare_log_download = tripleo_common.actions.logging_to_swift:PrepareLogDownloadAction
|
||||
tripleo.scale.delete_node = tripleo_common.actions.scale:ScaleDownAction
|
||||
tripleo.swift.tempurl = tripleo_common.actions.swifthelper:SwiftTempUrlAction
|
||||
tripleo.swift.swift_information = tripleo_common.actions.swifthelper:SwiftInformationAction
|
||||
|
@ -1,190 +0,0 @@
|
||||
# Copyright 2017 Red Hat, Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
import json
|
||||
import logging
|
||||
import shutil
|
||||
import tempfile
|
||||
import time
|
||||
|
||||
from mistral_lib import actions
|
||||
from oslo_concurrency import processutils
|
||||
from swiftclient import exceptions as swiftexceptions
|
||||
|
||||
from tripleo_common.actions import base
|
||||
from tripleo_common import constants
|
||||
from tripleo_common.utils import swift as swiftutils
|
||||
from tripleo_common.utils import time_functions as timeutils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class FormatMessagesAction(actions.Action):
|
||||
"""Format messages as logs
|
||||
|
||||
Given a list of Zaqar messages from the TripleO UI, return a log-formatted
|
||||
string
|
||||
"""
|
||||
def __init__(self, messages):
|
||||
super(FormatMessagesAction, self).__init__()
|
||||
self.messages = messages
|
||||
|
||||
def run(self, context):
|
||||
lines = []
|
||||
|
||||
for zaqar_message in self.messages:
|
||||
log_object = zaqar_message.get('body')
|
||||
|
||||
if not log_object:
|
||||
continue
|
||||
|
||||
body = log_object.get('message', '')
|
||||
level = log_object.get('level', 'info')
|
||||
timestamp = log_object.get('timestamp', time.time() * 1000)
|
||||
|
||||
if isinstance(body, (dict, list,)):
|
||||
body = json.dumps(body)
|
||||
|
||||
lines.append(
|
||||
'{date} {level} {body}'.format(
|
||||
date=timeutils.epoch_to_formatted_date(timestamp),
|
||||
level=level,
|
||||
body=body
|
||||
)
|
||||
)
|
||||
|
||||
return '\n'.join(lines)
|
||||
|
||||
|
||||
class PublishUILogToSwiftAction(base.TripleOAction):
|
||||
"""Publish logs from UI to Swift"""
|
||||
|
||||
def __init__(self, logging_data, logging_container):
|
||||
super(PublishUILogToSwiftAction, self).__init__()
|
||||
self.logging_data = logging_data
|
||||
self.logging_container = logging_container
|
||||
|
||||
def _rotate(self, swift):
|
||||
"""Optimistic log rotation
|
||||
|
||||
Failure to sucessfully complete log rotation doesn't cause the
|
||||
entire action to fail
|
||||
"""
|
||||
try:
|
||||
headers = swift.head_object(self.logging_container,
|
||||
constants.TRIPLEO_UI_LOG_FILENAME)
|
||||
content_length = int(headers['content-length'])
|
||||
if content_length < constants.TRIPLEO_UI_LOG_FILE_SIZE:
|
||||
LOG.debug("Log file hasn't reached a full size so it doesn't"
|
||||
" need to be rotated.")
|
||||
return
|
||||
except swiftexceptions.ClientException:
|
||||
LOG.debug("Couldn't get existing log file, skip log rotation.")
|
||||
return
|
||||
|
||||
try:
|
||||
files = swift.get_container(self.logging_container)[1]
|
||||
except swiftexceptions.ClientException:
|
||||
LOG.warn("Logging container doesn't exist, skip log rotation.")
|
||||
return
|
||||
|
||||
largest_existing_suffix = 0
|
||||
|
||||
for f in files:
|
||||
try:
|
||||
suffix = int(f['name'].split('.')[-1])
|
||||
if suffix > largest_existing_suffix:
|
||||
largest_existing_suffix = suffix
|
||||
except ValueError:
|
||||
continue
|
||||
|
||||
next_suffix = largest_existing_suffix + 1
|
||||
next_filename = '{}.{}'.format(
|
||||
constants.TRIPLEO_UI_LOG_FILENAME, next_suffix)
|
||||
try:
|
||||
swift.copy_object(
|
||||
self.logging_container,
|
||||
constants.TRIPLEO_UI_LOG_FILENAME,
|
||||
"/%s/%s" % (self.logging_container, next_filename))
|
||||
swift.delete_object(self.logging_container,
|
||||
constants.TRIPLEO_UI_LOG_FILENAME)
|
||||
except swiftexceptions.ClientException as err:
|
||||
msg = "Log rotation failed: %s" % err
|
||||
LOG.warn(msg)
|
||||
|
||||
def run(self, context):
|
||||
swift = self.get_object_client(context)
|
||||
swiftutils.create_container(swift, self.logging_container)
|
||||
self._rotate(swift)
|
||||
|
||||
try:
|
||||
old_contents = swiftutils.get_object_string(
|
||||
swift,
|
||||
self.logging_container,
|
||||
constants.TRIPLEO_UI_LOG_FILENAME)
|
||||
new_contents = "%s\n%s" % (old_contents, self.logging_data)
|
||||
except swiftexceptions.ClientException:
|
||||
LOG.debug(
|
||||
"There is no existing logging data, starting a new file.")
|
||||
new_contents = self.logging_data
|
||||
|
||||
try:
|
||||
swiftutils.put_object_string(
|
||||
swift,
|
||||
self.logging_container,
|
||||
constants.TRIPLEO_UI_LOG_FILENAME,
|
||||
new_contents)
|
||||
except swiftexceptions.ClientException as err:
|
||||
msg = "Failed to publish logs: %s" % err
|
||||
return actions.Result(error=msg)
|
||||
|
||||
|
||||
class PrepareLogDownloadAction(base.TripleOAction):
|
||||
"""Publish all GUI logs to a temporary URL"""
|
||||
|
||||
def __init__(self, logging_container, downloads_container, delete_after):
|
||||
super(PrepareLogDownloadAction, self).__init__()
|
||||
self.logging_container = logging_container
|
||||
self.downloads_container = downloads_container
|
||||
self.delete_after = delete_after
|
||||
|
||||
def run(self, context):
|
||||
swift = self.get_object_client(context)
|
||||
swift_service = self.get_object_service(context)
|
||||
|
||||
tmp_dir = tempfile.mkdtemp()
|
||||
tarball_name = 'logs-%s.tar.gz' % timeutils.timestamp()
|
||||
|
||||
try:
|
||||
swiftutils.download_container(
|
||||
swift, self.logging_container, tmp_dir)
|
||||
swiftutils.create_and_upload_tarball(
|
||||
swift_service, tmp_dir, self.downloads_container,
|
||||
tarball_name, delete_after=self.delete_after)
|
||||
except swiftexceptions.ClientException as err:
|
||||
msg = "Error attempting an operation on container: %s" % err
|
||||
return actions.Result(error=msg)
|
||||
except (OSError, IOError) as err:
|
||||
msg = "Error while writing file: %s" % err
|
||||
return actions.Result(error=msg)
|
||||
except processutils.ProcessExecutionError as err:
|
||||
msg = "Error while creating a tarball: %s" % err
|
||||
return actions.Result(error=msg)
|
||||
except Exception as err:
|
||||
msg = "Error exporting logs: %s" % err
|
||||
return actions.Result(error=msg)
|
||||
finally:
|
||||
shutil.rmtree(tmp_dir)
|
||||
|
||||
return tarball_name
|
@ -1,176 +0,0 @@
|
||||
# Copyright 2017 Red Hat, Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
import mock
|
||||
|
||||
from oslo_concurrency import processutils
|
||||
|
||||
from tripleo_common.actions import logging_to_swift
|
||||
from tripleo_common.tests import base
|
||||
|
||||
|
||||
class LogFormattingTest(base.TestCase):
|
||||
|
||||
def test_log_formatting(self):
|
||||
messages = [
|
||||
{
|
||||
'body': {
|
||||
'message': 'Test 1',
|
||||
'level': 'INFO',
|
||||
'timestamp': '1496322000000'
|
||||
}
|
||||
},
|
||||
{
|
||||
'body': {
|
||||
'message': 'Test 2',
|
||||
'level': 'WARN',
|
||||
'timestamp': '1496329200000'
|
||||
}
|
||||
}
|
||||
]
|
||||
action = logging_to_swift.FormatMessagesAction(messages)
|
||||
result = action.run({})
|
||||
self.assertEqual(result, ('2017-06-01 13:00:00 INFO Test 1\n'
|
||||
'2017-06-01 15:00:00 WARN Test 2'))
|
||||
|
||||
|
||||
class PublishUILogToSwiftActionTest(base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(PublishUILogToSwiftActionTest, self).setUp()
|
||||
self.container = 'container'
|
||||
self.swift = mock.MagicMock()
|
||||
swift_patcher = mock.patch(
|
||||
'tripleo_common.actions.base.TripleOAction.get_object_client',
|
||||
return_value=self.swift)
|
||||
swift_patcher.start()
|
||||
self.addCleanup(swift_patcher.stop)
|
||||
self.ctx = mock.MagicMock()
|
||||
|
||||
def test_simple_success(self):
|
||||
self.swift.head_object.return_value = {
|
||||
'content-length': 1
|
||||
}
|
||||
data = 'data'
|
||||
action = logging_to_swift.PublishUILogToSwiftAction(
|
||||
data, self.container)
|
||||
action.run(self.ctx)
|
||||
|
||||
self.swift.get_object.assert_called_once()
|
||||
self.swift.head_object.assert_called_once()
|
||||
self.swift.put_object.assert_called_once()
|
||||
self.swift.put_container.assert_called_once()
|
||||
|
||||
def test_rotate(self):
|
||||
self.swift.head_object.return_value = {
|
||||
'content-length': 2e7
|
||||
}
|
||||
self.swift.get_container.return_value = (
|
||||
{}, []
|
||||
)
|
||||
|
||||
old_data = 'old data'
|
||||
new_data = 'new data'
|
||||
result = old_data + '\n' + new_data
|
||||
|
||||
self.swift.get_object.return_value = ({}, old_data)
|
||||
|
||||
action = logging_to_swift.PublishUILogToSwiftAction(
|
||||
new_data, self.container)
|
||||
action.run(self.ctx)
|
||||
|
||||
self.swift.head_object.assert_called_once()
|
||||
self.swift.put_object.assert_called_with(
|
||||
self.container,
|
||||
'tripleo-ui.logs',
|
||||
result
|
||||
)
|
||||
|
||||
|
||||
class PrepareLogDownloadActionTest(base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(PrepareLogDownloadActionTest, self).setUp()
|
||||
self.log_files = (
|
||||
'tripleo-ui.logs.2',
|
||||
'tripleo-ui.logs.1',
|
||||
'tripleo-ui.logs'
|
||||
)
|
||||
self.swift = mock.MagicMock()
|
||||
self.swift.get_container.return_value = (
|
||||
{'x-container-meta-usage-tripleo': 'plan'}, [
|
||||
{'name': lf} for lf in self.log_files
|
||||
]
|
||||
)
|
||||
self.swift.get_object.return_value = ({}, 'log content')
|
||||
swift_patcher = mock.patch(
|
||||
'tripleo_common.actions.base.TripleOAction.get_object_client',
|
||||
return_value=self.swift)
|
||||
swift_patcher.start()
|
||||
self.addCleanup(swift_patcher.stop)
|
||||
|
||||
self.ctx = mock.MagicMock()
|
||||
|
||||
@mock.patch('tripleo_common.actions.base.TripleOAction.get_object_service')
|
||||
@mock.patch('tripleo_common.utils.tarball.create_tarball')
|
||||
def test_run_success(self,
|
||||
mock_create_tarball,
|
||||
mock_get_obj_service):
|
||||
|
||||
get_object_mock_calls = [
|
||||
mock.call('logging-container', lf) for lf in self.log_files
|
||||
]
|
||||
get_container_mock_calls = [
|
||||
mock.call('logging-container')
|
||||
]
|
||||
|
||||
swift_service = mock.MagicMock()
|
||||
swift_service.delete.return_value = ([
|
||||
{'success': True},
|
||||
])
|
||||
mock_get_obj_service.return_value = swift_service
|
||||
|
||||
action = logging_to_swift.PrepareLogDownloadAction(
|
||||
'logging-container', 'downloads-container', 3600
|
||||
)
|
||||
|
||||
action.run(self.ctx)
|
||||
|
||||
self.swift.get_container.assert_has_calls(get_container_mock_calls)
|
||||
self.swift.get_object.assert_has_calls(
|
||||
get_object_mock_calls, any_order=True)
|
||||
mock_create_tarball.assert_called_once()
|
||||
|
||||
@mock.patch('tripleo_common.actions.base.TripleOAction.get_object_service')
|
||||
@mock.patch('tripleo_common.utils.tarball.create_tarball')
|
||||
def test_run_error_creating_tarball(self,
|
||||
mock_create_tarball,
|
||||
mock_get_obj_service):
|
||||
|
||||
mock_create_tarball.side_effect = processutils.ProcessExecutionError
|
||||
|
||||
swift_service = mock.MagicMock()
|
||||
swift_service.delete.return_value = ([
|
||||
{'success': True},
|
||||
])
|
||||
mock_get_obj_service.return_value = swift_service
|
||||
|
||||
action = logging_to_swift.PrepareLogDownloadAction(
|
||||
'logging-container', 'downloads-container', 3600
|
||||
)
|
||||
|
||||
result = action.run(self.ctx)
|
||||
|
||||
error = "Error while creating a tarball"
|
||||
self.assertIn(error, result.error)
|
Loading…
x
Reference in New Issue
Block a user