mirror of
https://github.com/valitydev/salt.git
synced 2024-11-08 01:18:58 +00:00
Merge pull request #37060 from theredcat/lxc
Add lxc.get_pid and lxc.add_veth
This commit is contained in:
commit
454a721bff
@ -12,6 +12,7 @@ lxc >= 1.0 (even beta alpha) is required
|
||||
from __future__ import absolute_import, print_function
|
||||
import datetime
|
||||
import copy
|
||||
import string
|
||||
import textwrap
|
||||
import difflib
|
||||
import logging
|
||||
@ -4659,3 +4660,103 @@ def apply_network_profile(name, network_profile, nic_opts=None, path=None):
|
||||
tofile='after'):
|
||||
diff += line
|
||||
return diff
|
||||
|
||||
|
||||
def get_pid(name, path=None):
|
||||
'''
|
||||
Returns a container pid.
|
||||
Throw an exception if the container isn't running.
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' lxc.get_pid name
|
||||
'''
|
||||
if name not in list_(limit='running', path=path):
|
||||
raise CommandExecutionError('Container {0} is not running, can\'t determine PID'.format(name))
|
||||
info = __salt__['cmd.run']('lxc-info -n {0}'.format(name)).split("\n")
|
||||
pid = [line.split(':')[1].strip() for line in info if re.match(r'\s*PID', line) != None][0]
|
||||
return pid
|
||||
|
||||
|
||||
def add_veth(name, interface_name, bridge=None, path=None):
|
||||
'''
|
||||
Add a veth to a container.
|
||||
Note : this function doesn't update the container config, just add the interface at runtime
|
||||
|
||||
name
|
||||
Name of the container
|
||||
|
||||
interface_name
|
||||
Name of the interface in the container
|
||||
|
||||
bridge
|
||||
Name of the bridge to attach the interface to (facultative)
|
||||
|
||||
CLI Examples:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' lxc.add_veth container_name eth1 br1
|
||||
salt '*' lxc.add_veth container_name eth1
|
||||
'''
|
||||
|
||||
# Get container init PID
|
||||
pid = get_pid(name, path=path)
|
||||
|
||||
# Generate a ramdom string for veth and ensure that is isn't present on the system
|
||||
while True:
|
||||
random_veth = 'veth'+''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(6))
|
||||
if random_veth not in __salt__['network.interfaces']().keys():
|
||||
break
|
||||
|
||||
# Check prerequisites
|
||||
if not __salt__['file.directory_exists']('/var/run/'):
|
||||
raise CommandExecutionError('Directory /var/run required for lxc.add_veth doesn\'t exists')
|
||||
if not __salt__['file.file_exists']('/proc/{0}/ns/net'.format(pid)):
|
||||
raise CommandExecutionError('Proc file for container {0} network namespace doesn\'t exists'.format(name))
|
||||
|
||||
if not __salt__['file.directory_exists']('/var/run/netns'):
|
||||
__salt__['file.mkdir']('/var/run/netns')
|
||||
|
||||
# Ensure that the symlink is up to date (change on container restart)
|
||||
if __salt__['file.is_link']('/var/run/netns/{0}'.format(name)):
|
||||
__salt__['file.remove']('/var/run/netns/{0}'.format(name))
|
||||
|
||||
__salt__['file.symlink']('/proc/{0}/ns/net'.format(pid), '/var/run/netns/{0}'.format(name))
|
||||
|
||||
# Ensure that interface doesn't exists
|
||||
interface_exists = 0 == __salt__['cmd.retcode']('ip netns exec {netns} ip address list {interface}'.format(
|
||||
netns=name,
|
||||
interface=interface_name
|
||||
))
|
||||
|
||||
if interface_exists:
|
||||
raise CommandExecutionError('Interface {interface} already exists in {container}'.format(
|
||||
interface=interface_name,
|
||||
container=name
|
||||
))
|
||||
|
||||
# Create veth and bring it up
|
||||
if __salt__['cmd.retcode']('ip link add name {veth} type veth peer name {veth}_c'.format(veth=random_veth)) != 0:
|
||||
raise CommandExecutionError('Error while creating the veth pair {0}'.format(random_veth))
|
||||
if __salt__['cmd.retcode']('ip link set dev {0} up'.format(random_veth)) != 0:
|
||||
raise CommandExecutionError('Error while bringing up host-side veth {0}'.format(random_veth))
|
||||
|
||||
# Attach it to the container
|
||||
attached = 0 == __salt__['cmd.retcode']('ip link set dev {veth}_c netns {container} name {interface_name}'.format(
|
||||
veth=random_veth,
|
||||
container=name,
|
||||
interface_name=interface_name
|
||||
))
|
||||
if not attached:
|
||||
raise CommandExecutionError('Error while attaching the veth {veth} to container {container}'.format(
|
||||
veth=random_veth,
|
||||
container=name
|
||||
))
|
||||
|
||||
__salt__['file.remove']('/var/run/netns/{0}'.format(name))
|
||||
|
||||
if bridge is not None:
|
||||
__salt__['bridge.addif'](bridge, random_veth)
|
||||
|
Loading…
Reference in New Issue
Block a user