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

[UX] Make sky check more fine-grained for GCP #2196

Merged
merged 2 commits into from
Jul 10, 2023
Merged
Changes from 1 commit
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
77 changes: 57 additions & 20 deletions sky/clouds/gcp.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,33 @@ class GCP(clouds.Cloud):
# lower limit.
_MAX_CLUSTER_NAME_LEN_LIMIT = 35

_INDENT_PREFIX = ' '
_DEPENDENCY_HINT = (
'GCP tools are not installed. Run the following commands:\n'
# Install the Google Cloud SDK:
f'{_INDENT_PREFIX} $ pip install google-api-python-client\n'
f'{_INDENT_PREFIX} $ conda install -c conda-forge '
'google-cloud-sdk -y')

_CREDENTIAL_HINT = (
'Run the following commands:\n'
# This authenticates the CLI to make `gsutil` work:
f'{_INDENT_PREFIX} $ gcloud init\n'
# This will generate
# ~/.config/gcloud/application_default_credentials.json.
f'{_INDENT_PREFIX} $ gcloud auth application-default login\n'
f'{_INDENT_PREFIX}For more info: '
'https://skypilot.readthedocs.io/en/latest/getting-started/installation.html#google-cloud-platform-gcp' # pylint: disable=line-too-long
)
_APPLICATION_CREDENTIAL_HINT = (
'Run the following commands:\n'
f'{_INDENT_PREFIX} $ gcloud auth application-default login\n'
f'{_INDENT_PREFIX}Or set the environment variable GOOGLE_APPLICATION_CREDENTIALS '
'to the path of your service account key file.\n'
f'{_INDENT_PREFIX}For more info: '
'https://skypilot.readthedocs.io/en/latest/getting-started/installation.html#google-cloud-platform-gcp' # pylint: disable=line-too-long
)

@classmethod
def _cloud_unsupported_features(
cls) -> Dict[clouds.CloudImplementationFeatures, str]:
Expand Down Expand Up @@ -503,6 +530,17 @@ def check_credentials(cls) -> Tuple[bool, Optional[str]]:
# Check google-api-python-client installation.
import googleapiclient

# Check the installation of google-cloud-sdk.
_run_output('gcloud --version')
except (ImportError, subprocess.CalledProcessError) as e:
return False, (
f'{cls._DEPENDENCY_HINT}\n'
f'{cls._INDENT_PREFIX}Credentials may also need to be set. '
f'{cls._CREDENTIAL_HINT}\n'
f'{cls._INDENT_PREFIX}Details: '
f'{common_utils.format_exception(e, use_bracket=True)}')

try:
# These files are required because they will be synced to remote
# VMs for `gsutil` to access private storage buckets.
# `auth.default()` does not guarantee these files exist.
Expand All @@ -512,37 +550,36 @@ def check_credentials(cls) -> Tuple[bool, Optional[str]]:
]:
if not os.path.isfile(os.path.expanduser(file)):
raise FileNotFoundError(file)
except FileNotFoundError as e:
return False, (
f'Credentails are not set. '
f'{cls._CREDENTIAL_HINT}\n'
f'{cls._INDENT_PREFIX}Details: '
f'{common_utils.format_exception(e, use_bracket=True)}')

try:
cls._find_application_key_path()
except FileNotFoundError as e:
return False, (
f'Application credentials are not set. '
f'{cls._APPLICATION_CREDENTIAL_HINT}\n'
f'{cls._INDENT_PREFIX}Details: '
f'{common_utils.format_exception(e, use_bracket=True)}')

# Check the installation of google-cloud-sdk.
_run_output('gcloud --version')

try:
# Check if application default credentials are set.
project_id = cls.get_project_id()

# Check if the user is activated.
identity = cls.get_current_user_identity()
except (auth.exceptions.DefaultCredentialsError,
subprocess.CalledProcessError,
exceptions.CloudUserIdentityError, FileNotFoundError,
ImportError) as e:
exceptions.CloudUserIdentityError) as e:
# See also: https://stackoverflow.com/a/53307505/1165051
return False, (
'GCP tools are not installed or credentials are not set. '
'Run the following commands:\n '
# Install the Google Cloud SDK:
' $ pip install google-api-python-client\n '
' $ conda install -c conda-forge google-cloud-sdk -y\n '
# This authenticates the CLI to make `gsutil` work:
' $ gcloud init\n '
# This will generate
# ~/.config/gcloud/application_default_credentials.json.
' $ gcloud auth application-default login\n '
'For more info: '
'https://skypilot.readthedocs.io/en/latest/getting-started/installation.html' # pylint: disable=line-too-long
f'\nDetails: {common_utils.format_exception(e, use_bracket=True)}'
)
'Credentials are not correctly set. '
Copy link
Member

Choose a reason for hiding this comment

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

Can we also hint the CLI commands that are equivalent to L571 & 574? Something like "Getting project ID / current user failed. You can debug with "cmd1" and "cmd2". {_CREDENTIAL_HINT}"

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good point! Added. There is no exactly equivalent command for auth.default(), but this exception is a very rare case, if the previous checks pass. We only add the gcloud auth list command here, and can wait for more feedbacks if user encounter this issue. : )

f'{cls._CREDENTIAL_HINT}\n'
f'{cls._INDENT_PREFIX}Details: '
f'{common_utils.format_exception(e, use_bracket=True)}')

# Check APIs.
apis = (
Expand Down