• Stars
    star
    155
  • Rank 240,864 (Top 5 %)
  • Language
    Python
  • License
    Apache License 2.0
  • Created over 10 years ago
  • Updated about 5 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Pseudo-tty handler for docker Python client

Docker PTY

Provides the functionality needed to operate the pseudo-tty (PTY) allocated to a docker container, using the Python client.

[Build Status] (https://travis-ci.org/d11wtq/dockerpty)

Installation

Via pip:

pip install dockerpty

Dependencies:

  • docker-py>=0.3.2

However, this library does not explicitly declare this dependency in PyPi for a number of reasons. It is assumed you have it installed.

Usage

The following example will run busybox in a docker container and place the user at the shell prompt via Python.

This obviously only works when run in a terminal.

import docker
import dockerpty

client = docker.Client()
container = client.create_container(
    image='busybox:latest',
    stdin_open=True,
    tty=True,
    command='/bin/sh',
)

dockerpty.start(client, container)

Keyword arguments passed to start() will be forwarded onto the client to start the container.

When the dockerpty is started, control is yielded to the container's PTY until the container exits, or the container's PTY is closed.

This is a safe operation and all resources are restored back to their original states.

Note: dockerpty does support attaching to non-tty containers to stream container output, though it is obviously not possible to 'control' the container if you do not allocate a pseudo-tty.

If you press C-p C-q, the container's PTY will be closed, but the container will keep running. In other words, you will have detached from the container and can re-attach with another dockerpty.start() call.

Tests

If you want to hack on dockerpty and send a PR, you'll need to run the tests. In the features/ directory, are features/user stories for how dockerpty is supposed to work. To run them:

-bash$ pip install -r requirements-dev.txt
-bash$ behave features/

You'll need to have docker installed and running locally. The tests use busybox container as a test fixture, so are not too heavy.

Step definitions are defined in features/steps/.

There are also unit tests for the parts of the code that are not inherently dependent on controlling a TTY. To run those:

-bash$ pip install -r requirements-dev.txt
-bash$ py.test tests/

Travis CI runs this build inside a UML kernel that is new enough to run docker. Your PR will need to pass the build before I can merge it.

How it works

In a terminal, the three file descriptors stdin, stdout and stderr are all connected to the controlling terminal (TTY). When you pass the tty=True flag to docker's create_container(), docker allocates a fake TTY inside the container (a PTY) to which the container's stdin, stdout and stderr are all connected.

The docker API provides a way to access the three sockets connected to the PTY. If with access to the host system's TTY file descriptors and the container's PTY file descriptors, it is trivial to simply 'pipe' data written to these file descriptors between the host and the container. Doing this makes the user's terminal effectively become the pseudo-terminal from inside the container.

In reality it's a bit more complicated than this, since care must be taken to put the host terminal into raw mode (where keys such as enter are not interpreted with any special meaning) and restore it on exit. Additionally, the container's stdout and stderr streams along with sys.stdin must be made non-blocking so that they can be used with select() without blocking the main process. These attributes are restored on exit.

The size of a terminal cannot be controlled by sending data to stdin and can only be controlled by the terminal program itself. Since the pseudo-terminal is running inside a real terminal, it is import that the size of the PTY be kept the same as that of the presenting TTY. For this reason, docker provides an API call to resize the allocated PTY. A SIGWINCH handler is used to detect window size changes and resize the pseudo-terminal as needed.

Contributors

Copyright & Licensing

Copyright © 2014 Chris Corbyn. See the LICENSE.txt file for details.

More Repositories

1

whittle

Whittle: A small LALR(1) Parser in Pure Ruby (Not a Generator)
Ruby
116
star
2

gentoo-packer

Packer scripts to create a Gentoo Vagrant box
Shell
73
star
3

ctrlp_bdelete.vim

An extension to ctrlp.vim for deleting open buffers
Vim Script
58
star
4

node-http-cache

HTTP Caching Proxy Written in node.js
JavaScript
46
star
5

http-kit-fake

Fakes HTTP requests using the Clojure http-kit client
Clojure
41
star
6

skittle

Simple provisioning with bash
Shell
15
star
7

oedipus

Sphinx 2 Search Client for Ruby
Ruby
14
star
8

dm-sql-finders

DataMapper SQL Finders
Ruby
10
star
9

dm-master-slave-adapter

Master/Slave Adapter for DataMapper (for things like MySQL replication)
Ruby
9
star
10

docker-ami-packer

Packer recipe for a docker-capable Amazon EC2 AMI
Shell
9
star
11

php-docker

Docker container for running PHP + Apache apps
Shell
8
star
12

gentoo-vm

Dev environment using Gentoo Linux
Shell
7
star
13

kodify

Multi programming language syntax highlighter written in JavaScript
JavaScript
7
star
14

apache-docker

Docker container for running Apache
ApacheConf
6
star
15

oedipus-dm

DataMapper Frontend for the Oedipus Sphinx Client
Ruby
6
star
16

dot-vim

My .vimrc configuration
Vim Script
6
star
17

tomorrow-theme-vim

Auto-updated vim-specific files from https://github.com/chriskempson/tomorrow-theme.git
Vim Script
6
star
18

ruby-docker

Docker container for running Ruby apps
5
star
19

llvm-docker

Docker container for building LLVM-hosted apps
Shell
5
star
20

veritas-tutorial-d

Veritas Tutorial D
Ruby
5
star
21

node-memo-is

Memoization for Mocha/Jasmine test fixtures, like RSpec's let.
JavaScript
5
star
22

lx

A ECMAScript (JavaScript) based lex implementation
JavaScript
5
star
23

persistent

Persistent Data Structures for Go
Go
4
star
24

emacs.d

My emacs 24 configuration
Emacs Lisp
4
star
25

clojure-docker

Docker container for running Clojure apps
Shell
4
star
26

machinist-dm

DataMapper support for Machinist 2
Ruby
3
star
27

subatomic256.vim

Port of Emacs subatomic theme for Vim
Vim Script
3
star
28

netaddr.js

Utility for IP addresses and CIDR expressions
JavaScript
3
star
29

Cioccolata

FastCGI web application framework in Objective-C
C
3
star
30

macvim256.vim

macvim theme ported for 256 color terminals
Vim Script
3
star
31

rdo

RDO—Simple Database Connectivity for Ruby
Ruby
3
star
32

stack

AWS CloudFormation Stack Deployer
Clojure
3
star
33

rdo-postgres

PostgreSQL Driver for RDO
Ruby
2
star
34

lol-notes

Notes from Let Over Lambda
Common Lisp
2
star
35

fig-dev-docker

Docker container for developing fig
Shell
2
star
36

mojibaker-framework

Supporting framework used by the (watch this space) MojiBaker text editor for OS X
C
2
star
37

rdo-sqlite

SQLite Driver for RDO
Ruby
1
star
38

paas

Hosted PaaS in Node.js - Not maintained.
JavaScript
1
star
39

google-api-client

Fork of http://code.google.com/p/google-api-ruby-client/
Ruby
1
star
40

cuckoo

Distributed scheduling & queueing for Clojure
Clojure
1
star
41

mysql-docker

Docker container for MySQL 5.6
Shell
1
star
42

L.i.S.P

Exercises from Lisp in Small Pieces
Scheme
1
star
43

rdo-mysql

MySQL Driver for RDO
Ruby
1
star
44

iode-rb

Lisp-1 based functional programming language
Ruby
1
star
45

guile-docker

Docker container for Guile Scheme
Shell
1
star