smartmachine 0.8.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +661 -0
  3. data/README.md +147 -0
  4. data/bin/console +14 -0
  5. data/bin/setup +8 -0
  6. data/exe/smartmachine +3 -0
  7. data/lib/smart_machine/apps/app.rb +165 -181
  8. data/lib/smart_machine/apps/container.rb +120 -0
  9. data/lib/smart_machine/apps/manager.rb +182 -0
  10. data/lib/smart_machine/base.rb +24 -6
  11. data/lib/smart_machine/buildpackers/buildpacker.rb +95 -0
  12. data/lib/smart_machine/{engine/buildpacks → buildpackers}/rails/Dockerfile +3 -3
  13. data/lib/smart_machine/buildpackers/rails.rb +221 -0
  14. data/lib/smart_machine/commands/app.rb +112 -0
  15. data/lib/smart_machine/commands/buildpacker.rb +53 -0
  16. data/lib/smart_machine/commands/credentials.rb +17 -0
  17. data/lib/smart_machine/commands/docker.rb +23 -0
  18. data/lib/smart_machine/commands/engine.rb +27 -0
  19. data/lib/smart_machine/commands/grid.rb +33 -0
  20. data/lib/smart_machine/commands/grid_commands/elasticsearch.rb +68 -0
  21. data/lib/smart_machine/commands/grid_commands/minio.rb +65 -0
  22. data/lib/smart_machine/commands/grid_commands/mysql.rb +71 -0
  23. data/lib/smart_machine/commands/grid_commands/nginx.rb +53 -0
  24. data/lib/smart_machine/commands/grid_commands/prereceiver.rb +96 -0
  25. data/lib/smart_machine/commands/grid_commands/redis.rb +65 -0
  26. data/lib/smart_machine/commands/grid_commands/scheduler.rb +15 -0
  27. data/lib/smart_machine/commands/grid_commands/sub_thor.rb +15 -0
  28. data/lib/smart_machine/commands/machine.rb +24 -0
  29. data/lib/smart_machine/commands/syncer.rb +23 -0
  30. data/lib/smart_machine/commands/utilities.rb +37 -0
  31. data/lib/smart_machine/commands.rb +66 -0
  32. data/lib/smart_machine/configuration.rb +79 -0
  33. data/lib/smart_machine/credentials.rb +93 -95
  34. data/lib/smart_machine/docker.rb +144 -143
  35. data/lib/smart_machine/engine/Dockerfile +7 -5
  36. data/lib/smart_machine/engine.rb +104 -79
  37. data/lib/smart_machine/grids/elasticsearch.rb +70 -89
  38. data/lib/smart_machine/grids/minio.rb +79 -68
  39. data/lib/smart_machine/grids/mysql.rb +207 -202
  40. data/lib/smart_machine/grids/nginx.rb +176 -135
  41. data/lib/smart_machine/grids/prereceiver/Dockerfile +2 -2
  42. data/lib/smart_machine/grids/prereceiver/pre-receive +17 -0
  43. data/lib/smart_machine/grids/prereceiver.rb +169 -169
  44. data/lib/smart_machine/grids/redis.rb +75 -57
  45. data/lib/smart_machine/grids/scheduler/Dockerfile +1 -1
  46. data/lib/smart_machine/logger.rb +26 -26
  47. data/lib/smart_machine/machine.rb +128 -194
  48. data/lib/smart_machine/scp.rb +15 -0
  49. data/lib/smart_machine/ssh.rb +69 -40
  50. data/lib/smart_machine/syncer.rb +133 -0
  51. data/lib/smart_machine/templates/dotsmartmachine/Gemfile +7 -0
  52. data/lib/smart_machine/templates/dotsmartmachine/config/elasticsearch.yml +5 -0
  53. data/lib/smart_machine/templates/dotsmartmachine/config/environment.rb +0 -9
  54. data/lib/smart_machine/templates/dotsmartmachine/config/minio.yml +13 -0
  55. data/lib/smart_machine/templates/dotsmartmachine/config/mysql/schedule.rb +3 -3
  56. data/lib/smart_machine/templates/dotsmartmachine/config/mysql.yml +13 -0
  57. data/lib/smart_machine/templates/dotsmartmachine/config/prereceiver.yml +7 -0
  58. data/lib/smart_machine/templates/dotsmartmachine/config/redis.yml +15 -0
  59. data/lib/smart_machine/templates/dotsmartmachine/config/users.yml +1 -1
  60. data/lib/smart_machine/templates/dotsmartmachine/gitignore-template +47 -0
  61. data/lib/smart_machine/templates/dotsmartmachine/{grids/elasticsearch/data → vendor}/.keep +0 -0
  62. data/lib/smart_machine/version.rb +30 -6
  63. data/lib/smart_machine.rb +42 -16
  64. metadata +97 -47
  65. data/CHANGELOG.rdoc +0 -0
  66. data/MIT-LICENSE +0 -21
  67. data/README.rdoc +0 -87
  68. data/bin/buildpacker +0 -8
  69. data/bin/prereceiver +0 -8
  70. data/bin/scheduler +0 -18
  71. data/bin/smartmachine +0 -81
  72. data/bin/smartrunner +0 -33
  73. data/lib/smart_machine/apps/rails.rb +0 -250
  74. data/lib/smart_machine/apps.rb +0 -14
  75. data/lib/smart_machine/boot.rb +0 -32
  76. data/lib/smart_machine/buildpacker.rb +0 -106
  77. data/lib/smart_machine/gem_version.rb +0 -17
  78. data/lib/smart_machine/grids.rb +0 -18
  79. data/lib/smart_machine/sync.rb +0 -120
  80. data/lib/smart_machine/templates/dotsmartmachine/grids/elasticsearch/logs/.keep +0 -0
  81. data/lib/smart_machine/templates/dotsmartmachine/grids/minio/data/.keep +0 -0
  82. data/lib/smart_machine/templates/dotsmartmachine/grids/mysql/backups/.keep +0 -0
  83. data/lib/smart_machine/templates/dotsmartmachine/grids/mysql/data/.keep +0 -0
  84. data/lib/smart_machine/templates/dotsmartmachine/grids/prereceiver/pre-receive +0 -17
  85. data/lib/smart_machine/templates/dotsmartmachine/grids/redis/data/.keep +0 -0
  86. data/lib/smart_machine/user.rb +0 -38
@@ -0,0 +1,37 @@
1
+ module SmartMachine
2
+ module Commands
3
+ module Utilities
4
+
5
+ private
6
+
7
+ def in_machine_dir?
8
+ File.file?("./config/master.key")
9
+ end
10
+
11
+ def inside_machine_dir
12
+ if in_machine_dir?
13
+ yield
14
+ else
15
+ puts "Are you in the correct directory to run this command?"
16
+ end
17
+ end
18
+
19
+ def inside_engine_machine_dir
20
+ if ENV["INSIDE_ENGINE"] == "yes" && File.file?('./bin/smartengine')
21
+ yield
22
+ else
23
+ raise "Not inside the engine machine dir to run this command"
24
+ end
25
+ end
26
+
27
+ def with_docker_running
28
+ machine = SmartMachine::Machine.new
29
+ if machine.run_on_machine(commands: "docker info &>/dev/null")
30
+ yield
31
+ else
32
+ puts "Error: Docker daemon is not running. Have you installed docker? Please ensure docker daemon is running and try again."
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,66 @@
1
+ require 'thor'
2
+ require 'smart_machine'
3
+
4
+ require 'smart_machine/commands/utilities'
5
+
6
+ require 'smart_machine/commands/app'
7
+ require 'smart_machine/commands/buildpacker'
8
+ require 'smart_machine/commands/credentials'
9
+ require 'smart_machine/commands/docker'
10
+ require 'smart_machine/commands/engine'
11
+ require 'smart_machine/commands/grid'
12
+ require 'smart_machine/commands/machine'
13
+ require 'smart_machine/commands/syncer'
14
+
15
+ module SmartMachine
16
+ module Commands
17
+ class CLI < Thor
18
+ include Utilities
19
+
20
+ def self.exit_on_failure?
21
+ true
22
+ end
23
+
24
+ desc "new [NAME]", "Creates a new machine using the given name"
25
+ option :dev, type: :boolean, default: false
26
+ def new(name)
27
+ raise "Can't create a machine inside a machine. Please come out of the machine directory to create another machine." if in_machine_dir?
28
+
29
+ machine = SmartMachine::Machine.new
30
+ machine.create(name: name, dev: options[:dev])
31
+ end
32
+
33
+ desc "--version", "Shows the current SmartMachine version"
34
+ map ["--version", "-v"] => :version
35
+ def version
36
+ puts "SmartMachine #{SmartMachine.version}"
37
+ end
38
+
39
+ desc "app", "Run app commands"
40
+ subcommand "app", App
41
+
42
+ desc "buildpacker", "Run buildpacker commands"
43
+ subcommand "buildpacker", Buildpacker
44
+
45
+ desc "credentials:edit", "Allows editing the credentials"
46
+ subcommand "credentials:edit", Credentials
47
+
48
+ desc "docker", "Run docker commands"
49
+ subcommand "docker", Docker
50
+
51
+ desc "engine", "Run engine commands"
52
+ subcommand "engine", Engine
53
+
54
+ desc "grid", "Run grid commands"
55
+ subcommand "grid", Grid
56
+
57
+ desc "machine", "Run machine commands"
58
+ subcommand "machine", Machine
59
+
60
+ desc "syncer", "Run syncer commands"
61
+ subcommand "syncer", Syncer
62
+ end
63
+ end
64
+ end
65
+
66
+ SmartMachine::Commands::CLI.start(ARGV)
@@ -0,0 +1,79 @@
1
+ require "active_support/core_ext/hash/keys"
2
+ require "erb"
3
+
4
+ module SmartMachine
5
+ class Configuration < SmartMachine::Base
6
+
7
+ def initialize
8
+ end
9
+
10
+ def config
11
+ @config ||= OpenStruct.new(grids: grids)
12
+ end
13
+
14
+ private
15
+
16
+ def grids
17
+ @grids ||= OpenStruct.new(elasticsearch: elasticsearch, minio: minio, mysql: mysql, prereceiver: prereceiver, redis: redis)
18
+ end
19
+
20
+ def elasticsearch
21
+ # 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/elasticsearch.yml always exists
22
+ if File.exist? "config/elasticsearch.yml"
23
+ deserialize(IO.binread("config/elasticsearch.yml")).deep_symbolize_keys
24
+ elsif File.exist? "#{File.expand_path('~')}/machine/config/elasticsearch.yml"
25
+ deserialize(IO.binread("#{File.expand_path('~')}/machine/config/elasticsearch.yml")).deep_symbolize_keys
26
+ else
27
+ {}
28
+ end
29
+ end
30
+
31
+ def minio
32
+ # 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
+ if File.exist? "config/minio.yml"
34
+ deserialize(IO.binread("config/minio.yml")).deep_symbolize_keys
35
+ elsif File.exist? "#{File.expand_path('~')}/machine/config/minio.yml"
36
+ deserialize(IO.binread("#{File.expand_path('~')}/machine/config/minio.yml")).deep_symbolize_keys
37
+ else
38
+ {}
39
+ end
40
+ end
41
+
42
+ def mysql
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/mysql.yml always exists
44
+ if File.exist? "config/mysql.yml"
45
+ deserialize(IO.binread("config/mysql.yml")).deep_symbolize_keys
46
+ elsif File.exist? "#{File.expand_path('~')}/machine/config/mysql.yml"
47
+ deserialize(IO.binread("#{File.expand_path('~')}/machine/config/mysql.yml")).deep_symbolize_keys
48
+ else
49
+ {}
50
+ end
51
+ end
52
+
53
+ def prereceiver
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/prereceiver.yml always exists
55
+ if File.exist? "config/prereceiver.yml"
56
+ deserialize(IO.binread("config/prereceiver.yml")).deep_symbolize_keys
57
+ elsif File.exist? "#{File.expand_path('~')}/machine/config/prereceiver.yml" # To ensure file exists when inside the pre-receive hook of prereceiver.
58
+ deserialize(IO.binread("#{File.expand_path('~')}/machine/config/prereceiver.yml")).deep_symbolize_keys
59
+ else
60
+ {}
61
+ end
62
+ end
63
+
64
+ def redis
65
+ # 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/redis.yml always exists
66
+ if File.exist? "config/redis.yml"
67
+ deserialize(IO.binread("config/redis.yml")).deep_symbolize_keys
68
+ elsif File.exist? "#{File.expand_path('~')}/machine/config/redis.yml"
69
+ deserialize(IO.binread("#{File.expand_path('~')}/machine/config/redis.yml")).deep_symbolize_keys
70
+ else
71
+ {}
72
+ end
73
+ end
74
+
75
+ def deserialize(config)
76
+ YAML.load(ERB.new(config).result).presence || {}
77
+ end
78
+ end
79
+ end
@@ -3,124 +3,122 @@ require "tmpdir"
3
3
  require "active_support/message_encryptor"
4
4
  require "active_support/core_ext/hash/keys"
5
5
 
6
- # The main SmartMachine Credentials driver
7
6
  module SmartMachine
8
- class Credentials < SmartMachine::Base
7
+ class Credentials < SmartMachine::Base
9
8
 
10
- CIPHER = "aes-256-gcm"
9
+ CIPHER = "aes-256-gcm"
11
10
 
12
- def initialize
13
- end
11
+ def initialize
12
+ end
14
13
 
15
- def create
16
- write_key
17
- write credentials_template
18
- end
14
+ def create
15
+ write_key
16
+ write credentials_template
17
+ end
19
18
 
20
- def edit
21
- content_path = Pathname.new "config/credentials.yml.enc"
22
- tmp_file = "#{Process.pid}.#{content_path.basename.to_s.chomp('.enc')}"
23
- tmp_path = Pathname.new File.join(Dir.tmpdir, tmp_file)
24
- contents = read
25
- tmp_path.binwrite contents
19
+ def edit
20
+ content_path = Pathname.new "config/credentials.yml.enc"
21
+ tmp_file = "#{Process.pid}.#{content_path.basename.to_s.chomp('.enc')}"
22
+ tmp_path = Pathname.new File.join(Dir.tmpdir, tmp_file)
23
+ contents = read
24
+ tmp_path.binwrite contents
26
25
 
27
- system("#{ENV['EDITOR']} #{tmp_path}")
26
+ system("#{ENV['EDITOR']} #{tmp_path}")
28
27
 
29
- updated_contents = tmp_path.binread
28
+ updated_contents = tmp_path.binread
30
29
 
31
- if updated_contents != contents
32
- write(updated_contents)
33
- puts "File encrypted and saved."
34
- else
35
- puts "File contents were not changed."
36
- end
37
- ensure
38
- FileUtils.rm(tmp_path) if tmp_path&.exist?
39
- end
30
+ if updated_contents != contents
31
+ write(updated_contents)
32
+ puts "File encrypted and saved."
33
+ else
34
+ puts "File contents were not changed."
35
+ end
36
+ ensure
37
+ FileUtils.rm(tmp_path) if tmp_path&.exist?
38
+ end
40
39
 
41
- def read_key
42
- read_env_key || read_key_file || handle_missing_key
43
- end
40
+ def read_key
41
+ read_env_key || read_key_file || handle_missing_key
42
+ end
44
43
 
45
- def config
46
- @config ||= deserialize(read).deep_symbolize_keys
47
- end
44
+ def config
45
+ @config ||= deserialize(read).deep_symbolize_keys
46
+ end
48
47
 
49
- private
48
+ private
50
49
 
51
- def credentials_template
50
+ def credentials_template
52
51
  <<~YAML
53
52
  machine:
54
53
  name: #{SecureRandom.hex(8)}
55
- address: 122.122.122.122
54
+ address: 127.0.0.1
56
55
  port: 22
57
56
  root_password: #{SecureRandom.hex(16)}
58
57
  username: #{SecureRandom.hex(8)}
59
58
  password: #{SecureRandom.hex(16)}
60
-
61
- minio:
62
- name: #{SecureRandom.hex(8)}
59
+ minioone:
63
60
  access_key: #{SecureRandom.hex(8)}
64
61
  secret_key: #{SecureRandom.hex(16)}
65
- browser: on
66
- worm: off
67
-
68
- mysql:
69
- port: 3306
62
+ mysqlone:
70
63
  root_password: #{SecureRandom.hex(16)}
71
64
  username: #{SecureRandom.hex(8)}
72
65
  password: #{SecureRandom.hex(16)}
73
66
  database_name: #{SecureRandom.hex(8)}
74
-
75
- elasticsearch:
76
- port: 9200
67
+ redisone:
68
+ password: #{SecureRandom.hex(16)}
77
69
  YAML
78
- end
79
-
80
- def read
81
- decrypt IO.binread "config/credentials.yml.enc"
82
- end
83
-
84
- def write(contents)
85
- IO.binwrite "config/credentials.yml.enc.tmp", encrypt(contents)
86
- FileUtils.mv "config/credentials.yml.enc.tmp", "config/credentials.yml.enc"
87
- end
88
-
89
- def encrypt(contents)
90
- encryptor.encrypt_and_sign contents
91
- end
92
-
93
- def decrypt(contents)
94
- encryptor.decrypt_and_verify contents
95
- end
96
-
97
- def encryptor
98
- @encryptor ||= ActiveSupport::MessageEncryptor.new([ read_key ].pack("H*"), cipher: CIPHER)
99
- end
100
-
101
- def create_key
102
- SecureRandom.hex(ActiveSupport::MessageEncryptor.key_len(CIPHER))
103
- end
104
-
105
- def write_key
106
- IO.binwrite "config/master.key.tmp", create_key
107
- FileUtils.mv "config/master.key.tmp", "config/master.key"
108
- end
109
-
110
- def read_env_key
111
- ENV['SMARTMACHINE_MASTER_KEY']
112
- end
113
-
114
- def read_key_file
115
- IO.binread("config/master.key").strip if File.file?("config/master.key")
116
- end
117
-
118
- def handle_missing_key
119
- raise "Missing SMARTMACHINE_MASTER_KEY. Please add SMARTMACHINE_MASTER_KEY to your environment."
120
- end
121
-
122
- def deserialize(config)
123
- YAML.load(config).presence || {}
124
- end
125
- end
126
- end
70
+ end
71
+
72
+ def read
73
+ if File.exist? "config/credentials.yml.enc"
74
+ decrypt IO.binread "config/credentials.yml.enc"
75
+ elsif File.exist? "#{File.expand_path('~')}/machine/config/credentials.yml.enc"
76
+ decrypt IO.binread "#{File.expand_path('~')}/machine/config/credentials.yml.enc"
77
+ else
78
+ raise "Could not find credentials file."
79
+ end
80
+ end
81
+
82
+ def write(contents)
83
+ IO.binwrite "config/credentials.yml.enc.tmp", encrypt(contents)
84
+ FileUtils.mv "config/credentials.yml.enc.tmp", "config/credentials.yml.enc"
85
+ end
86
+
87
+ def encrypt(contents)
88
+ encryptor.encrypt_and_sign contents
89
+ end
90
+
91
+ def decrypt(contents)
92
+ encryptor.decrypt_and_verify contents
93
+ end
94
+
95
+ def encryptor
96
+ @encryptor ||= ActiveSupport::MessageEncryptor.new([ read_key ].pack("H*"), cipher: CIPHER)
97
+ end
98
+
99
+ def create_key
100
+ SecureRandom.hex(ActiveSupport::MessageEncryptor.key_len(CIPHER))
101
+ end
102
+
103
+ def write_key
104
+ IO.binwrite "config/master.key.tmp", create_key
105
+ FileUtils.mv "config/master.key.tmp", "config/master.key"
106
+ end
107
+
108
+ def read_env_key
109
+ ENV['SMARTMACHINE_MASTER_KEY']
110
+ end
111
+
112
+ def read_key_file
113
+ IO.binread("config/master.key").strip if File.file?("config/master.key")
114
+ end
115
+
116
+ def handle_missing_key
117
+ raise "Missing SMARTMACHINE_MASTER_KEY. Please add SMARTMACHINE_MASTER_KEY to your environment."
118
+ end
119
+
120
+ def deserialize(config)
121
+ YAML.load(config).presence || {}
122
+ end
123
+ end
124
+ end