Skip to content

Commit 10bcf29

Browse files
committed
Merge pull request #1529 from mike-tutkowski/marvin_replace_sleep
Marvin: Replace a timer.sleep(30) with pulling logichttps://issues.apache.org/jira/browse/CLOUDSTACK-9374 From the ticket: In the base.py file, there is a Host class with a delete instance method. This method first attempts to transition the host into the maintenance resource state. The first step in this process is to transition the host into the prepare-for-maintenance resource state. A while later, the host can be transitioned completely into the maintenance resource state. In an attempt to wait for this transition to occur, the delete method has a timer.sleep(30) call. The hope is that the host will have transitioned from the prepare-for-maintenance resource state to the maintenance resource state within 30 seconds, but this does not always happen. We should correct this problem by putting in logic to query the management server for the resource state of the host. If it's in the expected state, move on; else, sleep for a bit and try again (up to a certain limit). * pr/1529: Replace a timer.sleep(30) with pulling logic Signed-off-by: Will Stevens <williamstevens@gmail.com>
2 parents ccf2265 + eeb3373 commit 10bcf29

2 files changed

Lines changed: 57 additions & 4 deletions

File tree

tools/marvin/marvin/codes.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,31 @@
115115
'''
116116
ALLOCATED = "Allocated"
117117

118+
'''
119+
Host states
120+
'''
121+
HOST_CREATING = "Creating"
122+
HOST_CONNECTING = "Connecting"
123+
HOST_UP = "Up"
124+
HOST_DOWN = "Down"
125+
HOST_DISCONNECTED = "Disconnected"
126+
HOST_ALERT = "Alert"
127+
HOST_REMOVED = "Removed"
128+
HOST_ERROR = "Error"
129+
HOST_REBALANCING = "Rebalancing"
130+
HOST_UNKNOWN = "Unknown"
131+
132+
'''
133+
Host resource states
134+
'''
135+
HOST_RS_CREATING = "Creating"
136+
HOST_RS_ENABLED = "Enabled"
137+
HOST_RS_DISABLED = "Disabled"
138+
HOST_RS_PREPARE_FOR_MAINTENANCE = "PrepareForMaintenance"
139+
HOST_RS_ERROR_IN_MAINTENANCE = "ErrorInMaintenance"
140+
HOST_RS_MAINTENANCE = "Maintenance"
141+
HOST_RS_ERROR = "Error"
142+
118143
'''
119144
Storage Tags
120145
'''

tools/marvin/marvin/lib/base.py

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@
2323
from marvin.cloudstackAPI import *
2424
from marvin.codes import (FAILED, FAIL, PASS, RUNNING, STOPPED,
2525
STARTING, DESTROYED, EXPUNGING,
26-
STOPPING, BACKED_UP, BACKING_UP)
26+
STOPPING, BACKED_UP, BACKING_UP,
27+
HOST_RS_MAINTENANCE)
2728
from marvin.cloudstackException import GetDetailExceptionInfo, CloudstackAPIException
28-
from marvin.lib.utils import validateList, is_server_ssh_ready, random_gen
29+
from marvin.lib.utils import validateList, is_server_ssh_ready, random_gen, wait_until
2930
# Import System modules
3031
import time
3132
import hashlib
@@ -2459,13 +2460,40 @@ def create(cls, apiclient, cluster, services, zoneid=None, podid=None, hyperviso
24592460
GetDetailExceptionInfo(e)
24602461
return FAILED
24612462

2463+
@staticmethod
2464+
def _check_resource_state(apiclient, hostid, resourcestate):
2465+
hosts = Host.list(apiclient, id=hostid, listall=True)
2466+
2467+
validationresult = validateList(hosts)
2468+
2469+
assert validationresult is not None, "'validationresult' should not be equal to 'None'."
2470+
2471+
assert isinstance(validationresult, list), "'validationresult' should be a 'list'."
2472+
2473+
assert len(validationresult) == 3, "'validationresult' should be a list with three items in it."
2474+
2475+
if validationresult[0] == FAIL:
2476+
raise Exception("Host list validation failed: %s" % validationresult[2])
2477+
2478+
if str(hosts[0].resourcestate).lower().decode("string_escape") == str(resourcestate).lower():
2479+
return True, None
2480+
2481+
return False, "Host is not in the following state: " + str(resourcestate)
2482+
24622483
def delete(self, apiclient):
24632484
"""Delete Host"""
24642485
# Host must be in maintenance mode before deletion
24652486
cmd = prepareHostForMaintenance.prepareHostForMaintenanceCmd()
24662487
cmd.id = self.id
24672488
apiclient.prepareHostForMaintenance(cmd)
2468-
time.sleep(30)
2489+
2490+
retry_interval = 10
2491+
num_tries = 10
2492+
2493+
wait_result, return_val = wait_until(retry_interval, num_tries, Host._check_resource_state, apiclient, self.id, HOST_RS_MAINTENANCE)
2494+
2495+
if not wait_result:
2496+
raise Exception(return_val)
24692497

24702498
cmd = deleteHost.deleteHostCmd()
24712499
cmd.id = self.id
@@ -2711,7 +2739,7 @@ def getState(cls, apiclient, poolid, state, timeout=600):
27112739
id=poolid, listAll=True)
27122740
validationresult = validateList(pools)
27132741
if validationresult[0] == FAIL:
2714-
raise Exception("Host list validation failed: %s" % validationresult[2])
2742+
raise Exception("Pool list validation failed: %s" % validationresult[2])
27152743
elif str(pools[0].state).lower().decode("string_escape") == str(state).lower():
27162744
returnValue = [PASS, None]
27172745
break

0 commit comments

Comments
 (0)