smartmachine 1.2.2 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/lib/smart_machine/buildpackers/buildpacker.rb +0 -42
  3. data/lib/smart_machine/buildpackers/rails.rb +60 -0
  4. data/lib/smart_machine/commands/grid.rb +8 -0
  5. data/lib/smart_machine/commands/grid_commands/emailer.rb +107 -0
  6. data/lib/smart_machine/commands/grid_commands/roundcube.rb +65 -0
  7. data/lib/smart_machine/configuration.rb +35 -2
  8. data/lib/smart_machine/credentials.rb +10 -0
  9. data/lib/smart_machine/engine.rb +6 -0
  10. data/lib/smart_machine/grids/adminer.rb +1 -0
  11. data/lib/smart_machine/grids/certbot.rb +1 -0
  12. data/lib/smart_machine/grids/emailer/.keep +0 -0
  13. data/lib/smart_machine/grids/emailer.rb +188 -0
  14. data/lib/smart_machine/grids/haproxy.rb +1 -0
  15. data/lib/smart_machine/grids/mariadb.rb +1 -0
  16. data/lib/smart_machine/grids/postgresql.rb +1 -0
  17. data/lib/smart_machine/grids/roundcube.rb +114 -0
  18. data/lib/smart_machine/machine.rb +49 -0
  19. data/lib/smart_machine/syncer.rb +10 -0
  20. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/docker/command.rb +50 -0
  21. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/docker/entrypoint.rb +196 -0
  22. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/docker/logtailer.rb +75 -0
  23. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/dovecot/conf.d/10-auth.conf +132 -0
  24. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/dovecot/conf.d/10-mail.conf +427 -0
  25. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/dovecot/conf.d/10-master.conf +153 -0
  26. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/dovecot/conf.d/10-ssl.conf +87 -0
  27. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/dovecot/conf.d/15-mailboxes.conf +94 -0
  28. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/dovecot/conf.d/20-imap.conf +102 -0
  29. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/dovecot/conf.d/20-lmtp.conf +43 -0
  30. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/dovecot/conf.d/90-quota.conf +114 -0
  31. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/dovecot/conf.d/90-sieve.conf +229 -0
  32. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/dovecot/dovecot-sql.conf.ext +163 -0
  33. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/dovecot/sieve/learn-ham.sh +2 -0
  34. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/dovecot/sieve/learn-ham.sieve +5 -0
  35. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/dovecot/sieve/learn-spam.sh +2 -0
  36. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/dovecot/sieve/learn-spam.sieve +2 -0
  37. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/dovecot/sieve-after/spam-to-folder.sieve +6 -0
  38. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/haproxy/haproxy.cfg +58 -0
  39. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/monit/conf.d/services.cfg +70 -0
  40. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/monit/monitrc +344 -0
  41. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/opendkim.conf +71 -0
  42. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/postfix/main.cf +123 -0
  43. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/postfix/master.cf +149 -0
  44. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/postfix/mysql-sender-login-maps.cf +7 -0
  45. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/postfix/mysql-virtual-alias-domains.cf +7 -0
  46. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/postfix/mysql-virtual-alias-maps-domains.cf +7 -0
  47. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/postfix/mysql-virtual-alias-maps-masters.cf +7 -0
  48. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/postfix/mysql-virtual-alias-maps-users.cf +7 -0
  49. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/postfix/mysql-virtual-alias-maps-userstothemselves.cf +7 -0
  50. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/postfix/mysql-virtual-mailbox-domains.cf +7 -0
  51. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/postfix/mysql-virtual-mailbox-maps.cf +7 -0
  52. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/postfix-policyd-spf-python/policyd-spf.conf +12 -0
  53. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/etc/spamassassin/local.cf +124 -0
  54. data/lib/smart_machine/templates/dotsmartmachine/config/emailer/usr/local/bin/quota-warning.sh +22 -0
  55. data/lib/smart_machine/templates/dotsmartmachine/config/emailer.yml +37 -0
  56. data/lib/smart_machine/templates/dotsmartmachine/config/engine.yml +2 -0
  57. data/lib/smart_machine/templates/dotsmartmachine/config/roundcube/etc/apache2/sites-available/000-default.conf +35 -0
  58. data/lib/smart_machine/templates/dotsmartmachine/config/roundcube/usr/local/etc/php/conf.d/zzz_roundcube-custom.ini +4 -0
  59. data/lib/smart_machine/templates/dotsmartmachine/config/roundcube/var/roundcube/config/config.custom.inc.php +25 -0
  60. data/lib/smart_machine/templates/dotsmartmachine/config/roundcube.yml +41 -0
  61. data/lib/smart_machine/templates/dotsmartmachine/config/users.yml +1 -1
  62. data/lib/smart_machine/version.rb +2 -2
  63. data/lib/smart_machine.rb +2 -0
  64. metadata +55 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4ead0adeacd301bcd2ef709762b390ebdd7391bd22b1281bfb5816c61d5e5898
4
- data.tar.gz: 951b8525f250d09e74c2a9941e4f9ced364368094f3be6ab1c7f0a3d237f8b3c
3
+ metadata.gz: 5103e5b3902c6f7cf9e295547ff6a5fd43682c9ca11f4d740a5b193fc09a2090
4
+ data.tar.gz: c99f47d9287341f7960223dfcbd44feeacdfdaed16cbf15215865d370706c3f8
5
5
  SHA512:
6
- metadata.gz: 42c85a60e0a958b1b0261c44cace2a9aedadb9615341e098e274068284e71643525ffe2793ecc026c55023fb017ae8b4cc2c6fb3c8cb2436b4c69f09eea5dd16
7
- data.tar.gz: 1dfaf1d47f11b054831f69507c07acafd80f55ec3af82cceefd718212c72636fa6332d079e17a552741601957e313f59afe5d001ffcaaf89110a96b4e384e09c
6
+ metadata.gz: 93e8261b8739b1cc1a2fa3d0400ea8c2e4bbf0b10ec3ce697ef5597b61177fd0de253dbd47e49cd5411f172c4edfd87d73e9e40ea520569d74a8c7086444b1d0
7
+ data.tar.gz: 35abb8c1171082c17b76d277d2f77f9404c6888910b00be89cfb775ea702cec73085c017f3a8c70515c80b837c7c20bbc0f681a405247e25ad46d5ffd3ca9741
@@ -80,13 +80,9 @@ module SmartMachine
80
80
  libdb-dev \
81
81
  uuid-dev && \
82
82
  # ruby on rails
83
- curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
84
- echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
85
83
  apt-get update && \
86
84
  apt-get install -y --no-install-recommends \
87
85
  tzdata \
88
- nodejs \
89
- yarn \
90
86
  libmariadb-dev \
91
87
  libvips42 \
92
88
  ffmpeg \
@@ -109,44 +105,6 @@ module SmartMachine
109
105
 
110
106
  format(file)
111
107
  end
112
-
113
- # These swapfile methods can be used (after required modification), when you need to make swapfile for more memory.
114
- # def self.create_swapfile
115
- # # Creating swapfile for bundler to work properly
116
- # unless system("sudo swapon -s | grep -ci '/swapfile'", out: File::NULL)
117
- # print "-----> Creating swap swapfile ... "
118
- # system("sudo install -o root -g root -m 0600 /dev/null /swapfile", out: File::NULL)
119
- # system("sudo dd if=/dev/zero of=/swapfile bs=1k count=2048k", [:out, :err] => File::NULL)
120
- # system("sudo mkswap /swapfile", out: File::NULL)
121
- # system("sudo sh -c 'echo \"/swapfile none swap sw 0 0\" >> /etc/fstab'", out: File::NULL)
122
- # system("echo 10 | sudo tee /proc/sys/vm/swappiness", out: File::NULL)
123
- # system("sudo sed -i '/^vm.swappiness = /d' /etc/sysctl.conf", out: File::NULL)
124
- # system("echo vm.swappiness = 10 | sudo tee -a /etc/sysctl.conf", out: File::NULL)
125
- # puts "done"
126
- #
127
- # print "-----> Starting swap swapfile ... "
128
- # if system("sudo swapon /swapfile", out: File::NULL)
129
- # puts "done"
130
- # end
131
- # end
132
- # end
133
- #
134
- # def self.destroy_swapfile
135
- # if system("sudo swapon -s | grep -ci '/swapfile'", out: File::NULL)
136
- # print "-----> Stopping swap swapfile ... "
137
- # if system("sudo swapoff /swapfile", out: File::NULL)
138
- # system("sudo sed -i '/^vm.swappiness = /d' /etc/sysctl.conf", out: File::NULL)
139
- # system("echo 60 | sudo tee /proc/sys/vm/swappiness", out: File::NULL)
140
- # puts "done"
141
- #
142
- # print "-----> Removing swap swapfile ... "
143
- # system("sudo sed -i '/^\\/swapfile/d' /etc/fstab", out: File::NULL)
144
- # if system("sudo rm /swapfile", out: File::NULL)
145
- # puts "done"
146
- # end
147
- # end
148
- # end
149
- # end
150
108
  end
151
109
  end
152
110
  end
@@ -173,6 +173,66 @@ module SmartMachine
173
173
  system("alias bundler='bundler _#{bundler_version}_'")
174
174
  logger.info "Using bundler v" + bundler_version + "\n"
175
175
 
176
+ # Install nodejs
177
+ nodejs_version = `sed -n '/node/{p;n}' package.json`.strip.split(":").last&.strip&.delete_prefix('"')&.delete_suffix(',')&.delete_suffix('"')
178
+ if nodejs_version.nil? || nodejs_version.empty?
179
+ logger.error "Could not find nodejs version. Have you specified it explicitly in package.json with engines field and run yarn install?\n"
180
+ return false
181
+ end
182
+
183
+ unless system(user_bash("node -v"), [:out, :err] => File::NULL) && `#{user_bash('node -v')}`.strip&.delete_prefix('v') == nodejs_version
184
+ logger.info "Installing nodejs v#{nodejs_version}\n"
185
+
186
+ Open3.popen2e(user_bash("asdf plugin add nodejs https://github.com/asdf-vm/asdf-nodejs.git")) do |stdin, stdout_and_stderr, wait_thr|
187
+ stdout_and_stderr.each { |line| logger.info "#{line}" }
188
+ end
189
+ Open3.popen2e(user_bash("asdf plugin update nodejs")) do |stdin, stdout_and_stderr, wait_thr|
190
+ stdout_and_stderr.each { |line| logger.info "#{line}" }
191
+ end
192
+ Open3.popen2e(user_bash("asdf install nodejs #{nodejs_version}")) do |stdin, stdout_and_stderr, wait_thr|
193
+ stdout_and_stderr.each { |line| logger.info "#{line}" }
194
+ end
195
+ Open3.popen2e(user_bash("asdf local nodejs #{nodejs_version}")) do |stdin, stdout_and_stderr, wait_thr|
196
+ stdout_and_stderr.each { |line| logger.info "#{line}" }
197
+ end
198
+
199
+ unless `#{user_bash('node -v')}`.strip&.delete_prefix('v') == nodejs_version
200
+ logger.error "Could not install nodejs with version #{nodejs_version}. Please try another valid version that asdf supports.\n"
201
+ return false
202
+ end
203
+ end
204
+ logger.info "Using nodejs v" + `#{user_bash('node -v')}`.strip&.delete_prefix('v') + "\n"
205
+
206
+ # Install yarn
207
+ yarn_version = `sed -n '/yarn/{p;n}' package.json`.strip.split(":").last&.strip&.delete_prefix('"')&.delete_suffix(',')&.delete_suffix('"')
208
+ if yarn_version.nil? || yarn_version.empty?
209
+ logger.error "Could not find yarn version. Have you specified it explicitly in package.json with engines field and run yarn install?\n"
210
+ return false
211
+ end
212
+
213
+ unless system(user_bash("yarn -v"), [:out, :err] => File::NULL) && `#{user_bash('yarn -v')}`.strip == yarn_version
214
+ logger.info "Installing yarn v#{yarn_version}\n"
215
+
216
+ Open3.popen2e(user_bash("asdf plugin add yarn https://github.com/twuni/asdf-yarn.git")) do |stdin, stdout_and_stderr, wait_thr|
217
+ stdout_and_stderr.each { |line| logger.info "#{line}" }
218
+ end
219
+ Open3.popen2e(user_bash("asdf plugin update yarn")) do |stdin, stdout_and_stderr, wait_thr|
220
+ stdout_and_stderr.each { |line| logger.info "#{line}" }
221
+ end
222
+ Open3.popen2e(user_bash("asdf install yarn #{yarn_version}")) do |stdin, stdout_and_stderr, wait_thr|
223
+ stdout_and_stderr.each { |line| logger.info "#{line}" }
224
+ end
225
+ Open3.popen2e(user_bash("asdf local yarn #{yarn_version}")) do |stdin, stdout_and_stderr, wait_thr|
226
+ stdout_and_stderr.each { |line| logger.info "#{line}" }
227
+ end
228
+
229
+ unless `#{user_bash('yarn -v')}`.strip == yarn_version
230
+ logger.error "Could not install yarn with version #{yarn_version}. Please try another valid version that asdf supports.\n"
231
+ return false
232
+ end
233
+ end
234
+ logger.info "Using yarn v" + `#{user_bash('yarn -v')}`.strip + "\n"
235
+
176
236
  set_logger_formatter_arrow
177
237
 
178
238
  return true
@@ -1,5 +1,6 @@
1
1
  require 'smart_machine/commands/grid_commands/sub_thor'
2
2
  require 'smart_machine/commands/grid_commands/elasticsearch'
3
+ require 'smart_machine/commands/grid_commands/emailer'
3
4
  require 'smart_machine/commands/grid_commands/minio'
4
5
  require 'smart_machine/commands/grid_commands/mysql'
5
6
  require 'smart_machine/commands/grid_commands/nextcloud'
@@ -7,6 +8,7 @@ require 'smart_machine/commands/grid_commands/nginx'
7
8
  require 'smart_machine/commands/grid_commands/phpmyadmin'
8
9
  require 'smart_machine/commands/grid_commands/prereceiver'
9
10
  require 'smart_machine/commands/grid_commands/redis'
11
+ require 'smart_machine/commands/grid_commands/roundcube'
10
12
  require 'smart_machine/commands/grid_commands/terminal'
11
13
 
12
14
  module SmartMachine
@@ -17,6 +19,9 @@ module SmartMachine
17
19
  desc "elasticsearch", "Run elasticsearch grid commands"
18
20
  subcommand "elasticsearch", GridCommands::Elasticsearch
19
21
 
22
+ desc "emailer", "Run emailer grid commands"
23
+ subcommand "emailer", GridCommands::Emailer
24
+
20
25
  desc "minio", "Run minio grid commands"
21
26
  subcommand "minio", GridCommands::Minio
22
27
 
@@ -38,6 +43,9 @@ module SmartMachine
38
43
  desc "redis", "Run redis grid commands"
39
44
  subcommand "redis", GridCommands::Redis
40
45
 
46
+ desc "roundcube", "Run roundcube grid commands"
47
+ subcommand "roundcube", GridCommands::Roundcube
48
+
41
49
  desc "terminal", "Run terminal grid commands"
42
50
  subcommand "terminal", GridCommands::Terminal
43
51
  end
@@ -0,0 +1,107 @@
1
+ module SmartMachine
2
+ module Commands
3
+ module GridCommands
4
+ class Emailer < SubThor
5
+ include Utilities
6
+
7
+ desc "install", "Install emailer grid"
8
+ def install
9
+ inside_machine_dir do
10
+ with_docker_running do
11
+ puts "-----> Installing Emailer"
12
+ machine = SmartMachine::Machine.new
13
+ machine.run_on_machine commands: "smartengine grid emailer installer"
14
+ puts "-----> Emailer Installation Complete"
15
+ end
16
+ end
17
+ end
18
+
19
+ desc "uninstall", "Uninstall emailer grid"
20
+ def uninstall
21
+ inside_machine_dir do
22
+ with_docker_running do
23
+ puts "-----> Uninstalling Emailer"
24
+ machine = SmartMachine::Machine.new
25
+ machine.run_on_machine commands: "smartengine grid emailer uninstaller"
26
+ puts "-----> Emailer Uninstallation Complete"
27
+ end
28
+ end
29
+ end
30
+
31
+ desc "up", "Take UP the emailer grid"
32
+ option :name, type: :string
33
+ def up
34
+ inside_machine_dir do
35
+ with_docker_running do
36
+ machine = SmartMachine::Machine.new
37
+ name_option = options[:name] ? " --name=#{options[:name]}" : ""
38
+ machine.run_on_machine commands: "smartengine grid emailer uper#{name_option}"
39
+ end
40
+ end
41
+ end
42
+
43
+ desc "down", "Take DOWN the emailer grid"
44
+ option :name, type: :string
45
+ def down
46
+ inside_machine_dir do
47
+ with_docker_running do
48
+ machine = SmartMachine::Machine.new
49
+ name_option = options[:name] ? " --name=#{options[:name]}" : ""
50
+ machine.run_on_machine commands: "smartengine grid emailer downer#{name_option}"
51
+ end
52
+ end
53
+ end
54
+
55
+ desc "installer", "Emailer grid installer", hide: true
56
+ def installer
57
+ inside_engine_machine_dir do
58
+ name, config = SmartMachine.config.grids.emailer.first
59
+ emailer = SmartMachine::Grids::Emailer.new(name: name.to_s)
60
+ emailer.installer
61
+ end
62
+ end
63
+
64
+ desc "uninstaller", "Emailer grid uninstaller", hide: true
65
+ def uninstaller
66
+ inside_engine_machine_dir do
67
+ name, config = SmartMachine.config.grids.emailer.first
68
+ emailer = SmartMachine::Grids::Emailer.new(name: name.to_s)
69
+ emailer.uninstaller
70
+ end
71
+ end
72
+
73
+ desc "uper", "Emailer grid uper", hide: true
74
+ option :name, type: :string
75
+ def uper
76
+ inside_engine_machine_dir do
77
+ if options[:name]
78
+ emailer = SmartMachine::Grids::Emailer.new(name: options[:name])
79
+ emailer.uper
80
+ else
81
+ SmartMachine.config.grids.emailer.each do |name, config|
82
+ emailer = SmartMachine::Grids::Emailer.new(name: name.to_s)
83
+ emailer.uper
84
+ end
85
+ end
86
+ end
87
+ end
88
+
89
+ desc "downer", "Emailer grid downer", hide: true
90
+ option :name, type: :string
91
+ def downer
92
+ inside_engine_machine_dir do
93
+ if options[:name]
94
+ emailer = SmartMachine::Grids::Emailer.new(name: options[:name])
95
+ emailer.downer
96
+ else
97
+ SmartMachine.config.grids.emailer.each do |name, config|
98
+ emailer = SmartMachine::Grids::Emailer.new(name: name.to_s)
99
+ emailer.downer
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,65 @@
1
+ module SmartMachine
2
+ module Commands
3
+ module GridCommands
4
+ class Roundcube < SubThor
5
+ include Utilities
6
+
7
+ desc "up", "Take UP the roundcube grid"
8
+ option :name, type: :string
9
+ def up
10
+ inside_machine_dir do
11
+ with_docker_running do
12
+ machine = SmartMachine::Machine.new
13
+ name_option = options[:name] ? " --name=#{options[:name]}" : ""
14
+ machine.run_on_machine commands: "smartengine grid roundcube uper#{name_option}"
15
+ end
16
+ end
17
+ end
18
+
19
+ desc "down", "Take DOWN the roundcube grid"
20
+ option :name, type: :string
21
+ def down
22
+ inside_machine_dir do
23
+ with_docker_running do
24
+ machine = SmartMachine::Machine.new
25
+ name_option = options[:name] ? " --name=#{options[:name]}" : ""
26
+ machine.run_on_machine commands: "smartengine grid roundcube downer#{name_option}"
27
+ end
28
+ end
29
+ end
30
+
31
+ desc "uper", "Roundcube grid uper", hide: true
32
+ option :name, type: :string
33
+ def uper
34
+ inside_engine_machine_dir do
35
+ if options[:name]
36
+ roundcube = SmartMachine::Grids::Roundcube.new(name: options[:name])
37
+ roundcube.uper
38
+ else
39
+ SmartMachine.config.grids.roundcube.each do |name, config|
40
+ roundcube = SmartMachine::Grids::Roundcube.new(name: name.to_s)
41
+ roundcube.uper
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ desc "downer", "Roundcube grid downer", hide: true
48
+ option :name, type: :string
49
+ def downer
50
+ inside_engine_machine_dir do
51
+ if options[:name]
52
+ roundcube = SmartMachine::Grids::Roundcube.new(name: options[:name])
53
+ roundcube.downer
54
+ else
55
+ SmartMachine.config.grids.roundcube.each do |name, config|
56
+ roundcube = SmartMachine::Grids::Roundcube.new(name: name.to_s)
57
+ roundcube.downer
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -8,13 +8,24 @@ module SmartMachine
8
8
  end
9
9
 
10
10
  def config
11
- @config ||= OpenStruct.new(grids: grids, network: network)
11
+ @config ||= OpenStruct.new(engine: engine, grids: grids, network: network)
12
12
  end
13
13
 
14
14
  private
15
15
 
16
+ def engine
17
+ # Once the SmartMachine.config assignments in smart_machine.rb file has been removed, then this file exist condition can be removed to ensure that config/engine.yml always exists
18
+ if File.exist? "config/engine.yml"
19
+ deserialize(IO.binread("config/engine.yml")).deep_symbolize_keys
20
+ elsif File.exist? "#{File.expand_path('~')}/machine/config/engine.yml"
21
+ deserialize(IO.binread("#{File.expand_path('~')}/machine/config/engine.yml")).deep_symbolize_keys
22
+ else
23
+ {}
24
+ end
25
+ end
26
+
16
27
  def grids
17
- @grids ||= OpenStruct.new(elasticsearch: elasticsearch, minio: minio, mysql: mysql, nextcloud: nextcloud, phpmyadmin: phpmyadmin, prereceiver: prereceiver, redis: redis, terminal: terminal)
28
+ @grids ||= OpenStruct.new(elasticsearch: elasticsearch, emailer: emailer, minio: minio, mysql: mysql, nextcloud: nextcloud, phpmyadmin: phpmyadmin, prereceiver: prereceiver, redis: redis, roundcube: roundcube, terminal: terminal)
18
29
  end
19
30
 
20
31
  def elasticsearch
@@ -28,6 +39,17 @@ module SmartMachine
28
39
  end
29
40
  end
30
41
 
42
+ def emailer
43
+ # Once the SmartMachine.config assignments in smart_machine.rb file has been removed, then this file exist condition can be removed to ensure that config/emailer.yml always exists
44
+ if File.exist? "config/emailer.yml"
45
+ deserialize(IO.binread("config/emailer.yml")).deep_symbolize_keys
46
+ elsif File.exist? "#{File.expand_path('~')}/machine/config/emailer.yml"
47
+ deserialize(IO.binread("#{File.expand_path('~')}/machine/config/emailer.yml")).deep_symbolize_keys
48
+ else
49
+ {}
50
+ end
51
+ end
52
+
31
53
  def minio
32
54
  # Once the SmartMachine.config assignments in smart_machine.rb file has been removed, then this file exist condition can be removed to ensure that config/minio.yml always exists
33
55
  if File.exist? "config/minio.yml"
@@ -94,6 +116,17 @@ module SmartMachine
94
116
  end
95
117
  end
96
118
 
119
+ def roundcube
120
+ # Once the SmartMachine.config assignments in smart_machine.rb file has been removed, then this file exist condition can be removed to ensure that config/roundcube.yml always exists
121
+ if File.exist? "config/roundcube.yml"
122
+ deserialize(IO.binread("config/roundcube.yml")).deep_symbolize_keys
123
+ elsif File.exist? "#{File.expand_path('~')}/machine/config/roundcube.yml"
124
+ deserialize(IO.binread("#{File.expand_path('~')}/machine/config/roundcube.yml")).deep_symbolize_keys
125
+ else
126
+ {}
127
+ end
128
+ end
129
+
97
130
  def terminal
98
131
  # Once the SmartMachine.config assignments in smart_machine.rb file has been removed, then this file exist condition can be removed to ensure that config/terminal.yml always exists
99
132
  if File.exist? "config/terminal.yml"
@@ -56,6 +56,12 @@ module SmartMachine
56
56
  root_password: #{SecureRandom.hex(16)}
57
57
  username: #{SecureRandom.hex(8)}
58
58
  password: #{SecureRandom.hex(16)}
59
+ emailerone:
60
+ mysql_user: #{SecureRandom.hex(8)}
61
+ mysql_password: #{SecureRandom.hex(16)}
62
+ mysql_database_name: #{SecureRandom.hex(8)}
63
+ monit_smtp_username: yourmachineemailerone@yourdomain.com
64
+ monit_smtp_password: #{SecureRandom.hex(16)}
59
65
  minioone:
60
66
  access_key: #{SecureRandom.hex(8)}
61
67
  secret_key: #{SecureRandom.hex(16)}
@@ -66,6 +72,10 @@ module SmartMachine
66
72
  database_name: #{SecureRandom.hex(8)}
67
73
  redisone:
68
74
  password: #{SecureRandom.hex(16)}
75
+ roundcubeone:
76
+ database_user: #{SecureRandom.hex(8)}
77
+ database_pass: #{SecureRandom.hex(16)}
78
+ database_name: #{SecureRandom.hex(8)}
69
79
  nextcloudone:
70
80
  admin_user: #{SecureRandom.hex(8)}
71
81
  admin_password: #{SecureRandom.hex(16)}
@@ -29,6 +29,7 @@ module SmartMachine
29
29
  puts "-----> Creating image for Engine ... "
30
30
  command = [
31
31
  "docker image build --quiet --tag #{engine_image_name_with_version}",
32
+ "--build-arg TZDATA_TIMEZONE='#{SmartMachine.config.engine.dig(:engineone).dig(:timezone)}'",
32
33
  "--build-arg SMARTMACHINE_MASTER_KEY=#{SmartMachine::Credentials.new.read_key}",
33
34
  "--build-arg USER_NAME=`id -un`",
34
35
  "--build-arg USER_UID=`id -u`",
@@ -102,6 +103,11 @@ module SmartMachine
102
103
  FROM ruby:%<smartmachine_ruby_version>s-bullseye
103
104
  LABEL maintainer="plainsource <plainsource@humanmind.me>"
104
105
 
106
+ # Setting Localtime & Timezone using tzdata
107
+ ARG TZDATA_TIMEZONE
108
+ RUN ln -sf /usr/share/zoneinfo/$TZDATA_TIMEZONE /etc/localtime && \
109
+ dpkg-reconfigure -f noninteractive tzdata
110
+
105
111
  # User
106
112
  # --- Fix to change docker gid to 998 (if it is in use) so that addgroup is free to create a group with docker gid.
107
113
  ARG USER_NAME
@@ -0,0 +1 @@
1
+ # TODO: Add adminer as an alternative for phpmyadmin.
@@ -0,0 +1 @@
1
+ # TODO: Add certbot for SSL certificates.
File without changes
@@ -0,0 +1,188 @@
1
+ module SmartMachine
2
+ class Grids
3
+ class Emailer < SmartMachine::Base
4
+ def initialize(name:)
5
+ config = SmartMachine.config.grids.emailer.dig(name.to_sym)
6
+ raise "emailer config for #{name} not found." unless config
7
+
8
+ @image = "smartmachine/emailer:#{SmartMachine.version}"
9
+ @fqdn = config.dig(:fqdn)
10
+ @mailname = config.dig(:mailname)
11
+ @sysadmin_email = config.dig(:sysadmin_email)
12
+ @networks = config.dig(:networks)
13
+ @mysql_host = config.dig(:mysql_host)
14
+ @mysql_port = config.dig(:mysql_port)
15
+ @mysql_user = config.dig(:mysql_user)
16
+ @mysql_password = config.dig(:mysql_password)
17
+ @mysql_database_name = config.dig(:mysql_database_name)
18
+ @monit_smtp_email_name = config.dig(:monit_smtp_email_name)
19
+ @monit_smtp_email_address = config.dig(:monit_smtp_email_address)
20
+ @monit_smtp_host = config.dig(:monit_smtp_host)
21
+ @monit_smtp_port = config.dig(:monit_smtp_port)
22
+ @monit_smtp_username = config.dig(:monit_smtp_username)
23
+ @monit_smtp_password = config.dig(:monit_smtp_password)
24
+ @oracle_ips_allowed = config.dig(:oracle_ips_allowed)
25
+ @oracle_deflect_url = config.dig(:oracle_deflect_url)
26
+
27
+ @name = name.to_s
28
+ @home_dir = File.expand_path('~')
29
+ end
30
+
31
+ def installer
32
+ unless system("docker image inspect #{@image}", [:out, :err] => File::NULL)
33
+ puts "-----> Creating image #{@image} ... "
34
+ command = [
35
+ "docker image build -t #{@image}",
36
+ "--build-arg SMARTMACHINE_VERSION=#{SmartMachine.version}",
37
+ "-f- #{SmartMachine.config.gem_dir}/lib/smart_machine/grids/emailer",
38
+ "<<'EOF'\n#{dockerfile}EOF"
39
+ ]
40
+ if system(command.join(" "), out: File::NULL)
41
+ puts "done"
42
+ else
43
+ raise "Error: Could not install image: #{@image}"
44
+ end
45
+ else
46
+ raise "Error: Image already installed: #{@image}. Please uninstall using 'smartmachine grids emailer uninstall' and try installing again."
47
+ end
48
+ end
49
+
50
+ def uninstaller
51
+ unless system("docker inspect -f '{{.State.Running}}' '#{@name}'", [:out, :err] => File::NULL)
52
+ if system("docker image inspect #{@image}", [:out, :err] => File::NULL)
53
+ puts "-----> Removing image #{@image} ... "
54
+ if system("docker image rm #{@image}", out: File::NULL)
55
+ puts "done"
56
+ end
57
+ else
58
+ raise "Error: Emailer already uninstalled. Please install using 'smartmachine grids emailer install' and try uninstalling again."
59
+ end
60
+ else
61
+ raise "Error: Emailer is currently running. Please stop the emailer using 'smartmachine grids emailer down' and try uninstalling again."
62
+ end
63
+ end
64
+
65
+ def uper
66
+ if system("docker image inspect #{@image}", [:out, :err] => File::NULL)
67
+ FileUtils.mkdir_p("#{@home_dir}/machine/grids/emailer/#{@name}/backups")
68
+ FileUtils.mkdir_p("#{@home_dir}/machine/grids/emailer/#{@name}/data/vmail")
69
+ FileUtils.mkdir_p("#{@home_dir}/machine/grids/emailer/#{@name}/data/opendkim")
70
+
71
+ # Setting entrypoint permission.
72
+ system("chmod +x #{@home_dir}/machine/config/emailer/docker/entrypoint.rb")
73
+
74
+ # Creating & Starting containers
75
+ print "-----> Creating container #{@name} ... "
76
+
77
+ command = [
78
+ "docker create",
79
+ "--name='#{@name}'",
80
+ "--env VIRTUAL_HOST=#{@fqdn}",
81
+ "--env VIRTUAL_PATH='/'",
82
+ "--env LETSENCRYPT_HOST=#{@fqdn}",
83
+ "--env LETSENCRYPT_EMAIL=#{@sysadmin_email}",
84
+ "--env LETSENCRYPT_TEST=false",
85
+ "--env CONTAINER_NAME='#{@name}'",
86
+ "--env FQDN='#{@fqdn}'",
87
+ "--env MAILNAME='#{@mailname}'",
88
+ "--env SYSADMIN_EMAIL='#{@sysadmin_email}'",
89
+ "--env MYSQL_HOST='#{@mysql_host}'",
90
+ "--env MYSQL_PORT='#{@mysql_port}'",
91
+ "--env MYSQL_USER='#{@mysql_user}'",
92
+ "--env MYSQL_PASSWORD='#{@mysql_password}'",
93
+ "--env MYSQL_DATABASE_NAME='#{@mysql_database_name}'",
94
+ "--env MONIT_SMTP_EMAIL_NAME='#{@monit_smtp_email_name}'",
95
+ "--env MONIT_SMTP_EMAIL_ADDRESS='#{@monit_smtp_email_address}'",
96
+ "--env MONIT_SMTP_HOST='#{@monit_smtp_host}'",
97
+ "--env MONIT_SMTP_PORT='#{@monit_smtp_port}'",
98
+ "--env MONIT_SMTP_USERNAME='#{@monit_smtp_username}'",
99
+ "--env MONIT_SMTP_PASSWORD='#{@monit_smtp_password}'",
100
+ "--env ORACLE_IPS_ALLOWED='#{@oracle_ips_allowed.join(' ')}'",
101
+ "--env ORACLE_DEFLECT_URL='#{@oracle_deflect_url}'",
102
+ "--expose='80'",
103
+ "--publish='25:25'",
104
+ # "--publish='465:465'",
105
+ "--publish='587:587'",
106
+ # "--publish='110:110'",
107
+ "--publish='995:995'",
108
+ # "--publish='143:143'",
109
+ "--publish='993:993'",
110
+ "--volume='#{@home_dir}/smartmachine/grids/nginx/certificates/#{@fqdn}:/etc/letsencrypt/live/#{@fqdn}:ro'",
111
+ "--volume='#{@home_dir}/smartmachine/config/emailer:/smartmachine/config/emailer:ro'",
112
+ "--volume='#{@home_dir}/smartmachine/grids/emailer/#{@name}/data/vmail:/var/vmail'",
113
+ "--volume='#{@home_dir}/smartmachine/grids/emailer/#{@name}/data/opendkim:/etc/opendkim'",
114
+ "--entrypoint='/smartmachine/config/emailer/docker/entrypoint.rb'",
115
+ "--tmpfs /run/tmpfs",
116
+ "--init",
117
+ "--restart='always'",
118
+ "--network='nginx-network'",
119
+ "#{@image}"
120
+ ]
121
+ if system(command.compact.join(" "), out: File::NULL)
122
+ @networks.each do |network|
123
+ system("docker network connect --alias #{@fqdn} #{network} #{@name}")
124
+ end
125
+
126
+ puts "done"
127
+ puts "-----> Starting container #{@name} ... "
128
+ if system("docker start #{@name}", out: File::NULL)
129
+ puts "done"
130
+ else
131
+ raise "Error: Could not start container: #{@name}"
132
+ end
133
+ else
134
+ raise "Error: Could not create container: #{@name}"
135
+ end
136
+ else
137
+ raise "Error: Could not find image: #{@image}"
138
+ end
139
+ end
140
+
141
+ def downer
142
+ # Disconnecting networks
143
+ @networks.reverse.each do |network|
144
+ system("docker network disconnect #{network} #{@name}")
145
+ end
146
+
147
+ # Stopping & Removing containers - in reverse order
148
+ print "-----> Stopping container #{@name} ... "
149
+ if system("docker stop '#{@name}'", out: File::NULL)
150
+ puts "done"
151
+ print "-----> Removing container #{@name} ... "
152
+ if system("docker rm '#{@name}'", out: File::NULL)
153
+ puts "done"
154
+ end
155
+ end
156
+ end
157
+
158
+ private
159
+
160
+ def dockerfile
161
+ file = <<~'DOCKERFILE'
162
+ ARG SMARTMACHINE_VERSION
163
+
164
+ FROM smartmachine/smartengine:$SMARTMACHINE_VERSION
165
+ LABEL maintainer="plainsource <plainsource@humanmind.me>"
166
+
167
+ SHELL ["/bin/bash", "-c"]
168
+
169
+ RUN apt-get update && \
170
+ \
171
+ debconf-set-selections <<< "postfix postfix/main_mailer_type string 'Internet Site'" && \
172
+ debconf-set-selections <<< "postfix postfix/mailname string %<mailname>s" && \
173
+ apt-get install -y --no-install-recommends \
174
+ rsyslog \
175
+ postfix postfix-mysql \
176
+ dovecot-managesieved dovecot-imapd dovecot-pop3d dovecot-lmtpd dovecot-mysql \
177
+ spamassassin spamc \
178
+ opendkim opendkim-tools \
179
+ postfix-policyd-spf-python postfix-pcre \
180
+ haproxy monit && \
181
+ rm -rf /var/lib/apt/lists/*
182
+ DOCKERFILE
183
+
184
+ format(file, "mailname": @mailname)
185
+ end
186
+ end
187
+ end
188
+ end
@@ -0,0 +1 @@
1
+ # TODO: Add haproxy as an alternative to nginx.
@@ -0,0 +1 @@
1
+ # TODO: Add mariadb as an alternative for mysql.
@@ -0,0 +1 @@
1
+ # TODO: Add postgresql as an alternative for mariadb & mysql.