{ "info": { "author": "", "author_email": "", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3", "Topic :: System" ], "description": "Furnace\n=======\n\nA lightweight pure-python container implementation.\n\nIt is a wrapper around the Linux namespace functionality through libc\nfunctions like ``unshare()``, ``nsenter()`` and ``mount()``. You can\nthink of it as a sturdier chroot replacement, where cleanup is easy (no\nlingering processes or leaked mountpoints). It needs superuser\nprivileges to run.\n\nUsage\n-----\n\nInstallation\n~~~~~~~~~~~~\n\nYou can either install it with pip:\n\n::\n\n pip3 install furnace\n\nOr if you want, the following commands will install the bleeding-edge\nversion of furnace to your system.\n\n::\n\n git clone https://github.com/balabit/furnace.git\n cd furnace\n python3 setup.py install\n\nThis will of course install it into a virtualenv, if you activate it\nbeforehand.\n\nDependencies\n~~~~~~~~~~~~\n\nThe only dependencies are:\n\n- Python3.5+\n- Linux kernel 2.6.24+\n- A libc that implements setns() and nsenter() (that\u2019s basically any\n libc released after 2007)\n\nExample\n~~~~~~~\n\nAfter installing, the main interface to use is the ``ContainerContext``\nclass. It is, as the name suggests, a context manager, and after\nentering, its ``run()`` and ``Popen()`` methods can be used exactly like\n``subprocess``\\ \u2019s similarly named methods:\n\n.. code:: python\n\n from furnace.context import ContainerContext\n\n with ContainerContext('/opt/ChrootMcChrootface') as container:\n container.run(['ps', 'aux'])\n\nThe above example will run ``ps`` in the new namespace. It should show\ntwo processes, furnace\u2019s PID1, and the ``ps`` process itself. After\nleaving the context, furnace will kill all processes started inside, and\ndestroy the namespaces created, including any mountpoints that were\nmounted inside (e.g. with ``container.run(['mount', '...'])``).\n\nOf course, all other arguments of ``run()`` and ``Popen()`` are\nsupported:\n\n.. code:: python\n\n import sys\n import subprocess\n from furnace.context import ContainerContext\n\n with ContainerContext('/opt/ChrootMcChrootface') as container:\n ls_result = container.run(['ls', '/bin'], env={'LISTFLAGS': '-la'}, stdout=subprocess.PIPE, check=True)\n print('Files:')\n print(ls_result.stdout.decode('utf-8'))\n\n file_outside_container = open('the_magic_of_file_descriptors.gz', 'wb')\n process_1 = container.Popen(['cat', '/etc/passwd'], stdout=subprocess.PIPE)\n process_2 = container.Popen(['gzip'], stdin=process_1.stdout, stdout=file_outside_container)\n process_2.communicate()\n process_1.wait()\n\nAs you can see, the processes started can inherit file descriptors from\neach other, or outside the container, and can also be managed from the\npython code outside the container, if you wish.\n\nAs a convenience feature, the context has an ``interactive_shell()``\nmethod that takes you into bash shell inside the container. This is\nmostly useful for debugging:\n\n.. code:: python\n\n import traceback\n from furnace.context import ContainerContext\n\n with ContainerContext('/opt/ChrootMcChrootface') as container:\n try:\n container.run(['systemctl', '--enable', 'nginx.service'])\n except Exception as e:\n print(\"OOOPS, an exception occured:\")\n traceback.print_exc(file=sys.stdout)\n print(\"Entering debug shell\")\n container.interactive_shell()\n raise\n\nDevelopment\n-----------\n\nContributing\n~~~~~~~~~~~~\n\nWe appreciate any feedback, so if you have problems, or even\nsuggestions, don\u2019t hesitate to open an issue. Of course, Pull Requests\nare extra-welcome, as long as tests pass, and the code is not much worse\nthan all other existing code :)\n\nSetting up a development environment\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nTo set up a virtualenv with all the necessary tools for development,\nsimply run\n\n::\n\n make dev\n\nThis will create a virtualenv in a directory named .venv. This\nvirtualenv is used it for all other make targets, like ``check``\n\nRunning tests\n~~~~~~~~~~~~~\n\nDuring and after development, you usually want to run both coding style\nchecks, and integration tests:\n\n::\n\n make lint\n make check\n\nPlease make sure at least these pass before submitting a PR.\n\nLicense\n-------\n\nThis project is licensed under the GNU LGPLv2.1 License - see the\n`LICENSE.txt`_ for details\n\n.. _LICENSE.txt: LICENSE.txt\n\n\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/balabit/furnace", "keywords": "containers containerization", "license": "", "maintainer": "", "maintainer_email": "", "name": "furnace", "package_url": "https://pypi.org/project/furnace/", "platform": "", "project_url": "https://pypi.org/project/furnace/", "project_urls": { "Homepage": "https://github.com/balabit/furnace" }, "release_url": "https://pypi.org/project/furnace/0.0.5/", "requires_dist": [ "autopep8 (==1.3.3) ; extra == 'dev'", "flake8 (==3.5.0) ; extra == 'dev'", "pep8 (==1.7.1) ; extra == 'dev'", "pytest-cov (==2.5.1) ; extra == 'dev'", "pytest (==3.2.3) ; extra == 'dev'" ], "requires_python": ">=3.5", "summary": "A lightweight pure-python container implementation", "version": "0.0.5" }, "last_serial": 5272530, "releases": { "0.0.2": [ { "comment_text": "", "digests": { "md5": "a4ba331dc44d597d4a923de69ec4ab88", "sha256": "4b70ae33fba9d4bc999ac2c2bfb0cdc8d495f78d09e77ba23481e6a551b005b9" }, "downloads": -1, "filename": "furnace-0.0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "a4ba331dc44d597d4a923de69ec4ab88", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 16559, "upload_time": "2017-12-21T16:06:11", "url": "https://files.pythonhosted.org/packages/3d/8f/a72750402b6113cdc8255f892d271523b0f14925b1205cd8de40056978b3/furnace-0.0.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "260b4edf2ebbede05ce72dcdeed51f34", "sha256": "2b468b32b7df302537242fe3ed11c17784e0421675c8b77a1b9740f4f606a22f" }, "downloads": -1, "filename": "furnace-0.0.2.tar.gz", "has_sig": false, "md5_digest": "260b4edf2ebbede05ce72dcdeed51f34", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 22402, "upload_time": "2017-12-21T16:06:12", "url": "https://files.pythonhosted.org/packages/7c/1d/335f4668529c4f89f965008ce095ddbede0e8268f5e3ea60e3bbd8d1bc07/furnace-0.0.2.tar.gz" } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "6cc7f333f043d1e81845f6708c8ad9af", "sha256": "be418d8c2b3ea2b25f1ab74926b0c5fc0614575bb75e7eee2028dbc6996af6a3" }, "downloads": -1, "filename": "furnace-0.0.3-py3-none-any.whl", "has_sig": false, "md5_digest": "6cc7f333f043d1e81845f6708c8ad9af", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 23100, "upload_time": "2019-01-03T12:16:16", "url": "https://files.pythonhosted.org/packages/00/99/44fec60b294d133936850caf546bfae04b53effa72e106232cb09c592a7b/furnace-0.0.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "00687608ba9088e14e5ee19472c76e7f", "sha256": "06c81f71de735f33900dce21b7902bdc5e3eb9d065e877fbdc33864a6d8970c4" }, "downloads": -1, "filename": "furnace-0.0.3.tar.gz", "has_sig": false, "md5_digest": "00687608ba9088e14e5ee19472c76e7f", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 22576, "upload_time": "2019-01-03T12:16:18", "url": "https://files.pythonhosted.org/packages/e4/90/d26a15d528be0697b0622befe16b82ced8e729f73cd85e53112b55ce5282/furnace-0.0.3.tar.gz" } ], "0.0.4": [ { "comment_text": "", "digests": { "md5": "fbb1740f60bc12185feb7b508eea7880", "sha256": "d1f8eb42856b55b56ed874bccb8449065ac815a45003db80d5789893de1f4e89" }, "downloads": -1, "filename": "furnace-0.0.4-py3-none-any.whl", "has_sig": false, "md5_digest": "fbb1740f60bc12185feb7b508eea7880", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 23292, "upload_time": "2019-01-07T09:49:49", "url": "https://files.pythonhosted.org/packages/2a/55/a5e42b4837dee5a658ac6538bb10a8499eb1795e71bbf801ed45363a4b82/furnace-0.0.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "1ffc8c8ff09448647413208aaf55b9a9", "sha256": "15b66421762e3b3706b8b445c9c6e6760d0fa3fafa58eb3f076c591cc2a5a717" }, "downloads": -1, "filename": "furnace-0.0.4.tar.gz", "has_sig": false, "md5_digest": "1ffc8c8ff09448647413208aaf55b9a9", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 23154, "upload_time": "2019-01-07T09:49:51", "url": "https://files.pythonhosted.org/packages/b4/ff/f3e8435085c78ef7ac1158f20a5380ff300b4562d004d6c9acbc35096b72/furnace-0.0.4.tar.gz" } ], "0.0.5": [ { "comment_text": "", "digests": { "md5": "a44bebb479fb7d63722572738fbcd413", "sha256": "40e8e4974e2064a2cf0453a6eb60f38560e9c61db319d03219c9daf6fb65512d" }, "downloads": -1, "filename": "furnace-0.0.5-py3-none-any.whl", "has_sig": false, "md5_digest": "a44bebb479fb7d63722572738fbcd413", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 23430, "upload_time": "2019-05-15T13:26:21", "url": "https://files.pythonhosted.org/packages/45/0e/bb1ac7e7cd172c17abccbfc53bb38f5bb33701790ba27d2ddadf838faf54/furnace-0.0.5-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "61ac8592b5975255af11ad41432ba20a", "sha256": "fcf1c2bed1d04bf665bbd95045c5c2baebf8f9871805203bf8210ad69ca79370" }, "downloads": -1, "filename": "furnace-0.0.5.tar.gz", "has_sig": false, "md5_digest": "61ac8592b5975255af11ad41432ba20a", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 23293, "upload_time": "2019-05-15T13:26:23", "url": "https://files.pythonhosted.org/packages/96/47/0ce1a4e17d43487701ea023deb6f1af2b156bb55b4ecab12f28297b0d79d/furnace-0.0.5.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "a44bebb479fb7d63722572738fbcd413", "sha256": "40e8e4974e2064a2cf0453a6eb60f38560e9c61db319d03219c9daf6fb65512d" }, "downloads": -1, "filename": "furnace-0.0.5-py3-none-any.whl", "has_sig": false, "md5_digest": "a44bebb479fb7d63722572738fbcd413", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 23430, "upload_time": "2019-05-15T13:26:21", "url": "https://files.pythonhosted.org/packages/45/0e/bb1ac7e7cd172c17abccbfc53bb38f5bb33701790ba27d2ddadf838faf54/furnace-0.0.5-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "61ac8592b5975255af11ad41432ba20a", "sha256": "fcf1c2bed1d04bf665bbd95045c5c2baebf8f9871805203bf8210ad69ca79370" }, "downloads": -1, "filename": "furnace-0.0.5.tar.gz", "has_sig": false, "md5_digest": "61ac8592b5975255af11ad41432ba20a", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 23293, "upload_time": "2019-05-15T13:26:23", "url": "https://files.pythonhosted.org/packages/96/47/0ce1a4e17d43487701ea023deb6f1af2b156bb55b4ecab12f28297b0d79d/furnace-0.0.5.tar.gz" } ] }