dream-ops 0.1.0 → 0.2.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/README.md +21 -8
- data/lib/dream-ops.rb +17 -9
- data/lib/dream-ops/cli.rb +14 -41
- data/lib/dream-ops/deployment/base.rb +39 -3
- data/lib/dream-ops/deployment/opsworks.rb +80 -31
- data/lib/dream-ops/errors.rb +31 -1
- data/lib/dream-ops/formatters/human.rb +1 -1
- data/lib/dream-ops/logger.rb +18 -0
- data/lib/dream-ops/mixin/logging.rb +12 -0
- data/lib/dream-ops/version.rb +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fe5971e39855c322c3680d7495452950f6e129ac
|
4
|
+
data.tar.gz: 6d7b6cd6b14ae02429694879aa34d7656ecd2228
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 04e7efd3f5108eb2f547265bee1b326a1523d4e19b8cd49eea62b0d45c7331509ec380d5a7d4e996312bf6d90fcd3665226d4fa220fb8f81644e93d24be31ac5
|
7
|
+
data.tar.gz: 642468eaabb2ec607aa1c3415dc21052884927d6e8835bca5849a9d08eee1edf966cc66db02993962a34438b73f0649f776ca786c077f23e89ee43b03cda8d22
|
data/README.md
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
# DreamOps
|
2
|
+
[][gem]
|
2
3
|
|
3
|
-
|
4
|
+
[gem]: https://rubygems.org/gems/dream-ops
|
4
5
|
|
5
|
-
|
6
|
+
CLI for Dream projects based on the [berkshelf](https://github.com/berkshelf/berkshelf) project.
|
6
7
|
|
7
8
|
## Installation
|
8
9
|
|
@@ -22,7 +23,23 @@ Or install it yourself as:
|
|
22
23
|
|
23
24
|
## Usage
|
24
25
|
|
25
|
-
|
26
|
+
```bash
|
27
|
+
dream help
|
28
|
+
```
|
29
|
+
|
30
|
+
### Deploying to OpsWorks
|
31
|
+
|
32
|
+
```bash
|
33
|
+
dream deploy opsworks --stacks 08137c03-1e85-4787-b82c-cb825638cdfa
|
34
|
+
Stack: nodeapp
|
35
|
+
--- Cookbook: chef-nodeapp
|
36
|
+
--- Apps: ["nodeapp"]
|
37
|
+
...Building cookbook [chef-nodeapp]
|
38
|
+
...Deploying cookbook [chef-nodeapp]
|
39
|
+
...Updating custom cookbooks [stack="nodeapp"]
|
40
|
+
...Running setup command [stack="nodeapp"]
|
41
|
+
...Deploying [stack="nodeapp"] [app="nodeapp"]
|
42
|
+
```
|
26
43
|
|
27
44
|
## Development
|
28
45
|
|
@@ -32,8 +49,4 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
32
49
|
|
33
50
|
## Contributing
|
34
51
|
|
35
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/dream-ops.
|
36
|
-
|
37
|
-
## License
|
38
|
-
|
39
|
-
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
52
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/dream-ops.
|
data/lib/dream-ops.rb
CHANGED
@@ -11,24 +11,28 @@ end
|
|
11
11
|
require "berkshelf"
|
12
12
|
require "thor"
|
13
13
|
|
14
|
-
Berkshelf.ui.mute!
|
15
|
-
|
16
14
|
module DreamOps
|
17
15
|
|
18
16
|
require_relative "dream-ops/version"
|
19
17
|
require_relative "dream-ops/errors"
|
20
18
|
|
21
|
-
|
19
|
+
module Mixin
|
20
|
+
autoload :Logging, "dream-ops/mixin/logging"
|
21
|
+
end
|
22
|
+
|
23
|
+
autoload :Shell, "dream-ops/shell"
|
22
24
|
|
23
|
-
autoload :BaseFormatter,
|
24
|
-
autoload :HumanFormatter,
|
25
|
-
# autoload :JsonFormatter,
|
26
|
-
# autoload :NullFormatter,
|
25
|
+
autoload :BaseFormatter, "dream-ops/formatters/base"
|
26
|
+
autoload :HumanFormatter, "dream-ops/formatters/human"
|
27
|
+
# autoload :JsonFormatter, "dream-ops/formatters/json"
|
28
|
+
# autoload :NullFormatter, "dream-ops/formatters/null"
|
27
29
|
|
28
|
-
autoload :BaseDeployer,
|
30
|
+
autoload :BaseDeployer, "dream-ops/deployment/base"
|
29
31
|
autoload :OpsWorksDeployer, "dream-ops/deployment/opsworks"
|
30
32
|
|
31
33
|
class << self
|
34
|
+
include Mixin::Logging
|
35
|
+
|
32
36
|
# @return [DreamOps::Shell]
|
33
37
|
def ui
|
34
38
|
@ui ||= DreamOps::Shell.new
|
@@ -57,4 +61,8 @@ module DreamOps
|
|
57
61
|
end
|
58
62
|
end
|
59
63
|
|
60
|
-
require_relative "dream-ops/cli"
|
64
|
+
require_relative "dream-ops/cli"
|
65
|
+
require_relative "dream-ops/logger"
|
66
|
+
|
67
|
+
Ridley.logger = DreamOps.logger
|
68
|
+
DreamOps.logger.level = Logger::WARN
|
data/lib/dream-ops/cli.rb
CHANGED
@@ -27,12 +27,8 @@ module DreamOps
|
|
27
27
|
@kernel.exit(0)
|
28
28
|
rescue DreamOps::DreamOpsError => e
|
29
29
|
DreamOps.ui.error e
|
30
|
-
DreamOps.ui.error "\t" + e.backtrace.join("\n\t") if ENV["
|
30
|
+
DreamOps.ui.error "\t" + e.backtrace.join("\n\t") if ENV["DREAMOPS_DEBUG"]
|
31
31
|
@kernel.exit(e.status_code)
|
32
|
-
# rescue Ridley::Errors::RidleyError => e
|
33
|
-
# DreamOps.ui.error "#{e.class} #{e}"
|
34
|
-
# DreamOps.ui.error "\t" + e.backtrace.join("\n\t") if ENV["BERKSHELF_DEBUG"]
|
35
|
-
# @kernel.exit(47)
|
36
32
|
end
|
37
33
|
end
|
38
34
|
|
@@ -56,17 +52,11 @@ module DreamOps
|
|
56
52
|
def initialize(*args)
|
57
53
|
super(*args)
|
58
54
|
|
59
|
-
# if @options[:config]
|
60
|
-
# unless File.exist?(@options[:config])
|
61
|
-
# raise ConfigNotFound.new(:berkshelf, @options[:config])
|
62
|
-
# end
|
63
|
-
|
64
|
-
# DreamOps.config = DreamOps::Config.from_file(@options[:config])
|
65
|
-
# end
|
66
|
-
|
67
55
|
if @options[:debug]
|
68
|
-
ENV["
|
56
|
+
ENV["DREAMOPS_DEBUG"] = "true"
|
69
57
|
DreamOps.logger.level = ::Logger::DEBUG
|
58
|
+
else
|
59
|
+
Berkshelf.ui.mute!
|
70
60
|
end
|
71
61
|
|
72
62
|
if @options[:quiet]
|
@@ -77,19 +67,13 @@ module DreamOps
|
|
77
67
|
@options = options.dup # unfreeze frozen options Hash from Thor
|
78
68
|
end
|
79
69
|
|
80
|
-
namespace "
|
70
|
+
namespace "dream-ops"
|
81
71
|
|
82
|
-
map "ls" => :list
|
83
|
-
map "book" => :cookbook
|
72
|
+
# map "ls" => :list
|
84
73
|
map ["ver", "-v", "--version"] => :version
|
85
74
|
|
86
|
-
default_task :
|
75
|
+
default_task :version
|
87
76
|
|
88
|
-
class_option :config,
|
89
|
-
type: :string,
|
90
|
-
desc: "Path to DreamOps configuration to use.",
|
91
|
-
aliases: "-c",
|
92
|
-
banner: "PATH"
|
93
77
|
class_option :format,
|
94
78
|
type: :string,
|
95
79
|
default: "human",
|
@@ -115,8 +99,9 @@ module DreamOps
|
|
115
99
|
method_option :stacks,
|
116
100
|
type: :array,
|
117
101
|
desc: "Only these stack IDs.",
|
118
|
-
aliases: "-s"
|
119
|
-
|
102
|
+
aliases: "-s",
|
103
|
+
required: true
|
104
|
+
desc "deploy [TYPE]", "Deploys to specified targets"
|
120
105
|
def deploy(type)
|
121
106
|
deployer = nil
|
122
107
|
|
@@ -125,26 +110,14 @@ module DreamOps
|
|
125
110
|
deployer = OpsWorksDeployer.new
|
126
111
|
stack_ids = options[:stacks]
|
127
112
|
args = [*stack_ids]
|
113
|
+
else
|
114
|
+
DreamOps.ui.error "Deployment of type '#{type}' is not supported"
|
115
|
+
exit(1)
|
128
116
|
end
|
129
117
|
|
130
118
|
if !deployer.nil?
|
131
119
|
deployer.deploy(*args)
|
132
120
|
end
|
133
121
|
end
|
134
|
-
|
135
|
-
# tasks["cookbook"].options = DreamOps::CookbookGenerator.class_options
|
136
|
-
|
137
|
-
private
|
138
|
-
|
139
|
-
# Print a list of the given cookbooks. This is used by various
|
140
|
-
# methods like {list} and {contingent}.
|
141
|
-
#
|
142
|
-
# @param [Array<CachedCookbook>] cookbooks
|
143
|
-
#
|
144
|
-
def print_list(cookbooks)
|
145
|
-
Array(cookbooks).sort.each do |cookbook|
|
146
|
-
DreamOps.formatter.msg " * #{cookbook.cookbook_name} (#{cookbook.version})"
|
147
|
-
end
|
148
|
-
end
|
149
122
|
end
|
150
|
-
end
|
123
|
+
end
|
@@ -20,13 +20,47 @@ module DreamOps
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
#
|
23
|
+
# This method MUST be implemented by subclasses.
|
24
|
+
#
|
25
|
+
# @return [Hash]
|
26
|
+
# a hash containing cookbooks that need to be built/updated
|
27
|
+
# and deploy targets
|
28
|
+
#
|
29
|
+
# Example:
|
30
|
+
# {
|
31
|
+
# :cookbooks => [
|
32
|
+
# {
|
33
|
+
# :bucket => "chef-app",
|
34
|
+
# :cookbook_key => "chef-app-dev.zip",
|
35
|
+
# :sha_key => "chef-app-dev_SHA.txt",
|
36
|
+
# :name => "chef-app",
|
37
|
+
# :path => "./chef",
|
38
|
+
# :local_sha => "7bfa19491170563f422a321c144800f4435323b1",
|
39
|
+
# :remote_sha => ""
|
40
|
+
# }
|
41
|
+
# ],
|
42
|
+
# deploy_targets: [
|
43
|
+
# #<Hash>,
|
44
|
+
# #<Hash>
|
45
|
+
# ]
|
46
|
+
# }
|
24
47
|
deployer_method :analyze
|
48
|
+
|
49
|
+
# This method MUST be implemented by subclasses.
|
50
|
+
#
|
51
|
+
# @param [Hash] cookbook
|
52
|
+
# a hash containing the cookbook details
|
25
53
|
deployer_method :deploy_cookbook
|
54
|
+
|
55
|
+
|
56
|
+
# This method MUST be implemented by subclasses.
|
57
|
+
#
|
58
|
+
# @param [Hash] target
|
59
|
+
# a hash containing the deploy target details
|
26
60
|
deployer_method :deploy_target
|
27
61
|
|
28
62
|
# It may turn out that cookbook building will be different for different
|
29
|
-
# deployments, but for now all deployments build them the same way.
|
63
|
+
# deployments, but for now all deployments will build them the same way.
|
30
64
|
def build_cookbook(cookbook)
|
31
65
|
berksfile = Berkshelf::Berksfile.from_file(File.join(cookbook[:path], "Berksfile"))
|
32
66
|
berksfile.vendor("berks-cookbooks")
|
@@ -69,11 +103,13 @@ module DreamOps
|
|
69
103
|
deploy_threads.each do |t|
|
70
104
|
begin
|
71
105
|
t.join
|
72
|
-
rescue DreamOps::
|
106
|
+
rescue DreamOps::DreamOpsError
|
107
|
+
DreamOps.ui.error "#{$!}"
|
73
108
|
deploy_success = deploy_success && false
|
74
109
|
end
|
75
110
|
end
|
76
111
|
|
112
|
+
# If ANY deploy threads failed, exit with failure
|
77
113
|
exit(1) if !deploy_success
|
78
114
|
end
|
79
115
|
end
|
@@ -6,13 +6,48 @@ Aws.use_bundled_cert!
|
|
6
6
|
module DreamOps
|
7
7
|
class OpsWorksDeployer < BaseDeployer
|
8
8
|
|
9
|
-
#
|
9
|
+
# Analyze the OpsWorks stacks for deployment
|
10
|
+
#
|
11
|
+
# @return [Hash]
|
12
|
+
# a hash containing cookbooks that need to be built/updated
|
13
|
+
# and deploy targets
|
14
|
+
#
|
15
|
+
# Example:
|
16
|
+
# {
|
17
|
+
# :cookbooks => [
|
18
|
+
# {
|
19
|
+
# :bucket => "chef-app",
|
20
|
+
# :cookbook_key => "chef-app-dev.zip",
|
21
|
+
# :sha_key => "chef-app-dev_SHA.txt",
|
22
|
+
# :name => "chef-app",
|
23
|
+
# :path => "./chef",
|
24
|
+
# :local_sha => "7bfa19491170563f422a321c144800f4435323b1",
|
25
|
+
# :remote_sha => ""
|
26
|
+
# }
|
27
|
+
# ],
|
28
|
+
# deploy_targets: [
|
29
|
+
# {
|
30
|
+
# :stack => #<Stack: name="my-stack">,
|
31
|
+
# :apps => [
|
32
|
+
# #<App: name="my-app"
|
33
|
+
# ],
|
34
|
+
# :cookbook => {
|
35
|
+
# :bucket => "chef-app",
|
36
|
+
# :cookbook_key => "chef-app-dev.zip",
|
37
|
+
# :sha_key => "chef-app-dev_SHA.txt",
|
38
|
+
# :name => "chef-app",
|
39
|
+
# :path => "./chef",
|
40
|
+
# :local_sha => "7bfa19491170563f422a321c144800f4435323b1",
|
41
|
+
# :remote_sha => ""
|
42
|
+
# }
|
43
|
+
# }
|
44
|
+
# ]
|
45
|
+
# }
|
10
46
|
def analyze(stack_ids)
|
11
47
|
begin
|
12
48
|
@opsworks = Aws::OpsWorks::Client.new
|
13
49
|
stacks = @opsworks.describe_stacks({ stack_ids: stack_ids, }).stacks
|
14
50
|
rescue => e
|
15
|
-
DreamOps.ui.error "Failed to fetch OpsWorks stacks\n"
|
16
51
|
DreamOps.ui.error "#{$!}"
|
17
52
|
exit(1)
|
18
53
|
end
|
@@ -42,8 +77,6 @@ module DreamOps
|
|
42
77
|
return result
|
43
78
|
end
|
44
79
|
|
45
|
-
################## OpsWorks specific methods ##################
|
46
|
-
|
47
80
|
# Retrieves stack apps and gets all information about remote/local cookbook
|
48
81
|
def analyze_stack(stack)
|
49
82
|
cookbook = nil
|
@@ -118,13 +151,8 @@ module DreamOps
|
|
118
151
|
# If this stack has a new cookbook
|
119
152
|
if !target[:cookbook].nil?
|
120
153
|
if __cookbook_in_array(target[:cookbook], cookbooks)
|
121
|
-
|
122
|
-
|
123
|
-
update_custom_cookbooks(target[:stack])
|
124
|
-
rescue Aws::OpsWorks::Errors::ValidationException
|
125
|
-
DreamOps.ui.error "Stack \"#{target[:stack].name}\" has no running instances."
|
126
|
-
__bail_with_fatal_error
|
127
|
-
end
|
154
|
+
# Grab a fresh copy of the cookbook on all instances in the stack
|
155
|
+
update_custom_cookbooks(target[:stack])
|
128
156
|
|
129
157
|
# Re-run the setup step for all layers
|
130
158
|
setup(target[:stack])
|
@@ -133,22 +161,27 @@ module DreamOps
|
|
133
161
|
|
134
162
|
# Deploy all apps for stack
|
135
163
|
target[:apps].each do |app|
|
136
|
-
|
137
|
-
deploy_app(app, target[:stack])
|
138
|
-
rescue Aws::OpsWorks::Errors::ValidationException
|
139
|
-
DreamOps.ui.error "Stack \"#{target[:stack].name}\" has no running instances."
|
140
|
-
__bail_with_fatal_error
|
141
|
-
end
|
164
|
+
deploy_app(app, target[:stack])
|
142
165
|
end
|
143
166
|
end
|
144
167
|
|
145
168
|
def update_custom_cookbooks(stack)
|
146
169
|
DreamOps.ui.info "...Updating custom cookbooks [stack=\"#{stack.name}\"]"
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
170
|
+
begin
|
171
|
+
response = @opsworks.create_deployment({
|
172
|
+
stack_id: stack.stack_id,
|
173
|
+
command: { name: "update_custom_cookbooks" }
|
174
|
+
})
|
175
|
+
rescue Aws::OpsWorks::Errors::ValidationException
|
176
|
+
bail_with_fatal_error(NoRunningInstancesError.new(stack))
|
177
|
+
end
|
178
|
+
|
179
|
+
status = wait_for_deployment(response.deployment_id)
|
180
|
+
if status != 'successful'
|
181
|
+
bail_with_fatal_error(OpsWorksCommandFailedError.new(
|
182
|
+
stack, response.deployment_id, 'update_custom_cookbooks')
|
183
|
+
)
|
184
|
+
end
|
152
185
|
end
|
153
186
|
|
154
187
|
def setup(stack)
|
@@ -157,17 +190,33 @@ module DreamOps
|
|
157
190
|
stack_id: stack.stack_id,
|
158
191
|
command: { name: "setup" }
|
159
192
|
})
|
160
|
-
|
193
|
+
|
194
|
+
status = wait_for_deployment(response.deployment_id)
|
195
|
+
if status != 'successful'
|
196
|
+
bail_with_fatal_error(OpsWorksCommandFailedError.new(
|
197
|
+
stack, response.deployment_id, 'setup')
|
198
|
+
)
|
199
|
+
end
|
161
200
|
end
|
162
201
|
|
163
202
|
def deploy_app(app, stack)
|
164
203
|
DreamOps.ui.info "...Deploying [stack=\"#{stack.name}\"] [app=\"#{app.name}\"]"
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
204
|
+
begin
|
205
|
+
response = @opsworks.create_deployment({
|
206
|
+
stack_id: stack.stack_id,
|
207
|
+
app_id: app.app_id,
|
208
|
+
command: { name: "deploy" }
|
209
|
+
})
|
210
|
+
rescue Aws::OpsWorks::Errors::ValidationException
|
211
|
+
bail_with_fatal_error(NoRunningInstancesError.new(stack))
|
212
|
+
end
|
213
|
+
|
214
|
+
status = wait_for_deployment(response.deployment_id)
|
215
|
+
if status != 'successful'
|
216
|
+
bail_with_fatal_error(OpsWorksCommandFailedError.new(
|
217
|
+
stack, response.deployment_id, 'deploy')
|
218
|
+
)
|
219
|
+
end
|
171
220
|
end
|
172
221
|
|
173
222
|
def get_deployment_status(deployment_id)
|
@@ -188,8 +237,8 @@ module DreamOps
|
|
188
237
|
return status
|
189
238
|
end
|
190
239
|
|
191
|
-
def
|
192
|
-
raise
|
240
|
+
def bail_with_fatal_error(ex)
|
241
|
+
raise ex
|
193
242
|
Thread.exit
|
194
243
|
end
|
195
244
|
|
data/lib/dream-ops/errors.rb
CHANGED
@@ -11,5 +11,35 @@ module DreamOps
|
|
11
11
|
alias_method :message, :to_s
|
12
12
|
end
|
13
13
|
|
14
|
-
class
|
14
|
+
class NoRunningInstancesError < DreamOpsError
|
15
|
+
set_status_code(10)
|
16
|
+
|
17
|
+
def initialize(stack)
|
18
|
+
@stack = stack
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
"Stack \"#{@stack.name}\" has no running instances."
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class OpsWorksCommandFailedError < DreamOpsError
|
27
|
+
set_status_code(11)
|
28
|
+
|
29
|
+
def initialize(stack, deployment_id, command)
|
30
|
+
@stack = stack
|
31
|
+
@deployment_id = deployment_id
|
32
|
+
@command = command
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_s
|
36
|
+
[
|
37
|
+
"Stack \"#{@stack.name}\" failed running command '#{@command}'. To view the failure log, visit:",
|
38
|
+
"",
|
39
|
+
"https://console.aws.amazon.com/opsworks/home?region=#{@stack.region}#/stack/#{@stack.stack_id}/deployments/#{@deployment_id}",
|
40
|
+
].join("\n")
|
41
|
+
end
|
42
|
+
|
43
|
+
alias_method :message, :to_s
|
44
|
+
end
|
15
45
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module DreamOps
|
2
|
+
class Logger < Ridley::Logging::Logger
|
3
|
+
alias_method :fatal, :error
|
4
|
+
|
5
|
+
def deprecate(message)
|
6
|
+
trace = caller.join("\n\t")
|
7
|
+
warn "DEPRECATION WARNING: #{message}\n\t#{trace}"
|
8
|
+
end
|
9
|
+
|
10
|
+
# Log an exception and its backtrace to FATAL
|
11
|
+
#
|
12
|
+
# @param [Exception] ex
|
13
|
+
def exception(ex)
|
14
|
+
fatal("#{ex.class}: #{ex}")
|
15
|
+
fatal(ex.backtrace.join("\n")) unless ex.backtrace.nil?
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/dream-ops/version.rb
CHANGED
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.
|
4
|
+
version: 0.2.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: 2017-07-
|
11
|
+
date: 2017-07-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -152,6 +152,8 @@ files:
|
|
152
152
|
- lib/dream-ops/errors.rb
|
153
153
|
- lib/dream-ops/formatters/base.rb
|
154
154
|
- lib/dream-ops/formatters/human.rb
|
155
|
+
- lib/dream-ops/logger.rb
|
156
|
+
- lib/dream-ops/mixin/logging.rb
|
155
157
|
- lib/dream-ops/shell.rb
|
156
158
|
- lib/dream-ops/utils/zip.rb
|
157
159
|
- lib/dream-ops/version.rb
|
@@ -175,7 +177,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
175
177
|
version: 2.0.0
|
176
178
|
requirements: []
|
177
179
|
rubyforge_project:
|
178
|
-
rubygems_version: 2.
|
180
|
+
rubygems_version: 2.6.12
|
179
181
|
signing_key:
|
180
182
|
specification_version: 4
|
181
183
|
summary: This is the summary
|