Last active
December 24, 2015 16:49
Nova Nuke: Forcefully removes an instance from the Nova database. Useful for cleaning up instances stuck in an 'error' or 'deleting' state.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# | |
# nova_nuke.py | |
# usage: nova_nuke.py <uuid> | |
# | |
# Forcefully removes an instance from the Nova database. | |
# Useful for destroying instances stuck in an 'error' or 'deleting' state. | |
# | |
# Completes the following actions: | |
# * Marks the instance as deleted in nova.instances | |
# * Disassociates any fixed IPs assigned to the instance (nova-network) | |
# * Updates tenant quotas associated with the instance | |
# | |
# Because this script relies on Nova calls which are not exposed by the | |
# public API in order to access the database, this script must be run from | |
# a Controller or Compute node. | |
# | |
# Use with caution. | |
# | |
import sys | |
from nova.db.sqlalchemy import api | |
from oslo.config import cfg | |
class FakeAdminContext(object): | |
def __init__(self): | |
self.is_admin = True | |
self.read_deleted = 'no' | |
def usage(): | |
print "usage: %s <uuid>" % sys.argv[0] | |
def delete_instance(context, uuid): | |
return api.instance_destroy(context, uuid) | |
def disassociate_ips(context, instance): | |
ips = api.fixed_ip_get_by_instance(context, instance.uuid) | |
for ip in ips: | |
api.fixed_ip_disassociate(context, ip.address) | |
return ips | |
def update_quotas(context, instance, ips): | |
project_id = instance.project_id | |
instance_ips = len(ips) | |
ram = api.quota_usage_get(context, project_id, 'ram') | |
ram.update({'in_use': ram.in_use - instance.memory_mb}) | |
ram.save() | |
cores = api.quota_usage_get(context, project_id, 'cores') | |
cores.update({'in_use': cores.in_use - instance.vcpus}) | |
cores.save() | |
fixed_ips = api.quota_usage_get(context, project_id, 'fixed_ips') | |
fixed_ips.update({'in_use': fixed_ips.in_use - instance_ips}) | |
fixed_ips.save() | |
instances = api.quota_usage_get(context, project_id, 'instances') | |
instances.update({'in_use': instances.in_use - 1}) | |
instances.save() | |
def main(): | |
if len(sys.argv) != 2: | |
usage() | |
sys.exit(1) | |
uuid = sys.argv.pop() | |
# Trick the OpenStack APIs into thinking nova is issuing these requests | |
cfg.CONF(project='nova') | |
context = FakeAdminContext() | |
instance = delete_instance(context, uuid) | |
ips = disassociate_ips(context, instance) | |
update_quotas(context, instance, ips) | |
print "Successfully deleted instance %s (%s)" % (instance.hostname, uuid) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment