rat_deployer 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9434ec7c84475197340d979cd8cd297eeed41802
4
- data.tar.gz: 9168a21f79a69cb597c61b703b3ec1ede5d65026
3
+ metadata.gz: d8370c118d92b2f06d327225481cb3d592a11167
4
+ data.tar.gz: a03cf3b020a9d3e38d99c6f1fa3adf56aa078e0d
5
5
  SHA512:
6
- metadata.gz: 8f62a6495fe7e3fa55c7a958c1bcaf5b39c2355cb1278236abdf51ee0bcd71e4306b572b5f5ef1ad20f1714dbdf448ed2273e11b9673610f843eaac4c737cbb3
7
- data.tar.gz: 9b1870d24db2c922e4556d260f129363e3a5385a0f4ca8b7706a11b0b9cf18e14217d7a6f31ef0262f994347168141a342b2dfc032bf2c2b824499a017987d1f
6
+ metadata.gz: e6626360686e73f7d236290cd3e842748b6d4b64f41afba11f0d4c8fb0125d71b76a895be6156b42c52c8b04db37d3f3e147c1fe7ccdbad94cbe031f1df63963
7
+ data.tar.gz: 7a2f2e575bb63d46e7eb7a074fb14e43e4f13f909e2fb0015030d9329e56e10b99f06f7c776c39fdab1a1ead62e972916053a073f7f6dc3d07ba1f07da47ed08
@@ -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 "deploy", "deploys current environment"
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 Exception => e
26
- RatDeployer::Notifier.notify <<-STR
27
- Failed deploy on #{ENV.fetch('RAT_ENV')}"
28
- Reason:
29
- #{e.message}
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 "compose ARGS...", "runs docker-compose command with default flags"
27
+ desc 'compose ARGS...', 'runs docker-compose command with default flags'
35
28
  def compose(cmd, *cmd_flags, silent: false)
36
- env = RatDeployer::Config.env
37
- project_name = RatDeployer::Config.all.fetch('project_name')
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
- flags = [
40
- "-f config/default.yml",
41
- "-f config/#{env}.yml",
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-compose #{flags.join(' ')} #{cmd} #{cmd_flags.join(" ")}", silent: silent
49
+ cmd = run "docker #{flags.join(' ')} #{cmd} #{cmd_flags.join(' ')}"
50
50
  cmd.fetch(:output)
51
51
  end
52
52
 
53
- desc "docker ARGS...", "runs docker command with default flags"
54
- def docker(cmd, *cmd_flags)
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
- flags = []
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
- cmd = run "docker #{flags.join(' ')} #{cmd} #{cmd_flags.join(" ")}"
65
- cmd.fetch(:output)
85
+ flags
66
86
  end
67
87
  end
68
88
  end
@@ -1,13 +1,16 @@
1
- require "colorize"
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
- msg = "||=> Running command ".colorize(:blue) + "`#{cmd.colorize(:white)}`"
10
- puts msg
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, status = '', 1
22
+ output = ''
23
+ status = 1
20
24
 
21
- IO.popen(cmd) do |io|
22
- while line = io.gets do
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 = $?.to_i
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
@@ -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?() ENV['RAT_PROMPT'] != "false" end
18
- def self.machine() for_env.fetch("machine") end
19
- def self.remote() ENV['RAT_REMOTE'] =~ /true|1|yes/ end
20
- def self.env() ENV.fetch('RAT_ENV') end
21
- def self.images() all.fetch('images', {}) end
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
- "--tlsverify",
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 #{ENV.fetch('RAT_ENV')}"
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 #{ENV.fetch('RAT_ENV')}"
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
- self.slack_notifier.ping msg
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 = get_deploy_properties
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: get_deploy_properties.map do |k,v|
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["slack_webhook_url"]
57
+ @webhook_url ||= RatDeployer::Config.all['slack_webhook_url']
59
58
  end
60
59
 
61
- def self.get_deploy_properties
60
+ def self.deploy_properties
62
61
  require 'socket'
63
62
 
64
- docker_config = YAML.load(RatDeployer::Cli.new.compose('config', silent: true))
65
- images = docker_config['services'].map { |s,c| c['image'] }.uniq.sort
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: ENV.fetch('RAT_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,
@@ -1,3 +1,3 @@
1
1
  module RatDeployer
2
- VERSION = "0.4.0"
2
+ VERSION = '0.5.0'.freeze
3
3
  end
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.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-07-17 00:00:00.000000000 Z
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.5.1
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