Merge "Added support for injecting non-maskable interrupts"

This commit is contained in:
Zuul 2018-01-03 14:22:36 +00:00 committed by Gerrit Code Review
commit 77beab6cc4
9 changed files with 127 additions and 0 deletions

View File

@ -259,6 +259,18 @@ def node_get_supported_boot_devices(request, node_id):
return result.get('supported_boot_devices', [])
def node_inject_nmi(request, node_id):
"""Inject Non-Masking Interrupts into a specified node.
:param request: HTTP request.
:param node_id: The UUID or name of the node.
:return: Empty response.
http://docs.openstack.org/developer/python-ironicclient/api/ironicclient.v1.node.html#ironicclient.v1.node.NodeManager.inject_nmi
"""
return ironicclient(request).node.inject_nmi(node_id)
def driver_list(request):
"""Retrieve a list of drivers.

View File

@ -467,3 +467,20 @@ class DriverDetails(generic.View):
:return: Dictionary of details
"""
return ironic.driver_details(request, driver_name)
@urls.register
class InjectNmi(generic.View):
url_regex = r'ironic/nodes/(?P<node_id>{})/management/inject_nmi$'. \
format(LOGICAL_NAME_PATTERN)
@rest_utils.ajax(data_required=True)
def put(self, request, node_id):
"""Inject Non-Masking Interrupts into a specified node.
:param request: HTTP request.
:param node_id: Node name or uuid.
:return: Empty response.
"""
return ironic.node_inject_nmi(request, node_id)

View File

@ -662,6 +662,24 @@
return [status, null];
});
// Inject NMI
$httpBackend.whenPUT(/\/api\/ironic\/nodes\/(.+)\/management\/inject_nmi/,
undefined,
undefined,
['nodeId'])
.respond(function(method, url, data, headers, params) {
var status, response;
if (angular.isDefined(nodes[params.nodeId])) {
status = responseCode.EMPTY_RESPONSE;
response = '';
} else {
status = responseCode.INTERNAL_SERVER_ERROR;
response = 'Node ' + params.nodeId +
' could not be found. (HTTP 404)';
}
return [status, response];
});
// Validate the interfaces associated with a specified node
$httpBackend.whenGET(/\/api\/ironic\/nodes\/([^\/]+)\/validate$/,
undefined,

View File

@ -53,6 +53,7 @@
getPortsWithNode: getPortsWithNode,
getBootDevice: getBootDevice,
getSupportedBootDevices: getSupportedBootDevices,
injectNmi: injectNmi,
nodeGetConsole: nodeGetConsole,
nodeSetConsoleMode: nodeSetConsoleMode,
nodeSetMaintenance: nodeSetMaintenance,
@ -354,6 +355,26 @@
});
}
/**
* @description Inject Non-Masking Interrupts into a specified node
*
* http://developer.openstack.org/api-ref/baremetal/#inject-nmi
*
* @param {string} nodeId UUID or logical name of a node.
* @return {promise} Promise. No content on success.
*/
function injectNmi(nodeId) {
return apiService.put('/api/ironic/nodes/' + nodeId +
'/management/inject_nmi')
.catch(function(response) {
var msg = interpolate(gettext('Unable to inject NMI: %s'),
[response.data],
false);
toastService.add('error', msg);
return $q.reject(msg);
});
}
/**
* @description Create an Ironic node
*

View File

@ -34,6 +34,7 @@
'getPortsWithNode',
'getBootDevice',
'getSupportedBootDevices',
'injectNmi',
'nodeGetConsole',
'nodeSetBootDevice',
'nodeSetConsoleMode',
@ -662,6 +663,26 @@
ironicBackendMockService.flush();
});
it('injectNmi', function() {
createNode({driver: defaultDriver})
.then(function(node) {
return ironicAPI.injectNmi(node.uuid);
})
.then(function(response) {
expect(response.status).toBe(204);
expect(response.data).toBe('');
})
.catch(failTest);
ironicBackendMockService.flush();
});
it('injectNmi - nonexistent node', function() {
ironicAPI.injectNmi(0)
.then(failTest);
ironicBackendMockService.flush();
});
});
});
})();

View File

@ -104,6 +104,7 @@
ctrl.refresh = refresh;
ctrl.toggleConsoleMode = toggleConsoleMode;
ctrl.deletePortgroups = deletePortgroups;
ctrl.injectNmi = injectNmi;
$scope.emptyObject = function(obj) {
return angular.isUndefined(obj) || Object.keys(obj).length === 0;
@ -353,5 +354,15 @@
ctrl.refresh();
});
}
/**
* @name horizon.dashboard.admin.ironic.NodeDetailsController.injectNmi
* @description Inject non-masking interrupts into the current node
*
* @return {void}
*/
function injectNmi() {
ironic.injectNmi(ctrl.node.uuid);
}
}
})();

View File

@ -255,5 +255,18 @@
expect(ctrl.node['' + interfaceName + '_interface']).toBeDefined();
expect(ctrl.nodeValidation[0].hw_interface).toEqual(hwInterface);
});
it('should have injectNmi', function () {
var ctrl;
createNode()
.then(function(node) {
ctrl = createController(node);
})
.catch(function() {
fail();
});
ironicBackendMockService.flush();
expect(ctrl.injectNmi).toBeDefined();
});
});
})();

View File

@ -70,6 +70,14 @@
callback="ctrl.toggleConsoleMode">
{$ ctrl.node.console_enabled ? 'Disable console' : 'Enable console' | translate $}
</action>
<li role="presentation">
<a role="menuitem"
ng-click="ctrl.injectNmi();
$event.stopPropagation();
$event.preventDefault()">
<span>{$ "Inject NMI" | translate $}</span>
</a>
</li>
</menu>
</action-list>
</div>

View File

@ -0,0 +1,6 @@
---
features:
- |
Adds support for injecting non-maskable interrupts into a node. A new
action ``Inject NMI`` has been added to the node actions dropdown menu
in the ``Node Details`` page.