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

Implement info command #198

Closed
wants to merge 15 commits into from
94 changes: 94 additions & 0 deletions src/xpk/commands/info.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
"""
Copyright 2024 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""

from ..utils import xpk_exit, xpk_print
from ..core.kueue import verify_kueuectl_installation, install_kueuectl
from ..core.commands import (
run_command_for_value,
)

def prepare_kueuectl(args) -> int:
"""Verify if kueuectl is installed. If not install kueuectl.
Args:
args: user provided arguments.
Returns:
0 if succesful and 1 otherwise.
"""
xpk_print('Veryfing kueuectl installation')
args.dry_run = False
verify_kueuectl_installed_code = verify_kueuectl_installation(args)
if verify_kueuectl_installed_code == 0:
xpk_print('kueuectl installed')
return 0

if verify_kueuectl_installed_code != 0:
xpk_print('Installing kueuectl')
kueuectl_installation_code = install_kueuectl(args)
if kueuectl_installation_code != 0:
return kueuectl_installation_code

def info(args) -> None:
"""Function around list localqueue.

Args:
args: user provided arguments for running the command.
Returns:
0 if successful and 1 otherwise.
"""
pawloch00 marked this conversation as resolved.
Show resolved Hide resolved
installation_code = prepare_kueuectl(args)
if installation_code != 0:
xpk_exit(installation_code)

code = run_kueuectl_list(args)
if code != 0:
xpk_exit(code)
return

def run_kueuectl_list(args) -> int:
"""Run the kueuectl list localqueue command.

Args:
args: user provided arguments for running the command.

Returns:
0 if successful and 1 otherwise.
"""
command = (
'kubectl kueue list'
)
if args.localqueue and args.clusterqueue:
xpk_print('xpk info returned ERROR: only one of --clusterqueue, --localqueue can be set')
return 1

if not args.localqueue and not args.clusterqueue:
xpk_print('xpk info returned ERROR: either --clusterqueue or --localqueue must be set')
return 1

if args.localqueue:
command += ' localqueue'

if args.clusterqueue:
command += ' clusterqueue'

if args.cluster is not None:
command += f' --cluster={args.cluster}'
args.dry_run = False
return_code, val = run_command_for_value(command, 'List clusterqueues', args)
if return_code != 0:
xpk_print(f'Cluster info request returned ERROR {return_code}')
return 1
xpk_print(val)
return 0
76 changes: 75 additions & 1 deletion src/xpk/core/kueue.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"""

from ..utils import write_tmp_file, xpk_print
from .commands import run_command_with_updates_retry
from .commands import run_command_with_updates_retry, run_command_for_value
from .core import (
AutoprovisioningConfig,
create_accelerator_label,
Expand All @@ -27,6 +27,8 @@
AcceleratorTypeToAcceleratorCharacteristics,
SystemCharacteristics,
)
from sys import platform
from platform import machine

KUEUE_VERSION = 'v0.8.1'
CLUSTER_QUEUE_NAME = 'cluster-queue'
Expand Down Expand Up @@ -139,6 +141,78 @@
command: [ "sleep", "inf" ]
"""

def verify_kueuectl_installation(args) -> int:
"""Verify if if kueuectl is installed.
Args:
args: user provided arguments for running the command.
Returns:
0 if kueuectl installed and error code otherwise.
"""
command = (
'kubectl kueue version'
)
task = 'Verify kueuectl installation on cluster'
return_code, _ = run_command_for_value(command, task, args)
if return_code != 0:
xpk_print(f'{task} returned ERROR {return_code}')
return return_code

def get_system_spec() -> tuple[str, str]:
pawloch00 marked this conversation as resolved.
Show resolved Hide resolved
"""Get operating system and machine type

Returns:
tuple of strings in format (operating system, machine type).
"""
os = platform
machine_type = machine()
return os, machine_type


def get_kueuectl_installation_command(system, machine_type) -> list[str]:
"""Create command for installing kueuectl depending on operating system and machine type.
Function execution moves to /usr/local/bin/, therefore sudo is needed.
Args:
system: operating system, supported values are [darwin, linux].
machine_type: machine type, supported values are [x86_64, arm].
Returns
List of commands to download kueuectl.

"""
curl = ''
if system == 'darwin' and 'x86_64' in machine_type:
curl = 'curl -Lo ./kubectl-kueue https://github.com/kubernetes-sigs/kueue/releases/download/v0.8.1/kubectl-kueue-darwin-amd64'
if system == 'darwin' and 'arm' in machine_type:
curl = 'curl -Lo ./kubectl-kueue https://github.com/kubernetes-sigs/kueue/releases/download/v0.8.1/kubectl-kueue-darwin-arm64'
if system == 'linux' and 'arm' in machine_type:
curl = 'curl -Lo ./kubectl-kueue https://github.com/kubernetes-sigs/kueue/releases/download/v0.8.1/kubectl-kueue-linux-arm64'
if system == 'linux' and 'x86_64' in machine_type:
curl = 'curl -Lo ./kubectl-kueue https://github.com/kubernetes-sigs/kueue/releases/download/v0.8.1/kubectl-kueue-linux-amd64'

chmod = 'chmod +x ./kubectl-kueue'
mv = 'sudo mv ./kubectl-kueue /usr/local/bin/kubectl-kueue'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@44past4 Should we assume user will have sudo permissions? WDYT?


return [curl, chmod , mv]

def install_kueuectl(args) -> int:
"""Install Kueuectl on the cluster

Args:
args: user provided arguments for running the command.

Returns:
0 if successful and 1 otherwise.
"""

system, machine_type = get_system_spec()
commands = get_kueuectl_installation_command(system, machine_type)

task = 'Install kueuectl on cluster'
for command in commands:
return_code, _ = run_command_for_value(command, task, args)
if return_code != 0:
xpk_print(f'{task} returned ERROR {return_code}')
return return_code


def install_kueue_on_cluster(args) -> int:
"""Install Kueue on the cluster.
Expand Down
11 changes: 9 additions & 2 deletions src/xpk/parser/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from .cluster import set_cluster_parser
from .inspector import set_inspector_parser
from .workload import set_workload_parsers

from .info import set_info_parser

def set_parser(parser: argparse.ArgumentParser):
xpk_subcommands = parser.add_subparsers(
Expand All @@ -37,7 +37,11 @@ def set_parser(parser: argparse.ArgumentParser):
"inspector",
help="commands around investigating workload, and Kueue failures.",
)

info_parser = xpk_subcommands.add_parser(
"info",
help="commands around listing kueue clusterqueues and localqueues"
)

def default_subcommand_function(
_args,
) -> int: # args is unused, so pylint: disable=invalid-name
Expand All @@ -53,12 +57,15 @@ def default_subcommand_function(
parser.print_help()
cluster_parser.print_help()
workload_parser.print_help()
info_parser.print_help()
return 0

parser.set_defaults(func=default_subcommand_function)
workload_parser.set_defaults(func=default_subcommand_function)
cluster_parser.set_defaults(func=default_subcommand_function)
info_parser.set_defaults(func=default_subcommand_function)

set_workload_parsers(workload_parser=workload_parser)
set_cluster_parser(cluster_parser=cluster_parser)
set_inspector_parser(inspector_parser=inspector_parser)
set_info_parser(info_parser=info_parser)
42 changes: 42 additions & 0 deletions src/xpk/parser/info.py
pawloch00 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"""
Copyright 2024 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""

from ..commands.info import info

def set_info_parser(info_parser):
pawloch00 marked this conversation as resolved.
Show resolved Hide resolved
info_required_arguments = info_parser.add_argument_group(
'Required Arguments', 'Arguments required for info.'
)

info_required_arguments.add_argument(
'--cluster',
type = str,
default = None,
help = 'Cluster to which command applies.'
)

info_required_arguments.add_argument(
'--localqueue',
action='store_true',
help = 'Print info about localqueue',
)

info_required_arguments.add_argument(
'--clusterqueue',
action='store_true',
help = 'Print info about clusterqueue',
)
Comment on lines +35 to +45
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we would prefer to create two tables with every xpk info invocation. One for localqueues and the other for clusterqueues. WDYT @44past4? If you want to implement mutual exclusion between localqueue and clusterqueue flags use add_mutually_exclusive_group() - example

info_parser.set_defaults(func=info)