diff --git a/xos/openstack_xos/__init__.py b/xos/openstack_xos/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/xos/openstack_xos/__init__.py
+++ /dev/null
diff --git a/xos/openstack_xos/client.py b/xos/openstack_xos/client.py
deleted file mode 100644
index d1383f4..0000000
--- a/xos/openstack_xos/client.py
+++ /dev/null
@@ -1,210 +0,0 @@
-import urlparse
-try:
-    from keystoneauth1.identity import v2 as keystoneauth_v2
-    from keystoneauth1 import session as keystone_session
-    from keystoneclient.v2_0 import client as keystone_client
-    #from glance import client as glance_client
-    import glanceclient
-    from novaclient.v2 import client as nova_client
-    from neutronclient.v2_0 import client as neutron_client 
-    has_openstack = True
-except:
-    has_openstack = False
-
-from xos.config import Config
-
-def require_enabled(callable):
-    def wrapper(*args, **kwds):
-        if has_openstack:
-            return callable(*args, **kwds)
-        else:
-            return None
-    return wrapper
-
-def parse_novarc(filename):
-    opts = {}
-    f = open(filename, 'r')
-    for line in f:
-        try:
-            line = line.replace('export', '').strip()
-            parts = line.split('=')
-            if len(parts) > 1:
-                value = parts[1].replace("\'", "")
-                value = value.replace('\"', '')
-                opts[parts[0]] = value
-        except:
-            pass
-    f.close()
-    return opts
-
-class Client:
-    def __init__(self, username=None, password=None, tenant=None, url=None, token=None, endpoint=None, controller=None, cacert=None, admin=True, *args, **kwds):
-       
-        self.has_openstack = has_openstack
-        self.url = controller.auth_url
-        if admin:
-            self.username = controller.admin_user
-            self.password = controller.admin_password
-            self.tenant = controller.admin_tenant
-        else:
-            self.username = None
-            self.password = None
-            self.tenant = None
-
-        if username:
-            self.username = username
-        if password:
-            self.password = password
-        if tenant:
-            self.tenant = tenant
-        if url:
-            self.url = url
-        if token:
-            self.token = token    
-        if endpoint:
-            self.endpoint = endpoint
-
-        if cacert:
-            self.cacert = cacert
-        else:
-            self.cacert = getattr(Config(), "nova_ca_ssl_cert", "None")
-
-        #if '@' in self.username:
-        #    self.username = self.username[:self.username.index('@')]
-
-class KeystoneClient(Client):
-    def __init__(self, *args, **kwds):
-        Client.__init__(self, *args, **kwds)
-        if has_openstack:
-            auth = keystoneauth_v2.Password(username=self.username,
-                                            password=self.password,
-                                            tenant_name=self.tenant,
-                                            auth_url=self.url,
-                                            )
-            sess = keystone_session.Session(auth=auth, verify=self.cacert, )
-            self.client = keystone_client.Client(session=sess)
-
-    @require_enabled
-    def connect(self, *args, **kwds):
-        self.__init__(*args, **kwds)
-
-    @require_enabled
-    def __getattr__(self, name):
-        return getattr(self.client, name)
-
-
-class Glance(Client):
-    def __init__(self, *args, **kwds):
-        Client.__init__(self, *args, **kwds)
-        if has_openstack:
-            self.client = glanceclient.get_client(host='0.0.0.0',
-                                                   username=self.username,
-                                                   password=self.password,
-                                                   tenant=self.tenant,
-                                                   auth_url=self.url,
-                                                   cacert=self.cacert
-                                                   )
-    @require_enabled
-    def __getattr__(self, name):
-        return getattr(self.client, name)
-
-class GlanceClient(Client):
-    def __init__(self, version, endpoint, token, cacert=None, *args, **kwds):
-        Client.__init__(self, *args, **kwds)
-        if has_openstack:
-            self.client = glanceclient.Client(version, 
-                endpoint=endpoint, 
-                token=token,
-                cacert=cacert
-            )
-
-    @require_enabled
-    def __getattr__(self, name):
-        return getattr(self.client, name)        
-
-class NovaClient(Client):
-    def __init__(self, *args, **kwds):
-        Client.__init__(self, *args, **kwds)
-        if has_openstack:
-            self.client = nova_client.client.Client(
-                    "2",
-                    username=self.username,
-                    api_key=self.password,
-                    project_id=self.tenant,
-                    auth_url=self.url,
-                    region_name='',
-                    extensions=[],
-                    service_type='compute',
-                    service_name='',
-                    cacert=self.cacert
-                    )
-
-    @require_enabled
-    def connect(self, *args, **kwds):
-        self.__init__(*args, **kwds)
-
-    @require_enabled
-    def __getattr__(self, name):
-        return getattr(self.client, name)
-
-class NovaDB(Client):
-    def __init__(self, *args, **kwds):
-        Client.__init__(self, *args, **kwds)
-        if has_openstack:
-            self.ctx = get_admin_context()
-            nova_db_api.FLAGS(default_config_files=['/etc/nova/nova.conf'])
-            self.client = nova_db_api
-
-
-    @require_enabled
-    def connect(self, *args, **kwds):
-        self.__init__(*args, **kwds)
-
-    @require_enabled
-    def __getattr__(self, name):
-        return getattr(self.client, name)
-
-class NeutronClient(Client):
-    def __init__(self, *args, **kwds):
-        Client.__init__(self, *args, **kwds)
-        if has_openstack:
-            self.client = neutron_client.Client(username=self.username,
-                                                password=self.password,
-                                                tenant_name=self.tenant,
-                                                auth_url=self.url,
-                                                ca_cert=self.cacert
-                                                )
-    @require_enabled
-    def connect(self, *args, **kwds):
-        self.__init__(*args, **kwds)
-
-    @require_enabled
-    def __getattr__(self, name):
-        return getattr(self.client, name)
-
-class OpenStackClient:
-    """
-    A simple native shell to the openstack backend services.
-    This class can receive all nova calls to the underlying testbed
-    """
-
-    def __init__ ( self, *args, **kwds) :
-        # instantiate managers
-        self.keystone = KeystoneClient(*args, **kwds)
-        url_parsed = urlparse.urlparse(self.keystone.url)
-        hostname = url_parsed.netloc.split(':')[0]
-        token = self.keystone.client.tokens.authenticate(username=self.keystone.username, password=self.keystone.password, tenant_name=self.keystone.tenant)
-#        glance_endpoint = self.keystone.client.service_catalog.url_for(service_type='image', endpoint_type='publicURL')
-#        self.glanceclient = GlanceClient('1', endpoint=glance_endpoint, token=token.id, **kwds)
-        self.nova = NovaClient(*args, **kwds)
-        # self.nova_db = NovaDB(*args, **kwds)
-        self.neutron = NeutronClient(*args, **kwds)
-    
-
-    @require_enabled
-    def connect(self, *args, **kwds):
-        self.__init__(*args, **kwds)
-
-    @require_enabled
-    def authenticate(self):
-        return self.keystone.authenticate()
diff --git a/xos/openstack_xos/driver.py b/xos/openstack_xos/driver.py
deleted file mode 100644
index 3064eb2..0000000
--- a/xos/openstack_xos/driver.py
+++ /dev/null
@@ -1,488 +0,0 @@
-import commands
-import hashlib
-from xos.config import Config
-from core.models import Controller
-
-try:
-    from openstack_xos.client import OpenStackClient
-    has_openstack = True
-except:
-    has_openstack = False
-
-manager_enabled = Config().api_nova_enabled
-
-class OpenStackDriver:
-
-    def __init__(self, config = None, client=None):
-        if config:
-            self.config = Config(config)
-        else:
-            self.config = Config()
-
-        if client:
-            self.shell = client
-
-        self.enabled = manager_enabled
-        self.has_openstack = has_openstack
-        self.controller = None
-        self.admin_user = None
-
-    def client_driver(self, caller=None, tenant=None, controller=None):
-        if caller:
-            auth = {'username': caller.email,
-                    'password': hashlib.md5(caller.password).hexdigest()[:6],
-                    'tenant': tenant}
-            client = OpenStackClient(controller=controller, cacert=self.config.nova_ca_ssl_cert, **auth)
-        else:
-            admin_driver = self.admin_driver(tenant=tenant, controller=controller)
-            client = OpenStackClient(tenant=tenant, controller=admin_driver.controller)
-
-        driver = OpenStackDriver(client=client)
-        #driver.admin_user = admin_driver.admin_user
-        #driver.controller = admin_driver.controller
-        return driver
-
-    def admin_driver(self, tenant=None, controller=None):
-        if isinstance(controller, int):
-            controller = Controller.objects.get(id=controller.id)
-        if not tenant:
-            tenant = controller.admin_tenant
-        client = OpenStackClient(tenant=tenant, controller=controller, cacert=self.config.nova_ca_ssl_cert)
-        driver = OpenStackDriver(client=client)
-        driver.admin_user = client.keystone.users.find(name=controller.admin_user)
-        driver.controller = controller
-        return driver
-
-    def create_role(self, name):
-        roles = self.shell.keystone.roles.findall(name=name)
-        roles_title = self.shell.keystone.roles.findall(name=name.title())
-        roles_found = roles + roles_title
-        if not roles_found:
-            role = self.shell.keystone.roles.create(name)
-        else:
-            role = roles_found[0]
-        return role
-
-    def delete_role(self, filter):
-        roles = self.shell.keystone.roles.findall(**filter)
-        for role in roles:
-            self.shell.keystone.roles.delete(role)
-        return 1
-
-    def create_tenant(self, tenant_name, enabled, description):
-        """Create keystone tenant. Suggested fields: name, description, enabled"""
-        tenants = self.shell.keystone.tenants.findall(name=tenant_name)
-        if not tenants:
-            fields = {'tenant_name': tenant_name, 'enabled': enabled,
-                      'description': description}
-            tenant = self.shell.keystone.tenants.create(**fields)
-        else:
-            tenant = tenants[0]
-
-        # always give the admin user the admin role to any tenant created
-        # by the driver.
-        self.add_user_role(self.admin_user.id, tenant.id, 'admin')
-        return tenant
-
-    def update_tenant(self, id, **kwds):
-        return self.shell.keystone.tenants.update(id, **kwds)
-
-    def delete_tenant(self, id):
-        # FIXME: nova_db is commented out in clients.py, throws errors.
-        # Commenting this out for the time being until actually fixed
-
-        #ctx = self.shell.nova_db.ctx
-        tenants = self.shell.keystone.tenants.findall(id=id)
-        for tenant in tenants:
-            # nova does not automatically delete the tenant's instances
-            # so we manually delete instances before deleting the tenant
-            #instances = self.shell.nova_db.instance_get_all_by_filters(ctx,
-            #          {'project_id': tenant.id}, 'id', 'asc')
-            #client = OpenStackClient(tenant=tenant.name)
-            #driver = OpenStackDriver(client=client)
-            #for instance in instances:
-            #    driver.destroy_instance(instance.id)
-            self.shell.keystone.tenants.delete(tenant)
-        return 1
-
-    def create_user(self, name, email, password, enabled):
-        users = self.shell.keystone.users.findall(email=email)
-        if not users:
-            fields = {'name': name, 'email': email, 'password': password,
-                      'enabled': enabled}
-            user = self.shell.keystone.users.create(**fields)
-        else:
-            user = users[0]
-        return user
-
-    def delete_user(self, id):
-        users = self.shell.keystone.users.findall(id=id)
-        for user in users:
-            # delete users keys
-            keys = self.shell.nova.keypairs.findall()
-            for key in keys:
-                self.shell.nova.keypairs.delete(key)
-            self.shell.keystone.users.delete(user)
-        return 1
-
-    def get_admin_role(self):
-        role = None
-        for admin_role_name in ['admin', 'Admin']:
-            roles = self.shell.keystone.roles.findall(name=admin_role_name)
-            if roles:
-                role = roles[0]
-                break
-        return role
-
-    def add_user_role(self, kuser_id, tenant_id, role_name):
-        user = self.shell.keystone.users.find(id=kuser_id)
-        tenant = self.shell.keystone.tenants.find(id=tenant_id)
-        # admin role can be lowercase or title. Look for both
-        role = None
-        if role_name.lower() == 'admin':
-            role = self.get_admin_role()
-        else:
-            # look up non admin role or force exception when admin role isnt found
-            role = self.shell.keystone.roles.find(name=role_name)
-
-        role_found = False
-        user_roles = user.list_roles(tenant.id)
-        for user_role in user_roles:
-            if user_role.name == role.name:
-                role_found = True
-        if not role_found:
-            tenant.add_user(user, role)
-
-        return 1
-
-    def delete_user_role(self, kuser_id, tenant_id, role_name):
-        user = self.shell.keystone.users.find(id=kuser_id)
-        tenant = self.shell.keystone.tenants.find(id=tenant_id)
-        # admin role can be lowercase or title. Look for both
-        role = None
-        if role_name.lower() == 'admin':
-            role = self.get_admin_role()
-        else:
-            # look up non admin role or force exception when admin role isnt found
-            role = self.shell.keystone.roles.find(name=role_name)
-
-        role_found = False
-        user_roles = user.list_roles(tenant.id)
-        for user_role in user_roles:
-            if user_role.name == role.name:
-                role_found = True
-        if role_found:
-            tenant.remove_user(user, role)
-
-        return 1
-
-    def update_user(self, id, fields):
-        if 'password' in fields:
-            self.shell.keystone.users.update_password(id, fields['password'])
-        if 'enabled' in fields:
-            self.shell.keystone.users.update_enabled(id, fields['enabled'])
-        return 1
-
-    def create_router(self, name, set_gateway=True):
-        routers = self.shell.neutron.list_routers(name=name)['routers']
-        if routers:
-            router = routers[0]
-        else:
-            router = self.shell.neutron.create_router({'router': {'name': name}})['router']
-        # add router to external network
-        if set_gateway:
-            nets = self.shell.neutron.list_networks()['networks']
-            for net in nets:
-                if net['router:external'] == True:
-                    self.shell.neutron.add_gateway_router(router['id'],
-                                                          {'network_id': net['id']})
-
-        return router
-
-    def delete_router(self, id):
-        routers = self.shell.neutron.list_routers(id=id)['routers']
-        for router in routers:
-            self.shell.neutron.delete_router(router['id'])
-            # remove router form external network
-            #nets = self.shell.neutron.list_networks()['networks']
-            #for net in nets:
-            #    if net['router:external'] == True:
-            #        self.shell.neutron.remove_gateway_router(router['id'])
-
-    def add_router_interface(self, router_id, subnet_id):
-        router = self.shell.neutron.show_router(router_id)['router']
-        subnet = self.shell.neutron.show_subnet(subnet_id)['subnet']
-        if router and subnet:
-            self.shell.neutron.add_interface_router(router_id, {'subnet_id': subnet_id})
-
-    def delete_router_interface(self, router_id, subnet_id):
-        router = self.shell.neutron.show_router(router_id)
-        subnet = self.shell.neutron.show_subnet(subnet_id)
-        if router and subnet:
-            self.shell.neutron.remove_interface_router(router_id, {'subnet_id': subnet_id})
-
-    def create_network(self, name, shared=False):
-        nets = self.shell.neutron.list_networks(name=name)['networks']
-        if nets:
-            net = nets[0]
-        else:
-            net = self.shell.neutron.create_network({'network': {'name': name, 'shared': shared}})['network']
-        return net
-
-    def delete_network(self, id):
-        nets = self.shell.neutron.list_networks()['networks']
-        for net in nets:
-            if net['id'] == id:
-                # delete_all ports
-                self.delete_network_ports(net['id'])
-                # delete all subnets:
-                for subnet_id in net['subnets']:
-                    self.delete_subnet(subnet_id)
-                self.shell.neutron.delete_network(net['id'])
-        return 1
-
-    def delete_network_ports(self, network_id):
-        ports = self.shell.neutron.list_ports()['ports']
-        for port in ports:
-            if port['network_id'] == network_id:
-                self.shell.neutron.delete_port(port['id'])
-        return 1
-
-    def delete_subnet_ports(self, subnet_id):
-        ports = self.shell.neutron.list_ports()['ports']
-        for port in ports:
-            delete = False
-            for fixed_ip in port['fixed_ips']:
-                if fixed_ip['subnet_id'] == subnet_id:
-                    delete=True
-                    break
-            if delete:
-                self.shell.neutron.delete_port(port['id'])
-        return 1
-
-    def create_subnet(self, name, network_id, cidr_ip, ip_version, start, end):
-        #nets = self.shell.neutron.list_networks(name=network_name)['networks']
-        #if not nets:
-        #    raise Exception, "No such network: %s" % network_name
-        #net = nets[0]
-
-        subnet = None
-        subnets = self.shell.neutron.list_subnets()['subnets']
-        for snet in subnets:
-            if snet['cidr'] == cidr_ip and snet['network_id'] == network_id:
-                subnet = snet
-
-        if not subnet:
-            # HACK: Add metadata route -- Neutron does not reliably supply this
-            metadata_ip = cidr_ip.replace("0/24", "3")
-
-            allocation_pools = [{'start': start, 'end': end}]
-            subnet = {'subnet': {'name': name,
-                                 'network_id': network_id,
-                                 'ip_version': ip_version,
-                                 'cidr': cidr_ip,
-                                 #'dns_nameservers': ['8.8.8.8', '8.8.4.4'],
-                                 'host_routes': [{'destination':'169.254.169.254/32','nexthop':metadata_ip}],
-                                 'gateway_ip': None,
-                                 'allocation_pools': allocation_pools}}
-            subnet = self.shell.neutron.create_subnet(subnet)['subnet']
-            # self.add_external_route(subnet)
-
-        return subnet
-
-    def update_subnet(self, id, fields):
-        return self.shell.neutron.update_subnet(id, fields)
-
-    def delete_subnet(self, id):
-        #return self.shell.neutron.delete_subnet(id=id)
-        # inefficient but fault tolerant
-        subnets = self.shell.neutron.list_subnets()['subnets']
-        for subnet in subnets:
-            if subnet['id'] == id:
-                self.delete_subnet_ports(subnet['id'])
-                self.shell.neutron.delete_subnet(id)
-                self.delete_external_route(subnet)
-        return 1
-
-    def get_external_routes(self):
-        status, output = commands.getstatusoutput('route')
-        routes = output.split('\n')[3:]
-        return routes
-
-    def add_external_route(self, subnet, routes=[]):
-        if not routes:
-            routes = self.get_external_routes()
-
-        ports = self.shell.neutron.list_ports()['ports']
-
-        gw_ip = subnet['gateway_ip']
-        subnet_id = subnet['id']
-
-        # 1. Find the port associated with the subnet's gateway
-        # 2. Find the router associated with that port
-        # 3. Find the port associated with this router and on the external net
-        # 4. Set up route to the subnet through the port from step 3
-        ip_address = None
-        for port in ports:
-            for fixed_ip in port['fixed_ips']:
-                if fixed_ip['subnet_id'] == subnet_id and fixed_ip['ip_address'] == gw_ip:
-                    gw_port = port
-                    router_id = gw_port['device_id']
-                    router = self.shell.neutron.show_router(router_id)['router']
-                    if router and router.get('external_gateway_info'):
-                        ext_net = router['external_gateway_info']['network_id']
-                        for port in ports:
-                            if port['device_id'] == router_id and port['network_id'] == ext_net:
-                                ip_address = port['fixed_ips'][0]['ip_address']
-
-        if ip_address:
-            # check if external route already exists
-            route_exists = False
-            if routes:
-                for route in routes:
-                    if subnet['cidr'] in route and ip_address in route:
-                        route_exists = True
-            if not route_exists:
-                cmd = "route add -net %s dev br-ex gw %s" % (subnet['cidr'], ip_address)
-                s, o = commands.getstatusoutput(cmd)
-                #print cmd, "\n", s, o
-
-        return 1
-
-    def delete_external_route(self, subnet):
-        ports = self.shell.neutron.list_ports()['ports']
-
-        gw_ip = subnet['gateway_ip']
-        subnet_id = subnet['id']
-
-        # 1. Find the port associated with the subnet's gateway
-        # 2. Find the router associated with that port
-        # 3. Find the port associated with this router and on the external net
-        # 4. Set up route to the subnet through the port from step 3
-        ip_address = None
-        for port in ports:
-            for fixed_ip in port['fixed_ips']:
-                if fixed_ip['subnet_id'] == subnet_id and fixed_ip['ip_address'] == gw_ip:
-                    gw_port = port
-                    router_id = gw_port['device_id']
-                    router = self.shell.neutron.show_router(router_id)['router']
-                    ext_net = router['external_gateway_info']['network_id']
-                    for port in ports:
-                        if port['device_id'] == router_id and port['network_id'] == ext_net:
-                            ip_address = port['fixed_ips'][0]['ip_address']
-
-        if ip_address:
-            cmd = "route delete -net %s" % (subnet['cidr'])
-            commands.getstatusoutput(cmd)
-
-        return 1
-
-    def create_keypair(self, name, public_key):
-        keys = self.shell.nova.keypairs.findall(name=name)
-        if keys:
-            key = keys[0]
-            # update key
-            if key.public_key != public_key:
-                self.delete_keypair(key.id)
-                key = self.shell.nova.keypairs.create(name=name, public_key=public_key)
-        else:
-            key = self.shell.nova.keypairs.create(name=name, public_key=public_key)
-        return key
-
-    def delete_keypair(self, id):
-        keys = self.shell.nova.keypairs.findall(id=id)
-        for key in keys:
-            self.shell.nova.keypairs.delete(key)
-        return 1
-
-    def get_private_networks(self, tenant=None):
-        if not tenant:
-            tenant = self.shell.nova.tenant
-        tenant = self.shell.keystone.tenants.find(name=tenant)
-        search_opts = {"tenant_id": tenant.id, "shared": False}
-        private_networks = self.shell.neutron.list_networks(**search_opts)
-        return private_networks
-
-    def get_shared_networks(self):
-        search_opts = {"shared": True}
-        shared_networks = self.shell.neutron.list_networks(**search_opts)
-        return shared_networks
-
-    def get_network_subnet(self, network_id):
-        subnet_id = None
-        subnet = None
-        if network_id:
-            os_networks = self.shell.neutron.list_networks(id=network_id)["networks"]
-            if os_networks:
-                os_network = os_networks[0]
-                if os_network['subnets']:
-                    subnet_id = os_network['subnets'][0]
-                    os_subnets = self.shell.neutron.list_subnets(id=subnet_id)['subnets']
-                    if os_subnets:
-                        subnet = os_subnets[0]['cidr']
-
-        return (subnet_id, subnet)
-
-    def spawn_instance(self, name, key_name=None, availability_zone=None, hostname=None, image_id=None, security_group=None, pubkeys=[], nics=None, metadata=None, userdata=None, flavor_name=None):
-        if not flavor_name:
-            flavor_name = self.config.nova_default_flavor
-
-        flavor = self.shell.nova.flavors.find(name=flavor_name)
-
-        if not security_group:
-            security_group = self.config.nova_default_security_group
-
-        files = {}
-        #if pubkeys:
-        #    files["/root/.ssh/authorized_keys"] = "\n".join(pubkeys).encode('base64')
-        hints = {}
-
-        # determine availability zone and compute host
-        availability_zone_filter = None
-        if availability_zone is None or not availability_zone:
-            availability_zone_filter = 'nova'
-        else:
-            availability_zone_filter = availability_zone
-        if hostname:
-            availability_zone_filter += ':%s' % hostname
-
-        server = self.shell.nova.servers.create(
-                                            name=name,
-                                            key_name = key_name,
-                                            flavor=flavor.id,
-                                            image=image_id,
-                                            security_group = security_group,
-                                            #files = files,
-                                            scheduler_hints=hints,
-                                            availability_zone=availability_zone_filter,
-                                            nics=nics,
-                                            networks=nics,
-                                            meta=metadata,
-                                            userdata=userdata)
-        return server
-
-    def destroy_instance(self, id):
-        if (self.shell.nova.tenant=="admin"):
-            # findall() is implemented as a list() followed by a python search of the
-            # list. Since findall() doesn't accept "all_tenants", we do this using
-            # list() ourselves. This allows us to delete an instance as admin.
-            servers = self.shell.nova.servers.list(search_opts={"all_tenants": True})
-        else:
-            servers = self.shell.nova.servers.list()
-        for server in servers:
-            if server.id == id:
-                result=self.shell.nova.servers.delete(server)
-
-    def update_instance_metadata(self, id, metadata):
-        servers = self.shell.nova.servers.findall(id=id)
-        for server in servers:
-            self.shell.nova.servers.set_meta(server, metadata)
-            # note: set_meta() returns a broken Server() object. Don't try to
-            # print it in the shell or it will fail in __repr__.
-
-    def delete_instance_metadata(self, id, metadata):
-        # note: metadata is a dict. Only the keys matter, not the values.
-        servers = self.shell.nova.servers.findall(id=id)
-        for server in servers:
-            self.shell.nova.servers.delete_meta(server, metadata)
-
