ConfigLMM 0.4.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +34 -0
- data/CNAME +1 -0
- data/Examples/.lmm.state.yaml +159 -0
- data/Examples/ConfigLMM.mm.yaml +32 -0
- data/Examples/Implemented.mm.yaml +252 -4
- data/Examples/SmallBusiness.mm.yaml +492 -0
- data/Plugins/Apps/Answer/answer.lmm.rb +165 -0
- data/Plugins/Apps/Answer/answer@.service +40 -0
- data/Plugins/Apps/ArchiSteamFarm/ArchiSteamFarm.conf.erb +0 -3
- data/Plugins/Apps/ArchiSteamFarm/ArchiSteamFarm.lmm.rb +0 -1
- data/Plugins/Apps/Authentik/Authentik-ProxyOutpost.container +7 -1
- data/Plugins/Apps/Authentik/Authentik-Server.container +6 -1
- data/Plugins/Apps/Authentik/Authentik-Worker.container +6 -1
- data/Plugins/Apps/Authentik/Authentik.conf.erb +12 -7
- data/Plugins/Apps/Authentik/Authentik.lmm.rb +226 -61
- data/Plugins/Apps/BookStack/BookStack.conf.erb +0 -3
- data/Plugins/Apps/BookStack/BookStack.container +5 -0
- data/Plugins/Apps/BookStack/BookStack.lmm.rb +14 -3
- data/Plugins/Apps/Cassandra/Cassandra.lmm.rb +9 -19
- data/Plugins/Apps/ClickHouse/ClickHouse.container +28 -0
- data/Plugins/Apps/ClickHouse/ClickHouse.lmm.rb +113 -0
- data/Plugins/Apps/ClickHouse/Config/listen.yaml +2 -0
- data/Plugins/Apps/ClickHouse/Config/logger.yaml +8 -0
- data/Plugins/Apps/ClickHouse/Config/zookeepers.yaml +5 -0
- data/Plugins/Apps/ClickHouse/Connection.rb +96 -0
- data/Plugins/Apps/Discourse/Discourse-Sidekiq.container +5 -0
- data/Plugins/Apps/Discourse/Discourse.conf.erb +1 -4
- data/Plugins/Apps/Discourse/Discourse.container +4 -0
- data/Plugins/Apps/Discourse/Discourse.lmm.rb +116 -55
- data/Plugins/Apps/Dovecot/Dovecot.lmm.rb +74 -62
- data/Plugins/Apps/ERPNext/ERPNext-Frontend.container +6 -1
- data/Plugins/Apps/ERPNext/ERPNext-Queue.container +5 -0
- data/Plugins/Apps/ERPNext/ERPNext-Scheduler.container +5 -0
- data/Plugins/Apps/ERPNext/ERPNext-Websocket.container +6 -1
- data/Plugins/Apps/ERPNext/ERPNext.container +6 -1
- data/Plugins/Apps/ERPNext/ERPNext.lmm.rb +138 -127
- data/Plugins/Apps/GitLab/GitLab.container +6 -0
- data/Plugins/Apps/GitLab/GitLab.lmm.rb +43 -49
- data/Plugins/Apps/Homepage/Homepage.conf.erb +86 -0
- data/Plugins/Apps/Homepage/Homepage.container +19 -0
- data/Plugins/Apps/Homepage/Homepage.lmm.rb +54 -0
- data/Plugins/Apps/IPFS/IPFS.conf.erb +0 -3
- data/Plugins/Apps/IPFS/IPFS.lmm.rb +0 -1
- data/Plugins/Apps/InfluxDB/InfluxDB.conf.erb +0 -3
- data/Plugins/Apps/InfluxDB/InfluxDB.lmm.rb +0 -1
- data/Plugins/Apps/Jackett/Jackett.conf.erb +0 -3
- data/Plugins/Apps/Jackett/Jackett.lmm.rb +0 -1
- data/Plugins/Apps/Jellyfin/Jellyfin.conf.erb +0 -3
- data/Plugins/Apps/Jellyfin/Jellyfin.lmm.rb +0 -1
- data/Plugins/Apps/LetsEncrypt/LetsEncrypt.lmm.rb +49 -28
- data/Plugins/Apps/LibreTranslate/LibreTranslate.container +21 -0
- data/Plugins/Apps/LibreTranslate/LibreTranslate.lmm.rb +34 -0
- data/Plugins/Apps/Lobsters/Containerfile +81 -0
- data/Plugins/Apps/Lobsters/Lobsters-Tasks.container +26 -0
- data/Plugins/Apps/Lobsters/Lobsters.conf.erb +99 -0
- data/Plugins/Apps/Lobsters/Lobsters.container +27 -0
- data/Plugins/Apps/Lobsters/Lobsters.lmm.rb +196 -0
- data/Plugins/Apps/Lobsters/crontab +3 -0
- data/Plugins/Apps/Lobsters/database.yml +26 -0
- data/Plugins/Apps/Lobsters/entrypoint.sh +30 -0
- data/Plugins/Apps/Lobsters/generateCredentials.rb +19 -0
- data/Plugins/Apps/Lobsters/lobsters-cron.sh +25 -0
- data/Plugins/Apps/Lobsters/lobsters-daily.sh +23 -0
- data/Plugins/Apps/Lobsters/puma.rb +49 -0
- data/Plugins/Apps/MariaDB/Connection.rb +55 -0
- data/Plugins/Apps/MariaDB/MariaDB.lmm.rb +60 -53
- data/Plugins/Apps/Mastodon/Mastodon-Sidekiq.container +22 -0
- data/Plugins/Apps/Mastodon/Mastodon-Streaming.container +20 -0
- data/Plugins/Apps/Mastodon/Mastodon.conf.erb +34 -45
- data/Plugins/Apps/Mastodon/Mastodon.container +28 -0
- data/Plugins/Apps/Mastodon/Mastodon.lmm.rb +240 -5
- data/Plugins/Apps/Mastodon/configlmm.rake +30 -0
- data/Plugins/Apps/Mastodon/entrypoint.sh +16 -0
- data/Plugins/Apps/Matrix/Element.container +5 -0
- data/Plugins/Apps/Matrix/Matrix.conf.erb +2 -8
- data/Plugins/Apps/Matrix/Matrix.lmm.rb +100 -71
- data/Plugins/Apps/Matrix/Synapse.container +5 -0
- data/Plugins/Apps/Netdata/Netdata.conf.erb +0 -3
- data/Plugins/Apps/Netdata/Netdata.lmm.rb +0 -1
- data/Plugins/Apps/Nextcloud/Nextcloud.conf.erb +3 -4
- data/Plugins/Apps/Nextcloud/Nextcloud.lmm.rb +150 -68
- data/Plugins/Apps/Nextcloud/autoconfig.php +13 -0
- data/Plugins/Apps/Nextcloud/config.php +10 -1
- data/Plugins/Apps/Nextcloud/nextcloudcron.service +8 -0
- data/Plugins/Apps/Nextcloud/nextcloudcron.timer +10 -0
- data/Plugins/Apps/Nginx/Connection.rb +93 -0
- data/Plugins/Apps/Nginx/conf.d/configlmm.conf +50 -9
- data/Plugins/Apps/Nginx/conf.d/languages.conf +21 -0
- data/Plugins/Apps/Nginx/config-lmm/errors.conf +25 -20
- data/Plugins/Apps/Nginx/config-lmm/gateway-errors.conf +20 -0
- data/Plugins/Apps/Nginx/config-lmm/proxy.conf +1 -1
- data/Plugins/Apps/Nginx/main.conf.erb +7 -3
- data/Plugins/Apps/Nginx/nginx.conf +2 -2
- data/Plugins/Apps/Nginx/nginx.lmm.rb +99 -81
- data/Plugins/Apps/Nginx/proxy.conf.erb +11 -3
- data/Plugins/Apps/Odoo/Odoo.conf.erb +0 -3
- data/Plugins/Apps/Odoo/Odoo.container +5 -0
- data/Plugins/Apps/Odoo/Odoo.lmm.rb +4 -5
- data/Plugins/Apps/Ollama/Ollama.container +26 -0
- data/Plugins/Apps/Ollama/Ollama.lmm.rb +73 -0
- data/Plugins/Apps/OpenTelemetry/Config/config.yaml +704 -0
- data/Plugins/Apps/OpenTelemetry/OpenTelemetry.lmm.rb +154 -0
- data/Plugins/Apps/OpenVidu/Ingress.container +5 -0
- data/Plugins/Apps/OpenVidu/OpenVidu.conf.erb +0 -3
- data/Plugins/Apps/OpenVidu/OpenVidu.container +5 -0
- data/Plugins/Apps/OpenVidu/OpenVidu.lmm.rb +7 -3
- data/Plugins/Apps/OpenVidu/OpenViduCall.conf.erb +0 -3
- data/Plugins/Apps/OpenVidu/OpenViduCall.container +5 -0
- data/Plugins/Apps/PHP-FPM/Connection.rb +91 -0
- data/Plugins/Apps/PHP-FPM/PHP-FPM.lmm.rb +31 -4
- data/Plugins/Apps/Peppermint/Peppermint.conf.erb +2 -5
- data/Plugins/Apps/Peppermint/Peppermint.container +5 -0
- data/Plugins/Apps/Peppermint/Peppermint.lmm.rb +29 -33
- data/Plugins/Apps/Perplexica/Perplexica.container +25 -0
- data/Plugins/Apps/Perplexica/Perplexica.lmm.rb +92 -0
- data/Plugins/Apps/Perplexica/config.toml +26 -0
- data/Plugins/Apps/Podman/Connection.rb +24 -0
- data/Plugins/Apps/Podman/Podman.lmm.rb +80 -0
- data/Plugins/Apps/Podman/storage.conf +6 -0
- data/Plugins/Apps/Postfix/Postfix.lmm.rb +242 -164
- data/Plugins/Apps/PostgreSQL/Connection.rb +97 -0
- data/Plugins/Apps/PostgreSQL/PostgreSQL.lmm.rb +184 -148
- data/Plugins/Apps/Pterodactyl/Pterodactyl.conf.erb +0 -3
- data/Plugins/Apps/Pterodactyl/Pterodactyl.lmm.rb +0 -2
- data/Plugins/Apps/Pterodactyl/Wings.conf.erb +0 -3
- data/Plugins/Apps/RVM/RVM.lmm.rb +57 -0
- data/Plugins/Apps/Roundcube/Roundcube.conf.erb +0 -3
- data/Plugins/Apps/Roundcube/Roundcube.lmm.rb +15 -19
- data/Plugins/Apps/SSH/SSH.lmm.rb +9 -15
- data/Plugins/Apps/SearXNG/SearXNG.container +22 -0
- data/Plugins/Apps/SearXNG/SearXNG.lmm.rb +79 -0
- data/Plugins/Apps/SearXNG/limiter.toml +40 -0
- data/Plugins/Apps/SearXNG/settings.yml +2 -0
- data/Plugins/Apps/SigNoz/Config/alerts.yml +11 -0
- data/Plugins/Apps/SigNoz/Config/otel-collector-config.yaml +110 -0
- data/Plugins/Apps/SigNoz/Config/otel-collector-opamp-config.yaml +1 -0
- data/Plugins/Apps/SigNoz/Config/prometheus.yml +18 -0
- data/Plugins/Apps/SigNoz/SigNoz-Collector.container +23 -0
- data/Plugins/Apps/SigNoz/SigNoz-Migrator.container +17 -0
- data/Plugins/Apps/SigNoz/SigNoz.conf.erb +61 -0
- data/Plugins/Apps/SigNoz/SigNoz.container +26 -0
- data/Plugins/Apps/SigNoz/SigNoz.lmm.rb +319 -0
- data/Plugins/Apps/Solr/log4j2.xml +89 -0
- data/Plugins/Apps/Solr/solr.lmm.rb +82 -0
- data/Plugins/Apps/Sunshine/Sunshine.conf.erb +0 -3
- data/Plugins/Apps/Sunshine/Sunshine.lmm.rb +0 -1
- data/Plugins/Apps/Tunnel/tunnel.lmm.rb +33 -37
- data/Plugins/Apps/UVdesk/UVdesk.conf.erb +0 -3
- data/Plugins/Apps/Umami/Umami.container +19 -0
- data/Plugins/Apps/Umami/Umami.lmm.rb +108 -0
- data/Plugins/Apps/Valkey/Valkey.lmm.rb +54 -42
- data/Plugins/Apps/Vaultwarden/Vaultwarden.conf.erb +9 -6
- data/Plugins/Apps/Vaultwarden/Vaultwarden.container +7 -1
- data/Plugins/Apps/Vaultwarden/Vaultwarden.lmm.rb +64 -29
- data/Plugins/Apps/Wiki.js/Wiki.js.conf.erb +1 -4
- data/Plugins/Apps/Wiki.js/Wiki.js.container +5 -0
- data/Plugins/Apps/Wiki.js/Wiki.js.lmm.rb +31 -37
- data/Plugins/Apps/YaCy/YaCy.conf.erb +93 -0
- data/Plugins/Apps/YaCy/YaCy.container +21 -0
- data/Plugins/Apps/YaCy/YaCy.lmm.rb +160 -0
- data/Plugins/Apps/ZooKeeper/ZooKeeper.container +24 -0
- data/Plugins/Apps/ZooKeeper/ZooKeeper.lmm.rb +68 -0
- data/Plugins/Apps/bitmagnet/bitmagnet.conf.erb +0 -3
- data/Plugins/Apps/bitmagnet/bitmagnet.lmm.rb +0 -1
- data/Plugins/Apps/gollum/gollum.conf.erb +2 -4
- data/Plugins/Apps/gollum/gollum.container +6 -0
- data/Plugins/Apps/gollum/gollum.lmm.rb +51 -50
- data/Plugins/Apps/llama.cpp/llama.cpp.container +28 -0
- data/Plugins/Apps/llama.cpp/llama.cpp.lmm.rb +90 -0
- data/Plugins/Apps/vLLM/vLLM.container +32 -0
- data/Plugins/Apps/vLLM/vLLM.lmm.rb +89 -0
- data/Plugins/OS/General/Utils.lmm.rb +26 -0
- data/Plugins/OS/Linux/Connection.rb +472 -0
- data/Plugins/OS/Linux/Debian/preseed.cfg.erb +25 -6
- data/Plugins/OS/Linux/Flavours.yaml +13 -0
- data/Plugins/OS/Linux/Grub/grub.cfg +10 -0
- data/Plugins/OS/Linux/HTTP.rb +32 -0
- data/Plugins/OS/Linux/Linux.lmm.rb +533 -187
- data/Plugins/OS/Linux/Packages.yaml +20 -1
- data/Plugins/OS/Linux/Services.yaml +8 -0
- data/Plugins/OS/Linux/Shell.rb +70 -0
- data/Plugins/OS/Linux/Syslinux/default +8 -0
- data/Plugins/OS/Linux/WireGuard/WireGuard.lmm.rb +83 -59
- data/Plugins/OS/Linux/WireGuard/wg0.conf.erb +3 -0
- data/Plugins/OS/Linux/openSUSE/autoinst.xml.erb +29 -3
- data/Plugins/OS/Linux/systemd/systemd.lmm.rb +13 -11
- data/Plugins/OS/Routers/Aruba/ArubaInstant.lmm.rb +6 -5
- data/Plugins/Platforms/GitHub.lmm.rb +73 -28
- data/Plugins/Platforms/GoDaddy/GoDaddy.lmm.rb +9 -6
- data/Plugins/Platforms/Proxmox/Proxmox.lmm.rb +402 -0
- data/Plugins/Platforms/Proxmox/XTerm.rb +321 -0
- data/Plugins/Platforms/libvirt/libvirt.lmm.rb +38 -13
- data/Plugins/Platforms/porkbun.lmm.rb +12 -2
- data/Plugins/Platforms/porkbun_spec.rb +2 -2
- data/Plugins/Services/DNS/AmberBit.lmm.rb +1 -1
- data/Plugins/Services/DNS/ArubaItDNS.lmm.rb +1 -1
- data/Plugins/Services/DNS/NICLV.lmm.rb +1 -1
- data/Plugins/Services/DNS/PowerDNS.lmm.rb +70 -68
- data/Plugins/Services/DNS/tonic.lmm.rb +22 -12
- data/lib/ConfigLMM/Framework/plugins/dns.rb +4 -3
- data/lib/ConfigLMM/Framework/plugins/linuxApp.rb +145 -184
- data/lib/ConfigLMM/Framework/plugins/nginxApp.rb +34 -17
- data/lib/ConfigLMM/Framework/plugins/plugin.rb +53 -181
- data/lib/ConfigLMM/Framework/plugins/store.rb +4 -4
- data/lib/ConfigLMM/Framework/variables.rb +75 -0
- data/lib/ConfigLMM/Framework.rb +1 -0
- data/lib/ConfigLMM/cli.rb +12 -6
- data/lib/ConfigLMM/commands/configsCommand.rb +37 -6
- data/lib/ConfigLMM/commands/diff.rb +33 -9
- data/lib/ConfigLMM/context.rb +22 -3
- data/lib/ConfigLMM/io/configList.rb +82 -6
- data/lib/ConfigLMM/io/connection.rb +143 -0
- data/lib/ConfigLMM/io/dhcp.rb +330 -0
- data/lib/ConfigLMM/io/http.rb +78 -0
- data/lib/ConfigLMM/io/local.rb +207 -0
- data/lib/ConfigLMM/io/pxe.rb +92 -0
- data/lib/ConfigLMM/io/ssh.rb +156 -0
- data/lib/ConfigLMM/io/tftp.rb +105 -0
- data/lib/ConfigLMM/io.rb +2 -0
- data/lib/ConfigLMM/secrets/envStore.rb +39 -0
- data/lib/ConfigLMM/secrets/fileStore.rb +43 -0
- data/lib/ConfigLMM/state.rb +2 -1
- data/lib/ConfigLMM/version.rb +2 -1
- data/lib/ConfigLMM.rb +1 -0
- data/{Examples → scripts}/configlmmAuth.sh +7 -5
- metadata +205 -8
@@ -1,110 +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 =
|
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
17
|
target['Deploy'] = !!(target['ListenAll'] || target['Listen'] || target['Settings']) unless target.key?('Deploy')
|
16
|
-
activeState['Deploy'] = target['Deploy']
|
17
|
-
activeState['Users'] = target['Users']
|
18
|
-
activeState['Databases'] = target['Databases']
|
19
|
-
activeState['Publications'] = target['Publications']
|
20
|
-
activeState['Subscriptions'] = target['Subscriptions']
|
21
|
-
|
22
|
-
if target['Deploy']
|
23
|
-
self.ensurePackage(PACKAGE_NAME, target['Location'])
|
24
|
-
self.ensureServiceAutoStart(SERVICE_NAME, target['Location'])
|
25
|
-
self.startService(SERVICE_NAME, target['Location'])
|
26
|
-
end
|
27
|
-
|
28
|
-
if target['Location'] && target['Location'] != '@me'
|
29
|
-
uri = Addressable::URI.parse(target['Location'])
|
30
|
-
raise Framework::PluginProcessError.new("#{id}: Unknown Protocol: #{uri.scheme}!") if uri.scheme != 'ssh'
|
31
18
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
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)
|
36
50
|
end
|
37
|
-
self.class.createUsersOverSSH(target, ssh)
|
38
|
-
self.class.createDatabasesOverSSH(target, ssh)
|
39
|
-
self.class.createPublicationsOverSSH(target, ssh)
|
40
|
-
self.class.createSubscriptionsOverSSH(target, ssh)
|
41
|
-
end
|
42
|
-
else
|
43
|
-
if target['Deploy']
|
44
|
-
`pg_ctl reload`
|
45
51
|
end
|
46
52
|
end
|
47
|
-
|
48
|
-
activeState['Status'] = State::STATUS_DEPLOYED
|
49
53
|
end
|
50
54
|
|
51
55
|
def cleanup(configs, state, context, options)
|
52
|
-
cleanupType(:PostgreSQL, configs, state, context, options) do |item, id, state, context, options,
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
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]
|
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
|
64
72
|
end
|
65
|
-
else
|
66
|
-
# TODO
|
67
73
|
end
|
68
74
|
end
|
69
75
|
end
|
70
76
|
|
71
|
-
def
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
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
|
77
88
|
end
|
78
|
-
else
|
79
|
-
`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}`
|
80
89
|
end
|
81
90
|
end
|
82
91
|
|
83
|
-
def
|
84
|
-
dir = nil
|
92
|
+
def updateSettings(target, linuxConnection, postgres, options)
|
85
93
|
settingLines = []
|
86
94
|
hbaLines = []
|
87
95
|
if target['ListenAll']
|
88
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|'"
|
89
|
-
|
97
|
+
postgres.connection.exec(cmd + ' ' + postgres.pgsqlDir + HBA_FILE, false, options)
|
90
98
|
settingLines << "listen_addresses = '*'\n"
|
91
|
-
|
99
|
+
postgres.connection.firewallAddPort('5432/tcp', options)
|
92
100
|
elsif target['Listen'] && !target['Listen'].empty?
|
93
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|'"
|
94
|
-
|
102
|
+
postgres.connection.exec(cmd + ' ' + postgres.pgsqlDir + HBA_FILE, false, options)
|
95
103
|
|
96
104
|
ips = target['Listen'].map { |addr| addr.split('/').first }.join(',')
|
97
105
|
settingLines << "listen_addresses = '#{ips}'\n"
|
98
106
|
|
99
107
|
target['Listen'].each do |addr|
|
100
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+$/
|
101
111
|
hbaLines << "host all all #{addr} scram-sha-256\n"
|
102
112
|
end
|
103
113
|
end
|
104
114
|
else
|
105
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|'"
|
106
|
-
|
116
|
+
postgres.connection.exec(cmd + ' ' + postgres.pgsqlDir + HBA_FILE, false, options)
|
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
|
107
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
|
+
|
108
136
|
#if !target['Publications'].to_h.empty?
|
109
137
|
# target['Settings'] ||= {}
|
110
138
|
# target['Settings']['wal_level'] = 'logical'
|
@@ -113,41 +141,39 @@ module ConfigLMM
|
|
113
141
|
settingLines << "#{name} = #{value}\n"
|
114
142
|
end
|
115
143
|
if !hbaLines.empty?
|
116
|
-
|
144
|
+
postgres.connection.updateFile(postgres.pgsqlDir + HBA_FILE, options, false) do |configLines|
|
117
145
|
configLines += hbaLines
|
118
146
|
end
|
119
147
|
end
|
120
148
|
if !settingLines.empty?
|
121
|
-
|
149
|
+
postgres.connection.updateFile(postgres.pgsqlDir + CONFIG_FILE, options, false) do |configLines|
|
122
150
|
configLines += settingLines
|
123
151
|
end
|
124
152
|
end
|
125
153
|
end
|
126
154
|
|
127
|
-
def
|
155
|
+
def createUsers(target, postgres, context, options)
|
128
156
|
target['Users'].to_a.each do |user, info|
|
129
|
-
|
130
|
-
if !
|
131
|
-
password =
|
132
|
-
if !password.empty?
|
133
|
-
sql = "ALTER USER #{user} WITH PASSWORD '#{password}'"
|
134
|
-
self.executeSQL(sql, nil, ssh)
|
135
|
-
end
|
157
|
+
password = info['Password'].to_s
|
158
|
+
if !password.empty?
|
159
|
+
password = Framework::Variables.parse(info['Password'], context).to_s
|
136
160
|
end
|
137
|
-
|
138
|
-
|
139
|
-
|
161
|
+
postgres.createUser(user, password, options)
|
162
|
+
|
163
|
+
if info['Replication']
|
164
|
+
postgres.grantReplication(user)
|
140
165
|
end
|
141
166
|
end
|
142
167
|
end
|
143
168
|
|
144
|
-
def
|
169
|
+
def createDatabases(target, postgres, context, options)
|
145
170
|
target['Databases'].to_a.each do |db, info|
|
146
|
-
|
171
|
+
owner = info['Owner'] ? info['Owner'] : nil
|
172
|
+
postgres.createDB(db, owner, options)
|
147
173
|
end
|
148
174
|
end
|
149
175
|
|
150
|
-
def
|
176
|
+
def createPublications(target, postgres, context, options)
|
151
177
|
return if target['Publications'].to_h.empty?
|
152
178
|
|
153
179
|
target['Publications'].each do |name, data|
|
@@ -156,139 +182,149 @@ module ConfigLMM
|
|
156
182
|
# TODO
|
157
183
|
elsif data['Tables'] == 'All'
|
158
184
|
sql = "CREATE PUBLICATION #{name} FOR ALL TABLES"
|
159
|
-
|
185
|
+
postgres.exec(sql, data['Database'], true, [], options)
|
160
186
|
else
|
161
187
|
raise "Invalid Tables field: #{data['Tables']}"
|
162
188
|
end
|
163
189
|
end
|
164
190
|
end
|
165
191
|
|
166
|
-
def
|
192
|
+
def createSubscriptions(target, postgres, context, options)
|
167
193
|
return if target['Subscriptions'].to_h.empty?
|
168
194
|
|
169
195
|
target['Subscriptions'].each do |name, data|
|
170
196
|
data['Database'] = name unless data['Database']
|
171
197
|
data['Publication'] = name unless data['Publication']
|
172
|
-
connection =
|
198
|
+
connection = Framework::Variables.stringEval(data['Connection'], context)
|
173
199
|
|
174
200
|
authParams = '--host=' + connection.match('host=([^ ]+)')[1]
|
175
201
|
authParams += ' --username=' + connection.match('user=([^ ]+)')[1]
|
176
202
|
password = connection.match('password=([^ ]+)')[1]
|
177
203
|
|
178
|
-
|
204
|
+
importRemoteSchema(name, data['Database'], password, authParams, postgres, options)
|
179
205
|
|
180
206
|
sql = "CREATE SUBSCRIPTION #{name} CONNECTION '#{connection}' PUBLICATION #{data['Publication']}"
|
181
|
-
|
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
|
182
213
|
end
|
183
214
|
end
|
184
215
|
|
185
|
-
def
|
186
|
-
|
187
|
-
|
188
|
-
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 })
|
189
219
|
end
|
190
220
|
|
191
|
-
def self.
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
self.executeSQL("ALTER TABLE public.#{table} OWNER TO #{owner};", db, ssh)
|
196
|
-
end
|
197
|
-
|
198
|
-
sql = "SELECT sequence_name FROM information_schema.sequences WHERE NOT sequence_schema IN ('pg_catalog', 'information_schema')"
|
199
|
-
sequences = self.executeSQL(sql, db, ssh, false, ['--csv', '--tuples-only']).strip.lines
|
200
|
-
sequences.each do |sequence|
|
201
|
-
self.executeSQL("ALTER SEQUENCE public.#{sequence} OWNER TO #{owner};", db, ssh)
|
202
|
-
end
|
221
|
+
def self.defaults(settings)
|
222
|
+
settings['HostName'] = 'localhost' unless settings['HostName']
|
223
|
+
settings['Port'] = PORT unless settings['Port']
|
224
|
+
end
|
203
225
|
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
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
|
208
243
|
end
|
209
244
|
end
|
210
245
|
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
dir
|
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
|
217
251
|
end
|
218
252
|
|
253
|
+
# DEPRECATED
|
219
254
|
def self.createRemoteUserAndDBOverSSH(settings, user, password, ssh)
|
220
|
-
self.executeRemotely(settings, ssh) do |
|
221
|
-
self.createUserAndDBOverSSH(user, password,
|
255
|
+
self.executeRemotely(settings, ssh) do |connection|
|
256
|
+
self.createUserAndDBOverSSH(user, password, connection)
|
222
257
|
end
|
223
258
|
end
|
224
259
|
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
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)
|
229
265
|
end
|
230
266
|
end
|
231
267
|
|
232
|
-
|
233
|
-
|
268
|
+
# DEPRECATED
|
269
|
+
def self.createExtensions(settings, db, extensions, connectionOrSSH)
|
270
|
+
self.executeRemotely(settings, ssh) do |connection|
|
234
271
|
extensions.each do |extension|
|
235
|
-
self.executeSQL("CREATE EXTENSION #{extension}", db,
|
272
|
+
self.executeSQL("CREATE EXTENSION #{extension}", db, connection, true)
|
236
273
|
end
|
237
274
|
end
|
238
275
|
end
|
239
276
|
|
240
|
-
|
241
|
-
|
277
|
+
# DEPRECATED
|
278
|
+
def self.executeRemotely(settings, connectionOrSSH = nil)
|
279
|
+
prompt = TTY::Prompt.new
|
280
|
+
logger = TTY::Logger.new
|
281
|
+
self.defaults(settings)
|
242
282
|
if settings['HostName'] == 'localhost'
|
243
|
-
|
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)
|
244
290
|
else
|
245
291
|
self.sshStart("ssh://#{settings['HostName']}/") do |ssh|
|
246
|
-
yield(ssh)
|
292
|
+
yield(IO::Connection.new(:SSH, IO::SSH.new(prompt, logger, ssh), prompt, logger))
|
247
293
|
end
|
248
294
|
end
|
249
295
|
end
|
250
296
|
|
251
|
-
|
252
|
-
|
253
|
-
self.
|
254
|
-
if password
|
255
|
-
sql = "ALTER USER #{user} WITH PASSWORD '#{password}'"
|
256
|
-
self.executeSQL(sql, nil, ssh)
|
257
|
-
end
|
297
|
+
# DEPRECATED
|
298
|
+
def self.createUserAndDB(user, password, connection)
|
299
|
+
self.createUserAndDBOverSSH(user, password, connection)
|
258
300
|
end
|
259
301
|
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
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)
|
266
307
|
else
|
267
|
-
#
|
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)
|
268
310
|
end
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
if ssh
|
273
|
-
db = 'postgres' unless db
|
274
|
-
cmd = " su --login #{USER_NAME} --command ' psql #{options.join(' ')} --dbname=#{db} --command=\"#{sql.gsub("'", "'\"'\"'")};\"'"
|
275
|
-
self.sshExec!(ssh, cmd, allowFailure)
|
276
|
-
else
|
277
|
-
# TODO
|
311
|
+
if password
|
312
|
+
sql = "ALTER USER #{user} WITH PASSWORD '#{password}'"
|
313
|
+
self.executeSQL(sql, nil, connectionOrSSH)
|
278
314
|
end
|
279
315
|
end
|
280
316
|
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
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)
|
286
323
|
else
|
287
|
-
|
324
|
+
self.exec(cmd, connectionOrSSH, allowFailure, dry)
|
288
325
|
end
|
289
326
|
end
|
290
327
|
|
291
328
|
end
|
292
|
-
|
293
329
|
end
|
294
330
|
end
|
@@ -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
|
@@ -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
|