Some checks failed
morphit-release / Build + publish release tarball (push) Has been cancelled
235 lines
8.6 KiB
YAML
235 lines
8.6 KiB
YAML
---
|
|
# Every Morphit instance runs a small Kubo node that pins the signed release.
|
|
|
|
- name: Create the ipfs group
|
|
ansible.builtin.group:
|
|
name: "{{ morphit_ipfs_group }}"
|
|
system: true
|
|
|
|
- name: Create the unprivileged ipfs user
|
|
ansible.builtin.user:
|
|
name: "{{ morphit_ipfs_user }}"
|
|
group: "{{ morphit_ipfs_group }}"
|
|
home: "{{ morphit_ipfs_home }}"
|
|
shell: /usr/sbin/nologin
|
|
system: true
|
|
create_home: true
|
|
|
|
- name: Check the currently-installed Kubo version (idempotent install)
|
|
ansible.builtin.command: ipfs --version
|
|
register: morphit_ipfs_have
|
|
changed_when: false
|
|
failed_when: false
|
|
|
|
- name: Install Kubo (download + verify + place binary)
|
|
when: morphit_kubo_version | regex_replace('^v', '') not in (morphit_ipfs_have.stdout | default(''))
|
|
block:
|
|
- name: Make a scratch dir for the Kubo download
|
|
ansible.builtin.tempfile:
|
|
state: directory
|
|
suffix: kubo
|
|
register: morphit_kubo_tmp
|
|
|
|
- name: Detect a bundled Kubo tarball (offline appliance)
|
|
ansible.builtin.stat:
|
|
path: "{{ morphit_repo_path }}/vendor/kubo/kubo_{{ morphit_kubo_version }}_{{ morphit_kubo_arch }}.tar.gz"
|
|
register: morphit_kubo_vendor
|
|
|
|
- name: Use the bundled Kubo tarball (offline — still SHA-512 verified below)
|
|
ansible.builtin.copy:
|
|
src: "{{ morphit_repo_path }}/vendor/kubo/kubo_{{ morphit_kubo_version }}_{{ morphit_kubo_arch }}.tar.gz"
|
|
dest: "{{ morphit_kubo_tmp.path }}/kubo.tar.gz"
|
|
remote_src: true
|
|
mode: "0644"
|
|
when: morphit_kubo_vendor.stat.exists
|
|
|
|
- name: Download the Kubo tarball
|
|
ansible.builtin.get_url:
|
|
url: "{{ morphit_kubo_dist_base }}/{{ morphit_kubo_version }}/kubo_{{ morphit_kubo_version }}_{{ morphit_kubo_arch }}.tar.gz"
|
|
dest: "{{ morphit_kubo_tmp.path }}/kubo.tar.gz"
|
|
mode: "0644"
|
|
when: not morphit_kubo_vendor.stat.exists
|
|
|
|
- name: Download the official Kubo checksum (used when no explicit pin is set)
|
|
ansible.builtin.get_url:
|
|
url: "{{ morphit_kubo_dist_base }}/{{ morphit_kubo_version }}/kubo_{{ morphit_kubo_version }}_{{ morphit_kubo_arch }}.tar.gz.sha512"
|
|
dest: "{{ morphit_kubo_tmp.path }}/kubo.tar.gz.sha512"
|
|
mode: "0644"
|
|
when: morphit_kubo_sha512 | length == 0
|
|
|
|
- name: Compute the download's SHA-512
|
|
ansible.builtin.stat:
|
|
path: "{{ morphit_kubo_tmp.path }}/kubo.tar.gz"
|
|
checksum_algorithm: sha512
|
|
get_checksum: true
|
|
register: morphit_kubo_dl
|
|
|
|
- name: Verify against the operator-pinned SHA-512 (strong pin)
|
|
ansible.builtin.assert:
|
|
that:
|
|
- morphit_kubo_dl.stat.checksum | lower == morphit_kubo_sha512 | lower
|
|
fail_msg: >-
|
|
Kubo tarball SHA-512 mismatch — expected the pinned {{ morphit_kubo_sha512 }},
|
|
got {{ morphit_kubo_dl.stat.checksum }}. Refusing to install.
|
|
when: morphit_kubo_sha512 | length > 0
|
|
|
|
- name: Verify against the official published SHA-512
|
|
ansible.builtin.assert:
|
|
that:
|
|
- morphit_kubo_dl.stat.checksum | lower
|
|
== (lookup('file', morphit_kubo_tmp.path + '/kubo.tar.gz.sha512') | regex_search('[0-9a-fA-F]{128}')) | lower
|
|
fail_msg: "Kubo tarball did not match its published .sha512 — refusing to install."
|
|
when: morphit_kubo_sha512 | length == 0
|
|
|
|
- name: Extract Kubo
|
|
ansible.builtin.unarchive:
|
|
src: "{{ morphit_kubo_tmp.path }}/kubo.tar.gz"
|
|
dest: "{{ morphit_kubo_tmp.path }}"
|
|
remote_src: true
|
|
|
|
- name: Install the ipfs binary
|
|
ansible.builtin.copy:
|
|
src: "{{ morphit_kubo_tmp.path }}/kubo/ipfs"
|
|
dest: /usr/local/bin/ipfs
|
|
remote_src: true
|
|
owner: root
|
|
group: root
|
|
mode: "0755"
|
|
notify: Restart ipfs
|
|
|
|
- name: Remove the scratch dir
|
|
ansible.builtin.file:
|
|
path: "{{ morphit_kubo_tmp.path }}"
|
|
state: absent
|
|
|
|
- name: Initialise the Kubo repo (once; applies the low-footprint profile)
|
|
ansible.builtin.command:
|
|
cmd: "ipfs init --profile {{ morphit_ipfs_profile }}"
|
|
creates: "{{ morphit_ipfs_repo }}/config"
|
|
become: true
|
|
become_user: "{{ morphit_ipfs_user }}"
|
|
environment:
|
|
IPFS_PATH: "{{ morphit_ipfs_repo }}"
|
|
|
|
- name: Keep the node small — bind API/gateway to loopback + cap connections
|
|
ansible.builtin.command:
|
|
cmd: "ipfs config --json {{ item.key }} {{ item.value }}"
|
|
become: true
|
|
become_user: "{{ morphit_ipfs_user }}"
|
|
environment:
|
|
IPFS_PATH: "{{ morphit_ipfs_repo }}"
|
|
loop:
|
|
- { key: "Addresses.API", value: "'\"{{ morphit_ipfs_api_addr }}\"'" }
|
|
- { key: "Addresses.Gateway", value: "'\"{{ morphit_ipfs_gateway_addr }}\"'" }
|
|
- { key: "Swarm.ConnMgr.HighWater", value: "{{ morphit_ipfs_connmgr_high }}" }
|
|
- { key: "Swarm.ConnMgr.LowWater", value: "{{ morphit_ipfs_connmgr_low }}" }
|
|
- { key: "Routing.Type", value: "'\"auto\"'" }
|
|
changed_when: false
|
|
notify: Restart ipfs
|
|
|
|
- name: Ensure /etc/morphit exists (env dir)
|
|
ansible.builtin.file:
|
|
path: /etc/morphit
|
|
state: directory
|
|
owner: root
|
|
group: root
|
|
mode: "0755"
|
|
|
|
- name: Install /usr/local/lib/morphit (script dir)
|
|
ansible.builtin.file:
|
|
path: /usr/local/lib/morphit
|
|
state: directory
|
|
owner: root
|
|
group: root
|
|
mode: "0755"
|
|
|
|
- name: Install the release-pinning script
|
|
ansible.builtin.copy:
|
|
src: "{{ playbook_dir }}/../ipfs/morphit-ipfs-pin.sh"
|
|
dest: /usr/local/lib/morphit/morphit-ipfs-pin.sh
|
|
owner: root
|
|
group: root
|
|
mode: "0755"
|
|
|
|
- name: Install the IPNS-rebroadcast script
|
|
# Re-announces @morphit's on-chain signed IPNS record to the public DHT from
|
|
# this box (no key required), so ipns://<name> stays resolvable as long as ANY
|
|
# instance is alive. The hand-managed path (morphit-ipfs-setup.sh) installs the
|
|
# same script + timer; this wires it for Ansible/wizard installs too.
|
|
ansible.builtin.copy:
|
|
src: "{{ playbook_dir }}/../ipfs/morphit-ipns-rebroadcast.sh"
|
|
dest: /usr/local/lib/morphit/morphit-ipns-rebroadcast.sh
|
|
owner: root
|
|
group: root
|
|
mode: "0755"
|
|
|
|
- name: Install the pin service env file
|
|
ansible.builtin.template:
|
|
src: ipfs-pin.env.j2
|
|
dest: /etc/morphit/ipfs-pin.env
|
|
owner: root
|
|
group: "{{ morphit_ipfs_group }}"
|
|
mode: "0640"
|
|
|
|
- name: Install the Kubo daemon unit
|
|
ansible.builtin.template:
|
|
src: ipfs.service.j2
|
|
dest: /etc/systemd/system/ipfs.service
|
|
owner: root
|
|
group: root
|
|
mode: "0644"
|
|
notify:
|
|
- Reload systemd
|
|
- Restart ipfs
|
|
|
|
- name: Install the release-pinning + IPNS-rebroadcast services + timers
|
|
ansible.builtin.template:
|
|
src: "{{ item.src }}"
|
|
dest: "/etc/systemd/system/{{ item.dest }}"
|
|
owner: root
|
|
group: root
|
|
mode: "0644"
|
|
loop:
|
|
- { src: "morphit-ipfs-pin.service.j2", dest: "morphit-ipfs-pin.service" }
|
|
- { src: "morphit-ipfs-pin.timer.j2", dest: "morphit-ipfs-pin.timer" }
|
|
- { src: "morphit-ipns-rebroadcast.service.j2", dest: "morphit-ipns-rebroadcast.service" }
|
|
- { src: "morphit-ipns-rebroadcast.timer.j2", dest: "morphit-ipns-rebroadcast.timer" }
|
|
notify: Reload systemd
|
|
|
|
- name: Flush handlers so the daemon is running before we enable the timer
|
|
ansible.builtin.meta: flush_handlers
|
|
|
|
- name: Enable + start the Kubo daemon (best-effort — enabled always, started if it can)
|
|
ansible.builtin.systemd:
|
|
name: ipfs
|
|
state: started
|
|
enabled: true
|
|
# Same rationale as the handler: keep it ENABLED so it persists + retries, but
|
|
# don't let an offline-Phase-1 box (no network yet) fail the whole install here.
|
|
register: morphit_ipfs_started
|
|
failed_when: false
|
|
|
|
- name: Note that IPFS release-hosting is deferred if the daemon isn't up yet
|
|
ansible.builtin.debug:
|
|
msg: >-
|
|
The IPFS (Kubo) daemon didn't start just now — this is expected on an
|
|
offline/first-boot box. It's enabled with Restart=on-failure, so it comes up
|
|
once this machine has network (or on the next reboot); `sudo systemctl status
|
|
ipfs` shows why if it's still down after you're online.
|
|
when: morphit_ipfs_started is failed or (morphit_ipfs_started.status is defined and morphit_ipfs_started.status.ActiveState | default('') != 'active')
|
|
|
|
- name: Enable + start the release-pinning timer
|
|
ansible.builtin.systemd:
|
|
name: morphit-ipfs-pin.timer
|
|
state: started
|
|
enabled: true
|
|
|
|
- name: Enable + start the IPNS-rebroadcast timer
|
|
# Same best-effort posture as the daemon: a fresh offline box may not have the
|
|
# DHT reachable yet, but the timer stays enabled and fires once it's online, so
|
|
# ipns://<name> gets re-announced from this instance without operator action.
|
|
ansible.builtin.systemd:
|
|
name: morphit-ipns-rebroadcast.timer
|
|
state: started
|
|
enabled: true
|
|
failed_when: false
|