rat_deployer 0.4.0 → 0.5.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/lib/rat_deployer/cli.rb +50 -30
- data/lib/rat_deployer/command.rb +12 -24
- data/lib/rat_deployer/config.rb +24 -10
- data/lib/rat_deployer/notifier.rb +13 -13
- data/lib/rat_deployer/version.rb +1 -1
- data/lib/rat_deployer.rb +8 -0
- metadata +73 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d8370c118d92b2f06d327225481cb3d592a11167
|
4
|
+
data.tar.gz: a03cf3b020a9d3e38d99c6f1fa3adf56aa078e0d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e6626360686e73f7d236290cd3e842748b6d4b64f41afba11f0d4c8fb0125d71b76a895be6156b42c52c8b04db37d3f3e147c1fe7ccdbad94cbe031f1df63963
|
7
|
+
data.tar.gz: 7a2f2e575bb63d46e7eb7a074fb14e43e4f13f909e2fb0015030d9329e56e10b99f06f7c776c39fdab1a1ead62e972916053a073f7f6dc3d07ba1f07da47ed08
|
data/lib/rat_deployer/cli.rb
CHANGED
@@ -1,68 +1,88 @@
|
|
1
1
|
require 'thor'
|
2
2
|
require 'fileutils'
|
3
|
+
require 'active_support/core_ext/string/strip'
|
3
4
|
|
4
5
|
require 'rat_deployer/command'
|
5
6
|
require 'rat_deployer/notifier'
|
6
7
|
|
7
8
|
module RatDeployer
|
9
|
+
# The main Thor subclass
|
8
10
|
class Cli < Thor
|
9
11
|
include RatDeployer::Command
|
10
12
|
|
11
|
-
desc
|
13
|
+
desc 'deploy', 'deploys current environment'
|
12
14
|
def deploy(*services)
|
13
15
|
RatDeployer::Notifier.notify_deploy_start
|
14
|
-
|
15
|
-
if services.any?
|
16
|
-
services_str = services.join(' ')
|
17
|
-
compose("pull #{services_str}")
|
18
|
-
compose("up -d --no-deps --force-recreate #{services_str}")
|
19
|
-
else
|
20
|
-
compose('pull')
|
21
|
-
compose('up -d')
|
22
|
-
end
|
23
|
-
|
16
|
+
do_deploy(*services)
|
24
17
|
RatDeployer::Notifier.notify_deploy_end
|
25
|
-
rescue
|
26
|
-
RatDeployer::Notifier.notify <<-STR
|
27
|
-
Failed deploy on #{
|
28
|
-
Reason:
|
29
|
-
|
18
|
+
rescue StandardError => e
|
19
|
+
RatDeployer::Notifier.notify <<-STR.strip_heredoc
|
20
|
+
Failed deploy on #{RatDeployer::Config.env}
|
21
|
+
Reason:
|
22
|
+
#{e.message}
|
30
23
|
STR
|
31
24
|
raise e
|
32
25
|
end
|
33
26
|
|
34
|
-
desc
|
27
|
+
desc 'compose ARGS...', 'runs docker-compose command with default flags'
|
35
28
|
def compose(cmd, *cmd_flags, silent: false)
|
36
|
-
|
37
|
-
|
29
|
+
run(
|
30
|
+
[
|
31
|
+
'docker-compose',
|
32
|
+
compose_flags,
|
33
|
+
cmd,
|
34
|
+
cmd_flags
|
35
|
+
].flatten.join(' '),
|
36
|
+
silent: silent
|
37
|
+
)
|
38
|
+
.fetch(:output)
|
39
|
+
end
|
38
40
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
"-p #{project_name}_#{env}"
|
43
|
-
]
|
41
|
+
desc 'docker ARGS...', 'runs docker command with default flags'
|
42
|
+
def docker(cmd, *cmd_flags)
|
43
|
+
flags = []
|
44
44
|
|
45
45
|
if RatDeployer::Config.remote
|
46
46
|
flags.unshift(RatDeployer::Config.remote_machine_flags)
|
47
47
|
end
|
48
48
|
|
49
|
-
cmd = run "docker
|
49
|
+
cmd = run "docker #{flags.join(' ')} #{cmd} #{cmd_flags.join(' ')}"
|
50
50
|
cmd.fetch(:output)
|
51
51
|
end
|
52
52
|
|
53
|
-
|
54
|
-
|
53
|
+
private
|
54
|
+
|
55
|
+
def do_deploy(*services)
|
56
|
+
if services.any?
|
57
|
+
services_str = services.join(' ')
|
58
|
+
compose("pull #{services_str}")
|
59
|
+
compose("up -d --no-deps --force-recreate #{services_str}")
|
60
|
+
else
|
61
|
+
compose('pull')
|
62
|
+
compose('up -d')
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def compose_flags
|
55
67
|
env = RatDeployer::Config.env
|
56
68
|
project_name = RatDeployer::Config.all.fetch('project_name')
|
57
69
|
|
58
|
-
|
70
|
+
config_files =
|
71
|
+
RatDeployer::Config.for_env['config_files'] || %W[
|
72
|
+
config/default.yml
|
73
|
+
config/#{env}.yml
|
74
|
+
]
|
75
|
+
|
76
|
+
flags = [
|
77
|
+
config_files.map { |cf| "-f #{cf}" },
|
78
|
+
"-p #{project_name}_#{env}"
|
79
|
+
]
|
59
80
|
|
60
81
|
if RatDeployer::Config.remote
|
61
82
|
flags.unshift(RatDeployer::Config.remote_machine_flags)
|
62
83
|
end
|
63
84
|
|
64
|
-
|
65
|
-
cmd.fetch(:output)
|
85
|
+
flags
|
66
86
|
end
|
67
87
|
end
|
68
88
|
end
|
data/lib/rat_deployer/command.rb
CHANGED
@@ -1,13 +1,16 @@
|
|
1
|
-
require
|
1
|
+
require 'colorize'
|
2
2
|
require 'highline/import'
|
3
3
|
require 'rat_deployer/config'
|
4
|
+
require 'English'
|
4
5
|
|
5
6
|
module RatDeployer
|
7
|
+
# Rat::Deployer encapsulates all code related to running a shell command
|
8
|
+
# and displaying it's output.
|
6
9
|
module Command
|
7
10
|
def run(cmd, silent: false)
|
8
11
|
if !silent && RatDeployer::Config.prompt_enabled?
|
9
|
-
|
10
|
-
|
12
|
+
puts '||=> Running command '.colorize(:blue) +
|
13
|
+
"`#{cmd.colorize(:white)}`"
|
11
14
|
end
|
12
15
|
|
13
16
|
command = do_run(cmd, silent: silent)
|
@@ -16,18 +19,19 @@ module RatDeployer
|
|
16
19
|
end
|
17
20
|
|
18
21
|
def do_run(cmd, silent: false)
|
19
|
-
output
|
22
|
+
output = ''
|
23
|
+
status = 1
|
20
24
|
|
21
|
-
IO.popen(cmd) do |io|
|
22
|
-
while line = io.gets
|
25
|
+
IO.popen(ENV, cmd) do |io|
|
26
|
+
while line = io.gets # rubocop:disable Lint/AssignmentInCondition
|
23
27
|
puts line unless silent
|
24
28
|
output << line
|
25
29
|
end
|
26
30
|
io.close
|
27
|
-
status =
|
31
|
+
status = $CHILD_STATUS.to_i
|
28
32
|
end
|
29
33
|
|
30
|
-
{output: output, status: status}
|
34
|
+
{ output: output, status: status }
|
31
35
|
end
|
32
36
|
|
33
37
|
def put_heading(str)
|
@@ -45,22 +49,6 @@ module RatDeployer
|
|
45
49
|
puts colorize_warning(str)
|
46
50
|
end
|
47
51
|
|
48
|
-
def ask_for_confirmation
|
49
|
-
return unless RatDeployer::Config.prompt_enabled?
|
50
|
-
prompt = "Are you sure you want to continue?"
|
51
|
-
|
52
|
-
a = ''
|
53
|
-
s = '[y/n]'
|
54
|
-
d = 'y'
|
55
|
-
|
56
|
-
until %w[y n].include? a
|
57
|
-
a = ask(colorize_warning("#{prompt} #{s} ")) { |q| q.limit = 1; q.case = :downcase }
|
58
|
-
a = d if a.length == 0
|
59
|
-
end
|
60
|
-
|
61
|
-
exit 1 unless a == 'y'
|
62
|
-
end
|
63
|
-
|
64
52
|
def colorize_warning(str)
|
65
53
|
"\\\\ #{str}".colorize(:yellow)
|
66
54
|
end
|
data/lib/rat_deployer/config.rb
CHANGED
@@ -2,36 +2,50 @@ require 'yaml'
|
|
2
2
|
require 'deep_merge'
|
3
3
|
|
4
4
|
module RatDeployer
|
5
|
+
# This module handles config fetching from env and config files
|
5
6
|
module Config
|
6
7
|
def self.all
|
7
8
|
@all ||= YAML.load_file(File.expand_path('./rat_config.yml')) || {}
|
8
9
|
end
|
10
|
+
|
9
11
|
def self.for_env(e = env)
|
10
12
|
environmental = all.fetch('environments', {})
|
11
13
|
default_conf = environmental.fetch('default', {})
|
12
|
-
env_conf = environmental.fetch(e)
|
14
|
+
env_conf = environmental.fetch(e, {})
|
13
15
|
|
14
16
|
default_conf.deep_merge(env_conf)
|
15
17
|
end
|
16
18
|
|
17
|
-
def self.prompt_enabled?
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
def self.
|
19
|
+
def self.prompt_enabled?
|
20
|
+
ENV['RAT_PROMPT'] != 'false'
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.remote
|
24
|
+
ENV['RAT_REMOTE'] =~ /true|1|yes/
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.env
|
28
|
+
ENV['RAT_ENV'] || 'default'
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.images
|
32
|
+
all.fetch('images', {})
|
33
|
+
end
|
22
34
|
|
23
35
|
def self.remote_machine_flags
|
36
|
+
machine = for_env.fetch('machine')
|
37
|
+
|
24
38
|
case machine
|
25
|
-
when Symbol, String
|
26
|
-
`docker-machine config #{machine}`.gsub(/\n/, ' ')
|
27
39
|
when Hash
|
28
40
|
[
|
29
|
-
|
41
|
+
'--tlsverify',
|
30
42
|
"-H='#{machine.fetch('host')}'",
|
31
43
|
"--tlscacert='#{machine.fetch('ca_cert')}'",
|
32
44
|
"--tlscert='#{machine.fetch('cert')}'",
|
33
|
-
"--tlskey='#{machine.fetch('key')}'"
|
45
|
+
"--tlskey='#{machine.fetch('key')}'"
|
34
46
|
].join(' ')
|
47
|
+
else
|
48
|
+
raise 'Bad configuration value for `machine`'
|
35
49
|
end
|
36
50
|
end
|
37
51
|
end
|
@@ -3,39 +3,38 @@ require 'active_support/core_ext/string'
|
|
3
3
|
require 'slack-notifier'
|
4
4
|
|
5
5
|
module RatDeployer
|
6
|
+
# RatDeployer::Notifier handles notifications to slack
|
6
7
|
module Notifier
|
7
8
|
def self.notify_deploy_start
|
8
9
|
return unless webhook_url
|
9
|
-
notify_deploy "Starting deploy on #{
|
10
|
+
notify_deploy "Starting deploy on #{RatDeployer::Config.env}"
|
10
11
|
end
|
11
12
|
|
12
13
|
def self.notify_deploy_end
|
13
14
|
return unless webhook_url
|
14
|
-
notify_deploy "Ended deploy on #{
|
15
|
+
notify_deploy "Ended deploy on #{RatDeployer::Config.env}"
|
15
16
|
end
|
16
17
|
|
17
18
|
def self.notify(msg)
|
18
19
|
return unless webhook_url
|
19
20
|
return unless webhook_url
|
20
|
-
|
21
|
+
slack_notifier.ping msg
|
21
22
|
end
|
22
23
|
|
23
|
-
private
|
24
|
-
|
25
24
|
def self.notify_deploy(title)
|
26
25
|
return unless webhook_url
|
27
|
-
props =
|
26
|
+
props = deploy_properties
|
28
27
|
|
29
28
|
slack_notifier.post(
|
30
29
|
text: title,
|
31
30
|
attachments: [{
|
32
31
|
title: 'Deploy details',
|
33
|
-
fields:
|
32
|
+
fields: props.map do |k, v|
|
34
33
|
{
|
35
34
|
title: k.to_s.titleize,
|
36
35
|
value: k == :images ? v.join(' · ') : v,
|
37
36
|
short: k != :images
|
38
|
-
|
37
|
+
}
|
39
38
|
end
|
40
39
|
}]
|
41
40
|
)
|
@@ -55,17 +54,18 @@ module RatDeployer
|
|
55
54
|
end
|
56
55
|
|
57
56
|
def self.webhook_url
|
58
|
-
@webhook_url ||= RatDeployer::Config.all[
|
57
|
+
@webhook_url ||= RatDeployer::Config.all['slack_webhook_url']
|
59
58
|
end
|
60
59
|
|
61
|
-
def self.
|
60
|
+
def self.deploy_properties
|
62
61
|
require 'socket'
|
63
62
|
|
64
|
-
|
65
|
-
|
63
|
+
compose_config = RatDeployer::Cli.new.compose('config', silent: true)
|
64
|
+
docker_config = YAML.safe_load(compose_config)
|
65
|
+
images = docker_config['services'].map { |_s, c| c['image'] }.uniq.sort
|
66
66
|
|
67
67
|
{
|
68
|
-
env:
|
68
|
+
env: RatDeployer::Config.env,
|
69
69
|
user: ENV.fetch('USER'),
|
70
70
|
hostname: Socket.gethostname,
|
71
71
|
started_at: Time.now.to_s,
|
data/lib/rat_deployer/version.rb
CHANGED
data/lib/rat_deployer.rb
CHANGED
@@ -1,6 +1,14 @@
|
|
1
1
|
require 'rat_deployer/version'
|
2
2
|
require 'rat_deployer/config'
|
3
3
|
|
4
|
+
# Rat is a deploy tool for docker users.
|
5
|
+
# It implements a facade around 2 docker CLIs:
|
6
|
+
# - docker
|
7
|
+
# - docler-compose
|
8
|
+
#
|
9
|
+
# It is not very flexible and it is lightly tested.
|
10
|
+
# I named it rat because it is a rather little and
|
11
|
+
# ugly ball of code, but it does the job for now.
|
4
12
|
module RatDeployer
|
5
13
|
def self.print_rat
|
6
14
|
return unless RatDeployer::Config.prompt_enabled?
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rat_deployer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nicolas Oga
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-08-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -122,6 +122,76 @@ dependencies:
|
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '10.0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rspec
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 3.6.0
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 3.6.0
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: activesupport
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: 5.1.3
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: 5.1.3
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: pry
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: 0.10.4
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: 0.10.4
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: simplecov
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - "~>"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: 0.15.0
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - "~>"
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: 0.15.0
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: rubocop
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - "~>"
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: 0.49.1
|
188
|
+
type: :development
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - "~>"
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: 0.49.1
|
125
195
|
description: A micro-framework to deploy dockerized apps
|
126
196
|
email:
|
127
197
|
- 2112.oga@gmail.com
|
@@ -158,7 +228,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
158
228
|
version: '0'
|
159
229
|
requirements: []
|
160
230
|
rubyforge_project:
|
161
|
-
rubygems_version: 2.
|
231
|
+
rubygems_version: 2.6.12
|
162
232
|
signing_key:
|
163
233
|
specification_version: 4
|
164
234
|
summary: A micro-framework to deploy dockerized apps
|