mirror of https://github.com/docker/docs.git
First version with python3 support.
* Moved requirements*.txt files to proper spec definitions in setup.py * Added a new fig.compat module to store some compatibility code
This commit is contained in:
parent
f96a1a0b35
commit
93b9b6fd9f
|
@ -1,3 +1,5 @@
|
||||||
include LICENSE
|
include LICENSE
|
||||||
include *.md
|
include *.md
|
||||||
include requirements.txt
|
recursive-include tests *
|
||||||
|
global-exclude *.pyc
|
||||||
|
global-exclode *.pyo
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from __future__ import unicode_literals
|
||||||
from .service import Service
|
from .service import Service
|
||||||
|
|
||||||
__version__ = '0.0.2'
|
__version__ = '0.0.2'
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from __future__ import unicode_literals
|
||||||
NAMES = [
|
NAMES = [
|
||||||
'grey',
|
'grey',
|
||||||
'red',
|
'red',
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
from __future__ import absolute_import
|
||||||
from docker import Client
|
from docker import Client
|
||||||
import errno
|
import errno
|
||||||
import logging
|
import logging
|
||||||
|
@ -21,7 +23,7 @@ class Command(DocoptCommand):
|
||||||
def project(self):
|
def project(self):
|
||||||
try:
|
try:
|
||||||
config = yaml.load(open('fig.yml'))
|
config = yaml.load(open('fig.yml'))
|
||||||
except IOError, e:
|
except IOError as e:
|
||||||
if e.errno == errno.ENOENT:
|
if e.errno == errno.ENOENT:
|
||||||
log.error("Can't find %s. Are you in the right directory?", e.filename)
|
log.error("Can't find %s. Are you in the right directory?", e.filename)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
from __future__ import absolute_import
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from inspect import getdoc
|
from inspect import getdoc
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from __future__ import absolute_import
|
||||||
from textwrap import dedent
|
from textwrap import dedent
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
from __future__ import absolute_import
|
||||||
import texttable
|
import texttable
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
from __future__ import absolute_import
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from itertools import cycle
|
from itertools import cycle
|
||||||
|
@ -41,7 +43,7 @@ class LogPrinter(object):
|
||||||
'stream': True,
|
'stream': True,
|
||||||
}
|
}
|
||||||
params.update(self.attach_params)
|
params.update(self.attach_params)
|
||||||
params = dict((name, 1 if value else 0) for (name, value) in params.items())
|
params = dict((name, 1 if value else 0) for (name, value) in list(params.items()))
|
||||||
return container.attach_socket(params=params, ws=True)
|
return container.attach_socket(params=params, ws=True)
|
||||||
|
|
||||||
def read_websocket(websocket):
|
def read_websocket(websocket):
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from __future__ import absolute_import
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
from __future__ import absolute_import
|
||||||
import datetime
|
import datetime
|
||||||
import os
|
import os
|
||||||
import socket
|
import socket
|
||||||
|
@ -69,7 +71,7 @@ def prettydate(d):
|
||||||
return '{0} hours ago'.format(s/3600)
|
return '{0} hours ago'.format(s/3600)
|
||||||
|
|
||||||
|
|
||||||
def mkdir(path, permissions=0700):
|
def mkdir(path, permissions=0o700):
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
os.mkdir(path)
|
os.mkdir(path)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
|
||||||
|
|
||||||
|
# Taken from python2.7/3.3 functools
|
||||||
|
def cmp_to_key(mycmp):
|
||||||
|
"""Convert a cmp= function into a key= function"""
|
||||||
|
class K(object):
|
||||||
|
__slots__ = ['obj']
|
||||||
|
def __init__(self, obj):
|
||||||
|
self.obj = obj
|
||||||
|
def __lt__(self, other):
|
||||||
|
return mycmp(self.obj, other.obj) < 0
|
||||||
|
def __gt__(self, other):
|
||||||
|
return mycmp(self.obj, other.obj) > 0
|
||||||
|
def __eq__(self, other):
|
||||||
|
return mycmp(self.obj, other.obj) == 0
|
||||||
|
def __le__(self, other):
|
||||||
|
return mycmp(self.obj, other.obj) <= 0
|
||||||
|
def __ge__(self, other):
|
||||||
|
return mycmp(self.obj, other.obj) >= 0
|
||||||
|
def __ne__(self, other):
|
||||||
|
return mycmp(self.obj, other.obj) != 0
|
||||||
|
__hash__ = None
|
||||||
|
return K
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
from __future__ import absolute_import
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
@ -53,7 +55,7 @@ class Container(object):
|
||||||
if not self.dictionary['NetworkSettings']['Ports']:
|
if not self.dictionary['NetworkSettings']['Ports']:
|
||||||
return ''
|
return ''
|
||||||
ports = []
|
ports = []
|
||||||
for private, public in self.dictionary['NetworkSettings']['Ports'].items():
|
for private, public in list(self.dictionary['NetworkSettings']['Ports'].items()):
|
||||||
if public:
|
if public:
|
||||||
ports.append('%s->%s' % (public[0]['HostPort'], private))
|
ports.append('%s->%s' % (public[0]['HostPort'], private))
|
||||||
return ', '.join(ports)
|
return ', '.join(ports)
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
from __future__ import absolute_import
|
||||||
import logging
|
import logging
|
||||||
from .service import Service
|
from .service import Service
|
||||||
|
from .compat import cmp_to_key
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -13,7 +16,7 @@ def sort_service_dicts(services):
|
||||||
elif y_deps_x and not x_deps_y:
|
elif y_deps_x and not x_deps_y:
|
||||||
return -1
|
return -1
|
||||||
return 0
|
return 0
|
||||||
return sorted(services, cmp=cmp)
|
return sorted(services, key=cmp_to_key(cmp))
|
||||||
|
|
||||||
class Project(object):
|
class Project(object):
|
||||||
"""
|
"""
|
||||||
|
@ -43,7 +46,7 @@ class Project(object):
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_config(cls, name, config, client):
|
def from_config(cls, name, config, client):
|
||||||
dicts = []
|
dicts = []
|
||||||
for service_name, service in config.items():
|
for service_name, service in list(config.items()):
|
||||||
service['name'] = service_name
|
service['name'] = service_name
|
||||||
dicts.append(service)
|
dicts.append(service)
|
||||||
return cls.from_dicts(name, dicts, client)
|
return cls.from_dicts(name, dicts, client)
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
from __future__ import absolute_import
|
||||||
from docker.client import APIError
|
from docker.client import APIError
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
|
@ -64,7 +66,7 @@ class Service(object):
|
||||||
container_options = self._get_container_options(override_options, one_off=one_off)
|
container_options = self._get_container_options(override_options, one_off=one_off)
|
||||||
try:
|
try:
|
||||||
return Container.create(self.client, **container_options)
|
return Container.create(self.client, **container_options)
|
||||||
except APIError, e:
|
except APIError as e:
|
||||||
if e.response.status_code == 404 and e.explanation and 'No such image' in e.explanation:
|
if e.response.status_code == 404 and e.explanation and 'No such image' in e.explanation:
|
||||||
log.info('Pulling image %s...' % container_options['image'])
|
log.info('Pulling image %s...' % container_options['image'])
|
||||||
self.client.pull(container_options['image'])
|
self.client.pull(container_options['image'])
|
||||||
|
@ -82,7 +84,7 @@ class Service(object):
|
||||||
|
|
||||||
if options.get('ports', None) is not None:
|
if options.get('ports', None) is not None:
|
||||||
for port in options['ports']:
|
for port in options['ports']:
|
||||||
port = unicode(port)
|
port = str(port)
|
||||||
if ':' in port:
|
if ':' in port:
|
||||||
internal_port, external_port = port.split(':', 1)
|
internal_port, external_port = port.split(':', 1)
|
||||||
port_bindings[int(internal_port)] = int(external_port)
|
port_bindings[int(internal_port)] = int(external_port)
|
||||||
|
@ -107,7 +109,7 @@ class Service(object):
|
||||||
bits = [self.project, self.name]
|
bits = [self.project, self.name]
|
||||||
if one_off:
|
if one_off:
|
||||||
bits.append('run')
|
bits.append('run')
|
||||||
return '_'.join(bits + [unicode(self.next_container_number(one_off=one_off))])
|
return '_'.join(bits + [str(self.next_container_number(one_off=one_off))])
|
||||||
|
|
||||||
def next_container_number(self, one_off=False):
|
def next_container_number(self, one_off=False):
|
||||||
numbers = [parse_name(c.name)[2] for c in self.containers(stopped=True, one_off=one_off)]
|
numbers = [parse_name(c.name)[2] for c in self.containers(stopped=True, one_off=one_off)]
|
||||||
|
@ -132,7 +134,7 @@ class Service(object):
|
||||||
container_options['name'] = self.next_container_name(one_off)
|
container_options['name'] = self.next_container_name(one_off)
|
||||||
|
|
||||||
if 'ports' in container_options:
|
if 'ports' in container_options:
|
||||||
container_options['ports'] = [unicode(p).split(':')[0] for p in container_options['ports']]
|
container_options['ports'] = [str(p).split(':')[0] for p in container_options['ports']]
|
||||||
|
|
||||||
if 'volumes' in container_options:
|
if 'volumes' in container_options:
|
||||||
container_options['volumes'] = dict((v.split(':')[1], {}) for v in container_options['volumes'])
|
container_options['volumes'] = dict((v.split(':')[1], {}) for v in container_options['volumes'])
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
nose==1.3.0
|
|
||||||
unittest2==0.5.1
|
|
|
@ -1,4 +0,0 @@
|
||||||
docker-py==0.2.3
|
|
||||||
docopt==0.6.1
|
|
||||||
PyYAML==3.10
|
|
||||||
texttable==0.8.1
|
|
30
setup.py
30
setup.py
|
@ -1,16 +1,17 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
from setuptools import setup
|
from __future__ import absolute_import
|
||||||
|
from setuptools import setup, find_packages
|
||||||
import re
|
import re
|
||||||
import os
|
import os
|
||||||
import codecs
|
import codecs
|
||||||
|
|
||||||
|
|
||||||
# Borrowed from
|
|
||||||
# https://github.com/jezdez/django_compressor/blob/develop/setup.py
|
|
||||||
def read(*parts):
|
def read(*parts):
|
||||||
return codecs.open(os.path.join(os.path.dirname(__file__), *parts)).read()
|
path = os.path.join(os.path.dirname(__file__), *parts)
|
||||||
|
with codecs.open(path, encoding='utf-8') as fobj:
|
||||||
|
return fobj.read()
|
||||||
|
|
||||||
|
|
||||||
def find_version(*file_paths):
|
def find_version(*file_paths):
|
||||||
|
@ -21,8 +22,6 @@ def find_version(*file_paths):
|
||||||
return version_match.group(1)
|
return version_match.group(1)
|
||||||
raise RuntimeError("Unable to find version string.")
|
raise RuntimeError("Unable to find version string.")
|
||||||
|
|
||||||
with open('requirements.txt') as f:
|
|
||||||
install_requires = f.read().splitlines()
|
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='fig',
|
name='fig',
|
||||||
|
@ -31,10 +30,21 @@ setup(
|
||||||
url='https://github.com/orchardup/fig',
|
url='https://github.com/orchardup/fig',
|
||||||
author='Orchard Laboratories Ltd.',
|
author='Orchard Laboratories Ltd.',
|
||||||
author_email='hello@orchardup.com',
|
author_email='hello@orchardup.com',
|
||||||
packages=['fig', 'fig.cli'],
|
packages=find_packages(),
|
||||||
package_data={},
|
|
||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
install_requires=install_requires,
|
test_suite='nose.collector',
|
||||||
|
install_requires=[
|
||||||
|
'docker-py==0.2.3',
|
||||||
|
'docopt==0.6.1',
|
||||||
|
'PyYAML==3.10',
|
||||||
|
'texttable==0.8.1',
|
||||||
|
# unfortunately `docker` requires six ==1.3.0
|
||||||
|
'six==1.3.0',
|
||||||
|
],
|
||||||
|
tests_require=[
|
||||||
|
'nose==1.3.0',
|
||||||
|
'unittest2==0.5.1'
|
||||||
|
],
|
||||||
entry_points="""
|
entry_points="""
|
||||||
[console_scripts]
|
[console_scripts]
|
||||||
fig=fig.cli.main:main
|
fig=fig.cli.main:main
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from __future__ import unicode_literals
|
||||||
from .testcases import DockerClientTestCase
|
from .testcases import DockerClientTestCase
|
||||||
from fig.container import Container
|
from fig.container import Container
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from __future__ import unicode_literals
|
||||||
from fig.project import Project
|
from fig.project import Project
|
||||||
from .testcases import DockerClientTestCase
|
from .testcases import DockerClientTestCase
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
from __future__ import absolute_import
|
||||||
from fig import Service
|
from fig import Service
|
||||||
from .testcases import DockerClientTestCase
|
from .testcases import DockerClientTestCase
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
from __future__ import absolute_import
|
||||||
from docker import Client
|
from docker import Client
|
||||||
from fig.service import Service
|
from fig.service import Service
|
||||||
from fig.cli.utils import docker_url
|
from fig.cli.utils import docker_url
|
||||||
|
|
Loading…
Reference in New Issue