尝试使用GitLab CI来执行自制的Ansible模块CI
这是2018年 Ansible Advent Calendar 的第8篇文章。
我想在这里尝试一下使用GitLab CI进行Ansible自定义模块的CI。之前的一篇文章中我们介绍了如何使用GitLab CI。
(Note: The translation provided is in simplified Chinese. If you prefer traditional Chinese, please let me know.)
-
- Ansibleモジュールを自作したらsanityテストをしてみよう
- Ansibleモジュールを自作したらunitテストをしてみよう
我撰写了一篇关于这个问题的文章,目的是为了手动测试并希望自动化sanity/unit测试以提高效率。
由于我在这里省略了一些解释部分,建议您先阅读上述文章,然后会更容易理解。
1. 环境
2. 准备
2-1. GitLab安装
请参考以下内容以安装GitLab。
请点击以下链接,获取关于在CentOS 7上安装GitLab的详细说明:https://about.gitlab.com/install/#centos-7
准备gitlab-runner
请参考以下内容进行准备。
顺便提一下,我们将使用docker。
以下是该网址的汉语本地化短语(仅提供一种选项):
https://qiita.com/sky_jokerxx/items/2a264a0194a5cbc7bd12
– 这个链接是指向一个名为”sky_jokerxx”的个人主页的帖子。
3. 我尝试着做一下CI。
3-1. 创建Docker镜像
Docker镜像有以下选项可供选择。
-
- 公式のDockerイメージを使う
- 自分でイメージを作る
由于前者已经可用,因此可以轻松使用。然而,Python的版本包括所有(Python2.6〜3.7已安装),所以占用空间不大。
而后者的准备工作需要从头开始,但只需安装所需内容,其容量比官方提供的要小。
例如,如果已经确定要测试的Python版本,则可以选择从头开始创建。
在这里,我打算使用前者预先准备好的镜像。
3-1-1. 创建Dockerfile文件
只要你能把自己创建的模块保存在适当的组下 ansible/modules,这样就可以了。但是在这里,我们假设这是自制的模块,所以我会创建 ansible/modules/salf_made 和 test/units/modules/salf_made 这两个目录,并在其中保存自制的模块和测试用源码。
FROM quay.io/ansible/default-test-container:latest
RUN ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
RUN cd /opt && \
git clone https://github.com/ansible/ansible.git && \
cd ansible && \
mkdir lib/ansible/modules/salf_made/ && \
mkdir test/units/modules/salf_made
RUN apt-get -y install man-db
3-1-2. 创建Docker镜像
[root@GitLab ~]# mkdir ansible-ci-docker
[root@GitLab ~]# cd ansible-ci-docker/
[root@GitLab ansible-ci-docker]# vi Dockerfile
(上記のDockerfileをコピー)
[root@GitLab ansible-ci-docker]# docker build . -t ansible-ci:latest
创建存储库
在这里,我试着在GitLab上创建了以下仓库。

__init__.py 是一个空文件。
output_name.py 的源代码如下。我在这基础上进行了一些修改,以便能够进行单元测试(只是添加了一个 sum 函数)并重新利用它。
至于 test_output_name.py 的源代码,我会在 Unit test CI 中进行说明(在 sanity 测试中不需要)。
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright: (c) 2018, sky_joker
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {
'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'
}
DOCUMENTATION = '''
module: output_name
short_description: module that outputs a name.
author:
- sky_joker (@sky-jocker)
version_added: 2.x
description:
- Output the specified name.
requirements:
- python >= 2.7
options:
name:
description:
- Specify name.
required: True
'''
EXAMPLES = '''
---
- output_name:
name: taro
register: r
- debug: msg="{{ r }}"
'''
from ansible.module_utils.basic import AnsibleModule
def sum(a, b):
return a + b
def main():
argument_spec = dict(
name=dict(type="str", required=True)
)
module = AnsibleModule(argument_spec, supports_check_mode=True)
result = dict(changed=False)
name = module.params['name']
if(name):
result['name'] = name
module.exit_json(**result)
else:
module.fail_json(msg="Please specify name.")
if __name__ == "__main__":
main()
我将创建一个用于GitLab CI的文件。在这里,我将尝试在Python2.7、3.6和3.7上进行sanity test的CI。
image: ansible-ci:latest
stages:
- sanity_test
python2.7:
stage: sanity_test
script:
- cp __init__.py /opt/ansible/lib/ansible/modules/salf_made
- cp output_name.py /opt/ansible/lib/ansible/modules/salf_made
- cd /opt/ansible
- . hacking/env-setup
- ansible-test sanity --python 2.7 output_name
only:
- master
python3.6:
stage: sanity_test
script:
- cp __init__.py /opt/ansible/lib/ansible/modules/salf_made
- cp output_name.py /opt/ansible/lib/ansible/modules/salf_made
- cd /opt/ansible
- . hacking/env-setup
- ansible-test sanity --python 3.6 output_name
only:
- master
python3.7:
stage: sanity_test
script:
- cp __init__.py /opt/ansible/lib/ansible/modules/salf_made
- cp output_name.py /opt/ansible/lib/ansible/modules/salf_made
- cd /opt/ansible
- . hacking/env-setup
- ansible-test sanity --python 3.7 output_name
only:
- master
3-3. CI的合理性测试
创建.gitlab-ci.yml并提交到仓库后进行合并,CI将被执行。
[root@GitLab example]# vi .gitlab-ci.yml
(上記の.gitlab-ci.ymlをコピペする)
[root@GitLab example]# git add .
[root@GitLab example]# git commit -m 'update'
[master 64a2491] update
1 file changed, 12 insertions(+), 3 deletions(-)
[root@GitLab example]# git push origin master
Username for 'http://192.168.0.115': example
Password for 'http://example@192.168.0.115':
Counting objects: 5, done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 383 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
To http://192.168.0.115/example/example.git
1763223..64a2491 master -> master
结果如下。
3-4. 单元测试的持续集成
在CI的阶段中添加unit_test并运行CI。
.gitlab-ci.yml的内容如下所示。
image: ansible-ci:latest
stages:
- sanity_test
- unit_test
sanity_python2.7:
stage: sanity_test
script:
- cp __init__.py /opt/ansible/lib/ansible/modules/salf_made
- cp output_name.py /opt/ansible/lib/ansible/modules/salf_made
- cd /opt/ansible
- . hacking/env-setup
- ansible-test sanity --python 2.7 output_name
only:
- master
sanity_python3.6:
stage: sanity_test
script:
- cp __init__.py /opt/ansible/lib/ansible/modules/salf_made
- cp output_name.py /opt/ansible/lib/ansible/modules/salf_made
- cd /opt/ansible
- . hacking/env-setup
- ansible-test sanity --python 3.6 output_name
only:
- master
sanity_python3.7:
stage: sanity_test
script:
- cp __init__.py /opt/ansible/lib/ansible/modules/salf_made
- cp output_name.py /opt/ansible/lib/ansible/modules/salf_made
- cd /opt/ansible
- . hacking/env-setup
- ansible-test sanity --python 3.7 output_name
only:
- master
unit_python2.7:
stage: unit_test
script:
- cp __init__.py /opt/ansible/lib/ansible/modules/salf_made
- cp output_name.py /opt/ansible/lib/ansible/modules/salf_made
- cp test_output_name.py /opt/ansible/test/units/modules/salf_made
- cd /opt/ansible
- . hacking/env-setup
- ansible-test units --python 2.7 output_name
only:
- master
unit_python3.6:
stage: unit_test
script:
- cp __init__.py /opt/ansible/lib/ansible/modules/salf_made
- cp output_name.py /opt/ansible/lib/ansible/modules/salf_made
- cp test_output_name.py /opt/ansible/test/units/modules/salf_made
- cd /opt/ansible
- . hacking/env-setup
- ansible-test units --python 3.6 output_name
only:
- master
unit_python3.7:
stage: unit_test
script:
- cp __init__.py /opt/ansible/lib/ansible/modules/salf_made
- cp output_name.py /opt/ansible/lib/ansible/modules/salf_made
- cp test_output_name.py /opt/ansible/test/units/modules/salf_made
- cd /opt/ansible
- . hacking/env-setup
- ansible-test units --python 3.7 output_name
only:
- master
我已经将用于测试的 test_output_name 设定如下。
from ansible.modules.salf_made.output_name import sum
def test_sum():
assert sum(1, 2) == 3
结果将如下所示。

最后
我在GitLab上尝试了对Ansible自定义模块进行静态解析的健全性测试和单元测试的持续集成。
如果想要在多个Python版本上进行测试,需要执行相当多的步骤,所以通过自动化可以提高效率并留下记录,这样可以获得证据,非常好 🙂
另外,通过使用GitLab可以同时进行代码管理和持续集成,非常方便 🙂