Nodejs-storage: Cannot create bucket in a specific region

Created on 30 Aug 2018  ·  11Comments  ·  Source: googleapis/nodejs-storage

When I try to create a regional bucket:

let data = await bucket.create({ regional: true });

It fails, apparently because it doesn't know which region to use. I cannot find any APIs to specify which region.

 ApiError: The combination of locationConstraint and storageClass you provided is not supported for your project
  at Object.parseHttpRespBody (node_modules/@google-cloud/storage/node_modules/@google-cloud/common/src/util.js:193:30)
  at Object.handleResp (node_modules/@google-cloud/storage/node_modules/@google-cloud/common/src/util.js:131:18)
  at node_modules/@google-cloud/storage/node_modules/@google-cloud/common/src/util.js:496:12
  at Request.onResponse [as _callback] (node_modules/retry-request/index.js:198:7)
  at Request.self.callback (node_modules/request/request.js:185:22)
  at Request.<anonymous> (node_modules/request/request.js:1161:10)
  at IncomingMessage.<anonymous> (node_modules/request/request.js:1083:12)
  at endReadableNT (_stream_readable.js:1064:12)
  at _combinedTickCallback (internal/process/next_tick.js:138:11)
  at process._tickCallback (internal/process/next_tick.js:180:9)
storage question

All 11 comments

@stephenplusplus Can you have a look?

@bem7 we have an example on the docs that show this: https://cloud.google.com/nodejs/docs/reference/storage/1.7.x/Storage#createBucket:

Create a bucket in a specific location and region. See the Official JSON API docs for complete details on the location option.

const metadata = {
  location: 'US-CENTRAL1',
  regional: true
};

storage.createBucket('new-bucket', metadata, callback);

Please let me know if you still have any issues after trying this.

@stephenplusplus There is a problem here, at least for TypeScript.

  Object literal may only specify known properties, and 'location' does not exist in type 'CreateBucketRequest'.

And it's true, CreateBucketRequest, the parameter to createBucket(), has boolean options for nearline and so on, but no way to actually specify the location.

location is only a property of the interface BucketOptions, which is only a parameter to bucket(), the function for getting a bucket that is already created, ie after it's too late.

export interface BucketOptions extends CreateOptions { 
location?: string; 
kmsKeyName?: string; 
userProject?: string; }

It seems like a bug, probably somebody meant to add it to CreateBucketRequest.

Confirmed that my fix works:

screen shot 2018-11-16 at 5 52 56 pm

Nice! Would you mind sending a PR with that fix for TypeScript?

Sorry, I didn't see the PR you already made: #518 🤦‍♂️

@stephenplusplus @JustinBeckwith

Apparently, based on the failing test, the location field is also needed to get the already created bucket.

To me that makes no sense. This could be a case of the test simply enforcing the incorrect behaviour. But perhaps there is such a concept and location needs to be a parameter to both createBucket() and bucket().

In the raw API docs anyway, Bucket.create() takes CreateBucketRequest which has location, but Storage.bucket() does not.

Can one of you actually look at this and give your word on that?

Also this issue should probably be re-opened.

Yep, that location shouldn't have been there. Fixed it in a follow-up commit to your PR: #518

While we're all here and have already paid the price of context switching, there is one potential minor improvement to this API:

There is no version of this function that lets us use async AND pass the optional params.

So just to do:

const bucket: Bucket = await createBucket('example', { location: 'EUROPE-WEST4' });

we have to add a shim:

async function createBucket(name: string, options: CreateBucketRequest): Promise<Bucket> {
    return new Promise((resolve, reject) => {
        storage.createBucket(name, options, (err, bucket: Bucket) => {
            if (err) { reject(err); }
            resolve(bucket);
        });
    }) as Promise<Bucket>;
}

hi guys, I found the documentation to be lacking, and still a bit confused. How do I create a bucket at a specific location? https://googleapis.dev/nodejs/storage/latest/global.html#CreateBucketRequest doesn't list that we can provide location as a parameter, plus it's missing metadata options for bucket creation that should be there like retention etc. Some examples show possibilities but the createBucketRequest object only shows that you can specify bucket class

Was this page helpful?
0 / 5 - 0 ratings