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
@@ -1,76 +1,138 @@
1
1
 
2
2
  require_relative '../../OS/Linux/Linux.lmm.rb'
3
+ require_relative 'Connection'
3
4
 
4
5
  module ConfigLMM
5
6
  module LMM
6
7
  class PostgreSQL < Framework::LinuxApp
7
8
  PACKAGE_NAME = 'PostgreSQL'
8
- SERVICE_NAME = 'postgresql'
9
+ SERVICE_NAME = :postgresql
9
10
  USER_NAME = 'postgres'
11
+ PORT = '5432'
10
12
 
11
13
  HBA_FILE = 'data/pg_hba.conf'
12
14
  CONFIG_FILE = 'data/postgresql.conf'
13
15
 
14
16
  def actionPostgreSQLDeploy(id, target, activeState, context, options)
15
- self.ensurePackage(PACKAGE_NAME, target['Location'])
16
- self.ensureServiceAutoStart(SERVICE_NAME, target['Location'])
17
- self.startService(SERVICE_NAME, target['Location'])
18
-
19
- if target['Location'] && target['Location'] != '@me'
20
- uri = Addressable::URI.parse(target['Location'])
21
- raise Framework::PluginProcessError.new("#{id}: Unknown Protocol: #{uri.scheme}!") if uri.scheme != 'ssh'
22
-
23
- self.class.sshStart(uri) do |ssh|
24
- self.updateSettingsOverSSH(target, ssh, options)
25
- self.class.sshExec!(ssh, "su --login #{USER_NAME} --command 'pg_ctl reload'")
26
- self.class.createUsersOverSSH(target, ssh)
27
- self.class.createDatabasesOverSSH(target, ssh)
28
- self.class.createPublicationsOverSSH(target, ssh)
29
- self.class.createSubscriptionsOverSSH(target, ssh)
17
+ target['Deploy'] = !!(target['ListenAll'] || target['Listen'] || target['Settings']) unless target.key?('Deploy')
18
+
19
+ withConnection(target['Location'], target) do |connection|
20
+ Linux.withConnection(connection) do |linuxConnection|
21
+ self.class.withConnection({}, linuxConnection) do |postgres|
22
+ if target['Deploy']
23
+ linuxConnection.ensurePackage(PACKAGE_NAME, options)
24
+ linuxConnection.ensureServiceAutoStart(SERVICE_NAME, options)
25
+
26
+ # So that OpenTelemetry can read logs
27
+ linuxConnection.createDirs(options, '/var/log/postgresql')
28
+ linuxConnection.exec("chown postgres:postgres /var/log/postgresql", false, options)
29
+ linuxConnection.exec("chmod 750 /var/log/postgresql", false, options)
30
+
31
+ replicate(target, linuxConnection, postgres, context, options)
32
+ linuxConnection.startService(SERVICE_NAME, options)
33
+
34
+ updateSettings(target, linuxConnection, postgres, options)
35
+
36
+ if activeState['Status'] == State::STATUS_DEPLOYED
37
+ linuxConnection.withUserShell(USER_NAME) do |shellConnection|
38
+ shellConnection.exec("pg_ctl reload -D #{postgres.pgsqlDir}data", false, options)
39
+ end
40
+ else
41
+ # Restart only on first deploy
42
+ linuxConnection.restartService(SERVICE_NAME, options)
43
+ end
44
+ end
45
+
46
+ createUsers(target, postgres, context, options)
47
+ createDatabases(target, postgres, context, options)
48
+ createPublications(target, postgres, context, options)
49
+ createSubscriptions(target, postgres, context, options)
50
+ end
30
51
  end
31
- else
32
- `pg_ctl reload`
33
52
  end
53
+ end
54
+
55
+ def cleanup(configs, state, context, options)
56
+ cleanupType(:PostgreSQL, configs, state, context, options) do |item, id, state, context, options, connection|
57
+ withConnection(item['Config']['Location'], item['Config']) do |connection|
58
+ Linux.withConnection(connection) do |linuxConnection|
59
+ if item['Deploy']
60
+ linuxConnection.stopService(SERVICE_NAME, options)
61
+ linuxConnection.disableService(SERVICE_NAME, options)
62
+ linuxConnection.removePackage(PACKAGE_NAME, options)
63
+
64
+ state.item(id)['Status'] = State::STATUS_DELETED unless options[:dry]
34
65
 
66
+ if options[:destroy]
67
+ linuxConnection.deleteUserAndGroup(USER_NAME, options)
68
+
69
+ state.item(id)['Status'] = State::STATUS_DESTROYED unless options[:dry]
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
35
75
  end
36
76
 
37
- def updateListenLocal(target)
38
- dir = pgsqlDir(self.class.distroID)
39
- if target['ListenAll']
40
- `sed -i 's|^host all all 127.0.0.1/32 ident|host all all 0.0.0.0/0 scram-sha-256|' #{dir + HBA_FILE}`
41
- updateLocalFile(dir + CONFIG_FILE, options) do |configLines|
42
- configLines << "listen_addresses = '*'\n"
77
+ def replicate(target, linuxConnection, postgres, context, options)
78
+ if target['Replicate']
79
+ if !linuxConnection.filePresent?(postgres.pgsqlDir + "data")
80
+ linuxConnection.withUserShell(USER_NAME) do |shellConnection|
81
+ connection = Framework::Variables.stringEval(target['Replicate']['Connection'], context)
82
+ extra = ''
83
+ if target['Replicate']['Slot']
84
+ extra = "--create-slot --slot=#{target['Replicate']['Slot'].downcase}"
85
+ end
86
+ shellConnection.exec("pg_basebackup --dbname=#{connection.shellescape} --write-recovery-conf #{extra} --pgdata #{postgres.pgsqlDir}data", false, options)
87
+ end
43
88
  end
44
- else
45
- `sed -i 's|^host all all 127.0.0.1/32 ident|host all all 127.0.0.1/32 scram-sha-256|' #{dir + HBA_FILE}`
46
89
  end
47
90
  end
48
91
 
49
- def updateSettingsOverSSH(target, ssh, options)
50
- dir = nil
92
+ def updateSettings(target, linuxConnection, postgres, options)
51
93
  settingLines = []
52
94
  hbaLines = []
53
95
  if target['ListenAll']
54
96
  cmd = "sed -i 's|^host all all 127.0.0.1/32 ident|host all all 0.0.0.0/0 scram-sha-256|'"
55
- dir = updateConfigOverSSH(ssh, cmd)
97
+ postgres.connection.exec(cmd + ' ' + postgres.pgsqlDir + HBA_FILE, false, options)
56
98
  settingLines << "listen_addresses = '*'\n"
57
- Framework::LinuxApp.firewallAddPortOverSSH('5432/tcp', ssh)
99
+ postgres.connection.firewallAddPort('5432/tcp', options)
58
100
  elsif target['Listen'] && !target['Listen'].empty?
59
101
  cmd = "sed -i 's|^host all all 127.0.0.1/32 ident|host all all 127.0.0.1/32 scram-sha-256|'"
60
- dir = updateConfigOverSSH(ssh, cmd)
102
+ postgres.connection.exec(cmd + ' ' + postgres.pgsqlDir + HBA_FILE, false, options)
61
103
 
62
104
  ips = target['Listen'].map { |addr| addr.split('/').first }.join(',')
63
105
  settingLines << "listen_addresses = '#{ips}'\n"
64
106
 
65
107
  target['Listen'].each do |addr|
66
108
  if addr != 'localhost' && !addr.start_with?('127.0.0.1') && !addr.start_with?('::1')
109
+ addr += '/0' if addr == '0.0.0.0'
110
+ addr += '/32' if addr =~ /^\d+\.\d+\.\d+\.\d+$/
67
111
  hbaLines << "host all all #{addr} scram-sha-256\n"
68
112
  end
69
113
  end
70
114
  else
71
115
  cmd = "sed -i 's|^host all all 127.0.0.1/32 ident|host all all 127.0.0.1/32 scram-sha-256|'"
72
- dir = updateConfigOverSSH(ssh, cmd)
116
+ postgres.connection.exec(cmd + ' ' + postgres.pgsqlDir + HBA_FILE, false, options)
73
117
  end
118
+ if target['AllowReplication']
119
+ addresses = target['AllowReplication']
120
+ addresses = [addresses] unless addresses.is_a?(Array)
121
+ addresses.each do |addr|
122
+ addr += '/0' if addr == '0.0.0.0'
123
+ addr += '/32' if addr =~ /^\d+\.\d+\.\d+\.\d+$/
124
+ hbaLines << "host replication all #{addr} scram-sha-256\n"
125
+ end
126
+ end
127
+ postgres.connection.exec('sed -i "s|^log_destination|#log_destination|" ' + postgres.pgsqlDir + CONFIG_FILE, false, options)
128
+ postgres.connection.exec('sed -i "s|^logging_collector|#logging_collector|" ' + postgres.pgsqlDir + CONFIG_FILE, false, options)
129
+ postgres.connection.exec('sed -i "s|^log_directory|#log_directory|" ' + postgres.pgsqlDir + CONFIG_FILE, false, options)
130
+ postgres.connection.exec('sed -i "s|^log_file_mode|#log_file_mode|" ' + postgres.pgsqlDir + CONFIG_FILE, false, options)
131
+ settingLines << "log_destination = 'jsonlog'\n"
132
+ settingLines << "logging_collector = on\n"
133
+ settingLines << "log_directory = '/var/log/postgresql'\n"
134
+ settingLines << "log_file_mode = 0640\n"
135
+
74
136
  #if !target['Publications'].to_h.empty?
75
137
  # target['Settings'] ||= {}
76
138
  # target['Settings']['wal_level'] = 'logical'
@@ -79,41 +141,39 @@ module ConfigLMM
79
141
  settingLines << "#{name} = #{value}\n"
80
142
  end
81
143
  if !hbaLines.empty?
82
- updateRemoteFile(ssh, dir + HBA_FILE, options, false) do |configLines|
144
+ postgres.connection.updateFile(postgres.pgsqlDir + HBA_FILE, options, false) do |configLines|
83
145
  configLines += hbaLines
84
146
  end
85
147
  end
86
148
  if !settingLines.empty?
87
- updateRemoteFile(ssh, dir + CONFIG_FILE, options, false) do |configLines|
149
+ postgres.connection.updateFile(postgres.pgsqlDir + CONFIG_FILE, options, false) do |configLines|
88
150
  configLines += settingLines
89
151
  end
90
152
  end
91
153
  end
92
154
 
93
- def self.createUsersOverSSH(target, ssh)
155
+ def createUsers(target, postgres, context, options)
94
156
  target['Users'].to_a.each do |user, info|
95
- self.sshExec!(ssh, "su --login #{USER_NAME} --command 'createuser #{user}'", true)
96
- if !info['Password'].to_s.empty?
97
- password = self.loadVariable(info['Password'], target).to_s
98
- if !password.empty?
99
- sql = "ALTER USER #{user} WITH PASSWORD '#{password}'"
100
- self.executeSQL(sql, nil, ssh)
101
- end
157
+ password = info['Password'].to_s
158
+ if !password.empty?
159
+ password = Framework::Variables.parse(info['Password'], context).to_s
102
160
  end
103
- if info['Replication'] && info['Replication'] != 'no'
104
- self.executeSQL("ALTER USER #{user} REPLICATION", nil, ssh)
105
- self.executeSQL("GRANT pg_read_all_data TO #{user}", nil, ssh)
161
+ postgres.createUser(user, password, options)
162
+
163
+ if info['Replication']
164
+ postgres.grantReplication(user)
106
165
  end
107
166
  end
108
167
  end
109
168
 
110
- def self.createDatabasesOverSSH(target, ssh)
169
+ def createDatabases(target, postgres, context, options)
111
170
  target['Databases'].to_a.each do |db, info|
112
- self.sshExec!(ssh, "su --login #{USER_NAME} --command 'createdb #{db}'", true)
171
+ owner = info['Owner'] ? info['Owner'] : nil
172
+ postgres.createDB(db, owner, options)
113
173
  end
114
174
  end
115
175
 
116
- def self.createPublicationsOverSSH(target, ssh)
176
+ def createPublications(target, postgres, context, options)
117
177
  return if target['Publications'].to_h.empty?
118
178
 
119
179
  target['Publications'].each do |name, data|
@@ -122,104 +182,149 @@ module ConfigLMM
122
182
  # TODO
123
183
  elsif data['Tables'] == 'All'
124
184
  sql = "CREATE PUBLICATION #{name} FOR ALL TABLES"
125
- self.executeSQL(sql, data['Database'], ssh, true)
185
+ postgres.exec(sql, data['Database'], true, [], options)
126
186
  else
127
187
  raise "Invalid Tables field: #{data['Tables']}"
128
188
  end
129
189
  end
130
190
  end
131
191
 
132
- def self.createSubscriptionsOverSSH(target, ssh)
192
+ def createSubscriptions(target, postgres, context, options)
133
193
  return if target['Subscriptions'].to_h.empty?
134
194
 
135
195
  target['Subscriptions'].each do |name, data|
136
196
  data['Database'] = name unless data['Database']
137
197
  data['Publication'] = name unless data['Publication']
138
- connection = self.loadVariable(data['Connection'], target).to_s
198
+ connection = Framework::Variables.stringEval(data['Connection'], context)
139
199
 
140
200
  authParams = '--host=' + connection.match('host=([^ ]+)')[1]
141
201
  authParams += ' --username=' + connection.match('user=([^ ]+)')[1]
142
202
  password = connection.match('password=([^ ]+)')[1]
143
203
 
144
- self.importRemoteSchemaOverSSH(name, data['Database'], password, authParams, ssh)
204
+ importRemoteSchema(name, data['Database'], password, authParams, postgres, options)
145
205
 
146
206
  sql = "CREATE SUBSCRIPTION #{name} CONNECTION '#{connection}' PUBLICATION #{data['Publication']}"
147
- self.executeSQL(sql, data['Database'], ssh, true)
207
+ message = postgres.exec(sql, data['Database'], true, [], options)
208
+ # 'ERROR: subscription "$NAME" already exists' - is fine
209
+ # but other errors aren't like ERROR: could not create replication slot "$NAME": ERROR: replication slot "$NAME" already exists
210
+ if message.include?('ERROR') && !(message.include?('subscription') && message.include?('already exists'))
211
+ raise message
212
+ end
148
213
  end
149
214
  end
150
215
 
151
- def self.importRemoteSchemaOverSSH(sourceDB, targetDB, password, authParams, ssh)
152
- self.sshExec!(ssh, "su --login #{USER_NAME} --command 'createdb #{targetDB}'", true)
153
- cmd = " su --login #{USER_NAME} --command 'PGPASSWORD=#{password} pg_dump --schema-only --no-owner --dbname=#{sourceDB} #{authParams} | psql --dbname=#{targetDB}'"
154
- self.sshExec!(ssh, cmd)
216
+ def importRemoteSchema(sourceDB, targetDB, password, authParams, postgres, options)
217
+ postgres.createDB(targetDB, nil, options)
218
+ postgres.connection.exec(" PGPASSWORD=#{password} pg_dump --schema-only --no-owner --dbname=#{sourceDB} #{authParams} | psql --dbname=#{targetDB}", false, { **options, hide: true })
155
219
  end
156
220
 
157
- def updateConfigOverSSH(ssh, cmd)
158
- dir = ''
159
- distroID = self.class.distroID(ssh)
160
- dir = pgsqlDir(distroID)
161
- self.class.sshExec!(ssh, cmd + ' ' + dir + HBA_FILE)
162
- dir
221
+ def self.defaults(settings)
222
+ settings['HostName'] = 'localhost' unless settings['HostName']
223
+ settings['Port'] = PORT unless settings['Port']
163
224
  end
164
225
 
226
+ def self.withConnection(settings, linuxConnection)
227
+ if settings.nil? || settings['HostName'].nil? || settings['HostName'] == 'localhost' || settings['HostName'].start_with?('/')
228
+ settings ||= {}
229
+ settings = settings.dup
230
+ settings.delete('HostName')
231
+ settings.delete('Port')
232
+ linuxConnection.withUserShell(USER_NAME) do |shellConnection|
233
+ yield(PostgreSQLConnection.new(shellConnection, settings))
234
+ end
235
+ else
236
+ IO::Connection.tunnel("ssh://#{settings['HostName']}/", {}, {}, linuxConnection.prompt, linuxConnection.logger) do |connection|
237
+ Linux.withConnection(connection) do |linuxConnection|
238
+ linuxConnection.withUserShell(USER_NAME) do |shellConnection|
239
+ yield(PostgreSQLConnection.new(shellConnection, settings))
240
+ end
241
+ end
242
+ end
243
+ end
244
+ end
245
+
246
+ # DEPRECATED
247
+ def self.createRemoteUserAndDB(settings, user, password, connection)
248
+ self.executeRemotely(settings, connection) do |connection|
249
+ self.createUserAndDB(user, password, connection)
250
+ end
251
+ end
252
+
253
+ # DEPRECATED
165
254
  def self.createRemoteUserAndDBOverSSH(settings, user, password, ssh)
166
- self.executeRemotelyOverSSH(settings, ssh) do |ssh|
167
- self.createUserAndDBOverSSH(user, password, ssh)
255
+ self.executeRemotely(settings, ssh) do |connection|
256
+ self.createUserAndDBOverSSH(user, password, connection)
257
+ end
258
+ end
259
+
260
+ # DEPRECATED
261
+ def self.dropUserAndDB(settings, user, connection, dry)
262
+ self.executeRemotely(settings, connection) do |connection|
263
+ connection.exec("su --login #{USER_NAME} --command 'dropdb #{user}'", true, dry)
264
+ connection.exec("su --login #{USER_NAME} --command 'dropuser #{user}'", true, dry)
265
+ end
266
+ end
267
+
268
+ # DEPRECATED
269
+ def self.createExtensions(settings, db, extensions, connectionOrSSH)
270
+ self.executeRemotely(settings, ssh) do |connection|
271
+ extensions.each do |extension|
272
+ self.executeSQL("CREATE EXTENSION #{extension}", db, connection, true)
168
273
  end
274
+ end
169
275
  end
170
276
 
171
- def self.executeRemotelyOverSSH(settings, ssh)
172
- settings['HostName'] = 'localhost' unless settings['HostName']
277
+ # DEPRECATED
278
+ def self.executeRemotely(settings, connectionOrSSH = nil)
279
+ prompt = TTY::Prompt.new
280
+ logger = TTY::Logger.new
281
+ self.defaults(settings)
173
282
  if settings['HostName'] == 'localhost'
174
- yield(ssh)
283
+ connection = connectionOrSSH
284
+ if connectionOrSSH.nil?
285
+ connection = IO::Connection.new(:Local, IO::Local.new(prompt, logger), prompt, logger)
286
+ elsif !connectionOrSSH.is_a?(IO::Connection)
287
+ connection = IO::Connection.new(:SSH, IO::SSH.new(prompt, logger, connectionOrSSH), prompt, logger)
288
+ end
289
+ yield(connection)
175
290
  else
176
291
  self.sshStart("ssh://#{settings['HostName']}/") do |ssh|
177
- yield(ssh)
292
+ yield(IO::Connection.new(:SSH, IO::SSH.new(prompt, logger, ssh), prompt, logger))
178
293
  end
179
294
  end
180
295
  end
181
296
 
182
- def self.createUserAndDBOverSSH(user, password, ssh)
183
- self.sshExec!(ssh, "su --login #{USER_NAME} --command 'createuser #{user}'", true)
184
- self.sshExec!(ssh, "su --login #{USER_NAME} --command 'createdb --owner=#{user} #{user}'", true)
185
- if password
186
- sql = "ALTER USER #{user} WITH PASSWORD '#{password}'"
187
- self.executeSQL(sql, nil, ssh)
188
- end
297
+ # DEPRECATED
298
+ def self.createUserAndDB(user, password, connection)
299
+ self.createUserAndDBOverSSH(user, password, connection)
189
300
  end
190
301
 
191
- def self.importSQL(owner, db, sqlFile, ssh = nil)
192
- if ssh
193
- self.sshExec!(ssh, "echo \"SET ROLE '#{owner}';\" > /tmp/postgres_import.sql")
194
- self.sshExec!(ssh, "cat #{sqlFile} >> /tmp/postgres_import.sql")
195
- cmd = "su --login #{USER_NAME} --command 'psql #{db} < /tmp/postgres_import.sql'"
196
- self.sshExec!(ssh, cmd)
302
+ # DEPRECATED
303
+ def self.createUserAndDBOverSSH(user, password, connectionOrSSH)
304
+ if connectionOrSSH.is_a?(IO::Connection)
305
+ connectionOrSSH.exec("su --login #{USER_NAME} --command 'createuser #{user}'", true)
306
+ connectionOrSSH.exec("su --login #{USER_NAME} --command 'createdb --locale=C --template=template0 --owner=#{user} #{user}'", true)
197
307
  else
198
- # TODO
308
+ self.sshExec!(connectionOrSSH, "su --login #{USER_NAME} --command 'createuser #{user}'", true)
309
+ self.sshExec!(connectionOrSSH, "su --login #{USER_NAME} --command 'createdb --locale=C --template=template0 --owner=#{user} #{user}'", true)
199
310
  end
200
- end
201
-
202
- def self.executeSQL(sql, db, ssh = nil, allowFailure = false)
203
- if ssh
204
- db = 'postgres' unless db
205
- cmd = " su --login #{USER_NAME} --command ' psql --dbname=#{db} --command=\"#{sql.gsub("'", "\\\\'")};\"'"
206
- self.sshExec!(ssh, cmd, allowFailure)
207
- else
208
- # TODO
311
+ if password
312
+ sql = "ALTER USER #{user} WITH PASSWORD '#{password}'"
313
+ self.executeSQL(sql, nil, connectionOrSSH)
209
314
  end
210
315
  end
211
316
 
212
- def pgsqlDir(distroID)
213
- if distroID == 'opensuse-leap'
214
- '/var/lib/pgsql/'
215
- elsif distroID == 'arch'
216
- '/var/lib/postgres/'
317
+ # DEPRECATED
318
+ def self.executeSQL(sql, db, connectionOrSSH = nil, allowFailure = false, options = [], dry = false)
319
+ db = 'postgres' unless db
320
+ cmd = " su --login #{USER_NAME} --command ' psql #{options.join(' ')} --dbname=#{db} --command=\"#{sql.gsub("'", "'\"'\"'")};\"'"
321
+ if connectionOrSSH.is_a?(IO::Connection)
322
+ connectionOrSSH.exec(cmd, allowFailure, dry)
217
323
  else
218
- raise Framework::PluginProcessError.new("Unknown Linux Distro: #{distroID}!")
324
+ self.exec(cmd, connectionOrSSH, allowFailure, dry)
219
325
  end
220
326
  end
221
327
 
222
328
  end
223
-
224
329
  end
225
330
  end
@@ -14,9 +14,6 @@ server {
14
14
 
15
15
  server_name <%= config['Domain'] %>;
16
16
 
17
- access_log /var/log/nginx/pterodactyl.access.log;
18
- error_log /var/log/nginx/pterodactyl.error.log;
19
-
20
17
  include config-lmm/private.conf;
21
18
  include config-lmm/errors.conf;
22
19
 
@@ -10,7 +10,6 @@ module ConfigLMM
10
10
  def actionPterodactylDeploy(id, target, activeState, context, options)
11
11
  if !target['Location'] || target['Location'] == '@me'
12
12
  deployNginxConfig(id, target, activeState, context, options)
13
- activeState['Location'] = '@me'
14
13
  end
15
14
  end
16
15
 
@@ -21,7 +20,6 @@ module ConfigLMM
21
20
  def actionWingsDeploy(id, target, activeState, context, options)
22
21
  if !target['Location'] || target['Location'] == '@me'
23
22
  deployNginxConfig(id, target, activeState, context, options)
24
- activeState['Location'] = '@me'
25
23
  end
26
24
  end
27
25
  end
@@ -17,9 +17,6 @@ server {
17
17
 
18
18
  server_name <%= config['Domain'] %>;
19
19
 
20
- access_log /var/log/nginx/wings.access.log;
21
- error_log /var/log/nginx/wings.error.log;
22
-
23
20
  include config-lmm/private.conf;
24
21
  include config-lmm/errors.conf;
25
22
 
@@ -0,0 +1,57 @@
1
+
2
+ module ConfigLMM
3
+ module LMM
4
+ class RVM < Framework::Plugin
5
+
6
+ LATEST_RUBY_VERSION = '3.4.1'
7
+
8
+ def actionRVMDeploy(id, target, activeState, context, options)
9
+ self.withConnection(target['Location'], target) do |connection|
10
+ Linux.withConnection(connection) do |linuxConnection|
11
+ installPackages(linuxConnection, target, options)
12
+ installRVM(linuxConnection, true, target, options)
13
+ if target['User']
14
+ linuxConnection.exec("usermod --append --groups rvm #{target['User']}")
15
+ end
16
+ installGems(linuxConnection, target, options)
17
+ end
18
+ end
19
+ end
20
+
21
+ def installPackages(connection, target, options)
22
+ packages = target['Packages'].to_a
23
+ if !packages.empty?
24
+ connection.ensurePackages(packages, options)
25
+ end
26
+ end
27
+
28
+ def installRVM(connection, installDeps, target, options)
29
+ if !connection.hasBinaries?('rvm', options)
30
+ # Needs dirmngr
31
+ # connection.exec('gpg2 --keyserver hkp://keyserver.ubuntu.com --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB', false, options)
32
+
33
+ connection.exec('curl -sSL https://rvm.io/mpapis.asc | gpg --import -', false, options)
34
+ connection.exec('curl -sSL https://rvm.io/pkuczynski.asc | gpg --import -', false, options)
35
+ extra = ''
36
+ if !installDeps
37
+ extra = ' --autolibs=read-fail'
38
+ end
39
+ connection.exec("curl --silent --show-error --location https://get.rvm.io | bash -s stable --ruby=#{LATEST_RUBY_VERSION}#{extra}", false, options)
40
+ installFishFunction(connection, target, options)
41
+ end
42
+ end
43
+
44
+ def installFishFunction(connection, target, options)
45
+ connection.exec('curl --silent --show-error --location --create-dirs --output /etc/fish/conf.d/rvm.fish https://raw.github.com/lunks/fish-nuggets/master/functions/rvm.fish', false, options)
46
+ connection.fileAppend("/etc/fish/conf.d/rvm.fish", 'rvm default', options)
47
+ end
48
+
49
+ def installGems(connection, target, options)
50
+ gems = target['Gems'].to_a.join(' ')
51
+ if !gems.empty?
52
+ connection.exec("gem install #{gems}", false, options)
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,72 @@
1
+
2
+ upstream roundcube
3
+ {
4
+ <% if config['Server'] %>
5
+ server <%= config['Server'] %>;
6
+ <% else %>
7
+ server unix:/run/php-fpm/roundcube.sock;
8
+ <% end %>
9
+ }
10
+
11
+ server
12
+ {
13
+ <% if !config['TLS'] %>
14
+ listen <%= config['Port'] %>;
15
+ listen [::]:<%= config['Port'] %>;
16
+ <% else %>
17
+ <% if config['NginxVersion'] >= 1.25 %>
18
+ listen <%= config['Port'] %> ssl;
19
+ listen [::]:<%= config['Port'] %> ssl;
20
+ http2 on;
21
+ http3 on;
22
+ quic_retry on;
23
+ add_header Alt-Svc 'h3=":<%= config['Port'] %>"; ma=86400';
24
+ <% else %>
25
+ listen <%= config['Port'] %> ssl http2;
26
+ listen [::]:<%= config['Port'] %> ssl http2;
27
+ <% end %>
28
+
29
+ include config-lmm/ssl.conf;
30
+ <% end %>
31
+
32
+ server_name <%= config['Domain'] %>;
33
+
34
+ index index.php;
35
+ root /usr/share/webapps/roundcubemail;
36
+
37
+ include config-lmm/private.conf;
38
+ include config-lmm/errors.conf;
39
+
40
+ location / {
41
+ try_files $uri $uri/ $uri/index.php;
42
+ }
43
+
44
+ location ~ \.php$
45
+ {
46
+ fastcgi_pass roundcube;
47
+ include fastcgi.conf;
48
+
49
+ try_files $uri =404;
50
+ fastcgi_index index.php;
51
+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
52
+ include fastcgi_params;
53
+
54
+ fastcgi_intercept_errors off;
55
+ }
56
+
57
+ location ~ ^/(README|INSTALL|LICENSE|CHANGELOG|UPGRADING)$
58
+ {
59
+ deny all;
60
+ }
61
+
62
+ location ~ ^/(bin|SQL)/
63
+ {
64
+ deny all;
65
+ }
66
+
67
+ location ~* \.(jpg|jpeg|gif|png|webp|svg|woff|woff2|ttf|css|js|ico|xml)$
68
+ {
69
+ access_log off;
70
+ expires 360d;
71
+ }
72
+ }