mirror of
https://opendev.org/openstack/ansible-collections-openstack.git
synced 2026-07-28 18:54:29 +00:00
Added shelve and unshelve as new server actions
Task: 40737 Story: 2008056 Change-Id: I127ee59be74e9ebcf7f36b3fabdd6e41a5f7a3bb
This commit is contained in:
@@ -418,3 +418,103 @@
|
|||||||
that:
|
that:
|
||||||
- info19.openstack_servers.0.status in ('ACTIVE', 'REBUILD')
|
- info19.openstack_servers.0.status in ('ACTIVE', 'REBUILD')
|
||||||
- server is changed
|
- server is changed
|
||||||
|
|
||||||
|
- name: Shelve server
|
||||||
|
openstack.cloud.server_action:
|
||||||
|
cloud: "{{ cloud }}"
|
||||||
|
server: "{{ server_name }}"
|
||||||
|
action: shelve
|
||||||
|
wait: true
|
||||||
|
register: server
|
||||||
|
|
||||||
|
- name: Get info about server
|
||||||
|
openstack.cloud.server_info:
|
||||||
|
cloud: "{{ cloud }}"
|
||||||
|
server: "{{ server_name }}"
|
||||||
|
register: info20
|
||||||
|
|
||||||
|
- name: Ensure status for server is SHELVED or SHELVED_OFFLOADED
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- info20.openstack_servers.0.status in ['SHELVED', 'SHELVED_OFFLOADED']
|
||||||
|
- server is changed
|
||||||
|
|
||||||
|
- name: Shelve offload server
|
||||||
|
openstack.cloud.server_action:
|
||||||
|
cloud: "{{ cloud }}"
|
||||||
|
server: "{{ server_name }}"
|
||||||
|
action: shelve_offload
|
||||||
|
wait: true
|
||||||
|
register: server
|
||||||
|
|
||||||
|
- name: Get info about server
|
||||||
|
openstack.cloud.server_info:
|
||||||
|
cloud: "{{ cloud }}"
|
||||||
|
server: "{{ server_name }}"
|
||||||
|
register: info21
|
||||||
|
|
||||||
|
- name: Ensure status for server is SHELVED_OFFLOADED
|
||||||
|
# no change if server has been offloaded automatically after first shelve command
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- info21.openstack_servers.0.status == 'SHELVED_OFFLOADED'
|
||||||
|
|
||||||
|
- name: Shelve offload server again
|
||||||
|
openstack.cloud.server_action:
|
||||||
|
cloud: "{{ cloud }}"
|
||||||
|
server: "{{ server_name }}"
|
||||||
|
action: shelve_offload
|
||||||
|
wait: true
|
||||||
|
register: server
|
||||||
|
|
||||||
|
- name: Get info about server
|
||||||
|
openstack.cloud.server_info:
|
||||||
|
cloud: "{{ cloud }}"
|
||||||
|
server: "{{ server_name }}"
|
||||||
|
register: info22
|
||||||
|
|
||||||
|
- name: Ensure status for server is SHELVED_OFFLOADED
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- info22.openstack_servers.0.status == 'SHELVED_OFFLOADED'
|
||||||
|
- server is not changed
|
||||||
|
|
||||||
|
- name: Unshelve server
|
||||||
|
openstack.cloud.server_action:
|
||||||
|
cloud: "{{ cloud }}"
|
||||||
|
server: "{{ server_name }}"
|
||||||
|
action: unshelve
|
||||||
|
wait: true
|
||||||
|
register: server
|
||||||
|
|
||||||
|
- name: Get info about server
|
||||||
|
openstack.cloud.server_info:
|
||||||
|
cloud: "{{ cloud }}"
|
||||||
|
server: "{{ server_name }}"
|
||||||
|
register: info23
|
||||||
|
|
||||||
|
- name: Ensure status for server is ACTIVE
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- info23.openstack_servers.0.status == 'ACTIVE'
|
||||||
|
- server is changed
|
||||||
|
|
||||||
|
- name: Unshelve server again
|
||||||
|
openstack.cloud.server_action:
|
||||||
|
cloud: "{{ cloud }}"
|
||||||
|
server: "{{ server_name }}"
|
||||||
|
action: unshelve
|
||||||
|
wait: true
|
||||||
|
register: server
|
||||||
|
|
||||||
|
- name: Get info about server
|
||||||
|
openstack.cloud.server_info:
|
||||||
|
cloud: "{{ cloud }}"
|
||||||
|
server: "{{ server_name }}"
|
||||||
|
register: info24
|
||||||
|
|
||||||
|
- name: Ensure status for server is ACTIVE
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- info24.openstack_servers.0.status == 'ACTIVE'
|
||||||
|
- server is not changed
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ options:
|
|||||||
- Perform the given action. The lock and unlock actions always return
|
- Perform the given action. The lock and unlock actions always return
|
||||||
changed as the servers API does not provide lock status.
|
changed as the servers API does not provide lock status.
|
||||||
choices: [stop, start, pause, unpause, lock, unlock, suspend, resume,
|
choices: [stop, start, pause, unpause, lock, unlock, suspend, resume,
|
||||||
rebuild]
|
rebuild, shelve, shelve_offload, unshelve]
|
||||||
type: str
|
type: str
|
||||||
required: true
|
required: true
|
||||||
image:
|
image:
|
||||||
@@ -70,18 +70,43 @@ EXAMPLES = '''
|
|||||||
|
|
||||||
from ansible_collections.openstack.cloud.plugins.module_utils.openstack import OpenStackModule
|
from ansible_collections.openstack.cloud.plugins.module_utils.openstack import OpenStackModule
|
||||||
|
|
||||||
|
# If I(action) is set to C(shelve) then according to OpenStack's Compute API, the shelved
|
||||||
|
# server is in one of two possible states:
|
||||||
|
#
|
||||||
|
# SHELVED: The server is in shelved state. Depends on the shelve offload time,
|
||||||
|
# the server will be automatically shelved off loaded.
|
||||||
|
# SHELVED_OFFLOADED: The shelved server is offloaded (removed from the compute host) and
|
||||||
|
# it needs unshelved action to be used again.
|
||||||
|
#
|
||||||
|
# But wait_for_server can only wait for a single server state. If a shelved server is offloaded
|
||||||
|
# immediately, then a exceptions.ResourceTimeout will be raised if I(action) is set to C(shelve).
|
||||||
|
# This is likely to happen because shelved_offload_time in Nova's config is set to 0 by default.
|
||||||
|
# This also applies if you boot the server from volumes.
|
||||||
|
#
|
||||||
|
# Calling C(shelve_offload) instead of C(shelve) will also fail most likely because the default
|
||||||
|
# policy does not allow C(shelve_offload) for non-admin users while C(shelve) is allowed for
|
||||||
|
# admin users and server owners.
|
||||||
|
#
|
||||||
|
# As we cannot retrieve shelved_offload_time from Nova's config, we fall back to waiting for
|
||||||
|
# one state and if that fails then we fetch the server's state and match it against the other
|
||||||
|
# valid states from _action_map.
|
||||||
|
#
|
||||||
|
# Ref.: https://docs.openstack.org/api-guide/compute/server_concepts.html
|
||||||
|
|
||||||
_action_map = {'stop': 'SHUTOFF',
|
_action_map = {'stop': ['SHUTOFF'],
|
||||||
'start': 'ACTIVE',
|
'start': ['ACTIVE'],
|
||||||
'pause': 'PAUSED',
|
'pause': ['PAUSED'],
|
||||||
'unpause': 'ACTIVE',
|
'unpause': ['ACTIVE'],
|
||||||
'lock': 'ACTIVE', # API doesn't show lock/unlock status
|
'lock': ['ACTIVE'], # API doesn't show lock/unlock status
|
||||||
'unlock': 'ACTIVE',
|
'unlock': ['ACTIVE'],
|
||||||
'suspend': 'SUSPENDED',
|
'suspend': ['SUSPENDED'],
|
||||||
'resume': 'ACTIVE',
|
'resume': ['ACTIVE'],
|
||||||
'rebuild': 'ACTIVE'}
|
'rebuild': ['ACTIVE'],
|
||||||
|
'shelve': ['SHELVED_OFFLOADED', 'SHELVED'],
|
||||||
|
'shelve_offload': ['SHELVED_OFFLOADED'],
|
||||||
|
'unshelve': ['ACTIVE']}
|
||||||
|
|
||||||
_admin_actions = ['pause', 'unpause', 'suspend', 'resume', 'lock', 'unlock']
|
_admin_actions = ['pause', 'unpause', 'suspend', 'resume', 'lock', 'unlock', 'shelve_offload']
|
||||||
|
|
||||||
|
|
||||||
class ServerActionModule(OpenStackModule):
|
class ServerActionModule(OpenStackModule):
|
||||||
@@ -92,7 +117,7 @@ class ServerActionModule(OpenStackModule):
|
|||||||
action=dict(required=True, type='str',
|
action=dict(required=True, type='str',
|
||||||
choices=['stop', 'start', 'pause', 'unpause',
|
choices=['stop', 'start', 'pause', 'unpause',
|
||||||
'lock', 'unlock', 'suspend', 'resume',
|
'lock', 'unlock', 'suspend', 'resume',
|
||||||
'rebuild']),
|
'rebuild', 'shelve', 'shelve_offload', 'unshelve']),
|
||||||
image=dict(required=False, type='str'),
|
image=dict(required=False, type='str'),
|
||||||
admin_password=dict(required=False, type='str'),
|
admin_password=dict(required=False, type='str'),
|
||||||
)
|
)
|
||||||
@@ -128,6 +153,9 @@ class ServerActionModule(OpenStackModule):
|
|||||||
def _execute_server_action(self, os_server):
|
def _execute_server_action(self, os_server):
|
||||||
if self.params['action'] == 'rebuild':
|
if self.params['action'] == 'rebuild':
|
||||||
return self._rebuild_server(os_server)
|
return self._rebuild_server(os_server)
|
||||||
|
if self.params['action'] == 'shelve_offload':
|
||||||
|
# shelve_offload is not supported in OpenstackSDK
|
||||||
|
return self._action(os_server, json={'shelveOffload': None})
|
||||||
action_name = self.params['action'] + "_server"
|
action_name = self.params['action'] + "_server"
|
||||||
try:
|
try:
|
||||||
func_name = getattr(self.conn.compute, action_name)
|
func_name = getattr(self.conn.compute, action_name)
|
||||||
@@ -154,23 +182,38 @@ class ServerActionModule(OpenStackModule):
|
|||||||
admin_password=self.params['admin_password']
|
admin_password=self.params['admin_password']
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.conn.compute.post(
|
self._action(os_server, json={'rebuild': {'imageRef': image['id']}})
|
||||||
'/servers/{server_id}/action'.format(
|
|
||||||
server_id=os_server['id']),
|
def _action(self, os_server, json):
|
||||||
json={'rebuild': {'imageRef': image['id']}})
|
response = self.conn.compute.post(
|
||||||
|
'/servers/{server_id}/action'.format(server_id=os_server['id']),
|
||||||
|
json=json)
|
||||||
|
self.sdk.exceptions.raise_from_response(response)
|
||||||
|
return response
|
||||||
|
|
||||||
def _wait(self, os_server):
|
def _wait(self, os_server):
|
||||||
"""Wait for the server to reach the desired state for the given action."""
|
"""Wait for the server to reach the desired state for the given action."""
|
||||||
# Using Server object for wait_for_server function
|
# Using Server object for wait_for_server function
|
||||||
server = self.conn.compute.find_server(self.params['server'])
|
server = self.conn.compute.find_server(self.params['server'])
|
||||||
self.conn.compute.wait_for_server(
|
states = _action_map[self.params['action']]
|
||||||
server,
|
|
||||||
status=_action_map[self.params['action']],
|
try:
|
||||||
wait=self.params['timeout'])
|
self.conn.compute.wait_for_server(
|
||||||
|
server,
|
||||||
|
status=states[0],
|
||||||
|
wait=self.params['timeout'])
|
||||||
|
except self.sdk.exceptions.ResourceTimeout:
|
||||||
|
# raise if there is only one valid state
|
||||||
|
if len(states) < 2:
|
||||||
|
raise
|
||||||
|
# fetch current server status and compare to other valid states
|
||||||
|
server = self.conn.compute.get_server(os_server['id'])
|
||||||
|
if server.status not in states:
|
||||||
|
raise
|
||||||
|
|
||||||
def __system_state_change(self, os_server):
|
def __system_state_change(self, os_server):
|
||||||
"""Check if system state would change."""
|
"""Check if system state would change."""
|
||||||
return os_server.status != _action_map[self.params['action']]
|
return os_server.status not in _action_map[self.params['action']]
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|||||||
Reference in New Issue
Block a user