Merge with main
This commit is contained in:
commit
d9c9b08453
@ -545,6 +545,15 @@ class NetworkCommands(object):
|
||||
network.dhcp_start,
|
||||
network.dns)
|
||||
|
||||
def delete(self, fixed_range):
|
||||
"""Deletes a network"""
|
||||
network = db.network_get_by_cidr(context.get_admin_context(), \
|
||||
fixed_range)
|
||||
if network.project_id is not None:
|
||||
raise ValueError(_('Network must be disassociated from project %s'
|
||||
' before delete' % network.project_id))
|
||||
db.network_delete_safe(context.get_admin_context(), network.id)
|
||||
|
||||
|
||||
class ServiceCommands(object):
|
||||
"""Enable and disable running services"""
|
||||
|
@ -36,15 +36,18 @@ def limited(items, request, max_limit=1000):
|
||||
try:
|
||||
offset = int(request.GET.get('offset', 0))
|
||||
except ValueError:
|
||||
offset = 0
|
||||
raise webob.exc.HTTPBadRequest(_('offset param must be an integer'))
|
||||
|
||||
try:
|
||||
limit = int(request.GET.get('limit', max_limit))
|
||||
except ValueError:
|
||||
limit = max_limit
|
||||
raise webob.exc.HTTPBadRequest(_('limit param must be an integer'))
|
||||
|
||||
if offset < 0 or limit < 0:
|
||||
raise webob.exc.HTTPBadRequest()
|
||||
if limit < 0:
|
||||
raise webob.exc.HTTPBadRequest(_('limit param must be positive'))
|
||||
|
||||
if offset < 0:
|
||||
raise webob.exc.HTTPBadRequest(_('offset param must be positive'))
|
||||
|
||||
limit = min(max_limit, limit or max_limit)
|
||||
range_end = offset + limit
|
||||
|
@ -98,7 +98,7 @@ class Controller(wsgi.Controller):
|
||||
'application/xml': {
|
||||
"attributes": {
|
||||
"server": ["id", "imageId", "name", "flavorId", "hostId",
|
||||
"status", "progress"]}}}
|
||||
"status", "progress", "adminPass"]}}}
|
||||
|
||||
def __init__(self):
|
||||
self.compute_api = compute.API()
|
||||
@ -178,7 +178,14 @@ class Controller(wsgi.Controller):
|
||||
key_data=key_pair['public_key'],
|
||||
metadata=metadata,
|
||||
onset_files=env.get('onset_files', []))
|
||||
return _translate_keys(instances[0])
|
||||
|
||||
server = _translate_keys(instances[0])
|
||||
password = "%s%s" % (server['server']['name'][:4],
|
||||
utils.generate_password(12))
|
||||
server['server']['adminPass'] = password
|
||||
self.compute_api.set_admin_password(context, server['server']['id'],
|
||||
password)
|
||||
return server
|
||||
|
||||
def update(self, req, id):
|
||||
""" Updates the server name or password """
|
||||
|
@ -498,9 +498,10 @@ class API(base.Base):
|
||||
"""Unrescue the given instance."""
|
||||
self._cast_compute_message('unrescue_instance', context, instance_id)
|
||||
|
||||
def set_admin_password(self, context, instance_id):
|
||||
def set_admin_password(self, context, instance_id, password=None):
|
||||
"""Set the root/admin password for the given instance."""
|
||||
self._cast_compute_message('set_admin_password', context, instance_id)
|
||||
self._cast_compute_message('set_admin_password', context, instance_id,
|
||||
password)
|
||||
|
||||
def inject_file(self, context, instance_id):
|
||||
"""Write a file to the given instance."""
|
||||
|
@ -517,6 +517,13 @@ def network_create_safe(context, values):
|
||||
return IMPL.network_create_safe(context, values)
|
||||
|
||||
|
||||
def network_delete_safe(context, network_id):
|
||||
"""Delete network with key network_id.
|
||||
This method assumes that the network is not associated with any project
|
||||
"""
|
||||
return IMPL.network_delete_safe(context, network_id)
|
||||
|
||||
|
||||
def network_create_fixed_ips(context, network_id, num_vpn_clients):
|
||||
"""Create the ips for the network, reserving sepecified ips."""
|
||||
return IMPL.network_create_fixed_ips(context, network_id, num_vpn_clients)
|
||||
@ -553,6 +560,11 @@ def network_get_by_bridge(context, bridge):
|
||||
return IMPL.network_get_by_bridge(context, bridge)
|
||||
|
||||
|
||||
def network_get_by_cidr(context, cidr):
|
||||
"""Get a network by cidr or raise if it does not exist"""
|
||||
return IMPL.network_get_by_cidr(context, cidr)
|
||||
|
||||
|
||||
def network_get_by_instance(context, instance_id):
|
||||
"""Get a network by instance id or raise if it does not exist."""
|
||||
return IMPL.network_get_by_instance(context, instance_id)
|
||||
|
@ -1054,6 +1054,15 @@ def network_create_safe(context, values):
|
||||
return None
|
||||
|
||||
|
||||
@require_admin_context
|
||||
def network_delete_safe(context, network_id):
|
||||
session = get_session()
|
||||
with session.begin():
|
||||
network_ref = network_get(context, network_id=network_id, \
|
||||
session=session)
|
||||
session.delete(network_ref)
|
||||
|
||||
|
||||
@require_admin_context
|
||||
def network_disassociate(context, network_id):
|
||||
network_update(context, network_id, {'project_id': None,
|
||||
@ -1127,6 +1136,18 @@ def network_get_by_bridge(context, bridge):
|
||||
return result
|
||||
|
||||
|
||||
@require_admin_context
|
||||
def network_get_by_cidr(context, cidr):
|
||||
session = get_session()
|
||||
result = session.query(models.Network).\
|
||||
filter_by(cidr=cidr).first()
|
||||
|
||||
if not result:
|
||||
raise exception.NotFound(_('Network with cidr %s does not exist') %
|
||||
cidr)
|
||||
return result
|
||||
|
||||
|
||||
@require_admin_context
|
||||
def network_get_by_instance(_context, instance_id):
|
||||
session = get_session()
|
||||
|
@ -321,6 +321,8 @@ DEFINE_integer('auth_token_ttl', 3600, 'Seconds for auth tokens to linger')
|
||||
|
||||
DEFINE_string('state_path', os.path.join(os.path.dirname(__file__), '../'),
|
||||
"Top-level directory for maintaining nova's state")
|
||||
DEFINE_string('lock_path', os.path.join(os.path.dirname(__file__), '../'),
|
||||
"Directory for lock files")
|
||||
DEFINE_string('logdir', None, 'output to a per-service log file in named '
|
||||
'directory')
|
||||
|
||||
|
@ -563,6 +563,16 @@ class VlanManager(NetworkManager):
|
||||
# NOTE(vish): This makes ports unique accross the cloud, a more
|
||||
# robust solution would be to make them unique per ip
|
||||
net['vpn_public_port'] = vpn_start + index
|
||||
network_ref = None
|
||||
try:
|
||||
network_ref = db.network_get_by_cidr(context, cidr)
|
||||
except exception.NotFound:
|
||||
pass
|
||||
|
||||
if network_ref is not None:
|
||||
raise ValueError(_('Network with cidr %s already exists' %
|
||||
cidr))
|
||||
|
||||
network_ref = self.db.network_create_safe(context, net)
|
||||
if network_ref:
|
||||
self._create_fixed_ips(context, network_ref['id'])
|
||||
|
@ -79,20 +79,14 @@ class LimiterTest(test.TestCase):
|
||||
Test offset key works with a blank offset.
|
||||
"""
|
||||
req = Request.blank('/?offset=')
|
||||
self.assertEqual(limited(self.tiny, req), self.tiny)
|
||||
self.assertEqual(limited(self.small, req), self.small)
|
||||
self.assertEqual(limited(self.medium, req), self.medium)
|
||||
self.assertEqual(limited(self.large, req), self.large[:1000])
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, limited, self.tiny, req)
|
||||
|
||||
def test_limiter_offset_bad(self):
|
||||
"""
|
||||
Test offset key works with a BAD offset.
|
||||
"""
|
||||
req = Request.blank(u'/?offset=\u0020aa')
|
||||
self.assertEqual(limited(self.tiny, req), self.tiny)
|
||||
self.assertEqual(limited(self.small, req), self.small)
|
||||
self.assertEqual(limited(self.medium, req), self.medium)
|
||||
self.assertEqual(limited(self.large, req), self.large[:1000])
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, limited, self.tiny, req)
|
||||
|
||||
def test_limiter_nothing(self):
|
||||
"""
|
||||
@ -166,18 +160,12 @@ class LimiterTest(test.TestCase):
|
||||
"""
|
||||
Test a negative limit.
|
||||
"""
|
||||
def _limit_large():
|
||||
limited(self.large, req, max_limit=2000)
|
||||
|
||||
req = Request.blank('/?limit=-3000')
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, _limit_large)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, limited, self.tiny, req)
|
||||
|
||||
def test_limiter_negative_offset(self):
|
||||
"""
|
||||
Test a negative offset.
|
||||
"""
|
||||
def _limit_large():
|
||||
limited(self.large, req, max_limit=2000)
|
||||
|
||||
req = Request.blank('/?offset=-30')
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, _limit_large)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, limited, self.tiny, req)
|
||||
|
@ -188,9 +188,37 @@ class ServersTest(test.TestCase):
|
||||
self.assertEqual(s.get('imageId', None), None)
|
||||
i += 1
|
||||
|
||||
def test_get_servers_with_limit(self):
|
||||
req = webob.Request.blank('/v1.0/servers?limit=3')
|
||||
res = req.get_response(fakes.wsgi_app())
|
||||
servers = json.loads(res.body)['servers']
|
||||
self.assertEqual([s['id'] for s in servers], [0, 1, 2])
|
||||
|
||||
req = webob.Request.blank('/v1.0/servers?limit=aaa')
|
||||
res = req.get_response(fakes.wsgi_app())
|
||||
self.assertEqual(res.status_int, 400)
|
||||
self.assertTrue('limit' in res.body)
|
||||
|
||||
def test_get_servers_with_offset(self):
|
||||
req = webob.Request.blank('/v1.0/servers?offset=2')
|
||||
res = req.get_response(fakes.wsgi_app())
|
||||
servers = json.loads(res.body)['servers']
|
||||
self.assertEqual([s['id'] for s in servers], [2, 3, 4])
|
||||
|
||||
req = webob.Request.blank('/v1.0/servers?offset=aaa')
|
||||
res = req.get_response(fakes.wsgi_app())
|
||||
self.assertEqual(res.status_int, 400)
|
||||
self.assertTrue('offset' in res.body)
|
||||
|
||||
def test_get_servers_with_limit_and_offset(self):
|
||||
req = webob.Request.blank('/v1.0/servers?limit=2&offset=1')
|
||||
res = req.get_response(fakes.wsgi_app())
|
||||
servers = json.loads(res.body)['servers']
|
||||
self.assertEqual([s['id'] for s in servers], [1, 2])
|
||||
|
||||
def test_create_instance(self):
|
||||
def instance_create(context, inst):
|
||||
return {'id': '1', 'display_name': ''}
|
||||
return {'id': '1', 'display_name': 'server_test'}
|
||||
|
||||
def server_update(context, id, params):
|
||||
return instance_create(context, id)
|
||||
@ -234,6 +262,12 @@ class ServersTest(test.TestCase):
|
||||
|
||||
res = req.get_response(fakes.wsgi_app())
|
||||
|
||||
server = json.loads(res.body)['server']
|
||||
self.assertEqual('serv', server['adminPass'][:4])
|
||||
self.assertEqual(16, len(server['adminPass']))
|
||||
self.assertEqual('server_test', server['name'])
|
||||
self.assertEqual('1', server['id'])
|
||||
|
||||
self.assertEqual(res.status_int, 200)
|
||||
|
||||
def test_update_no_body(self):
|
||||
|
@ -14,10 +14,12 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import errno
|
||||
import os
|
||||
import select
|
||||
|
||||
from nova import test
|
||||
from nova.utils import parse_mailmap, str_dict_replace
|
||||
from nova.utils import parse_mailmap, str_dict_replace, synchronized
|
||||
|
||||
|
||||
class ProjectTestCase(test.TestCase):
|
||||
@ -55,3 +57,47 @@ class ProjectTestCase(test.TestCase):
|
||||
'%r not listed in Authors' % missing)
|
||||
finally:
|
||||
tree.unlock()
|
||||
|
||||
|
||||
class LockTestCase(test.TestCase):
|
||||
def test_synchronized_wrapped_function_metadata(self):
|
||||
@synchronized('whatever')
|
||||
def foo():
|
||||
"""Bar"""
|
||||
pass
|
||||
self.assertEquals(foo.__doc__, 'Bar', "Wrapped function's docstring "
|
||||
"got lost")
|
||||
self.assertEquals(foo.__name__, 'foo', "Wrapped function's name "
|
||||
"got mangled")
|
||||
|
||||
def test_synchronized(self):
|
||||
rpipe1, wpipe1 = os.pipe()
|
||||
rpipe2, wpipe2 = os.pipe()
|
||||
|
||||
@synchronized('testlock')
|
||||
def f(rpipe, wpipe):
|
||||
try:
|
||||
os.write(wpipe, "foo")
|
||||
except OSError, e:
|
||||
self.assertEquals(e.errno, errno.EPIPE)
|
||||
return
|
||||
|
||||
rfds, _, __ = select.select([rpipe], [], [], 1)
|
||||
self.assertEquals(len(rfds), 0, "The other process, which was"
|
||||
" supposed to be locked, "
|
||||
"wrote on its end of the "
|
||||
"pipe")
|
||||
os.close(rpipe)
|
||||
|
||||
pid = os.fork()
|
||||
if pid > 0:
|
||||
os.close(wpipe1)
|
||||
os.close(rpipe2)
|
||||
|
||||
f(rpipe1, wpipe2)
|
||||
else:
|
||||
os.close(rpipe1)
|
||||
os.close(wpipe2)
|
||||
|
||||
f(rpipe2, wpipe1)
|
||||
os._exit(0)
|
||||
|
@ -23,10 +23,14 @@ System-level utilities and helper functions.
|
||||
|
||||
import base64
|
||||
import datetime
|
||||
import functools
|
||||
import inspect
|
||||
import json
|
||||
import lockfile
|
||||
import netaddr
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
import socket
|
||||
import string
|
||||
import struct
|
||||
@ -34,8 +38,6 @@ import sys
|
||||
import time
|
||||
import types
|
||||
from xml.sax import saxutils
|
||||
import re
|
||||
import netaddr
|
||||
|
||||
from eventlet import event
|
||||
from eventlet import greenthread
|
||||
@ -43,11 +45,13 @@ from eventlet.green import subprocess
|
||||
None
|
||||
from nova import exception
|
||||
from nova.exception import ProcessExecutionError
|
||||
from nova import flags
|
||||
from nova import log as logging
|
||||
|
||||
|
||||
LOG = logging.getLogger("nova.utils")
|
||||
TIME_FORMAT = "%Y-%m-%dT%H:%M:%SZ"
|
||||
FLAGS = flags.FLAGS
|
||||
|
||||
|
||||
def import_class(import_str):
|
||||
@ -500,6 +504,18 @@ def loads(s):
|
||||
return json.loads(s)
|
||||
|
||||
|
||||
def synchronized(name):
|
||||
def wrap(f):
|
||||
@functools.wraps(f)
|
||||
def inner(*args, **kwargs):
|
||||
lock = lockfile.FileLock(os.path.join(FLAGS.lock_path,
|
||||
'nova-%s.lock' % name))
|
||||
with lock:
|
||||
return f(*args, **kwargs)
|
||||
return inner
|
||||
return wrap
|
||||
|
||||
|
||||
def ensure_b64_encoding(val):
|
||||
"""Safety method to ensure that values expected to be base64-encoded
|
||||
actually are. If they are, the value is returned unchanged. Otherwise,
|
||||
|
@ -35,7 +35,7 @@ if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
|
||||
import boto
|
||||
import nova
|
||||
from boto.ec2.connection import EC2Connection
|
||||
from euca2ools import Euca2ool, InstanceValidationError, Util, ConnectionFailed
|
||||
from euca2ools import Euca2ool, InstanceValidationError, Util
|
||||
|
||||
usage_string = """
|
||||
Retrieves a url to an ajax console terminal
|
||||
@ -147,7 +147,7 @@ def main():
|
||||
|
||||
try:
|
||||
euca_conn = euca.make_connection()
|
||||
except ConnectionFailed, e:
|
||||
except Exception, e:
|
||||
print e.message
|
||||
sys.exit(1)
|
||||
try:
|
||||
|
Loading…
x
Reference in New Issue
Block a user