3
3
# This file contains functions used by the hooks to deploy PLUMgrid Edge.
10
from collections import OrderedDict
11
from socket import gethostname as get_unit_hostname
12
from copy import deepcopy
5
13
from charmhelpers.contrib.openstack.neutron import neutron_plugin_attribute
6
from copy import deepcopy
14
from charmhelpers.contrib.storage.linux.ceph import modprobe
15
from charmhelpers.core.host import set_nic_mtu
16
from charmhelpers.contrib.openstack import templating
7
17
from charmhelpers.core.hookenv import (
22
from charmhelpers.contrib.network.ip import (
26
is_address_in_network,
11
29
from charmhelpers.core.host import (
17
from charmhelpers.contrib.storage.linux.ceph import modprobe
18
from charmhelpers.core.host import set_nic_mtu
19
from charmhelpers.fetch import apt_install
20
from charmhelpers.contrib.openstack import templating
21
from collections import OrderedDict
36
from charmhelpers.fetch import (
22
40
from charmhelpers.contrib.openstack.utils import (
25
import pg_edge_context
30
44
SHARED_SECRET = "/etc/nova/secret.txt"
31
45
LXC_CONF = '/etc/libvirt/lxc.conf'
32
46
TEMPLATES = 'templates/'
33
47
PG_LXC_DATA_PATH = '/var/lib/libvirt/filesystems/plumgrid-data'
35
48
PG_CONF = '%s/conf/pg/plumgrid.conf' % PG_LXC_DATA_PATH
36
49
PG_HN_CONF = '%s/conf/etc/hostname' % PG_LXC_DATA_PATH
37
50
PG_HS_CONF = '%s/conf/etc/hosts' % PG_LXC_DATA_PATH
38
51
PG_IFCS_CONF = '%s/conf/pg/ifcs.conf' % PG_LXC_DATA_PATH
39
52
AUTH_KEY_PATH = '%s/root/.ssh/authorized_keys' % PG_LXC_DATA_PATH
41
53
SUDOERS_CONF = '/etc/sudoers.d/ifc_ctl_sudoers'
42
54
FILTERS_CONF_DIR = '/etc/nova/rootwrap.d'
43
55
FILTERS_CONF = '%s/network.filters' % FILTERS_CONF_DIR
71
83
Returns list of packages required by PLUMgrid Edge as specified
72
84
in the neutron_plugins dictionary in charmhelpers.
74
return neutron_plugin_attribute('plumgrid', 'packages', 'neutron')
88
for pkg in neutron_plugin_attribute('plumgrid', 'packages', 'neutron'):
90
tag = config('plumgrid-build')
91
elif pkg == 'iovisor-dkms':
92
tag = config('iovisor-build')
97
if tag in [i.ver_str for i in apt_cache()[pkg].version_list]:
98
pkgs.append('%s=%s' % (pkg, tag))
101
"Build version '%s' for package '%s' not available" \
103
raise ValueError(error_msg)
77
107
def register_configs(release=None):
147
190
Removes iovisor kernel module.
149
_exec_cmd(cmd=['rmmod', 'iovisor'], error_msg='Error Loading Iovisor Kernel Module')
192
_exec_cmd(cmd=['rmmod', 'iovisor'],
193
error_msg='Error Removing IOVisor Kernel Module')
197
def interface_exists(interface):
199
Checks if interface exists on node.
202
subprocess.check_call(['ip', 'link', 'show', interface],
203
stdout=open(os.devnull, 'w'),
204
stderr=subprocess.STDOUT)
205
except subprocess.CalledProcessError:
210
def get_mgmt_interface():
212
Returns the managment interface.
214
mgmt_interface = config('mgmt-interface')
215
if interface_exists(mgmt_interface):
216
return mgmt_interface
218
log('Provided managment interface %s does not exist'
220
return get_iface_from_addr(unit_get('private-address'))
223
def fabric_interface_changed():
225
Returns true if interface for node changed.
227
fabric_interface = get_fabric_interface()
229
with open(PG_IFCS_CONF, 'r') as ifcs:
231
if 'fabric_core' in line:
232
if line.split()[0] == fabric_interface:
239
def get_fabric_interface():
241
Returns the fabric interface.
243
fabric_interfaces = config('fabric-interfaces')
244
if fabric_interfaces == 'MANAGEMENT':
245
return get_mgmt_interface()
248
all_fabric_interfaces = json.loads(fabric_interfaces)
250
raise ValueError('Invalid json provided for fabric interfaces')
251
hostname = get_unit_hostname()
252
if hostname in all_fabric_interfaces:
253
node_fabric_interface = all_fabric_interfaces[hostname]
254
elif 'DEFAULT' in all_fabric_interfaces:
255
node_fabric_interface = all_fabric_interfaces['DEFAULT']
257
raise ValueError('No fabric interface provided for node')
258
if interface_exists(node_fabric_interface):
259
if is_address_in_network(config('os-data-network'),
260
get_iface_addr(node_fabric_interface)[0]):
261
return node_fabric_interface
263
raise ValueError('Fabric interface not in fabric network')
265
log('Provided fabric interface %s does not exist'
266
% node_fabric_interface)
267
raise ValueError('Provided fabric interface does not exist')
268
return node_fabric_interface
152
271
def ensure_mtu():
154
273
Ensures required MTU of the underlying networking of the node.
156
log("Changing MTU of juju-br0 and all attached interfaces")
157
275
interface_mtu = config('network-device-mtu')
158
cmd = subprocess.check_output(["brctl", "show", "juju-br0"])
162
set_nic_mtu(word, interface_mtu)
163
set_nic_mtu('juju-br0', interface_mtu)
166
def _exec_cmd(cmd=None, error_msg='Command exited with ERRORs', fatal=False):
276
fabric_interface = get_fabric_interface()
277
if fabric_interface in get_bridges():
278
attached_interfaces = get_bridge_nics(fabric_interface)
279
for interface in attached_interfaces:
280
set_nic_mtu(interface, interface_mtu)
281
set_nic_mtu(fabric_interface, interface_mtu)
284
def _exec_cmd(cmd=None, error_msg='Command exited with ERRORs', fatal=False,
168
287
Function to execute any bash command on the node.
171
290
log("No command specified")
292
if fatal and verbose:
293
subprocess.check_call(cmd, stdout=open(os.devnull, 'w'),
294
stderr=subprocess.STDOUT)
295
elif fatal and not verbose:
174
296
subprocess.check_call(cmd)
177
subprocess.check_call(cmd)
300
subprocess.check_call(cmd, stdout=open(os.devnull, 'w'),
301
stderr=subprocess.STDOUT)
303
subprocess.check_call(cmd)
178
304
except subprocess.CalledProcessError:
372
Loads iptables rules to allow all PLUMgrid communication.
374
network = get_cidr_from_iface(get_mgmt_interface())
376
_exec_cmd(['sudo', 'iptables', '-A', 'INPUT', '-p', 'tcp',
377
'-j', 'ACCEPT', '-s', network, '-d',
378
network, '-m', 'state', '--state', 'NEW'])
379
_exec_cmd(['sudo', 'iptables', '-A', 'INPUT', '-p', 'udp', '-j',
380
'ACCEPT', '-s', network, '-d', network,
381
'-m', 'state', '--state', 'NEW'])
382
apt_install('iptables-persistent')
385
def get_cidr_from_iface(interface):
387
Determines Network CIDR from interface.
393
os_info = subprocess.check_output(['ohai', '-l', 'fatal'])
395
log('Unable to get operating system information')
398
os_info_json = json.loads(os_info)
400
log('Unable to determine network')
402
device = os_info_json['network']['interfaces'].get(interface)
403
if device is not None:
404
if device.get('routes'):
405
routes = device['routes']
408
return net.get('destination')