Implemented a single storage for resources

This commit is contained in:
Evgeniy L 2015-05-29 12:01:57 +02:00
parent 41a52748dc
commit 2fd5cca1f5
5 changed files with 51 additions and 70 deletions

View File

@ -7,10 +7,8 @@ examples-dir: /vagrant/examples
extensions-dir: /vagrant/solar/solar/extensions extensions-dir: /vagrant/solar/solar/extensions
file-system-db: file-system-db:
resources-path: ./schema/resources
storage-path: /vagrant/tmp/storage storage-path: /vagrant/tmp/storage
template-dir: /vagrant/templates template-dir: /vagrant/templates
resources-files-mask: /vagrant/resources/*/*.yaml resources-files-mask: /vagrant/resources/*/*.yaml
resource-instances-path: /vagrant/tmp/resource-instances
node_resource_template: /vagrant/resources/ro_node/ node_resource_template: /vagrant/resources/ro_node/

View File

@ -107,12 +107,7 @@ class Cmd(object):
lambda r: Expression(args.resources, r.get('tags', [])).evaluate(), lambda r: Expression(args.resources, r.get('tags', [])).evaluate(),
self._get_resources_list()) self._get_resources_list())
resource_instances_path = utils.read_config()['resource-instances-path'] assign_resources_to_nodes(resources, nodes)
utils.create_dir(resource_instances_path)
assign_resources_to_nodes(
resources,
nodes,
resource_instances_path)
def _get_resources_list(self): def _get_resources_list(self):
result = [] result = []

View File

@ -11,19 +11,20 @@ import yaml
import solar import solar
from solar.core import actions from solar.core import actions
from solar.core import db
from solar.core import observer from solar.core import observer
from solar.core import signals from solar.core import signals
from solar import utils from solar import utils
from solar.core import validation from solar.core import validation
from solar.core.connections import ResourcesConnectionGraph from solar.core.connections import ResourcesConnectionGraph
from solar.interfaces.db import get_db
db = get_db()
class Resource(object): class Resource(object):
def __init__(self, name, metadata, args, base_dir, tags=None): def __init__(self, name, metadata, args, tags=None):
self.name = name self.name = name
self.base_dir = base_dir
self.metadata = metadata self.metadata = metadata
self.actions = metadata['actions'].keys() if metadata['actions'] else None self.actions = metadata['actions'].keys() if metadata['actions'] else None
self.args = {} self.args = {}
@ -44,11 +45,10 @@ class Resource(object):
def __repr__(self): def __repr__(self):
return ("Resource(name='{0}', metadata={1}, args={2}, " return ("Resource(name='{0}', metadata={1}, args={2}, "
"base_dir='{3}', tags={4})").format(self.name, "tags={3})").format(self.name,
json.dumps(self.metadata), json.dumps(self.metadata),
json.dumps(self.args_show()), json.dumps(self.args_show()),
self.base_dir, self.tags)
self.tags)
def args_show(self): def args_show(self):
def formatter(v): def formatter(v):
@ -113,24 +113,12 @@ class Resource(object):
for k, v in self.args_dict().items(): for k, v in self.args_dict().items():
metadata['input'][k]['value'] = v metadata['input'][k]['value'] = v
meta_file = os.path.join(self.base_dir, 'meta.yaml') db.add_resource(self.name, metadata)
with open(meta_file, 'w') as f:
f.write(yaml.dump(metadata, default_flow_style=False))
def create(name, base_path, dest_path, args, connections={}): def create(name, base_path, args, connections={}):
if not os.path.exists(base_path): if not os.path.exists(base_path):
raise Exception('Base resource does not exist: {0}'.format(base_path)) raise Exception('Base resource does not exist: {0}'.format(base_path))
if not os.path.exists(dest_path):
raise Exception('Dest dir does not exist: {0}'.format(dest_path))
if not os.path.isdir(dest_path):
raise Exception('Dest path is not a directory: {0}'.format(dest_path))
dest_path = os.path.abspath(os.path.join(dest_path, name))
if os.path.exists(dest_path):
print 'Skip creation of resource {0} because is already exists'.format(dest_path)
return db.get_resource(name) or get_resource_from_db(name)
base_meta_file = os.path.join(base_path, 'meta.yaml') base_meta_file = os.path.join(base_path, 'meta.yaml')
actions_path = os.path.join(base_path, 'actions') actions_path = os.path.join(base_path, 'actions')
@ -139,42 +127,32 @@ def create(name, base_path, dest_path, args, connections={}):
meta['id'] = name meta['id'] = name
meta['version'] = '1.0.0' meta['version'] = '1.0.0'
meta['actions'] = {} meta['actions'] = {}
meta['actions_path'] = actions_path
if os.path.exists(actions_path): if os.path.exists(actions_path):
for f in os.listdir(actions_path): for f in os.listdir(actions_path):
meta['actions'][os.path.splitext(f)[0]] = f meta['actions'][os.path.splitext(f)[0]] = f
resource = Resource(name, meta, args, dest_path, tags=args.get('tags', [])) resource = Resource(name, meta, args, tags=args.get('tags', []))
signals.assign_connections(resource, connections) signals.assign_connections(resource, connections)
# save
shutil.copytree(base_path, dest_path)
resource.save() resource.save()
db.resource_add(name, resource)
return resource return resource
def load(dest_path): def wrap_resource(raw_resource):
meta_file = os.path.join(dest_path, 'meta.yaml') name = raw_resource['id']
meta = utils.load_file(meta_file) args = raw_resource['input']
name = meta['id'] tags = raw_resource.get('tags', [])
args = meta['input']
tags = meta.get('tags', [])
resource = Resource(name, meta, args, dest_path, tags=tags) return Resource(name, raw_resource, args, tags=tags)
db.resource_add(name, resource)
return resource
def load_all(dest_path): def load_all():
ret = {} ret = {}
for name in os.listdir(dest_path): for raw_resource in db.get_list('resource'):
resource_path = os.path.join(dest_path, name) resource = wrap_resource(raw_resource)
resource = load(resource_path)
ret[resource.name] = resource ret[resource.name] = resource
signals.Connections.reconnect_all() signals.Connections.reconnect_all()
@ -182,12 +160,7 @@ def load_all(dest_path):
return ret return ret
def get_resource_from_db(uid): def assign_resources_to_nodes(resources, nodes):
resource_path = os.path.join(solar.utils.read_config()['resource-instances-path'], uid)
return load(resource_path)
def assign_resources_to_nodes(resources, nodes, dst_dir):
for node in nodes: for node in nodes:
for resource in resources: for resource in resources:
res = deepcopy(resource) res = deepcopy(resource)
@ -200,14 +173,14 @@ def assign_resources_to_nodes(resources, nodes, dst_dir):
node_uuid = node['id'] node_uuid = node['id']
node_resource_template = solar.utils.read_config()['node_resource_template'] node_resource_template = solar.utils.read_config()['node_resource_template']
created_resource = create(resource_uuid, resource['dir_path'], dst_dir, res['input']) created_resource = create(resource_uuid, resource['dir_path'], res['input'])
created_node = create(node_uuid, node_resource_template, dst_dir, node) created_node = create(node_uuid, node_resource_template, node)
signals.connect(created_node, created_resource) signals.connect(created_node, created_resource)
def connect_resources(profile): def connect_resources(profile):
connections = profile.get('connections', []) connections = profile.get('connections', [])
resources = load_all(solar.utils.read_config()['resource-instances-path']) resources = load_all()
graph = ResourcesConnectionGraph(connections, resources.values()) graph = ResourcesConnectionGraph(connections, resources.values())
for connection in graph.iter_connections(): for connection in graph.iter_connections():

View File

@ -4,9 +4,11 @@ import itertools
import networkx as nx import networkx as nx
import os import os
import db
from solar import utils from solar import utils
from solar.interfaces.db import get_db
db = get_db()
CLIENTS_CONFIG_KEY = 'clients-data-file' CLIENTS_CONFIG_KEY = 'clients-data-file'
@ -46,10 +48,10 @@ class Connections(object):
:return: :return:
""" """
for emitter_name, dest_dict in CLIENTS.items(): for emitter_name, dest_dict in CLIENTS.items():
emitter = db.get_resource(emitter_name) emitter = db.get_obj_resource(emitter_name)
for emitter_input, destinations in dest_dict.items(): for emitter_input, destinations in dest_dict.items():
for receiver_name, receiver_input in destinations: for receiver_name, receiver_input in destinations:
receiver = db.get_resource(receiver_name) receiver = db.get_obj_resource(receiver_name)
emitter.args[emitter_input].subscribe( emitter.args[emitter_input].subscribe(
receiver.args[receiver_input]) receiver.args[receiver_input])
@ -107,7 +109,7 @@ def connect(emitter, receiver, mapping=None):
def disconnect(emitter, receiver): def disconnect(emitter, receiver):
for src, destinations in CLIENTS[emitter.name].items(): for src, destinations in CLIENTS[emitter.name].items():
disconnect_by_src(emitter, src, receiver) disconnect_by_src(emitter.name, src, receiver)
for destination in destinations: for destination in destinations:
receiver_input = destination[1] receiver_input = destination[1]
@ -125,13 +127,13 @@ def disconnect_receiver_by_input(receiver, input):
""" """
for emitter_name, inputs in CLIENTS.items(): for emitter_name, inputs in CLIENTS.items():
emitter = db.get_resource(emitter_name) emitter = db.get_resource(emitter_name)
disconnect_by_src(emitter, input, receiver) disconnect_by_src(emitter['id'], input, receiver)
def disconnect_by_src(emitter, src, receiver): def disconnect_by_src(emitter_name, src, receiver):
if src in CLIENTS[emitter.name]: if src in CLIENTS[emitter_name]:
CLIENTS[emitter.name][src] = [ CLIENTS[emitter_name][src] = [
destination for destination in CLIENTS[emitter.name][src] destination for destination in CLIENTS[emitter_name][src]
if destination[0] != receiver.name if destination[0] != receiver.name
] ]
@ -143,7 +145,7 @@ def notify(source, key, value):
print 'Notify', source.name, key, value, CLIENTS[source.name] print 'Notify', source.name, key, value, CLIENTS[source.name]
if key in CLIENTS[source.name]: if key in CLIENTS[source.name]:
for client, r_key in CLIENTS[source.name][key]: for client, r_key in CLIENTS[source.name][key]:
resource = db.get_resource(client) resource = db.get_obj_resource(client)
print 'Resource found', client print 'Resource found', client
if resource: if resource:
resource.update({r_key: value}, emitter=source) resource.update({r_key: value}, emitter=source)

View File

@ -13,12 +13,25 @@ from solar import errors
class FileSystemDB(DirDBM): class FileSystemDB(DirDBM):
STORAGE_PATH = utils.read_config()['file-system-db']['storage-path'] STORAGE_PATH = utils.read_config()['file-system-db']['storage-path']
RESOURCE_COLLECTION_NAME = 'resource'
def __init__(self): def __init__(self):
utils.create_dir(self.STORAGE_PATH) utils.create_dir(self.STORAGE_PATH)
super(FileSystemDB, self).__init__(self.STORAGE_PATH) super(FileSystemDB, self).__init__(self.STORAGE_PATH)
self.entities = {} self.entities = {}
def get_resource(self, uid):
return self[self._make_key(self.RESOURCE_COLLECTION_NAME, uid)]
def get_obj_resource(self, uid):
from solar.core.resource import wrap_resource
raw_resource = self[self._make_key(self.RESOURCE_COLLECTION_NAME, uid)]
return wrap_resource(raw_resource)
def add_resource(self, uid, resource):
self[self._make_key(self.RESOURCE_COLLECTION_NAME, uid)] = resource
def store(self, collection, obj): def store(self, collection, obj):
if 'id' in obj: if 'id' in obj:
self[self._make_key(collection, obj['id'])] = obj self[self._make_key(collection, obj['id'])] = obj