dream-ops 0.5.0 → 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9729a06fc81ca0a17b9897304d0de3562c28f05a
4
- data.tar.gz: 707bbb6ca751d6d55e5a6c2d0557d0f87c99329d
3
+ metadata.gz: 635291c5f60c092e9a6aadccbbb94b9c406f44aa
4
+ data.tar.gz: b53af42711e3c850419e528221e568bf14c136b7
5
5
  SHA512:
6
- metadata.gz: fd9d0dc3bc43af57f596e2d9e161481cf4b0bdc529c7c769c752d67df07f92258beb5f6fc2702949809a3a057e723f34d52da3e306a17e341c548c808ded35d5
7
- data.tar.gz: 7a9a2de51970785f8ce5a71bcffaf6f5f7cc523a0465350a1ef227a2cafaffded305f632007872b6246b61c2c05273e419731f3c22440a22522d3e3da4d79ef2
6
+ metadata.gz: dec24a3be06450e6b4aadd9907d65e5f3020681680337bf8c8e119e76ce1e39049fdfb22dc712195135d0a60b992aa365ad1652a9e99e1268efc44e1a681e1ad
7
+ data.tar.gz: 52451f10fd6658f6b443ad632c60285c24be4b28d3117fafa45bc617638e40eeaa8e603d3543b4a9a53c737c8a95ff9ff65d6607983f4b50aa5d3e8abdb4c69f
@@ -6,6 +6,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.6.0]
10
+
11
+ ### Added
12
+ - Added global `aws_profile` option
13
+ - Added spinner to all deployments to avoid CI hangs
14
+
9
15
  ## [0.5.0]
10
16
 
11
17
  ### Changed
data/README.md CHANGED
@@ -33,11 +33,12 @@ Commands:
33
33
  dream version # Display version
34
34
 
35
35
  Options:
36
- -F, [--format=FORMAT] # Output format to use.
37
- # Default: human
38
- -q, [--quiet], [--no-quiet] # Silence all informational output.
39
- -d, [--debug], [--no-debug] # Output debug information
40
- -i, [--ssh-key=SSH_KEY] # Path to SSH key
36
+ -F, [--format=FORMAT] # Output format to use.
37
+ # Default: human
38
+ -q, [--quiet], [--no-quiet] # Silence all informational output.
39
+ -d, [--debug], [--no-debug] # Output debug information
40
+ -i, [--ssh-key=SSH_KEY] # Path to SSH key
41
+ -p, [--aws-profile=AWS_PROFILE] # AWS profile to use
41
42
 
42
43
  ```
43
44
 
@@ -36,6 +36,7 @@ Gem::Specification.new do |spec|
36
36
 
37
37
  spec.add_dependency "rubyzip", "~> 1.2"
38
38
  spec.add_dependency "aws-sdk", "~> 2"
39
+ spec.add_dependency "inifile", "~> 3.0"
39
40
  spec.add_dependency "berkshelf", "~> 7.0"
40
41
  spec.add_dependency "thor", "~> 0.20"
41
42
  spec.add_dependency "chef", "~> 13.6"
@@ -10,6 +10,8 @@ end
10
10
 
11
11
  require "berkshelf"
12
12
  require "thor"
13
+ require "aws-sdk"
14
+ require "inifile"
13
15
 
14
16
  module DreamOps
15
17
 
@@ -76,6 +78,29 @@ module DreamOps
76
78
  @ssh_key = key
77
79
  end
78
80
 
81
+ # Specify AWS profile to use
82
+ def use_aws_profile(profile)
83
+ begin
84
+ shared_creds = Aws::SharedCredentials.new(profile_name: profile)
85
+ Aws.config.update(credentials: shared_creds)
86
+ rescue Aws::Errors::NoSuchProfileError => error
87
+ DreamOps.ui.error error
88
+ exit(1)
89
+ end
90
+
91
+ # Unfortunately, Aws::OpsWorks::Client only loads the default profile's
92
+ # region. This parses the INI files and honors the profile region if set.
93
+ ini = IniFile.load("#{ENV['HOME']}/.aws/config")
94
+ if ini.nil? || !ini.has_section(profile)
95
+ ini = IniFile.load("#{ENV['HOME']}/.aws/credentials")
96
+ end
97
+
98
+ region = ini.to_h[profile]['region']
99
+ if !region.nil? && !region.empty?
100
+ Aws.config.update(region: region)
101
+ end
102
+ end
103
+
79
104
  # Get whether to always run setup
80
105
  #
81
106
  # @return [~boolean]
@@ -65,10 +65,14 @@ module DreamOps
65
65
 
66
66
  DreamOps.set_format @options[:format]
67
67
 
68
- if @options[:ssh_key]
68
+ if !@options[:ssh_key].empty?
69
69
  DreamOps.set_ssh_key @options[:ssh_key]
70
70
  end
71
71
 
72
+ if !@options[:aws_profile].empty?
73
+ DreamOps.use_aws_profile @options[:aws_profile]
74
+ end
75
+
72
76
  @options = options.dup # unfreeze frozen options Hash from Thor
73
77
  end
74
78
 
@@ -100,6 +104,11 @@ module DreamOps
100
104
  desc: "Path to SSH key",
101
105
  aliases: "-i",
102
106
  default: ""
107
+ class_option :aws_profile,
108
+ type: :string,
109
+ desc: "AWS profile to use",
110
+ aliases: "-p",
111
+ default: ""
103
112
 
104
113
  desc "version", "Display version"
105
114
  def version
@@ -3,6 +3,15 @@ require 'fileutils'
3
3
 
4
4
  module DreamOps
5
5
  class BaseDeployer
6
+ @@spinner = Enumerator.new do |e|
7
+ loop do
8
+ e.yield '|'
9
+ e.yield '/'
10
+ e.yield '-'
11
+ e.yield '\\'
12
+ end
13
+ end
14
+
6
15
  class << self
7
16
  #
8
17
  # @macro deployer_method
@@ -96,6 +105,11 @@ module DreamOps
96
105
  end
97
106
 
98
107
  def deploy(*args)
108
+ # Ensure git is installed
109
+ if (!system("which git > /dev/null 2>&1"))
110
+ __bail_with_fatal_error(GitNotInstalledError.new)
111
+ end
112
+
99
113
  # Find unique cookbooks and deploy targets
100
114
  result = analyze(args)
101
115
 
@@ -240,8 +240,12 @@ module DreamOps
240
240
  status = "failed"
241
241
  while true
242
242
  status = get_deployment_status(deployment_id)
243
- break if ["successful", "failed"].include? status
243
+ if ["successful", "failed"].include? status
244
+ print "\b"
245
+ break
246
+ end
244
247
  sleep(2)
248
+ print "\r#{@@spinner.next}"
245
249
  end
246
250
  return status
247
251
  end
@@ -1,4 +1,5 @@
1
1
  require 'securerandom'
2
+ require 'timeout'
2
3
 
3
4
  module DreamOps
4
5
  class SoloDeployer < BaseDeployer
@@ -10,6 +11,20 @@ module DreamOps
10
11
  return cookbooks.any? {|c| c[:targets].include? target }
11
12
  end
12
13
 
14
+ def __wait_for_pid(pid)
15
+ while true do
16
+ begin
17
+ Timeout.timeout(5) do
18
+ Process.wait pid
19
+ end
20
+ print "\b"
21
+ return $?.exitstatus == 0
22
+ rescue Timeout::Error
23
+ print "\r#{@@spinner.next}"
24
+ end
25
+ end
26
+ end
27
+
13
28
  # Analyze the SSH hosts for deployment
14
29
  #
15
30
  # @return [Hash]
@@ -146,11 +161,18 @@ module DreamOps
146
161
 
147
162
  uuid = SecureRandom.uuid
148
163
 
149
- if ! system(
150
- "ssh #{@ssh_opts} #{target[:host]} \"" +
151
- "set -o pipefail && " +
152
- "sudo chef-solo -j /var/chef/chef.json -o \"role[#{role}]\" 2>&1 | sudo tee /var/log/chef/#{uuid}.log #{@q_all}\""
153
- )
164
+ pid = fork do
165
+ if ! system(
166
+ "ssh #{@ssh_opts} #{target[:host]} \"" +
167
+ "set -o pipefail && " +
168
+ "sudo chef-solo -j /var/chef/chef.json -o \"role[#{role}]\" 2>&1 | sudo tee /var/log/chef/#{uuid}.log #{@q_all}\""
169
+ )
170
+ exit 1
171
+ end
172
+ exit 0
173
+ end
174
+
175
+ if !__wait_for_pid(pid)
154
176
  __bail_with_fatal_error(ChefSoloFailedError.new(target[:host], "/var/log/chef/#{uuid}.log"))
155
177
  end
156
178
  end
@@ -148,4 +148,12 @@ module DreamOps
148
148
  ].join("\n")
149
149
  end
150
150
  end
151
+
152
+ class GitNotInstalledError < DreamOpsError
153
+ set_status_code(19)
154
+
155
+ def to_s
156
+ "Unabled to find git in your PATH."
157
+ end
158
+ end
151
159
  end
@@ -1,3 +1,3 @@
1
1
  module DreamOps
2
- VERSION = "0.5.0"
2
+ VERSION = "0.6.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dream-ops
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Allen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-02-14 00:00:00.000000000 Z
11
+ date: 2020-03-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '2'
69
+ - !ruby/object:Gem::Dependency
70
+ name: inifile
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: berkshelf
71
85
  requirement: !ruby/object:Gem::Requirement