You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@senssoft.apache.org by ar...@apache.org on 2016/12/16 17:11:07 UTC
[49/58] [abbrv] [partial] incubator-senssoft-tap git commit: Fixed
.gitignore file
http://git-wip-us.apache.org/repos/asf/incubator-senssoft-tap/blob/6a81d1e7/env2/lib/python2.7/site-packages/compose/cli/main.py
----------------------------------------------------------------------
diff --git a/env2/lib/python2.7/site-packages/compose/cli/main.py b/env2/lib/python2.7/site-packages/compose/cli/main.py
deleted file mode 100644
index b487bb7..0000000
--- a/env2/lib/python2.7/site-packages/compose/cli/main.py
+++ /dev/null
@@ -1,1046 +0,0 @@
-from __future__ import absolute_import
-from __future__ import print_function
-from __future__ import unicode_literals
-
-import contextlib
-import functools
-import json
-import logging
-import re
-import sys
-from inspect import getdoc
-from operator import attrgetter
-
-from . import errors
-from . import signals
-from .. import __version__
-from ..bundle import get_image_digests
-from ..bundle import MissingDigests
-from ..bundle import serialize_bundle
-from ..config import ConfigurationError
-from ..config import parse_environment
-from ..config.environment import Environment
-from ..config.serialize import serialize_config
-from ..const import DEFAULT_TIMEOUT
-from ..const import IS_WINDOWS_PLATFORM
-from ..progress_stream import StreamOutputError
-from ..project import NoSuchService
-from ..project import OneOffFilter
-from ..project import ProjectError
-from ..service import BuildAction
-from ..service import BuildError
-from ..service import ConvergenceStrategy
-from ..service import ImageType
-from ..service import NeedsBuildError
-from ..service import OperationFailedError
-from .command import get_config_from_options
-from .command import project_from_options
-from .docopt_command import DocoptDispatcher
-from .docopt_command import get_handler
-from .docopt_command import NoSuchCommand
-from .errors import UserError
-from .formatter import ConsoleWarningFormatter
-from .formatter import Formatter
-from .log_printer import build_log_presenters
-from .log_printer import LogPrinter
-from .utils import get_version_info
-from .utils import yesno
-
-
-if not IS_WINDOWS_PLATFORM:
- from dockerpty.pty import PseudoTerminal, RunOperation, ExecOperation
-
-log = logging.getLogger(__name__)
-console_handler = logging.StreamHandler(sys.stderr)
-
-
-def main():
- command = dispatch()
-
- try:
- command()
- except (KeyboardInterrupt, signals.ShutdownException):
- log.error("Aborting.")
- sys.exit(1)
- except (UserError, NoSuchService, ConfigurationError,
- ProjectError, OperationFailedError) as e:
- log.error(e.msg)
- sys.exit(1)
- except BuildError as e:
- log.error("Service '%s' failed to build: %s" % (e.service.name, e.reason))
- sys.exit(1)
- except StreamOutputError as e:
- log.error(e)
- sys.exit(1)
- except NeedsBuildError as e:
- log.error("Service '%s' needs to be built, but --no-build was passed." % e.service.name)
- sys.exit(1)
- except errors.ConnectionError:
- sys.exit(1)
-
-
-def dispatch():
- setup_logging()
- dispatcher = DocoptDispatcher(
- TopLevelCommand,
- {'options_first': True, 'version': get_version_info('compose')})
-
- try:
- options, handler, command_options = dispatcher.parse(sys.argv[1:])
- except NoSuchCommand as e:
- commands = "\n".join(parse_doc_section("commands:", getdoc(e.supercommand)))
- log.error("No such command: %s\n\n%s", e.command, commands)
- sys.exit(1)
-
- setup_console_handler(console_handler, options.get('--verbose'))
- return functools.partial(perform_command, options, handler, command_options)
-
-
-def perform_command(options, handler, command_options):
- if options['COMMAND'] in ('help', 'version'):
- # Skip looking up the compose file.
- handler(command_options)
- return
-
- if options['COMMAND'] in ('config', 'bundle'):
- command = TopLevelCommand(None)
- handler(command, options, command_options)
- return
-
- project = project_from_options('.', options)
- command = TopLevelCommand(project)
- with errors.handle_connection_errors(project.client):
- handler(command, command_options)
-
-
-def setup_logging():
- root_logger = logging.getLogger()
- root_logger.addHandler(console_handler)
- root_logger.setLevel(logging.DEBUG)
-
- # Disable requests logging
- logging.getLogger("requests").propagate = False
-
-
-def setup_console_handler(handler, verbose):
- if handler.stream.isatty():
- format_class = ConsoleWarningFormatter
- else:
- format_class = logging.Formatter
-
- if verbose:
- handler.setFormatter(format_class('%(name)s.%(funcName)s: %(message)s'))
- handler.setLevel(logging.DEBUG)
- else:
- handler.setFormatter(format_class())
- handler.setLevel(logging.INFO)
-
-
-# stolen from docopt master
-def parse_doc_section(name, source):
- pattern = re.compile('^([^\n]*' + name + '[^\n]*\n?(?:[ \t].*?(?:\n|$))*)',
- re.IGNORECASE | re.MULTILINE)
- return [s.strip() for s in pattern.findall(source)]
-
-
-class TopLevelCommand(object):
- """Define and run multi-container applications with Docker.
-
- Usage:
- docker-compose [-f <arg>...] [options] [COMMAND] [ARGS...]
- docker-compose -h|--help
-
- Options:
- -f, --file FILE Specify an alternate compose file (default: docker-compose.yml)
- -p, --project-name NAME Specify an alternate project name (default: directory name)
- --verbose Show more output
- -v, --version Print version and exit
- -H, --host HOST Daemon socket to connect to
-
- --tls Use TLS; implied by --tlsverify
- --tlscacert CA_PATH Trust certs signed only by this CA
- --tlscert CLIENT_CERT_PATH Path to TLS certificate file
- --tlskey TLS_KEY_PATH Path to TLS key file
- --tlsverify Use TLS and verify the remote
- --skip-hostname-check Don't check the daemon's hostname against the name specified
- in the client certificate (for example if your docker host
- is an IP address)
-
- Commands:
- build Build or rebuild services
- bundle Generate a Docker bundle from the Compose file
- config Validate and view the compose file
- create Create services
- down Stop and remove containers, networks, images, and volumes
- events Receive real time events from containers
- exec Execute a command in a running container
- help Get help on a command
- kill Kill containers
- logs View output from containers
- pause Pause services
- port Print the public port for a port binding
- ps List containers
- pull Pulls service images
- push Push service images
- restart Restart services
- rm Remove stopped containers
- run Run a one-off command
- scale Set number of containers for a service
- start Start services
- stop Stop services
- unpause Unpause services
- up Create and start containers
- version Show the Docker-Compose version information
- """
-
- def __init__(self, project, project_dir='.'):
- self.project = project
- self.project_dir = '.'
-
- def build(self, options):
- """
- Build or rebuild services.
-
- Services are built once and then tagged as `project_service`,
- e.g. `composetest_db`. If you change a service's `Dockerfile` or the
- contents of its build directory, you can run `docker-compose build` to rebuild it.
-
- Usage: build [options] [SERVICE...]
-
- Options:
- --force-rm Always remove intermediate containers.
- --no-cache Do not use cache when building the image.
- --pull Always attempt to pull a newer version of the image.
- """
- self.project.build(
- service_names=options['SERVICE'],
- no_cache=bool(options.get('--no-cache', False)),
- pull=bool(options.get('--pull', False)),
- force_rm=bool(options.get('--force-rm', False)))
-
- def bundle(self, config_options, options):
- """
- Generate a Distributed Application Bundle (DAB) from the Compose file.
-
- Images must have digests stored, which requires interaction with a
- Docker registry. If digests aren't stored for all images, you can fetch
- them with `docker-compose pull` or `docker-compose push`. To push images
- automatically when bundling, pass `--push-images`. Only services with
- a `build` option specified will have their images pushed.
-
- Usage: bundle [options]
-
- Options:
- --push-images Automatically push images for any services
- which have a `build` option specified.
-
- -o, --output PATH Path to write the bundle file to.
- Defaults to "<project name>.dab".
- """
- self.project = project_from_options('.', config_options)
- compose_config = get_config_from_options(self.project_dir, config_options)
-
- output = options["--output"]
- if not output:
- output = "{}.dab".format(self.project.name)
-
- with errors.handle_connection_errors(self.project.client):
- try:
- image_digests = get_image_digests(
- self.project,
- allow_push=options['--push-images'],
- )
- except MissingDigests as e:
- def list_images(images):
- return "\n".join(" {}".format(name) for name in sorted(images))
-
- paras = ["Some images are missing digests."]
-
- if e.needs_push:
- command_hint = (
- "Use `docker-compose push {}` to push them. "
- "You can do this automatically with `docker-compose bundle --push-images`."
- .format(" ".join(sorted(e.needs_push)))
- )
- paras += [
- "The following images can be pushed:",
- list_images(e.needs_push),
- command_hint,
- ]
-
- if e.needs_pull:
- command_hint = (
- "Use `docker-compose pull {}` to pull them. "
- .format(" ".join(sorted(e.needs_pull)))
- )
-
- paras += [
- "The following images need to be pulled:",
- list_images(e.needs_pull),
- command_hint,
- ]
-
- raise UserError("\n\n".join(paras))
-
- with open(output, 'w') as f:
- f.write(serialize_bundle(compose_config, image_digests))
-
- log.info("Wrote bundle to {}".format(output))
-
- def config(self, config_options, options):
- """
- Validate and view the compose file.
-
- Usage: config [options]
-
- Options:
- -q, --quiet Only validate the configuration, don't print
- anything.
- --services Print the service names, one per line.
-
- """
- compose_config = get_config_from_options(self.project_dir, config_options)
-
- if options['--quiet']:
- return
-
- if options['--services']:
- print('\n'.join(service['name'] for service in compose_config.services))
- return
-
- print(serialize_config(compose_config))
-
- def create(self, options):
- """
- Creates containers for a service.
-
- Usage: create [options] [SERVICE...]
-
- Options:
- --force-recreate Recreate containers even if their configuration and
- image haven't changed. Incompatible with --no-recreate.
- --no-recreate If containers already exist, don't recreate them.
- Incompatible with --force-recreate.
- --no-build Don't build an image, even if it's missing.
- --build Build images before creating containers.
- """
- service_names = options['SERVICE']
-
- self.project.create(
- service_names=service_names,
- strategy=convergence_strategy_from_opts(options),
- do_build=build_action_from_opts(options),
- )
-
- def down(self, options):
- """
- Stops containers and removes containers, networks, volumes, and images
- created by `up`.
-
- By default, the only things removed are:
-
- - Containers for services defined in the Compose file
- - Networks defined in the `networks` section of the Compose file
- - The default network, if one is used
-
- Networks and volumes defined as `external` are never removed.
-
- Usage: down [options]
-
- Options:
- --rmi type Remove images. Type must be one of:
- 'all': Remove all images used by any service.
- 'local': Remove only images that don't have a custom tag
- set by the `image` field.
- -v, --volumes Remove named volumes declared in the `volumes` section
- of the Compose file and anonymous volumes
- attached to containers.
- --remove-orphans Remove containers for services not defined in the
- Compose file
- """
- image_type = image_type_from_opt('--rmi', options['--rmi'])
- self.project.down(image_type, options['--volumes'], options['--remove-orphans'])
-
- def events(self, options):
- """
- Receive real time events from containers.
-
- Usage: events [options] [SERVICE...]
-
- Options:
- --json Output events as a stream of json objects
- """
- def format_event(event):
- attributes = ["%s=%s" % item for item in event['attributes'].items()]
- return ("{time} {type} {action} {id} ({attrs})").format(
- attrs=", ".join(sorted(attributes)),
- **event)
-
- def json_format_event(event):
- event['time'] = event['time'].isoformat()
- event.pop('container')
- return json.dumps(event)
-
- for event in self.project.events():
- formatter = json_format_event if options['--json'] else format_event
- print(formatter(event))
- sys.stdout.flush()
-
- def exec_command(self, options):
- """
- Execute a command in a running container
-
- Usage: exec [options] SERVICE COMMAND [ARGS...]
-
- Options:
- -d Detached mode: Run command in the background.
- --privileged Give extended privileges to the process.
- --user USER Run the command as this user.
- -T Disable pseudo-tty allocation. By default `docker-compose exec`
- allocates a TTY.
- --index=index index of the container if there are multiple
- instances of a service [default: 1]
- """
- index = int(options.get('--index'))
- service = self.project.get_service(options['SERVICE'])
- detach = options['-d']
-
- if IS_WINDOWS_PLATFORM and not detach:
- raise UserError(
- "Interactive mode is not yet supported on Windows.\n"
- "Please pass the -d flag when using `docker-compose exec`."
- )
- try:
- container = service.get_container(number=index)
- except ValueError as e:
- raise UserError(str(e))
- command = [options['COMMAND']] + options['ARGS']
- tty = not options["-T"]
-
- create_exec_options = {
- "privileged": options["--privileged"],
- "user": options["--user"],
- "tty": tty,
- "stdin": tty,
- }
-
- exec_id = container.create_exec(command, **create_exec_options)
-
- if detach:
- container.start_exec(exec_id, tty=tty)
- return
-
- signals.set_signal_handler_to_shutdown()
- try:
- operation = ExecOperation(
- self.project.client,
- exec_id,
- interactive=tty,
- )
- pty = PseudoTerminal(self.project.client, operation)
- pty.start()
- except signals.ShutdownException:
- log.info("received shutdown exception: closing")
- exit_code = self.project.client.exec_inspect(exec_id).get("ExitCode")
- sys.exit(exit_code)
-
- @classmethod
- def help(cls, options):
- """
- Get help on a command.
-
- Usage: help [COMMAND]
- """
- if options['COMMAND']:
- subject = get_handler(cls, options['COMMAND'])
- else:
- subject = cls
-
- print(getdoc(subject))
-
- def kill(self, options):
- """
- Force stop service containers.
-
- Usage: kill [options] [SERVICE...]
-
- Options:
- -s SIGNAL SIGNAL to send to the container.
- Default signal is SIGKILL.
- """
- signal = options.get('-s', 'SIGKILL')
-
- self.project.kill(service_names=options['SERVICE'], signal=signal)
-
- def logs(self, options):
- """
- View output from containers.
-
- Usage: logs [options] [SERVICE...]
-
- Options:
- --no-color Produce monochrome output.
- -f, --follow Follow log output.
- -t, --timestamps Show timestamps.
- --tail="all" Number of lines to show from the end of the logs
- for each container.
- """
- containers = self.project.containers(service_names=options['SERVICE'], stopped=True)
-
- tail = options['--tail']
- if tail is not None:
- if tail.isdigit():
- tail = int(tail)
- elif tail != 'all':
- raise UserError("tail flag must be all or a number")
- log_args = {
- 'follow': options['--follow'],
- 'tail': tail,
- 'timestamps': options['--timestamps']
- }
- print("Attaching to", list_containers(containers))
- log_printer_from_project(
- self.project,
- containers,
- options['--no-color'],
- log_args,
- event_stream=self.project.events(service_names=options['SERVICE'])).run()
-
- def pause(self, options):
- """
- Pause services.
-
- Usage: pause [SERVICE...]
- """
- containers = self.project.pause(service_names=options['SERVICE'])
- exit_if(not containers, 'No containers to pause', 1)
-
- def port(self, options):
- """
- Print the public port for a port binding.
-
- Usage: port [options] SERVICE PRIVATE_PORT
-
- Options:
- --protocol=proto tcp or udp [default: tcp]
- --index=index index of the container if there are multiple
- instances of a service [default: 1]
- """
- index = int(options.get('--index'))
- service = self.project.get_service(options['SERVICE'])
- try:
- container = service.get_container(number=index)
- except ValueError as e:
- raise UserError(str(e))
- print(container.get_local_port(
- options['PRIVATE_PORT'],
- protocol=options.get('--protocol') or 'tcp') or '')
-
- def ps(self, options):
- """
- List containers.
-
- Usage: ps [options] [SERVICE...]
-
- Options:
- -q Only display IDs
- """
- containers = sorted(
- self.project.containers(service_names=options['SERVICE'], stopped=True) +
- self.project.containers(service_names=options['SERVICE'], one_off=OneOffFilter.only),
- key=attrgetter('name'))
-
- if options['-q']:
- for container in containers:
- print(container.id)
- else:
- headers = [
- 'Name',
- 'Command',
- 'State',
- 'Ports',
- ]
- rows = []
- for container in containers:
- command = container.human_readable_command
- if len(command) > 30:
- command = '%s ...' % command[:26]
- rows.append([
- container.name,
- command,
- container.human_readable_state,
- container.human_readable_ports,
- ])
- print(Formatter().table(headers, rows))
-
- def pull(self, options):
- """
- Pulls images for services.
-
- Usage: pull [options] [SERVICE...]
-
- Options:
- --ignore-pull-failures Pull what it can and ignores images with pull failures.
- """
- self.project.pull(
- service_names=options['SERVICE'],
- ignore_pull_failures=options.get('--ignore-pull-failures')
- )
-
- def push(self, options):
- """
- Pushes images for services.
-
- Usage: push [options] [SERVICE...]
-
- Options:
- --ignore-push-failures Push what it can and ignores images with push failures.
- """
- self.project.push(
- service_names=options['SERVICE'],
- ignore_push_failures=options.get('--ignore-push-failures')
- )
-
- def rm(self, options):
- """
- Removes stopped service containers.
-
- By default, anonymous volumes attached to containers will not be removed. You
- can override this with `-v`. To list all volumes, use `docker volume ls`.
-
- Any data which is not in a volume will be lost.
-
- Usage: rm [options] [SERVICE...]
-
- Options:
- -f, --force Don't ask to confirm removal
- -v Remove any anonymous volumes attached to containers
- -a, --all Obsolete. Also remove one-off containers created by
- docker-compose run
- """
- if options.get('--all'):
- log.warn(
- '--all flag is obsolete. This is now the default behavior '
- 'of `docker-compose rm`'
- )
- one_off = OneOffFilter.include
-
- all_containers = self.project.containers(
- service_names=options['SERVICE'], stopped=True, one_off=one_off
- )
- stopped_containers = [c for c in all_containers if not c.is_running]
-
- if len(stopped_containers) > 0:
- print("Going to remove", list_containers(stopped_containers))
- if options.get('--force') \
- or yesno("Are you sure? [yN] ", default=False):
- self.project.remove_stopped(
- service_names=options['SERVICE'],
- v=options.get('-v', False),
- one_off=one_off
- )
- else:
- print("No stopped containers")
-
- def run(self, options):
- """
- Run a one-off command on a service.
-
- For example:
-
- $ docker-compose run web python manage.py shell
-
- By default, linked services will be started, unless they are already
- running. If you do not want to start linked services, use
- `docker-compose run --no-deps SERVICE COMMAND [ARGS...]`.
-
- Usage: run [options] [-p PORT...] [-e KEY=VAL...] SERVICE [COMMAND] [ARGS...]
-
- Options:
- -d Detached mode: Run container in the background, print
- new container name.
- --name NAME Assign a name to the container
- --entrypoint CMD Override the entrypoint of the image.
- -e KEY=VAL Set an environment variable (can be used multiple times)
- -u, --user="" Run as specified username or uid
- --no-deps Don't start linked services.
- --rm Remove container after run. Ignored in detached mode.
- -p, --publish=[] Publish a container's port(s) to the host
- --service-ports Run command with the service's ports enabled and mapped
- to the host.
- -T Disable pseudo-tty allocation. By default `docker-compose run`
- allocates a TTY.
- -w, --workdir="" Working directory inside the container
- """
- service = self.project.get_service(options['SERVICE'])
- detach = options['-d']
-
- if IS_WINDOWS_PLATFORM and not detach:
- raise UserError(
- "Interactive mode is not yet supported on Windows.\n"
- "Please pass the -d flag when using `docker-compose run`."
- )
-
- if options['--publish'] and options['--service-ports']:
- raise UserError(
- 'Service port mapping and manual port mapping '
- 'can not be used togather'
- )
-
- if options['COMMAND'] is not None:
- command = [options['COMMAND']] + options['ARGS']
- elif options['--entrypoint'] is not None:
- command = []
- else:
- command = service.options.get('command')
-
- container_options = build_container_options(options, detach, command)
- run_one_off_container(container_options, self.project, service, options)
-
- def scale(self, options):
- """
- Set number of containers to run for a service.
-
- Numbers are specified in the form `service=num` as arguments.
- For example:
-
- $ docker-compose scale web=2 worker=3
-
- Usage: scale [options] [SERVICE=NUM...]
-
- Options:
- -t, --timeout TIMEOUT Specify a shutdown timeout in seconds.
- (default: 10)
- """
- timeout = int(options.get('--timeout') or DEFAULT_TIMEOUT)
-
- for s in options['SERVICE=NUM']:
- if '=' not in s:
- raise UserError('Arguments to scale should be in the form service=num')
- service_name, num = s.split('=', 1)
- try:
- num = int(num)
- except ValueError:
- raise UserError('Number of containers for service "%s" is not a '
- 'number' % service_name)
- self.project.get_service(service_name).scale(num, timeout=timeout)
-
- def start(self, options):
- """
- Start existing containers.
-
- Usage: start [SERVICE...]
- """
- containers = self.project.start(service_names=options['SERVICE'])
- exit_if(not containers, 'No containers to start', 1)
-
- def stop(self, options):
- """
- Stop running containers without removing them.
-
- They can be started again with `docker-compose start`.
-
- Usage: stop [options] [SERVICE...]
-
- Options:
- -t, --timeout TIMEOUT Specify a shutdown timeout in seconds.
- (default: 10)
- """
- timeout = int(options.get('--timeout') or DEFAULT_TIMEOUT)
- self.project.stop(service_names=options['SERVICE'], timeout=timeout)
-
- def restart(self, options):
- """
- Restart running containers.
-
- Usage: restart [options] [SERVICE...]
-
- Options:
- -t, --timeout TIMEOUT Specify a shutdown timeout in seconds.
- (default: 10)
- """
- timeout = int(options.get('--timeout') or DEFAULT_TIMEOUT)
- containers = self.project.restart(service_names=options['SERVICE'], timeout=timeout)
- exit_if(not containers, 'No containers to restart', 1)
-
- def unpause(self, options):
- """
- Unpause services.
-
- Usage: unpause [SERVICE...]
- """
- containers = self.project.unpause(service_names=options['SERVICE'])
- exit_if(not containers, 'No containers to unpause', 1)
-
- def up(self, options):
- """
- Builds, (re)creates, starts, and attaches to containers for a service.
-
- Unless they are already running, this command also starts any linked services.
-
- The `docker-compose up` command aggregates the output of each container. When
- the command exits, all containers are stopped. Running `docker-compose up -d`
- starts the containers in the background and leaves them running.
-
- If there are existing containers for a service, and the service's configuration
- or image was changed after the container's creation, `docker-compose up` picks
- up the changes by stopping and recreating the containers (preserving mounted
- volumes). To prevent Compose from picking up changes, use the `--no-recreate`
- flag.
-
- If you want to force Compose to stop and recreate all containers, use the
- `--force-recreate` flag.
-
- Usage: up [options] [SERVICE...]
-
- Options:
- -d Detached mode: Run containers in the background,
- print new container names.
- Incompatible with --abort-on-container-exit.
- --no-color Produce monochrome output.
- --no-deps Don't start linked services.
- --force-recreate Recreate containers even if their configuration
- and image haven't changed.
- Incompatible with --no-recreate.
- --no-recreate If containers already exist, don't recreate them.
- Incompatible with --force-recreate.
- --no-build Don't build an image, even if it's missing.
- --build Build images before starting containers.
- --abort-on-container-exit Stops all containers if any container was stopped.
- Incompatible with -d.
- -t, --timeout TIMEOUT Use this timeout in seconds for container shutdown
- when attached or when containers are already
- running. (default: 10)
- --remove-orphans Remove containers for services not
- defined in the Compose file
- """
- start_deps = not options['--no-deps']
- cascade_stop = options['--abort-on-container-exit']
- service_names = options['SERVICE']
- timeout = int(options.get('--timeout') or DEFAULT_TIMEOUT)
- remove_orphans = options['--remove-orphans']
- detached = options.get('-d')
-
- if detached and cascade_stop:
- raise UserError("--abort-on-container-exit and -d cannot be combined.")
-
- with up_shutdown_context(self.project, service_names, timeout, detached):
- to_attach = self.project.up(
- service_names=service_names,
- start_deps=start_deps,
- strategy=convergence_strategy_from_opts(options),
- do_build=build_action_from_opts(options),
- timeout=timeout,
- detached=detached,
- remove_orphans=remove_orphans)
-
- if detached:
- return
-
- log_printer = log_printer_from_project(
- self.project,
- filter_containers_to_service_names(to_attach, service_names),
- options['--no-color'],
- {'follow': True},
- cascade_stop,
- event_stream=self.project.events(service_names=service_names))
- print("Attaching to", list_containers(log_printer.containers))
- log_printer.run()
-
- if cascade_stop:
- print("Aborting on container exit...")
- self.project.stop(service_names=service_names, timeout=timeout)
-
- @classmethod
- def version(cls, options):
- """
- Show version informations
-
- Usage: version [--short]
-
- Options:
- --short Shows only Compose's version number.
- """
- if options['--short']:
- print(__version__)
- else:
- print(get_version_info('full'))
-
-
-def convergence_strategy_from_opts(options):
- no_recreate = options['--no-recreate']
- force_recreate = options['--force-recreate']
- if force_recreate and no_recreate:
- raise UserError("--force-recreate and --no-recreate cannot be combined.")
-
- if force_recreate:
- return ConvergenceStrategy.always
-
- if no_recreate:
- return ConvergenceStrategy.never
-
- return ConvergenceStrategy.changed
-
-
-def image_type_from_opt(flag, value):
- if not value:
- return ImageType.none
- try:
- return ImageType[value]
- except KeyError:
- raise UserError("%s flag must be one of: all, local" % flag)
-
-
-def build_action_from_opts(options):
- if options['--build'] and options['--no-build']:
- raise UserError("--build and --no-build can not be combined.")
-
- if options['--build']:
- return BuildAction.force
-
- if options['--no-build']:
- return BuildAction.skip
-
- return BuildAction.none
-
-
-def build_container_options(options, detach, command):
- container_options = {
- 'command': command,
- 'tty': not (detach or options['-T'] or not sys.stdin.isatty()),
- 'stdin_open': not detach,
- 'detach': detach,
- }
-
- if options['-e']:
- container_options['environment'] = Environment.from_command_line(
- parse_environment(options['-e'])
- )
-
- if options['--entrypoint']:
- container_options['entrypoint'] = options.get('--entrypoint')
-
- if options['--rm']:
- container_options['restart'] = None
-
- if options['--user']:
- container_options['user'] = options.get('--user')
-
- if not options['--service-ports']:
- container_options['ports'] = []
-
- if options['--publish']:
- container_options['ports'] = options.get('--publish')
-
- if options['--name']:
- container_options['name'] = options['--name']
-
- if options['--workdir']:
- container_options['working_dir'] = options['--workdir']
-
- return container_options
-
-
-def run_one_off_container(container_options, project, service, options):
- if not options['--no-deps']:
- deps = service.get_dependency_names()
- if deps:
- project.up(
- service_names=deps,
- start_deps=True,
- strategy=ConvergenceStrategy.never)
-
- project.initialize()
-
- container = service.create_container(
- quiet=True,
- one_off=True,
- **container_options)
-
- if options['-d']:
- service.start_container(container)
- print(container.name)
- return
-
- def remove_container(force=False):
- if options['--rm']:
- project.client.remove_container(container.id, force=True)
-
- signals.set_signal_handler_to_shutdown()
- try:
- try:
- operation = RunOperation(
- project.client,
- container.id,
- interactive=not options['-T'],
- logs=False,
- )
- pty = PseudoTerminal(project.client, operation)
- sockets = pty.sockets()
- service.start_container(container)
- pty.start(sockets)
- exit_code = container.wait()
- except signals.ShutdownException:
- project.client.stop(container.id)
- exit_code = 1
- except signals.ShutdownException:
- project.client.kill(container.id)
- remove_container(force=True)
- sys.exit(2)
-
- remove_container()
- sys.exit(exit_code)
-
-
-def log_printer_from_project(
- project,
- containers,
- monochrome,
- log_args,
- cascade_stop=False,
- event_stream=None,
-):
- return LogPrinter(
- containers,
- build_log_presenters(project.service_names, monochrome),
- event_stream or project.events(),
- cascade_stop=cascade_stop,
- log_args=log_args)
-
-
-def filter_containers_to_service_names(containers, service_names):
- if not service_names:
- return containers
-
- return [
- container
- for container in containers if container.service in service_names
- ]
-
-
-@contextlib.contextmanager
-def up_shutdown_context(project, service_names, timeout, detached):
- if detached:
- yield
- return
-
- signals.set_signal_handler_to_shutdown()
- try:
- try:
- yield
- except signals.ShutdownException:
- print("Gracefully stopping... (press Ctrl+C again to force)")
- project.stop(service_names=service_names, timeout=timeout)
- except signals.ShutdownException:
- project.kill(service_names=service_names)
- sys.exit(2)
-
-
-def list_containers(containers):
- return ", ".join(c.name for c in containers)
-
-
-def exit_if(condition, message, exit_code):
- if condition:
- log.error(message)
- raise SystemExit(exit_code)
http://git-wip-us.apache.org/repos/asf/incubator-senssoft-tap/blob/6a81d1e7/env2/lib/python2.7/site-packages/compose/cli/signals.py
----------------------------------------------------------------------
diff --git a/env2/lib/python2.7/site-packages/compose/cli/signals.py b/env2/lib/python2.7/site-packages/compose/cli/signals.py
deleted file mode 100644
index 68a0598..0000000
--- a/env2/lib/python2.7/site-packages/compose/cli/signals.py
+++ /dev/null
@@ -1,21 +0,0 @@
-from __future__ import absolute_import
-from __future__ import unicode_literals
-
-import signal
-
-
-class ShutdownException(Exception):
- pass
-
-
-def shutdown(signal, frame):
- raise ShutdownException()
-
-
-def set_signal_handler(handler):
- signal.signal(signal.SIGINT, handler)
- signal.signal(signal.SIGTERM, handler)
-
-
-def set_signal_handler_to_shutdown():
- set_signal_handler(shutdown)
http://git-wip-us.apache.org/repos/asf/incubator-senssoft-tap/blob/6a81d1e7/env2/lib/python2.7/site-packages/compose/cli/utils.py
----------------------------------------------------------------------
diff --git a/env2/lib/python2.7/site-packages/compose/cli/utils.py b/env2/lib/python2.7/site-packages/compose/cli/utils.py
deleted file mode 100644
index f60f61c..0000000
--- a/env2/lib/python2.7/site-packages/compose/cli/utils.py
+++ /dev/null
@@ -1,124 +0,0 @@
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import unicode_literals
-
-import os
-import platform
-import ssl
-import subprocess
-import sys
-
-import docker
-
-import compose
-
-# WindowsError is not defined on non-win32 platforms. Avoid runtime errors by
-# defining it as OSError (its parent class) if missing.
-try:
- WindowsError
-except NameError:
- WindowsError = OSError
-
-
-def yesno(prompt, default=None):
- """
- Prompt the user for a yes or no.
-
- Can optionally specify a default value, which will only be
- used if they enter a blank line.
-
- Unrecognised input (anything other than "y", "n", "yes",
- "no" or "") will return None.
- """
- answer = input(prompt).strip().lower()
-
- if answer == "y" or answer == "yes":
- return True
- elif answer == "n" or answer == "no":
- return False
- elif answer == "":
- return default
- else:
- return None
-
-
-def input(prompt):
- """
- Version of input (raw_input in Python 2) which forces a flush of sys.stdout
- to avoid problems where the prompt fails to appear due to line buffering
- """
- sys.stdout.write(prompt)
- sys.stdout.flush()
- return sys.stdin.readline().rstrip('\n')
-
-
-def call_silently(*args, **kwargs):
- """
- Like subprocess.call(), but redirects stdout and stderr to /dev/null.
- """
- with open(os.devnull, 'w') as shutup:
- try:
- return subprocess.call(*args, stdout=shutup, stderr=shutup, **kwargs)
- except WindowsError:
- # On Windows, subprocess.call() can still raise exceptions. Normalize
- # to POSIXy behaviour by returning a nonzero exit code.
- return 1
-
-
-def is_mac():
- return platform.system() == 'Darwin'
-
-
-def is_ubuntu():
- return platform.system() == 'Linux' and platform.linux_distribution()[0] == 'Ubuntu'
-
-
-def get_version_info(scope):
- versioninfo = 'docker-compose version {}, build {}'.format(
- compose.__version__,
- get_build_version())
-
- if scope == 'compose':
- return versioninfo
- if scope == 'full':
- return (
- "{}\n"
- "docker-py version: {}\n"
- "{} version: {}\n"
- "OpenSSL version: {}"
- ).format(
- versioninfo,
- docker.version,
- platform.python_implementation(),
- platform.python_version(),
- ssl.OPENSSL_VERSION)
-
- raise ValueError("{} is not a valid version scope".format(scope))
-
-
-def get_build_version():
- filename = os.path.join(os.path.dirname(compose.__file__), 'GITSHA')
- if not os.path.exists(filename):
- return 'unknown'
-
- with open(filename) as fh:
- return fh.read().strip()
-
-
-def is_docker_for_mac_installed():
- return is_mac() and os.path.isdir('/Applications/Docker.app')
-
-
-def generate_user_agent():
- parts = [
- "docker-compose/{}".format(compose.__version__),
- "docker-py/{}".format(docker.__version__),
- ]
- try:
- p_system = platform.system()
- p_release = platform.release()
- except IOError:
- pass
- else:
- parts.append("{}/{}".format(p_system, p_release))
- return " ".join(parts)
http://git-wip-us.apache.org/repos/asf/incubator-senssoft-tap/blob/6a81d1e7/env2/lib/python2.7/site-packages/compose/cli/verbose_proxy.py
----------------------------------------------------------------------
diff --git a/env2/lib/python2.7/site-packages/compose/cli/verbose_proxy.py b/env2/lib/python2.7/site-packages/compose/cli/verbose_proxy.py
deleted file mode 100644
index b1592ea..0000000
--- a/env2/lib/python2.7/site-packages/compose/cli/verbose_proxy.py
+++ /dev/null
@@ -1,60 +0,0 @@
-from __future__ import absolute_import
-from __future__ import unicode_literals
-
-import functools
-import logging
-import pprint
-from itertools import chain
-
-import six
-
-
-def format_call(args, kwargs):
- args = (repr(a) for a in args)
- kwargs = ("{0!s}={1!r}".format(*item) for item in six.iteritems(kwargs))
- return "({0})".format(", ".join(chain(args, kwargs)))
-
-
-def format_return(result, max_lines):
- if isinstance(result, (list, tuple, set)):
- return "({0} with {1} items)".format(type(result).__name__, len(result))
-
- if result:
- lines = pprint.pformat(result).split('\n')
- extra = '\n...' if len(lines) > max_lines else ''
- return '\n'.join(lines[:max_lines]) + extra
-
- return result
-
-
-class VerboseProxy(object):
- """Proxy all function calls to another class and log method name, arguments
- and return values for each call.
- """
-
- def __init__(self, obj_name, obj, log_name=None, max_lines=10):
- self.obj_name = obj_name
- self.obj = obj
- self.max_lines = max_lines
- self.log = logging.getLogger(log_name or __name__)
-
- def __getattr__(self, name):
- attr = getattr(self.obj, name)
-
- if not six.callable(attr):
- return attr
-
- return functools.partial(self.proxy_callable, name)
-
- def proxy_callable(self, call_name, *args, **kwargs):
- self.log.info("%s %s <- %s",
- self.obj_name,
- call_name,
- format_call(args, kwargs))
-
- result = getattr(self.obj, call_name)(*args, **kwargs)
- self.log.info("%s %s -> %s",
- self.obj_name,
- call_name,
- format_return(result, self.max_lines))
- return result
http://git-wip-us.apache.org/repos/asf/incubator-senssoft-tap/blob/6a81d1e7/env2/lib/python2.7/site-packages/compose/config/__init__.py
----------------------------------------------------------------------
diff --git a/env2/lib/python2.7/site-packages/compose/config/__init__.py b/env2/lib/python2.7/site-packages/compose/config/__init__.py
deleted file mode 100644
index 7cf71eb..0000000
--- a/env2/lib/python2.7/site-packages/compose/config/__init__.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# flake8: noqa
-from __future__ import absolute_import
-from __future__ import unicode_literals
-
-from . import environment
-from .config import ConfigurationError
-from .config import DOCKER_CONFIG_KEYS
-from .config import find
-from .config import load
-from .config import merge_environment
-from .config import parse_environment
http://git-wip-us.apache.org/repos/asf/incubator-senssoft-tap/blob/6a81d1e7/env2/lib/python2.7/site-packages/compose/config/config.py
----------------------------------------------------------------------
diff --git a/env2/lib/python2.7/site-packages/compose/config/config.py b/env2/lib/python2.7/site-packages/compose/config/config.py
deleted file mode 100644
index 7a2b3d3..0000000
--- a/env2/lib/python2.7/site-packages/compose/config/config.py
+++ /dev/null
@@ -1,997 +0,0 @@
-from __future__ import absolute_import
-from __future__ import unicode_literals
-
-import functools
-import logging
-import ntpath
-import os
-import string
-import sys
-from collections import namedtuple
-
-import six
-import yaml
-from cached_property import cached_property
-
-from ..const import COMPOSEFILE_V1 as V1
-from ..const import COMPOSEFILE_V2_0 as V2_0
-from ..utils import build_string_dict
-from .environment import env_vars_from_file
-from .environment import Environment
-from .environment import split_env
-from .errors import CircularReference
-from .errors import ComposeFileNotFound
-from .errors import ConfigurationError
-from .errors import VERSION_EXPLANATION
-from .interpolation import interpolate_environment_variables
-from .sort_services import get_container_name_from_network_mode
-from .sort_services import get_service_name_from_network_mode
-from .sort_services import sort_service_dicts
-from .types import parse_extra_hosts
-from .types import parse_restart_spec
-from .types import ServiceLink
-from .types import VolumeFromSpec
-from .types import VolumeSpec
-from .validation import match_named_volumes
-from .validation import validate_against_config_schema
-from .validation import validate_config_section
-from .validation import validate_depends_on
-from .validation import validate_extends_file_path
-from .validation import validate_links
-from .validation import validate_network_mode
-from .validation import validate_service_constraints
-from .validation import validate_top_level_object
-from .validation import validate_ulimits
-
-
-DOCKER_CONFIG_KEYS = [
- 'cap_add',
- 'cap_drop',
- 'cgroup_parent',
- 'command',
- 'cpu_quota',
- 'cpu_shares',
- 'cpuset',
- 'detach',
- 'devices',
- 'dns',
- 'dns_search',
- 'domainname',
- 'entrypoint',
- 'env_file',
- 'environment',
- 'extra_hosts',
- 'hostname',
- 'image',
- 'ipc',
- 'labels',
- 'links',
- 'mac_address',
- 'mem_limit',
- 'memswap_limit',
- 'net',
- 'pid',
- 'ports',
- 'privileged',
- 'read_only',
- 'restart',
- 'security_opt',
- 'shm_size',
- 'stdin_open',
- 'stop_signal',
- 'tty',
- 'user',
- 'volume_driver',
- 'volumes',
- 'volumes_from',
- 'working_dir',
-]
-
-ALLOWED_KEYS = DOCKER_CONFIG_KEYS + [
- 'build',
- 'container_name',
- 'dockerfile',
- 'log_driver',
- 'log_opt',
- 'logging',
- 'network_mode',
-]
-
-DOCKER_VALID_URL_PREFIXES = (
- 'http://',
- 'https://',
- 'git://',
- 'github.com/',
- 'git@',
-)
-
-SUPPORTED_FILENAMES = [
- 'docker-compose.yml',
- 'docker-compose.yaml',
-]
-
-DEFAULT_OVERRIDE_FILENAME = 'docker-compose.override.yml'
-
-
-log = logging.getLogger(__name__)
-
-
-class ConfigDetails(namedtuple('_ConfigDetails', 'working_dir config_files environment')):
- """
- :param working_dir: the directory to use for relative paths in the config
- :type working_dir: string
- :param config_files: list of configuration files to load
- :type config_files: list of :class:`ConfigFile`
- :param environment: computed environment values for this project
- :type environment: :class:`environment.Environment`
- """
- def __new__(cls, working_dir, config_files, environment=None):
- if environment is None:
- environment = Environment.from_env_file(working_dir)
- return super(ConfigDetails, cls).__new__(
- cls, working_dir, config_files, environment
- )
-
-
-class ConfigFile(namedtuple('_ConfigFile', 'filename config')):
- """
- :param filename: filename of the config file
- :type filename: string
- :param config: contents of the config file
- :type config: :class:`dict`
- """
-
- @classmethod
- def from_filename(cls, filename):
- return cls(filename, load_yaml(filename))
-
- @cached_property
- def version(self):
- if 'version' not in self.config:
- return V1
-
- version = self.config['version']
-
- if isinstance(version, dict):
- log.warn('Unexpected type for "version" key in "{}". Assuming '
- '"version" is the name of a service, and defaulting to '
- 'Compose file version 1.'.format(self.filename))
- return V1
-
- if not isinstance(version, six.string_types):
- raise ConfigurationError(
- 'Version in "{}" is invalid - it should be a string.'
- .format(self.filename))
-
- if version == '1':
- raise ConfigurationError(
- 'Version in "{}" is invalid. {}'
- .format(self.filename, VERSION_EXPLANATION))
-
- if version == '2':
- version = V2_0
-
- if version != V2_0:
- raise ConfigurationError(
- 'Version in "{}" is unsupported. {}'
- .format(self.filename, VERSION_EXPLANATION))
-
- return version
-
- def get_service(self, name):
- return self.get_service_dicts()[name]
-
- def get_service_dicts(self):
- return self.config if self.version == V1 else self.config.get('services', {})
-
- def get_volumes(self):
- return {} if self.version == V1 else self.config.get('volumes', {})
-
- def get_networks(self):
- return {} if self.version == V1 else self.config.get('networks', {})
-
-
-class Config(namedtuple('_Config', 'version services volumes networks')):
- """
- :param version: configuration version
- :type version: int
- :param services: List of service description dictionaries
- :type services: :class:`list`
- :param volumes: Dictionary mapping volume names to description dictionaries
- :type volumes: :class:`dict`
- :param networks: Dictionary mapping network names to description dictionaries
- :type networks: :class:`dict`
- """
-
-
-class ServiceConfig(namedtuple('_ServiceConfig', 'working_dir filename name config')):
-
- @classmethod
- def with_abs_paths(cls, working_dir, filename, name, config):
- if not working_dir:
- raise ValueError("No working_dir for ServiceConfig.")
-
- return cls(
- os.path.abspath(working_dir),
- os.path.abspath(filename) if filename else filename,
- name,
- config)
-
-
-def find(base_dir, filenames, environment):
- if filenames == ['-']:
- return ConfigDetails(
- os.getcwd(),
- [ConfigFile(None, yaml.safe_load(sys.stdin))],
- environment
- )
-
- if filenames:
- filenames = [os.path.join(base_dir, f) for f in filenames]
- else:
- filenames = get_default_config_files(base_dir)
-
- log.debug("Using configuration files: {}".format(",".join(filenames)))
- return ConfigDetails(
- os.path.dirname(filenames[0]),
- [ConfigFile.from_filename(f) for f in filenames],
- environment
- )
-
-
-def validate_config_version(config_files):
- main_file = config_files[0]
- validate_top_level_object(main_file)
- for next_file in config_files[1:]:
- validate_top_level_object(next_file)
-
- if main_file.version != next_file.version:
- raise ConfigurationError(
- "Version mismatch: file {0} specifies version {1} but "
- "extension file {2} uses version {3}".format(
- main_file.filename,
- main_file.version,
- next_file.filename,
- next_file.version))
-
-
-def get_default_config_files(base_dir):
- (candidates, path) = find_candidates_in_parent_dirs(SUPPORTED_FILENAMES, base_dir)
-
- if not candidates:
- raise ComposeFileNotFound(SUPPORTED_FILENAMES)
-
- winner = candidates[0]
-
- if len(candidates) > 1:
- log.warn("Found multiple config files with supported names: %s", ", ".join(candidates))
- log.warn("Using %s\n", winner)
-
- return [os.path.join(path, winner)] + get_default_override_file(path)
-
-
-def get_default_override_file(path):
- override_filename = os.path.join(path, DEFAULT_OVERRIDE_FILENAME)
- return [override_filename] if os.path.exists(override_filename) else []
-
-
-def find_candidates_in_parent_dirs(filenames, path):
- """
- Given a directory path to start, looks for filenames in the
- directory, and then each parent directory successively,
- until found.
-
- Returns tuple (candidates, path).
- """
- candidates = [filename for filename in filenames
- if os.path.exists(os.path.join(path, filename))]
-
- if not candidates:
- parent_dir = os.path.join(path, '..')
- if os.path.abspath(parent_dir) != os.path.abspath(path):
- return find_candidates_in_parent_dirs(filenames, parent_dir)
-
- return (candidates, path)
-
-
-def load(config_details):
- """Load the configuration from a working directory and a list of
- configuration files. Files are loaded in order, and merged on top
- of each other to create the final configuration.
-
- Return a fully interpolated, extended and validated configuration.
- """
- validate_config_version(config_details.config_files)
-
- processed_files = [
- process_config_file(config_file, config_details.environment)
- for config_file in config_details.config_files
- ]
- config_details = config_details._replace(config_files=processed_files)
-
- main_file = config_details.config_files[0]
- volumes = load_mapping(
- config_details.config_files, 'get_volumes', 'Volume'
- )
- networks = load_mapping(
- config_details.config_files, 'get_networks', 'Network'
- )
- service_dicts = load_services(config_details, main_file)
-
- if main_file.version != V1:
- for service_dict in service_dicts:
- match_named_volumes(service_dict, volumes)
-
- return Config(main_file.version, service_dicts, volumes, networks)
-
-
-def load_mapping(config_files, get_func, entity_type):
- mapping = {}
-
- for config_file in config_files:
- for name, config in getattr(config_file, get_func)().items():
- mapping[name] = config or {}
- if not config:
- continue
-
- external = config.get('external')
- if external:
- if len(config.keys()) > 1:
- raise ConfigurationError(
- '{} {} declared as external but specifies'
- ' additional attributes ({}). '.format(
- entity_type,
- name,
- ', '.join([k for k in config.keys() if k != 'external'])
- )
- )
- if isinstance(external, dict):
- config['external_name'] = external.get('name')
- else:
- config['external_name'] = name
-
- mapping[name] = config
-
- if 'driver_opts' in config:
- config['driver_opts'] = build_string_dict(
- config['driver_opts']
- )
-
- return mapping
-
-
-def load_services(config_details, config_file):
- def build_service(service_name, service_dict, service_names):
- service_config = ServiceConfig.with_abs_paths(
- config_details.working_dir,
- config_file.filename,
- service_name,
- service_dict)
- resolver = ServiceExtendsResolver(
- service_config, config_file, environment=config_details.environment
- )
- service_dict = process_service(resolver.run())
-
- service_config = service_config._replace(config=service_dict)
- validate_service(service_config, service_names, config_file.version)
- service_dict = finalize_service(
- service_config,
- service_names,
- config_file.version,
- config_details.environment)
- return service_dict
-
- def build_services(service_config):
- service_names = service_config.keys()
- return sort_service_dicts([
- build_service(name, service_dict, service_names)
- for name, service_dict in service_config.items()
- ])
-
- def merge_services(base, override):
- all_service_names = set(base) | set(override)
- return {
- name: merge_service_dicts_from_files(
- base.get(name, {}),
- override.get(name, {}),
- config_file.version)
- for name in all_service_names
- }
-
- service_configs = [
- file.get_service_dicts() for file in config_details.config_files
- ]
-
- service_config = service_configs[0]
- for next_config in service_configs[1:]:
- service_config = merge_services(service_config, next_config)
-
- return build_services(service_config)
-
-
-def interpolate_config_section(filename, config, section, environment):
- validate_config_section(filename, config, section)
- return interpolate_environment_variables(config, section, environment)
-
-
-def process_config_file(config_file, environment, service_name=None):
- services = interpolate_config_section(
- config_file.filename,
- config_file.get_service_dicts(),
- 'service',
- environment,)
-
- if config_file.version == V2_0:
- processed_config = dict(config_file.config)
- processed_config['services'] = services
- processed_config['volumes'] = interpolate_config_section(
- config_file.filename,
- config_file.get_volumes(),
- 'volume',
- environment,)
- processed_config['networks'] = interpolate_config_section(
- config_file.filename,
- config_file.get_networks(),
- 'network',
- environment,)
-
- if config_file.version == V1:
- processed_config = services
-
- config_file = config_file._replace(config=processed_config)
- validate_against_config_schema(config_file)
-
- if service_name and service_name not in services:
- raise ConfigurationError(
- "Cannot extend service '{}' in {}: Service not found".format(
- service_name, config_file.filename))
-
- return config_file
-
-
-class ServiceExtendsResolver(object):
- def __init__(self, service_config, config_file, environment, already_seen=None):
- self.service_config = service_config
- self.working_dir = service_config.working_dir
- self.already_seen = already_seen or []
- self.config_file = config_file
- self.environment = environment
-
- @property
- def signature(self):
- return self.service_config.filename, self.service_config.name
-
- def detect_cycle(self):
- if self.signature in self.already_seen:
- raise CircularReference(self.already_seen + [self.signature])
-
- def run(self):
- self.detect_cycle()
-
- if 'extends' in self.service_config.config:
- service_dict = self.resolve_extends(*self.validate_and_construct_extends())
- return self.service_config._replace(config=service_dict)
-
- return self.service_config
-
- def validate_and_construct_extends(self):
- extends = self.service_config.config['extends']
- if not isinstance(extends, dict):
- extends = {'service': extends}
-
- config_path = self.get_extended_config_path(extends)
- service_name = extends['service']
-
- extends_file = ConfigFile.from_filename(config_path)
- validate_config_version([self.config_file, extends_file])
- extended_file = process_config_file(
- extends_file, self.environment, service_name=service_name
- )
- service_config = extended_file.get_service(service_name)
-
- return config_path, service_config, service_name
-
- def resolve_extends(self, extended_config_path, service_dict, service_name):
- resolver = ServiceExtendsResolver(
- ServiceConfig.with_abs_paths(
- os.path.dirname(extended_config_path),
- extended_config_path,
- service_name,
- service_dict),
- self.config_file,
- already_seen=self.already_seen + [self.signature],
- environment=self.environment
- )
-
- service_config = resolver.run()
- other_service_dict = process_service(service_config)
- validate_extended_service_dict(
- other_service_dict,
- extended_config_path,
- service_name)
-
- return merge_service_dicts(
- other_service_dict,
- self.service_config.config,
- self.config_file.version)
-
- def get_extended_config_path(self, extends_options):
- """Service we are extending either has a value for 'file' set, which we
- need to obtain a full path too or we are extending from a service
- defined in our own file.
- """
- filename = self.service_config.filename
- validate_extends_file_path(
- self.service_config.name,
- extends_options,
- filename)
- if 'file' in extends_options:
- return expand_path(self.working_dir, extends_options['file'])
- return filename
-
-
-def resolve_environment(service_dict, environment=None):
- """Unpack any environment variables from an env_file, if set.
- Interpolate environment values if set.
- """
- env = {}
- for env_file in service_dict.get('env_file', []):
- env.update(env_vars_from_file(env_file))
-
- env.update(parse_environment(service_dict.get('environment')))
- return dict(resolve_env_var(k, v, environment) for k, v in six.iteritems(env))
-
-
-def resolve_build_args(build, environment):
- args = parse_build_arguments(build.get('args'))
- return dict(resolve_env_var(k, v, environment) for k, v in six.iteritems(args))
-
-
-def validate_extended_service_dict(service_dict, filename, service):
- error_prefix = "Cannot extend service '%s' in %s:" % (service, filename)
-
- if 'links' in service_dict:
- raise ConfigurationError(
- "%s services with 'links' cannot be extended" % error_prefix)
-
- if 'volumes_from' in service_dict:
- raise ConfigurationError(
- "%s services with 'volumes_from' cannot be extended" % error_prefix)
-
- if 'net' in service_dict:
- if get_container_name_from_network_mode(service_dict['net']):
- raise ConfigurationError(
- "%s services with 'net: container' cannot be extended" % error_prefix)
-
- if 'network_mode' in service_dict:
- if get_service_name_from_network_mode(service_dict['network_mode']):
- raise ConfigurationError(
- "%s services with 'network_mode: service' cannot be extended" % error_prefix)
-
- if 'depends_on' in service_dict:
- raise ConfigurationError(
- "%s services with 'depends_on' cannot be extended" % error_prefix)
-
-
-def validate_service(service_config, service_names, version):
- service_dict, service_name = service_config.config, service_config.name
- validate_service_constraints(service_dict, service_name, version)
- validate_paths(service_dict)
-
- validate_ulimits(service_config)
- validate_network_mode(service_config, service_names)
- validate_depends_on(service_config, service_names)
- validate_links(service_config, service_names)
-
- if not service_dict.get('image') and has_uppercase(service_name):
- raise ConfigurationError(
- "Service '{name}' contains uppercase characters which are not valid "
- "as part of an image name. Either use a lowercase service name or "
- "use the `image` field to set a custom name for the service image."
- .format(name=service_name))
-
-
-def process_service(service_config):
- working_dir = service_config.working_dir
- service_dict = dict(service_config.config)
-
- if 'env_file' in service_dict:
- service_dict['env_file'] = [
- expand_path(working_dir, path)
- for path in to_list(service_dict['env_file'])
- ]
-
- if 'build' in service_dict:
- if isinstance(service_dict['build'], six.string_types):
- service_dict['build'] = resolve_build_path(working_dir, service_dict['build'])
- elif isinstance(service_dict['build'], dict) and 'context' in service_dict['build']:
- path = service_dict['build']['context']
- service_dict['build']['context'] = resolve_build_path(working_dir, path)
-
- if 'volumes' in service_dict and service_dict.get('volume_driver') is None:
- service_dict['volumes'] = resolve_volume_paths(working_dir, service_dict)
-
- if 'labels' in service_dict:
- service_dict['labels'] = parse_labels(service_dict['labels'])
-
- if 'extra_hosts' in service_dict:
- service_dict['extra_hosts'] = parse_extra_hosts(service_dict['extra_hosts'])
-
- for field in ['dns', 'dns_search', 'tmpfs']:
- if field in service_dict:
- service_dict[field] = to_list(service_dict[field])
-
- return service_dict
-
-
-def finalize_service(service_config, service_names, version, environment):
- service_dict = dict(service_config.config)
-
- if 'environment' in service_dict or 'env_file' in service_dict:
- service_dict['environment'] = resolve_environment(service_dict, environment)
- service_dict.pop('env_file', None)
-
- if 'volumes_from' in service_dict:
- service_dict['volumes_from'] = [
- VolumeFromSpec.parse(vf, service_names, version)
- for vf in service_dict['volumes_from']
- ]
-
- if 'volumes' in service_dict:
- service_dict['volumes'] = [
- VolumeSpec.parse(v) for v in service_dict['volumes']]
-
- if 'net' in service_dict:
- network_mode = service_dict.pop('net')
- container_name = get_container_name_from_network_mode(network_mode)
- if container_name and container_name in service_names:
- service_dict['network_mode'] = 'service:{}'.format(container_name)
- else:
- service_dict['network_mode'] = network_mode
-
- if 'networks' in service_dict:
- service_dict['networks'] = parse_networks(service_dict['networks'])
-
- if 'restart' in service_dict:
- service_dict['restart'] = parse_restart_spec(service_dict['restart'])
-
- normalize_build(service_dict, service_config.working_dir, environment)
-
- service_dict['name'] = service_config.name
- return normalize_v1_service_format(service_dict)
-
-
-def normalize_v1_service_format(service_dict):
- if 'log_driver' in service_dict or 'log_opt' in service_dict:
- if 'logging' not in service_dict:
- service_dict['logging'] = {}
- if 'log_driver' in service_dict:
- service_dict['logging']['driver'] = service_dict['log_driver']
- del service_dict['log_driver']
- if 'log_opt' in service_dict:
- service_dict['logging']['options'] = service_dict['log_opt']
- del service_dict['log_opt']
-
- if 'dockerfile' in service_dict:
- service_dict['build'] = service_dict.get('build', {})
- service_dict['build'].update({
- 'dockerfile': service_dict.pop('dockerfile')
- })
-
- return service_dict
-
-
-def merge_service_dicts_from_files(base, override, version):
- """When merging services from multiple files we need to merge the `extends`
- field. This is not handled by `merge_service_dicts()` which is used to
- perform the `extends`.
- """
- new_service = merge_service_dicts(base, override, version)
- if 'extends' in override:
- new_service['extends'] = override['extends']
- elif 'extends' in base:
- new_service['extends'] = base['extends']
- return new_service
-
-
-class MergeDict(dict):
- """A dict-like object responsible for merging two dicts into one."""
-
- def __init__(self, base, override):
- self.base = base
- self.override = override
-
- def needs_merge(self, field):
- return field in self.base or field in self.override
-
- def merge_field(self, field, merge_func, default=None):
- if not self.needs_merge(field):
- return
-
- self[field] = merge_func(
- self.base.get(field, default),
- self.override.get(field, default))
-
- def merge_mapping(self, field, parse_func):
- if not self.needs_merge(field):
- return
-
- self[field] = parse_func(self.base.get(field))
- self[field].update(parse_func(self.override.get(field)))
-
- def merge_sequence(self, field, parse_func):
- def parse_sequence_func(seq):
- return to_mapping((parse_func(item) for item in seq), 'merge_field')
-
- if not self.needs_merge(field):
- return
-
- merged = parse_sequence_func(self.base.get(field, []))
- merged.update(parse_sequence_func(self.override.get(field, [])))
- self[field] = [item.repr() for item in sorted(merged.values())]
-
- def merge_scalar(self, field):
- if self.needs_merge(field):
- self[field] = self.override.get(field, self.base.get(field))
-
-
-def merge_service_dicts(base, override, version):
- md = MergeDict(base, override)
-
- md.merge_mapping('environment', parse_environment)
- md.merge_mapping('labels', parse_labels)
- md.merge_mapping('ulimits', parse_ulimits)
- md.merge_mapping('networks', parse_networks)
- md.merge_sequence('links', ServiceLink.parse)
-
- for field in ['volumes', 'devices']:
- md.merge_field(field, merge_path_mappings)
-
- for field in [
- 'ports', 'cap_add', 'cap_drop', 'expose', 'external_links',
- 'security_opt', 'volumes_from', 'depends_on',
- ]:
- md.merge_field(field, merge_unique_items_lists, default=[])
-
- for field in ['dns', 'dns_search', 'env_file', 'tmpfs']:
- md.merge_field(field, merge_list_or_string)
-
- for field in set(ALLOWED_KEYS) - set(md):
- md.merge_scalar(field)
-
- if version == V1:
- legacy_v1_merge_image_or_build(md, base, override)
- elif md.needs_merge('build'):
- md['build'] = merge_build(md, base, override)
-
- return dict(md)
-
-
-def merge_unique_items_lists(base, override):
- return sorted(set().union(base, override))
-
-
-def merge_build(output, base, override):
- def to_dict(service):
- build_config = service.get('build', {})
- if isinstance(build_config, six.string_types):
- return {'context': build_config}
- return build_config
-
- md = MergeDict(to_dict(base), to_dict(override))
- md.merge_scalar('context')
- md.merge_scalar('dockerfile')
- md.merge_mapping('args', parse_build_arguments)
- return dict(md)
-
-
-def legacy_v1_merge_image_or_build(output, base, override):
- output.pop('image', None)
- output.pop('build', None)
- if 'image' in override:
- output['image'] = override['image']
- elif 'build' in override:
- output['build'] = override['build']
- elif 'image' in base:
- output['image'] = base['image']
- elif 'build' in base:
- output['build'] = base['build']
-
-
-def merge_environment(base, override):
- env = parse_environment(base)
- env.update(parse_environment(override))
- return env
-
-
-def split_label(label):
- if '=' in label:
- return label.split('=', 1)
- else:
- return label, ''
-
-
-def parse_dict_or_list(split_func, type_name, arguments):
- if not arguments:
- return {}
-
- if isinstance(arguments, list):
- return dict(split_func(e) for e in arguments)
-
- if isinstance(arguments, dict):
- return dict(arguments)
-
- raise ConfigurationError(
- "%s \"%s\" must be a list or mapping," %
- (type_name, arguments)
- )
-
-
-parse_build_arguments = functools.partial(parse_dict_or_list, split_env, 'build arguments')
-parse_environment = functools.partial(parse_dict_or_list, split_env, 'environment')
-parse_labels = functools.partial(parse_dict_or_list, split_label, 'labels')
-parse_networks = functools.partial(parse_dict_or_list, lambda k: (k, None), 'networks')
-
-
-def parse_ulimits(ulimits):
- if not ulimits:
- return {}
-
- if isinstance(ulimits, dict):
- return dict(ulimits)
-
-
-def resolve_env_var(key, val, environment):
- if val is not None:
- return key, val
- elif environment and key in environment:
- return key, environment[key]
- else:
- return key, None
-
-
-def resolve_volume_paths(working_dir, service_dict):
- return [
- resolve_volume_path(working_dir, volume)
- for volume in service_dict['volumes']
- ]
-
-
-def resolve_volume_path(working_dir, volume):
- container_path, host_path = split_path_mapping(volume)
-
- if host_path is not None:
- if host_path.startswith('.'):
- host_path = expand_path(working_dir, host_path)
- host_path = os.path.expanduser(host_path)
- return u"{}:{}".format(host_path, container_path)
- else:
- return container_path
-
-
-def normalize_build(service_dict, working_dir, environment):
-
- if 'build' in service_dict:
- build = {}
- # Shortcut where specifying a string is treated as the build context
- if isinstance(service_dict['build'], six.string_types):
- build['context'] = service_dict.pop('build')
- else:
- build.update(service_dict['build'])
- if 'args' in build:
- build['args'] = build_string_dict(
- resolve_build_args(build, environment)
- )
-
- service_dict['build'] = build
-
-
-def resolve_build_path(working_dir, build_path):
- if is_url(build_path):
- return build_path
- return expand_path(working_dir, build_path)
-
-
-def is_url(build_path):
- return build_path.startswith(DOCKER_VALID_URL_PREFIXES)
-
-
-def validate_paths(service_dict):
- if 'build' in service_dict:
- build = service_dict.get('build', {})
-
- if isinstance(build, six.string_types):
- build_path = build
- elif isinstance(build, dict) and 'context' in build:
- build_path = build['context']
- else:
- # We have a build section but no context, so nothing to validate
- return
-
- if (
- not is_url(build_path) and
- (not os.path.exists(build_path) or not os.access(build_path, os.R_OK))
- ):
- raise ConfigurationError(
- "build path %s either does not exist, is not accessible, "
- "or is not a valid URL." % build_path)
-
-
-def merge_path_mappings(base, override):
- d = dict_from_path_mappings(base)
- d.update(dict_from_path_mappings(override))
- return path_mappings_from_dict(d)
-
-
-def dict_from_path_mappings(path_mappings):
- if path_mappings:
- return dict(split_path_mapping(v) for v in path_mappings)
- else:
- return {}
-
-
-def path_mappings_from_dict(d):
- return [join_path_mapping(v) for v in sorted(d.items())]
-
-
-def split_path_mapping(volume_path):
- """
- Ascertain if the volume_path contains a host path as well as a container
- path. Using splitdrive so windows absolute paths won't cause issues with
- splitting on ':'.
- """
- # splitdrive is very naive, so handle special cases where we can be sure
- # the first character is not a drive.
- if (volume_path.startswith('.') or volume_path.startswith('~') or
- volume_path.startswith('/')):
- drive, volume_config = '', volume_path
- else:
- drive, volume_config = ntpath.splitdrive(volume_path)
-
- if ':' in volume_config:
- (host, container) = volume_config.split(':', 1)
- return (container, drive + host)
- else:
- return (volume_path, None)
-
-
-def join_path_mapping(pair):
- (container, host) = pair
- if host is None:
- return container
- else:
- return ":".join((host, container))
-
-
-def expand_path(working_dir, path):
- return os.path.abspath(os.path.join(working_dir, os.path.expanduser(path)))
-
-
-def merge_list_or_string(base, override):
- return to_list(base) + to_list(override)
-
-
-def to_list(value):
- if value is None:
- return []
- elif isinstance(value, six.string_types):
- return [value]
- else:
- return value
-
-
-def to_mapping(sequence, key_field):
- return {getattr(item, key_field): item for item in sequence}
-
-
-def has_uppercase(name):
- return any(char in string.ascii_uppercase for char in name)
-
-
-def load_yaml(filename):
- try:
- with open(filename, 'r') as fh:
- return yaml.safe_load(fh)
- except (IOError, yaml.YAMLError) as e:
- error_name = getattr(e, '__module__', '') + '.' + e.__class__.__name__
- raise ConfigurationError(u"{}: {}".format(error_name, e))
http://git-wip-us.apache.org/repos/asf/incubator-senssoft-tap/blob/6a81d1e7/env2/lib/python2.7/site-packages/compose/config/config_schema_v1.json
----------------------------------------------------------------------
diff --git a/env2/lib/python2.7/site-packages/compose/config/config_schema_v1.json b/env2/lib/python2.7/site-packages/compose/config/config_schema_v1.json
deleted file mode 100644
index 36a9379..0000000
--- a/env2/lib/python2.7/site-packages/compose/config/config_schema_v1.json
+++ /dev/null
@@ -1,187 +0,0 @@
-{
- "$schema": "http://json-schema.org/draft-04/schema#",
- "id": "config_schema_v1.json",
-
- "type": "object",
-
- "patternProperties": {
- "^[a-zA-Z0-9._-]+$": {
- "$ref": "#/definitions/service"
- }
- },
-
- "additionalProperties": false,
-
- "definitions": {
- "service": {
- "id": "#/definitions/service",
- "type": "object",
-
- "properties": {
- "build": {"type": "string"},
- "cap_add": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
- "cap_drop": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
- "cgroup_parent": {"type": "string"},
- "command": {
- "oneOf": [
- {"type": "string"},
- {"type": "array", "items": {"type": "string"}}
- ]
- },
- "container_name": {"type": "string"},
- "cpu_shares": {"type": ["number", "string"]},
- "cpu_quota": {"type": ["number", "string"]},
- "cpuset": {"type": "string"},
- "devices": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
- "dns": {"$ref": "#/definitions/string_or_list"},
- "dns_search": {"$ref": "#/definitions/string_or_list"},
- "dockerfile": {"type": "string"},
- "domainname": {"type": "string"},
- "entrypoint": {
- "oneOf": [
- {"type": "string"},
- {"type": "array", "items": {"type": "string"}}
- ]
- },
- "env_file": {"$ref": "#/definitions/string_or_list"},
- "environment": {"$ref": "#/definitions/list_or_dict"},
-
- "expose": {
- "type": "array",
- "items": {
- "type": ["string", "number"],
- "format": "expose"
- },
- "uniqueItems": true
- },
-
- "extends": {
- "oneOf": [
- {
- "type": "string"
- },
- {
- "type": "object",
-
- "properties": {
- "service": {"type": "string"},
- "file": {"type": "string"}
- },
- "required": ["service"],
- "additionalProperties": false
- }
- ]
- },
-
- "extra_hosts": {"$ref": "#/definitions/list_or_dict"},
- "external_links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
- "hostname": {"type": "string"},
- "image": {"type": "string"},
- "ipc": {"type": "string"},
- "labels": {"$ref": "#/definitions/list_or_dict"},
- "links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
- "log_driver": {"type": "string"},
- "log_opt": {"type": "object"},
- "mac_address": {"type": "string"},
- "mem_limit": {"type": ["number", "string"]},
- "memswap_limit": {"type": ["number", "string"]},
- "net": {"type": "string"},
- "pid": {"type": ["string", "null"]},
-
- "ports": {
- "type": "array",
- "items": {
- "type": ["string", "number"],
- "format": "ports"
- },
- "uniqueItems": true
- },
-
- "privileged": {"type": "boolean"},
- "read_only": {"type": "boolean"},
- "restart": {"type": "string"},
- "security_opt": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
- "shm_size": {"type": ["number", "string"]},
- "stdin_open": {"type": "boolean"},
- "stop_signal": {"type": "string"},
- "tty": {"type": "boolean"},
- "ulimits": {
- "type": "object",
- "patternProperties": {
- "^[a-z]+$": {
- "oneOf": [
- {"type": "integer"},
- {
- "type":"object",
- "properties": {
- "hard": {"type": "integer"},
- "soft": {"type": "integer"}
- },
- "required": ["soft", "hard"],
- "additionalProperties": false
- }
- ]
- }
- }
- },
- "user": {"type": "string"},
- "volumes": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
- "volume_driver": {"type": "string"},
- "volumes_from": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
- "working_dir": {"type": "string"}
- },
-
- "dependencies": {
- "memswap_limit": ["mem_limit"]
- },
- "additionalProperties": false
- },
-
- "string_or_list": {
- "oneOf": [
- {"type": "string"},
- {"$ref": "#/definitions/list_of_strings"}
- ]
- },
-
- "list_of_strings": {
- "type": "array",
- "items": {"type": "string"},
- "uniqueItems": true
- },
-
- "list_or_dict": {
- "oneOf": [
- {
- "type": "object",
- "patternProperties": {
- ".+": {
- "type": ["string", "number", "null"]
- }
- },
- "additionalProperties": false
- },
- {"type": "array", "items": {"type": "string"}, "uniqueItems": true}
- ]
- },
-
- "constraints": {
- "service": {
- "id": "#/definitions/constraints/service",
- "anyOf": [
- {
- "required": ["build"],
- "not": {"required": ["image"]}
- },
- {
- "required": ["image"],
- "not": {"anyOf": [
- {"required": ["build"]},
- {"required": ["dockerfile"]}
- ]}
- }
- ]
- }
- }
- }
-}