Merge lp:~vishvananda/nova/fix-curl-project, fix conflicts with changes
to images.image_url, and add the same fix to xenapi.
This commit is contained in:
commit
570dffd716
@ -419,6 +419,12 @@ class AuthManager(object):
|
||||
raise exception.NotAuthorized('Signature does not match')
|
||||
return (user, project)
|
||||
|
||||
def get_access_key(self, user, project):
|
||||
"""Get an access key that includes user and project"""
|
||||
if not isinstance(user, User):
|
||||
user = self.get_user(user)
|
||||
return "%s:%s" % (user.access, Project.safe_id(project))
|
||||
|
||||
def is_superuser(self, user):
|
||||
"""Checks for superuser status, allowing user to bypass rbac
|
||||
|
||||
|
@ -27,6 +27,7 @@ import urllib
|
||||
|
||||
from nova import flags
|
||||
from nova import utils
|
||||
from nova.auth import manager
|
||||
|
||||
|
||||
FLAGS = flags.FLAGS
|
||||
@ -75,13 +76,16 @@ def deregister(context, image_id):
|
||||
query_args=qs({'image_id': image_id}))
|
||||
|
||||
def conn(context):
|
||||
return boto.s3.connection.S3Connection (
|
||||
aws_access_key_id=str('%s:%s' % (context.user.access, context.project.name)),
|
||||
aws_secret_access_key=str(context.user.secret),
|
||||
is_secure=False,
|
||||
calling_format=boto.s3.connection.OrdinaryCallingFormat(),
|
||||
port=FLAGS.s3_port,
|
||||
host=FLAGS.s3_host)
|
||||
access = manager.AuthManager().get_access_key(context.user,
|
||||
context.project)
|
||||
secret = str(context.user.secret)
|
||||
calling = boto.s3.connection.OrdinaryCallingFormat()
|
||||
return boto.s3.connection.S3Connection(aws_access_key_id=access,
|
||||
aws_secret_access_key=secret,
|
||||
is_secure=False,
|
||||
calling_format=calling,
|
||||
port=FLAGS.s3_port,
|
||||
host=FLAGS.s3_host)
|
||||
|
||||
|
||||
def qs(params):
|
||||
|
@ -28,6 +28,7 @@ import urlparse
|
||||
from nova import flags
|
||||
from nova import process
|
||||
from nova.auth import signer
|
||||
from nova.auth import manager
|
||||
|
||||
FLAGS = flags.FLAGS
|
||||
|
||||
@ -35,14 +36,14 @@ flags.DEFINE_bool('use_s3', True,
|
||||
'whether to get images from s3 or use local copy')
|
||||
|
||||
|
||||
def fetch(image, path, user):
|
||||
def fetch(image, path, user, project):
|
||||
if FLAGS.use_s3:
|
||||
f = _fetch_s3_image
|
||||
else:
|
||||
f = _fetch_local_image
|
||||
return f(image, path, user)
|
||||
return f(image, path, user, project)
|
||||
|
||||
def _fetch_s3_image(image, path, user):
|
||||
def _fetch_s3_image(image, path, user, project):
|
||||
url = image_url(image)
|
||||
|
||||
# This should probably move somewhere else, like e.g. a download_as
|
||||
@ -52,8 +53,11 @@ def _fetch_s3_image(image, path, user):
|
||||
headers['Date'] = time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime())
|
||||
|
||||
(_, _, url_path, _, _, _) = urlparse.urlparse(url)
|
||||
auth = signer.Signer(user.secret.encode()).s3_authorization(headers, 'GET', url_path)
|
||||
headers['Authorization'] = 'AWS %s:%s' % (user.access, auth)
|
||||
access = manager.AuthManager().get_access_key(user, project)
|
||||
signature = signer.Signer(user.secret.encode()).s3_authorization(headers,
|
||||
'GET',
|
||||
url_path)
|
||||
headers['Authorization'] = 'AWS %s:%s' % (access, signature)
|
||||
|
||||
cmd = ['/usr/bin/curl', '--silent', url]
|
||||
for (k,v) in headers.iteritems():
|
||||
|
@ -25,7 +25,6 @@ import json
|
||||
import logging
|
||||
import os.path
|
||||
import shutil
|
||||
import sys
|
||||
|
||||
from twisted.internet import defer
|
||||
from twisted.internet import task
|
||||
@ -187,12 +186,13 @@ class LibvirtConnection(object):
|
||||
f.close()
|
||||
|
||||
user = manager.AuthManager().get_user(data['user_id'])
|
||||
project = manager.AuthManager().get_project(data['project_id'])
|
||||
if not os.path.exists(basepath('disk')):
|
||||
yield images.fetch(data['image_id'], basepath('disk-raw'), user)
|
||||
yield images.fetch(data['image_id'], basepath('disk-raw'), user, project)
|
||||
if not os.path.exists(basepath('kernel')):
|
||||
yield images.fetch(data['kernel_id'], basepath('kernel'), user)
|
||||
yield images.fetch(data['kernel_id'], basepath('kernel'), user, project)
|
||||
if not os.path.exists(basepath('ramdisk')):
|
||||
yield images.fetch(data['ramdisk_id'], basepath('ramdisk'), user)
|
||||
yield images.fetch(data['ramdisk_id'], basepath('ramdisk'), user, project)
|
||||
|
||||
execute = lambda cmd, input=None: \
|
||||
process.simple_execute(cmd=cmd,
|
||||
@ -255,7 +255,7 @@ class LibvirtConnection(object):
|
||||
"""
|
||||
Note that this function takes an instance ID, not an Instance, so
|
||||
that it can be called by monitor.
|
||||
|
||||
|
||||
Returns a list of all block devices for this domain.
|
||||
"""
|
||||
domain = self._conn.lookupByName(instance_id)
|
||||
@ -298,7 +298,7 @@ class LibvirtConnection(object):
|
||||
"""
|
||||
Note that this function takes an instance ID, not an Instance, so
|
||||
that it can be called by monitor.
|
||||
|
||||
|
||||
Returns a list of all network interfaces for this instance.
|
||||
"""
|
||||
domain = self._conn.lookupByName(instance_id)
|
||||
@ -341,7 +341,7 @@ class LibvirtConnection(object):
|
||||
"""
|
||||
Note that this function takes an instance ID, not an Instance, so
|
||||
that it can be called by monitor.
|
||||
"""
|
||||
"""
|
||||
domain = self._conn.lookupByName(instance_id)
|
||||
return domain.blockStats(disk)
|
||||
|
||||
@ -350,6 +350,6 @@ class LibvirtConnection(object):
|
||||
"""
|
||||
Note that this function takes an instance ID, not an Instance, so
|
||||
that it can be called by monitor.
|
||||
"""
|
||||
"""
|
||||
domain = self._conn.lookupByName(instance_id)
|
||||
return domain.interfaceStats(interface)
|
||||
|
@ -92,12 +92,13 @@ class XenAPIConnection(object):
|
||||
mac_address = ''
|
||||
|
||||
user = AuthManager().get_user(instance.datamodel['user_id'])
|
||||
project = AuthManager().get_project(instance.datamodel['project_id'])
|
||||
vdi_uuid = yield self.fetch_image(
|
||||
instance.datamodel['image_id'], user, True)
|
||||
instance.datamodel['image_id'], user, project, True)
|
||||
kernel = yield self.fetch_image(
|
||||
instance.datamodel['kernel_id'], user, False)
|
||||
instance.datamodel['kernel_id'], user, project, False)
|
||||
ramdisk = yield self.fetch_image(
|
||||
instance.datamodel['ramdisk_id'], user, False)
|
||||
instance.datamodel['ramdisk_id'], user, project, False)
|
||||
vdi_ref = yield self._conn.xenapi.VDI.get_by_uuid(vdi_uuid)
|
||||
|
||||
vm_ref = yield self.create_vm(instance, kernel, ramdisk)
|
||||
@ -195,17 +196,18 @@ class XenAPIConnection(object):
|
||||
raise Exception('Found no network for bridge %s' % bridge)
|
||||
|
||||
|
||||
def fetch_image(self, image, user, use_sr):
|
||||
def fetch_image(self, image, user, project, use_sr):
|
||||
"""use_sr: True to put the image as a VDI in an SR, False to place
|
||||
it on dom0's filesystem. The former is for VM disks, the latter for
|
||||
its kernel and ramdisk (if external kernels are being used)."""
|
||||
|
||||
url = images.image_url(image)
|
||||
logging.debug("Asking xapi to fetch %s as %s" % (url, user.access))
|
||||
access = AuthManager().get_access_key(user, project)
|
||||
logging.debug("Asking xapi to fetch %s as %s" % (url, access))
|
||||
fn = use_sr and 'get_vdi' or 'get_kernel'
|
||||
args = {}
|
||||
args['src_url'] = url
|
||||
args['username'] = user.access
|
||||
args['username'] = access
|
||||
args['password'] = user.secret
|
||||
if use_sr:
|
||||
args['add_partition'] = 'true'
|
||||
|
Loading…
Reference in New Issue
Block a user