-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(CLI): StorageTransferAction support
This is based on my suggestion to remove the `action` group in #202, which I think was ill-defined. Instead: * Adds an `--actions` flag to `node show` and `group show` to show relevant `StorageTransferAction`s affecting the node/group. * Adds an `--all` flag to `node show` and `group show` to provide a way to list everything without having to know what lists what. * Adds two new commands to manipulate `StorageTransferAction`s: * `group auto-sync GROUP NODE` to set/clear the autosync flag * `node auto-clean NODE GROUP` to set/clear the autoclean flag For a given (NODE, GROUP) pair, these two commands modify the same row in the `StorageTransferAction` table (the pair has to be unique in the table). So, there's ambiguity over which command goes with which "noun". The way I've done it, the command is associated with the object that the auto-action modifies (auto-sync adds files to GROUP; auto-clean deletes files from NODE). There's probably an argument for doing it the other way; I'm not sure it matters much, so long as we are consistent about it. Also: should the command names have a dash in them? Or would `group autosync GROUP NODE` etc. be better?
- Loading branch information
1 parent
56348b1
commit c22981c
Showing
10 changed files
with
642 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
"""alpenhorn group auto-sync command""" | ||
|
||
import click | ||
import peewee as pw | ||
|
||
from ...db import StorageGroup, StorageNode, StorageTransferAction, database_proxy | ||
from ..cli import echo | ||
|
||
|
||
@click.command() | ||
@click.argument("group_name", metavar="GROUP") | ||
@click.argument("node_name", metavar="NODE") | ||
@click.option( | ||
"--remove", | ||
is_flag=True, | ||
help="Remove (instead of add) NODE as an auto-sync source.", | ||
) | ||
@click.pass_context | ||
def autosync(ctx, group_name, node_name, remove): | ||
"""Manage auto-sync sources for this group. | ||
This allows you to add (the default) or remove (using --remove) | ||
the StorageNode named NODE as a an auto-sync souce for the Storage | ||
Group named GROUP. | ||
If NODE is added as an auto-sync source for GROUP, then, whenever | ||
a file is added to NODE, it will be automatically synced into the | ||
Group GROUP, so long as the file isn't already present in the Group. | ||
""" | ||
|
||
with database_proxy.atomic(): | ||
try: | ||
group = StorageGroup.get(name=group_name) | ||
except pw.DoesNotExist: | ||
raise click.ClickException(f"no such group: {group_name}") | ||
|
||
try: | ||
node = StorageNode.get(name=node_name) | ||
except pw.DoesNotExist: | ||
raise click.ClickException(f"no such node: {node_name}") | ||
|
||
# Sanity check: can't auto-sync within a group | ||
if group == node.group and not remove: | ||
raise click.ClickException( | ||
"can't enable auto-sync: " | ||
f'Node "{node_name}" is in group "{group_name}"' | ||
) | ||
|
||
# What's the current state? | ||
try: | ||
action = StorageTransferAction.get(node_from=node, group_to=group) | ||
if action.autosync is not remove: | ||
echo("No change") | ||
ctx.exit() | ||
except pw.DoesNotExist: | ||
# No need to create a record to set autosync to zero | ||
if remove: | ||
echo("No change") | ||
ctx.exit() | ||
action = None | ||
|
||
# Upsert the change | ||
if action: | ||
StorageTransferAction.update(autosync=not remove).where( | ||
StorageTransferAction.id == action.id | ||
).execute() | ||
else: | ||
StorageTransferAction.create( | ||
node_from=node, group_to=group, autosync=not remove | ||
) | ||
|
||
echo( | ||
'Auto-sync from "' | ||
+ node.name | ||
+ ('" started' if not remove else '" stopped.') | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
"""alpenhorn node auto-clean command""" | ||
|
||
import click | ||
import peewee as pw | ||
|
||
from ...db import StorageGroup, StorageNode, StorageTransferAction, database_proxy | ||
from ..cli import echo | ||
|
||
|
||
@click.command() | ||
@click.argument("node_name", metavar="NODE") | ||
@click.argument("group_name", metavar="GROUP") | ||
@click.option( | ||
"--remove", | ||
is_flag=True, | ||
help="Remove (instead of add) GROUP as an auto-clean trigger.", | ||
) | ||
@click.pass_context | ||
def autoclean(ctx, group_name, node_name, remove): | ||
"""Manage auto-clean triggers for this node. | ||
This allows you to add (the default) or remove (using --remove) | ||
the StorageGroup named GROUP as a an auto-clean trigger for the | ||
Storage Node named NODE. | ||
If GROUP is added as an auto-clean trigger for NODE, then, whenever | ||
a file is added to GROUP, it will be automatically released for | ||
deletion on NODE. | ||
""" | ||
|
||
with database_proxy.atomic(): | ||
try: | ||
node = StorageNode.get(name=node_name) | ||
except pw.DoesNotExist: | ||
raise click.ClickException(f"no such node: {node_name}") | ||
|
||
try: | ||
group = StorageGroup.get(name=group_name) | ||
except pw.DoesNotExist: | ||
raise click.ClickException(f"no such group: {group_name}") | ||
|
||
# Sanity check: can't auto-clean within a group | ||
if group == node.group and not remove: | ||
raise click.ClickException( | ||
"can't enable auto-clean: " | ||
f'Node "{node_name}" is in group "{group_name}"' | ||
) | ||
|
||
# What's the current state? | ||
try: | ||
action = StorageTransferAction.get(node_from=node, group_to=group) | ||
if action.autoclean is not remove: | ||
echo("No change") | ||
ctx.exit() | ||
except pw.DoesNotExist: | ||
# No need to create a record to set autoclean to zero | ||
if remove: | ||
echo("No change") | ||
ctx.exit() | ||
action = None | ||
|
||
# Upsert the change | ||
if action: | ||
StorageTransferAction.update(autoclean=not remove).where( | ||
StorageTransferAction.id == action.id | ||
).execute() | ||
else: | ||
StorageTransferAction.create( | ||
node_from=node, group_to=group, autoclean=not remove | ||
) | ||
|
||
echo( | ||
'Auto-clean trigger: Group "' | ||
+ group.name | ||
+ ('" added' if not remove else '" removed.') | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.