Skip to content

Commit

Permalink
Code change for nova support glance ipv6 address
Browse files Browse the repository at this point in the history
This code change is for nova can parse glance api servers which is
IPv6 address correctly, also make sure nova commands can be run
successfully in pure ipv6 environment, such as 'nova image-list'
and 'nova boot' command.

Fixes bug 1182830

Change-Id: Ia71002c7038b820db7a63f7d6892e76de4743d8d
  • Loading branch information
dzyu committed Sep 12, 2013
1 parent 04eee47 commit cdfb789
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 5 deletions.
15 changes: 12 additions & 3 deletions nova/image/glance.py
Expand Up @@ -37,6 +37,7 @@
from nova.openstack.common import jsonutils
from nova.openstack.common import log as logging
from nova.openstack.common import timeutils
from nova import utils


glance_opts = [
Expand Down Expand Up @@ -78,7 +79,10 @@

def generate_glance_url():
"""Generate the URL to glance."""
return "%s://%s:%d" % (CONF.glance_protocol, CONF.glance_host,
glance_host = CONF.glance_host
if utils.is_valid_ipv6(glance_host):
glance_host = '[%s]' % glance_host
return "%s://%s:%d" % (CONF.glance_protocol, glance_host,
CONF.glance_port)


Expand All @@ -97,7 +101,7 @@ def _parse_image_ref(image_href):
"""
o = urlparse.urlparse(image_href)
port = o.port or 80
host = o.netloc.split(':', 1)[0]
host = o.netloc.rsplit(':', 1)[0]
image_id = o.path.split('/')[-1]
use_ssl = (o.scheme == 'https')
return (image_id, host, port, use_ssl)
Expand Down Expand Up @@ -131,6 +135,9 @@ def _create_glance_client(context, host, port, use_ssl, version=1):
# header 'X-Auth-Token' and 'token'
params['token'] = context.auth_token
params['identity_headers'] = generate_identity_headers(context)
if utils.is_valid_ipv6(host):
#if so, it is ipv6 address, need to wrap it with '[]'
host = '[%s]' % host
endpoint = '%s://%s:%s' % (scheme, host, port)
return glanceclient.Client(str(version), endpoint, **params)

Expand All @@ -147,7 +154,9 @@ def get_api_servers():
api_server = 'http://' + api_server
o = urlparse.urlparse(api_server)
port = o.port or 80
host = o.netloc.split(':', 1)[0]
host = o.netloc.rsplit(':', 1)[0]
if host[0] == '[' and host[-1] == ']':
host = host[1:-1]
use_ssl = (o.scheme == 'https')
api_servers.append((host, port, use_ssl))
random.shuffle(api_servers)
Expand Down
50 changes: 48 additions & 2 deletions nova/tests/image/test_glance.py
Expand Up @@ -23,6 +23,9 @@
import tempfile
import time

import sys
import testtools

import mox

import glanceclient.exc
Expand All @@ -35,6 +38,8 @@
from nova.tests.api.openstack import fakes
from nova.tests.glance import stubs as glance_stubs
from nova.tests import matchers
from nova import utils

import nova.virt.libvirt.utils as lv_utils

CONF = cfg.CONF
Expand Down Expand Up @@ -948,11 +953,52 @@ class TestGlanceUrl(test.TestCase):

def test_generate_glance_http_url(self):
generated_url = glance.generate_glance_url()
http_url = "http://%s:%d" % (CONF.glance_host, CONF.glance_port)
glance_host = CONF.glance_host
# ipv6 address, need to wrap it with '[]'
if utils.is_valid_ipv6(glance_host):
glance_host = '[%s]' % glance_host
http_url = "http://%s:%d" % (glance_host, CONF.glance_port)
self.assertEqual(generated_url, http_url)

def test_generate_glance_https_url(self):
self.flags(glance_protocol="https")
generated_url = glance.generate_glance_url()
https_url = "https://%s:%d" % (CONF.glance_host, CONF.glance_port)
glance_host = CONF.glance_host
# ipv6 address, need to wrap it with '[]'
if utils.is_valid_ipv6(glance_host):
glance_host = '[%s]' % glance_host
https_url = "https://%s:%d" % (glance_host, CONF.glance_port)
self.assertEqual(generated_url, https_url)


class TestGlanceApiServers(test.TestCase):

def test_get_ipv4_api_servers(self):
self.flags(glance_api_servers=['10.0.1.1:9292',
'https://10.0.0.1:9293',
'http://10.0.2.2:9294'])
glance_host = ['10.0.1.1', '10.0.0.1',
'10.0.2.2']
api_servers = glance.get_api_servers()
i = 0
for server in api_servers:
i += 1
self.assertIn(server[0], glance_host)
if i > 2:
break

# Python 2.6 can not parse ipv6 address correctly
@testtools.skipIf(sys.version_info < (2, 7), "py27 or greater only")
def test_get_ipv6_api_servers(self):
self.flags(glance_api_servers=['[2001:2012:1:f101::1]:9292',
'https://[2010:2013:1:f122::1]:9293',
'http://[2001:2011:1:f111::1]:9294'])
glance_host = ['2001:2012:1:f101::1', '2010:2013:1:f122::1',
'2001:2011:1:f111::1']
api_servers = glance.get_api_servers()
i = 0
for server in api_servers:
i += 1
self.assertIn(server[0], glance_host)
if i > 2:
break

0 comments on commit cdfb789

Please sign in to comment.