~canonical-hw-cert/charms/xenial/snappy-device-agent/trunk

« back to all changes in this revision

Viewing changes to hooks/charmhelpers/contrib/mellanox/infiniband.py

  • Committer: Paul Larson
  • Date: 2016-05-16 20:27:32 UTC
  • Revision ID: paul.larson@canonical.com-20160516202732-9r4nkyl2f91w9xo3
Add support for xenial

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
# -*- coding: utf-8 -*-
 
3
 
 
4
# Copyright 2014-2015 Canonical Limited.
 
5
#
 
6
# This file is part of charm-helpers.
 
7
#
 
8
# charm-helpers is free software: you can redistribute it and/or modify
 
9
# it under the terms of the GNU Lesser General Public License version 3 as
 
10
# published by the Free Software Foundation.
 
11
#
 
12
# charm-helpers is distributed in the hope that it will be useful,
 
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
# GNU Lesser General Public License for more details.
 
16
#
 
17
# You should have received a copy of the GNU Lesser General Public License
 
18
# along with charm-helpers.  If not, see <http://www.gnu.org/licenses/>.
 
19
 
 
20
 
 
21
__author__ = "Jorge Niedbalski <jorge.niedbalski@canonical.com>"
 
22
 
 
23
from charmhelpers.fetch import (
 
24
    apt_install,
 
25
    apt_update,
 
26
)
 
27
 
 
28
from charmhelpers.core.hookenv import (
 
29
    log,
 
30
    INFO,
 
31
)
 
32
 
 
33
try:
 
34
    from netifaces import interfaces as network_interfaces
 
35
except ImportError:
 
36
    apt_install('python-netifaces')
 
37
    from netifaces import interfaces as network_interfaces
 
38
 
 
39
import os
 
40
import re
 
41
import subprocess
 
42
 
 
43
from charmhelpers.core.kernel import modprobe
 
44
 
 
45
REQUIRED_MODULES = (
 
46
    "mlx4_ib",
 
47
    "mlx4_en",
 
48
    "mlx4_core",
 
49
    "ib_ipath",
 
50
    "ib_mthca",
 
51
    "ib_srpt",
 
52
    "ib_srp",
 
53
    "ib_ucm",
 
54
    "ib_isert",
 
55
    "ib_iser",
 
56
    "ib_ipoib",
 
57
    "ib_cm",
 
58
    "ib_uverbs"
 
59
    "ib_umad",
 
60
    "ib_sa",
 
61
    "ib_mad",
 
62
    "ib_core",
 
63
    "ib_addr",
 
64
    "rdma_ucm",
 
65
)
 
66
 
 
67
REQUIRED_PACKAGES = (
 
68
    "ibutils",
 
69
    "infiniband-diags",
 
70
    "ibverbs-utils",
 
71
)
 
72
 
 
73
IPOIB_DRIVERS = (
 
74
    "ib_ipoib",
 
75
)
 
76
 
 
77
ABI_VERSION_FILE = "/sys/class/infiniband_mad/abi_version"
 
78
 
 
79
 
 
80
class DeviceInfo(object):
 
81
    pass
 
82
 
 
83
 
 
84
def install_packages():
 
85
    apt_update()
 
86
    apt_install(REQUIRED_PACKAGES, fatal=True)
 
87
 
 
88
 
 
89
def load_modules():
 
90
    for module in REQUIRED_MODULES:
 
91
        modprobe(module, persist=True)
 
92
 
 
93
 
 
94
def is_enabled():
 
95
    """Check if infiniband is loaded on the system"""
 
96
    return os.path.exists(ABI_VERSION_FILE)
 
97
 
 
98
 
 
99
def stat():
 
100
    """Return full output of ibstat"""
 
101
    return subprocess.check_output(["ibstat"])
 
102
 
 
103
 
 
104
def devices():
 
105
    """Returns a list of IB enabled devices"""
 
106
    return subprocess.check_output(['ibstat', '-l']).splitlines()
 
107
 
 
108
 
 
109
def device_info(device):
 
110
    """Returns a DeviceInfo object with the current device settings"""
 
111
 
 
112
    status = subprocess.check_output([
 
113
        'ibstat', device, '-s']).splitlines()
 
114
 
 
115
    regexes = {
 
116
        "CA type: (.*)": "device_type",
 
117
        "Number of ports: (.*)": "num_ports",
 
118
        "Firmware version: (.*)": "fw_ver",
 
119
        "Hardware version: (.*)": "hw_ver",
 
120
        "Node GUID: (.*)": "node_guid",
 
121
        "System image GUID: (.*)": "sys_guid",
 
122
    }
 
123
 
 
124
    device = DeviceInfo()
 
125
 
 
126
    for line in status:
 
127
        for expression, key in regexes.items():
 
128
            matches = re.search(expression, line)
 
129
            if matches:
 
130
                setattr(device, key, matches.group(1))
 
131
 
 
132
    return device
 
133
 
 
134
 
 
135
def ipoib_interfaces():
 
136
    """Return a list of IPOIB capable ethernet interfaces"""
 
137
    interfaces = []
 
138
 
 
139
    for interface in network_interfaces():
 
140
        try:
 
141
            driver = re.search('^driver: (.+)$', subprocess.check_output([
 
142
                'ethtool', '-i',
 
143
                interface]), re.M).group(1)
 
144
 
 
145
            if driver in IPOIB_DRIVERS:
 
146
                interfaces.append(interface)
 
147
        except:
 
148
            log("Skipping interface %s" % interface, level=INFO)
 
149
            continue
 
150
 
 
151
    return interfaces