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
data/README.md
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
# SmartMachine
|
2
|
+
|
3
|
+
Git push should deploy.
|
4
|
+
|
5
|
+
SmartMachine is a full-stack deployment framework for rails optimized for admin programmer happiness and peaceful administration. It encourages natural simplicity by favoring convention over configuration.
|
6
|
+
|
7
|
+
Before you begin, you should install ruby on your system.
|
8
|
+
|
9
|
+
Deploy your Rails apps to your own server with - git push production main
|
10
|
+
|
11
|
+
### How does it help?
|
12
|
+
|
13
|
+
After you run the below commands, you get.
|
14
|
+
1. Setup of basic best practices of setting up and securing a VPS server.
|
15
|
+
2. Setup and installation of Docker.
|
16
|
+
3. Setup and installation of docker based Mysql, Solr, Nginx, App Prereceiver.
|
17
|
+
4. Deployment of your Rails apps to your own server with - git push production main
|
18
|
+
|
19
|
+
### Prerequisites
|
20
|
+
|
21
|
+
If using SmartMachine on a server, perform the below steps before proceeding.
|
22
|
+
|
23
|
+
Ensure that you have debian LTS installed on the server.
|
24
|
+
Running the below command should say some latest version of debian LTS.
|
25
|
+
|
26
|
+
$ cat /etc/issue
|
27
|
+
|
28
|
+
Then complete, getting started with linode.
|
29
|
+
|
30
|
+
https://www.linode.com/docs/getting-started/
|
31
|
+
|
32
|
+
And then secure your server.
|
33
|
+
|
34
|
+
https://www.linode.com/docs/security/securing-your-server/
|
35
|
+
|
36
|
+
## Installation
|
37
|
+
|
38
|
+
Install SmartMachine at the command prompt:
|
39
|
+
|
40
|
+
$ gem install smartmachine
|
41
|
+
|
42
|
+
Then create a new machine and move into it:
|
43
|
+
|
44
|
+
$ smartmachine new yourmachinename
|
45
|
+
$ cd yourmachinename
|
46
|
+
|
47
|
+
here "yourmachinename" is the machine name you can choose
|
48
|
+
|
49
|
+
Add your credentials using:
|
50
|
+
|
51
|
+
$ smartmachine credentials:edit
|
52
|
+
|
53
|
+
Add your environment details using: - Coming Soon
|
54
|
+
|
55
|
+
$ smartmachine environment:edit
|
56
|
+
|
57
|
+
Add your users using:
|
58
|
+
|
59
|
+
$ smartmachine grid nginx users:edit
|
60
|
+
|
61
|
+
Install docker, and add UFW rules for Docker if specified at the end of installation.
|
62
|
+
|
63
|
+
$ smartmachine docker install
|
64
|
+
|
65
|
+
Install the engine and buildpacker:
|
66
|
+
|
67
|
+
$ smartmachine engine install
|
68
|
+
$ smartmachine buildpacker install rails
|
69
|
+
|
70
|
+
## Usage
|
71
|
+
|
72
|
+
### Choose Your Grids
|
73
|
+
|
74
|
+
Choose only the grids you need. You can start or stop a grid at anytime using <b>up</b> or <b>down</b> commands respectively.
|
75
|
+
|
76
|
+
#### 1. Nginx Grid
|
77
|
+
Lets you run a nginx web server fully equipped with https encryption using letsencrypt.
|
78
|
+
|
79
|
+
$ smartmachine grid nginx up
|
80
|
+
$ smartmachine grid nginx down
|
81
|
+
|
82
|
+
#### 2. Prereceiver Grid
|
83
|
+
Lets you push rails apps to your server without any additional configuration or downtime using <b>git push production main</b>.
|
84
|
+
|
85
|
+
$ smartmachine grid prereceiver install
|
86
|
+
$ smartmachine grid prereceiver up
|
87
|
+
$ smartmachine grid prereceiver down
|
88
|
+
$ smartmachine grid prereceiver uninstall
|
89
|
+
|
90
|
+
#### 3. Mysql Grid
|
91
|
+
Lets you run a mysql server instance with as many databases as you need.
|
92
|
+
|
93
|
+
$ smartmachine grid mysql up
|
94
|
+
$ smartmachine grid mysql down
|
95
|
+
|
96
|
+
#### 4. Minio Grid
|
97
|
+
Lets you run minio server instance with file storage persistance.
|
98
|
+
|
99
|
+
$ smartmachine grid minio up
|
100
|
+
$ smartmachine grid minio down
|
101
|
+
|
102
|
+
#### 5. Elasticsearch Grid
|
103
|
+
Lets you run elasticsearch server instance with data persistance.
|
104
|
+
|
105
|
+
$ smartmachine grid elasticsearch up
|
106
|
+
$ smartmachine grid elasticsearch down
|
107
|
+
|
108
|
+
#### 4. Redis Grid
|
109
|
+
Lets you run redis server instance for cache storage and job queueing.
|
110
|
+
|
111
|
+
$ smartmachine grid redis up
|
112
|
+
$ smartmachine grid redis down
|
113
|
+
|
114
|
+
#### 6. Scheduler Grid - Coming Soon
|
115
|
+
Lets you setup scheduling services like database backups, etc.
|
116
|
+
|
117
|
+
$ smartmachine grid scheduler install
|
118
|
+
$ smartmachine grid scheduler up
|
119
|
+
$ smartmachine grid scheduler down
|
120
|
+
$ smartmachine grid scheduler uninstall
|
121
|
+
|
122
|
+
### Setup Your Apps
|
123
|
+
|
124
|
+
Create your apps and manage them.
|
125
|
+
|
126
|
+
#### 1. New App on the server
|
127
|
+
Lets you create a new bare app on the server.
|
128
|
+
|
129
|
+
$ smartmachine app create <APPNAME> <APPDOMAIN> <USERNAME>
|
130
|
+
|
131
|
+
## Development
|
132
|
+
|
133
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
134
|
+
|
135
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
136
|
+
|
137
|
+
## Contributing
|
138
|
+
|
139
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/plainsource/smartmachine. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/plainsource/smartmachine/blob/main/CODE_OF_CONDUCT.md).
|
140
|
+
|
141
|
+
## License
|
142
|
+
|
143
|
+
The gem is available as open source under the terms of the [AGPL License](https://www.gnu.org/licenses/agpl-3.0.html).
|
144
|
+
|
145
|
+
## Code of Conduct
|
146
|
+
|
147
|
+
Everyone interacting in the SmartMachine project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/plainsource/smartmachine/blob/main/CODE_OF_CONDUCT.md).
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "smart_machine"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/exe/smartmachine
ADDED
@@ -1,182 +1,166 @@
|
|
1
|
-
# The main SmartMachine App driver
|
2
1
|
module SmartMachine
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
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
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
end
|
169
|
-
|
170
|
-
env_vars = {}
|
171
|
-
File.open("#{container_path}/env").each_line do |line|
|
172
|
-
line.chomp!
|
173
|
-
next if line.empty? || line.start_with?('#')
|
174
|
-
key, value = line.split "="
|
175
|
-
env_vars[key] = value
|
176
|
-
end
|
177
|
-
|
178
|
-
env_vars
|
179
|
-
end
|
180
|
-
end
|
181
|
-
end
|
182
|
-
end
|
2
|
+
module Apps
|
3
|
+
class App < SmartMachine::Base
|
4
|
+
def initialize(appname:, container_number: nil, username: nil)
|
5
|
+
@home_dir = File.expand_path('~')
|
6
|
+
@appname = appname
|
7
|
+
@container_number = container_number
|
8
|
+
@username = username
|
9
|
+
|
10
|
+
@repository_path = "#{@home_dir}/machine/apps/repositories/#{@appname}.git"
|
11
|
+
@container_path = "#{@home_dir}/machine/apps/containers/#{@appname}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def creater(appdomain:, prereceiver_name:)
|
15
|
+
raise "Please provide appname and username" if @appname.empty? || @username.empty?
|
16
|
+
prereceiver_name = prereceiver_name.to_s
|
17
|
+
|
18
|
+
print "-----> Creating Application ... "
|
19
|
+
|
20
|
+
# Checking if app with given name already exists
|
21
|
+
if Dir.exist?(@repository_path)
|
22
|
+
puts "failed. App with name '#{@appname}' already exists."
|
23
|
+
exit
|
24
|
+
end
|
25
|
+
|
26
|
+
# Creating Directories
|
27
|
+
FileUtils.mkdir_p(@repository_path)
|
28
|
+
FileUtils.mkdir_p(@container_path)
|
29
|
+
|
30
|
+
# Initializing bare repo and pre-receive
|
31
|
+
Dir.chdir(@repository_path) do
|
32
|
+
%x[git init --bare]
|
33
|
+
%x[ln -s ../../../../grids/prereceiver/#{prereceiver_name}/pre-receive hooks/pre-receive]
|
34
|
+
puts "done"
|
35
|
+
end
|
36
|
+
|
37
|
+
# Creating Environment File
|
38
|
+
if File.exist?("#{@home_dir}/machine/config/environment.rb")
|
39
|
+
require "#{@home_dir}/machine/config/environment"
|
40
|
+
end
|
41
|
+
unless File.exist? "#{@container_path}/env"
|
42
|
+
print "-----> Creating App Environment ... "
|
43
|
+
page = <<~HEREDOC
|
44
|
+
## System
|
45
|
+
USERNAME=#{@username}
|
46
|
+
KEEP_RELEASES=3
|
47
|
+
|
48
|
+
## Docker
|
49
|
+
VIRTUAL_HOST=#{@appname}.#{appdomain}
|
50
|
+
LETSENCRYPT_HOST=#{@appname}.#{appdomain}
|
51
|
+
LETSENCRYPT_EMAIL=#{@username}
|
52
|
+
LETSENCRYPT_TEST=false
|
53
|
+
HEREDOC
|
54
|
+
puts "done" if system("echo '#{page}' > #{@container_path}/env")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def destroyer
|
59
|
+
raise "Please provide appname" if @appname.empty?
|
60
|
+
|
61
|
+
# Checking if app with given name exists
|
62
|
+
unless Dir.exist?(@repository_path)
|
63
|
+
raise "App with name '#{@appname}' does not exist. Please provide a valid appname."
|
64
|
+
end
|
65
|
+
|
66
|
+
container_id = `docker ps -a -q --filter='name=^#{@appname}$' --filter='status=running'`.chomp
|
67
|
+
if container_id.empty?
|
68
|
+
# Destroying Directories
|
69
|
+
print "-----> Deleting App #{@appname} ... "
|
70
|
+
FileUtils.rm_r(@repository_path)
|
71
|
+
FileUtils.rm_r(@container_path)
|
72
|
+
puts "done"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def uper(version:)
|
77
|
+
raise "Please provide appname" if @appname.empty?
|
78
|
+
|
79
|
+
# Checking if app with given name exists
|
80
|
+
unless Dir.exist?(@repository_path)
|
81
|
+
raise "App with name '#{@appname}' does not exist. Please provide a valid appname."
|
82
|
+
end
|
83
|
+
|
84
|
+
logger.formatter = proc do |severity, datetime, progname, message|
|
85
|
+
severity_text = { "DEBUG" => "\u{1f527} #{severity}:", "INFO" => " \u{276f}", "WARN" => "\u{2757} #{severity}:",
|
86
|
+
"ERROR" => "\u{274c} #{severity}:", "FATAL" => "\u{2b55} #{severity}:", "UNKNOWN" => "\u{2753} #{severity}:"
|
87
|
+
}
|
88
|
+
"\t\t\t\t#{severity_text[severity]} #{message}\n"
|
89
|
+
end
|
90
|
+
|
91
|
+
Dir.chdir("#{@container_path}/releases") do
|
92
|
+
# Getting App Version
|
93
|
+
if version == 0
|
94
|
+
versions = Dir.glob('*').select { |f| File.directory? f }.sort
|
95
|
+
version = versions.last
|
96
|
+
end
|
97
|
+
|
98
|
+
logger.info "Launching Application ..."
|
99
|
+
|
100
|
+
buildpacker_rails = SmartMachine::Buildpackers::Rails.new(appname: @appname, version: version)
|
101
|
+
buildpacker_rails.uper
|
102
|
+
end
|
103
|
+
|
104
|
+
logger.formatter = nil
|
105
|
+
end
|
106
|
+
|
107
|
+
def downer
|
108
|
+
raise "Please provide appname" if @appname.empty?
|
109
|
+
|
110
|
+
# Checking if app with given name exists
|
111
|
+
unless Dir.exist?(@repository_path)
|
112
|
+
raise "App with name '#{@appname}' does not exist. Please provide a valid appname."
|
113
|
+
end
|
114
|
+
|
115
|
+
container_name = @appname
|
116
|
+
container_name += "_" + @container_number if @container_number
|
117
|
+
|
118
|
+
container_id = `docker ps -a -q --filter='name=^#{container_name}$'`.chomp
|
119
|
+
unless container_id.empty?
|
120
|
+
logger.debug "Stopping & Removing container #{container_name} ..."
|
121
|
+
if system("docker stop #{container_name} && docker rm #{container_name}", out: File::NULL)
|
122
|
+
logger.debug "Stopped & Removed container #{container_name} ..."
|
123
|
+
end
|
124
|
+
else
|
125
|
+
logger.debug "Container '#{container_name}' does not exist to stop."
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def cleaner
|
130
|
+
env_vars = get_env_vars
|
131
|
+
return unless env_vars
|
132
|
+
|
133
|
+
logger.info "Cleaning up ..."
|
134
|
+
|
135
|
+
# Clean up very old versions
|
136
|
+
Dir.chdir("#{@container_path}/releases") do
|
137
|
+
versions = Dir.glob('*').select { |f| File.directory? f }.sort
|
138
|
+
destroy_count = versions.count - env_vars['KEEP_RELEASES'].to_i
|
139
|
+
if destroy_count > 0
|
140
|
+
logger.debug "Deleting older application releases ..."
|
141
|
+
destroy_count.times do
|
142
|
+
FileUtils.rm_r(File.join(Dir.pwd, versions.shift))
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def get_env_vars
|
149
|
+
unless File.exist? "#{@container_path}/env"
|
150
|
+
logger.fatal "Environment could not be loaded ... Failed."
|
151
|
+
return false
|
152
|
+
end
|
153
|
+
|
154
|
+
env_vars = {}
|
155
|
+
File.open("#{@container_path}/env").each_line do |line|
|
156
|
+
line.chomp!
|
157
|
+
next if line.empty? || line.start_with?('#')
|
158
|
+
key, value = line.split "="
|
159
|
+
env_vars[key] = value
|
160
|
+
end
|
161
|
+
|
162
|
+
env_vars
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
module SmartMachine
|
2
|
+
module Apps
|
3
|
+
class Container < SmartMachine::Base
|
4
|
+
def initialize(name:, appname:, appversion:)
|
5
|
+
@name = name
|
6
|
+
@appname = appname
|
7
|
+
@appversion = appversion
|
8
|
+
@appimage = "smartmachine/apps/#{@appname}:#{@appversion}"
|
9
|
+
|
10
|
+
@home_dir = File.expand_path('~')
|
11
|
+
end
|
12
|
+
|
13
|
+
def create!(using_command:, using_buildpacker: false)
|
14
|
+
unless using_buildpacker
|
15
|
+
unless system("docker image inspect #{@appimage}", [:out, :err] => File::NULL)
|
16
|
+
raise "Error: App Image with name #{@appimage} not found. Could not create #{@name} container."
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
logger.debug "-----> Creating container #{@name} ... "
|
21
|
+
command = [
|
22
|
+
"docker create",
|
23
|
+
"--name='#{@name}'",
|
24
|
+
"--env-file='#{@home_dir}/machine/apps/containers/#{@appname}/env'",
|
25
|
+
"--user `id -u`:`id -g`",
|
26
|
+
"--workdir /app",
|
27
|
+
"--expose='3000'",
|
28
|
+
"--volume='#{@home_dir}/smartmachine/config/environment.rb:#{@home_dir}/machine/config/environment.rb'",
|
29
|
+
"--volume='#{@home_dir}/smartmachine/apps/containers/#{@appname}/releases/#{@appversion}:/app'",
|
30
|
+
"--volume='#{@home_dir}/smartmachine/apps/containers/#{@appname}/app/vendor/bundle:/app/vendor/bundle'",
|
31
|
+
"--volume='#{@home_dir}/smartmachine/apps/containers/#{@appname}/app/public/assets:/app/public/assets'",
|
32
|
+
"--volume='#{@home_dir}/smartmachine/apps/containers/#{@appname}/app/public/packs:/app/public/packs'",
|
33
|
+
"--volume='#{@home_dir}/smartmachine/apps/containers/#{@appname}/app/node_modules:/app/node_modules'",
|
34
|
+
"--volume='#{@home_dir}/smartmachine/apps/containers/#{@appname}/app/storage:/app/storage'",
|
35
|
+
"--restart='always'",
|
36
|
+
"--init",
|
37
|
+
# "--network='nginx-network'",
|
38
|
+
"#{using_buildpacker ? "smartmachine/buildpackers/rails:#{SmartMachine.version}" : @appimage}"
|
39
|
+
]
|
40
|
+
command.push(using_command) if using_command.present?
|
41
|
+
|
42
|
+
if system(command.compact.join(" "), out: File::NULL)
|
43
|
+
logger.debug "done"
|
44
|
+
return true
|
45
|
+
else
|
46
|
+
raise "Error: Could not create #{@name} container"
|
47
|
+
end
|
48
|
+
|
49
|
+
return false
|
50
|
+
end
|
51
|
+
|
52
|
+
def start!
|
53
|
+
logger.debug "-----> Starting container #{@name} ... "
|
54
|
+
if system("docker start #{@name}", out: File::NULL)
|
55
|
+
logger.debug "done"
|
56
|
+
return true
|
57
|
+
else
|
58
|
+
raise "Error: Could not start #{@name} container"
|
59
|
+
end
|
60
|
+
|
61
|
+
return false
|
62
|
+
end
|
63
|
+
|
64
|
+
def stop!
|
65
|
+
container_id = `docker ps -a -q --filter='name=^#{@name}$'`.chomp
|
66
|
+
unless container_id.empty?
|
67
|
+
logger.debug "Stopping & Removing container #{@name} ..."
|
68
|
+
if system("docker stop #{@name} && docker rm #{@name}", out: File::NULL)
|
69
|
+
logger.debug "Stopped & Removed container #{@name} ..."
|
70
|
+
return true
|
71
|
+
else
|
72
|
+
raise "Error: Container '#{@name}' could not be stopped and removed."
|
73
|
+
end
|
74
|
+
else
|
75
|
+
raise "Error: Container '#{@name}' does not exist to stop."
|
76
|
+
end
|
77
|
+
|
78
|
+
return false
|
79
|
+
end
|
80
|
+
|
81
|
+
def connect_to_network!(network_name:)
|
82
|
+
unless `docker network ls -q --filter name=^#{network_name}$`.chomp.empty?
|
83
|
+
if system("docker network connect #{network_name} #{@name}", out: File::NULL)
|
84
|
+
logger.debug "Connected to network #{network_name}."
|
85
|
+
return true
|
86
|
+
else
|
87
|
+
raise "Error: Could not connect to #{network_name} network."
|
88
|
+
end
|
89
|
+
else
|
90
|
+
raise "Error: The network with name #{network_name} was not found."
|
91
|
+
end
|
92
|
+
|
93
|
+
return false
|
94
|
+
end
|
95
|
+
|
96
|
+
def commit_app_image!
|
97
|
+
if create!(using_command: "smartmachine buildpacker packer rails", using_buildpacker: true)
|
98
|
+
logger.debug "-----> Starting attached container #{@name} ... "
|
99
|
+
if system("docker start --attach #{@name}")
|
100
|
+
logger.debug "-----> Committing container #{@name} to image... "
|
101
|
+
if system("docker commit #{@name} #{@appimage}", out: File::NULL)
|
102
|
+
stop!
|
103
|
+
return true
|
104
|
+
else
|
105
|
+
stop!
|
106
|
+
raise "Error: Could not commit #{@name} container to image."
|
107
|
+
end
|
108
|
+
else
|
109
|
+
stop!
|
110
|
+
raise "Error: Could not start attached #{@name} container"
|
111
|
+
end
|
112
|
+
else
|
113
|
+
raise "Error: Could not create #{@name} container"
|
114
|
+
end
|
115
|
+
|
116
|
+
return false
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|