Fleshed out the basics for the guest-agent scp firstboot.

* Copying ssh keys from the host to the image
* Added a bootstrap_init.sh which does the scp work to the instance
* Finished the bootstrap.sh so it will upload to glance
* Added a service images table for identifing the current image on create
* Added some dummy guest-agent code for testing purposes
* Added a delete method, which is not finished
This commit is contained in:
Michael Basnight 2012-03-04 15:52:29 -06:00
parent 2e56dc4d69
commit caedfab456
9 changed files with 151 additions and 8 deletions

1
.gitignore vendored
View File

@ -4,3 +4,4 @@ vagrant/
reddwarf_test.sqlite
.venv
run_tests.log
guest-agent-files.txt

41
development/bootstrap/bootstrap.sh Normal file → Executable file
View File

@ -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';"

View File

@ -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

View File

@ -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

View File

@ -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):

View File

@ -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__

View File

@ -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,])

View File

@ -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.

View File

@ -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"])