Created
September 2, 2014 12:09
-
-
Save Mic92/e2ff67f1d6f19ad0b2a2 to your computer and use it in GitHub Desktop.
ansible connection plugin for lxc using lxc-attach
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# add the following line to your ansible.cfg | |
connection_plugins = /usr/share/ansible_plugins/connection_plugins:/etc/ansible/connection_plugins |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# example hosts file | |
containername ansible_connection=lxc |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# put the following file into /etc/ansible/connection_plugins/lxc.py | |
from __future__ import absolute_import | |
import distutils.spawn | |
import os,sys | |
import subprocess | |
import shutil | |
from ansible import errors | |
from ansible.callbacks import vvv | |
import lxc as _lxc | |
class Connection(object): | |
''' Local lxc based connections ''' | |
def _search_executable(self, executable): | |
cmd = distutils.spawn.find_executable(executable) | |
if not cmd: | |
raise errors.AnsibleError("%s command not found in PATH") % executable | |
return cmd | |
def _root_fs(self): | |
rootfs = self.container.get_running_config_item("lxc.rootfs") | |
if not rootfs: | |
raise errors.AnsibleError("rootfs not set in configuration for %s") % self.host | |
return rootfs | |
def __init__(self, runner, host, port, *args, **kwargs): | |
self.has_pipelining = False | |
self.host = host | |
# port is unused, since this is local | |
self.port = port | |
self.runner = runner | |
self.lxc_attach = self._search_executable("lxc-attach") | |
self.container = _lxc.Container(host) | |
if self.container.state == "STOPPED": | |
raise errors.AnsibleError("%s is not running" % host) | |
self.rootfs = self._root_fs() | |
def connect(self, port=None): | |
''' connect to the lxc; nothing to do here ''' | |
vvv("THIS IS A LOCAL LXC DIR", host=self.host) | |
return self | |
def _generate_cmd(self, executable, cmd): | |
if executable: | |
return [self.lxc_attach, "--name", self.host, "--", executable, '-c', cmd] | |
else: | |
return '%s --name %s -- %s' % (self.lxc_attach, self.host, cmd) | |
def exec_command(self, cmd, tmp_path, sudo_user=None, sudoable=False, executable='/bin/sh', in_data=None, su=None, su_user=None): | |
''' run a command on the chroot ''' | |
# We enter lxc as root so sudo stuff can be ignored | |
local_cmd = self._generate_cmd(executable, cmd) | |
vvv("EXEC %s" % (local_cmd), host=self.host) | |
p = subprocess.Popen(local_cmd, shell=isinstance(local_cmd, basestring), | |
cwd=self.runner.basedir, | |
stdin=subprocess.PIPE, | |
stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
stdout, stderr = p.communicate() | |
return (p.returncode, '', stdout, stderr) | |
def _normalize_path(self, path, prefix): | |
if not path.startswith(os.path.sep): | |
path = os.path.join(os.path.sep, path) | |
normpath = os.path.normpath(path) | |
return os.path.join(prefix, normpath[1:]) | |
def _copy(self, in_path, out_path): | |
if not os.path.exists(in_path): | |
raise errors.AnsibleFileNotFound("file or module does not exist: %s" % in_path) | |
try: | |
shutil.copyfile(in_path, out_path) | |
except shutil.Error: | |
traceback.print_exc() | |
raise errors.AnsibleError("failed to copy: %s and %s are the same" % (in_path, out_path)) | |
except IOError: | |
traceback.print_exc() | |
raise errors.AnsibleError("failed to transfer file to %s" % out_path) | |
def put_file(self, in_path, out_path): | |
''' transfer a file from local to lxc ''' | |
out_path = self._normalize_path(out_path, self.rootfs) | |
vvv("PUT %s TO %s" % (in_path, out_path), host=self.host) | |
self._copy(in_path, out_path) | |
def fetch_file(self, in_path, out_path): | |
''' fetch a file from lxc to local ''' | |
in_path = self._normalize_path(in_path, self.rootfs) | |
vvv("FETCH %s TO %s" % (in_path, out_path), host=self.host) | |
self._copy(in_path, out_path) | |
def close(self): | |
''' terminate the connection; nothing to do here ''' | |
pass |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment