Last active
October 8, 2018 14:53
-
-
Save shirou/10021756 to your computer and use it in GitHub Desktop.
ansible docker direct connection plugin
This file contains 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
前提 | |
----------- | |
- docker 0.9.1 | |
- lxcを入れること | |
- linux 3.11で確認。 3.8以上じゃないとだめっぽい。 | |
- ubuntu image (docker pull ubuntuで取ってきたもので試してみた) | |
- imageにはpython2を入れておくこと | |
- /usr/bin/tee がimageにあること | |
準備 | |
----------- | |
1. docker -e lxc でlxcドライバーで立ち上げる | |
2. docker run でコンテナを起動しておく | |
3. ファイルを2つ配置する | |
docker_inventory.py はinventoryファイルの置き場に。 chmod ugo+x して実行権限を付けておく | |
docker_connection.pyは connection_plugins というディレクトリの下に | |
こんな構成になる | |
|- docker_inventory.py | |
|- connection_plugins | |
| | | |
| +- docker_connection.py | |
+- なにか.yml | |
実行方法 | |
----------- | |
ansible-playbook -i docker_inventory.py なにか.yml | |
dockerという名前のグループの中のホストとして配置されるので、なにか.ymlのhostsには注意 | |
中でsudoを読んでいるのでパスワードが聞かれるかも。 |
This file contains 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
# Based on local.py (c) 2012, Michael DeHaan <[email protected]> | |
# Based on chroot.py (c) 2013, Maykel Moya <[email protected]> | |
# Based on libvirt_lxc.py (c) 2013, Michael Scherer <[email protected]> | |
# (c) 2014, WAKAYAMA Shirou <[email protected]> | |
# This file is part of Ansible | |
# | |
# Ansible is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, either version 3 of the License, or | |
# (at your option) any later version. | |
# | |
# Ansible is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with Ansible. If not, see <http://www.gnu.org/licenses/>. | |
import distutils.spawn | |
import os | |
import subprocess | |
from ansible import errors | |
from ansible.callbacks import vvv | |
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 _check_domain(self, domain): | |
p = subprocess.Popen([self.cmd, '-q', '-c', 'lxc:///', 'dominfo', domain], | |
stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
p.communicate() | |
if p.returncode: | |
raise errors.AnsibleError("%s is not a lxc defined" % domain) | |
def __init__(self, runner, host, port, *args, **kwargs): | |
self.lxc = host | |
self.has_pipelining = False | |
self.cmd = self._search_executable('lxc-attach') | |
# self._check_domain(host) | |
self.runner = runner | |
self.host = host | |
# port is unused, since this is local | |
self.port = port | |
def connect(self, port=None): | |
''' connect to the lxc; nothing to do here ''' | |
vvv("THIS IS A LOCAL LXC DIR", host=self.lxc) | |
return self | |
def _generate_cmd(self, executable, cmd): | |
if executable: | |
local_cmd = ['sudo', self.cmd, '-q', '-n', self.lxc, '--', executable , '-c', cmd] | |
else: | |
local_cmd = 'sudo %s -q -n %s -- %s' % (self.cmd, self.lxc, cmd) | |
return local_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.lxc) | |
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 put_file(self, in_path, out_path): | |
''' transfer a file from local to lxc ''' | |
out_path = self._normalize_path(out_path, '/') | |
vvv("PUT %s TO %s" % (in_path, out_path), host=self.lxc) | |
local_cmd = ['sudo', self.cmd, '-q', '-n', self.lxc, '--', '/usr/bin/tee', out_path] | |
vvv("EXEC %s" % (local_cmd), host=self.lxc) | |
p = subprocess.Popen(local_cmd, cwd=self.runner.basedir, | |
stdin=subprocess.PIPE, | |
stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
stdout, stderr = p.communicate(open(in_path,'rb').read()) | |
def fetch_file(self, in_path, out_path): | |
''' fetch a file from lxc to local ''' | |
in_path = self._normalize_path(in_path, '/') | |
vvv("FETCH %s TO %s" % (in_path, out_path), host=self.lxc) | |
local_cmd = ['sudo', self.cmd, '-q', '-n', self.lxc, '--', '/bin/cat', in_path] | |
vvv("EXEC %s" % (local_cmd), host=self.lxc) | |
p = subprocess.Popen(local_cmd, cwd=self.runner.basedir, | |
stdin=subprocess.PIPE, | |
stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
stdout, stderr = p.communicate() | |
open(out_path,'wb').write(stdout) | |
def close(self): | |
''' terminate the connection; nothing to do here ''' | |
pass |
This file contains 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
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
# (c) 2014, WAKAYAMA Shirou <[email protected]> | |
# | |
# Ansible is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, either version 3 of the License, or | |
# (at your option) any later version. | |
# | |
# Ansible is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with Ansible. If not, see <http://www.gnu.org/licenses/>. | |
from __future__ import division, print_function, absolute_import | |
import os | |
import subprocess | |
import sys | |
import json | |
def docker_ps(): | |
cmd = ['sudo', 'docker', 'ps', '--no-trunc', '-q'] | |
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
stdout, stderr = p.communicate() | |
return (p.returncode, stdout, stderr) | |
def parse(stdout): | |
hosts = {'docker': []} | |
host_vars = {} | |
for row in stdout.split("\n"): | |
if not row: | |
continue | |
hosts['docker'].append(row) | |
host_vars[row] = { | |
'ansible_connection': 'docker_connection' | |
} | |
return hosts, host_vars | |
if __name__ == '__main__': | |
rc, stdout, stderr = docker_ps() | |
hosts, host_vars = parse(stdout) | |
if sys.argv[1] == '--list': | |
print(json.dumps(hosts)) | |
else: | |
hostname = sys.argv[2] | |
print(json.dumps(host_vars[hostname])) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment