| OLD | NEW |
| (Empty) | |
| 1 # Copyright 2011 Google Inc. |
| 2 # |
| 3 # Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 # you may not use this file except in compliance with the License. |
| 5 # You may obtain a copy of the License at |
| 6 # |
| 7 # http://www.apache.org/licenses/LICENSE-2.0 |
| 8 # |
| 9 # Unless required by applicable law or agreed to in writing, software |
| 10 # distributed under the License is distributed on an "AS IS" BASIS, |
| 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 # See the License for the specific language governing permissions and |
| 13 # limitations under the License. |
| 14 |
| 15 import boto |
| 16 |
| 17 from gslib.command import Command |
| 18 from gslib.command import COMMAND_NAME |
| 19 from gslib.command import COMMAND_NAME_ALIASES |
| 20 from gslib.command import CONFIG_REQUIRED |
| 21 from gslib.command import FILE_URIS_OK |
| 22 from gslib.command import MAX_ARGS |
| 23 from gslib.command import MIN_ARGS |
| 24 from gslib.command import PROVIDER_URIS_OK |
| 25 from gslib.command import SUPPORTED_SUB_ARGS |
| 26 from gslib.command import URIS_START_ARG |
| 27 from gslib.exception import CommandException |
| 28 from gslib.help_provider import HELP_NAME |
| 29 from gslib.help_provider import HELP_NAME_ALIASES |
| 30 from gslib.help_provider import HELP_ONE_LINE_SUMMARY |
| 31 from gslib.help_provider import HELP_TEXT |
| 32 from gslib.help_provider import HelpType |
| 33 from gslib.help_provider import HELP_TYPE |
| 34 from gslib.util import NO_MAX |
| 35 |
| 36 _detailed_help_text = (""" |
| 37 <B>SYNOPSIS</B> |
| 38 gsutil rm [-f] [-R] uri... |
| 39 |
| 40 |
| 41 <B>DESCRIPTION</B> |
| 42 The gsutil rm command removes objects. |
| 43 For example, the command: |
| 44 |
| 45 gsutil rm gs://bucket/subdir/* |
| 46 |
| 47 will remove all objects in gs://bucket/subdir, but not in any of its |
| 48 sub-directories. In contrast: |
| 49 |
| 50 gsutil rm gs://bucket/subdir/** |
| 51 |
| 52 will remove all objects under gs://bucket/subdir or any of its |
| 53 subdirectories. |
| 54 |
| 55 You can also use the -R option to specify recursive object deletion. Thus, for |
| 56 example, the following two commands will both remove all objects in a bucket: |
| 57 |
| 58 gsutil rm gs://bucket/** |
| 59 gsutil rm -R gs://bucket |
| 60 |
| 61 If you have a large number of objects to remove you might want to use the |
| 62 gsutil -m option, to perform a parallel (multi-threaded/multi-processing) |
| 63 removes: |
| 64 |
| 65 gsutil -m rm -R gs://my_bucket/subdir |
| 66 |
| 67 Note that gsutil rm will refuse to remove files from the local |
| 68 file system. For example this will fail: |
| 69 |
| 70 gsutil rm *.txt |
| 71 |
| 72 |
| 73 <B>OPTIONS</B> |
| 74 -f Continues silently (without printing error messages) despite |
| 75 errors when removing multiple objects. |
| 76 |
| 77 -R, -r Causes bucket contents to be removed recursively (i.e., including |
| 78 all objects and subdirectories). Will not delete the bucket |
| 79 itself; you need to run the gsutil rb command separately to do |
| 80 that. |
| 81 """) |
| 82 |
| 83 |
| 84 class RmCommand(Command): |
| 85 """Implementation of gsutil rm command.""" |
| 86 |
| 87 # Command specification (processed by parent class). |
| 88 command_spec = { |
| 89 # Name of command. |
| 90 COMMAND_NAME : 'rm', |
| 91 # List of command name aliases. |
| 92 COMMAND_NAME_ALIASES : ['del', 'delete', 'remove'], |
| 93 # Min number of args required by this command. |
| 94 MIN_ARGS : 1, |
| 95 # Max number of args required by this command, or NO_MAX. |
| 96 MAX_ARGS : NO_MAX, |
| 97 # Getopt-style string specifying acceptable sub args. |
| 98 SUPPORTED_SUB_ARGS : 'frR', |
| 99 # True if file URIs acceptable for this command. |
| 100 FILE_URIS_OK : False, |
| 101 # True if provider-only URIs acceptable for this command. |
| 102 PROVIDER_URIS_OK : False, |
| 103 # Index in args of first URI arg. |
| 104 URIS_START_ARG : 0, |
| 105 # True if must configure gsutil before running command. |
| 106 CONFIG_REQUIRED : True, |
| 107 } |
| 108 help_spec = { |
| 109 # Name of command or auxiliary help info for which this help applies. |
| 110 HELP_NAME : 'rm', |
| 111 # List of help name aliases. |
| 112 HELP_NAME_ALIASES : ['del', 'delete', 'remove'], |
| 113 # Type of help: |
| 114 HELP_TYPE : HelpType.COMMAND_HELP, |
| 115 # One line summary of this help. |
| 116 HELP_ONE_LINE_SUMMARY : 'Remove objects', |
| 117 # The full help text. |
| 118 HELP_TEXT : _detailed_help_text, |
| 119 } |
| 120 |
| 121 # Command entry point. |
| 122 def RunCommand(self): |
| 123 # self.recursion_requested initialized in command.py (so can be checked |
| 124 # in parent class for all commands). |
| 125 continue_on_error = False |
| 126 if self.sub_opts: |
| 127 for o, unused_a in self.sub_opts: |
| 128 if o == '-f': |
| 129 continue_on_error = True |
| 130 elif o == '-r' or o == '-R': |
| 131 self.recursion_requested = True |
| 132 |
| 133 # Used to track if any files failed to be removed. |
| 134 self.everything_removed_okay = True |
| 135 |
| 136 def _RemoveExceptionHandler(e): |
| 137 """Simple exception handler to allow post-completion status.""" |
| 138 self.THREADED_LOGGER.error(str(e)) |
| 139 self.everything_removed_okay = False |
| 140 |
| 141 def _RemoveFunc(src_uri, exp_src_uri, _unused_src_uri_names_container, |
| 142 _unused_src_uri_expands_to_multi, |
| 143 _unused_have_multiple_srcs, |
| 144 _unused_have_existing_dest_subdir): |
| 145 if exp_src_uri.names_container(): |
| 146 if exp_src_uri.is_cloud_uri(): |
| 147 # Before offering advice about how to do rm + rb, ensure those |
| 148 # commands won't fail because of bucket naming problems. |
| 149 boto.s3.connection.check_lowercase_bucketname(exp_src_uri.bucket_name) |
| 150 uri_str = exp_src_uri.object_name.rstrip('/') |
| 151 raise CommandException('"rm" command will not remove buckets. To ' |
| 152 'delete this/these bucket(s) do:\n\tgsutil rm ' |
| 153 '%s/*\n\tgsutil rb %s' % (uri_str, uri_str)) |
| 154 self.THREADED_LOGGER.info('Removing %s...', exp_src_uri) |
| 155 try: |
| 156 exp_src_uri.delete_key(validate=False, headers=self.headers) |
| 157 except: |
| 158 if continue_on_error: |
| 159 self.everything_removed_okay = False |
| 160 else: |
| 161 raise |
| 162 |
| 163 # Expand wildcards, dirs, buckets, and bucket subdirs in URIs. |
| 164 src_uri_expansion = self.exp_handler.ExpandWildcardsAndContainers( |
| 165 self.args, self.recursion_requested, flat=self.recursion_requested) |
| 166 if src_uri_expansion.IsEmpty(): |
| 167 raise CommandException('No URIs matched') |
| 168 |
| 169 # Perform remove requests in parallel (-m) mode, if requested, using |
| 170 # configured number of parallel processes and threads. Otherwise, |
| 171 # perform requests with sequential function calls in current process. |
| 172 self.Apply(_RemoveFunc, src_uri_expansion, _RemoveExceptionHandler) |
| 173 |
| 174 if not self.everything_removed_okay: |
| 175 raise CommandException('Some files could not be removed.') |
| OLD | NEW |