From 72f08004f3f722a98316018a8e9ec2e270c3669f Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Wed, 19 Jan 2011 10:26:55 -0800 Subject: add helpful error messages to nova-manage and update nova.sh --- bin/nova-manage | 29 ++++++++++++++++++++++++----- contrib/nova.sh | 36 +++++++++++++++++++++++------------- 2 files changed, 47 insertions(+), 18 deletions(-) diff --git a/bin/nova-manage b/bin/nova-manage index d0901ddfc..b116e79a5 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -61,6 +61,7 @@ import sys import time import IPy +from sqlalchemy import exc # If ../nova/__init__.py exists, add ../ to Python search path, so that # it will override what happens to be installed in /usr/(local/)lib/python... @@ -255,6 +256,13 @@ class RoleCommands(object): self.manager.remove_role(user, role, project) +def _db_error(caught_exception): + print caught_exception + print _("The above error may show that the database has not " + "been created.\nPlease create a database using " + "nova-manage sync db before running this command.") + exit(1) + class UserCommands(object): """Class for managing users.""" @@ -270,13 +278,19 @@ class UserCommands(object): def admin(self, name, access=None, secret=None): """creates a new admin and prints exports arguments: name [access] [secret]""" - user = self.manager.create_user(name, access, secret, True) + try: + user = self.manager.create_user(name, access, secret, True) + except exc.OperationalError, e: + _db_error(e) self._print_export(user) def create(self, name, access=None, secret=None): """creates a new user and prints exports arguments: name [access] [secret]""" - user = self.manager.create_user(name, access, secret, False) + try: + user = self.manager.create_user(name, access, secret, False) + except exc.OperationalError, e: + _db_error(e) self._print_export(user) def delete(self, name): @@ -397,9 +411,14 @@ class ProjectCommands(object): with open(filename, 'w') as f: f.write(zip_file) except db.api.NoMoreNetworks: - print ('No more networks available. If this is a new ' - 'installation, you need\nto call something like this:\n\n' - ' nova-manage network create 10.0.0.0/8 10 64\n\n') + print _('No more networks available. If this is a new ' + 'installation, you need\nto call something like this:\n\n' + ' nova-manage network create 10.0.0.0/8 10 64\n\n') + except exception.ProcessExecutionError, e: + print e + print _("The above error may show that the certificate db has not " + "been created.\nPlease create a database by running a " + "nova-api server on this host.") class FloatingIpCommands(object): diff --git a/contrib/nova.sh b/contrib/nova.sh index a0e8e642c..87f500eec 100755 --- a/contrib/nova.sh +++ b/contrib/nova.sh @@ -24,6 +24,8 @@ TEST=${TEST:-0} USE_LDAP=${USE_LDAP:-0} # Use OpenDJ instead of OpenLDAP when using LDAP USE_OPENDJ=${USE_OPENDJ:-0} +# Use IPv6 +USE_IPV6=${USE_IPV6:-0} LIBVIRT_TYPE=${LIBVIRT_TYPE:-qemu} NET_MAN=${NET_MAN:-VlanManager} # NOTE(vish): If you are using FlatDHCP on multiple hosts, set the interface @@ -60,6 +62,10 @@ if [ -n "$FLAT_INTERFACE" ]; then echo "--flat_interface=$FLAT_INTERFACE" >>$NOVA_DIR/bin/nova.conf fi +if [ -n "$USE_IPV6" ]; then + echo "--use_ipv6" >>$NOVA_DIR/bin/nova.conf +fi + if [ "$CMD" == "branch" ]; then sudo apt-get install -y bzr rm -rf $NOVA_DIR @@ -74,7 +80,7 @@ if [ "$CMD" == "install" ]; then sudo apt-get install -y python-software-properties sudo add-apt-repository ppa:nova-core/trunk sudo apt-get update - sudo apt-get install -y dnsmasq kpartx kvm gawk iptables ebtables + sudo apt-get install -y dnsmasq-base kpartx kvm gawk iptables ebtables sudo apt-get install -y user-mode-linux kvm libvirt-bin sudo apt-get install -y screen euca2ools vlan curl rabbitmq-server sudo apt-get install -y lvm2 iscsitarget open-iscsi @@ -85,15 +91,16 @@ if [ "$CMD" == "install" ]; then sudo /etc/init.d/libvirt-bin restart sudo modprobe nbd sudo apt-get install -y python-twisted python-sqlalchemy python-mox python-greenlet python-carrot - sudo apt-get install -y python-daemon python-eventlet python-gflags python-ipy + sudo apt-get install -y python-daemon python-eventlet python-gflags python-ipy python-tempita sudo apt-get install -y python-libvirt python-libxml2 python-routes python-cheetah -#For IPV6 - sudo apt-get install -y python-netaddr - sudo apt-get install -y radvd -#(Nati) Note that this configuration is only needed for nova-network node. - sudo bash -c "echo 1 > /proc/sys/net/ipv6/conf/all/forwarding" - sudo bash -c "echo 0 > /proc/sys/net/ipv6/conf/all/accept_ra" - + sudo apt-get install -y python-netaddr python-paste python-pastedeploy python-glance + + if [ -n "$USE_IPV6" ]; then + sudo apt-get install -y radvd + sudo bash -c "echo 1 > /proc/sys/net/ipv6/conf/all/forwarding" + sudo bash -c "echo 0 > /proc/sys/net/ipv6/conf/all/accept_ra" + fi + if [ "$USE_MYSQL" == 1 ]; then cat < Date: Wed, 19 Jan 2011 10:43:50 -0800 Subject: update the docs to reflect db sync as well --- doc/source/adminguide/multi.node.install.rst | 118 +++++++++++++------------- doc/source/adminguide/nova.manage.rst | 35 +++++--- doc/source/adminguide/single.node.install.rst | 28 +++--- doc/source/man/novamanage.rst | 35 +++++--- 4 files changed, 123 insertions(+), 93 deletions(-) diff --git a/doc/source/adminguide/multi.node.install.rst b/doc/source/adminguide/multi.node.install.rst index 5918b0d38..584f1e6cf 100644 --- a/doc/source/adminguide/multi.node.install.rst +++ b/doc/source/adminguide/multi.node.install.rst @@ -18,45 +18,45 @@ Installing Nova on Multiple Servers =================================== - + When you move beyond evaluating the technology and into building an actual production environment, you will need to know how to configure your datacenter and how to deploy components across your clusters. This guide should help you through that process. - + You can install multiple nodes to increase performance and availability of the OpenStack Compute installation. - + This setup is based on an Ubuntu Lucid 10.04 installation with the latest updates. Most of this works around issues that need to be resolved in the installation and configuration scripts as of October 18th 2010. It also needs to eventually be generalized, but the intent here is to get the multi-node configuration bootstrapped so folks can move forward. - - + + Requirements for a multi-node installation ------------------------------------------ - + * You need a real database, compatible with SQLAlchemy (mysql, postgresql) There's not a specific reason to choose one over another, it basically depends what you know. MySQL is easier to do High Availability (HA) with, but people may already know Postgres. We should document both configurations, though. * For a recommended HA setup, consider a MySQL master/slave replication, with as many slaves as you like, and probably a heartbeat to kick one of the slaves into being a master if it dies. * For performance optimization, split reads and writes to the database. MySQL proxy is the easiest way to make this work if running MySQL. - + Assumptions ----------- - + * Networking is configured between/through the physical machines on a single subnet. * Installation and execution are both performed by ROOT user. - - + + Step 1 - Use apt-get to get the latest code ------------------------------------------- 1. Setup Nova PPA with https://launchpad.net/~nova-core/+archive/trunk. The ‘python-software-properties’ package is a pre-requisite for setting up the nova package repo: :: - + sudo apt-get install python-software-properties sudo add-apt-repository ppa:nova-core/trunk - + 2. Run update. :: - + sudo apt-get update 3. Install nova-pkgs (dependencies should be automatically installed). @@ -72,15 +72,15 @@ Step 2 Setup configuration file (installed in /etc/nova) -------------------------------------------------------- 1. Nova development has consolidated all config files to nova.conf as of November 2010. There is a default set of options that are already configured in nova.conf: - + :: - + --daemonize=1 --dhcpbridge_flagfile=/etc/nova/nova.conf --dhcpbridge=/usr/bin/nova-dhcpbridge --logdir=/var/log/nova --state_path=/var/lib/nova - + The following items ALSO need to be defined in /etc/nova/nova.conf. I’ve added some explanation of the variables, as comments CANNOT be in nova.conf. There seems to be an issue with nova-manage not processing the comments/whitespace correctly: --sql_connection ### Location of Nova SQL DB @@ -110,31 +110,31 @@ The following code can be cut and paste, and edited to your setup: Note: CC_ADDR= Detailed explanation of the following example is available above. - + :: - + --sql_connection=mysql://root:nova@/nova --s3_host= --rabbit_host= ---cc_host= ---verbose +--cc_host= +--verbose --ec2_url=http://:8773/services/Cloud --network_manager=nova.network.manager.VlanManager --fixed_range= ---network_size=<# of addrs> - +--network_size=<# of addrs> + 2. Create a “nova” group, and set permissions:: addgroup nova - + The Nova config file should have its owner set to root:nova, and mode set to 0644, since they contain your MySQL server's root password. :: chown -R root:nova /etc/nova chmod 644 /etc/nova/nova.conf - + Step 3 - Setup the SQL DB (MySQL for this setup) ------------------------------------------------ - + 1. First you 'preseed' to bypass all the installation prompts:: bash @@ -144,92 +144,94 @@ Step 3 - Setup the SQL DB (MySQL for this setup) mysql-server-5.1 mysql-server/root_password_again password $MYSQL_PASS mysql-server-5.1 mysql-server/start_on_boot boolean true MYSQL_PRESEED - + 2. Install MySQL:: - + apt-get install -y mysql-server - + 3. Edit /etc/mysql/my.cnf to change ‘bind-address’ from localhost to any:: sed -i 's/127.0.0.1/0.0.0.0/g' /etc/mysql/my.cnf service mysql restart - + 3. Network Configuration - + If you use FlatManager (as opposed to VlanManager that we set) as your network manager, there are some additional networking changes you’ll have to make to ensure connectivity between your nodes and VMs. If you chose VlanManager or FlatDHCP, you may skip this section, as it’s set up for you automatically. - + Nova defaults to a bridge device named 'br100'. This needs to be created and somehow integrated into YOUR network. To keep things as simple as possible, have all the VM guests on the same network as the VM hosts (the compute nodes). To do so, set the compute node's external IP address to be on the bridge and add eth0 to that bridge. To do this, edit your network interfaces config to look like the following:: < begin /etc/network/interfaces > # The loopback network interface auto lo iface lo inet loopback - + # Networking for NOVA auto br100 - + iface br100 inet dhcp bridge_ports eth0 bridge_stp off bridge_maxwait 0 bridge_fd 0 < end /etc/network/interfaces > - + Next, restart networking to apply the changes:: - + sudo /etc/init.d/networking restart 4. MySQL DB configuration: - + Create NOVA database:: mysql -uroot -p$MYSQL_PASS -e 'CREATE DATABASE nova;' - + Update the DB to include user 'root'@'%' with super user privileges:: mysql -uroot -p$MYSQL_PASS -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;" - + Set mySQL root password:: mysql -uroot -p$MYSQL_PASS -e "SET PASSWORD FOR 'root'@'%' = PASSWORD('$MYSQL_PASS');" - + Step 4 - Setup Nova environment ------------------------------- These are the commands you run to set up a user and project:: + /usr/bin/python /usr/bin/nova-manage db sync /usr/bin/python /usr/bin/nova-manage user admin /usr/bin/python /usr/bin/nova-manage project create /usr/bin/python /usr/bin/nova-manage network create - + Here is an example of what this looks like with real data:: + /usr/bin/python /usr/bin/nova-manage db sync /usr/bin/python /usr/bin/nova-manage user admin dub /usr/bin/python /usr/bin/nova-manage project create dubproject dub /usr/bin/python /usr/bin/nova-manage network create 192.168.0.0/24 1 255 - + (I chose a /24 since that falls inside my /12 range I set in ‘fixed-range’ in nova.conf. Currently, there can only be one network, and I am using the max IP’s available in a /24. You can choose to use any valid amount that you would like.) - + Note: The nova-manage service assumes that the first IP address is your network (like 192.168.0.0), that the 2nd IP is your gateway (192.168.0.1), and that the broadcast is the very last IP in the range you defined (192.168.0.255). If this is not the case you will need to manually edit the sql db 'networks' table.o. - + On running this command, entries are made in the 'networks' and 'fixed_ips' table. However, one of the networks listed in the 'networks' table needs to be marked as bridge in order for the code to know that a bridge exists. The Network is marked as bridged automatically based on the type of network manager selected. This is ONLY necessary if you chose FlatManager as your network type. More information can be found at the end of this document discussing setting up the bridge device. - - + + Step 5 - Create Nova certifications ----------------------------------- - -1. Generate the certs as a zip file. These are the certs you will use to launch instances, bundle images, and all the other assorted api functions. + +1. Generate the certs as a zip file. These are the certs you will use to launch instances, bundle images, and all the other assorted api functions. :: mkdir –p /root/creds /usr/bin/python /usr/bin/nova-manage project zipfile $NOVA_PROJECT $NOVA_PROJECT_USER /root/creds/novacreds.zip - -2. Unzip them in your home directory, and add them to your environment. + +2. Unzip them in your home directory, and add them to your environment. :: - unzip /root/creds/novacreds.zip -d /root/creds/ + unzip /root/creds/novacreds.zip -d /root/creds/ cat /root/creds/novarc >> ~/.bashrc source ~/.bashrc @@ -237,7 +239,7 @@ Step 6 - Restart all relevant services -------------------------------------- Restart all six services in total, just to cover the entire spectrum:: - + libvirtd restart; service nova-network restart; service nova-compute restart; service nova-api restart; service nova-objectstore restart; service nova-scheduler restart Step 7 - Closing steps, and cleaning up @@ -260,19 +262,19 @@ You can then use `euca2ools` to test some items:: euca-describe-images euca-describe-instances - + If you have issues with the API key, you may need to re-source your creds file:: . /root/creds/novarc - + If you don’t get any immediate errors, you’re successfully making calls to your cloud! -Step 9 - Spinning up a VM for testing +Step 9 - Spinning up a VM for testing ------------------------------------- -(This excerpt is from Thierry Carrez's blog, with reference to http://wiki.openstack.org/GettingImages.) +(This excerpt is from Thierry Carrez's blog, with reference to http://wiki.openstack.org/GettingImages.) -The image that you will use here will be a ttylinux image, so this is a limited function server. You will be able to ping and SSH to this instance, but it is in no way a full production VM. +The image that you will use here will be a ttylinux image, so this is a limited function server. You will be able to ping and SSH to this instance, but it is in no way a full production VM. Download the image, and publish to your bucket: @@ -296,13 +298,13 @@ Boot your instance: :: - euca-run-instances $emi -k mykey -t m1.tiny + euca-run-instances $emi -k mykey -t m1.tiny ($emi is replaced with the output from the previous command) Checking status, and confirming communication: -Once you have booted the instance, you can check the status the the `euca-describe-instances` command. Here you can view the instance ID, IP, and current status of the VM. +Once you have booted the instance, you can check the status the the `euca-describe-instances` command. Here you can view the instance ID, IP, and current status of the VM. :: diff --git a/doc/source/adminguide/nova.manage.rst b/doc/source/adminguide/nova.manage.rst index 0ec67c69c..0e9a29b6b 100644 --- a/doc/source/adminguide/nova.manage.rst +++ b/doc/source/adminguide/nova.manage.rst @@ -42,6 +42,17 @@ You can also run with a category argument such as user to see a list of all comm These sections describe the available categories and arguments for nova-manage. +Nova Db +~~~~~~~ + +``nova-manage db version`` + + Print the current database version. + +``nova-manage db sync`` + + Sync the database up to the most recent version. This is the standard way to create the db as well. + Nova User ~~~~~~~~~ @@ -68,7 +79,7 @@ Nova User ``nova-manage user modify `` Updates the indicated user keys, indicating with T or F if the user is an admin user. Leave any argument blank if you do not want to update it. - + Nova Project ~~~~~~~~~~~~ @@ -79,7 +90,7 @@ Nova Project ``nova-manage project create `` Create a new nova project with the name (you still need to do nova-manage project add to add it to the database). - + ``nova-manage project delete `` Delete a nova project with the name . @@ -87,7 +98,7 @@ Nova Project ``nova-manage project environment `` Exports environment variables for the named project to a file named novarc. - + ``nova-manage project list`` Outputs a list of all the projects to the screen. @@ -103,27 +114,27 @@ Nova Project ``nova-manage project zipfile`` Compresses all related files for a created project into a zip file nova.zip. - + Nova Role ~~~~~~~~~ -nova-manage role [] +nova-manage role [] ``nova-manage role add <(optional) projectname>`` - Add a user to either a global or project-based role with the indicated assigned to the named user. Role names can be one of the following five roles: admin, itsec, projectmanager, netadmin, developer. If you add the project name as the last argument then the role is assigned just for that project, otherwise the user is assigned the named role for all projects. + Add a user to either a global or project-based role with the indicated assigned to the named user. Role names can be one of the following five roles: admin, itsec, projectmanager, netadmin, developer. If you add the project name as the last argument then the role is assigned just for that project, otherwise the user is assigned the named role for all projects. ``nova-manage role has `` Checks the user or project and responds with True if the user has a global role with a particular project. ``nova-manage role remove `` - Remove the indicated role from the user. + Remove the indicated role from the user. Nova Shell ~~~~~~~~~~ ``nova-manage shell bpython`` - Starts a new bpython shell. + Starts a new bpython shell. ``nova-manage shell ipython`` @@ -150,12 +161,12 @@ Nova VPN ``nova-manage vpn run `` - Starts the VPN for the named project. + Starts the VPN for the named project. ``nova-manage vpn spawn`` Runs all VPNs. - + Nova Floating IPs ~~~~~~~~~~~~~~~~~ @@ -165,8 +176,8 @@ Nova Floating IPs ``nova-manage floating delete `` - Deletes floating IP addresses in the range given. - + Deletes floating IP addresses in the range given. + ``nova-manage floating list`` Displays a list of all floating IP addresses. diff --git a/doc/source/adminguide/single.node.install.rst b/doc/source/adminguide/single.node.install.rst index 8572c5a4a..b1b5c25a8 100644 --- a/doc/source/adminguide/single.node.install.rst +++ b/doc/source/adminguide/single.node.install.rst @@ -52,7 +52,13 @@ When the installation is complete, you'll see the following lines: Finished processing dependencies for nova==2010.1 -Step 4: Create a Nova administrator +Step 4: Create the Nova Database +-------------------------------- +Type or copy/paste in the following line to create your nova db:: + + sudo nova-manage db sync + +Step 5: Create a Nova administrator ----------------------------------- Type or copy/paste in the following line to create a user named "anne.":: @@ -63,10 +69,10 @@ You see an access key and a secret key export, such as these made-up ones::: export EC2_ACCESS_KEY=4e6498a2-blah-blah-blah-17d1333t97fd export EC2_SECRET_KEY=0a520304-blah-blah-blah-340sp34k05bbe9a7 -Step 5: Create the network +Step 6: Create the network -------------------------- -Type or copy/paste in the following line to create a network prior to creating a project. +Type or copy/paste in the following line to create a network prior to creating a project. :: @@ -76,7 +82,7 @@ For this command, the IP address is the cidr notation for your netmask, such as After running this command, entries are made in the 'networks' and 'fixed_ips' table in the database. -Step 6: Create a project with the user you created +Step 7: Create a project with the user you created -------------------------------------------------- Type or copy/paste in the following line to create a project named IRT (for Ice Road Truckers, of course) with the newly-created user named anne. @@ -106,7 +112,7 @@ Type or copy/paste in the following line to create a project named IRT (for Ice Data Base Updated -Step 7: Unzip the nova.zip +Step 8: Unzip the nova.zip -------------------------- You should have a nova.zip file in your current working directory. Unzip it with this command: @@ -128,7 +134,7 @@ You'll see these files extract. extracting: cacert.pem -Step 8: Source the rc file +Step 9: Source the rc file -------------------------- Type or copy/paste the following to source the novarc file in your current working directory. @@ -137,14 +143,14 @@ Type or copy/paste the following to source the novarc file in your current worki . novarc -Step 9: Pat yourself on the back :) +Step 10: Pat yourself on the back :) ----------------------------------- Congratulations, your cloud is up and running, you’ve created an admin user, created a network, retrieved the user's credentials and put them in your environment. Now you need an image. -Step 9: Get an image +Step 11: Get an image -------------------- To make things easier, we've provided a small image on the Rackspace CDN. Use this command to get it on your server. @@ -168,7 +174,7 @@ To make things easier, we've provided a small image on the Rackspace CDN. Use th -Step 10: Decompress the image file +Step 12: Decompress the image file ---------------------------------- Use this command to extract the image files::: @@ -187,7 +193,7 @@ You get a directory listing like so::: |-- image `-- info.json -Step 11: Send commands to upload sample image to the cloud +Step 13: Send commands to upload sample image to the cloud ---------------------------------------------------------- Type or copy/paste the following commands to create a manifest for the kernel.:: @@ -340,7 +346,7 @@ You should see this in response::: Type or copy/paste the following commands to ssh to the instance using your private key.:: ssh -i mykey.priv root@10.0.0.3 - + Troubleshooting Installation ---------------------------- diff --git a/doc/source/man/novamanage.rst b/doc/source/man/novamanage.rst index 0cb6c7c90..bb9d7a7fe 100644 --- a/doc/source/man/novamanage.rst +++ b/doc/source/man/novamanage.rst @@ -42,6 +42,17 @@ You can also run with a category argument such as user to see a list of all comm These sections describe the available categories and arguments for nova-manage. +Nova Db +~~~~~~~ + +``nova-manage db version`` + + Print the current database version. + +``nova-manage db sync`` + + Sync the database up to the most recent version. This is the standard way to create the db as well. + Nova User ~~~~~~~~~ @@ -68,7 +79,7 @@ Nova User ``nova-manage user modify `` Updates the indicated user keys, indicating with T or F if the user is an admin user. Leave any argument blank if you do not want to update it. - + Nova Project ~~~~~~~~~~~~ @@ -79,7 +90,7 @@ Nova Project ``nova-manage project create `` Create a new nova project with the name (you still need to do nova-manage project add to add it to the database). - + ``nova-manage project delete `` Delete a nova project with the name . @@ -87,7 +98,7 @@ Nova Project ``nova-manage project environment `` Exports environment variables for the named project to a file named novarc. - + ``nova-manage project list`` Outputs a list of all the projects to the screen. @@ -103,27 +114,27 @@ Nova Project ``nova-manage project zipfile`` Compresses all related files for a created project into a zip file nova.zip. - + Nova Role ~~~~~~~~~ -nova-manage role [] +nova-manage role [] ``nova-manage role add <(optional) projectname>`` - Add a user to either a global or project-based role with the indicated assigned to the named user. Role names can be one of the following five roles: admin, itsec, projectmanager, netadmin, developer. If you add the project name as the last argument then the role is assigned just for that project, otherwise the user is assigned the named role for all projects. + Add a user to either a global or project-based role with the indicated assigned to the named user. Role names can be one of the following five roles: admin, itsec, projectmanager, netadmin, developer. If you add the project name as the last argument then the role is assigned just for that project, otherwise the user is assigned the named role for all projects. ``nova-manage role has `` Checks the user or project and responds with True if the user has a global role with a particular project. ``nova-manage role remove `` - Remove the indicated role from the user. + Remove the indicated role from the user. Nova Shell ~~~~~~~~~~ ``nova-manage shell bpython`` - Starts a new bpython shell. + Starts a new bpython shell. ``nova-manage shell ipython`` @@ -150,20 +161,20 @@ Nova VPN ``nova-manage vpn run `` - Starts the VPN for the named project. + Starts the VPN for the named project. ``nova-manage vpn spawn`` Runs all VPNs. - + Nova Floating IPs ~~~~~~~~~~~~~~~~~ ``nova-manage floating create `` Creates floating IP addresses for the named host by the given range. - floating delete Deletes floating IP addresses in the range given. - + floating delete Deletes floating IP addresses in the range given. + ``nova-manage floating list`` Displays a list of all floating IP addresses. -- cgit From ffe08ea0c5c47ef13a459ac2821e7f706b4070a4 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Thu, 20 Jan 2011 00:40:57 -0800 Subject: fix ipv6 conditional --- contrib/nova.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contrib/nova.sh b/contrib/nova.sh index 87f500eec..41e1e0f7e 100755 --- a/contrib/nova.sh +++ b/contrib/nova.sh @@ -62,7 +62,7 @@ if [ -n "$FLAT_INTERFACE" ]; then echo "--flat_interface=$FLAT_INTERFACE" >>$NOVA_DIR/bin/nova.conf fi -if [ -n "$USE_IPV6" ]; then +if [ "$USE_IPV6" == 1 ]; then echo "--use_ipv6" >>$NOVA_DIR/bin/nova.conf fi @@ -95,7 +95,7 @@ if [ "$CMD" == "install" ]; then sudo apt-get install -y python-libvirt python-libxml2 python-routes python-cheetah sudo apt-get install -y python-netaddr python-paste python-pastedeploy python-glance - if [ -n "$USE_IPV6" ]; then + if [ "$USE_IPV6" == 1 ]; then sudo apt-get install -y radvd sudo bash -c "echo 1 > /proc/sys/net/ipv6/conf/all/forwarding" sudo bash -c "echo 0 > /proc/sys/net/ipv6/conf/all/accept_ra" @@ -122,7 +122,7 @@ function screen_it { if [ "$CMD" == "run" ]; then killall dnsmasq - if [ -n "$USE_IPV6" ]; then + if [ "$USE_IPV6" == 1 ]; then killall radvd fi screen -d -m -S nova -t nova -- cgit From edceeb76885a246191315c6a6c76a7e4e89511e5 Mon Sep 17 00:00:00 2001 From: Tushar Patil Date: Thu, 20 Jan 2011 16:47:46 -0800 Subject: Fix for LP Bug #699654 --- Authors | 1 + nova/api/ec2/__init__.py | 17 +++++++++-------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Authors b/Authors index 608fec523..33895be74 100644 --- a/Authors +++ b/Authors @@ -49,6 +49,7 @@ Soren Hansen Thierry Carrez Todd Willey Trey Morris +Tushar Patil Vishvananda Ishaya Youcef Laribi Zhixue Wu diff --git a/nova/api/ec2/__init__.py b/nova/api/ec2/__init__.py index 238cb0f38..f251c8d41 100644 --- a/nova/api/ec2/__init__.py +++ b/nova/api/ec2/__init__.py @@ -168,7 +168,7 @@ class Authenticate(wsgi.Middleware): req.path) # Be explicit for what exceptions are 403, the rest bubble as 500 except (exception.NotFound, exception.NotAuthorized) as ex: - LOG.audit(_("Authentication Failure: %s"), str(ex)) + LOG.error(_("Authentication Failure: %s"), ex.args[0]) raise webob.exc.HTTPForbidden() # Authenticated! @@ -310,17 +310,17 @@ class Executor(wsgi.Application): try: result = api_request.invoke(context) except exception.NotFound as ex: - LOG.info(_('NotFound raised: %s'), str(ex), context=context) - return self._error(req, context, type(ex).__name__, str(ex)) + LOG.info(_('NotFound raised: %s'), ex.args[0], context=context) + return self._error(req, context, type(ex).__name__, ex.args[0]) except exception.ApiError as ex: - LOG.exception(_('ApiError raised: %s'), str(ex), context=context) + LOG.exception(_('ApiError raised: %s'), ex.args[0], context=context) if ex.code: - return self._error(req, context, ex.code, str(ex)) + return self._error(req, context, ex.code, ex.args[0]) else: - return self._error(req, context, type(ex).__name__, str(ex)) + return self._error(req, context, type(ex).__name__, ex.args[0]) except Exception as ex: extra = {'environment': req.environ} - LOG.exception(_('Unexpected error raised: %s'), str(ex), + LOG.exception(_('Unexpected error raised: %s'), ex.args[0], extra=extra, context=context) return self._error(req, context, @@ -343,7 +343,8 @@ class Executor(wsgi.Application): '%s' '%s' '%s' % - (code, message, context.request_id)) + (utils.utf8(code), utils.utf8(message), + utils.utf8(context.request_id))) return resp -- cgit From 14f01f5daeca8cac9d669c584348712c2e893bc1 Mon Sep 17 00:00:00 2001 From: Tushar Patil Date: Thu, 20 Jan 2011 17:29:17 -0800 Subject: Reverted log type from error to audit --- nova/api/ec2/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/api/ec2/__init__.py b/nova/api/ec2/__init__.py index f251c8d41..3656bb44b 100644 --- a/nova/api/ec2/__init__.py +++ b/nova/api/ec2/__init__.py @@ -168,7 +168,7 @@ class Authenticate(wsgi.Middleware): req.path) # Be explicit for what exceptions are 403, the rest bubble as 500 except (exception.NotFound, exception.NotAuthorized) as ex: - LOG.error(_("Authentication Failure: %s"), ex.args[0]) + LOG.audit(_("Authentication Failure: %s"), ex.args[0]) raise webob.exc.HTTPForbidden() # Authenticated! -- cgit From 842bd9646ad0e9008af86da9153fdf592788b3c3 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Fri, 21 Jan 2011 14:51:24 -0800 Subject: Wrap instance at api layer to print the proper error. Use same logic for volumes. --- nova/api/ec2/cloud.py | 28 +++++++++++++++++++++------- nova/db/sqlalchemy/api.py | 2 ++ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index c94540793..766727b56 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -529,11 +529,18 @@ class CloudController(object): def describe_volumes(self, context, volume_id=None, **kwargs): if volume_id: - volume_id = [ec2_id_to_id(x) for x in volume_id] - volumes = self.volume_api.get_all(context) - # NOTE(vish): volume_id is an optional list of volume ids to filter by. - volumes = [self._format_volume(context, v) for v in volumes - if volume_id is None or v['id'] in volume_id] + volumes = [] + for ec2_id in volume_id: + internal_id = ec2_id_to_id(ec2_id) + try: + volume = self.volume_api.get(context, internal_id) + volumes.append(volume) + except exception.NotFound: + raise exception.NotFound("Volume %s could not be found" + % ec2_id) + else: + volumes = self.volume_api.get_all(context) + volumes = [self._format_volume(context, v) for v in volumes] return {'volumeSet': volumes} def _format_volume(self, context, volume): @@ -657,8 +664,15 @@ class CloudController(object): reservations = {} # NOTE(vish): instance_id is an optional list of ids to filter by if instance_id: - instance_id = [ec2_id_to_id(x) for x in instance_id] - instances = [self.compute_api.get(context, x) for x in instance_id] + instances = [] + for ec2_id in instance_id: + internal_id = ec2_id_to_id(ec2_id) + try: + instance = self.compute_api.get(context, internal_id) + instances.append(instance) + except exception.NotFound: + raise exception.NotFound("Instance %s could not be found" + % ec2_id) else: instances = self.compute_api.get_all(context, **kwargs) for instance in instances: diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 7b965f672..5edca0cd0 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1395,11 +1395,13 @@ def volume_get(context, volume_id, session=None): if is_admin_context(context): result = session.query(models.Volume).\ + options(joinedload('instance')).\ filter_by(id=volume_id).\ filter_by(deleted=can_read_deleted(context)).\ first() elif is_user_context(context): result = session.query(models.Volume).\ + options(joinedload('instance')).\ filter_by(project_id=context.project_id).\ filter_by(id=volume_id).\ filter_by(deleted=False).\ -- cgit From 9bdcc71733105a49636f74a99130112ef96d0bce Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Fri, 21 Jan 2011 15:48:10 -0800 Subject: wrap sqlalchemy exceptions in a generic error --- bin/nova-manage | 5 ++-- contrib/nova.sh | 67 +++++++++++++++++++++++-------------------- nova/db/api.py | 1 - nova/db/sqlalchemy/session.py | 3 ++ nova/exception.py | 18 ++++++++++++ 5 files changed, 59 insertions(+), 35 deletions(-) diff --git a/bin/nova-manage b/bin/nova-manage index b116e79a5..70355a591 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -61,7 +61,6 @@ import sys import time import IPy -from sqlalchemy import exc # If ../nova/__init__.py exists, add ../ to Python search path, so that # it will override what happens to be installed in /usr/(local/)lib/python... @@ -280,7 +279,7 @@ class UserCommands(object): arguments: name [access] [secret]""" try: user = self.manager.create_user(name, access, secret, True) - except exc.OperationalError, e: + except exception.DBError, e: _db_error(e) self._print_export(user) @@ -289,7 +288,7 @@ class UserCommands(object): arguments: name [access] [secret]""" try: user = self.manager.create_user(name, access, secret, False) - except exc.OperationalError, e: + except exception.DBError, e: _db_error(e) self._print_export(user) diff --git a/contrib/nova.sh b/contrib/nova.sh index 41e1e0f7e..9259035ca 100755 --- a/contrib/nova.sh +++ b/contrib/nova.sh @@ -1,15 +1,14 @@ #!/usr/bin/env bash DIR=`pwd` CMD=$1 -SOURCE_BRANCH=lp:nova -if [ -n "$2" ]; then - SOURCE_BRANCH=$2 +if [ "$CMD" = "branch" ]; then + SOURCE_BRANCH=${2:-lp:nova} + DIRNAME=${3:-nova} +else + DIRNAME=${2:-nova} fi -DIRNAME=nova + NOVA_DIR=$DIR/$DIRNAME -if [ -n "$3" ]; then - NOVA_DIR=$DIR/$3 -fi if [ ! -n "$HOST_IP" ]; then # NOTE(vish): This will just get the first ip in the list, so if you @@ -45,34 +44,17 @@ else AUTH=dbdriver.DbDriver fi -mkdir -p /etc/nova -cat >$NOVA_DIR/bin/nova.conf << NOVA_CONF_EOF ---verbose ---nodaemon ---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 ---auth_driver=nova.auth.$AUTH ---libvirt_type=$LIBVIRT_TYPE -NOVA_CONF_EOF - -if [ -n "$FLAT_INTERFACE" ]; then - echo "--flat_interface=$FLAT_INTERFACE" >>$NOVA_DIR/bin/nova.conf -fi - -if [ "$USE_IPV6" == 1 ]; then - echo "--use_ipv6" >>$NOVA_DIR/bin/nova.conf -fi - if [ "$CMD" == "branch" ]; then sudo apt-get install -y bzr + if [ ! -e "$DIR/.bzr" ]; then + bzr init-repo $DIR + fi rm -rf $NOVA_DIR bzr branch $SOURCE_BRANCH $NOVA_DIR cd $NOVA_DIR mkdir -p $NOVA_DIR/instances mkdir -p $NOVA_DIR/networks + exit fi # You should only have to run this once @@ -91,7 +73,7 @@ if [ "$CMD" == "install" ]; then sudo /etc/init.d/libvirt-bin restart sudo modprobe nbd sudo apt-get install -y python-twisted python-sqlalchemy python-mox python-greenlet python-carrot - sudo apt-get install -y python-daemon python-eventlet python-gflags python-ipy python-tempita + sudo apt-get install -y python-migrate python-eventlet python-gflags python-ipy python-tempita sudo apt-get install -y python-libvirt python-libxml2 python-routes python-cheetah sudo apt-get install -y python-netaddr python-paste python-pastedeploy python-glance @@ -109,8 +91,10 @@ mysql-server-5.1 mysql-server/start_on_boot boolean true MYSQL_PRESEED apt-get install -y mysql-server python-mysqldb fi - wget -c http://c2477062.cdn.cloudfiles.rackspacecloud.com/images.tgz - tar -C $DIR -zxf images.tgz + mkdir -p $DIR/images + wget -c http://images.ansolabs.com/tty.tgz + tar -C $DIR/images -zxf tty.tgz + exit fi NL=`echo -ne '\015'` @@ -121,6 +105,27 @@ function screen_it { } if [ "$CMD" == "run" ]; then + + cat >$NOVA_DIR/bin/nova.conf << NOVA_CONF_EOF +--verbose +--nodaemon +--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 +--auth_driver=nova.auth.$AUTH +--libvirt_type=$LIBVIRT_TYPE +NOVA_CONF_EOF + + if [ -n "$FLAT_INTERFACE" ]; then + echo "--flat_interface=$FLAT_INTERFACE" >>$NOVA_DIR/bin/nova.conf + fi + + if [ "$USE_IPV6" == 1 ]; then + echo "--use_ipv6" >>$NOVA_DIR/bin/nova.conf + fi + killall dnsmasq if [ "$USE_IPV6" == 1 ]; then killall radvd diff --git a/nova/db/api.py b/nova/db/api.py index f9d561587..8afe74eea 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -71,7 +71,6 @@ class NoMoreTargets(exception.Error): """No more available blades""" pass - ################### diff --git a/nova/db/sqlalchemy/session.py b/nova/db/sqlalchemy/session.py index c3876c02a..dc885f138 100644 --- a/nova/db/sqlalchemy/session.py +++ b/nova/db/sqlalchemy/session.py @@ -22,6 +22,7 @@ Session Handling for SQLAlchemy backend from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker +from nova import exception from nova import flags FLAGS = flags.FLAGS @@ -43,4 +44,6 @@ def get_session(autocommit=True, expire_on_commit=False): autocommit=autocommit, expire_on_commit=expire_on_commit)) session = _MAKER() + session.query = exception.wrap_db_error(session.query) + session.flush = exception.wrap_db_error(session.flush) return session diff --git a/nova/exception.py b/nova/exception.py index ecd814e5d..f36ffaee1 100644 --- a/nova/exception.py +++ b/nova/exception.py @@ -80,6 +80,24 @@ class TimeoutException(Error): pass +class DBError(Error): + """Wraps an implementation specific exception""" + def __init__(self, inner_exception): + self.inner_exception = inner_exception + super(DBError, self).__init__(str(inner_exception)) + + +def wrap_db_error(f): + def _wrap(*args, **kwargs): + try: + return f(*args, **kwargs) + except Exception, e: + LOG.exception(_('DB exception wrapped')) + raise DBError(e) + return _wrap + _wrap.func_name = f.func_name + + def wrap_exception(f): def _wrap(*args, **kw): try: -- cgit From 60f992b7fa1d1abf494cc210f7f199414a0538bb Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Fri, 21 Jan 2011 16:03:51 -0800 Subject: i18n! --- nova/api/ec2/cloud.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 766727b56..60e47fb87 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -536,7 +536,7 @@ class CloudController(object): volume = self.volume_api.get(context, internal_id) volumes.append(volume) except exception.NotFound: - raise exception.NotFound("Volume %s could not be found" + raise exception.NotFound(_("Volume %s not found") % ec2_id) else: volumes = self.volume_api.get_all(context) @@ -671,7 +671,7 @@ class CloudController(object): instance = self.compute_api.get(context, internal_id) instances.append(instance) except exception.NotFound: - raise exception.NotFound("Instance %s could not be found" + raise exception.NotFound(_("Instance %s not found") % ec2_id) else: instances = self.compute_api.get_all(context, **kwargs) -- cgit From a9ab2d0f0618f855686cb8713b28c3737faabdcc Mon Sep 17 00:00:00 2001 From: Rick Harris Date: Sat, 22 Jan 2011 21:20:09 +0000 Subject: Use Glance to relate machine image with kernel and ramdisk --- krm_mapping.json.sample | 3 --- nova/api/openstack/__init__.py | 3 --- nova/api/openstack/servers.py | 28 +++++++++++++++++----------- 3 files changed, 17 insertions(+), 17 deletions(-) delete mode 100644 krm_mapping.json.sample diff --git a/krm_mapping.json.sample b/krm_mapping.json.sample deleted file mode 100644 index 1ecfba635..000000000 --- a/krm_mapping.json.sample +++ /dev/null @@ -1,3 +0,0 @@ -{ - "machine" : ["kernel", "ramdisk"] -} diff --git a/nova/api/openstack/__init__.py b/nova/api/openstack/__init__.py index f2caac483..c70bb39ed 100644 --- a/nova/api/openstack/__init__.py +++ b/nova/api/openstack/__init__.py @@ -38,9 +38,6 @@ from nova.api.openstack import shared_ip_groups LOG = logging.getLogger('nova.api.openstack') FLAGS = flags.FLAGS -flags.DEFINE_string('os_krm_mapping_file', - 'krm_mapping.json', - 'Location of OpenStack Flavor/OS:EC2 Kernel/Ramdisk/Machine JSON file.') flags.DEFINE_bool('allow_admin_api', False, 'When True, this API service will accept admin operations.') diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 8cbcebed2..9d308ea24 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -124,17 +124,22 @@ class Controller(wsgi.Controller): return faults.Fault(exc.HTTPNotFound()) return exc.HTTPAccepted() - def _get_kernel_ramdisk_from_image(self, image_id): - mapping_filename = FLAGS.os_krm_mapping_file - - with open(mapping_filename) as f: - mapping = json.load(f) - if image_id in mapping: - return mapping[image_id] + def _get_kernel_ramdisk_from_image(self, req, image_id): + """ + Machine images are associated with Kernels and Ramdisk images via + metadata stored in Glance as 'image_properties' + """ + def lookup(param): + _image_id = image_id + try: + return image['properties'][param] + except KeyError: + raise exception.NotFound( + _("%(param)s property not found for image %(_image_id)s") % + locals()) - raise exception.NotFound( - _("No entry for image '%s' in mapping file '%s'") % - (image_id, mapping_filename)) + image = self._image_service.show(req.environ['nova.context'], image_id) + return lookup('kernel_id'), lookup('ramdisk_id') def create(self, req): """ Creates a new server for a given user """ @@ -146,7 +151,8 @@ class Controller(wsgi.Controller): req.environ['nova.context'])[0] image_id = common.get_image_id_from_image_hash(self._image_service, req.environ['nova.context'], env['server']['imageId']) - kernel_id, ramdisk_id = self._get_kernel_ramdisk_from_image(image_id) + kernel_id, ramdisk_id = self._get_kernel_ramdisk_from_image( + req, image_id) instances = self.compute_api.create( req.environ['nova.context'], instance_types.get_by_flavor_id(env['server']['flavorId']), -- cgit From 70d97f5ca927dbf26e2d2590e54acce036b6179e Mon Sep 17 00:00:00 2001 From: Ryan Lane Date: Mon, 24 Jan 2011 19:07:12 +0000 Subject: Changes __dn_to_uid to return the uid attribute from the user's object. --- nova/auth/ldapdriver.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nova/auth/ldapdriver.py b/nova/auth/ldapdriver.py index a6915ce03..db7b345d6 100644 --- a/nova/auth/ldapdriver.py +++ b/nova/auth/ldapdriver.py @@ -585,11 +585,11 @@ class LdapDriver(object): else: return None - @staticmethod - def __dn_to_uid(dn): + def __dn_to_uid(self,dn): """Convert user dn to uid""" - return dn.split(',')[0].split('=')[1] - + query = '(objectclass=novaUser)' + user = self.__find_object(dn,query) + return user[FLAGS.ldap_user_id_attribute][0] class FakeLdapDriver(LdapDriver): """Fake Ldap Auth driver""" -- cgit From 9ab4670464e65aaa10f1e032adda2c39b7ca1981 Mon Sep 17 00:00:00 2001 From: Ryan Lane Date: Mon, 24 Jan 2011 21:25:13 +0000 Subject: PEP8 fixes --- nova/auth/ldapdriver.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/nova/auth/ldapdriver.py b/nova/auth/ldapdriver.py index db7b345d6..4562c92ee 100644 --- a/nova/auth/ldapdriver.py +++ b/nova/auth/ldapdriver.py @@ -585,12 +585,13 @@ class LdapDriver(object): else: return None - def __dn_to_uid(self,dn): + def __dn_to_uid(self, dn): """Convert user dn to uid""" query = '(objectclass=novaUser)' - user = self.__find_object(dn,query) + user = self.__find_object(dn, query) return user[FLAGS.ldap_user_id_attribute][0] + class FakeLdapDriver(LdapDriver): """Fake Ldap Auth driver""" -- cgit From 6e7364cb00fd33e82d87aa2006be1b512ae35cc2 Mon Sep 17 00:00:00 2001 From: John Dewey Date: Mon, 24 Jan 2011 18:31:04 -0800 Subject: Updated a couple data structures to pass pep8. --- bin/nova-spoolsentry | 6 ++---- nova/tests/test_virt.py | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/bin/nova-spoolsentry b/bin/nova-spoolsentry index ab20268a9..325e92191 100644 --- a/bin/nova-spoolsentry +++ b/bin/nova-spoolsentry @@ -74,10 +74,8 @@ class SpoolSentry(object): return rv def send_data(self, data): - data = { - 'data': base64.b64encode(pickle.dumps(data).encode('zlib')), - 'key': self.key - } + data = {'data': base64.b64encode(pickle.dumps(data).encode('zlib')), + 'key': self.key} req = urllib2.Request(self.sentry_url) res = urllib2.urlopen(req, urllib.urlencode(data)) if res.getcode() != 200: diff --git a/nova/tests/test_virt.py b/nova/tests/test_virt.py index f6800e3d9..0b9b847a0 100644 --- a/nova/tests/test_virt.py +++ b/nova/tests/test_virt.py @@ -256,7 +256,7 @@ class IptablesFirewallTestCase(test.TestCase): ':FORWARD ACCEPT [0:0]', ':OUTPUT ACCEPT [349256:75777230]', 'COMMIT', - '# Completed on Tue Jan 18 23:47:56 2011' + '# Completed on Tue Jan 18 23:47:56 2011', ] def test_static_filters(self): -- cgit From c0514b68b03b4409fd553c08e4599ef153a2875d Mon Sep 17 00:00:00 2001 From: John Dewey Date: Mon, 24 Jan 2011 18:39:47 -0800 Subject: corrected nesting of the data dictionary --- bin/nova-spoolsentry | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/nova-spoolsentry b/bin/nova-spoolsentry index 325e92191..c53482852 100644 --- a/bin/nova-spoolsentry +++ b/bin/nova-spoolsentry @@ -75,7 +75,7 @@ class SpoolSentry(object): def send_data(self, data): data = {'data': base64.b64encode(pickle.dumps(data).encode('zlib')), - 'key': self.key} + 'key': self.key} req = urllib2.Request(self.sentry_url) res = urllib2.urlopen(req, urllib.urlencode(data)) if res.getcode() != 200: -- cgit From 87189b3952cdda465a9cbb3df433a3ecba1152db Mon Sep 17 00:00:00 2001 From: John Dewey Date: Mon, 24 Jan 2011 20:16:09 -0800 Subject: Added myself (John Dewey) to Authors. --- Authors | 1 + 1 file changed, 1 insertion(+) diff --git a/Authors b/Authors index 608fec523..4b227cc76 100644 --- a/Authors +++ b/Authors @@ -21,6 +21,7 @@ Jay Pipes Jesse Andrews Joe Heck Joel Moore +John Dewey Jonathan Bryce Josh Durgin Josh Kearney -- cgit From 722d6076ea3d6bcfc521e3f30c4be39645bbd8ab Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Tue, 25 Jan 2011 13:24:16 +0100 Subject: Set the default number of IP's to to reserver for VPN to 0. --- nova/network/manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/network/manager.py b/nova/network/manager.py index 5d7589090..c8be670ab 100644 --- a/nova/network/manager.py +++ b/nova/network/manager.py @@ -83,7 +83,7 @@ flags.DEFINE_string('floating_range', '4.4.4.0/24', 'Floating IP address block') flags.DEFINE_string('fixed_range', '10.0.0.0/8', 'Fixed IP address block') flags.DEFINE_string('fixed_range_v6', 'fd00::/48', 'Fixed IPv6 address block') -flags.DEFINE_integer('cnt_vpn_clients', 5, +flags.DEFINE_integer('cnt_vpn_clients', 0, 'Number of addresses reserved for vpn clients') flags.DEFINE_string('network_driver', 'nova.network.linux_net', 'Driver to use for network creation') -- cgit From e811667b1e08bdfd7647cc29f792441db2cfb752 Mon Sep 17 00:00:00 2001 From: Ilya Alekseyev Date: Tue, 25 Jan 2011 21:58:07 +0300 Subject: Added iptables rule to IptablesFirewallDriver like in Hisaharu Ishii patch with some workaround --- nova/virt/libvirt_conn.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 259e19a69..cb8528e96 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -1270,11 +1270,20 @@ class IptablesFirewallDriver(FirewallDriver): dhcp_server = self._dhcp_server_for_instance(instance) our_rules += ['-A %s -s %s -p udp --sport 67 --dport 68' % (chain_name, dhcp_server)] + #Allow project network traffic + if (FLAGS.allow_project_net_traffic): + cidr = self._project_cidr_for_instance(instance) + our_rules += ['-A %s -s %s -j ACCEPT' % (chain_name, cidr)] elif(ip_version == 6): # Allow RA responses ra_server = self._ra_server_for_instance(instance) our_rules += ['-A %s -s %s -p icmpv6' % (chain_name, ra_server)] + #Allow project network traffic + if (FLAGS.allow_project_net_traffic): + cidrv6 = self._project_cidrv6_for_instance(instance) + our_rules += ['-A %s -s %s -j ACCEPT' % + (chain_name, cidrv6)] # If nothing matches, jump to the fallback chain our_rules += ['-A %s -j nova-fallback' % (chain_name,)] @@ -1369,3 +1378,13 @@ class IptablesFirewallDriver(FirewallDriver): network = db.network_get_by_instance(context.get_admin_context(), instance['id']) return network['ra_server'] + + def _project_cidr_for_instance(self, instance): + network = db.network_get_by_instance(context.get_admin_context(), + instance['id']) + return network['cidr'] + + def _project_cidrv6_for_instance(self, instance): + network = db.network_get_by_instance(context.get_admin_context(), + instance['id']) + return network['cidr_v6'] \ No newline at end of file -- cgit From 7d66725e5a1e5438453aedcec809f8a25fae08d8 Mon Sep 17 00:00:00 2001 From: Tushar Patil Date: Tue, 25 Jan 2011 11:10:26 -0800 Subject: Fix for LP Bug #707554 --- nova/virt/libvirt_conn.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 259e19a69..d5db42543 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -1268,13 +1268,13 @@ class IptablesFirewallDriver(FirewallDriver): if(ip_version == 4): # Allow DHCP responses dhcp_server = self._dhcp_server_for_instance(instance) - our_rules += ['-A %s -s %s -p udp --sport 67 --dport 68' % - (chain_name, dhcp_server)] + our_rules += ['-A %s -s %s -p udp --sport 67 --dport 68 ' + '-j ACCEPT' % (chain_name, dhcp_server)] elif(ip_version == 6): # Allow RA responses ra_server = self._ra_server_for_instance(instance) - our_rules += ['-A %s -s %s -p icmpv6' % - (chain_name, ra_server)] + our_rules += ['-A %s -s %s -p icmpv6 ' + '-j ACCEPT' % (chain_name, ra_server)] # If nothing matches, jump to the fallback chain our_rules += ['-A %s -j nova-fallback' % (chain_name,)] -- cgit From 83213922360b68f3a1c26c6b0a319a21f390ffb7 Mon Sep 17 00:00:00 2001 From: Tushar Patil Date: Tue, 25 Jan 2011 11:46:24 -0800 Subject: updated authors since build is failing --- Authors | 1 + 1 file changed, 1 insertion(+) diff --git a/Authors b/Authors index 608fec523..33895be74 100644 --- a/Authors +++ b/Authors @@ -49,6 +49,7 @@ Soren Hansen Thierry Carrez Todd Willey Trey Morris +Tushar Patil Vishvananda Ishaya Youcef Laribi Zhixue Wu -- cgit From f51526b596f3d89cda2ec4501e19baf085c534e0 Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Tue, 25 Jan 2011 20:49:29 +0100 Subject: Add a host argument to virt driver's init_host method. It will be set to the name of host it's running on. Make libvirt's init_host method go and look at what virtual machines are running when the compute worker starts up. This ensures firewalls are set up correctly for existing VM's. It also enables easier rolling upgrades. --- nova/compute/manager.py | 2 +- nova/db/api.py | 5 +++++ nova/db/sqlalchemy/api.py | 11 +++++++++++ nova/virt/fake.py | 5 +++-- nova/virt/hyperv.py | 2 +- nova/virt/libvirt_conn.py | 27 +++++++++++++++++++++++++-- nova/virt/xenapi_conn.py | 2 +- 7 files changed, 47 insertions(+), 7 deletions(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 6f09ce674..5ebf3f08d 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -118,7 +118,7 @@ class ComputeManager(manager.Manager): """Do any initialization that needs to be run if this is a standalone service. """ - self.driver.init_host() + self.driver.init_host(host=self.host) def _update_state(self, context, instance_id): """Update the state of an instance from the driver info.""" diff --git a/nova/db/api.py b/nova/db/api.py index f9d561587..da1e3d1f2 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -351,6 +351,11 @@ def instance_get_all_by_project(context, project_id): return IMPL.instance_get_all_by_project(context, project_id) +def instance_get_all_by_host(context, host): + """Get all instance belonging to a host.""" + return IMPL.instance_get_all_by_host(context, host) + + def instance_get_all_by_reservation(context, reservation_id): """Get all instance belonging to a reservation.""" return IMPL.instance_get_all_by_reservation(context, reservation_id) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 7b965f672..5404ac77e 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -723,6 +723,17 @@ def instance_get_all_by_user(context, user_id): all() +@require_admin_context +def instance_get_all_by_host(context, host): + session = get_session() + return session.query(models.Instance).\ + options(joinedload_all('fixed_ip.floating_ips')).\ + options(joinedload('security_groups')).\ + filter_by(host=host).\ + filter_by(deleted=can_read_deleted(context)).\ + all() + + @require_context def instance_get_all_by_project(context, project_id): authorize_project_context(context, project_id) diff --git a/nova/virt/fake.py b/nova/virt/fake.py index f8b3c7807..161445b86 100644 --- a/nova/virt/fake.py +++ b/nova/virt/fake.py @@ -76,9 +76,10 @@ class FakeConnection(object): cls._instance = cls() return cls._instance - def init_host(self): + def init_host(self, host): """ - Initialize anything that is necessary for the driver to function + Initialize anything that is necessary for the driver to function, + including catching up with currently running VM's on the given host. """ return diff --git a/nova/virt/hyperv.py b/nova/virt/hyperv.py index 30dc1c79b..cb52e1ade 100644 --- a/nova/virt/hyperv.py +++ b/nova/virt/hyperv.py @@ -113,7 +113,7 @@ class HyperVConnection(object): self._conn = wmi.WMI(moniker='//./root/virtualization') self._cim_conn = wmi.WMI(moniker='//./root/cimv2') - def init_host(self): + def init_host(self, host): #FIXME(chiradeep): implement this LOG.debug(_('In init host')) pass diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index d8c1bf48a..5808d273a 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -157,8 +157,31 @@ class LibvirtConnection(object): else: self.firewall_driver = utils.import_object(FLAGS.firewall_driver) - def init_host(self): - pass + def init_host(self, host): + # Adopt existing VM's running here + ctxt = context.get_admin_context() + for instance in db.instance_get_all_by_host(ctxt, host): + try: + LOG.debug(_('Checking state of %s'), instance['name']) + state = self.get_info(instance['name'])['state'] + except exception.NotFound: + state = power_state.SHUTOFF + + LOG.debug(_('Current state of %(name)s was %(state)s.'), + {'name': instance['name'], 'state': state}) + db.instance_set_state(ctxt, instance['id'], state) + + if state == power_state.SHUTOFF: + # TODO(soren): This is what the compute manager does when you + # terminate # an instance. At some point I figure we'll have a + # "terminated" state and some sort of cleanup job that runs + # occasionally, cleaning them out. + db.instance_destroy(ctxt, instance['id']) + + if state != power_state.RUNNING: + continue + self.firewall_driver.prepare_instance_filter(instance) + self.firewall_driver.apply_instance_filter(instance) def _get_connection(self): if not self._wrapped_conn or not self._test_connection(): diff --git a/nova/virt/xenapi_conn.py b/nova/virt/xenapi_conn.py index 927f5905b..acf89f0c1 100644 --- a/nova/virt/xenapi_conn.py +++ b/nova/virt/xenapi_conn.py @@ -141,7 +141,7 @@ class XenAPIConnection(object): self._vmops = VMOps(session) self._volumeops = VolumeOps(session) - def init_host(self): + def init_host(self, host): #FIXME(armando): implement this #NOTE(armando): would we need a method #to call when shutting down the host? -- cgit From 588bf6717a11930435ad3b3aa1941cff8495e2b5 Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Tue, 25 Jan 2011 21:19:34 +0100 Subject: Fix pep-8 problem from prereq branch. --- nova/virt/libvirt_conn.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index d5db42543..37eb02e4f 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -1269,12 +1269,12 @@ class IptablesFirewallDriver(FirewallDriver): # Allow DHCP responses dhcp_server = self._dhcp_server_for_instance(instance) our_rules += ['-A %s -s %s -p udp --sport 67 --dport 68 ' - '-j ACCEPT' % (chain_name, dhcp_server)] + '-j ACCEPT' % (chain_name, dhcp_server)] elif(ip_version == 6): # Allow RA responses ra_server = self._ra_server_for_instance(instance) our_rules += ['-A %s -s %s -p icmpv6 ' - '-j ACCEPT' % (chain_name, ra_server)] + '-j ACCEPT' % (chain_name, ra_server)] # If nothing matches, jump to the fallback chain our_rules += ['-A %s -j nova-fallback' % (chain_name,)] -- cgit From e44b28a0daa771c67fa8672f89f7d52ee1bfec22 Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Tue, 25 Jan 2011 21:20:42 +0100 Subject: Perform same filtering for OUTPUT as FORWARD in iptables. This removes a way around the filtering. --- nova/virt/libvirt_conn.py | 1 + 1 file changed, 1 insertion(+) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 37eb02e4f..ac7fd8ef0 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -1228,6 +1228,7 @@ class IptablesFirewallDriver(FirewallDriver): our_chains += [':nova-local - [0:0]'] our_rules += ['-A FORWARD -j nova-local'] + our_rules += ['-A OUTPUT -j nova-local'] security_groups = {} # Add our chains -- cgit From 1b259ba6ac7401d99eff2ded3100c73f3048728e Mon Sep 17 00:00:00 2001 From: Tushar Patil Date: Tue, 25 Jan 2011 12:38:20 -0800 Subject: Fixed pep8 errors --- nova/virt/libvirt_conn.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index d5db42543..548d82ba9 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -1269,12 +1269,12 @@ class IptablesFirewallDriver(FirewallDriver): # Allow DHCP responses dhcp_server = self._dhcp_server_for_instance(instance) our_rules += ['-A %s -s %s -p udp --sport 67 --dport 68 ' - '-j ACCEPT' % (chain_name, dhcp_server)] + '-j ACCEPT ' % (chain_name, dhcp_server)] elif(ip_version == 6): # Allow RA responses ra_server = self._ra_server_for_instance(instance) our_rules += ['-A %s -s %s -p icmpv6 ' - '-j ACCEPT' % (chain_name, ra_server)] + '-j ACCEPT' % (chain_name, ra_server)] # If nothing matches, jump to the fallback chain our_rules += ['-A %s -j nova-fallback' % (chain_name,)] -- cgit From 50d845e717b3e9ceb650fb5058d44ed4fc1507ca Mon Sep 17 00:00:00 2001 From: Tushar Patil Date: Tue, 25 Jan 2011 12:50:54 -0800 Subject: Fixed pep8 errors --- nova/api/ec2/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/api/ec2/__init__.py b/nova/api/ec2/__init__.py index 3656bb44b..bb060ec8b 100644 --- a/nova/api/ec2/__init__.py +++ b/nova/api/ec2/__init__.py @@ -344,7 +344,7 @@ class Executor(wsgi.Application): '%s' '%s' % (utils.utf8(code), utils.utf8(message), - utils.utf8(context.request_id))) + utils.utf8(context.request_id))) return resp -- cgit From 7a57a10a6a12302915ebbac0744833e365d7961b Mon Sep 17 00:00:00 2001 From: Ryan Lane Date: Tue, 25 Jan 2011 20:51:57 +0000 Subject: Adds driver.init_host() call to flatdhcp driver --- nova/network/manager.py | 1 + 1 file changed, 1 insertion(+) diff --git a/nova/network/manager.py b/nova/network/manager.py index dd429d122..7bc41b577 100644 --- a/nova/network/manager.py +++ b/nova/network/manager.py @@ -396,6 +396,7 @@ class FlatDHCPManager(FlatManager): """ super(FlatDHCPManager, self).init_host() self.driver.metadata_forward() + self.driver.init_host() def setup_compute_network(self, context, instance_id): """Sets up matching network for compute hosts.""" -- cgit From 0d247586e708078e590913d1e36e4b2afa70d750 Mon Sep 17 00:00:00 2001 From: Ilya Alekseyev Date: Wed, 26 Jan 2011 01:02:34 +0300 Subject: Trunk merged --- nova/virt/libvirt_conn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index ee4b6f563..e975db90f 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -1387,4 +1387,4 @@ class IptablesFirewallDriver(FirewallDriver): def _project_cidrv6_for_instance(self, instance): network = db.network_get_by_instance(context.get_admin_context(), instance['id']) - return network['cidr_v6'] \ No newline at end of file + return network['cidr_v6'] -- cgit From 7f04601100c06140445705ee74418907d9b27c0f Mon Sep 17 00:00:00 2001 From: Tushar Patil Date: Tue, 25 Jan 2011 14:50:04 -0800 Subject: Limit all lines to a maximum of 79 characters --- nova/api/ec2/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nova/api/ec2/__init__.py b/nova/api/ec2/__init__.py index bb060ec8b..f661493b1 100644 --- a/nova/api/ec2/__init__.py +++ b/nova/api/ec2/__init__.py @@ -313,7 +313,8 @@ class Executor(wsgi.Application): LOG.info(_('NotFound raised: %s'), ex.args[0], context=context) return self._error(req, context, type(ex).__name__, ex.args[0]) except exception.ApiError as ex: - LOG.exception(_('ApiError raised: %s'), ex.args[0], context=context) + LOG.exception(_('ApiError raised: %s'), ex.args[0], + context=context) if ex.code: return self._error(req, context, ex.code, ex.args[0]) else: -- cgit From 2155505ca082c644e7b4f373d8fae3e157a451bb Mon Sep 17 00:00:00 2001 From: Ryan Lane Date: Tue, 25 Jan 2011 22:53:09 +0000 Subject: Moving init_host before metadata_forward, as metadata_forward modifies prerouting rules --- nova/network/manager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nova/network/manager.py b/nova/network/manager.py index 7bc41b577..fe99f2612 100644 --- a/nova/network/manager.py +++ b/nova/network/manager.py @@ -395,8 +395,8 @@ class FlatDHCPManager(FlatManager): standalone service. """ super(FlatDHCPManager, self).init_host() - self.driver.metadata_forward() self.driver.init_host() + self.driver.metadata_forward() def setup_compute_network(self, context, instance_id): """Sets up matching network for compute hosts.""" @@ -461,8 +461,8 @@ class VlanManager(NetworkManager): standalone service. """ super(VlanManager, self).init_host() - self.driver.metadata_forward() self.driver.init_host() + self.driver.metadata_forward() def allocate_fixed_ip(self, context, instance_id, *args, **kwargs): """Gets a fixed ip from the pool.""" -- cgit From 12952feab2fdcf0fe705114404c303cbb0f7c0d1 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 25 Jan 2011 15:29:30 -0800 Subject: fix pep8 issue (and my commit hook that didn't catch it) --- bin/nova-manage | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/nova-manage b/bin/nova-manage index 4f3cfc50c..1b70ebf17 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -274,6 +274,7 @@ def _db_error(caught_exception): "nova-manage sync db before running this command.") exit(1) + class UserCommands(object): """Class for managing users.""" -- cgit From ccb5e573f7a3f85a2b591d3a1fb968003e321b28 Mon Sep 17 00:00:00 2001 From: Tushar Patil Date: Tue, 25 Jan 2011 15:53:43 -0800 Subject: Fixed pep8 errors --- nova/api/ec2/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/api/ec2/__init__.py b/nova/api/ec2/__init__.py index f661493b1..79f5af897 100644 --- a/nova/api/ec2/__init__.py +++ b/nova/api/ec2/__init__.py @@ -313,7 +313,7 @@ class Executor(wsgi.Application): LOG.info(_('NotFound raised: %s'), ex.args[0], context=context) return self._error(req, context, type(ex).__name__, ex.args[0]) except exception.ApiError as ex: - LOG.exception(_('ApiError raised: %s'), ex.args[0], + LOG.exception(_('ApiError raised: %s'), ex.args[0], context=context) if ex.code: return self._error(req, context, ex.code, ex.args[0]) -- cgit From 687886beeb7519e79b792ff6c42eaab75e664336 Mon Sep 17 00:00:00 2001 From: Todd Willey Date: Tue, 25 Jan 2011 16:40:23 -0800 Subject: Add DescribeInstanceTypes to admin api (dashboard uses it). --- nova/adminclient.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ nova/api/ec2/admin.py | 13 +++++++++++++ 2 files changed, 57 insertions(+) diff --git a/nova/adminclient.py b/nova/adminclient.py index b2609c8c4..3cdd8347f 100644 --- a/nova/adminclient.py +++ b/nova/adminclient.py @@ -190,6 +190,45 @@ class HostInfo(object): setattr(self, name, value) +class InstanceType(object): + """ + Information about a Nova instance type, as parsed through SAX. + + **Fields include** + + * name + * vcpus + * disk_gb + * memory_mb + * flavor_id + + """ + + def __init__(self, connection=None): + self.connection = connection + self.name = None + self.vcpus = None + self.disk_gb = None + self.memory_mb = None + self.flavor_id = None + + def __repr__(self): + return 'InstanceType:%s' % self.name + + def startElement(self, name, attrs, connection): + return None + + def endElement(self, name, value, connection): + if name == "memoryMb": + self.memory_mb = str(value) + elif name == "flavorId": + self.flavor_id = str(value) + elif name == "diskGb": + self.disk_gb = str(value) + else: + setattr(self, name, str(value)) + + class NovaAdminClient(object): def __init__( @@ -373,3 +412,8 @@ class NovaAdminClient(object): def get_hosts(self): return self.apiconn.get_list('DescribeHosts', {}, [('item', HostInfo)]) + + def get_instance_types(self): + """Grabs the list of all users.""" + return self.apiconn.get_list('DescribeInstanceTypes', {}, + [('item', InstanceType)]) diff --git a/nova/api/ec2/admin.py b/nova/api/ec2/admin.py index 78ff1b3e0..d7e899d12 100644 --- a/nova/api/ec2/admin.py +++ b/nova/api/ec2/admin.py @@ -26,6 +26,7 @@ from nova import db from nova import exception from nova import log as logging from nova.auth import manager +from nova.compute import instance_types LOG = logging.getLogger('nova.api.ec2.admin') @@ -62,6 +63,14 @@ def host_dict(host): return {} +def instance_dict(name, inst): + return {'name': name, + 'memory_mb': inst['memory_mb'], + 'vcpus': inst['vcpus'], + 'disk_gb': inst['local_gb'], + 'flavor_id': inst['flavorid']} + + class AdminController(object): """ API Controller for users, hosts, nodes, and workers. @@ -70,6 +79,10 @@ class AdminController(object): def __str__(self): return 'AdminController' + def describe_instance_types(self, _context, **_kwargs): + return {'instanceTypeSet': [instance_dict(n, v) for n, v in + instance_types.INSTANCE_TYPES.iteritems()]} + def describe_user(self, _context, name, **_kwargs): """Returns user data, including access and secret keys.""" return user_dict(manager.AuthManager().get_user(name)) -- cgit