Merge "Implement hypervisor hostname exact pattern match"
This commit is contained in:
commit
68877e9959
|
@ -633,6 +633,12 @@ class FakeSessionClient(base_client.SessionClient):
|
|||
def post_servers_uuid4_metadata(self, **kw):
|
||||
return (204, {}, {'metadata': {'key1': 'val1'}})
|
||||
|
||||
def post_servers_uuid5_metadata(self, **kw):
|
||||
return (204, {}, {'metadata': {'key1': 'val1'}})
|
||||
|
||||
def post_servers_uuid6_metadata(self, **kw):
|
||||
return (204, {}, {'metadata': {'key1': 'val1'}})
|
||||
|
||||
def delete_servers_uuid1_metadata_key1(self, **kw):
|
||||
return (200, {}, {'data': 'Fake diagnostics'})
|
||||
|
||||
|
@ -645,6 +651,12 @@ class FakeSessionClient(base_client.SessionClient):
|
|||
def delete_servers_uuid4_metadata_key1(self, **kw):
|
||||
return (200, {}, {'data': 'Fake diagnostics'})
|
||||
|
||||
def delete_servers_uuid5_metadata_key1(self, **kw):
|
||||
return (200, {}, {'data': 'Fake diagnostics'})
|
||||
|
||||
def delete_servers_uuid6_metadata_key1(self, **kw):
|
||||
return (200, {}, {'data': 'Fake diagnostics'})
|
||||
|
||||
def get_servers_1234_os_security_groups(self, **kw):
|
||||
return (200, {}, {
|
||||
"security_groups": [{
|
||||
|
@ -1773,6 +1785,26 @@ class FakeSessionClient(base_client.SessionClient):
|
|||
{'name': 'inst4', 'uuid': 'uuid4'}]}]
|
||||
})
|
||||
|
||||
def get_os_hypervisors_hyper1_servers(self, **kw):
|
||||
return (200, {}, {
|
||||
'hypervisors': [
|
||||
{'id': 1234,
|
||||
'hypervisor_hostname': 'hyper1',
|
||||
'servers': [
|
||||
{'name': 'inst1', 'uuid': 'uuid1'},
|
||||
{'name': 'inst2', 'uuid': 'uuid2'}]}]
|
||||
})
|
||||
|
||||
def get_os_hypervisors_hyper2_servers(self, **kw):
|
||||
return (200, {}, {
|
||||
'hypervisors': [
|
||||
{'id': 5678,
|
||||
'hypervisor_hostname': 'hyper2',
|
||||
'servers': [
|
||||
{'name': 'inst3', 'uuid': 'uuid3'},
|
||||
{'name': 'inst4', 'uuid': 'uuid4'}]}]
|
||||
})
|
||||
|
||||
def get_os_hypervisors_hyper_no_servers_servers(self, **kw):
|
||||
return (200, {}, {'hypervisors':
|
||||
[{'id': 1234, 'hypervisor_hostname': 'hyper1'}]})
|
||||
|
@ -1986,6 +2018,12 @@ class FakeSessionClient(base_client.SessionClient):
|
|||
def post_servers_uuid4_action(self, **kw):
|
||||
return 202, {}, {}
|
||||
|
||||
def post_servers_uuid5_action(self, **kw):
|
||||
return 202, {}, {}
|
||||
|
||||
def post_servers_uuid6_action(self, **kw):
|
||||
return 202, {}, {}
|
||||
|
||||
def get_os_cells_child_cell(self, **kw):
|
||||
cell = {'cell': {
|
||||
'username': 'cell1_user',
|
||||
|
|
|
@ -1921,16 +1921,40 @@ class ShellTest(utils.TestCase):
|
|||
{'metadata': {'key1': 'val1', 'key2': 'val2'}},
|
||||
pos=4)
|
||||
|
||||
def test_set_host_meta_strict(self):
|
||||
self.run_command('host-meta hyper1 --strict set key1=val1 key2=val2')
|
||||
self.assert_called('GET', '/os-hypervisors/hyper1/servers', pos=0)
|
||||
self.assert_called('POST', '/servers/uuid1/metadata',
|
||||
{'metadata': {'key1': 'val1', 'key2': 'val2'}},
|
||||
pos=1)
|
||||
self.assert_called('POST', '/servers/uuid2/metadata',
|
||||
{'metadata': {'key1': 'val1', 'key2': 'val2'}},
|
||||
pos=2)
|
||||
|
||||
def test_set_host_meta_no_match(self):
|
||||
cmd = 'host-meta hyper --strict set key1=val1 key2=val2'
|
||||
self.assertRaises(exceptions.NotFound, self.run_command, cmd)
|
||||
|
||||
def test_set_host_meta_with_no_servers(self):
|
||||
self.run_command('host-meta hyper_no_servers set key1=val1 key2=val2')
|
||||
self.assert_called('GET', '/os-hypervisors/hyper_no_servers/servers')
|
||||
|
||||
def test_set_host_meta_with_no_servers_strict(self):
|
||||
cmd = 'host-meta hyper_no_servers --strict set key1=val1 key2=val2'
|
||||
self.assertRaises(exceptions.NotFound, self.run_command, cmd)
|
||||
|
||||
def test_delete_host_meta(self):
|
||||
self.run_command('host-meta hyper delete key1')
|
||||
self.assert_called('GET', '/os-hypervisors/hyper/servers', pos=0)
|
||||
self.assert_called('DELETE', '/servers/uuid1/metadata/key1', pos=1)
|
||||
self.assert_called('DELETE', '/servers/uuid2/metadata/key1', pos=2)
|
||||
|
||||
def test_delete_host_meta_strict(self):
|
||||
self.run_command('host-meta hyper1 --strict delete key1')
|
||||
self.assert_called('GET', '/os-hypervisors/hyper1/servers', pos=0)
|
||||
self.assert_called('DELETE', '/servers/uuid1/metadata/key1', pos=1)
|
||||
self.assert_called('DELETE', '/servers/uuid2/metadata/key1', pos=2)
|
||||
|
||||
def test_usage_list(self):
|
||||
cmd = 'usage-list --start 2000-01-20 --end 2005-02-01'
|
||||
stdout, _stderr = self.run_command(cmd)
|
||||
|
@ -2306,6 +2330,19 @@ class ShellTest(utils.TestCase):
|
|||
self.assert_called('POST', '/servers/uuid3/action', body, pos=3)
|
||||
self.assert_called('POST', '/servers/uuid4/action', body, pos=4)
|
||||
|
||||
def test_host_evacuate_live_with_no_target_host_strict(self):
|
||||
self.run_command('host-evacuate-live hyper1 --strict')
|
||||
self.assert_called('GET', '/os-hypervisors/hyper1/servers', pos=0)
|
||||
body = {'os-migrateLive': {'host': None,
|
||||
'block_migration': False,
|
||||
'disk_over_commit': False}}
|
||||
self.assert_called('POST', '/servers/uuid1/action', body, pos=1)
|
||||
self.assert_called('POST', '/servers/uuid2/action', body, pos=2)
|
||||
|
||||
def test_host_evacuate_live_no_match(self):
|
||||
cmd = 'host-evacuate-live hyper --strict'
|
||||
self.assertRaises(exceptions.NotFound, self.run_command, cmd)
|
||||
|
||||
def test_host_evacuate_live_2_25(self):
|
||||
self.run_command('host-evacuate-live hyper', api_version='2.25')
|
||||
self.assert_called('GET', '/os-hypervisors/hyper/servers', pos=0)
|
||||
|
@ -2315,6 +2352,14 @@ class ShellTest(utils.TestCase):
|
|||
self.assert_called('POST', '/servers/uuid3/action', body, pos=3)
|
||||
self.assert_called('POST', '/servers/uuid4/action', body, pos=4)
|
||||
|
||||
def test_host_evacuate_live_2_25_strict(self):
|
||||
self.run_command('host-evacuate-live hyper1 --strict',
|
||||
api_version='2.25')
|
||||
self.assert_called('GET', '/os-hypervisors/hyper1/servers', pos=0)
|
||||
body = {'os-migrateLive': {'host': None, 'block_migration': 'auto'}}
|
||||
self.assert_called('POST', '/servers/uuid1/action', body, pos=1)
|
||||
self.assert_called('POST', '/servers/uuid2/action', body, pos=2)
|
||||
|
||||
def test_host_evacuate_live_with_target_host(self):
|
||||
self.run_command('host-evacuate-live hyper '
|
||||
'--target-host hostname')
|
||||
|
@ -2327,6 +2372,16 @@ class ShellTest(utils.TestCase):
|
|||
self.assert_called('POST', '/servers/uuid3/action', body, pos=3)
|
||||
self.assert_called('POST', '/servers/uuid4/action', body, pos=4)
|
||||
|
||||
def test_host_evacuate_live_with_target_host_strict(self):
|
||||
self.run_command('host-evacuate-live hyper1 '
|
||||
'--target-host hostname --strict')
|
||||
self.assert_called('GET', '/os-hypervisors/hyper1/servers', pos=0)
|
||||
body = {'os-migrateLive': {'host': 'hostname',
|
||||
'block_migration': False,
|
||||
'disk_over_commit': False}}
|
||||
self.assert_called('POST', '/servers/uuid1/action', body, pos=1)
|
||||
self.assert_called('POST', '/servers/uuid2/action', body, pos=2)
|
||||
|
||||
def test_host_evacuate_live_2_30(self):
|
||||
self.run_command('host-evacuate-live --force hyper '
|
||||
'--target-host hostname',
|
||||
|
@ -2340,6 +2395,17 @@ class ShellTest(utils.TestCase):
|
|||
self.assert_called('POST', '/servers/uuid3/action', body, pos=3)
|
||||
self.assert_called('POST', '/servers/uuid4/action', body, pos=4)
|
||||
|
||||
def test_host_evacuate_live_2_30_strict(self):
|
||||
self.run_command('host-evacuate-live --force hyper1 '
|
||||
'--target-host hostname --strict',
|
||||
api_version='2.30')
|
||||
self.assert_called('GET', '/os-hypervisors/hyper1/servers', pos=0)
|
||||
body = {'os-migrateLive': {'host': 'hostname',
|
||||
'block_migration': 'auto',
|
||||
'force': True}}
|
||||
self.assert_called('POST', '/servers/uuid1/action', body, pos=1)
|
||||
self.assert_called('POST', '/servers/uuid2/action', body, pos=2)
|
||||
|
||||
def test_host_evacuate_live_with_block_migration(self):
|
||||
self.run_command('host-evacuate-live --block-migrate hyper')
|
||||
self.assert_called('GET', '/os-hypervisors/hyper/servers', pos=0)
|
||||
|
@ -2351,6 +2417,15 @@ class ShellTest(utils.TestCase):
|
|||
self.assert_called('POST', '/servers/uuid3/action', body, pos=3)
|
||||
self.assert_called('POST', '/servers/uuid4/action', body, pos=4)
|
||||
|
||||
def test_host_evacuate_live_with_block_migration_strict(self):
|
||||
self.run_command('host-evacuate-live --block-migrate hyper2 --strict')
|
||||
self.assert_called('GET', '/os-hypervisors/hyper2/servers', pos=0)
|
||||
body = {'os-migrateLive': {'host': None,
|
||||
'block_migration': True,
|
||||
'disk_over_commit': False}}
|
||||
self.assert_called('POST', '/servers/uuid3/action', body, pos=1)
|
||||
self.assert_called('POST', '/servers/uuid4/action', body, pos=2)
|
||||
|
||||
def test_host_evacuate_live_with_block_migration_2_25(self):
|
||||
self.run_command('host-evacuate-live --block-migrate hyper',
|
||||
api_version='2.25')
|
||||
|
@ -2361,6 +2436,14 @@ class ShellTest(utils.TestCase):
|
|||
self.assert_called('POST', '/servers/uuid3/action', body, pos=3)
|
||||
self.assert_called('POST', '/servers/uuid4/action', body, pos=4)
|
||||
|
||||
def test_host_evacuate_live_with_block_migration_2_25_strict(self):
|
||||
self.run_command('host-evacuate-live --block-migrate hyper2 --strict',
|
||||
api_version='2.25')
|
||||
self.assert_called('GET', '/os-hypervisors/hyper2/servers', pos=0)
|
||||
body = {'os-migrateLive': {'host': None, 'block_migration': True}}
|
||||
self.assert_called('POST', '/servers/uuid3/action', body, pos=1)
|
||||
self.assert_called('POST', '/servers/uuid4/action', body, pos=2)
|
||||
|
||||
def test_host_evacuate_live_with_disk_over_commit(self):
|
||||
self.run_command('host-evacuate-live --disk-over-commit hyper')
|
||||
self.assert_called('GET', '/os-hypervisors/hyper/servers', pos=0)
|
||||
|
@ -2372,11 +2455,26 @@ class ShellTest(utils.TestCase):
|
|||
self.assert_called('POST', '/servers/uuid3/action', body, pos=3)
|
||||
self.assert_called('POST', '/servers/uuid4/action', body, pos=4)
|
||||
|
||||
def test_host_evacuate_live_with_disk_over_commit_strict(self):
|
||||
self.run_command('host-evacuate-live --disk-over-commit hyper2 '
|
||||
'--strict')
|
||||
self.assert_called('GET', '/os-hypervisors/hyper2/servers', pos=0)
|
||||
body = {'os-migrateLive': {'host': None,
|
||||
'block_migration': False,
|
||||
'disk_over_commit': True}}
|
||||
self.assert_called('POST', '/servers/uuid3/action', body, pos=1)
|
||||
self.assert_called('POST', '/servers/uuid4/action', body, pos=2)
|
||||
|
||||
def test_host_evacuate_live_with_disk_over_commit_2_25(self):
|
||||
self.assertRaises(SystemExit, self.run_command,
|
||||
'host-evacuate-live --disk-over-commit hyper',
|
||||
api_version='2.25')
|
||||
|
||||
def test_host_evacuate_live_with_disk_over_commit_2_25_strict(self):
|
||||
self.assertRaises(SystemExit, self.run_command,
|
||||
'host-evacuate-live --disk-over-commit hyper2 '
|
||||
'--strict', api_version='2.25')
|
||||
|
||||
def test_host_evacuate_list_with_max_servers(self):
|
||||
self.run_command('host-evacuate-live --max-servers 1 hyper')
|
||||
self.assert_called('GET', '/os-hypervisors/hyper/servers', pos=0)
|
||||
|
@ -2385,6 +2483,14 @@ class ShellTest(utils.TestCase):
|
|||
'disk_over_commit': False}}
|
||||
self.assert_called('POST', '/servers/uuid1/action', body, pos=1)
|
||||
|
||||
def test_host_evacuate_list_with_max_servers_strict(self):
|
||||
self.run_command('host-evacuate-live --max-servers 1 hyper1 --strict')
|
||||
self.assert_called('GET', '/os-hypervisors/hyper1/servers', pos=0)
|
||||
body = {'os-migrateLive': {'host': None,
|
||||
'block_migration': False,
|
||||
'disk_over_commit': False}}
|
||||
self.assert_called('POST', '/servers/uuid1/action', body, pos=1)
|
||||
|
||||
def test_reset_state(self):
|
||||
self.run_command('reset-state sample-server')
|
||||
self.assert_called('POST', '/servers/1234/action',
|
||||
|
@ -2512,6 +2618,15 @@ class ShellTest(utils.TestCase):
|
|||
self.assert_called('POST', '/servers/uuid4/action',
|
||||
{'evacuate': {'host': 'target_hyper'}}, pos=4)
|
||||
|
||||
def test_host_evacuate_v2_14_strict(self):
|
||||
self.run_command('host-evacuate hyper1 --target target_hyper --strict',
|
||||
api_version='2.14')
|
||||
self.assert_called('GET', '/os-hypervisors/hyper1/servers', pos=0)
|
||||
self.assert_called('POST', '/servers/uuid1/action',
|
||||
{'evacuate': {'host': 'target_hyper'}}, pos=1)
|
||||
self.assert_called('POST', '/servers/uuid2/action',
|
||||
{'evacuate': {'host': 'target_hyper'}}, pos=2)
|
||||
|
||||
def test_host_evacuate(self):
|
||||
self.run_command('host-evacuate hyper --target target_hyper')
|
||||
self.assert_called('GET', '/os-hypervisors/hyper/servers', pos=0)
|
||||
|
@ -2528,6 +2643,20 @@ class ShellTest(utils.TestCase):
|
|||
{'evacuate': {'host': 'target_hyper',
|
||||
'onSharedStorage': False}}, pos=4)
|
||||
|
||||
def test_host_evacuate_strict(self):
|
||||
self.run_command('host-evacuate hyper1 --target target_hyper --strict')
|
||||
self.assert_called('GET', '/os-hypervisors/hyper1/servers', pos=0)
|
||||
self.assert_called('POST', '/servers/uuid1/action',
|
||||
{'evacuate': {'host': 'target_hyper',
|
||||
'onSharedStorage': False}}, pos=1)
|
||||
self.assert_called('POST', '/servers/uuid2/action',
|
||||
{'evacuate': {'host': 'target_hyper',
|
||||
'onSharedStorage': False}}, pos=2)
|
||||
|
||||
def test_host_evacuate_no_match(self):
|
||||
cmd = 'host-evacuate hyper --target target_hyper --strict'
|
||||
self.assertRaises(exceptions.NotFound, self.run_command, cmd)
|
||||
|
||||
def test_host_evacuate_v2_29(self):
|
||||
self.run_command('host-evacuate hyper --target target_hyper --force',
|
||||
api_version='2.29')
|
||||
|
@ -2545,6 +2674,17 @@ class ShellTest(utils.TestCase):
|
|||
{'evacuate': {'host': 'target_hyper', 'force': True}
|
||||
}, pos=4)
|
||||
|
||||
def test_host_evacuate_v2_29_strict(self):
|
||||
self.run_command('host-evacuate hyper1 --target target_hyper'
|
||||
' --force --strict', api_version='2.29')
|
||||
self.assert_called('GET', '/os-hypervisors/hyper1/servers', pos=0)
|
||||
self.assert_called('POST', '/servers/uuid1/action',
|
||||
{'evacuate': {'host': 'target_hyper', 'force': True}
|
||||
}, pos=1)
|
||||
self.assert_called('POST', '/servers/uuid2/action',
|
||||
{'evacuate': {'host': 'target_hyper', 'force': True}
|
||||
}, pos=2)
|
||||
|
||||
def test_host_evacuate_with_shared_storage(self):
|
||||
self.run_command(
|
||||
'host-evacuate --on-shared-storage hyper --target target_hyper')
|
||||
|
@ -2562,6 +2702,17 @@ class ShellTest(utils.TestCase):
|
|||
{'evacuate': {'host': 'target_hyper',
|
||||
'onSharedStorage': True}}, pos=4)
|
||||
|
||||
def test_host_evacuate_with_shared_storage_strict(self):
|
||||
self.run_command('host-evacuate --on-shared-storage hyper1'
|
||||
' --target target_hyper --strict')
|
||||
self.assert_called('GET', '/os-hypervisors/hyper1/servers', pos=0)
|
||||
self.assert_called('POST', '/servers/uuid1/action',
|
||||
{'evacuate': {'host': 'target_hyper',
|
||||
'onSharedStorage': True}}, pos=1)
|
||||
self.assert_called('POST', '/servers/uuid2/action',
|
||||
{'evacuate': {'host': 'target_hyper',
|
||||
'onSharedStorage': True}}, pos=2)
|
||||
|
||||
def test_host_evacuate_with_no_target_host(self):
|
||||
self.run_command('host-evacuate --on-shared-storage hyper')
|
||||
self.assert_called('GET', '/os-hypervisors/hyper/servers', pos=0)
|
||||
|
@ -2574,6 +2725,14 @@ class ShellTest(utils.TestCase):
|
|||
self.assert_called('POST', '/servers/uuid4/action',
|
||||
{'evacuate': {'onSharedStorage': True}}, pos=4)
|
||||
|
||||
def test_host_evacuate_with_no_target_host_strict(self):
|
||||
self.run_command('host-evacuate --on-shared-storage hyper1 --strict')
|
||||
self.assert_called('GET', '/os-hypervisors/hyper1/servers', pos=0)
|
||||
self.assert_called('POST', '/servers/uuid1/action',
|
||||
{'evacuate': {'onSharedStorage': True}}, pos=1)
|
||||
self.assert_called('POST', '/servers/uuid2/action',
|
||||
{'evacuate': {'onSharedStorage': True}}, pos=2)
|
||||
|
||||
def test_host_servers_migrate(self):
|
||||
self.run_command('host-servers-migrate hyper')
|
||||
self.assert_called('GET', '/os-hypervisors/hyper/servers', pos=0)
|
||||
|
@ -2586,6 +2745,18 @@ class ShellTest(utils.TestCase):
|
|||
self.assert_called('POST',
|
||||
'/servers/uuid4/action', {'migrate': None}, pos=4)
|
||||
|
||||
def test_host_servers_migrate_strict(self):
|
||||
self.run_command('host-servers-migrate hyper1 --strict')
|
||||
self.assert_called('GET', '/os-hypervisors/hyper1/servers', pos=0)
|
||||
self.assert_called('POST',
|
||||
'/servers/uuid1/action', {'migrate': None}, pos=1)
|
||||
self.assert_called('POST',
|
||||
'/servers/uuid2/action', {'migrate': None}, pos=2)
|
||||
|
||||
def test_host_servers_migrate_no_match(self):
|
||||
cmd = 'host-servers-migrate hyper --strict'
|
||||
self.assertRaises(exceptions.NotFound, self.run_command, cmd)
|
||||
|
||||
def test_hypervisor_list(self):
|
||||
self.run_command('hypervisor-list')
|
||||
self.assert_called('GET', '/os-hypervisors')
|
||||
|
|
|
@ -4675,6 +4675,23 @@ def _server_evacuate(cs, server, args):
|
|||
"error_message": error_message})
|
||||
|
||||
|
||||
def _hyper_servers(cs, host, strict):
|
||||
hypervisors = cs.hypervisors.search(host, servers=True)
|
||||
for hyper in hypervisors:
|
||||
if strict and hyper.hypervisor_hostname != host:
|
||||
continue
|
||||
if hasattr(hyper, 'servers'):
|
||||
for server in hyper.servers:
|
||||
yield server
|
||||
if strict:
|
||||
break
|
||||
else:
|
||||
if strict:
|
||||
msg = (_("No hypervisor matching '%s' could be found.") %
|
||||
host)
|
||||
raise exceptions.NotFound(404, msg)
|
||||
|
||||
|
||||
@utils.arg('host', metavar='<host>',
|
||||
help='The hypervisor hostname (or pattern) to search for. '
|
||||
'WARNING: Use a fully qualified domain name if you only '
|
||||
|
@ -4700,18 +4717,22 @@ def _server_evacuate(cs, server, args):
|
|||
default=False,
|
||||
help=_('Force to not verify the scheduler if a host is provided.'),
|
||||
start_version='2.29')
|
||||
@utils.arg(
|
||||
'--strict',
|
||||
dest='strict',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_('Evacuate host with exact hypervisor hostname match'))
|
||||
def do_host_evacuate(cs, args):
|
||||
"""Evacuate all instances from failed host."""
|
||||
|
||||
hypervisors = cs.hypervisors.search(args.host, servers=True)
|
||||
response = []
|
||||
for hyper in hypervisors:
|
||||
if hasattr(hyper, 'servers'):
|
||||
for server in hyper.servers:
|
||||
response.append(_server_evacuate(cs, server, args))
|
||||
|
||||
utils.print_list(response,
|
||||
["Server UUID", "Evacuate Accepted", "Error Message"])
|
||||
for server in _hyper_servers(cs, args.host, args.strict):
|
||||
response.append(_server_evacuate(cs, server, args))
|
||||
utils.print_list(response, [
|
||||
"Server UUID",
|
||||
"Evacuate Accepted",
|
||||
"Error Message",
|
||||
])
|
||||
|
||||
|
||||
def _server_live_migrate(cs, server, args):
|
||||
|
@ -4781,22 +4802,29 @@ def _server_live_migrate(cs, server, args):
|
|||
default=False,
|
||||
help=_('Force to not verify the scheduler if a host is provided.'),
|
||||
start_version='2.30')
|
||||
@utils.arg(
|
||||
'--strict',
|
||||
dest='strict',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_('live Evacuate host with exact hypervisor hostname match'))
|
||||
def do_host_evacuate_live(cs, args):
|
||||
"""Live migrate all instances of the specified host
|
||||
to other available hosts.
|
||||
"""
|
||||
hypervisors = cs.hypervisors.search(args.host, servers=True)
|
||||
response = []
|
||||
migrating = 0
|
||||
for hyper in hypervisors:
|
||||
for server in getattr(hyper, 'servers', []):
|
||||
response.append(_server_live_migrate(cs, server, args))
|
||||
migrating += 1
|
||||
if args.max_servers is not None and migrating >= args.max_servers:
|
||||
break
|
||||
|
||||
utils.print_list(response, ["Server UUID", "Live Migration Accepted",
|
||||
"Error Message"])
|
||||
for server in _hyper_servers(cs, args.host, args.strict):
|
||||
response.append(_server_live_migrate(cs, server, args))
|
||||
migrating = migrating + 1
|
||||
if (args.max_servers is not None and
|
||||
migrating >= args.max_servers):
|
||||
break
|
||||
utils.print_list(response, [
|
||||
"Server UUID",
|
||||
"Live Migration Accepted",
|
||||
"Error Message",
|
||||
])
|
||||
|
||||
|
||||
class HostServersMigrateResponse(base.Resource):
|
||||
|
@ -4821,20 +4849,24 @@ def _server_migrate(cs, server):
|
|||
help='The hypervisor hostname (or pattern) to search for. '
|
||||
'WARNING: Use a fully qualified domain name if you only '
|
||||
'want to cold migrate from a specific host.')
|
||||
@utils.arg(
|
||||
'--strict',
|
||||
dest='strict',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_('Migrate host with exact hypervisor hostname match'))
|
||||
def do_host_servers_migrate(cs, args):
|
||||
"""Cold migrate all instances off the specified host to other available
|
||||
hosts.
|
||||
"""
|
||||
|
||||
hypervisors = cs.hypervisors.search(args.host, servers=True)
|
||||
response = []
|
||||
for hyper in hypervisors:
|
||||
if hasattr(hyper, 'servers'):
|
||||
for server in hyper.servers:
|
||||
response.append(_server_migrate(cs, server))
|
||||
|
||||
utils.print_list(response,
|
||||
["Server UUID", "Migration Accepted", "Error Message"])
|
||||
for server in _hyper_servers(cs, args.host, args.strict):
|
||||
response.append(_server_migrate(cs, server))
|
||||
utils.print_list(response, [
|
||||
"Server UUID",
|
||||
"Migration Accepted",
|
||||
"Error Message",
|
||||
])
|
||||
|
||||
|
||||
@utils.arg(
|
||||
|
@ -4964,17 +4996,20 @@ def do_list_extensions(cs, _args):
|
|||
action='append',
|
||||
default=[],
|
||||
help=_('Metadata to set or delete (only key is necessary on delete)'))
|
||||
@utils.arg(
|
||||
'--strict',
|
||||
dest='strict',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_('Set host-meta to the hypervisor with exact hostname match'))
|
||||
def do_host_meta(cs, args):
|
||||
"""Set or Delete metadata on all instances of a host."""
|
||||
hypervisors = cs.hypervisors.search(args.host, servers=True)
|
||||
for hyper in hypervisors:
|
||||
for server in _hyper_servers(cs, args.host, args.strict):
|
||||
metadata = _extract_metadata(args)
|
||||
if hasattr(hyper, 'servers'):
|
||||
for server in hyper.servers:
|
||||
if args.action == 'set':
|
||||
cs.servers.set_meta(server['uuid'], metadata)
|
||||
elif args.action == 'delete':
|
||||
cs.servers.delete_meta(server['uuid'], metadata.keys())
|
||||
if args.action == 'set':
|
||||
cs.servers.set_meta(server['uuid'], metadata)
|
||||
elif args.action == 'delete':
|
||||
cs.servers.delete_meta(server['uuid'], metadata.keys())
|
||||
|
||||
|
||||
def _print_migrations(cs, migrations):
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
features:
|
||||
- |
|
||||
Provides "--strict" option for "nova host-servers-migrate", "nova host-evacuate",
|
||||
"nova host-evacuate-live" and "nova host-meta" commands. When "--strict" option is
|
||||
used, the action will be applied to a single compute with the exact hypervisor
|
||||
hostname string match rather than to the computes with hostname substring match.
|
||||
When the specified hostname does not exist in the system, "NotFound" error code
|
||||
will be returned.
|
Loading…
Reference in New Issue