-
Notifications
You must be signed in to change notification settings - Fork 432
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
[FluidStack] Add FluidStack Integration (Provisioner Interface) #3086
Changes from 2 commits
2fbb563
40c70f1
cfffd43
4b79c03
e4699f5
bf0283c
366c380
ca493e8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
"""fluidstack cloud adaptor.""" | ||
|
||
import functools | ||
|
||
_fluidstack_sdk = None | ||
|
||
|
||
def import_package(func): | ||
|
||
@functools.wraps(func) | ||
def wrapper(*args, **kwargs): | ||
global _fluidstack_sdk | ||
if _fluidstack_sdk is None: | ||
try: | ||
import fluidstack as _fluidstack # pylint: disable=import-outside-toplevel | ||
_fluidstack_sdk = _fluidstack | ||
except ImportError: | ||
raise ImportError( | ||
'Fail to import dependencies for fluidstack.' | ||
'Try pip install "skypilot[fluidstack]"') from None | ||
return func(*args, **kwargs) | ||
|
||
return wrapper | ||
|
||
|
||
@import_package | ||
def fluidstack(): | ||
"""Return the fluidstack package.""" | ||
return _fluidstack_sdk |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -790,6 +790,10 @@ def write_cluster_config( | |
if isinstance(cloud, clouds.GCP): | ||
gcp_project_id = cloud.get_project_id(dryrun=dryrun) | ||
|
||
fluidstack_username = 'ubuntu' | ||
if isinstance(cloud, clouds.Fluidstack): | ||
fluidstack_username = cloud.default_username(to_provision.region) | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's move this into the |
||
specific_reservations = set( | ||
skypilot_config.get_nested(('gcp', 'specific_reservations'), set())) | ||
|
||
|
@@ -898,6 +902,9 @@ def write_cluster_config( | |
'specific_reservations': filtered_specific_reservations, | ||
'tpu_node_name': tpu_node_name, | ||
|
||
# Fluidstack only: | ||
'fluidstack_username': fluidstack_username, | ||
|
||
# Conda setup | ||
'conda_installation_commands': | ||
constants.CONDA_INSTALLATION_COMMANDS, | ||
|
@@ -1001,6 +1008,8 @@ def _add_auth_to_cluster_config(cloud: clouds.Cloud, cluster_config_file: str): | |
config = auth.setup_ibm_authentication(config) | ||
elif isinstance(cloud, clouds.RunPod): | ||
config = auth.setup_runpod_authentication(config) | ||
elif isinstance(cloud, clouds.Fluidstack): | ||
config = auth.setup_fluidstack_authentication(config) | ||
else: | ||
assert isinstance(cloud, clouds.Local), cloud | ||
# Local cluster case, authentication is already filled by the user | ||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -152,6 +152,7 @@ def _get_cluster_config_template(cloud): | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
clouds.RunPod: 'runpod-ray.yml.j2', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
clouds.Kubernetes: 'kubernetes-ray.yml.j2', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
clouds.Vsphere: 'vsphere-ray.yml.j2', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
clouds.Fluidstack: 'fluidstack-ray.yml.j2' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return cloud_to_template[type(cloud)] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -929,6 +930,38 @@ def _oci_handler(blocked_resources: Set['resources_lib.Resources'], | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
blocked_resources, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
launchable_resources.copy(zone=zone.name)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@staticmethod | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
def _fluidstack_handler(blocked_resources: Set['resources_lib.Resources'], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
launchable_resources: 'resources_lib.Resources', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
region: 'clouds.Region', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
zones: Optional[List['clouds.Zone']], stdout: str, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
stderr: str) -> None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
del zones # Unused. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
style = colorama.Style | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
stdout_splits = stdout.split('\n') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
stderr_splits = stderr.split('\n') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
errors = [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
s.strip() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for s in stdout_splits + stderr_splits | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if 'FluidstackAPIError:' in s.strip() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if not errors: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
logger.info('====== stdout ======') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for s in stdout_splits: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
print(s) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
logger.info('====== stderr ======') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for s in stderr_splits: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
print(s) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
with ux_utils.print_exception_no_traceback(): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
raise RuntimeError('Errors occurred during provision; ' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
'check logs above.') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
logger.warning(f'Got error(s) in {region.name}:') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
messages = '\n\t'.join(errors) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
logger.warning(f'{style.DIM}\t{messages}{style.RESET_ALL}') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
_add_to_blocked_resources(blocked_resources, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
launchable_resources.copy(zone=None)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not needed now, as we will use the
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@staticmethod | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
def update_blocklist_on_error( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
blocked_resources: Set['resources_lib.Resources'], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -11,6 +11,7 @@ | |||||
# isort: split | ||||||
from sky.clouds.aws import AWS | ||||||
from sky.clouds.azure import Azure | ||||||
from sky.clouds.fluidstack import Fluidstack | ||||||
from sky.clouds.gcp import GCP | ||||||
from sky.clouds.ibm import IBM | ||||||
from sky.clouds.kubernetes import Kubernetes | ||||||
|
@@ -22,22 +23,8 @@ | |||||
from sky.clouds.vsphere import Vsphere | ||||||
|
||||||
__all__ = [ | ||||||
'IBM', | ||||||
'AWS', | ||||||
'Azure', | ||||||
'Cloud', | ||||||
'GCP', | ||||||
'Lambda', | ||||||
'Local', | ||||||
'SCP', | ||||||
'RunPod', | ||||||
'OCI', | ||||||
'Vsphere', | ||||||
'Kubernetes', | ||||||
'CloudImplementationFeatures', | ||||||
'Region', | ||||||
'Zone', | ||||||
'CLOUD_REGISTRY', | ||||||
'ProvisionerVersion', | ||||||
'StatusVersion', | ||||||
'IBM', 'AWS', 'Azure', 'Cloud', 'GCP', 'Lambda', 'Local', 'SCP', 'RunPod', | ||||||
'OCI', 'Vsphere', 'Kubernetes', 'CloudImplementationFeatures', 'Region', | ||||||
'Zone', 'CLOUD_REGISTRY', 'ProvisionerVersion', 'StatusVersion', | ||||||
'Fluidstack' | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: just for readability
Suggested change
|
||||||
] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should update the
setup.py
to have an extra forfluidstack
that installs the dependency.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, actually, it seems we are not using
fluidstack
package anywhere. Should we leave this file out?