Skip to content

Commit c21920f

Browse files
Joanna Grycziennae
authored andcommitted
feat: compute_instance_create_replicated_boot_disk
1 parent 8df436d commit c21920f

File tree

6 files changed

+274
-122
lines changed

6 files changed

+274
-122
lines changed

compute/disks/attachRegionalDisk.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ async function main(diskName, region, vmName, zone) {
3434
const projectId = await instancesClient.getProjectId();
3535

3636
// The zone of your VM.
37-
// zone = 'europe-central2-a';
37+
// zone = 'us-central1-a';
3838

3939
// The name of the VM to which you're adding the new replicated disk.
4040
// vmName = 'vm-name';
@@ -43,14 +43,16 @@ async function main(diskName, region, vmName, zone) {
4343
// diskName = 'disk-name';
4444

4545
// The region where the replicated disk is located.
46-
// region = 'europe-central2';
46+
// region = 'us-central1';
4747

4848
async function callAttachRegionalDisk() {
4949
const [response] = await instancesClient.attachDisk({
5050
instance: vmName,
5151
project: projectId,
5252
attachedDiskResource: new compute.AttachedDisk({
5353
source: `projects/${projectId}/regions/${region}/disks/${diskName}`,
54+
// If you want to force the disk to be attached, uncomment next line.
55+
// forceAttach: true,
5456
}),
5557
zone,
5658
});

compute/disks/attachRegionalDiskForce.js

Lines changed: 0 additions & 82 deletions
This file was deleted.

compute/disks/createRegionalReplicatedDisk.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@ async function main(diskName, region, zone1, zone2) {
3535

3636
// The region for the replicated disk to reside in.
3737
// The disk must be in the same region as the VM that you plan to attach it to.
38-
// region = 'europe-central2';
38+
// region = 'us-central1';
3939

4040
// The zones within the region where the two disk replicas are located
41-
// zone1 = 'europe-central2-a';
42-
// zone2 = 'europe-central2-b';
41+
// zone1 = 'us-central1-a';
42+
// zone2 = 'us-central1-b';
4343

4444
// The name of the new disk.
4545
// diskName = 'disk-name';
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
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(zone, remoteZone, instanceName, snapshotLink) {
20+
// [START compute_instance_create_replicated_boot_disk]
21+
// Import the Compute library
22+
const computeLib = require('@google-cloud/compute');
23+
const compute = computeLib.protos.google.cloud.compute.v1;
24+
25+
// Instantiate an instancesClient
26+
const instancesClient = new computeLib.InstancesClient();
27+
// Instantiate a zoneOperationsClient
28+
const zoneOperationsClient = new computeLib.ZoneOperationsClient();
29+
30+
/**
31+
* TODO(developer): Update/uncomment these variables before running the sample.
32+
*/
33+
// Project ID or project number of the Cloud project you want to use.
34+
const projectId = await instancesClient.getProjectId();
35+
36+
// The name of the new virtual machine (VM) instance.
37+
// instanceName = 'vm-name';
38+
39+
// The link to the snapshot you want to use as the source of your
40+
// data disk in the form of: "projects/{project_name}/global/snapshots/{boot_snapshot_name}"
41+
// snapshotLink = 'projects/project_name/global/snapshots/boot_snapshot_name';
42+
43+
// The name of the zone where you want to create the VM.
44+
// zone = 'us-central1-a';
45+
46+
// The remote zone for the replicated disk.
47+
// remoteZone = 'us-central1-b';
48+
49+
// Creates a new VM instance with replicated boot disk created from a snapshot.
50+
async function createInstanceReplicatedBootDisk() {
51+
const [response] = await instancesClient.insert({
52+
project: projectId,
53+
zone,
54+
instanceResource: new compute.Instance({
55+
name: instanceName,
56+
disks: [
57+
new compute.AttachedDisk({
58+
initializeParams: new compute.AttachedDiskInitializeParams({
59+
diskSizeGb: '500',
60+
sourceSnapshot: snapshotLink,
61+
diskType: `zones/${zone}/diskTypes/pd-standard`,
62+
replicaZones: [
63+
`projects/${projectId}/zones/${zone}`,
64+
`projects/${projectId}/zones/${remoteZone}`,
65+
],
66+
}),
67+
autoDelete: true,
68+
boot: true,
69+
type: 'PERSISTENT',
70+
}),
71+
],
72+
machineType: `zones/${zone}/machineTypes/n1-standard-1`,
73+
networkInterfaces: [
74+
{
75+
name: 'global/networks/default',
76+
},
77+
],
78+
}),
79+
});
80+
81+
let operation = response.latestResponse;
82+
83+
// Wait for the create operation to complete.
84+
while (operation.status !== 'DONE') {
85+
[operation] = await zoneOperationsClient.wait({
86+
operation: operation.name,
87+
project: projectId,
88+
zone: operation.zone.split('/').pop(),
89+
});
90+
}
91+
92+
console.log(`Instance: ${instanceName} with replicated boot disk created.`);
93+
}
94+
95+
createInstanceReplicatedBootDisk();
96+
// [END compute_instance_create_replicated_boot_disk]
97+
}
98+
99+
main(...process.argv.slice(2)).catch(err => {
100+
console.error(err);
101+
process.exitCode = 1;
102+
});
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
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('node:assert/strict');
21+
const uuid = require('uuid');
22+
const {after, before, describe, it} = require('mocha');
23+
const cp = require('child_process');
24+
const computeLib = require('@google-cloud/compute');
25+
const {getStaleVMInstances, deleteInstance} = require('./util');
26+
27+
const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
28+
const cwd = path.join(__dirname, '..');
29+
30+
const disksClient = new computeLib.DisksClient();
31+
32+
async function createDisk(projectId, zone, diskName) {
33+
const [response] = await disksClient.insert({
34+
project: projectId,
35+
zone,
36+
diskResource: {
37+
name: diskName,
38+
},
39+
});
40+
let operation = response.latestResponse;
41+
const operationsClient = new computeLib.ZoneOperationsClient();
42+
43+
// Wait for the create operation to complete.
44+
while (operation.status !== 'DONE') {
45+
[operation] = await operationsClient.wait({
46+
operation: operation.name,
47+
project: projectId,
48+
zone: operation.zone.split('/').pop(),
49+
});
50+
}
51+
}
52+
53+
async function deleteDisk(projectId, zone, diskName) {
54+
const [response] = await disksClient.delete({
55+
project: projectId,
56+
zone,
57+
disk: diskName,
58+
});
59+
let operation = response.latestResponse;
60+
const operationsClient = new computeLib.ZoneOperationsClient();
61+
62+
// Wait for the delete operation to complete.
63+
while (operation.status !== 'DONE') {
64+
[operation] = await operationsClient.wait({
65+
operation: operation.name,
66+
project: projectId,
67+
zone: operation.zone.split('/').pop(),
68+
});
69+
}
70+
}
71+
72+
async function createDiskSnapshot(projectId, zone, diskName, snapshotName) {
73+
const [response] = await disksClient.createSnapshot({
74+
project: projectId,
75+
zone,
76+
disk: diskName,
77+
snapshotResource: {
78+
name: snapshotName,
79+
},
80+
});
81+
let operation = response.latestResponse;
82+
const operationsClient = new computeLib.ZoneOperationsClient();
83+
84+
// Wait for the create operation to complete.
85+
while (operation.status !== 'DONE') {
86+
[operation] = await operationsClient.wait({
87+
operation: operation.name,
88+
project: projectId,
89+
zone: operation.zone.split('/').pop(),
90+
});
91+
}
92+
}
93+
94+
async function deleteDiskSnapshot(projectId, snapshotName) {
95+
const snapshotsClient = new computeLib.SnapshotsClient();
96+
const [response] = await snapshotsClient.delete({
97+
project: projectId,
98+
snapshot: snapshotName,
99+
});
100+
let operation = response.latestResponse;
101+
const operationsClient = new computeLib.GlobalOperationsClient();
102+
103+
// Wait for the delete operation to complete.
104+
while (operation.status !== 'DONE') {
105+
[operation] = await operationsClient.wait({
106+
operation: operation.name,
107+
project: projectId,
108+
});
109+
}
110+
}
111+
112+
describe('Create compute instance with replicated boot disk', async () => {
113+
const vmName = `instance-replicated-disk-${uuid.v4()}`;
114+
const snapshotName = `snapshot-${uuid.v4()}`;
115+
const diskName = `snapshot-disk-${uuid.v4()}`;
116+
const zone1 = 'us-central1-a';
117+
const zone2 = 'us-central1-b';
118+
let projectId;
119+
let diskSnapshotLink;
120+
121+
before(async () => {
122+
const instancesClient = new computeLib.InstancesClient();
123+
projectId = await instancesClient.getProjectId();
124+
diskSnapshotLink = `projects/${projectId}/global/snapshots/${snapshotName}`;
125+
126+
await createDisk(projectId, zone1, diskName);
127+
await createDiskSnapshot(projectId, zone1, diskName, snapshotName);
128+
});
129+
130+
after(async () => {
131+
// Cleanup resources
132+
const instances = await getStaleVMInstances();
133+
await Promise.all(
134+
instances.map(instance =>
135+
deleteInstance(instance.zone, instance.instanceName)
136+
)
137+
);
138+
await deleteDiskSnapshot(projectId, snapshotName);
139+
await deleteDisk(projectId, zone1, diskName);
140+
});
141+
142+
it('should create an instance with replicated boot disk', () => {
143+
const response = execSync(
144+
`node ./instances/create-start-instance/createInstanceReplicatedBootDisk.js ${zone1} ${zone2} ${vmName} ${diskSnapshotLink}`,
145+
{
146+
cwd,
147+
}
148+
);
149+
150+
assert(
151+
response.includes(
152+
`Instance: ${vmName} with replicated boot disk created.`
153+
)
154+
);
155+
});
156+
});

0 commit comments

Comments
 (0)