Skip to content
This repository was archived by the owner on Dec 31, 2023. It is now read-only.

Commit 685d909

Browse files
authored
docs(samples): Add samples for suspending/resuming an instance (#259)
* chore(samples): Adding samples for suspend/resume * Fixing lint problems
1 parent cf212ba commit 685d909

File tree

7 files changed

+321
-0
lines changed

7 files changed

+321
-0
lines changed
+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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+
# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
16+
# folder for complete code samples that are ready to be used.
17+
# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
18+
# flake8: noqa
19+
import time
20+
21+
from google.cloud import compute_v1
22+
23+
24+
# <INGREDIENT resume_instance>
25+
def resume_instance(project_id: str, zone: str, instance_name: str) -> None:
26+
"""
27+
Resume a suspended Google Compute Engine instance (with unencrypted disks).
28+
Args:
29+
project_id: project ID or project number of the Cloud project your instance belongs to.
30+
zone: name of the zone your instance belongs to.
31+
instance_name: name of the instance your want to resume.
32+
"""
33+
instance_client = compute_v1.InstancesClient()
34+
op_client = compute_v1.ZoneOperationsClient()
35+
36+
instance = instance_client.get(project=project_id, zone=zone, instance=instance_name)
37+
if instance.status != compute_v1.Instance.Status.SUSPENDED.name:
38+
raise RuntimeError(f"Only suspended instances can be resumed. "
39+
f"Instance {instance_name} is in {instance.status} state.")
40+
41+
op = instance_client.resume_unary(
42+
project=project_id, zone=zone, instance=instance_name
43+
)
44+
45+
start = time.time()
46+
while op.status != compute_v1.Operation.Status.DONE:
47+
op = op_client.wait(operation=op.name, zone=zone, project=project_id)
48+
if time.time() - start >= 300: # 5 minutes
49+
raise TimeoutError()
50+
return
51+
# </INGREDIENT>
52+
+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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+
# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
16+
# folder for complete code samples that are ready to be used.
17+
# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
18+
# flake8: noqa
19+
import time
20+
21+
from google.cloud import compute_v1
22+
23+
24+
# <INGREDIENT suspend_instance>
25+
def suspend_instance(project_id: str, zone: str, instance_name: str) -> None:
26+
"""
27+
Suspend a running Google Compute Engine instance.
28+
Args:
29+
project_id: project ID or project number of the Cloud project your instance belongs to.
30+
zone: name of the zone your instance belongs to.
31+
instance_name: name of the instance your want to suspend.
32+
"""
33+
instance_client = compute_v1.InstancesClient()
34+
op_client = compute_v1.ZoneOperationsClient()
35+
36+
op = instance_client.suspend_unary(
37+
project=project_id, zone=zone, instance=instance_name
38+
)
39+
40+
start = time.time()
41+
while op.status != compute_v1.Operation.Status.DONE:
42+
op = op_client.wait(operation=op.name, zone=zone, project=project_id)
43+
if time.time() - start >= 300: # 5 minutes
44+
raise TimeoutError()
45+
return
46+
# </INGREDIENT>
47+

samples/recipes/instances/resume.py

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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+
# flake8: noqa
15+
16+
# <REGION compute_resume_instance>
17+
# <IMPORTS/>
18+
19+
20+
# <INGREDIENT resume_instance />
21+
# </REGION compute_resume_instance>

samples/recipes/instances/suspend.py

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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+
# flake8: noqa
15+
16+
# <REGION compute_suspend_instance>
17+
# <IMPORTS/>
18+
19+
20+
# <INGREDIENT suspend_instance />
21+
# </REGION compute_suspend_instance>

samples/snippets/instances/resume.py

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
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+
# flake8: noqa
15+
16+
17+
# This file is automatically generated. Please do not modify it directly.
18+
# Find the relevant recipe file in the samples/recipes or samples/ingredients
19+
# directory and apply your changes there.
20+
21+
22+
# [START compute_resume_instance]
23+
import time
24+
25+
from google.cloud import compute_v1
26+
27+
28+
def resume_instance(project_id: str, zone: str, instance_name: str) -> None:
29+
"""
30+
Resume a suspended Google Compute Engine instance (with unencrypted disks).
31+
Args:
32+
project_id: project ID or project number of the Cloud project your instance belongs to.
33+
zone: name of the zone your instance belongs to.
34+
instance_name: name of the instance your want to resume.
35+
"""
36+
instance_client = compute_v1.InstancesClient()
37+
op_client = compute_v1.ZoneOperationsClient()
38+
39+
instance = instance_client.get(
40+
project=project_id, zone=zone, instance=instance_name
41+
)
42+
if instance.status != compute_v1.Instance.Status.SUSPENDED.name:
43+
raise RuntimeError(
44+
f"Only suspended instances can be resumed. "
45+
f"Instance {instance_name} is in {instance.status} state."
46+
)
47+
48+
op = instance_client.resume_unary(
49+
project=project_id, zone=zone, instance=instance_name
50+
)
51+
52+
start = time.time()
53+
while op.status != compute_v1.Operation.Status.DONE:
54+
op = op_client.wait(operation=op.name, zone=zone, project=project_id)
55+
if time.time() - start >= 300: # 5 minutes
56+
raise TimeoutError()
57+
return
58+
59+
60+
# [END compute_resume_instance]

samples/snippets/instances/suspend.py

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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+
# flake8: noqa
15+
16+
17+
# This file is automatically generated. Please do not modify it directly.
18+
# Find the relevant recipe file in the samples/recipes or samples/ingredients
19+
# directory and apply your changes there.
20+
21+
22+
# [START compute_suspend_instance]
23+
import time
24+
25+
from google.cloud import compute_v1
26+
27+
28+
def suspend_instance(project_id: str, zone: str, instance_name: str) -> None:
29+
"""
30+
Suspend a running Google Compute Engine instance.
31+
Args:
32+
project_id: project ID or project number of the Cloud project your instance belongs to.
33+
zone: name of the zone your instance belongs to.
34+
instance_name: name of the instance your want to suspend.
35+
"""
36+
instance_client = compute_v1.InstancesClient()
37+
op_client = compute_v1.ZoneOperationsClient()
38+
39+
op = instance_client.suspend_unary(
40+
project=project_id, zone=zone, instance=instance_name
41+
)
42+
43+
start = time.time()
44+
while op.status != compute_v1.Operation.Status.DONE:
45+
op = op_client.wait(operation=op.name, zone=zone, project=project_id)
46+
if time.time() - start >= 300: # 5 minutes
47+
raise TimeoutError()
48+
return
49+
50+
51+
# [END compute_suspend_instance]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
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+
import time
15+
import uuid
16+
17+
import google.auth
18+
from google.cloud import compute_v1
19+
import pytest
20+
21+
22+
from ..images.get import get_image_from_family
23+
from ..instances.create import create_instance, disk_from_image
24+
from ..instances.delete import delete_instance
25+
from ..instances.resume import resume_instance
26+
from ..instances.suspend import suspend_instance
27+
28+
PROJECT = google.auth.default()[1]
29+
30+
INSTANCE_ZONE = "europe-central2-b"
31+
32+
33+
def _get_status(instance: compute_v1.Instance) -> compute_v1.Instance.Status:
34+
instance_client = compute_v1.InstancesClient()
35+
return instance_client.get(
36+
project=PROJECT, zone=INSTANCE_ZONE, instance=instance.name
37+
).status
38+
39+
40+
@pytest.fixture
41+
def compute_instance():
42+
instance_name = "test-instance-" + uuid.uuid4().hex[:10]
43+
newest_debian = get_image_from_family(project="ubuntu-os-cloud", family="ubuntu-2004-lts")
44+
disk_type = f"zones/{INSTANCE_ZONE}/diskTypes/pd-standard"
45+
disks = [disk_from_image(disk_type, 100, True, newest_debian.self_link)]
46+
instance = create_instance(
47+
PROJECT, INSTANCE_ZONE, instance_name, disks
48+
)
49+
yield instance
50+
51+
delete_instance(PROJECT, INSTANCE_ZONE, instance_name)
52+
53+
54+
def test_instance_suspend_resume(compute_instance):
55+
assert _get_status(compute_instance) == compute_v1.Instance.Status.RUNNING.name
56+
57+
# Once the machine is running, give it some time to fully start all processes
58+
# before trying to suspend it
59+
time.sleep(45)
60+
61+
suspend_instance(PROJECT, INSTANCE_ZONE, compute_instance.name)
62+
63+
while _get_status(compute_instance) == compute_v1.Instance.Status.SUSPENDING.name:
64+
time.sleep(5)
65+
66+
assert _get_status(compute_instance) == compute_v1.Instance.Status.SUSPENDED.name
67+
68+
resume_instance(PROJECT, INSTANCE_ZONE, compute_instance.name)
69+
assert _get_status(compute_instance) == compute_v1.Instance.Status.RUNNING.name

0 commit comments

Comments
 (0)