Skip to content

Commit c08518a

Browse files
gryczjsubfuzion
andauthored
feat: compute_hyperdisk_create_from_pool (#3800)
* feat: compute_hyperdisk_create_from_pool * Changed debian-10 -> debian-11 * code refactor * Remove deleteDisk method from util.js * fix: test fails if resources already exist * debug: test failure * debug: test failure (add delay) * test: isolate failing test * test: isolate failing test * test: debug failing test * test: resume all tests * test: diagnose test failure� --------- Co-authored-by: Tony Pujals <[email protected]> Co-authored-by: Tony Pujals <[email protected]>
1 parent 933522c commit c08518a

5 files changed

+266
-33
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/*
2+
* Copyright 2024 Google LLC
3+
*
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
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
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+
*/
16+
17+
'use strict';
18+
19+
async function main() {
20+
// [START compute_hyperdisk_create_from_pool]
21+
// Import the Compute library
22+
const computeLib = require('@google-cloud/compute');
23+
const compute = computeLib.protos.google.cloud.compute.v1;
24+
25+
// Instantiate a diskClient
26+
const disksClient = new computeLib.DisksClient();
27+
// Instantiate a zoneOperationsClient
28+
const zoneOperationsClient = new computeLib.ZoneOperationsClient();
29+
30+
/**
31+
* TODO(developer): Update these variables before running the sample.
32+
*/
33+
// Project ID or project number of the Google Cloud project you want to use.
34+
const projectId = await disksClient.getProjectId();
35+
// The zone where your VM and new disk are located.
36+
const zone = 'europe-central2-b';
37+
// The name of the new disk
38+
const diskName = 'disk-name-from-pool';
39+
// The name of the storage pool
40+
const storagePoolName = 'storage-pool-name-hyperdisk';
41+
// Link to the storagePool you want to use. Use format:
42+
// https://www.googleapis.com/compute/v1/projects/{projectId}/zones/{zone}/storagePools/{storagePoolName}
43+
const storagePool = `https://www.googleapis.com/compute/v1/projects/${projectId}/zones/${zone}/storagePools/${storagePoolName}`;
44+
// The type of disk. This value uses the following format:
45+
// "zones/{zone}/diskTypes/(hyperdisk-balanced|hyperdisk-extreme|hyperdisk-ml|hyperdisk-throughput)".
46+
// For example: "zones/us-west3-b/diskTypes/hyperdisk-balanced"
47+
const diskType = `zones/${zone}/diskTypes/hyperdisk-balanced`;
48+
// Size of the new disk in gigabytes.
49+
const diskSizeGb = 10;
50+
// Optional: For Hyperdisk Balanced or Hyperdisk Extreme disks,
51+
// this is the number of I/O operations per second (IOPS) that the disk can handle.
52+
const provisionedIops = 3000;
53+
// Optional: For Hyperdisk Balanced or Hyperdisk Throughput volumes,
54+
// this is an integer that represents the throughput,
55+
// measured in MiB per second, that the disk can handle.
56+
const provisionedThroughput = 140;
57+
58+
async function callCreateComputeHyperdiskFromPool() {
59+
// Create a disk
60+
const disk = new compute.Disk({
61+
sizeGb: diskSizeGb,
62+
name: diskName,
63+
type: diskType,
64+
zone,
65+
storagePool,
66+
provisionedIops,
67+
provisionedThroughput,
68+
});
69+
70+
const [response] = await disksClient.insert({
71+
project: projectId,
72+
zone,
73+
diskResource: disk,
74+
});
75+
76+
let operation = response.latestResponse;
77+
78+
// Wait for the create disk operation to complete.
79+
while (operation.status !== 'DONE') {
80+
[operation] = await zoneOperationsClient.wait({
81+
operation: operation.name,
82+
project: projectId,
83+
zone: operation.zone.split('/').pop(),
84+
});
85+
}
86+
87+
const hyperdisk = (
88+
await disksClient.get({
89+
project: projectId,
90+
zone,
91+
disk: diskName,
92+
})
93+
)[0];
94+
95+
console.log(JSON.stringify(hyperdisk));
96+
}
97+
98+
await callCreateComputeHyperdiskFromPool();
99+
// [END compute_hyperdisk_create_from_pool]
100+
}
101+
102+
main().catch(err => {
103+
console.error(err);
104+
process.exitCode = 1;
105+
});

compute/test/createComputeHyperdisk.test.js

+16-3
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,9 @@
1818

1919
const path = require('path');
2020
const {assert} = require('chai');
21-
const {describe, it} = require('mocha');
21+
const {before, after, describe, it} = require('mocha');
2222
const cp = require('child_process');
2323
const {DisksClient} = require('@google-cloud/compute').v1;
24-
const {deleteDisk} = require('./util');
2524

2625
const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
2726
const cwd = path.join(__dirname, '..');
@@ -34,10 +33,24 @@ describe('Create compute hyperdisk', async () => {
3433

3534
before(async () => {
3635
projectId = await disksClient.getProjectId();
36+
try {
37+
// Ensure resource is deleted attempting to recreate it
38+
await disksClient.delete({
39+
project: projectId,
40+
disk: diskName,
41+
zone,
42+
});
43+
} catch {
44+
// ok to ignore (resource doesn't exist)
45+
}
3746
});
3847

3948
after(async () => {
40-
await deleteDisk(disksClient, projectId, zone, diskName);
49+
await disksClient.delete({
50+
project: projectId,
51+
disk: diskName,
52+
zone,
53+
});
4154
});
4255

4356
it('should create a new hyperdisk', () => {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/*
2+
* Copyright 2024 Google LLC
3+
*
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
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
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+
*/
16+
17+
'use strict';
18+
19+
const path = require('path');
20+
const {assert} = require('chai');
21+
const {after, before, describe, it} = require('mocha');
22+
const cp = require('child_process');
23+
const {DisksClient, StoragePoolsClient} = require('@google-cloud/compute').v1;
24+
25+
const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
26+
const cwd = path.join(__dirname, '..');
27+
28+
describe('Create compute hyperdisk from pool', async () => {
29+
const diskName = 'disk-name-from-pool';
30+
const zone = 'europe-central2-b';
31+
const storagePoolName = 'storage-pool-name-hyperdisk';
32+
const disksClient = new DisksClient();
33+
const storagePoolsClient = new StoragePoolsClient();
34+
let projectId;
35+
36+
before(async () => {
37+
projectId = await disksClient.getProjectId();
38+
39+
// Ensure resources are deleted before attempting to recreate them
40+
try {
41+
await disksClient.delete({
42+
project: projectId,
43+
disk: diskName,
44+
zone,
45+
});
46+
} catch (err) {
47+
// Should be ok to ignore (resource doesn't exist)
48+
console.error(err);
49+
}
50+
51+
try {
52+
await storagePoolsClient.delete({
53+
project: projectId,
54+
storagePool: storagePoolName,
55+
zone,
56+
});
57+
} catch (err) {
58+
// Should be ok to ignore (resource doesn't exist)
59+
console.error(err);
60+
}
61+
62+
await storagePoolsClient.insert({
63+
project: projectId,
64+
storagePoolResource: {
65+
name: storagePoolName,
66+
poolProvisionedCapacityGb: 10240,
67+
poolProvisionedIops: 10000,
68+
poolProvisionedThroughput: 1024,
69+
storagePoolType: `projects/${projectId}/zones/${zone}/storagePoolTypes/hyperdisk-balanced`,
70+
capacityProvisioningType: 'advanced',
71+
zone,
72+
},
73+
zone,
74+
});
75+
});
76+
77+
after(async () => {
78+
// Trying to delete the disk too quickly seems to fail
79+
const deleteDisk = async () => {
80+
setTimeout(async () => {
81+
await disksClient.delete({
82+
project: projectId,
83+
disk: diskName,
84+
zone,
85+
});
86+
}, 120 * 1000); // wait two minutes
87+
};
88+
89+
try {
90+
await deleteDisk();
91+
} catch {
92+
// Try one more time after repeating the delay
93+
await deleteDisk();
94+
}
95+
96+
// Need enough time after removing the disk before removing the pool
97+
const deletePool = async () => {
98+
setTimeout(async () => {
99+
await storagePoolsClient.delete({
100+
project: projectId,
101+
storagePool: storagePoolName,
102+
zone,
103+
});
104+
}, 120 * 1000); // wait two minutes
105+
};
106+
107+
try {
108+
await deletePool();
109+
} catch {
110+
// Try one more time after repeating the delay
111+
await deletePool();
112+
}
113+
});
114+
115+
it('should create a new hyperdisk from pool', () => {
116+
const response = JSON.parse(
117+
execSync('node ./disks/createComputeHyperdiskFromPool.js', {
118+
cwd,
119+
})
120+
);
121+
122+
assert.equal(response.name, diskName);
123+
assert.equal(
124+
response.storagePool,
125+
`https://www.googleapis.com/compute/v1/projects/${projectId}/zones/${zone}/storagePools/${storagePoolName}`
126+
);
127+
});
128+
});

compute/test/createComputeHyperdiskPool.test.js

+17-16
Original file line numberDiff line numberDiff line change
@@ -18,38 +18,39 @@
1818

1919
const path = require('path');
2020
const assert = require('node:assert/strict');
21-
const {describe, it} = require('mocha');
21+
const {after, before, describe, it} = require('mocha');
2222
const cp = require('child_process');
2323
const {StoragePoolsClient} = require('@google-cloud/compute').v1;
2424

2525
const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
2626
const cwd = path.join(__dirname, '..');
27-
const storagePoolsClient = new StoragePoolsClient();
28-
29-
async function deleteStoragePool(projectId, zone, storagePoolName) {
30-
try {
31-
await storagePoolsClient.delete({
32-
project: projectId,
33-
storagePool: storagePoolName,
34-
zone,
35-
});
36-
} catch (err) {
37-
console.error('Deleting storage pool failed: ', err);
38-
throw new Error(err);
39-
}
40-
}
4127

4228
describe('Create compute hyperdisk pool', async () => {
4329
const storagePoolName = 'storage-pool-name';
4430
const zone = 'us-central1-a';
31+
const storagePoolsClient = new StoragePoolsClient();
4532
let projectId;
4633

4734
before(async () => {
4835
projectId = await storagePoolsClient.getProjectId();
36+
try {
37+
// Ensure resource is deleted attempting to recreate it
38+
await storagePoolsClient.delete({
39+
project: projectId,
40+
storagePool: storagePoolName,
41+
zone,
42+
});
43+
} catch {
44+
// ok to ignore (resource doesn't exist)
45+
}
4946
});
5047

5148
after(async () => {
52-
await deleteStoragePool(projectId, zone, storagePoolName);
49+
await storagePoolsClient.delete({
50+
project: projectId,
51+
storagePool: storagePoolName,
52+
zone,
53+
});
5354
});
5455

5556
it('should create a new storage pool', () => {

compute/test/util.js

-14
Original file line numberDiff line numberDiff line change
@@ -82,22 +82,8 @@ async function deleteInstance(zone, instanceName) {
8282
}
8383
}
8484

85-
async function deleteDisk(disksClient, projectId, zone, diskName) {
86-
try {
87-
await disksClient.delete({
88-
project: projectId,
89-
disk: diskName,
90-
zone,
91-
});
92-
} catch (err) {
93-
console.error('Deleting disk failed: ', err);
94-
throw new Error(err);
95-
}
96-
}
97-
9885
module.exports = {
9986
generateTestId,
10087
getStaleVMInstances,
10188
deleteInstance,
102-
deleteDisk,
10389
};

0 commit comments

Comments
 (0)