diff --git a/bin/bastion.py b/bin/bastion.py index b815e92..b26de0c 100755 --- a/bin/bastion.py +++ b/bin/bastion.py @@ -368,8 +368,7 @@ def do_bank_asset(self, request): result = vault.push(asset, client = self.hostname) if result.indicates_success: - blonde = result.record['blonde'] - return request.succeeded(result, report = "pushed full backup of {} to {}".format(str(ark), str(blonde))) + return request.succeeded(result, report = "pushed full backup of {} to {}".format(str(ark), str(result.blonde))) else: return request.failed(result, report = "while pushing full backup of {}, something went wrong!".format(str(ark))) diff --git a/lib/Bastion/CARP.py b/lib/Bastion/CARP.py index 845ae46..775f54f 100644 --- a/lib/Bastion/CARP.py +++ b/lib/Bastion/CARP.py @@ -26,6 +26,8 @@ import yaml +from collections.abc import Sequence + from Bastion.Common import toJDN class ReplyStatus(tuple): @@ -336,20 +338,36 @@ class isReceiptOfResults(isReceipt): I am a thin wrapper around a sequence of results. I am mostly used to build a single "record" from a sequence of operations, with each operation having its own report. + Results can also be given with a key as part of a tuple such as (stage, result) where stage is a string key. """ def __init__(self, results): self.results = [ ] + self.tags = { } for result in results: if isinstance(result, isResult): self.results.append(result) + elif isinstance(result, Sequence) and (len(result) == 2) and isinstance(result[1], isResult): + tag = str(result[0]) + result_actual = result[1] + self.results.append(result_actual) + self.tags[tag] = len(self.results) else: raise ValueError("result must be an instance of Bastion.CARP.isResult") - def __getitem__(self, i): - return self.results[i] + def __getitem__(self, n): + if isinstance(n, int): + return self.results[n] + if isinstance(n, str): + i = self.keyed[n] + return self.results[i] + raise KeyError(n) def __iter__(self): - return iter(self.results) + staged = [self.results[i] for i in range(len(self.results))] + return iter(staged) def toJDN(self, **kwargs): - return [result.toJDN(**kwargs) for result in self.results] + jdn = { } + jdn['results'] = [result.toJDN(**kwargs) for result in self] + jdn['tags'] = self.tags.copy() + return jdn diff --git a/lib/Bastion/Vaults/CARP.py b/lib/Bastion/Vaults/CARP.py index f822b01..44c7f98 100644 --- a/lib/Bastion/Vaults/CARP.py +++ b/lib/Bastion/Vaults/CARP.py @@ -1,7 +1,7 @@ import logging import datetime -from Bastion.CARP import isRequest, isReceiptOfResults +from Bastion.CARP import isRequest, isReceiptOfResults, isReport from Bastion.Curator import BLONDE logger = logging.getLogger(__name__) @@ -10,6 +10,39 @@ class PushReceipt(isReceiptOfResults): pass +class PushReport(isReport): + #---------------------------------------------------------------------- + #-- BEGIN ACCESSORS | + #-- These properties are pass throughs to the initial request object. | + #-- They are given here only as convenience. | + #↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ + @property + def asset(self): + return self.request['asset'] + + @property + def basis(self): + return self.request['basis'] + + @property + def detail(self): + return self.request['detail'] + + @property + def blonde(self): + return self.request['blonde'] + + @property + def since(self): + return self.request['since'] + + @property + def genus(self): + return self.request['genus'] + #↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ + #-- END ACCESSORS | + #---------------------------------------------------------------------- + class PushRequest(isRequest): """ @@ -80,3 +113,6 @@ def since(self): @property def genus(self): return self['genus'] + + def succeeded(self, record = None, *args, **kwargs): + return PushReport.Success(self, record, *args, **kwargs) \ No newline at end of file diff --git a/lib/Bastion/Vaults/Common.py b/lib/Bastion/Vaults/Common.py index e1647e4..48162b2 100644 --- a/lib/Bastion/Vaults/Common.py +++ b/lib/Bastion/Vaults/Common.py @@ -38,17 +38,18 @@ def push(self, asset, basis = None, **kwargs): packing = self.pack(asset, basis, **kwargs) if packing.failed: - return request.failed( PushReceipt([packing]) ) + return request.failed( PushReceipt([('packed',packing)]) ) movement = self.put(packing.record.tarp, packing.record.tag) - if movement.failed: - return request.failed( PushReceipt([packing, movement]) ) #-- clean up! - #if packing.record.tarp.exists(): - # packing.record.tarp.unlink() + if packing.record.tarp.exists(): + packing.record.tarp.unlink() - return request.succeeded( PushReceipt([packing, movement]) ) + if movement.failed: + return request.failed( PushReceipt([('packed', packing), ('moved', movement)]) ) + else: + return request.succeeded( PushReceipt([('packed', packing), ('moved', movement)]) ) def pull(self, ark, **kwargs): raise NotImplementedError