def _load_instance(self, instance_id, force_reload=True): """ Return instance with the given id. For performance reasons, the instance ID is first searched for in the collection of VM instances started by ElastiCluster (`self._instances`), then in the list of all instances known to the cloud provider at the time of the last update (`self._cached_instances`), and finally the cloud provider is directly queried. :param str instance_id: instance identifier :param bool force_reload: if ``True``, skip searching caches and reload instance from server and immediately reload instance data from cloud provider :return: py:class:`novaclient.v1_1.servers.Server` - instance :raises: `InstanceError` is returned if the instance can't be found in the local cache or in the cloud. """ self._init_os_api() if force_reload: try: # Remove from cache and get from server again vm = self.nova_client.servers.get(instance_id) except NotFound: raise InstanceNotFoundError( "Instance `{instance_id}` not found".format( instance_id=instance_id)) # update caches self._instances[instance_id] = vm self._cached_instances[instance_id] = vm # if instance is known, return it if instance_id in self._instances: return self._instances[instance_id] # else, check (cached) list from provider if instance_id not in self._cached_instances: # Refresh the cache, just in case self._cached_instances = dict( (vm.id, vm) for vm in self.nova_client.servers.list()) if instance_id in self._cached_instances: inst = self._cached_instances[instance_id] self._instances[instance_id] = inst return inst # If we reached this point, the instance was not found neither # in the caches nor on the website. raise InstanceNotFoundError( "Instance `{instance_id}` not found".format( instance_id=instance_id))
def _load_instance(self, instance_id): """ Return instance with the given id. For performance reasons, the instance ID is first searched for in the collection of VM instances started by ElastiCluster (`self._instances`), then in the list of all instances known to the cloud provider at the time of the last update (`self._cached_instances`), and finally the cloud provider is directly queried. :param str instance_id: instance identifier :return: py:class:`boto.ec2.instance.Reservation` - instance :raises: `InstanceError` is returned if the instance can't be found in the local cache or in the cloud. """ # if instance is known, return it if instance_id in self._instances: return self._instances[instance_id] # else, check (cached) list from provider if instance_id not in self._cached_instances: self._cached_instances = self._build_cached_instances() if instance_id in self._cached_instances: inst = self._cached_instances[instance_id] self._instances[instance_id] = inst return inst # If we reached this point, the instance was not found neither # in the caches nor on the website. raise InstanceNotFoundError( "Instance `{instance_id}` not found".format( instance_id=instance_id))
def stop_instance(self, instance_id): """Stops the instance gracefully. :param str instance_id: instance identifier :raises: `InstanceError` if instance can not be stopped """ if not instance_id: log.info("Instance to stop has no instance id") return gce = self._connect() try: request = gce.instances().delete(project=self._project_id, instance=instance_id, zone=self._zone) response = self._execute_request(request) self._check_response(response) except HttpError as e: # If the instance does not exist, we get a 404 if e.resp.status == 404: raise InstanceNotFoundError( "Instance `{instance_id}` was not found".format( instance_id=instance_id)) else: raise InstanceError( "Could not stop instance `{instance_id}`: `{e}`".format( instance_id=instance_id, e=e)) except CloudProviderError as e: raise InstanceError( "Could not stop instance `{instance_id}`: `{e}`".format( instance_id=instance_id, e=e))
def _get_vm(self, instance_id, force_reload=True): """ Return details on the VM with the given name. :param str node_name: instance identifier :param bool force_reload: if ``True``, skip searching caches and reload instance from server and immediately reload instance data from cloud provider :return: py:class:`novaclient.v1_1.servers.Server` - instance :raises: `InstanceError` is returned if the instance can't be found in the local cache or in the cloud. """ self._init_az_api() if force_reload: # Remove from cache and get from server again self._inventory = {} cluster_name, node_name = instance_id self._init_inventory(cluster_name) # if instance is known, return it if node_name not in self._vm_details: vm_info = self._compute_client.virtual_machines.get( cluster_name, node_name, 'instanceView') self._vm_details[node_name] = vm_info try: return self._vm_details[node_name] except KeyError: raise InstanceNotFoundError( "Instance `{instance_id}` not found" .format(instance_id=instance_id))