faq.rst 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. FAQ
  2. ===
  3. 1. Using cloudbridge across zones
  4. Currently, each instance of a cloudbridge provider is designated to work within a
  5. particular zone, for reasons clarified here: :ref:`single-zone-provider`.
  6. To perform cross-zonal operations, we recommend cloning the provider into a different
  7. zone as in this example:
  8. .. code-block:: python
  9. all_instances = []
  10. for zone in provider.compute.regions.current.zones:
  11. new_provider = provider.clone(zone=zone)
  12. all_instances.append(list(new_provider.compute.instances))
  13. print(all_instances)
  14. 2. Cleaning up resources/left over resources
  15. The trickiest part about using cloud resources is the orderly cleanup of resources
  16. when they are no longer needed. Cleanup is often complicated, as cloud-providers
  17. may have delays in responding at certain times, and transient errors at other times.
  18. While cloudbridge does not designate a particular strategy to combat this,
  19. the `controller pattern`_ is a recommended mechanism for handling such scenarios:
  20. Cloudbridge provides some utilities that can aid in simpler scenarios, such as
  21. `wait_for`, the cleanup helper and retries.
  22. The following example demonstrates a scenario where an instance and its attached
  23. volume must be deleted.
  24. .. code-block:: python
  25. from cloudbridge.base import helpers as cb_helpers
  26. import tenacity
  27. def does_instance_or_volume_still_exist(inst, vol):
  28. return provider.compute.instances.get(inst.id) or
  29. provider.storage.volumes.get(vol.id)
  30. def detach_and_delete(inst, vol)
  31. with cb_helpers.cleanup_action(lambda: inst.delete()):
  32. vol.detach()
  33. vol.wait_for(
  34. [VolumeState.AVAILABLE],
  35. terminal_states=[VolumeState.ERROR, VolumeState.DELETED])
  36. vol.delete()
  37. self.wait_for([VolumeState.UNKNOWN, VolumeState.ERROR])
  38. def delete_my_instance_and_attached_volume(provider, instance, vol):
  39. retryer = tenacity.Retrying(
  40. stop=tenacity.stop_after_delay(300),
  41. retry=tenacity.retry_if_result(does_instance_or_volume_still_exist(instance, vol),
  42. wait=tenacity.wait_fixed(5))
  43. retryer(detach_and_delete, instance, vol)
  44. # invoke with the instance and vol you want to delete
  45. delete_my_instance_and_attached_volume(my_inst, my_vol)
  46. The code above attempts to first detach and then delete the volume.
  47. If an exception occurs, such as the volume not existing, the `cleanup_action` code
  48. ensures that the `inst.delete()` code runs regardless of the success or failure
  49. of the volume deletion operation. The tenacity.retryer wraps the entire operation
  50. so that the overall process will repeat till both the volume nor the instance no
  51. longer exist.
  52. .. _controller pattern: https://kubernetes.io/docs/concepts/architecture/controller/#controller-pattern