1 # -*- coding: utf-8 -*-
2 # Copyright 2013 Google Inc. All Rights Reserved.
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 """Implementation of lifecycle configuration command for GCS buckets."""
17 from __future__
import absolute_import
21 from gslib
.command
import Command
22 from gslib
.command_argument
import CommandArgument
23 from gslib
.cs_api_map
import ApiSelector
24 from gslib
.exception
import CommandException
25 from gslib
.help_provider
import CreateHelpText
26 from gslib
.third_party
.storage_apitools
import storage_v1_messages
as apitools_messages
27 from gslib
.translation_helper
import LifecycleTranslation
28 from gslib
.util
import NO_MAX
29 from gslib
.util
import UrlsAreForSingleProvider
33 gsutil lifecycle get url
37 gsutil lifecycle set config-json-file url...
40 _SYNOPSIS
= _GET_SYNOPSIS
+ _SET_SYNOPSIS
.lstrip('\n') + '\n'
42 _GET_DESCRIPTION
= """
44 Gets the lifecycle configuration for a given bucket. You can get the
45 lifecycle configuration for only one bucket at a time. The output can be
46 redirected into a file, edited and then updated via the set sub-command.
50 _SET_DESCRIPTION
= """
52 Sets the lifecycle configuration on one or more buckets. The config-json-file
53 specified on the command line should be a path to a local file containing
54 the lifecycle configuration JSON document.
59 The lifecycle command can be used to get or set lifecycle management policies
60 for the given bucket(s). This command is supported for buckets only, not
61 objects. For more information on object lifecycle management, please see the
62 `developer guide <https://developers.google.com/storage/docs/lifecycle>`_.
64 The lifecycle command has two sub-commands:
65 """ + _GET_DESCRIPTION
+ _SET_DESCRIPTION
+ """
67 The following lifecycle configuration JSON document specifies that all objects
68 in this bucket that are more than 365 days old will be deleted automatically:
74 "action": {"type": "Delete"},
75 "condition": {"age": 365}
80 The following (empty) lifecycle configuration JSON document removes all
81 lifecycle configuration for a bucket:
87 _DETAILED_HELP_TEXT
= CreateHelpText(_SYNOPSIS
, _DESCRIPTION
)
89 _get_help_text
= CreateHelpText(_GET_SYNOPSIS
, _GET_DESCRIPTION
)
90 _set_help_text
= CreateHelpText(_SET_SYNOPSIS
, _SET_DESCRIPTION
)
93 class LifecycleCommand(Command
):
94 """Implementation of gsutil lifecycle command."""
96 # Command specification. See base class for documentation.
97 command_spec
= Command
.CreateCommandSpec(
99 command_name_aliases
=['lifecycleconfig'],
100 usage_synopsis
=_SYNOPSIS
,
103 supported_sub_args
='',
105 provider_url_ok
=False,
107 gs_api_support
=[ApiSelector
.XML
, ApiSelector
.JSON
],
108 gs_default_api
=ApiSelector
.JSON
,
111 CommandArgument
.MakeNFileURLsArgument(1),
112 CommandArgument
.MakeZeroOrMoreCloudBucketURLsArgument()
115 CommandArgument
.MakeNCloudBucketURLsArgument(1)
119 # Help specification. See help_provider.py for documentation.
120 help_spec
= Command
.HelpSpec(
121 help_name
='lifecycle',
122 help_name_aliases
=['getlifecycle', 'setlifecycle'],
123 help_type
='command_help',
124 help_one_line_summary
=(
125 'Get or set lifecycle configuration for a bucket'),
126 help_text
=_DETAILED_HELP_TEXT
,
127 subcommand_help_text
={'get': _get_help_text
, 'set': _set_help_text
},
130 def _SetLifecycleConfig(self
):
131 """Sets lifecycle configuration for a Google Cloud Storage bucket."""
132 lifecycle_arg
= self
.args
[0]
133 url_args
= self
.args
[1:]
134 # Disallow multi-provider 'lifecycle set' requests.
135 if not UrlsAreForSingleProvider(url_args
):
136 raise CommandException('"%s" command spanning providers not allowed.' %
139 # Open, read and parse file containing JSON document.
140 lifecycle_file
= open(lifecycle_arg
, 'r')
141 lifecycle_txt
= lifecycle_file
.read()
142 lifecycle_file
.close()
144 # Iterate over URLs, expanding wildcards and setting the lifecycle on each.
146 for url_str
in url_args
:
147 bucket_iter
= self
.GetBucketUrlIterFromArg(url_str
,
148 bucket_fields
=['lifecycle'])
149 for blr
in bucket_iter
:
150 url
= blr
.storage_url
152 self
.logger
.info('Setting lifecycle configuration on %s...', blr
)
153 if url
.scheme
== 's3':
154 self
.gsutil_api
.XmlPassThroughSetLifecycle(
155 lifecycle_txt
, url
, provider
=url
.scheme
)
157 lifecycle
= LifecycleTranslation
.JsonLifecycleToMessage(lifecycle_txt
)
158 bucket_metadata
= apitools_messages
.Bucket(lifecycle
=lifecycle
)
159 self
.gsutil_api
.PatchBucket(url
.bucket_name
, bucket_metadata
,
160 provider
=url
.scheme
, fields
=['id'])
162 raise CommandException('No URLs matched')
165 def _GetLifecycleConfig(self
):
166 """Gets lifecycle configuration for a Google Cloud Storage bucket."""
167 bucket_url
, bucket_metadata
= self
.GetSingleBucketUrlFromArg(
168 self
.args
[0], bucket_fields
=['lifecycle'])
170 if bucket_url
.scheme
== 's3':
171 sys
.stdout
.write(self
.gsutil_api
.XmlPassThroughGetLifecycle(
172 bucket_url
, provider
=bucket_url
.scheme
))
174 if bucket_metadata
.lifecycle
and bucket_metadata
.lifecycle
.rule
:
175 sys
.stdout
.write(LifecycleTranslation
.JsonLifecycleFromMessage(
176 bucket_metadata
.lifecycle
))
178 sys
.stdout
.write('%s has no lifecycle configuration.\n' % bucket_url
)
182 def RunCommand(self
):
183 """Command entry point for the lifecycle command."""
184 subcommand
= self
.args
.pop(0)
185 if subcommand
== 'get':
186 return self
._GetLifecycleConfig
()
187 elif subcommand
== 'set':
188 return self
._SetLifecycleConfig
()
190 raise CommandException('Invalid subcommand "%s" for the %s command.' %
191 (subcommand
, self
.command_name
))