python-novaclient/novaclient/v2/contrib/host_evacuate_live.py
Artom Lifshitz 3d9c01b2d3 Option to specify max servers for live evacuate
The current behaviour of live evacuate is to naively request that all
servers on the hypervisor be evacuated. The more VMs are migrated
simultaneously, the more bandwidth is required. Once a certain number
of migrating VMs is reached, there is not enough bandwidth to cope
with the rate at which they dirty their memory. The migrations will
thus never complete.

The correct solution to this would be a whole lot of work on the Nova
side. As a stopgap measure, this patch introduces a --max-servers
option to host-evacuate-live. With this option, the user can control
the number of VMs that are live-migrated at the same time, thus
allowing the user to avoid the dirty memory scenario described above.

Change-Id: I17bad5f3253d6657fc1e6610159fc8e3921e6ea4
2015-09-02 17:13:47 +00:00

79 lines
2.7 KiB
Python

# Copyright 2014 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from novaclient.i18n import _
from novaclient.openstack.common import cliutils
from novaclient import utils
def _server_live_migrate(cs, server, args):
class HostEvacuateLiveResponse(object):
def __init__(self, server_uuid, live_migration_accepted,
error_message):
self.server_uuid = server_uuid
self.live_migration_accepted = live_migration_accepted
self.error_message = error_message
success = True
error_message = ""
try:
cs.servers.live_migrate(server['uuid'], args.target_host,
args.block_migrate, args.disk_over_commit)
except Exception as e:
success = False
error_message = _("Error while live migrating instance: %s") % e
return HostEvacuateLiveResponse(server['uuid'],
success,
error_message)
@cliutils.arg('host', metavar='<host>', help='Name of host.')
@cliutils.arg(
'--target-host',
metavar='<target_host>',
default=None,
help=_('Name of target host.'))
@cliutils.arg(
'--block-migrate',
action='store_true',
default=False,
help=_('Enable block migration.'))
@cliutils.arg(
'--disk-over-commit',
action='store_true',
default=False,
help=_('Enable disk overcommit.'))
@cliutils.arg(
'--max-servers',
type=int,
dest='max_servers',
metavar='<max_servers>',
help='Maximum number of servers to live migrate simultaneously')
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 = 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"])