diff --git a/.gitignore b/.gitignore index 1a8ae70163..60600168a3 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ vagrant/ reddwarf_test.sqlite .venv run_tests.log +guest-agent-files.txt diff --git a/development/bootstrap/bootstrap.sh b/development/bootstrap/bootstrap.sh old mode 100644 new mode 100755 index 8e8ab8f3bb..17b4ba88d6 --- a/development/bootstrap/bootstrap.sh +++ b/development/bootstrap/bootstrap.sh @@ -1,18 +1,49 @@ +EXPECTED_ARGS=1 +if [ $# -ne $EXPECTED_ARGS ] +then + echo "Usage: `basename $0` REDDWARF_TOKEN" + exit 65 +fi + # Be sure to pass in the token for glance auth REDDWARF_TOKEN=$1 +# # This takes about ~12 minutes to finish sudo apt-get install kvm-pxe -VM_PATH=oneiric_mysql_image +VM_PATH=~/oneiric_mysql_image UBUNTU_DISTRO="ubuntu 11.10" UBUNTU_DISTRO_NAME=oneiric +USERNAME=reddwarf rm -fr $VM_PATH +# Create the guest with the specific files +# Assuming this is run from development/bootstrap/bootstrap.sh +COPY_FILE=guest-agent-files.txt +rm -fr $COPY_FILE +# These will be the way the firstboot script phones home to get the latest guest via scp. +# See bootstrap_init.sh for more info on what it does +echo "$HOME/.ssh/id_rsa.pub /home/$USERNAME/.ssh/id_rsa.pub" >> $COPY_FILE +echo "$HOME/.ssh/id_rsa /home/$USERNAME/.ssh/id_rsa" >> $COPY_FILE + +# Now put the pub key in this machines auth keys so the vm can log in to the host (scp) +# TODO(hub-cap): make this better using a ssh command or checking for existence +cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys + #build a qemu image sudo ubuntu-vm-builder qemu $UBUNTU_DISTRO_NAME --addpkg vim \ - --addpkg mysql-server --addpkg openssh-server --addpkg kvm-pxe \ - --user reddwarf --pass reddwarf -d $VM_PATH + --addpkg mysql-server --addpkg openssh-server \ + --copy $COPY_FILE --user $USERNAME --pass $USERNAME \ + --firstboot `pwd`/bootstrap_init.sh -d $VM_PATH QCOW_IMAGE=`find $VM_PATH -name '*.qcow2'` -glance add name="lucid_mysql_image" is_public=true \ + +function get_id () { + echo `$@ | awk '{print $6}'` +} + +GLANCE_IMAGEID=`get_id glance add name="${UBUNTU_DISTRO_NAME}_mysql_image" is_public=true \ container_format=ovf disk_format=qcow2 \ - distro="$UBUNTU_DISTRO" -A $REDDWARF_TOKEN < $QCOW_IMAGE + distro='"$UBUNTU_DISTRO"' -A $REDDWARF_TOKEN < $QCOW_IMAGE` + +echo "Run this query in your db" +echo "update service_images set image_id = '$GLANCE_IMAGEID';" \ No newline at end of file diff --git a/development/bootstrap/bootstrap_init.sh b/development/bootstrap/bootstrap_init.sh new file mode 100644 index 0000000000..d5cda29951 --- /dev/null +++ b/development/bootstrap/bootstrap_init.sh @@ -0,0 +1,9 @@ +### THINGS TO NOTE +# Make sure the host code is in /src +# Make sure the username is the same as the vm/host +# ** Assuming the username is reddwarf +# Make sure the host/vm bridge is at 10.0.0.1, which is the default devstack bridge +PATH_TO_HOST=/src/reddwarf + +sudo -u reddwarf scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -r 10.0.0.1:${PATH_TO_HOST}/guest-agent ~reddwarf +python ~reddwarf/guest-agent/agent.py \ No newline at end of file diff --git a/development/development_enviroment.sh b/development/development_enviroment.sh index 3fffdb1fa5..b09d14a672 100644 --- a/development/development_enviroment.sh +++ b/development/development_enviroment.sh @@ -37,7 +37,9 @@ curl -d '{"auth":{"passwordCredentials":{"username": "reddwarf", "password": "RE # now get a list of instances, which connects over python-novaclient to nova # NOTE THIS AUTH TOKEN NEEDS TO BE CHANGED # Also note that keystone uses the tenant id now and _not_ the name -# curl -H'X-Auth-Token:AUTH_TOKEN' http://0.0.0.0:8779/v0.1/$REDDWARF_TENANT/instances +# curl -H"X-Auth-Token:$REDDWARF_TOKEN" http://0.0.0.0:8779/v0.1/$REDDWARF_TENANT/instances +# curl -H"Content-type:application/json" -H"X-Auth-Token:$REDDWARF_TOKEN" \ +# http://0.0.0.0:8779/v0.1/$REDDWARF_TENANT/instances -d '{"name":"my_test","flavor":"1"}' # Also, you should start up the api node like this # bin/reddwarf-server --config-file=etc/reddwarf/reddwarf.conf.sample diff --git a/reddwarf/database/models.py b/reddwarf/database/models.py index e918a3b8e9..1bd5affa38 100644 --- a/reddwarf/database/models.py +++ b/reddwarf/database/models.py @@ -98,7 +98,6 @@ class RemoteModelBase(ModelBase): else: return self.data_item(self._data_object) - class Instance(RemoteModelBase): _data_fields = ['name', 'status', 'updated', 'id', 'flavor'] @@ -106,6 +105,9 @@ class Instance(RemoteModelBase): def __init__(self, proxy_token, uuid): self._data_object = self.get_client(proxy_token).servers.get(uuid) + @classmethod + def delete(cls, proxy_token, uuid): + return cls.get_client(proxy_token).servers.delete(uuid) class Instances(Instance): diff --git a/reddwarf/database/service.py b/reddwarf/database/service.py index f56825e20c..64fde4d795 100644 --- a/reddwarf/database/service.py +++ b/reddwarf/database/service.py @@ -57,12 +57,26 @@ class InstanceController(BaseController): server = models.Instance(req.headers["X-Auth-Token"], id).data() return wsgi.Result(views.InstanceView(server).data(), 201) + def delete(self, req, tenant_id, id): + """Delete a single instance.""" + result = models.Instance.delete(req.headers["X-Auth-Token"], id) + # TODO(hub-cap): fixgure out why the result is coming back as None + LOG.info("result of delete %s" % result) + return wsgi.Result(202) + def create(self, req, body, tenant_id): # find the service id (cant be done yet at startup due to inconsitencies w/ the load app paste # TODO(hub-cap): figure out how to get this to work in __init__ time + # TODO(hub-cap): The problem with this in __init__ is that the paste config + # is generated w/ the same config file as the db flags that are needed + # for init. These need to be split so the db can be init'd w/o the paste + # stuff. Since the paste stuff inits the database.service module, it + # is a chicken before the egg problem. Simple refactor will fix it and + # we can move this into the __init__ code. Or maybe we shouldnt due to + # the nature of changing images. This needs discussion. image_id = models.ServiceImage.find_by(service_name="database")['image_id'] server = self.get_client(req).servers.create(body['name'], image_id, body['flavor']) - LOG.info(server) + # Now wait for the response from the create to do additional work return "server created %s" % server.__dict__ diff --git a/reddwarf/db/sqlalchemy/migrate_repo/versions/002_service_images.py b/reddwarf/db/sqlalchemy/migrate_repo/versions/002_service_images.py new file mode 100644 index 0000000000..5e395bff25 --- /dev/null +++ b/reddwarf/db/sqlalchemy/migrate_repo/versions/002_service_images.py @@ -0,0 +1,48 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 OpenStack LLC. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from sqlalchemy import ForeignKey +from sqlalchemy.schema import Column +from sqlalchemy.schema import MetaData +from sqlalchemy.schema import UniqueConstraint + +from reddwarf.db.sqlalchemy.migrate_repo.schema import Boolean +from reddwarf.db.sqlalchemy.migrate_repo.schema import create_tables +from reddwarf.db.sqlalchemy.migrate_repo.schema import DateTime +from reddwarf.db.sqlalchemy.migrate_repo.schema import drop_tables +from reddwarf.db.sqlalchemy.migrate_repo.schema import Integer +from reddwarf.db.sqlalchemy.migrate_repo.schema import BigInteger +from reddwarf.db.sqlalchemy.migrate_repo.schema import String +from reddwarf.db.sqlalchemy.migrate_repo.schema import Table + + +meta = MetaData() + +service_images = Table('service_images', meta, + Column('id', String(36), primary_key=True, nullable=False), + Column('service_name', String(255)), + Column('image_id', String(255))) + + +def upgrade(migrate_engine): + meta.bind = migrate_engine + create_tables([service_images,]) + + +def downgrade(migrate_engine): + meta.bind = migrate_engine + drop_tables([service_images,]) diff --git a/reddwarf/guest-agent/__init__.py b/reddwarf/guest-agent/__init__.py new file mode 100644 index 0000000000..d65c689a83 --- /dev/null +++ b/reddwarf/guest-agent/__init__.py @@ -0,0 +1,16 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 OpenStack LLC. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. diff --git a/reddwarf/guest-agent/agent.py b/reddwarf/guest-agent/agent.py new file mode 100644 index 0000000000..a34cd64126 --- /dev/null +++ b/reddwarf/guest-agent/agent.py @@ -0,0 +1,20 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 OpenStack LLC. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import subprocess +print "This is only a test!" +subprocess.call(["touch", "FOO.txt"])