Merge pull request #74 from xarses/stages
Fixes for stage commit processing
This commit is contained in:
commit
354ea71fdd
20
cli.py
20
cli.py
@ -92,19 +92,13 @@ def init_cli_resource():
|
||||
resource.add_command(show)
|
||||
|
||||
@click.command()
|
||||
@click.argument('path')
|
||||
@click.argument('name')
|
||||
@click.argument('args')
|
||||
def update(args, path):
|
||||
print 'Update', path, args
|
||||
def update(name, args):
|
||||
args = json.loads(args)
|
||||
# Need to load all resources for bubbling effect to take place
|
||||
# TODO: resources can be scattered around, this is a simple
|
||||
# situation when we assume resources are all in one directory
|
||||
base_path, name = os.path.split(path)
|
||||
all = xr.load_all(base_path)
|
||||
all = xr.load_all()
|
||||
r = all[name]
|
||||
r.update(args)
|
||||
|
||||
resource.add_command(update)
|
||||
|
||||
|
||||
@ -154,8 +148,12 @@ def init_changes():
|
||||
changes.add_command(stage)
|
||||
|
||||
@click.command()
|
||||
def commit():
|
||||
operations.commit_changes()
|
||||
@click.option('--one', is_flag=True, default=False)
|
||||
def commit(one):
|
||||
if one:
|
||||
operations.commit_one()
|
||||
else:
|
||||
operations.commit_changes()
|
||||
|
||||
changes.add_command(commit)
|
||||
|
||||
|
@ -202,11 +202,15 @@ def ensure_endpoint_present(keystone, name, public_url, internal_url,
|
||||
def ensure_service_absent(keystone, name, check_mode):
|
||||
""" Ensure the service is absent"""
|
||||
|
||||
raise NotImplementedError()
|
||||
service = get_service(keystone, name)
|
||||
keystone.services.delete(service.id)
|
||||
return True
|
||||
|
||||
def ensure_endpoint_absent(keystone, name, check_mode):
|
||||
""" Ensure the service endpoint """
|
||||
raise NotImplementedError()
|
||||
endpoint = get_endpoint(keystone, name)
|
||||
keystone.endpoints.delete(endpoint.id)
|
||||
return True
|
||||
|
||||
|
||||
def dispatch(keystone, name, service_type, description, public_url,
|
||||
|
@ -15,6 +15,5 @@
|
||||
- {{ admin_port }}:35357
|
||||
volumes:
|
||||
- {{ config_dir }}:/etc/keystone
|
||||
|
||||
- name: wait for keystone
|
||||
wait_for: host={{ip}} port={{port}} timeout=20
|
||||
|
@ -4,7 +4,7 @@ version: 1.0.0
|
||||
input:
|
||||
image:
|
||||
schema: str!
|
||||
value: kollaglue/centos-rdo-j-keystone
|
||||
value: kollaglue/centos-rdo-k-keystone
|
||||
config_dir:
|
||||
schema: str!
|
||||
value: /etc/solar/keystone
|
||||
|
@ -1,6 +1,20 @@
|
||||
- hosts: [{{ ip }}]
|
||||
sudo: yes
|
||||
vars:
|
||||
ip: {{ip}}
|
||||
port: {{port}}
|
||||
admin_port: {{admin_port}}
|
||||
tasks:
|
||||
- name: keystone service and endpoint
|
||||
#TODO: not implemented in module
|
||||
pause: seconds=1
|
||||
- name: remove keystone service and endpoint
|
||||
keystone_service:
|
||||
token: {{admin_token}}
|
||||
name: {{name}}
|
||||
type: {{type}}
|
||||
description: {{description}}
|
||||
publicurl: {{publicurl}}
|
||||
internalurl: {{internalurl}}
|
||||
adminurl: {{adminurl}}
|
||||
region: "RegionOne"
|
||||
state: present
|
||||
endpoint: http://{{keystone_host}}:{{keystone_port}}/v2.0/
|
||||
|
||||
|
@ -16,3 +16,4 @@
|
||||
until: result.rc == 0
|
||||
retries: 30
|
||||
delay: 0.5
|
||||
|
||||
|
@ -5,7 +5,7 @@ import handlers
|
||||
def resource_action(resource, action):
|
||||
handler = resource.metadata['handler']
|
||||
with handlers.get(handler)([resource]) as h:
|
||||
h.action(resource, action)
|
||||
return h.action(resource, action)
|
||||
|
||||
|
||||
def tag_action(tag, action):
|
||||
|
@ -3,6 +3,7 @@ import os
|
||||
import subprocess
|
||||
|
||||
from solar.core.handlers.base import BaseHandler
|
||||
from solar.state import STATES
|
||||
|
||||
|
||||
class Ansible(BaseHandler):
|
||||
@ -13,6 +14,7 @@ class Ansible(BaseHandler):
|
||||
print 'playbook_file', playbook_file
|
||||
call_args = ['ansible-playbook', '--module-path', '/vagrant/library', '-i', inventory_file, playbook_file]
|
||||
print 'EXECUTING: ', ' '.join(call_args)
|
||||
|
||||
try:
|
||||
subprocess.check_output(call_args)
|
||||
except subprocess.CalledProcessError as e:
|
||||
|
@ -121,9 +121,10 @@ def disconnect(emitter, receiver):
|
||||
|
||||
for destination in destinations:
|
||||
receiver_input = destination[1]
|
||||
if receiver.args[receiver_input].type_ != 'list':
|
||||
print 'Removing input {} from {}'.format(receiver_input, receiver.name)
|
||||
emitter.args[src].unsubscribe(receiver.args[receiver_input])
|
||||
if receiver_input in receiver.args:
|
||||
if receiver.args[receiver_input].type_ != 'list':
|
||||
print 'Removing input {} from {}'.format(receiver_input, receiver.name)
|
||||
emitter.args[src].unsubscribe(receiver.args[receiver_input])
|
||||
|
||||
|
||||
def disconnect_receiver_by_input(receiver, input):
|
||||
|
@ -11,6 +11,7 @@ db = get_db()
|
||||
|
||||
from dictdiffer import diff, patch, revert
|
||||
import networkx as nx
|
||||
import subprocess
|
||||
|
||||
|
||||
def guess_action(from_, to):
|
||||
@ -78,6 +79,55 @@ def stage_changes():
|
||||
return log
|
||||
|
||||
|
||||
def execute(res, action):
|
||||
try:
|
||||
actions.resource_action(res, action)
|
||||
return state.STATES.success
|
||||
except subprocess.CalledProcessError:
|
||||
return state.STATES.error
|
||||
|
||||
|
||||
def commit(li, resources):
|
||||
commited = state.CD()
|
||||
history = state.CL()
|
||||
staged = state.SL()
|
||||
|
||||
staged_res = resources[li.res]
|
||||
|
||||
staged_data = patch(li.diff, commited.get(li.res, {}))
|
||||
|
||||
# TODO(dshulyak) think about this hack for update
|
||||
if li.action == 'update':
|
||||
commited_res = resource.Resource(
|
||||
staged_res.name,
|
||||
staged_res.metadata,
|
||||
commited[li.res]['args'],
|
||||
commited[li.res]['tags'])
|
||||
result_state = execute(commited_res, 'remove')
|
||||
|
||||
if result_state is state.STATES.success:
|
||||
result_state = execute(staged_res, 'run')
|
||||
else:
|
||||
result_state = execute(staged_res, li.action)
|
||||
|
||||
# resource_action return None in case there is no actions
|
||||
result_state = result_state or state.STATES.success
|
||||
|
||||
commited[li.res] = staged_data
|
||||
li.state = result_state
|
||||
|
||||
history.add(li)
|
||||
|
||||
if result_state is state.STATES.error:
|
||||
raise Exception('Failed')
|
||||
|
||||
|
||||
def commit_one():
|
||||
staged = state.SL()
|
||||
resources = resource.load_all()
|
||||
commit(staged.popleft(), resources)
|
||||
|
||||
|
||||
def commit_changes():
|
||||
# just shortcut to test stuff
|
||||
commited = state.CD()
|
||||
@ -86,25 +136,7 @@ def commit_changes():
|
||||
resources = resource.load_all()
|
||||
|
||||
while staged:
|
||||
l = staged.popleft()
|
||||
wrapper = resources[l.res]
|
||||
|
||||
staged_data = patch(l.diff, commited.get(l.res, {}))
|
||||
|
||||
# TODO(dshulyak) think about this hack for update
|
||||
if l.action == 'update':
|
||||
commited_args = commited[l.res]['args']
|
||||
wrapper.update(commited_args)
|
||||
actions.resource_action(wrapper, 'remove')
|
||||
|
||||
wrapper.update(staged_data.get('args', {}))
|
||||
actions.resource_action(wrapper, 'run')
|
||||
else:
|
||||
actions.resource_action(wrapper, l.action)
|
||||
|
||||
commited[l.res] = staged_data
|
||||
l.state = state.STATES.success
|
||||
history.add(l)
|
||||
commit(staged.popleft(), resources)
|
||||
|
||||
|
||||
def rollback(log_item):
|
||||
@ -128,7 +160,7 @@ def rollback(log_item):
|
||||
log_item.res, df, guess_action(commited, staged))
|
||||
log.add(log_item)
|
||||
|
||||
res = resource.wrap_resource(db.get_resource(log_item.res))
|
||||
res = db.get_obj_resource(log_item.res)
|
||||
res.update(staged.get('args', {}))
|
||||
res.save()
|
||||
|
||||
@ -136,7 +168,7 @@ def rollback(log_item):
|
||||
|
||||
|
||||
def rollback_uid(uid):
|
||||
item = next(l for l in state.CL() if l.uuid == uid)
|
||||
item = next(l for l in state.CL() if l.uid == uid)
|
||||
return rollback(item)
|
||||
|
||||
|
||||
|
@ -75,10 +75,10 @@ class Log(object):
|
||||
|
||||
def __init__(self, path):
|
||||
self.path = path
|
||||
items = []
|
||||
if path in db:
|
||||
items = db[path]
|
||||
else:
|
||||
items = []
|
||||
items = db[path] or items
|
||||
|
||||
self.items = deque([LogItem(
|
||||
l['uid'], l['res'],
|
||||
l['diff'], l['action'],
|
||||
@ -120,10 +120,9 @@ class Data(collections.MutableMapping):
|
||||
|
||||
def __init__(self, path):
|
||||
self.path = path
|
||||
self.store = {}
|
||||
if path in db:
|
||||
self.store = db[path]
|
||||
else:
|
||||
self.store = {}
|
||||
self.store = db[path] or self.store
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self.store[key]
|
||||
|
Loading…
x
Reference in New Issue
Block a user