lae.travis-lxc
lae.travis-lxc
配置并启动多个 LXC 容器,以便在 Travis CI 环境中使用,从而在不同的发行版中更简单地测试 Ansible 角色。
用法
如果你想在 Travis CI 上测试你的 Ansible 角色,但不想使用 Docker,因为它不能模拟完整的操作系统? LXC 是你想要使用的。这款角色希望能为你抽象出许多可能会用到的样板代码。
要开始,你可以使用一个简单的 .travis.yml
文件,彻底测试你的角色是有效的、幂等的和功能正常的,可能长这样:
---
language: python
sudo: required
dist: bionic
install:
- pip install ansible
- ansible-galaxy install lae.travis-lxc,v0.9.0
- ansible-playbook tests/install.yml -i tests/inventory
before_script: cd tests/
script:
# 验证你的部署剧本语法,它应该包含你的角色
- ansible-playbook -i inventory deploy.yml --syntax-check
# 运行部署剧本
- ansible-playbook -i inventory deploy.yml
# 再次运行部署剧本,将输出保存到名为 play.log 的文件中,
# 然后检查没有已更改/失败的任务,如果有则失败。
- 'ANSIBLE_STDOUT_CALLBACK=debug ANSIBLE_DISPLAY_SKIPPED_HOSTS=no ANSIBLE_DISPLAY_OK_HOSTS=no
unbuffer ansible-playbook -vvi inventory deploy.yml &>play.log; printf "幂等性: ";
grep -A1 "PLAY RECAP" play.log | grep -qP "changed=0 .*failed=0 .*"
&& (echo "通过"; exit 0) || (echo "失败"; cat play.log; exit 1)'
# 集成测试等等
- ANSIBLE_STDOUT_CALLBACK=debug ansible-playbook -i inventory -v test.yml
你会注意到引用了四个文件。你可以决定如何定义你的构建过程,但以下内容通常能满足大多数需求:
- tests/install.yml: 执行
lae.travis-lxc
和其他安装前步骤 - tests/deploy.yml: 执行你正在测试的角色
- tests/test.yml: 对你的部署执行验证测试
- tests/inventory: 包含 LXC 容器主机名的列表
install.yml
可能长这样:
---
- hosts: localhost
connection: local
roles:
- lae.travis-lxc
vars:
test_profiles:
- profile: debian-buster
- profile: ubuntu-focal
- profile: centos-7
- profile: alpine-v3.11
# 添加你可能需要的其他设置任务,但不一定需要在你的角色中
- hosts: all
tasks: []
第一个剧本启动三个不同发行版的三个容器。第二个剧本可以用来运行其他角色或预安装任务,你希望你的角色不执行这些任务(例如,安装 epel-release
或为 FUSE 创建设备节点(因为 LXC 不会为你做这些))。
deploy.yml
可能长这样:
---
- hosts: all
become: true
any_errors_fatal: true
roles:
- ansible-role-strawberry-milk
vars:
number_of_cartons: 15
这基本上是 ansible-galaxy init
在 test.yml
中的输出结果。这将包含你正确执行角色所需的一切。对于更复杂的角色,分割变量到 tests/group_vars
文件夹中,适当配置你的清单是合理的。
test.yml
应该包含你的测试,如果你想运行的话:
---
- hosts: all
tasks:
- name: 确保草莓牛奶 HTTP 服务正在运行
uri:
url: "http://{{ inventory_hostname }}:1515"
- block:
- name: 打印草莓牛奶配置
shell: cat /etc/strawberry_milk.conf
changed_when: false
- name: 打印系统日志
shell: "cat /var/log/messages || cat /var/log/syslog || journalctl -xb"
ignore_errors: yes
这对于确保服务正在运行、集群处于健康状态、某些文件正在创建等情况很有用。这里的 block
是我运行诊断任务来帮助我调试问题的地方,包括打印日志等。它包裹在 ignore_errors
中,以确保这里的任务不会影响构建(一个主要导致错误的因素是在测试多个发行版时的日志打印任务)。
最后是清单:
debian-buster-01
ubuntu-focal-01
centos-7-01
alpine-v3-11-01
主机名由两部分组成,前缀和后缀。默认情况下,这些是根据 test_profiles
中的 profile
关键字生成的,格式为 {{ profile }}-{{ suffix }}
,其中后缀默认是 01
。
一旦你编写了这些文件,你就准备好在 Travis CI 中测试你的角色了。不过,你可能想获得更多功能,所以我们来讨论其他一些主题。
测试多个 Ansible 版本
你可能想测试你角色的开发分支以及所有当前支持的 Ansible 版本。这是你需要在 .travis.yml
中配置的内容,有多种方法可以实现:
env:
- ANSIBLE_GIT_VERSION='devel'
- ANSIBLE_VERSION='~=2.9.0'
- ANSIBLE_VERSION='~=2.9.0'
- ANSIBLE_VERSION='~=2.7.0'
install:
- if [ "$ANSIBLE_GIT_VERSION" ]; then pip install "https://github.com/ansible/ansible/archive/${ANSIBLE_GIT_VERSION}.tar.gz";
else pip install "ansible${ANSIBLE_VERSION}"; fi
- ansible --version
在这里,我们添加了一个安装任务,这将根据有效的 Ansible git 仓库中的 ANSIBLE_GIT_VERSION
,或者可以传递给 pip 的 ANSIBLE_VERSION
有效版本字符串来进行安装。
Ansible 性能和剖析
你可以在 tests/ansible.cfg
中放入几乎任何内容。
[defaults]
callback_whitelist=profile_tasks
forks=20
internal_poll_interval = 0.001
这会在你的剧本上运行 profile_tasks
回调,帮助识别哪些任务完成所需时间最长。你可以用这个来识别任何性能回归,例如。如果你在多个容器上运行你的剧本,指定 forks
。当你有多个任务/循环时,internal_poll_interval
是一个好的常规设置。
缓存
LXC 镜像可以被缓存,以节省引导时间,特别是在你测试多个配置文件时。将以下内容放入你的 .travis.yml
中,这个角色会处理其余的部分。
cache:
directories:
- "$HOME/lxc"
pip: true
(pip: true
对这个角色没有意义,但这里包含它是因为你可能也希望缓存你的 Ansible 安装。)
角色变量
要指定要测试的发行版,请使用 test_profiles
。支持的配置文件包括(欢迎请求/贡献新的配置文件):
test_profiles:
- profile: alpine-v3.11
- profile: alpine-v3.10
- profile: alpine-v3.9
- profile: centos-7
- profile: debian-buster
- profile: debian-stretch
- profile: ubuntu-focal
- profile: ubuntu-bionic
- profile: ubuntu-xenial
以下配置文件有定义,但不一定作为这个角色的目标被积极支持(即测试不再针对这些进行),因为它们在上游已经正式结束生命周期或相对较旧。不能保证它们仍然有效(但它们可能仍然有效)。
test_profiles:
- profile: alpine-v3.8
- profile: alpine-v3.7
- profile: alpine-v3.6
- profile: centos-6
- profile: debian-jessie
- profile: debian-wheezy
- profile: fedora-28
- profile: fedora-27
- profile: fedora-26
- profile: fedora-25
- profile: ubuntu-trusty
你可以查看 vars/main.yml
获取有关这些配置文件的更多信息。
如果没有指定前缀,测试容器会被赋予主机名 {{ profile }}-{{ suffix }}
,其中 profile
被清理以便用于 DNS 名称。默认前缀在 vars/main.yml
中定义,如果你不确定特定配置文件的前缀是什么,请参考它。如果未定义 test_host_suffixes
,则 suffix
在这里变为从 1 开始的零填充双位整数(最多到 test_hosts_per_profile
中指定的主机数量)。
例如,以下内容会创建 debian01
、debian02
和 debian03
:
test_profiles:
- profile: debian-buster
prefix: debian
test_hosts_per_profile: 3
以下内容会创建 ubuntu-app-python2
和 ubuntu-app-python3
:
test_profiles:
- profile: ubuntu-focal
prefix: ubuntu-
test_host_suffixes:
- app-python2
- app-python3
你还可以在必要时覆盖使用的容器配置(,例如,挂载共享文件夹):
container_config:
- "lxc.aa_profile=unconfined"
- "lxc.mount.auto=proc:rw sys:rw cgroup-full:rw"
- "lxc.cgroup.devices.allow=a *:* rmw"
如果你需要(“缺失” 包应由此角色默认安装),你还可以在测试容器中安装额外的软件包:
additional_packages:
- make
如果在 .travis.yml
中确认启用了缓存,则你可以通过在 lxc_cache_profiles
中指定它们选择性地缓存某个测试配置文件子集。这些必须是有效配置文件,并且出现在 test_profiles
中。
如果你需要将缓存到与 $HOME/lxc
不同的目录中,可以修改 lxc_cache_directory
。
如果你需要禁止在 LXC 容器中使用 OverlayFS(例如,如果你尝试在 LXC 容器内部使用 OverlayFS),请将 lxc_use_overlayfs
设置为 no
(或任何 False
变体)。
贡献者
Musee Ullah (@lae, lae@lae.is)
Wilmar den Ouden (@wilmardo)
稳定性
此角色目前仍处于 1.0 发布前,因此不保证稳定性。如果你在使用此角色时遇到问题,请打开一个问题,简要描述并附上任何相关日志,以便我们可以修复它,让我们更接近首个稳定版本。
请确保在使用此角色时锁定到特定版本(锁定到小版本可能也可以)。不这样做可能导致由于小版本更新中的破坏性更改而出现测试失败。