diff options
19 files changed, 233 insertions, 211 deletions
diff --git a/mattertimectl/build/defaults/main.yaml b/mattertimectl/build/defaults/main.yaml new file mode 100644 index 0000000..56cabdc --- /dev/null +++ b/mattertimectl/build/defaults/main.yaml @@ -0,0 +1,16 @@ +--- + +mattertimectl_version: "0.1.0" +# https://github.com/lukehoersten/mattertimectl/tags +# Rust project: cargo build --release produces one self-contained binary +# (all runtime deps are pure Rust), so the target only needs the binary to +# run it. The source tarball must point at the Rust implementation. +mattertimectl_tar: "https://github.com/{{github_user}}/mattertimectl/archive/refs/tags/v{{mattertimectl_version}}.tar.gz" +mattertimectl_build_dir: "{{build_work_dir}}/mattertimectl-{{mattertimectl_version}}" +mattertimectl_srv_dir: "{{build_srv_dir}}" + +# Keep cargo's registry cache, the rustup toolchains, and the build output +# on build_work_dir (the SSD), not the SD card. +mattertimectl_cargo_home: "{{build_work_dir}}/.cargo" +mattertimectl_rustup_home: "{{build_work_dir}}/.rustup" +mattertimectl_cargo_target_dir: "{{build_work_dir}}/.cargo-target" diff --git a/mattertimectl/build/meta/main.yaml b/mattertimectl/build/meta/main.yaml new file mode 100644 index 0000000..dae4be5 --- /dev/null +++ b/mattertimectl/build/meta/main.yaml @@ -0,0 +1,5 @@ +--- + +# No role dependency: the Rust toolchain is installed inline via rustup +# (the distro rustc is too old for this crate's Rust edition). +dependencies: [] diff --git a/mattertimectl/build/tasks/main.yaml b/mattertimectl/build/tasks/main.yaml new file mode 100644 index 0000000..d5721d7 --- /dev/null +++ b/mattertimectl/build/tasks/main.yaml @@ -0,0 +1,71 @@ +--- + +- name: ensure build work dir exists + become: yes + file: + path: "{{build_work_dir}}" + state: "directory" + owner: "{{ansible_user}}" + group: "{{ansible_user}}" + mode: "0755" + +- name: check if mattertimectl build exists + stat: + path: "{{mattertimectl_srv_dir}}/mattertimectl-{{mattertimectl_version}}.tar.gz" + register: build_file + +# NOTE: rustup is used only because rs-matter requires a newer rustc than +# Ubuntu 24.04's apt ships (apt rustc is 1.75; rs-matter needs >= 1.87). Once +# the build host runs an Ubuntu whose apt rustc/cargo are new enough, drop +# rustup and the toolchain tasks below and just `apt install rustc cargo`. +- name: install rustup + become: yes + apt: + name: "rustup" + state: "present" + +- name: install a current stable rust toolchain + command: "rustup toolchain install stable" + environment: + CARGO_HOME: "{{mattertimectl_cargo_home}}" + RUSTUP_HOME: "{{mattertimectl_rustup_home}}" + when: not build_file.stat.exists + +- name: unarchive mattertimectl source + unarchive: + remote_src: yes + src: "{{mattertimectl_tar}}" + dest: "{{build_work_dir}}/" + creates: "{{mattertimectl_build_dir}}" + +- name: build mattertimectl release binary + # rustup run stable dispatches cargo through the toolchain regardless of + # the apt rustup package's proxy layout or the configured default. + command: "rustup run stable cargo build --release" + args: + chdir: "{{mattertimectl_build_dir}}" + creates: "{{mattertimectl_cargo_target_dir}}/release/mattertimectl" + environment: + CARGO_HOME: "{{mattertimectl_cargo_home}}" + RUSTUP_HOME: "{{mattertimectl_rustup_home}}" + CARGO_TARGET_DIR: "{{mattertimectl_cargo_target_dir}}" + when: not build_file.stat.exists + +- name: create build server dir + become: yes + file: + path: "{{mattertimectl_srv_dir}}" + mode: "0755" + state: "directory" + +- name: create gz archive of mattertimectl binary + become: yes + archive: + path: "{{mattertimectl_cargo_target_dir}}/release/mattertimectl" + dest: "{{mattertimectl_srv_dir}}/mattertimectl-{{mattertimectl_version}}.tar.gz" + format: "gz" + # force a real tar for the single-file binary; the module otherwise gzips + # a lone file into a bare .gz that the server's unarchive can't extract. + # The tar preserves the executable bit the target relies on. + force_archive: true + when: not build_file.stat.exists diff --git a/mattertimectl/controller/defaults/main.yaml b/mattertimectl/controller/defaults/main.yaml new file mode 100644 index 0000000..933a4bb --- /dev/null +++ b/mattertimectl/controller/defaults/main.yaml @@ -0,0 +1,25 @@ +--- + +# https://github.com/lukehoersten/mattertimectl/tags +mattertimectl_version: "0.1.0" + +mattertimectl_user: "mattertimectl" +mattertimectl_install_dir: "/opt/mattertimectl" +mattertimectl_config_dir: "/etc/mattertimectl" +# Persistent Matter fabric state: holds the controller's private keys and +# operational certs, so it stays mode 0700 and owned by the service user. +mattertimectl_storage_path: "/var/lib/mattertimectl" + +# --- config.json --- +# IANA time-zone name (never a fixed UTC offset; DST is derived from it). +mattertimectl_timezone: "America/Chicago" +mattertimectl_log_level: "info" # debug, info, warn, error +mattertimectl_fabric_label: "Matter Time Controller" + +# --- systemd timer schedule --- +mattertimectl_on_boot_sec: "2min" +mattertimectl_on_active_sec: "1h" +mattertimectl_randomized_delay_sec: "5min" + +# mattertimectl_bin_url: required, set in host_vars, e.g. +# http://{{build_server_host}}:{{build_server_port}}/mattertimectl-{{mattertimectl_version}}.tar.gz diff --git a/mattertimesync/server/handlers/main.yaml b/mattertimectl/controller/handlers/main.yaml index 9b124e3..9b124e3 100644 --- a/mattertimesync/server/handlers/main.yaml +++ b/mattertimectl/controller/handlers/main.yaml diff --git a/mattertimectl/controller/meta/main.yaml b/mattertimectl/controller/meta/main.yaml new file mode 100644 index 0000000..0fa3794 --- /dev/null +++ b/mattertimectl/controller/meta/main.yaml @@ -0,0 +1,5 @@ +--- + +# No runtime dependency: the Rust build is a single self-contained binary, +# so the target needs no node or other runtime. +dependencies: [] diff --git a/mattertimectl/controller/tasks/main.yaml b/mattertimectl/controller/tasks/main.yaml new file mode 100644 index 0000000..a77145c --- /dev/null +++ b/mattertimectl/controller/tasks/main.yaml @@ -0,0 +1,80 @@ +--- + +- name: add mattertimectl user + become: yes + user: + name: "{{mattertimectl_user}}" + system: "yes" + shell: "/usr/sbin/nologin" + home: "{{mattertimectl_storage_path}}" + create_home: "no" + +- name: create mattertimectl directories + become: yes + file: + path: "{{item.path}}" + state: "directory" + owner: "{{item.owner}}" + group: "{{item.owner}}" + mode: "{{item.mode}}" + loop: + - { path: "{{mattertimectl_install_dir}}", owner: "root", mode: "0755" } + - { path: "{{mattertimectl_config_dir}}", owner: "root", mode: "0755" } + - { path: "{{mattertimectl_storage_path}}", owner: "{{mattertimectl_user}}", mode: "0700" } + +- name: check installed mattertimectl version + become: yes + stat: + path: "{{mattertimectl_install_dir}}/.installed-{{mattertimectl_version}}" + register: mattertimectl_installed + +- name: install mattertimectl bundle + become: yes + unarchive: + remote_src: yes + src: "{{mattertimectl_bin_url}}" + dest: "{{mattertimectl_install_dir}}/" + owner: "root" + group: "root" + when: not mattertimectl_installed.stat.exists + +- name: stamp installed mattertimectl version + become: yes + copy: + dest: "{{mattertimectl_install_dir}}/.installed-{{mattertimectl_version}}" + content: "{{mattertimectl_version}}\n" + mode: "0644" + when: not mattertimectl_installed.stat.exists + +- name: configure mattertimectl + become: yes + template: + src: "config.json.j2" + dest: "{{mattertimectl_config_dir}}/config.json" + owner: "root" + group: "{{mattertimectl_user}}" + mode: "0640" + +- name: install mattertimectl systemd service + become: yes + template: + src: "mattertimectl.service.j2" + dest: "/etc/systemd/system/mattertimectl.service" + mode: "0644" + notify: reload systemd + +- name: install mattertimectl systemd timer + become: yes + template: + src: "mattertimectl.timer.j2" + dest: "/etc/systemd/system/mattertimectl.timer" + mode: "0644" + notify: reload systemd + +- name: enable mattertimectl timer + become: yes + systemd: + name: "mattertimectl.timer" + enabled: "yes" + state: "started" + daemon_reload: "yes" diff --git a/mattertimectl/controller/templates/config.json.j2 b/mattertimectl/controller/templates/config.json.j2 new file mode 100644 index 0000000..34f319c --- /dev/null +++ b/mattertimectl/controller/templates/config.json.j2 @@ -0,0 +1,6 @@ +{ + "storagePath": "{{mattertimectl_storage_path}}", + "timezone": "{{mattertimectl_timezone}}", + "logLevel": "{{mattertimectl_log_level}}", + "fabricLabel": "{{mattertimectl_fabric_label}}" +} diff --git a/mattertimectl/controller/templates/mattertimectl.service.j2 b/mattertimectl/controller/templates/mattertimectl.service.j2 new file mode 100644 index 0000000..96cbeee --- /dev/null +++ b/mattertimectl/controller/templates/mattertimectl.service.j2 @@ -0,0 +1,15 @@ +[Unit] +Description=Matter device clock synchronization +Wants=network-online.target +After=network-online.target time-sync.target + +[Service] +Type=oneshot +User={{mattertimectl_user}} +Group={{mattertimectl_user}} +ExecStart={{mattertimectl_install_dir}}/mattertimectl --config {{mattertimectl_config_dir}}/config.json sync +NoNewPrivileges=true +PrivateTmp=true +ProtectSystem=strict +ProtectHome=true +ReadWritePaths={{mattertimectl_storage_path}} diff --git a/mattertimectl/controller/templates/mattertimectl.timer.j2 b/mattertimectl/controller/templates/mattertimectl.timer.j2 new file mode 100644 index 0000000..a4242de --- /dev/null +++ b/mattertimectl/controller/templates/mattertimectl.timer.j2 @@ -0,0 +1,10 @@ +[Unit] +Description=Periodic Matter device clock synchronization + +[Timer] +OnBootSec={{mattertimectl_on_boot_sec}} +OnUnitActiveSec={{mattertimectl_on_active_sec}} +RandomizedDelaySec={{mattertimectl_randomized_delay_sec}} + +[Install] +WantedBy=timers.target diff --git a/mattertimesync/build/defaults/main.yaml b/mattertimesync/build/defaults/main.yaml deleted file mode 100644 index bee4e58..0000000 --- a/mattertimesync/build/defaults/main.yaml +++ /dev/null @@ -1,9 +0,0 @@ ---- - -mattertimesync_version: "0.1.0" -# https://github.com/lukehoersten/mattertimesync/tags -# Pure-JS project: npm run bundle produces one self-contained mattertimesync.mjs -# (no native modules), so the target only needs node to run it. -mattertimesync_tar: "https://github.com/{{github_user}}/mattertimesync/archive/refs/tags/v{{mattertimesync_version}}.tar.gz" -mattertimesync_build_dir: "{{build_work_dir}}/mattertimesync-{{mattertimesync_version}}" -mattertimesync_srv_dir: "{{build_srv_dir}}" diff --git a/mattertimesync/build/meta/main.yaml b/mattertimesync/build/meta/main.yaml deleted file mode 100644 index 6116998..0000000 --- a/mattertimesync/build/meta/main.yaml +++ /dev/null @@ -1,4 +0,0 @@ ---- - -dependencies: - - nodejs diff --git a/mattertimesync/build/tasks/main.yaml b/mattertimesync/build/tasks/main.yaml deleted file mode 100644 index c586e01..0000000 --- a/mattertimesync/build/tasks/main.yaml +++ /dev/null @@ -1,58 +0,0 @@ ---- - -- name: ensure build work dir exists - become: yes - file: - path: "{{build_work_dir}}" - state: "directory" - owner: "{{ansible_user}}" - group: "{{ansible_user}}" - mode: "0755" - -- name: unarchive mattertimesync source - unarchive: - remote_src: yes - src: "{{mattertimesync_tar}}" - dest: "{{build_work_dir}}/" - creates: "{{mattertimesync_build_dir}}" - -- name: check if mattertimesync build exists - stat: - path: "{{mattertimesync_srv_dir}}/mattertimesync-{{mattertimesync_version}}.tar.gz" - register: build_file - -- name: install mattertimesync build dependencies - command: "npm ci" - args: - chdir: "{{mattertimesync_build_dir}}" - # Keep the npm cache on build_work_dir (the SSD) instead of the SD card. - environment: - npm_config_cache: "{{build_work_dir}}/.npm" - when: not build_file.stat.exists - -- name: bundle mattertimesync - command: "npm run bundle" - args: - chdir: "{{mattertimesync_build_dir}}" - creates: "{{mattertimesync_build_dir}}/mattertimesync.mjs" - environment: - npm_config_cache: "{{build_work_dir}}/.npm" - when: not build_file.stat.exists - -- name: create build server dir - become: yes - file: - path: "{{mattertimesync_srv_dir}}" - mode: "0755" - state: "directory" - -- name: create gz archive of mattertimesync bundle - become: yes - archive: - path: "{{mattertimesync_build_dir}}/mattertimesync.mjs" - dest: "{{mattertimesync_srv_dir}}/mattertimesync-{{mattertimesync_version}}.tar.gz" - format: "gz" - # force a real tar for the single-file bundle; the module otherwise gzips a - # lone file into a bare .gz that the server's unarchive can't extract. - force_archive: true - when: not build_file.stat.exists diff --git a/mattertimesync/server/defaults/main.yaml b/mattertimesync/server/defaults/main.yaml deleted file mode 100644 index e78e700..0000000 --- a/mattertimesync/server/defaults/main.yaml +++ /dev/null @@ -1,25 +0,0 @@ ---- - -# https://github.com/lukehoersten/mattertimesync/tags -mattertimesync_version: "0.1.0" - -mattertimesync_user: "mattertimesync" -mattertimesync_install_dir: "/opt/mattertimesync" -mattertimesync_config_dir: "/etc/mattertimesync" -# Persistent Matter fabric state — holds the controller's private keys and -# operational certs, so it stays mode 0700 and owned by the service user. -mattertimesync_storage_path: "/var/lib/mattertimesync" - -# --- config.json --- -# IANA time-zone name (never a fixed UTC offset; DST is derived from it). -mattertimesync_timezone: "America/Chicago" -mattertimesync_log_level: "info" # debug, info, warn, error -mattertimesync_fabric_label: "Matter Time Sync" - -# --- systemd timer schedule --- -mattertimesync_on_boot_sec: "2min" -mattertimesync_on_active_sec: "1h" -mattertimesync_randomized_delay_sec: "5min" - -# mattertimesync_bin_url: — required, set in host_vars, e.g. -# http://{{build_server_host}}:{{build_server_port}}/mattertimesync-{{mattertimesync_version}}.tar.gz diff --git a/mattertimesync/server/meta/main.yaml b/mattertimesync/server/meta/main.yaml deleted file mode 100644 index 6116998..0000000 --- a/mattertimesync/server/meta/main.yaml +++ /dev/null @@ -1,4 +0,0 @@ ---- - -dependencies: - - nodejs diff --git a/mattertimesync/server/tasks/main.yaml b/mattertimesync/server/tasks/main.yaml deleted file mode 100644 index 7be2392..0000000 --- a/mattertimesync/server/tasks/main.yaml +++ /dev/null @@ -1,80 +0,0 @@ ---- - -- name: add mattertimesync user - become: yes - user: - name: "{{mattertimesync_user}}" - system: "yes" - shell: "/usr/sbin/nologin" - home: "{{mattertimesync_storage_path}}" - create_home: "no" - -- name: create mattertimesync directories - become: yes - file: - path: "{{item.path}}" - state: "directory" - owner: "{{item.owner}}" - group: "{{item.owner}}" - mode: "{{item.mode}}" - loop: - - { path: "{{mattertimesync_install_dir}}", owner: "root", mode: "0755" } - - { path: "{{mattertimesync_config_dir}}", owner: "root", mode: "0755" } - - { path: "{{mattertimesync_storage_path}}", owner: "{{mattertimesync_user}}", mode: "0700" } - -- name: check installed mattertimesync version - become: yes - stat: - path: "{{mattertimesync_install_dir}}/.installed-{{mattertimesync_version}}" - register: mattertimesync_installed - -- name: install mattertimesync bundle - become: yes - unarchive: - remote_src: yes - src: "{{mattertimesync_bin_url}}" - dest: "{{mattertimesync_install_dir}}/" - owner: "root" - group: "root" - when: not mattertimesync_installed.stat.exists - -- name: stamp installed mattertimesync version - become: yes - copy: - dest: "{{mattertimesync_install_dir}}/.installed-{{mattertimesync_version}}" - content: "{{mattertimesync_version}}\n" - mode: "0644" - when: not mattertimesync_installed.stat.exists - -- name: configure mattertimesync - become: yes - template: - src: "config.json.j2" - dest: "{{mattertimesync_config_dir}}/config.json" - owner: "root" - group: "{{mattertimesync_user}}" - mode: "0640" - -- name: install mattertimesync systemd service - become: yes - template: - src: "mattertimesync.service.j2" - dest: "/etc/systemd/system/mattertimesync.service" - mode: "0644" - notify: reload systemd - -- name: install mattertimesync systemd timer - become: yes - template: - src: "mattertimesync.timer.j2" - dest: "/etc/systemd/system/mattertimesync.timer" - mode: "0644" - notify: reload systemd - -- name: enable mattertimesync timer - become: yes - systemd: - name: "mattertimesync.timer" - enabled: "yes" - state: "started" - daemon_reload: "yes" diff --git a/mattertimesync/server/templates/config.json.j2 b/mattertimesync/server/templates/config.json.j2 deleted file mode 100644 index a9b30c3..0000000 --- a/mattertimesync/server/templates/config.json.j2 +++ /dev/null @@ -1,6 +0,0 @@ -{ - "storagePath": "{{mattertimesync_storage_path}}", - "timezone": "{{mattertimesync_timezone}}", - "logLevel": "{{mattertimesync_log_level}}", - "fabricLabel": "{{mattertimesync_fabric_label}}" -} diff --git a/mattertimesync/server/templates/mattertimesync.service.j2 b/mattertimesync/server/templates/mattertimesync.service.j2 deleted file mode 100644 index e47cc35..0000000 --- a/mattertimesync/server/templates/mattertimesync.service.j2 +++ /dev/null @@ -1,15 +0,0 @@ -[Unit] -Description=Matter device clock synchronization -Wants=network-online.target -After=network-online.target time-sync.target - -[Service] -Type=oneshot -User={{mattertimesync_user}} -Group={{mattertimesync_user}} -ExecStart=/usr/bin/node {{mattertimesync_install_dir}}/mattertimesync.mjs --config {{mattertimesync_config_dir}}/config.json sync -NoNewPrivileges=true -PrivateTmp=true -ProtectSystem=strict -ProtectHome=true -ReadWritePaths={{mattertimesync_storage_path}} diff --git a/mattertimesync/server/templates/mattertimesync.timer.j2 b/mattertimesync/server/templates/mattertimesync.timer.j2 deleted file mode 100644 index e378dfc..0000000 --- a/mattertimesync/server/templates/mattertimesync.timer.j2 +++ /dev/null @@ -1,10 +0,0 @@ -[Unit] -Description=Periodic Matter device clock synchronization - -[Timer] -OnBootSec={{mattertimesync_on_boot_sec}} -OnUnitActiveSec={{mattertimesync_on_active_sec}} -RandomizedDelaySec={{mattertimesync_randomized_delay_sec}} - -[Install] -WantedBy=timers.target |
