paknife 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bca870d53bfd6d690e0e82382be3cbc60829adc8
4
+ data.tar.gz: f8d3ac0dfe5d9c3cf50fc82f99e2b0a67f655d2a
5
+ SHA512:
6
+ metadata.gz: bca71ede71f52a8834b84af345566e3c6b25556c8a625eba1a81b03f652f13170b277ce599b000a3e264409d67e949f22e4a813e204a028dfd78ca90c8436641
7
+ data.tar.gz: e31008fbfd8a20d8539767642f96ecffc9b5fdf612a317b50b2be99068fd85e7a8f560da1aa1ab041c0437d6cb5026ba61eda8ad036dcd09d4e67f268b90dfa9
@@ -0,0 +1,16 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /sample/.vagrant
11
+ /sample/Gemfile.lock
12
+ *.bundle
13
+ *.so
14
+ *.o
15
+ *.a
16
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in paknife.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Masato Ikeda
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,79 @@
1
+ # Paknife
2
+
3
+ Run knife-solo in parallel.
4
+
5
+ $ paknife [<options>] <backend> <subcommand> <nodes> [<knife_options>]
6
+
7
+ ## Requirements
8
+
9
+ - Ruby >= 2.1
10
+ - [knife-solo](http://rubygems.org/gems/knife-solo) (or [knife-zero](http://rubygems.org/gems/knife-zero))
11
+
12
+ ## Installation
13
+
14
+ ```ruby
15
+ gem 'paknife'
16
+ ```
17
+
18
+ And then execute:
19
+
20
+ $ bundle
21
+
22
+ Or install it yourself as:
23
+
24
+ $ gem install paknife
25
+
26
+ ## Usage
27
+
28
+ You can run `knife solo cook` in parallel like:
29
+
30
+ $ paknife solo cook node1 node2 node3 node4
31
+
32
+ By default, it runs `bundle exec knife solo cook node1` and so on in two threads.
33
+
34
+ paknife may work with knife-zero like below, but isn't well tested yet:
35
+
36
+ $ paknife zero cook node1 node2
37
+
38
+ ### Knife's original options
39
+
40
+ You can pass knife-solo's (or knife-zero's) original options after nodes arguments like:
41
+
42
+ $ paknife solo cook node1 node2 -i /path/to/your/pem
43
+
44
+
45
+ ### Number of threads
46
+
47
+ You can specify the number of threads with `--threads VALUE` and `-t VALUE` options like:
48
+
49
+ $ paknife --threads 4 solo cook node1 node2 node3 node4
50
+
51
+ or
52
+
53
+ $ paknife --threads max solo cook node1 node2 nod3 node4
54
+
55
+ where `max` means "the number of nodes".
56
+
57
+ This feature is also available with `PARAKNIFE_THREADS` environment variable like:
58
+
59
+ $ export PARAKNIFE_THREADS=max
60
+ $ paknife solo cook node1 node2 node3 node4
61
+
62
+ ### Knife command
63
+
64
+ You can specify knife command with `--knife VALUE` and `-k VALUE` options like:
65
+
66
+ $ paknife --knife="/path/to/your/knife" solo cook node1 node2
67
+
68
+ This feature is also available with `PARAKNIFE_KNIFE` environment variable like:
69
+
70
+ $ export PARAKNIFE_KNIFE=/path/to/your/knife
71
+ $ paknife solo cook node1 node2
72
+
73
+ ## Contributing
74
+
75
+ 1. Fork it ( https://github.com/a2ikm/paknife/fork )
76
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
77
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
78
+ 4. Push to the branch (`git push origin my-new-feature`)
79
+ 5. Create a new Pull Request
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "paknife"
4
+
5
+ Paknife::Cli.run(ARGV)
@@ -0,0 +1,32 @@
1
+ #compdef paknife
2
+
3
+ _knife() {
4
+ local curcontext="$curcontext" state line
5
+ typeset -A opt_args
6
+ _arguments \
7
+ '(-k --knife)'{-k,--knife=}':knife: '\
8
+ '(-q --quiet)'{-q,--quiet}''\
9
+ '(-t --threads)'{-t,--threads=}':threads: '\
10
+ '(-h --help)'{-h,--help}''\
11
+ '(-v --version)'{-v,--version}''\
12
+ '1: :->backend'\
13
+ '2: :->subcommand'\
14
+ '(-)*:nodes:->nodes'
15
+
16
+ case $state in
17
+ backend)
18
+ compadd -Q "$@" solo zero
19
+ ;;
20
+ subcommand)
21
+ compadd -Q "$@" bootstrap clean cook prepare
22
+ ;;
23
+ nodes)
24
+ for node_file in $(ls -1 nodes/* | egrep "\.(rb|json)\$"); do
25
+ compadd "$@" $(basename $node_file | sed 's/.json$//' | sed 's/.rb$//')
26
+ done
27
+ ;;
28
+ *)
29
+ esac
30
+ }
31
+
32
+ _knife "$@"
@@ -0,0 +1,5 @@
1
+ require "paknife/version"
2
+ require "paknife/cli"
3
+
4
+ module Paknife
5
+ end
@@ -0,0 +1,146 @@
1
+ require "optparse"
2
+ require "parallel"
3
+ require "paknife/context"
4
+
5
+ module Paknife
6
+ class Cli
7
+ BACKENDS = %w(solo zero)
8
+ SUBCOMMANDS = %w(bootstrap clean cook prepare)
9
+
10
+ DEFAULT_KNIFE = "bundle exec knife"
11
+ DEFAULT_THREADS = 2
12
+
13
+ DEFAULT_OPTIONS = {
14
+ knife: nil,
15
+ quiet: false,
16
+ threads: nil,
17
+ }
18
+
19
+ def self.run(argv)
20
+ new(argv).run
21
+ end
22
+
23
+ attr_reader :contexts
24
+
25
+ def initialize(argv)
26
+ @options, backend, subcommand, nodes, knife_options = parse_argv(argv)
27
+ @contexts = build_contexts(backend, subcommand, nodes, knife_options)
28
+ end
29
+
30
+ def run
31
+ Parallel.each(contexts, in_threads: determine_threads) do |context|
32
+ context.run
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def parse_argv(argv)
39
+ [parse_options(argv), *parse_knife_argv(argv)]
40
+ end
41
+
42
+ def parse_options(argv)
43
+ opts = {}
44
+
45
+ OptionParser.new do |op|
46
+ op.banner = <<-USAGE
47
+ Usage:
48
+ #{op.program_name} [<options>] <backend> <subcommand> <nodes> [<knife_options>]
49
+
50
+ Backend:
51
+ solo : run knife-solo
52
+ zero : run knffe-zero (Not well tested)
53
+
54
+ Options:
55
+ USAGE
56
+ op.version = VERSION
57
+
58
+ op.on("-k", "--knife VALUE") do |v|
59
+ opts[:knife] = v
60
+ end
61
+
62
+ op.on("-q", "--[no-]quiet") do |v|
63
+ opts[:quiet] = v
64
+ end
65
+
66
+ op.on("-t", "--threads VALUE") do |v|
67
+ if v == "max"
68
+ opts[:threads] = :max
69
+ elsif v.to_i > 0
70
+ opts[:threads] = v.to_i
71
+ else
72
+ abort "Invalid value for `--thread` option: #{v}"
73
+ end
74
+ end
75
+
76
+ op.on_tail("-h", "--help") do
77
+ puts op.help
78
+ exit
79
+ end
80
+
81
+ op.on_tail("-v", "--version") do
82
+ puts "#{op.program_name} #{op.version}"
83
+ exit
84
+ end
85
+ end.order!
86
+
87
+ DEFAULT_OPTIONS.merge(opts)
88
+ end
89
+
90
+ def parse_knife_argv(argv)
91
+ backend = argv.shift # solo or zero
92
+ abort "Invalid backend: `#{backend}`" unless BACKENDS.include?(backend)
93
+
94
+ subcommand = argv.shift
95
+ abort "Invalid subcommand: `#{subcommand}`" unless SUBCOMMANDS.include?(subcommand)
96
+
97
+ nodes = []
98
+ knife_options = []
99
+ knife_options_section = false
100
+
101
+ argv.each do |arg|
102
+ knife_options_section ||= arg.start_with?("-")
103
+ if knife_options_section
104
+ knife_options << arg
105
+ else
106
+ nodes << arg
107
+ end
108
+ end
109
+
110
+ [backend, subcommand, nodes, knife_options]
111
+ end
112
+
113
+ def build_contexts(backend, subcommand, nodes, knife_options)
114
+ opts = {
115
+ log_level: determine_log_level,
116
+ knife: determine_knife,
117
+ }
118
+
119
+ nodes.map.with_index do |node, index|
120
+ Context.new(index, backend, subcommand, node, knife_options, opts)
121
+ end
122
+ end
123
+
124
+ def determine_knife
125
+ @options[:knife] || ENV["PARAKNIFE_KNIFE"] || DEFAULT_KNIFE
126
+ end
127
+
128
+ def determine_threads
129
+ threads = @options[:threads] || ENV["PARAKNIFE_THREADS"] || DEFAULT_THREADS
130
+
131
+ if threads.to_s.downcase == "max"
132
+ @contexts.count
133
+ else
134
+ [@contexts.count, threads.to_i].min
135
+ end
136
+ end
137
+
138
+ def determine_log_level
139
+ if @options[:quiet]
140
+ :warn
141
+ else
142
+ :info
143
+ end
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,73 @@
1
+ require "logger"
2
+ require "open3"
3
+ require "term/ansicolor"
4
+
5
+ module Paknife
6
+ class Context
7
+ attr_reader :logger, :index, :backend, :subcommand, :node, :knife_options
8
+
9
+ def initialize(index, backend, subcommand, node, knife_options, options = {})
10
+ @index = index
11
+ @backend = backend
12
+ @subcommand = subcommand
13
+ @node = node
14
+ @knife_options = knife_options
15
+ @options = options
16
+
17
+ setup_logger
18
+ end
19
+
20
+ def run
21
+ logger.info command
22
+ Open3.popen3(command) do |stdin, stdout, stderr, wait_thr|
23
+ stdin.close_write
24
+
25
+ begin
26
+ loop do
27
+ IO.select([stdout, stderr]).flatten.compact.each do |io|
28
+ io.each do |line|
29
+ next if line.nil? || line.empty?
30
+
31
+ if io == stdout
32
+ logger.info line
33
+ elsif io == stderr
34
+ logger.warn line
35
+ end
36
+ end
37
+ end
38
+ break if stdout.eof? && stderr.eof?
39
+ end
40
+ rescue EOFError
41
+ end
42
+ end
43
+ end
44
+
45
+ def command
46
+ [
47
+ @options[:knife],
48
+ backend,
49
+ subcommand,
50
+ node,
51
+ knife_options,
52
+ ].flatten.compact.join(" ")
53
+ end
54
+
55
+ private
56
+
57
+ COLOR_CODES = (1..15).to_a
58
+
59
+ def setup_logger
60
+ color = COLOR_CODES[index % COLOR_CODES.length]
61
+ colored_node = Term::ANSIColor.color(color, node)
62
+
63
+ @logger = Logger.new(STDOUT)
64
+ @logger.formatter = proc { |severity, datetime, progname, msg| "[#{colored_node}] #{msg.chomp}\n" }
65
+ @logger.level =
66
+ if @options[:log_level]
67
+ Logger.const_get(@options[:log_level].upcase)
68
+ else
69
+ Logger::INFO
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,3 @@
1
+ module Paknife
2
+ VERSION = "0.0.6"
3
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'paknife/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "paknife"
8
+ spec.version = Paknife::VERSION
9
+ spec.authors = ["Masato Ikeda"]
10
+ spec.email = ["masato.ikeda@gmail.com"]
11
+ spec.summary = %q{Run knife-solo in parallel}
12
+ spec.description = %q{Run knife-solo in parallel}
13
+ spec.homepage = "https://github.com/a2ikm/paknife"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "parallel", "~> 1.3"
22
+ spec.add_dependency "term-ansicolor", "~> 1.3"
23
+ spec.add_development_dependency "bundler", "~> 1.7"
24
+ spec.add_development_dependency "rake", "~> 10.0"
25
+ end
@@ -0,0 +1,8 @@
1
+ cookbook_path ["cookbooks", "site-cookbooks"]
2
+ node_path "nodes"
3
+ role_path "roles"
4
+ environment_path "environments"
5
+ data_bag_path "data_bags"
6
+ #encrypted_data_bag_secret "data_bag_key"
7
+
8
+ knife[:berkshelf_path] = "cookbooks"
@@ -0,0 +1 @@
1
+ PATH=./bin:$PATH
@@ -0,0 +1 @@
1
+ /cookbooks/
@@ -0,0 +1 @@
1
+ site :opscode
@@ -0,0 +1,7 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "chef"
4
+ gem "berkshelf"
5
+ gem "knife-solo"
6
+
7
+ gem "paknife", path: ".."
@@ -0,0 +1,17 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ VAGRANTFILE_API_VERSION = "2"
5
+
6
+ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
7
+ config.vm.box = "paknife-centos-6.6"
8
+ config.vm.box_url = "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-6.6_chef-provisionerless.box"
9
+
10
+ config.vm.define "s1" do |s1|
11
+ s1.vm.network "private_network", ip: "192.168.33.55"
12
+ end
13
+
14
+ config.vm.define "s2" do |s2|
15
+ s2.vm.network "private_network", ip: "192.168.33.56"
16
+ end
17
+ end
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'chef-apply' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('chef', 'chef-apply')
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'chef-client' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('chef', 'chef-client')
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'chef-service-manager' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('chef', 'chef-service-manager')
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'chef-shell' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('chef', 'chef-shell')
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'chef-solo' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('chef', 'chef-solo')
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'knife' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('chef', 'knife')
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'paknife' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('paknife', 'paknife')
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'shef' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('chef', 'shef')
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env bash
2
+
3
+ prefix=${1:-paknife}
4
+
5
+ vagrant ssh-config s1 --host ${prefix}-s1
6
+ vagrant ssh-config s2 --host ${prefix}-s2
File without changes
File without changes
File without changes
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "paknife-s1",
3
+ "runlist": [
4
+ ]
5
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "paknife-s1",
3
+ "runlist": [
4
+ ]
5
+ }
File without changes
File without changes
metadata ADDED
@@ -0,0 +1,136 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: paknife
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.6
5
+ platform: ruby
6
+ authors:
7
+ - Masato Ikeda
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-11-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: parallel
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: term-ansicolor
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.7'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.7'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ description: Run knife-solo in parallel
70
+ email:
71
+ - masato.ikeda@gmail.com
72
+ executables:
73
+ - paknife
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - ".gitignore"
78
+ - Gemfile
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - bin/paknife
83
+ - completions/paknife.zsh
84
+ - lib/paknife.rb
85
+ - lib/paknife/cli.rb
86
+ - lib/paknife/context.rb
87
+ - lib/paknife/version.rb
88
+ - paknife.gemspec
89
+ - sample/.chef/knife.rb
90
+ - sample/.envrc
91
+ - sample/.gitignore
92
+ - sample/Berksfile
93
+ - sample/Gemfile
94
+ - sample/Vagrantfile
95
+ - sample/bin/chef-apply
96
+ - sample/bin/chef-client
97
+ - sample/bin/chef-service-manager
98
+ - sample/bin/chef-shell
99
+ - sample/bin/chef-solo
100
+ - sample/bin/knife
101
+ - sample/bin/paraknife
102
+ - sample/bin/shef
103
+ - sample/bin/ssh-config
104
+ - sample/data_bags/.gitkeep
105
+ - sample/environments/.gitkeep
106
+ - sample/nodes/.gitkeep
107
+ - sample/nodes/paknife-s1.json
108
+ - sample/nodes/paknife-s2.json
109
+ - sample/roles/.gitkeep
110
+ - sample/site-cookbooks/.gitkeep
111
+ homepage: https://github.com/a2ikm/paknife
112
+ licenses:
113
+ - MIT
114
+ metadata: {}
115
+ post_install_message:
116
+ rdoc_options: []
117
+ require_paths:
118
+ - lib
119
+ required_ruby_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ required_rubygems_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ requirements: []
130
+ rubyforge_project:
131
+ rubygems_version: 2.2.2
132
+ signing_key:
133
+ specification_version: 4
134
+ summary: Run knife-solo in parallel
135
+ test_files: []
136
+ has_rdoc: