330 Clone jails and create inventory
Use case
Fetch releases, create basejails, clone from the basejails, and start the jails. Create and display the inventory. Use the role vbotka.freebsd.iocage instead of the Plugins.
Tree
shell> tree .
.
├── ansible.cfg
├── host_vars
│ ├── iocage_02
│ │ └── iocage.yml
│ └── iocage_04
│ └── iocage.yml
├── iocage.ini
├── pb-iocage-fetch-base-clone.yml
├── pb-iocage-list.yml
└── pb-test.yml
Synopsis
At two managed nodes: In the playbook
pb-iocage-fetch-base-clone.yml, use the role vbotka.freebsd.iocage to:fetch the release
create basejail
clone 3 jails from the basejail.
In the playbook
pb-iocage-list.yml, use the role vbotka.freebsd.iocage to:create the lists of bases and jails
optionally, display the lists.
In the playbook
pb-test-01.yml:create the inventory group
testand compose variablesdisplay the hosts and composed variables in the group
testdisplay all groups.
Requirements
root privilege in the managed nodes
activated
iocage
Notes
This example demonstrates a functionality similar to 010 Clone basejails and create inventory.
The role vbotka.freebsd.iocage is preinstalled in this collection.
ansible.cfg
[defaults]
gathering = explicit
callback_result_format = yaml
display_skipped_hosts = false
[connection]
pipelining = true
Inventory iocage.ini
iocage_02 ansible_host=10.1.0.73
iocage_04 ansible_host=10.1.0.29
[iocage]
iocage_02
iocage_04
[iocage:vars]
ansible_user=admin
ansible_become=true
ansible_python_interpreter=auto_silent
host_vars
freebsd_iocage_pool: zroot
freebsd_iocage_pool_mount: /zroot
freebsd_iocage_mount: "{{ freebsd_iocage_pool_mount }}/iocage"
properties:
notes: "vmm={{ inventory_hostname }}"
fetch:
- 14.3-RELEASE
basejails:
- name: ansible_client
release: 14.3-RELEASE
properties:
ip4_addr: 'em0|10.1.0.199/24'
clones:
- name: test_111
clone_from: ansible_client
properties:
ip4_addr: 'em0|10.1.0.111/24'
- name: test_112
clone_from: ansible_client
properties:
ip4_addr: 'em0|10.1.0.112/24'
- name: test_113
clone_from: ansible_client
properties:
ip4_addr: 'em0|10.1.0.113/24'
start:
- test_113
iocage_env:
CRYPTOGRAPHY_OPENSSL_NO_LEGACY: 1
# Required by the role vbotka.freebsd.iocage
freebsd_iocage_runner_env: "{{ iocage_env }}"
freebsd_iocage_pool: iocage
freebsd_iocage_pool_mount: /iocage
freebsd_iocage_mount: "{{ freebsd_iocage_pool_mount }}/iocage"
properties:
vnet: 'on'
defaultrouter: 10.1.0.10
notes: "vmm={{ inventory_hostname }}"
fetch:
- 15.0-RELEASE
basejails:
- name: ansible_client
release: 15.0-RELEASE
properties:
vnet: 1
defaultrouter: 10.1.0.10
ip4_addr: 'vnet0|10.1.0.198/24'
clones:
- name: test_101
clone_from: ansible_client
properties:
ip4_addr: 'vnet0|10.1.0.101/24'
- name: test_102
clone_from: ansible_client
properties:
ip4_addr: 'vnet0|10.1.0.102/24'
- name: test_103
clone_from: ansible_client
properties:
ip4_addr: 'vnet0|10.1.0.103/24'
start:
- test_103
# In production, put the password into the vault.
ansible_become_password: admin
Playbook pb-iocage-fetch-base-clone.yml
- name: Iocage fetch releases, create basejail, and clone jails.
hosts: iocage
vars:
freebsd_iocage_runner_exec: "fetch,create,clone"
freebsd_iocage_runner_cmd: |
{% filter from_yaml %}
fetch:
{% for release in fetch %}
- cmd: iocage fetch --release {{ release }}
creates: {{ freebsd_iocage_mount }}/releases/{{ release }}
{% endfor %}
create:
{% for jail in basejails %}
- cmd: iocage create --release {{ jail.release }} --name {{ jail.name }}
creates: {{ freebsd_iocage_mount }}/jails/{{ jail.name }}
{% endfor %}
{% for jail in basejails %}
{% for k, v in (properties | combine(jail.properties)).items() %}
- cmd: iocage set {{ k }}={{ v }} {{ jail.name }}
{% endfor %}
{% endfor %}
clone:
{% for jail in clones %}
- cmd: iocage clone {{ jail.clone_from }} --name {{ jail.name }}
creates: {{ freebsd_iocage_mount }}/jails/{{ jail.name }}
{% endfor %}
{% for jail in clones %}
{% for k, v in (properties | combine(jail.properties)).items() %}
- cmd: iocage set {{ k }}={{ v }} {{ jail.name }}
{% endfor %}
{% endfor %}
{% endfilter %}
tasks:
- name: Debug
when: debug | d(false) | bool
tags: debug
ansible.builtin.debug:
msg: |
freebsd_iocage_runner_exec: {{ freebsd_iocage_runner_exec }}
freebsd_iocage_runner_cmd:
{{ freebsd_iocage_runner_cmd | to_nice_yaml(indent=2) | indent(2) }}
- name: Fetch releases, create jails, and clone jails.
tags: runner
block:
- name: Run commands
register: out
ansible.builtin.import_role:
name: vbotka.freebsd.iocage
tasks_from: runner
- name: Debug
when: debug2 | d(false) | bool
ansible.builtin.debug:
var: out
Playbook output - Display variables
(env) > ansible-playbook pb-iocage-fetch-base-clone.yml -i iocage.ini \
-t debug \
-e debug=true
PLAY [Iocage fetch releases, create basejail, and clone jails.] ****************
TASK [Debug] *******************************************************************
ok: [iocage_04] =>
msg: |-
freebsd_iocage_runner_exec: fetch,create,clone
freebsd_iocage_runner_cmd:
clone:
- cmd: iocage clone ansible_client --name test_101
creates: /iocage/iocage/jails/test_101
- cmd: iocage clone ansible_client --name test_102
creates: /iocage/iocage/jails/test_102
- cmd: iocage clone ansible_client --name test_103
creates: /iocage/iocage/jails/test_103
- cmd: iocage set vnet=on test_101
- cmd: iocage set defaultrouter=10.1.0.10 test_101
- cmd: iocage set notes=vmm=iocage_04 test_101
- cmd: iocage set ip4_addr=vnet0|10.1.0.101/24 test_101
- cmd: iocage set vnet=on test_102
- cmd: iocage set defaultrouter=10.1.0.10 test_102
- cmd: iocage set notes=vmm=iocage_04 test_102
- cmd: iocage set ip4_addr=vnet0|10.1.0.102/24 test_102
- cmd: iocage set vnet=on test_103
- cmd: iocage set defaultrouter=10.1.0.10 test_103
- cmd: iocage set notes=vmm=iocage_04 test_103
- cmd: iocage set ip4_addr=vnet0|10.1.0.103/24 test_103
create:
- cmd: iocage create --release 15.0-RELEASE --name ansible_client
creates: /iocage/iocage/jails/ansible_client
- cmd: iocage set vnet=1 ansible_client
- cmd: iocage set defaultrouter=10.1.0.10 ansible_client
- cmd: iocage set notes=vmm=iocage_04 ansible_client
- cmd: iocage set ip4_addr=vnet0|10.1.0.198/24 ansible_client
fetch:
- cmd: iocage fetch --release 15.0-RELEASE
creates: /iocage/iocage/releases/15.0-RELEASE
ok: [iocage_02] =>
msg: |-
freebsd_iocage_runner_exec: fetch,create,clone
freebsd_iocage_runner_cmd:
clone:
- cmd: iocage clone ansible_client --name test_111
creates: /zroot/iocage/jails/test_111
- cmd: iocage clone ansible_client --name test_112
creates: /zroot/iocage/jails/test_112
- cmd: iocage clone ansible_client --name test_113
creates: /zroot/iocage/jails/test_113
- cmd: iocage set notes=vmm=iocage_02 test_111
- cmd: iocage set ip4_addr=em0|10.1.0.111/24 test_111
- cmd: iocage set notes=vmm=iocage_02 test_112
- cmd: iocage set ip4_addr=em0|10.1.0.112/24 test_112
- cmd: iocage set notes=vmm=iocage_02 test_113
- cmd: iocage set ip4_addr=em0|10.1.0.113/24 test_113
create:
- cmd: iocage create --release 14.3-RELEASE --name ansible_client
creates: /zroot/iocage/jails/ansible_client
- cmd: iocage set notes=vmm=iocage_02 ansible_client
- cmd: iocage set ip4_addr=em0|10.1.0.199/24 ansible_client
fetch:
- cmd: iocage fetch --release 14.3-RELEASE
creates: /zroot/iocage/releases/14.3-RELEASE
PLAY RECAP *********************************************************************
iocage_02 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
iocage_04 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Playbook output - Runner
(env) > ansible-playbook pb-iocage-fetch-base-clone.yml -i iocage.ini \
-t runner
PLAY [Iocage fetch releases, create basejail, and clone jails.] ****************
TASK [vbotka.freebsd.iocage : Runner: Assert all commands are available.] ******
ok: [iocage_02]
ok: [iocage_04]
TASK [vbotka.freebsd.iocage : Runner: Assert all commands are iocage.] *********
ok: [iocage_02]
ok: [iocage_04]
TASK [vbotka.freebsd.iocage : Runner: Run listed commands.] ********************
ok: [iocage_04] => (item=iocage fetch --release 15.0-RELEASE)
ok: [iocage_02] => (item=iocage fetch --release 14.3-RELEASE)
changed: [iocage_04] => (item=iocage create --release 15.0-RELEASE --name ansible_client)
changed: [iocage_04] => (item=iocage set vnet=1 ansible_client)
changed: [iocage_04] => (item=iocage set defaultrouter=10.1.0.10 ansible_client)
changed: [iocage_04] => (item=iocage set notes=vmm=iocage_04 ansible_client)
changed: [iocage_04] => (item=iocage set ip4_addr=vnet0|10.1.0.198/24 ansible_client)
changed: [iocage_04] => (item=iocage clone ansible_client --name test_101)
changed: [iocage_04] => (item=iocage clone ansible_client --name test_102)
changed: [iocage_02] => (item=iocage create --release 14.3-RELEASE --name ansible_client)
changed: [iocage_04] => (item=iocage clone ansible_client --name test_103)
changed: [iocage_04] => (item=iocage set vnet=on test_101)
changed: [iocage_04] => (item=iocage set defaultrouter=10.1.0.10 test_101)
changed: [iocage_04] => (item=iocage set notes=vmm=iocage_04 test_101)
changed: [iocage_04] => (item=iocage set ip4_addr=vnet0|10.1.0.101/24 test_101)
changed: [iocage_04] => (item=iocage set vnet=on test_102)
changed: [iocage_02] => (item=iocage set notes=vmm=iocage_02 ansible_client)
changed: [iocage_04] => (item=iocage set defaultrouter=10.1.0.10 test_102)
changed: [iocage_04] => (item=iocage set notes=vmm=iocage_04 test_102)
changed: [iocage_04] => (item=iocage set ip4_addr=vnet0|10.1.0.102/24 test_102)
changed: [iocage_04] => (item=iocage set vnet=on test_103)
changed: [iocage_04] => (item=iocage set defaultrouter=10.1.0.10 test_103)
changed: [iocage_04] => (item=iocage set notes=vmm=iocage_04 test_103)
changed: [iocage_04] => (item=iocage set ip4_addr=vnet0|10.1.0.103/24 test_103)
changed: [iocage_02] => (item=iocage set ip4_addr=em0|10.1.0.199/24 ansible_client)
changed: [iocage_02] => (item=iocage clone ansible_client --name test_111)
changed: [iocage_02] => (item=iocage clone ansible_client --name test_112)
changed: [iocage_02] => (item=iocage clone ansible_client --name test_113)
changed: [iocage_02] => (item=iocage set notes=vmm=iocage_02 test_111)
changed: [iocage_02] => (item=iocage set ip4_addr=em0|10.1.0.111/24 test_111)
changed: [iocage_02] => (item=iocage set notes=vmm=iocage_02 test_112)
changed: [iocage_02] => (item=iocage set ip4_addr=em0|10.1.0.112/24 test_112)
changed: [iocage_02] => (item=iocage set notes=vmm=iocage_02 test_113)
changed: [iocage_02] => (item=iocage set ip4_addr=em0|10.1.0.113/24 test_113)
PLAY RECAP *********************************************************************
iocage_02 : ok=3 changed=1 unreachable=0 failed=0 skipped=3 rescued=0 ignored=0
iocage_04 : ok=3 changed=1 unreachable=0 failed=0 skipped=3 rescued=0 ignored=0
Note
The commands iocage set ... are not idempotent.
Hint
See the log on the remote host
shell> tail -f /var/log/iocage.log
Jails at iocage_02
[iocage_02]# iocage list -l
+------+----------------+------+-------+------+-----------------+-------------------+-----+----------------+----------+
| JID | NAME | BOOT | STATE | TYPE | RELEASE | IP4 | IP6 | TEMPLATE | BASEJAIL |
+======+================+======+=======+======+=================+===================+=====+================+==========+
| None | ansible_client | off | down | jail | 14.3-RELEASE-p8 | em0|10.1.0.199/24 | - | - | no |
+------+----------------+------+-------+------+-----------------+-------------------+-----+----------------+----------+
| None | test_111 | off | down | jail | 14.3-RELEASE-p8 | em0|10.1.0.111/24 | - | ansible_client | no |
+------+----------------+------+-------+------+-----------------+-------------------+-----+----------------+----------+
| None | test_112 | off | down | jail | 14.3-RELEASE-p8 | em0|10.1.0.112/24 | - | ansible_client | no |
+------+----------------+------+-------+------+-----------------+-------------------+-----+----------------+----------+
| None | test_113 | off | down | jail | 14.3-RELEASE-p8 | em0|10.1.0.113/24 | - | ansible_client | no |
+------+----------------+------+-------+------+-----------------+-------------------+-----+----------------+----------+
Jails at iocage_04
[iocage_04]# iocage list -l
+------+----------------+------+-------+------+-----------------+---------------------+-----+----------------+----------+
| JID | NAME | BOOT | STATE | TYPE | RELEASE | IP4 | IP6 | TEMPLATE | BASEJAIL |
+======+================+======+=======+======+=================+=====================+=====+================+==========+
| None | ansible_client | off | down | jail | 15.0-RELEASE-p3 | vnet0|10.1.0.198/24 | - | - | no |
+------+----------------+------+-------+------+-----------------+---------------------+-----+----------------+----------+
| None | test_101 | off | down | jail | 15.0-RELEASE-p3 | vnet0|10.1.0.101/24 | - | ansible_client | no |
+------+----------------+------+-------+------+-----------------+---------------------+-----+----------------+----------+
| None | test_102 | off | down | jail | 15.0-RELEASE-p3 | vnet0|10.1.0.102/24 | - | ansible_client | no |
+------+----------------+------+-------+------+-----------------+---------------------+-----+----------------+----------+
| None | test_103 | off | down | jail | 15.0-RELEASE-p3 | vnet0|10.1.0.103/24 | - | ansible_client | no |
+------+----------------+------+-------+------+-----------------+---------------------+-----+----------------+----------+
Playbook pb-iocage-list.yml
- name: Iocage list datasets.
hosts: iocage
vars:
jail_attr: [jid, name, boot, state, type, release, ip4, ip6, template, basejail]
tasks:
- name: Run commands
tags: runner
ansible.builtin.import_role:
name: vbotka.freebsd.iocage
tasks_from: runner
vars:
freebsd_iocage_runner_exec: lists
freebsd_iocage_runner_cmd:
lists:
- cmd: iocage list -rh
- cmd: iocage list -lh
- cmd: iocage list -Ph
- cmd: iocage list -th
- name: Debug
when: debug2 | d(false) | bool
ansible.builtin.debug:
var: out
- name: Set lists
ansible.builtin.set_fact:
iocage_releases: "{{ out.results.0.stdout.splitlines() }}"
iocage_jails: "{{ dict(out.results.1.stdout.splitlines()
| map('split', '\t')
| map('zip', jail_attr)
| map('map', 'reverse')
| map('community.general.dict')
| json_query('[].[name, @]')) }}"
- name: Display lists
when: debug | d(false) | bool
ansible.builtin.debug:
msg: |-
iocage_releases: {{ iocage_releases }}
iocage_jails:
{{ iocage_jails | to_nice_yaml(indent=2) | indent(2) }}
# iocage_plugins: {{ iocage_plugins }}
# iocage_templates: {{ iocage_templates }}
Playbook output - Display iocage_jails
(env) > ansible-playbook pb-iocage-list.yml -i iocage.ini -e debug=true
PLAY [Iocage list datasets.] ***************************************************
TASK [vbotka.freebsd.iocage : Runner: Assert all commands are available.] ******
ok: [iocage_04]
ok: [iocage_02]
TASK [vbotka.freebsd.iocage : Runner: Assert all commands are iocage.] *********
ok: [iocage_04]
ok: [iocage_02]
TASK [vbotka.freebsd.iocage : Runner: Run listed commands.] ********************
changed: [iocage_04] => (item=iocage list -rh)
changed: [iocage_04] => (item=iocage list -lh)
changed: [iocage_04] => (item=iocage list -Ph)
changed: [iocage_04] => (item=iocage list -th)
changed: [iocage_02] => (item=iocage list -rh)
changed: [iocage_02] => (item=iocage list -lh)
changed: [iocage_02] => (item=iocage list -Ph)
changed: [iocage_02] => (item=iocage list -th)
TASK [Set lists] ***************************************************************
ok: [iocage_02]
ok: [iocage_04]
TASK [Display lists] ***********************************************************
ok: [iocage_04] =>
msg: |-
iocage_releases: ['14.3-RELEASE', '15.0-RELEASE']
iocage_jails:
ansible_client:
basejail: 'no'
boot: 'off'
ip4: vnet0|10.1.0.198/24
ip6: '-'
jid: None
name: ansible_client
release: 15.0-RELEASE-p3
state: down
template: '-'
type: jail
test_101:
basejail: 'no'
boot: 'off'
ip4: vnet0|10.1.0.101/24
ip6: '-'
jid: None
name: test_101
release: 15.0-RELEASE-p3
state: down
template: ansible_client
type: jail
test_102:
basejail: 'no'
boot: 'off'
ip4: vnet0|10.1.0.102/24
ip6: '-'
jid: None
name: test_102
release: 15.0-RELEASE-p3
state: down
template: ansible_client
type: jail
test_103:
basejail: 'no'
boot: 'off'
ip4: vnet0|10.1.0.103/24
ip6: '-'
jid: None
name: test_103
release: 15.0-RELEASE-p3
state: down
template: ansible_client
type: jail
ok: [iocage_02] =>
msg: |-
iocage_releases: ['14.2-RELEASE', '14.3-RELEASE']
iocage_jails:
ansible_client:
basejail: 'no'
boot: 'off'
ip4: em0|10.1.0.199/24
ip6: '-'
jid: None
name: ansible_client
release: 14.3-RELEASE-p8
state: down
template: '-'
type: jail
test_111:
basejail: 'no'
boot: 'off'
ip4: em0|10.1.0.111/24
ip6: '-'
jid: None
name: test_111
release: 14.3-RELEASE-p8
state: down
template: ansible_client
type: jail
test_112:
basejail: 'no'
boot: 'off'
ip4: em0|10.1.0.112/24
ip6: '-'
jid: None
name: test_112
release: 14.3-RELEASE-p8
state: down
template: ansible_client
type: jail
test_113:
basejail: 'no'
boot: 'off'
ip4: em0|10.1.0.113/24
ip6: '-'
jid: None
name: test_113
release: 14.3-RELEASE-p8
state: down
template: ansible_client
type: jail
PLAY RECAP *********************************************************************
iocage_02 : ok=5 changed=1 unreachable=0 failed=0 skipped=3 rescued=0 ignored=0
iocage_04 : ok=5 changed=1 unreachable=0 failed=0 skipped=3 rescued=0 ignored=0
Playbook pb-test.yml
- name: Create lists
import_playbook: pb-iocage-list.yml
- name: Create group test
hosts: iocage
vars:
jails: "{{ hostvars | json_query('*.iocage_jails') | combine }}"
tasks:
- name: Create inventory group test
run_once: true
block:
- name: Debug
when: debug | d(false) | bool
ansible.builtin.debug:
var: jails
- name: Create inventory group test
ansible.builtin.add_host:
groups: test
name: "{{ item }}"
ansible_host: "{{ jails[item].ip4 | split('|') | last
| split('/') | first }}"
release: "{{ jails[item].release }}"
loop: "{{ jails.keys() | select('match', 'test') }}"
- name: Use group test
hosts: test
tasks:
- debug:
msg: |
inventory_hostname: {{ inventory_hostname }}
ansible_host: {{ ansible_host }}
release: {{ release }}
- debug:
msg: |
groups:
{{ groups | to_yaml(indent=2) | indent(2) }}
run_once: true
Playbook output - Create and use group
(env) > ansible-playbook pb-test.yml -i iocage.ini
PLAY [Iocage list datasets.] ***************************************************
TASK [vbotka.freebsd.iocage : Runner: Assert all commands are available.] ******
ok: [iocage_04]
ok: [iocage_02]
TASK [vbotka.freebsd.iocage : Runner: Assert all commands are iocage.] *********
ok: [iocage_04]
ok: [iocage_02]
TASK [vbotka.freebsd.iocage : Runner: Run listed commands.] ********************
changed: [iocage_04] => (item=iocage list -rh)
changed: [iocage_04] => (item=iocage list -lh)
changed: [iocage_04] => (item=iocage list -Ph)
changed: [iocage_04] => (item=iocage list -th)
changed: [iocage_02] => (item=iocage list -rh)
changed: [iocage_02] => (item=iocage list -lh)
changed: [iocage_02] => (item=iocage list -Ph)
changed: [iocage_02] => (item=iocage list -th)
TASK [Set lists] ***************************************************************
ok: [iocage_02]
ok: [iocage_04]
PLAY [Create group test] *******************************************************
TASK [Create inventory group test] *********************************************
changed: [iocage_02] => (item=test_111)
changed: [iocage_02] => (item=test_112)
changed: [iocage_02] => (item=test_113)
changed: [iocage_02] => (item=test_101)
changed: [iocage_02] => (item=test_102)
changed: [iocage_02] => (item=test_103)
PLAY [Use group test] **********************************************************
TASK [debug] *******************************************************************
ok: [test_111] =>
msg: |-
inventory_hostname: test_111
ansible_host: 10.1.0.111
release: 14.3-RELEASE-p8
ok: [test_112] =>
msg: |-
inventory_hostname: test_112
ansible_host: 10.1.0.112
release: 14.3-RELEASE-p8
ok: [test_113] =>
msg: |-
inventory_hostname: test_113
ansible_host: 10.1.0.113
release: 14.3-RELEASE-p8
ok: [test_102] =>
msg: |-
inventory_hostname: test_102
ansible_host: 10.1.0.102
release: 15.0-RELEASE-p3
ok: [test_101] =>
msg: |-
inventory_hostname: test_101
ansible_host: 10.1.0.101
release: 15.0-RELEASE-p3
ok: [test_103] =>
msg: |-
inventory_hostname: test_103
ansible_host: 10.1.0.103
release: 15.0-RELEASE-p3
TASK [debug] *******************************************************************
ok: [test_111] =>
msg: |-
groups:
all: [test_111, test_112, test_113, test_101, test_102, test_103, iocage_02, iocage_04]
iocage: [iocage_02, iocage_04]
test: [test_111, test_112, test_113, test_101, test_102, test_103]
ungrouped: []
PLAY RECAP *********************************************************************
iocage_02 : ok=5 changed=2 unreachable=0 failed=0 skipped=5 rescued=0 ignored=0
iocage_04 : ok=4 changed=1 unreachable=0 failed=0 skipped=4 rescued=0 ignored=0
test_101 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_102 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_103 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_111 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_112 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_113 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0