197 lines
7.0 KiB
Python
197 lines
7.0 KiB
Python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
|
|
# Copyright (C) 2012 Yahoo! Inc. All Rights Reserved.
|
|
#
|
|
# 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.
|
|
|
|
import psutil
|
|
import re
|
|
import weakref
|
|
|
|
from anvil import shell as sh
|
|
from anvil import utils
|
|
|
|
from anvil.components.configurators import nova as nconf
|
|
from anvil.components.helpers import virt as lv
|
|
|
|
|
|
def get_shared_params(ip, protocol,
|
|
api_host, api_port,
|
|
s3_host, s3_port,
|
|
ec2_host, ec2_port,
|
|
ec2_admin_host, ec2_admin_port, **kwargs):
|
|
mp = {}
|
|
mp['service_host'] = ip
|
|
|
|
# Uri's of the various nova endpoints
|
|
mp['endpoints'] = {
|
|
'ec2_admin': {
|
|
'uri': utils.make_url(protocol, ec2_admin_host, ec2_admin_port, "services/Admin"),
|
|
'port': ec2_admin_port,
|
|
'host': ec2_admin_host,
|
|
'protocol': protocol,
|
|
},
|
|
'ec2_cloud': {
|
|
'uri': utils.make_url(protocol, ec2_host, ec2_port, "services/Cloud"),
|
|
'port': ec2_port,
|
|
'host': ec2_host,
|
|
'protocol': protocol,
|
|
},
|
|
's3': {
|
|
'uri': utils.make_url(protocol, s3_host, s3_port),
|
|
'port': s3_port,
|
|
'host': s3_host,
|
|
'protocol': protocol,
|
|
},
|
|
'api': {
|
|
'uri': utils.make_url(protocol, api_host, api_port, "v2"),
|
|
'port': api_port,
|
|
'host': api_host,
|
|
'protocol': protocol,
|
|
},
|
|
}
|
|
|
|
return mp
|
|
|
|
|
|
class ComputeCleaner(object):
|
|
def __init__(self, uninstaller):
|
|
self.uninstaller = weakref.proxy(uninstaller)
|
|
|
|
def clean(self):
|
|
virsh = lv.Virsh(self.uninstaller.get_int_option('service_wait_seconds'), self.uninstaller.distro)
|
|
virt_driver = utils.canon_virt_driver(self.uninstaller.get_option('virt_driver'))
|
|
if virt_driver == 'libvirt':
|
|
inst_prefix = self.uninstaller.get_option('instance_name_prefix', default_value='instance-')
|
|
libvirt_type = lv.canon_libvirt_type(self.uninstaller.get_option('libvirt_type'))
|
|
virsh.clear_domains(libvirt_type, inst_prefix)
|
|
|
|
|
|
class NetworkCleaner(object):
|
|
def __init__(self, uninstaller):
|
|
self.uninstaller = weakref.proxy(uninstaller)
|
|
|
|
def _stop_dnsmasq(self):
|
|
# Shutdown dnsmasq which is typically used by nova-network
|
|
# to provide dhcp leases and since nova currently doesn't
|
|
# seem to shut them down itself (why not?) we have to do it for it..
|
|
#
|
|
# TODO(harlowja) file a bug to get that fixed...
|
|
to_kill = []
|
|
for proc in psutil.process_iter():
|
|
if proc.name.find("dnsmasq") == -1:
|
|
continue
|
|
cwd = ''
|
|
cmdline = ''
|
|
cwd = proc.getcwd()
|
|
cmdline = " ".join(proc.cmdline)
|
|
to_try = False
|
|
for t in [cwd, cmdline]:
|
|
if t.lower().find("nova") != -1:
|
|
to_try = True
|
|
if to_try:
|
|
to_kill.append(proc.pid)
|
|
if len(to_kill):
|
|
utils.log_iterable(to_kill,
|
|
header="Killing leftover nova dnsmasq processes with process ids",
|
|
logger=nconf.LOG)
|
|
for pid in to_kill:
|
|
sh.kill(pid)
|
|
|
|
def _clean_iptables(self):
|
|
# Nova doesn't seem to cleanup its iptables rules that it
|
|
# establishes when it is removed, this is unfortunate as that
|
|
# means that when nova is uninstalled it may have just left the
|
|
# host machine in a un-useable state...
|
|
#
|
|
# TODO(harlowja) file a bug to get that fixed...
|
|
|
|
def line_matcher(line, start_text):
|
|
if not line:
|
|
return False
|
|
if not line.startswith(start_text):
|
|
return False
|
|
if line.lower().find("nova") == -1:
|
|
return False
|
|
return True
|
|
|
|
def translate_rule(line, start_search, start_replace):
|
|
line = re.sub(r"-c\s+[0-9]*\s+[0-9]*", "", line, re.I)
|
|
if not line.startswith(start_search):
|
|
return line
|
|
return line.replace(start_search, start_replace, 1)
|
|
|
|
# Isolate the nova rules
|
|
clean_rules = []
|
|
list_cmd = ['iptables', '--list-rules', '--verbose']
|
|
(stdout, _stderr) = sh.execute(list_cmd)
|
|
for line in stdout.splitlines():
|
|
line = line.strip()
|
|
if not line_matcher(line, "-A"):
|
|
continue
|
|
# Translate it into a delete rule operation
|
|
rule = translate_rule(line, "-A", "-D")
|
|
if rule:
|
|
clean_rules.append(rule)
|
|
|
|
# Isolate the nova nat rules
|
|
clean_nats = []
|
|
nat_cmd = ['iptables', '--list-rules', '--verbose', '--table', 'nat']
|
|
(stdout, _stderr) = sh.execute(nat_cmd)
|
|
for line in stdout.splitlines():
|
|
line = line.strip()
|
|
if not line_matcher(line, "-A"):
|
|
continue
|
|
# Translate it into a delete rule operation
|
|
rule = translate_rule(line, "-A", "-D")
|
|
if rule:
|
|
clean_nats.append(rule)
|
|
|
|
# Isolate the nova chains
|
|
clean_chains = []
|
|
chain_cmd = ['iptables', '--list-rules', '--verbose']
|
|
(stdout, _stderr) = sh.execute(chain_cmd)
|
|
for line in stdout.splitlines():
|
|
if not line_matcher(line, "-N"):
|
|
continue
|
|
# Translate it into a delete rule operation
|
|
rule = translate_rule(line, "-N", "-X")
|
|
if rule:
|
|
clean_chains.append(rule)
|
|
|
|
# Isolate the nova nat chains
|
|
clean_nat_chains = []
|
|
nat_chain_cmd = ['iptables', '--list-rules', '--verbose', '--table', 'nat']
|
|
(stdout, _stderr) = sh.execute(nat_chain_cmd)
|
|
for line in stdout.splitlines():
|
|
if not line_matcher(line, "-N"):
|
|
continue
|
|
# Translate it into a delete rule operation
|
|
rule = translate_rule(line, "-N", "-X")
|
|
if rule:
|
|
clean_nat_chains.append(rule)
|
|
|
|
# Now execute them...
|
|
for r in clean_rules + clean_chains:
|
|
pieces = r.split(None)
|
|
pieces = ['iptables'] + pieces
|
|
sh.execute(pieces, shell=True)
|
|
for r in clean_nats + clean_nat_chains:
|
|
pieces = r.split(None)
|
|
pieces = ['iptables', '--table', 'nat'] + pieces
|
|
sh.execute(pieces, shell=True)
|
|
|
|
def clean(self):
|
|
self._stop_dnsmasq()
|
|
self._clean_iptables()
|