smartmachine 0.8.0 → 1.0.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/LICENSE.txt +661 -0
- data/README.md +147 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/smartmachine +3 -0
- data/lib/smart_machine/apps/app.rb +165 -181
- data/lib/smart_machine/apps/container.rb +120 -0
- data/lib/smart_machine/apps/manager.rb +182 -0
- data/lib/smart_machine/base.rb +24 -6
- data/lib/smart_machine/buildpackers/buildpacker.rb +95 -0
- data/lib/smart_machine/{engine/buildpacks → buildpackers}/rails/Dockerfile +3 -3
- data/lib/smart_machine/buildpackers/rails.rb +221 -0
- data/lib/smart_machine/commands/app.rb +112 -0
- data/lib/smart_machine/commands/buildpacker.rb +53 -0
- data/lib/smart_machine/commands/credentials.rb +17 -0
- data/lib/smart_machine/commands/docker.rb +23 -0
- data/lib/smart_machine/commands/engine.rb +27 -0
- data/lib/smart_machine/commands/grid.rb +33 -0
- data/lib/smart_machine/commands/grid_commands/elasticsearch.rb +68 -0
- data/lib/smart_machine/commands/grid_commands/minio.rb +65 -0
- data/lib/smart_machine/commands/grid_commands/mysql.rb +71 -0
- data/lib/smart_machine/commands/grid_commands/nginx.rb +53 -0
- data/lib/smart_machine/commands/grid_commands/prereceiver.rb +96 -0
- data/lib/smart_machine/commands/grid_commands/redis.rb +65 -0
- data/lib/smart_machine/commands/grid_commands/scheduler.rb +15 -0
- data/lib/smart_machine/commands/grid_commands/sub_thor.rb +15 -0
- data/lib/smart_machine/commands/machine.rb +24 -0
- data/lib/smart_machine/commands/syncer.rb +23 -0
- data/lib/smart_machine/commands/utilities.rb +37 -0
- data/lib/smart_machine/commands.rb +66 -0
- data/lib/smart_machine/configuration.rb +79 -0
- data/lib/smart_machine/credentials.rb +93 -95
- data/lib/smart_machine/docker.rb +144 -143
- data/lib/smart_machine/engine/Dockerfile +7 -5
- data/lib/smart_machine/engine.rb +104 -79
- data/lib/smart_machine/grids/elasticsearch.rb +70 -89
- data/lib/smart_machine/grids/minio.rb +79 -68
- data/lib/smart_machine/grids/mysql.rb +207 -202
- data/lib/smart_machine/grids/nginx.rb +176 -135
- data/lib/smart_machine/grids/prereceiver/Dockerfile +2 -2
- data/lib/smart_machine/grids/prereceiver/pre-receive +17 -0
- data/lib/smart_machine/grids/prereceiver.rb +169 -169
- data/lib/smart_machine/grids/redis.rb +75 -57
- data/lib/smart_machine/grids/scheduler/Dockerfile +1 -1
- data/lib/smart_machine/logger.rb +26 -26
- data/lib/smart_machine/machine.rb +128 -194
- data/lib/smart_machine/scp.rb +15 -0
- data/lib/smart_machine/ssh.rb +69 -40
- data/lib/smart_machine/syncer.rb +133 -0
- data/lib/smart_machine/templates/dotsmartmachine/Gemfile +7 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/elasticsearch.yml +5 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/environment.rb +0 -9
- data/lib/smart_machine/templates/dotsmartmachine/config/minio.yml +13 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/mysql/schedule.rb +3 -3
- data/lib/smart_machine/templates/dotsmartmachine/config/mysql.yml +13 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/prereceiver.yml +7 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/redis.yml +15 -0
- data/lib/smart_machine/templates/dotsmartmachine/config/users.yml +1 -1
- data/lib/smart_machine/templates/dotsmartmachine/gitignore-template +47 -0
- data/lib/smart_machine/templates/dotsmartmachine/{grids/elasticsearch/data → vendor}/.keep +0 -0
- data/lib/smart_machine/version.rb +30 -6
- data/lib/smart_machine.rb +42 -16
- metadata +97 -47
- data/CHANGELOG.rdoc +0 -0
- data/MIT-LICENSE +0 -21
- data/README.rdoc +0 -87
- data/bin/buildpacker +0 -8
- data/bin/prereceiver +0 -8
- data/bin/scheduler +0 -18
- data/bin/smartmachine +0 -81
- data/bin/smartrunner +0 -33
- data/lib/smart_machine/apps/rails.rb +0 -250
- data/lib/smart_machine/apps.rb +0 -14
- data/lib/smart_machine/boot.rb +0 -32
- data/lib/smart_machine/buildpacker.rb +0 -106
- data/lib/smart_machine/gem_version.rb +0 -17
- data/lib/smart_machine/grids.rb +0 -18
- data/lib/smart_machine/sync.rb +0 -120
- data/lib/smart_machine/templates/dotsmartmachine/grids/elasticsearch/logs/.keep +0 -0
- data/lib/smart_machine/templates/dotsmartmachine/grids/minio/data/.keep +0 -0
- data/lib/smart_machine/templates/dotsmartmachine/grids/mysql/backups/.keep +0 -0
- data/lib/smart_machine/templates/dotsmartmachine/grids/mysql/data/.keep +0 -0
- data/lib/smart_machine/templates/dotsmartmachine/grids/prereceiver/pre-receive +0 -17
- data/lib/smart_machine/templates/dotsmartmachine/grids/redis/data/.keep +0 -0
- 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
|
-
|
7
|
+
class Credentials < SmartMachine::Base
|
9
8
|
|
10
|
-
|
9
|
+
CIPHER = "aes-256-gcm"
|
11
10
|
|
12
|
-
|
13
|
-
|
11
|
+
def initialize
|
12
|
+
end
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
def create
|
15
|
+
write_key
|
16
|
+
write credentials_template
|
17
|
+
end
|
19
18
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
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
|
-
|
26
|
+
system("#{ENV['EDITOR']} #{tmp_path}")
|
28
27
|
|
29
|
-
|
28
|
+
updated_contents = tmp_path.binread
|
30
29
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
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
|
-
|
42
|
-
|
43
|
-
|
40
|
+
def read_key
|
41
|
+
read_env_key || read_key_file || handle_missing_key
|
42
|
+
end
|
44
43
|
|
45
|
-
|
46
|
-
|
47
|
-
|
44
|
+
def config
|
45
|
+
@config ||= deserialize(read).deep_symbolize_keys
|
46
|
+
end
|
48
47
|
|
49
|
-
|
48
|
+
private
|
50
49
|
|
51
|
-
|
50
|
+
def credentials_template
|
52
51
|
<<~YAML
|
53
52
|
machine:
|
54
53
|
name: #{SecureRandom.hex(8)}
|
55
|
-
address:
|
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
|
-
|
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
|
-
|
76
|
-
port: 9200
|
67
|
+
redisone:
|
68
|
+
password: #{SecureRandom.hex(16)}
|
77
69
|
YAML
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
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
|