Skip to content

Commit

Permalink
Mulligan!
Browse files Browse the repository at this point in the history
  • Loading branch information
ndenny committed Apr 1, 2025
1 parent b7f6f44 commit 9fcbbff
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 61 deletions.
98 changes: 43 additions & 55 deletions bin/bastion.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@
sys.path.insert(0, str(LIB_PATH))


from Bastion.Common import Boggle, asPath, toJDN
from Bastion.Common import Boggle, asPath, toJDN
from Bastion.Chronology import Quantim
from Bastion.Site import Site
from Bastion.Condo import Condex
from Bastion.Model import ARK, isAsset
from Bastion.CARP import Request, isResult, isReport, BagReceipt
from Bastion.Model import ARK
from Bastion.CARP import Request, isResult, isReport
import Bastion.Vaults.HPSS
import Bastion.Vaults.BFD
import Bastion.Vaults.SFTP
Expand Down Expand Up @@ -119,31 +119,18 @@ def site(self, s):
def asset(self, ark):
return self.site(ark.site).asset(ark)

def vault(self, which, site = None):
def vault(self, name, site = None):
"""
I answer an instance of a storage vault given a name and optional site.
.vault(name:str)
.vault(asset:isAsset)
.vault(ark:ARK)
"""
if isinstance(which, str):
name = which
if ((name[0] == '{') and (name[-1] == '}')):
name = name[1:-1]
if name in self.conf['vaults']:
protocol = self.conf['vaults'][name]['protocol']
cls = Bastion.Model.Vault.handling(protocol)
return cls(name).configured(self.conf)

if isinstance(which, isAsset):
asset = which
return self.vault(asset.policy.vault)

if isinstance(which, ARK):
asset = self.asset(which)
return self.vault(asset.policy.vault)

return None
if ((name[0] == '{') and (name[-1] == '}')):
name = name[1:-1]
if name in self.conf['vaults']:
protocol = self.conf['vaults'][name]['protocol']
cls = Bastion.Model.Vault.handling(protocol)
return cls(name).configured(self.conf)
else:
return None

@property
def sites(self):
Expand Down Expand Up @@ -259,25 +246,25 @@ def run(self):
else:
sys.exit(1)

def remember(self, result):
def remember(self, answer):
"""
Given an answer structure and opts (as a dict),
I serialize the answer to YAML and save the answer as a file in the logs.
I need answer to include "log.scope" in the context block.
If no "log.scope" is declared, I silently ignore the request to record.
"""
if 'log.scope' in result.request.context:
if 'log.scope' in answer.request.context:
#-- only write a log file if we have an explicit log.scope in the answer's context block.
session = result.request.ID
session = answer.request.ID

scope = self.logroot
if result.request.context['log.scope'] != '*':
scope = scope / result.request.context['log.scope']
if answer.request.context['log.scope'] != '*':
scope = scope / answer.request.context['log.scope']

halo = scope / "{}.yaml".format(session)
halo.parent.mkdir(parents = True, exist_ok = True)
with open(halo, 'wt') as fout:
self.emit_YAML(toJDN(result), fout)
self.emit_YAML(answer.toJDN(), fout)

def emit(self, answer, ostream = None):
ostream = ostream if (ostream is not None) else sys.stdout
Expand All @@ -300,7 +287,6 @@ def emit_JSON(self, result, ostream):

def emit_PROSE(self, result, ostream):
request = result.request
ostream.write("ID: {}\n".format(request.ID))
ostream.write("request: {}\n".format(request.lede))
ostream.write("reply: {reply.code} {reply.gloss}\n".format(reply=result.status))
ostream.write("# {reply.lede}\n".format(reply=result))
Expand Down Expand Up @@ -359,7 +345,7 @@ def do_bank_asset(self, request):
request['log.scope'] = "site/{}".format(ark.site)
result = vault.push(asset, client = self.hostname)

if result.succeeded:
if result.indicates_success:
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)))
Expand Down Expand Up @@ -399,7 +385,7 @@ def do_bank_zone(self, request):

site = self.site(ark)
zone = site.zone(ark)
arks = [asset.ARK for asset in zone]
arks = [asset.ark for asset in zone]
request['log.scope'] = "site/{}".format(site.name)
return self._bank_assets(request, arks)

Expand All @@ -415,17 +401,18 @@ def _bank_assets(self, request, arks):
"""
helper method to push (bank) many assets given a single (batched) request.
"""
results = BagReceipt()
results = [ ]
for ark in arks:
asset = self.asset(ark)
vault = self.vault(asset)
vault = self.vault(asset.policy.vault)
result = vault.push(asset, client = self.hostname)
results.append(result)

all_succeeded = all([result.succeeded for result in results])
all_failed = all([result.failed for result in results])
all_succeeded = all([result.indicates_success for result in results])
all_failed = all([result.indicates_failure for result in results])

pushed = [result['blonde'] for result in results if result.indicates_success]

pushed = [result.blonde for result in results if result.succeeded]
if all_succeeded:
return request.succeeded(results, report = "all {} assets successfully pushed".format(len(results)))
elif all_failed:
Expand All @@ -450,15 +437,14 @@ def do_amend_asset(self, request):
site = self.site(ark)
asset = site.asset(ark)
vault = self.vault(asset.policy.vault)
result = vault.amend(asset)
action = vault.amend(asset)

request['log.scope'] = "site/{}".format(ark.site)

if result.indicates_success:
blonde = result.body['blonde']
return request.succeeded(result, report = "amended asset {} to {}".format(str(ark), str(blonde)))
if action.succeeded:
return request.succeeded(action, report = "amended asset {} to {}".format(str(ark), str(action.blonde)))
else:
return request.failed(result, report = "amend operation on asset {} failed".format(str(ark)))
return request.failed(action, report = "amend operation on asset {} failed".format(str(ark)))

def do_amend_site(self, request):
"""
Expand Down Expand Up @@ -495,25 +481,25 @@ def do_amend_zone(self, request):

site = self.site(ark)
zone = site.zone(ark)
arks = [asset.ARK for asset in zone]
arks = [asset.ark for asset in zone]
request['log.scope'] = "site/{}".format(site.name)
return self._amend_assets(request, arks)

def _amend_assets(self, request, arks):
"""
helper method to amend (differential backup) many assets given a single (batched) request.
"""
results = BagReceipt()
results = [ ]
for ark in arks:
asset = self.asset(ark)
vault = self.vault(asset.policy.vault)
result = vault.amend(asset, client = self.hostname)
results.append(result)

all_succeeded = all([result.succeeded for result in results])
all_failed = all([result.failed for result in results])
amended = [result.blonde for result in results if result.succeeded]
all_succeeded = all([result.indicates_success for result in results])
all_failed = all([result.indicates_failure for result in results])

amended = [result['blonde'] for result in results if result.indicates_success]

if all_succeeded:
return request.succeeded(result, report = "all {} assets successfully amended".format(len(results)))
Expand Down Expand Up @@ -670,10 +656,9 @@ def do_export_site_catalog(self, request):
for asset_name in catalog[zone_name]:
manifest = vault.manifest(ARK(site_name, zone_name, asset_name))
anchor = manifest.head.anchor
origin = manifest.head.earliest.isoformat()
recent = manifest.head.latest.isoformat()
#doclins.append("* {} {} ({} → {})".format(asset_name, str(anchor), origin, recent))
doclins.append(" * {}".format(repr(manifest.head)))
origin = anchor.when.datetime.isoformat()
recent = manifest.head.tail.when.datetime.isoformat()
doclins.append("* {} {} ({} → {})".format(asset_name, str(anchor), origin, recent))
doc = '\n'.join(doclins)

return request.succeeded(catalog, report = doc)
Expand All @@ -700,6 +685,9 @@ def do_export_zones_provisioned(self, request):
* lists all zones provisioned in the given vault for the named site
"""
vault = self.vault( request.args[0] )
if not vault:
return request.failed(None, "no vault {} exists".format(vault))

site_name = request.args[1]

zone_names = vault.zones(site_name)
Expand Down Expand Up @@ -823,7 +811,7 @@ def do_refresh_keytab(self, request):
rusina = app.site('rusina')
soundscapes = rusina.zone('soundscapes')
asset = soundscapes['HackathonData']
vault = app.vault(asset)
vault = app.vault(asset.policy.vault)
else:
app.run( )

Expand Down
10 changes: 4 additions & 6 deletions lib/Bastion/Clerks/SFTP.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@ def assets(self, site, zone):
assets = [ ]
zroot = self.scurler / site / zone
if zroot.exists( ):
for alien in zroot.is_dir():
assets.append(alien.name)
for alien in zroot:
if alien.is_folder:
assets.append(alien.name)
return tuple(sorted(assets))

def manifest(self, *args):
Expand All @@ -75,12 +76,9 @@ def manifest(self, *args):

blondes = [ ]
cell = self.scurler / ark.site / ark.zone / ark.asset
print("CELL:", cell)
print(type(cell))
if cell.exists:
for alien in cell.lsall():
print("ALIEN: ", alien)
if not alien.is_dir():
if not alien.is_folder:
blondes.append( BLONDE.decode(alien.stem) )
manifest = Manifest(ark, blondes)

Expand Down
2 changes: 2 additions & 0 deletions lib/Bastion/Site.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ def named(nm):
def __new__(cls, site):
if isinstance(site, cls):
return site
elif isinstance(site, ARK):
return cls(site.site)
else:
if site in Site.SITES:
return Site.SITES[site]
Expand Down

0 comments on commit 9fcbbff

Please sign in to comment.