summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Brandt <alunduil@gentoo.org>2014-10-27 15:25:51 +0000
committerAlex Brandt <alunduil@gentoo.org>2014-10-27 15:25:51 +0000
commit41a93aae2fc4f1e91fb043943d8bd2408f1bbc17 (patch)
treea4017c4b2ababcc60926ee71e1d716e0f6b13e47 /app-emulation
parentRevision bump: EAPI=5; Add sub-slot for perl dependency (diff)
downloadgentoo-2-41a93aae2fc4f1e91fb043943d8bd2408f1bbc17.tar.gz
gentoo-2-41a93aae2fc4f1e91fb043943d8bd2408f1bbc17.tar.bz2
gentoo-2-41a93aae2fc4f1e91fb043943d8bd2408f1bbc17.zip
add ebuild for fig
(Portage version: 2.2.14/cvs/Linux x86_64, signed Manifest commit with key 11A8217C!)
Diffstat (limited to 'app-emulation')
-rw-r--r--app-emulation/fig/ChangeLog11
-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
5 files changed, 928 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/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>