**Related Flags**
-:backup_swift_url: The URL of the Swift endpoint (default:
- localhost:8080).
+:backup_swift_url: The URL of the Swift endpoint (default: None, use catalog).
+:swift_catalog_info: Info to match when looking for swift in the service '
+ catalog.
:backup_swift_object_size: The size in bytes of the Swift objects used
for volume backups (default: 52428800).
:backup_swift_retry_attempts: The number of retries to make for Swift
swiftbackup_service_opts = [
cfg.StrOpt('backup_swift_url',
- default='http://localhost:8080/v1/AUTH_',
+ default=None,
help='The URL of the Swift endpoint'),
+ cfg.StrOpt('swift_catalog_info',
+ default='object-store:swift:publicURL',
+ help='Info to match when looking for swift in the service '
+ 'catalog. Format is: separated values of the form: '
+ '<service_type>:<service_name>:<endpoint_type> - '
+ 'Only used if backup_swift_url is unset'),
cfg.StrOpt('backup_swift_auth',
default='per_user',
help='Swift authentication mechanism'),
def __init__(self, context, db_driver=None):
super(SwiftBackupDriver, self).__init__(context, db_driver)
- self.swift_url = '%s%s' % (CONF.backup_swift_url,
- self.context.project_id)
+ if CONF.backup_swift_url is None:
+ self.swift_url = None
+ info = CONF.swift_catalog_info
+ try:
+ service_type, service_name, endpoint_type = info.split(':')
+ except ValueError:
+ raise exception.BackupDriverException(_(
+ "Failed to parse the configuration option "
+ "'swift_catalog_info', must be in the form "
+ "<service_type>:<service_name>:<endpoint_type>"))
+ for entry in context.service_catalog:
+ if entry.get('type') == service_type:
+ self.swift_url = entry.get(
+ 'endpoints')[0].get(endpoint_type)
+ else:
+ self.swift_url = '%s%s' % (CONF.backup_swift_url,
+ context.project_id)
+ if self.swift_url is None:
+ raise exception.BackupDriverException(_(
+ "Could not determine which Swift endpoint to use. This can "
+ " either be set in the service catalog or with the "
+ " cinder.conf config option 'backup_swift_url'."))
+ LOG.debug("Using swift URL %s", self.swift_url)
self.az = CONF.storage_availability_zone
self.data_block_size_bytes = CONF.backup_swift_object_size
self.swift_attempts = CONF.backup_swift_retry_attempts
if service_catalog:
# Only include required parts of service_catalog
self.service_catalog = [s for s in service_catalog
- if s.get('type') in ('compute',)]
+ if s.get('type') in ('compute',
+ 'object-store')]
else:
# if list is empty or none
self.service_catalog = []
import tempfile
import zlib
+from oslo.config import cfg
from swiftclient import client as swift
from cinder.backup.drivers.swift import SwiftBackupDriver
LOG = logging.getLogger(__name__)
+CONF = cfg.CONF
+
def fake_md5(arg):
class result(object):
def setUp(self):
super(BackupSwiftTestCase, self).setUp()
+ service_catalog = [{u'type': u'object-store', u'name': u'swift',
+ u'endpoints': [{
+ u'publicURL': u'http://example.com'}]}]
self.ctxt = context.get_admin_context()
+ self.ctxt.service_catalog = service_catalog
self.stubs.Set(swift, 'Connection', FakeSwiftClient.Connection)
self.stubs.Set(hashlib, 'md5', fake_md5)
for i in xrange(0, 128):
self.volume_file.write(os.urandom(1024))
+ def test_backup_swift_url(self):
+ self.ctxt.service_catalog = [{u'type': u'object-store',
+ u'name': u'swift',
+ u'endpoints': [{
+ u'adminURL': u'http://example.com'}]
+ }]
+ self.assertRaises(exception.BackupDriverException,
+ SwiftBackupDriver,
+ self.ctxt)
+
+ def test_backup_swift_url_conf(self):
+ self.ctxt.service_catalog = [{u'type': u'object-store',
+ u'name': u'swift',
+ u'endpoints': [{
+ u'adminURL': u'http://example.com'}]
+ }]
+ self.ctxt.project_id = "12345678"
+ CONF.set_override("backup_swift_url", "http://public.example.com/")
+ backup = SwiftBackupDriver(self.ctxt)
+ self.assertEqual("%s%s" % (CONF.backup_swift_url,
+ self.ctxt.project_id),
+ backup.swift_url)
+
+ def test_backup_swift_info(self):
+ CONF.set_override("swift_catalog_info", "dummy")
+ self.assertRaises(exception.BackupDriverException,
+ SwiftBackupDriver,
+ self.ctxt)
+
def test_backup_uncompressed(self):
self._create_backup_db_entry()
self.flags(backup_compression_algorithm='none')
'read_deleted',
True)
- def test_service_catalog_nova_only(self):
+ def test_service_catalog_nova_and_swift(self):
service_catalog = [
{u'type': u'compute', u'name': u'nova'},
{u'type': u's3', u'name': u's3'},
{u'type': u'co', u'name': u'S_partofcompute'}]
compute_catalog = [{u'type': u'compute', u'name': u'nova'}]
+ object_catalog = [{u'name': u'swift', u'type': u'object-store'}]
ctxt = context.RequestContext('111', '222',
service_catalog=service_catalog)
- self.assertEqual(ctxt.service_catalog, compute_catalog)
+ self.assertEqual(len(ctxt.service_catalog), 2)
+ return_compute = [v for v in ctxt.service_catalog if
+ v['type'] == u'compute']
+ return_object = [v for v in ctxt.service_catalog if
+ v['type'] == u'object-store']
+ self.assertEqual(return_compute, compute_catalog)
+ self.assertEqual(return_object, object_catalog)
def test_user_identity(self):
ctx = context.RequestContext("user", "tenant",
#
# The URL of the Swift endpoint (string value)
-#backup_swift_url=http://localhost:8080/v1/AUTH_
+#backup_swift_url=<None>
+
+# Info to match when looking for swift in the service catalog.
+# Format is: separated values of the form:
+# <service_type>:<service_name>:<endpoint_type> - Only used if
+# backup_swift_url is unset (string value)
+#swift_catalog_info=object-store:swift:publicURL
# Swift authentication mechanism (string value)
#backup_swift_auth=per_user