docker_swarm: hopefully fix debug CI problems, and fix check mode (#52825)

* Let's see some debug output.

* Also check LocalNodeState.

* Improve tests.

* Actually implement check mode.

* Add changelog.

* Add pretty-printing and more output.

(cherry picked from commit 81d58cfef6)
pull/53192/head
Felix Fontein 6 years ago committed by Toshio Kuratomi
parent 8ae9f99979
commit 23d9efc1f3

@ -0,0 +1,3 @@
bugfixes:
- "docker_swarm - improve Swarm detection."
- "docker_swarm - properly implement check mode (it did apply changes)."

@ -295,6 +295,7 @@ class SwarmManager(DockerBaseClass):
self.client = client self.client = client
self.results = results self.results = results
self.check_mode = self.client.check_mode self.check_mode = self.client.check_mode
self.swarm_info = {}
self.parameters = TaskParameters(client) self.parameters = TaskParameters(client)
@ -333,17 +334,18 @@ class SwarmManager(DockerBaseClass):
self.__update_swarm() self.__update_swarm()
return return
try: if not self.check_mode:
self.client.init_swarm( try:
advertise_addr=self.parameters.advertise_addr, listen_addr=self.parameters.listen_addr, self.client.init_swarm(
force_new_cluster=self.parameters.force_new_cluster, swarm_spec=self.parameters.spec) advertise_addr=self.parameters.advertise_addr, listen_addr=self.parameters.listen_addr,
except APIError as exc: force_new_cluster=self.parameters.force_new_cluster, swarm_spec=self.parameters.spec)
self.client.fail(msg="Can not create a new Swarm Cluster: %s" % to_native(exc)) except APIError as exc:
self.client.fail("Can not create a new Swarm Cluster: %s" % to_native(exc))
self.__isSwarmManager() self.__isSwarmManager()
self.results['actions'].append("New Swarm cluster created: %s" % (self.swarm_info['ID'])) self.results['actions'].append("New Swarm cluster created: %s" % (self.swarm_info.get('ID')))
self.results['changed'] = True self.results['changed'] = True
self.results['swarm_facts'] = {u'JoinTokens': self.swarm_info['JoinTokens']} self.results['swarm_facts'] = {u'JoinTokens': self.swarm_info.get('JoinTokens')}
def __update_spec(self, spec): def __update_spec(self, spec):
if (self.parameters.node_cert_expiry is None): if (self.parameters.node_cert_expiry is None):
@ -393,9 +395,10 @@ class SwarmManager(DockerBaseClass):
self.results['actions'].append("No modification") self.results['actions'].append("No modification")
self.results['changed'] = False self.results['changed'] = False
return return
self.client.update_swarm( if not self.check_mode:
version=version, swarm_spec=new_spec, rotate_worker_token=self.parameters.rotate_worker_token, self.client.update_swarm(
rotate_manager_token=self.parameters.rotate_manager_token) version=version, swarm_spec=new_spec, rotate_worker_token=self.parameters.rotate_worker_token,
rotate_manager_token=self.parameters.rotate_manager_token)
except APIError as exc: except APIError as exc:
self.client.fail(msg="Can not update a Swarm Cluster: %s" % to_native(exc)) self.client.fail(msg="Can not update a Swarm Cluster: %s" % to_native(exc))
return return
@ -411,18 +414,21 @@ class SwarmManager(DockerBaseClass):
self.swarm_info = json.loads(json_str) self.swarm_info = json.loads(json_str)
if self.swarm_info['Swarm']['NodeID']: if self.swarm_info['Swarm']['NodeID']:
return True return True
if self.swarm_info['Swarm']['LocalNodeState'] in ('active', 'pending', 'locked'):
return True
return False return False
def join(self): def join(self):
if self.__isSwarmNode(): if self.__isSwarmNode():
self.results['actions'].append("This node is already part of a swarm.") self.results['actions'].append("This node is already part of a swarm.")
return return
try: if not self.check_mode:
self.client.join_swarm( try:
remote_addrs=self.parameters.remote_addrs, join_token=self.parameters.join_token, listen_addr=self.parameters.listen_addr, self.client.join_swarm(
advertise_addr=self.parameters.advertise_addr) remote_addrs=self.parameters.remote_addrs, join_token=self.parameters.join_token, listen_addr=self.parameters.listen_addr,
except APIError as exc: advertise_addr=self.parameters.advertise_addr)
self.client.fail(msg="Can not join the Swarm Cluster: %s" % to_native(exc)) except APIError as exc:
self.client.fail("Can not join the Swarm Cluster: %s" % to_native(exc))
self.results['actions'].append("New node is added to swarm cluster") self.results['actions'].append("New node is added to swarm cluster")
self.results['changed'] = True self.results['changed'] = True
@ -430,11 +436,12 @@ class SwarmManager(DockerBaseClass):
if not(self.__isSwarmNode()): if not(self.__isSwarmNode()):
self.results['actions'].append("This node is not part of a swarm.") self.results['actions'].append("This node is not part of a swarm.")
return return
try: if not self.check_mode:
self.client.leave_swarm(force=self.parameters.force) try:
except APIError as exc: self.client.leave_swarm(force=self.parameters.force)
self.client.fail(msg="This node can not leave the Swarm Cluster: %s" % to_native(exc)) except APIError as exc:
self.results['actions'].append("Node has leaved the swarm cluster") self.client.fail("This node can not leave the Swarm Cluster: %s" % to_native(exc))
self.results['actions'].append("Node has left the swarm cluster")
self.results['changed'] = True self.results['changed'] = True
def __get_node_info(self): def __get_node_info(self):
@ -466,10 +473,11 @@ class SwarmManager(DockerBaseClass):
if not(status_down): if not(status_down):
self.client.fail(msg="Can not remove the node. The status node is ready and not down.") self.client.fail(msg="Can not remove the node. The status node is ready and not down.")
try: if not self.check_mode:
self.client.remove_node(node_id=self.parameters.node_id, force=self.parameters.force) try:
except APIError as exc: self.client.remove_node(node_id=self.parameters.node_id, force=self.parameters.force)
self.client.fail(msg="Can not remove the node from the Swarm Cluster: %s" % to_native(exc)) except APIError as exc:
self.client.fail("Can not remove the node from the Swarm Cluster: %s" % to_native(exc))
self.results['actions'].append("Node is removed from swarm cluster.") self.results['actions'].append("Node is removed from swarm cluster.")
self.results['changed'] = True self.results['changed'] = True

@ -29,30 +29,73 @@
- 'output.failed' - 'output.failed'
- 'output.msg == "state is remove but all of the following are missing: node_id"' - 'output.msg == "state is remove but all of the following are missing: node_id"'
- name: Create a Swarm cluster (check mode)
docker_swarm:
state: present
check_mode: yes
register: output_1
- name: Create a Swarm cluster - name: Create a Swarm cluster
docker_swarm: docker_swarm:
state: present state: present
register: output register: output_2
- name: Create a Swarm cluster (idempotent)
docker_swarm:
state: present
register: output_3
- name: Create a Swarm cluster (idempotent, check mode)
docker_swarm:
state: present
check_mode: yes
register: output_4
- name: assert changed when create a new swarm cluster - name: assert changed when create a new swarm cluster
assert: assert:
that: that:
- 'output.changed' - 'output_1 is changed'
- 'output.actions[0] | regex_search("New Swarm cluster created: ")' - 'output_2 is changed'
- 'output.swarm_facts.JoinTokens.Manager' - 'output_2.actions[0] | regex_search("New Swarm cluster created: ")'
- 'output.swarm_facts.JoinTokens.Worker' - 'output_2.swarm_facts.JoinTokens.Manager'
- 'output_2.swarm_facts.JoinTokens.Worker'
- 'output_3 is not changed'
- 'output_4 is not changed'
- name: Remove a Swarm cluster (check mode)
docker_swarm:
state: absent
force: true
check_mode: yes
register: output_1
- name: Remove a Swarm cluster - name: Remove a Swarm cluster
docker_swarm: docker_swarm:
state: absent state: absent
force: true force: true
register: output register: output_2
- name: Remove a Swarm cluster (idempotent)
docker_swarm:
state: absent
force: true
register: output_3
- name: Remove a Swarm cluster (idempotent, check mode)
docker_swarm:
state: absent
force: true
check_mode: yes
register: output_4
- name: assert changed when remove a swarm cluster - name: assert changed when remove a swarm cluster
assert: assert:
that: that:
- 'output.changed' - 'output_1 is changed'
- 'output.actions[0] == "Node has leaved the swarm cluster"' - 'output_2 is changed'
- 'output_2.actions[0] == "Node has left the swarm cluster"'
- 'output_3 is not changed'
- 'output_4 is not changed'
always: always:
- name: Cleanup - name: Cleanup

Loading…
Cancel
Save