# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.command
+from sys import stdout
+from time import localtime, strftime
+from logging import getLogger
+from os import path
+
from kamaki.cli import command
from kamaki.cli.command_tree import CommandTree
from kamaki.cli.errors import raiseCLIError, CLISyntaxError
from kamaki.cli.argument import FlagArgument, ValueArgument, IntArgument
from kamaki.cli.argument import KeyValueArgument, DateArgument
from kamaki.cli.argument import ProgressBarArgument
-from kamaki.cli.commands import _command_init
+from kamaki.cli.commands import _command_init, errors
from kamaki.clients.pithos import PithosClient, ClientError
from kamaki.cli.utils import bold
-from sys import stdout
-from time import localtime, strftime
-from logging import getLogger
-from os import path
+
kloger = getLogger('kamaki')
class _pithos_init(_command_init):
"""Initialize a pithos+ kamaki client"""
- def main(self):
+ @errors.generic.all
+ def _run(self):
self.token = self.config.get('store', 'token')\
or self.config.get('global', 'token')
self.base_url = self.config.get('store', 'url')\
account=self.account,
container=self.container)
+ def main(self):
+ self._run()
+
class _store_account_command(_pithos_init):
"""Base class for account level storage commands"""
'Set user account (not permanent)',
'--account')
- def main(self):
- super(_store_account_command, self).main()
+ def _run(self):
+ super(_store_account_command, self)._run()
if self['account']:
self.client.account = self['account']
+ @errors.generic.all
+ def main(self):
+ self._run()
+
class _store_container_command(_store_account_command):
"""Base class for container level storage commands"""
- generic_err_details = ['To specify a container:',
- ' 1. Set store.container variable (permanent)',
- ' /config set store.container <container>',
- ' 2. --container=<container> (temporary, overrides 1)',
- ' 3. Use the container:path format (temporary, overrides all)']
-
container = None
path = None
'Set container to work with (temporary)',
'--container')
+ @errors.generic.all
+ def _dest_container_path(self, dest_container_path):
+ dst = dest_container_path.split(':')
+ return (dst[0], dst[1]) if len(dst) > 1 else (None, dst[0])
+
def extract_container_and_path(self,
container_with_path,
path_is_optional=True):
+ """Contains all heuristics for deciding what should be used as
+ container or path. Options are:
+ * user string of the form container:path
+ * self.container, self.path variables set by super constructor, or
+ explicitly by the caller application
+ Error handling is explicit as these error cases happen only here
+ """
try:
assert isinstance(container_with_path, str)
except AssertionError as err:
raiseCLIError(err)
- cont, sep, path = container_with_path.partition(':')
+ user_cont, sep, userpath = container_with_path.partition(':')
if sep:
- if not cont:
+ if not user_cont:
raiseCLIError(CLISyntaxError('Container is missing\n',
- details=self.generic_err_details))
+ details=errors.pithos.container_howto))
alt_cont = self['container']
- if alt_cont and cont != alt_cont:
+ if alt_cont and user_cont != alt_cont:
raiseCLIError(CLISyntaxError(
- 'Conflict: 2 containers (%s, %s)' % (cont, alt_cont),
- details=self.generic_err_details)
+ 'Conflict: 2 containers (%s, %s)' % (user_cont, alt_cont),
+ details=errors.pithos.container_howto)
)
- self.container = cont
- if not path:
+ self.container = user_cont
+ if not userpath:
raiseCLIError(CLISyntaxError(
- 'Path is missing for object in container %s' % cont,
- details=self.generic_err_details)
+ 'Path is missing for object in container %s' % user_cont,
+ details=errors.pithos.container_howto)
)
- self.path = path
+ self.path = userpath
else:
alt_cont = self['container'] or self.client.container
if alt_cont:
self.container = alt_cont
- self.path = cont
+ self.path = user_cont
elif path_is_optional:
- self.container = cont
+ self.container = user_cont
self.path = None
else:
- self.container = cont
+ self.container = user_cont
raiseCLIError(CLISyntaxError(
'Both container and path are required',
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
)
- def main(self, container_with_path=None, path_is_optional=True):
- super(_store_container_command, self).main()
+ @errors.generic.all
+ def _run(self, container_with_path=None, path_is_optional=True):
+ super(_store_container_command, self)._run()
if container_with_path is not None:
self.extract_container_and_path(
container_with_path,
self.client.container = self['container']
self.container = self.client.container
+ def main(self, container_with_path=None, path_is_optional=True):
+ self._run(container_with_path, path_is_optional)
+
@command(pithos_cmds)
class store_list(_store_container_command):
if self['more']:
page_hold(index + 1, limit, len(container_list))
+ @errors.generic.all
+ @errors.pithos.connection
+ @errors.pithos.object_path
+ @errors.pithos.container
+ def _run(self):
+ if self.container is None:
+ r = self.client.account_get(
+ limit=False if self['more'] else self['limit'],
+ marker=self['marker'],
+ if_modified_since=self['if_modified_since'],
+ if_unmodified_since=self['if_unmodified_since'],
+ until=self['until'],
+ show_only_shared=self['shared'])
+ self.print_containers(r.json)
+ else:
+ prefix = self.path if self.path else self['prefix']
+ r = self.client.container_get(
+ limit=False if self['more'] else self['limit'],
+ marker=self['marker'],
+ prefix=prefix,
+ delimiter=self['delimiter'],
+ path=self['path'],
+ if_modified_since=self['if_modified_since'],
+ if_unmodified_since=self['if_unmodified_since'],
+ until=self['until'],
+ meta=self['meta'],
+ show_only_shared=self['shared'])
+ self.print_objects(r.json)
+
def main(self, container____path__=None):
- super(self.__class__, self).main(container____path__)
- try:
- if self.container is None:
- r = self.client.account_get(
- limit=False if self['more'] else self['limit'],
- marker=self['marker'],
- if_modified_since=self['if_modified_since'],
- if_unmodified_since=self['if_unmodified_since'],
- until=self['until'],
- show_only_shared=self['shared'])
- self.print_containers(r.json)
- else:
- prefix = self.path if self.path else self['prefix']
- r = self.client.container_get(
- limit=False if self['more'] else self['limit'],
- marker=self['marker'],
- prefix=prefix,
- delimiter=self['delimiter'],
- path=self['path'],
- if_modified_since=self['if_modified_since'],
- if_unmodified_since=self['if_unmodified_since'],
- until=self['until'],
- meta=self['meta'],
- show_only_shared=self['shared'])
- self.print_objects(r.json)
- except ClientError as err:
- if err.status == 404:
- if 'container' in ('%s' % err).lower():
- raiseCLIError(
- err,
- 'No container %s in account %s'\
- % (self.container, self.account),
- details=self.generic_err_details)
- elif 'object' in ('%s' % err).lower():
- raiseCLIError(
- err,
- 'No object %s in %s\'s container %s'\
- % (self.path, self.account, self.container),
- details=self.generic_err_details)
- raise_connection_errors(err)
- raiseCLIError(err)
- except Exception as e:
- raiseCLIError(e)
+ super(self.__class__, self)._run(container____path__)
+ self._run()
@command(pithos_cmds)
__doc__ += '\n. '.join(about_directories)
+ @errors.generic.all
+ @errors.pithos.connection
+ @errors.pithos.container
+ def _run(self):
+ self.client.create_directory(self.path)
+
def main(self, container___directory):
- super(self.__class__,
- self).main(container___directory, path_is_optional=False)
- try:
- self.client.create_directory(self.path)
- except ClientError as err:
- if err.status == 404:
- if 'container' in ('%s' % err).lower():
- raiseCLIError(
- err,
- 'No container %s in account %s'\
- % (self.container, self.account),
- details=self.generic_err_details)
- elif 'object' in ('%s' % err).lower():
- raiseCLIError(
- err,
- 'No object %s in container %s'\
- % (self.path, self.container),
- details=self.generic_err_details)
- raise_connection_errors(err)
- raiseCLIError(err)
- except Exception as err:
- raiseCLIError(err)
+ super(self.__class__, self)._run(
+ container___directory,
+ path_is_optional=False)
+ self._run()
@command(pithos_cmds)
default='application/octet-stream')
)
+ @errors.generic.all
+ @errors.pithos.connection
+ @errors.pithos.container
+ def _run(self):
+ self.client.create_object(self.path, self['content_type'])
+
def main(self, container___path):
- super(store_touch, self).main(container___path)
- try:
- self.client.create_object(self.path, self['content_type'])
- except ClientError as err:
- if err.status == 404:
- if 'container' in ('%s' % err).lower():
- raiseCLIError(
- err,
- 'No container %s in account %s'\
- % (self.container, self.account),
- details=self.generic_err_details)
- elif 'object' in ('%s' % err).lower():
- raiseCLIError(
- err,
- 'No object %s in container %s'\
- % (self.path, self.container),
- details=self.generic_err_details)
- raise_connection_errors(err)
- raiseCLIError(err)
- except Exception as err:
- raiseCLIError(err)
+ super(store_touch, self)._run(container___path)
+ self._run()
@command(pithos_cmds)
'--meta')
)
+ @errors.generic.all
+ @errors.pithos.connection
+ @errors.pithos.container
+ def _run(self):
+ self.client.container_put(quota=self['quota'],
+ versioning=self['versioning'],
+ metadata=self['meta'])
+
def main(self, container):
- super(self.__class__, self).main(container)
- try:
- self.client.container_put(quota=self['quota'],
- versioning=self['versioning'],
- metadata=self['meta'])
- except ClientError as err:
- if err.status == 404:
- if 'container' in ('%s' % err).lower():
- raiseCLIError(
- err,
- 'No container %s in account %s'\
- % (self.container, self.account),
- details=self.generic_err_details)
- elif 'object' in ('%s' % err).lower():
- raiseCLIError(
- err,
- 'No object %s in container %s'\
- % (self.path, self.container),
- details=self.generic_err_details)
- raise_connection_errors(err)
- raiseCLIError(err)
- except Exception as e:
- raiseCLIError(e)
+ super(self.__class__, self)._run(container)
+ if self.container != container:
+ raiseCLIError('Invalid container name %s' % container, details=[
+ 'Did you mean "%s" ?' % self.container])
+ self._run()
@command(pithos_cmds)
obj['name'][len(self.path) if self['replace'] else 0:])
) for obj in r.json]
+ @errors.generic.all
+ @errors.pithos.connection
+ @errors.pithos.container
+ def _run(self, dst_cont, dst_path):
+ no_source_object = True
+ for src_object, dst_object in self._objlist(dst_path):
+ no_source_object = False
+ self.client.copy_object(
+ src_container=self.container,
+ src_object=src_object,
+ dst_container=dst_cont if dst_cont else self.container,
+ dst_object=dst_object,
+ source_version=self['source_version'],
+ public=self['public'],
+ content_type=self['content_type'])
+ if no_source_object:
+ raiseCLIError('No object %s in container %s' % (
+ self.path,
+ self.container))
+
def main(self, source_container___path, destination_container___path):
- super(self.__class__,
- self).main(source_container___path, path_is_optional=False)
- try:
- dst = destination_container___path.split(':')
- (dst_cont, dst_path) = (dst[0], dst[1])\
- if len(dst) > 1 else (None, dst[0])
- for src_object, dst_object in self._objlist(dst_path):
- self.client.copy_object(src_container=self.container,
- src_object=src_object,
- dst_container=dst_cont if dst_cont else self.container,
- dst_object=dst_object,
- source_version=self['source_version'],
- public=self['public'],
- content_type=self['content_type'])
- except ClientError as err:
- if err.status == 404:
- if 'object' in ('%s' % err).lower():
- raiseCLIError(
- err,
- 'No object %s in container %s'\
- % (self.path, self.container),
- details=self.generic_err_details)
- elif 'container' in ('%s' % err).lower():
- cont_msg = '(either %s or %s)' % (
- self.container,
- dst_cont
- ) if dst_cont else self.container
- raiseCLIError(
- err,
- 'No container %s in account %s'\
- % (cont_msg, self.account),
- details=self.generic_err_details)
- raise_connection_errors(err)
- raiseCLIError(err)
- except Exception as e:
- raiseCLIError(e)
+ super(self.__class__, self)._run(
+ source_container___path,
+ path_is_optional=False)
+ (dst_cont, dst_path) = self._dest_container_path(
+ destination_container___path)
+ self._run(dst_cont=dst_cont, dst_path=dst_path)
@command(pithos_cmds)
obj['name'][len(self.path) if self['replace'] else 0:])
) for obj in r.json]
- def main(self, source_container___path, destination_container____path__):
- super(self.__class__,
- self).main(source_container___path, path_is_optional=False)
- try:
- dst = destination_container____path__.split(':')
- (dst_cont, dst_path) = (dst[0], dst[1])\
- if len(dst) > 1 else (None, dst[0])
- for src_object, dst_object in self._objlist(dst_path):
- self.client.move_object(
- src_container=self.container,
- src_object=src_object,
- dst_container=dst_cont if dst_cont else self.container,
- dst_object=dst_object,
- source_version=self['source_version'],
- public=self['public'],
- content_type=self['content_type'])
- except ClientError as err:
- if err.status == 404:
- if 'object' in ('%s' % err).lower():
- raiseCLIError(
- err,
- 'No object %s in container %s'\
- % (self.path, self.container),
- details=self.generic_err_details)
- elif 'container' in ('%s' % err).lower():
- cont_msg = '(either %s or %s)' % (
- self.container,
- dst_cont
- ) if dst_cont else self.container
- raiseCLIError(
- err,
- 'No container %s in account %s'\
- % (cont_msg, self.account),
- details=self.generic_err_details)
- raise_connection_errors(err)
- raiseCLIError(err)
- except Exception as e:
- raiseCLIError(e)
+ @errors.generic.all
+ @errors.pithos.connection
+ @errors.pithos.container
+ def _run(self, dst_cont, dst_path):
+ no_source_object = True
+ for src_object, dst_object in self._objlist(dst_path):
+ no_source_object = False
+ self.client.move_object(
+ src_container=self.container,
+ src_object=src_object,
+ dst_container=dst_cont if dst_cont else self.container,
+ dst_object=dst_object,
+ source_version=self['source_version'],
+ public=self['public'],
+ content_type=self['content_type'])
+ if no_source_object:
+ raiseCLIError('No object %s in container %s' % (
+ self.path,
+ self.container))
+
+ def main(self, source_container___path, destination_container___path):
+ super(self.__class__, self)._run(
+ source_container___path,
+ path_is_optional=False)
+ (dst_cont, dst_path) = self._dest_container_path(
+ destination_container___path)
+ self._run(dst_cont=dst_cont, dst_path=dst_path)
@command(pithos_cmds)
err,
'No container %s in account %s'\
% (self.container, self.account),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
elif 'object' in ('%s' % err).lower():
raiseCLIError(
err,
'No object %s in container %s'\
% (self.path, self.container),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
raise_connection_errors(err)
raiseCLIError(err)
except Exception as e:
err,
'No container %s in account %s'\
% (self.container, self.account),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
elif 'object' in ('%s' % err).lower():
raiseCLIError(
err,
'No object %s in container %s'\
% (self.path, self.container),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
if err.status == 400 and\
'object length is smaller than range length'\
in ('%s' % err).lower():
err,
'No container %s in account %s'\
% (self.container, self.account),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
elif 'object' in ('%s' % err).lower():
raiseCLIError(
err,
'No object %s in container %s'\
% (self.path, self.container),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
raise_connection_errors(err)
raiseCLIError(err)
except Exception as e:
err,
'No container %s in account %s'\
% (self.container, self.account),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
elif 'object' in ('%s' % err).lower():
raiseCLIError(
err,
'No object %s in container %s'\
% (self.path, self.container),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
raise_connection_errors(err)
raiseCLIError(err)
except Exception as e:
err,
'No container %s in account %s'\
% (self.container, self.account),
- details=[self.generic_err_details])
+ details=[errors.pithos.container_howto])
elif err.status == 800:
raiseCLIError(err, details=[
'Possible cause: temporary server failure',
err,
'No container %s in account %s'\
% (self.container, self.account),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
elif 'object' in ('%s' % err).lower():
raiseCLIError(
err,
'No object %s in container %s'\
% (self.path, self.container),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
raise_connection_errors(err)
raiseCLIError(err)
except Exception as e:
err,
'No container %s in account %s'\
% (self.container, self.account),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
elif 'object' in ('%s' % err).lower():
raiseCLIError(
err,
'No object %s in container %s'\
% (self.path, self.container),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
raise_connection_errors(err)
raiseCLIError(err, '"%s" not accessible' % container___path)
except IOError as err:
err,
'No container %s in account %s'\
% (self.container, self.account),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
elif 'object' in ('%s' % err).lower():
raiseCLIError(
err,
'No object %s in container %s'\
% (self.path, self.container),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
raise_connection_errors(err)
raiseCLIError(err)
except Exception as e:
err,
'No container %s in account %s'\
% (self.container, self.account),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
elif 'object' in ('%s' % err).lower():
raiseCLIError(
err,
'No object %s in container %s'\
% (self.path, self.container),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
raise_connection_errors(err)
raiseCLIError(err)
except Exception as e:
err,
'No container %s in account %s'\
% (self.container, self.account),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
raise_connection_errors(err)
raiseCLIError(err)
except Exception as e:
err,
'No container %s in account %s'\
% (self.container, self.account),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
elif 'object' in ('%s' % err).lower():
raiseCLIError(
err,
'No object %s in container %s'\
% (self.path, self.container),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
raise_connection_errors(err)
raiseCLIError(err)
except Exception as e:
err,
'No container %s in account %s'\
% (self.container, self.account),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
elif 'object' in ('%s' % err).lower():
raiseCLIError(
err,
'No object %s in container %s'\
% (self.path, self.container),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
raise_connection_errors(err)
raiseCLIError(err)
except Exception as e:
err,
'No container %s in account %s'\
% (self.container, self.account),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
elif 'object' in ('%s' % err).lower():
raiseCLIError(
err,
'No object %s in container %s'\
% (self.path, self.container),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
raise_connection_errors(err)
raiseCLIError(err)
except Exception as e:
err,
'No container %s in account %s'\
% (self.container, self.account),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
elif 'object' in ('%s' % err).lower():
raiseCLIError(
err,
'No object %s in container %s'\
% (self.path, self.container),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
raise_connection_errors(err)
raiseCLIError(err)
except Exception as e:
err,
'No container %s in account %s'\
% (self.container, self.account),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
elif 'object' in ('%s' % err).lower():
raiseCLIError(
err,
'No object %s in container %s'\
% (self.path, self.container),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
raise_connection_errors(err)
raiseCLIError(err)
except Exception as e:
err,
'No container %s in account %s'\
% (self.container, self.account),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
elif 'object' in ('%s' % err).lower():
raiseCLIError(
err,
'No object %s in container %s'\
% (self.path, self.container),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
raise_connection_errors(err)
raiseCLIError(err)
except Exception as e:
err,
'No container %s in account %s'\
% (self.container, self.account),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
elif 'object' in ('%s' % err).lower():
raiseCLIError(
err,
'No object %s in container %s'\
% (self.path, self.container),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
else:
- raiseCLIError(err, details=self.generic_err_details)
+ raiseCLIError(err, details=errors.pithos.container_howto)
raise_connection_errors(err)
raiseCLIError(err)
except Exception as e:
err,
'No container %s in account %s'\
% (self.container, self.account),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
elif 'object' in ('%s' % err).lower():
raiseCLIError(
err,
'No object %s in container %s'\
% (self.path, self.container),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
else:
- raiseCLIError(err, details=self.generic_err_details)
+ raiseCLIError(err, details=errors.pithos.container_howto)
raise_connection_errors(err)
raiseCLIError(err)
except Exception as err:
err,
'No container %s in account %s'\
% (self.container, self.account),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
elif 'object' in ('%s' % err).lower():
raiseCLIError(
err,
'No object %s in container %s'\
% (self.path, self.container),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
else:
- raiseCLIError(err, details=self.generic_err_details)
+ raiseCLIError(err, details=errors.pithos.container_howto)
raise_connection_errors(err)
raiseCLIError(err)
except Exception as err:
err,
'No container %s in account %s'\
% (self.container, self.account),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
else:
- raiseCLIError(err, details=self.generic_err_details)
+ raiseCLIError(err, details=errors.pithos.container_howto)
raise_connection_errors(err)
raiseCLIError(err)
except Exception as err:
err,
'No container %s in account %s'\
% (self.container, self.account),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
else:
- raiseCLIError(err, details=self.generic_err_details)
+ raiseCLIError(err, details=errors.pithos.container_howto)
raise_connection_errors(err)
raiseCLIError(err)
except Exception as err:
err,
'No container %s in account %s'\
% (self.container, self.account),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
elif 'object' in ('%s' % err).lower():
raiseCLIError(
err,
'No object %s in container %s'\
% (self.path, self.container),
- details=self.generic_err_details)
+ details=errors.pithos.container_howto)
else:
- raiseCLIError(err, details=self.generic_err_details)
+ raiseCLIError(err, details=errors.pithos.container_howto)
raise_connection_errors(err)
raiseCLIError(err)
except Exception as err: