Skip to content

pombredanne/plash

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

[ http://plash.io/ ] [ https://travis-ci.org/ihucos/plash ]

           ████                          ██       
           ████                          ██       
             ██                          ██       
 ██░███▒     ██       ▒████▓    ▒█████░  ██░████  
 ███████▒    ██       ██████▓  ████████  ███████▓ 
 ███  ███    ██       █▒  ▒██  ██▒  ░▒█  ███  ▒██ 
 ██░  ░██    ██        ▒█████  █████▓░   ██    ██ 
 ██    ██    ██      ░███████  ░██████▒  ██    ██ 
 ██░  ░██    ██      ██▓░  ██     ░▒▓██  ██    ██ 
 ███  ███    ██▒     ██▒  ███  █▒░  ▒██  ██    ██ 
 ███████▒    █████   ████████  ████████  ██    ██ 
 ██░███▒     ░████    ▓███░██  ░▓████▓   ██    ██ 
 ██                                               
 ██                                               
 ██                                               
   
containerized  Processes


###
# What is plash?
###

Plash is a tool to run, build and manage containers.

Unlike containers, plash instances are just chrooted, user-mapped processes
that interact naturally with the host operating system and each other. Plash
attempts to find the sweet spot between the isolation of containers and the
trivial resource availability of a process. An example:

user@devbox:~/myproject$ plash -f ubuntu --apt gitg
root@devbox:~/myproject# gitg


###
# Why plash?
###

* Secure
Plash instances are run as unprivileged users without any privileged daemons or
homemade setuid helpers. There is no setup step or sandboxing attempts with
elevated privileges. Therefore it is difficult to have privilege escalation
bugs since there is no code in plash that runs with escalated privileges at
all. The process starting a plash container and the plash container itself have
the same access rights. With plash you can leverage other existing tools and
facilities for additional security like simply creating and using additional
users.

* Lightweight
Plash is designed for quick command line usage and pick ups more lightweight
use cases like: I want to use gimp from Arch Linux now (`plash -R gimp --
gimp`) or needing something more advanced than a virtualenv but more
unobtrusive than Docker.

* Transparent
Plash "containers" are just processes. You can list them with `ps`, send
signals to them with `kill`, write AppArmor profiles or run them within another
container software and so on. Plash integrates well with the existing
ecosystem.


###
# Install
###

$ sudo sh -c 'curl -Lf https://github.com/ihucos/plash/archive/master.tar.gz | tar -xzC / --strip-components=1'

###
# Uninstall
###

$ sudo rm -rf /usr/local/bin/plash /usr/local/bin/plash-exec /opt/plash/


###
# Documentation
###

Reference documentation and tutorial: http://plash.io/

Examples:
- https://github.com/ihucos/plash-travis-example         Run plash in travis CI
- https://github.com/ihucos/plash-python-example/        Example of OS-Level isolation of python packages
- https://github.com/ihucos/plashmisc                    Custom build file commands (macros)
- https://git.io/fAdM0 and https://git.io/fAdMg          Run docker inside plash
- https://github.com/ihucos/noapt                        Use Ubuntu packages in other Linux distributions
- https://github.com/ihucos/megaman                      Use Arch Linux packages in other Linux distributions.
- https://github.com/ihucos/plash-plash                  Example of running plash in plash
- https://zpkg.plash.io/                                 A meta package manager


###
# Backwards Compatibility
###

One goal of plash is to have strong backwards compatibility. As the project
matures, less and less breaking changes will be introduced until a finished
state is reached. There never ever will be a "plash 2" or "plash 3".


###
# Plashfiles
###

Plashfiles are executable build files featuring a lightweight configuration
management language. There may be many use cases like packaging scripts or
bigger programs in a portable way. Here is an example:

$ cat ~/bin/gtk-hello-world
#!/usr/bin/env plash-exec
--from archlinux
--pacman gtk3 python-gobject
--layer
--entrypoint-script 
#!/usr/bin/env python
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
Gtk.init(None)
Hello = Gtk.MessageDialog(message_type=Gtk.MessageType.INFO,
                          buttons=Gtk.ButtonsType.OK,
                          text="Hello world!",
                          secondary_text="This is running inside a plash container.")
Hello.run()


###
# Some Recipes
###

# export an image to docker
$ plash export-tar --from alpine | docker import -

# run an image from docker
$ plash --from-docker busybox

# run plash inside docker
$ docker run --privileged --volume /var/lib/plash --volume /tmp -ti python bash
root@5750a18ea217:/# curl -Lf https://github.com/ihucos/plash/archive/master.tar.gz | tar -xzC / --strip-components=1
root@5750a18ea217:/# plash test
0_quickfail          PASS
basic-call-test      PASS
error-messages       PASS
macros/defpm         PASS
macros/eval-file     PASS
macros/eval-stdin    PASS
...

# run plash inside plash
$ plash -A python3 curl bash unionfs-fuse --layer -x 'curl -Lf https://github.com/ihucos/plash/archive/master.tar.gz | tar -xzC / --strip-components=1'
localhost:/home/resu# plash test
0_quickfail          PASS
...

# use an image from https://images.linuxcontainers.org 
$ plash --from-lxc archlinux
$ plash --from archlinux  # actually --from fallbacks to --from-lxc

# use an image from the web
$ plash --from-url http://example.com/rootfs.tar

# run a plash build file
$ plash --eval-file ./mybuildfile

# see how much space an image is taking
$ plash with-mount --from alpine -- du -sh

# delete an image
$ plash rm --from ubuntu

# Delete some older containers
$ plash shrink

# cleanup internal state (like tmp dirs)
$ plash clean

Check out the tutorial: http://plash.io/


###
# Requirements
###

Note: in this section the focus is on usability, not immaculate accuracy.

For unprivileged use:
  - linux Kernel >= 4.18
  - unionfs-fuse or fuse-overlayfs
  - optional newuidmap/newgidmap for setuid/setgid support
  - python3
  
Failsafe mode:
  - any Linux Kernel
  - root access
  - chroot system call
  - mount system call
  - overlay, unionfs-fuse or fuse-overlayfs
  - python3

  WARNING: The failsafe mode does not clean up mountpoints. It is designed to
  run inside another short lived container/machine/mount namespace. Enable with
  `export PLASH_NO_UNSHARE=1`

For privileged use:
  - all from failsafe mode
  - support for mount namespaces


###
# Environment variables
###

- PLASH_DATA
  Select a different directory for the build data. Default is "~/.plashdata"

- PLASH_DEBUG
  Raises exceptions instead of error messages.

- PLASH_EXPORT
  Tells plash which environment variables to export into containers. Separate
  multiple variables with ":".

- PLASH_INIT_UNION_TASTE
  Tells `plash init` which union filesystem to use for the build data. The
  default is "unionfs-fuse".

- PLASH_NO_UNSHARE
  The failsafe mode. It disables the attempt to create the mountpoints inside a
  fresh mount namespace. Setting this environment variable will pollute your
  current mount namespace. Only use this inside a throw-away mount namespace
  like another container.


###
# Choosing an union filesystem
###

By default, after you run `plash init`, the build directory will be configured
with the "unionfs-fuse" filesystem. If you want to use "overlay" instead, run
the following command: `echo overlay | plash data tee config/union_taste`

The difference is that "unionfs-fuse" is slower but more flexible. Overlay on
the other hand is faster but in most cases requires root access or an ubuntu
system. If you can, go with "overlay".

Note that "overlay" and "unionfs-fuse" may not be compatible to each other, so
you have to decide for one of them right after initializing a build directory.

Another fuse based filesystem is also supported: "fuse-overlayfs"


###
# setuid/setgid support
###

Plash will fallback to single user mapping if newuidmap/newgidmap is not
installed or subuids/subgids for the current user are not configured properly
in "/etc/subuid" and "/etc/subgid". Especially the apt package manager need
this configuration to work properly inside plash.


###
# Development Guidelines
###

- Keep the script character.
- Don't fall in love with the code, embrace its absence.
- All dependencies will get unmaintained at some point.
- Use honest thin wrappers, documented leaky abstractions are better then difficult promises.
- Don't be a monolith but don't try too hard not to be one.
- Don't complain or warn via stderr, do it or don't do it.
- Only be as smart as necessary and keep it simple and stupid (KISS).
- Still be able to run this in five years without any maintenance work.
- Define well what this project is and especially what it is not.
- Say no to features, say yes to solved use cases.
- Postpone compromises.
- Ditch everything that turns out too fiddly.
- Be as vanilla as you can be
- Be humble, don't oversell your abstraction layer.
- Sometimes the dirty solution is cleaner than the proper one.
- Don't differentiate root from non-root users (this is a TODO)
- Crude is better than complex.
- Only eat your own dog food if you are hungry.
- Work toward a timeless, finished product that will require no maintenance.
- The right guidelines for the right situation.


###
# Caveats
###

- Plash processes have the same operating system access rights than the process
  that started it. There is no security relevant isolation feature. Exactly as
  with running programs "normally", don't run programs you do not trust with
  plash and try to avoid using plash with the root user.

- Sometimes there are issues with apt-get failing that still need to be ironed
  out, sometimes it's due to an older kernel, sometimes due the lxc ubuntu
  build and I suppose it could also be related to unionfs-fuse in certain
  cases. Currently I don't see a single solution for this, this problems will
  have to be managed and fixed bit by bit. Other package managers seem to be
  more robust.

- Plash only runs inside Docker containers started with the `--privileged`
  flag, see GitHub issue #51 for details. 

- There is some bug in unionfs-fuse that impedes nested plash instances with
  unionfs: ihucos#69
  But fuse-overlayfs and overlay work fine.


###
# FAQ
###

* Can I contribute?
Please! Write me an mail mail@irae.me, open an issue, do a pull request or ask
me out for a friendly chat about plash in Berlin.

* Who are you?
A Django/Python software-developer. Since this is an open source project I hope
this software grows organically and collaboratively.

* Why write a containerization software?
Technical idealism. I wanted a better technical solution for a problem. In my
personal opinion Docker is revolutionary but has some shortcomings: awkward
interface, reinvention of established software or interfaces, bundling, vendor
lock in and overengineering. In a way it kills it's idea by trying too hard to
build a huge company on top of it. Plash thrives not to be more than a useful
tool with one task: Building and running containerized processes. Ultimately I
wanted something I can if necessary maintain by myself.

* Are there plans to commercialise this?
No, there isn't. At the same time I don't want to risk disappointing anyone and
am not making any absolute guarantees.

* What is the Licence?
plash is licensed under the MIT Licence.

* How does the code look?
Some python3, some C. Very little code, very maintainable.

* How does plash compare to Docker?
Docker is a bloated SUV you have to bring to the car workshop every week, for
random alterations, features and new advertising stickers. Plash is a nice
fixed gear bike, but the welds are still hot and nobody checked the bolts yet.

* Can I run this in production?
You can. It probably still has some warts, what I can guarantee is to
enthusiastically support this software and all issues that may come with it and
focus on backward compatibility.

* Is plash secure?
Plash does not use any daemons or have its own setuid helper binaries. Note
that plash does not try to isolate containers (which are just normal
processes). That means that running a program inside plash is not a security
feature. Running any container software introduces more entities to trust, that
is the root file system image with its additional linux distribution and its
own package manager. Using a program from alpine edge could be considered less
secure than a package from debian stable or vice versa. Also note that keeping
containers updated is more difficult than keeping "normal" system software
updated. Furthermore note that programs could be not used to run inside
semi-isolated containers and behave oddly. Plash uses unmodified lxc images and
checks their signatures with gpgv (if in PATH). Using plash as root should be
avoided and should not be necessary for most use cases.  Until now plash was
written by one person and of course I could be wrong about something. But
generally speaking it really should be good enough.

* Why the unusual project structure?
Source code and packaged directory structure is the same to reduce complexity.

About

Run, build and manage containers

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Python 50.6%
  • Shell 22.8%
  • C 20.2%
  • HTML 6.0%
  • Makefile 0.4%