-
Notifications
You must be signed in to change notification settings - Fork 338
Add GCS Support #6
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
Changes from all commits
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 |
|---|---|---|
|
|
@@ -22,3 +22,8 @@ class SdkTaskType(object): | |
|
|
||
|
|
||
| GLOBAL_INPUT_NODE_ID = '' | ||
|
|
||
|
|
||
| class CloudProvider(object): | ||
| AWS = "aws" | ||
| GCP = "gcp" | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| from __future__ import absolute_import | ||
|
|
||
| from flytekit.configuration import common as _config_common | ||
|
|
||
| GCS_PREFIX = _config_common.FlyteRequiredStringConfigurationEntry('gcp', 'gcs_prefix') |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,10 @@ | ||
| from __future__ import absolute_import | ||
|
|
||
| from flytekit.configuration import common as _config_common | ||
| from flytekit.common import constants as _constants | ||
|
|
||
| URL = _config_common.FlyteRequiredStringConfigurationEntry('platform', 'url') | ||
| INSECURE = _config_common.FlyteBoolConfigurationEntry('platform', 'insecure', default=False) | ||
| CLOUD_PROVIDER = _config_common.FlyteStringConfigurationEntry( | ||
| 'platform', 'cloud_provider', default=_constants.CloudProvider.AWS | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,112 @@ | ||
| from __future__ import absolute_import | ||
|
|
||
| import os as _os | ||
| import sys as _sys | ||
| import uuid as _uuid | ||
|
|
||
| from flytekit.configuration import gcp as _gcp_config | ||
| from flytekit.interfaces import random as _flyte_random | ||
| from flytekit.interfaces.data import common as _common_data | ||
| from flytekit.tools import subprocess as _subprocess | ||
| from flytekit.common.exceptions.user import FlyteUserException as _FlyteUserException | ||
|
|
||
|
|
||
| if _sys.version_info >= (3,): | ||
| from shutil import which as _which | ||
| else: | ||
| from distutils.spawn import find_executable as _which | ||
|
|
||
|
|
||
| def _update_cmd_config_and_execute(cmd): | ||
| env = _os.environ.copy() | ||
| return _subprocess.check_call(cmd, env=env) | ||
|
|
||
|
|
||
| class GCSProxy(_common_data.DataProxy): | ||
| _GS_UTIL_CLI = "gsutil" | ||
|
|
||
| @staticmethod | ||
| def _check_binary(): | ||
| """ | ||
| Make sure that the AWS cli is present | ||
| """ | ||
| if not _which(GCSProxy._GS_UTIL_CLI): | ||
| raise _FlyteUserException('gsutil (gcloud cli) not found at Please install.') | ||
|
|
||
| def exists(self, remote_path): | ||
| """ | ||
| :param Text remote_path: remote gs:// path | ||
| :rtype bool: whether the gs file exists or not | ||
| """ | ||
| GCSProxy._check_binary() | ||
|
|
||
| if not remote_path.startswith("gs://"): | ||
| raise ValueError("Not an GS Key. Please use FQN (GS ARN) of the format gs://...") | ||
|
|
||
| cmd = [GCSProxy._GS_UTIL_CLI, "-q", "stat", remote_path] | ||
| try: | ||
| _update_cmd_config_and_execute(cmd) | ||
| return True | ||
| except Exception: | ||
| return False | ||
|
|
||
| def download_directory(self, remote_path, local_path): | ||
| """ | ||
| :param Text remote_path: remote s3:// path | ||
| :param Text local_path: directory to copy to | ||
| """ | ||
| GCSProxy._check_binary() | ||
|
|
||
| if not remote_path.startswith("gs://"): | ||
| raise ValueError("Not an GS Key. Please use FQN (GS ARN) of the format gs://...") | ||
|
|
||
| cmd = [GCSProxy._GS_UTIL_CLI, "cp", "-r", remote_path, local_path] | ||
| return _update_cmd_config_and_execute(cmd) | ||
|
|
||
| def download(self, remote_path, local_path): | ||
| """ | ||
| :param Text remote_path: remote s3:// path | ||
| :param Text local_path: directory to copy to | ||
| """ | ||
| if not remote_path.startswith("gs://"): | ||
| raise ValueError("Not an GS Key. Please use FQN (GS ARN) of the format gs://...") | ||
|
|
||
| GCSProxy._check_binary() | ||
| cmd = [GCSProxy._GS_UTIL_CLI, "cp", remote_path, local_path] | ||
| return _update_cmd_config_and_execute(cmd) | ||
|
|
||
| def upload(self, file_path, to_path): | ||
| """ | ||
| :param Text file_path: | ||
| :param Text to_path: | ||
| """ | ||
| GCSProxy._check_binary() | ||
|
|
||
| cmd = [GCSProxy._GS_UTIL_CLI, "cp", file_path, to_path] | ||
|
|
||
| return _update_cmd_config_and_execute(cmd) | ||
|
|
||
| def upload_directory(self, local_path, remote_path): | ||
| """ | ||
| :param Text local_path: | ||
| :param Text remote_path: | ||
| """ | ||
| if not remote_path.startswith("gs://"): | ||
| raise ValueError("Not an GS Key. Please use FQN (GS ARN) of the format gs://...") | ||
|
|
||
| GCSProxy._check_binary() | ||
| cmd = [GCSProxy._GS_UTIL_CLI, "cp", "-r", local_path, remote_path] | ||
|
Contributor
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. I think we can change
Member
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. The current behaviour in this PR seems fine to me, because the expectation of this function is to upload the specified local path. Maybe it is the caller who should use
Member
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. We can confirm that e.g: vs. |
||
| return _update_cmd_config_and_execute(cmd) | ||
|
|
||
| def get_random_path(self): | ||
| """ | ||
| :rtype: Text | ||
| """ | ||
| key = _uuid.UUID(int=_flyte_random.random.getrandbits(128)).hex | ||
| return _os.path.join(_gcp_config.GCS_PREFIX.get(), key) | ||
|
|
||
| def get_random_directory(self): | ||
| """ | ||
| :rtype: Text | ||
| """ | ||
| return self.get_random_path() + "/" | ||
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.
s/s3/gs/g