Skip to content

Commit b30b005

Browse files
FrodoTheTrueAce Nassri
authored andcommitted
chore(samples): add preemptible vm samples (#732)
1 parent bef3bf4 commit b30b005

4 files changed

Lines changed: 285 additions & 0 deletions

File tree

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// Copyright 2022 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
/**
16+
* Creates a new preemptible VM instance with Debian 11 operating system.
17+
*
18+
* @param {string} projectId - ID or number of the project you want to use.
19+
* @param {string} zone - Name of the zone you want to use, for example: us-west3-b
20+
* @param {string} instanceName - Name of the new machine.
21+
*/
22+
function main(projectId, zone, instanceName) {
23+
// [START compute_preemptible_create]
24+
/**
25+
* TODO(developer): Uncomment and replace these variables before running the sample.
26+
*/
27+
// const projectId = 'YOUR_PROJECT_ID';
28+
// const zone = 'europe-central2-b';
29+
// const instanceName = 'YOUR_INSTANCE_NAME';
30+
31+
const compute = require('@google-cloud/compute');
32+
33+
async function createPreemptible() {
34+
const instancesClient = new compute.InstancesClient();
35+
36+
const [response] = await instancesClient.insert({
37+
instanceResource: {
38+
name: instanceName,
39+
disks: [
40+
{
41+
initializeParams: {
42+
diskSizeGb: '64',
43+
sourceImage:
44+
'projects/debian-cloud/global/images/family/debian-11/',
45+
},
46+
autoDelete: true,
47+
boot: true,
48+
},
49+
],
50+
scheduling: {
51+
// Set the preemptible setting
52+
preemptible: true,
53+
},
54+
machineType: `zones/${zone}/machineTypes/e2-small`,
55+
networkInterfaces: [
56+
{
57+
name: 'global/networks/default',
58+
},
59+
],
60+
},
61+
project: projectId,
62+
zone,
63+
});
64+
let operation = response.latestResponse;
65+
const operationsClient = new compute.ZoneOperationsClient();
66+
67+
// Wait for the create operation to complete.
68+
while (operation.status !== 'DONE') {
69+
[operation] = await operationsClient.wait({
70+
operation: operation.name,
71+
project: projectId,
72+
zone: operation.zone.split('/').pop(),
73+
});
74+
}
75+
76+
console.log('Instance created.');
77+
}
78+
79+
createPreemptible();
80+
// [END compute_preemptible_create]
81+
}
82+
83+
process.on('unhandledRejection', err => {
84+
console.error(err.message);
85+
process.exitCode = 1;
86+
});
87+
88+
main(...process.argv.slice(2));
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Copyright 2022 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
/**
16+
* Gets a list of preemption operations from given zone in a project.
17+
* Optionally limit the results to instance name.
18+
*
19+
* @param {string} projectId - ID or number of the project you want to use.
20+
* @param {string} zone - Name of the zone you want to check, for example: us-west3-b.
21+
* @param {string} instanceName - Name of the virtual machine to look for.
22+
* @param {string} customFilter - Filter string to be used for this listing operation.
23+
*/
24+
function main(projectId, zone, instanceName = '', customFilter = '') {
25+
// [START compute_preemptible_history]
26+
/**
27+
* TODO(developer): Uncomment and replace these variables before running the sample.
28+
*/
29+
// const projectId = 'YOUR_PROJECT_ID';
30+
// const zone = 'europe-central2-b';
31+
// const instanceName = 'YOUR_INSTANCE_NAME';
32+
// const customFilter = 'operationType="compute.instances.preempted"';
33+
34+
const compute = require('@google-cloud/compute');
35+
36+
async function preemptionHistory() {
37+
const zoneOperationsClient = new compute.ZoneOperationsClient();
38+
39+
let filter;
40+
41+
if (customFilter !== '') {
42+
filter = customFilter;
43+
} else {
44+
filter = 'operationType="compute.instances.preempted"';
45+
46+
if (instanceName !== '') {
47+
filter += ` AND targetLink="https://www.googleapis.com/compute/v1/projects/${projectId}/zones/${zone}/instances/${instanceName}"`;
48+
}
49+
}
50+
51+
const [operationsList] = await zoneOperationsClient.list({
52+
project: projectId,
53+
zone,
54+
filter,
55+
});
56+
57+
for (const operation of operationsList) {
58+
const thisInstanceName = operation.targetLink.split('/').pop();
59+
if (thisInstanceName === instanceName) {
60+
// The filter used is not 100% accurate, it's `contains` not `equals`
61+
// So we need to check the name to make sure it's the one we want.
62+
console.log(`- ${instanceName} ${operation.insertTime}`);
63+
}
64+
}
65+
}
66+
67+
preemptionHistory();
68+
// [END compute_preemptible_history]
69+
}
70+
71+
process.on('unhandledRejection', err => {
72+
console.error(err.message);
73+
process.exitCode = 1;
74+
});
75+
76+
main(...process.argv.slice(2));
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Copyright 2022 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
/**
16+
* Prints if a given instance is preemptible or not.
17+
*
18+
* @param {string} projectId - ID or number of the project you want to use.
19+
* @param {string} zone - Name of the zone you want to use, for example: us-west3-b
20+
* @param {string} instanceName - name of the virtual machine to check.
21+
*/
22+
function main(projectId, zone, instanceName) {
23+
// [START compute_preemptible_check]
24+
/**
25+
* TODO(developer): Uncomment and replace these variables before running the sample.
26+
*/
27+
// const projectId = 'YOUR_PROJECT_ID';
28+
// const zone = 'europe-central2-b';
29+
// const instanceName = 'YOUR_INSTANCE_NAME';
30+
31+
const compute = require('@google-cloud/compute');
32+
33+
async function printPreemptible() {
34+
const instancesClient = new compute.InstancesClient();
35+
36+
const [instance] = await instancesClient.get({
37+
project: projectId,
38+
zone,
39+
instance: instanceName,
40+
});
41+
42+
console.log(`Is instance preemptible: ${instance.scheduling.preemptible}`);
43+
}
44+
45+
printPreemptible();
46+
// [END compute_preemptible_check]
47+
}
48+
49+
process.on('unhandledRejection', err => {
50+
console.error(err.message);
51+
process.exitCode = 1;
52+
});
53+
54+
main(...process.argv.slice(2));

compute/test/preemptible.test.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Copyright 2022 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
'use strict';
16+
17+
const compute = require('@google-cloud/compute');
18+
19+
const {describe, it} = require('mocha');
20+
const cp = require('child_process');
21+
const {assert} = require('chai');
22+
23+
const {generateTestId, getStaleVMInstances, deleteInstance} = require('./util');
24+
25+
const instancesClient = new compute.InstancesClient();
26+
27+
const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
28+
29+
describe('preemptible instances tests', () => {
30+
const instanceName = generateTestId();
31+
const zone = 'europe-central2-b';
32+
33+
before(async () => {
34+
const instances = await getStaleVMInstances();
35+
await Promise.all(
36+
instances.map(instance =>
37+
deleteInstance(instance.zone, instance.instanceName)
38+
)
39+
);
40+
});
41+
42+
it('create and print preemptible instance', async () => {
43+
const projectId = await instancesClient.getProjectId();
44+
45+
let output;
46+
47+
output = execSync(
48+
`node instances/preemptible/createPreemptible ${projectId} ${zone} ${instanceName}`
49+
);
50+
assert.match(output, /Instance created./);
51+
52+
output = execSync(
53+
`node instances/preemptible/printPreemptible ${projectId} ${zone} ${instanceName}`
54+
);
55+
assert.include(output, 'Is instance preemptible: true');
56+
57+
const filter = `'targetLink="https://www.googleapis.com/compute/v1/projects/${projectId}/zones/${zone}/instances/${instanceName}"'`;
58+
59+
output = execSync(
60+
`node instances/preemptible/preemptionHistory ${projectId} ${zone} ${instanceName} ${filter}`
61+
);
62+
63+
assert.include(output, `- ${instanceName}`);
64+
65+
execSync(`node deleteInstance ${projectId} ${zone} ${instanceName}`);
66+
});
67+
});

0 commit comments

Comments
 (0)