XenAPI: Remove bittorrent.py which is already deprecated

With XenAPI driver, bit torrent related configurations are
deprecated since 15.0.0, this patch is to remove it as a
cleanup action under XenAPI driver

Change-Id: I5589f76f397a02a46e45cf571fd180842c0fdf17
This commit is contained in:
Huan Xie 2017-05-25 22:50:10 -07:00
parent 6e64cb032e
commit 812cfc14f8
6 changed files with 8 additions and 499 deletions

View File

@ -159,99 +159,6 @@ session, which allows you to make concurrent XenAPI connections.
]
xenapi_torrent_opts = [
cfg.StrOpt('torrent_base_url',
deprecated_for_removal=True,
deprecated_since='15.0.0',
deprecated_reason="""
The torrent feature has not been tested nor maintained, and as such is being
removed.
""",
help="""
Base URL for torrent files; must contain a slash character (see RFC 1808,
step 6).
"""),
cfg.FloatOpt('torrent_seed_chance',
default=1.0,
min=0,
deprecated_for_removal=True,
deprecated_since='15.0.0',
deprecated_reason="""
The torrent feature has not been tested nor maintained, and as such is being
removed.
""",
help='Probability that peer will become a seeder (1.0 = 100%)'),
cfg.IntOpt('torrent_seed_duration',
default=3600,
deprecated_for_removal=True,
deprecated_since='15.0.0',
deprecated_reason="""
The torrent feature has not been tested nor maintained, and as such is being
removed.
""",
help="""
Number of seconds after downloading an image via BitTorrent that it should
be seeded for other peers.'
"""),
cfg.IntOpt('torrent_max_last_accessed',
default=86400,
min=0,
deprecated_for_removal=True,
deprecated_since='15.0.0',
deprecated_reason="""
The torrent feature has not been tested nor maintained, and as such is being
removed.
""",
help="""
Cached torrent files not accessed within this number of seconds can be reaped.
"""),
cfg.PortOpt('torrent_listen_port_start',
default=6881,
deprecated_for_removal=True,
deprecated_since='15.0.0',
deprecated_reason="""
The torrent feature has not been tested nor maintained, and as such is being
removed.
""",
help='Beginning of port range to listen on'),
cfg.PortOpt('torrent_listen_port_end',
default=6891,
deprecated_for_removal=True,
deprecated_since='15.0.0',
deprecated_reason="""
The torrent feature has not been tested nor maintained, and as such is being
removed.
""",
help='End of port range to listen on'),
cfg.IntOpt('torrent_download_stall_cutoff',
default=600,
min=0,
deprecated_for_removal=True,
deprecated_since='15.0.0',
deprecated_reason="""
The torrent feature has not been tested nor maintained, and as such is being
removed.
""",
help="""
Number of seconds a download can remain at the same progress percentage w/o
being considered a stall.
"""),
cfg.IntOpt('torrent_max_seeder_processes_per_host',
default=1,
min=-1,
deprecated_for_removal=True,
deprecated_since='15.0.0',
deprecated_reason="""
The torrent feature has not been tested nor maintained, and as such is being
removed.
""",
help="""
Maximum number of seeder processes to run concurrently within a given dom0
(-1 = no limit).
""")
]
xenapi_vm_utils_opts = [
cfg.StrOpt('cache_images',
default='all',
@ -331,22 +238,6 @@ considerably since large runs of zeros won't have to be rsynced.
help="""
Maximum number of retries to unplug VBD.
If set to 0, should try once, no retries.
"""),
cfg.StrOpt('torrent_images',
default='none',
choices=('all', 'some', 'none'),
help="""
Whether or not to download images via Bit Torrent.
The value for this option must be chosen from the choices listed
here. Configuring a value other than these will default to 'none'.
Possible values:
* `all`: will download all images.
* `some`: will only download images that have the image_property
`bittorrent=true`.
* `none`: will turnoff downloading images via Bit Torrent.
"""),
cfg.StrOpt('ipxe_network_name',
help="""
@ -661,7 +552,6 @@ Possible values:
ALL_XENSERVER_OPTS = (xenapi_agent_opts +
xenapi_session_opts +
xenapi_torrent_opts +
xenapi_vm_utils_opts +
xenapi_opts +
xenapi_vmops_opts +

View File

@ -1,128 +0,0 @@
# Copyright 2013 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.
import mock
from os_xenapi import client
import six
from nova import context
from nova import test
from nova.tests.unit.virt.xenapi import stubs
from nova.virt.xenapi import driver as xenapi_conn
from nova.virt.xenapi import fake
from nova.virt.xenapi.image import bittorrent
class TestBittorrentStore(stubs.XenAPITestBaseNoDB):
def setUp(self):
super(TestBittorrentStore, self).setUp()
self.store = bittorrent.BittorrentStore()
self.flags(torrent_base_url='http://foo',
connection_url='test_url',
connection_password='test_pass',
group='xenserver')
self.context = context.RequestContext(
'user', 'project', auth_token='foobar')
fake.reset()
stubs.stubout_session(self.stubs, fake.SessionBase)
driver = xenapi_conn.XenAPIDriver(False)
self.session = driver._session
self.stub_out('nova.virt.xenapi.vm_utils.get_sr_path',
lambda *a, **kw: '/fake/sr/path')
@mock.patch.object(client.session.XenAPISession, 'call_plugin_serialized')
def test_download_image(self, mock_call_plugin):
instance = {'uuid': '00000000-0000-0000-0000-000000007357'}
params = {'image_id': 'fake_image_uuid',
'sr_path': '/fake/sr/path',
'torrent_download_stall_cutoff': 600,
'torrent_listen_port_end': 6891,
'torrent_listen_port_start': 6881,
'torrent_max_last_accessed': 86400,
'torrent_max_seeder_processes_per_host': 1,
'torrent_seed_chance': 1.0,
'torrent_seed_duration': 3600,
'torrent_url': 'http://foo/fake_image_uuid.torrent',
'uuid_stack': ['uuid1']}
self.stub_out('nova.virt.xenapi.vm_utils._make_uuid_stack',
lambda *a, **kw: ['uuid1'])
self.store.download_image(self.context, self.session,
instance, 'fake_image_uuid')
mock_call_plugin.assert_called_once_with('bittorrent.py',
'download_vhd', **params)
def test_upload_image(self):
self.assertRaises(NotImplementedError, self.store.upload_image,
self.context, self.session, mock.ANY, 'fake_image_uuid',
['fake_vdi_uuid'])
class LookupTorrentURLTestCase(test.NoDBTestCase):
def setUp(self):
super(LookupTorrentURLTestCase, self).setUp()
self.store = bittorrent.BittorrentStore()
self.image_id = 'fakeimageid'
def test_default_fetch_url_no_base_url_set(self):
self.flags(torrent_base_url=None,
group='xenserver')
exc = self.assertRaises(
RuntimeError, self.store._lookup_torrent_url_fn)
self.assertEqual('Cannot create default bittorrent URL without'
' xenserver.torrent_base_url configuration option'
' set.',
six.text_type(exc))
def test_default_fetch_url_base_url_is_set(self):
self.flags(torrent_base_url='http://foo',
group='xenserver')
lookup_fn = self.store._lookup_torrent_url_fn()
self.assertEqual('http://foo/fakeimageid.torrent',
lookup_fn(self.image_id))
def test_invalid_base_url_warning_logged(self):
self.flags(torrent_base_url='www.foo.com',
group='xenserver')
# Make sure a warning is logged when an invalid base URL is set,
# where invalid means it does not contain any slash characters
warnings = []
def fake_warn(msg):
warnings.append(msg)
self.stub_out('nova.virt.xenapi.image.bittorrent.LOG.warning',
fake_warn)
lookup_fn = self.store._lookup_torrent_url_fn()
self.assertEqual('fakeimageid.torrent',
lookup_fn(self.image_id))
self.assertTrue(any('does not contain a slash character' in msg for
msg in warnings),
'_lookup_torrent_url_fn() did not log a warning '
'message when the torrent_base_url did not contain a '
'slash character.')

View File

@ -268,33 +268,7 @@ class FetchVhdImageTestCase(VMUtilsTestBase):
else:
func.AndReturn({'root': {'uuid': 'vdi'}})
def _stub_bittorrent_download_vhd(self, raise_exc=None):
self.mox.StubOutWithMock(
self.session, 'call_plugin_serialized')
func = self.session.call_plugin_serialized(
'bittorrent.py', 'download_vhd',
image_id='image_id',
uuid_stack=["uuid_stack"],
sr_path='sr_path',
torrent_download_stall_cutoff=600,
torrent_listen_port_start=6881,
torrent_listen_port_end=6891,
torrent_max_last_accessed=86400,
torrent_max_seeder_processes_per_host=1,
torrent_seed_chance=1.0,
torrent_seed_duration=3600,
torrent_url='http://foo/image_id.torrent'
)
if raise_exc:
func.AndRaise(raise_exc)
else:
func.AndReturn({'root': {'uuid': 'vdi'}})
def test_fetch_vhd_image_works_with_glance(self):
self.mox.StubOutWithMock(vm_utils, '_image_uses_bittorrent')
vm_utils._image_uses_bittorrent(
self.context, self.instance).AndReturn(False)
self._stub_glance_download_vhd()
self.mox.StubOutWithMock(vm_utils, 'safe_find_sr')
@ -314,37 +288,7 @@ class FetchVhdImageTestCase(VMUtilsTestBase):
self.mox.VerifyAll()
def test_fetch_vhd_image_works_with_bittorrent(self):
self.flags(torrent_base_url='http://foo', group='xenserver')
self.mox.StubOutWithMock(vm_utils, '_image_uses_bittorrent')
vm_utils._image_uses_bittorrent(
self.context, self.instance).AndReturn(True)
self._stub_bittorrent_download_vhd()
self.mox.StubOutWithMock(vm_utils, 'safe_find_sr')
vm_utils.safe_find_sr(self.session).AndReturn("sr")
self.mox.StubOutWithMock(vm_utils, '_scan_sr')
vm_utils._scan_sr(self.session, "sr")
self.mox.StubOutWithMock(vm_utils, '_check_vdi_size')
vm_utils._check_vdi_size(self.context, self.session, self.instance,
"vdi")
self.mox.ReplayAll()
self.assertEqual("vdi", vm_utils._fetch_vhd_image(self.context,
self.session, self.instance, 'image_id')['root']['uuid'])
self.mox.VerifyAll()
def test_fetch_vhd_image_cleans_up_vdi_on_fail(self):
self.mox.StubOutWithMock(vm_utils, '_image_uses_bittorrent')
vm_utils._image_uses_bittorrent(
self.context, self.instance).AndReturn(False)
self._stub_glance_download_vhd()
self.mox.StubOutWithMock(vm_utils, 'safe_find_sr')
@ -373,44 +317,7 @@ class FetchVhdImageTestCase(VMUtilsTestBase):
self.mox.VerifyAll()
def test_fallback_to_default_handler(self):
self.flags(torrent_base_url='http://foo', group='xenserver')
self.mox.StubOutWithMock(vm_utils, '_image_uses_bittorrent')
vm_utils._image_uses_bittorrent(
self.context, self.instance).AndReturn(True)
self._stub_bittorrent_download_vhd(raise_exc=RuntimeError)
vm_utils._make_uuid_stack().AndReturn(["uuid_stack"])
vm_utils.get_sr_path(self.session).AndReturn('sr_path')
self._stub_glance_download_vhd()
self.mox.StubOutWithMock(vm_utils, 'safe_find_sr')
vm_utils.safe_find_sr(self.session).AndReturn("sr")
self.mox.StubOutWithMock(vm_utils, '_scan_sr')
vm_utils._scan_sr(self.session, "sr")
self.mox.StubOutWithMock(vm_utils, '_check_vdi_size')
vm_utils._check_vdi_size(self.context, self.session, self.instance,
"vdi")
self.mox.ReplayAll()
self.assertEqual("vdi", vm_utils._fetch_vhd_image(self.context,
self.session, self.instance, 'image_id')['root']['uuid'])
self.mox.VerifyAll()
def test_default_handler_does_not_fallback_to_itself(self):
self.flags(torrent_base_url='http://foo', group='xenserver')
self.mox.StubOutWithMock(vm_utils, '_image_uses_bittorrent')
vm_utils._image_uses_bittorrent(
self.context, self.instance).AndReturn(False)
def test_fetch_vhd_image_download_exception(self):
self._stub_glance_download_vhd(raise_exc=RuntimeError)
self.mox.ReplayAll()
@ -728,47 +635,6 @@ class CreateCachedImageTestCase(VMUtilsTestBase):
vm_utils.ImageType.DISK_VHD))
class BittorrentTestCase(VMUtilsTestBase):
def setUp(self):
super(BittorrentTestCase, self).setUp()
self.context = context.get_admin_context()
def test_image_uses_bittorrent(self):
instance = {'system_metadata': {'image_bittorrent': True}}
self.flags(torrent_images='some', group='xenserver')
self.assertTrue(vm_utils._image_uses_bittorrent(self.context,
instance))
def _test_create_image(self, cache_type):
instance = {'system_metadata': {'image_cache_in_nova': True}}
self.flags(cache_images=cache_type, group='xenserver')
was = {'called': None}
def fake_create_cached_image(*args):
was['called'] = 'some'
return (False, {})
self.stubs.Set(vm_utils, '_create_cached_image',
fake_create_cached_image)
def fake_fetch_image(*args):
was['called'] = 'none'
return {}
self.stubs.Set(vm_utils, '_fetch_image',
fake_fetch_image)
vm_utils.create_image(self.context, None, instance,
'foo', 'bar', 'baz')
self.assertEqual(was['called'], cache_type)
def test_create_image_cached(self):
self._test_create_image('some')
def test_create_image_uncached(self):
self._test_create_image('none')
class ShutdownTestCase(VMUtilsTestBase):
def test_hardshutdown_should_return_true_when_vm_is_shutdown(self):

View File

@ -1,80 +0,0 @@
# Copyright 2013 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 oslo_log import log as logging
import six.moves.urllib.parse as urlparse
import nova.conf
from nova.i18n import _, _LW
from nova.virt.xenapi import vm_utils
LOG = logging.getLogger(__name__)
CONF = nova.conf.CONF
class BittorrentStore(object):
@staticmethod
def _lookup_torrent_url_fn():
"""Load a "fetcher" func to get the right torrent URL.
"""
if CONF.xenserver.torrent_base_url:
if '/' not in CONF.xenserver.torrent_base_url:
LOG.warning(_LW('Value specified in conf file for'
' xenserver.torrent_base_url does not contain a'
' slash character, therefore it will not be used'
' as part of the torrent URL. Specify a valid'
' base URL as defined by RFC 1808 (see step 6).'))
def _default_torrent_url_fn(image_id):
return urlparse.urljoin(CONF.xenserver.torrent_base_url,
"%s.torrent" % image_id)
return _default_torrent_url_fn
raise RuntimeError(_('Cannot create default bittorrent URL'
' without xenserver.torrent_base_url'
' configuration option set.'))
def download_image(self, context, session, instance, image_id):
params = {}
params['image_id'] = image_id
params['uuid_stack'] = vm_utils._make_uuid_stack()
params['sr_path'] = vm_utils.get_sr_path(session)
params['torrent_seed_duration'] = CONF.xenserver.torrent_seed_duration
params['torrent_seed_chance'] = CONF.xenserver.torrent_seed_chance
params['torrent_max_last_accessed'] = \
CONF.xenserver.torrent_max_last_accessed
params['torrent_listen_port_start'] = \
CONF.xenserver.torrent_listen_port_start
params['torrent_listen_port_end'] = \
CONF.xenserver.torrent_listen_port_end
params['torrent_download_stall_cutoff'] = \
CONF.xenserver.torrent_download_stall_cutoff
params['torrent_max_seeder_processes_per_host'] = \
CONF.xenserver.torrent_max_seeder_processes_per_host
lookup_fn = self._lookup_torrent_url_fn()
params['torrent_url'] = lookup_fn(image_id)
vdis = session.call_plugin_serialized(
'bittorrent.py', 'download_vhd', **params)
return vdis
def upload_image(self, context, session, instance, image_id, vdi_uuids):
raise NotImplementedError

View File

@ -1343,42 +1343,12 @@ def _make_uuid_stack():
return [uuidutils.generate_uuid() for i in range(MAX_VDI_CHAIN_SIZE)]
def _image_uses_bittorrent(context, instance):
bittorrent = False
torrent_images = CONF.xenserver.torrent_images.lower()
if torrent_images == 'all':
bittorrent = True
elif torrent_images == 'some':
sys_meta = utils.instance_sys_meta(instance)
try:
bittorrent = strutils.bool_from_string(
sys_meta['image_bittorrent'])
except KeyError:
pass
elif torrent_images == 'none':
pass
else:
LOG.warning(_LW("Invalid value '%s' for torrent_images"),
torrent_images)
return bittorrent
def _default_download_handler():
# TODO(sirp): This should be configurable like upload_handler
return importutils.import_object(
'nova.virt.xenapi.image.glance.GlanceStore')
def _choose_download_handler(context, instance):
if _image_uses_bittorrent(context, instance):
return importutils.import_object(
'nova.virt.xenapi.image.bittorrent.BittorrentStore')
else:
return _default_download_handler()
def get_compression_level():
level = CONF.xenserver.image_compression_level
if level is not None and (level < 1 or level > 9):
@ -1396,26 +1366,12 @@ def _fetch_vhd_image(context, session, instance, image_id):
LOG.debug("Asking xapi to fetch vhd image %s", image_id,
instance=instance)
handler = _choose_download_handler(context, instance)
handler = _default_download_handler()
try:
vdis = handler.download_image(context, session, instance, image_id)
except Exception:
default_handler = _default_download_handler()
# Using type() instead of isinstance() so instance of subclass doesn't
# test as equivalent
if type(handler) == type(default_handler):
raise
LOG.exception(_LE("Download handler '%(handler)s' raised an"
" exception, falling back to default handler"
" '%(default_handler)s'"),
{'handler': handler,
'default_handler': default_handler})
vdis = default_handler.download_image(
context, session, instance, image_id)
raise
# Ensure we can see the import VHDs as VDIs
scan_default_sr(session)

View File

@ -0,0 +1,5 @@
---
other:
- |
With XenAPI driver, we have deprecated bittorrent since '15.0.0', so we
decide to remove all bittorrent related files and unit tests.