ConfigLMM 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (250) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +70 -0
  3. data/CNAME +1 -0
  4. data/Examples/.lmm.state.yaml +159 -0
  5. data/Examples/ConfigLMM.mm.yaml +32 -0
  6. data/Examples/Implemented.mm.yaml +252 -4
  7. data/Examples/SmallBusiness.mm.yaml +492 -0
  8. data/Plugins/Apps/Answer/answer.lmm.rb +165 -0
  9. data/Plugins/Apps/Answer/answer@.service +40 -0
  10. data/Plugins/Apps/ArchiSteamFarm/ArchiSteamFarm.conf.erb +0 -3
  11. data/Plugins/Apps/ArchiSteamFarm/ArchiSteamFarm.lmm.rb +0 -1
  12. data/Plugins/Apps/Authentik/Authentik-ProxyOutpost.container +20 -0
  13. data/Plugins/Apps/Authentik/Authentik-Server.container +7 -1
  14. data/Plugins/Apps/Authentik/Authentik-Worker.container +7 -1
  15. data/Plugins/Apps/Authentik/Authentik.conf.erb +18 -6
  16. data/Plugins/Apps/Authentik/Authentik.lmm.rb +232 -45
  17. data/Plugins/Apps/BookStack/BookStack.conf.erb +38 -0
  18. data/Plugins/Apps/BookStack/BookStack.container +20 -0
  19. data/Plugins/Apps/BookStack/BookStack.lmm.rb +91 -0
  20. data/Plugins/Apps/Cassandra/Cassandra.lmm.rb +9 -19
  21. data/Plugins/Apps/ClickHouse/ClickHouse.container +28 -0
  22. data/Plugins/Apps/ClickHouse/ClickHouse.lmm.rb +113 -0
  23. data/Plugins/Apps/ClickHouse/Config/listen.yaml +2 -0
  24. data/Plugins/Apps/ClickHouse/Config/logger.yaml +8 -0
  25. data/Plugins/Apps/ClickHouse/Config/zookeepers.yaml +5 -0
  26. data/Plugins/Apps/ClickHouse/Connection.rb +96 -0
  27. data/Plugins/Apps/Discourse/Discourse-Sidekiq.container +22 -0
  28. data/Plugins/Apps/Discourse/Discourse.conf.erb +38 -0
  29. data/Plugins/Apps/Discourse/Discourse.container +21 -0
  30. data/Plugins/Apps/Discourse/Discourse.lmm.rb +156 -0
  31. data/Plugins/Apps/Dovecot/Dovecot.lmm.rb +87 -52
  32. data/Plugins/Apps/ERPNext/ERPNext-Frontend.container +24 -0
  33. data/Plugins/Apps/ERPNext/ERPNext-Queue.container +22 -0
  34. data/Plugins/Apps/ERPNext/ERPNext-Scheduler.container +22 -0
  35. data/Plugins/Apps/ERPNext/ERPNext-Websocket.container +24 -0
  36. data/Plugins/Apps/ERPNext/ERPNext.container +23 -0
  37. data/Plugins/Apps/ERPNext/ERPNext.lmm.rb +204 -0
  38. data/Plugins/Apps/ERPNext/ERPNext.network +12 -0
  39. data/Plugins/Apps/ERPNext/sites/apps.json +10 -0
  40. data/Plugins/Apps/ERPNext/sites/apps.txt +3 -0
  41. data/Plugins/Apps/ERPNext/sites/common_site_config.json +11 -0
  42. data/Plugins/Apps/GitLab/GitLab.container +9 -2
  43. data/Plugins/Apps/GitLab/GitLab.lmm.rb +52 -33
  44. data/Plugins/Apps/Homepage/Homepage.conf.erb +86 -0
  45. data/Plugins/Apps/Homepage/Homepage.container +19 -0
  46. data/Plugins/Apps/Homepage/Homepage.lmm.rb +54 -0
  47. data/Plugins/Apps/IPFS/IPFS.conf.erb +0 -3
  48. data/Plugins/Apps/IPFS/IPFS.lmm.rb +0 -1
  49. data/Plugins/Apps/InfluxDB/InfluxDB.conf.erb +0 -3
  50. data/Plugins/Apps/InfluxDB/InfluxDB.lmm.rb +0 -1
  51. data/Plugins/Apps/Jackett/Jackett.conf.erb +0 -3
  52. data/Plugins/Apps/Jackett/Jackett.lmm.rb +0 -1
  53. data/Plugins/Apps/Jellyfin/Jellyfin.conf.erb +0 -3
  54. data/Plugins/Apps/Jellyfin/Jellyfin.lmm.rb +0 -1
  55. data/Plugins/Apps/LetsEncrypt/LetsEncrypt.lmm.rb +78 -0
  56. data/Plugins/Apps/LetsEncrypt/hooks/dovecot.sh +2 -0
  57. data/Plugins/Apps/LetsEncrypt/hooks/nginx.sh +2 -0
  58. data/Plugins/Apps/LetsEncrypt/hooks/postfix.sh +2 -0
  59. data/Plugins/Apps/LetsEncrypt/renew-certificates.service +7 -0
  60. data/Plugins/Apps/LetsEncrypt/renew-certificates.timer +12 -0
  61. data/Plugins/Apps/LetsEncrypt/rfc2136.ini +11 -0
  62. data/Plugins/Apps/LibreTranslate/LibreTranslate.container +21 -0
  63. data/Plugins/Apps/LibreTranslate/LibreTranslate.lmm.rb +34 -0
  64. data/Plugins/Apps/Lobsters/Containerfile +81 -0
  65. data/Plugins/Apps/Lobsters/Lobsters-Tasks.container +26 -0
  66. data/Plugins/Apps/Lobsters/Lobsters.conf.erb +99 -0
  67. data/Plugins/Apps/Lobsters/Lobsters.container +27 -0
  68. data/Plugins/Apps/Lobsters/Lobsters.lmm.rb +196 -0
  69. data/Plugins/Apps/Lobsters/crontab +3 -0
  70. data/Plugins/Apps/Lobsters/database.yml +26 -0
  71. data/Plugins/Apps/Lobsters/entrypoint.sh +30 -0
  72. data/Plugins/Apps/Lobsters/generateCredentials.rb +19 -0
  73. data/Plugins/Apps/Lobsters/lobsters-cron.sh +25 -0
  74. data/Plugins/Apps/Lobsters/lobsters-daily.sh +23 -0
  75. data/Plugins/Apps/Lobsters/puma.rb +49 -0
  76. data/Plugins/Apps/MariaDB/Connection.rb +55 -0
  77. data/Plugins/Apps/MariaDB/MariaDB.lmm.rb +122 -0
  78. data/Plugins/Apps/Mastodon/Mastodon-Sidekiq.container +22 -0
  79. data/Plugins/Apps/Mastodon/Mastodon-Streaming.container +20 -0
  80. data/Plugins/Apps/Mastodon/Mastodon.conf.erb +34 -45
  81. data/Plugins/Apps/Mastodon/Mastodon.container +28 -0
  82. data/Plugins/Apps/Mastodon/Mastodon.lmm.rb +240 -5
  83. data/Plugins/Apps/Mastodon/configlmm.rake +30 -0
  84. data/Plugins/Apps/Mastodon/entrypoint.sh +16 -0
  85. data/Plugins/Apps/Matrix/Element.container +19 -0
  86. data/Plugins/Apps/Matrix/Matrix.conf.erb +47 -9
  87. data/Plugins/Apps/Matrix/Matrix.lmm.rb +119 -5
  88. data/Plugins/Apps/Matrix/Synapse.container +22 -0
  89. data/Plugins/Apps/Matrix/config.json +50 -0
  90. data/Plugins/Apps/Matrix/homeserver.yaml +70 -0
  91. data/Plugins/Apps/Matrix/log.config +30 -0
  92. data/Plugins/Apps/Netdata/Netdata.conf.erb +0 -3
  93. data/Plugins/Apps/Netdata/Netdata.lmm.rb +0 -1
  94. data/Plugins/Apps/Nextcloud/Nextcloud.conf.erb +3 -4
  95. data/Plugins/Apps/Nextcloud/Nextcloud.lmm.rb +155 -48
  96. data/Plugins/Apps/Nextcloud/autoconfig.php +13 -0
  97. data/Plugins/Apps/Nextcloud/config.php +10 -1
  98. data/Plugins/Apps/Nextcloud/nextcloudcron.service +8 -0
  99. data/Plugins/Apps/Nextcloud/nextcloudcron.timer +10 -0
  100. data/Plugins/Apps/Nginx/Connection.rb +93 -0
  101. data/Plugins/Apps/Nginx/conf.d/configlmm.conf +54 -4
  102. data/Plugins/Apps/Nginx/conf.d/languages.conf +21 -0
  103. data/Plugins/Apps/Nginx/config-lmm/errors.conf +33 -22
  104. data/Plugins/Apps/Nginx/config-lmm/gateway-errors.conf +20 -0
  105. data/Plugins/Apps/Nginx/config-lmm/proxy.conf +6 -2
  106. data/Plugins/Apps/Nginx/main.conf.erb +7 -3
  107. data/Plugins/Apps/Nginx/nginx.conf +2 -2
  108. data/Plugins/Apps/Nginx/nginx.lmm.rb +103 -81
  109. data/Plugins/Apps/Nginx/proxy.conf.erb +24 -6
  110. data/Plugins/Apps/Odoo/Odoo.conf.erb +0 -3
  111. data/Plugins/Apps/Odoo/Odoo.container +7 -1
  112. data/Plugins/Apps/Odoo/Odoo.lmm.rb +4 -5
  113. data/Plugins/Apps/Ollama/Ollama.container +26 -0
  114. data/Plugins/Apps/Ollama/Ollama.lmm.rb +73 -0
  115. data/Plugins/Apps/OpenTelemetry/Config/config.yaml +704 -0
  116. data/Plugins/Apps/OpenTelemetry/OpenTelemetry.lmm.rb +154 -0
  117. data/Plugins/Apps/OpenVidu/Ingress.container +23 -0
  118. data/Plugins/Apps/{GitLab/GitLab.conf.erb → OpenVidu/OpenVidu.conf.erb} +8 -3
  119. data/Plugins/Apps/OpenVidu/OpenVidu.container +21 -0
  120. data/Plugins/Apps/OpenVidu/OpenVidu.lmm.rb +94 -0
  121. data/Plugins/Apps/OpenVidu/OpenViduCall.conf.erb +32 -0
  122. data/Plugins/Apps/OpenVidu/OpenViduCall.container +20 -0
  123. data/Plugins/Apps/OpenVidu/ingress.yaml +10 -0
  124. data/Plugins/Apps/OpenVidu/livekit.yaml +13 -0
  125. data/Plugins/Apps/PHP-FPM/Connection.rb +91 -0
  126. data/Plugins/Apps/PHP-FPM/PHP-FPM.lmm.rb +31 -4
  127. data/Plugins/Apps/Peppermint/Peppermint.conf.erb +2 -9
  128. data/Plugins/Apps/Peppermint/Peppermint.container +7 -1
  129. data/Plugins/Apps/Peppermint/Peppermint.lmm.rb +29 -33
  130. data/Plugins/Apps/Perplexica/Perplexica.container +25 -0
  131. data/Plugins/Apps/Perplexica/Perplexica.lmm.rb +92 -0
  132. data/Plugins/Apps/Perplexica/config.toml +26 -0
  133. data/Plugins/Apps/Podman/Connection.rb +24 -0
  134. data/Plugins/Apps/Podman/Podman.lmm.rb +80 -0
  135. data/Plugins/Apps/Podman/storage.conf +6 -0
  136. data/Plugins/Apps/Postfix/Postfix.lmm.rb +249 -145
  137. data/Plugins/Apps/PostgreSQL/Connection.rb +97 -0
  138. data/Plugins/Apps/PostgreSQL/PostgreSQL.lmm.rb +204 -99
  139. data/Plugins/Apps/Pterodactyl/Pterodactyl.conf.erb +0 -3
  140. data/Plugins/Apps/Pterodactyl/Pterodactyl.lmm.rb +0 -2
  141. data/Plugins/Apps/Pterodactyl/Wings.conf.erb +0 -3
  142. data/Plugins/Apps/RVM/RVM.lmm.rb +57 -0
  143. data/Plugins/Apps/Roundcube/Roundcube.conf.erb +72 -0
  144. data/Plugins/Apps/Roundcube/Roundcube.lmm.rb +141 -0
  145. data/Plugins/Apps/SSH/SSH.lmm.rb +9 -15
  146. data/Plugins/Apps/SearXNG/SearXNG.container +22 -0
  147. data/Plugins/Apps/SearXNG/SearXNG.lmm.rb +79 -0
  148. data/Plugins/Apps/SearXNG/limiter.toml +40 -0
  149. data/Plugins/Apps/SearXNG/settings.yml +2 -0
  150. data/Plugins/Apps/SigNoz/Config/alerts.yml +11 -0
  151. data/Plugins/Apps/SigNoz/Config/otel-collector-config.yaml +110 -0
  152. data/Plugins/Apps/SigNoz/Config/otel-collector-opamp-config.yaml +1 -0
  153. data/Plugins/Apps/SigNoz/Config/prometheus.yml +18 -0
  154. data/Plugins/Apps/SigNoz/SigNoz-Collector.container +23 -0
  155. data/Plugins/Apps/SigNoz/SigNoz-Migrator.container +17 -0
  156. data/Plugins/Apps/SigNoz/SigNoz.conf.erb +61 -0
  157. data/Plugins/Apps/SigNoz/SigNoz.container +26 -0
  158. data/Plugins/Apps/SigNoz/SigNoz.lmm.rb +319 -0
  159. data/Plugins/Apps/Solr/log4j2.xml +89 -0
  160. data/Plugins/Apps/Solr/solr.lmm.rb +82 -0
  161. data/Plugins/Apps/Sunshine/Sunshine.conf.erb +0 -3
  162. data/Plugins/Apps/Sunshine/Sunshine.lmm.rb +0 -1
  163. data/Plugins/Apps/Tunnel/tunnel.lmm.rb +59 -0
  164. data/Plugins/Apps/Tunnel/tunnelTCP.service +9 -0
  165. data/Plugins/Apps/Tunnel/tunnelTCP.socket +9 -0
  166. data/Plugins/Apps/Tunnel/tunnelUDP.service +9 -0
  167. data/Plugins/Apps/Tunnel/tunnelUDP.socket +9 -0
  168. data/Plugins/Apps/UVdesk/UVdesk.conf.erb +0 -3
  169. data/Plugins/Apps/Umami/Umami.container +19 -0
  170. data/Plugins/Apps/Umami/Umami.lmm.rb +108 -0
  171. data/Plugins/Apps/Valkey/Valkey.lmm.rb +64 -20
  172. data/Plugins/Apps/Vaultwarden/Vaultwarden.conf.erb +9 -6
  173. data/Plugins/Apps/Vaultwarden/Vaultwarden.container +7 -1
  174. data/Plugins/Apps/Vaultwarden/Vaultwarden.lmm.rb +67 -28
  175. data/Plugins/Apps/Wiki.js/Wiki.js.conf.erb +39 -0
  176. data/Plugins/Apps/Wiki.js/Wiki.js.container +20 -0
  177. data/Plugins/Apps/Wiki.js/Wiki.js.lmm.rb +55 -0
  178. data/Plugins/Apps/YaCy/YaCy.conf.erb +93 -0
  179. data/Plugins/Apps/YaCy/YaCy.container +21 -0
  180. data/Plugins/Apps/YaCy/YaCy.lmm.rb +160 -0
  181. data/Plugins/Apps/ZooKeeper/ZooKeeper.container +24 -0
  182. data/Plugins/Apps/ZooKeeper/ZooKeeper.lmm.rb +68 -0
  183. data/Plugins/Apps/bitmagnet/bitmagnet.conf.erb +0 -3
  184. data/Plugins/Apps/bitmagnet/bitmagnet.lmm.rb +0 -1
  185. data/Plugins/Apps/gollum/gollum.conf.erb +40 -4
  186. data/Plugins/Apps/gollum/gollum.container +10 -1
  187. data/Plugins/Apps/gollum/gollum.lmm.rb +56 -47
  188. data/Plugins/Apps/llama.cpp/llama.cpp.container +28 -0
  189. data/Plugins/Apps/llama.cpp/llama.cpp.lmm.rb +90 -0
  190. data/Plugins/Apps/vLLM/vLLM.container +32 -0
  191. data/Plugins/Apps/vLLM/vLLM.lmm.rb +89 -0
  192. data/Plugins/OS/General/Utils.lmm.rb +26 -0
  193. data/Plugins/OS/Linux/Connection.rb +472 -0
  194. data/Plugins/OS/Linux/Debian/preseed.cfg.erb +81 -0
  195. data/Plugins/OS/Linux/Distributions.yaml +32 -0
  196. data/Plugins/OS/Linux/Flavours.yaml +24 -0
  197. data/Plugins/OS/Linux/Grub/grub.cfg +10 -0
  198. data/Plugins/OS/Linux/HTTP.rb +32 -0
  199. data/Plugins/OS/Linux/Linux.lmm.rb +708 -174
  200. data/Plugins/OS/Linux/Packages.yaml +67 -3
  201. data/Plugins/OS/Linux/Proxmox/answer.toml.erb +30 -0
  202. data/Plugins/OS/Linux/Services.yaml +8 -0
  203. data/Plugins/OS/Linux/Shell.rb +70 -0
  204. data/Plugins/OS/Linux/Syslinux/default +8 -0
  205. data/Plugins/OS/Linux/WireGuard/WireGuard.lmm.rb +93 -40
  206. data/Plugins/OS/Linux/WireGuard/wg0.conf.erb +3 -0
  207. data/Plugins/OS/Linux/openSUSE/autoinst.xml.erb +29 -3
  208. data/Plugins/OS/Linux/systemd/systemd.lmm.rb +13 -11
  209. data/Plugins/OS/Routers/Aruba/ArubaInstant.lmm.rb +6 -5
  210. data/Plugins/Platforms/GitHub.lmm.rb +73 -28
  211. data/Plugins/Platforms/GoDaddy/GoDaddy.lmm.rb +10 -7
  212. data/Plugins/Platforms/Proxmox/Proxmox.lmm.rb +402 -0
  213. data/Plugins/Platforms/Proxmox/XTerm.rb +321 -0
  214. data/Plugins/Platforms/libvirt/libvirt.lmm.rb +41 -15
  215. data/Plugins/Platforms/porkbun.lmm.rb +12 -2
  216. data/Plugins/Platforms/porkbun_spec.rb +2 -2
  217. data/Plugins/Services/DNS/AmberBit.lmm.rb +1 -1
  218. data/Plugins/Services/DNS/ArubaItDNS.lmm.rb +1 -1
  219. data/Plugins/Services/DNS/NICLV.lmm.rb +1 -1
  220. data/Plugins/Services/DNS/PowerDNS.lmm.rb +130 -41
  221. data/Plugins/Services/DNS/tonic.lmm.rb +22 -12
  222. data/bootstrap.sh +41 -3
  223. data/lib/ConfigLMM/Framework/plugins/dns.rb +4 -3
  224. data/lib/ConfigLMM/Framework/plugins/linuxApp.rb +187 -144
  225. data/lib/ConfigLMM/Framework/plugins/nginxApp.rb +54 -6
  226. data/lib/ConfigLMM/Framework/plugins/plugin.rb +68 -140
  227. data/lib/ConfigLMM/Framework/plugins/store.rb +4 -4
  228. data/lib/ConfigLMM/Framework/variables.rb +75 -0
  229. data/lib/ConfigLMM/Framework.rb +1 -0
  230. data/lib/ConfigLMM/cli.rb +13 -5
  231. data/lib/ConfigLMM/commands/cleanup.rb +1 -0
  232. data/lib/ConfigLMM/commands/configsCommand.rb +38 -5
  233. data/lib/ConfigLMM/commands/diff.rb +33 -9
  234. data/lib/ConfigLMM/context.rb +22 -3
  235. data/lib/ConfigLMM/io/configList.rb +85 -7
  236. data/lib/ConfigLMM/io/connection.rb +143 -0
  237. data/lib/ConfigLMM/io/dhcp.rb +330 -0
  238. data/lib/ConfigLMM/io/http.rb +78 -0
  239. data/lib/ConfigLMM/io/local.rb +207 -0
  240. data/lib/ConfigLMM/io/pxe.rb +92 -0
  241. data/lib/ConfigLMM/io/ssh.rb +156 -0
  242. data/lib/ConfigLMM/io/tftp.rb +105 -0
  243. data/lib/ConfigLMM/io.rb +2 -0
  244. data/lib/ConfigLMM/secrets/envStore.rb +39 -0
  245. data/lib/ConfigLMM/secrets/fileStore.rb +43 -0
  246. data/lib/ConfigLMM/state.rb +12 -3
  247. data/lib/ConfigLMM/version.rb +2 -1
  248. data/lib/ConfigLMM.rb +1 -0
  249. data/{Examples → scripts}/configlmmAuth.sh +7 -5
  250. metadata +257 -9
@@ -0,0 +1,122 @@
1
+ require_relative '../../OS/Linux/Linux.lmm.rb'
2
+ require_relative 'Connection'
3
+
4
+ module ConfigLMM
5
+ module LMM
6
+ class MariaDB < Framework::LinuxApp
7
+ PACKAGE_NAME = 'MariaDB'
8
+ SERVICE_NAME = :mariadb
9
+ USER_NAME = 'mariadb'
10
+
11
+ def actionMariaDBDeploy(id, target, activeState, context, options)
12
+ self.withConnection(target['Location'], target) do |connection|
13
+ Linux.withConnection(connection) do |linuxConnection|
14
+ linuxConnection.ensurePackage(PACKAGE_NAME, options)
15
+ linuxConnection.ensureServiceAutoStart(SERVICE_NAME, options)
16
+ linuxConnection.startService(SERVICE_NAME, options)
17
+
18
+ self.class.secureInstallation(connection)
19
+ linuxConnection.exec("sed -i 's|^log-error |#log-error |' /etc/my.cnf", false, options)
20
+ if target['Listen']
21
+ linuxConnection.exec("sed -i 's|bind-address .*|bind-address = #{target['Listen']}|' /etc/my.cnf", false, options)
22
+ linuxConnection.restartService(SERVICE_NAME, options)
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ def cleanup(configs, state, context, options)
29
+ cleanupType(:MariaDB, configs, state, context, options) do |item, id, state, context, options, connection|
30
+ Linux.withConnection(connection) do |linuxConnection|
31
+ linuxConnection.stopService(SERVICE_NAME, options)
32
+ linuxConnection.disableService(SERVICE_NAME, options)
33
+ linuxConnection.removePackage(PACKAGE_NAME, options)
34
+ end
35
+ state.item(id)['Status'] = State::STATUS_DELETED unless options[:dry]
36
+ end
37
+ end
38
+
39
+ def self.secureInstallation(connection)
40
+ status = {}
41
+ output = ''
42
+ # TODO: FIXME to work with non-ssh connection aswell
43
+ channel = connection.tunnel.ssh.exec("mariadb-secure-installation", status: status) do |channel, stream, data|
44
+ output += data
45
+ channel.send_data("\n") # Empty root password
46
+ channel.send_data("Y\n") # unix_socket authentication
47
+ channel.send_data("N\n") # change the root password
48
+ channel.send_data("Y\n") # remove anonymous users
49
+ channel.send_data("Y\n") # disallow root login remotely
50
+ channel.send_data("Y\n") # remove test database
51
+ channel.send_data("Y\n") # reload privileges
52
+ end
53
+ channel.wait
54
+ if !status[:exit_code].zero?
55
+ $stderr.puts(output)
56
+ raise Framework::PluginProcessError.new("mariadb-secure-installation failed!")
57
+ end
58
+ end
59
+
60
+ # DEPRECATED
61
+ def self.createRemoteUserAndDB(settings, user, password, ssh = nil)
62
+ self.executeRemotely(settings, ssh) do |connection|
63
+ host = 'localhost'
64
+ host = '%' if settings['HostName'] != 'localhost'
65
+ self.createUserAndDB(user, password, host, connection)
66
+ end
67
+ end
68
+
69
+ def self.withConnection(settings, linuxConnection)
70
+ if settings['HostName'].nil? || settings['HostName'] == 'localhost'
71
+ settings['HostName'] = 'localhost'
72
+ yield(MariaDBConnection.new(linuxConnection, settings))
73
+ else
74
+ IO::Connection.tunnel("ssh://#{settings['HostName']}/", {}, {}, linuxConnection.prompt, linuxConnection.logger) do |connection|
75
+ yield(MariaDBConnection.new(connection, settings))
76
+ end
77
+ end
78
+ end
79
+
80
+ # DEPRECATED
81
+ def self.executeRemotely(settings, connectionOrSSH = nil)
82
+ prompt = TTY::Prompt.new
83
+ logger = TTY::Logger.new
84
+ settings['HostName'] = 'localhost' unless settings['HostName']
85
+ if settings['HostName'] == 'localhost'
86
+ connection = connectionOrSSH
87
+ if connectionOrSSH.nil?
88
+ connection = IO::Connection.new(:Local, IO::Local.new(prompt, logger), prompt, logger)
89
+ elsif !connectionOrSSH.is_a?(IO::Connection)
90
+ connection = IO::Connection.new(:SSH, SSH.new(prompt, logger, connectionOrSSH), prompt, logger)
91
+ end
92
+ yield(connection)
93
+ else
94
+ self.sshStart("ssh://#{settings['HostName']}/") do |ssh|
95
+ yield(IO::Connection.new(:SSH, SSH.new(prompt, logger, ssh), prompt, logger))
96
+ end
97
+ end
98
+ end
99
+
100
+ # DEPRECATED
101
+ def self.createUserAndDB(user, password, host, connectionOrSSH = nil)
102
+ self.executeSQL("CREATE USER '#{user}'@'#{host}'", nil, connectionOrSSH, true)
103
+ self.executeSQL("ALTER USER '#{user}'@'#{host}' IDENTIFIED BY '#{password}'", nil, connectionOrSSH)
104
+ self.executeSQL("CREATE DATABASE #{user}", nil, connectionOrSSH, true)
105
+ self.executeSQL("GRANT ALL PRIVILEGES ON #{user}.* TO '#{user}'@'#{host}'", nil, connectionOrSSH)
106
+ end
107
+
108
+ # DEPRECATED
109
+ def self.executeSQL(sql, db = nil, connectionOrSSH = nil, allowFailure = false, dry = false)
110
+ db = '' unless db
111
+ cmd = " mariadb #{db} --execute=\"#{sql.gsub('"', '\\"')};\""
112
+ if connectionOrSSH.is_a?(IO::Connection)
113
+ connectionOrSSH.exec(cmd, allowFailure, dry)
114
+ else
115
+ self.exec(cmd, connectionOrSSH, allowFailure, dry)
116
+ end
117
+ end
118
+
119
+ end
120
+
121
+ end
122
+ end
@@ -0,0 +1,22 @@
1
+
2
+ [Unit]
3
+ Description=Mastodon Sidekiq container
4
+ After=local-fs.target
5
+
6
+ [Container]
7
+ ContainerName=Mastodon-Sidekiq
8
+ Image=ghcr.io/mastodon/mastodon:latest
9
+ Exec=bundle exec sidekiq
10
+ EnvironmentFile=/var/lib/mastodon/.config/containers/systemd/Mastodon.env
11
+ Network=slirp4netns:allow_host_loopback=true
12
+ UserNS=keep-id:uid=991,gid=991
13
+ Volume=/var/lib/mastodon/system:/mastodon/public/system
14
+ LogDriver=journald
15
+ AutoUpdate=registry
16
+
17
+ [Service]
18
+ TimeoutStartSec=6min
19
+ Restart=on-failure
20
+
21
+ [Install]
22
+ WantedBy=multi-user.target default.target
@@ -0,0 +1,20 @@
1
+
2
+ [Unit]
3
+ Description=Mastodon Streaming container
4
+ After=local-fs.target
5
+
6
+ [Container]
7
+ ContainerName=Mastodon-Streaming
8
+ Image=ghcr.io/mastodon/mastodon-streaming:latest
9
+ EnvironmentFile=/var/lib/mastodon/.config/containers/systemd/Mastodon.env
10
+ Network=slirp4netns:allow_host_loopback=true
11
+ PublishPort=127.0.0.1:14000:4000
12
+ LogDriver=journald
13
+ AutoUpdate=registry
14
+
15
+ [Service]
16
+ TimeoutStartSec=6min
17
+ Restart=on-failure
18
+
19
+ [Install]
20
+ WantedBy=multi-user.target default.target
@@ -1,6 +1,6 @@
1
1
 
2
2
  upstream mastodon {
3
- server unix:///run/mastodon.sock fail_timeout=0;
3
+ server <%= config['Server'] %>:13600 fail_timeout=0;
4
4
  }
5
5
 
6
6
  upstream mastodon-streaming {
@@ -8,70 +8,59 @@ upstream mastodon-streaming {
8
8
  # to ensure load is distributed evenly.
9
9
  least_conn;
10
10
 
11
- server 127.0.0.1:4000 fail_timeout=0;
11
+ server <%= config['Server'] %>:14000 fail_timeout=0;
12
12
  # Uncomment these lines for load-balancing multiple instances of streaming for scaling,
13
- # this assumes your running the streaming server on ports 4000, 4001, and 4002:
14
- # server 127.0.0.1:4001 fail_timeout=0;
15
- # server 127.0.0.1:4002 fail_timeout=0;
13
+ # this assumes your running the streaming server on ports 14000, 14001, and 14002:
14
+ # server <%= config['Server'] %>:14001 fail_timeout=0;
15
+ # server <%= config['Server'] %>:14002 fail_timeout=0;
16
16
  }
17
17
 
18
- # proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=CACHE:10m inactive=7d max_size=1g;
19
-
20
18
  server {
21
- <% if !config['TLS'] %>
22
- listen <%= config['Port'] %>;
23
- listen [::]:<%= config['Port'] %>;
24
- <% else %>
25
- listen <%= config['Port'] %> ssl;
26
- listen [::]:<%= config['Port'] %> ssl;
19
+
20
+ <% if config['NginxVersion'] >= 1.25 %>
21
+ <% if !config['TLS'] %>
22
+ listen <%= config['Port'] %>;
23
+ listen [::]:<%= config['Port'] %>;
24
+ <% else %>
25
+ listen <%= config['Port'] %> ssl;
26
+ listen [::]:<%= config['Port'] %> ssl;
27
+
28
+ include config-lmm/ssl.conf;
29
+ <% end %>
27
30
  http2 on;
28
- include config-lmm/ssl.conf;
31
+ http3 on;
32
+ quic_retry on;
33
+ add_header Alt-Svc 'h3=":443"; ma=86400';
34
+ <% else %>
35
+ <% if !config['TLS'] %>
36
+ listen <%= config['Port'] %>;
37
+ listen [::]:<%= config['Port'] %>;
38
+ <% else %>
39
+ listen <%= config['Port'] %> ssl http2;
40
+ listen [::]:<%= config['Port'] %> ssl http2;
41
+
42
+ include config-lmm/ssl.conf;
43
+ <% end %>
29
44
  <% end %>
30
45
 
31
46
  server_name <%= config['Domain'] %>;
32
47
 
33
- access_log /var/log/nginx/mastodon.access.log;
34
- error_log /var/log/nginx/mastodon.error.log;
48
+ <% if config['CertName'] %>
49
+ ssl_certificate "/etc/letsencrypt/live/<%= config['CertName'] %>/fullchain.pem";
50
+ ssl_certificate_key "/etc/letsencrypt/live/<%= config['CertName'] %>/privkey.pem";
51
+ ssl_trusted_certificate "/etc/letsencrypt/live/<%= config['CertName'] %>/chain.pem";
52
+ <% end %>
35
53
 
36
54
  client_max_body_size 99M;
37
55
 
38
56
  include config-lmm/errors.conf;
39
57
 
40
- # proxy_redirect off;
41
- # proxy_cache CACHE;
42
- # proxy_cache_valid 200 7d;
43
- # proxy_cache_valid 410 24h;
44
- # proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
45
- # add_header X-Cached $upstream_cache_status;
46
-
47
- root /var/lib/mastodon/public;
48
-
49
58
  location / {
50
- try_files $uri @mastodon;
51
- }
52
-
53
- location @mastodon {
54
59
  proxy_pass http://mastodon;
55
60
  include config-lmm/proxy.conf;
56
61
  }
57
62
 
58
- location ~ ^/assets|avatars|emoji|headers|packs|shortcuts|sounds/ {
59
-
60
- add_header Cache-Control "public, max-age=2419200, must-revalidate";
61
- add_header Strict-Transport-Security "max-age=63072000; includeSubDomains";
62
- try_files $uri =404;
63
- }
64
-
65
- location ~ ^/system/ {
66
- add_header Cache-Control "public, max-age=2419200, immutable";
67
- add_header Strict-Transport-Security "max-age=63072000; includeSubDomains";
68
- #add_header X-Content-Type-Options nosniff;
69
- add_header Content-Security-Policy "default-src 'none'; form-action 'none'";
70
- try_files $uri =404;
71
- }
72
-
73
63
  location ^~ /api/v1/streaming {
74
-
75
64
  proxy_buffering off;
76
65
  proxy_cache off;
77
66
  proxy_pass http://mastodon-streaming;
@@ -0,0 +1,28 @@
1
+
2
+ [Unit]
3
+ Description=Mastodon container
4
+ After=local-fs.target
5
+
6
+ [Container]
7
+ ContainerName=Mastodon
8
+ Image=ghcr.io/mastodon/mastodon:latest
9
+ # Need newer Podman
10
+ # Entrypoint=/entrypoint.sh
11
+ PodmanArgs=--entrypoint /entrypoint.sh
12
+ Exec=server
13
+ EnvironmentFile=/var/lib/mastodon/.config/containers/systemd/Mastodon.env
14
+ Network=slirp4netns:allow_host_loopback=true
15
+ PublishPort=127.0.0.1:13600:3000
16
+ UserNS=keep-id:uid=991,gid=991
17
+ Volume=/var/lib/mastodon/system:/mastodon/public/system
18
+ Volume=/var/lib/mastodon/.configlmm/entrypoint.sh:/entrypoint.sh
19
+ Volume=/var/lib/mastodon/.configlmm/configlmm.rake:/mastodon/lib/tasks/configlmm.rake
20
+ LogDriver=journald
21
+ AutoUpdate=registry
22
+
23
+ [Service]
24
+ TimeoutStartSec=6min
25
+ Restart=on-failure
26
+
27
+ [Install]
28
+ WantedBy=multi-user.target default.target
@@ -1,10 +1,22 @@
1
1
 
2
+ require 'base64'
3
+ require 'openssl'
4
+ require 'public_suffix'
5
+
2
6
  module ConfigLMM
3
7
  module LMM
4
- class Mastodon < Framework::NginxApp
8
+ class Mastodon < Framework::Plugin
9
+
10
+ NAME = 'Mastodon'
11
+ USER = 'mastodon'
12
+ HOME_DIR = '/var/lib/mastodon'
13
+ PORT = '13600'
14
+ STREAMING_PORT = '14000'
5
15
 
6
16
  def actionMastodonBuild(id, target, state, context, options)
7
- writeNginxConfig(__dir__, 'Mastodon', id, target, state, context, options)
17
+ Nginx.withConnection(local) do |nginxConnection|
18
+ nginxConnection.writeConfig(__dir__, NAME, target, state, context, options)
19
+ end
8
20
  end
9
21
 
10
22
  def actionMastodonDiff(id, target, activeState, context, options)
@@ -12,9 +24,232 @@ module ConfigLMM
12
24
  end
13
25
 
14
26
  def actionMastodonDeploy(id, target, activeState, context, options)
15
- if !target['Location'] || target['Location'] == '@me'
16
- deployNginxConfig(id, target, activeState, context, options)
17
- activeState['Location'] = '@me'
27
+ raise Framework::PluginProcessError.new('Domain field must be set!') unless target['Domain']
28
+
29
+ self.withConnection(target['Location'], target) do |connection|
30
+ Linux.withConnection(connection) do |linuxConnection|
31
+ if !target.key?('Proxy') || target['Proxy'] == false
32
+ deployService(linuxConnection, target, activeState, context, options)
33
+ end
34
+
35
+ deployNginxConfig(linuxConnection, target, activeState, context, options)
36
+ end
37
+ end
38
+ end
39
+
40
+ def deployService(linuxConnection, target, activeState, context, options)
41
+ target['Database'] ||= {}
42
+ dbPassword = self.configurePostgreSQL(target['Database'], linuxConnection, options)
43
+
44
+ Podman.ensurePresent(linuxConnection, options)
45
+ Podman.createUser(USER, HOME_DIR, 'Mastodon', linuxConnection, options)
46
+ linuxConnection.withUserShell(USER) do |shell|
47
+ shell.createDirs(options, '~/system', '~/.configlmm')
48
+ end
49
+
50
+ path = Podman.containersPath(HOME_DIR)
51
+
52
+ localDomain = PublicSuffix.domain(target['Domain'])
53
+ raise Framework::PluginProcessError.new('Invalid Domain!') unless localDomain
54
+
55
+ localDomain = target['LocalDomain'] if target['LocalDomain']
56
+ linuxConnection.fileWrite("#{path}/Mastodon.env", "LOCAL_DOMAIN=#{Addressable::IDNA.to_ascii(localDomain)}", options)
57
+
58
+ webDomain = nil
59
+ if localDomain != target['Domain']
60
+ webDomain = target['Domain']
61
+ end
62
+ linuxConnection.fileAppend("#{path}/Mastodon.env", "WEB_DOMAIN=#{Addressable::IDNA.to_ascii(webDomain)}", options) if webDomain
63
+
64
+ secretKeyBase = context.secrets.load(target['SecretId'], 'SECRET_KEY_BASE')
65
+ if !secretKeyBase
66
+ secretKeyBase = SecureRandom.hex(64)
67
+ context.secrets.store(target['SecretId'], 'SECRET_KEY_BASE', secretKeyBase) unless options['dry']
68
+ end
69
+ linuxConnection.fileAppend("#{path}/Mastodon.env", "SECRET_KEY_BASE=#{secretKeyBase}", { **options, hide: true })
70
+
71
+ otpSecret = context.secrets.load(target['SecretId'], 'OTP_SECRET')
72
+ if !otpSecret
73
+ otpSecret = SecureRandom.hex(64)
74
+ context.secrets.store(target['SecretId'], 'OTP_SECRET', otpSecret) unless options['dry']
75
+ end
76
+ linuxConnection.fileAppend("#{path}/Mastodon.env", "OTP_SECRET=#{otpSecret}", { **options, hide: true })
77
+
78
+ deterministicKey = context.secrets.load(target['SecretId'], 'ENCRYPTION_DETERMINISTIC_KEY')
79
+ if !deterministicKey
80
+ deterministicKey = SecureRandom.alphanumeric(32)
81
+ context.secrets.store(target['SecretId'], 'ENCRYPTION_DETERMINISTIC_KEY', deterministicKey) unless options['dry']
82
+ end
83
+
84
+ keySalt = context.secrets.load(target['SecretId'], 'KEY_DERIVATION_SALT')
85
+ if !keySalt
86
+ keySalt = SecureRandom.alphanumeric(32)
87
+ context.secrets.store(target['SecretId'], 'KEY_DERIVATION_SALT', keySalt) unless options['dry']
88
+ end
89
+
90
+ primaryKey = context.secrets.load(target['SecretId'], 'ENCRYPTION_PRIMARY_KEY')
91
+ if !primaryKey
92
+ primaryKey = SecureRandom.alphanumeric(32)
93
+ context.secrets.store(target['SecretId'], 'ENCRYPTION_PRIMARY_KEY', primaryKey) unless options['dry']
94
+ end
95
+
96
+ linuxConnection.fileAppend("#{path}/Mastodon.env", "ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY=#{deterministicKey}", { **options, hide: true })
97
+ linuxConnection.fileAppend("#{path}/Mastodon.env", "ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT=#{keySalt}", { **options, hide: true })
98
+ linuxConnection.fileAppend("#{path}/Mastodon.env", "ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY=#{primaryKey}", { **options, hide: true })
99
+
100
+ vapidPrivateKey = context.secrets.load(target['SecretId'], 'VAPID_PRIVATE_KEY')
101
+ vapidPublicKey = context.secrets.load(target['SecretId'], 'VAPID_PUBLIC_KEY')
102
+ if !vapidPrivateKey || !vapidPublicKey
103
+ curve = OpenSSL::PKey::EC.generate('prime256v1')
104
+ vapidPrivateKey = Base64.urlsafe_encode64(curve.public_key.to_bn.to_s(2))
105
+ vapidPublicKey = Base64.urlsafe_encode64(curve.private_key.to_s(2))
106
+ context.secrets.store(target['SecretId'], 'VAPID_PRIVATE_KEY', vapidPrivateKey) unless options['dry']
107
+ context.secrets.store(target['SecretId'], 'VAPID_PUBLIC_KEY', vapidPublicKey) unless options['dry']
108
+ end
109
+
110
+ linuxConnection.fileAppend("#{path}/Mastodon.env", "VAPID_PRIVATE_KEY=#{vapidPrivateKey}", { **options, hide: true })
111
+ linuxConnection.fileAppend("#{path}/Mastodon.env", "VAPID_PUBLIC_KEY=#{vapidPublicKey}", { **options, hide: true })
112
+
113
+ databaseHost = Podman.updateHost(target['Database'].to_h['HostName'])
114
+ linuxConnection.fileAppend("#{path}/Mastodon.env", "DB_HOST=#{databaseHost}", options)
115
+ linuxConnection.fileAppend("#{path}/Mastodon.env", "DB_PORT=#{target['Database']['Port']}", options) if target['Database'].to_h['Port']
116
+ linuxConnection.fileAppend("#{path}/Mastodon.env", "DB_USER=#{USER}", options)
117
+ linuxConnection.fileAppend("#{path}/Mastodon.env", "DB_NAME=#{USER}", options)
118
+ linuxConnection.fileAppend("#{path}/Mastodon.env", "DB_PASS=#{dbPassword}", { **options, hide: true })
119
+
120
+ valkeyHost = Podman.updateHost(target['Valkey'].to_h['Host'])
121
+ linuxConnection.fileAppend("#{path}/Mastodon.env", "REDIS_HOST=#{valkeyHost}", options)
122
+ if target['Valkey'].to_h['SecretId']
123
+ valkeyPassword = context.secrets.load(target['Valkey']['SecretId'], 'VALKEY_PASSWORD')
124
+ if !valkeyPassword.nil?
125
+ linuxConnection.fileAppend("#{path}/Mastodon.env", "REDIS_PASSWORD=#{valkeyPassword}", { **options, hide: true })
126
+ end
127
+ end
128
+
129
+ if target['Admin'].to_h['Username']
130
+ linuxConnection.fileAppend("#{path}/Mastodon.env", "ADMIN_USERNAME=#{target['Admin']['Username']}", options)
131
+ end
132
+
133
+ if target['Admin'].to_h['EMail']
134
+ adminPassword = context.secrets.load(target['SecretId'], 'ADMIN_PASSWORD')
135
+ if adminPassword.nil?
136
+ adminPassword = SecureRandom.alphanumeric(20)
137
+ context.secrets.store(target['SecretId'], 'ADMIN_PASSWORD', adminPassword)
138
+ context.secrets.print("Mastodon Admin '#{target['Admin']['EMail']}' password", adminPassword)
139
+ end
140
+ linuxConnection.fileAppend("#{path}/Mastodon.env", "ADMIN_EMAIL=#{target['Admin']['EMail']}", options)
141
+ linuxConnection.fileAppend("#{path}/Mastodon.env", "ADMIN_PASSWORD=#{adminPassword}", options)
142
+ end
143
+
144
+ if !target['SMTP'].to_h.empty?
145
+ emailHost = Podman.updateHost(target['SMTP']['Host'])
146
+
147
+ linuxConnection.fileAppend("#{path}/Mastodon.env", "SMTP_SERVER=#{emailHost}", options)
148
+
149
+ if target['SMTP']['Port']
150
+ linuxConnection.fileAppend("#{path}/Mastodon.env", "SMTP_PORT=#{target['SMTP']['Port']}", options)
151
+ end
152
+
153
+ if target['SMTP']['Username']
154
+ linuxConnection.fileAppend("#{path}/Mastodon.env", "SMTP_LOGIN=#{target['SMTP']['Username']}", options)
155
+ end
156
+
157
+ if target['SMTP']['SecretId']
158
+ smtpPassword = context.secrets.load(target['SMTP']['SecretId'], target['SMTP']['Username'].upcase + '_PASSWORD')
159
+ linuxConnection.fileAppend("#{path}/Mastodon.env", "SMTP_PASSWORD=#{smtpPassword}", { **options, hide: true })
160
+ end
161
+
162
+ if target['SMTP']['Port'] == 465
163
+ linuxConnection.fileAppend("#{path}/Mastodon.env", "SMTP_TLS=true", options)
164
+ end
165
+
166
+ if target['SMTP']['From']
167
+ linuxConnection.fileAppend("#{path}/Mastodon.env", "SMTP_FROM_ADDRESS=#{target['SMTP']['From']}", options)
168
+ end
169
+ end
170
+
171
+ if !target['Settings'].to_h.empty?
172
+ target['Settings'].each do |name, value|
173
+ linuxConnection.fileAppend("#{path}/Mastodon.env", "#{name}=#{value}", options)
174
+ end
175
+ end
176
+
177
+ linuxConnection.setUserGroup("#{path}/Mastodon.env", USER, USER, options)
178
+ linuxConnection.setPrivate("#{path}/Mastodon.env", options)
179
+
180
+ linuxConnection.upload(__dir__ + '/configlmm.rake', HOME_DIR + '/.configlmm/', options)
181
+ linuxConnection.upload(__dir__ + '/entrypoint.sh', HOME_DIR + '/.configlmm/', options)
182
+ linuxConnection.makeExecutable(HOME_DIR + '/.configlmm/entrypoint.sh', options)
183
+
184
+ linuxConnection.upload(__dir__ + '/Mastodon.container', path, options)
185
+ linuxConnection.upload(__dir__ + '/Mastodon-Sidekiq.container', path, options)
186
+ linuxConnection.upload(__dir__ + '/Mastodon-Streaming.container', path, options)
187
+
188
+ if target['Proxy'] == false
189
+ linuxConnection.fileReplace("#{path}/Mastodon.container", 'PublishPort=127.0.0.1:', 'PublishPort=0.0.0.0:', options)
190
+ linuxConnection.fileReplace("#{path}/Mastodon-Streaming.container", 'PublishPort=127.0.0.1:', 'PublishPort=0.0.0.0:', options)
191
+ linuxConnection.firewallAddPort("#{PORT}/tcp", options)
192
+ linuxConnection.firewallAddPort("#{STREAMING_PORT}/tcp", options)
193
+ end
194
+
195
+ linuxConnection.reloadUserServices(USER, options)
196
+ linuxConnection.restartUserService(USER, 'Mastodon', options)
197
+ linuxConnection.restartUserService(USER, 'Mastodon-Sidekiq', options)
198
+ linuxConnection.restartUserService(USER, 'Mastodon-Streaming', options)
199
+ end
200
+
201
+ def deployNginxConfig(linuxConnection, target, activeState, context, options)
202
+ if !target.key?('Proxy') || target['Proxy']
203
+ Nginx.withConnection(linuxConnection) do |nginxConnection|
204
+ target['Server'] = '127.0.0.1' unless target['Server']
205
+ nginxConnection.provision(__dir__, 'Mastodon', target, activeState, context, options)
206
+ end
207
+ end
208
+ end
209
+
210
+ def configurePostgreSQL(dbSettings, linuxConnection, options)
211
+ password = SecureRandom.alphanumeric(20)
212
+ PostgreSQL.withConnection(dbSettings, linuxConnection) do |postgresConnection|
213
+ postgresConnection.createUserAndDB(USER, password, options)
214
+ end
215
+ password
216
+ end
217
+
218
+ def cleanup(configs, state, context, options)
219
+ cleanupType(:Mastodon, configs, state, context, options) do |item, id, state, context, options, connection|
220
+ Linux.withConnection(connection) do |linuxConnection|
221
+
222
+ if !item['Config'].key?('Proxy') || item['Config']['Proxy']
223
+ Nginx.withConnection(linuxConnection) do |nginxConnection|
224
+ nginxConnection.cleanupConfig('Mastodon', context, options)
225
+ nginxConnection.reload(options)
226
+ end
227
+ elsif item['Config'].key?('Proxy') && item['Config']['Proxy'] == false
228
+ linuxConnection.firewallRemovePort("#{PORT}/tcp", options)
229
+ linuxConnection.firewallRemovePort("#{STREAMING_PORT}/tcp", options)
230
+ end
231
+
232
+ if !item['Config'].key?('Proxy') || item['Config']['Proxy'] == false
233
+ linuxConnection.stopUserService(USER, 'Mastodon-Sidekiq', options)
234
+ linuxConnection.stopUserService(USER, 'Mastodon-Streaming', options)
235
+ linuxConnection.stopUserService(USER, 'Mastodon', options)
236
+
237
+ path = Podman.containersPath(HOME_DIR)
238
+ linuxConnection.rm(path + '/Mastodon.container', options[:dry])
239
+ linuxConnection.rm(path + '/Mastodon-Streaming.container', options[:dry])
240
+ linuxConnection.rm(path + '/Mastodon-Sidekiq.container', options[:dry])
241
+
242
+ state.item(id)['Status'] = State::STATUS_DELETED unless options[:dry]
243
+
244
+ if options[:destroy]
245
+ linuxConnection.deleteUserAndGroup(USER, options)
246
+ linuxConnection.rm(HOME_DIR, options[:dry])
247
+ state.item(id)['Status'] = State::STATUS_DESTROYED unless options[:dry]
248
+ end
249
+ else
250
+ state.item(id)['Status'] = options[:destroy] ? State::STATUS_DESTROYED : State::STATUS_DELETED unless options[:dry]
251
+ end
252
+ end
18
253
  end
19
254
  end
20
255
 
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Based on https://github.com/mastodon/mastodon/blob/main/lib/tasks/mastodon.rake#L7
4
+
5
+ namespace :configlmm do
6
+ desc 'Configure the instance for production use'
7
+ task :setup do
8
+ username = 'admin'
9
+ username = ENV['ADMIN_USERNAME'] if ENV['ADMIN_USERNAME']
10
+ emailLocal, emailDomain = ENV['ADMIN_EMAIL'].to_s.split('@')
11
+ password = ENV['ADMIN_PASSWORD']
12
+
13
+ if !emailLocal.to_s.empty? && !emailDomain.to_s.empty? && !password.to_s.empty?
14
+ require_relative '../../config/environment'
15
+ require 'addressable/idna'
16
+
17
+ email = emailLocal + '@' + Addressable::IDNA.to_ascii(emailDomain)
18
+ user = User.where('LOWER(email) = ?', email.downcase).first
19
+ account = Account.where('LOWER(username) = ?', username.downcase).first
20
+ if !user && !account
21
+ owner_role = UserRole.find_by(name: 'Owner')
22
+ user = User.new(email: email, password: password, confirmed_at: Time.now.utc, account_attributes: { username: username }, bypass_invite_request_check: true, role: owner_role)
23
+ user.save(validate: false)
24
+ user.approve!
25
+
26
+ Setting.site_contact_username = username
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/sh
2
+
3
+ set -o errexit
4
+ set -o nounset
5
+
6
+ cmd="/usr/bin/tini"
7
+
8
+ if [ $# -gt 0 ] && [ "$1" = "server" ]; then
9
+ bin/rails db:prepare
10
+ bin/rails configlmm:setup
11
+ unset ADMIN_PASSWORD
12
+
13
+ exec $cmd -- bundle exec puma -C config/puma.rb
14
+ else
15
+ exec $cmd -- "$@"
16
+ fi
@@ -0,0 +1,19 @@
1
+
2
+ [Unit]
3
+ Description=Matrix (Element) container
4
+ After=local-fs.target
5
+
6
+ [Container]
7
+ ContainerName=Element
8
+ Image=docker.io/vectorim/element-web:latest
9
+ EnvironmentFile=/var/lib/matrix/.config/containers/systemd/Matrix.env
10
+ PublishPort=127.0.0.1:18300:80
11
+ Volume=/var/lib/matrix/config.json:/app/config.json
12
+ LogDriver=journald
13
+ AutoUpdate=registry
14
+
15
+ [Service]
16
+ Restart=on-failure
17
+
18
+ [Install]
19
+ WantedBy=multi-user.target default.target