synchronize default vpc creation across threads
when two clients come for functions where check_default_vpc is present then one goes to create default vpc and other fails. it fails because vpc with is_default flag is already in DB but children objects (like subnets) are not yet created. For we will lock check_default_vpc function. Another way is to rework _create_vpc. It can create VPC without is_default flag. And at the end it can set the flag. First thread will pass this. And second thread will fail at flag set operation and will revert all created object. Then second thread can check presence of default VPC again. This way is better cause it can work across several controllers. Change-Id: I5586fa234257b72721e328a9fa2375a56d1553c2
This commit is contained in:
parent
25dbbb3c71
commit
219dbc7db5
|
@ -215,6 +215,8 @@ function configure_ec2api {
|
|||
iniset $NOVA_CONF DEFAULT metadata_use_ssl "True"
|
||||
fi
|
||||
|
||||
iniset $EC2API_CONF_FILE oslo_concurrency lock_path $EC2API_STATE_PATH
|
||||
|
||||
# configure the database.
|
||||
iniset $EC2API_CONF_FILE database connection `database_connection_url ec2api`
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
|
||||
from neutronclient.common import exceptions as neutron_exception
|
||||
from oslo_concurrency import lockutils
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
|
||||
|
@ -33,6 +34,8 @@ from ec2api.i18n import _
|
|||
CONF = cfg.CONF
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
synchronized = lockutils.synchronized_with_prefix('ec2api-')
|
||||
|
||||
|
||||
"""VPC-object related API implementation
|
||||
"""
|
||||
|
@ -164,7 +167,13 @@ def _create_vpc(context, cidr_block, is_default=False):
|
|||
|
||||
|
||||
def _check_and_create_default_vpc(context):
|
||||
if CONF.disable_ec2_classic and not context.is_os_admin:
|
||||
if not CONF.disable_ec2_classic or context.is_os_admin:
|
||||
return
|
||||
|
||||
lock_name = 'default-vpc-lock-{}-'.format(context.project_id)
|
||||
|
||||
@synchronized(lock_name, external=True)
|
||||
def _check():
|
||||
for vpc in db_api.get_items(context, 'vpc'):
|
||||
if vpc.get('is_default'):
|
||||
return vpc
|
||||
|
@ -176,6 +185,8 @@ def _check_and_create_default_vpc(context):
|
|||
LOG.exception('Failed to create default vpc')
|
||||
return None
|
||||
|
||||
return _check()
|
||||
|
||||
|
||||
ec2utils.set_check_and_create_default_vpc(_check_and_create_default_vpc)
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@ def list_opts():
|
|||
ec2api.exception.exc_log_opts,
|
||||
ec2api.paths.path_opts,
|
||||
ec2api.service.service_opts,
|
||||
ec2api.utils.utils_opts,
|
||||
ec2api.wsgi.wsgi_opts,
|
||||
)),
|
||||
]
|
||||
|
|
|
@ -16,9 +16,11 @@ import copy
|
|||
import itertools
|
||||
|
||||
from cinderclient import client as cinderclient
|
||||
import fixtures
|
||||
from glanceclient import client as glanceclient
|
||||
import mock
|
||||
from novaclient import client as novaclient
|
||||
from oslo_concurrency import lockutils
|
||||
from oslo_config import fixture as config_fixture
|
||||
from oslotest import base as test_base
|
||||
|
||||
|
@ -160,6 +162,11 @@ class BaseTestCase(MockOSMixin, MockDBMixin, test_base.BaseTestCase):
|
|||
super(BaseTestCase, self).setUp()
|
||||
self._conf = self.useFixture(config_fixture.Config())
|
||||
self.configure(fatal_exception_format_errors=True)
|
||||
lock_path = self.useFixture(fixtures.TempDir()).path
|
||||
self.fixture = self.useFixture(
|
||||
config_fixture.Config(lockutils.CONF))
|
||||
self.fixture.config(lock_path=lock_path,
|
||||
group='oslo_concurrency')
|
||||
|
||||
def configure(self, **kwargs):
|
||||
self._conf.config(**kwargs)
|
||||
|
|
14
install.sh
14
install.sh
|
@ -11,10 +11,10 @@ CONNECTION="mysql://ec2api:ec2api@127.0.0.1/ec2api?charset=utf8"
|
|||
LOG_DIR=/var/log/ec2api
|
||||
CONF_DIR=/etc/ec2api
|
||||
NOVA_CONF=/etc/nova/nova.conf
|
||||
SIGNING_DIR=/var/cache/ec2api
|
||||
CONF_FILE=$CONF_DIR/ec2api.conf
|
||||
APIPASTE_FILE=$CONF_DIR/api-paste.ini
|
||||
|
||||
DATA_DIR=${DATA_DIR:-/var/lib/ec2api}
|
||||
AUTH_CACHE_DIR=${AUTH_CACHE_DIR:-/var/cache/ec2api}
|
||||
|
||||
CACHE_BACKEND='oslo_cache.dict'
|
||||
|
@ -289,6 +289,8 @@ iniset $CONF_FILE DEFAULT keystone_ec2_tokens_url "$OS_AUTH_URL/v3/ec2tokens"
|
|||
iniset $CONF_FILE database connection "$CONNECTION"
|
||||
iniset $CONF_FILE DEFAULT disable_ec2_classic "$DISABLE_EC2_CLASSIC"
|
||||
iniset $CONF_FILE DEFAULT external_network "$EXTERNAL_NETWORK"
|
||||
iniset $CONF_FILE oslo_concurrency lock_path "$EC2API_STATE_PATH"
|
||||
iniset $CONF_FILE DEFAULT state_path "$DATA_DIR"
|
||||
|
||||
GROUP_AUTHTOKEN="keystone_authtoken"
|
||||
iniset $CONF_FILE $GROUP_AUTHTOKEN signing_dir "$AUTH_CACHE_DIR"
|
||||
|
@ -328,10 +330,6 @@ if [[ -f "$NOVA_CONF" ]]; then
|
|||
iniset $CONF_FILE DEFAULT s3_url "$s3_proto://$s3_host:$s3_port"
|
||||
|
||||
fi
|
||||
|
||||
nova_state_path=$(iniget $NOVA_CONF DEFAULT state_path)
|
||||
root_state_path=$(dirname $nova_state_path)
|
||||
iniset $CONF_FILE DEFAULT state_path ${root_state_path}/ec2api
|
||||
fi
|
||||
|
||||
#init cache dir
|
||||
|
@ -340,6 +338,12 @@ sudo mkdir -p $AUTH_CACHE_DIR
|
|||
sudo chown $USER $AUTH_CACHE_DIR
|
||||
sudo rm -f $AUTH_CACHE_DIR/*
|
||||
|
||||
#init data dir
|
||||
echo Creating data dir
|
||||
sudo mkdir -p $DATA_DIR
|
||||
sudo chown $USER $DATA_DIR
|
||||
sudo rm -f $DATA_DIR/*
|
||||
|
||||
#install it
|
||||
echo Installing package
|
||||
if [[ -z "$VIRTUAL_ENV" ]]; then
|
||||
|
|
Loading…
Reference in New Issue