248 lines
7.3 KiB
Python
248 lines
7.3 KiB
Python
import subprocess
|
|
import os
|
|
import uuid
|
|
import base64
|
|
import apt_pkg as apt
|
|
from lib.utils import (
|
|
juju_log as log,
|
|
configure_source,
|
|
config_get
|
|
)
|
|
|
|
|
|
OVS = "ovs"
|
|
|
|
OVS_PLUGIN = \
|
|
"quantum.plugins.openvswitch.ovs_quantum_plugin.OVSQuantumPluginV2"
|
|
CORE_PLUGIN = {
|
|
OVS: OVS_PLUGIN,
|
|
}
|
|
|
|
OVS_PLUGIN_CONF = \
|
|
"/etc/quantum/plugins/openvswitch/ovs_quantum_plugin.ini"
|
|
PLUGIN_CONF = {
|
|
OVS: OVS_PLUGIN_CONF,
|
|
}
|
|
|
|
GATEWAY_PKGS = {
|
|
OVS: [
|
|
"quantum-plugin-openvswitch-agent",
|
|
"quantum-l3-agent",
|
|
"quantum-dhcp-agent",
|
|
'python-mysqldb',
|
|
"nova-api-metadata"
|
|
],
|
|
}
|
|
|
|
GATEWAY_AGENTS = {
|
|
OVS: [
|
|
"quantum-plugin-openvswitch-agent",
|
|
"quantum-l3-agent",
|
|
"quantum-dhcp-agent",
|
|
"nova-api-metadata"
|
|
],
|
|
}
|
|
|
|
EXT_PORT_CONF = '/etc/init/ext-port.conf'
|
|
|
|
|
|
def get_os_version(package=None):
|
|
apt.init()
|
|
cache = apt.Cache()
|
|
pkg = cache[package or 'quantum-common']
|
|
if pkg.current_ver:
|
|
return apt.upstream_version(pkg.current_ver.ver_str)
|
|
else:
|
|
return None
|
|
|
|
|
|
if get_os_version('quantum-common') >= "2013.1":
|
|
for plugin in GATEWAY_AGENTS:
|
|
GATEWAY_AGENTS[plugin].append("quantum-metadata-agent")
|
|
|
|
DB_USER = "quantum"
|
|
QUANTUM_DB = "quantum"
|
|
KEYSTONE_SERVICE = "quantum"
|
|
NOVA_DB_USER = "nova"
|
|
NOVA_DB = "nova"
|
|
|
|
QUANTUM_CONF = "/etc/quantum/quantum.conf"
|
|
L3_AGENT_CONF = "/etc/quantum/l3_agent.ini"
|
|
DHCP_AGENT_CONF = "/etc/quantum/dhcp_agent.ini"
|
|
METADATA_AGENT_CONF = "/etc/quantum/metadata_agent.ini"
|
|
NOVA_CONF = "/etc/nova/nova.conf"
|
|
|
|
RESTART_MAP = {
|
|
QUANTUM_CONF: [
|
|
'quantum-l3-agent',
|
|
'quantum-dhcp-agent',
|
|
'quantum-metadata-agent',
|
|
'quantum-plugin-openvswitch-agent'
|
|
],
|
|
DHCP_AGENT_CONF: [
|
|
'quantum-dhcp-agent'
|
|
],
|
|
L3_AGENT_CONF: [
|
|
'quantum-l3-agent'
|
|
],
|
|
METADATA_AGENT_CONF: [
|
|
'quantum-metadata-agent'
|
|
],
|
|
OVS_PLUGIN_CONF: [
|
|
'quantum-plugin-openvswitch-agent'
|
|
],
|
|
NOVA_CONF: [
|
|
'nova-api-metadata'
|
|
]
|
|
}
|
|
|
|
RABBIT_USER = "nova"
|
|
RABBIT_VHOST = "nova"
|
|
|
|
INT_BRIDGE = "br-int"
|
|
EXT_BRIDGE = "br-ex"
|
|
|
|
|
|
def add_bridge(name):
|
|
status = subprocess.check_output(["ovs-vsctl", "show"])
|
|
if "Bridge {}".format(name) not in status:
|
|
log('INFO', 'Creating bridge {}'.format(name))
|
|
subprocess.check_call(["ovs-vsctl", "add-br", name])
|
|
|
|
|
|
def del_bridge(name):
|
|
status = subprocess.check_output(["ovs-vsctl", "show"])
|
|
if "Bridge {}".format(name) in status:
|
|
log('INFO', 'Deleting bridge {}'.format(name))
|
|
subprocess.check_call(["ovs-vsctl", "del-br", name])
|
|
|
|
|
|
def add_bridge_port(name, port):
|
|
status = subprocess.check_output(["ovs-vsctl", "show"])
|
|
if ("Bridge {}".format(name) in status and
|
|
"Interface \"{}\"".format(port) not in status):
|
|
log('INFO',
|
|
'Adding port {} to bridge {}'.format(port, name))
|
|
subprocess.check_call(["ovs-vsctl", "add-port", name, port])
|
|
subprocess.check_call(["ip", "link", "set", port, "up"])
|
|
|
|
|
|
def del_bridge_port(name, port):
|
|
status = subprocess.check_output(["ovs-vsctl", "show"])
|
|
if ("Bridge {}".format(name) in status and
|
|
"Interface \"{}\"".format(port) in status):
|
|
log('INFO',
|
|
'Deleting port {} from bridge {}'.format(port, name))
|
|
subprocess.check_call(["ovs-vsctl", "del-port", name, port])
|
|
subprocess.check_call(["ip", "link", "set", port, "down"])
|
|
|
|
|
|
SHARED_SECRET = "/etc/quantum/secret.txt"
|
|
|
|
|
|
def get_shared_secret():
|
|
secret = None
|
|
if not os.path.exists(SHARED_SECRET):
|
|
secret = str(uuid.uuid4())
|
|
with open(SHARED_SECRET, 'w') as secret_file:
|
|
secret_file.write(secret)
|
|
else:
|
|
with open(SHARED_SECRET, 'r') as secret_file:
|
|
secret = secret_file.read().strip()
|
|
return secret
|
|
|
|
|
|
def flush_local_configuration():
|
|
if os.path.exists('/usr/bin/quantum-netns-cleanup'):
|
|
cmd = [
|
|
"quantum-netns-cleanup",
|
|
"--config-file=/etc/quantum/quantum.conf"
|
|
]
|
|
for agent_conf in ['l3_agent.ini', 'dhcp_agent.ini']:
|
|
agent_cmd = list(cmd)
|
|
agent_cmd.append('--config-file=/etc/quantum/{}'\
|
|
.format(agent_conf))
|
|
subprocess.call(agent_cmd)
|
|
|
|
|
|
def install_ca(ca_cert):
|
|
with open('/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt',
|
|
'w') as crt:
|
|
crt.write(base64.b64decode(ca_cert))
|
|
subprocess.check_call(['update-ca-certificates', '--fresh'])
|
|
|
|
DHCP_AGENT = "DHCP Agent"
|
|
L3_AGENT = "L3 Agent"
|
|
|
|
|
|
def reassign_agent_resources(env):
|
|
''' Use agent scheduler API to detect down agents and re-schedule '''
|
|
from quantumclient.v2_0 import client
|
|
# TODO: Fixup for https keystone
|
|
auth_url = 'http://%(keystone_host)s:%(auth_port)s/v2.0' % env
|
|
quantum = client.Client(username=env['service_username'],
|
|
password=env['service_password'],
|
|
tenant_name=env['service_tenant'],
|
|
auth_url=auth_url,
|
|
region_name=env['region'])
|
|
|
|
agents = quantum.list_agents(agent_type=DHCP_AGENT)
|
|
dhcp_agents = []
|
|
l3_agents = []
|
|
networks = {}
|
|
for agent in agents['agents']:
|
|
if not agent['alive']:
|
|
log('INFO', 'DHCP Agent %s down' % agent['id'])
|
|
for network in \
|
|
quantum.list_networks_on_dhcp_agent(agent['id'])['networks']:
|
|
networks[network['id']] = agent['id']
|
|
else:
|
|
dhcp_agents.append(agent['id'])
|
|
|
|
agents = quantum.list_agents(agent_type=L3_AGENT)
|
|
routers = {}
|
|
for agent in agents['agents']:
|
|
if not agent['alive']:
|
|
log('INFO', 'L3 Agent %s down' % agent['id'])
|
|
for router in \
|
|
quantum.list_routers_on_l3_agent(agent['id'])['routers']:
|
|
routers[router['id']] = agent['id']
|
|
else:
|
|
l3_agents.append(agent['id'])
|
|
|
|
index = 0
|
|
for router_id in routers:
|
|
agent = index % len(l3_agents)
|
|
log('INFO',
|
|
'Moving router %s from %s to %s' % \
|
|
(router_id, routers[router_id], l3_agents[agent]))
|
|
quantum.remove_router_from_l3_agent(l3_agent=routers[router_id],
|
|
router_id=router_id)
|
|
quantum.add_router_to_l3_agent(l3_agent=l3_agents[agent],
|
|
body={'router_id': router_id})
|
|
index += 1
|
|
|
|
index = 0
|
|
for network_id in networks:
|
|
agent = index % len(dhcp_agents)
|
|
log('INFO',
|
|
'Moving network %s from %s to %s' % \
|
|
(network_id, networks[network_id], dhcp_agents[agent]))
|
|
quantum.remove_network_from_dhcp_agent(dhcp_agent=networks[network_id],
|
|
network_id=network_id)
|
|
quantum.add_network_to_dhcp_agent(dhcp_agent=dhcp_agents[agent],
|
|
body={'network_id': network_id})
|
|
index += 1
|
|
|
|
def do_openstack_upgrade():
|
|
configure_source()
|
|
plugin = config_get('plugin')
|
|
pkgs = []
|
|
if plugin in GATEWAY_PKGS.keys():
|
|
pkgs += GATEWAY_PKGS[plugin]
|
|
if plugin == OVS:
|
|
pkgs.append('openvswitch-datapath-dkms')
|
|
cmd = ['apt-get', '--option', 'Dpkg::Options::=--force-confnew', '-y',
|
|
'install'] + pkgs
|
|
subprocess.check_call(cmd)
|