# Path: fabricio/utils.py
# DEFAULT = object()
# def patch(obj, attr, value, default=DEFAULT, force_delete=False):
#     def __init__(self, func=None, default=None):
#     def __get__(self, instance, owner=None):
#     def __call__(self, func):
#     def make_option(self, option, value=None):
#     def make_options(self):
#     def __str__(self):
# def strtobool(value):
# def once_per_command(*args, **kwargs):  # pragma: no cover
#     def __init__(self, iterable=None, priority=None, **kwargs):
#     def items(self):
#     def __init__(self, iterable=None):
#     def __len__(self):
#     def __contains__(self, key):
#     def add(self, key):
#     def discard(self, key):
#     def __iter__(self):
#     def __reversed__(self):
#     def pop(self, last=True):
#     def __repr__(self):
#     def __eq__(self, other):
# class default_property(object):
# class Options(collections.OrderedDict):
# class AttrDict(dict):
# class PriorityDict(dict):
# class OrderedSet(collections.MutableSet):  # pragma: no cover
# 
# Path: fabricio/docker/base.py
# class ManagedService(BaseService):
# 
#     def __init__(self, *args, **kwargs):
#         super(ManagedService, self).__init__(*args, **kwargs)
#         self.managers = multiprocessing.Manager().dict()
# 
#     def _is_manager(self):
#         command = 'docker info 2>&1 | grep "Is Manager:"'
#         return fabricio.run(command).endswith('true')
# 
#     def is_manager(self, raise_manager_error=True):
#         is_manager = self.managers.get(fab.env.host)
#         try:
#             if is_manager is None:
#                 is_manager = self.managers[fab.env.host] = self._is_manager()
#         except fabricio.host_errors as error:
#             is_manager = self.managers[fab.env.host] = False
#             fabricio.log(
#                 'WARNING: {error}'.format(error=error),
#                 output=sys.stderr,
#                 color=colors.red,
#             )
#         finally:
#             if (
#                 raise_manager_error
#                 and len(self.managers) >= len(fab.env.all_hosts)
#                 and not any(self.managers.values())
#             ):
#                 msg = 'service manager not found or it failed to pull image'
#                 raise ManagerNotFoundError(msg)
#         return is_manager
# 
#     def pull_image(self, *args, **kwargs):
#         try:
#             return super(ManagedService, self).pull_image(*args, **kwargs)
#         except fabricio.host_errors as error:
#             self.managers[fab.env.host] = False
#             fabricio.log(
#                 'WARNING: {error}'.format(error=error),
#                 output=sys.stderr,
#                 color=colors.red,
#             )
# 
#     def migrate(self, *args, **kwargs):
#         if self.is_manager():
#             super(ManagedService, self).migrate(*args, **kwargs)
# 
#     def migrate_back(self):
#         if self.is_manager():
#             super(ManagedService, self).migrate_back()
# 
#     def backup(self):
#         if self.is_manager():
#             super(ManagedService, self).backup()
# 
#     def restore(self, backup_name=None):
#         if self.is_manager():
#             super(ManagedService, self).restore(backup_name=backup_name)
# 
# class Option(utils.default_property):
# 
#     def __init__(
#         self,
#         func=None,
#         default=None,
#         name=None,
#         safe=False,
#         safe_name=None,
#     ):
#         super(Option, self).__init__(func=func, default=default)
#         self.name = name
#         self.safe = safe
#         self.safe_name = safe_name
# 
# class Attribute(utils.default_property):
#     pass
# 
# class ServiceError(fabricio.Error):
#     pass


import functools
import hashlib
import itertools
import json
import re
import shlex
import dpath
import six
import fabricio
from cached_property import cached_property
from frozendict import frozendict
from six.moves import map, shlex_quote, range
from fabricio import utils
from .base import ManagedService, Option, Attribute, ServiceError


class Service(ManagedService):

    options_label_name = 'fabricio.service.options'

    command = Attribute()
    args = Attribute()
    mode = Attribute()

    env = EnvOption(safe=True)
    label = LabelOption(path='/Spec/Labels')
    container_label = LabelOption(
        name='container-label',
        path='/Spec/TaskTemplate/ContainerSpec/Labels',
        safe_name='label',
    )
    publish = PublishOption()
    constraint = RemovableOption(
        path='/Spec/TaskTemplate/Placement/Constraints/*',
    )
    replicas = Option()
    mount = MountOption(safe=True)
    network = RemovableOption(
        path='/Spec/TaskTemplate/Networks/*/Target',
        force_add=True,
        force_rm=True,
        safe=True,
    )
    restart_condition = Option(name='restart-condition')

# Path: fabricio/utils.py
# DEFAULT = object()
# def patch(obj, attr, value, default=DEFAULT, force_delete=False):
#     def __init__(self, func=None, default=None):
#     def __get__(self, instance, owner=None):
#     def __call__(self, func):
#     def make_option(self, option, value=None):
#     def make_options(self):
#     def __str__(self):
# def strtobool(value):
# def once_per_command(*args, **kwargs):  # pragma: no cover
#     def __init__(self, iterable=None, priority=None, **kwargs):
#     def items(self):
#     def __init__(self, iterable=None):
#     def __len__(self):
#     def __contains__(self, key):
#     def add(self, key):
#     def discard(self, key):
#     def __iter__(self):
#     def __reversed__(self):
#     def pop(self, last=True):
#     def __repr__(self):
#     def __eq__(self, other):
# class default_property(object):
# class Options(collections.OrderedDict):
# class AttrDict(dict):
# class PriorityDict(dict):
# class OrderedSet(collections.MutableSet):  # pragma: no cover
# 
# Path: fabricio/docker/base.py
# class ManagedService(BaseService):
# 
#     def __init__(self, *args, **kwargs):
#         super(ManagedService, self).__init__(*args, **kwargs)
#         self.managers = multiprocessing.Manager().dict()
# 
#     def _is_manager(self):
#         command = 'docker info 2>&1 | grep "Is Manager:"'
#         return fabricio.run(command).endswith('true')
# 
#     def is_manager(self, raise_manager_error=True):
#         is_manager = self.managers.get(fab.env.host)
#         try:
#             if is_manager is None:
#                 is_manager = self.managers[fab.env.host] = self._is_manager()
#         except fabricio.host_errors as error:
#             is_manager = self.managers[fab.env.host] = False
#             fabricio.log(
#                 'WARNING: {error}'.format(error=error),
#                 output=sys.stderr,
#                 color=colors.red,
#             )
#         finally:
#             if (
#                 raise_manager_error
#                 and len(self.managers) >= len(fab.env.all_hosts)
#                 and not any(self.managers.values())
#             ):
#                 msg = 'service manager not found or it failed to pull image'
#                 raise ManagerNotFoundError(msg)
#         return is_manager
# 
#     def pull_image(self, *args, **kwargs):
#         try:
#             return super(ManagedService, self).pull_image(*args, **kwargs)
#         except fabricio.host_errors as error:
#             self.managers[fab.env.host] = False
#             fabricio.log(
#                 'WARNING: {error}'.format(error=error),
#                 output=sys.stderr,
#                 color=colors.red,
#             )
# 
#     def migrate(self, *args, **kwargs):
#         if self.is_manager():
#             super(ManagedService, self).migrate(*args, **kwargs)
# 
#     def migrate_back(self):
#         if self.is_manager():
#             super(ManagedService, self).migrate_back()
# 
#     def backup(self):
#         if self.is_manager():
#             super(ManagedService, self).backup()
# 
#     def restore(self, backup_name=None):
#         if self.is_manager():
#             super(ManagedService, self).restore(backup_name=backup_name)
# 
# class Option(utils.default_property):
# 
#     def __init__(
#         self,
#         func=None,
#         default=None,
#         name=None,
#         safe=False,
#         safe_name=None,
#     ):
#         super(Option, self).__init__(func=func, default=default)
#         self.name = name
#         self.safe = safe
#         self.safe_name = safe_name
# 
# class Attribute(utils.default_property):
#     pass
# 
# class ServiceError(fabricio.Error):
#     pass


# Path: fabricio/docker/service.py
import functools
import hashlib
import itertools
import json
import re
import shlex
import dpath
import six
import fabricio
from cached_property import cached_property
from frozendict import frozendict
from six.moves import map, shlex_quote, range
from fabricio import utils
from .base import ManagedService, Option, Attribute, ServiceError



class Service(ManagedService):

    options_label_name = 'fabricio.service.options'

    command = Attribute()
    args = Attribute()
    mode = Attribute()

    env = EnvOption(safe=True)
    label = LabelOption(path='/Spec/Labels')
    container_label = LabelOption(
        name='container-label',
        path='/Spec/TaskTemplate/ContainerSpec/Labels',
        safe_name='label',
    )
    publish = PublishOption()
    constraint = RemovableOption(
        path='/Spec/TaskTemplate/Placement/Constraints/*',
    )
    replicas = Option()
    mount = MountOption(safe=True)
    network = RemovableOption(
        path='/Spec/TaskTemplate/Networks/*/Target',
        force_add=True,
        force_rm=True,
        safe=True,
    )
    restart_condition = Option(name='restart-condition')

    stop_grace_period = Option(name='stop-grace-period')