summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xbin/nova-compute2
-rwxr-xr-xbin/nova-instancemonitor2
-rwxr-xr-xbin/nova-manage2
-rwxr-xr-xbin/nova-network2
-rwxr-xr-xbin/nova-scheduler2
-rwxr-xr-xbin/nova-volume2
-rwxr-xr-xcontrib/nova.sh53
-rw-r--r--nova/api/ec2/cloud.py7
-rw-r--r--nova/api/openstack/auth.py22
-rw-r--r--nova/api/openstack/faults.py2
-rw-r--r--nova/auth/nova_openldap.schema84
-rw-r--r--nova/auth/nova_sun.schema16
-rw-r--r--nova/auth/openssh-lpk_openldap.schema19
-rw-r--r--nova/auth/openssh-lpk_sun.schema10
-rwxr-xr-xnova/auth/slap.sh112
-rw-r--r--nova/compute/manager.py2
-rw-r--r--nova/compute/monitor.py2
-rw-r--r--nova/crypto.py4
-rw-r--r--nova/flags.py33
-rw-r--r--nova/network/linux_net.py22
-rw-r--r--nova/network/manager.py91
-rw-r--r--nova/objectstore/bucket.py2
-rw-r--r--nova/objectstore/image.py4
-rw-r--r--nova/tests/api/openstack/fakes.py1
-rw-r--r--nova/tests/api/openstack/test_api.py8
-rw-r--r--nova/tests/api/openstack/test_auth.py4
26 files changed, 324 insertions, 186 deletions
diff --git a/bin/nova-compute b/bin/nova-compute
index 1724e9659..a66477af5 100755
--- a/bin/nova-compute
+++ b/bin/nova-compute
@@ -34,10 +34,12 @@ if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
from nova import service
from nova import twistd
+from nova import utils
if __name__ == '__main__':
twistd.serve(__file__)
if __name__ == '__builtin__':
+ utils.default_flagfile()
application = service.Service.create() # pylint: disable=C0103
diff --git a/bin/nova-instancemonitor b/bin/nova-instancemonitor
index 094da4033..a7b7fb0c6 100755
--- a/bin/nova-instancemonitor
+++ b/bin/nova-instancemonitor
@@ -34,6 +34,7 @@ possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
sys.path.insert(0, possible_topdir)
+from nova import utils
from nova import twistd
from nova.compute import monitor
@@ -44,6 +45,7 @@ if __name__ == '__main__':
twistd.serve(__file__)
if __name__ == '__builtin__':
+ utils.default_flagfile()
logging.warn('Starting instance monitor')
# pylint: disable-msg=C0103
monitor = monitor.InstanceMonitor()
diff --git a/bin/nova-manage b/bin/nova-manage
index 08b3da123..eb7c6b87b 100755
--- a/bin/nova-manage
+++ b/bin/nova-manage
@@ -467,7 +467,7 @@ def methods_of(obj):
def main():
"""Parse options and call the appropriate class/method."""
- utils.default_flagfile('/etc/nova/nova-manage.conf')
+ utils.default_flagfile()
argv = FLAGS(sys.argv)
if FLAGS.verbose:
diff --git a/bin/nova-network b/bin/nova-network
index fa88aeb47..342a63058 100755
--- a/bin/nova-network
+++ b/bin/nova-network
@@ -34,10 +34,12 @@ if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
from nova import service
from nova import twistd
+from nova import utils
if __name__ == '__main__':
twistd.serve(__file__)
if __name__ == '__builtin__':
+ utils.default_flagfile()
application = service.Service.create() # pylint: disable-msg=C0103
diff --git a/bin/nova-scheduler b/bin/nova-scheduler
index 38a8f213f..069b5a6fa 100755
--- a/bin/nova-scheduler
+++ b/bin/nova-scheduler
@@ -34,10 +34,12 @@ if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
from nova import service
from nova import twistd
+from nova import utils
if __name__ == '__main__':
twistd.serve(__file__)
if __name__ == '__builtin__':
+ utils.default_flagfile()
application = service.Service.create()
diff --git a/bin/nova-volume b/bin/nova-volume
index b9e235717..26148b0ec 100755
--- a/bin/nova-volume
+++ b/bin/nova-volume
@@ -34,10 +34,12 @@ if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
from nova import service
from nova import twistd
+from nova import utils
if __name__ == '__main__':
twistd.serve(__file__)
if __name__ == '__builtin__':
+ utils.default_flagfile()
application = service.Service.create() # pylint: disable-msg=C0103
diff --git a/contrib/nova.sh b/contrib/nova.sh
index f47d972ab..1a9f93a3b 100755
--- a/contrib/nova.sh
+++ b/contrib/nova.sh
@@ -17,11 +17,17 @@ if [ ! -n "$HOST_IP" ]; then
# you should explicitly set HOST_IP in your environment
HOST_IP=`ifconfig | grep -m 1 'inet addr:'| cut -d: -f2 | awk '{print $1}'`
fi
-TEST=0
-USE_MYSQL=0
-MYSQL_PASS=nova
-USE_LDAP=0
-LIBVIRT_TYPE=qemu
+
+USE_MYSQL=${USE_MYSQL:-0}
+MYSQL_PASS=${MYSQL_PASS:-nova}
+TEST=${TEST:-0}
+USE_LDAP=${USE_LDAP:-0}
+LIBVIRT_TYPE=${LIBVIRT_TYPE:-qemu}
+NET_MAN=${NET_MAN:-VlanManager}
+# NOTE(vish): If you are using FlatDHCP on multiple hosts, set the interface
+# below but make sure that the interface doesn't already have an
+# ip or you risk breaking things.
+# FLAT_INTERFACE=eth0
if [ "$USE_MYSQL" == 1 ]; then
SQL_CONN=mysql://root:$MYSQL_PASS@localhost/nova
@@ -36,10 +42,11 @@ else
fi
mkdir -p /etc/nova
-cat >/etc/nova/nova-manage.conf << NOVA_CONF_EOF
+cat >$NOVA_DIR/bin/nova.conf << NOVA_CONF_EOF
--verbose
--nodaemon
---dhcpbridge_flagfile=/etc/nova/nova-manage.conf
+--dhcpbridge_flagfile=$NOVA_DIR/bin/nova.conf
+--network_manager=nova.network.manager.$NET_MAN
--cc_host=$HOST_IP
--routing_source_ip=$HOST_IP
--sql_connection=$SQL_CONN
@@ -47,6 +54,10 @@ cat >/etc/nova/nova-manage.conf << NOVA_CONF_EOF
--libvirt_type=$LIBVIRT_TYPE
NOVA_CONF_EOF
+if [ -n "$FLAT_INTERFACE" ]; then
+ echo "--flat_interface=$FLAT_INTERFACE" >>$NOVA_DIR/bin/nova.conf
+fi
+
if [ "$CMD" == "branch" ]; then
sudo apt-get install -y bzr
rm -rf $NOVA_DIR
@@ -61,9 +72,12 @@ if [ "$CMD" == "install" ]; then
sudo apt-get install -y python-software-properties
sudo add-apt-repository ppa:nova-core/ppa
sudo apt-get update
- sudo apt-get install -y dnsmasq open-iscsi kpartx kvm gawk iptables ebtables
+ sudo apt-get install -y dnsmasq kpartx kvm gawk iptables ebtables
sudo apt-get install -y user-mode-linux kvm libvirt-bin
- sudo apt-get install -y screen iscsitarget euca2ools vlan curl rabbitmq-server
+ sudo apt-get install -y screen euca2ools vlan curl rabbitmq-server
+ sudo apt-get install -y lvm2 iscsitarget open-iscsi
+ echo "ISCSITARGET_ENABLE=true" | sudo tee /etc/default/iscsitarget
+ sudo /etc/init.d/iscsitarget restart
sudo modprobe kvm
sudo /etc/init.d/libvirt-bin restart
sudo apt-get install -y python-twisted python-sqlalchemy python-mox python-greenlet python-carrot
@@ -122,31 +136,32 @@ if [ "$CMD" == "run" ]; then
$NOVA_DIR/bin/nova-manage project create admin admin
# export environment variables for project 'admin' and user 'admin'
$NOVA_DIR/bin/nova-manage project environment admin admin $NOVA_DIR/novarc
- # create 3 small networks
- $NOVA_DIR/bin/nova-manage network create 10.0.0.0/8 3 16
+ # create a small network
+ $NOVA_DIR/bin/nova-manage network create 10.0.0.0/8 1 32
# nova api crashes if we start it with a regular screen command,
# so send the start command by forcing text into the window.
- screen_it api "$NOVA_DIR/bin/nova-api --flagfile=/etc/nova/nova-manage.conf"
- screen_it objectstore "$NOVA_DIR/bin/nova-objectstore --flagfile=/etc/nova/nova-manage.conf"
- screen_it compute "$NOVA_DIR/bin/nova-compute --flagfile=/etc/nova/nova-manage.conf"
- screen_it network "$NOVA_DIR/bin/nova-network --flagfile=/etc/nova/nova-manage.conf"
- screen_it scheduler "$NOVA_DIR/bin/nova-scheduler --flagfile=/etc/nova/nova-manage.conf"
- screen_it volume "$NOVA_DIR/bin/nova-volume --flagfile=/etc/nova/nova-manage.conf"
+ screen_it api "$NOVA_DIR/bin/nova-api"
+ screen_it objectstore "$NOVA_DIR/bin/nova-objectstore"
+ screen_it compute "$NOVA_DIR/bin/nova-compute"
+ screen_it network "$NOVA_DIR/bin/nova-network"
+ screen_it scheduler "$NOVA_DIR/bin/nova-scheduler"
+ screen_it volume "$NOVA_DIR/bin/nova-volume"
screen_it test ". $NOVA_DIR/novarc"
- screen -x
+ screen -S nova -x
fi
if [ "$CMD" == "run" ] || [ "$CMD" == "terminate" ]; then
# shutdown instances
. $NOVA_DIR/novarc; euca-describe-instances | grep i- | cut -f2 | xargs euca-terminate-instances
sleep 2
+ # delete volumes
+ . $NOVA_DIR/novarc; euca-describe-volumes | grep vol- | cut -f2 | xargs -n1 euca-delete-volume
fi
if [ "$CMD" == "run" ] || [ "$CMD" == "clean" ]; then
screen -S nova -X quit
rm *.pid*
- $NOVA_DIR/tools/setup_iptables.sh clear
fi
if [ "$CMD" == "scrub" ]; then
diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py
index 9327bf0d4..884372ce7 100644
--- a/nova/api/ec2/cloud.py
+++ b/nova/api/ec2/cloud.py
@@ -994,8 +994,11 @@ class CloudController(object):
return True
def describe_images(self, context, image_id=None, **kwargs):
- imageSet = self.image_service.index(context, image_id)
- return {'imagesSet': imageSet}
+ # Note: image_id is a list!
+ images = self.image_service.index(context)
+ if image_id:
+ images = filter(lambda x: x['imageId'] in image_id, images)
+ return {'imagesSet': images}
def deregister_image(self, context, image_id, **kwargs):
self.image_service.deregister(context, image_id)
diff --git a/nova/api/openstack/auth.py b/nova/api/openstack/auth.py
index ff428ff70..205035915 100644
--- a/nova/api/openstack/auth.py
+++ b/nova/api/openstack/auth.py
@@ -23,10 +23,7 @@ class Context(object):
class BasicApiAuthManager(object):
""" Implements a somewhat rudimentary version of OpenStack Auth"""
- def __init__(self, host=None, db_driver=None):
- if not host:
- host = FLAGS.host
- self.host = host
+ def __init__(self, db_driver=None):
if not db_driver:
db_driver = FLAGS.db_driver
self.db = utils.import_object(db_driver)
@@ -47,7 +44,7 @@ class BasicApiAuthManager(object):
except KeyError:
return faults.Fault(webob.exc.HTTPUnauthorized())
- token, user = self._authorize_user(username, key)
+ token, user = self._authorize_user(username, key, req)
if user and token:
res = webob.Response()
res.headers['X-Auth-Token'] = token.token_hash
@@ -82,8 +79,13 @@ class BasicApiAuthManager(object):
return {'id': user.id}
return None
- def _authorize_user(self, username, key):
- """ Generates a new token and assigns it to a user """
+ def _authorize_user(self, username, key, req):
+ """Generates a new token and assigns it to a user.
+
+ username - string
+ key - string API key
+ req - webob.Request object
+ """
user = self.auth.get_user_from_access_key(key)
if user and user.name == username:
token_hash = hashlib.sha1('%s%s%f' % (username, key,
@@ -91,12 +93,10 @@ class BasicApiAuthManager(object):
token_dict = {}
token_dict['token_hash'] = token_hash
token_dict['cdn_management_url'] = ''
- token_dict['server_management_url'] = self._get_server_mgmt_url()
+ # Same as auth url, e.g. http://foo.org:8774/baz/v1.0
+ token_dict['server_management_url'] = req.url
token_dict['storage_url'] = ''
token_dict['user_id'] = user.id
token = self.db.auth_create_token(self.context, token_dict)
return token, user
return None, None
-
- def _get_server_mgmt_url(self):
- return 'https://%s/v1.0/' % self.host
diff --git a/nova/api/openstack/faults.py b/nova/api/openstack/faults.py
index e69e51439..224a7ef0b 100644
--- a/nova/api/openstack/faults.py
+++ b/nova/api/openstack/faults.py
@@ -47,7 +47,7 @@ class Fault(webob.exc.HTTPException):
"""Generate a WSGI response based on the exception passed to ctor."""
# Replace the body with fault details.
code = self.wrapped_exc.status_int
- fault_name = self._fault_names.get(code, "cloudServersFault")
+ fault_name = self._fault_names.get(code, "computeFault")
fault_data = {
fault_name: {
'code': code,
diff --git a/nova/auth/nova_openldap.schema b/nova/auth/nova_openldap.schema
new file mode 100644
index 000000000..4047361de
--- /dev/null
+++ b/nova/auth/nova_openldap.schema
@@ -0,0 +1,84 @@
+#
+# Person object for Nova
+# inetorgperson with extra attributes
+# Author: Vishvananda Ishaya <vishvananda@yahoo.com>
+#
+#
+
+# using internet experimental oid arc as per BP64 3.1
+objectidentifier novaSchema 1.3.6.1.3.1.666.666
+objectidentifier novaAttrs novaSchema:3
+objectidentifier novaOCs novaSchema:4
+
+attributetype (
+ novaAttrs:1
+ NAME 'accessKey'
+ DESC 'Key for accessing data'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ SINGLE-VALUE
+ )
+
+attributetype (
+ novaAttrs:2
+ NAME 'secretKey'
+ DESC 'Secret key'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ SINGLE-VALUE
+ )
+
+attributetype (
+ novaAttrs:3
+ NAME 'keyFingerprint'
+ DESC 'Fingerprint of private key'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ SINGLE-VALUE
+ )
+
+attributetype (
+ novaAttrs:4
+ NAME 'isAdmin'
+ DESC 'Is user an administrator?'
+ EQUALITY booleanMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
+ SINGLE-VALUE
+ )
+
+attributetype (
+ novaAttrs:5
+ NAME 'projectManager'
+ DESC 'Project Managers of a project'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
+ )
+
+objectClass (
+ novaOCs:1
+ NAME 'novaUser'
+ DESC 'access and secret keys'
+ AUXILIARY
+ MUST ( uid )
+ MAY ( accessKey $ secretKey $ isAdmin )
+ )
+
+objectClass (
+ novaOCs:2
+ NAME 'novaKeyPair'
+ DESC 'Key pair for User'
+ SUP top
+ STRUCTURAL
+ MUST ( cn $ sshPublicKey $ keyFingerprint )
+ )
+
+objectClass (
+ novaOCs:3
+ NAME 'novaProject'
+ DESC 'Container for project'
+ SUP groupOfNames
+ STRUCTURAL
+ MUST ( cn $ projectManager )
+ )
diff --git a/nova/auth/nova_sun.schema b/nova/auth/nova_sun.schema
new file mode 100644
index 000000000..e925e05e4
--- /dev/null
+++ b/nova/auth/nova_sun.schema
@@ -0,0 +1,16 @@
+#
+# Person object for Nova
+# inetorgperson with extra attributes
+# Author: Vishvananda Ishaya <vishvananda@yahoo.com>
+# Modified for strict RFC 4512 compatibility by: Ryan Lane <ryan@ryandlane.com>
+#
+# using internet experimental oid arc as per BP64 3.1
+dn: cn=schema
+attributeTypes: ( 1.3.6.1.3.1.666.666.3.1 NAME 'accessKey' DESC 'Key for accessing data' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )
+attributeTypes: ( 1.3.6.1.3.1.666.666.3.2 NAME 'secretKey' DESC 'Secret key' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )
+attributeTypes: ( 1.3.6.1.3.1.666.666.3.3 NAME 'keyFingerprint' DESC 'Fingerprint of private key' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE)
+attributeTypes: ( 1.3.6.1.3.1.666.666.3.4 NAME 'isAdmin' DESC 'Is user an administrator?' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
+attributeTypes: ( 1.3.6.1.3.1.666.666.3.5 NAME 'projectManager' DESC 'Project Managers of a project' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
+objectClasses: ( 1.3.6.1.3.1.666.666.4.1 NAME 'novaUser' DESC 'access and secret keys' SUP top AUXILIARY MUST ( uid ) MAY ( accessKey $ secretKey $ isAdmin ) )
+objectClasses: ( 1.3.6.1.3.1.666.666.4.2 NAME 'novaKeyPair' DESC 'Key pair for User' SUP top STRUCTURAL MUST ( cn $ sshPublicKey $ keyFingerprint ) )
+objectClasses: ( 1.3.6.1.3.1.666.666.4.3 NAME 'novaProject' DESC 'Container for project' SUP groupOfNames STRUCTURAL MUST ( cn $ projectManager ) )
diff --git a/nova/auth/openssh-lpk_openldap.schema b/nova/auth/openssh-lpk_openldap.schema
new file mode 100644
index 000000000..93351da6d
--- /dev/null
+++ b/nova/auth/openssh-lpk_openldap.schema
@@ -0,0 +1,19 @@
+#
+# LDAP Public Key Patch schema for use with openssh-ldappubkey
+# Author: Eric AUGE <eau@phear.org>
+#
+# Based on the proposal of : Mark Ruijter
+#
+
+
+# octetString SYNTAX
+attributetype ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey'
+ DESC 'MANDATORY: OpenSSH Public key'
+ EQUALITY octetStringMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
+
+# printableString SYNTAX yes|no
+objectclass ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY
+ DESC 'MANDATORY: OpenSSH LPK objectclass'
+ MAY ( sshPublicKey $ uid )
+ )
diff --git a/nova/auth/openssh-lpk_sun.schema b/nova/auth/openssh-lpk_sun.schema
new file mode 100644
index 000000000..5f52db3b6
--- /dev/null
+++ b/nova/auth/openssh-lpk_sun.schema
@@ -0,0 +1,10 @@
+#
+# LDAP Public Key Patch schema for use with openssh-ldappubkey
+# Author: Eric AUGE <eau@phear.org>
+#
+# Schema for Sun Directory Server.
+# Based on the original schema, modified by Stefan Fischer.
+#
+dn: cn=schema
+attributeTypes: ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey' DESC 'MANDATORY: OpenSSH Public key' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
+objectClasses: ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY DESC 'MANDATORY: OpenSSH LPK objectclass' MAY ( sshPublicKey $ uid ) )
diff --git a/nova/auth/slap.sh b/nova/auth/slap.sh
index fdc0e39dc..797675d2e 100755
--- a/nova/auth/slap.sh
+++ b/nova/auth/slap.sh
@@ -20,115 +20,9 @@
apt-get install -y slapd ldap-utils python-ldap
-cat >/etc/ldap/schema/openssh-lpk_openldap.schema <<LPK_SCHEMA_EOF
-#
-# LDAP Public Key Patch schema for use with openssh-ldappubkey
-# Author: Eric AUGE <eau@phear.org>
-#
-# Based on the proposal of : Mark Ruijter
-#
-
-
-# octetString SYNTAX
-attributetype ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey'
- DESC 'MANDATORY: OpenSSH Public key'
- EQUALITY octetStringMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
-
-# printableString SYNTAX yes|no
-objectclass ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY
- DESC 'MANDATORY: OpenSSH LPK objectclass'
- MAY ( sshPublicKey $ uid )
- )
-LPK_SCHEMA_EOF
-
-cat >/etc/ldap/schema/nova.schema <<NOVA_SCHEMA_EOF
-#
-# Person object for Nova
-# inetorgperson with extra attributes
-# Author: Vishvananda Ishaya <vishvananda@yahoo.com>
-#
-#
-
-# using internet experimental oid arc as per BP64 3.1
-objectidentifier novaSchema 1.3.6.1.3.1.666.666
-objectidentifier novaAttrs novaSchema:3
-objectidentifier novaOCs novaSchema:4
-
-attributetype (
- novaAttrs:1
- NAME 'accessKey'
- DESC 'Key for accessing data'
- EQUALITY caseIgnoreMatch
- SUBSTR caseIgnoreSubstringsMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
- SINGLE-VALUE
- )
-
-attributetype (
- novaAttrs:2
- NAME 'secretKey'
- DESC 'Secret key'
- EQUALITY caseIgnoreMatch
- SUBSTR caseIgnoreSubstringsMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
- SINGLE-VALUE
- )
-
-attributetype (
- novaAttrs:3
- NAME 'keyFingerprint'
- DESC 'Fingerprint of private key'
- EQUALITY caseIgnoreMatch
- SUBSTR caseIgnoreSubstringsMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
- SINGLE-VALUE
- )
-
-attributetype (
- novaAttrs:4
- NAME 'isAdmin'
- DESC 'Is user an administrator?'
- EQUALITY booleanMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
- SINGLE-VALUE
- )
-
-attributetype (
- novaAttrs:5
- NAME 'projectManager'
- DESC 'Project Managers of a project'
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
- )
-
-objectClass (
- novaOCs:1
- NAME 'novaUser'
- DESC 'access and secret keys'
- AUXILIARY
- MUST ( uid )
- MAY ( accessKey $ secretKey $ isAdmin )
- )
-
-objectClass (
- novaOCs:2
- NAME 'novaKeyPair'
- DESC 'Key pair for User'
- SUP top
- STRUCTURAL
- MUST ( cn $ sshPublicKey $ keyFingerprint )
- )
-
-objectClass (
- novaOCs:3
- NAME 'novaProject'
- DESC 'Container for project'
- SUP groupOfNames
- STRUCTURAL
- MUST ( cn $ projectManager )
- )
-
-NOVA_SCHEMA_EOF
+abspath=`dirname "$(cd "${0%/*}" 2>/dev/null; echo "$PWD"/"${0##*/}")"`
+cp $abspath/openssh-lpk_openldap.schema /etc/ldap/schema/openssh-lpk_openldap.schema
+cp $abspath/nova_openldap.schema /etc/ldap/schema/nova_openldap.schema
mv /etc/ldap/slapd.conf /etc/ldap/slapd.conf.orig
cat >/etc/ldap/slapd.conf <<SLAPD_CONF_EOF
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index 890d79fba..50a9d316b 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -47,7 +47,7 @@ from nova.compute import power_state
FLAGS = flags.FLAGS
-flags.DEFINE_string('instances_path', utils.abspath('../instances'),
+flags.DEFINE_string('instances_path', '$state_path/instances',
'where instances are stored on disk')
flags.DEFINE_string('compute_driver', 'nova.virt.connection.get_connection',
'Driver to use for volume creation')
diff --git a/nova/compute/monitor.py b/nova/compute/monitor.py
index ce45b14f6..22653113a 100644
--- a/nova/compute/monitor.py
+++ b/nova/compute/monitor.py
@@ -46,7 +46,7 @@ flags.DEFINE_integer('monitoring_instances_delay', 5,
'Sleep time between updates')
flags.DEFINE_integer('monitoring_instances_step', 300,
'Interval of RRD updates')
-flags.DEFINE_string('monitoring_rrd_path', '/var/nova/monitor/instances',
+flags.DEFINE_string('monitoring_rrd_path', '$state_path/monitor/instances',
'Location of RRD files')
diff --git a/nova/crypto.py b/nova/crypto.py
index d73559587..aacc50b17 100644
--- a/nova/crypto.py
+++ b/nova/crypto.py
@@ -40,9 +40,9 @@ from nova import flags
FLAGS = flags.FLAGS
flags.DEFINE_string('ca_file', 'cacert.pem', 'Filename of root CA')
-flags.DEFINE_string('keys_path', utils.abspath('../keys'),
+flags.DEFINE_string('keys_path', '$state_path/keys',
'Where we keep our keys')
-flags.DEFINE_string('ca_path', utils.abspath('../CA'),
+flags.DEFINE_string('ca_path', '$state_path/CA',
'Where we keep our root CA')
flags.DEFINE_boolean('use_intermediate_ca', False,
'Should we use intermediate CAs for each project?')
diff --git a/nova/flags.py b/nova/flags.py
index f7ae26050..cb9fa105b 100644
--- a/nova/flags.py
+++ b/nova/flags.py
@@ -24,6 +24,7 @@ where they're used.
import getopt
import os
import socket
+import string
import sys
import gflags
@@ -38,11 +39,12 @@ class FlagValues(gflags.FlagValues):
"""
- def __init__(self):
+ def __init__(self, extra_context=None):
gflags.FlagValues.__init__(self)
self.__dict__['__dirty'] = []
self.__dict__['__was_already_parsed'] = False
self.__dict__['__stored_argv'] = []
+ self.__dict__['__extra_context'] = extra_context
def __call__(self, argv):
# We're doing some hacky stuff here so that we don't have to copy
@@ -112,7 +114,7 @@ class FlagValues(gflags.FlagValues):
def ParseNewFlags(self):
if '__stored_argv' not in self.__dict__:
return
- new_flags = FlagValues()
+ new_flags = FlagValues(self)
for k in self.__dict__['__dirty']:
new_flags[k] = gflags.FlagValues.__getitem__(self, k)
@@ -134,9 +136,29 @@ class FlagValues(gflags.FlagValues):
def __getattr__(self, name):
if self.IsDirty(name):
self.ParseNewFlags()
- return gflags.FlagValues.__getattr__(self, name)
+ val = gflags.FlagValues.__getattr__(self, name)
+ if type(val) is str:
+ tmpl = string.Template(val)
+ context = [self, self.__dict__['__extra_context']]
+ return tmpl.substitute(StrWrapper(context))
+ return val
+class StrWrapper(object):
+ """Wrapper around FlagValues objects
+
+ Wraps FlagValues objects for string.Template so that we're
+ sure to return strings."""
+ def __init__(self, context_objs):
+ self.context_objs = context_objs
+
+ def __getitem__(self, name):
+ for context in self.context_objs:
+ val = getattr(context, name, False)
+ if val:
+ return str(val)
+ raise KeyError(name)
+
FLAGS = FlagValues()
gflags.FLAGS = FLAGS
gflags.DEFINE_flag(gflags.HelpFlag(), FLAGS)
@@ -222,8 +244,11 @@ DEFINE_string('vpn_key_suffix',
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('sql_connection',
- 'sqlite:///%s/nova.sqlite' % os.path.abspath("./"),
+ 'sqlite:///$state_path/nova.sqlite',
'connection string for sql database')
DEFINE_string('compute_manager', 'nova.compute.manager.ComputeManager',
diff --git a/nova/network/linux_net.py b/nova/network/linux_net.py
index 4ea24cda6..7b00e65d4 100644
--- a/nova/network/linux_net.py
+++ b/nova/network/linux_net.py
@@ -38,12 +38,12 @@ flags.DEFINE_string('dhcpbridge_flagfile',
'/etc/nova/nova-dhcpbridge.conf',
'location of flagfile for dhcpbridge')
-flags.DEFINE_string('networks_path', utils.abspath('../networks'),
+flags.DEFINE_string('networks_path', '$state_path/networks',
'Location to keep network config files')
flags.DEFINE_string('public_interface', 'vlan1',
'Interface for public IP addresses')
-flags.DEFINE_string('bridge_dev', 'eth0',
- 'network device for bridges')
+flags.DEFINE_string('vlan_interface', 'eth0',
+ 'network device for vlans')
flags.DEFINE_string('dhcpbridge', _bin_file('nova-dhcpbridge'),
'location of nova-dhcpbridge')
flags.DEFINE_string('routing_source_ip', '127.0.0.1',
@@ -54,14 +54,15 @@ flags.DEFINE_bool('use_nova_chains', False,
DEFAULT_PORTS = [("tcp", 80), ("tcp", 22), ("udp", 1194), ("tcp", 443)]
-def init_host():
- """Basic networking setup goes here"""
- # NOTE(devcamcar): Cloud public DNAT entries, CloudPipe port
- # forwarding entries and a default DNAT entry.
+def metadata_forward():
+ """Create forwarding rule for metadata"""
_confirm_rule("PREROUTING", "-t nat -s 0.0.0.0/0 "
"-d 169.254.169.254/32 -p tcp -m tcp --dport 80 -j DNAT "
"--to-destination %s:%s" % (FLAGS.cc_host, FLAGS.cc_port))
+
+def init_host():
+ """Basic networking setup goes here"""
# NOTE(devcamcar): Cloud public SNAT entries and the default
# SNAT rule for outbound traffic.
_confirm_rule("POSTROUTING", "-t nat -s %s "
@@ -134,7 +135,7 @@ def ensure_vlan(vlan_num):
if not _device_exists(interface):
logging.debug("Starting VLAN inteface %s", interface)
_execute("sudo vconfig set_name_type VLAN_PLUS_VID_NO_PAD")
- _execute("sudo vconfig add %s %s" % (FLAGS.bridge_dev, vlan_num))
+ _execute("sudo vconfig add %s %s" % (FLAGS.vlan_interface, vlan_num))
_execute("sudo ifconfig %s up" % interface)
return interface
@@ -142,12 +143,13 @@ def ensure_vlan(vlan_num):
def ensure_bridge(bridge, interface, net_attrs=None):
"""Create a bridge unless it already exists"""
if not _device_exists(bridge):
- logging.debug("Starting Bridge inteface for %s", interface)
+ logging.debug("Starting Bridge interface for %s", interface)
_execute("sudo brctl addbr %s" % bridge)
_execute("sudo brctl setfd %s 0" % bridge)
# _execute("sudo brctl setageing %s 10" % bridge)
_execute("sudo brctl stp %s off" % bridge)
- _execute("sudo brctl addif %s %s" % (bridge, interface))
+ if interface:
+ _execute("sudo brctl addif %s %s" % (bridge, interface))
if net_attrs:
_execute("sudo ifconfig %s %s broadcast %s netmask %s up" % \
(bridge,
diff --git a/nova/network/manager.py b/nova/network/manager.py
index b033bb0a4..a7298b47f 100644
--- a/nova/network/manager.py
+++ b/nova/network/manager.py
@@ -27,6 +27,7 @@ topologies. All of the network commands are issued to a subclass of
:network_driver: Driver to use for network creation
:flat_network_bridge: Bridge device for simple network instances
+:flat_interface: FlatDhcp will bridge into this interface if set
:flat_network_dns: Dns for simple network
:flat_network_dhcp_start: Dhcp start for FlatDhcp
:vlan_start: First VLAN for private networks
@@ -63,7 +64,11 @@ flags.DEFINE_string('flat_network_bridge', 'br100',
'Bridge for simple network instances')
flags.DEFINE_string('flat_network_dns', '8.8.4.4',
'Dns for simple network')
-flags.DEFINE_string('flat_network_dhcp_start', '192.168.0.2',
+flags.DEFINE_bool('flat_injected', True,
+ 'Whether to attempt to inject network setup into guest')
+flags.DEFINE_string('flat_interface', None,
+ 'FlatDhcp will bridge into this interface if set')
+flags.DEFINE_string('flat_network_dhcp_start', '10.0.0.2',
'Dhcp start for FlatDhcp')
flags.DEFINE_integer('vlan_start', 100, 'First VLAN for private networks')
flags.DEFINE_integer('num_networks', 1000, 'Number of networks to support')
@@ -175,9 +180,11 @@ class NetworkManager(manager.Manager):
if instance_ref['mac_address'] != mac:
raise exception.Error("IP %s leased to bad mac %s vs %s" %
(address, instance_ref['mac_address'], mac))
+ now = datetime.datetime.utcnow()
self.db.fixed_ip_update(context,
fixed_ip_ref['address'],
- {'leased': True})
+ {'leased': True,
+ 'updated_at': now})
if not fixed_ip_ref['allocated']:
logging.warn("IP %s leased that was already deallocated", address)
@@ -246,7 +253,31 @@ class NetworkManager(manager.Manager):
class FlatManager(NetworkManager):
- """Basic network where no vlans are used."""
+ """Basic network where no vlans are used.
+
+ FlatManager does not do any bridge or vlan creation. The user is
+ responsible for setting up whatever bridge is specified in
+ flat_network_bridge (br100 by default). This bridge needs to be created
+ on all compute hosts.
+
+ The idea is to create a single network for the host with a command like:
+ nova-manage network create 192.168.0.0/24 1 256. Creating multiple
+ networks for for one manager is currently not supported, but could be
+ added by modifying allocate_fixed_ip and get_network to get the a network
+ with new logic instead of network_get_by_bridge. Arbitrary lists of
+ addresses in a single network can be accomplished with manual db editing.
+
+ If flat_injected is True, the compute host will attempt to inject network
+ config into the guest. It attempts to modify /etc/network/interfaces and
+ currently only works on debian based systems. To support a wider range of
+ OSes, some other method may need to be devised to let the guest know which
+ ip it should be using so that it can configure itself. Perhaps an attached
+ disk or serial device with configuration info.
+
+ Metadata forwarding must be handled by the gateway, and since nova does
+ not do any setup in this mode, it must be done manually. Requests to
+ 169.254.169.254 port 80 will need to be forwarded to the api server.
+ """
def allocate_fixed_ip(self, context, instance_id, *args, **kwargs):
"""Gets a fixed ip from the pool."""
@@ -285,6 +316,7 @@ class FlatManager(NetworkManager):
cidr = "%s/%s" % (fixed_net[start], significant_bits)
project_net = IPy.IP(cidr)
net = {}
+ net['bridge'] = FLAGS.flat_network_bridge
net['cidr'] = cidr
net['netmask'] = str(project_net.netmask())
net['gateway'] = str(project_net[1])
@@ -306,18 +338,36 @@ class FlatManager(NetworkManager):
def _on_set_network_host(self, context, network_id):
"""Called when this host becomes the host for a network."""
net = {}
- net['injected'] = True
- net['bridge'] = FLAGS.flat_network_bridge
+ net['injected'] = FLAGS.flat_injected
net['dns'] = FLAGS.flat_network_dns
self.db.network_update(context, network_id, net)
-class FlatDHCPManager(NetworkManager):
- """Flat networking with dhcp."""
+class FlatDHCPManager(FlatManager):
+ """Flat networking with dhcp.
+
+ FlatDHCPManager will start up one dhcp server to give out addresses.
+ It never injects network settings into the guest. Otherwise it behaves
+ like FlatDHCPManager.
+ """
+
+ def init_host(self):
+ """Do any initialization that needs to be run if this is a
+ standalone service.
+ """
+ super(FlatDHCPManager, self).init_host()
+ self.driver.metadata_forward()
+
+ def setup_compute_network(self, context, instance_id):
+ """Sets up matching network for compute hosts."""
+ network_ref = db.network_get_by_instance(context, instance_id)
+ self.driver.ensure_bridge(network_ref['bridge'],
+ FLAGS.flat_interface,
+ network_ref)
def setup_fixed_ip(self, context, address):
"""Setup dhcp for this network."""
- network_ref = db.fixed_ip_get_by_address(context, address)
+ network_ref = db.fixed_ip_get_network(context, address)
self.driver.update_dhcp(context, network_ref['id'])
def deallocate_fixed_ip(self, context, address, *args, **kwargs):
@@ -326,18 +376,28 @@ class FlatDHCPManager(NetworkManager):
def _on_set_network_host(self, context, network_id):
"""Called when this host becomes the host for a project."""
- super(FlatDHCPManager, self)._on_set_network_host(context, network_id)
- network_ref = self.db.network_get(context, network_id)
- self.db.network_update(context,
- network_id,
- {'dhcp_start': FLAGS.flat_network_dhcp_start})
+ net = {}
+ net['dhcp_start'] = FLAGS.flat_network_dhcp_start
+ self.db.network_update(context, network_id, net)
+ network_ref = db.network_get(context, network_id)
self.driver.ensure_bridge(network_ref['bridge'],
- FLAGS.bridge_dev,
+ FLAGS.flat_interface,
network_ref)
class VlanManager(NetworkManager):
- """Vlan network with dhcp."""
+ """Vlan network with dhcp.
+
+ VlanManager is the most complicated. It will create a host-managed
+ vlan for each project. Each project gets its own subnet. The networks
+ and associated subnets are created with nova-manage using a command like:
+ nova-manage network create 10.0.0.0/8 3 16. This will create 3 networks
+ of 16 addresses from the beginning of the 10.0.0.0 range.
+
+ A dhcp server is run for each subnet, so each project will have its own.
+ For this mode to be useful, each project will need a vpn to access the
+ instances in its subnet.
+ """
@defer.inlineCallbacks
def periodic_tasks(self, context=None):
@@ -357,6 +417,7 @@ class VlanManager(NetworkManager):
standalone service.
"""
super(VlanManager, self).init_host()
+ self.driver.metadata_forward()
self.driver.init_host()
def allocate_fixed_ip(self, context, instance_id, *args, **kwargs):
diff --git a/nova/objectstore/bucket.py b/nova/objectstore/bucket.py
index 697982538..82767e52f 100644
--- a/nova/objectstore/bucket.py
+++ b/nova/objectstore/bucket.py
@@ -33,7 +33,7 @@ from nova.objectstore import stored
FLAGS = flags.FLAGS
-flags.DEFINE_string('buckets_path', utils.abspath('../buckets'),
+flags.DEFINE_string('buckets_path', '$state_path/buckets',
'path to s3 buckets')
diff --git a/nova/objectstore/image.py b/nova/objectstore/image.py
index 4554444fa..7292dbab8 100644
--- a/nova/objectstore/image.py
+++ b/nova/objectstore/image.py
@@ -39,8 +39,8 @@ from nova.objectstore import bucket
FLAGS = flags.FLAGS
-flags.DEFINE_string('images_path', utils.abspath('../images'),
- 'path to decrypted images')
+flags.DEFINE_string('images_path', '$state_path/images',
+ 'path to decrypted images')
class Image(object):
diff --git a/nova/tests/api/openstack/fakes.py b/nova/tests/api/openstack/fakes.py
index 639a2ebe4..6e91ca7bb 100644
--- a/nova/tests/api/openstack/fakes.py
+++ b/nova/tests/api/openstack/fakes.py
@@ -54,7 +54,6 @@ def fake_auth_init(self):
self.db = FakeAuthDatabase()
self.context = Context()
self.auth = FakeAuthManager()
- self.host = 'foo'
@webob.dec.wsgify
diff --git a/nova/tests/api/openstack/test_api.py b/nova/tests/api/openstack/test_api.py
index dd83991b9..d8b202e21 100644
--- a/nova/tests/api/openstack/test_api.py
+++ b/nova/tests/api/openstack/test_api.py
@@ -50,12 +50,12 @@ class APITest(unittest.TestCase):
api.application = succeed
resp = Request.blank('/').get_response(api)
- self.assertFalse('cloudServersFault' in resp.body, resp.body)
+ self.assertFalse('computeFault' in resp.body, resp.body)
self.assertEqual(resp.status_int, 200, resp.body)
api.application = raise_webob_exc
resp = Request.blank('/').get_response(api)
- self.assertFalse('cloudServersFault' in resp.body, resp.body)
+ self.assertFalse('computeFault' in resp.body, resp.body)
self.assertEqual(resp.status_int, 404, resp.body)
api.application = raise_api_fault
@@ -65,10 +65,10 @@ class APITest(unittest.TestCase):
api.application = fail
resp = Request.blank('/').get_response(api)
- self.assertTrue('{"cloudServersFault' in resp.body, resp.body)
+ self.assertTrue('{"computeFault' in resp.body, resp.body)
self.assertEqual(resp.status_int, 500, resp.body)
api.application = fail
resp = Request.blank('/.xml').get_response(api)
- self.assertTrue('<cloudServersFault' in resp.body, resp.body)
+ self.assertTrue('<computeFault' in resp.body, resp.body)
self.assertEqual(resp.status_int, 500, resp.body)
diff --git a/nova/tests/api/openstack/test_auth.py b/nova/tests/api/openstack/test_auth.py
index 29f4b8874..14e720be4 100644
--- a/nova/tests/api/openstack/test_auth.py
+++ b/nova/tests/api/openstack/test_auth.py
@@ -62,14 +62,14 @@ class Test(unittest.TestCase):
f = fakes.FakeAuthManager()
f.add_user('derp', nova.auth.manager.User(1, 'herp', None, None, None))
- req = webob.Request.blank('/v1.0/')
+ req = webob.Request.blank('/v1.0/', {'HTTP_HOST': 'foo'})
req.headers['X-Auth-User'] = 'herp'
req.headers['X-Auth-Key'] = 'derp'
result = req.get_response(nova.api.API('os'))
self.assertEqual(result.status, '204 No Content')
self.assertEqual(len(result.headers['X-Auth-Token']), 40)
self.assertEqual(result.headers['X-Server-Management-Url'],
- "https://foo/v1.0/")
+ "http://foo/v1.0/")
self.assertEqual(result.headers['X-CDN-Management-Url'],
"")
self.assertEqual(result.headers['X-Storage-Url'], "")