Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use juju-run to invoke juju-reboot for unit reboot #575

Merged
merged 2 commits into from
Sep 20, 2022
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
7 changes: 7 additions & 0 deletions unit_tests/utilities/test_zaza_utilities_generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,13 @@ def test_reboot(self):
['juju', 'ssh', _unit,
'sudo', 'reboot', '&&', 'exit'])

def test_juju_reboot(self):
_unit = "app/2"
generic_utils.juju_reboot(_unit)
self.subprocess.check_call.assert_called_once_with(
['juju', 'ssh', _unit,
f'sudo juju-run -u {_unit} "juju-reboot --now"'])
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We tend not to use f-strings in zaza purely due to the python3.5 support. We need to formally make a break on it, but zaza still tentatively supports py35!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 7417002

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test code still uses the f-string? I see the code-under-test does use .format().


def test_run_via_ssh(self):
_unit = "app/2"
_cmd = "hostname"
Expand Down
9 changes: 5 additions & 4 deletions unit_tests/utilities/test_zaza_utilities_machine_os.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,8 @@ def test_reboot_hvs(self):
unit = mock.MagicMock()
unit.name = 'someApp/0'
self.get_units.return_value = [unit]
self.patch_object(machine_os_utils.zaza.utilities.generic, 'reboot')
self.patch_object(machine_os_utils.zaza.utilities.generic,
'juju_reboot')
self.patch_object(machine_os_utils.zaza.model,
'block_until_unit_wl_status')
self.patch_object(machine_os_utils.zaza.charm_lifecycle.utils,
Expand All @@ -164,17 +165,17 @@ def test_reboot_hvs(self):
'wait_for_application_states')
machine_os_utils.reboot_hvs()
self.get_units.assert_called_once_with('someApp')
self.reboot.assert_called_once_with('someApp/0')
self.juju_reboot.assert_called_once_with('someApp/0')
self.wait_for_application_states.assert_called_once_with(
states={'someDeployStatus': None})

# Units provided as argument
self.get_units.reset_mock()
self.reboot.reset_mock()
self.juju_reboot.reset_mock()
self.wait_for_application_states.reset_mock()
machine_os_utils.reboot_hvs(units=[unit])
self.assertFalse(self.get_units.called)
self.reboot.assert_called_once_with('someApp/0')
self.juju_reboot.assert_called_once_with('someApp/0')
self.wait_for_application_states.assert_called_once_with(
states={'someDeployStatus': None})

Expand Down
19 changes: 19 additions & 0 deletions zaza/utilities/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,25 @@ def reboot(unit_name):
pass


def juju_reboot(unit_name):
"""Reboot a unit using juju-reboot.

As `juju run` does not allow running juju-reboot (see LP: #1990140), use
`juju ssh` to invoke juju-run with the unit context with the juju-reboot
command. This will trigger a Juju-controlled reboot during which Juju
will not attempt to run any hooks asynchronously which can cause an
unintended hook execution failure upon reboot (for example, this happens
with update-status hooks causing intermittent CI failures).
"""
cmd = ['juju', 'ssh', unit_name,
'sudo juju-run -u {} "juju-reboot --now"'.format(unit_name)]
try:
subprocess.check_call(cmd)
except subprocess.CalledProcessError as e:
logging.info(e)
pass


def set_dpkg_non_interactive_on_unit(
unit_name, apt_conf_d="/etc/apt/apt.conf.d/50unattended-upgrades"):
"""Set dpkg options on unit.
Expand Down
2 changes: 1 addition & 1 deletion zaza/utilities/machine_os.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ def reboot_hvs(units=None):
return
units = units or zaza.model.get_units(hv_application)
for unit in units:
zaza.utilities.generic.reboot(unit.name)
zaza.utilities.generic.juju_reboot(unit.name)
zaza.model.block_until_unit_wl_status(unit.name, "unknown")
target_deploy_status = zaza.charm_lifecycle.utils.get_charm_config().get(
'target_deploy_status', {})
Expand Down