Skip to content
Browse files
AIRAVATA-3475 Adds create_symlink() to user_storage module
  • Loading branch information
machristie committed Jun 30, 2021
1 parent d437dca commit beddf0f82f7d0bbae6d661866c883f8eaa59a6ee
Showing 4 changed files with 50 additions and 1 deletion.
@@ -1,5 +1,6 @@
from .api import (
@@ -29,6 +30,7 @@

__all__ = [
@@ -656,6 +656,15 @@ def create_user_dir(request, path="", dir_names=(), create_unique=False, storage
return storage_resource_id, resource_path

def create_symlink(request, src_path, dest_path, storage_resource_id=None):
"""Create link named dest_path pointing to src_path on storage resource."""
if _is_remote_api():
logger.warning("create_symlink isn't supported in Remote API mode")
backend = get_user_storage_provider(request, storage_resource_id=storage_resource_id)
backend.create_symlink(src_path, dest_path)

def get_rel_experiment_dir(request, experiment_id, storage_resource_id=None):
"""Return experiment data dir path relative to user's directory."""
warnings.warn("Use 'list_experiment_dir' instead.", DeprecationWarning)
@@ -1,12 +1,14 @@

class ProvidesDownloadUrl:
"""Mixin for UserStorageProvider that provides download url."""

def get_download_url(self, resource_path):
raise NotImplementedError()

class ProvidesUploadUrl:
"""Mixin for UserStorageProvider that provides upload url."""

def get_upload_url(self, resource_path):
raise NotImplementedError()

@@ -65,6 +67,13 @@ def create_dirs(self, resource_path, dir_names=[], create_unique=False):
raise NotImplementedError()

def create_symlink(self, source_path, dest_path):
Create a symlink at dest_path in user's storage that points to
source_path, a filesystem path on the storage resource.
raise NotImplementedError()

def username(self):
return self.authz_token.claimsMap['userName']
@@ -121,6 +121,17 @@ def create_dirs(self, resource_path, dir_names=[], create_unique=False):
return self.storage_resource_id, datastore.path(final_path)

def create_symlink(self, source_path, dest_path):
datastore = self.datastore
if (datastore.symlink_exists(dest_path) and
os.path.realpath(source_path) == os.path.realpath(datastore.path(dest_path))):
logger.debug(f"symlink at {dest_path} already points to {source_path}")
elif datastore.exists(dest_path):
raise Exception(f"{dest_path} already exists, but isn't the expected symlink")
datastore.create_symlink(source_path, dest_path)

def datastore(self):
directory = os.path.join(, self.username)
@@ -163,6 +174,15 @@ def dir_exists(self, path):
logger.warning(f"Invalid path: {e}")
return False

def symlink_exists(self, path):
"""Check if symlink path exists in this data store."""
logger.debug(f"symlink_exists: {path}, {self.path(path)}")
return and os.path.islink(self.path(path))
except SuspiciousFileOperation as e:
logger.warning(f"Invalid path: {e}")
return False

def open(self, path):
"""Open path for user if it exists in this data store."""
if self.exists(path):
@@ -189,6 +209,12 @@ def create_user_dir(self, path):
raise Exception("Directory {} already exists".format(path))

def create_symlink(self, source_path, dest_path):
user_data_storage =
full_path = user_data_storage.path(dest_path)
os.symlink(source_path, full_path)
return full_path

def delete(self, path):
"""Delete file in this data store."""
if self.file_exists(path):
@@ -200,7 +226,10 @@ def delete(self, path):

def delete_dir(self, path):
"""Delete entire directory in this data store."""
if self.dir_exists(path):
if self.symlink_exists(path):
user_path = self.path(path)
elif self.dir_exists(path):
user_path = self.path(path)

0 comments on commit beddf0f

Please sign in to comment.