You are viewing a plain text version of this content. The canonical link for it is here.
Posted to tashi-commits@incubator.apache.org by mr...@apache.org on 2008/11/03 14:45:27 UTC
svn commit: r710072 [1/3] - in /incubator/tashi/import: ./ tashi-intel-r399/
tashi-intel-r399/doc/ tashi-intel-r399/etc/ tashi-intel-r399/guest/
tashi-intel-r399/scripts/ tashi-intel-r399/src/ tashi-intel-r399/src/tashi/
tashi-intel-r399/src/tashi/agen...
Author: mryan3
Date: Mon Nov 3 06:45:25 2008
New Revision: 710072
URL: http://svn.apache.org/viewvc?rev=710072&view=rev
Log:
This is the initial import of Tashi into the repository.
I'm keeping it in this import folder until repository organization and other administrative matters are dealt with.
Added:
incubator/tashi/import/
incubator/tashi/import/tashi-intel-r399/
incubator/tashi/import/tashi-intel-r399/.project
incubator/tashi/import/tashi-intel-r399/.pydevproject
incubator/tashi/import/tashi-intel-r399/Makefile
incubator/tashi/import/tashi-intel-r399/README
incubator/tashi/import/tashi-intel-r399/STYLE
incubator/tashi/import/tashi-intel-r399/TODO
incubator/tashi/import/tashi-intel-r399/doc/
incubator/tashi/import/tashi-intel-r399/etc/
incubator/tashi/import/tashi-intel-r399/etc/TashiDefaults.cfg
incubator/tashi/import/tashi-intel-r399/etc/TestConfig.cfg
incubator/tashi/import/tashi-intel-r399/guest/
incubator/tashi/import/tashi-intel-r399/guest/tashi (with props)
incubator/tashi/import/tashi-intel-r399/scripts/
incubator/tashi/import/tashi-intel-r399/scripts/create (with props)
incubator/tashi/import/tashi-intel-r399/scripts/demo-yahoo-08-14-08 (with props)
incubator/tashi/import/tashi-intel-r399/scripts/mryan3-database-setup (with props)
incubator/tashi/import/tashi-intel-r399/scripts/resume (with props)
incubator/tashi/import/tashi-intel-r399/scripts/stress (with props)
incubator/tashi/import/tashi-intel-r399/scripts/tomer-database-setup (with props)
incubator/tashi/import/tashi-intel-r399/src/
incubator/tashi/import/tashi-intel-r399/src/tashi/
incubator/tashi/import/tashi-intel-r399/src/tashi/__init__.py
incubator/tashi/import/tashi-intel-r399/src/tashi/agents/
incubator/tashi/import/tashi-intel-r399/src/tashi/agents/__init__.py
incubator/tashi/import/tashi-intel-r399/src/tashi/agents/examplepolicy.py
incubator/tashi/import/tashi-intel-r399/src/tashi/client/
incubator/tashi/import/tashi-intel-r399/src/tashi/client/__init__.py
incubator/tashi/import/tashi-intel-r399/src/tashi/client/client.py (with props)
incubator/tashi/import/tashi-intel-r399/src/tashi/client/test.py
incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/
incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/__init__.py
incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/clustermanager.py (with props)
incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/clustermanagerservice.py
incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/data/
incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/data/__init__.py
incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/data/datainterface.py
incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/data/fromconfig.py
incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/data/pickled.py
incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/data/sql.py
incubator/tashi/import/tashi-intel-r399/src/tashi/connectionmanager.py
incubator/tashi/import/tashi-intel-r399/src/tashi/dfs/
incubator/tashi/import/tashi-intel-r399/src/tashi/dfs/__init__.py
incubator/tashi/import/tashi-intel-r399/src/tashi/dfs/dfsinterface.py
incubator/tashi/import/tashi-intel-r399/src/tashi/dfs/vfs.py
incubator/tashi/import/tashi-intel-r399/src/tashi/messaging/
incubator/tashi/import/tashi-intel-r399/src/tashi/messaging/__init__.py
incubator/tashi/import/tashi-intel-r399/src/tashi/messaging/messageBroker.py
incubator/tashi/import/tashi-intel-r399/src/tashi/messaging/messaging.py
incubator/tashi/import/tashi-intel-r399/src/tashi/messaging/soapmessaging.py (with props)
incubator/tashi/import/tashi-intel-r399/src/tashi/messaging/tashimessaging.py
incubator/tashi/import/tashi-intel-r399/src/tashi/messaging/threadpool.py
incubator/tashi/import/tashi-intel-r399/src/tashi/messaging/thriftmessaging.py (with props)
incubator/tashi/import/tashi-intel-r399/src/tashi/nodemanager/
incubator/tashi/import/tashi-intel-r399/src/tashi/nodemanager/__init__.py
incubator/tashi/import/tashi-intel-r399/src/tashi/nodemanager/nodemanager.py (with props)
incubator/tashi/import/tashi-intel-r399/src/tashi/nodemanager/nodemanagerservice.py (with props)
incubator/tashi/import/tashi-intel-r399/src/tashi/nodemanager/notification.py
incubator/tashi/import/tashi-intel-r399/src/tashi/nodemanager/vmcontrol/
incubator/tashi/import/tashi-intel-r399/src/tashi/nodemanager/vmcontrol/__init__.py
incubator/tashi/import/tashi-intel-r399/src/tashi/nodemanager/vmcontrol/newxen.py
incubator/tashi/import/tashi-intel-r399/src/tashi/nodemanager/vmcontrol/qemu.py
incubator/tashi/import/tashi-intel-r399/src/tashi/nodemanager/vmcontrol/vmcontrolinterface.py
incubator/tashi/import/tashi-intel-r399/src/tashi/nodemanager/vmcontrol/xenpv.py
incubator/tashi/import/tashi-intel-r399/src/tashi/parallel.py
incubator/tashi/import/tashi-intel-r399/src/tashi/thrift/
incubator/tashi/import/tashi-intel-r399/src/tashi/thrift/build.py (with props)
incubator/tashi/import/tashi-intel-r399/src/tashi/thrift/messagingthrift.thrift
incubator/tashi/import/tashi-intel-r399/src/tashi/thrift/services.thrift
incubator/tashi/import/tashi-intel-r399/src/tashi/util.py
incubator/tashi/import/tashi-intel-r399/src/utils/
incubator/tashi/import/tashi-intel-r399/src/utils/Makefile
incubator/tashi/import/tashi-intel-r399/src/utils/nmd.c
incubator/tashi/import/tashi-intel-r399/svn-pull
incubator/tashi/import/tashi-intel-r399/test/
incubator/tashi/import/tashi-intel-r399/test/clustermanager-rpc-data-management/
incubator/tashi/import/tashi-intel-r399/test/clustermanager-rpc-data-management/test
incubator/tashi/import/tashi-intel-r399/test/runall (with props)
Added: incubator/tashi/import/tashi-intel-r399/.project
URL: http://svn.apache.org/viewvc/incubator/tashi/import/tashi-intel-r399/.project?rev=710072&view=auto
==============================================================================
--- incubator/tashi/import/tashi-intel-r399/.project (added)
+++ incubator/tashi/import/tashi-intel-r399/.project Mon Nov 3 06:45:25 2008
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>tashi</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.python.pydev.PyDevBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.python.pydev.pythonNature</nature>
+ </natures>
+</projectDescription>
Added: incubator/tashi/import/tashi-intel-r399/.pydevproject
URL: http://svn.apache.org/viewvc/incubator/tashi/import/tashi-intel-r399/.pydevproject?rev=710072&view=auto
==============================================================================
--- incubator/tashi/import/tashi-intel-r399/.pydevproject (added)
+++ incubator/tashi/import/tashi-intel-r399/.pydevproject Mon Nov 3 06:45:25 2008
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?eclipse-pydev version="1.0"?>
+
+<pydev_project>
+<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.5</pydev_property>
+</pydev_project>
Added: incubator/tashi/import/tashi-intel-r399/Makefile
URL: http://svn.apache.org/viewvc/incubator/tashi/import/tashi-intel-r399/Makefile?rev=710072&view=auto
==============================================================================
--- incubator/tashi/import/tashi-intel-r399/Makefile (added)
+++ incubator/tashi/import/tashi-intel-r399/Makefile Mon Nov 3 06:45:25 2008
@@ -0,0 +1,69 @@
+# This Makefile doesn't build a binary, but sets up this folder after a fresh checkout
+
+# Setup
+.SILENT:
+
+# Explicit builds
+all: src/tashi/services bin src/utils/nmd
+ @echo Done
+
+mryan3: src/tashi/services bin src/utils/nmd src/tags doc/html
+ @echo Done
+
+doc: rmdoc doc/html
+ @echo Done
+
+clean: rmnmd rmbin rmtags rmservices rmdoc
+ if [ `find . -name "*.pyc" | wc -l` -gt 0 ]; then echo Removing python byte-code...; rm `find . -name "*.pyc"`; fi
+ if [ `find ./test -name "log.txt" | wc -l` -gt 0 ]; then echo Removing test logs...; rm `find ./test -name "log.txt"`; fi
+ @echo Done
+
+# Implicit builds
+src/utils/nmd: src/utils/Makefile src/utils/nmd.c
+ @echo Building nmd...
+ (cd src/utils; make)
+ ln -s src/utils/nmd/nmd ./bin/nmd
+
+rmnmd:
+ if test -e src/utils/nmd; then echo Removing nmd...; (cd src/utils; make clean); rm -f bin/nmd; fi
+
+src/tashi/services: src/tashi/thrift/services.thrift
+ @echo Building tashi.services...
+ (cd src/tashi/thrift; ./build.py)
+
+rmservices:
+ if test -d src/tashi/services; then echo Removing tashi.services...; rm -rf src/tashi/services; fi
+ if test -d src/tashi/thrift/gen-py; then echo Removing tashi.thrift.gen-py...; rm -rf src/tashi/thrift/gen-py; fi
+ if test -d src/tashi/messaging/messagingthrift; then echo Removing tashi.messaging.messagingthrift; rm -rf src/tashi/messaging/messagingthrift; fi
+
+bin: bindir bin/getInstances bin/clustermanager.py bin/nodemanager.py
+bindir:
+ if test ! -d bin; then mkdir bin; fi
+rmbin: rmclustermanager rmnodemanager rmclients
+ if test -d bin; then rmdir bin; fi
+bin/getInstances: src/tashi/services
+ if test ! -e bin/getInstances; then (echo "Generating client symlinks..."; cd bin; PYTHONPATH=../src ../src/tashi/client/client.py --makesyms); fi
+rmclients:
+ if test -e bin/getInstances; then (echo Removing client symlinks...; make src/tashi/services; cd bin; PYTHONPATH=../src ../src/tashi/client/client.py --rmsyms; cd ..); fi
+bin/clustermanager.py: src/tashi/clustermanager/clustermanager.py
+ @echo Symlinking in clustermanager...
+ (cd bin; ln -s ../src/tashi/clustermanager/clustermanager.py .)
+rmclustermanager:
+ if test -e bin/clustermanager.py; then echo Removing clustermanager symlink...; rm bin/clustermanager.py; fi
+bin/nodemanager.py: src/tashi/nodemanager/nodemanager.py
+ @echo Symlinking in nodemanager...
+ (cd bin; ln -s ../src/tashi/nodemanager/nodemanager.py .)
+rmnodemanager:
+ if test -e bin/nodemanager.py; then echo Removing nodemanager symlink...; rm bin/nodemanager.py; fi
+
+src/tags:
+ @echo Generating tags...
+ (cd src; ctags-exuberant -R --c++-kinds=+p --fields=+iaS --extra=+q -f ./tags .)
+rmtags:
+ if test -e src/tags; then echo Removing tags...; rm src/tags; fi
+
+doc/html:
+ @echo Generating HTML docs...
+ epydoc --html -o doc/html --include-log --name=tashi --graph=all --exclude=tashi.services --exclude=tashi.messaging.messagingthrift ./src/tashi
+rmdoc:
+ if test -d doc/html; then echo Removing HTML docs...; rm -rf ./doc/html; fi
Added: incubator/tashi/import/tashi-intel-r399/README
URL: http://svn.apache.org/viewvc/incubator/tashi/import/tashi-intel-r399/README?rev=710072&view=auto
==============================================================================
--- incubator/tashi/import/tashi-intel-r399/README (added)
+++ incubator/tashi/import/tashi-intel-r399/README Mon Nov 3 06:45:25 2008
@@ -0,0 +1,106 @@
+This is the Tashi package.
+
+Currently, we are using KVM and Xen.
+
+Quick start
+========================================================================================================================
+ XXX: This needs to be rewritten
+
+Notes on the VMs
+========================================================================================================================
+ KVM - uses Intel VT and is open source
+ KQEMU - syscalls faster than KVM, but everything else is slower
+ QEMU - same as KVM, but slower
+ Xen - crashed for me, but will try it again in the future
+ VMware - Not open-source -- does this exclude it?
+
+Filename Description
+========================================================================================================================
+STYLE Specifies some rules about what should and shouldn't be done to the code
+README This file
+doc Project documentation
+doc/external_OC2_pitch_04_03_08 First round of the external "OC2" pitch
+doc/reading_group_03_10_08 Reading group presentation
+doc/notes Notes from project meetings
+doc/html Automatically generated HTML doc for the project (made by mkhtmldoc.sh)
+mkhtmldoc.sh Automatically generates HTML doc for the project
+.pydevproject Eclipse project file?
+.project Eclipse project file?
+TODO List of things to do for the project
+src Root of the python packages
+src/tashi Base tashi package
+src/tashi/__init__.py Contains some universally useful functions
+src/tashi/messaging Messaging subsystem
+src/tashi/client Client package
+src/tashi/client/client.py Client executable
+src/tashi/client/__init__.py Package stub
+src/tashi/data Data backend package (for Cluster manager)
+src/tashi/data/__init__.py Package functions
+src/tashi/data/schema.py Database schema
+src/tashi/data/util.py Utility functions
+src/tashi/services Generated by tashi/thrift/build.py (thrift generated code)
+src/tashi/nodemanager Node manager package -- needs to be reorganized
+src/tashi/thrift Thrift stuff
+src/tashi/thrift/services.thrift Thrift spec
+src/tashi/thrift/build.py Tool to build the thrift code and put it in the right place
+src/tashi/clustermanager Cluster manager package
+src/tashi/clustermanager/__init__.py Cluster manager functions
+src/tashi/clustermanager/policies.py Simple policy implementation (XXX: this needs to be reorganized)
+src/tashi/clustermanager/service.py Service implemenation (for thrift RPCs)
+src/tashi/clustermanager/demo.py Populate the data backend with test data
+src/tashi/clustermanager/clusterman... Cluster manager executable
+etc Configuration files
+etc/ClusterManager.cfg Cluster manager configuration file
+etc/ClusterManagerLogging.cfg Cluster manager logging configuration file (going away)
+guest Guest stuff
+guest/tashi Script for setting the hostname from the IP and registering the IP
+
+Client
+========================================================================================================================
+The client uses thrift RPCs to communicate with the Cluster Manager
+
+Guest
+========================================================================================================================
+Steps to setup a guest:
+ XXX: Optional
+ Remove /etc/hostname so that the hostname is not fixed
+ Place "oc2" script n /etc/network/if-up.d/ to set the hostname and register the IP with the master
+ Comment out eth0 in /etc/iftab so that multiple mac addresses show up as eth0
+ Add "acpi=force" to the kernel arguments to support shutdown
+ Add "noapictimer" if configuring a 64-bit guest
+ Install SSH so that the machine can be accessed
+
+NodeManager
+========================================================================================================================
+The steps currently involved in preping a machine to be a host include:
+ XXX: This list needs to be rewritten
+ # Enable VT in the BIOS (for Dell machines, "./tokenCtlS --token 0x014b --activate"), rebooting if necessary
+ # Install KVM ("cd /; tar xvjf kvm-60-bin.tar.bz2")
+ # Load the new kernel modules ("rmmod kvm; rmmod kvm-intel; depmod -a; modprobe kvm-intel")
+ # Make sure SDL is installed ("apt-get install libsdl1.2debian-oss")
+ # Make sure bridge-utils is installed ("apt-get install bridge-utils")
+ # Setup a bridge for the guests ("brctl addbr vmbr")
+ # Add a physical NIC to the bridge ("brctl addif vmbr eth1")
+ # Setup that physical NIC to be up and in promiscuous mode ("ifconfig eth1 0.0.0.0 up promisc")
+ # Setup the bridge to be up and in promiscuous mode ("ifconfig vmbr up promisc")
+ Make sure the disk images are available ("mkdir /mnt/mryan3; mount mryan3-d3:/export /mnt/mryan3")
+
+To prepare an image for booting natively on a host:
+ XXX: This also needs to be rewritten
+ Add losetup to the initrd in /sbin
+ Apply the diff "initrd-real-boot-diff.txt" to the initrd
+ Rebuild the initrd
+ Place the image at /x/hd.img on the host machine (this could be part of initrd)
+ Set the kernel parameters to "root=/dev/hda1 rw --"
+
+ClusterManager
+========================================================================================================================
+XXX: There is a server that runs here -- more doc needed later
+
+Packages
+========================================================================================================================
+Python [Python, does not affect code]
+KVM [GPL & LPGL, external binary -- shouldn't affect code]
+Xen [?, external binary or library?]
+SQLAlchemy [MIT]
+Thrift [ASL eventually?]
Added: incubator/tashi/import/tashi-intel-r399/STYLE
URL: http://svn.apache.org/viewvc/incubator/tashi/import/tashi-intel-r399/STYLE?rev=710072&view=auto
==============================================================================
--- incubator/tashi/import/tashi-intel-r399/STYLE (added)
+++ incubator/tashi/import/tashi-intel-r399/STYLE Mon Nov 3 06:45:25 2008
@@ -0,0 +1,28 @@
+This is not specifically about syntax, but includes some info about trunk
+checkins in general.
+
+Rules
+================================================================================
+1. Use comments, and make them docstrings. epydoc will automatically generate
+HTML docs from this.
+2. Do not modify auto-generated code (thrift output specifically).
+3. If you're going to make a big change to the code (restructuring, replacing
+core functionality, etc.), do it in a branch and do it in such a way that life
+is not painful for the trunk maintainer.
+4. If you're going to make a big change to the code, only make one big change
+at a time.
+5. You should not check in code you know doesn't work to trunk.
+6. Library dependencies should not require the newest releases of packages. A
+rule of thumb: if it doesn't work on something a year old (feisty at the time
+of this writting), it doesn't count as working.
+7. When making a big change, if you would like it to eventually go into trunk
+(and you should always want that -- this is an Apache project), make sure that
+everybody who would care about what you're doing atleast gives some form of
+approval.
+
+Testing
+================================================================================
+Currently, testing means testing the classes that implement an interface
+(VmControlInterface, DFSInterface, etc) as well as the RPC servers (test every
+RPC call). Additionally, it means regression testing. We are not currently
+doing strict unit testing.
Added: incubator/tashi/import/tashi-intel-r399/TODO
URL: http://svn.apache.org/viewvc/incubator/tashi/import/tashi-intel-r399/TODO?rev=710072&view=auto
==============================================================================
--- incubator/tashi/import/tashi-intel-r399/TODO (added)
+++ incubator/tashi/import/tashi-intel-r399/TODO Mon Nov 3 06:45:25 2008
@@ -0,0 +1 @@
+XXX: I emptied this file because it was hopelessly out of date -- MPR
Added: incubator/tashi/import/tashi-intel-r399/etc/TashiDefaults.cfg
URL: http://svn.apache.org/viewvc/incubator/tashi/import/tashi-intel-r399/etc/TashiDefaults.cfg?rev=710072&view=auto
==============================================================================
--- incubator/tashi/import/tashi-intel-r399/etc/TashiDefaults.cfg (added)
+++ incubator/tashi/import/tashi-intel-r399/etc/TashiDefaults.cfg Mon Nov 3 06:45:25 2008
@@ -0,0 +1,88 @@
+# ClusterManager portion
+[ClusterManager]
+service = tashi.clustermanager.ClusterManagerService
+data = tashi.clustermanager.data.Pickled
+sqlLogging = 0
+nodeManagerPort = 9883
+
+[ClusterManagerService]
+convertExceptions = True
+port = 9882
+expireHostTime = 30.0
+allowDecayed = 30.0
+;bind = 0.0.0.0 ; not supported (Thrift is missing support to specify what to bind to!)
+
+[FromConfig]
+host1 = Host(d={'id':1,'name':'blade043'})
+host2 = Host(d={'id':2,'name':'blade044'})
+host3 = Host(d={'id':3,'name':'blade045'})
+host4 = Host(d={'id':4,'name':'blade074'})
+machineType1 = MachineType(d={'id':1,'name':'1c-512m','memory':512,'cores':1})
+network1 = Network(d={'id':1,'name':'global'})
+network2 = Network(d={'id':2,'name':'NAT'})
+user1 = User(d={'id':1,'name':'mryan3'})
+
+[Pickled]
+file = /var/tmp/cm.dat
+
+# NodeManger portion
+[NodeManager]
+Dfs = tashi.dfs.Vfs
+VmControl = tashi.nodemanager.vmcontrol.Qemu
+Service = tashi.nodemanager.NodeManagerService
+
+[NodeManagerService]
+convertExceptions = True
+port = 9883
+registerFrequency = 10.0
+infoFile = /var/tmp/nm.dat
+clusterManagerHost = fillmein
+clusterManagerPort = 9882
+;bind = 0.0.0.0 ; not supported (Thrift is missing support to specify what to bind to!)
+
+[Qemu]
+qemuBin = /usr/local/bin/qemu-system-x86_64
+infoDir = /var/tmp/VmControlQemu/
+pollDelay = 1.0
+migrationRetries = 10
+monitorTimeout = 60.0
+migrateTimeout = 300.0
+maxParallelMigrations = 10
+
+[XenPV]
+vmNamePrefix = tashi
+
+[Vfs]
+prefix = /var/tmp/
+
+# Logging stuff
+[loggers]
+keys = root
+
+[handlers]
+keys = consoleHandler
+
+[formatters]
+keys = standardFormatter
+
+[logger_root]
+level = DEBUG
+handlers = consoleHandler
+propagate = 1
+
+[handler_consoleHandler]
+class = StreamHandler
+level = NOTSET
+formatter = standardFormatter
+args = (sys.stdout,)
+
+[formatter_standardFormatter]
+format=%(asctime)s [%(name)s:%(levelname)s] %(message)s
+datefmt=
+class=logging.Formatter
+
+# Message Broker
+[MessageBroker]
+host = localhost
+port = 1717
+
Added: incubator/tashi/import/tashi-intel-r399/etc/TestConfig.cfg
URL: http://svn.apache.org/viewvc/incubator/tashi/import/tashi-intel-r399/etc/TestConfig.cfg?rev=710072&view=auto
==============================================================================
--- incubator/tashi/import/tashi-intel-r399/etc/TestConfig.cfg (added)
+++ incubator/tashi/import/tashi-intel-r399/etc/TestConfig.cfg Mon Nov 3 06:45:25 2008
@@ -0,0 +1,3 @@
+[MessageBroker]
+host = localhost
+port = 1717
\ No newline at end of file
Added: incubator/tashi/import/tashi-intel-r399/guest/tashi
URL: http://svn.apache.org/viewvc/incubator/tashi/import/tashi-intel-r399/guest/tashi?rev=710072&view=auto
==============================================================================
--- incubator/tashi/import/tashi-intel-r399/guest/tashi (added)
+++ incubator/tashi/import/tashi-intel-r399/guest/tashi Mon Nov 3 06:45:25 2008
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+if [ "$IFACE" != eth0 ]; then
+ exit 0
+fi
+
+MAC_ADDR=`ifconfig eth0 | grep "HWaddr" | awk '{print $5}'`
+IP=`ifconfig eth0 | grep "inet addr" | sed 's/:/ /' | awk '{print $3}'`
+HN=`echo vm-${IP} | sed 's/\./-/g'`
+
+hostname ${HN}
+wget -O- "http://optimus.irp-cluster/tashi/register-ip.php?mac=${MAC_ADDR}&ip=${IP}" > /dev/null 2>&1
Propchange: incubator/tashi/import/tashi-intel-r399/guest/tashi
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/tashi/import/tashi-intel-r399/scripts/create
URL: http://svn.apache.org/viewvc/incubator/tashi/import/tashi-intel-r399/scripts/create?rev=710072&view=auto
==============================================================================
--- incubator/tashi/import/tashi-intel-r399/scripts/create (added)
+++ incubator/tashi/import/tashi-intel-r399/scripts/create Mon Nov 3 06:45:25 2008
@@ -0,0 +1,3 @@
+#! /bin/bash
+
+./bin/createVm "Instance(d={'name':'foobar','type':$1,'disks':[DiskConfiguration(d={'uri':'hercules.qcow','persistent':False})],'nics':[NetworkConfiguration(d={'network':2,'mac':'52:54:00:00:10:$2'})], 'hints':{'display':'True'}})"
Propchange: incubator/tashi/import/tashi-intel-r399/scripts/create
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/tashi/import/tashi-intel-r399/scripts/demo-yahoo-08-14-08
URL: http://svn.apache.org/viewvc/incubator/tashi/import/tashi-intel-r399/scripts/demo-yahoo-08-14-08?rev=710072&view=auto
==============================================================================
--- incubator/tashi/import/tashi-intel-r399/scripts/demo-yahoo-08-14-08 (added)
+++ incubator/tashi/import/tashi-intel-r399/scripts/demo-yahoo-08-14-08 Mon Nov 3 06:45:25 2008
@@ -0,0 +1,92 @@
+#! /bin/bash
+
+export PYTHONPATH=`pwd`/src/
+
+NUM=10
+
+BIGNODE=172.16.250.254
+
+BASEID=0
+
+date
+
+echo "Creating small VMs..."
+for h in `seq -w 1 ${NUM}`; do
+ echo "Creating VM #${h}..."
+ INFO=`./create 1 $h 2>/dev/null | grep "[ \t]id:"`
+ if [[ ${BASEID} -eq 0 ]]; then
+ BASEID=`echo ${INFO} | sed 's/[^0-9]*\([0-9]*\).*/\1/'`
+ fi
+done
+echo "Small VMs created"
+echo "Waiting for startup..."
+while [[ true ]]; do
+ PASS="True"
+ for h in `cat ~/hosts/vms.txt`; do
+ HN=`ssh root@bd.${h} "hostname 2> /dev/null" 2> /dev/null | cut -c -2`
+ if [[ "${HN}" != "vm" ]]; then
+ PASS="False"
+ fi
+ done
+ if [[ "${PASS}" == "True" ]]; then
+ break
+ fi
+ sleep 1
+done
+echo "Waiting finished"
+echo "Starting work on small VMs..."
+for h in `cat ~/hosts/vms.txt`; do
+ ssh root@bd.${h} "./run > /dev/null 2>&1" > /dev/null 2>&1 &
+done
+echo "Creating large VM..."
+./create 2 11 > /dev/null 2>&1
+echo "Done creating large VM"
+while [[ true ]]; do
+ sleep 5
+ COUNT=0
+ for h in `cat ~/hosts/vms.txt`; do
+ CNT=`ssh root@bd.${h} "ls /x/mryan3/cvm-out/*/*.txt 2> /dev/null | wc -l 2> /dev/null" 2> /dev/null`
+ COUNT=$((COUNT+CNT))
+ done
+ echo "${COUNT}/64 work items completed..."
+ if [[ ${COUNT} -eq 64 ]]; then
+ break
+ fi
+done
+echo "Work on small VMs completed"
+for i in `seq 1 ${NUM}`; do
+ wait
+done
+echo "Collecting output from small VMs to the large VM..."
+ssh root@bd.${BIGNODE} ./gather > /dev/null 2>&1
+echo "Done collecting output"
+echo "Destroying small VMs..."
+for i in `seq 1 ${NUM}`; do
+ ./bin/destroyVm $((i+BASEID-1)) > /dev/null 2>&1
+done
+echo "Done destroying small VMs"
+echo "Doing work on large VM..."
+ssh root@bd.${BIGNODE} ./build > /dev/null 2>&1 &
+while [[ true ]]; do
+ sleep 2
+ SIZE=`ssh root@bd.${BIGNODE} "du -hs ./out.e 2> /dev/null | awk '{print "'$1'"}' 2> /dev/null" 2> /dev/null`
+ echo "${SIZE}/154M output data generated..."
+ if [[ "${SIZE}" == "154M" ]]; then
+ break
+ fi
+done
+wait
+echo "Work on large VM complete"
+echo "Copying final output file to localhost..."
+scp root@bd.${BIGNODE}:./out.e /tmp/out.e
+echo "Copy complete"
+echo "Destroying large VM..."
+./bin/destroyVm $((11+BASEID-1)) > /dev/null 2>&1
+echo "Large VM destroyed"
+echo "Generating output image from etree..."
+(cd ~/local/src/mryan3/BigDatavis/src; ./util/draw_slice -d /tmp/out.e 0 0 0 512 0 0 0 512 0 512 512 /tmp/output.jpg > /dev/null 2>&1)
+echo "Image complete"
+
+date
+
+qiv /tmp/output.jpg
Propchange: incubator/tashi/import/tashi-intel-r399/scripts/demo-yahoo-08-14-08
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/tashi/import/tashi-intel-r399/scripts/mryan3-database-setup
URL: http://svn.apache.org/viewvc/incubator/tashi/import/tashi-intel-r399/scripts/mryan3-database-setup?rev=710072&view=auto
==============================================================================
--- incubator/tashi/import/tashi-intel-r399/scripts/mryan3-database-setup (added)
+++ incubator/tashi/import/tashi-intel-r399/scripts/mryan3-database-setup Mon Nov 3 06:45:25 2008
@@ -0,0 +1,11 @@
+#! /bin/sh
+
+./bin/addUser "User(d={'username':'mryan3'})"
+./bin/addPersistentImage "PersistentImage(d={'userId':1,'name':'i386-ubuntu.qcow'})"
+./bin/addInstanceConfiguration "InstanceConfiguration(d={'name':'i386-512','memory':512,'cores':1})"
+./bin/addHardDiskConfiguration "HardDiskConfiguration(d={'index':0,'persistentImageId':1,'persistent':False,'instanceConfigurationId':1})"
+./bin/addNetworkInterfaceConfiguration "NetworkInterfaceConfiguration(d={'index':0,'instanceConfigurationId':1})"
+./bin/addHost "Host(d={'hostname':'blade043'})"
+./bin/addHost "Host(d={'hostname':'blade044'})"
+./bin/addHost "Host(d={'hostname':'blade045'})"
+./bin/addHost "Host(d={'hostname':'blade074'})"
Propchange: incubator/tashi/import/tashi-intel-r399/scripts/mryan3-database-setup
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/tashi/import/tashi-intel-r399/scripts/resume
URL: http://svn.apache.org/viewvc/incubator/tashi/import/tashi-intel-r399/scripts/resume?rev=710072&view=auto
==============================================================================
--- incubator/tashi/import/tashi-intel-r399/scripts/resume (added)
+++ incubator/tashi/import/tashi-intel-r399/scripts/resume Mon Nov 3 06:45:25 2008
@@ -0,0 +1,3 @@
+#! /bin/bash
+
+./bin/resumeVm "Instance(d={'name':'foobar','type':$1,'disks':[DiskConfiguration(d={'uri':'i386-ubuntu.qcow','persistent':False})],'nics':[NetworkConfiguration(d={'network':2,'mac':'52:54:00:00:05:$2'})], 'hints':{'display':'True'}})" "\"$3\""
Propchange: incubator/tashi/import/tashi-intel-r399/scripts/resume
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/tashi/import/tashi-intel-r399/scripts/stress
URL: http://svn.apache.org/viewvc/incubator/tashi/import/tashi-intel-r399/scripts/stress?rev=710072&view=auto
==============================================================================
--- incubator/tashi/import/tashi-intel-r399/scripts/stress (added)
+++ incubator/tashi/import/tashi-intel-r399/scripts/stress Mon Nov 3 06:45:25 2008
@@ -0,0 +1,92 @@
+#! /bin/bash
+
+if [[ $# -eq 1 ]]; then
+ VMS=$1
+else
+ VMS=20
+fi
+
+date
+
+#HOSTS=`./bin/getHosts | grep name | wc -l`
+HOSTS="4"
+
+echo "Hosts: ${HOSTS}"
+
+echo "Create:"
+
+MID=10240000
+for i in `seq -w 1 $VMS`; do
+ echo "./scripts/create 2 $i"
+ ID=`./scripts/create 2 $i | grep "id: " | awk '{print $2}'`
+ if [[ ${ID} -lt ${MID} ]]; then
+ MID=${ID}
+ fi
+done
+
+date
+
+echo "Wait:"
+
+while [[ true ]]; do
+ CNT=`./bin/getInstances | grep -c Running`
+ echo ${CNT}
+ if [[ ${CNT} -eq ${VMS} ]]; then
+ break
+ fi
+ sleep 1
+done
+
+sleep 20
+
+date
+
+echo "Migrate:"
+
+for i in `seq 0 $((VMS-1))`; do
+ echo "./bin/migrateVm $((MID+i)) $((((i+1)%HOSTS)+1))"
+ ./bin/migrateVm $((MID+i)) $((((i+1)%HOSTS)+1)) > /dev/null &
+done
+for i in `seq 0 $((VMS-1))`; do
+ wait
+done
+
+date
+
+echo "Wait:"
+
+while [[ true ]]; do
+ CNT=`./bin/getInstances | grep -c Running`
+ echo ${CNT}
+ if [[ ${CNT} -eq ${VMS} ]]; then
+ break
+ fi
+ sleep 1
+done
+
+date
+
+echo "Destroy:"
+
+for i in `seq 0 $((VMS-1))`; do
+ echo "./bin/destroyVm $((MID+i))"
+ ./bin/destroyVm $((MID+i)) > /dev/null 2>&1 &
+done
+for i in `seq 0 $((VMS-1))`; do
+ wait
+done
+
+date
+
+echo "Wait:"
+
+while [[ true ]]; do
+ CNT=`./bin/getInstances | wc -l`
+ echo ${CNT}
+ if [[ ${CNT} -eq 1 ]]; then
+ break
+ fi
+ sleep 1
+done
+
+date
Propchange: incubator/tashi/import/tashi-intel-r399/scripts/stress
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/tashi/import/tashi-intel-r399/scripts/tomer-database-setup
URL: http://svn.apache.org/viewvc/incubator/tashi/import/tashi-intel-r399/scripts/tomer-database-setup?rev=710072&view=auto
==============================================================================
--- incubator/tashi/import/tashi-intel-r399/scripts/tomer-database-setup (added)
+++ incubator/tashi/import/tashi-intel-r399/scripts/tomer-database-setup Mon Nov 3 06:45:25 2008
@@ -0,0 +1,12 @@
+#! /bin/sh
+
+./bin/addUser "User(d={'username':'administrator'})"
+./bin/addUser "User(d={'username':'tshiran'})"
+./bin/addUser "User(d={'username':'jcipar'})"
+./bin/addPersistentImage "PersistentImage(d={'userId':1,'name':'hardy-25G.img'})"
+./bin/addPersistentImage "PersistentImage(d={'userId':1,'name':'hardy-25G-pdl.img','parentId':1})"
+./bin/addPersistentImage "PersistentImage(d={'userId':2,'name':'hardy-25G-tshiran.img','parentId':2})"
+./bin/addPersistentImage "PersistentImage(d={'userId':3,'name':'hardy-25G-jcipar.img','parentId':2})"
+./bin/addPersistentImage "PersistentImage(d={'userId':2,'name':'hardy-25G-tshiran-hadoop.img','parentId':3})"
+./bin/addHost "Host(d={'hostname':'ss306'})"
+./bin/addHost "Host(d={'hostname':'ss308'})"
Propchange: incubator/tashi/import/tashi-intel-r399/scripts/tomer-database-setup
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/tashi/import/tashi-intel-r399/src/tashi/__init__.py
URL: http://svn.apache.org/viewvc/incubator/tashi/import/tashi-intel-r399/src/tashi/__init__.py?rev=710072&view=auto
==============================================================================
--- incubator/tashi/import/tashi-intel-r399/src/tashi/__init__.py (added)
+++ incubator/tashi/import/tashi-intel-r399/src/tashi/__init__.py Mon Nov 3 06:45:25 2008
@@ -0,0 +1,2 @@
+from util import *
+from connectionmanager import ConnectionManager
Added: incubator/tashi/import/tashi-intel-r399/src/tashi/agents/__init__.py
URL: http://svn.apache.org/viewvc/incubator/tashi/import/tashi-intel-r399/src/tashi/agents/__init__.py?rev=710072&view=auto
==============================================================================
(empty)
Added: incubator/tashi/import/tashi-intel-r399/src/tashi/agents/examplepolicy.py
URL: http://svn.apache.org/viewvc/incubator/tashi/import/tashi-intel-r399/src/tashi/agents/examplepolicy.py?rev=710072&view=auto
==============================================================================
--- incubator/tashi/import/tashi-intel-r399/src/tashi/agents/examplepolicy.py (added)
+++ incubator/tashi/import/tashi-intel-r399/src/tashi/agents/examplepolicy.py Mon Nov 3 06:45:25 2008
@@ -0,0 +1,80 @@
+from socket import gethostname
+import os
+import threading
+import time
+
+from tashi.services.ttypes import *
+from thrift.transport.TSocket import TServerSocket, TSocket
+from thrift.server.TServer import TThreadedServer
+from thrift.protocol.TBinaryProtocol import TBinaryProtocol
+from thrift.transport.TTransport import TBufferedTransport
+from tashi.services import clustermanagerservice
+
+class ExamplePolicy():
+ def __init__(self, client, transport):
+ self.client = client
+ self.transport = transport
+
+ def start(self):
+ while True:
+ try:
+ if (not self.transport.isOpen()):
+ self.transport.open()
+ hosts = {}
+ load = {}
+ for h in self.client.getHosts():
+ hosts[h.id] = h
+ load[h.id] = []
+ load[None] = []
+ for i in self.client.getInstances():
+ if (i.hostId or i.state == InstanceState.Pending):
+ load[i.hostId] = load[i.hostId] + [i.id]
+ self.hosts = hosts
+ self.load = load
+ if (len(self.load.get(None, [])) > 0):
+ i = self.load[None][0]
+ min = None
+ minHost = None
+ for h in self.hosts.values():
+ if ((min is None or len(load[h.id]) < min) and h.up == True):
+ min = len(load[h.id])
+ minHost = h
+ if (minHost):
+ print "Scheduling instance %d on host %s" % (i, minHost.name)
+ self.client.activateVm(i, minHost)
+ continue
+ time.sleep(2)
+ except TashiException, e:
+ print e.msg
+ try:
+ self.transport.close()
+ except Exception, e:
+ print e
+ time.sleep(2)
+ except Exception, e:
+ print e
+ try:
+ self.transport.close()
+ except Exception, e:
+ print e
+ time.sleep(2)
+
+def createClient():
+ host = os.getenv('TASHI_CM_HOST', 'localhost')
+ port = os.getenv('TASHI_CM_PORT', '9882')
+ timeout = float(os.getenv('TASHI_CM_TIMEOUT', '5000.0'))
+ socket = TSocket(host, int(port))
+ socket.setTimeout(timeout)
+ transport = TBufferedTransport(socket)
+ protocol = TBinaryProtocol(transport)
+ client = clustermanagerservice.Client(protocol)
+ transport.open()
+ return (client, transport)
+
+def main():
+ (client, transport) = createClient()
+ agent = ExamplePolicy(client, transport)
+ agent.start()
+
+if __name__ == "__main__":
+ main()
Added: incubator/tashi/import/tashi-intel-r399/src/tashi/client/__init__.py
URL: http://svn.apache.org/viewvc/incubator/tashi/import/tashi-intel-r399/src/tashi/client/__init__.py?rev=710072&view=auto
==============================================================================
(empty)
Added: incubator/tashi/import/tashi-intel-r399/src/tashi/client/client.py
URL: http://svn.apache.org/viewvc/incubator/tashi/import/tashi-intel-r399/src/tashi/client/client.py?rev=710072&view=auto
==============================================================================
--- incubator/tashi/import/tashi-intel-r399/src/tashi/client/client.py (added)
+++ incubator/tashi/import/tashi-intel-r399/src/tashi/client/client.py Mon Nov 3 06:45:25 2008
@@ -0,0 +1,168 @@
+#! /usr/bin/env python
+
+import inspect
+import os
+import sys
+from tashi.services.ttypes import *
+from thrift.protocol.TBinaryProtocol import TBinaryProtocol
+from thrift.transport.TTransport import TBufferedTransport
+from thrift.transport.TSocket import TSocket
+
+from tashi.services import clustermanagerservice
+from tashi import vmStates
+
+def makeHTMLTable(list):
+ (stdin_r, stdin_w) = os.pipe()
+ pipe = os.popen("tput cols")
+ columns = pipe.read().strip()
+ keys = {}
+ for k in list:
+ for k2 in k.__dict__.keys():
+ if (not k2.endswith("Obj")):
+ keys[k2] = k2
+ output = "<html>"
+ output = output + "<table>"
+ output = output + "<tr>"
+ for k in keys.keys():
+ output = output + "<td>%s</td>" % (k)
+ output = output + "</tr>"
+ for k in list:
+ output = output + "<tr>"
+ for k2 in keys.keys():
+ if (k2 == "state"):
+ output = output + "<td>%s</td>" % (str(vmStates[k.__dict__.get(k2, None)]))
+ else:
+ output = output + "<td>%s</td>" % (str(k.__dict__.get(k2, None)))
+ output = output + "</tr>"
+ output = output + "</table>"
+ output = output + "</html>"
+ pid = os.fork()
+ if (pid == 0):
+ os.close(stdin_w)
+ os.dup2(stdin_r, 0)
+ os.close(stdin_r)
+ os.execl("/usr/bin/lynx", "/usr/bin/lynx", "-width=%s" % (columns), "-dump", "-stdin")
+ sys.exit(-1)
+ os.close(stdin_r)
+ os.write(stdin_w, output)
+ os.close(stdin_w)
+ os.waitpid(pid, 0)
+
+def getFunction(argv):
+ """Tries to determine the name of the function requested by the user -- may be called multiple times if the binary name is 'client'"""
+ function = "None"
+ if (len(argv) > 0):
+ function = argv[0].strip()
+ if (function.rfind("/") != -1):
+ function = function[function.rfind("/")+1:]
+ if (function.rfind(".") != -1):
+ function = function[:function.rfind(".")]
+ return function
+
+def getFunctionInfo(m):
+ """Gets a string that describes a function from the interface"""
+ f = getattr(clustermanagerservice.Iface, m)
+ argspec = inspect.getargspec(f)[0][1:]
+ return m + inspect.formatargspec(argspec)
+
+def usage():
+ """Print program usage"""
+ print "Available methods:"
+ for m in methods:
+ print "\t" + getFunctionInfo(m)
+ print
+ print "Examples:"
+ print "\tgetInstances"
+ print "\taddUser 'User(d={\"username\":\"foobar\"})'"
+ print "\tremoveUser 2"
+ print "\tcreateVM 1 1"
+
+def simpleType(obj):
+ """Determines whether an object is a simple type -- used as a helper function to pprint"""
+ if (type(obj) is not type([])):
+ if (not getattr(obj, "__dict__", None)):
+ return True
+ return False
+
+def pprint(obj, depth = 0, key = None):
+ """My own version of pprint that prints out a dict in a readable, but slightly more compact format"""
+ valueManip = lambda x: x
+ if (key):
+ keyString = key + ": "
+ if (key == "state"):
+ valueManip = lambda x: vmStates[x]
+ else:
+ keyString = ""
+ if (type(obj) is type([])):
+ if (reduce(lambda x, y: x and simpleType(y), obj, True)):
+ print (" " * (depth * INDENT)) + keyString + str(obj)
+ else:
+ print (" " * (depth * INDENT)) + keyString + "["
+ for o in obj:
+ pprint(o, depth + 1)
+ print (" " * (depth * INDENT)) + "]"
+ elif (getattr(obj, "__dict__", None)):
+ if (reduce(lambda x, y: x and simpleType(y), obj.__dict__.itervalues(), True)):
+ print (" " * (depth * INDENT)) + keyString + str(obj)
+ else:
+ print (" " * (depth * INDENT)) + keyString + "{"
+ for (k, v) in obj.__dict__.iteritems():
+ pprint(v, depth + 1, k)
+ print (" " * (depth * INDENT)) + "}"
+ else:
+ print (" " * (depth * INDENT)) + keyString + str(valueManip(obj))
+
+def main():
+ """Main function for the client program"""
+ global INDENT, methods, exitCode
+ exitCode = 0
+ INDENT = (os.getenv("INDENT", 4))
+ methods = filter(lambda x: not x.startswith("__"), clustermanagerservice.Iface.__dict__.keys())
+ function = getFunction(sys.argv)
+ if (function == "client"):
+ function = getFunction(sys.argv[1:])
+ if (function == "--makesyms"):
+ for m in methods:
+ os.symlink(sys.argv[0], m)
+ sys.exit(0)
+ if (function == "--rmsyms"):
+ for m in methods:
+ os.unlink(m)
+ sys.exit(0)
+ host = os.getenv('TASHI_CM_HOST', 'localhost')
+ port = os.getenv('TASHI_CM_PORT', '9882')
+ timeout = float(os.getenv('TASHI_CM_TIMEOUT', '5000.0'))
+ socket = TSocket(host, int(port))
+ socket.setTimeout(timeout)
+ transport = TBufferedTransport(socket)
+ protocol = TBinaryProtocol(transport)
+ client = clustermanagerservice.Client(protocol)
+ client._transport = transport
+ client._transport.open()
+ f = getattr(client, function, None)
+ if not f:
+ usage()
+ sys.exit(-1)
+ args = map(lambda x: eval(x), sys.argv[1:])
+ try:
+ res = f(*args)
+ if (os.getenv("USE_HTML_TABLES")):
+ try:
+ makeHTMLTable(res)
+ except:
+ pprint(res)
+ else:
+ pprint(res)
+ except TashiException, e:
+ print e.msg
+ exitCode = e.errno
+ except TypeError, e:
+ print e
+ print "\t" + getFunctionInfo(function)
+ exitCode = -1
+ finally:
+ client._transport.close()
+ sys.exit(exitCode)
+
+if __name__ == "__main__":
+ main()
Propchange: incubator/tashi/import/tashi-intel-r399/src/tashi/client/client.py
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/tashi/import/tashi-intel-r399/src/tashi/client/test.py
URL: http://svn.apache.org/viewvc/incubator/tashi/import/tashi-intel-r399/src/tashi/client/test.py?rev=710072&view=auto
==============================================================================
--- incubator/tashi/import/tashi-intel-r399/src/tashi/client/test.py (added)
+++ incubator/tashi/import/tashi-intel-r399/src/tashi/client/test.py Mon Nov 3 06:45:25 2008
@@ -0,0 +1,297 @@
+import unittest
+import logging
+import sys
+import signal
+import os.path
+import copy
+import time
+import random
+from ConfigParser import ConfigParser
+
+from tashi.services.ttypes import *
+from thrift.transport.TSocket import TSocket
+from thrift.protocol.TBinaryProtocol import TBinaryProtocol
+from thrift.transport.TTransport import TBufferedTransport
+
+from tashi.services import clustermanagerservice
+from tashi.messaging.threadpool import synchronized
+from tashi.messaging.tashimessaging import TestTashiSubscriber
+
+from tashi.util import getConfig
+
+import tashi.client.client
+
+class ClientConnection():
+ '''Creates an rpc proxy'''
+ def __init__(self, host, port):
+ self.host = host
+ self.port = port
+ self.transport = TBufferedTransport(TSocket(host, int(port)))
+ self.protocol = TBinaryProtocol(self.transport)
+ self.client = clustermanagerservice.Client(self.protocol)
+ self.client._transport = self.transport
+ self.client._transport.open()
+ def __del__(self):
+ self.client._transport.close()
+
+def incrementor(init=0):
+ while 1:
+ yield init
+ init = init + 1
+
+# FIXME: don't duplicate code from clustermanager
+# def getConfig(args):
+# config = ConfigParser()
+# configFiles = [
+# '/usr/share/tashi/ClusterManagerDefaults.cfg',
+# '/etc/tashi/ClusterManager.cfg',
+# os.path.expanduser('~/.tashi/ClusterManager.cfg')
+# ] + ([args[0]] if len(args) > 0 else [])
+
+# configFiles = config.read(configFiles)
+# if len(configFiles) == 0:
+# print >>sys.stderr, 'Unable to find the configuration file\n'
+# sys.exit(3)
+
+# return config
+
+
+class TestClient(unittest.TestCase):
+ @synchronized()
+ def getPortNum(self):
+ return self.portnum.next()
+
+ """macro test cases for single-host tests
+
+ Assumes cwd is 'src/tashi/client/'
+ """
+ def setUp(self):
+ """Create a CM and single NM on local host"""
+ logging.info('setting up test')
+
+ (self.config, self.configfiles) = getConfig([])
+
+ self.port = 1717 # FIXME: take this (and other things) from config file
+ self.portnum = incrementor(self.port)
+
+ self.cwd = os.getcwd()
+ self.srcd = os.path.dirname(os.path.dirname(self.cwd))
+
+ self.environ = copy.copy(os.environ)
+ self.environ['PYTHONPATH'] = self.srcd
+ logging.info('base path = %s' % self.srcd)
+
+ self.nm = os.spawnlpe(os.P_NOWAIT, 'python', 'python',
+ os.path.join(self.srcd, 'tashi', 'nodemanager', 'nodemanager.py'),
+ self.environ)
+ self.cm = os.spawnlpe(os.P_WAIT, 'python', 'python',
+ os.path.join(self.srcd, 'tashi', 'clustermanager', 'clustermanager.py'),
+ '--drop', '--create',
+ os.path.expanduser('~/.tashi/ClusterManager.cfg'),
+ self.environ)
+ self.cm = os.spawnlpe(os.P_NOWAIT, 'python', 'python',
+ os.path.join(self.srcd, 'tashi', 'clustermanager', 'clustermanager.py'),
+ os.path.expanduser('~/.tashi/ClusterManager.cfg'),
+ self.environ)
+ # since we are spawning with P_NOWAIT, we need to sleep to ensure that the CM is listening
+ time.sleep(1)
+ try:
+ self.connection = ClientConnection('localhost', self.config.get('ClusterManagerService', 'port'))
+ except Exception, e:
+ logging.warning('client connection failed')
+ ex = None
+ try:
+ logging.warning("setUp killing node manager " + str(self.nm))
+ os.kill(self.nm, signal.SIGKILL)
+ except Exception, e:
+ ex = e
+ logging.warning('could not kill node manager: '+ str(e))
+ try:
+ logging.warning('setUp killing cluster manager ' + str(self.cm))
+ os.kill(self.cm, signal.SIGKILL)
+ except Exception, e:
+ ex = e
+ logging.warning('could not kill cluster manager: ' + str(e))
+ if e != None:
+ raise e
+
+ logging.info('node manager PID: %i' % self.nm)
+ def tearDown(self):
+ '''Kill the CM and NM that were created by setUP'''
+ logging.info('tearing down test')
+ ex = None
+ try:
+ logging.debug("killing cluster manager " + str(self.cm))
+ os.kill(self.cm, signal.SIGKILL)
+ except Exception, e:
+ ex = e
+ logging.error('Could not kill cluster manager: ' + str(e))
+
+ try:
+ logging.debug("killing node manager " + str(self.nm))
+ os.kill(self.nm, signal.SIGKILL)
+ except Exception, e:
+ ex = e
+ logging.error('Could not kill node manager: ' + str(e))
+ if ex != None:
+ raise ex
+ def testSetup(self):
+ '''empty test to ensure that setUp code works'''
+ logging.info('setting up')
+ def testHostManagement(self):
+ '''test adding/removing/listing hosts
+
+ Right now this just adds a single host: localhost. Eventually
+ it should 1) take a list of hosts from a test configuration
+ file, 2) ensure that all were added, 3) remove a random
+ subset, 4) ensure that they were correctly removed, 5) remove
+ all, 6) ensure that they were correctly removed.'''
+
+ # get empty host list
+ hosts = self.connection.client.getHosts()
+ self.assertEqual(hosts, [], 'starting host list not empty: ' + str(hosts) )
+
+ # add a host
+ host = Host()
+ host.hostname = 'localhost'
+ host.enabled=True
+ self.connection.client.addHost(host)
+ hosts = self.connection.client.getHosts()
+ self.assertEqual(len(hosts), 1, 'wrong number of hosts %i, should be %i' % (len(hosts), 1) )
+ self.assertEqual(hosts[0].hostname, 'localhost', 'wrong hostname: ' + str(hosts[0].hostname) )
+
+ # remove first host
+ hid = hosts[0].id
+ self.connection.client.removeHost(hid)
+ hosts = self.connection.client.getHosts()
+ self.assertEqual(hosts, [], 'host list not empty after remove: ' + str(hosts) )
+
+ def testMessaging(self):
+ '''test messaging system started by CM
+
+ tests messages published directly, through events in the CM,
+ and the log system'''
+ # FIXME: add tests for generating events as a side-effect of
+ # rpc commands, as well as logging in the CM
+ portnum = self.getPortNum()
+ self.sub = TestTashiSubscriber(self.config, portnum)
+ self.assertEqual(self.sub.messageQueue.qsize(), 0)
+ self.pub = tashi.messaging.thriftmessaging.PublisherThrift(self.config.get('MessageBroker', 'host'),
+ int(self.config.get('MessageBroker', 'port')))
+ self.pub.publish({'message-type':'text', 'message':'Hello World!'})
+ time.sleep(0.5)
+ print '*** QSIZE', self.sub.messageQueue.qsize()
+ self.assertEqual(self.sub.messageQueue.qsize(), 1)
+
+ self.log = logging.getLogger(__name__)
+ messageHandler = tashi.messaging.tashimessaging.TashiLogHandler(self.config)
+ self.log.addHandler(messageHandler)
+ # FIXME: why can't we log messages with severity below 'warning'?
+ self.log.warning('test log message')
+ time.sleep(0.5)
+ self.assertEqual(self.sub.messageQueue.qsize(), 2)
+
+ # This should generate at least one log message
+# hosts = self.connection.client.getHosts()
+# time.sleep(0.5)
+# if (self.sub.messageQueue.qsize() <= 2):
+# self.fail()
+
+ def testUserManagement(self):
+ '''test adding/removing/listing users
+
+ same as testHostManagement, but with users'''
+ usernames = ['sleepy', 'sneezy', 'dopey', 'doc',
+ 'grumpy', 'bashful', 'happy']
+ # add all users
+ for un in usernames:
+ user = User()
+ user.username = un
+ self.connection.client.addUser(user)
+ # ensure that all were added
+ users = self.connection.client.getUsers()
+ self.assertEqual(len(usernames), len(users))
+ for user in users:
+ usernames.remove(user.username)
+ self.assertEqual(0, len(usernames))
+ # remove a random subset
+ rm = random.sample(users, 4)
+ for user in rm:
+ self.connection.client.removeUser(user.id)
+ users.remove(user)
+ newUsers = self.connection.client.getUsers()
+ # This ensures that the remaining ones are what we expect:
+ for user in newUsers:
+ # if there is a user remaining that we asked to be removed,
+ # this will throw an exception
+ users.remove(user)
+ # if a user was removed that we did not intend, this will
+ # throw an exception
+ self.assertEqual(0, len(users))
+
+# def testInstanceConfigurationManagement(self):
+# '''test adding/removing/listing instance configurations
+
+# same as testHostManagement, but with instance configurations'''
+# self.fail('test not implemented')
+ def testHardDiskConfigurationManagement(self):
+ '''test adding/removing/listing hard disk configurations
+
+ same as testHostManagement, but with hard disk configurations'''
+
+ user = User(d={'username':'sleepy'})
+ self.connection.client.addUser(user)
+ users = self.connection.client.getUsers()
+
+ per = PersistentImage()
+ per.userId = users[0].id
+ per.name = 'sleepy-PersistentImage'
+ self.connection.client.addPersistentImage(per)
+ pers = self.connection.client.getPersistentImages()
+
+ inst = InstanceConfiguration()
+ inst.name = 'sleepy-inst'
+ inst.memory = 512
+ inst.cores = 1
+ self.connection.client.addInstanceConfiguration(inst)
+ insts = self.connection.client.getInstanceConfigurations()
+
+ hdc = HardDiskConfiguration()
+ hdc.index = 0
+ hdc.persistentImageId = pers[0].id
+ hdc.persistent = False
+ hdc.instanceConfigurationId = insts[0].id
+
+# def testCreateDestroyShutdown(self):
+# '''test creating/destroying/shutting down VMs
+
+# not implemented'''
+# self.fail('test not implemented')
+# def testSuspendResume(self):
+# '''test suspending/resuming VMs
+
+# not implemented'''
+# self.fail('test not implemented')
+# def testMigrate(self):
+# '''test migration
+
+# not implemented'''
+# self.fail('test not implemented')
+# def testPauseUnpause(self):
+# '''test pausing/unpausing VMs
+
+# not implemented'''
+# self.fail('test not implemented')
+
+
+##############################
+# Test Code
+##############################
+if __name__ == '__main__':
+ logging.basicConfig(level=logging.NOTSET,
+ format="%(asctime)s %(levelname)s:\t %(message)s",
+ stream=sys.stdout)
+
+ suite = unittest.TestLoader().loadTestsFromTestCase(TestClient)
+ unittest.TextTestRunner(verbosity=2).run(suite)
+
Added: incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/__init__.py
URL: http://svn.apache.org/viewvc/incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/__init__.py?rev=710072&view=auto
==============================================================================
--- incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/__init__.py (added)
+++ incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/__init__.py Mon Nov 3 06:45:25 2008
@@ -0,0 +1 @@
+from clustermanagerservice import ClusterManagerService
Added: incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/clustermanager.py
URL: http://svn.apache.org/viewvc/incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/clustermanager.py?rev=710072&view=auto
==============================================================================
--- incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/clustermanager.py (added)
+++ incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/clustermanager.py Mon Nov 3 06:45:25 2008
@@ -0,0 +1,59 @@
+#!/usr/bin/env python
+
+import os
+import sys
+import threading
+import signal
+import logging.config
+from getopt import getopt, GetoptError
+from ConfigParser import ConfigParser
+from thrift.transport.TSocket import TServerSocket
+from thrift.server.TServer import TThreadedServer
+
+from tashi.messaging.thriftmessaging import MessageBrokerThrift
+from tashi.messaging.tashimessaging import TashiLogHandler
+from tashi.services import clustermanagerservice
+from tashi.util import signalHandler, boolean, instantiateImplementation, getConfig, debugConsole
+
+def startClusterManager(config):
+ global service, data
+
+ # start the event broker
+ broker = MessageBrokerThrift(int(config.get('MessageBroker', 'port')))
+ broker.ready.wait()
+ messageHandler = TashiLogHandler(config)
+ log.addHandler(messageHandler)
+
+ data = instantiateImplementation(config.get("ClusterManager", "data"), config)
+ service = instantiateImplementation(config.get("ClusterManager", "service"), config, data)
+ processor = clustermanagerservice.Processor(service)
+ transport = TServerSocket(int(config.get('ClusterManagerService', 'port')))
+ server = TThreadedServer(processor, transport)
+
+ debugConsole(globals())
+
+ try:
+ server.serve()
+ except KeyboardInterrupt:
+ handleSIGTERM(signal.SIGTERM, None)
+
+@signalHandler(signal.SIGTERM)
+def handleSIGTERM(signalNumber, stackFrame):
+ log.info('Exiting cluster manager after receiving a SIGINT signal')
+ sys.exit(0)
+
+def main():
+ global log
+
+ # setup configuration and logging
+ (config, configFiles) = getConfig(["ClusterManager"])
+ logging.config.fileConfig(configFiles)
+ log = logging.getLogger(__file__)
+ log.info('Using configuration file(s) %s' % configFiles)
+
+ # bind the database
+ log.info('Starting cluster manager')
+ startClusterManager(config)
+
+if __name__ == "__main__":
+ main()
Propchange: incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/clustermanager.py
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/clustermanagerservice.py
URL: http://svn.apache.org/viewvc/incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/clustermanagerservice.py?rev=710072&view=auto
==============================================================================
--- incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/clustermanagerservice.py (added)
+++ incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/clustermanagerservice.py Mon Nov 3 06:45:25 2008
@@ -0,0 +1,446 @@
+from __future__ import with_statement
+
+from datetime import datetime
+from random import randint
+from socket import gethostname
+from thrift.transport.TSocket import TSocket
+from thrift.protocol.TBinaryProtocol import TBinaryProtocol
+from thrift.transport.TTransport import TBufferedTransport
+import logging
+import threading
+import time
+
+from tashi.messaging.thriftmessaging import MessageBrokerThrift
+from tashi.messaging.tashimessaging import TashiLogHandler
+from tashi.services.ttypes import Errors, InstanceState, HostState, TashiException
+from tashi.services import nodemanagerservice
+from tashi import boolean, convertExceptions, ConnectionManager, vmStates, timed
+
+def RPC(oldFunc):
+ return convertExceptions(oldFunc)
+
+class ClusterManagerService():
+ """RPC service for the ClusterManager"""
+
+ def __init__(self, config, data):
+ self.config = config
+ self.data = data
+ self.proxy = ConnectionManager(nodemanagerservice.Client, int(self.config.get('ClusterManager', 'nodeManagerPort')))
+ self.convertExceptions = boolean(config.get('ClusterManagerService', 'convertExceptions'))
+ self.log = logging.getLogger(__name__)
+ self.messageHandler = TashiLogHandler(config)
+ self.log.addHandler(self.messageHandler)
+ self.lastContacted = {}
+ self.decayedHosts = {}
+ self.decayedInstances = {}
+ self.expireHostTime = float(self.config.get('ClusterManagerService', 'expireHostTime'))
+ self.allowDecayed = float(self.config.get('ClusterManagerService', 'allowDecayed'))
+ now = time.time()
+ for instance in self.data.getInstances().itervalues():
+ instanceId = instance.id
+ instance = self.data.acquireInstance(instanceId)
+ instance.decayed = False
+ self.stateTransition(instance, None, InstanceState.Orphaned)
+ self.data.releaseInstance(instance)
+ for host in self.data.getHosts().itervalues():
+ hostId = host.id
+ host = self.data.acquireHost(hostId)
+ host.up = False
+ host.decayed = False
+ self.data.releaseHost(host)
+ self.decayLock = threading.Lock()
+ threading.Thread(target=self.monitorHosts).start()
+
+ def stateTransition(self, instance, old, cur):
+ if (old and instance.state != old):
+ self.data.releaseInstance(instance)
+ raise TashiException(d={'errno':Errors.IncorrectVmState,'msg':"VmState is not %s - it is %s" % (vmStates[old], vmStates[instance.state])})
+ instance.state = cur
+
+ def updateDecay(self, set, obj):
+ now = time.time()
+ self.decayLock.acquire()
+ if (obj.decayed and obj.id not in set):
+ set[obj.id] = now
+ elif (not obj.decayed and obj.id in set):
+ del set[obj.id]
+ self.decayLock.release()
+
+
+ def monitorHosts(self):
+ # XXX: retry multiple hosts (iterate through them even with an exception)
+ while True:
+ now = time.time()
+ sleepFor = min(self.expireHostTime, self.allowDecayed)
+ try:
+ for k in self.lastContacted.keys():
+ if (self.lastContacted[k] < (now-self.expireHostTime)):
+ host = self.data.acquireHost(k)
+ try:
+ self.log.warning('Host %s has expired after %f seconds' % (host.name, now-self.expireHostTime))
+ for instanceId in [instance.id for instance in self.data.getInstances().itervalues() if instance.hostId == host.id]:
+ instance = self.data.acquireInstance(instanceId)
+ instance.decayed = True
+ self.stateTransition(instance, None, InstanceState.Orphaned)
+ self.data.releaseInstance(instance)
+ host.up = False
+ host.decayed = False
+ finally:
+ self.data.releaseHost(host)
+ del self.lastContacted[k]
+ else:
+ sleepFor = min(self.lastContacted[k] + self.expireHostTime - now, sleepFor)
+ for hostId in self.decayedHosts.keys():
+ if (self.decayedHosts[hostId] < (now-self.allowDecayed)):
+ host = self.data.getHost(hostId)
+ self.log.warning('Fetching state from host %s because it is decayed' % (host.name))
+ hostProxy = self.proxy[host.name]
+ oldInstances = [i for i in self.data.getInstances().values() if i.hostId == host.id]
+ instances = [hostProxy.getVmInfo(vmId) for vmId in hostProxy.listVms()]
+ instanceIds = [i.id for i in instances]
+ for instance in instances:
+ if (instance.id not in self.data.getInstances()):
+ instance.hostId = host.id
+ instance = self.data.registerInstance(instance)
+ self.data.releaseInstance(instance)
+ for instance in oldInstances:
+ if (instance.id not in instanceIds):
+ instance = self.data.acquireInstance(instance.id)
+ self.data.removeInstance(instance)
+ self.decayedHosts[hostId] = now
+ else:
+ sleepFor = min(self.decayedHosts[hostId] + self.allowDecayed - now, sleepFor)
+ for instanceId in self.decayedInstances.keys():
+ try:
+ if (self.decayedInstances[instanceId] < (now-self.allowDecayed)):
+ self.log.warning('Fetching state on instance %d because it is decayed' % (instanceId))
+ try:
+ instance = self.data.getInstance(instanceId)
+ except TashiException, e:
+ if (e.errno == Errors.NoSuchInstanceId):
+ del self.decayedInstances[instanceId]
+ continue
+ else:
+ raise
+ host = self.data.getHost(instance.hostId)
+ hostProxy = self.proxy[host.name]
+ instance = hostProxy.getVmInfo(instance.vmId)
+ oldInstance = self.data.acquireInstance(instanceId)
+ oldInstance.state = instance.state
+ self.data.releaseInstance(oldInstance)
+ self.decayedInstances[instanceId] = now
+ else:
+ sleepFor = min(self.decayedInstances[instanceId] + self.allowDecayed - now, sleepFor)
+ except Exception, e:
+ self.log.exception('Exception in monitorHosts trying to get instance information')
+ except Exception, e:
+ self.log.exception('Exception in monitorHosts')
+ time.sleep(sleepFor)
+
+ @RPC
+ def createVm(self, instance):
+ """Function to add a VM to the list of pending VMs"""
+ instance.state = InstanceState.Pending
+ # XXX: Synchronize on MachineType
+ instance.typeObj = self.data.getMachineTypes()[instance.type]
+ instance.decayed = False
+ instance = self.data.registerInstance(instance)
+ self.data.releaseInstance(instance)
+ return instance
+
+ @RPC
+ def shutdownVm(self, instanceId):
+ instance = self.data.acquireInstance(instanceId)
+ self.stateTransition(instance, InstanceState.Running, InstanceState.ShuttingDown)
+ self.data.releaseInstance(instance)
+ hostname = self.data.getHost(instance.hostId).name
+ try:
+ self.proxy[hostname].shutdownVm(instance.vmId)
+ except Exception:
+ self.log.exception('shutdownVm failed for host %s vmId %d' % (instance.hostname, instance.vmId))
+ raise
+ return
+
+ @RPC
+ def destroyVm(self, instanceId):
+ instance = self.data.acquireInstance(instanceId)
+ if (instance.state is InstanceState.Pending or instance.state is InstanceState.Held):
+ self.data.removeInstance(instance)
+ elif (instance.state is InstanceState.Activating):
+ self.stateTransition(instance, InstanceState.Activating, InstanceState.Destroying)
+ self.data.releaseInstance(instance)
+ else:
+ self.stateTransition(instance, None, InstanceState.Destroying)
+ self.data.releaseInstance(instance)
+ hostname = self.data.getHost(instance.hostId).name
+ try:
+ self.proxy[hostname].destroyVm(instance.vmId)
+ except Exception:
+ self.log.exception('destroyVm failed for host %s vmId %d' % (hostname, instance.vmId))
+ raise
+ return
+
+ @RPC
+ def suspendVm(self, instanceId, destination):
+ instance = self.data.acquireInstance(instanceId)
+ self.stateTransition(instance, InstanceState.Running, InstanceState.Suspending)
+ self.data.releaseInstance(instance)
+ suspendCookie = ""
+ hostname = self.data.getHost(instance.hostId).name
+ try:
+ self.proxy[hostname].suspendVm(instance.vmId, destination, suspendCookie)
+ except Exception:
+ self.log.exception('suspendVm failed for host %s vmId %d' % (hostname, instance.vmId))
+ raise
+ return
+
+ @RPC
+ def resumeVm(self, instance, source):
+ instance.state = InstanceState.Pending
+ # XXX: Synchronize on MachineType
+ instance.typeObj = self.data.getMachineTypes()[instance.type]
+ instance.decayed = False
+ instance.hints['__resume_source'] = source
+ instance = self.data.registerInstance(instance)
+ self.data.releaseInstance(instance)
+ return instance
+
+ @RPC
+ def migrateVm(self, instanceId, targetHostId):
+ instance = self.data.acquireInstance(instanceId)
+ try:
+ # FIXME: should these be acquire/release host?
+ targetHost = self.data.getHost(targetHostId)
+ sourceHost = self.data.getHost(instance.hostId)
+ # FIXME: Are these the correct state transitions?
+ except:
+ self.data.releaseInstance(instance)
+ raise
+ self.stateTransition(instance, InstanceState.Running, InstanceState.MigratePrep)
+ self.data.releaseInstance(instance)
+ try:
+ # Prepare the target
+ cookie = self.proxy[targetHost.name].prepReceiveVm(instance, sourceHost)
+ except Exception, e:
+ self.log.exception('prepReceiveVm failed')
+ raise
+ instance = self.data.acquireInstance(instance.id)
+ self.stateTransition(instance, InstanceState.MigratePrep, InstanceState.MigrateTrans)
+ self.data.releaseInstance(instance)
+ try:
+ # Send the VM
+ self.proxy[sourceHost.name].migrateVm(instance.vmId, targetHost, cookie)
+ except Exception, e:
+ self.log.exception('migrateVm failed')
+ raise
+ #instance = self.data.acquireInstance(instance.id)
+ #try:
+ # instance.hostId = targetHost.id
+ #finally:
+ # self.data.releaseInstance(instance)
+ try:
+ # Notify the target
+ vmId = self.proxy[targetHost.name].receiveVm(instance, cookie)
+ except Exception, e:
+ self.log.exception('receiveVm failed')
+ raise
+ #print 'VM %i Migrated! New vmId=%i, new hostId=%i' % (instance.id, vmId, targetHostId)
+ return
+
+ @RPC
+ def pauseVm(self, instanceId):
+ instance = self.data.acquireInstance(instanceId)
+ self.stateTransition(instance, InstanceState.Running, InstanceState.Pausing)
+ self.data.releaseInstance(instance)
+ hostname = self.data.getHost(instance.hostId).name
+ try:
+ self.proxy[hostname].pauseVm(instance.vmId)
+ except Exception:
+ self.log.exception('pauseVm failed on host %s with vmId %d' % (hostname, instance.vmId))
+ raise
+ instance = self.data.acquireInstance(instanceId)
+ self.stateTransition(instance, InstanceState.Pausing, InstanceState.Paused)
+ self.data.releaseInstance(instance)
+ return
+
+ @RPC
+ def unpauseVm(self, instanceId):
+ instance = self.data.acquireInstance(instanceId)
+ self.stateTransition(instance, InstanceState.Paused, InstanceState.Unpausing)
+ self.data.releaseInstance(instance)
+ hostname = self.data.getHost(instance.hostId).name
+ try:
+ self.proxy[hostname].unpauseVm(instance.vmId)
+ except Exception:
+ self.log.exception('unpauseVm failed on host %s with vmId %d' % (hostname, instance.vmId))
+ raise
+ instance = self.data.acquireInstance(instanceId)
+ self.stateTransition(instance, InstanceState.Unpausing, InstanceState.Running)
+ self.data.releaseInstance(instance)
+ return
+
+ @RPC
+ def getMachineTypes(self):
+ return self.data.getMachineTypes().values()
+
+ @RPC
+ def getHosts(self):
+ return self.data.getHosts().values()
+
+ @RPC
+ def getNetworks(self):
+ return self.data.getNetworks().values()
+
+ @RPC
+ def getUsers(self):
+ return self.data.getUsers().values()
+
+ @RPC
+ def getInstances(self):
+ instances = self.data.getInstances().values()
+ for instance in instances:
+ if (instance.hostId):
+ instance.hostObj = self.data.getHost(instance.hostId)
+ else:
+ instance.hostObj = None
+ if (instance.userId):
+ instance.userObj = self.data.getUser(instance.userId)
+ else:
+ instance.userObj = None
+ return instances
+
+# @timed
+ @RPC
+ def registerNodeManager(self, host, instances):
+ """Called by the NM every so often as a keep-alive/state polling -- state changes here are NOT AUTHORITATIVE"""
+ if (host.id == None):
+ hostList = [h for h in self.data.getHosts().itervalues() if h.name == host.name]
+ if (len(hostList) != 1):
+ raise TashiException(d={'errno':Errors.NoSuchHost, 'msg':'A host with name %s is not identifiable' % (host.name)})
+ host.id = hostList[0].id
+ oldHost = self.data.acquireHost(host.id)
+ if (oldHost.name != host.name):
+ self.data.releaseHost(oldHost)
+ raise TashiException(d={'errno':Errors.NoSuchHostId, 'msg':'Host id and hostname mismatch'})
+ try:
+ self.lastContacted[host.id] = time.time()
+ oldHost.memory = host.memory
+ oldHost.cores = host.cores
+ oldHost.up = True
+ oldHost.decayed = False
+ for instance in instances:
+ try:
+ oldInstance = self.data.acquireInstance(instance.id)
+ except TashiException, e:
+ if (e.errno == Errors.NoSuchInstanceId):
+ self.log.info('Host %s reported an instance %d that did not previously exist (decay)' % (host.name, instance.id))
+ oldHost.decayed = True
+ continue
+ #oldInstance = self.data.registerInstance(instance)
+ else:
+ raise
+ try:
+ if (oldInstance.hostId != host.id):
+ self.log.info('Host %s is claiming instance %d actually owned by hostId %s (decay)' % (host.name, oldInstance.id, str(oldInstance.hostId)))
+ oldHost.decayed = True
+ continue
+ oldInstance.decayed = (oldInstance.state != instance.state)
+ self.updateDecay(self.decayedInstances, oldInstance)
+ if (oldInstance.decayed):
+ self.log.info('State reported as %s instead of %s for instance %d on host %s (decay)' % (vmStates[instance.state], vmStates[oldInstance.state], instance.id, host.name))
+ finally:
+ self.data.releaseInstance(oldInstance)
+ instanceIds = [instance.id for instance in instances]
+ for instanceId in [instance.id for instance in self.data.getInstances().itervalues() if instance.hostId == host.id]:
+ if (instanceId not in instanceIds):
+ self.log.info('instance %d was not reported by host %s as expected (decay)' % (instanceId, host.name))
+ instance = self.data.acquireInstance(instanceId)
+ instance.decayed = True
+ self.updateDecay(self.decayedInstances, instance)
+ oldHost.decayed = True
+ self.data.releaseInstance(instance)
+ except Exception, e:
+ oldHost.decayed = True
+ raise
+ finally:
+ self.updateDecay(self.decayedHosts, oldHost)
+ self.data.releaseHost(oldHost)
+ return host.id
+
+ @RPC
+ def vmUpdate(self, instanceId, instance, oldState):
+ try:
+ oldInstance = self.data.acquireInstance(instanceId)
+ except TashiException, e:
+ if (e.errno == Errors.NoSuchInstanceId):
+ self.log.exception('Got vmUpdate for unknown instanceId %d' % (instanceId))
+ return
+ else:
+ raise
+ if (instance.state == InstanceState.Exited):
+ oldInstance.decayed = False
+ self.updateDecay(self.decayedInstances, oldInstance)
+ self.data.removeInstance(oldInstance)
+ hostname = self.data.getHost(oldInstance.hostId).name
+ if (oldInstance.state not in [InstanceState.ShuttingDown, InstanceState.Destroying, InstanceState.Suspending]):
+ self.log.warning('Unexpected exit on %s of instance %d (vmId %d)' % (hostname, instanceId, oldInstance.vmId))
+ else:
+ if (instance.state):
+ if (oldState and oldInstance.state != oldState):
+ self.log.warning('Got vmUpdate of state from %s to %s, but the instance was previously %s' % (vmStates[oldState], vmStates[instance.state], vmStates[oldInstance.state]))
+ oldInstance.state = instance.state
+ if (instance.vmId):
+ oldInstance.vmId = instance.vmId
+ if (instance.hostId):
+ oldInstance.hostId = instance.hostId
+ oldInstance.decayed = False
+ self.updateDecay(self.decayedInstances, oldInstance)
+ self.data.releaseInstance(oldInstance)
+ return
+
+ @RPC
+ def activateVm(self, instanceId, host):
+ dataHost = self.data.acquireHost(host.id)
+ if (dataHost.name != host.name):
+ self.data.releaseHost(dataHost)
+ raise TashiException(d={'errno':Errors.HostNameMismatch,'msg':"Mismatched target host"})
+ if (not dataHost.up):
+ self.data.releaseHost(dataHost)
+ raise TashiException(d={'errno':Errors.HostNotUp,'msg':"Target host is not up"})
+ if (dataHost.state != HostState.Normal):
+ self.data.releaseHost(dataHost)
+ raise TashiException(d={'errno':Errors.HostStateError,'msg':"Target host state is not normal"})
+ self.data.releaseHost(dataHost)
+ instance = self.data.acquireInstance(instanceId)
+ self.stateTransition(instance, InstanceState.Pending, InstanceState.Activating)
+ instance.hostId = host.id
+ self.data.releaseInstance(instance)
+ try:
+ if ('__resume_source' in instance.hints):
+ resumeVmId = self.proxy[host.name].resumeVm(instance, instance.hints['__resume_source'])
+ vmId = resumeVmId.vmId
+ suspendCookie = resumeVmId.suspendCookie
+ else:
+ vmId = self.proxy[host.name].instantiateVm(instance)
+ except Exception, e:
+ instance = self.data.acquireInstance(instanceId)
+ if (instance.state is InstanceState.Destroying): # Special case for if destroyVm is called during initialization and initialization fails
+ self.data.removeInstance(instance)
+ else:
+ self.stateTransition(instance, None, InstanceState.Held)
+ instance.hostId = None
+ self.data.releaseInstance(instance)
+ raise
+ instance = self.data.acquireInstance(instanceId)
+ instance.vmId = vmId
+ if (instance.state is InstanceState.Destroying): # Special case for if destroyVm is called during initialization
+ self.data.releaseInstnace(instance)
+ try:
+ self.proxy[host.name].destroyVm(vmId)
+ except Exception:
+ self.log.exception('destroyVm failed for host %s vmId %d' % (host.name, instance.vmId))
+ raise
+ else:
+ self.stateTransition(instance, InstanceState.Activating, InstanceState.Running)
+ self.data.releaseInstance(instance)
+ return
Added: incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/data/__init__.py
URL: http://svn.apache.org/viewvc/incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/data/__init__.py?rev=710072&view=auto
==============================================================================
--- incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/data/__init__.py (added)
+++ incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/data/__init__.py Mon Nov 3 06:45:25 2008
@@ -0,0 +1,3 @@
+from datainterface import DataInterface
+from fromconfig import FromConfig
+from pickled import Pickled
Added: incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/data/datainterface.py
URL: http://svn.apache.org/viewvc/incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/data/datainterface.py?rev=710072&view=auto
==============================================================================
--- incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/data/datainterface.py (added)
+++ incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/data/datainterface.py Mon Nov 3 06:45:25 2008
@@ -0,0 +1,54 @@
+class DataInterface(object):
+ """Interface for a functional data access mechanism"""
+ def __init__(self, config):
+ if (self.__class__ is DataInterface):
+ raise NotImplementedError
+ self.config = config
+
+ def registerInstance(self, instance):
+ raise NotImplementedError
+
+ def acquireInstance(self, instanceId):
+ raise NotImplementedError
+
+ def releaseInstance(self, instance):
+ raise NotImplementedError
+
+ def removeInstance(self, instance):
+ raise NotImplementedError
+
+ def acquireHost(self, hostId):
+ raise NotImplementedError
+
+ def releaseHost(self, host):
+ raise NotImplementedError
+
+ def getHosts(self):
+ raise NotImplementedError
+
+ def getHost(self, id):
+ raise NotImplementedError
+
+ def getInstances(self):
+ raise NotImplementedError
+
+ def getInstance(self, id):
+ raise NotImplementedError
+
+ def getMachineTypes(self):
+ raise NotImplementedError
+
+ def getMachineType(self, id):
+ raise NotImplementedError
+
+ def getNetworks(self):
+ raise NotImplementedError
+
+ def getNetwork(self, id):
+ raise NotImplementedError
+
+ def getUsers(self):
+ raise NotImplementedError
+
+ def getUser(self, id):
+ raise NotImplementedError
Added: incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/data/fromconfig.py
URL: http://svn.apache.org/viewvc/incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/data/fromconfig.py?rev=710072&view=auto
==============================================================================
--- incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/data/fromconfig.py (added)
+++ incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/data/fromconfig.py Mon Nov 3 06:45:25 2008
@@ -0,0 +1,153 @@
+import threading
+
+from tashi.services.ttypes import *
+from tashi.clustermanager.data import DataInterface
+
+class FromConfig(DataInterface):
+ def __init__(self, config):
+ DataInterface.__init__(self, config)
+ self.hosts = {}
+ self.instances = {}
+ self.machineTypes = {}
+ self.networks = {}
+ self.users = {}
+# self.locks = {}
+ self.lockNames = {}
+ self.instanceLock = threading.Lock()
+ self.lockNames[self.instanceLock] = "instanceLock"
+ self.instanceIdLock = threading.Lock()
+ self.lockNames[self.instanceIdLock] = "instanceIdLock"
+ self.maxInstanceId = 1
+ for (name, value) in self.config.items("FromConfig"):
+ name = name.lower()
+ if (name.startswith("host")):
+ host = eval(value)
+ if (host.__class__ is not Host):
+ raise ValueError, "Entry %s is not a Host" % (name)
+ host._lock = threading.Lock()
+ self.lockNames[host._lock] = "h%d" % (host.id)
+ self.hosts[host.id] = host
+ if (name.startswith("machinetype")):
+ machineType = eval(value)
+ if (machineType.__class__ is not MachineType):
+ raise ValueError, "Entry %s is not a MachineType" % (name)
+ self.machineTypes[machineType.id] = machineType
+ if (name.startswith("network")):
+ network = eval(value)
+ if (network.__class__ is not Network):
+ raise ValueError, "Entry %s is not a Network" % (name)
+ self.networks[network.id] = network
+ if (name.startswith("user")):
+ user = eval(value)
+ if (user.__class__ is not User):
+ raise ValueError, "Entry %s is not a User" % (name)
+ self.users[user.id] = user
+
+ def acquireLock(self, l):
+ l.acquire()
+# self.locks[l] = threading.currentThread()
+
+ def releaseLock(self, l):
+# del self.locks[l]
+ l.release()
+
+ def getNewInstanceId(self):
+ self.acquireLock(self.instanceIdLock)
+ instanceId = self.maxInstanceId
+ self.maxInstanceId = self.maxInstanceId + 1
+ self.releaseLock(self.instanceIdLock)
+ return instanceId
+
+ def registerInstance(self, instance):
+ self.acquireLock(self.instanceLock)
+ try:
+ if (instance.id is not None and instance.id not in self.instances):
+ self.acquireLock(self.instanceIdLock)
+ if (instance.id >= self.maxInstanceId):
+ self.maxInstanceId = instance.id + 1
+ self.releaseLock(self.instanceIdLock)
+ else:
+ instance.id = self.getNewInstanceId()
+ instance._lock = threading.Lock()
+ self.lockNames[instance._lock] = "i%d" % (instance.id)
+ self.acquireLock(instance._lock)
+ self.instances[instance.id] = instance
+ finally:
+ self.releaseLock(self.instanceLock)
+ return instance
+
+ def acquireInstance(self, instanceId):
+ self.acquireLock(self.instanceLock)
+ try:
+ instance = self.instances.get(instanceId, None)
+ if (instance is None):
+ raise TashiException(d={'errno':Errors.NoSuchInstanceId,'msg':"No such instanceId - %d" % (instanceId)})
+ self.acquireLock(instance._lock)
+ finally:
+ self.releaseLock(self.instanceLock)
+ return instance
+
+ def releaseInstance(self, instance):
+ try:
+ if (instance.id not in self.instances): # MPR: should never be true, but good to check
+ raise TashiException(d={'errno':Errors.NoSuchInstanceId,'msg':"No such instanceId - %d" % (instanceId)})
+ finally:
+ self.releaseLock(instance._lock)
+
+ def removeInstance(self, instance):
+ self.acquireLock(self.instanceLock)
+ try:
+ del self.instances[instance.id]
+ self.releaseLock(instance._lock)
+ finally:
+ self.releaseLock(self.instanceLock)
+
+ def acquireHost(self, hostId):
+ host = self.hosts.get(hostId, None)
+ if (host is None):
+ raise TashiException(d={'errno':Errors.NoSuchHostId,'msg':"No such hostId - %s" % (hostId)})
+ self.acquireLock(host._lock)
+ return host
+
+ def releaseHost(self, host):
+ try:
+ if (host.id not in self.hosts): # MPR: should never be true, but good to check
+ raise TashiException(d={'errno':Errors.NoSuchHostId,'msg':"No such hostId - %s" % (hostId)})
+ finally:
+ self.releaseLock(host._lock)
+
+ def getHosts(self):
+ return self.hosts
+
+ def getHost(self, id):
+ host = self.hosts.get(id, None)
+ if (not host):
+ raise TashiException(d={'errno':Errors.NoSuchHostId,'msg':"No such hostId - %s" % (id)})
+ return host
+
+ def getInstances(self):
+ return self.instances
+
+ def getInstance(self, id):
+ instance = self.instances.get(id, None)
+ if (not instance):
+ raise TashiException(d={'errno':Errors.NoSuchInstanceId,'msg':"No such instanceId - %d" % (id)})
+ return instance
+
+ def getMachineTypes(self):
+ return self.machineTypes
+
+ def getMachineType(self, id):
+ return self.machineTypes[id]
+
+ def getNetworks(self):
+ return self.networks
+
+ def getNetwork(self, id):
+ return self.networks[id]
+
+ def getUsers(self):
+ return self.users
+
+ def getUser(self, id):
+ return self.users[id]
Added: incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/data/pickled.py
URL: http://svn.apache.org/viewvc/incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/data/pickled.py?rev=710072&view=auto
==============================================================================
--- incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/data/pickled.py (added)
+++ incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/data/pickled.py Mon Nov 3 06:45:25 2008
@@ -0,0 +1,56 @@
+import cPickle
+import os
+import threading
+from tashi.services.ttypes import *
+from tashi.clustermanager.data import FromConfig, DataInterface
+
+class Pickled(FromConfig):
+ def __init__(self, config):
+ DataInterface.__init__(self, config)
+ self.file = self.config.get("Pickled", "file")
+ self.locks = {}
+ self.lockNames = {}
+ self.instanceLock = threading.Lock()
+ self.lockNames[self.instanceLock] = "instanceLock"
+ self.instanceIdLock = threading.Lock()
+ self.lockNames[self.instanceIdLock] = "instanceIdLock"
+ self.maxInstanceId = 1
+ self.load()
+
+ def cleanInstances(self):
+ ci = {}
+ for i in self.instances.itervalues():
+ i2 = Instance(d=i.__dict__)
+ ci[i2.id] = i2
+ return ci
+
+ def cleanHosts(self):
+ ch = {}
+ for h in self.hosts.itervalues():
+ h2 = Host(d=h.__dict__)
+ ch[h2.id] = h2
+ return ch
+
+ def save(self):
+ file = open(self.file, "w")
+ cPickle.dump((self.cleanHosts(), self.cleanInstances(), self.machineTypes, self.networks, self.users), file)
+ file.close()
+
+ def load(self):
+ if (os.access(self.file, os.F_OK)):
+ file = open(self.file, "r")
+ (hosts, instances, machineTypes, networks, users) = cPickle.load(file)
+ file.close()
+ else:
+ (hosts, instances, machineTypes, networks, users) = ({}, {}, {}, {}, {})
+ self.hosts = hosts
+ self.instances = instances
+ self.machineTypes = machineTypes
+ self.networks = networks
+ self.users = users
+ for i in self.instances.itervalues():
+ i._lock = threading.Lock()
+ self.lockNames[i._lock] = "i%d" % (i.id)
+ for h in self.hosts.itervalues():
+ h._lock = threading.Lock()
+ self.lockNames[h._lock] = "h%d" % (h.id)
Added: incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/data/sql.py
URL: http://svn.apache.org/viewvc/incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/data/sql.py?rev=710072&view=auto
==============================================================================
--- incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/data/sql.py (added)
+++ incubator/tashi/import/tashi-intel-r399/src/tashi/clustermanager/data/sql.py Mon Nov 3 06:45:25 2008
@@ -0,0 +1,12 @@
+import time
+import types
+from tashi.clustermanager.data.datainterface import DataInterface
+
+class SQL(DataInterface):
+ def __init__(self, config):
+ DataInterface.__init__(self, config)
+ self.uri = self.config.get("SQL", "uri")
+ if (self.uri.startswith("sqlite://")):
+ raise NotImplementedError
+ else:
+ raise ValueException, "Unknown SQL uri: %s" % (self.uri)
Added: incubator/tashi/import/tashi-intel-r399/src/tashi/connectionmanager.py
URL: http://svn.apache.org/viewvc/incubator/tashi/import/tashi-intel-r399/src/tashi/connectionmanager.py?rev=710072&view=auto
==============================================================================
--- incubator/tashi/import/tashi-intel-r399/src/tashi/connectionmanager.py (added)
+++ incubator/tashi/import/tashi-intel-r399/src/tashi/connectionmanager.py Mon Nov 3 06:45:25 2008
@@ -0,0 +1,46 @@
+from thrift.transport.TSocket import TSocket, socket
+from thrift.protocol.TBinaryProtocol import TBinaryProtocol
+from thrift.transport.TTransport import TBufferedTransport
+
+class ConnectionManager(object):
+ def __init__(self, clientClass, port, timeout=10000.0):
+ self.clientClass = clientClass
+ self.timeout = timeout
+ self.port = port
+
+ class anonClass(object):
+ def __init__(self, clientObject):
+ self.co = clientObject
+
+ def __getattr__(self, name):
+ if (name.startswith("_")):
+ return self.__dict__[name]
+ def connectWrap(*args, **kw):
+ if (not self.co._iprot.trans.isOpen()):
+ self.co._iprot.trans.open()
+ try:
+ res = getattr(self.co, name)(*args, **kw)
+ except socket.error, e:
+ # Force a close for the case of a "Broken pipe"
+# print "Forced a socket close"
+ self.co._iprot.trans.close()
+ self.co._iprot.trans.open()
+ res = getattr(self.co, name)(*args, **kw)
+ self.co._iprot.trans.close()
+ raise
+ self.co._iprot.trans.close()
+ return res
+ return connectWrap
+
+ def __getitem__(self, hostname):
+ port = self.port
+ if len(hostname) == 2:
+ port = hostname[1]
+ hostname = hostname[0]
+ socket = TSocket(hostname, port)
+ socket.setTimeout(self.timeout)
+ transport = TBufferedTransport(socket)
+ protocol = TBinaryProtocol(transport)
+ client = self.clientClass(protocol)
+ client.__transport__ = transport
+ return self.anonClass(client)
Added: incubator/tashi/import/tashi-intel-r399/src/tashi/dfs/__init__.py
URL: http://svn.apache.org/viewvc/incubator/tashi/import/tashi-intel-r399/src/tashi/dfs/__init__.py?rev=710072&view=auto
==============================================================================
--- incubator/tashi/import/tashi-intel-r399/src/tashi/dfs/__init__.py (added)
+++ incubator/tashi/import/tashi-intel-r399/src/tashi/dfs/__init__.py Mon Nov 3 06:45:25 2008
@@ -0,0 +1,2 @@
+from dfsinterface import DfsInterface
+from vfs import Vfs