def run(self, connection, state, *pargs, **kwargs): """ Send an HTTP POST request to the nova cluster to destroy a random ACTIVE server. Update `state` to indicate TERMINATING. `connection` : object returned by kong.nova.API `state` : `State` object describing our view of state of cluster `pargs` : positional arguments `kwargs` : keyword arguments, which include: `timeout` : how long to wait before issuing Exception """ # check for active machines vms = state.get_machines() active_vms = [v for k, v in vms.iteritems() if v and v[1] == 'ACTIVE'] # no active vms, so return null if not active_vms: self._logger.info('no ACTIVE machines to delete') return _timeout = kwargs.get('timeout', 600) target = random.choice(active_vms) kill_target = target[0] connection.delete_server(kill_target['id']) self._logger.info('machine %s: ACTIVE -> TERMINATING' % kill_target['id']) state.set_machine_state(kill_target['id'], (kill_target, 'TERMINATING')) return VerifyKillActiveVM(connection, state, kill_target, timeout=_timeout)
def run(self, connection, state, *pargs, **kwargs): """ Send an HTTP POST request to the nova cluster to resize a random server. Update `state` to indicate server is rebooting. `connection` : object returned by kong.nova.API `state` : `State` object describing our view of state of cluster `pargs` : positional arguments `kwargs` : keyword arguments, which include: `timeout` : how long to wait before issuing Exception """ vms = state.get_machines() active_vms = [v for k, v in vms.iteritems() if v and v[1] == 'ACTIVE'] # no active vms, so return null if not active_vms: self._logger.debug('no ACTIVE machines to resize') return target = random.choice(active_vms) resize_target = target[0] print resize_target _timeout = kwargs.get('timeout', 600) # determine current flavor type, and resize to a different type # m1.tiny -> m1.small, m1.small -> m1.tiny curr_size = int(resize_target['flavor']['id']) if curr_size == 1: new_size = 2 else: new_size = 1 flavor_type = { 'flavorRef': new_size } # resize to m1.small post_body = json.dumps({'resize' : flavor_type}) url = '/servers/%s/action' % resize_target['id'] (response, body) = connection.request('POST', url, body=post_body) if (response.status != 202): self._logger.error("response: %s" % response) raise Exception state_name = check_for_status(connection, resize_target, 'RESIZE') if state_name == 'RESIZE': self._logger.info('machine %s: ACTIVE -> RESIZE' % resize_target['id']) state.set_machine_state(resize_target['id'], (resize_target, 'RESIZE')) return VerifyResizeVM(connection, state, resize_target, state_name=state_name, timeout=_timeout)
def run(self, connection, state, *pargs, **kwargs): """ Issue HTTP POST request to change the name of active server. Update state of server to reflect name changing. `connection` : object returned by kong.nova.API `state` : `State` object describing our view of state of cluster `pargs` : positional arguments `kwargs` : keyword arguments, which include: `timeout` : how long to wait before issuing Exception """ # select one machine from active ones vms = state.get_machines() active_vms = [v for k, v in vms.iteritems() if v and v[1] == 'ACTIVE'] # no active vms, so return null if not active_vms: self._logger.info('no active machines to update') return _timeout = kwargs.get('timeout', 600) target = random.choice(active_vms) update_target = target[0] # Update name by appending '_updated' to the name new_server = {'name': update_target['name'] + '_updated'} put_body = json.dumps({ 'server': new_server, }) url = '/servers/%s' % update_target['id'] (response, body) = connection.request('PUT', url, body=put_body) if (response.status != 200): self._logger.error("response: %s " % response) self._logger.error("body: %s " % body) raise Exception data = json.loads(body) assert(data.keys() == ['server']) _assert_server_entity(data['server'], connection) assert(update_target['name'] + '_updated' == data['server']['name']) self._logger.info('machine %s: ACTIVE -> UPDATING_NAME' % data['server']['id']) state.set_machine_state(data['server']['id'], (data['server'], 'UPDATING_NAME')) return VerifyUpdateVMName(connection, state, data['server'], timeout=_timeout)
def run(self, connection, state, *pargs, **kwargs): """ Send an HTTP POST request to the nova cluster to reboot a random server. Update state of object in `state` variable to indicate that it is rebooting. `connection` : object returned by kong.nova.API `state` : `State` object describing our view of state of cluster `pargs` : positional arguments `kwargs` : keyword arguments, which include: `timeout` : how long to wait before issuing Exception `type` : reboot type [SOFT or HARD] (default is SOFT) """ vms = state.get_machines() active_vms = [v for k, v in vms.iteritems() if v and v[1] == 'ACTIVE'] # no active vms, so return null if not active_vms: self._logger.info('no ACTIVE machines to reboot') return _reboot_type = kwargs.get('type', 'SOFT') _timeout = kwargs.get('timeout', 600) # select active vm to reboot and then send request to nova controller target = random.choice(active_vms) reboot_target = target[0] # allocate public address to this vm _ip_addr = allocate_ip(connection, reboot_target) reboot_body = { 'type': _reboot_type } post_body = json.dumps({'reboot' : reboot_body}) url = '/servers/%s/action' % reboot_target['id'] (response, body) = connection.request('POST', url, body=post_body) if (response.status != 202): self._logger.error("response: %s" % response) raise Exception if _reboot_type == 'SOFT': state_name = 'REBOOT' else: state_name = 'REBOOT' ### this is a bug, should be HARD_REBOOT self._logger.info('waiting for machine %s to change to %s' % (reboot_target['id'], state_name)) # check for state transition try: state_string = state_name connection.wait_for_server_status( reboot_target['id'], state_name, timeout=0 ) except AssertionError: # grab the actual state as we think it is temp_obj = state.get_machines()[self._target['id']] self._logger.debug( "machine %s in state %s" % (reboot_target['id'], temp_obj[1]) ) state_string = temp_obj[1] if state_string == state_name: self._logger.info('machine %s ACTIVE -> %s' % (reboot_target['id'], state_name)) state.set_machine_state(reboot_target['id'], (reboot_target, state_name)) return VerifyRebootVM(connection, state, reboot_target, timeout=_timeout, reboot_type=_reboot_type, state_name=state_string, ip_addr=_ip_addr)
def retry(self): """ Check to see that the server was actually resized. And change `state` of server to running again. """ # don't run resize if target machine has been deleted # or is going to be deleted if (self._target['id'] not in self._state.get_machines().keys() or self._state.get_machines()[self._target['id']][1] == 'TERMINATING'): self._logger.debug('machine %s is deleted or TERMINATING' % self._target['id']) return True if time.time() - self._start_time > self._timeout: raise TimeoutException if self._retry_state == self.States.VERIFY_RESIZE_CHECK: if self._check_for_status('VERIFY_RESIZE') == 'VERIFY_RESIZE': # now issue command to CONFIRM RESIZE post_body = json.dumps({'confirmResize' : null}) url = '/servers/%s/action' % self._target['id'] (response, body) = connection.request('POST', url, body=post_body) if (response.status != 204): self._logger.error("response: %s" % response) raise Exception self._logger.info( 'CONFIRMING RESIZE of machine %s [%.1f secs elapsed]' % (self._target['id'], time.time() - self._start_time) ) state.set_machine_state(self._target['id'], (self._target, 'CONFIRM_RESIZE')) # change states self._retry_state = self.States.ACTIVE_CHECK return False elif self._retry_state == self.States.ACTIVE_CHECK: if not self._check_connection("ACTIVE"): return False else: server = self._connection.get_server(self._target['id']) # Find private IP of server? try: (_, network) = server['addresses'].popitem() ip = network[0]['addr'] except KeyError: self._logger.error( 'could not get ip address for machine %s' % self._target['id'] ) raise Exception self._logger.info( 'machine %s: VERIFY_RESIZE -> ACTIVE [%.1f secs elapsed]' % (self._target['id'], time.time() - self._start_time) ) self._state.set_machine_state(self._target['id'], (self._target, 'ACTIVE')) return True else: # should never get here self._logger.error('Unexpected state') raise Exception
def run(self, connection, state, *pargs, **kwargs): """ Send an HTTP POST request to the nova cluster to build a server. Update the state variable to track state of new server and set to PENDING state. `connection` : object returned by kong.nova.API `state` : `State` object describing our view of state of cluster `pargs` : positional arguments `kwargs` : keyword arguments, which include: `key_name` : name of keypair `timeout` : how long to wait before issuing Exception `image_ref` : index to image types availablexs `flavor_ref`: index to flavor types available (default = 1, which is tiny) """ # restrict number of instances we can launch if len(state.get_machines()) >= state.get_max_machines(): self._logger.debug("maximum number of machines created: %d" % state.get_max_machines()) return None _key_name = kwargs.get('key_name', '') _timeout = int(kwargs.get('timeout', 60)) _image_ref = int(kwargs.get('image_ref', 2)) _flavor_ref = int(kwargs.get('flavor_ref', 1)) expected_server = { 'name': 'server' + str(TestCreateVM._vm_id), 'metadata': { 'key1': 'value1', 'key2': 'value2', }, 'imageRef': _image_ref, 'flavorRef': _flavor_ref, 'adminPass': '******', 'key_name' : _key_name } TestCreateVM._vm_id = TestCreateVM._vm_id + 1 post_body = json.dumps({'server': expected_server}) (response, body) = connection.request('POST', '/servers', body=post_body) if (response.status != 202): self._logger.error("response: %s" % response) self._logger.error("body: %s" % body) raise Exception _body = json.loads(body) assert(_body.keys() == ['server']) created_server = _body['server'] self._logger.info('setting machine %s to BUILD' % created_server['id']) state.set_machine_state(created_server['id'], (created_server, 'BUILD')) return VerifyCreateVM(connection, state, created_server, expected_server, timeout=_timeout)