diff --git a/example-riaks-template.py b/example-riaks-template.py index 654838f7..f114313e 100644 --- a/example-riaks-template.py +++ b/example-riaks-template.py @@ -1,3 +1,10 @@ +from solar.interfaces.db import get_db +from solar.core import signals + +db = get_db() +db.clear() +signals.Connections.clear() + from solar import template @@ -11,7 +18,7 @@ riak_services = nodes.on_each( 'riak_name': 'riak{num}@riak_server{num}.solar', }) -slave_riak_services = riak_services.filter(lambda num: num > 0) +slave_riak_services = riak_services.tail() riak_services.take(0).connect_list( slave_riak_services, @@ -27,7 +34,8 @@ riak_services.connect_list_to_each( { 'ip': 'hosts_ips', 'riak_hostname': 'hosts_names', - } + }, + events=False ) @@ -35,3 +43,71 @@ hosts_files.add_deps('run/success', riak_services, 'run') slave_riak_services.add_reacts('run/success', slave_riak_services, 'join') slave_riak_services.add_reacts('leave/success', slave_riak_services, 'join') slave_riak_services.add_react('run/success', riak_services.take(0), 'commit') + + +haproxy_services = nodes.on_each( + 'resources/haproxy_service' +) +haproxy_configs = nodes.on_each( + 'resources/haproxy_config' +) +haproxy_service_configs_http = nodes.on_each( + 'resources/haproxy_service_config', + { + 'listen_port': 8098, + 'protocol': 'http', + } +) +haproxy_service_configs_pb = nodes.on_each( + 'resources/haproxy_service_config', + { + 'listen_port': 8087, + 'protocol': 'tcp', + } +) + +riak_services.connect_list_to_each( + haproxy_service_configs_http, + { + 'riak_hostname': 'servers', + 'riak_port_http': 'ports', + } +) +riak_services.connect_list_to_each( + haproxy_service_configs_pb, + { + 'riak_hostname': 'servers', + 'riak_port_pb': 'ports', + } +) +haproxy_service_configs_http.connect_list( + haproxy_configs, + { + 'protocol': 'configs_protocols', + 'listen_port': 'listen_ports', + 'name': 'configs_names', + 'servers': 'configs', + 'ports': 'configs_ports', + } +) +haproxy_service_configs_pb.connect_list( + haproxy_configs, + { + 'protocol': 'configs_protocols', + 'listen_port': 'listen_ports', + 'name': 'configs_names', + 'servers': 'configs', + 'ports': 'configs_ports', + } +) +haproxy_configs.connect_list( + haproxy_services, + { + 'listen_ports': 'ports', + } +) + +nodes.add_reacts('run/success', haproxy_services, 'install') +haproxy_services.add_deps('install/success', haproxy_configs, 'run') +haproxy_configs.add_reacts('run/success', haproxy_services, 'run') +haproxy_configs.add_reacts('update/success', haproxy_services, 'update') diff --git a/solar/solar/template.py b/solar/solar/template.py index 4dd65c33..7dab7b03 100644 --- a/solar/solar/template.py +++ b/solar/solar/template.py @@ -9,8 +9,13 @@ from solar.events import controls class BaseTemplate(object): @staticmethod def args_fmt(args, kwargs): + def fmt(v, kwargs): + if isinstance(v, basestring): + return v.format(**kwargs) + return v + return { - k.format(**kwargs): v.format(**kwargs) for k, v in args.items() + fmt(k, kwargs): fmt(v, kwargs) for k, v in args.items() } @staticmethod @@ -27,6 +32,32 @@ class ResourceTemplate(BaseTemplate): def __init__(self, resource): self.resource = resource + def add_dep(self, action_state, resource, action): + action_state = self.action_state_parse(action_state) + + add_event( + controls.Dep( + self.resource.name, + action_state['action'], + action_state['state'], + resource.resource.name, + action + ) + ) + + def add_react(self, action_state, resource, action): + action_state = self.action_state_parse(action_state) + + add_event( + controls.React( + self.resource.name, + action_state['action'], + action_state['state'], + resource.resource.name, + action + ) + ) + def connect_list(self, resources, args={}): for receiver_num, resource in enumerate(resources.resources): kwargs = { @@ -66,53 +97,43 @@ class ResourceListTemplate(BaseTemplate): return ResourceListTemplate(created_resources) def add_deps(self, action_state, resources, action): - action_state = self.action_state_parse(action_state) - for r, dep_r in zip(self.resources, resources.resources): - add_event( - controls.Dep( - r.name, - action_state['action'], - action_state['state'], - dep_r.name, - action - ) + ResourceTemplate(r).add_dep( + action_state, + ResourceTemplate(dep_r), + action ) def add_react(self, action_state, resource, action): - action_state = self.action_state_parse(action_state) - for r in self.resources: - add_event( - controls.React( - r.name, - action_state['action'], - action_state['state'], - resource.resource.name, - action - ) + ResourceTemplate(r).add_react( + action_state, + resource, + action ) def add_reacts(self, action_state, resources, action): - action_state = self.action_state_parse(action_state) - - for r, react_r in zip(self.resources, resources.resources): - add_event( - controls.React( - r.name, - action_state['action'], - action_state['state'], - react_r.name, - action - ) - ) + for r in resources.resources: + self.add_react(action_state, ResourceTemplate(r), action) def filter(self, func): - resources = filter(func, self.resources) + resources = filter(func, enumerate(self.resources)) return ResourceListTemplate(resources) - def connect_list_to_each(self, resources, args={}): + def connect_list(self, resources, args={}, events=None): + for num, er in enumerate(zip(self.resources, resources.resources)): + emitter, receiver = er + + kwargs = { + 'num': num, + } + + args_fmt = self.args_fmt(args, kwargs) + + signals.connect(emitter, receiver, mapping=args_fmt, events=events) + + def connect_list_to_each(self, resources, args={}, events=None): for emitter_num, emitter in enumerate(self.resources): for receiver_num, receiver in enumerate(resources.resources): kwargs = { @@ -122,7 +143,12 @@ class ResourceListTemplate(BaseTemplate): args_fmt = self.args_fmt(args, kwargs) - signals.connect(emitter, receiver, args_fmt) + signals.connect( + emitter, + receiver, + mapping=args_fmt, + events=events + ) def on_each(self, resource_path, args={}): created_resources = ResourceListTemplate.create( @@ -139,6 +165,9 @@ class ResourceListTemplate(BaseTemplate): def take(self, i): return ResourceTemplate(self.resources[i]) + def tail(self): + return ResourceListTemplate(self.resources[1:]) + def nodes_from(template_path): nodes = vr.create('nodes', template_path, {})