# 010 Clone jails and create inventory (plugins)

## Tree

    shell> tree .
    .
    ├── ansible.cfg
    ├── host_vars
    │   ├── iocage_01
    │   │   └── iocage.yml
    │   └── iocage_02
    │       └── iocage.yml
    ├── iocage-hosts.ini
    ├── iocage.yml
    ├── pb-iocage-fetch-base-clone-list.yml
    └── pb-test-01.yml

## Synopsis

- On two iocage hosts:

  - iocage_01

  - iocage_02

  In the playbook pb-iocage-fetch-base-clone-list.yml, use the module vbotka.freebsd.iocage to:

  - fetch the release

  - create basejail

  - clone 3 jails from the basejail

  - start 1 jail

  - display lists of bases, plugins, templates, and jails.

- On the iocage host iocage_02

  In the playbook pb-test-01.yml, use the inventory plugin vbotka.freebsd.iocage to:

  - create the inventory groups and compose variables

  - display the hosts and composed variables in the group test

  - display all created groups.

## Requirements

- Module vbotka.freebsd.iocage

- Inventory vbotka.freebsd.iocage

- root privilege on the iocage hosts

- Activated iocage

## Notes

See also

- Fetch a Release

- Create a Jail

- Start, Stop, or Restart a Jail

- Listing Jails

## Inventory iocage-hosts.ini

    iocage_01 ansible_host=10.1.0.18
    iocage_02 ansible_host=10.1.0.73

    [iocage]
    iocage_01
    iocage_02

    [iocage:vars]
    ansible_user=admin
    ansible_become=true

## host_vars/iocage_01/iocage.yml

    ansible_python_interpreter: /usr/local/bin/python3.9

    fetch:
      - 13.3-RELEASE
      - 13.4-RELEASE

    basejails:
      - name: ansible_client
        release: 13.4-RELEASE

    clones:
      - name: test_101
        clone_from: ansible_client
        properties:
          vnet: 'on'
          defaultrouter: 10.1.0.10
          ip4_addr: 'vnet0|10.1.0.101/24'
      - name: test_102
        clone_from: ansible_client
        properties:
          vnet: 'on'
          defaultrouter: 10.1.0.10
          ip4_addr: 'vnet0|10.1.0.102/24'
      - name: test_103
        clone_from: ansible_client
        properties:
          vnet: 'on'
          defaultrouter: 10.1.0.10
          ip4_addr: 'vnet0|10.1.0.103/24'

    start:
      - test_103

## host_vars/iocage_02/iocage.yml

    ansible_python_interpreter: /usr/local/bin/python3.11

    fetch:
      - 14.1-RELEASE

    basejails:
      - name: ansible_client
        release: 14.1-RELEASE

    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

## Playbook pb-iocage-fetch-base-clone-list.yml

    - hosts: iocage
      environment:
        CRYPTOGRAPHY_OPENSSL_NO_LEGACY: 1

      tasks:

        - name: Fetch releases
          vbotka.freebsd.iocage:
            release: "{{ item }}"
          loop: "{{ fetch }}"

        - name: Create basejail
          vbotka.freebsd.iocage:
            state: basejail
            name: "{{ item.name }}"
            release: "{{ item.release }}"
            properties: "{{ item.properties | d(omit) }}"
          loop: "{{ basejails }}"

        - name: Clone from basejail
          vbotka.freebsd.iocage:
            state: cloned
            clone_from: "{{ item.clone_from }}"
            name: "{{ item.name }}"
            properties: "{{ item.properties | d(omit) }}"
          loop: "{{ clones }}"

        - name: Start clones
          vbotka.freebsd.iocage:
            state: started
            name: "{{ item }}"
          loop: "{{ start }}"

        - name: Create Ansible facts iocage_*. This is the default state.
          vbotka.freebsd.iocage:

        - name: Display lists of bases, plugins, templates, and jails.
          debug:
            msg: |-
              {{ iocage_releases }}
              {{ iocage_plugins.keys() | list }}
              {{ iocage_templates.keys() | list }}
              {{ iocage_jails.keys() | list }}

## Playbook output

    (env) > ansible-playbook -i iocage-hosts.ini pb-iocage-fetch-base-clone-list.yml

    PLAY [iocage] *******************************************************************************************************

    TASK [Fetch releases] ***********************************************************************************************
    ok: [iocage_01] => (item=13.3-RELEASE)
    ok: [iocage_01] => (item=13.4-RELEASE)
    ok: [iocage_02] => (item=14.1-RELEASE)

    TASK [Create basejail] **********************************************************************************************
    changed: [iocage_02] => (item={'name': 'ansible_client', 'release': '14.1-RELEASE'})
    changed: [iocage_01] => (item={'name': 'ansible_client', 'release': '13.4-RELEASE'})

    TASK [Clone from basejail] ******************************************************************************************
    changed: [iocage_01] => (item={'name': 'test_101', 'clone_from': 'ansible_client', 'properties': {'vnet': 'on', 'defaultrouter': '10.1.0.10', 'ip4_addr': 'vnet0|10.1.0.101/24'}})
    changed: [iocage_01] => (item={'name': 'test_102', 'clone_from': 'ansible_client', 'properties': {'vnet': 'on', 'defaultrouter': '10.1.0.10', 'ip4_addr': 'vnet0|10.1.0.102/24'}})
    changed: [iocage_02] => (item={'name': 'test_111', 'clone_from': 'ansible_client', 'properties': {'ip4_addr': 'em0|10.1.0.111/24'}})
    changed: [iocage_01] => (item={'name': 'test_103', 'clone_from': 'ansible_client', 'properties': {'vnet': 'on', 'defaultrouter': '10.1.0.10', 'ip4_addr': 'vnet0|10.1.0.103/24'}})
    changed: [iocage_02] => (item={'name': 'test_112', 'clone_from': 'ansible_client', 'properties': {'ip4_addr': 'em0|10.1.0.112/24'}})
    changed: [iocage_02] => (item={'name': 'test_113', 'clone_from': 'ansible_client', 'properties': {'ip4_addr': 'em0|10.1.0.113/24'}})

    TASK [Start clones] *************************************************************************************************
    changed: [iocage_01] => (item=test_103)
    changed: [iocage_02] => (item=test_113)

    TASK [Create Ansible facts iocage_*. This is the default state.] ****************************************************
    ok: [iocage_01]
    ok: [iocage_02]

    TASK [Display lists of bases, plugins, templates, and jails.] *******************************************************
    ok: [iocage_01] =>
      msg: |-
        ['13.3-RELEASE', '13.4-RELEASE']
        []
        []
        ['ansible_client', 'test_101', 'test_102', 'test_103']
    ok: [iocage_02] =>
      msg: |-
        ['14.1-RELEASE']
        []
        []
        ['ansible_client', 'test_111', 'test_112', 'test_113']

    PLAY RECAP **********************************************************************************************************
    iocage_01: ok=6    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    iocage_02: ok=6    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

## List all jails at iocage_01

    [iocage_01]# iocage list -l
    +------+----------------+------+-------+------+-----------------+---------------------+-----+----------------+----------+
    | JID  |      NAME      | BOOT | STATE | TYPE |     RELEASE     |         IP4         | IP6 |    TEMPLATE    | BASEJAIL |
    +======+================+======+=======+======+=================+=====================+=====+================+==========+
    | None | ansible_client | off  | down  | jail | 13.4-RELEASE-p2 | -                   | -   | -              | yes      |
    +------+----------------+------+-------+------+-----------------+---------------------+-----+----------------+----------+
    | None | test_101       | off  | down  | jail | 13.4-RELEASE-p2 | vnet0|10.1.0.101/24 | -   | ansible_client | yes      |
    +------+----------------+------+-------+------+-----------------+---------------------+-----+----------------+----------+
    | None | test_102       | off  | down  | jail | 13.4-RELEASE-p2 | vnet0|10.1.0.102/24 | -   | ansible_client | yes      |
    +------+----------------+------+-------+------+-----------------+---------------------+-----+----------------+----------+
    | 43   | test_103       | off  | up    | jail | 13.4-RELEASE-p2 | vnet0|10.1.0.103/24 | -   | ansible_client | yes      |
    +------+----------------+------+-------+------+-----------------+---------------------+-----+----------------+----------+

## List all 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.1-RELEASE | -                 | -   | -              | yes      |
    +------+----------------+------+-------+------+--------------+-------------------+-----+----------------+----------+
    | None | test_111       | off  | down  | jail | 14.1-RELEASE | em0|10.1.0.111/24 | -   | ansible_client | yes      |
    +------+----------------+------+-------+------+--------------+-------------------+-----+----------------+----------+
    | None | test_112       | off  | down  | jail | 14.1-RELEASE | em0|10.1.0.112/24 | -   | ansible_client | yes      |
    +------+----------------+------+-------+------+--------------+-------------------+-----+----------------+----------+
    | 60   | test_113       | off  | up    | jail | 14.1-RELEASE | em0|10.1.0.113/24 | -   | ansible_client | yes      |
    +------+----------------+------+-------+------+--------------+-------------------+-----+----------------+----------+

## Inventory iocage.yml

    plugin: vbotka.freebsd.iocage
    host: 10.1.0.73
    user: admin
    env:
      - CRYPTOGRAPHY_OPENSSL_NO_LEGACY=1
    get_properties: False
    cache: False
    strict: True
    compose:
      ansible_host: iocage_ip4
      release: iocage_release | split('-') | first
      release_major: iocage_release | split('-') | first | split('.') | first
      release_minor: iocage_release | split('-') | first | split('.') | last
    groups:
        test: inventory_hostname.startswith('test')
    keyed_groups:
      - prefix: distro
        key: iocage_release
      - prefix: state
        key: iocage_state

See also

- Inventory plugin ansible.builtin.constructed

- Enabling inventory cache plugins

## Playbook pb-test-01.yml

    - hosts: test

      tasks:

        - debug:
            msg: |
              inventory_hostname: {{ inventory_hostname }}
              ansible_host: {{ ansible_host }}
              release: {{ release }}
              release_major: {{ release_major }}
              release_minor: {{ release_minor }}

        - debug:
            msg: |
              groups:
                {{ groups | to_yaml(indent=2) | indent(2) }}
          run_once: true

## Playbook output

    (env) > ansible-playbook -i iocage.yml pb-test-01.yml

    PLAY [test] *********************************************************************************************************

    TASK [debug] ********************************************************************************************************
    ok: [test_111] =>
      msg: |-
        inventory_hostname: test_111
        ansible_host: 10.1.0.111
        release: 14.1
        release_major: 14
        release_minor: 1
    ok: [test_112] =>
      msg: |-
        inventory_hostname: test_112
        ansible_host: 10.1.0.112
        release: 14.1
        release_major: 14
        release_minor: 1
    ok: [test_113] =>
      msg: |-
        inventory_hostname: test_113
        ansible_host: 10.1.0.113
        release: 14.1
        release_major: 14
        release_minor: 1

    TASK [debug] ********************************************************************************************************
    ok: [test_111] =>
      msg: |-
        groups:
          all: [ansible_client, test_111, test_112, test_113]
          distro_14_1_RELEASE: [ansible_client, test_111, test_112, test_113]
          state_down: [ansible_client, test_111, test_112]
          state_up: [test_113]
          test: [test_111, test_112, test_113]
          ungrouped: []

    PLAY RECAP **********************************************************************************************************
    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