jboss module: add check mode support and integration tests (#58959)

* git war file and wildfly archive from S3
* create setup_wildfly_server role for integration tests
This commit is contained in:
Andrey Klychkov 2019-07-15 19:17:08 +03:00 committed by Sam Doran
parent 30206d3066
commit 2a07123fdd
12 changed files with 433 additions and 7 deletions

View file

@ -28,6 +28,8 @@ options:
src: src:
description: description:
- The remote path of the application ear or war to deploy. - The remote path of the application ear or war to deploy.
- Required when I(state=present).
- Ignored when I(state=absent).
type: path type: path
deploy_path: deploy_path:
default: /var/lib/jbossas/standalone/deployments default: /var/lib/jbossas/standalone/deployments
@ -42,25 +44,28 @@ options:
type: str type: str
notes: notes:
- The JBoss standalone deployment-scanner has to be enabled in standalone.xml - The JBoss standalone deployment-scanner has to be enabled in standalone.xml
- The module can wait until I(deployment) file is deployed/undeployed by deployment-scanner.
Duration of waiting time depends on scan-interval parameter from standalone.xml.
- Ensure no identically named application is deployed through the JBoss CLI - Ensure no identically named application is deployed through the JBoss CLI
author: author:
- Jeroen Hoekx (@jhoekx) - Jeroen Hoekx (@jhoekx)
""" """
EXAMPLES = r""" EXAMPLES = r"""
- name: Deploy a hello world application - name: Deploy a hello world application to the default deploy_path
jboss: jboss:
src: /tmp/hello-1.0-SNAPSHOT.war src: /tmp/hello-1.0-SNAPSHOT.war
deployment: hello.war deployment: hello.war
state: present state: present
- name: Update the hello world application - name: Update the hello world application to the non-default deploy_path
jboss: jboss:
src: /tmp/hello-1.1-SNAPSHOT.war src: /tmp/hello-1.1-SNAPSHOT.war
deploy_path: /opt/wildfly/deployment
deployment: hello.war deployment: hello.war
state: present state: present
- name: Undeploy the hello world application - name: Undeploy the hello world application from the default deploy_path
jboss: jboss:
deployment: hello.war deployment: hello.war
state: absent state: absent
@ -74,6 +79,9 @@ import time
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
DEFAULT_DEPLOY_PATH = '/var/lib/jbossas/standalone/deployments'
def is_deployed(deploy_path, deployment): def is_deployed(deploy_path, deployment):
return os.path.exists(os.path.join(deploy_path, "%s.deployed" % deployment)) return os.path.exists(os.path.join(deploy_path, "%s.deployed" % deployment))
@ -91,10 +99,11 @@ def main():
argument_spec=dict( argument_spec=dict(
src=dict(type='path'), src=dict(type='path'),
deployment=dict(type='str', required=True), deployment=dict(type='str', required=True),
deploy_path=dict(type='path', default='/var/lib/jbossas/standalone/deployments'), deploy_path=dict(type='path', default=DEFAULT_DEPLOY_PATH),
state=dict(type='str', choices=['absent', 'present'], default='present'), state=dict(type='str', choices=['absent', 'present'], default='present'),
), ),
required_if=[('state', 'present', ('src',))] required_if=[('state', 'present', ('src',))],
supports_check_mode=True
) )
result = dict(changed=False) result = dict(changed=False)
@ -107,11 +116,30 @@ def main():
if not os.path.exists(deploy_path): if not os.path.exists(deploy_path):
module.fail_json(msg="deploy_path does not exist.") module.fail_json(msg="deploy_path does not exist.")
if state == 'absent' and src:
module.warn('Parameter src is ignored when state=absent')
elif state == 'present' and not os.path.exists(src):
module.fail_json(msg='Source file %s does not exist.' % src)
deployed = is_deployed(deploy_path, deployment) deployed = is_deployed(deploy_path, deployment)
# === when check_mode ===
if module.check_mode:
if state == 'present':
if not deployed:
result['changed'] = True
elif deployed:
if module.sha1(src) != module.sha1(os.path.join(deploy_path, deployment)):
result['changed'] = True
elif state == 'absent' and deployed:
result['changed'] = True
module.exit_json(**result)
# =======================
if state == 'present' and not deployed: if state == 'present' and not deployed:
if not os.path.exists(src):
module.fail_json(msg='Source file %s does not exist.' % src)
if is_failed(deploy_path, deployment): if is_failed(deploy_path, deployment):
# Clean up old failed deployment # Clean up old failed deployment
os.remove(os.path.join(deploy_path, "%s.failed" % deployment)) os.remove(os.path.join(deploy_path, "%s.failed" % deployment))

View file

@ -0,0 +1,6 @@
destructive
shippable/posix/group1
skip/osx
skip/freebsd
skip/rhel
needs/root

View file

@ -0,0 +1,3 @@
---
dependencies:
- setup_wildfly_server

View file

@ -0,0 +1,236 @@
# Copyright: (c) 2019, Andrew Klychkov (@Andersson007) <aaklychkov@mail.ru>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# Integration tests for jboss module.
# helloworld.war (got from https://github.com/aeimer/java-example-helloworld-war/) license:
# MIT License
#
# Copyright (c) 2017 Alex Eimer
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
# ===============================
# Module's note section contains:
# "- The JBoss standalone deployment-scanner has to be enabled in standalone.xml"
#
# Also from https://docs.jboss.org/author/display/WFLY10/Application+deployment?_sscc=t
# "Deployment content (for example, war, ear, jar, and sar files) can be placed
# in the standalone/deployments directory of the WildFly distribution,
# in order to be automatically deployed into the server runtime.
# For this to work the deployment-scanner subsystem must be present.
# The scanner periodically checks the contents of the deployments directory
# and reacts to changes by updating the server."
# Regarding the information above JBoss server must be installed and running for full test suite.
# We use WildFly server, free alternative, instead. See setup_wildfly_server role for more information.
- vars:
war_file_1: 'helloworld-1.war'
war_file_1_path: '{{ wf_homedir }}/{{ war_file_1 }}'
fake_src_path: /fake/src
test_deployment: helloworld-1.war
task_parameters: &task_parameters
become_user: '{{ wf_user }}'
become: yes
register: result
block:
- name: Create test files
<<: *task_parameters
get_url:
url: 'https://ansible-ci-files.s3.amazonaws.com/test/integration/targets/jboss/{{ war_file_1 }}'
dest: '{{ wf_homedir }}'
##################
# Start the tests:
# Test if state=present and not deployed, check_mode:
- name: jboss - deploy war in check_mode, the default deploy_path
<<: *task_parameters
jboss:
deployment: '{{ war_file_1 }}'
src: '{{ war_file_1_path }}'
check_mode: yes
- assert:
that:
- result is changed
# Check
- name: check that nothing changed after the previous step
<<: *task_parameters
file:
path: '{{ deploy_dir }}/{{ war_file_1 }}.deployed'
ignore_errors: yes
- assert:
that:
- "'is absent' in result.msg"
# Test if state=present and not deployed, actual mode:
- name: jboss - deploy war
<<: *task_parameters
jboss:
deployment: helloworld-1.war
deploy_path: '{{ deploy_dir }}'
src: '{{ war_file_1_path }}'
- assert:
that:
- result is changed
# Check
- name: check that the file is deployed after the previous step
<<: *task_parameters
file:
path: '{{ deploy_dir }}/{{ war_file_1 }}.deployed'
- assert:
that:
- result.state == 'file'
# Test if state=present and deployed in check mode, try again:
- name: jboss - try again to deploy war in check_mode, war is deployed now
<<: *task_parameters
jboss:
deployment: '{{ war_file_1 }}'
src: '{{ war_file_1_path }}'
deploy_path: '{{ deploy_dir }}'
check_mode: yes
- assert:
that:
- result is not changed
# Test if state=present and deployed, try again:
- name: jboss - try again to deploy war in actual mode, war is deployed now
<<: *task_parameters
jboss:
deployment: '{{ war_file_1 }}'
src: '{{ war_file_1_path }}'
deploy_path: '{{ deploy_dir }}'
- assert:
that:
- result is not changed
# Check
- name: check that nothing changed after the previous step
<<: *task_parameters
file:
path: '{{ deploy_dir }}/{{ war_file_1 }}.deployed'
- assert:
that:
- result.state == 'file'
# Test if state=absent and deployed:
- name: jboss - undeploy war in check_mode, war is deployed
<<: *task_parameters
jboss:
deployment: '{{ war_file_1 }}'
deploy_path: '{{ deploy_dir }}'
state: absent
check_mode: yes
- assert:
that:
- result is changed
- name: check that nothing actually changed after the previous step
<<: *task_parameters
file:
path: '{{ deploy_dir }}/{{ war_file_1 }}.deployed'
- assert:
that:
- result.state == 'file'
# Test if state=absent and deployed:
- name: jboss - undeploy war in actual mode, war is deployed
<<: *task_parameters
jboss:
deployment: '{{ war_file_1 }}'
deploy_path: '{{ deploy_dir }}'
state: absent
- assert:
that:
- result is changed
- name: check that file is undeployed after the previous step
<<: *task_parameters
file:
path: '{{ deploy_dir }}/{{ war_file_1 }}.undeployed'
- assert:
that:
- result.state == 'file'
# Test if state=absent and undeployed:
- name: jboss - undeploy war in check_mode, war is undeployed
<<: *task_parameters
jboss:
deployment: '{{ war_file_1 }}'
deploy_path: '{{ deploy_dir }}'
state: absent
check_mode: yes
- assert:
that:
- result is not changed
# Test if state=absent and undeployed:
- name: jboss - undeploy war in actual_mode, war is undeployed
<<: *task_parameters
jboss:
deployment: '{{ war_file_1 }}'
deploy_path: '{{ deploy_dir }}'
state: absent
- assert:
that:
- result is not changed
# Test fake src:
- name: jboss - test fake src
<<: *task_parameters
jboss:
deployment: '{{ war_file_1 }}'
deploy_path: '{{ deploy_dir }}'
src: '{{ fake_src_path }}'
state: present
ignore_errors: yes
- assert:
that:
- result is failed
- "'Source file {{ fake_src_path }} does not exist.' in result.msg"
# Test errors where state=present and src is not passed:
- name: jboss - must fail when state=present and src is not passed
<<: *task_parameters
jboss:
deployment: '{{ war_file_1 }}'
state: present
ignore_errors: yes
- assert:
that:
- result is failed
- "'state is present but all of the following are missing: src' in result.msg"

View file

@ -0,0 +1 @@
- import_tasks: jboss.yml

View file

@ -0,0 +1,8 @@
wf_tmp_dir: '{{ remote_tmp_dir }}/wildfly_tmp'
wf_homedir: '{{ wf_tmp_dir }}/wildfly'
wf_service_file_path: /etc/systemd/system/wildfly.service
wf_version: 16.0.0.Final
wf_user: wildfly
jboss_root: '{{ wf_homedir }}'
deploy_dir: '{{ jboss_root }}/standalone/deployments'
default_deploy_root: /var/lib/jbossas/standalone/deployments

View file

@ -0,0 +1,8 @@
# The configuration you want to run
WILDFLY_CONFIG=standalone.xml
# The mode you want to run
WILDFLY_MODE=standalone
# The address to bind to
WILDFLY_BIND=0.0.0.0

View file

@ -0,0 +1,13 @@
- name: Stop wildfly (jboss)
systemd:
name: wildfly
state: stopped
ignore_errors: yes
- name: Remove files
file:
path: '{{ item }}'
state: absent
loop:
- '{{ wf_service_file_path }}'
- '{{ default_deploy_root }}'

View file

@ -0,0 +1,2 @@
dependencies:
- setup_remote_tmp_dir

View file

@ -0,0 +1,94 @@
- name: Skip unsupported platforms
meta: end_play
when: (ansible_distribution != 'CentOS') or
(ansible_distribution == 'CentOS' and ansible_distribution_major_version is not version('7', '>='))
- name: Install java
package:
name: java-1.8.0-openjdk-devel
- name: Create wf_tmp_dir
file:
path: '{{ wf_tmp_dir }}'
state: directory
- name: Download wildfly
get_url:
url: 'https://ansible-ci-files.s3.amazonaws.com/test/integration/targets/setup_wildfly_server/wildfly-{{ wf_version }}.tar.gz'
dest: '{{ wf_tmp_dir }}/wildfly-{{ wf_version }}.tar.gz'
- name: Unarchive tar
unarchive:
src: '{{ wf_tmp_dir }}/wildfly-{{ wf_version }}.tar.gz'
dest: '{{ wf_tmp_dir }}'
remote_src: yes
- name: Remove tar
file:
path: '{{ wf_tmp_dir }}/wildfly-{{ wf_version }}.tar.gz'
state: absent
- name: Create symlink
file:
src: '{{ wf_tmp_dir }}/wildfly-{{ wf_version }}'
dest: '{{ wf_tmp_dir }}/wildfly'
state: link
- name: Create group for wildfly
group:
name: '{{ wf_user }}'
system: yes
- name: Create user for wildfly
user:
name: '{{ wf_user }}'
system: yes
group: '{{ wf_user }}'
home: '{{ wf_homedir }}'
- name: Set permissions
file:
path: '{{ remote_tmp_dir }}'
state: directory
owner: '{{ wf_user }}'
group: '{{ wf_user }}'
recurse: yes
- name: Create config file
copy:
src: wildfly.conf
dest: '{{ wf_homedir }}/wildfly.conf'
- name: Create launcher
template:
src: launch.sh.j2
dest: '{{ wf_homedir }}/bin/launch.sh'
- name: Make scripts executable
shell: 'chmod +x {{ wf_homedir }}/bin/*.sh'
- name: Create service file
template:
src: wildfly.service.j2
dest: '{{ wf_service_file_path }}'
- name: Create directories for testing the default deploy_path
become: yes
file:
path: '{{ default_deploy_root }}'
state: directory
recurse: yes
owner: '{{ wf_user }}'
group: '{{ wf_user }}'
- name: Create simlink for testing the default deploy_path
file:
state: link
src: '{{ deploy_dir }}'
dest: '{{ default_deploy_root }}/deployments'
- name: Reload systemd and start wildfly
systemd:
daemon_reload: yes
name: wildfly
state: started

View file

@ -0,0 +1,11 @@
#!/usr/bin/env bash
if [ "x$WILDFLY_HOME" = "x" ]; then
WILDFLY_HOME="{{ wf_homedir }}"
fi
if [[ "$1" == "domain" ]]; then
$WILDFLY_HOME/bin/domain.sh -c "$2" -b "$3"
else
$WILDFLY_HOME/bin/standalone.sh -c "$2" -b "$3"
fi

View file

@ -0,0 +1,16 @@
[Unit]
Description=The WildFly Application Server
After=syslog.target network.target
Before=httpd.service
[Service]
Environment=LAUNCH_JBOSS_IN_BACKGROUND=1
EnvironmentFile=-{{ wf_homedir }}/wildfly.conf
User=wildfly
LimitNOFILE=102642
PIDFile=/var/run/wildfly/wildfly.pid
ExecStart={{ wf_homedir }}/bin/launch.sh $WILDFLY_MODE $WILDFLY_CONFIG $WILDFLY_BIND
StandardOutput=null
[Install]
WantedBy=multi-user.target