Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jz/ci: pipeline ci #13

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: CI

on:
pull_request:

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

jobs:
lint-format:
name: Check linting and formatting
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3
with:
fetch-depth: 0

- name: pip update
run: python -m pip install --upgrade pip

- name: Install dependencies
run: python -m pip install build setuptools_scm[toml]

- name: Install dependencies
run: python -m pip install .[dev]

- name: Lint
run: python -m ruff .

- name: Check format
run: python -m ruff format .

- name: Check Diff
run: |
DIFF="$(git diff --name-only)"

if [ -z "$DIFF" ]; then
echo "OK: Format is clean"
else
echo "Error: Format was not clean"
echo "List of files:"
echo "$DIFF"
git diff
exit 1
fi

build-test:
name: Build and test Python
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3
with:
fetch-depth: 0

- name: pip update
run: python -m pip install --upgrade pip

- name: Install dependencies
run: python -m pip install build setuptools_scm[toml]

- name: Install dependencies
run: python -m pip install .[tests]

- name: Run tests
run: python -m pytest tests

207 changes: 162 additions & 45 deletions src/armonik_cli/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,19 @@
import grpc
from armonik.client.sessions import ArmoniKSessions, SessionFieldFilter
from armonik.client.tasks import ArmoniKTasks, TaskFieldFilter
from armonik.common.enumwrapper import TASK_STATUS_ERROR, TASK_STATUS_CREATING , SESSION_STATUS_RUNNING, SESSION_STATUS_CANCELLED
from armonik.client.results import ArmoniKResults, ResultFieldFilter
from armonik.common.enumwrapper import (
TASK_STATUS_ERROR,
TASK_STATUS_CREATING,
SESSION_STATUS_RUNNING,
SESSION_STATUS_CANCELLED,
RESULT_STATUS_COMPLETED,
RESULT_STATUS_CREATED,
)
from armonik.common.filter import Filter


def create_channel(endpoint: str, ca: str, key: str, cert: str) -> grpc.Channel:
def create_channel(endpoint: str, ca: str, key: str, cert: str) -> grpc.Channel:
"""
Create a gRPC channel for communication with the ArmoniK control plane

Expand All @@ -19,13 +27,13 @@ def create_channel(endpoint: str, ca: str, key: str, cert: str) -> grpc.Channel

Returns:
grpc.Channel: gRPC channel for communication
"""
"""
try:
if ca:
with open(ca, 'rb') as ca_file:
with open(ca, "rb") as ca_file:
ca_data = ca_file.read()
if cert and key:
with open(cert, 'rb') as cert_file, open(key, 'rb') as key_file:
with open(cert, "rb") as cert_file, open(key, "rb") as key_file:
key_data = key_file.read()
cert_data = cert_file.read()
else:
Expand All @@ -38,8 +46,7 @@ def create_channel(endpoint: str, ca: str, key: str, cert: str) -> grpc.Channel
return grpc.insecure_channel(endpoint)
except FileNotFoundError as e:
print(e)
sys.exit(1)

sys.exit(1)


def list_sessions(client: ArmoniKSessions, session_filter: Filter):
Expand All @@ -52,14 +59,14 @@ def list_sessions(client: ArmoniKSessions, session_filter: Filter):
"""
page = 0
sessions = client.list_sessions(session_filter, page=page)

while len(sessions[1]) > 0:
for session in sessions[1]:
print(f'Session ID: {session.session_id}')
print(f"Session ID: {session.session_id}")
page += 1
sessions = client.list_sessions(session_filter, page=page)

print(f'\nNumber of sessions: {sessions[0]}\n')
print(f"\nNumber of sessions: {sessions[0]}\n")


def cancel_sessions(client: ArmoniKSessions, sessions: list):
Expand All @@ -78,7 +85,9 @@ def cancel_sessions(client: ArmoniKSessions, sessions: list):
print(f"Error for canceling session {session_id}: {error.details()}")


def create_task_filter(session_id: str, all: bool , creating: bool, error: bool) -> Filter:
def create_task_filter(
session_id: str, all: bool, creating: bool, error: bool
) -> Filter:
"""
Create a task Filter based on the provided options

Expand All @@ -94,14 +103,18 @@ def create_task_filter(session_id: str, all: bool , creating: bool, error: bool)
if all:
tasks_filter = TaskFieldFilter.SESSION_ID == session_id
elif creating:
tasks_filter = (TaskFieldFilter.SESSION_ID == session_id) & (TaskFieldFilter.STATUS == TASK_STATUS_CREATING)
tasks_filter = (TaskFieldFilter.SESSION_ID == session_id) & (
TaskFieldFilter.STATUS == TASK_STATUS_CREATING
)
elif error:
tasks_filter = (TaskFieldFilter.SESSION_ID == session_id) & (TaskFieldFilter.STATUS == TASK_STATUS_ERROR)
tasks_filter = (TaskFieldFilter.SESSION_ID == session_id) & (
TaskFieldFilter.STATUS == TASK_STATUS_ERROR
)
else:
raise ValueError("SELECT ARGUMENT [--all | --creating | --error]")
raise ValueError("SELECT ARGUMENT [--all | --creating | --error]")

return tasks_filter


def list_tasks(client: ArmoniKTasks, task_filter: Filter):
"""
Expand All @@ -116,12 +129,13 @@ def list_tasks(client: ArmoniKTasks, task_filter: Filter):
tasks = client.list_tasks(task_filter, page=page)
while len(tasks[1]) > 0:
for task in tasks[1]:
print(f'Task ID: {task.id}')
print(f"Task ID: {task.id}")
page += 1
tasks = client.list_tasks(task_filter, page=page)

print(f"\nTotal tasks: {tasks[0]}\n")


def check_task(client: ArmoniKTasks, task_ids: list):
"""
Check the status of a task based on its ID.
Expand All @@ -138,6 +152,19 @@ def check_task(client: ArmoniKTasks, task_ids: list):
else:
print(f"No task found with ID {task_id}")


def list_results(client: ArmoniKResults, result_filter: Filter):
page = 0
results = client.list_results(result_filter, page=page)
while len(results[1]) > 0:
for result in results[1]:
print(f"Result ID: {result}")
page += 1
results = client.list_results(result_filter, page=page)

print(f"\nTotal results: {results[0]}\n")


def get_task_durations(client: ArmoniKTasks, task_filter: Filter):
"""
Get task durations per partition
Expand All @@ -162,54 +189,144 @@ def get_task_durations(client: ArmoniKTasks, task_filter: Filter):
print(f"Partition: {partition} = {duration} secondes")


def main():
def hello():
return "Hello, World!"

parser = argparse.ArgumentParser(description="ArmoniK Admin CLI to perform administration tasks for ArmoniK")
parser.add_argument("-v","--version", action="version", version="ArmoniK Admin CLI 0.0.1")
parser.add_argument("--endpoint", default="localhost:5001", help="ArmoniK control plane endpoint")

def main():
parser = argparse.ArgumentParser(
description="ArmoniK Admin CLI to perform administration tasks for ArmoniK"
)
parser.add_argument(
"-v", "--version", action="version", version="ArmoniK Admin CLI 0.0.1"
)
parser.add_argument(
"--endpoint", default="localhost:5001", help="ArmoniK control plane endpoint"
)
parser.add_argument("--ca", help="CA file for mutual TLS")
parser.add_argument("--cert", help="Certificate for mutual TLS")
parser.add_argument("--key", help="Private key for mutual TLS")
parser.set_defaults(func=lambda _: parser.print_help())

subparsers = parser.add_subparsers()

list_session_parser = subparsers.add_parser('list-session', help='List sessions with specific filters')
list_session_parser = subparsers.add_parser(
"list-session", help="List sessions with specific filters"
)
group_list_session = list_session_parser.add_mutually_exclusive_group(required=True)
group_list_session.add_argument("--all", dest="filter", action="store_const", const=None, help="Select all sessions")
group_list_session.add_argument("--running", dest="filter", action="store_const", const=SessionFieldFilter.STATUS == SESSION_STATUS_RUNNING, help="Select running sessions")
group_list_session.add_argument("--cancelled", dest="filter", action="store_const", const=SessionFieldFilter.STATUS == SESSION_STATUS_CANCELLED, help="Select cancelled sessions")
group_list_session.set_defaults(func=lambda args: list_sessions(session_client, args.filter))


list_task_parser = subparsers.add_parser('list-task', help='List tasks with specific filters')
group_list_session.add_argument(
"--all",
dest="filter",
action="store_const",
const=None,
help="Select all sessions",
)
group_list_session.add_argument(
"--running",
dest="filter",
action="store_const",
const=SessionFieldFilter.STATUS == SESSION_STATUS_RUNNING,
help="Select running sessions",
)
group_list_session.add_argument(
"--cancelled",
dest="filter",
action="store_const",
const=SessionFieldFilter.STATUS == SESSION_STATUS_CANCELLED,
help="Select cancelled sessions",
)
group_list_session.set_defaults(
func=lambda args: list_sessions(session_client, args.filter)
)

list_task_parser = subparsers.add_parser(
"list-task", help="List tasks with specific filters"
)
list_task_parser.add_argument(dest="session_id", help="Select ID from SESSION")

group_list_task = list_task_parser.add_mutually_exclusive_group(required=True)
group_list_task.add_argument("--all", dest="all", action="store_true", help="Select all tasks")
group_list_task.add_argument("--creating", dest="creating", action="store_true", help="Select creating tasks")
group_list_task.add_argument("--error", dest="error", action="store_true", help="Select error tasks")
group_list_task.set_defaults(func=lambda args: list_tasks(task_client, create_task_filter(args.session_id, args.all, args.creating, args.error)))

check_task_parser = subparsers.add_parser('check-task', help='Check the status of a specific task')
check_task_parser.add_argument(dest="task_ids", nargs="+", help="Select ID from TASK")
check_task_parser.set_defaults(func=lambda args: check_task(task_client, args.task_ids))


cancel_session_parser = subparsers.add_parser('cancel-session', help='Cancel sessions')
cancel_session_parser.add_argument(dest="session_ids", nargs="+", help="Session IDs to cancel")
cancel_session_parser.set_defaults(func=lambda args: cancel_sessions(session_client, args.session_ids))

task_duration_parser = subparsers.add_parser('task-duration', help='Print task durations per partition')
group_list_task.add_argument(
"--all", dest="all", action="store_true", help="Select all tasks"
)
group_list_task.add_argument(
"--creating", dest="creating", action="store_true", help="Select creating tasks"
)
group_list_task.add_argument(
"--error", dest="error", action="store_true", help="Select error tasks"
)
group_list_task.set_defaults(
func=lambda args: list_tasks(
task_client,
create_task_filter(args.session_id, args.all, args.creating, args.error),
)
)

check_task_parser = subparsers.add_parser(
"check-task", help="Check the status of a specific task"
)
check_task_parser.add_argument(
dest="task_ids", nargs="+", help="Select ID from TASK"
)
check_task_parser.set_defaults(
func=lambda args: check_task(task_client, args.task_ids)
)

cancel_session_parser = subparsers.add_parser(
"cancel-session", help="Cancel sessions"
)
cancel_session_parser.add_argument(
dest="session_ids", nargs="+", help="Session IDs to cancel"
)
cancel_session_parser.set_defaults(
func=lambda args: cancel_sessions(session_client, args.session_ids)
)

task_duration_parser = subparsers.add_parser(
"task-duration", help="Print task durations per partition"
)
task_duration_parser.add_argument(dest="session_id", help="Select ID from SESSION")
task_duration_parser.set_defaults(func=lambda args: get_task_durations(task_client, create_task_filter(args.session_id, True, False, False)))
task_duration_parser.set_defaults(
func=lambda args: get_task_durations(
task_client, create_task_filter(args.session_id, True, False, False)
)
)

list_result_parser = subparsers.add_parser(
"list-result", help="List results with specific filters"
)
group_list_result = list_result_parser.add_mutually_exclusive_group(required=True)
group_list_result.add_argument(
"--all",
dest="filter",
action="store_const",
const=None,
help="Select completed result",
)
group_list_result.add_argument(
"--completed",
dest="filter",
action="store_const",
const=ResultFieldFilter.STATUS == RESULT_STATUS_COMPLETED,
help="Select completed result",
)
group_list_result.add_argument(
"--created",
dest="filter",
action="store_const",
const=ResultFieldFilter.STATUS == RESULT_STATUS_CREATED,
help="Select created result",
)
group_list_result.set_defaults(
func=lambda args: list_results(result_client, args.filter)
)

args = parser.parse_args()
grpc_channel = create_channel(args.endpoint, args.ca, args.key, args.cert)
task_client = ArmoniKTasks(grpc_channel)
session_client = ArmoniKSessions(grpc_channel)
result_client = ArmoniKResults(grpc_channel)
args.func(args)


if __name__ == '__main__':
if __name__ == "__main__":
main()
Empty file added tests/conftest.py
Empty file.
5 changes: 5 additions & 0 deletions tests/unit/test_hello.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from armonik_cli.admin import hello


def test_hello():
assert hello() == "Hello, World!"
Loading