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
file-system-db:
resources-path: ./schema/resources
storage-path: /vagrant/tmp/storage
template-dir: /vagrant/templates
resources-files-mask: /vagrant/resources/*/*.yaml
resource-instances-path: /vagrant/tmp/resource-instances
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(),
self._get_resources_list())
resource_instances_path = utils.read_config()['resource-instances-path']
utils.create_dir(resource_instances_path)
assign_resources_to_nodes(
resources,
nodes,
resource_instances_path)
assign_resources_to_nodes(resources, nodes)
def _get_resources_list(self):
result = []

View File

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

View File

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

View File

@ -13,12 +13,25 @@ from solar import errors
class FileSystemDB(DirDBM):
STORAGE_PATH = utils.read_config()['file-system-db']['storage-path']
RESOURCE_COLLECTION_NAME = 'resource'
def __init__(self):
utils.create_dir(self.STORAGE_PATH)
super(FileSystemDB, self).__init__(self.STORAGE_PATH)
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):
if 'id' in obj:
self[self._make_key(collection, obj['id'])] = obj