# -*- coding: utf-8 -*- # Copyright 2011 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Implementation of mb command for creating cloud storage buckets.""" from __future__ import absolute_import import textwrap from gslib.cloud_api import BadRequestException from gslib.command import Command from gslib.command_argument import CommandArgument from gslib.cs_api_map import ApiSelector from gslib.exception import CommandException from gslib.storage_url import StorageUrlFromString from gslib.third_party.storage_apitools import storage_v1_messages as apitools_messages from gslib.util import NO_MAX _SYNOPSIS = """ gsutil mb [-c class] [-l location] [-p proj_id] uri... """ _DETAILED_HELP_TEXT = (""" <B>SYNOPSIS</B> """ + _SYNOPSIS + """ <B>DESCRIPTION</B> The mb command creates a new bucket. Google Cloud Storage has a single namespace, so you will not be allowed to create a bucket with a name already in use by another user. You can, however, carve out parts of the bucket name space corresponding to your company's domain name (see "gsutil help naming"). If you don't specify a project ID using the -p option, the bucket will be created using the default project ID specified in your gsutil configuration file (see "gsutil help config"). For more details about projects see "gsutil help projects". The -c and -l options specify the storage class and location, respectively, for the bucket. Once a bucket is created in a given location and with a given storage class, it cannot be moved to a different location, and the storage class cannot be changed. Instead, you would need to create a new bucket and move the data over and then delete the original bucket. <B>BUCKET STORAGE CLASSES</B> If you don't specify a -c option, the bucket will be created with the default (Standard) storage class. If you specify -c DURABLE_REDUCED_AVAILABILITY (or -c DRA), it causes the data stored in the bucket to use Durable Reduced Availability storage. Buckets created with this storage class have lower availability than Standard storage class buckets, but durability equal to that of buckets created with Standard storage class. This option allows users to reduce costs for data for which lower availability is acceptable. Durable Reduced Availability storage would not be appropriate for "hot" objects (i.e., objects being accessed frequently) or for interactive workloads; however, it might be appropriate for other types of applications. See the online documentation for `pricing <https://cloud.google.com/storage/pricing>`_ and `SLA <https://cloud.google.com/storage/sla>`_ details. If you specify -c NEARLINE (or -c NL), it causes the data stored in the bucket to use Nearline storage. Buckets created with this storage class have higher latency and lower throughput than Standard storage class buckets. The availability and durability remains equal to that of buckets created with the Standard storage class. This option is best for objects which are accessed rarely and for which slower performance is acceptable. See the online documentation for `pricing <https://cloud.google.com/storage/pricing>`_ and `SLA <https://cloud.google.com/storage/sla>`_ details. <B>BUCKET LOCATIONS</B> If you don't specify a -l option, the bucket will be created in the default location (US). Otherwise, you can specify one of the available continental locations: - ASIA (Asia) - EU (European Union) - US (United States) Example: gsutil mb -l ASIA gs://some-bucket If you specify the Durable Reduced Availability storage class (-c DRA), you can specify one of the continental locations above or one of the regional locations below: [1]_ - ASIA-EAST1 (Eastern Asia-Pacific) - US-EAST1 (Eastern United States) - US-EAST2 (Eastern United States) - US-EAST3 (Eastern United States) - US-CENTRAL1 (Central United States) - US-CENTRAL2 (Central United States) - US-WEST1 (Western United States) Example: gsutil mb -c DRA -l US-CENTRAL1 gs://some-bucket .. [1] These locations are for `Regional Buckets <https://developers.google.com/storage/docs/regional-buckets>`_. Regional Buckets is an experimental feature and data stored in these locations is not subject to the usual SLA. See the documentation for additional information. <B>OPTIONS</B> -c class Can be DRA (or DURABLE_REDUCED_AVAILABILITY), NL (or NEARLINE), or S (or STANDARD). Default is STANDARD. -l location Can be any continental location as described above, or for DRA storage class, any regional or continental location. Default is US. Locations are case insensitive. -p proj_id Specifies the project ID under which to create the bucket. """) class MbCommand(Command): """Implementation of gsutil mb command.""" # Command specification. See base class for documentation. command_spec = Command.CreateCommandSpec( 'mb', command_name_aliases=['makebucket', 'createbucket', 'md', 'mkdir'], usage_synopsis=_SYNOPSIS, min_args=1, max_args=NO_MAX, supported_sub_args='c:l:p:', file_url_ok=False, provider_url_ok=False, urls_start_arg=0, gs_api_support=[ApiSelector.XML, ApiSelector.JSON], gs_default_api=ApiSelector.JSON, argparse_arguments=[ CommandArgument.MakeZeroOrMoreCloudBucketURLsArgument() ] ) # Help specification. See help_provider.py for documentation. help_spec = Command.HelpSpec( help_name='mb', help_name_aliases=[ 'createbucket', 'makebucket', 'md', 'mkdir', 'location', 'dra', 'dras', 'reduced_availability', 'durable_reduced_availability', 'rr', 'reduced_redundancy', 'standard', 'storage class', 'nearline', 'nl'], help_type='command_help', help_one_line_summary='Make buckets', help_text=_DETAILED_HELP_TEXT, subcommand_help_text={}, ) def RunCommand(self): """Command entry point for the mb command.""" location = None storage_class = None if self.sub_opts: for o, a in self.sub_opts: if o == '-l': location = a elif o == '-p': self.project_id = a elif o == '-c': storage_class = self._Normalize_Storage_Class(a) bucket_metadata = apitools_messages.Bucket(location=location, storageClass=storage_class) for bucket_uri_str in self.args: bucket_uri = StorageUrlFromString(bucket_uri_str) if not bucket_uri.IsBucket(): raise CommandException('The mb command requires a URI that specifies a ' 'bucket.\n"%s" is not valid.' % bucket_uri) self.logger.info('Creating %s...', bucket_uri) # Pass storage_class param only if this is a GCS bucket. (In S3 the # storage class is specified on the key object.) try: self.gsutil_api.CreateBucket( bucket_uri.bucket_name, project_id=self.project_id, metadata=bucket_metadata, provider=bucket_uri.scheme) except BadRequestException as e: if (e.status == 400 and e.reason == 'DotfulBucketNameNotUnderTld' and bucket_uri.scheme == 'gs'): bucket_name = bucket_uri.bucket_name final_comp = bucket_name[bucket_name.rfind('.')+1:] raise CommandException('\n'.join(textwrap.wrap( 'Buckets with "." in the name must be valid DNS names. The bucket' ' you are attempting to create (%s) is not a valid DNS name,' ' because the final component (%s) is not currently a valid part' ' of the top-level DNS tree.' % (bucket_name, final_comp)))) else: raise return 0 def _Normalize_Storage_Class(self, sc): sc = sc.upper() if sc in ('DRA', 'DURABLE_REDUCED_AVAILABILITY'): return 'DURABLE_REDUCED_AVAILABILITY' if sc in ('S', 'STD', 'STANDARD'): return 'STANDARD' if sc in ('NL', 'NEARLINE'): return 'NEARLINE' return sc