knife-update 0.0.1
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.
- data/.gitignore +3 -0
- data/.rspec +1 -0
- data/Gemfile +8 -0
- data/README.md +78 -0
- data/Rakefile +20 -0
- data/knife-update.gemspec +21 -0
- data/lib/chef/knife/update.rb +86 -0
- data/lib/chef/knife/update_run.rb +117 -0
- data/lib/chef/knife/update_run_list.rb +53 -0
- data/lib/chef/knife/update_status.rb +39 -0
- data/lib/knife-update/version.rb +24 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/unit/update_spec.rb +23 -0
- metadata +99 -0
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
# knife update
|
2
|
+
|
3
|
+
A small collection of knife plugins to ease the process of safely updating
|
4
|
+
chef in a setup with hundreds of nodes.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
gem install knife-update
|
9
|
+
|
10
|
+
## Usage
|
11
|
+
|
12
|
+
### knife update status
|
13
|
+
|
14
|
+
Returns the current state of installed chef-client versions.
|
15
|
+
|
16
|
+
```bash
|
17
|
+
$ knife update status
|
18
|
+
Search nodes '*:*'
|
19
|
+
|
20
|
+
Currently installed chef-client versions:
|
21
|
+
Chef 0.9.12: 5 nodes
|
22
|
+
Chef 0.9.16: 10 nodes
|
23
|
+
Chef 0.9.18: 400 nodes
|
24
|
+
Chef 10.14.4: 500 nodes
|
25
|
+
Chef 10.24.0: 1000 nodes
|
26
|
+
```
|
27
|
+
|
28
|
+
### knife update run_list
|
29
|
+
|
30
|
+
Displays lists of run_list items both used and not yet used in the target
|
31
|
+
chef-client version.
|
32
|
+
|
33
|
+
```bash
|
34
|
+
$ knife update run_list
|
35
|
+
Search nodes '*:*'
|
36
|
+
|
37
|
+
Compatbile Chef 10.24.0 run_list items:
|
38
|
+
role[base]
|
39
|
+
role[web-server]
|
40
|
+
|
41
|
+
Incompatible / not tested run_list items:
|
42
|
+
role[loadbalancer]
|
43
|
+
role[database-server]
|
44
|
+
```
|
45
|
+
|
46
|
+
### knife update run
|
47
|
+
|
48
|
+
Updates all nodes which contain only run_list items already applied on other
|
49
|
+
nodes running the target chef-client version (therefore, assuming these are
|
50
|
+
compatible).
|
51
|
+
|
52
|
+
```bash
|
53
|
+
$ knife update run
|
54
|
+
Search nodes '*:*'
|
55
|
+
|
56
|
+
Update 2 nodes to chef 10.24.0
|
57
|
+
node01.example.com Successfully installed chef-10.24.0
|
58
|
+
node01.example.com 1 gem installed
|
59
|
+
node33.example.com Successfully installed chef-10.24.0
|
60
|
+
node33.example.com 1 gem installed
|
61
|
+
```
|
62
|
+
|
63
|
+
### Options
|
64
|
+
|
65
|
+
Lookup possible options for each command with the `-h` option. In addition to
|
66
|
+
common knife ssh options, the two update specific options are:
|
67
|
+
|
68
|
+
* `-q, --search-query QUERY`
|
69
|
+
|
70
|
+
Filter nodes by a different search query, defaults to `*:*`.
|
71
|
+
|
72
|
+
* `-t, --target-version VERSION`
|
73
|
+
|
74
|
+
The desired chef-client version, defaults to `Chef::VERSION` of knife.
|
75
|
+
|
76
|
+
## Authors
|
77
|
+
|
78
|
+
SoundCloud Inc., [Tobias Schmidt](mailto:ts@soundcloud.com)
|
data/Rakefile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
require 'rdoc/task'
|
3
|
+
|
4
|
+
Bundler::GemHelper.install_tasks
|
5
|
+
|
6
|
+
begin
|
7
|
+
require 'rspec/core/rake_task'
|
8
|
+
|
9
|
+
desc 'Default: run specs'
|
10
|
+
task :default => :spec
|
11
|
+
|
12
|
+
desc "Run all specs in spec directory"
|
13
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
14
|
+
t.pattern = 'spec/unit/**/*_spec.rb'
|
15
|
+
end
|
16
|
+
|
17
|
+
rescue LoadError
|
18
|
+
STDERR.puts "\n*** RSpec not available. (sudo) gem install rspec to run unit tests. ***\n\n"
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path('../lib', __FILE__)
|
3
|
+
require 'knife-update/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'knife-update'
|
7
|
+
s.version = Knife::Update::VERSION
|
8
|
+
s.authors = ['Tobias Schmidt']
|
9
|
+
s.email = ['ts@soundcloud.com']
|
10
|
+
s.homepage = 'https://github.com/soundcloud/knife-update'
|
11
|
+
s.summary = 'knife update plugin'
|
12
|
+
s.description = 'A small collection of knife plugins to ease the process of safely updating chef in a setup with hundreds of nodes.'
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
|
+
s.require_paths = ['lib']
|
18
|
+
|
19
|
+
s.add_dependency 'chef', '>= 0.10.24'
|
20
|
+
s.add_development_dependency 'rspec'
|
21
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Tobias Schmidt (<ts@soundcloud.com>)
|
3
|
+
# Copyright:: Copyright (c) 2013 SoundCloud, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'chef/knife'
|
20
|
+
|
21
|
+
class Chef
|
22
|
+
class Knife
|
23
|
+
module Update
|
24
|
+
def self.included(includer)
|
25
|
+
includer.class_eval do
|
26
|
+
|
27
|
+
deps do
|
28
|
+
require 'net/ssh'
|
29
|
+
require 'net/ssh/multi'
|
30
|
+
require 'chef/knife/ssh'
|
31
|
+
require 'chef/search/query'
|
32
|
+
|
33
|
+
Chef::Knife::Ssh.load_deps
|
34
|
+
end
|
35
|
+
|
36
|
+
option :query,
|
37
|
+
:short => "-q QUERY",
|
38
|
+
:long => "--search-query QUERY",
|
39
|
+
:description => "Filter nodes by search query",
|
40
|
+
:default => '*:*'
|
41
|
+
|
42
|
+
option :target_version,
|
43
|
+
:short => "-t VERSION",
|
44
|
+
:long => "--target-version VERSION",
|
45
|
+
:description => "The target chef-client version",
|
46
|
+
:default => Chef::VERSION
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Get a list of nodes and their used chef version
|
51
|
+
def node_list
|
52
|
+
list = {}
|
53
|
+
search = Chef::Search::Query.new
|
54
|
+
query = config[:query]
|
55
|
+
|
56
|
+
ui.msg "Search nodes '#{query}'"
|
57
|
+
search.search('node', query) do |node|
|
58
|
+
if node['chef'] && node['chef']['client_version']
|
59
|
+
version = node['chef']['client_version']
|
60
|
+
|
61
|
+
list[version] ||= []
|
62
|
+
list[version] << node
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
list
|
67
|
+
end
|
68
|
+
|
69
|
+
# List of all compatible run_list items
|
70
|
+
def run_list_items(nodes)
|
71
|
+
nodes.inject([]) do |memo, node|
|
72
|
+
node.run_list.each do |item|
|
73
|
+
memo << item.to_s unless memo.include?(item.to_s)
|
74
|
+
end
|
75
|
+
|
76
|
+
memo
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Returns target update chef version
|
81
|
+
def target_version
|
82
|
+
config[:target_version] || Chef::VERSION
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Tobias Schmidt (<ts@soundcloud.com>)
|
3
|
+
# Copyright:: Copyright (c) 2013 SoundCloud, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'chef/knife'
|
20
|
+
|
21
|
+
class Chef
|
22
|
+
class Knife
|
23
|
+
class UpdateRun < Knife
|
24
|
+
banner 'knife update run (options)'
|
25
|
+
|
26
|
+
option :ssh_user,
|
27
|
+
:short => "-x USERNAME",
|
28
|
+
:long => "--ssh-user USERNAME",
|
29
|
+
:description => "The ssh username",
|
30
|
+
:default => "root"
|
31
|
+
|
32
|
+
option :ssh_password,
|
33
|
+
:short => "-P PASSWORD",
|
34
|
+
:long => "--ssh-password PASSWORD",
|
35
|
+
:description => "The ssh password"
|
36
|
+
|
37
|
+
option :ssh_port,
|
38
|
+
:short => "-p PORT",
|
39
|
+
:long => "--ssh-port PORT",
|
40
|
+
:description => "The ssh port",
|
41
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:ssh_port] = key }
|
42
|
+
|
43
|
+
option :ssh_gateway,
|
44
|
+
:short => "-G GATEWAY",
|
45
|
+
:long => "--ssh-gateway GATEWAY",
|
46
|
+
:description => "The ssh gateway",
|
47
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:ssh_gateway] = key }
|
48
|
+
|
49
|
+
option :identity_file,
|
50
|
+
:short => "-i IDENTITY_FILE",
|
51
|
+
:long => "--identity-file IDENTITY_FILE",
|
52
|
+
:description => "The SSH identity file used for authentication"
|
53
|
+
|
54
|
+
option :host_key_verify,
|
55
|
+
:long => "--[no-]host-key-verify",
|
56
|
+
:description => "Verify host key, enabled by default.",
|
57
|
+
:boolean => true,
|
58
|
+
:default => true
|
59
|
+
|
60
|
+
option :use_sudo,
|
61
|
+
:long => "--sudo",
|
62
|
+
:description => "Execute the update via sudo",
|
63
|
+
:boolean => true
|
64
|
+
|
65
|
+
include Chef::Knife::Update
|
66
|
+
|
67
|
+
def run
|
68
|
+
list = node_list
|
69
|
+
items = run_list_items(list[target_version])
|
70
|
+
|
71
|
+
nodes = list.inject([]) do |memo, (version, nodes)|
|
72
|
+
if version != target_version
|
73
|
+
nodes.each do |node|
|
74
|
+
if node.run_list.all? { |item| items.include?(item.to_s) }
|
75
|
+
memo << node
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
memo
|
81
|
+
end
|
82
|
+
|
83
|
+
ui.msg "\nUpdate #{nodes.size} nodes to chef #{target_version}"
|
84
|
+
update_ssh(nodes, target_version).run
|
85
|
+
end
|
86
|
+
|
87
|
+
# Update given nodes to specified version
|
88
|
+
def update_ssh(nodes, version)
|
89
|
+
fqdns = nodes.map { |node| node.fqdn }.join(' ')
|
90
|
+
|
91
|
+
ssh = Chef::Knife::Ssh.new
|
92
|
+
ssh.ui = ui
|
93
|
+
ssh.name_args = [ fqdns, ssh_command(version) ]
|
94
|
+
ssh.config[:manual] = true
|
95
|
+
ssh.config[:ssh_user] = Chef::Config[:knife][:ssh_user] || config[:ssh_user]
|
96
|
+
ssh.config[:ssh_password] = config[:ssh_password]
|
97
|
+
ssh.config[:ssh_port] = Chef::Config[:knife][:ssh_port] || config[:ssh_port]
|
98
|
+
ssh.config[:ssh_gateway] = Chef::Config[:knife][:ssh_gateway] || config[:ssh_gateway]
|
99
|
+
ssh.config[:identity_file] = Chef::Config[:knife][:identity_file] || config[:identity_file]
|
100
|
+
ssh.config[:host_key_verify] = Chef::Config[:knife][:host_key_verify] || config[:host_key_verify]
|
101
|
+
ssh.config[:on_error] = :raise
|
102
|
+
ssh
|
103
|
+
end
|
104
|
+
|
105
|
+
def ssh_command(version)
|
106
|
+
command = "gem install chef -v #{version}"
|
107
|
+
|
108
|
+
if config[:use_sudo]
|
109
|
+
command = "sudo #{command}"
|
110
|
+
end
|
111
|
+
|
112
|
+
command
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Tobias Schmidt (<ts@soundcloud.com>)
|
3
|
+
# Copyright:: Copyright (c) 2013 SoundCloud, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'chef/knife'
|
20
|
+
|
21
|
+
class Chef
|
22
|
+
class Knife
|
23
|
+
class UpdateRunList < Knife
|
24
|
+
banner 'knife update run_list (options)'
|
25
|
+
|
26
|
+
include Chef::Knife::Update
|
27
|
+
|
28
|
+
def run
|
29
|
+
list = node_list
|
30
|
+
old_nodes = list.inject([]) do |memo, (version, nodes)|
|
31
|
+
version == target_version ? memo : memo += nodes
|
32
|
+
end
|
33
|
+
compatible = run_list_items(list[target_version])
|
34
|
+
incompatible = run_list_items(old_nodes)
|
35
|
+
|
36
|
+
if compatible.any?
|
37
|
+
ui.msg "\nCompatbile Chef #{target_version} run_list items:"
|
38
|
+
compatible.sort.each do |item|
|
39
|
+
ui.msg " #{item}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
if incompatible.any?
|
44
|
+
ui.msg "\Incompatible / not tested run_list items:"
|
45
|
+
incompatible.sort.each do |item|
|
46
|
+
ui.msg " #{item}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Tobias Schmidt (<ts@soundcloud.com>)
|
3
|
+
# Copyright:: Copyright (c) 2013 SoundCloud, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'chef/knife'
|
20
|
+
|
21
|
+
class Chef
|
22
|
+
class Knife
|
23
|
+
class UpdateStatus < Knife
|
24
|
+
banner 'knife update status (options)'
|
25
|
+
|
26
|
+
include Chef::Knife::Update
|
27
|
+
|
28
|
+
def run
|
29
|
+
list = node_list
|
30
|
+
|
31
|
+
ui.msg "\nCurrently installed chef-client versions:"
|
32
|
+
list.sort.each do |version, nodes|
|
33
|
+
ui.msg " Chef #{version}: #{nodes.size} nodes"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Tobias Schmidt (<ts@soundcloud.com>)
|
3
|
+
# Copyright:: Copyright (c) 2013 SoundCloud, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
module Knife
|
20
|
+
module Update
|
21
|
+
VERSION = '0.0.1'
|
22
|
+
MAJOR, MINOR, TINY = VERSION.split('.')
|
23
|
+
end
|
24
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Tobias Schmidt (<ts@soundcloud.com>)
|
3
|
+
# Copyright:: Copyright (c) 2013 SoundCloud, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
20
|
+
require 'chef/knife/update'
|
21
|
+
|
22
|
+
describe Chef::Knife::Update do
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: knife-update
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Tobias Schmidt
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-05-18 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: chef
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.10.24
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.10.24
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
description: A small collection of knife plugins to ease the process of safely updating
|
47
|
+
chef in a setup with hundreds of nodes.
|
48
|
+
email:
|
49
|
+
- ts@soundcloud.com
|
50
|
+
executables: []
|
51
|
+
extensions: []
|
52
|
+
extra_rdoc_files: []
|
53
|
+
files:
|
54
|
+
- .gitignore
|
55
|
+
- .rspec
|
56
|
+
- Gemfile
|
57
|
+
- README.md
|
58
|
+
- Rakefile
|
59
|
+
- knife-update.gemspec
|
60
|
+
- lib/chef/knife/update.rb
|
61
|
+
- lib/chef/knife/update_run.rb
|
62
|
+
- lib/chef/knife/update_run_list.rb
|
63
|
+
- lib/chef/knife/update_status.rb
|
64
|
+
- lib/knife-update/version.rb
|
65
|
+
- spec/spec_helper.rb
|
66
|
+
- spec/unit/update_spec.rb
|
67
|
+
homepage: https://github.com/soundcloud/knife-update
|
68
|
+
licenses: []
|
69
|
+
post_install_message:
|
70
|
+
rdoc_options: []
|
71
|
+
require_paths:
|
72
|
+
- lib
|
73
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ! '>='
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
segments:
|
80
|
+
- 0
|
81
|
+
hash: -334156609659399358
|
82
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
segments:
|
89
|
+
- 0
|
90
|
+
hash: -334156609659399358
|
91
|
+
requirements: []
|
92
|
+
rubyforge_project:
|
93
|
+
rubygems_version: 1.8.25
|
94
|
+
signing_key:
|
95
|
+
specification_version: 3
|
96
|
+
summary: knife update plugin
|
97
|
+
test_files:
|
98
|
+
- spec/spec_helper.rb
|
99
|
+
- spec/unit/update_spec.rb
|