http://habrahabr.ru/post/256647/
Hello, {{username}}
Я DevOps и очень люблю Linux. Понятное дело, что с такой связкой я просто не мог не полюбить LinuX Containers (тем более, что BSD и Solaris давно радуют аналогичными возможностями своих пользователей).
Естественно, бизнес тоже увидел привлекательную возможность и программы для управления контейнерами стали расти и множиться:
docker ,
rocket,
vagga,
lxc,
systemd-nspawn, etc…
Docker стал стандартом де-факто в первую очередь благодаря системе создания и доставки контента. Но главный демон докера запускается от root, и, на мой взгляд, это минус этого проекта (
Пруф).
Rocket и vagga пошли другим путем, и путь этот носит название unprivileged containers. Вам больше не нужны root привилегии, чтобы запустить процесс в новых namespaces, и это открывает интересные перспективы для построения тестовых площадок и безопасного окружения.
Но во всех этих проектах есть один фатальный недостаток: они все написаны с использованием c, go и rust, а я люблю python и не могу поучаствовать в их разработке. Согласитесь, довольно обидно пропускать все веселье.
Так что под катом вас ждет библиотека для запуска процессов в новых
linux user namespaces:
Детка, Ты просто космосGoals
Сейчас нет удобного способа работать с linux namespaces из python:
- можно использовать asylum — проект выглядит мертвым и хостится непонятно где
- или можно попробовать python-libvirt биндинги с большим уровнем абстракции
- использовать код на c, как это делают vagga и lxc
- или дергать glibc вызовы с помощью ctypes
- в противном случае остается subprocess.Popen
Я хочу изменить это: я хочу создать native python bindings к билбиотеке glibc с интерфейсом как в multiprocessing.Process. И еще немножко целей:
- популяризировать linux
- популяризировать python
- поучаствовать в создании популярного open source проекта
- прославиться
- популярность и девушки будут приятным бонусом
ЗЫ: так же посмотрите на
python-nsenter — выглядит здорово!
Example
import os
from pyspaces import Container
def execute(argv):
os.execvp(argv[0], argv)
cmd = "mount -t proc proc /proc; ps ax"
c = Container(target=execute, args=(('bash', '-c', cmd),),
uid_map='0 1000 1',
newpid=True, newuser=True, newns=True
)
c.start()
print("PID of child created by clone() is %ld\n" % c.pid)
c.join()
print("Child returned: pid %s, status %s" % (c.pid, c.exitcode))
PID of child created by clone() is 15978
PID TTY STAT TIME COMMAND
1 pts/19 S+ 0:00 bash -c mount -t proc proc /proc; ps ax
3 pts/19 R+ 0:00 ps ax
Child returned: pid 15978, status 0
CLI
space -v execute --pid --fs --user --uid '0 1000 1' bash -c 'mount -t proc /proc; ps ax'
space chroot --pid --uid '0 1000 1' ~/.local/share/lxc/ubuntu/rootfs/ /bin/ls /home/
TODO
- [x] clone & Container
- [x] CLI
- [x] Chroot
- [ ] process list
- [ ] inject
- [ ] move CLI to separate package
- [ ] addons
- [ ] support for lxc, vagga, rocket, docker, etc...
- [ ] ...
- [ ] one tool for rule them all!!1
Links
Лицензия — MIT, но так же собираюсь добавить BSD и Apache 2.0
It's not the end
Работы предстоит очень много: нужны нормальные тесты, документация, новые фичи и приятное cli. Откладывание анонса в долгий ящик прервали ребята из
Minsk Python Meetup, за что им большое спасибо. Теперь я надеюсь на поддержку и интерес у сообщества ;)
И в завершение хотелось бы привести цитату создателя scipy & numpy:
Keys to success: Hard work — specially up front
Often lonely — initially nobody believes in your idea more than you do. Others need some 'proof' before they join you.
The more complicated what you are doing is the lonelier it will be initially.
I spent 18 months not publishing papers to write NumPy
(despite many people telling me it was foolish)
Travis Oliphant
ЗЫ: в живую со мной можно пообщаться по теме и не только на очередном
Minsk Python Meetup