Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/vm-repair/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
Release History
===============

2.4.3
++++++
Advisory warnings raised by a command are now also returned in its output, under a ``warnings`` key. Until now the only warning ``az vm repair create`` raises — that the repair VM size supports NVMe but not SCSI, so repair scripts which locate the attached OS disk by its SCSI model name will not find it — was written to the log and nowhere else. A script or portal experience driving the command received a success payload with no indication that the repair VM it just created is one several repair scripts cannot work on. The key is only present when a warning was raised, so existing output is unchanged otherwise.

2.4.2
++++++
Adding examples to ``az vm repair run -h`` for checking whether Windows and Linux guests are ready to boot from an NVMe controller. Both examples run the corresponding read-only readiness detector on the linked repair VM. The README now also lists which platform-migration scenarios the extension can currently help with, so that an unsupported combination is not mistaken for a supported one.
Expand Down
6 changes: 6 additions & 0 deletions src/vm-repair/azext_vm_repair/command_helper_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ def __init__(self, logger, cmd, command_name):
# Return message
self.message = ''

# Advisory messages that also went to the log. Returned so a caller can act on them without
# parsing stderr, which is where they would otherwise only exist.
self.warnings = []

# Return error message
self.error_message = ''

Expand Down Expand Up @@ -131,6 +135,8 @@ def init_return_dict(self):
self.return_dict = {}
self.return_dict["status"] = self.status
self.return_dict["message"] = self.message
if self.warnings:
self.return_dict["warnings"] = list(self.warnings)
if not self.is_status_success():
self.return_dict["error_message"] = self.error_message
if self.error_message:
Expand Down
2 changes: 2 additions & 0 deletions src/vm-repair/azext_vm_repair/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,8 @@ def create(cmd, vm_name, resource_group_name, repair_password=None, repair_usern
selected_controller, level, message = _select_repair_disk_controller_type(
source_controller, supported_controllers, disk_controller_type)
getattr(logger, level)(message)
if level == 'warning':
command.warnings.append(message)
if selected_controller:
create_repair_vm_command += ' --disk-controller-type {controller}'.format(controller=selected_controller)
if hasattr(command, 'set_resource_context'):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------
import unittest
from unittest import mock

from azext_vm_repair.command_helper_class import command_helper


class ReturnedWarningsTest(unittest.TestCase):

# The NVMe-only repair VM warning reached the operator on stderr but never entered the returned
# JSON, so an automated caller could not tell that the repair VM it just created is one several
# repair scripts cannot find a disk on.
def _helper(self):
# The real __init__/__del__ start a progress controller and emit telemetry; neither is
# relevant to how the return payload is assembled.
with mock.patch.object(command_helper, '__init__', return_value=None), \
mock.patch.object(command_helper, '__del__', lambda self: None):
helper = command_helper(None, None, 'vm repair create')
helper.status = 'SUCCESS'
helper.message = 'done'
helper.warnings = []
helper.logger = mock.MagicMock()
return helper

def test_no_warnings_key_when_nothing_was_raised(self):
helper = self._helper()
self.assertNotIn('warnings', helper.init_return_dict())

def test_warnings_are_returned_when_raised(self):
helper = self._helper()
helper.warnings.append('The repair VM size only supports NVMe.')
self.assertEqual(['The repair VM size only supports NVMe.'], helper.init_return_dict()['warnings'])

def test_returned_warnings_are_a_copy(self):
helper = self._helper()
helper.warnings.append('first')
returned = helper.init_return_dict()['warnings']
helper.warnings.append('second')
self.assertEqual(['first'], returned)


if __name__ == '__main__':
unittest.main()
2 changes: 1 addition & 1 deletion src/vm-repair/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from codecs import open
from setuptools import setup, find_packages

VERSION = "2.4.2"
VERSION = "2.4.3"

CLASSIFIERS = [
'Development Status :: 4 - Beta',
Expand Down
Loading