Merge pull request #46683 from homolkad/libvirt_create_network_pool

Add create network and pool in libvirt
This commit is contained in:
Nicole Thomas 2018-04-04 17:09:21 -04:00 committed by GitHub
commit bd88287504
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 329 additions and 0 deletions

View File

@ -338,6 +338,52 @@ def _gen_vol_xml(vmname,
return template.render(**context)
def _gen_net_xml(name,
bridge,
forward,
vport,
tag=None):
'''
Generate the XML string to define a libvirt network
'''
context = {
'name': name,
'bridge': bridge,
'forward': forward,
'vport': vport,
'tag': tag,
}
fn_ = 'libvirt_network.jinja'
try:
template = JINJA.get_template(fn_)
except jinja2.exceptions.TemplateNotFound:
log.error('Could not load template %s', fn_)
return ''
return template.render(**context)
def _gen_pool_xml(name,
ptype,
target,
source=None):
'''
Generate the XML string to define a libvirt storage pool
'''
context = {
'name': name,
'ptype': ptype,
'target': target,
'source': source,
}
fn_ = 'libvirt_pool.jinja'
try:
template = JINJA.get_template(fn_)
except jinja2.exceptions.TemplateNotFound:
log.error('Could not load template %s', fn_)
return ''
return template.render(**context)
def _qemu_image_info(path):
'''
Detect information for the image at path
@ -2195,3 +2241,130 @@ def cpu_baseline(full=False, migratable=False, out='libvirt'):
'vendor': cpu.getElementsByTagName('vendor')[0].childNodes[0].nodeValue,
'features': [feature.getAttribute('name') for feature in cpu.getElementsByTagName('feature')]
}
def net_define(name, bridge, forward, **kwargs):
'''
Create libvirt network.
:param name: Network name
:param bridge: Bridge name
:param forward: Forward mode(bridge, router, nat)
:param vport: Virtualport type
:param tag: Vlan tag
:param autostart: Network autostart (default True)
:param start: Network start (default True)
CLI Example:
.. code-block:: bash
salt '*' virt.net_define network main bridge openvswitch
'''
conn = __get_conn()
vport = kwargs.get('vport', None)
tag = kwargs.get('tag', None)
autostart = kwargs.get('autostart', True)
starting = kwargs.get('start', True)
xml = _gen_net_xml(
name,
bridge,
forward,
vport,
tag,
)
try:
conn.networkDefineXML(xml)
except libvirtError as err:
log.warning(err)
raise err # a real error we should report upwards
try:
network = conn.networkLookupByName(name)
except libvirtError as err:
log.warning(err)
raise err # a real error we should report upwards
if network is None:
return False
if (starting is True or autostart is True) and network.isActive() != 1:
network.create()
if autostart is True and network.autostart() != 1:
network.setAutostart(int(autostart))
elif autostart is False and network.autostart() == 1:
network.setAutostart(int(autostart))
return True
def pool_define_build(name, **kwargs):
'''
Create libvirt pool.
:param name: Pool name
:param ptype: Pool type
:param target: Pool path target
:param source: Pool dev source
:param autostart: Pool autostart (default True)
:param start: Pool start (default True)
CLI Example:
.. code-block:: bash
salt '*' virt.pool_defin base logical base
'''
exist = False
update = False
conn = __get_conn()
ptype = kwargs.pop('ptype', None)
target = kwargs.pop('target', None)
source = kwargs.pop('source', None)
autostart = kwargs.pop('autostart', True)
starting = kwargs.pop('start', True)
xml = _gen_pool_xml(
name,
ptype,
target,
source,
)
try:
conn.storagePoolDefineXML(xml)
except libvirtError as err:
log.warning(err)
if err.get_error_code() == libvirt.VIR_ERR_STORAGE_POOL_BUILT or libvirt.VIR_ERR_OPERATION_FAILED:
exist = True
else:
raise err # a real error we should report upwards
try:
pool = conn.storagePoolLookupByName(name)
except libvirtError as err:
log.warning(err)
raise err # a real error we should report upwards
if pool is None:
return False
if (starting is True or autostart is True) and pool.isActive() != 1:
if exist is True:
update = True
pool.create()
else:
pool.create(libvirt.VIR_STORAGE_POOL_CREATE_WITH_BUILD)
if autostart is True and pool.autostart() != 1:
if exist is True:
update = True
pool.setAutostart(int(autostart))
elif autostart is False and pool.autostart() == 1:
if exist is True:
update = True
pool.setAutostart(int(autostart))
if exist is True:
if update is True:
return (True, 'Pool exist', 'Pool update')
return (True, 'Pool exist')
return True

View File

@ -390,3 +390,109 @@ def reverted(name, snapshot=None, cleanup=False):
ret['comment'] = six.text_type(err)
return ret
def network_define(name, bridge, forward, **kwargs):
'''
Defines and starts a new network with specified arguments.
.. code-block:: yaml
domain_name:
virt.network_define
.. code-block:: yaml
network_name:
virt.network_define:
- bridge: main
- forward: bridge
- vport: openvswitch
- tag: 180
- autostart: True
- start: True
'''
ret = {'name': name,
'changes': {},
'result': False,
'comment': ''
}
kwargs = salt.utils.args.clean_kwargs(**kwargs)
vport = kwargs.pop('vport', None)
tag = kwargs.pop('tag', None)
autostart = kwargs.pop('autostart', True)
start = kwargs.pop('start', True)
try:
result = __salt__['virt.net_define'](name, bridge, forward, vport, tag=tag, autostart=autostart, start=start)
if result:
ret['changes'][name] = 'Network {0} has been created'.format(name)
ret['result'] = True
else:
ret['comment'] = 'Network {0} created fail'.format(name)
except libvirt.libvirtError as err:
if err.get_error_code() == libvirt.VIR_ERR_NETWORK_EXIST or libvirt.VIR_ERR_OPERATION_FAILED:
ret['result'] = True
ret['comment'] = 'The network already exist'
else:
ret['comment'] = err.get_error_message()
return ret
def pool_define(name, **kwargs):
'''
Defines and starts a new pool with specified arguments.
.. code-block:: yaml
pool_name:
virt.pool_define
.. code-block:: yaml
pool_name:
virt.pool_define:
- ptype: logical
- target: pool
- source: sda1
- autostart: True
- start: True
'''
ret = {'name': name,
'changes': {},
'result': False,
'comment': ''
}
kwargs = salt.utils.args.clean_kwargs(**kwargs)
ptype = kwargs.pop('ptype', None)
target = kwargs.pop('target', None)
source = kwargs.pop('source', None)
autostart = kwargs.pop('autostart', True)
start = kwargs.pop('start', True)
try:
result = __salt__['virt.pool_define_build'](name, ptype=ptype, target=target,
source=source, autostart=autostart, start=start)
if result:
if 'Pool exist' in result:
if 'Pool update' in result:
ret['changes'][name] = 'Pool {0} has been updated'.format(name)
else:
ret['comment'] = 'Pool {0} already exist'.format(name)
else:
ret['changes'][name] = 'Pool {0} has been created'.format(name)
ret['result'] = True
else:
ret['comment'] = 'Pool {0} created fail'.format(name)
except libvirt.libvirtError as err:
if err.get_error_code() == libvirt.VIR_ERR_STORAGE_POOL_BUILT or libvirt.VIR_ERR_OPERATION_FAILED:
ret['result'] = True
ret['comment'] = 'The pool already exist'
ret['comment'] = err.get_error_message()
return ret

View File

@ -0,0 +1,9 @@
<network>
<name>{{ name }}</name>
<bridge name='{{ bridge }}'/>
<forward mode='{{ forward }}'/>{% if vport != None %}
<virtualport type='{{ vport }}'/>{% endif %}{% if tag != None %}
<vlan>
<tag id='{{ tag }}'/>
</vlan>{% endif %}
</network>

View File

@ -0,0 +1,9 @@
<pool type='{{ ptype }}'>
<name>{{ name }}</name>
<target>
<path>/dev/{{ target }}</path>
</target>{% if source != None %}
<source>
<device path='/dev/{{ source }}'/>
</source>{% endif %}
</pool>

View File

@ -507,3 +507,35 @@ class VirtTestCase(TestCase, LoaderModuleMockMixin):
nic = nics[list(nics)[0]]
self.assertEqual('bridge', nic['type'])
self.assertEqual('ac:de:48:b6:8b:59', nic['mac'])
def test_network(self):
xml_data = virt._gen_net_xml('network', 'main', 'bridge', 'openvswitch')
root = ET.fromstring(xml_data)
self.assertEqual(root.find('name').text, 'network')
self.assertEqual(root.find('bridge').attrib['name'], 'main')
self.assertEqual(root.find('forward').attrib['mode'], 'bridge')
self.assertEqual(root.find('virtualport').attrib['type'], 'openvswitch')
def test_network_tag(self):
xml_data = virt._gen_net_xml('network', 'main', 'bridge', 'openvswitch', 1001)
root = ET.fromstring(xml_data)
self.assertEqual(root.find('name').text, 'network')
self.assertEqual(root.find('bridge').attrib['name'], 'main')
self.assertEqual(root.find('forward').attrib['mode'], 'bridge')
self.assertEqual(root.find('virtualport').attrib['type'], 'openvswitch')
self.assertEqual(root.find('vlan/tag').attrib['id'], '1001')
def test_pool(self):
xml_data = virt._gen_pool_xml('pool', 'logical', 'base')
root = ET.fromstring(xml_data)
self.assertEqual(root.find('name').text, 'pool')
self.assertEqual(root.attrib['type'], 'logical')
self.assertEqual(root.find('target/path').text, '/dev/base')
def test_pool_with_source(self):
xml_data = virt._gen_pool_xml('pool', 'logical', 'base', 'sda')
root = ET.fromstring(xml_data)
self.assertEqual(root.find('name').text, 'pool')
self.assertEqual(root.attrib['type'], 'logical')
self.assertEqual(root.find('target/path').text, '/dev/base')
self.assertEqual(root.find('source/device').attrib['path'], '/dev/sda')