serverspec-runner-0.2.4/0000755000175000017500000000000012421735224013675 5ustar kurakuraserverspec-runner-0.2.4/Gemfile0000644000175000017500000000014612421735224015171 0ustar kurakurasource "https://rubygems.org" # Specify your gem's dependencies in serverspec-runner.gemspec gemspec serverspec-runner-0.2.4/README.md0000644000175000017500000001341712421735224015162 0ustar kurakuraserverspec-runner ====================== Simple execution framework for [serverspec](http://serverspec.org/). ---- ## Installation $ gem install serverspec-runner ---- ## Usage initialize spec direcotries and create skeleton-specfiles. $ serverspec-runner -r /path/to/your_serverspec_root Edit your [spec-files](http://serverspec.org/resource_types.html). $ vim /path/to/your_serverspec_root/test_top_dir/.../your_serverspec_test.rb Edit your infrastructure or middleware tests scenario to "scenario.yml". ``` test_top_dir: # test directory top : # test hierarchy directories test_bottom_dir: # test directory bottom - servername # ssh-accessible ip address or fqdn. or alias - : - : : --- servername: # alias name(not required) host: 192.168.0.11 # ssh-accessible ip address or fqdn(required if alias exist) ssh_opts: # ssh options(not required) port: 22 # ssh port option(not required) user: "anyone" # ssh user option(not required) : # any other Net::SSH Options(not required) any_attribute: "aaa" # host attributes. left example available to get "property[:servername][:any_attribute]" from code(not required) : : ``` do tests. $ serverspec-runner -r /path/to/your_serverspec_root -s /path/to/your_scenario.yml or $ cd /path/to/your_serverspec_root && serverspec-runner You can also specify [ssh_options.yml](http://net-ssh.github.io/net-ssh/classes/Net/SSH.html)(Net::SSH options) file by "-o" option for default ssh options. $ serverspec-runner -s /path/to/your_scenario.yml -o /path/to/your_ssh_options.yml For example. You write serverspec code like this. ``` describe "nginx" do describe "check running" do describe process('nginx') do it { should be_running } end end describe file('/etc/logrotate.d/nginx') do it { should be_file } it { should contain "rotate 14" } end end ``` You can get the following outputs. * serverspec-runner -t aa : asci-art table(default) ``` +-------------------------------------------+ |description | result | +-------------------------------------------+ |example@anyhost-01(192.168.11.1) | | | nginx | | | check running | | | Process "nginx" | | | should be running | OK | | File "/etc/logrotate.d/nginx" | | | should be file | OK | | should contain "rotate 14" | OK | |example@anyhost-02(192.168.11.2) | | | nginx | | | check running | | | Process "nginx" | | | should be running | OK | | File "/etc/logrotate.d/nginx" | | | should be file | OK | | should contain "rotate 14" | NG | +-------------------------------------------+ ``` * serverspec-runner -t mkd : markdown table format ``` |description | result | |:---------------------------------|:------:| |example@anyhost-01(192.168.11.1) | | | nginx | | | check running | | | Process "nginx" | | | should be running | OK | | File "/etc/logrotate.d/nginx" | | | should be file | OK | | should contain "rotate 14" | OK | |example@anyhost-02(192.168.11.2) | | | nginx | | | check running | | | Process "nginx" | | | should be running | OK | | File "/etc/logrotate.d/nginx" | | | should be file | OK | | should contain "rotate 14" | NG | ``` this example parsed for markdown to that(use -e long option) |description | result | |:----------------------------------------------------------------|:------:| |example@anyhost-01(192.168.11.1) | | | nginx check running Process "nginx" should be running | OK | | nginx File "/etc/logrotate.d/nginx" should be file | OK | | nginx File "/etc/logrotate.d/nginx" should contain "rotate 14" | OK | |example@anyhost-01(192.168.11.2) | | | nginx check running Process "nginx" should be running | OK | | nginx File "/etc/logrotate.d/nginx" should be file | OK | | nginx File "/etc/logrotate.d/nginx" should contain "rotate 14" | NG | * serverspec-runner -t bool : only 'ok' or 'ng' result string.t You can use for cluster monitoring system health. ``` ng ``` * serverspec-runner -t csv : CSV file format You can get result CSV format output and can use redirect to file. ``` description,,,,,result example@anyhost-01(192.168.11.1),,,,, ,nginx,,,, ,,check running,,, ,,,Process "nginx",, ,,,,should be running,OK ,,File "/etc/logrotate.d/nginx",,, ,,,should be file,,OK ,,,should contain "rotate 14",,OK example@anyhost-02(192.168.11.2),,,,, ,nginx,,,, ,,check running,,, ,,,Process "nginx",, ,,,,should be running,OK ,,File "/etc/logrotate.d/nginx",,, ,,,should be file,,OK ,,,should contain "rotate 14",,NG ``` For more detail. You can see from `serverspec-runner -h` command. ---- ## Contributing 1. Fork it 2. Create your feature branch (`git checkout -b my-new-feature`) 3. Commit your changes (`git commit -am 'Add some feature'`) 4. Push to the branch (`git push origin my-new-feature`) 5. Create new Pull Request serverspec-runner-0.2.4/ssh_options_default.yml0000644000175000017500000000016012421735224020471 0ustar kurakura:port: 22 :paranoid: false #:user: "youre_name" #:keys: ["/path/to/private_key"] #:passphrase: "yourpassphrase" serverspec-runner-0.2.4/.gitignore0000644000175000017500000000025312421735224015665 0ustar kurakura*.gem *.rbc .bundle .config .yardoc Gemfile.lock InstalledFiles _yardoc coverage doc/ lib/bundler/man pkg rdoc spec/reports test/tmp test/version_tmp tmp .DS_Store .rvmrc serverspec-runner-0.2.4/bin/0000755000175000017500000000000012421735224014445 5ustar kurakuraserverspec-runner-0.2.4/bin/serverspec-runner0000755000175000017500000000426312421735224020070 0ustar kurakura#!/usr/bin/env ruby $LOAD_PATH.unshift File.join(File.dirname(__FILE__), *%w[.. lib]) require 'rubygems' require 'rake' require 'getoptlong' raketask = 'spec' showtasks = false opts = GetoptLong.new( ["--scenario", "-s", GetoptLong::REQUIRED_ARGUMENT], ["--specroot", "-r", GetoptLong::REQUIRED_ARGUMENT], ["--ssh_options", "-o", GetoptLong::REQUIRED_ARGUMENT], ["--explain", "-e", GetoptLong::REQUIRED_ARGUMENT], ["--tableformat", "-t", GetoptLong::REQUIRED_ARGUMENT], ["--help", "-h", GetoptLong::NO_ARGUMENT], ["--tmpdir", "-1", GetoptLong::REQUIRED_ARGUMENT], ["--raketask", "-2", GetoptLong::REQUIRED_ARGUMENT], ["--tasks", "-T", GetoptLong::NO_ARGUMENT] ) opts.each do |opt, arg| case opt when '--scenario' ENV['scenario'] = arg when '--specroot' ENV['specroot'] = arg when '--ssh_options' ENV['ssh_options'] = arg when '--explain' ENV['explain'] = arg when '--tableformat' ENV['tableformat'] = arg when '--tmpdir' ENV['tmpdir'] = arg when '--raketask' raketask += "::" + arg when '--tasks' showtasks = true else puts "Usage: serverspec-runner (options)" puts "-s, --scenario SCENARIO_FILE path to scenario yml file" puts "-r, --specroot SPEC_ROOT path to spec tests root dir" puts "-o, --ssh_options SSH_OPTIONS_FILE path to ssh options yml file" puts "-e, --explain (short|long) specify result explain length(default: short)" puts "-t, --tableformat (aa|mkd|csv|bool) specify result table type(default: aa)" puts "-T, --tasks display the tasks with descriptions(exec rake -T)" puts "-h, --help show help" exit 0 end end Rake::TaskManager.record_task_metadata = showtasks load "#{File.dirname(__FILE__)}/../Rakefile" if showtasks mLen = (Rake.application.tasks.max_by { |t| t.name_with_args.size }).name_with_args.size Rake.application.tasks.reject{|t| ['spec:all', 'spec:stdout'].include?(t.name_with_args)}.each do |t| printf("%-#{mLen + 2}s # %s\n", t.name_with_args, t.comment) end exit(0) end Rake::Task[raketask.to_sym].invoke serverspec-runner-0.2.4/serverspec-runner.gemspec0000644000175000017500000000174712421735224020743 0ustar kurakura# coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'serverspec-runner/version' Gem::Specification.new do |spec| spec.name = "serverspec-runner" spec.version = ServerspecRunner::VERSION spec.authors = ["hiracy"] spec.email = ["leizhen@mbr.nifty.com"] spec.description = %q{simple execution framework for serverspec} spec.summary = %q{simple execution framework for serverspec} spec.homepage = "https://github.com/hiracy/serverspec-runner" spec.license = "MIT" spec.files = `git ls-files`.split($/) spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) spec.require_paths = ["lib"] spec.add_runtime_dependency "serverspec" spec.add_runtime_dependency "net-ssh" spec.add_development_dependency "rake" spec.add_development_dependency "rspec-core" spec.add_development_dependency "bundler", "~> 1.3" end serverspec-runner-0.2.4/lib/0000755000175000017500000000000012421735224014443 5ustar kurakuraserverspec-runner-0.2.4/lib/serverspec-runner.rb0000644000175000017500000000004412421735224020456 0ustar kurakurarequire 'serverspec-runner/version' serverspec-runner-0.2.4/lib/serverspec-runner/0000755000175000017500000000000012421735224020133 5ustar kurakuraserverspec-runner-0.2.4/lib/serverspec-runner/version.rb0000644000175000017500000000006012421735224022141 0ustar kurakuramodule ServerspecRunner VERSION = "0.2.4" end serverspec-runner-0.2.4/lib/serverspec-runner/util/0000755000175000017500000000000012421735224021110 5ustar kurakuraserverspec-runner-0.2.4/lib/serverspec-runner/util/hash.rb0000644000175000017500000000013012421735224022352 0ustar kurakuraclass Hash def depth 1 + (values.map{|v| Hash === v ? v.depth : 1}.max) end end serverspec-runner-0.2.4/.rspec0000644000175000017500000000003712421735224015012 0ustar kurakura--color --format documentation serverspec-runner-0.2.4/scenario.yml0000644000175000017500000000037512421735224016230 0ustar kurakura# # role_1: # role_detail_1: # - ssh-access-host-or-symbol # - : # role_detail_2: # - : # : # role_2: # : # --- # ssh-access-host-or-symbol: # host: xxx.xxx.xxx.xxx # example: - anyhost-01 --- anyhost-01: host: 127.0.0.1 serverspec-runner-0.2.4/LICENSE0000644000175000017500000000206012421735224014700 0ustar kurakuraThe MIT License (MIT) Copyright (c) 2014 hiracy Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.serverspec-runner-0.2.4/Rakefile0000644000175000017500000001543112421735224015346 0ustar kurakurarequire 'rake' require 'rspec/core/rake_task' require 'yaml' require 'csv' require 'fileutils' require 'net/ssh' require 'open-uri' require 'serverspec-runner' desc "Run serverspec to all scenario" task :spec => 'spec:all' namespace :spec do ENV['EXEC_PATH'] = '/usr/local/bin:/usr/sbin:/sbin:/usr/bin:/bin' ENV['specroot'] = ENV['specroot'] || "." ENV['specpath'] = "#{ENV['specroot']}/spec" ENV['ssh_options'] = ENV['ssh_options'] || "#{ENV['specroot']}/ssh_options_default.yml" || "#{File.dirname(__FILE__)}/ssh_options_default.yml" ENV['ssh_options'] = "#{File.dirname(__FILE__)}/ssh_options_default.yml" unless File.exists?(ENV['ssh_options']) ssh_options = YAML.load_file(ENV['ssh_options']) ENV['result_csv'] = ENV['result_csv'] || './_serverspec_result.csv' csv_file = ENV['result_csv'] CSV.open(csv_file, 'w') { |w| w << ['description', 'result'] } ENV['explain'] = ENV['explain'] || "short" ENV['tableformat'] = ENV['tableformat'] || "aa" ENV['scenario'] = ENV['scenario'] || "./scenario.yml" def init_specpath(path) begin print "want to create spec-tree to #{ENV['specpath']}? (y/n): " ans = STDIN.gets.strip exit 0 unless (ans == 'y' || ans == 'yes') rescue Exception exit 0 end FileUtils.mkdir_p(path) FileUtils.cp("#{File.dirname(__FILE__)}/scenario.yml", ENV['specroot']) FileUtils.cp("#{File.dirname(__FILE__)}/ssh_options_default.yml", ENV['specroot']) FileUtils.cp("#{File.dirname(__FILE__)}/.rspec", ENV['specroot']) FileUtils.cp_r("#{File.dirname(__FILE__)}/spec/.", path) puts("Please edit \"#{ENV['specroot']}/scenario.yml\" and change directory to \"#{ENV['specroot']}\" and exec \"serverspec-runner\" command !!") end def gen_exec_plan(parent, node, path, ssh_options, tasks, platform) if parent == nil abs_node = node else abs_node = parent[node] end if abs_node.kind_of?(Hash) abs_node.keys.each do |n| path.push(n.to_s) gen_exec_plan(abs_node, n, path, ssh_options, tasks, platform) end path.pop elsif abs_node.kind_of?(Array) abs_node.each do |host_alias| if platform.include?(host_alias.to_sym) ssh_host = platform[host_alias.to_sym][:host] else platform[host_alias.to_sym] = {} ssh_host = host_alias end platform[host_alias.to_sym][:ssh_opts].each { |k, v| ssh_options[k.to_sym] = v } if platform[host_alias.to_sym].include?(:ssh_opts) tasks << "#{path.join('::')}::#{host_alias}" end path.pop end end def exec_tasks(parent, node, real_path, platform) if parent == nil abs_node = node else abs_node = parent[node] end if abs_node.kind_of?(Hash) abs_node.keys.each do |n| real_path.push(n) exec_tasks(abs_node, n, real_path, platform) end real_path.pop elsif abs_node.kind_of?(Array) task_path = "#{real_path.join('::')}" abs_node.each do |host_alias| desc "Run serverspec to #{task_path}@#{host_alias}" RSpec::Core::RakeTask.new("#{task_path}::#{host_alias}".to_sym) do |t| fpath = task_path.gsub(/::/, '/') t.pattern = %W[ #{ENV['specpath']}/#{fpath}/{default.rb} #{ENV['specpath']}/#{fpath}/{#{platform[host_alias.to_sym][:platform_name]}.rb} #{ENV['specpath']}/#{fpath}/{#{platform[host_alias.to_sym][:platform_detail_name]}.rb} ] raise "\e[31mspec file not found!![#{t.pattern.to_s}]\e[m" if Dir.glob(t.pattern).empty? t.fail_on_error = false ENV['TARGET_HOST'] = host_alias ENV['TARGET_SSH_HOST'] = platform[host_alias.to_sym][:host] || host_alias end end real_path.pop end end if !Dir.exists?(ENV['specpath']) init_specpath(ENV['specpath']) exit 0 end if !ENV['tmpdir'] ENV['platforms_tmp'] = "./_platforms.yml" ENV['scenario_tmp'] = "./_scenario.yml" else ENV['platforms_tmp'] = "#{ENV['tmpdir']}/_platforms.yml" ENV['scenario_tmp'] = "#{ENV['tmpdir']}/_scenario.yml" end scenarios = nil platform = {} if ENV['scenario'] =~ /^(http|https):\/\// open(ENV['scenario_tmp'], 'w') do |f| open(ENV['scenario']) do |data| f.write(data.read) end end ENV['scenario'] = ENV['scenario_tmp'] end File.open(ENV['scenario'] || "#{ENV['specroot']}/scenario.yml") do |f| YAML.load_documents(f).each_with_index do |data, idx| if idx == 0 scenarios = data else data.each do |k, v| platform[k.to_sym] = {} v.each do |kk, vv| platform[k.to_sym][kk.to_sym] = vv end end end end end if !scenarios print "\e[31m" puts "scenario.yml is empty." print "\e[m" exit 1 end tasks = [] gen_exec_plan(nil, scenarios, [], ssh_options, tasks, platform) task :stdout do if ENV['tableformat'] == 'bool' ret = 'ok' CSV.foreach(csv_file) do |r| ret = 'ng' if r[1] == 'NG' end puts ret elsif ENV['tableformat'] == 'csv' maxrows = 0 CSV.foreach(csv_file) do |r| maxrows = r[2].to_i if r[2].to_i > maxrows end maxrows += 1 # host row CSV.foreach(csv_file) do |r| pad_comma = ',' * (maxrows - r[0].split(',').length) puts "#{r[0]}#{pad_comma},#{r[1]}" end else maxlen = 0 CSV.foreach(csv_file) do |r| n = r[0].each_char.map{|c| c.bytesize == 1 ? 1 : 2}.reduce(0, &:+) maxlen = n if n > maxlen end pad_spaces = 4 spacer = nil if ENV['tableformat'] == 'mkd' spacer = "|:" + ("-" * maxlen) + "|:" + ("-" * "result".length) + ":|" elsif ENV['tableformat'] == 'aa' spacer = "+" + ("-" * (maxlen + "result".length + pad_spaces)) + "+" end puts spacer unless ENV['tableformat'] == 'mkd' is_header = true CSV.foreach(csv_file) do |r| n = r[0].each_char.map{|c| c.bytesize == 1 ? 1 : 2}.reduce(0, &:+) if r[1] == 'OK' s_effect = "\e[32m" e_effect = "\e[m" r[1] = ' ' + r[1] elsif r[1] == 'NG' s_effect = "\e[31m" e_effect = "\e[m" r[1] = ' ' + r[1] end pad_mid = (" " * (maxlen - n)) + " | " pad_tail = (" " * ("result".length - r[1].length)) + " |" puts "|#{s_effect}#{r[0]}#{e_effect}#{pad_mid}#{s_effect}#{r[1]}#{e_effect}#{pad_tail}" if is_header puts spacer is_header = false end end puts spacer unless ENV['tableformat'] == 'mkd' end end tasks << :stdout task :all => tasks # tempファイルに書き出し open(ENV['platforms_tmp'] ,"w") do |y| YAML.dump(platform, y) end path = {} exec_tasks(nil, scenarios, [], platform) end serverspec-runner-0.2.4/spec/0000755000175000017500000000000012421735224014627 5ustar kurakuraserverspec-runner-0.2.4/spec/example/0000755000175000017500000000000012421735224016262 5ustar kurakuraserverspec-runner-0.2.4/spec/example/default.rb0000644000175000017500000000123712421735224020236 0ustar kurakurarequire "#{File.dirname(__FILE__)}/../spec_helper" describe package('httpd'), :if => os[:family] == 'redhat' do it { should be_installed } end describe package('apache2'), :if => os[:family] == 'ubuntu' do it { should be_installed } end describe service('httpd'), :if => os[:family] == 'redhat' do it { should be_enabled } it { should be_running } end describe service('apache2'), :if => os[:family] == 'ubuntu' do it { should be_enabled } it { should be_running } end describe service('org.apache.httpd'), :if => os[:family] == 'darwin' do it { should be_enabled } it { should be_running } end describe port(80) do it { should be_listening } end serverspec-runner-0.2.4/spec/spec_helper.rb0000644000175000017500000000623212421735224017450 0ustar kurakurarequire 'serverspec' require 'pathname' require 'net/ssh' require 'yaml' require 'csv' require 'serverspec-runner/util/hash' ssh_opts_default = YAML.load_file(ENV['ssh_options']) csv_path = ENV['result_csv'] explains = [] results = [] row_num = [] spacer_char = ' ' unless ENV['tableformat'] == 'csv' spacer_char = ',' if ENV['tableformat'] == 'csv' def get_example_desc(example_group, descriptions) descriptions << example_group[:description] return descriptions if example_group[:parent_example_group] == nil get_example_desc(example_group[:parent_example_group], descriptions) end RSpec.configure do |c| c.expose_current_running_example_as :example c.path = ENV['EXEC_PATH'] run_path = c.files_to_run[0].split('/') speck_i = 0 run_path.reverse.each_with_index do |r,i| if r == 'spec' speck_i = ((run_path.size - 1) - i) end end sliced = run_path.slice((speck_i + 1)..(run_path.size - 2)) role_name = sliced.join('-') if ENV['ASK_SUDO_PASSWORD'] require 'highline/import' c.sudo_password = ask("Enter sudo password: ") { |q| q.echo = false } else c.sudo_password = ENV['SUDO_PASSWORD'] end set_property (YAML.load_file(ENV['platforms_tmp']))[ENV['TARGET_HOST'].to_sym] if ENV['TARGET_SSH_HOST'] !~ /localhost|127\.0\.0\.1/ c.host = ENV['TARGET_SSH_HOST'] options = Net::SSH::Config.for(c.host, files=["~/.ssh/config"]) ssh_opts ||= ssh_opts_default property[:ssh_opts].each { |k, v| ssh_opts[k.to_sym] = v } if property[:ssh_opts] user = options[:user] || ssh_opts[:user] || Etc.getlogin options.merge!(ssh_opts) set :ssh_options, options set :backend, :ssh else set :backend, :exec end prev_desc_hierarchy = nil c.before(:suite) do entity_host = (((ENV['TARGET_HOST'] != ENV['TARGET_SSH_HOST']) && (ENV['TARGET_SSH_HOST'] != nil)) ? "(#{ENV['TARGET_SSH_HOST']})" : "") puts "\e[33m" puts "### start [#{role_name}@#{ENV['TARGET_HOST']}] #{entity_host} serverspec... ###" print "\e[m" explains << "#{role_name}@#{ENV['TARGET_HOST']}#{entity_host}" results << "" row_num << 1 end c.after(:each) do if ENV['explain'] == 'long' explains << spacer_char + example.metadata[:full_description] + (RSpec::Matchers.generated_description || '') results << (self.example.exception ? 'NG' : 'OK') row_num << 1 else spacer = '' desc_hierarchy = get_example_desc(self.example.metadata[:example_group], []).reverse desc_hierarchy.each_with_index do |ex, i| spacer += spacer_char if prev_desc_hierarchy != nil && prev_desc_hierarchy.length > i && prev_desc_hierarchy[i] == desc_hierarchy[i] else explains << spacer + ex results << '' row_num << i + 1 end end explains << spacer + spacer_char + RSpec::Matchers.generated_description results << (self.example.exception ? 'NG' : 'OK') row_num << desc_hierarchy.length + 1 prev_desc_hierarchy = desc_hierarchy end end c.after(:suite) do CSV.open(csv_path, 'a') do |writer| explains.each_with_index do |v, i| writer << [v, results[i], row_num[i]] end end end end serverspec-runner-0.2.4/metadata.yml0000644000175000017500000000606412421735224016206 0ustar kurakura--- !ruby/object:Gem::Specification name: serverspec-runner version: !ruby/object:Gem::Version version: 0.2.4 platform: ruby authors: - hiracy autorequire: bindir: bin cert_chain: [] date: 2014-10-21 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: serverspec requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: net-ssh requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: rake requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: rspec-core requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: bundler requirement: !ruby/object:Gem::Requirement requirements: - - "~>" - !ruby/object:Gem::Version version: '1.3' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - "~>" - !ruby/object:Gem::Version version: '1.3' description: simple execution framework for serverspec email: - leizhen@mbr.nifty.com executables: - serverspec-runner extensions: [] extra_rdoc_files: [] files: - ".gitignore" - ".rspec" - Gemfile - LICENSE - README.md - Rakefile - bin/serverspec-runner - lib/serverspec-runner.rb - lib/serverspec-runner/util/hash.rb - lib/serverspec-runner/version.rb - scenario.yml - serverspec-runner.gemspec - spec/example/default.rb - spec/spec_helper.rb - ssh_options_default.yml homepage: https://github.com/hiracy/serverspec-runner licenses: - MIT metadata: {} post_install_message: rdoc_options: [] require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' required_rubygems_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' requirements: [] rubyforge_project: rubygems_version: 2.2.2 signing_key: specification_version: 4 summary: simple execution framework for serverspec test_files: - spec/example/default.rb - spec/spec_helper.rb