summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Brandt <alunduil@gentoo.org>2014-10-27 15:25:59 +0000
committerAlex Brandt <alunduil@gentoo.org>2014-10-27 15:25:59 +0000
commit8fbfceb2b3a0a1579adcddfecda04af53a89b687 (patch)
treedc71ad3c88b9d2cf4a809f3ded315d44191cc4b6 /app-emulation
parentRevision bump: EAPI=5; Add sub-slot for perl dependency (diff)
downloadhistorical-8fbfceb2b3a0a1579adcddfecda04af53a89b687.tar.gz
historical-8fbfceb2b3a0a1579adcddfecda04af53a89b687.tar.bz2
historical-8fbfceb2b3a0a1579adcddfecda04af53a89b687.zip
add ebuild for fig
Package-Manager: portage-2.2.14/cvs/Linux x86_64 Manifest-Sign-Key: 0x11A8217C!
Diffstat (limited to 'app-emulation')
-rw-r--r--app-emulation/fig/ChangeLog11
-rw-r--r--app-emulation/fig/Manifest27
-rw-r--r--app-emulation/fig/fig-0.5.2.ebuild60
-rw-r--r--app-emulation/fig/fig-1.0.0.ebuild57
-rw-r--r--app-emulation/fig/files/1.0.0-unvendorize-dockerpty.patch790
-rw-r--r--app-emulation/fig/metadata.xml10
6 files changed, 955 insertions, 0 deletions
diff --git a/app-emulation/fig/ChangeLog b/app-emulation/fig/ChangeLog
new file mode 100644
index 000000000000..cc8fe77c0dd8
--- /dev/null
+++ b/app-emulation/fig/ChangeLog
@@ -0,0 +1,11 @@
+# ChangeLog for app-emulation/fig
+# Copyright 1999-2014 Gentoo Foundation; Distributed under the GPL v2
+# $Header: /var/cvsroot/gentoo-x86/app-emulation/fig/ChangeLog,v 1.1 2014/10/27 15:25:51 alunduil Exp $
+
+*fig-1.0.0 (27 Oct 2014)
+*fig-0.5.2 (27 Oct 2014)
+
+ 27 Oct 2014; Alex Brandt <alunduil@gentoo.org> +fig-0.5.2.ebuild,
+ +fig-1.0.0.ebuild, +files/1.0.0-unvendorize-dockerpty.patch, +metadata.xml:
+ add ebuild written by me
+
diff --git a/app-emulation/fig/Manifest b/app-emulation/fig/Manifest
new file mode 100644
index 000000000000..0677c5142366
--- /dev/null
+++ b/app-emulation/fig/Manifest
@@ -0,0 +1,27 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA256
+
+AUX 1.0.0-unvendorize-dockerpty.patch 22719 SHA256 e8e3edc01737fa4ed9e9063cdd384d4560727f292be16cabb834afe8ea663c60 SHA512 0fe684dc090ba717114cca6d7dc4c0735229562c64a3736a21c2c96d82dfdf498358c758f38489fabe6332b493fdb1f35d4543ba680622319b1086d0167bf665 WHIRLPOOL 32a302a86b435537ffa3b619027f560b534986e4ec846758aabc22a5cfb8cfd46c14deb6383a536951fb206c2a66df4105db34e4a73ecc55badc5fabbdc096c6
+DIST fig-0.5.2.tar.gz 213700 SHA256 02097d15d30cf6b3996a8982bcc0bec76377a42e8fc03191d33471c6f97ac835 SHA512 15bea312d2bfed765c32d98a8bd9cd8faf305467e135ca9fe73136cce4d0dfd1d585bc90bc67afe4f49acc0674f933dea851edea989315ea23d8528b4c3b2097 WHIRLPOOL 722a49d8b96156fe9c4121925355bd8e153fc5419d5aa315c1e7edb4bf1b444d1ffcb9e611f2bf7c199c72513f477065bc4dbcd245d67d0c8808ac3e7c2a60e8
+DIST fig-1.0.0.tar.gz 211497 SHA256 3ac21ce253e3ad791fb35d2b5cb83a530d9b16830a02e71587533664796b261a SHA512 82ca0e5932ce67057dec4fd30f334ff3029c04804ef2fc01bc86076f04cc3fdeee6675ff9a06f03a9e4ef7da18fce949ccb4c24ddba707f7419bbbd165166b31 WHIRLPOOL 43d90efcc24d836116cb3e473b4a50ef67cfaf422746dff6a0f7b2e1efb759d38401131d03d0a59a98326b23955e0187f4aca94f8fa9decac4dc045bfac86b0e
+EBUILD fig-0.5.2.ebuild 1509 SHA256 fc5c5eafee8764ffd10ec9297e3fb363e4afeca34c178155d72491a36d27f2ed SHA512 4ebb9d9f5b743182693b324dbe94e533018b2a53fe07e8ca1823dbfbc5451f418a150be3985d57b08eee0248f2b5ca7d955bc6d85b08585cd0b75b7b269d25db WHIRLPOOL 4473cea7eab7a203ac3a61890461c203cb229863402be31f9719c2513cc3305b3d176c5dc27fec6edaa5f463435de876861b88bfde1c0138879cf29c67ba7d33
+EBUILD fig-1.0.0.ebuild 1750 SHA256 6ad4ac2b14ea68732c08ba326874afe69f6a7e69bbb2ac584ed2faacdda4ea53 SHA512 2c51e5d8ea83bc4eaed7029a067b7a003be16b383a439309696012ee2d21132ffa7a4fcd13995f14e91fec7e1755e4991230e074696cb60acd318fcf8a2c6406 WHIRLPOOL 118aa70a63a4ad6789e58c201475afd0b6b28e8f5965c503f347f0c235779ab1f6d6d2a84e611ed8f699a31a4b152251ca758fee885ef035299ba3e68e30ad30
+MISC ChangeLog 434 SHA256 cfb8c025b7ad57d849d06c1fc218866ee54fb7552db9e103b7c0ec2d99c13ae3 SHA512 af4464bd1253d9bf365211d3e33b9cbe02bed251b5a402a9f345e8d621d9b72cc2ca59098a81cb7fc5ce4ef649b638cb8dfa1b0f2b1e93442e4f3b0c26cc9e45 WHIRLPOOL 3dde494ec8df31fa976fdacd2b177cad1429f236376eb49b375ca7d93a4f87ac24109dd3bce4bc1c9c29a83f1f84e3534101956da86eb0958354994fb84cf7e9
+MISC metadata.xml 281 SHA256 4f517e212ebf30022599267011b7d752fb61f1063c90f9d442242fba23e5207f SHA512 c4d7e9c37508015a286fc8288d3c201c5779aca1252bc6ed7f25ce87555b513817d4e3fa624255e7644b24e4db0e1b976ea34810ece8f718dac3b027a3e601ba WHIRLPOOL d144bd0785d423f05e5ff568d7c7c5b6f4aa6d651d44ec9f55dce23aafc6552d0d39f8229a612109665cfb3e839ff746e64c0cb0130fe93e9f231238c61a87ba
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v2
+
+iQIcBAEBCAAGBQJUTmQAAAoJECZUyt4RqCF8uCMQALaGvJv5iKh1uZfbHnEVJqNR
+YrlO8FbU+BaCxiirgETJnfofgjNyqb03fM/4/q64x+vsx13D0tbeDimH/L2EepGs
+CgvuWiGcXIFzf0uqXP3QhXuoeieHwsDootwgwRUiAjHjrTo+RAjL+QPl95pmHjZ0
+DXXeyH9MFarorplrCXv+vXJVqqOMVpV85s2DLQ59RlFziPk7lb+/SpZaHUayMvZk
+dSxdx5qs5naDYkRYBDfegN8EuznEubGyRWMyO8vrAy/owJrFiC/5w6P+I1OIJhlM
+kmjpTGhLW0vCYS5e9NG7Yyw21RknSW+a8O3XQW4pNRMLMYw2dZsFwgg1TFwldJql
+8Pmrb2bx06IafV9QfrGjiDcDuRigpTnYAVYqQqm/oEzsfnnqm5b+I1p0K4MBM8+C
+UgyoMQFk6CWiFuJuzQjxD6g3TMd04wRwgWi9LnUEj8dDoDOFJQ3AHKqE5aNuDEqh
+aFnteJTmHYmSjOGQ8lRi9rUmtjifbqAd6ju9SPeVSWiJn8cFw5/q1lvN66ASX99U
+c23qpMCtUaE08Tyt9YgPtc6Z+EQQkiPg+Yn6FZTsZeCvTvhrdlRCG2YbDbVVKWqW
+J4W1phaAkGfNrH3ds58dunbrSQY/UnUG2avcdkAkWVPSiPYDySxnqnlc0m7UOWRh
+wcfhHFpkjSuDR/GQGo8+
+=e0fZ
+-----END PGP SIGNATURE-----
diff --git a/app-emulation/fig/fig-0.5.2.ebuild b/app-emulation/fig/fig-0.5.2.ebuild
new file mode 100644
index 000000000000..1e4f1838f734
--- /dev/null
+++ b/app-emulation/fig/fig-0.5.2.ebuild
@@ -0,0 +1,60 @@
+# Copyright 1999-2014 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-x86/app-emulation/fig/fig-0.5.2.ebuild,v 1.1 2014/10/27 15:25:51 alunduil Exp $
+
+EAPI=5
+PYTHON_COMPAT=( python2_7 )
+
+inherit distutils-r1 vcs-snapshot
+
+DESCRIPTION="Punctual, lightweight development environments using Docker"
+HOMEPAGE="http://www.fig.sh/"
+SRC_URI="https://github.com/docker/${PN}/archive/${PV}.tar.gz -> ${P}.tar.gz"
+
+LICENSE="Apache-2.0"
+SLOT="0"
+KEYWORDS="~amd64"
+IUSE="test"
+
+CDEPEND="
+ >=dev-python/dockerpty-0.2.3[${PYTHON_USEDEP}]
+ ~dev-python/docopt-0.6.1[${PYTHON_USEDEP}]
+ ~dev-python/pyyaml-3.10[${PYTHON_USEDEP}]
+ >=dev-python/requests-2.2.1[${PYTHON_USEDEP}]
+ ~dev-python/texttable-0.8.1[${PYTHON_USEDEP}]
+ ~dev-python/websocket-client-0.11.0[${PYTHON_USEDEP}]
+"
+DEPEND="
+ dev-python/setuptools[${PYTHON_USEDEP}]
+ test? (
+ ${CDEPEND}
+ ~dev-python/mock-1.0.1[${PYTHON_USEDEP}]
+ ~dev-python/nose-1.3.0[${PYTHON_USEDEP}]
+ dev-python/unittest2[${PYTHON_USEDEP}]
+ )
+"
+RDEPEND="${CDEPEND}"
+
+python_prepare_all() {
+ ebegin 'patching setup.py'
+ sed \
+ -e 's/packages=find_packages(/&exclude=["tests.*", "tests"]/' \
+ -i setup.py
+ STATUS=$?
+ eend ${STATUS}
+ [[ ${STATUS} -gt 0 ]] && die
+
+ ebegin 'patching requirements.txt'
+ sed \
+ -e '3s/==/>=/' \
+ -i requirements.txt
+ STATUS=$?
+ eend ${STATUS}
+ [[ ${STATUS} -gt 0 ]] && die
+
+ distutils-r1_python_prepare_all
+}
+
+python_test() {
+ nosetests tests/unit || die "Tests failed under ${EPYTHON}"
+}
diff --git a/app-emulation/fig/fig-1.0.0.ebuild b/app-emulation/fig/fig-1.0.0.ebuild
new file mode 100644
index 000000000000..667056872661
--- /dev/null
+++ b/app-emulation/fig/fig-1.0.0.ebuild
@@ -0,0 +1,57 @@
+# Copyright 1999-2014 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-x86/app-emulation/fig/fig-1.0.0.ebuild,v 1.1 2014/10/27 15:25:51 alunduil Exp $
+
+EAPI=5
+PYTHON_COMPAT=( python2_7 )
+
+inherit distutils-r1 vcs-snapshot
+
+DESCRIPTION="Punctual, lightweight development environments using Docker"
+HOMEPAGE="http://www.fig.sh/"
+SRC_URI="https://github.com/docker/${PN}/archive/${PV}.tar.gz -> ${P}.tar.gz"
+
+LICENSE="Apache-2.0"
+SLOT="0"
+KEYWORDS="~amd64"
+IUSE="test"
+
+CDEPEND="
+ >=dev-python/dockerpty-0.2.4[${PYTHON_USEDEP}]
+ >=dev-python/docker-py-0.5[${PYTHON_USEDEP}]
+ <dev-python/docker-py-0.6[${PYTHON_USEDEP}]
+ >=dev-python/docopt-0.6.1[${PYTHON_USEDEP}]
+ <dev-python/docopt-0.7[${PYTHON_USEDEP}]
+ >=dev-python/pyyaml-3.10[${PYTHON_USEDEP}]
+ <dev-python/pyyaml-4[${PYTHON_USEDEP}]
+ >=dev-python/requests-2.2.1[${PYTHON_USEDEP}]
+ <dev-python/requests-3[${PYTHON_USEDEP}]
+ >=dev-python/six-1.3.0[${PYTHON_USEDEP}]
+ <dev-python/six-2[${PYTHON_USEDEP}]
+ >=dev-python/texttable-0.8.1[${PYTHON_USEDEP}]
+ <dev-python/texttable-0.9[${PYTHON_USEDEP}]
+ >=dev-python/websocket-client-0.11.0[${PYTHON_USEDEP}]
+ <dev-python/websocket-client-0.12[${PYTHON_USEDEP}]
+"
+DEPEND="
+ dev-python/setuptools[${PYTHON_USEDEP}]
+ test? (
+ ${CDEPEND}
+ >=dev-python/mock-1.0.1[${PYTHON_USEDEP}]
+ dev-python/nose[${PYTHON_USEDEP}]
+ $(python_gen_cond_dep 'dev-python/unittest2[${PYTHON_USEDEP}]' 'python2*')
+ )
+"
+RDEPEND="${CDEPEND}"
+
+python_prepare_all() {
+ # Note: patch is 22KiB but should be removed next release.
+ local PATCHES=(
+ "${FILESDIR}"/1.0.0-unvendorize-dockerpty.patch
+ )
+ distutils-r1_python_prepare_all
+}
+
+python_test() {
+ nosetests tests/unit || die "Tests failed under ${EPYTHON}"
+}
diff --git a/app-emulation/fig/files/1.0.0-unvendorize-dockerpty.patch b/app-emulation/fig/files/1.0.0-unvendorize-dockerpty.patch
new file mode 100644
index 000000000000..9b69d3fbf787
--- /dev/null
+++ b/app-emulation/fig/files/1.0.0-unvendorize-dockerpty.patch
@@ -0,0 +1,790 @@
+diff --git a/fig/cli/main.py b/fig/cli/main.py
+index 9a47771..98a1624 100644
+--- a/fig/cli/main.py
++++ b/fig/cli/main.py
+@@ -7,7 +7,7 @@ import signal
+ from operator import attrgetter
+
+ from inspect import getdoc
+-from fig.packages import dockerpty
++import dockerpty
+
+ from .. import __version__
+ from ..project import NoSuchService, ConfigurationError
+diff --git a/fig/packages/__init__.py b/fig/packages/__init__.py
+deleted file mode 100644
+index e69de29..0000000
+diff --git a/fig/packages/dockerpty/__init__.py b/fig/packages/dockerpty/__init__.py
+deleted file mode 100644
+index a5d707a..0000000
+--- a/fig/packages/dockerpty/__init__.py
++++ /dev/null
+@@ -1,27 +0,0 @@
+-# dockerpty.
+-#
+-# Copyright 2014 Chris Corbyn <chris@w3style.co.uk>
+-#
+-# Licensed under the Apache License, Version 2.0 (the "License");
+-# you may not use this file except in compliance with the License.
+-# You may obtain a copy of the License at
+-#
+-# http://www.apache.org/licenses/LICENSE-2.0
+-#
+-# Unless required by applicable law or agreed to in writing, software
+-# distributed under the License is distributed on an "AS IS" BASIS,
+-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-# See the License for the specific language governing permissions and
+-# limitations under the License.
+-
+-from .pty import PseudoTerminal
+-
+-
+-def start(client, container):
+- """
+- Present the PTY of the container inside the current process.
+-
+- This is just a wrapper for PseudoTerminal(client, container).start()
+- """
+-
+- PseudoTerminal(client, container).start()
+diff --git a/fig/packages/dockerpty/io.py b/fig/packages/dockerpty/io.py
+deleted file mode 100644
+index c31c540..0000000
+--- a/fig/packages/dockerpty/io.py
++++ /dev/null
+@@ -1,294 +0,0 @@
+-# dockerpty: io.py
+-#
+-# Copyright 2014 Chris Corbyn <chris@w3style.co.uk>
+-#
+-# Licensed under the Apache License, Version 2.0 (the "License");
+-# you may not use this file except in compliance with the License.
+-# You may obtain a copy of the License at
+-#
+-# http://www.apache.org/licenses/LICENSE-2.0
+-#
+-# Unless required by applicable law or agreed to in writing, software
+-# distributed under the License is distributed on an "AS IS" BASIS,
+-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-# See the License for the specific language governing permissions and
+-# limitations under the License.
+-
+-import os
+-import fcntl
+-import errno
+-import struct
+-import select as builtin_select
+-
+-
+-def set_blocking(fd, blocking=True):
+- """
+- Set the given file-descriptor blocking or non-blocking.
+-
+- Returns the original blocking status.
+- """
+-
+- old_flag = fcntl.fcntl(fd, fcntl.F_GETFL)
+-
+- if blocking:
+- new_flag = old_flag &~ os.O_NONBLOCK
+- else:
+- new_flag = old_flag | os.O_NONBLOCK
+-
+- fcntl.fcntl(fd, fcntl.F_SETFL, new_flag)
+-
+- return not bool(old_flag & os.O_NONBLOCK)
+-
+-
+-def select(read_streams, timeout=0):
+- """
+- Select the streams from `read_streams` that are ready for reading.
+-
+- Uses `select.select()` internally but returns a flat list of streams.
+- """
+-
+- write_streams = []
+- exception_streams = []
+-
+- try:
+- return builtin_select.select(
+- read_streams,
+- write_streams,
+- exception_streams,
+- timeout,
+- )[0]
+- except builtin_select.error as e:
+- # POSIX signals interrupt select()
+- if e[0] == errno.EINTR:
+- return []
+- else:
+- raise e
+-
+-
+-class Stream(object):
+- """
+- Generic Stream class.
+-
+- This is a file-like abstraction on top of os.read() and os.write(), which
+- add consistency to the reading of sockets and files alike.
+- """
+-
+-
+- """
+- Recoverable IO/OS Errors.
+- """
+- ERRNO_RECOVERABLE = [
+- errno.EINTR,
+- errno.EDEADLK,
+- errno.EWOULDBLOCK,
+- ]
+-
+-
+- def __init__(self, fd):
+- """
+- Initialize the Stream for the file descriptor `fd`.
+-
+- The `fd` object must have a `fileno()` method.
+- """
+- self.fd = fd
+-
+-
+- def fileno(self):
+- """
+- Return the fileno() of the file descriptor.
+- """
+-
+- return self.fd.fileno()
+-
+-
+- def set_blocking(self, value):
+- if hasattr(self.fd, 'setblocking'):
+- self.fd.setblocking(value)
+- return True
+- else:
+- return set_blocking(self.fd, value)
+-
+-
+- def read(self, n=4096):
+- """
+- Return `n` bytes of data from the Stream, or None at end of stream.
+- """
+-
+- try:
+- if hasattr(self.fd, 'recv'):
+- return self.fd.recv(n)
+- return os.read(self.fd.fileno(), n)
+- except EnvironmentError as e:
+- if e.errno not in Stream.ERRNO_RECOVERABLE:
+- raise e
+-
+-
+- def write(self, data):
+- """
+- Write `data` to the Stream.
+- """
+-
+- if not data:
+- return None
+-
+- while True:
+- try:
+- if hasattr(self.fd, 'send'):
+- self.fd.send(data)
+- return len(data)
+- os.write(self.fd.fileno(), data)
+- return len(data)
+- except EnvironmentError as e:
+- if e.errno not in Stream.ERRNO_RECOVERABLE:
+- raise e
+-
+- def __repr__(self):
+- return "{cls}({fd})".format(cls=type(self).__name__, fd=self.fd)
+-
+-
+-class Demuxer(object):
+- """
+- Wraps a multiplexed Stream to read in data demultiplexed.
+-
+- Docker multiplexes streams together when there is no PTY attached, by
+- sending an 8-byte header, followed by a chunk of data.
+-
+- The first 4 bytes of the header denote the stream from which the data came
+- (i.e. 0x01 = stdout, 0x02 = stderr). Only the first byte of these initial 4
+- bytes is used.
+-
+- The next 4 bytes indicate the length of the following chunk of data as an
+- integer in big endian format. This much data must be consumed before the
+- next 8-byte header is read.
+- """
+-
+- def __init__(self, stream):
+- """
+- Initialize a new Demuxer reading from `stream`.
+- """
+-
+- self.stream = stream
+- self.remain = 0
+-
+-
+- def fileno(self):
+- """
+- Returns the fileno() of the underlying Stream.
+-
+- This is useful for select() to work.
+- """
+-
+- return self.stream.fileno()
+-
+-
+- def set_blocking(self, value):
+- return self.stream.set_blocking(value)
+-
+-
+- def read(self, n=4096):
+- """
+- Read up to `n` bytes of data from the Stream, after demuxing.
+-
+- Less than `n` bytes of data may be returned depending on the available
+- payload, but the number of bytes returned will never exceed `n`.
+-
+- Because demuxing involves scanning 8-byte headers, the actual amount of
+- data read from the underlying stream may be greater than `n`.
+- """
+-
+- size = self._next_packet_size(n)
+-
+- if size <= 0:
+- return
+- else:
+- return self.stream.read(size)
+-
+-
+- def write(self, data):
+- """
+- Delegates the the underlying Stream.
+- """
+-
+- return self.stream.write(data)
+-
+-
+- def _next_packet_size(self, n=0):
+- size = 0
+-
+- if self.remain > 0:
+- size = min(n, self.remain)
+- self.remain -= size
+- else:
+- data = self.stream.read(8)
+- if data is None:
+- return 0
+- if len(data) == 8:
+- __, actual = struct.unpack('>BxxxL', data)
+- size = min(n, actual)
+- self.remain = actual - size
+-
+- return size
+-
+- def __repr__(self):
+- return "{cls}({stream})".format(cls=type(self).__name__,
+- stream=self.stream)
+-
+-
+-class Pump(object):
+- """
+- Stream pump class.
+-
+- A Pump wraps two Streams, reading from one and and writing its data into
+- the other, much like a pipe but manually managed.
+-
+- This abstraction is used to facilitate piping data between the file
+- descriptors associated with the tty and those associated with a container's
+- allocated pty.
+-
+- Pumps are selectable based on the 'read' end of the pipe.
+- """
+-
+- def __init__(self, from_stream, to_stream):
+- """
+- Initialize a Pump with a Stream to read from and another to write to.
+- """
+-
+- self.from_stream = from_stream
+- self.to_stream = to_stream
+-
+-
+- def fileno(self):
+- """
+- Returns the `fileno()` of the reader end of the Pump.
+-
+- This is useful to allow Pumps to function with `select()`.
+- """
+-
+- return self.from_stream.fileno()
+-
+-
+- def set_blocking(self, value):
+- return self.from_stream.set_blocking(value)
+-
+-
+- def flush(self, n=4096):
+- """
+- Flush `n` bytes of data from the reader Stream to the writer Stream.
+-
+- Returns the number of bytes that were actually flushed. A return value
+- of zero is not an error.
+-
+- If EOF has been reached, `None` is returned.
+- """
+-
+- try:
+- return self.to_stream.write(self.from_stream.read(n))
+- except OSError as e:
+- if e.errno != errno.EPIPE:
+- raise e
+-
+- def __repr__(self):
+- return "{cls}(from={from_stream}, to={to_stream})".format(
+- cls=type(self).__name__,
+- from_stream=self.from_stream,
+- to_stream=self.to_stream)
+diff --git a/fig/packages/dockerpty/pty.py b/fig/packages/dockerpty/pty.py
+deleted file mode 100644
+index 4e11ca0..0000000
+--- a/fig/packages/dockerpty/pty.py
++++ /dev/null
+@@ -1,235 +0,0 @@
+-# dockerpty: pty.py
+-#
+-# Copyright 2014 Chris Corbyn <chris@w3style.co.uk>
+-#
+-# Licensed under the Apache License, Version 2.0 (the "License");
+-# you may not use this file except in compliance with the License.
+-# You may obtain a copy of the License at
+-#
+-# http://www.apache.org/licenses/LICENSE-2.0
+-#
+-# Unless required by applicable law or agreed to in writing, software
+-# distributed under the License is distributed on an "AS IS" BASIS,
+-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-# See the License for the specific language governing permissions and
+-# limitations under the License.
+-
+-import sys
+-import signal
+-from ssl import SSLError
+-
+-from . import io
+-from . import tty
+-
+-
+-class WINCHHandler(object):
+- """
+- WINCH Signal handler to keep the PTY correctly sized.
+- """
+-
+- def __init__(self, pty):
+- """
+- Initialize a new WINCH handler for the given PTY.
+-
+- Initializing a handler has no immediate side-effects. The `start()`
+- method must be invoked for the signals to be trapped.
+- """
+-
+- self.pty = pty
+- self.original_handler = None
+-
+-
+- def __enter__(self):
+- """
+- Invoked on entering a `with` block.
+- """
+-
+- self.start()
+- return self
+-
+-
+- def __exit__(self, *_):
+- """
+- Invoked on exiting a `with` block.
+- """
+-
+- self.stop()
+-
+-
+- def start(self):
+- """
+- Start trapping WINCH signals and resizing the PTY.
+-
+- This method saves the previous WINCH handler so it can be restored on
+- `stop()`.
+- """
+-
+- def handle(signum, frame):
+- if signum == signal.SIGWINCH:
+- self.pty.resize()
+-
+- self.original_handler = signal.signal(signal.SIGWINCH, handle)
+-
+-
+- def stop(self):
+- """
+- Stop trapping WINCH signals and restore the previous WINCH handler.
+- """
+-
+- if self.original_handler is not None:
+- signal.signal(signal.SIGWINCH, self.original_handler)
+-
+-
+-class PseudoTerminal(object):
+- """
+- Wraps the pseudo-TTY (PTY) allocated to a docker container.
+-
+- The PTY is managed via the current process' TTY until it is closed.
+-
+- Example:
+-
+- import docker
+- from dockerpty import PseudoTerminal
+-
+- client = docker.Client()
+- container = client.create_container(
+- image='busybox:latest',
+- stdin_open=True,
+- tty=True,
+- command='/bin/sh',
+- )
+-
+- # hijacks the current tty until the pty is closed
+- PseudoTerminal(client, container).start()
+-
+- Care is taken to ensure all file descriptors are restored on exit. For
+- example, you can attach to a running container from within a Python REPL
+- and when the container exits, the user will be returned to the Python REPL
+- without adverse effects.
+- """
+-
+-
+- def __init__(self, client, container):
+- """
+- Initialize the PTY using the docker.Client instance and container dict.
+- """
+-
+- self.client = client
+- self.container = container
+- self.raw = None
+-
+-
+- def start(self, **kwargs):
+- """
+- Present the PTY of the container inside the current process.
+-
+- This will take over the current process' TTY until the container's PTY
+- is closed.
+- """
+-
+- pty_stdin, pty_stdout, pty_stderr = self.sockets()
+-
+- mappings = [
+- (io.Stream(sys.stdin), pty_stdin),
+- (pty_stdout, io.Stream(sys.stdout)),
+- (pty_stderr, io.Stream(sys.stderr)),
+- ]
+-
+- pumps = [io.Pump(a, b) for (a, b) in mappings if a and b]
+-
+- if not self.container_info()['State']['Running']:
+- self.client.start(self.container, **kwargs)
+-
+- flags = [p.set_blocking(False) for p in pumps]
+-
+- try:
+- with WINCHHandler(self):
+- self._hijack_tty(pumps)
+- finally:
+- if flags:
+- for (pump, flag) in zip(pumps, flags):
+- io.set_blocking(pump, flag)
+-
+-
+- def israw(self):
+- """
+- Returns True if the PTY should operate in raw mode.
+-
+- If the container was not started with tty=True, this will return False.
+- """
+-
+- if self.raw is None:
+- info = self.container_info()
+- self.raw = sys.stdout.isatty() and info['Config']['Tty']
+-
+- return self.raw
+-
+-
+- def sockets(self):
+- """
+- Returns a tuple of sockets connected to the pty (stdin,stdout,stderr).
+-
+- If any of the sockets are not attached in the container, `None` is
+- returned in the tuple.
+- """
+-
+- info = self.container_info()
+-
+- def attach_socket(key):
+- if info['Config']['Attach{0}'.format(key.capitalize())]:
+- socket = self.client.attach_socket(
+- self.container,
+- {key: 1, 'stream': 1, 'logs': 1},
+- )
+- stream = io.Stream(socket)
+-
+- if info['Config']['Tty']:
+- return stream
+- else:
+- return io.Demuxer(stream)
+- else:
+- return None
+-
+- return map(attach_socket, ('stdin', 'stdout', 'stderr'))
+-
+-
+- def resize(self, size=None):
+- """
+- Resize the container's PTY.
+-
+- If `size` is not None, it must be a tuple of (height,width), otherwise
+- it will be determined by the size of the current TTY.
+- """
+-
+- if not self.israw():
+- return
+-
+- size = size or tty.size(sys.stdout)
+-
+- if size is not None:
+- rows, cols = size
+- try:
+- self.client.resize(self.container, height=rows, width=cols)
+- except IOError: # Container already exited
+- pass
+-
+-
+- def container_info(self):
+- """
+- Thin wrapper around client.inspect_container().
+- """
+-
+- return self.client.inspect_container(self.container)
+-
+-
+- def _hijack_tty(self, pumps):
+- with tty.Terminal(sys.stdin, raw=self.israw()):
+- self.resize()
+- while True:
+- _ready = io.select(pumps, timeout=60)
+- try:
+- if all([p.flush() is None for p in pumps]):
+- break
+- except SSLError as e:
+- if 'The operation did not complete' not in e.strerror:
+- raise e
+diff --git a/fig/packages/dockerpty/tty.py b/fig/packages/dockerpty/tty.py
+deleted file mode 100644
+index bd2ccb5..0000000
+--- a/fig/packages/dockerpty/tty.py
++++ /dev/null
+@@ -1,130 +0,0 @@
+-# dockerpty: tty.py
+-#
+-# Copyright 2014 Chris Corbyn <chris@w3style.co.uk>
+-#
+-# Licensed under the Apache License, Version 2.0 (the "License");
+-# you may not use this file except in compliance with the License.
+-# You may obtain a copy of the License at
+-#
+-# http://www.apache.org/licenses/LICENSE-2.0
+-#
+-# Unless required by applicable law or agreed to in writing, software
+-# distributed under the License is distributed on an "AS IS" BASIS,
+-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-# See the License for the specific language governing permissions and
+-# limitations under the License.
+-
+-from __future__ import absolute_import
+-
+-import os
+-import termios
+-import tty
+-import fcntl
+-import struct
+-
+-
+-def size(fd):
+- """
+- Return a tuple (rows,cols) representing the size of the TTY `fd`.
+-
+- The provided file descriptor should be the stdout stream of the TTY.
+-
+- If the TTY size cannot be determined, returns None.
+- """
+-
+- if not os.isatty(fd.fileno()):
+- return None
+-
+- try:
+- dims = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, 'hhhh'))
+- except:
+- try:
+- dims = (os.environ['LINES'], os.environ['COLUMNS'])
+- except:
+- return None
+-
+- return dims
+-
+-
+-class Terminal(object):
+- """
+- Terminal provides wrapper functionality to temporarily make the tty raw.
+-
+- This is useful when streaming data from a pseudo-terminal into the tty.
+-
+- Example:
+-
+- with Terminal(sys.stdin, raw=True):
+- do_things_in_raw_mode()
+- """
+-
+- def __init__(self, fd, raw=True):
+- """
+- Initialize a terminal for the tty with stdin attached to `fd`.
+-
+- Initializing the Terminal has no immediate side effects. The `start()`
+- method must be invoked, or `with raw_terminal:` used before the
+- terminal is affected.
+- """
+-
+- self.fd = fd
+- self.raw = raw
+- self.original_attributes = None
+-
+-
+- def __enter__(self):
+- """
+- Invoked when a `with` block is first entered.
+- """
+-
+- self.start()
+- return self
+-
+-
+- def __exit__(self, *_):
+- """
+- Invoked when a `with` block is finished.
+- """
+-
+- self.stop()
+-
+-
+- def israw(self):
+- """
+- Returns True if the TTY should operate in raw mode.
+- """
+-
+- return self.raw
+-
+-
+- def start(self):
+- """
+- Saves the current terminal attributes and makes the tty raw.
+-
+- This method returns None immediately.
+- """
+-
+- if os.isatty(self.fd.fileno()) and self.israw():
+- self.original_attributes = termios.tcgetattr(self.fd)
+- tty.setraw(self.fd)
+-
+-
+- def stop(self):
+- """
+- Restores the terminal attributes back to before setting raw mode.
+-
+- If the raw terminal was not started, does nothing.
+- """
+-
+- if self.original_attributes is not None:
+- termios.tcsetattr(
+- self.fd,
+- termios.TCSADRAIN,
+- self.original_attributes,
+- )
+-
+- def __repr__(self):
+- return "{cls}({fd}, raw={raw})".format(
+- cls=type(self).__name__,
+- fd=self.fd,
+- raw=self.raw)
+diff --git a/tests/integration/cli_test.py b/tests/integration/cli_test.py
+index 0581e8b..369e6c8 100644
+--- a/tests/integration/cli_test.py
++++ b/tests/integration/cli_test.py
+@@ -129,13 +129,13 @@ class CLITestCase(DockerClientTestCase):
+
+ self.assertEqual(old_ids, new_ids)
+
+- @patch('fig.packages.dockerpty.start')
++ @patch('dockerpty.start')
+ def test_run_service_without_links(self, mock_stdout):
+ self.command.base_dir = 'tests/fixtures/links-figfile'
+ self.command.dispatch(['run', 'console', '/bin/true'], None)
+ self.assertEqual(len(self.project.containers()), 0)
+
+- @patch('fig.packages.dockerpty.start')
++ @patch('dockerpty.start')
+ def test_run_service_with_links(self, __):
+ self.command.base_dir = 'tests/fixtures/links-figfile'
+ self.command.dispatch(['run', 'web', '/bin/true'], None)
+@@ -144,14 +144,14 @@ class CLITestCase(DockerClientTestCase):
+ self.assertEqual(len(db.containers()), 1)
+ self.assertEqual(len(console.containers()), 0)
+
+- @patch('fig.packages.dockerpty.start')
++ @patch('dockerpty.start')
+ def test_run_with_no_deps(self, __):
+ self.command.base_dir = 'tests/fixtures/links-figfile'
+ self.command.dispatch(['run', '--no-deps', 'web', '/bin/true'], None)
+ db = self.project.get_service('db')
+ self.assertEqual(len(db.containers()), 0)
+
+- @patch('fig.packages.dockerpty.start')
++ @patch('dockerpty.start')
+ def test_run_does_not_recreate_linked_containers(self, __):
+ self.command.base_dir = 'tests/fixtures/links-figfile'
+ self.command.dispatch(['up', '-d', 'db'], None)
+@@ -167,7 +167,7 @@ class CLITestCase(DockerClientTestCase):
+
+ self.assertEqual(old_ids, new_ids)
+
+- @patch('fig.packages.dockerpty.start')
++ @patch('dockerpty.start')
+ def test_run_without_command(self, __):
+ self.command.base_dir = 'tests/fixtures/commands-figfile'
+ self.check_build('tests/fixtures/simple-dockerfile', tag='figtest_test')
+@@ -191,7 +191,7 @@ class CLITestCase(DockerClientTestCase):
+ [u'/bin/true'],
+ )
+
+- @patch('fig.packages.dockerpty.start')
++ @patch('dockerpty.start')
+ def test_run_service_with_entrypoint_overridden(self, _):
+ self.command.base_dir = 'tests/fixtures/dockerfile_with_entrypoint'
+ name = 'service'
+@@ -206,7 +206,7 @@ class CLITestCase(DockerClientTestCase):
+ u'/bin/echo helloworld'
+ )
+
+- @patch('fig.packages.dockerpty.start')
++ @patch('dockerpty.start')
+ def test_run_service_with_environement_overridden(self, _):
+ name = 'service'
+ self.command.base_dir = 'tests/fixtures/environment-figfile'
diff --git a/app-emulation/fig/metadata.xml b/app-emulation/fig/metadata.xml
new file mode 100644
index 000000000000..02be8c5eb78f
--- /dev/null
+++ b/app-emulation/fig/metadata.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd">
+<pkgmetadata>
+ <maintainer>
+ <email>alunduil@gentoo.org</email>
+ <name>Alex Brandt</name>
+ </maintainer>
+ <longdescription lang="en">
+ </longdescription>
+</pkgmetadata>