smartmachine 1.2.3 → 1.3.1
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/lib/smart_machine/apps/app.rb +1 -0
- data/lib/smart_machine/buildpackers/buildpacker.rb +2 -2
- data/lib/smart_machine/commands/grid.rb +8 -0
- data/lib/smart_machine/commands/grid_commands/emailer.rb +107 -0
- data/lib/smart_machine/commands/grid_commands/roundcube.rb +107 -0
- data/lib/smart_machine/configuration.rb +35 -2
- data/lib/smart_machine/credentials.rb +10 -0
- data/lib/smart_machine/engine.rb +7 -1
- data/lib/smart_machine/grids/adminer.rb +1 -0
- data/lib/smart_machine/grids/certbot.rb +1 -0
- data/lib/smart_machine/grids/emailer/imapsync.rb +7 -0
- data/lib/smart_machine/grids/emailer.rb +188 -0
- data/lib/smart_machine/grids/haproxy.rb +1 -0
- data/lib/smart_machine/grids/mariadb.rb +1 -0
- data/lib/smart_machine/grids/postgresql.rb +1 -0
- data/lib/smart_machine/grids/roundcube/.keep +0 -0
- data/lib/smart_machine/grids/roundcube.rb +184 -0
- data/lib/smart_machine/machine.rb +7 -0
- data/lib/smart_machine/syncer.rb +10 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/docker/command.rb +50 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/docker/entrypoint.rb +196 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/docker/logtailer.rb +75 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/dovecot/conf.d/10-auth.conf +132 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/dovecot/conf.d/10-mail.conf +427 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/dovecot/conf.d/10-master.conf +153 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/dovecot/conf.d/10-ssl.conf +87 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/dovecot/conf.d/15-mailboxes.conf +94 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/dovecot/conf.d/20-imap.conf +102 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/dovecot/conf.d/20-lmtp.conf +43 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/dovecot/conf.d/90-quota.conf +114 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/dovecot/conf.d/90-sieve.conf +229 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/dovecot/dovecot-sql.conf.ext +163 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/dovecot/sieve/learn-ham.sh +2 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/dovecot/sieve/learn-ham.sieve +5 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/dovecot/sieve/learn-spam.sh +2 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/dovecot/sieve/learn-spam.sieve +2 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/dovecot/sieve-after/spam-to-folder.sieve +6 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/haproxy/haproxy.cfg +58 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/monit/conf.d/services.cfg +70 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/monit/monitrc +344 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/opendkim.conf +71 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/postfix/main.cf +128 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/postfix/master.cf +149 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/postfix/mysql-sender-login-maps.cf +7 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/postfix/mysql-virtual-alias-domains.cf +7 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/postfix/mysql-virtual-alias-maps-domains.cf +7 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/postfix/mysql-virtual-alias-maps-masters.cf +7 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/postfix/mysql-virtual-alias-maps-users.cf +7 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/postfix/mysql-virtual-alias-maps-userstothemselves.cf +7 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/postfix/mysql-virtual-mailbox-domains.cf +7 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/postfix/mysql-virtual-mailbox-maps.cf +7 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/postfix-policyd-spf-python/policyd-spf.conf +12 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/spamassassin/local.cf +124 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer/usr/local/bin/quota-warning.sh +22 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/emailer.yml +37 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/engine.yml +2 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/roundcube/docker/custom-docker-entrypoint.sh +185 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/roundcube/docker/entrypoint.rb +58 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/roundcube/etc/apache2/sites-available/000-default.conf +36 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/roundcube/usr/local/etc/php/conf.d/zzz_roundcube-custom.ini +4 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/roundcube/var/roundcube/config/config.custom.inc.php +25 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/roundcube/var/www/html/plugins/password/config.inc.php +523 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/roundcube.yml +49 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/users.yml +1 -1
- data/lib/smart_machine/version.rb +2 -2
- data/lib/smart_machine.rb +2 -0
- metadata +89 -8
@@ -0,0 +1,184 @@
|
|
1
|
+
module SmartMachine
|
2
|
+
class Grids
|
3
|
+
class Roundcube < SmartMachine::Base
|
4
|
+
def initialize(name:)
|
5
|
+
config = SmartMachine.config.grids.roundcube.dig(name.to_sym)
|
6
|
+
raise "roundcube config for #{name} not found." unless config
|
7
|
+
|
8
|
+
@fqdn = config.dig(:fqdn)
|
9
|
+
@image = "smartmachine/roundcube:#{SmartMachine.version}"
|
10
|
+
@sysadmin_email = config.dig(:sysadmin_email)
|
11
|
+
@networks = config.dig(:networks)
|
12
|
+
@database_type = config.dig(:database_type)
|
13
|
+
@database_host = config.dig(:database_host)
|
14
|
+
@database_port = config.dig(:database_port)
|
15
|
+
@database_user = config.dig(:database_user)
|
16
|
+
@database_pass = config.dig(:database_pass)
|
17
|
+
@database_name = config.dig(:database_name)
|
18
|
+
@mail_host = config.dig(:mail_host)
|
19
|
+
@mail_port = config.dig(:mail_port)
|
20
|
+
@smtp_host = config.dig(:smtp_host)
|
21
|
+
@smtp_port = config.dig(:smtp_port)
|
22
|
+
@request_path = config.dig(:request_path)
|
23
|
+
@plugins = config.dig(:plugins)
|
24
|
+
@plugins_password_database_type = config.dig(:plugins_password_database_type)
|
25
|
+
@plugins_password_database_host = config.dig(:plugins_password_database_host)
|
26
|
+
@plugins_password_database_user = config.dig(:plugins_password_database_user)
|
27
|
+
@plugins_password_database_pass = config.dig(:plugins_password_database_pass)
|
28
|
+
@plugins_password_database_name = config.dig(:plugins_password_database_name)
|
29
|
+
@skin = config.dig(:skin)
|
30
|
+
@upload_max_filesize = config.dig(:upload_max_filesize)
|
31
|
+
@aspell_dictionaries = config.dig(:aspell_dictionaries)
|
32
|
+
|
33
|
+
@name = name.to_s
|
34
|
+
@home_dir = File.expand_path('~')
|
35
|
+
end
|
36
|
+
|
37
|
+
def installer
|
38
|
+
unless system("docker image inspect #{@image}", [:out, :err] => File::NULL)
|
39
|
+
puts "-----> Creating image #{@image} ... "
|
40
|
+
command = [
|
41
|
+
"docker image build -t #{@image}",
|
42
|
+
"--build-arg SMARTMACHINE_VERSION=#{SmartMachine.version}",
|
43
|
+
"-f- #{SmartMachine.config.gem_dir}/lib/smart_machine/grids/roundcube",
|
44
|
+
"<<'EOF'\n#{dockerfile}EOF"
|
45
|
+
]
|
46
|
+
if system(command.join(" "), out: File::NULL)
|
47
|
+
puts "done"
|
48
|
+
else
|
49
|
+
raise "Error: Could not install image: #{@image}"
|
50
|
+
end
|
51
|
+
else
|
52
|
+
raise "Error: Image already installed: #{@image}. Please uninstall using 'smartmachine grids roundcube uninstall' and try installing again."
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def uninstaller
|
57
|
+
unless system("docker inspect -f '{{.State.Running}}' '#{@name}'", [:out, :err] => File::NULL)
|
58
|
+
if system("docker image inspect #{@image}", [:out, :err] => File::NULL)
|
59
|
+
puts "-----> Removing image #{@image} ... "
|
60
|
+
if system("docker image rm #{@image}", out: File::NULL)
|
61
|
+
puts "done"
|
62
|
+
end
|
63
|
+
else
|
64
|
+
raise "Error: Roundcube already uninstalled. Please install using 'smartmachine grids roundcube install' and try uninstalling again."
|
65
|
+
end
|
66
|
+
else
|
67
|
+
raise "Error: Roundcube is currently running. Please stop the roundcube using 'smartmachine grids roundcube down' and try uninstalling again."
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def uper
|
72
|
+
if system("docker image inspect #{@image}", [:out, :err] => File::NULL)
|
73
|
+
FileUtils.mkdir_p("#{@home_dir}/machine/grids/roundcube/#{@name}/backups")
|
74
|
+
FileUtils.mkdir_p("#{@home_dir}/machine/grids/roundcube/#{@name}/data/roundcube-temp")
|
75
|
+
|
76
|
+
# Setting entrypoint permission.
|
77
|
+
system("chmod +x #{@home_dir}/machine/config/roundcube/docker/custom-docker-entrypoint.sh")
|
78
|
+
system("chmod +x #{@home_dir}/machine/config/roundcube/docker/entrypoint.rb")
|
79
|
+
|
80
|
+
# Creating & Starting containers
|
81
|
+
print "-----> Creating container #{@name} ... "
|
82
|
+
|
83
|
+
command = [
|
84
|
+
"docker create",
|
85
|
+
"--name='#{@name}'",
|
86
|
+
"--env VIRTUAL_HOST=#{@fqdn}",
|
87
|
+
"--env VIRTUAL_PATH='#{@request_path}'",
|
88
|
+
"--env LETSENCRYPT_HOST=#{@fqdn}",
|
89
|
+
"--env LETSENCRYPT_EMAIL=#{@sysadmin_email}",
|
90
|
+
"--env LETSENCRYPT_TEST=false",
|
91
|
+
"--env CONTAINER_NAME='#{@name}'",
|
92
|
+
"--env FQDN='#{@fqdn}'",
|
93
|
+
"--env ROUNDCUBEMAIL_DEFAULT_HOST='#{@mail_host}'",
|
94
|
+
"--env ROUNDCUBEMAIL_DEFAULT_PORT='#{@mail_port}'",
|
95
|
+
"--env ROUNDCUBEMAIL_SMTP_SERVER='#{@smtp_host}'",
|
96
|
+
"--env ROUNDCUBEMAIL_SMTP_PORT='#{@smtp_port}'",
|
97
|
+
"--env ROUNDCUBEMAIL_USERNAME_DOMAIN=''",
|
98
|
+
"--env ROUNDCUBEMAIL_REQUEST_PATH='#{@request_path}'",
|
99
|
+
"--env ROUNDCUBEMAIL_PLUGINS='#{@plugins.join(',')}'",
|
100
|
+
"--env ROUNDCUBEMAIL_PLUGINS_PASSWORD_DATABASE_TYPE='#{@plugins_password_database_type}'",
|
101
|
+
"--env ROUNDCUBEMAIL_PLUGINS_PASSWORD_DATABASE_HOST='#{@plugins_password_database_host}'",
|
102
|
+
"--env ROUNDCUBEMAIL_PLUGINS_PASSWORD_DATABASE_USER='#{@plugins_password_database_user}'",
|
103
|
+
"--env ROUNDCUBEMAIL_PLUGINS_PASSWORD_DATABASE_PASS='#{@plugins_password_database_pass}'",
|
104
|
+
"--env ROUNDCUBEMAIL_PLUGINS_PASSWORD_DATABASE_NAME='#{@plugins_password_database_name}'",
|
105
|
+
"--env ROUNDCUBEMAIL_INSTALL_PLUGINS='1'",
|
106
|
+
"--env ROUNDCUBEMAIL_SKIN='#{@skin}'",
|
107
|
+
"--env ROUNDCUBEMAIL_UPLOAD_MAX_FILESIZE='#{@upload_max_filesize}'",
|
108
|
+
"--env ROUNDCUBEMAIL_SPELLCHECK_URI=''",
|
109
|
+
"--env ROUNDCUBEMAIL_ASPELL_DICTS='#{@aspell_dictionaries.join(',')}'",
|
110
|
+
"--env ROUNDCUBEMAIL_DB_TYPE='#{@database_type}'",
|
111
|
+
"--env ROUNDCUBEMAIL_DB_HOST='#{@database_host}'",
|
112
|
+
"--env ROUNDCUBEMAIL_DB_PORT='#{@database_port}'",
|
113
|
+
"--env ROUNDCUBEMAIL_DB_USER='#{@database_user}'",
|
114
|
+
"--env ROUNDCUBEMAIL_DB_PASSWORD='#{@database_pass}'",
|
115
|
+
"--env ROUNDCUBEMAIL_DB_NAME='#{@database_name}'",
|
116
|
+
"--volume='#{@home_dir}/smartmachine/config/roundcube:/smartmachine/config/roundcube:ro'",
|
117
|
+
"--volume='#{@home_dir}/smartmachine/grids/roundcube/#{@name}/data/roundcube-temp:/tmp/roundcube-temp'",
|
118
|
+
"--tmpfs /run/tmpfs",
|
119
|
+
"--init",
|
120
|
+
"--restart='always'",
|
121
|
+
"--network='nginx-network'",
|
122
|
+
"#{@image}"
|
123
|
+
]
|
124
|
+
if system(command.compact.join(" "), out: File::NULL)
|
125
|
+
@networks.each do |network|
|
126
|
+
system("docker network connect #{network} #{@name}")
|
127
|
+
end
|
128
|
+
|
129
|
+
puts "done"
|
130
|
+
puts "-----> Starting container #{@name} ... "
|
131
|
+
if system("docker start #{@name}", out: File::NULL)
|
132
|
+
puts "done"
|
133
|
+
else
|
134
|
+
raise "Error: Could not start container: #{@name}"
|
135
|
+
end
|
136
|
+
else
|
137
|
+
raise "Error: Could not create container: #{@name}"
|
138
|
+
end
|
139
|
+
else
|
140
|
+
raise "Error: Could not find image: #{@image}"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def downer
|
145
|
+
# Disconnecting networks
|
146
|
+
@networks.reverse.each do |network|
|
147
|
+
system("docker network disconnect #{network} #{@name}")
|
148
|
+
end
|
149
|
+
|
150
|
+
# Stopping & Removing containers - in reverse order
|
151
|
+
print "-----> Stopping container #{@name} ... "
|
152
|
+
if system("docker stop '#{@name}'", out: File::NULL)
|
153
|
+
puts "done"
|
154
|
+
print "-----> Removing container #{@name} ... "
|
155
|
+
if system("docker rm '#{@name}'", out: File::NULL)
|
156
|
+
puts "done"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
private
|
162
|
+
|
163
|
+
def dockerfile
|
164
|
+
file = <<~'DOCKERFILE'
|
165
|
+
ARG SMARTMACHINE_VERSION
|
166
|
+
|
167
|
+
FROM roundcube/roundcubemail:1.6.8-apache
|
168
|
+
LABEL maintainer="plainsource <plainsource@humanmind.me>"
|
169
|
+
|
170
|
+
RUN apt-get update && \
|
171
|
+
apt-get install -y --no-install-recommends \
|
172
|
+
ruby-full build-essential zlib1g-dev \
|
173
|
+
dovecot-common && \
|
174
|
+
rm -rf /var/lib/apt/lists/*
|
175
|
+
|
176
|
+
ENTRYPOINT ["/smartmachine/config/roundcube/docker/custom-docker-entrypoint.sh"]
|
177
|
+
CMD ["apache2-foreground"]
|
178
|
+
DOCKERFILE
|
179
|
+
|
180
|
+
format(file, "mailname": @mailname)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
@@ -77,6 +77,13 @@ module SmartMachine
|
|
77
77
|
# puts 'You may be prompted to make a menu selection when the Grub package is updated on Ubuntu. If prompted, select keep the local version currently installed.'
|
78
78
|
|
79
79
|
# dpkg-reconfigure tzdata
|
80
|
+
# debconf-set-selections <<EOF
|
81
|
+
# tzdata tzdata/Areas select Asia
|
82
|
+
# tzdata tzdata/Areas seen true
|
83
|
+
# tzdata tzdata/Zones/Asia select Kolkata
|
84
|
+
# tzdata tzdata/Zones/Asia seen true
|
85
|
+
# EOF
|
86
|
+
# dpkg-reconfigure -fnoninteractive tzdata
|
80
87
|
# date
|
81
88
|
|
82
89
|
# hostnamectl set-hostname SmartMachine.credentials.machine[:name]
|
data/lib/smart_machine/syncer.rb
CHANGED
@@ -64,6 +64,9 @@ module SmartMachine
|
|
64
64
|
'grids/elasticsearch',
|
65
65
|
'grids/elasticsearch/***',
|
66
66
|
|
67
|
+
'grids/emailer',
|
68
|
+
'grids/emailer/***',
|
69
|
+
|
67
70
|
'grids/minio',
|
68
71
|
'grids/minio/***',
|
69
72
|
|
@@ -103,11 +106,17 @@ module SmartMachine
|
|
103
106
|
'bin/smartmachine',
|
104
107
|
|
105
108
|
'config',
|
109
|
+
'config/emailer',
|
110
|
+
'config/emailer/***',
|
106
111
|
'config/mysql',
|
107
112
|
'config/mysql/schedule.rb',
|
108
113
|
'config/phpmyadmin',
|
109
114
|
'config/phpmyadmin/***',
|
115
|
+
'config/roundcube',
|
116
|
+
'config/roundcube/***',
|
110
117
|
'config/credentials.yml.enc',
|
118
|
+
'config/emailer.yml',
|
119
|
+
'config/engine.yml',
|
111
120
|
'config/environment.rb',
|
112
121
|
'config/elasticsearch.yml',
|
113
122
|
'config/minio.yml',
|
@@ -117,6 +126,7 @@ module SmartMachine
|
|
117
126
|
'config/phpmyadmin.yml',
|
118
127
|
'config/prereceiver.yml',
|
119
128
|
'config/redis.yml',
|
129
|
+
'config/roundcube.yml',
|
120
130
|
'config/terminal.yml',
|
121
131
|
|
122
132
|
'grids',
|
@@ -0,0 +1,50 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
STDOUT.sync = true
|
5
|
+
|
6
|
+
class Services
|
7
|
+
def initialize
|
8
|
+
@services = %w(rsyslog haproxy spamassassin spamassassin.update opendkim postfix dovecot)
|
9
|
+
end
|
10
|
+
|
11
|
+
def start
|
12
|
+
puts "Starting Services..."
|
13
|
+
@services.each { |service| system("monit start #{service}") }
|
14
|
+
system("monit")
|
15
|
+
|
16
|
+
puts "Starting Logtailer..."
|
17
|
+
system("/usr/bin/logtailer.rb start")
|
18
|
+
end
|
19
|
+
|
20
|
+
def stop(signo)
|
21
|
+
puts "Stopping Logtailer..."
|
22
|
+
system("/usr/bin/logtailer.rb stop")
|
23
|
+
|
24
|
+
puts "Stopping Services... SIGNAL: SIG#{Signal.signame(signo)}."
|
25
|
+
system("monit quit")
|
26
|
+
sleep(3)
|
27
|
+
@services.reverse.each { |service| system("monit stop #{service}") }
|
28
|
+
|
29
|
+
puts "Flushing Logtailer..."
|
30
|
+
system("/usr/bin/logtailer.rb flush")
|
31
|
+
|
32
|
+
exit
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
trap('SIGINT') do |signo|
|
37
|
+
Services.new.stop(signo)
|
38
|
+
end
|
39
|
+
|
40
|
+
trap('SIGTERM') do |signo|
|
41
|
+
Services.new.stop(signo)
|
42
|
+
end
|
43
|
+
|
44
|
+
at_exit do
|
45
|
+
# Clean up.
|
46
|
+
end
|
47
|
+
|
48
|
+
Services.new.start
|
49
|
+
|
50
|
+
sleep
|
@@ -0,0 +1,196 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'fileutils'
|
5
|
+
require 'logger'
|
6
|
+
|
7
|
+
logger = Logger.new(STDOUT)
|
8
|
+
STDOUT.sync = true
|
9
|
+
|
10
|
+
def update_envkeys_in(filepaths, envkeys)
|
11
|
+
filepaths.each do |filepath|
|
12
|
+
str = File.read(filepath)
|
13
|
+
str = str.gsub(/%(?!<)/, '%%')
|
14
|
+
str = format(str, envkeys)
|
15
|
+
File.open(filepath, "w") { |file| file << str }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# initial setup
|
20
|
+
unless File.exist?('/run/initial_container_start')
|
21
|
+
FileUtils.touch('/run/initial_container_start')
|
22
|
+
|
23
|
+
# EnvKeys
|
24
|
+
envkeys = {
|
25
|
+
container_name: ENV.delete('CONTAINER_NAME'),
|
26
|
+
fqdn: ENV.delete('FQDN'),
|
27
|
+
mailname: ENV.delete('MAILNAME'),
|
28
|
+
sysadmin_email: ENV.delete('SYSADMIN_EMAIL'),
|
29
|
+
mysql_host: ENV.delete('MYSQL_HOST'),
|
30
|
+
mysql_port: ENV.delete('MYSQL_PORT'),
|
31
|
+
mysql_user: ENV.delete('MYSQL_USER'),
|
32
|
+
mysql_password: ENV.delete('MYSQL_PASSWORD'),
|
33
|
+
mysql_database_name: ENV.delete('MYSQL_DATABASE_NAME'),
|
34
|
+
monit_smtp_email_name: ENV.delete('MONIT_SMTP_EMAIL_NAME'),
|
35
|
+
monit_smtp_email_address: ENV.delete('MONIT_SMTP_EMAIL_ADDRESS'),
|
36
|
+
monit_smtp_host: ENV.delete('MONIT_SMTP_HOST'),
|
37
|
+
monit_smtp_port: ENV.delete('MONIT_SMTP_PORT'),
|
38
|
+
monit_smtp_username: ENV.delete('MONIT_SMTP_USERNAME'),
|
39
|
+
monit_smtp_password: ENV.delete('MONIT_SMTP_PASSWORD'),
|
40
|
+
oracle_ips_allowed: ENV.delete('ORACLE_IPS_ALLOWED'),
|
41
|
+
oracle_deflect_url: ENV.delete('ORACLE_DEFLECT_URL'),
|
42
|
+
timezone: `cat /etc/timezone`.chomp
|
43
|
+
}
|
44
|
+
|
45
|
+
# rsyslog
|
46
|
+
# imklog module is commented in rsyslog.conf because rsyslog does not
|
47
|
+
# have privileges to run it and hence throws error on startup.
|
48
|
+
system("sed -i '/imklog/s/^/#/' /etc/rsyslog.conf")
|
49
|
+
|
50
|
+
# Postfix
|
51
|
+
FileUtils.cp '/smartmachine/config/emailer/etc/postfix/main.cf', '/etc/postfix/main.cf'
|
52
|
+
FileUtils.cp '/smartmachine/config/emailer/etc/postfix/master.cf', '/etc/postfix/master.cf'
|
53
|
+
FileUtils.cp '/smartmachine/config/emailer/etc/postfix/mysql-sender-login-maps.cf', '/etc/postfix/mysql-sender-login-maps.cf'
|
54
|
+
FileUtils.cp '/smartmachine/config/emailer/etc/postfix/mysql-virtual-alias-domains.cf', '/etc/postfix/mysql-virtual-alias-domains.cf'
|
55
|
+
FileUtils.cp '/smartmachine/config/emailer/etc/postfix/mysql-virtual-alias-maps-domains.cf', '/etc/postfix/mysql-virtual-alias-maps-domains.cf'
|
56
|
+
FileUtils.cp '/smartmachine/config/emailer/etc/postfix/mysql-virtual-alias-maps-masters.cf', '/etc/postfix/mysql-virtual-alias-maps-masters.cf'
|
57
|
+
FileUtils.cp '/smartmachine/config/emailer/etc/postfix/mysql-virtual-alias-maps-users.cf', '/etc/postfix/mysql-virtual-alias-maps-users.cf'
|
58
|
+
FileUtils.cp '/smartmachine/config/emailer/etc/postfix/mysql-virtual-alias-maps-userstothemselves.cf', '/etc/postfix/mysql-virtual-alias-maps-userstothemselves.cf'
|
59
|
+
FileUtils.cp '/smartmachine/config/emailer/etc/postfix/mysql-virtual-mailbox-domains.cf', '/etc/postfix/mysql-virtual-mailbox-domains.cf'
|
60
|
+
FileUtils.cp '/smartmachine/config/emailer/etc/postfix/mysql-virtual-mailbox-maps.cf', '/etc/postfix/mysql-virtual-mailbox-maps.cf'
|
61
|
+
FileUtils.cp '/smartmachine/config/emailer/etc/postfix-policyd-spf-python/policyd-spf.conf', '/etc/postfix-policyd-spf-python/policyd-spf.conf'
|
62
|
+
filepaths = [
|
63
|
+
'/etc/postfix/main.cf',
|
64
|
+
'/etc/postfix/mysql-sender-login-maps.cf',
|
65
|
+
'/etc/postfix/mysql-virtual-alias-domains.cf',
|
66
|
+
'/etc/postfix/mysql-virtual-alias-maps-domains.cf',
|
67
|
+
'/etc/postfix/mysql-virtual-alias-maps-masters.cf',
|
68
|
+
'/etc/postfix/mysql-virtual-alias-maps-users.cf',
|
69
|
+
'/etc/postfix/mysql-virtual-alias-maps-userstothemselves.cf',
|
70
|
+
'/etc/postfix/mysql-virtual-mailbox-domains.cf',
|
71
|
+
'/etc/postfix/mysql-virtual-mailbox-maps.cf'
|
72
|
+
]
|
73
|
+
update_envkeys_in(filepaths, envkeys)
|
74
|
+
system("chgrp postfix /etc/postfix/mysql-*.cf")
|
75
|
+
system("chmod -R o-rwx /etc/postfix/mysql-*.cf")
|
76
|
+
|
77
|
+
# Dovecot
|
78
|
+
FileUtils.cp '/smartmachine/config/emailer/etc/dovecot/conf.d/10-auth.conf', '/etc/dovecot/conf.d/10-auth.conf'
|
79
|
+
FileUtils.cp '/smartmachine/config/emailer/etc/dovecot/conf.d/10-mail.conf', '/etc/dovecot/conf.d/10-mail.conf'
|
80
|
+
FileUtils.cp '/smartmachine/config/emailer/etc/dovecot/conf.d/10-master.conf', '/etc/dovecot/conf.d/10-master.conf'
|
81
|
+
FileUtils.cp '/smartmachine/config/emailer/etc/dovecot/conf.d/10-ssl.conf', '/etc/dovecot/conf.d/10-ssl.conf'
|
82
|
+
FileUtils.cp '/smartmachine/config/emailer/etc/dovecot/conf.d/15-mailboxes.conf', '/etc/dovecot/conf.d/15-mailboxes.conf'
|
83
|
+
FileUtils.cp '/smartmachine/config/emailer/etc/dovecot/conf.d/20-imap.conf', '/etc/dovecot/conf.d/20-imap.conf'
|
84
|
+
FileUtils.cp '/smartmachine/config/emailer/etc/dovecot/conf.d/20-lmtp.conf', '/etc/dovecot/conf.d/20-lmtp.conf'
|
85
|
+
FileUtils.cp '/smartmachine/config/emailer/etc/dovecot/conf.d/90-quota.conf', '/etc/dovecot/conf.d/90-quota.conf'
|
86
|
+
FileUtils.cp '/smartmachine/config/emailer/etc/dovecot/conf.d/90-sieve.conf', '/etc/dovecot/conf.d/90-sieve.conf'
|
87
|
+
|
88
|
+
FileUtils.mkdir '/etc/dovecot/sieve'
|
89
|
+
FileUtils.cp '/smartmachine/config/emailer/etc/dovecot/sieve/learn-ham.sh', '/etc/dovecot/sieve/learn-ham.sh'
|
90
|
+
FileUtils.cp '/smartmachine/config/emailer/etc/dovecot/sieve/learn-spam.sh', '/etc/dovecot/sieve/learn-spam.sh'
|
91
|
+
FileUtils.cp '/smartmachine/config/emailer/etc/dovecot/sieve/learn-ham.sieve', '/etc/dovecot/sieve/learn-ham.sieve'
|
92
|
+
FileUtils.cp '/smartmachine/config/emailer/etc/dovecot/sieve/learn-spam.sieve', '/etc/dovecot/sieve/learn-spam.sieve'
|
93
|
+
|
94
|
+
FileUtils.mkdir '/etc/dovecot/sieve-after'
|
95
|
+
FileUtils.cp '/smartmachine/config/emailer/etc/dovecot/sieve-after/spam-to-folder.sieve', '/etc/dovecot/sieve-after/spam-to-folder.sieve'
|
96
|
+
|
97
|
+
FileUtils.cp '/smartmachine/config/emailer/etc/dovecot/dovecot-sql.conf.ext', '/etc/dovecot/dovecot-sql.conf.ext'
|
98
|
+
|
99
|
+
FileUtils.cp '/smartmachine/config/emailer/usr/local/bin/quota-warning.sh', '/usr/local/bin/quota-warning.sh'
|
100
|
+
|
101
|
+
filepaths = [
|
102
|
+
'/etc/dovecot/conf.d/10-ssl.conf',
|
103
|
+
'/etc/dovecot/dovecot-sql.conf.ext',
|
104
|
+
'/usr/local/bin/quota-warning.sh'
|
105
|
+
]
|
106
|
+
update_envkeys_in(filepaths, envkeys)
|
107
|
+
|
108
|
+
system("groupadd -g 5000 vmail")
|
109
|
+
system("useradd -g vmail -u 5000 vmail -d /var/vmail")
|
110
|
+
system("chown -R vmail:vmail /var/vmail")
|
111
|
+
|
112
|
+
system("sievec /etc/dovecot/sieve/learn-ham.sieve")
|
113
|
+
system("sievec /etc/dovecot/sieve/learn-spam.sieve")
|
114
|
+
system("chmod u=rwx,go= /etc/dovecot/sieve/learn-*.sh")
|
115
|
+
system("chown vmail:vmail /etc/dovecot/sieve/learn-*.sh")
|
116
|
+
system("chmod u=rw,go= /etc/dovecot/sieve/learn-*.sieve")
|
117
|
+
system("chown vmail:vmail /etc/dovecot/sieve/learn-*.sieve")
|
118
|
+
system("chmod u=rw,go= /etc/dovecot/sieve/learn-*.svbin")
|
119
|
+
system("chown vmail:vmail /etc/dovecot/sieve/learn-*.svbin")
|
120
|
+
|
121
|
+
system("sievec /etc/dovecot/sieve-after/spam-to-folder.sieve")
|
122
|
+
system("chmod u=rw,go= /etc/dovecot/sieve-after/spam-to-folder.sieve")
|
123
|
+
system("chown vmail:vmail /etc/dovecot/sieve-after/spam-to-folder.sieve")
|
124
|
+
system("chmod u=rw,go= /etc/dovecot/sieve-after/spam-to-folder.svbin")
|
125
|
+
system("chown vmail:vmail /etc/dovecot/sieve-after/spam-to-folder.svbin")
|
126
|
+
|
127
|
+
system("chown root:root /etc/dovecot/dovecot-sql.conf.ext")
|
128
|
+
system("chmod go= /etc/dovecot/dovecot-sql.conf.ext")
|
129
|
+
|
130
|
+
system("chmod +x /usr/local/bin/quota-warning.sh")
|
131
|
+
|
132
|
+
# Spamassassin
|
133
|
+
FileUtils.cp '/smartmachine/config/emailer/etc/spamassassin/local.cf', '/etc/spamassassin/local.cf'
|
134
|
+
system("adduser --gecos '' --disabled-login spamd", out: File::NULL)
|
135
|
+
|
136
|
+
# OpenDKIM
|
137
|
+
FileUtils.cp '/smartmachine/config/emailer/etc/opendkim.conf', '/etc/opendkim.conf'
|
138
|
+
system("adduser postfix opendkim", out: File::NULL)
|
139
|
+
system("chmod u=rw,go=r /etc/opendkim.conf")
|
140
|
+
unless File.exists? '/etc/opendkim/key.table'
|
141
|
+
FileUtils.mkdir_p '/etc/opendkim/keys'
|
142
|
+
FileUtils.touch '/etc/opendkim/key.table'
|
143
|
+
FileUtils.touch '/etc/opendkim/signing.table'
|
144
|
+
FileUtils.touch '/etc/opendkim/trusted.hosts'
|
145
|
+
key_shortname = envkeys[:mailname].gsub(/[^[:alnum:]]/, "")
|
146
|
+
raise "Could not create key_shortname from mailname to use in opendkim." if key_shortname.match(/\A[a-zA-Z0-9]*\z/).nil?
|
147
|
+
key_selector = Time.now.getlocal('+05:30').strftime("%Y%m")
|
148
|
+
raise "Could not create key_selector from Local Time to use in opendkim." if key_selector.match(/\A[0-9]*\z/).nil?
|
149
|
+
key_filename = "#{key_shortname}_#{key_selector}"
|
150
|
+
IO.write("/etc/opendkim/key.table",
|
151
|
+
"#{key_shortname} #{envkeys[:mailname]}:#{key_selector}:/etc/opendkim/keys/#{key_filename}.private\n")
|
152
|
+
IO.write("/etc/opendkim/signing.table",
|
153
|
+
"*@#{envkeys[:mailname]} #{key_shortname}\n")
|
154
|
+
IO.write("/etc/opendkim/trusted.hosts",
|
155
|
+
"127.0.0.1\n::1\nlocalhost\n#{envkeys[:fqdn]}\n#{envkeys[:mailname]}\n")
|
156
|
+
Dir.chdir("/etc/opendkim/keys") do
|
157
|
+
raise "Could not create DKIM keys." unless system("opendkim-genkey -b 2048 -h rsa-sha256 -r -s #{key_selector} -d #{envkeys[:mailname]} -v")
|
158
|
+
FileUtils.mv("#{key_selector}.private", "#{key_filename}.private")
|
159
|
+
FileUtils.mv("#{key_selector}.txt", "#{key_filename}.txt")
|
160
|
+
end
|
161
|
+
end
|
162
|
+
system("chown -R opendkim:opendkim /etc/opendkim")
|
163
|
+
system("chmod -R go-rw /etc/opendkim/keys")
|
164
|
+
system("mkdir /var/spool/postfix/opendkim")
|
165
|
+
system("chown opendkim:postfix /var/spool/postfix/opendkim")
|
166
|
+
|
167
|
+
# Haproxy
|
168
|
+
FileUtils.mkdir_p '/var/lib/haproxy/dev'
|
169
|
+
FileUtils.mkdir_p '/run/haproxy'
|
170
|
+
FileUtils.cp '/smartmachine/config/emailer/etc/haproxy/haproxy.cfg', '/etc/haproxy/haproxy.cfg'
|
171
|
+
filepaths = [
|
172
|
+
'/etc/haproxy/haproxy.cfg'
|
173
|
+
]
|
174
|
+
update_envkeys_in(filepaths, envkeys)
|
175
|
+
|
176
|
+
# Monit
|
177
|
+
FileUtils.cp '/smartmachine/config/emailer/etc/monit/monitrc', '/etc/monit/monitrc'
|
178
|
+
FileUtils.cp_r '/smartmachine/config/emailer/etc/monit/conf.d/.', '/etc/monit/conf.d'
|
179
|
+
filepaths = [
|
180
|
+
'/etc/monit/conf.d/services.cfg',
|
181
|
+
'/etc/monit/monitrc'
|
182
|
+
]
|
183
|
+
update_envkeys_in(filepaths, envkeys)
|
184
|
+
|
185
|
+
# Logtailer
|
186
|
+
FileUtils.cp '/smartmachine/config/emailer/docker/logtailer.rb', '/usr/bin/logtailer.rb'
|
187
|
+
system("chmod +x /usr/bin/logtailer.rb")
|
188
|
+
|
189
|
+
# Command
|
190
|
+
FileUtils.cp '/smartmachine/config/emailer/docker/command.rb', '/usr/bin/command.rb'
|
191
|
+
system("chmod +x /usr/bin/command.rb")
|
192
|
+
|
193
|
+
logger.info "Initial setup completed for #{envkeys[:container_name]}."
|
194
|
+
end
|
195
|
+
|
196
|
+
ARGV.empty? ? exec("/usr/bin/command.rb") : exec(*ARGV)
|
@@ -0,0 +1,75 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
STDOUT.sync = true
|
5
|
+
|
6
|
+
require 'fileutils'
|
7
|
+
|
8
|
+
class Logtailer
|
9
|
+
def initialize
|
10
|
+
@tailers = {
|
11
|
+
"/var/log/monit.log" => 1,
|
12
|
+
"/var/log/haproxy.log" => 1,
|
13
|
+
"/var/log/mail.log" => 1,
|
14
|
+
"/home/spamd/spamd.log" => 1
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
def start
|
19
|
+
set_start_from_line
|
20
|
+
|
21
|
+
pids = []
|
22
|
+
@tailers.each do |path, start_from_line|
|
23
|
+
pid = Process.spawn("tail", "--lines=+#{start_from_line}", "-q", "-F", "#{path}", [:out, :err] => "/proc/1/fd/1")
|
24
|
+
Process.detach(pid)
|
25
|
+
pids.push(pid)
|
26
|
+
end
|
27
|
+
IO.write("/run/tmpfs/logtailer.pid", "#{pids.join(' ')}\n")
|
28
|
+
|
29
|
+
puts "Started Logtailer with PIDs " + `cat /run/tmpfs/logtailer.pid`.chomp + "."
|
30
|
+
end
|
31
|
+
|
32
|
+
def stop
|
33
|
+
pids = `cat /run/tmpfs/logtailer.pid`.chomp.split(" ")
|
34
|
+
pids.each do |pid|
|
35
|
+
system("/bin/kill --signal SIGTERM #{pid}")
|
36
|
+
end
|
37
|
+
save_start_from_line
|
38
|
+
|
39
|
+
puts "Stopped Logtailer with PIDs " + `cat /run/tmpfs/logtailer.pid`.chomp + "."
|
40
|
+
FileUtils.rm("/run/tmpfs/logtailer.pid")
|
41
|
+
end
|
42
|
+
|
43
|
+
def flush
|
44
|
+
set_start_from_line
|
45
|
+
@tailers.each do |path, start_from_line|
|
46
|
+
system("tail --lines=+#{start_from_line} -q #{path} >> /proc/1/fd/1")
|
47
|
+
end
|
48
|
+
save_start_from_line
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def set_start_from_line
|
54
|
+
if File.exist?('/run/logtailer.lines')
|
55
|
+
lines = IO.read('/run/logtailer.lines').split("\n")
|
56
|
+
lines.each do |line|
|
57
|
+
previous_line_no, path = line.split(" ")
|
58
|
+
@tailers[path] = previous_line_no.to_i + 1
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def save_start_from_line
|
64
|
+
str = `wc -l #{@tailers.keys.join(' ')} | head --lines=-1`
|
65
|
+
IO.write("/run/logtailer.lines", "#{str}")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
if ARGV[0] == "start"
|
70
|
+
Logtailer.new.start
|
71
|
+
elsif ARGV[0] == "stop"
|
72
|
+
Logtailer.new.stop
|
73
|
+
elsif ARGV[0] == "flush"
|
74
|
+
Logtailer.new.flush
|
75
|
+
end
|