|
|
@@ -971,25 +971,42 @@ class TopLevelCommand(object):
|
|
|
if ignore_orphans and remove_orphans:
|
|
|
raise UserError("COMPOSE_IGNORE_ORPHANS and --remove-orphans cannot be combined.")
|
|
|
|
|
|
- if no_start:
|
|
|
- for excluded in ['-d', '--abort-on-container-exit', '--exit-code-from']:
|
|
|
- if options.get(excluded):
|
|
|
- raise UserError('--no-start and {} cannot be combined.'.format(excluded))
|
|
|
+ opts = ['-d', '--abort-on-container-exit', '--exit-code-from']
|
|
|
+ for excluded in [x for x in opts if options.get(x) and no_start]:
|
|
|
+ raise UserError('--no-start and {} cannot be combined.'.format(excluded))
|
|
|
|
|
|
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,
|
|
|
- ignore_orphans=ignore_orphans,
|
|
|
- scale_override=parse_scale_args(options['--scale']),
|
|
|
- start=not no_start,
|
|
|
- always_recreate_deps=always_recreate_deps
|
|
|
- )
|
|
|
+ warn_for_swarm_mode(self.project.client)
|
|
|
+
|
|
|
+ def up(rebuild):
|
|
|
+ return 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,
|
|
|
+ ignore_orphans=ignore_orphans,
|
|
|
+ scale_override=parse_scale_args(options['--scale']),
|
|
|
+ start=not no_start,
|
|
|
+ always_recreate_deps=always_recreate_deps,
|
|
|
+ reset_container_image=rebuild,
|
|
|
+ )
|
|
|
+
|
|
|
+ try:
|
|
|
+ to_attach = up(False)
|
|
|
+ except docker.errors.ImageNotFound as e:
|
|
|
+ log.error(
|
|
|
+ "The image for the service you're trying to recreate has been removed. "
|
|
|
+ "If you continue, volume data could be lost. Consider backing up your data "
|
|
|
+ "before continuing.\n".format(e.explanation)
|
|
|
+ )
|
|
|
+ res = yesno("Continue with the new image? [yN]", False)
|
|
|
+ if res is None or not res:
|
|
|
+ raise e
|
|
|
+
|
|
|
+ to_attach = up(True)
|
|
|
|
|
|
if detached or no_start:
|
|
|
return
|
|
|
@@ -1412,3 +1429,19 @@ def build_filter(arg):
|
|
|
key, val = arg.split('=', 1)
|
|
|
filt[key] = val
|
|
|
return filt
|
|
|
+
|
|
|
+
|
|
|
+def warn_for_swarm_mode(client):
|
|
|
+ info = client.info()
|
|
|
+ if info.get('Swarm', {}).get('LocalNodeState') == 'active':
|
|
|
+ if info.get('ServerVersion', '').startswith('ucp'):
|
|
|
+ # UCP does multi-node scheduling with traditional Compose files.
|
|
|
+ return
|
|
|
+
|
|
|
+ log.warn(
|
|
|
+ "The Docker Engine you're using is running in swarm mode.\n\n"
|
|
|
+ "Compose does not use swarm mode to deploy services to multiple nodes in a swarm. "
|
|
|
+ "All containers will be scheduled on the current node.\n\n"
|
|
|
+ "To deploy your application across the swarm, "
|
|
|
+ "use `docker stack deploy`.\n"
|
|
|
+ )
|