Add enum34 and use it to create a ConvergenceStrategy enum.
Signed-off-by: Daniel Nephin <dnephin@gmail.com>
This commit is contained in:
parent
d4372bc98f
commit
0484e22a84
11 changed files with 105 additions and 77 deletions
|
|
@ -19,6 +19,7 @@ from ..progress_stream import StreamOutputError
|
|||
from ..project import ConfigurationError
|
||||
from ..project import NoSuchService
|
||||
from ..service import BuildError
|
||||
from ..service import ConvergenceStrategy
|
||||
from ..service import NeedsBuildError
|
||||
from .command import Command
|
||||
from .docopt_command import NoSuchCommand
|
||||
|
|
@ -332,7 +333,7 @@ class TopLevelCommand(Command):
|
|||
project.up(
|
||||
service_names=deps,
|
||||
start_deps=True,
|
||||
allow_recreate=False,
|
||||
strategy=ConvergenceStrategy.never,
|
||||
)
|
||||
|
||||
tty = True
|
||||
|
|
@ -515,29 +516,20 @@ class TopLevelCommand(Command):
|
|||
if options['--allow-insecure-ssl']:
|
||||
log.warn(INSECURE_SSL_WARNING)
|
||||
|
||||
detached = options['-d']
|
||||
|
||||
monochrome = options['--no-color']
|
||||
|
||||
start_deps = not options['--no-deps']
|
||||
allow_recreate = not options['--no-recreate']
|
||||
force_recreate = options['--force-recreate']
|
||||
service_names = options['SERVICE']
|
||||
timeout = int(options.get('--timeout') or DEFAULT_TIMEOUT)
|
||||
|
||||
if force_recreate and not allow_recreate:
|
||||
raise UserError("--force-recreate and --no-recreate cannot be combined.")
|
||||
|
||||
to_attach = project.up(
|
||||
service_names=service_names,
|
||||
start_deps=start_deps,
|
||||
allow_recreate=allow_recreate,
|
||||
force_recreate=force_recreate,
|
||||
strategy=convergence_strategy_from_opts(options),
|
||||
do_build=not options['--no-build'],
|
||||
timeout=timeout
|
||||
)
|
||||
|
||||
if not detached:
|
||||
if not options['-d']:
|
||||
log_printer = build_log_printer(to_attach, service_names, monochrome)
|
||||
attach_to_logs(project, log_printer, service_names, timeout)
|
||||
|
||||
|
|
@ -582,6 +574,21 @@ class TopLevelCommand(Command):
|
|||
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 build_log_printer(containers, service_names, monochrome):
|
||||
if service_names:
|
||||
containers = [c for c in containers if c.service in service_names]
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ from .const import LABEL_SERVICE
|
|||
from .container import Container
|
||||
from .legacy import check_for_legacy_containers
|
||||
from .service import ContainerNet
|
||||
from .service import ConvergenceStrategy
|
||||
from .service import Net
|
||||
from .service import Service
|
||||
from .service import ServiceNet
|
||||
|
|
@ -266,24 +267,16 @@ class Project(object):
|
|||
def up(self,
|
||||
service_names=None,
|
||||
start_deps=True,
|
||||
allow_recreate=True,
|
||||
force_recreate=False,
|
||||
strategy=ConvergenceStrategy.changed,
|
||||
do_build=True,
|
||||
timeout=DEFAULT_TIMEOUT):
|
||||
|
||||
if force_recreate and not allow_recreate:
|
||||
raise ValueError("force_recreate and allow_recreate are in conflict")
|
||||
|
||||
services = self.get_services(service_names, include_deps=start_deps)
|
||||
|
||||
for service in services:
|
||||
service.remove_duplicate_containers()
|
||||
|
||||
plans = self._get_convergence_plans(
|
||||
services,
|
||||
allow_recreate=allow_recreate,
|
||||
force_recreate=force_recreate,
|
||||
)
|
||||
plans = self._get_convergence_plans(services, strategy)
|
||||
|
||||
return [
|
||||
container
|
||||
|
|
@ -295,11 +288,7 @@ class Project(object):
|
|||
)
|
||||
]
|
||||
|
||||
def _get_convergence_plans(self,
|
||||
services,
|
||||
allow_recreate=True,
|
||||
force_recreate=False):
|
||||
|
||||
def _get_convergence_plans(self, services, strategy):
|
||||
plans = {}
|
||||
|
||||
for service in services:
|
||||
|
|
@ -310,20 +299,13 @@ class Project(object):
|
|||
and plans[name].action == 'recreate'
|
||||
]
|
||||
|
||||
if updated_dependencies and allow_recreate:
|
||||
log.debug(
|
||||
'%s has upstream changes (%s)',
|
||||
service.name, ", ".join(updated_dependencies),
|
||||
)
|
||||
plan = service.convergence_plan(
|
||||
allow_recreate=allow_recreate,
|
||||
force_recreate=True,
|
||||
)
|
||||
if updated_dependencies and strategy.allows_recreate:
|
||||
log.debug('%s has upstream changes (%s)',
|
||||
service.name,
|
||||
", ".join(updated_dependencies))
|
||||
plan = service.convergence_plan(ConvergenceStrategy.always)
|
||||
else:
|
||||
plan = service.convergence_plan(
|
||||
allow_recreate=allow_recreate,
|
||||
force_recreate=force_recreate,
|
||||
)
|
||||
plan = service.convergence_plan(strategy)
|
||||
|
||||
plans[service.name] = plan
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import sys
|
|||
from collections import namedtuple
|
||||
from operator import attrgetter
|
||||
|
||||
import enum
|
||||
import six
|
||||
from docker.errors import APIError
|
||||
from docker.utils import create_host_config
|
||||
|
|
@ -86,6 +87,20 @@ ServiceName = namedtuple('ServiceName', 'project service number')
|
|||
ConvergencePlan = namedtuple('ConvergencePlan', 'action containers')
|
||||
|
||||
|
||||
@enum.unique
|
||||
class ConvergenceStrategy(enum.Enum):
|
||||
"""Enumeration for all possible convergence strategies. Values refer to
|
||||
when containers should be recreated.
|
||||
"""
|
||||
changed = 1
|
||||
always = 2
|
||||
never = 3
|
||||
|
||||
@property
|
||||
def allows_recreate(self):
|
||||
return self is not type(self).never
|
||||
|
||||
|
||||
class Service(object):
|
||||
def __init__(
|
||||
self,
|
||||
|
|
@ -326,22 +341,19 @@ class Service(object):
|
|||
else:
|
||||
return self.options['image']
|
||||
|
||||
def convergence_plan(self,
|
||||
allow_recreate=True,
|
||||
force_recreate=False):
|
||||
|
||||
if force_recreate and not allow_recreate:
|
||||
raise ValueError("force_recreate and allow_recreate are in conflict")
|
||||
|
||||
def convergence_plan(self, strategy=ConvergenceStrategy.changed):
|
||||
containers = self.containers(stopped=True)
|
||||
|
||||
if not containers:
|
||||
return ConvergencePlan('create', [])
|
||||
|
||||
if not allow_recreate:
|
||||
if strategy is ConvergenceStrategy.never:
|
||||
return ConvergencePlan('start', containers)
|
||||
|
||||
if force_recreate or self._containers_have_diverged(containers):
|
||||
if (
|
||||
strategy is ConvergenceStrategy.always or
|
||||
self._containers_have_diverged(containers)
|
||||
):
|
||||
return ConvergencePlan('recreate', containers)
|
||||
|
||||
stopped = [c for c in containers if not c.is_running]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue