Commit d370a511005a88fc42c08e735111d941f47b72df

Authored by Georg Hopp
0 parents

Add vry basic README.md

  1 +# ignore vim swap files
  2 +.*.sw?
  3 +
  4 +# ignore generated stuff
  5 +demo_userns
  6 +create_user_cgroup
  1 +PROGRAMS = demo_userns
  2 +
  3 +demo_userns_OBJS = demo_userns.o
  4 +OBJECTS = $(demo_userns_OBJS)
  5 +
  6 +CFLAGS = -O0 -ggdb -Wall -Werror
  7 +
  8 +$(PROGRAMS): $(OBJECTS)
  9 + $(CC) $(LDFLAGS) -lcap -o $@ $($@_OBJS)
  10 +
  11 +%.o: %.c
  12 + $(CC) $(CFLAGS) -c -o $@ $<
  1 +# LXC-Coding
  2 +
  3 +Playground for user namespaces and other Linux Container stuff.
  4 +
  5 +## Requirements
  6 +
  7 +A proper kernel...
  8 +
  9 +## License
  10 +
  11 +> This program is free software: you can redistribute it and/or modify
  12 +> it under the terms of the GNU General Public License as published by
  13 +> the Free Software Foundation, either version 3 of the License, or
  14 +> (at your option) any later version.
  15 +>
  16 +> This program is distributed in the hope that it will be useful,
  17 +> but WITHOUT ANY WARRANTY; without even the implied warranty of
  18 +> MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19 +> GNU General Public License for more details.
  20 +>
  21 +> You should have received a copy of the GNU General Public License
  22 +> along with this program. If not, see <http://www.gnu.org/licenses/>.
  23 +
  24 +## Author
  25 +
  26 +Georg Hopp <<georg@steffers.org>>
  1 +[defaults]
  2 +inventory = hosts
  3 +host_key_checking = False
  4 +nocows=0
  5 +
  6 +ansible_managed = Ansible managed: {file} on {host}
  7 +
  8 +# # do redis facts caching
  9 +# gathering = smart
  10 +# fact_caching = redis
  11 +# fact_caching_timeout = 86400
  1 +/*
  2 + * demo_userns.c
  3 + *
  4 + * Copyright 2013, Michael Kerrisk
  5 + * Licensed under GNU General Public License v2 or later
  6 + *
  7 + * Demonstrate the use of the clone() CLONE_NEWUSER flag.
  8 + *
  9 + * Link with "-lcap" and make sure that the "libcap-devel" (or
  10 + * similar) package is installed on the system.
  11 + */
  12 +
  13 +#define _GNU_SOURCE
  14 +
  15 +#include <sys/capability.h>
  16 +#include <sys/wait.h>
  17 +#include <sched.h>
  18 +#include <stdio.h>
  19 +#include <stdlib.h>
  20 +#include <unistd.h>
  21 +
  22 +#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
  23 +} while (0)
  24 +
  25 +static int /* Startup function for cloned child */
  26 +childFunc(void *arg)
  27 +{
  28 + cap_t caps;
  29 +
  30 + for (;;) {
  31 + printf("eUID = %ld; eGID = %ld; ",
  32 + (long) geteuid(), (long) getegid());
  33 +
  34 + caps = cap_get_proc();
  35 + printf("capabilities: %s\n", cap_to_text(caps, NULL));
  36 +
  37 + if (arg == NULL)
  38 + break;
  39 +
  40 + sleep(5);
  41 + }
  42 +
  43 + return 0;
  44 +}
  45 +
  46 +#define STACK_SIZE (1024 * 1024)
  47 +
  48 +static char child_stack[STACK_SIZE]; /* Space for child's stack */
  49 +
  50 +int
  51 +main(int argc, char *argv[])
  52 +{
  53 + pid_t pid;
  54 +
  55 + /* Create child; child commences execution in childFunc() */
  56 +
  57 + pid = clone(childFunc, child_stack + STACK_SIZE, /* Assume stack
  58 + grows downward */
  59 + CLONE_NEWUSER | SIGCHLD, argv[1]);
  60 + if (pid == -1)
  61 + errExit("clone");
  62 +
  63 + /* Parent falls through to here. Wait for child. */
  64 +
  65 + if (waitpid(pid, NULL, 0) == -1)
  66 + errExit("waitpid");
  67 +
  68 + exit(EXIT_SUCCESS);
  69 +}
  70 +
  71 +// vim: ft=c cindent ts=4 sw=4 sts=4:
No preview for this file type
  1 +localhost ansible_connection=local
  1 +import lxc
  2 +import os
  3 +import sys
  4 +import hashlib
  5 +import json
  6 +import getpass
  7 +import subprocess
  8 +
  9 +scriptpath = os.path.dirname(os.path.realpath(__file__))
  10 +
  11 +def lxc_start(cont):
  12 + if (os.getuid() != 0):
  13 + uname = getpass.getuser()
  14 + subprocess.call([scriptpath + '/create_user_cgroup']);
  15 + for i in os.listdir('/sys/fs/cgroup'):
  16 + if (i == 'openrc'):
  17 + continue
  18 + with open('/sys/fs/cgroup/'+i+'/'+uname+'/tasks', 'a') as f:
  19 + f.write(str(os.getpid())+'\n');
  20 +
  21 + cont.start();
  22 +
  23 +def basic(cont):
  24 + def work(data):
  25 + print data
  26 + sys.stdout.flush()
  27 + sys.exit(0)
  28 +
  29 + lxc_read, lxc_write = os.pipe()
  30 +
  31 + cont.attach_wait(work, 'testtest', stdout=lxc_write)
  32 + os.close(lxc_write)
  33 +
  34 + lxc_readfd = os.fdopen(lxc_read)
  35 + data = lxc_readfd.readline().rstrip('\n')
  36 +
  37 + lxc_readfd.close()
  38 +
  39 + print data
  40 +
  41 +def basic2(cont):
  42 + def work(data):
  43 + print data
  44 + sys.stdout.flush()
  45 + sys.exit(0)
  46 +
  47 + lxc_read, lxc_write = os.pipe()
  48 +
  49 + cont.attach(work, 'testtest', stdout=lxc_write)
  50 + os.close(lxc_write)
  51 +
  52 + lxc_readfd = os.fdopen(lxc_read)
  53 + data = lxc_readfd.readline().rstrip('\n')
  54 +
  55 + lxc_readfd.close()
  56 +
  57 + print data
  58 +
  59 +def copy(cont, src, dest):
  60 + def work(dest):
  61 + infno = sys.stdin.fileno()
  62 + data = os.read(infno, 100)
  63 + print(data)
  64 +
  65 + lxc_read, lxc_write = os.pipe()
  66 +
  67 + pid = cont.attach(work, 'foo', stdin=lxc_read)
  68 + os.close(lxc_read)
  69 +
  70 + os.write(lxc_write, 'fooooobadooooo')
  71 +
  72 + os.close(lxc_write)
  73 + os.waitpid(pid, 0)
  74 +
  75 +def copy2(cont, src, dest):
  76 + bufsize = 2048
  77 +
  78 + def work(dest):
  79 + infno = sys.stdin.fileno()
  80 + with open(dest, 'w') as outfile:
  81 + data = os.read(infno, bufsize)
  82 + while (bufsize == len(data)):
  83 + outfile.write(data)
  84 + data = os.read(infno, bufsize)
  85 + outfile.write(data)
  86 +
  87 + lxc_read, lxc_write = os.pipe()
  88 +
  89 + pid = cont.attach(work, dest, stdin=lxc_read)
  90 + os.close(lxc_read)
  91 +
  92 + with open(src, 'r') as infile:
  93 + data = infile.read(bufsize)
  94 + while (bufsize == len(data)):
  95 + os.write(lxc_write, data)
  96 + data = infile.read(bufsize)
  97 + os.write(lxc_write, data)
  98 +
  99 + os.close(lxc_write)
  100 + os.waitpid(pid, 0)
  101 +
  102 +def verify(cont, src, dest):
  103 + bufsize = 2048
  104 +
  105 + def work(dest):
  106 + digest = ''
  107 + try:
  108 + chk = hashlib.sha1()
  109 + with open(dest, 'r') as dfile:
  110 + data = dfile.read(bufsize)
  111 + while(bufsize == len(data)):
  112 + chk.update(data)
  113 + data = dfile.read(bufsize)
  114 + chk.update(data)
  115 + digest = chk.hexdigest()
  116 + except:
  117 + pass
  118 + sys.stdout.write(digest)
  119 + sys.stdout.flush()
  120 +
  121 + lxc_read, lxc_write = os.pipe()
  122 +
  123 + pid = cont.attach(work, dest, stdout=lxc_write)
  124 + os.close(lxc_write)
  125 +
  126 + chk = hashlib.sha1()
  127 + with open(src, 'r') as dfile:
  128 + data = dfile.read(bufsize)
  129 + while (bufsize == len(data)):
  130 + chk.update(data)
  131 + data = dfile.read(bufsize)
  132 + chk.update(data)
  133 +
  134 + lxc_chk = os.read(lxc_read, 100)
  135 + os.close(lxc_read)
  136 +
  137 + return json.dumps({
  138 + 'equal': lxc_chk == chk.hexdigest(),
  139 + 'local_sum': chk.hexdigest(),
  140 + 'container_sum': lxc_chk})
  141 +
  142 +cont = lxc.Container('ansible_test')
  143 +
  144 +assert cont.defined
  145 +
  146 +started = False
  147 +
  148 +if not cont.running:
  149 + lxc_start(cont)
  150 + if not cont.wait('RUNNING', timeout=5):
  151 + raise EnvironmentError(0x01, '[lxc] unable to start container', cont)
  152 + started = True
  153 +
  154 +#basic(cont)
  155 +#basic2(cont)
  156 +#copy(cont, 'verkauf.jpg', '/tmp/foo')
  157 +
  158 +print __file__
  159 +print os.path.realpath(__file__)
  160 +print os.path.dirname(os.path.realpath(__file__))
  161 +
  162 +vres = json.loads(verify(cont, 'verkauf.jpg', '/tmp/foo'))
  163 +if not vres['equal']:
  164 + print "copy file"
  165 + copy2(cont, 'verkauf.jpg', '/tmp/foo')
  166 +else:
  167 + print "files are equal"
  168 +
  169 +if started:
  170 + cont.shutdown(5)
  171 +
  1 +#!/usr/bin/python
  2 +#
  3 +
  4 +# (c) 2014, Pavel Antonov <antonov@adwz.ru>
  5 +#
  6 +# This file is part of Ansible
  7 +#
  8 +# This module is free software: you can redistribute it and/or modify
  9 +# it under the terms of the GNU General Public License as published by
  10 +# the Free Software Foundation, either version 3 of the License, or
  11 +# (at your option) any later version.
  12 +#
  13 +# This software is distributed in the hope that it will be useful,
  14 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16 +# GNU General Public License for more details.
  17 +#
  18 +# You should have received a copy of the GNU General Public License
  19 +# along with this software. If not, see <http://www.gnu.org/licenses/>.
  20 +
  21 +######################################################################
  22 +
  23 +DOCUMENTATION = '''
  24 +---
  25 +module: lxc_copy
  26 +author: Georg Hopp
  27 +version_added: "1.9"
  28 +short_description: copy files in an lxc
  29 +description:
  30 + - Very simple first start to copy files from host to lxc container
  31 + even in non privileged containers
  32 +options:
  33 + name:
  34 + description:
  35 + - Lxc container name to use
  36 + required: true
  37 + default: null
  38 + aliases: []
  39 + src:
  40 + description:
  41 + - Path to source file
  42 + required: true
  43 + default: null
  44 + aliases: []
  45 + dest:
  46 + description:
  47 + - Path to file in container
  48 + required: true
  49 + default: null
  50 + aliases: []
  51 +requirements: [ "lxc", "create_user_cgroup" ]
  52 +'''
  53 +
  54 +EXAMPLES = '''
  55 +Copy a file from the host in the container:
  56 +
  57 +- hosts: localhost
  58 + tasks:
  59 + - name: copy host file to container
  60 + lxc_copy:
  61 + name: ansible_test
  62 + src: nicefile
  63 + dest: /tmp/verynicefile
  64 +'''
  65 +
  66 +try:
  67 + import lxc
  68 + import sys
  69 + import os
  70 + import json
  71 + import getpass
  72 + import hashlib
  73 + from contextlib import contextmanager
  74 +except ImportError, e:
  75 + print "failed=True msg='failed to import python module: %s'" % e
  76 + sys.exit(1)
  77 +
  78 +class LxcManager:
  79 + @contextmanager
  80 + def lxc_started(self):
  81 + started = self.container.running
  82 +
  83 + if not started and not self.container.running:
  84 + if (os.getuid() != 0):
  85 + uname = getpass.getuser()
  86 + subprocess.call(["create_user_cgroup"]);
  87 + for i in os.listdir('/sys/fs/cgroup'):
  88 + if (i == 'openrc'):
  89 + continue
  90 + with open('/sys/fs/cgroup/'+i+'/'+uname+'/tasks', 'a') as f:
  91 + f.write(str(os.getpid())+'\n');
  92 +
  93 + self.container.start();
  94 +
  95 + yield self
  96 +
  97 + if not started and self.container.running:
  98 + self.container.shutdown(5)
  99 +
  100 + def __init__(self, module):
  101 + self.module = module
  102 + self.name = self.module.params.get('name')
  103 + self.src = self.module.params.get('src')
  104 + self.dest = self.module.params.get('dest')
  105 + self.container = lxc.Container(self.name)
  106 + self.changed = False
  107 + self.log = []
  108 + self.error_msg = None
  109 + self.buffer_size = 20480
  110 +
  111 + def get_log(self, as_string=True):
  112 + return "".join(self.log) if as_string else self.log
  113 +
  114 + def _verify(self):
  115 + def work(dest):
  116 + digest = ''
  117 + try:
  118 + chk = hashlib.sha1()
  119 + with open(dest, 'r') as dfile:
  120 + data = dfile.read(self.buffer_size)
  121 + while(self.buffer_size == len(data)):
  122 + chk.update(data)
  123 + data = dfile.read(self.buffer_size)
  124 + chk.update(data)
  125 + digest = chk.hexdigest()
  126 + except:
  127 + pass
  128 + sys.stdout.write(digest)
  129 + sys.stdout.flush()
  130 +
  131 + lxc_read, lxc_write = os.pipe()
  132 +
  133 + pid = self.container.attach(work, self.dest, stdout=lxc_write)
  134 + os.close(lxc_write)
  135 +
  136 + chk = hashlib.sha1()
  137 + with open(self.src, 'r') as dfile:
  138 + data = dfile.read(self.buffer_size)
  139 + while (self.buffer_size == len(data)):
  140 + chk.update(data)
  141 + data = dfile.read(self.buffer_size)
  142 + chk.update(data)
  143 +
  144 + lxc_chk = os.read(lxc_read, 100) # read digest from container....
  145 + os.close(lxc_read)
  146 +
  147 + self.files_equal = lxc_chk == chk.hexdigest()
  148 + self.local_sum = chk.hexdigest()
  149 + self.container_sum = lxc_chk
  150 +
  151 + def copy(self):
  152 + with self.lxc_started():
  153 + self._verify()
  154 + if not self.files_equal:
  155 + def work(dest):
  156 + infno = sys.stdin.fileno()
  157 + with open(dest, 'w') as outfile:
  158 + data = os.read(infno, self.buffer_size)
  159 + while (self.buffer_size == len(data)):
  160 + outfile.write(data)
  161 + data = os.read(infno, self.buffer_size)
  162 + outfile.write(data)
  163 +
  164 + lxc_read, lxc_write = os.pipe()
  165 +
  166 + pid = self.container.attach(work, self.dest, stdin=lxc_read)
  167 + os.close(lxc_read)
  168 +
  169 + with open(self.src, 'r') as infile:
  170 + data = infile.read(self.buffer_size)
  171 + while (self.buffer_size == len(data)):
  172 + os.write(lxc_write, data)
  173 + data = infile.read(self.buffer_size)
  174 + os.write(lxc_write, data)
  175 +
  176 + os.close(lxc_write)
  177 + os.waitpid(pid, 0)
  178 + self.changed = True
  179 +
  180 + def has_changed(self):
  181 + return self.changed
  182 +
  183 +
  184 +def main():
  185 + module = AnsibleModule(
  186 + argument_spec = dict(
  187 + name = dict(required=True, default=None),
  188 + src = dict(required=True, default=None),
  189 + dest = dict(required=True, default=None),
  190 + )
  191 + )
  192 +
  193 + manager = LxcManager(module)
  194 +
  195 + image_id = None
  196 + msg = ''
  197 + do_build = False
  198 +
  199 + manager.copy()
  200 +
  201 + module.exit_json(failed=False, changed=manager.has_changed(), msg="File copied")
  202 +
  203 +# import module snippets
  204 +from ansible.module_utils.basic import *
  205 +if __name__ == '__main__':
  206 + main()
  1 +---
  2 +- name: test playbook for lxc_copy
  3 + hosts: all
  4 + tasks:
  5 + - name: copy single file in container
  6 + lxc_copy:
  7 + args:
  8 + name: ansible_test
  9 + src: files/verkauf.jpg
  10 + dest: /tmp/foo
  11 +
  12 + - name: copy files in container
  13 + lxc_copy:
  14 + args:
  15 + name: ansible_test
  16 + src: files/{{ item }}
  17 + dest: /tmp/{{ item }}
  18 + with_items: ['a', 'b', 'c', 'd', 'e', 'f', 'g']
Please register or login to post a comment