Commit 19522a57 authored by Stavros Sachtouris's avatar Stavros Sachtouris

Check server status before changing it

Fixes grnet/kamaki#57

This fix affects the CLI commands "server_start", "server_reboot"
and "server_shutdown" which are specified in "kamaki.cli.cmds.cyclades".
These are the operations that modify the status of a server.

The problem was caused when the target status was the same as the current.
In this case, the request for status modification would fail with a 400
error code response. At this point, kamaki couldn't have adequate information
to correctly evaluate the error.

This problem is solved by checking the current status before attempting to
modify it.  Also, the server ID is validated in advance, instead of waiting
for a 400 server error.
parent 26115ba5
......@@ -16,6 +16,7 @@ Bug fixes
* Handle non-ascii characters when managing configuration options
[grnet/kamaki#76]
* Handle SSL unicode bug with grace [grnet/kamaki#67]
* Check server status before changing it [grnet/kamaki#57]
v0.13rc5
========
......
......@@ -76,6 +76,17 @@ class _ServerWait(Wait):
countdown=(current_status not in ('BUILD', )),
timeout=timeout if current_status not in ('BUILD', ) else 100)
def assert_not_in_status(self, server_id, status):
"""
:returns: current server status
:raises CLIError: if server is already in this status
:raises ClientError: (404) if server not found
"""
current = self.client.get_server_details(server_id).get('status', None)
if current in (status, ):
raiseCLIError('Server %s is already %s' % (server_id, status))
return current
class _CycladesInit(CommandInit):
@errors.Generic.all
......@@ -790,13 +801,7 @@ class server_start(_CycladesInit, _ServerWait):
@errors.Cyclades.connection
@errors.Cyclades.server_id
def _run(self, server_id):
status = 'ACTIVE'
if self['wait']:
details = self.client.get_server_details(server_id)
status = details['status']
if status in ('ACTIVE', ):
return
status = self.assert_not_in_status(server_id, 'ACTIVE')
self.client.start_server(int(server_id))
if self['wait']:
self.wait(server_id, status)
......@@ -818,13 +823,7 @@ class server_shutdown(_CycladesInit, _ServerWait):
@errors.Cyclades.connection
@errors.Cyclades.server_id
def _run(self, server_id):
status = 'STOPPED'
if self['wait']:
details = self.client.get_server_details(server_id)
status = details['status']
if status in ('STOPPED', ):
return
status = self.assert_not_in_status(server_id, 'STOPPED')
self.client.shutdown_server(int(server_id))
if self['wait']:
self.wait(server_id, status)
......
......@@ -432,18 +432,21 @@ class Cyclades(object):
@classmethod
def server_id(this, func):
def _raise(self, *args, **kwargs):
details = ['To get a list of all servers', ' kamaki server list']
server_id = kwargs.get('server_id', None)
try:
server_id = int(server_id)
assert server_id > 0, 'error: %s is not positive' % server_id
except (ValueError, AssertionError) as err:
raise CLIError(
'Invalid server id %s' % server_id,
importance=2, details=[
'Server id must be a positive integer'] + details + [
err, ])
try:
return func(self, *args, **kwargs)
except ClientError as ce:
if ce.status in (404, 400):
server_id = kwargs.get('server_id', None)
details = [
'to get a list of all servers', ' kamaki server list']
if ce.status in (404, ):
try:
server_id = int(server_id)
except ValueError:
details.insert(0, 'Server ID must be an integer')
if ce.status in (404, ):
raise CLIError(
'No servers with ID %s' % server_id,
importance=2, details=details + [
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment