ConfigLMM 0.3.0 → 0.4.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 +36 -0
- data/Plugins/Apps/Authentik/Authentik-ProxyOutpost.container +14 -0
- data/Plugins/Apps/Authentik/Authentik-Server.container +1 -0
- data/Plugins/Apps/Authentik/Authentik-Worker.container +1 -0
- data/Plugins/Apps/Authentik/Authentik.conf.erb +7 -0
- data/Plugins/Apps/Authentik/Authentik.lmm.rb +24 -2
- data/Plugins/Apps/BookStack/BookStack.conf.erb +41 -0
- data/Plugins/Apps/BookStack/BookStack.container +15 -0
- data/Plugins/Apps/BookStack/BookStack.lmm.rb +80 -0
- data/Plugins/Apps/Discourse/Discourse-Sidekiq.container +17 -0
- data/Plugins/Apps/Discourse/Discourse.conf.erb +41 -0
- data/Plugins/Apps/Discourse/Discourse.container +17 -0
- data/Plugins/Apps/Discourse/Discourse.lmm.rb +95 -0
- data/Plugins/Apps/Dovecot/Dovecot.lmm.rb +25 -2
- data/Plugins/Apps/ERPNext/ERPNext-Frontend.container +19 -0
- data/Plugins/Apps/ERPNext/ERPNext-Queue.container +17 -0
- data/Plugins/Apps/ERPNext/ERPNext-Scheduler.container +17 -0
- data/Plugins/Apps/ERPNext/ERPNext-Websocket.container +19 -0
- data/Plugins/Apps/ERPNext/ERPNext.container +18 -0
- data/Plugins/Apps/ERPNext/ERPNext.lmm.rb +193 -0
- data/Plugins/Apps/ERPNext/ERPNext.network +12 -0
- data/Plugins/Apps/ERPNext/sites/apps.json +10 -0
- data/Plugins/Apps/ERPNext/sites/apps.txt +3 -0
- data/Plugins/Apps/ERPNext/sites/common_site_config.json +11 -0
- data/Plugins/Apps/GitLab/GitLab.container +3 -2
- data/Plugins/Apps/GitLab/GitLab.lmm.rb +37 -12
- data/Plugins/Apps/LetsEncrypt/LetsEncrypt.lmm.rb +57 -0
- data/Plugins/Apps/LetsEncrypt/hooks/dovecot.sh +2 -0
- data/Plugins/Apps/LetsEncrypt/hooks/nginx.sh +2 -0
- data/Plugins/Apps/LetsEncrypt/hooks/postfix.sh +2 -0
- data/Plugins/Apps/LetsEncrypt/renew-certificates.service +7 -0
- data/Plugins/Apps/LetsEncrypt/renew-certificates.timer +12 -0
- data/Plugins/Apps/LetsEncrypt/rfc2136.ini +11 -0
- data/Plugins/Apps/MariaDB/MariaDB.lmm.rb +115 -0
- data/Plugins/Apps/Matrix/Element.container +14 -0
- data/Plugins/Apps/Matrix/Matrix.conf.erb +49 -5
- data/Plugins/Apps/Matrix/Matrix.lmm.rb +86 -1
- data/Plugins/Apps/Matrix/Synapse.container +17 -0
- data/Plugins/Apps/Matrix/config.json +50 -0
- data/Plugins/Apps/Matrix/homeserver.yaml +70 -0
- data/Plugins/Apps/Matrix/log.config +30 -0
- data/Plugins/Apps/Nextcloud/Nextcloud.lmm.rb +70 -45
- data/Plugins/Apps/Nginx/conf.d/configlmm.conf +9 -0
- data/Plugins/Apps/Nginx/config-lmm/errors.conf +10 -4
- data/Plugins/Apps/Nginx/config-lmm/proxy.conf +5 -1
- data/Plugins/Apps/Nginx/nginx.lmm.rb +15 -11
- data/Plugins/Apps/Nginx/proxy.conf.erb +13 -3
- data/Plugins/Apps/Odoo/Odoo.container +2 -1
- data/Plugins/Apps/Odoo/Odoo.lmm.rb +1 -1
- data/Plugins/Apps/OpenVidu/Ingress.container +18 -0
- data/Plugins/Apps/OpenVidu/OpenVidu.conf.erb +34 -0
- data/Plugins/Apps/OpenVidu/OpenVidu.container +16 -0
- data/Plugins/Apps/OpenVidu/OpenVidu.lmm.rb +90 -0
- data/Plugins/Apps/OpenVidu/OpenViduCall.conf.erb +35 -0
- data/Plugins/Apps/OpenVidu/OpenViduCall.container +15 -0
- data/Plugins/Apps/OpenVidu/ingress.yaml +10 -0
- data/Plugins/Apps/OpenVidu/livekit.yaml +13 -0
- data/Plugins/Apps/Peppermint/Peppermint.conf.erb +0 -4
- data/Plugins/Apps/Peppermint/Peppermint.container +2 -1
- data/Plugins/Apps/Postfix/Postfix.lmm.rb +32 -6
- data/Plugins/Apps/PostgreSQL/PostgreSQL.lmm.rb +80 -11
- data/Plugins/Apps/Roundcube/Roundcube.conf.erb +75 -0
- data/Plugins/Apps/Roundcube/Roundcube.lmm.rb +145 -0
- data/Plugins/Apps/Tunnel/tunnel.lmm.rb +63 -0
- data/Plugins/Apps/Tunnel/tunnelTCP.service +9 -0
- data/Plugins/Apps/Tunnel/tunnelTCP.socket +9 -0
- data/Plugins/Apps/Tunnel/tunnelUDP.service +9 -0
- data/Plugins/Apps/Tunnel/tunnelUDP.socket +9 -0
- data/Plugins/Apps/Valkey/Valkey.lmm.rb +32 -0
- data/Plugins/Apps/Vaultwarden/Vaultwarden.lmm.rb +4 -0
- data/Plugins/Apps/Wiki.js/Wiki.js.conf.erb +42 -0
- data/Plugins/Apps/Wiki.js/Wiki.js.container +15 -0
- data/Plugins/Apps/Wiki.js/Wiki.js.lmm.rb +61 -0
- data/Plugins/Apps/gollum/gollum.conf.erb +39 -1
- data/Plugins/Apps/gollum/gollum.container +4 -1
- data/Plugins/Apps/gollum/gollum.lmm.rb +11 -3
- data/Plugins/OS/Linux/Debian/preseed.cfg.erb +62 -0
- data/Plugins/OS/Linux/Distributions.yaml +32 -0
- data/Plugins/OS/Linux/Flavours.yaml +11 -0
- data/Plugins/OS/Linux/Linux.lmm.rb +255 -67
- data/Plugins/OS/Linux/Packages.yaml +47 -2
- data/Plugins/OS/Linux/Proxmox/answer.toml.erb +30 -0
- data/Plugins/OS/Linux/WireGuard/WireGuard.lmm.rb +33 -4
- data/Plugins/Platforms/GoDaddy/GoDaddy.lmm.rb +1 -1
- data/Plugins/Platforms/libvirt/libvirt.lmm.rb +3 -2
- data/Plugins/Services/DNS/PowerDNS.lmm.rb +95 -8
- data/bootstrap.sh +41 -3
- data/lib/ConfigLMM/Framework/plugins/linuxApp.rb +146 -64
- data/lib/ConfigLMM/Framework/plugins/nginxApp.rb +34 -3
- data/lib/ConfigLMM/Framework/plugins/plugin.rb +62 -6
- data/lib/ConfigLMM/cli.rb +3 -1
- data/lib/ConfigLMM/commands/cleanup.rb +1 -0
- data/lib/ConfigLMM/commands/configsCommand.rb +3 -1
- data/lib/ConfigLMM/io/configList.rb +3 -1
- data/lib/ConfigLMM/state.rb +10 -2
- data/lib/ConfigLMM/version.rb +1 -1
- metadata +54 -3
- data/Plugins/Apps/GitLab/GitLab.conf.erb +0 -26
|
@@ -4,7 +4,7 @@ Description=Odoo container
|
|
|
4
4
|
After=local-fs.target
|
|
5
5
|
|
|
6
6
|
[Container]
|
|
7
|
-
Image=odoo:latest
|
|
7
|
+
Image=docker.io/odoo:latest
|
|
8
8
|
EnvironmentFile=/var/lib/odoo/.config/containers/systemd/Odoo.env
|
|
9
9
|
Network=slirp4netns:allow_host_loopback=true
|
|
10
10
|
PublishPort=0.0.0.0:8069:8069
|
|
@@ -12,6 +12,7 @@ UserNS=keep-id:uid=101,gid=101
|
|
|
12
12
|
Volume=/var/lib/odoo/config:/etc/odoo
|
|
13
13
|
Volume=/var/lib/odoo/data:/var/lib/odoo
|
|
14
14
|
Volume=/var/lib/odoo/addons:/mnt/extra-addons
|
|
15
|
+
AutoUpdate=registry
|
|
15
16
|
|
|
16
17
|
[Install]
|
|
17
18
|
WantedBy=multi-user.target default.target
|
|
@@ -71,7 +71,7 @@ module ConfigLMM
|
|
|
71
71
|
def configurePostgreSQL(settings, ssh)
|
|
72
72
|
user = USER
|
|
73
73
|
password = SecureRandom.alphanumeric(20)
|
|
74
|
-
PostgreSQL.
|
|
74
|
+
PostgreSQL.executeRemotely(settings, ssh) do |ssh|
|
|
75
75
|
self.class.sshExec!(ssh, "su --login #{PostgreSQL::USER_NAME} --command 'createuser --createdb #{user}'", true)
|
|
76
76
|
PostgreSQL.executeSQL("ALTER USER #{user} WITH PASSWORD '#{password}'", nil, ssh)
|
|
77
77
|
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
|
|
2
|
+
[Unit]
|
|
3
|
+
Description=LiveKit Ingress container
|
|
4
|
+
After=local-fs.target
|
|
5
|
+
|
|
6
|
+
[Container]
|
|
7
|
+
Image=docker.io/livekit/ingress:latest
|
|
8
|
+
EnvironmentFile=/var/lib/openvidu/.config/containers/systemd/OpenVidu.env
|
|
9
|
+
Network=slirp4netns:allow_host_loopback=true
|
|
10
|
+
PublishPort=127.0.0.1:1935:1935
|
|
11
|
+
PublishPort=127.0.0.1:8085:8085
|
|
12
|
+
PublishPort=127.0.0.1:7895:7895/udp
|
|
13
|
+
UserNS=keep-id:uid=1000,gid=1000
|
|
14
|
+
Volume=/var/lib/openvidu/ingress.yaml:/etc/ingress.yaml
|
|
15
|
+
AutoUpdate=registry
|
|
16
|
+
|
|
17
|
+
[Install]
|
|
18
|
+
WantedBy=multi-user.target default.target
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
|
|
2
|
+
server {
|
|
3
|
+
<% if config['NginxVersion'] >= 1.25 %>
|
|
4
|
+
listen 443 ssl;
|
|
5
|
+
listen [::]:443 ssl;
|
|
6
|
+
http2 on;
|
|
7
|
+
http3 on;
|
|
8
|
+
quic_retry on;
|
|
9
|
+
add_header Alt-Svc 'h3=":443"; ma=86400';
|
|
10
|
+
<% else %>
|
|
11
|
+
listen 443 ssl http2;
|
|
12
|
+
listen [::]:443 ssl http2;
|
|
13
|
+
<% end %>
|
|
14
|
+
|
|
15
|
+
include config-lmm/ssl.conf;
|
|
16
|
+
|
|
17
|
+
server_name <%= config['Domain'] %>;
|
|
18
|
+
|
|
19
|
+
<% if config['CertName'] %>
|
|
20
|
+
ssl_certificate "/etc/letsencrypt/live/<%= config['CertName'] %>/fullchain.pem";
|
|
21
|
+
ssl_certificate_key "/etc/letsencrypt/live/<%= config['CertName'] %>/privkey.pem";
|
|
22
|
+
ssl_trusted_certificate "/etc/letsencrypt/live/<%= config['CertName'] %>/chain.pem";
|
|
23
|
+
<% end %>
|
|
24
|
+
|
|
25
|
+
access_log /var/log/nginx/openvidu.access.log;
|
|
26
|
+
error_log /var/log/nginx/openvidu.error.log;
|
|
27
|
+
|
|
28
|
+
# Proxy site
|
|
29
|
+
location / {
|
|
30
|
+
proxy_pass http://127.0.0.1:7880;
|
|
31
|
+
include config-lmm/proxy.conf;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
|
|
2
|
+
[Unit]
|
|
3
|
+
Description=OpenVidu container
|
|
4
|
+
After=local-fs.target
|
|
5
|
+
|
|
6
|
+
[Container]
|
|
7
|
+
Image=docker.io/openvidu/openvidu-server:main
|
|
8
|
+
Exec=--config /etc/livekit.yaml --bind=$BindIP
|
|
9
|
+
EnvironmentFile=/var/lib/openvidu/.config/containers/systemd/OpenVidu.env
|
|
10
|
+
Network=host
|
|
11
|
+
UserNS=keep-id:uid=1000,gid=1000
|
|
12
|
+
Volume=/var/lib/openvidu/livekit.yaml:/etc/livekit.yaml
|
|
13
|
+
AutoUpdate=registry
|
|
14
|
+
|
|
15
|
+
[Install]
|
|
16
|
+
WantedBy=multi-user.target default.target
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
|
|
2
|
+
module ConfigLMM
|
|
3
|
+
module LMM
|
|
4
|
+
class OpenVidu < Framework::NginxApp
|
|
5
|
+
|
|
6
|
+
USER = 'openvidu'
|
|
7
|
+
HOME_DIR = '/var/lib/openvidu'
|
|
8
|
+
HOST_IP = '10.0.2.2'
|
|
9
|
+
|
|
10
|
+
def actionOpenViduDeploy(id, target, activeState, context, options)
|
|
11
|
+
raise Framework::PluginProcessError.new('Domain field must be set!') unless target['Domain']
|
|
12
|
+
raise Framework::PluginProcessError.new('CallDomain field must be set!') unless target['CallDomain']
|
|
13
|
+
|
|
14
|
+
if target['Location'] && target['Location'] != '@me'
|
|
15
|
+
uri = Addressable::URI.parse(target['Location'])
|
|
16
|
+
raise Framework::PluginProcessError.new("#{id}: Unknown Protocol: #{uri.scheme}!") if uri.scheme != 'ssh'
|
|
17
|
+
|
|
18
|
+
self.class.sshStart(uri) do |ssh|
|
|
19
|
+
|
|
20
|
+
distroInfo = Framework::LinuxApp.currentDistroInfo(ssh)
|
|
21
|
+
Framework::LinuxApp.configurePodmanServiceOverSSH(USER, HOME_DIR, 'OpenVidu', distroInfo, ssh)
|
|
22
|
+
|
|
23
|
+
secretKey = SecureRandom.alphanumeric(40)
|
|
24
|
+
bindIp = target['BindIP']
|
|
25
|
+
bindIp = '127.0.0.1' unless bindIp
|
|
26
|
+
|
|
27
|
+
path = Framework::LinuxApp::SYSTEMD_CONTAINERS_PATH.gsub('~', HOME_DIR)
|
|
28
|
+
self.class.exec("echo 'INGRESS_CONFIG_FILE=/etc/ingress.yaml' > #{path}/OpenVidu.env", ssh)
|
|
29
|
+
self.class.exec("echo 'LIVEKIT_URL=wss://#{target['Domain']}' >> #{path}/OpenVidu.env", ssh)
|
|
30
|
+
self.class.exec("echo 'LIVEKIT_API_KEY=Main' >> #{path}/OpenVidu.env", ssh)
|
|
31
|
+
self.class.exec("echo 'LIVEKIT_API_SECRET=#{secretKey}' >> #{path}/OpenVidu.env", ssh)
|
|
32
|
+
self.class.exec("echo 'CALL_PRIVATE_ACCESS=true' >> #{path}/OpenVidu.env", ssh)
|
|
33
|
+
self.class.exec("echo 'CALL_USER=guest' >> #{path}/OpenVidu.env", ssh)
|
|
34
|
+
callSecret = SecureRandom.alphanumeric(20)
|
|
35
|
+
prompt.say("OpenVidu Call guest password: #{callSecret}", :color => :magenta)
|
|
36
|
+
self.class.exec("echo 'CALL_SECRET=#{callSecret}' >> #{path}/OpenVidu.env", ssh)
|
|
37
|
+
self.class.exec("echo 'CALL_ADMIN_USER=admin' >> #{path}/OpenVidu.env", ssh)
|
|
38
|
+
callAdminSecret = SecureRandom.alphanumeric(20)
|
|
39
|
+
prompt.say("OpenVidu Call admin password: #{callAdminSecret}", :color => :magenta)
|
|
40
|
+
self.class.exec("echo 'CALL_ADMIN_SECRET=#{callAdminSecret}' >> #{path}/OpenVidu.env", ssh)
|
|
41
|
+
|
|
42
|
+
ssh.scp.upload!(__dir__ + '/livekit.yaml', HOME_DIR)
|
|
43
|
+
ssh.scp.upload!(__dir__ + '/ingress.yaml', HOME_DIR)
|
|
44
|
+
|
|
45
|
+
self.class.exec("sed -i 's|$SECRET|#{secretKey}|' #{HOME_DIR}/livekit.yaml", ssh)
|
|
46
|
+
|
|
47
|
+
if target['Valkey']
|
|
48
|
+
self.class.exec("sed -i 's|10.0.2.2|#{target['Valkey']['Host']}|' #{HOME_DIR}/ingress.yaml", ssh) if target['Valkey']['Host']
|
|
49
|
+
end
|
|
50
|
+
if ENV['VALKEY_PASSWORD']
|
|
51
|
+
self.class.exec("sed -i 's|password:|password: #{ENV['VALKEY_PASSWORD']}|' #{HOME_DIR}/ingress.yaml", ssh)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
self.class.exec("chown #{USER}:#{USER} #{path}/OpenVidu.env #{HOME_DIR}/livekit.yaml #{HOME_DIR}/ingress.yaml", ssh)
|
|
55
|
+
self.class.exec("chmod 600 #{path}/OpenVidu.env #{HOME_DIR}/livekit.yaml #{HOME_DIR}/ingress.yaml", ssh)
|
|
56
|
+
|
|
57
|
+
ssh.scp.upload!(__dir__ + '/OpenVidu.container', path)
|
|
58
|
+
ssh.scp.upload!(__dir__ + '/OpenViduCall.container', path)
|
|
59
|
+
ssh.scp.upload!(__dir__ + '/Ingress.container', path)
|
|
60
|
+
|
|
61
|
+
self.class.exec("sed -i 's|$BindIP|#{bindIp}|' #{path}/OpenVidu.container", ssh)
|
|
62
|
+
|
|
63
|
+
Framework::LinuxApp.firewallAddPortOverSSH('7881/tcp', ssh)
|
|
64
|
+
Framework::LinuxApp.firewallAddPortOverSSH('7900-7999/udp', ssh)
|
|
65
|
+
Framework::LinuxApp.firewallAddPortOverSSH('45000-55000/udp', ssh)
|
|
66
|
+
|
|
67
|
+
self.class.exec("systemctl --user --machine=#{USER}@ daemon-reload", ssh)
|
|
68
|
+
self.class.exec("systemctl --user --machine=#{USER}@ restart OpenVidu", ssh)
|
|
69
|
+
self.class.exec("systemctl --user --machine=#{USER}@ restart OpenViduCall", ssh)
|
|
70
|
+
self.class.exec("systemctl --user --machine=#{USER}@ restart Ingress", ssh)
|
|
71
|
+
|
|
72
|
+
Framework::LinuxApp.ensurePackages([NGINX_PACKAGE], ssh)
|
|
73
|
+
Framework::LinuxApp.ensureServiceAutoStartOverSSH(NGINX_PACKAGE, ssh)
|
|
74
|
+
self.class.prepareNginxConfig(target, ssh)
|
|
75
|
+
target['CallDomain'] = Addressable::IDNA.to_ascii(target['CallDomain'])
|
|
76
|
+
self.writeNginxConfig(__dir__, 'OpenVidu', id, target, state, context, options)
|
|
77
|
+
self.writeNginxConfig(__dir__, 'OpenViduCall', id, target, state, context, options)
|
|
78
|
+
self.deployNginxConfig(id, target, activeState, context, options)
|
|
79
|
+
Framework::LinuxApp.startServiceOverSSH(NGINX_PACKAGE, ssh)
|
|
80
|
+
|
|
81
|
+
end
|
|
82
|
+
else
|
|
83
|
+
# TODO
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
|
|
2
|
+
server {
|
|
3
|
+
<% if config['NginxVersion'] >= 1.25 %>
|
|
4
|
+
listen 443 ssl;
|
|
5
|
+
listen [::]:443 ssl;
|
|
6
|
+
http2 on;
|
|
7
|
+
http3 on;
|
|
8
|
+
quic_retry on;
|
|
9
|
+
add_header Alt-Svc 'h3=":443"; ma=86400';
|
|
10
|
+
<% else %>
|
|
11
|
+
listen 443 ssl http2;
|
|
12
|
+
listen [::]:443 ssl http2;
|
|
13
|
+
<% end %>
|
|
14
|
+
|
|
15
|
+
include config-lmm/ssl.conf;
|
|
16
|
+
|
|
17
|
+
server_name <%= config['CallDomain'] %>;
|
|
18
|
+
|
|
19
|
+
<% if config['CallCertName'] %>
|
|
20
|
+
ssl_certificate "/etc/letsencrypt/live/<%= config['CallCertName'] %>/fullchain.pem";
|
|
21
|
+
ssl_certificate_key "/etc/letsencrypt/live/<%= config['CallCertName'] %>/privkey.pem";
|
|
22
|
+
ssl_trusted_certificate "/etc/letsencrypt/live/<%= config['CallCertName'] %>/chain.pem";
|
|
23
|
+
<% end %>
|
|
24
|
+
|
|
25
|
+
access_log /var/log/nginx/openvidu-call.access.log;
|
|
26
|
+
error_log /var/log/nginx/openvidu-call.error.log;
|
|
27
|
+
|
|
28
|
+
# Proxy site
|
|
29
|
+
location / {
|
|
30
|
+
proxy_pass http://127.0.0.1:6080;
|
|
31
|
+
include config-lmm/proxy.conf;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
}
|
|
35
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
[Unit]
|
|
4
|
+
Description=OpenVidu Call container
|
|
5
|
+
After=local-fs.target
|
|
6
|
+
|
|
7
|
+
[Container]
|
|
8
|
+
Image=docker.io/openvidu/openvidu-call:main
|
|
9
|
+
EnvironmentFile=/var/lib/openvidu/.config/containers/systemd/OpenVidu.env
|
|
10
|
+
PublishPort=127.0.0.1:6080:6080
|
|
11
|
+
UserNS=keep-id:uid=1000,gid=1000
|
|
12
|
+
AutoUpdate=registry
|
|
13
|
+
|
|
14
|
+
[Install]
|
|
15
|
+
WantedBy=multi-user.target default.target
|
|
@@ -4,11 +4,12 @@ Description=Peppermint Ticket Management container
|
|
|
4
4
|
After=local-fs.target
|
|
5
5
|
|
|
6
6
|
[Container]
|
|
7
|
-
Image=pepperlabs/peppermint:latest
|
|
7
|
+
Image=docker.io/pepperlabs/peppermint:latest
|
|
8
8
|
EnvironmentFile=/var/lib/peppermint/.config/containers/systemd/Peppermint.env
|
|
9
9
|
Network=slirp4netns:allow_host_loopback=true
|
|
10
10
|
PublishPort=127.0.0.1:13000:3000
|
|
11
11
|
PublishPort=127.0.0.1:15003:5003
|
|
12
|
+
AutoUpdate=registry
|
|
12
13
|
|
|
13
14
|
[Install]
|
|
14
15
|
WantedBy=multi-user.target default.target
|
|
@@ -12,9 +12,13 @@ module ConfigLMM
|
|
|
12
12
|
plugins[:Linux].ensurePackages([PACKAGE_NAME, 'CyrusSASL'], target['Location'])
|
|
13
13
|
plugins[:Linux].ensureServiceAutoStart(SERVICE_NAME, target['Location'])
|
|
14
14
|
|
|
15
|
+
activeState['Instance'] = target['Instance']
|
|
16
|
+
activeState['AlternativePort'] = target['AlternativePort']
|
|
15
17
|
deploySettings(target, target['Location'], options)
|
|
16
18
|
|
|
17
19
|
plugins[:Linux].startService(SERVICE_NAME, target['Location'])
|
|
20
|
+
|
|
21
|
+
activeState['Status'] = State::STATUS_DEPLOYED
|
|
18
22
|
end
|
|
19
23
|
|
|
20
24
|
def deploySettings(target, location, options)
|
|
@@ -91,14 +95,11 @@ module ConfigLMM
|
|
|
91
95
|
|
|
92
96
|
|
|
93
97
|
if target['AlternativePort']
|
|
94
|
-
|
|
95
|
-
self.class.sshExec!(ssh, "firewall-cmd -q --permanent --add-port='#{target['AlternativePort']}/tcp'")
|
|
98
|
+
Framework::LinuxApp.firewallAddPort("#{target['AlternativePort']}/tcp", ssh)
|
|
96
99
|
else
|
|
97
|
-
|
|
98
|
-
self.class.sshExec!(ssh, "firewall-cmd -q --permanent --add-service='smtp'")
|
|
100
|
+
Framework::LinuxApp.firewallAddService('smtp', ssh)
|
|
99
101
|
end
|
|
100
|
-
|
|
101
|
-
self.class.sshExec!(ssh, "firewall-cmd -q --permanent --add-service='smtps'")
|
|
102
|
+
Framework::LinuxApp.firewallAddService('smtps', ssh)
|
|
102
103
|
|
|
103
104
|
ssh.scp.upload!(__dir__ + '/smtpd.conf', '/etc/sasl2/smtpd.conf')
|
|
104
105
|
self.class.sshExec!(ssh, "touch /etc/sasldb2")
|
|
@@ -178,6 +179,31 @@ module ConfigLMM
|
|
|
178
179
|
end
|
|
179
180
|
end
|
|
180
181
|
|
|
182
|
+
def cleanup(configs, state, context, options)
|
|
183
|
+
cleanupType(:Postfix, configs, state, context, options) do |item, id, state, context, options, ssh|
|
|
184
|
+
instances = self.class.exec('postmulti -l | wc -l', ssh, true).strip.to_i
|
|
185
|
+
if instances <= 1
|
|
186
|
+
Framework::LinuxApp.stopService(SERVICE_NAME, ssh, options[:dry])
|
|
187
|
+
Framework::LinuxApp.firewallRemoveService('smtps', ssh, options[:dry])
|
|
188
|
+
if item['AlternativePort']
|
|
189
|
+
Framework::LinuxApp.firewallRemovePort("#{item['AlternativePort']}/tcp", ssh, options[:dry])
|
|
190
|
+
else
|
|
191
|
+
Framework::LinuxApp.firewallRemoveService('smtp', ssh, options[:dry])
|
|
192
|
+
end
|
|
193
|
+
Framework::LinuxApp.removePackage(PACKAGE_NAME, ssh, options[:dry])
|
|
194
|
+
|
|
195
|
+
state.item(id)['Status'] = State::STATUS_DELETED unless options[:dry]
|
|
196
|
+
|
|
197
|
+
if options[:destroy]
|
|
198
|
+
rm('/etc/postfix', options[:dry], ssh)
|
|
199
|
+
|
|
200
|
+
state.item(id)['Status'] = State::STATUS_DESTROYED unless options[:dry]
|
|
201
|
+
end
|
|
202
|
+
else
|
|
203
|
+
prompt.say('Postfix multiple instance cleanup not implemented!', :color => :red)
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
end
|
|
181
207
|
end
|
|
182
208
|
|
|
183
209
|
end
|
|
@@ -12,26 +12,60 @@ module ConfigLMM
|
|
|
12
12
|
CONFIG_FILE = 'data/postgresql.conf'
|
|
13
13
|
|
|
14
14
|
def actionPostgreSQLDeploy(id, target, activeState, context, options)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
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
|
|
18
27
|
|
|
19
28
|
if target['Location'] && target['Location'] != '@me'
|
|
20
29
|
uri = Addressable::URI.parse(target['Location'])
|
|
21
30
|
raise Framework::PluginProcessError.new("#{id}: Unknown Protocol: #{uri.scheme}!") if uri.scheme != 'ssh'
|
|
22
31
|
|
|
23
32
|
self.class.sshStart(uri) do |ssh|
|
|
24
|
-
|
|
25
|
-
|
|
33
|
+
if target['Deploy']
|
|
34
|
+
self.updateSettingsOverSSH(target, ssh, options)
|
|
35
|
+
self.class.sshExec!(ssh, "su --login #{USER_NAME} --command 'pg_ctl reload'")
|
|
36
|
+
end
|
|
26
37
|
self.class.createUsersOverSSH(target, ssh)
|
|
27
38
|
self.class.createDatabasesOverSSH(target, ssh)
|
|
28
39
|
self.class.createPublicationsOverSSH(target, ssh)
|
|
29
40
|
self.class.createSubscriptionsOverSSH(target, ssh)
|
|
30
41
|
end
|
|
31
42
|
else
|
|
32
|
-
|
|
43
|
+
if target['Deploy']
|
|
44
|
+
`pg_ctl reload`
|
|
45
|
+
end
|
|
33
46
|
end
|
|
34
47
|
|
|
48
|
+
activeState['Status'] = State::STATUS_DEPLOYED
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def cleanup(configs, state, context, options)
|
|
52
|
+
cleanupType(:PostgreSQL, configs, state, context, options) do |item, id, state, context, options, ssh|
|
|
53
|
+
if item['Deploy']
|
|
54
|
+
Framework::LinuxApp.stopService(SERVICE_NAME, ssh, options[:dry])
|
|
55
|
+
Framework::LinuxApp.disableService(SERVICE_NAME, ssh, options[:dry])
|
|
56
|
+
Framework::LinuxApp.removePackage(PACKAGE_NAME, ssh, options[:dry])
|
|
57
|
+
|
|
58
|
+
state.item(id)['Status'] = State::STATUS_DELETED unless options[:dry]
|
|
59
|
+
|
|
60
|
+
if options[:destroy]
|
|
61
|
+
Framework::LinuxApp.deleteUserAndGroup(USER_NAME, ssh, options[:dry])
|
|
62
|
+
|
|
63
|
+
state.item(id)['Status'] = State::STATUS_DESTROYED unless options[:dry]
|
|
64
|
+
end
|
|
65
|
+
else
|
|
66
|
+
# TODO
|
|
67
|
+
end
|
|
68
|
+
end
|
|
35
69
|
end
|
|
36
70
|
|
|
37
71
|
def updateListenLocal(target)
|
|
@@ -154,6 +188,26 @@ module ConfigLMM
|
|
|
154
188
|
self.sshExec!(ssh, cmd)
|
|
155
189
|
end
|
|
156
190
|
|
|
191
|
+
def self.updateOwner(db, owner, ssh)
|
|
192
|
+
sql = "SELECT tablename FROM pg_tables WHERE NOT schemaname IN ('pg_catalog', 'information_schema')"
|
|
193
|
+
tables = self.executeSQL(sql, db, ssh, false, ['--csv', '--tuples-only']).strip.lines
|
|
194
|
+
tables.each do |table|
|
|
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
|
|
203
|
+
|
|
204
|
+
sql = "SELECT table_name FROM information_schema.views WHERE NOT table_schema IN ('pg_catalog', 'information_schema')"
|
|
205
|
+
views = self.executeSQL(sql, db, ssh, false, ['--csv', '--tuples-only']).strip.lines
|
|
206
|
+
views.each do |view|
|
|
207
|
+
self.executeSQL("ALTER VIEW public.#{view} OWNER TO #{owner};", db, ssh)
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
157
211
|
def updateConfigOverSSH(ssh, cmd)
|
|
158
212
|
dir = ''
|
|
159
213
|
distroID = self.class.distroID(ssh)
|
|
@@ -163,12 +217,27 @@ module ConfigLMM
|
|
|
163
217
|
end
|
|
164
218
|
|
|
165
219
|
def self.createRemoteUserAndDBOverSSH(settings, user, password, ssh)
|
|
166
|
-
|
|
167
|
-
|
|
220
|
+
self.executeRemotely(settings, ssh) do |ssh|
|
|
221
|
+
self.createUserAndDBOverSSH(user, password, ssh)
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def self.dropUserAndDB(settings, user, ssh, dry)
|
|
226
|
+
self.executeRemotely(settings, ssh) do |ssh|
|
|
227
|
+
self.exec("su --login #{USER_NAME} --command 'dropdb #{user}'", ssh, true, dry)
|
|
228
|
+
self.exec("su --login #{USER_NAME} --command 'dropuser #{user}'", ssh, true, dry)
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
def self.createExtensions(settings, db, extensions, ssh)
|
|
233
|
+
self.executeRemotely(settings, ssh) do |ssh|
|
|
234
|
+
extensions.each do |extension|
|
|
235
|
+
self.executeSQL("CREATE EXTENSION #{extension}", db, ssh, true)
|
|
168
236
|
end
|
|
237
|
+
end
|
|
169
238
|
end
|
|
170
239
|
|
|
171
|
-
def self.
|
|
240
|
+
def self.executeRemotely(settings, ssh = nil)
|
|
172
241
|
settings['HostName'] = 'localhost' unless settings['HostName']
|
|
173
242
|
if settings['HostName'] == 'localhost'
|
|
174
243
|
yield(ssh)
|
|
@@ -199,10 +268,10 @@ module ConfigLMM
|
|
|
199
268
|
end
|
|
200
269
|
end
|
|
201
270
|
|
|
202
|
-
def self.executeSQL(sql, db, ssh = nil, allowFailure = false)
|
|
271
|
+
def self.executeSQL(sql, db, ssh = nil, allowFailure = false, options = [])
|
|
203
272
|
if ssh
|
|
204
273
|
db = 'postgres' unless db
|
|
205
|
-
cmd = " su --login #{USER_NAME} --command ' psql --dbname=#{db} --command=\"#{sql.gsub("'", "
|
|
274
|
+
cmd = " su --login #{USER_NAME} --command ' psql #{options.join(' ')} --dbname=#{db} --command=\"#{sql.gsub("'", "'\"'\"'")};\"'"
|
|
206
275
|
self.sshExec!(ssh, cmd, allowFailure)
|
|
207
276
|
else
|
|
208
277
|
# TODO
|
|
@@ -0,0 +1,75 @@
|
|
|
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
|
+
access_log /var/log/nginx/roundcube.access.log;
|
|
35
|
+
error_log /var/log/nginx/roundcube.error.log;
|
|
36
|
+
|
|
37
|
+
index index.php;
|
|
38
|
+
root /usr/share/webapps/roundcubemail;
|
|
39
|
+
|
|
40
|
+
include config-lmm/private.conf;
|
|
41
|
+
include config-lmm/errors.conf;
|
|
42
|
+
|
|
43
|
+
location / {
|
|
44
|
+
try_files $uri $uri/ $uri/index.php;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
location ~ \.php$
|
|
48
|
+
{
|
|
49
|
+
fastcgi_pass roundcube;
|
|
50
|
+
include fastcgi.conf;
|
|
51
|
+
|
|
52
|
+
try_files $uri =404;
|
|
53
|
+
fastcgi_index index.php;
|
|
54
|
+
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
|
55
|
+
include fastcgi_params;
|
|
56
|
+
|
|
57
|
+
fastcgi_intercept_errors off;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
location ~ ^/(README|INSTALL|LICENSE|CHANGELOG|UPGRADING)$
|
|
61
|
+
{
|
|
62
|
+
deny all;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
location ~ ^/(bin|SQL)/
|
|
66
|
+
{
|
|
67
|
+
deny all;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
location ~* \.(jpg|jpeg|gif|png|webp|svg|woff|woff2|ttf|css|js|ico|xml)$
|
|
71
|
+
{
|
|
72
|
+
access_log off;
|
|
73
|
+
expires 360d;
|
|
74
|
+
}
|
|
75
|
+
}
|