-
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.
fix(client): Fix group command group
Commands per the list in #201. Re-engineered running the client in the test-suite. Also, fixed common.logger.echo
- Loading branch information
1 parent
dbb47da
commit 0b50a15
Showing
19 changed files
with
1,007 additions
and
225 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 was deleted.
Oops, something went wrong.
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,24 @@ | ||
"""Alpenhorn client interface for operations on `StorageGroup`s.""" | ||
|
||
import click | ||
import peewee as pw | ||
|
||
from ...db import StorageGroup, StorageNode | ||
|
||
from .create import create | ||
from .list import list_ | ||
from .modify import modify | ||
from .rename import rename | ||
from .show import show | ||
|
||
|
||
@click.group(context_settings={"help_option_names": ["-h", "--help"]}) | ||
def cli(): | ||
"""Manage Storage Groups.""" | ||
|
||
|
||
cli.add_command(create, "create") | ||
cli.add_command(list_, "list") | ||
cli.add_command(modify, "modify") | ||
cli.add_command(rename, "rename") | ||
cli.add_command(show, "show") |
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,39 @@ | ||
"""alpenhorn group create command""" | ||
|
||
import click | ||
import json | ||
import peewee as pw | ||
|
||
from ...db import database_proxy, StorageGroup | ||
from ..options import client_option, set_io_config | ||
from ..cli import echo | ||
|
||
|
||
@click.command() | ||
@click.argument("group_name", metavar="NAME") | ||
@client_option("io_class", default="Default", show_default=True) | ||
@client_option("io_config") | ||
@client_option("io_var") | ||
@client_option("notes") | ||
def create(group_name, io_class, io_config, io_var, notes): | ||
"""Create a new storage group. | ||
The group will be called NAME, which must not already exist. | ||
""" | ||
|
||
io_config = set_io_config(io_config, io_var, dict()) | ||
|
||
with database_proxy.atomic(): | ||
try: | ||
StorageGroup.get(name=group_name) | ||
raise click.ClickException(f'Group "{group_name}" already exists.') | ||
except pw.DoesNotExist: | ||
pass | ||
|
||
StorageGroup.create( | ||
name=group_name, | ||
notes=notes, | ||
io_class=io_class, | ||
io_config=json.dumps(io_config), | ||
) | ||
echo(f'Created storage group "{group_name}".') |
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,24 @@ | ||
"""alpenhorn group list command""" | ||
|
||
import click | ||
from tabulate import tabulate | ||
from ...db import StorageGroup | ||
from ..cli import echo | ||
|
||
|
||
@click.command() | ||
def list_(): | ||
"""List all storage groups.""" | ||
|
||
data = StorageGroup.select( | ||
StorageGroup.name, StorageGroup.io_class, StorageGroup.notes | ||
).tuples() | ||
if data: | ||
# Add Default I/O class where needed | ||
data = list(data) | ||
for index, row in enumerate(data): | ||
if row[1] is None: | ||
data[index] = (row[0], "Default", row[2]) | ||
echo(tabulate(data, headers=["Name", "I/O Class", "Notes"])) | ||
else: | ||
echo("No storage groups found.") |
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,56 @@ | ||
"""alpenhorn group modify command""" | ||
|
||
import json | ||
import click | ||
import peewee as pw | ||
|
||
from ...db import StorageGroup, database_proxy | ||
from ..cli import echo | ||
from ..options import client_option, set_io_config | ||
|
||
|
||
@click.command() | ||
@click.argument("group_name", metavar="GROUP") | ||
@client_option("io_class") | ||
@client_option("io_config") | ||
@client_option("io_var") | ||
@client_option("notes") | ||
def modify(group_name, io_class, io_config, io_var, notes): | ||
"""Modify storage group metadata. | ||
Modifies the metadata of the storage group named GROUP, which must already exist. | ||
NOTE: to change the name of a storage group, use: | ||
alpenhorn group rename | ||
""" | ||
|
||
if notes == "": | ||
notes = None | ||
if io_class == "": | ||
io_class = None | ||
|
||
with database_proxy.atomic(): | ||
try: | ||
group = StorageGroup.get(name=group_name) | ||
except pw.DoesNotExist: | ||
raise click.ClickException(f'Storage group "{group_name}" does not exist.') | ||
|
||
io_config = set_io_config(io_config, io_var, group.io_config) | ||
|
||
# collect the updated parameters | ||
updates = dict() | ||
if notes != group.notes: | ||
updates["notes"] = notes | ||
if io_class != group.io_class: | ||
updates["io_class"] = io_class | ||
if io_config != group.io_config: | ||
updates["io_config"] = json.dumps(io_config) | ||
|
||
# Update if necessary. | ||
if updates: | ||
update = StorageGroup.update(**updates).where(StorageGroup.id == group.id) | ||
update.execute() | ||
echo("Storage group updated.") | ||
else: | ||
echo("Nothing to do.") |
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,39 @@ | ||
"""alpenhorn group rename command""" | ||
|
||
import click | ||
import peewee as pw | ||
|
||
from ...db import StorageGroup, database_proxy | ||
from ..cli import echo | ||
|
||
|
||
@click.command() | ||
@click.argument("group_name", metavar="GROUP") | ||
@click.argument("new_name", metavar="NEW_NAME") | ||
def rename(group_name, new_name): | ||
"""Rename a storage group. | ||
The existing storage group named GROUP will be renamed to NEW_NAME. | ||
NEW_NAME must not already be the name of another group. | ||
""" | ||
|
||
if group_name == new_name: | ||
# The easy case | ||
echo("No change.") | ||
else: | ||
with database_proxy.atomic(): | ||
try: | ||
StorageGroup.get(name=new_name) | ||
raise click.ClickException( | ||
f'Storage group "{group_name}" already exists.' | ||
) | ||
except pw.DoesNotExist: | ||
pass | ||
|
||
try: | ||
group = StorageGroup.get(name=group_name) | ||
group.name = new_name | ||
group.save() | ||
echo(f'Storage group "{group_name}" renamed to "new_name"') | ||
except pw.DoesNotExist: | ||
raise click.ClickException(f"No such storage group: {group_name}.") |
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,73 @@ | ||
"""alpenhorn group show command""" | ||
|
||
import json | ||
import click | ||
import peewee as pw | ||
from tabulate import tabulate | ||
|
||
from ...db import StorageGroup, StorageNode | ||
from ..cli import echo | ||
|
||
|
||
@click.command() | ||
@click.argument("group_name", metavar="GROUP") | ||
@click.option("--node-details", is_flag=True, help="Show details of listed nodes.") | ||
@click.option("--node-stats", is_flag=True, help="Show usage stats of listed nodes.") | ||
def show(group_name, node_details, node_stats): | ||
"""Show details of a storage group. | ||
Shows details of the storage group named GROUP. | ||
""" | ||
|
||
try: | ||
group = StorageGroup.get(name=group_name) | ||
except pw.DoesNotExist: | ||
raise click.ClickException(f"no such group: {group_name}") | ||
|
||
# Print a report | ||
echo("Storage Group: " + group.name) | ||
echo(" Notes: " + (group.notes if group.notes else "")) | ||
echo(" I/O Class: " + (group.io_class if group.io_class else "Default")) | ||
|
||
echo("\nI/O Config:\n") | ||
if group.io_config: | ||
try: | ||
io_config = json.loads(group.io_config) | ||
if io_config: | ||
# Find length of longest key (but not too long) | ||
keylen = min(max([len(key) for key in io_config]), 30) | ||
for key, value in io_config.items(): | ||
echo(" " + key.rjust(keylen) + ": " + str(value)) | ||
else: | ||
echo(" empty") | ||
except json.JSONDecodeError: | ||
echo("INVALID (JSON decode error)") | ||
else: | ||
echo(" none") | ||
|
||
# List nodes, if any | ||
echo("\nNodes:\n") | ||
nodes = list(StorageNode.select().where(StorageNode.group == group)) | ||
if nodes: | ||
if node_details or node_stats: | ||
if node_details: | ||
data = [ | ||
( | ||
node.name, | ||
node.host, | ||
"Yes" if node.active else "No", | ||
node.io_class if node.io_class else "Default", | ||
) | ||
for node in nodes | ||
] | ||
headers = ["Name", "Host", "Active", "I/O Class"] | ||
if node_stats: | ||
# TODO: add --node-stats support when "alpenhorn node stats" is implemented | ||
raise NotImplementedError() | ||
echo(tabulate(data, headers=headers)) | ||
else: | ||
# simple list | ||
for node in nodes: | ||
echo(" " + node.name) | ||
else: | ||
echo(" none") |
Oops, something went wrong.