14
14
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15
15
# License for the specific language governing permissions and limitations
16
16
# under the License.
18
17
"""Implementation of an image service that uses Glance as the backend"""
19
from __future__ import absolute_import
24
from nova import exception
25
from nova import flags
26
from nova import log as logging
27
27
from nova import utils
28
from nova import flags
29
from nova import exception
30
import nova.image.service
28
from nova.image import service
31
LOG = logging.getLogger('nova.image.glance')
32
33
FLAGS = flags.FLAGS
35
flags.DEFINE_string('glance_teller_address', 'http://127.0.0.1',
36
'IP address or URL where Glance\'s Teller service resides')
37
flags.DEFINE_string('glance_teller_port', '9191',
38
'Port for Glance\'s Teller service')
39
flags.DEFINE_string('glance_parallax_address', 'http://127.0.0.1',
40
'IP address or URL where Glance\'s Parallax service '
42
flags.DEFINE_string('glance_parallax_port', '9292',
43
'Port for Glance\'s Parallax service')
46
class TellerClient(object):
49
self.address = FLAGS.glance_teller_address
50
self.port = FLAGS.glance_teller_port
51
url = urlparse.urlparse(self.address)
52
self.netloc = url.netloc
53
self.connection_type = {'http': httplib.HTTPConnection,
54
'https': httplib.HTTPSConnection}[url.scheme]
57
class ParallaxClient(object):
60
self.address = FLAGS.glance_parallax_address
61
self.port = FLAGS.glance_parallax_port
62
url = urlparse.urlparse(self.address)
63
self.netloc = url.netloc
64
self.connection_type = {'http': httplib.HTTPConnection,
65
'https': httplib.HTTPSConnection}[url.scheme]
67
def get_image_index(self):
69
Returns a list of image id/name mappings from Parallax
72
c = self.connection_type(self.netloc, self.port)
73
c.request("GET", "images")
76
# Parallax returns a JSONified dict(images=image_list)
77
data = json.loads(res.read())['images']
80
logging.warn("Parallax returned HTTP error %d from "
81
"request for /images", res.status_int)
86
def get_image_details(self):
88
Returns a list of detailed image data mappings from Parallax
91
c = self.connection_type(self.netloc, self.port)
92
c.request("GET", "images/detail")
95
# Parallax returns a JSONified dict(images=image_list)
96
data = json.loads(res.read())['images']
99
logging.warn("Parallax returned HTTP error %d from "
100
"request for /images/detail", res.status_int)
105
def get_image_metadata(self, image_id):
107
Returns a mapping of image metadata from Parallax
110
c = self.connection_type(self.netloc, self.port)
111
c.request("GET", "images/%s" % image_id)
112
res = c.getresponse()
113
if res.status == 200:
114
# Parallax returns a JSONified dict(image=image_info)
115
data = json.loads(res.read())['image']
118
# TODO(jaypipes): log the error?
123
def add_image_metadata(self, image_metadata):
125
Tells parallax about an image's metadata
128
c = self.connection_type(self.netloc, self.port)
129
body = json.dumps(image_metadata)
130
c.request("POST", "images", body)
131
res = c.getresponse()
132
if res.status == 200:
133
# Parallax returns a JSONified dict(image=image_info)
134
data = json.loads(res.read())['image']
137
# TODO(jaypipes): log the error?
142
def update_image_metadata(self, image_id, image_metadata):
144
Updates Parallax's information about an image
147
c = self.connection_type(self.netloc, self.port)
148
body = json.dumps(image_metadata)
149
c.request("PUT", "images/%s" % image_id, body)
150
res = c.getresponse()
151
return res.status == 200
155
def delete_image_metadata(self, image_id):
157
Deletes Parallax's information about an image
160
c = self.connection_type(self.netloc, self.port)
161
c.request("DELETE", "images/%s" % image_id)
162
res = c.getresponse()
163
return res.status == 200
168
class GlanceImageService(nova.image.service.BaseImageService):
35
GlanceClient = utils.import_class('glance.client.Client')
38
class GlanceImageService(service.BaseImageService):
169
39
"""Provides storage and retrieval of disk image objects within Glance."""
171
41
def __init__(self):
172
self.teller = TellerClient()
173
self.parallax = ParallaxClient()
42
self.client = GlanceClient(FLAGS.glance_host, FLAGS.glance_port)
175
44
def index(self, context):
177
Calls out to Parallax for a list of images available
46
Calls out to Glance for a list of images available
179
images = self.parallax.get_image_index()
48
return self.client.get_images()
182
50
def detail(self, context):
184
Calls out to Parallax for a list of detailed image information
52
Calls out to Glance for a list of detailed image information
186
images = self.parallax.get_image_details()
54
return self.client.get_images_detailed()
189
56
def show(self, context, id):
191
58
Returns a dict containing image data for the given opaque image id.
193
image = self.parallax.get_image_metadata(id)
60
image = self.client.get_image_meta(id)
196
63
raise exception.NotFound