-
Notifications
You must be signed in to change notification settings - Fork 5.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Speed up fig up #586
Speed up fig up #586
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -50,6 +50,17 @@ | |
'workdir' : 'working_dir', | ||
} | ||
|
||
DOCKER_START_KEYS = [ | ||
'cap_add', | ||
'cap_drop', | ||
'dns', | ||
'dns_search', | ||
'env_file', | ||
'net', | ||
'privileged', | ||
'restart', | ||
] | ||
|
||
VALID_NAME_CHARS = '[a-zA-Z0-9]' | ||
|
||
|
||
|
@@ -145,7 +156,8 @@ def restart(self, **options): | |
|
||
def scale(self, desired_num): | ||
""" | ||
Adjusts the number of containers to the specified number and ensures they are running. | ||
Adjusts the number of containers to the specified number and ensures | ||
they are running. | ||
|
||
- creates containers until there are at least `desired_num` | ||
- stops containers until there are at most `desired_num` running | ||
|
@@ -192,12 +204,24 @@ def remove_stopped(self, **options): | |
log.info("Removing %s..." % c.name) | ||
c.remove(**options) | ||
|
||
def create_container(self, one_off=False, insecure_registry=False, **override_options): | ||
def create_container(self, | ||
one_off=False, | ||
insecure_registry=False, | ||
do_build=True, | ||
**override_options): | ||
""" | ||
Create a container for this service. If the image doesn't exist, attempt to pull | ||
it. | ||
""" | ||
container_options = self._get_container_create_options(override_options, one_off=one_off) | ||
container_options = self._get_container_create_options( | ||
override_options, | ||
one_off=one_off) | ||
|
||
if (do_build and | ||
self.can_be_built() and | ||
not self.client.images(name=self.full_name)): | ||
self.build() | ||
|
||
try: | ||
return Container.create(self.client, **container_options) | ||
except APIError as e: | ||
|
@@ -212,15 +236,18 @@ def create_container(self, one_off=False, insecure_registry=False, **override_op | |
return Container.create(self.client, **container_options) | ||
raise | ||
|
||
def recreate_containers(self, insecure_registry=False, **override_options): | ||
def recreate_containers(self, insecure_registry=False, do_build=True, **override_options): | ||
""" | ||
If a container for this service doesn't exist, create and start one. If there are | ||
any, stop them, create+start new ones, and remove the old containers. | ||
""" | ||
containers = self.containers(stopped=True) | ||
if not containers: | ||
log.info("Creating %s..." % self._next_container_name(containers)) | ||
container = self.create_container(insecure_registry=insecure_registry, **override_options) | ||
container = self.create_container( | ||
insecure_registry=insecure_registry, | ||
do_build=do_build, | ||
**override_options) | ||
self.start_container(container) | ||
return [(None, container)] | ||
else: | ||
|
@@ -259,7 +286,7 @@ def recreate_container(self, container, **override_options): | |
container.remove() | ||
|
||
options = dict(override_options) | ||
new_container = self.create_container(**options) | ||
new_container = self.create_container(do_build=False, **options) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I set this to always False. I believe since this is in |
||
self.start_container(new_container, intermediate_container=intermediate_container) | ||
|
||
intermediate_container.remove() | ||
|
@@ -273,8 +300,7 @@ def start_container_if_stopped(self, container, **options): | |
log.info("Starting %s..." % container.name) | ||
return self.start_container(container, **options) | ||
|
||
def start_container(self, container=None, intermediate_container=None, **override_options): | ||
container = container or self.create_container(**override_options) | ||
def start_container(self, container, intermediate_container=None, **override_options): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I removed the call to |
||
options = dict(self.options, **override_options) | ||
port_bindings = build_port_bindings(options.get('ports') or []) | ||
|
||
|
@@ -307,14 +333,19 @@ def start_container(self, container=None, intermediate_container=None, **overrid | |
) | ||
return container | ||
|
||
def start_or_create_containers(self, insecure_registry=False, detach=False): | ||
def start_or_create_containers( | ||
self, | ||
insecure_registry=False, | ||
detach=False, | ||
do_build=True): | ||
containers = self.containers(stopped=True) | ||
|
||
if not containers: | ||
log.info("Creating %s..." % self._next_container_name(containers)) | ||
new_container = self.create_container( | ||
insecure_registry=insecure_registry, | ||
detach=detach | ||
detach=detach, | ||
do_build=do_build, | ||
) | ||
return [self.start_container(new_container)] | ||
else: | ||
|
@@ -407,16 +438,13 @@ def _get_container_create_options(self, override_options, one_off=False): | |
container_options['environment'] = merge_environment(container_options) | ||
|
||
if self.can_be_built(): | ||
if len(self.client.images(name=self._build_tag_name())) == 0: | ||
self.build() | ||
container_options['image'] = self._build_tag_name() | ||
container_options['image'] = self.full_name | ||
else: | ||
container_options['image'] = self._get_image_name(container_options['image']) | ||
|
||
# Delete options which are only used when starting | ||
for key in ['privileged', 'net', 'dns', 'dns_search', 'restart', 'cap_add', 'cap_drop', 'env_file']: | ||
if key in container_options: | ||
del container_options[key] | ||
for key in DOCKER_START_KEYS: | ||
container_options.pop(key, None) | ||
|
||
return container_options | ||
|
||
|
@@ -431,7 +459,7 @@ def build(self, no_cache=False): | |
|
||
build_output = self.client.build( | ||
self.options['build'], | ||
tag=self._build_tag_name(), | ||
tag=self.full_name, | ||
stream=True, | ||
rm=True, | ||
nocache=no_cache, | ||
|
@@ -451,14 +479,15 @@ def build(self, no_cache=False): | |
image_id = match.group(1) | ||
|
||
if image_id is None: | ||
raise BuildError(self) | ||
raise BuildError(self, event if all_events else 'Unknown') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. bug fix, picked from #457 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using the Happy to merge this change as a separate PR btw. |
||
|
||
return image_id | ||
|
||
def can_be_built(self): | ||
return 'build' in self.options | ||
|
||
def _build_tag_name(self): | ||
@property | ||
def full_name(self): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. picked from #457 |
||
""" | ||
The tag to give to images built for this service. | ||
""" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This block was moved from
_get_container_create_options()
, which is mostly focused on building up an options dict. It feels a lot more appropriate here, since this function is doing other docker operations related to creating the container.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍