From 7c5d9a4bd24dae59576e09fbc7576679821d6d4c Mon Sep 17 00:00:00 2001 From: Robert Kaussow Date: Sun, 29 Nov 2020 21:59:41 +0100 Subject: [PATCH] migrate to docker container --- defaults/main.yml | 74 +++++++++++++--- handlers/main.yml | 10 ++- molecule/centos7/converge.yml | 21 +++-- molecule/centos7/tests/test_default.py | 5 -- molecule/requirements.yml | 8 +- tasks/install.yml | 76 ---------------- tasks/main.yml | 4 +- tasks/post_tasks.yml | 9 -- tasks/prepare.yml | 26 ------ tasks/setup.yml | 52 +++++++++++ .../etc/ansible/facts.d/zigbee2mqtt.fact.j2 | 4 - .../etc/systemd/system/zigbee2mqtt.service.j2 | 16 ---- templates/services/zigbee2mqtt_compose.yml.j2 | 86 +++++++++++++++++++ .../zigbee2mqtt/data/configuration.yaml.j2 | 1 - 14 files changed, 227 insertions(+), 165 deletions(-) delete mode 100644 tasks/install.yml delete mode 100644 tasks/post_tasks.yml delete mode 100644 tasks/prepare.yml create mode 100644 tasks/setup.yml delete mode 100644 templates/etc/ansible/facts.d/zigbee2mqtt.fact.j2 delete mode 100644 templates/etc/systemd/system/zigbee2mqtt.service.j2 create mode 100644 templates/services/zigbee2mqtt_compose.yml.j2 diff --git a/defaults/main.yml b/defaults/main.yml index 9313912..d8981a9 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1,17 +1,67 @@ --- -zigbee2mqtt_version: 1.5.1 +zigbee2mqtt_version: latest +zigbee2mqtt_image: "koenkk/zigbee2mqtt:{{ zigbee2mqtt_version }}" -zigbee2mqtt_user: zigbee2mqtt -zigbee2mqtt_group: zigbee2mqtt -zigbee2mqtt_secondary_groups: - - tty - - dialout +zigbee2mqtt_service_directory: /var/lib/docker/services/zigbee2mqtt +zigbee2mqtt_container_name: zigbee2mqtt +zigbee2mqtt_restart_policy: always +zigbee2mqtt_service_stopped: False +# @var zigbee2mqtt_networks:example: > +# zigbee2mqtt_networks: +# - name: default +# # optional network driver, defaults to 'bride' +# driver: host +# @end +zigbee2mqtt_networks: + - name: default -zigbee2mqtt_service_state: started -zigbee2mqtt_service_restart_state: restarted +zigbee2mqtt_networks_applied: + - default + +# @var zigbee2mqtt_volumes:description: Define required docker volumes. +# @var zigbee2mqtt_volumes:example: > +# zigbee2mqtt_volumes: +# # Instead of the name you could specify a path on the container host system, +# # but you also have to enable bind mount for this volume +# - name: data +# # target location inside the container +# dest: /var/www/app/data +# # enable bind mount, if false volume will be configured as named volume +# # keep in mind you MUST set bind in any case +# bind: True +# # Options for bind mounts +# bind_opt: "ro,z" +# @end +zigbee2mqtt_volumes: + - name: "{{ zigbee2mqtt_data_volume }}" + dest: /app/data + bind: True + +# @var zigbee2mqtt_devices:description: Define required devices e.g. `/dev/ttyACM0`. +# @var zigbee2mqtt_devices:example: > +# zigbee2mqtt_devices: +# - src: "{{ zigbee2mqtt_serial_port }}" +# dest: "{{ zigbee2mqtt_serial_port }}" +# opt: z +# @end + +zigbee2mqtt_data_volume: "/opt/zigbee2mqtt/data" + +zigbee2mqtt_exposed_ports: [] +zigbee2mqtt_extra_hosts: [] + +# @var zigbee2mqtt_memory_limit: $ "_unset_" +# @var zigbee2mqtt_memory_limit:example: $ "512m" +# @var zigbee2mqtt_memory_reservation: $ "_unset_" +# @var zigbee2mqtt_memory_reservation:example: $ "256m" +# @var zigbee2mqtt_cpu_shares: $ "_unset_" +# @var zigbee2mqtt_cpu_shares:example: $ "1024" + +zigbee2mqtt_cap_add: [] +zigbee2mqtt_cap_drop: [] +zigbee2mqtt_security_opt: [] +# @var zigbee2mqtt_pids_limit: $ "_unset_" -zigbee2mqtt_base_dir: /opt/zigbee2mqtt -zigbee2mqtt_log_dir: "{{ zigbee2mqtt_base_dir }}/log" zigbee2mqtt_log_level: info zigbee2mqtt_homeassistant_enabled: False @@ -26,7 +76,7 @@ zigbee2mqtt_mqtt_reject_unauthorized: False zigbee2mqtt_mqtt_include_device_information: False # @var zigbee2mqtt_serial_port: $ "_unset_" -# @var zigbee2mqtt_serial_port:example: $ "/dev/ttyACM0" +# @var zigbee2mqtt_serial_port:example: $ "" zigbee2mqtt_serial_disable_led: False zigbee2mqtt_pan_id: "0x1a62" @@ -45,3 +95,5 @@ zigbee2mqtt_homeassistant_status_topic: "hass/status" zigbee2mqtt_devices_ban: [] zigbee2mqtt_devices_whitelist: [] + +zigbee2mqtt_timezone: Europe/Berlin diff --git a/handlers/main.yml b/handlers/main.yml index 0ca5823..5e5c5ad 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -1,9 +1,11 @@ --- - name: Restart zigbee2mqtt service - systemd: - state: "{{ zigbee2mqtt_service_restart_state }}" - daemon_reload: yes - name: zigbee2mqtt + docker_compose: + project_src: "{{ zigbee2mqtt_service_directory }}" + pull: yes + remove_orphans: yes + stopped: "{{ zigbee2mqtt_service_stopped }}" + restarted: "{{ not zigbee2mqtt_service_stopped }}" listen: __zigbee2mqtt_restart become: True become_user: root diff --git a/molecule/centos7/converge.yml b/molecule/centos7/converge.yml index b5cf6fe..b12556c 100644 --- a/molecule/centos7/converge.yml +++ b/molecule/centos7/converge.yml @@ -1,14 +1,23 @@ --- -- name: Converge +- name: Converge (Stage 1) hosts: all vars: - mosquitto_packages_extra: + dockerengine_packages_extra: - epel-release + - python-pip + - python-virtualenv + + roles: + - role: xoxys.docker_engine + +- name: Converge (Stage 2) + hosts: all + environment: + PYTHONPATH: /opt/python2/ansible-deps/lib/python2.7/site-packages + vars: mosquitto_bind_address: "127.0.0.1" - zigbee2mqtt_service_state: stopped - zigbee2mqtt_service_restart_state: stopped + zigbee2mqtt_service_stopped: True roles: - role: xoxys.mosquitto - - role: xoxys.nodejs - - role: xoxys.zigbee2mqtt + - role: xoxys.zigbee2mqtt_docker diff --git a/molecule/centos7/tests/test_default.py b/molecule/centos7/tests/test_default.py index 47e1e85..bf5955d 100644 --- a/molecule/centos7/tests/test_default.py +++ b/molecule/centos7/tests/test_default.py @@ -15,8 +15,3 @@ def test_hosts_file(host): f = host.file('/etc/hosts') assert f.exists - -# def test_zigbee2mqtt_running_and_enabled(host): -# zigbee2mqtt = host.service("zigbee2mqtt") -# assert zigbee2mqtt.is_running -# assert zigbee2mqtt.is_enabled diff --git a/molecule/requirements.yml b/molecule/requirements.yml index b7b2495..f01152d 100644 --- a/molecule/requirements.yml +++ b/molecule/requirements.yml @@ -4,12 +4,12 @@ collections: - name: community.general roles: - - src: https://gitea.rknet.org/ansible/xoxys.mosquitto.git - name: xoxys.mosquitto + - src: https://gitea.rknet.org/ansible/xoxys.docker_engine.git + name: xoxys.docker_engine scm: git version: master - - src: https://gitea.rknet.org/ansible/xoxys.nodejs.git - name: xoxys.nodejs + - src: https://gitea.rknet.org/ansible/xoxys.mosquitto.git + name: xoxys.mosquitto scm: git version: master diff --git a/tasks/install.yml b/tasks/install.yml deleted file mode 100644 index b46edb4..0000000 --- a/tasks/install.yml +++ /dev/null @@ -1,76 +0,0 @@ ---- -- name: Create directories - file: - path: "{{ item }}" - state: directory - owner: "{{ zigbee2mqtt_user }}" - group: "{{ zigbee2mqtt_group }}" - mode: 0750 - loop: - - "{{ zigbee2mqtt_base_dir }}" - - "{{ zigbee2mqtt_base_dir }}/data" - - "{{ zigbee2mqtt_log_dir }}" - become: True - become_user: root - -- block: - - name: Download release 'v{{ zigbee2mqtt_version }}' - unarchive: - src: "https://github.com/Koenkk/zigbee2mqtt/archive/{{ zigbee2mqtt_version }}.tar.gz" - dest: "{{ zigbee2mqtt_base_dir }}" - remote_src: yes - exclude: "{{ __zigbee2mqtt_release_exclude }}" - extra_opts: - - --strip-components=1 - - - name: Delete existing node_modules folder - file: - path: "{{ zigbee2mqtt_base_dir }}/node_modules" - state: absent - - - name: Install nodejs dependencies - npm: - path: "{{ zigbee2mqtt_base_dir }}" - environment: - PATH: "{{ __zigbee2mqtt_npm_executable | dirname }}:{{ ansible_env.PATH }}" - notify: __zigbee2mqtt_restart - when: zigbee2mqtt_version is version(zigbee2mqtt_current_version, ">") - become: True - become_user: "{{ zigbee2mqtt_user }}" - -- block: - - name: Deploy configuration file - template: - src: "zigbee2mqtt/data/configuration.yaml.j2" - dest: "{{ zigbee2mqtt_base_dir }}/data/configuration.yaml" - mode: 0600 - notify: __zigbee2mqtt_restart - - - name: Ensure device files exists - file: - path: "{{ item }}" - state: touch - access_time: preserve - modification_time: preserve - loop: - - "{{ zigbee2mqtt_base_dir }}/data/devices.yaml" - - "{{ zigbee2mqtt_base_dir }}/data/groups.yaml" - become: True - become_user: "{{ zigbee2mqtt_user }}" - -- block: - - name: Create systemd unit files - template: - src: "etc/systemd/system/zigbee2mqtt.service.j2" - dest: "/etc/systemd/system/zigbee2mqtt.service" - mode: 0644 - notify: __zigbee2mqtt_restart - - - name: Set current version to custom fact - template: - src: etc/ansible/facts.d/zigbee2mqtt.fact.j2 - dest: /etc/ansible/facts.d/zigbee2mqtt.fact - mode: 0644 - when: zigbee2mqtt_version is version(zigbee2mqtt_current_version, ">") or zigbee2mqtt_current_version is version('0.0.0', "=") - become: True - become_user: root diff --git a/tasks/main.yml b/tasks/main.yml index f02fa9a..1f69f7a 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -1,4 +1,2 @@ --- -- import_tasks: prepare.yml -- import_tasks: install.yml -- import_tasks: post_tasks.yml +- include_tasks: setup.yml diff --git a/tasks/post_tasks.yml b/tasks/post_tasks.yml deleted file mode 100644 index 0d2a66b..0000000 --- a/tasks/post_tasks.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -- name: Ensure zigbee2mqtt service is up and running - systemd: - state: "{{ zigbee2mqtt_service_state }}" - daemon_reload: yes - enabled: yes - name: zigbee2mqtt - become: True - become_user: root diff --git a/tasks/prepare.yml b/tasks/prepare.yml deleted file mode 100644 index baf60fe..0000000 --- a/tasks/prepare.yml +++ /dev/null @@ -1,26 +0,0 @@ ---- -- block: - - name: Create local facts dir - file: - path: /etc/ansible/facts.d - state: directory - - - name: Set current zigbee2mqtt version - set_fact: - zigbee2mqtt_current_version: "{{ (ansible_local.zigbee2mqtt | default (dict(version='0.0.0')))['version'] }}" - - - debug: - msg: Current version is '{{ zigbee2mqtt_current_version }}' - - - name: Create group '{{ zigbee2mqtt_group }}' - group: - name: "{{ zigbee2mqtt_group }}" - state: present - - - name: Create user '{{ zigbee2mqtt_user }}' - user: - name: "{{ zigbee2mqtt_user }}" - group: "{{ zigbee2mqtt_group }}" - groups: "{{ zigbee2mqtt_secondary_groups }}" - become: True - become_user: root diff --git a/tasks/setup.yml b/tasks/setup.yml new file mode 100644 index 0000000..8d7d1e5 --- /dev/null +++ b/tasks/setup.yml @@ -0,0 +1,52 @@ +--- +- block: + - name: Ensure service directory exists + file: + path: "{{ zigbee2mqtt_service_directory }}" + state: directory + mode: 0755 + + - name: Create bind mount source directory + file: + path: "{{ item.name }}" + state: directory + loop: "{{ zigbee2mqtt_volumes }}" + loop_control: + label: "{{ item.name }}" + when: item.bind | bool + + - name: Deploy compose file to '{{ zigbee2mqtt_service_directory }}' + template: + src: "services/zigbee2mqtt_compose.yml.j2" + dest: "{{ zigbee2mqtt_service_directory }}/docker-compose.yml" + owner: root + group: root + mode: 0640 + validate: "docker-compose -f %s config -q" + + - name: Deploy configuration file + template: + src: "zigbee2mqtt/data/configuration.yaml.j2" + dest: "{{ zigbee2mqtt_data_volume }}/configuration.yaml" + mode: 0600 + notify: __zigbee2mqtt_restart + + - name: Ensure device files exists + file: + path: "{{ item }}" + state: touch + access_time: preserve + modification_time: preserve + loop: + - "{{ zigbee2mqtt_data_volume }}/devices.yaml" + - "{{ zigbee2mqtt_data_volume }}/groups.yaml" + + - name: Ensure service is up and running + docker_compose: + project_src: "{{ zigbee2mqtt_service_directory }}" + pull: yes + remove_orphans: yes + stopped: "{{ zigbee2mqtt_service_stopped }}" + state: present + become: True + become_user: root diff --git a/templates/etc/ansible/facts.d/zigbee2mqtt.fact.j2 b/templates/etc/ansible/facts.d/zigbee2mqtt.fact.j2 deleted file mode 100644 index 261d502..0000000 --- a/templates/etc/ansible/facts.d/zigbee2mqtt.fact.j2 +++ /dev/null @@ -1,4 +0,0 @@ -{ - "comment" : "{{ ansible_managed }}", - "version" : "{{ zigbee2mqtt_version }}" -} diff --git a/templates/etc/systemd/system/zigbee2mqtt.service.j2 b/templates/etc/systemd/system/zigbee2mqtt.service.j2 deleted file mode 100644 index 613036c..0000000 --- a/templates/etc/systemd/system/zigbee2mqtt.service.j2 +++ /dev/null @@ -1,16 +0,0 @@ -#jinja2:lstrip_blocks: True -{{ ansible_managed | comment }} - -[Unit] -Description=zigbee2mqtt -After=network.target - -[Service] -ExecStart=/usr/local/bin/npm start -WorkingDirectory={{ zigbee2mqtt_base_dir }} -StandardError=inherit -Restart=always -User={{ zigbee2mqtt_user }} - -[Install] -WantedBy=multi-user.target diff --git a/templates/services/zigbee2mqtt_compose.yml.j2 b/templates/services/zigbee2mqtt_compose.yml.j2 new file mode 100644 index 0000000..3a81f9a --- /dev/null +++ b/templates/services/zigbee2mqtt_compose.yml.j2 @@ -0,0 +1,86 @@ +#jinja2:lstrip_blocks: True +{{ ansible_managed | comment }} +version: "2.4" + +services: + zigbee2mqtt: + container_name: {{ zigbee2mqtt_container_name }} + image: {{ zigbee2mqtt_image }} + restart: {{ zigbee2mqtt_restart_policy }} + {% if zigbee2mqtt_exposed_ports | default([]) %} + ports: + {% for port in zigbee2mqtt_exposed_ports %} + - {{ port | quote }} + {% endfor %} + {% endif %} + {% if zigbee2mqtt_volumes | default([]) %} + volumes: + {% for volume in zigbee2mqtt_volumes %} + - "{{ volume.name }}:{{ volume.dest }}{% if volume.bind_opt is defined %}:{{ volume.bind_opt }}{% endif %}" + {% endfor %} + {% endif %} + {% if zigbee2mqtt_devices | default([]) %} + devices: + {% for device in zigbee2mqtt_devices %} + - "{{ device.src }}:{{ device.dest }}{% if device.opt is defined %}:{{ device.opt }}{% endif %}" + {% endfor %} + {% endif %} + {% if zigbee2mqtt_networks_applied | default([]) %} + networks: + {% for network in zigbee2mqtt_networks_applied %} + - {{ network }} + {% endfor %} + {% endif %} + {% if zigbee2mqtt_extra_hosts | default([]) %} + extra_hosts: + {% for host in zigbee2mqtt_extra_hosts %} + - {{ host | quote }} + {% endfor %} + {% endif %} + environment: + - TZ={{ zigbee2mqtt_timezone }} + {% if zigbee2mqtt_memory_limit is defined %} + mem_limit: {{ zigbee2mqtt_memory_limit }} + {% endif %} + {% if zigbee2mqtt_memory_reservation is defined %} + mem_reservation: {{ zigbee2mqtt_memory_reservation }} + {% endif %} + {% if zigbee2mqtt_cpu_shares is defined %} + cpu_shares: {{ zigbee2mqtt_cpu_shares }} + {% endif %} + {% if not zigbee2mqtt_cap_add | length == 0 %} + cap_add: + {% for item in zigbee2mqtt_cap_add %} + - {{ item }} + {% endfor %} + {% endif %} + {% if not zigbee2mqtt_cap_drop | length == 0 %} + cap_drop: + {% for item in zigbee2mqtt_cap_drop %} + - {{ item }} + {% endfor %} + {% endif %} + {% if not zigbee2mqtt_security_opt | length == 0 %} + security_opt: + {% for item in zigbee2mqtt_security_opt %} + - {{ item }} + {% endfor %} + {% endif %} + {% if zigbee2mqtt_pids_limit is defined %} + pids_limit: {{ zigbee2mqtt_pids_limit }} + {% endif %} +{% if zigbee2mqtt_volumes | default([]) | rejectattr("bind") | list | length > 0 %} + +volumes: + {% for volume in zigbee2mqtt_volumes | rejectattr("bind") %} + {{ volume.name }}: + {% endfor %} +{% endif %} +{% if zigbee2mqtt_networks | default([]) | length > 0 %} + +networks: + {% for network in zigbee2mqtt_networks %} + {{ network.name }}: + driver: {{ network.backend | default("bridge") }} + {% endfor %} +{% endif %} diff --git a/templates/zigbee2mqtt/data/configuration.yaml.j2 b/templates/zigbee2mqtt/data/configuration.yaml.j2 index f7c4f56..79cf88c 100644 --- a/templates/zigbee2mqtt/data/configuration.yaml.j2 +++ b/templates/zigbee2mqtt/data/configuration.yaml.j2 @@ -43,7 +43,6 @@ advanced: channel: {{ zigbee2mqtt_channel }} cache_state: {{ zigbee2mqtt_cache_state }} log_level: "{{ zigbee2mqtt_log_level }}" - log_directory: "{{ zigbee2mqtt_log_dir }}" {% if zigbee2mqtt_network_key is defined and zigbee2mqtt_network_key %} network_key: {{ zigbee2mqtt_network_key }} {% endif %}