Browse Source

Add vry basic README.md

master
Georg Hopp 10 years ago
commit
d370a51100
  1. 6
      .gitignore
  2. 12
      Makefile
  3. 26
      README.md
  4. 11
      ansible.cfg
  5. 71
      demo_userns.c
  6. BIN
      demo_userns.o
  7. 1
      hosts
  8. 171
      lxc-test.py
  9. 206
      lxc_copy.py
  10. 18
      playbook.yml

6
.gitignore

@ -0,0 +1,6 @@
# ignore vim swap files
.*.sw?
# ignore generated stuff
demo_userns
create_user_cgroup

12
Makefile

@ -0,0 +1,12 @@
PROGRAMS = demo_userns
demo_userns_OBJS = demo_userns.o
OBJECTS = $(demo_userns_OBJS)
CFLAGS = -O0 -ggdb -Wall -Werror
$(PROGRAMS): $(OBJECTS)
$(CC) $(LDFLAGS) -lcap -o $@ $($@_OBJS)
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<

26
README.md

@ -0,0 +1,26 @@
# LXC-Coding
Playground for user namespaces and other Linux Container stuff.
## Requirements
A proper kernel...
## License
> This program 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.
>
> This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
## Author
Georg Hopp <<georg@steffers.org>>

11
ansible.cfg

@ -0,0 +1,11 @@
[defaults]
inventory = hosts
host_key_checking = False
nocows=0
ansible_managed = Ansible managed: {file} on {host}
# # do redis facts caching
# gathering = smart
# fact_caching = redis
# fact_caching_timeout = 86400

71
demo_userns.c

@ -0,0 +1,71 @@
/*
* demo_userns.c
*
* Copyright 2013, Michael Kerrisk
* Licensed under GNU General Public License v2 or later
*
* Demonstrate the use of the clone() CLONE_NEWUSER flag.
*
* Link with "-lcap" and make sure that the "libcap-devel" (or
* similar) package is installed on the system.
*/
#define _GNU_SOURCE
#include <sys/capability.h>
#include <sys/wait.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
} while (0)
static int /* Startup function for cloned child */
childFunc(void *arg)
{
cap_t caps;
for (;;) {
printf("eUID = %ld; eGID = %ld; ",
(long) geteuid(), (long) getegid());
caps = cap_get_proc();
printf("capabilities: %s\n", cap_to_text(caps, NULL));
if (arg == NULL)
break;
sleep(5);
}
return 0;
}
#define STACK_SIZE (1024 * 1024)
static char child_stack[STACK_SIZE]; /* Space for child's stack */
int
main(int argc, char *argv[])
{
pid_t pid;
/* Create child; child commences execution in childFunc() */
pid = clone(childFunc, child_stack + STACK_SIZE, /* Assume stack
grows downward */
CLONE_NEWUSER | SIGCHLD, argv[1]);
if (pid == -1)
errExit("clone");
/* Parent falls through to here. Wait for child. */
if (waitpid(pid, NULL, 0) == -1)
errExit("waitpid");
exit(EXIT_SUCCESS);
}
// vim: ft=c cindent ts=4 sw=4 sts=4:

BIN
demo_userns.o

1
hosts

@ -0,0 +1 @@
localhost ansible_connection=local

171
lxc-test.py

@ -0,0 +1,171 @@
import lxc
import os
import sys
import hashlib
import json
import getpass
import subprocess
scriptpath = os.path.dirname(os.path.realpath(__file__))
def lxc_start(cont):
if (os.getuid() != 0):
uname = getpass.getuser()
subprocess.call([scriptpath + '/create_user_cgroup']);
for i in os.listdir('/sys/fs/cgroup'):
if (i == 'openrc'):
continue
with open('/sys/fs/cgroup/'+i+'/'+uname+'/tasks', 'a') as f:
f.write(str(os.getpid())+'\n');
cont.start();
def basic(cont):
def work(data):
print data
sys.stdout.flush()
sys.exit(0)
lxc_read, lxc_write = os.pipe()
cont.attach_wait(work, 'testtest', stdout=lxc_write)
os.close(lxc_write)
lxc_readfd = os.fdopen(lxc_read)
data = lxc_readfd.readline().rstrip('\n')
lxc_readfd.close()
print data
def basic2(cont):
def work(data):
print data
sys.stdout.flush()
sys.exit(0)
lxc_read, lxc_write = os.pipe()
cont.attach(work, 'testtest', stdout=lxc_write)
os.close(lxc_write)
lxc_readfd = os.fdopen(lxc_read)
data = lxc_readfd.readline().rstrip('\n')
lxc_readfd.close()
print data
def copy(cont, src, dest):
def work(dest):
infno = sys.stdin.fileno()
data = os.read(infno, 100)
print(data)
lxc_read, lxc_write = os.pipe()
pid = cont.attach(work, 'foo', stdin=lxc_read)
os.close(lxc_read)
os.write(lxc_write, 'fooooobadooooo')
os.close(lxc_write)
os.waitpid(pid, 0)
def copy2(cont, src, dest):
bufsize = 2048
def work(dest):
infno = sys.stdin.fileno()
with open(dest, 'w') as outfile:
data = os.read(infno, bufsize)
while (bufsize == len(data)):
outfile.write(data)
data = os.read(infno, bufsize)
outfile.write(data)
lxc_read, lxc_write = os.pipe()
pid = cont.attach(work, dest, stdin=lxc_read)
os.close(lxc_read)
with open(src, 'r') as infile:
data = infile.read(bufsize)
while (bufsize == len(data)):
os.write(lxc_write, data)
data = infile.read(bufsize)
os.write(lxc_write, data)
os.close(lxc_write)
os.waitpid(pid, 0)
def verify(cont, src, dest):
bufsize = 2048
def work(dest):
digest = ''
try:
chk = hashlib.sha1()
with open(dest, 'r') as dfile:
data = dfile.read(bufsize)
while(bufsize == len(data)):
chk.update(data)
data = dfile.read(bufsize)
chk.update(data)
digest = chk.hexdigest()
except:
pass
sys.stdout.write(digest)
sys.stdout.flush()
lxc_read, lxc_write = os.pipe()
pid = cont.attach(work, dest, stdout=lxc_write)
os.close(lxc_write)
chk = hashlib.sha1()
with open(src, 'r') as dfile:
data = dfile.read(bufsize)
while (bufsize == len(data)):
chk.update(data)
data = dfile.read(bufsize)
chk.update(data)
lxc_chk = os.read(lxc_read, 100)
os.close(lxc_read)
return json.dumps({
'equal': lxc_chk == chk.hexdigest(),
'local_sum': chk.hexdigest(),
'container_sum': lxc_chk})
cont = lxc.Container('ansible_test')
assert cont.defined
started = False
if not cont.running:
lxc_start(cont)
if not cont.wait('RUNNING', timeout=5):
raise EnvironmentError(0x01, '[lxc] unable to start container', cont)
started = True
#basic(cont)
#basic2(cont)
#copy(cont, 'verkauf.jpg', '/tmp/foo')
print __file__
print os.path.realpath(__file__)
print os.path.dirname(os.path.realpath(__file__))
vres = json.loads(verify(cont, 'verkauf.jpg', '/tmp/foo'))
if not vres['equal']:
print "copy file"
copy2(cont, 'verkauf.jpg', '/tmp/foo')
else:
print "files are equal"
if started:
cont.shutdown(5)

206
lxc_copy.py

@ -0,0 +1,206 @@
#!/usr/bin/python
#
# (c) 2014, Pavel Antonov <antonov@adwz.ru>
#
# This file is part of Ansible
#
# This module 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.
#
# This software 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 this software. If not, see <http://www.gnu.org/licenses/>.
######################################################################
DOCUMENTATION = '''
---
module: lxc_copy
author: Georg Hopp
version_added: "1.9"
short_description: copy files in an lxc
description:
- Very simple first start to copy files from host to lxc container
even in non privileged containers
options:
name:
description:
- Lxc container name to use
required: true
default: null
aliases: []
src:
description:
- Path to source file
required: true
default: null
aliases: []
dest:
description:
- Path to file in container
required: true
default: null
aliases: []
requirements: [ "lxc", "create_user_cgroup" ]
'''
EXAMPLES = '''
Copy a file from the host in the container:
- hosts: localhost
tasks:
- name: copy host file to container
lxc_copy:
name: ansible_test
src: nicefile
dest: /tmp/verynicefile
'''
try:
import lxc
import sys
import os
import json
import getpass
import hashlib
from contextlib import contextmanager
except ImportError, e:
print "failed=True msg='failed to import python module: %s'" % e
sys.exit(1)
class LxcManager:
@contextmanager
def lxc_started(self):
started = self.container.running
if not started and not self.container.running:
if (os.getuid() != 0):
uname = getpass.getuser()
subprocess.call(["create_user_cgroup"]);
for i in os.listdir('/sys/fs/cgroup'):
if (i == 'openrc'):
continue
with open('/sys/fs/cgroup/'+i+'/'+uname+'/tasks', 'a') as f:
f.write(str(os.getpid())+'\n');
self.container.start();
yield self
if not started and self.container.running:
self.container.shutdown(5)
def __init__(self, module):
self.module = module
self.name = self.module.params.get('name')
self.src = self.module.params.get('src')
self.dest = self.module.params.get('dest')
self.container = lxc.Container(self.name)
self.changed = False
self.log = []
self.error_msg = None
self.buffer_size = 20480
def get_log(self, as_string=True):
return "".join(self.log) if as_string else self.log
def _verify(self):
def work(dest):
digest = ''
try:
chk = hashlib.sha1()
with open(dest, 'r') as dfile:
data = dfile.read(self.buffer_size)
while(self.buffer_size == len(data)):
chk.update(data)
data = dfile.read(self.buffer_size)
chk.update(data)
digest = chk.hexdigest()
except:
pass
sys.stdout.write(digest)
sys.stdout.flush()
lxc_read, lxc_write = os.pipe()
pid = self.container.attach(work, self.dest, stdout=lxc_write)
os.close(lxc_write)
chk = hashlib.sha1()
with open(self.src, 'r') as dfile:
data = dfile.read(self.buffer_size)
while (self.buffer_size == len(data)):
chk.update(data)
data = dfile.read(self.buffer_size)
chk.update(data)
lxc_chk = os.read(lxc_read, 100) # read digest from container....
os.close(lxc_read)
self.files_equal = lxc_chk == chk.hexdigest()
self.local_sum = chk.hexdigest()
self.container_sum = lxc_chk
def copy(self):
with self.lxc_started():
self._verify()
if not self.files_equal:
def work(dest):
infno = sys.stdin.fileno()
with open(dest, 'w') as outfile:
data = os.read(infno, self.buffer_size)
while (self.buffer_size == len(data)):
outfile.write(data)
data = os.read(infno, self.buffer_size)
outfile.write(data)
lxc_read, lxc_write = os.pipe()
pid = self.container.attach(work, self.dest, stdin=lxc_read)
os.close(lxc_read)
with open(self.src, 'r') as infile:
data = infile.read(self.buffer_size)
while (self.buffer_size == len(data)):
os.write(lxc_write, data)
data = infile.read(self.buffer_size)
os.write(lxc_write, data)
os.close(lxc_write)
os.waitpid(pid, 0)
self.changed = True
def has_changed(self):
return self.changed
def main():
module = AnsibleModule(
argument_spec = dict(
name = dict(required=True, default=None),
src = dict(required=True, default=None),
dest = dict(required=True, default=None),
)
)
manager = LxcManager(module)
image_id = None
msg = ''
do_build = False
manager.copy()
module.exit_json(failed=False, changed=manager.has_changed(), msg="File copied")
# import module snippets
from ansible.module_utils.basic import *
if __name__ == '__main__':
main()

18
playbook.yml

@ -0,0 +1,18 @@
---
- name: test playbook for lxc_copy
hosts: all
tasks:
- name: copy single file in container
lxc_copy:
args:
name: ansible_test
src: files/verkauf.jpg
dest: /tmp/foo
- name: copy files in container
lxc_copy:
args:
name: ansible_test
src: files/{{ item }}
dest: /tmp/{{ item }}
with_items: ['a', 'b', 'c', 'd', 'e', 'f', 'g']
Loading…
Cancel
Save