From 69ff43d253ea0a0fa91c3f8e907dbb10a926e6d3 Mon Sep 17 00:00:00 2001 From: Bryan Larsen Date: Thu, 11 Jul 2013 13:30:42 -0400 Subject: [PATCH 1/3] digital_ocean: don't run update_attr if wait=no Sometimes when using digital_ocean with wait=no I get the error "No ip is found". But with wait=no I wouldn't expect there to be any IP, that gets allocated later. However, looking at the code, it turns out that with even with wait=no it waits up to 10 seconds for an IP to be allocated. We could wait longer, but with wait=no that seems like the wrong choice; it's easy enough to grab an IP later with a wait=yes command. To make this change I removed the call to update_attr in @classmethod add. An add is always followed by an ensure_powered_on which will do the update_attr if wait=yes. It would be possible to instead do a call to update_attr with no retries and ignore the errors but I figured it would be better to be consistently not return an IP than to sometimes return it and sometimes not. Inconsistent behaviour makes debugging deployment scripts very difficult. --- cloud/digital_ocean | 1 - 1 file changed, 1 deletion(-) diff --git a/cloud/digital_ocean b/cloud/digital_ocean index 60ee4928fbf..dbf8406c77c 100644 --- a/cloud/digital_ocean +++ b/cloud/digital_ocean @@ -233,7 +233,6 @@ class Droplet(JsonfyMixIn): def add(cls, name, size_id, image_id, region_id, ssh_key_ids=None): json = cls.manager.new_droplet(name, size_id, image_id, region_id, ssh_key_ids) droplet = cls(json) - droplet.update_attr() return droplet @classmethod From 3fe9756281a7e93d0a174d3e3df73d91a8261b72 Mon Sep 17 00:00:00 2001 From: Bryan Larsen Date: Thu, 11 Jul 2013 13:33:42 -0400 Subject: [PATCH 2/3] digital_ocean doc update --- cloud/digital_ocean | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cloud/digital_ocean b/cloud/digital_ocean index dbf8406c77c..c2359ade5df 100644 --- a/cloud/digital_ocean +++ b/cloud/digital_ocean @@ -59,7 +59,7 @@ options: - Optional, comma separated list of ssh_key_ids that you would like to be added to the server wait: description: - - Wait for the droplet to be in state 'running' before returning. + - Wait for the droplet to be in state 'running' before returning. If wait is "no" an ip_address may not be returned. default: "yes" choices: [ "yes", "no" ] wait_timeout: @@ -101,6 +101,8 @@ EXAMPLES = ''' region_id=2 image_id=3 wait_timeout=500 + register: my_droplet +- debug: msg="ID: {{ my_droplet.droplet.id }} IP: {{ my_droplet.droplet.ip_address }}" # Ensure a droplet is present # If droplet id already exist, will return the droplet details and changed = False From f440b5b46a542b2c2ffd90ef9f4b01ee81222298 Mon Sep 17 00:00:00 2001 From: Bryan Larsen Date: Thu, 11 Jul 2013 14:05:26 -0400 Subject: [PATCH 3/3] update_attr should wait for the full wait timeout before checking for a missing IP addres --- cloud/digital_ocean | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/cloud/digital_ocean b/cloud/digital_ocean index c2359ade5df..d020b07b8a3 100644 --- a/cloud/digital_ocean +++ b/cloud/digital_ocean @@ -189,19 +189,13 @@ class Droplet(JsonfyMixIn): def is_powered_on(self): return self.status == 'active' - def update_attr(self, attrs=None, times=5): + def update_attr(self, attrs=None): if attrs: for k, v in attrs.iteritems(): setattr(self, k, v) else: json = self.manager.show_droplet(self.id) - if not json['ip_address']: - if times > 0: - time.sleep(2) - self.update_attr(times=times-1) - else: - raise TimeoutError('No ip is found.', self.id) - else: + if json['ip_address']: self.update_attr(json) def power_on(self): @@ -221,6 +215,8 @@ class Droplet(JsonfyMixIn): time.sleep(min(20, end_time-time.time())) self.update_attr() if self.is_powered_on(): + if not self.ip_address: + raise TimeoutError('No ip is found.', self.id) return raise TimeoutError('Wait for droplet running timeout', self.id)