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

Commit

Permalink
docs(samples): Adding samples for Spot VMs (#285)
Browse files Browse the repository at this point in the history
* docs(samples): Adding samples for Spot VMs

* Fixing tests perhaps

* Update samples/snippets/instances/spot/__init__.py

Co-authored-by: Leah E. Cole <6719667+leahecole@users.noreply.github.com>

* Update samples/recipes/instances/spot/__init__.py

Co-authored-by: Leah E. Cole <6719667+leahecole@users.noreply.github.com>

Co-authored-by: Leah E. Cole <6719667+leahecole@users.noreply.github.com>
  • Loading branch information
m-strzelczyk and leahecole committed Jul 14, 2022
1 parent e5afa2c commit 5b82f47
Show file tree
Hide file tree
Showing 30 changed files with 832 additions and 71 deletions.
19 changes: 16 additions & 3 deletions samples/ingredients/instances/create_instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import re
from typing import List
import warnings

from google.cloud import compute_v1

Expand All @@ -37,6 +38,8 @@ def create_instance(
external_ipv4: str = None,
accelerators: List[compute_v1.AcceleratorConfig] = None,
preemptible: bool = False,
spot: bool = False,
instance_termination_action: str = "STOP",
custom_hostname: str = None,
delete_protection: bool = False,
) -> compute_v1.Instance:
Expand Down Expand Up @@ -69,7 +72,10 @@ def create_instance(
accelerators: a list of AcceleratorConfig objects describing the accelerators that will
be attached to the new instance.
preemptible: boolean value indicating if the new instance should be preemptible
or not.
or not. Preemptible VMs have been deprecated and you should now use Spot VMs.
spot: boolean value indicating if the new instance should be a Spot VM or not.
instance_termination_action: What action should be taken once a Spot VM is terminated.
Possible values: "STOP", "DELETE"
custom_hostname: Custom hostname of the new VM instance.
Custom hostnames must conform to RFC 1035 requirements for valid hostnames.
delete_protection: boolean value indicating if the new virtual machine should be
Expand Down Expand Up @@ -97,8 +103,10 @@ def create_instance(
access.nat_i_p = external_ipv4
network_interface.access_configs = [access]


# Collect information into the Instance object.
instance = compute_v1.Instance()
instance.network_interfaces = [network_interface]
instance.name = instance_name
instance.disks = disks
if re.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$", machine_type):
Expand All @@ -109,13 +117,18 @@ def create_instance(
if accelerators:
instance.guest_accelerators = accelerators

instance.network_interfaces = [network_interface]

if preemptible:
# Set the preemptible setting
warnings.warn("Preemptible VMs are being replaced by Spot VMs.", DeprecationWarning)
instance.scheduling = compute_v1.Scheduling()
instance.scheduling.preemptible = True

if spot:
# Set the Spot VM setting
instance.scheduling = compute_v1.Scheduling()
instance.scheduling.provisioning_model = compute_v1.Scheduling.ProvisioningModel.SPOT.name
instance.scheduling.instance_termination_action = instance_termination_action

if custom_hostname is not None:
# Set the custom hostname for the instance
instance.hostname = custom_hostname
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def create_instance_from_template_with_overrides(
instance = compute_v1.Instance()
instance.name = instance_name
instance.machine_type = machine_type
instance.disks = instance_template.properties.disks
instance.disks = list(instance_template.properties.disks)

new_disk = compute_v1.AttachedDisk()
new_disk.initialize_params.disk_size_gb = 50
Expand Down
17 changes: 0 additions & 17 deletions samples/ingredients/instances/preemptible/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.

# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
# folder for complete code samples that are ready to be used.
# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
# flake8: noqa
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
# folder for complete code samples that are ready to be used.
# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
Expand Down
43 changes: 43 additions & 0 deletions samples/ingredients/instances/spot/create.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
# folder for complete code samples that are ready to be used.
# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
# flake8: noqa

from google.cloud import compute_v1


# <INGREDIENT create_spot_instance>
def create_spot_instance(project_id: str, zone: str, instance_name: str) -> compute_v1.Instance:
"""
Create a new Spot VM instance with Debian 10 operating system.
Args:
project_id: project ID or project number of the Cloud project you want to use.
zone: name of the zone to create the instance in. For example: "us-west3-b"
instance_name: name of the new virtual machine (VM) instance.
Returns:
Instance object.
"""
newest_debian = get_image_from_family(
project="debian-cloud", family="debian-11"
)
disk_type = f"zones/{zone}/diskTypes/pd-standard"
disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]
instance = create_instance(project_id, zone, instance_name, disks, spot=True)
return instance
# </INGREDIENT>
39 changes: 39 additions & 0 deletions samples/ingredients/instances/spot/get.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
# folder for complete code samples that are ready to be used.
# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
# flake8: noqa
from google.cloud import compute_v1


# <INGREDIENT is_spot_vm>
def is_spot_vm(project_id: str, zone: str, instance_name: str) -> bool:
"""
Check if a given instance is Spot VM or not.
Args:
project_id: project ID or project number of the Cloud project you want to use.
zone: name of the zone you want to use. For example: "us-west3-b"
instance_name: name of the virtual machine to check.
Returns:
The Spot VM status of the instance.
"""
instance_client = compute_v1.InstancesClient()
instance = instance_client.get(
project=project_id, zone=zone, instance=instance_name
)
return instance.scheduling.provisioning_model == compute_v1.Scheduling.ProvisioningModel.SPOT.name
# </INGREDIENT>

Empty file.
31 changes: 31 additions & 0 deletions samples/recipes/instances/spot/create.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# flake8: noqa

# <REGION compute_spot_create>
# <IMPORTS/>

# <INGREDIENT get_image_from_family />


# <INGREDIENT disk_from_image />

# <INGREDIENT wait_for_extended_operation />


# <INGREDIENT create_instance />


# <INGREDIENT create_spot_instance />
# </REGION compute_spot_create>
21 changes: 21 additions & 0 deletions samples/recipes/instances/spot/is_spot_vm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# flake8: noqa

# <REGION compute_spot_check>
# <IMPORTS/>

# <INGREDIENT is_spot_vm />

# </REGION compute_spot_check>
22 changes: 19 additions & 3 deletions samples/snippets/instances/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import re
import sys
from typing import Any, List
import warnings

from google.api_core.extended_operation import ExtendedOperation
from google.cloud import compute_v1
Expand Down Expand Up @@ -143,6 +144,8 @@ def create_instance(
external_ipv4: str = None,
accelerators: List[compute_v1.AcceleratorConfig] = None,
preemptible: bool = False,
spot: bool = False,
instance_termination_action: str = "STOP",
custom_hostname: str = None,
delete_protection: bool = False,
) -> compute_v1.Instance:
Expand Down Expand Up @@ -175,7 +178,10 @@ def create_instance(
accelerators: a list of AcceleratorConfig objects describing the accelerators that will
be attached to the new instance.
preemptible: boolean value indicating if the new instance should be preemptible
or not.
or not. Preemptible VMs have been deprecated and you should now use Spot VMs.
spot: boolean value indicating if the new instance should be a Spot VM or not.
instance_termination_action: What action should be taken once a Spot VM is terminated.
Possible values: "STOP", "DELETE"
custom_hostname: Custom hostname of the new VM instance.
Custom hostnames must conform to RFC 1035 requirements for valid hostnames.
delete_protection: boolean value indicating if the new virtual machine should be
Expand Down Expand Up @@ -205,6 +211,7 @@ def create_instance(

# Collect information into the Instance object.
instance = compute_v1.Instance()
instance.network_interfaces = [network_interface]
instance.name = instance_name
instance.disks = disks
if re.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$", machine_type):
Expand All @@ -215,13 +222,22 @@ def create_instance(
if accelerators:
instance.guest_accelerators = accelerators

instance.network_interfaces = [network_interface]

if preemptible:
# Set the preemptible setting
warnings.warn(
"Preemptible VMs are being replaced by Spot VMs.", DeprecationWarning
)
instance.scheduling = compute_v1.Scheduling()
instance.scheduling.preemptible = True

if spot:
# Set the Spot VM setting
instance.scheduling = compute_v1.Scheduling()
instance.scheduling.provisioning_model = (
compute_v1.Scheduling.ProvisioningModel.SPOT.name
)
instance.scheduling.instance_termination_action = instance_termination_action

if custom_hostname is not None:
# Set the custom hostname for the instance
instance.hostname = custom_hostname
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import re
import sys
from typing import Any, List
import warnings

from google.api_core.extended_operation import ExtendedOperation
from google.cloud import compute_v1
Expand Down Expand Up @@ -143,6 +144,8 @@ def create_instance(
external_ipv4: str = None,
accelerators: List[compute_v1.AcceleratorConfig] = None,
preemptible: bool = False,
spot: bool = False,
instance_termination_action: str = "STOP",
custom_hostname: str = None,
delete_protection: bool = False,
) -> compute_v1.Instance:
Expand Down Expand Up @@ -175,7 +178,10 @@ def create_instance(
accelerators: a list of AcceleratorConfig objects describing the accelerators that will
be attached to the new instance.
preemptible: boolean value indicating if the new instance should be preemptible
or not.
or not. Preemptible VMs have been deprecated and you should now use Spot VMs.
spot: boolean value indicating if the new instance should be a Spot VM or not.
instance_termination_action: What action should be taken once a Spot VM is terminated.
Possible values: "STOP", "DELETE"
custom_hostname: Custom hostname of the new VM instance.
Custom hostnames must conform to RFC 1035 requirements for valid hostnames.
delete_protection: boolean value indicating if the new virtual machine should be
Expand Down Expand Up @@ -205,6 +211,7 @@ def create_instance(

# Collect information into the Instance object.
instance = compute_v1.Instance()
instance.network_interfaces = [network_interface]
instance.name = instance_name
instance.disks = disks
if re.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$", machine_type):
Expand All @@ -215,13 +222,22 @@ def create_instance(
if accelerators:
instance.guest_accelerators = accelerators

instance.network_interfaces = [network_interface]

if preemptible:
# Set the preemptible setting
warnings.warn(
"Preemptible VMs are being replaced by Spot VMs.", DeprecationWarning
)
instance.scheduling = compute_v1.Scheduling()
instance.scheduling.preemptible = True

if spot:
# Set the Spot VM setting
instance.scheduling = compute_v1.Scheduling()
instance.scheduling.provisioning_model = (
compute_v1.Scheduling.ProvisioningModel.SPOT.name
)
instance.scheduling.instance_termination_action = instance_termination_action

if custom_hostname is not None:
# Set the custom hostname for the instance
instance.hostname = custom_hostname
Expand Down
Loading

0 comments on commit 5b82f47

Please sign in to comment.