Allow customizing ramdisk logs file names and simplify the default

The template for ramdisk logs file names can now be changed via
the configuration. The default now contains only node UUID and datetime.
Also a proper tar.gz extension is appended to avoid confusion.

Depends-On: Ie507e2e5c58cffa255bbfb2fa5ffb95cb98ed8c4
Change-Id: I738f9bd35705d0d11c95b0164186ed0b366b5252
This commit is contained in:
Dmitry Tantsur 2016-07-01 13:51:05 +02:00
parent 1809443612
commit c98d3f479b
5 changed files with 96 additions and 57 deletions

View File

@ -408,15 +408,15 @@
# From ironic_inspector.common.ironic
#
# Authentication URL (unknown value)
# Authentication URL (string value)
#auth_url = <None>
# Method to use for authentication: noauth or keystone. (string value)
# Allowed values: keystone, noauth
#auth_strategy = keystone
# Authentication type to load (unknown value)
# Deprecated group/name - [DEFAULT]/auth_plugin
# Authentication type to load (string value)
# Deprecated group/name - [ironic]/auth_plugin
#auth_type = <None>
# PEM encoded Certificate Authority to use when verifying HTTPs
@ -428,18 +428,18 @@
# Optional domain ID to use with v3 and v2 parameters. It will be used
# for both the user and project domain in v3 and ignored in v2
# authentication. (unknown value)
# authentication. (string value)
#default_domain_id = <None>
# Optional domain name to use with v3 API and v2 parameters. It will
# be used for both the user and project domain in v3 and ignored in v2
# authentication. (unknown value)
# authentication. (string value)
#default_domain_name = <None>
# Domain ID to scope to (unknown value)
# Domain ID to scope to (string value)
#domain_id = <None>
# Domain name to scope to (unknown value)
# Domain name to scope to (string value)
#domain_name = <None>
# DEPRECATED: Keystone admin endpoint. DEPRECATED: Use
@ -510,50 +510,50 @@
# Reason: Use options presented by configured keystone auth plugin.
#os_username =
# User's password (unknown value)
# User's password (string value)
#password = <None>
# Domain ID containing project (unknown value)
# Domain ID containing project (string value)
#project_domain_id = <None>
# Domain name containing project (unknown value)
# Domain name containing project (string value)
#project_domain_name = <None>
# Project ID to scope to (unknown value)
# Deprecated group/name - [DEFAULT]/tenant-id
# Project ID to scope to (string value)
# Deprecated group/name - [ironic]/tenant-id
#project_id = <None>
# Project name to scope to (unknown value)
# Deprecated group/name - [DEFAULT]/tenant-name
# Project name to scope to (string value)
# Deprecated group/name - [ironic]/tenant-name
#project_name = <None>
# Interval between retries in case of conflict error (HTTP 409).
# (integer value)
#retry_interval = 2
# Tenant ID (unknown value)
# Tenant ID (string value)
#tenant_id = <None>
# Tenant Name (unknown value)
# Tenant Name (string value)
#tenant_name = <None>
# Timeout value for http requests (integer value)
#timeout = <None>
# Trust ID (unknown value)
# Trust ID (string value)
#trust_id = <None>
# User's domain id (unknown value)
# User's domain id (string value)
#user_domain_id = <None>
# User's domain name (unknown value)
# User's domain name (string value)
#user_domain_name = <None>
# User id (unknown value)
# User id (string value)
#user_id = <None>
# Username (unknown value)
# Deprecated group/name - [DEFAULT]/user-name
# Username (string value)
# Deprecated group/name - [ironic]/user-name
#username = <None>
@ -609,7 +609,7 @@
# Optionally specify a list of memcached server(s) to use for caching.
# If left undefined, tokens will instead be cached in-process. (list
# value)
# Deprecated group/name - [DEFAULT]/memcache_servers
# Deprecated group/name - [keystone_authtoken]/memcache_servers
#memcached_servers = <None>
# In order to prevent excessive effort spent validating tokens, the
@ -693,11 +693,11 @@
# value)
#hash_algorithms = md5
# Authentication type to load (unknown value)
# Deprecated group/name - [DEFAULT]/auth_plugin
# Authentication type to load (string value)
# Deprecated group/name - [keystone_authtoken]/auth_plugin
#auth_type = <None>
# Config Section from which to load plugin specific options (unknown
# Config Section from which to load plugin specific options (string
# value)
#auth_section = <None>
@ -785,6 +785,12 @@
# processing. (boolean value)
#log_bmc_address = true
# File name template for storing ramdisk logs. The following
# replacements can be used: {uuid} - node UUID or "unknown", {bmc} -
# node BMC address or "unknown", {dt} - current UTC date and time,
# {mac} - PXE booting MAC or "unknown". (string value)
#ramdisk_logs_filename_format = {uuid}_bmc_{bmc}-{dt:%Y.%m.%d_%H.%M.%S_%f}.tar.gz
[swift]
@ -792,11 +798,11 @@
# From ironic_inspector.common.swift
#
# Authentication URL (unknown value)
# Authentication URL (string value)
#auth_url = <None>
# Authentication type to load (unknown value)
# Deprecated group/name - [DEFAULT]/auth_plugin
# Authentication type to load (string value)
# Deprecated group/name - [swift]/auth_plugin
#auth_type = <None>
# PEM encoded Certificate Authority to use when verifying HTTPs
@ -811,22 +817,22 @@
# Optional domain ID to use with v3 and v2 parameters. It will be used
# for both the user and project domain in v3 and ignored in v2
# authentication. (unknown value)
# authentication. (string value)
#default_domain_id = <None>
# Optional domain name to use with v3 API and v2 parameters. It will
# be used for both the user and project domain in v3 and ignored in v2
# authentication. (unknown value)
# authentication. (string value)
#default_domain_name = <None>
# Number of seconds that the Swift object will last before being
# deleted. (set to 0 to never delete the object). (integer value)
#delete_after = 0
# Domain ID to scope to (unknown value)
# Domain ID to scope to (string value)
#domain_id = <None>
# Domain name to scope to (unknown value)
# Domain name to scope to (string value)
#domain_name = <None>
# Verify HTTPS connections. (boolean value)
@ -860,44 +866,44 @@
# Swift service type. (string value)
#os_service_type = object-store
# User's password (unknown value)
# User's password (string value)
#password = <None>
# Domain ID containing project (unknown value)
# Domain ID containing project (string value)
#project_domain_id = <None>
# Domain name containing project (unknown value)
# Domain name containing project (string value)
#project_domain_name = <None>
# Project ID to scope to (unknown value)
# Deprecated group/name - [DEFAULT]/tenant-id
# Project ID to scope to (string value)
# Deprecated group/name - [swift]/tenant-id
#project_id = <None>
# Project name to scope to (unknown value)
# Deprecated group/name - [DEFAULT]/tenant-name
# Project name to scope to (string value)
# Deprecated group/name - [swift]/tenant-name
#project_name = <None>
# Tenant ID (unknown value)
# Tenant ID (string value)
#tenant_id = <None>
# Tenant Name (unknown value)
# Tenant Name (string value)
#tenant_name = <None>
# Timeout value for http requests (integer value)
#timeout = <None>
# Trust ID (unknown value)
# Trust ID (string value)
#trust_id = <None>
# User's domain id (unknown value)
# User's domain id (string value)
#user_domain_id = <None>
# User's domain name (unknown value)
# User's domain name (string value)
#user_domain_name = <None>
# User id (unknown value)
# User id (string value)
#user_id = <None>
# Username (unknown value)
# Deprecated group/name - [DEFAULT]/user-name
# Username (string value)
# Deprecated group/name - [swift]/user-name
#username = <None>

View File

@ -129,6 +129,14 @@ PROCESSING_OPTS = [
default=True,
help='Whether to log node BMC address with every message '
'during processing.'),
cfg.StrOpt('ramdisk_logs_filename_format',
default='{uuid}_{dt:%Y%m%d-%H%M%S.%f}.tar.gz',
help='File name template for storing ramdisk logs. The '
'following replacements can be used: '
'{uuid} - node UUID or "unknown", '
'{bmc} - node BMC address or "unknown", '
'{dt} - current UTC date and time, '
'{mac} - PXE booting MAC or "unknown".'),
]

View File

@ -41,7 +41,6 @@ _CREDENTIALS_WAIT_RETRIES = 10
_CREDENTIALS_WAIT_PERIOD = 3
_STORAGE_EXCLUDED_KEYS = {'logs'}
_UNPROCESSED_DATA_STORE_SUFFIX = 'UNPROCESSED'
_DATETIME_FORMAT = '%Y.%m.%d_%H.%M.%S_%f'
def _store_logs(introspection_data, node_info):
@ -58,10 +57,16 @@ def _store_logs(introspection_data, node_info):
data=introspection_data, node_info=node_info)
return
time_fmt = datetime.datetime.utcnow().strftime(_DATETIME_FORMAT)
bmc_address = (utils.get_ipmi_address_from_data(introspection_data)
or 'unknown')
file_name = 'bmc_%s_%s' % (bmc_address, time_fmt)
fmt_args = {
'uuid': node_info.uuid if node_info is not None else 'unknown',
'mac': (utils.get_pxe_mac(introspection_data) or
'unknown').replace(':', ''),
'dt': datetime.datetime.utcnow(),
'bmc': (utils.get_ipmi_address_from_data(introspection_data) or
'unknown')
}
file_name = CONF.processing.ramdisk_logs_filename_format.format(**fmt_args)
try:
if not os.path.exists(CONF.processing.ramdisk_logs_dir):

View File

@ -258,13 +258,15 @@ class TestStoreLogs(BaseProcessTest):
self.logs = b'test logs'
self.data['logs'] = base64.b64encode(self.logs)
def _check_contents(self):
def _check_contents(self, name=None):
files = os.listdir(self.tempdir)
self.assertEqual(1, len(files))
filename = files[0]
self.assertTrue(filename.startswith('bmc_%s_' % self.bmc_address),
'%s does not start with bmc_%s'
% (filename, self.bmc_address))
if name is None:
self.assertTrue(filename.startswith(self.uuid),
'%s does not start with uuid' % filename)
else:
self.assertEqual(name, filename)
with open(os.path.join(self.tempdir, filename), 'rb') as fp:
self.assertEqual(self.logs, fp.read())
@ -323,6 +325,16 @@ class TestStoreLogs(BaseProcessTest):
self.assertRaises(utils.Error, process.process, self.data)
self._check_contents()
def test_store_custom_name(self, hook_mock):
CONF.set_override('ramdisk_logs_filename_format',
'{uuid}-{bmc}-{mac}',
'processing')
self.process_mock.side_effect = utils.Error('boom')
self.assertRaises(utils.Error, process.process, self.data)
self._check_contents(name='%s-%s-%s' % (self.uuid,
self.bmc_address,
self.pxe_mac.replace(':', '')))
class TestProcessNode(BaseTest):
def setUp(self):

View File

@ -0,0 +1,8 @@
---
features:
- File name for stored ramdisk logs can now be customized via
"ramdisk_logs_filename_format" option.
upgrade:
- The default file name for stored ramdisk logs was change to contain only
node UUID (if known) and the current date time. A proper ".tar.gz"
extension is now appended.