Matrix Docker Ansible eploy
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

121 строка
4.2 KiB

  1. #!/usr/bin/env bash
  2. # SPDX-FileCopyrightText: 2026 MDAD project contributors
  3. # SPDX-FileCopyrightText: 2026 Slavi Pantaleev
  4. #
  5. # SPDX-License-Identifier: AGPL-3.0-or-later
  6. # Adds a new host to the inventory, based on the example files in `examples/`:
  7. # - creates `inventory/hosts` (or adds the host to it, if it already exists)
  8. # - creates `inventory/host_vars/matrix.DOMAIN/vars.yml` with strong secrets generated automatically
  9. #
  10. # Existing configuration for the same host is never overwritten - the script refuses to run instead.
  11. #
  12. # Usage: bin/add-inventory-host.sh <base-domain> <server-address>
  13. #
  14. # - <base-domain> is the base domain (`example.com`), not the Matrix server hostname (`matrix.example.com`)
  15. # - <server-address> is the server's external IP address or domain name
  16. set -euo pipefail
  17. base_path="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
  18. if [ $# -ne 2 ]; then
  19. echo "Usage: $0 <base-domain> <server-address>" >&2
  20. echo "Example: $0 example.com 1.2.3.4" >&2
  21. exit 1
  22. fi
  23. domain="$1"
  24. server_address="$2"
  25. if ! printf '%s' "${domain}" | grep -Eq '^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)+$'; then
  26. echo "Error: '${domain}' does not look like a valid domain name" >&2
  27. exit 1
  28. fi
  29. if ! printf '%s' "${server_address}" | grep -Eq '^[A-Za-z0-9.:_-]+$'; then
  30. echo "Error: '${server_address}' does not look like a valid server address (IP address or domain name)" >&2
  31. exit 1
  32. fi
  33. case "${domain}" in
  34. matrix.*)
  35. echo "Warning: you likely need to pass your base domain (example.com), not the Matrix server hostname (matrix.example.com)." >&2
  36. echo "Proceeding anyway. Your Matrix server hostname will be: matrix.${domain}" >&2
  37. ;;
  38. esac
  39. matrix_hostname="matrix.${domain}"
  40. hosts_file="${base_path}/inventory/hosts"
  41. vars_dir="${base_path}/inventory/host_vars/${matrix_hostname}"
  42. vars_file="${vars_dir}/vars.yml"
  43. hosts_entry="${matrix_hostname} ansible_host=${server_address} ansible_ssh_user=root"
  44. if [ -e "${vars_dir}" ]; then
  45. echo "Error: ${vars_dir} already exists. Refusing to overwrite it." >&2
  46. exit 1
  47. fi
  48. if [ -f "${hosts_file}" ]; then
  49. if ! grep -q '^\[matrix_servers\]' "${hosts_file}"; then
  50. echo "Error: ${hosts_file} exists, but does not contain a [matrix_servers] section." >&2
  51. echo "Unrecognized inventory format. Add the host to it manually:" >&2
  52. echo "${hosts_entry}" >&2
  53. exit 1
  54. fi
  55. matrix_hostname_pattern="$(printf '%s' "${matrix_hostname}" | sed 's|\.|\\.|g')"
  56. if grep -Eq "^${matrix_hostname_pattern}([[:space:]]|$)" "${hosts_file}"; then
  57. echo "Error: ${hosts_file} already contains an entry for ${matrix_hostname}. Refusing to modify it." >&2
  58. exit 1
  59. fi
  60. fi
  61. generate_secret() {
  62. if command -v pwgen >/dev/null 2>&1; then
  63. pwgen -s 64 1
  64. elif command -v openssl >/dev/null 2>&1; then
  65. openssl rand -base64 192 | LC_ALL=C tr -dc 'A-Za-z0-9' | head -c 64
  66. else
  67. head -c 4096 /dev/urandom | LC_ALL=C tr -dc 'A-Za-z0-9' | head -c 64
  68. fi
  69. }
  70. generic_secret_key="$(generate_secret)"
  71. postgres_password="$(generate_secret)"
  72. for secret in "${generic_secret_key}" "${postgres_password}"; do
  73. if [ "${#secret}" -lt 64 ]; then
  74. echo "Error: failed to generate a secret" >&2
  75. exit 1
  76. fi
  77. done
  78. mkdir -p "${vars_dir}"
  79. sed \
  80. -e "s|^matrix_domain:.*|matrix_domain: ${domain}|" \
  81. -e "s|^matrix_homeserver_generic_secret_key:.*|matrix_homeserver_generic_secret_key: '${generic_secret_key}'|" \
  82. -e "s|^postgres_connection_password:.*|postgres_connection_password: '${postgres_password}'|" \
  83. "${base_path}/examples/vars.yml" > "${vars_file}"
  84. if [ -f "${hosts_file}" ]; then
  85. # Insert the new host right after the [matrix_servers] section header.
  86. hosts_file_tmp="$(mktemp "${hosts_file}.XXXXXX")"
  87. awk -v entry="${hosts_entry}" '{print} $0 ~ /^\[matrix_servers\]/ && !done {print entry; done=1}' \
  88. "${hosts_file}" > "${hosts_file_tmp}"
  89. mv "${hosts_file_tmp}" "${hosts_file}"
  90. else
  91. sed \
  92. -e "s|^matrix\.example\.com .*|${hosts_entry}|" \
  93. "${base_path}/examples/hosts" > "${hosts_file}"
  94. fi
  95. echo "Added host ${matrix_hostname} to the inventory:"
  96. echo "- ${hosts_file}"
  97. echo "- ${vars_file}"
  98. echo ""
  99. echo "Secrets were generated automatically for matrix_homeserver_generic_secret_key and postgres_connection_password."
  100. echo "Review and adjust these files before installing."