Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(51)

Side by Side Diff: gslib/commands/lifecycle.py

Issue 698893003: Update checked in version of gsutil to version 4.6 (Closed) Base URL: http://dart.googlecode.com/svn/third_party/gsutil/
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « gslib/commands/help.py ('k') | gslib/commands/logging.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # -*- coding: utf-8 -*-
1 # Copyright 2013 Google Inc. All Rights Reserved. 2 # Copyright 2013 Google Inc. All Rights Reserved.
2 # 3 #
3 # Licensed under the Apache License, Version 2.0 (the "License"); 4 # 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 not use this file except in compliance with the License.
5 # You may obtain a copy of the License at 6 # You may obtain a copy of the License at
6 # 7 #
7 # http://www.apache.org/licenses/LICENSE-2.0 8 # http://www.apache.org/licenses/LICENSE-2.0
8 # 9 #
9 # Unless required by applicable law or agreed to in writing, software 10 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS, 11 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and 13 # See the License for the specific language governing permissions and
13 # limitations under the License. 14 # limitations under the License.
15 """Implementation of lifecycle configuration command for GCS buckets."""
16
17 from __future__ import absolute_import
14 18
15 import sys 19 import sys
16 import xml
17 20
18 from boto import handler
19 from boto.gs.lifecycle import LifecycleConfig
20 from gslib.command import Command 21 from gslib.command import Command
21 from gslib.command import COMMAND_NAME 22 from gslib.cs_api_map import ApiSelector
22 from gslib.command import COMMAND_NAME_ALIASES
23 from gslib.command import FILE_URIS_OK
24 from gslib.command import MAX_ARGS
25 from gslib.command import MIN_ARGS
26 from gslib.command import NO_MAX
27 from gslib.command import PROVIDER_URIS_OK
28 from gslib.command import SUPPORTED_SUB_ARGS
29 from gslib.command import URIS_START_ARG
30 from gslib.exception import CommandException 23 from gslib.exception import CommandException
31 from gslib.help_provider import CreateHelpText 24 from gslib.help_provider import CreateHelpText
32 from gslib.help_provider import HELP_NAME 25 from gslib.third_party.storage_apitools import storage_v1_messages as apitools_m essages
33 from gslib.help_provider import HELP_NAME_ALIASES 26 from gslib.translation_helper import LifecycleTranslation
34 from gslib.help_provider import HELP_ONE_LINE_SUMMARY 27 from gslib.util import NO_MAX
35 from gslib.help_provider import HELP_TEXT 28 from gslib.util import UrlsAreForSingleProvider
36 from gslib.help_provider import HelpType
37 from gslib.help_provider import HELP_TYPE
38 from gslib.help_provider import SUBCOMMAND_HELP_TEXT
39 29
40 30
41 _GET_SYNOPSIS = """ 31 _GET_SYNOPSIS = """
42 gsutil lifecycle get uri 32 gsutil lifecycle get url
43 """ 33 """
44 34
45 _SET_SYNOPSIS = """ 35 _SET_SYNOPSIS = """
46 gsutil lifecycle set config-xml-file uri... 36 gsutil lifecycle set config-json-file url...
47 """ 37 """
48 38
49 _SYNOPSIS = _GET_SYNOPSIS + _SET_SYNOPSIS.lstrip('\n') + '\n' 39 _SYNOPSIS = _GET_SYNOPSIS + _SET_SYNOPSIS.lstrip('\n') + '\n'
50 40
51 _GET_DESCRIPTION = """ 41 _GET_DESCRIPTION = """
52 <B>GET</B> 42 <B>GET</B>
53 Gets the lifecycle configuration for a given bucket. You can get the 43 Gets the lifecycle configuration for a given bucket. You can get the
54 lifecycle configuration for only one bucket at a time. The output can be 44 lifecycle configuration for only one bucket at a time. The output can be
55 redirected into a file, edited and then updated via the set sub-command. 45 redirected into a file, edited and then updated via the set sub-command.
56 46
57 """ 47 """
58 48
59 _SET_DESCRIPTION = """ 49 _SET_DESCRIPTION = """
60 <B>SET</B> 50 <B>SET</B>
61 Sets the lifecycle configuration on one or more buckets. The config-xml-file 51 Sets the lifecycle configuration on one or more buckets. The config-json-file
62 specified on the command line should be a path to a local file containing 52 specified on the command line should be a path to a local file containing
63 the lifecycle congfiguration XML document. 53 the lifecycle congfiguration JSON document.
64 54
65 """ 55 """
66 56
67 _DESCRIPTION = """ 57 _DESCRIPTION = """
68 The lifecycle command can be used to get or set lifecycle management policies 58 The lifecycle command can be used to get or set lifecycle management policies
69 for the given bucket(s). This command is supported for buckets only, not 59 for the given bucket(s). This command is supported for buckets only, not
70 objects. For more information on object lifecycle management, please see the 60 objects. For more information on object lifecycle management, please see the
71 `developer guide <https://developers.google.com/storage/docs/lifecycle>`_. 61 `developer guide <https://developers.google.com/storage/docs/lifecycle>`_.
72 62
73 The lifecycle command has two sub-commands: 63 The lifecycle command has two sub-commands:
74 """ + _GET_DESCRIPTION + _SET_DESCRIPTION + """ 64 """ + _GET_DESCRIPTION + _SET_DESCRIPTION + """
75 <B>EXAMPLES</B> 65 <B>EXAMPLES</B>
76 The following lifecycle configuration XML document specifies that all objects 66 The following lifecycle configuration JSON document specifies that all objects
77 that are more than 365 days old will be deleted automatically: 67 in this bucket that are more than 365 days old will be deleted automatically:
78 68
79 <?xml version="1.0" ?> 69 {
80 <LifecycleConfiguration> 70 "rule":
81 <Rule> 71 [
82 <Action> 72 {
83 <Delete/> 73 "action": {"type": "Delete"},
84 </Action> 74 "condition": {"age": 365}
85 <Condition> 75 }
86 <Age>365</Age> 76 ]
87 </Condition> 77 }
88 </Rule> 78
89 </LifecycleConfiguration> 79 The following (empty) lifecycle configuration JSON document removes all
80 lifecycle configuration for a bucket:
81
82 {}
83
90 """ 84 """
91 85
92 _detailed_help_text = CreateHelpText(_SYNOPSIS, _DESCRIPTION) 86 _DETAILED_HELP_TEXT = CreateHelpText(_SYNOPSIS, _DESCRIPTION)
93 87
94 _get_help_text = CreateHelpText(_GET_SYNOPSIS, _GET_DESCRIPTION) 88 _get_help_text = CreateHelpText(_GET_SYNOPSIS, _GET_DESCRIPTION)
95 _set_help_text = CreateHelpText(_SET_SYNOPSIS, _SET_DESCRIPTION) 89 _set_help_text = CreateHelpText(_SET_SYNOPSIS, _SET_DESCRIPTION)
96 90
97 91
98 class LifecycleCommand(Command): 92 class LifecycleCommand(Command):
99 """Implementation of gsutil lifecycle command.""" 93 """Implementation of gsutil lifecycle command."""
100 94
101 # Command specification (processed by parent class). 95 # Command specification. See base class for documentation.
102 command_spec = { 96 command_spec = Command.CreateCommandSpec(
103 # Name of command. 97 'lifecycle',
104 COMMAND_NAME : 'lifecycle', 98 command_name_aliases=['lifecycleconfig'],
105 # List of command name aliases. 99 min_args=2,
106 COMMAND_NAME_ALIASES : ['lifecycleconfig'], 100 max_args=NO_MAX,
107 # Min number of args required by this command. 101 supported_sub_args='',
108 MIN_ARGS : 2, 102 file_url_ok=True,
109 # Max number of args required by this command, or NO_MAX. 103 provider_url_ok=False,
110 MAX_ARGS : NO_MAX, 104 urls_start_arg=1,
111 # Getopt-style string specifying acceptable sub args. 105 gs_api_support=[ApiSelector.XML, ApiSelector.JSON],
112 SUPPORTED_SUB_ARGS : '', 106 gs_default_api=ApiSelector.JSON,
113 # True if file URIs acceptable for this command. 107 )
114 FILE_URIS_OK : True, 108 # Help specification. See help_provider.py for documentation.
115 # True if provider-only URIs acceptable for this command. 109 help_spec = Command.HelpSpec(
116 PROVIDER_URIS_OK : False, 110 help_name='lifecycle',
117 # Index in args of first URI arg. 111 help_name_aliases=['getlifecycle', 'setlifecycle'],
118 URIS_START_ARG : 1, 112 help_type='command_help',
119 } 113 help_one_line_summary=(
120 help_spec = { 114 'Get or set lifecycle configuration for a bucket'),
121 # Name of command or auxiliary help info for which this help applies. 115 help_text=_DETAILED_HELP_TEXT,
122 HELP_NAME : 'lifecycle', 116 subcommand_help_text={'get': _get_help_text, 'set': _set_help_text},
123 # List of help name aliases. 117 )
124 HELP_NAME_ALIASES : ['getlifecycle', 'setlifecycle'],
125 # Type of help)
126 HELP_TYPE : HelpType.COMMAND_HELP,
127 # One line summary of this help.
128 HELP_ONE_LINE_SUMMARY : 'Get or set lifecycle configuration for a bucket',
129 # The full help text.
130 HELP_TEXT : _detailed_help_text,
131 # Help text for sub-commands.
132 SUBCOMMAND_HELP_TEXT : {'get' : _get_help_text,
133 'set' : _set_help_text},
134 }
135 118
136 # Get lifecycle configuration
137 def _GetLifecycleConfig(self):
138 # Wildcarding is allowed but must resolve to just one bucket.
139 uris = list(self.WildcardIterator(self.args[0]).IterUris())
140 if len(uris) == 0:
141 raise CommandException('No URIs matched')
142 if len(uris) != 1:
143 raise CommandException('%s matched more than one URI, which is not\n'
144 'allowed by the %s command' % (self.args[0], self.command_name))
145 uri = uris[0]
146 if not uri.names_bucket():
147 raise CommandException('"%s" command must specify a bucket' %
148 self.command_name)
149 lifecycle_config = uri.get_lifecycle_config(False, self.headers)
150 # Pretty-print the XML to make it more easily human editable.
151 parsed_xml = xml.dom.minidom.parseString(
152 lifecycle_config.to_xml().encode('utf-8'))
153 sys.stdout.write(parsed_xml.toprettyxml(indent=' '))
154 return 0
155
156 # Set lifecycle configuration
157 def _SetLifecycleConfig(self): 119 def _SetLifecycleConfig(self):
120 """Sets lifecycle configuration for a Google Cloud Storage bucket."""
158 lifecycle_arg = self.args[0] 121 lifecycle_arg = self.args[0]
159 uri_args = self.args[1:] 122 url_args = self.args[1:]
160 # Disallow multi-provider setlifecycle requests. 123 # Disallow multi-provider 'lifecycle set' requests.
161 storage_uri = self.UrisAreForSingleProvider(uri_args) 124 if not UrlsAreForSingleProvider(url_args):
162 if not storage_uri:
163 raise CommandException('"%s" command spanning providers not allowed.' % 125 raise CommandException('"%s" command spanning providers not allowed.' %
164 self.command_name) 126 self.command_name)
165 127
166 # Open, read and parse file containing XML document. 128 # Open, read and parse file containing JSON document.
167 lifecycle_file = open(lifecycle_arg, 'r') 129 lifecycle_file = open(lifecycle_arg, 'r')
168 lifecycle_txt = lifecycle_file.read() 130 lifecycle_txt = lifecycle_file.read()
169 lifecycle_file.close() 131 lifecycle_file.close()
170 lifecycle_config = LifecycleConfig() 132 lifecycle = LifecycleTranslation.JsonLifecycleToMessage(lifecycle_txt)
171 133
172 # Parse XML document and convert into LifecycleConfig object. 134 # Iterate over URLs, expanding wildcards and setting the lifecycle on each.
173 h = handler.XmlHandler(lifecycle_config, None) 135 some_matched = False
174 try: 136 for url_str in url_args:
175 xml.sax.parseString(lifecycle_txt, h) 137 bucket_iter = self.GetBucketUrlIterFromArg(url_str,
176 except xml.sax._exceptions.SAXParseException, e: 138 bucket_fields=['lifecycle'])
177 raise CommandException( 139 for blr in bucket_iter:
178 'Requested lifecycle config is invalid: %s at line %s, column %s' % 140 url = blr.storage_url
179 (e.getMessage(), e.getLineNumber(), e.getColumnNumber())) 141 some_matched = True
142 self.logger.info('Setting lifecycle configuration on %s...', blr)
143 if url.scheme == 's3':
144 self.gsutil_api.XmlPassThroughSetLifecycle(
145 lifecycle_txt, url, provider=url.scheme)
146 else:
147 bucket_metadata = apitools_messages.Bucket(lifecycle=lifecycle)
148 self.gsutil_api.PatchBucket(url.bucket_name, bucket_metadata,
149 provider=url.scheme, fields=['id'])
150 if not some_matched:
151 raise CommandException('No URLs matched')
152 return 0
180 153
181 # Iterate over URIs, expanding wildcards, and setting the lifecycle config 154 def _GetLifecycleConfig(self):
182 # on each. 155 """Gets lifecycle configuration for a Google Cloud Storage bucket."""
183 some_matched = False 156 bucket_url, bucket_metadata = self.GetSingleBucketUrlFromArg(
184 for uri_str in uri_args: 157 self.args[0], bucket_fields=['lifecycle'])
185 for blr in self.WildcardIterator(uri_str): 158
186 uri = blr.GetUri() 159 if bucket_url.scheme == 's3':
187 if not uri.names_bucket(): 160 sys.stdout.write(self.gsutil_api.XmlPassThroughGetLifecycle(
188 raise CommandException('URI %s must name a bucket for the %s command' 161 bucket_url, provider=bucket_url.scheme))
189 % (str(uri), self.command_name)) 162 else:
190 some_matched = True 163 if bucket_metadata.lifecycle and bucket_metadata.lifecycle.rule:
191 self.logger.info('Setting lifecycle configuration on %s...', uri) 164 sys.stdout.write(LifecycleTranslation.JsonLifecycleFromMessage(
192 uri.configure_lifecycle(lifecycle_config, False, self.headers) 165 bucket_metadata.lifecycle))
193 if not some_matched: 166 else:
194 raise CommandException('No URIs matched') 167 sys.stdout.write('%s has no lifecycle configuration.\n' % bucket_url)
195 168
196 return 0 169 return 0
197 170
198 # Command entry point.
199 def RunCommand(self): 171 def RunCommand(self):
172 """Command entry point for the lifecycle command."""
200 subcommand = self.args.pop(0) 173 subcommand = self.args.pop(0)
201 if subcommand == 'get': 174 if subcommand == 'get':
202 return self._GetLifecycleConfig() 175 return self._GetLifecycleConfig()
203 elif subcommand == 'set': 176 elif subcommand == 'set':
204 return self._SetLifecycleConfig() 177 return self._SetLifecycleConfig()
205 else: 178 else:
206 raise CommandException('Invalid subcommand "%s" for the %s command.' % 179 raise CommandException('Invalid subcommand "%s" for the %s command.' %
207 (subcommand, self.command_name)) 180 (subcommand, self.command_name))
OLDNEW
« no previous file with comments | « gslib/commands/help.py ('k') | gslib/commands/logging.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698