Set lock_path correctly.
[openstack-build/neutron-build.git] / neutron / agent / linux / ip_link_support.py
1 # Copyright 2014 Mellanox Technologies, Ltd
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #    http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12 # implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15
16 import re
17
18 from oslo_log import log as logging
19
20 from neutron._i18n import _, _LE
21 from neutron.agent.linux import utils
22 from neutron.common import exceptions as n_exc
23
24
25 LOG = logging.getLogger(__name__)
26
27
28 class IpLinkSupportError(n_exc.NeutronException):
29     pass
30
31
32 class UnsupportedIpLinkCommand(IpLinkSupportError):
33     message = _("ip link command is not supported: %(reason)s")
34
35
36 class InvalidIpLinkCapability(IpLinkSupportError):
37     message = _("ip link capability %(capability)s is not supported")
38
39
40 class IpLinkConstants(object):
41     IP_LINK_CAPABILITY_STATE = "state"
42     IP_LINK_CAPABILITY_VLAN = "vlan"
43     IP_LINK_CAPABILITY_RATE = "rate"
44     IP_LINK_CAPABILITY_SPOOFCHK = "spoofchk"
45     IP_LINK_SUB_CAPABILITY_QOS = "qos"
46
47
48 class IpLinkSupport(object):
49     VF_BLOCK_REGEX = r"\[ vf NUM(?P<vf_block>.*) \] \]"
50
51     CAPABILITY_REGEX = r"\[ %s (.*)"
52     SUB_CAPABILITY_REGEX = r"\[ %(cap)s (.*) \[ %(subcap)s (.*)"
53
54     @classmethod
55     def get_vf_mgmt_section(cls):
56         """Parses ip link help output, and gets vf block"""
57
58         output = cls._get_ip_link_output()
59         vf_block_pattern = re.search(cls.VF_BLOCK_REGEX,
60                                      output,
61                                      re.DOTALL | re.MULTILINE)
62         if vf_block_pattern:
63             return vf_block_pattern.group("vf_block")
64
65     @classmethod
66     def vf_mgmt_capability_supported(cls, vf_section, capability,
67                                      subcapability=None):
68         """Validate vf capability support
69
70         Checks if given vf capability (and sub capability
71         if given) supported
72         :param vf_section: vf Num block content
73         :param capability: for example: vlan, rate, spoofchk, state
74         :param subcapability: for example: qos
75         """
76         if not vf_section:
77             return False
78         if subcapability:
79             regex = cls.SUB_CAPABILITY_REGEX % {"cap": capability,
80                                                 "subcap": subcapability}
81         else:
82             regex = cls.CAPABILITY_REGEX % capability
83         pattern_match = re.search(regex, vf_section,
84                                   re.DOTALL | re.MULTILINE)
85         return pattern_match is not None
86
87     @classmethod
88     def _get_ip_link_output(cls):
89         """Gets the output of the ip link help command
90
91         Runs ip link help command and stores its output
92         Note: ip link help return error and writes its output to stderr
93                 so we get the output from there. however, if this issue
94                 will be solved and the command will write to stdout, we
95                 will get the output from there too.
96         """
97         try:
98             ip_cmd = ['ip', 'link', 'help']
99             _stdout, _stderr = utils.execute(
100                 ip_cmd,
101                 check_exit_code=False,
102                 return_stderr=True,
103                 log_fail_as_error=False)
104         except Exception as e:
105             LOG.exception(_LE("Failed executing ip command"))
106             raise UnsupportedIpLinkCommand(reason=e)
107         return _stdout or _stderr