pax_global_header00006660000000000000000000000064126170477700014525gustar00rootroot0000000000000052 comment=d8619f04da4af40540b0f27f8f4d6bc2c1bef2ed serverspec-runner-master/000077500000000000000000000000001261704777000160525ustar00rootroot00000000000000serverspec-runner-master/.gitignore000066400000000000000000000002531261704777000200420ustar00rootroot00000000000000*.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-master/.rspec000066400000000000000000000000371261704777000171670ustar00rootroot00000000000000--color --format documentation serverspec-runner-master/.travis.yml000066400000000000000000000002101261704777000201540ustar00rootroot00000000000000language: ruby rvm: - 1.9.3 - 2.0.0 - 2.1.5 - 2.2.0 before_install: - gem update bundler script: - bundle exec rake spec serverspec-runner-master/Gemfile000066400000000000000000000001461261704777000173460ustar00rootroot00000000000000source "https://rubygems.org" # Specify your gem's dependencies in serverspec-runner.gemspec gemspec serverspec-runner-master/LICENSE000066400000000000000000000020601261704777000170550ustar00rootroot00000000000000The 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-master/README.md000066400000000000000000000142401261704777000173320ustar00rootroot00000000000000serverspec-runner [![Gem Version](https://badge.fury.io/rb/serverspec-runner.svg)](http://badge.fury.io/rb/serverspec-runner) [![BuildStatus](https://secure.travis-ci.org/hiracy/serverspec-runner.png)](http://travis-ci.org/hiracy/serverspec-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) keys: ["~/.ssh/id_rsa"] # ssh private keys option(not required) : # any other Net::SSH Options(not required) any_attribute: "aaa" # host attributes. this example available to get "property[:any_attribute]" from your codes(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. ``` require 'spec_helper' 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' string You can use for cluster monitoring system health. ``` ok ``` ``` 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-master/Rakefile000066400000000000000000000167511261704777000175310ustar00rootroot00000000000000require 'rake' require 'rspec/core/rake_task' require 'yaml' require 'csv' require 'fileutils' require 'net/ssh' require 'open-uri' require 'serverspec-runner' require 'serverspec-runner/util/hash' 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' if ENV['specroot'] == nil if ENV['scenario'] != nil ENV['specroot'] = "#{File.dirname(ENV['scenario'])}" else ENV['specroot'] = '.' end end Dir.chdir(ENV['specroot']) if Dir.exists?(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) abs_path = File::expand_path(path) begin print "want to create spec-tree to #{abs_path}? (y/n): " ans = STDIN.gets.strip exit 0 unless (ans == 'y' || ans == 'yes') rescue Exception exit 0 end FileUtils.mkdir_p("#{path}/lib") FileUtils.cp("#{File.dirname(__FILE__)}/scenario.yml", path) FileUtils.cp("#{File.dirname(__FILE__)}/ssh_options_default.yml", path) FileUtils.cp("#{File.dirname(__FILE__)}/.rspec", path) FileUtils.cp_r("#{File.dirname(__FILE__)}/spec", path) FileUtils.cp_r("#{File.dirname(__FILE__)}/lib/extension", "#{path}/lib") puts("Please edit \"#{abs_path}/scenario.yml\" and change directory to \"#{abs_path}\" 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(/::/, '/') if Dir.exists?("#{ENV['specpath']}/#{fpath}") t.pattern = %W[ #{ENV['specpath']}/#{fpath}/*.rb ] elsif File.file?("#{ENV['specpath']}/#{fpath}.rb") t.pattern = %W[ #{ENV['specpath']}/#{fpath}.rb ] end 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['specroot']) 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.deep_symbolize_keys 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 exec_tasks = [] if ENV['parallels'] processes = ENV['parallels'].to_i split_group = [] groups = 0 tasks.each_with_index do |t,pos| split_group << t if pos % processes == 0 || pos == tasks.length - 1 multitask "parallel_tasks_#{groups}".to_s => split_group groups += 1 split_group = [] end end groups.times {|i| exec_tasks << "parallel_tasks_#{i}" } else exec_tasks = tasks end exec_tasks << :stdout task :all => exec_tasks # tempファイルに書き出し open(ENV['platforms_tmp'] ,"w") do |y| YAML.dump(platform, y) end path = {} exec_tasks(nil, scenarios, [], platform) end serverspec-runner-master/bin/000077500000000000000000000000001261704777000166225ustar00rootroot00000000000000serverspec-runner-master/bin/serverspec-runner000077500000000000000000000047211261704777000222440ustar00rootroot00000000000000#!/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], ["--parallel", "-p", GetoptLong::REQUIRED_ARGUMENT], ["--help", "-h", GetoptLong::NO_ARGUMENT], ["--raketask", "-1", GetoptLong::REQUIRED_ARGUMENT], ["--tmpdir", "-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 '--parallel' ENV['parallels'] = 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 "-p, --parallel execute tasks in parallel" puts "-1, --raketask RAKE_TASK_NAME execute specified rake task only(ex: spec:test::anyhost-01)" 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-master/lib/000077500000000000000000000000001261704777000166205ustar00rootroot00000000000000serverspec-runner-master/lib/extension/000077500000000000000000000000001261704777000206345ustar00rootroot00000000000000serverspec-runner-master/lib/extension/serverspec/000077500000000000000000000000001261704777000230155ustar00rootroot00000000000000serverspec-runner-master/lib/extension/serverspec/helper/000077500000000000000000000000001261704777000242745ustar00rootroot00000000000000serverspec-runner-master/lib/extension/serverspec/helper/type.rb000066400000000000000000000005531261704777000256050ustar00rootroot00000000000000module Serverspec module Helper module Type types = %w( mysql ) types.each {|type| require "extension/serverspec/type/#{type}" } types.each do |type| define_method type do |*args| name = args.first eval "Serverspec::Type::#{type.to_camel_case}.new(name)" end end end end end serverspec-runner-master/lib/extension/serverspec/matcher/000077500000000000000000000000001261704777000244405ustar00rootroot00000000000000serverspec-runner-master/lib/extension/serverspec/matcher/be_replicated.rb000066400000000000000000000005461261704777000275540ustar00rootroot00000000000000RSpec::Matchers.define :be_replicated do match do |host| host.replicated?(@master, @user, @password, @port) end chain :from do |master| @master = master end chain :with_user do |user| @user = user end chain :with_password do |password| @password = password end chain :with_port do |port| @port = port end end serverspec-runner-master/lib/extension/serverspec/type/000077500000000000000000000000001261704777000237765ustar00rootroot00000000000000serverspec-runner-master/lib/extension/serverspec/type/file.rb000066400000000000000000000001641261704777000252430ustar00rootroot00000000000000module Serverspec::Type class File < Base def text? @runner.check_file_is_text(@name) end end end serverspec-runner-master/lib/extension/serverspec/type/mysql.rb000066400000000000000000000003071261704777000254700ustar00rootroot00000000000000module Serverspec::Type class Mysql < Base def replicated?(master=nil, user=nil, password=nil, port=nil) @runner.check_mysql_is_replicated(master, user, password, port) end end end serverspec-runner-master/lib/extension/specinfra/000077500000000000000000000000001261704777000226065ustar00rootroot00000000000000serverspec-runner-master/lib/extension/specinfra/command/000077500000000000000000000000001261704777000242245ustar00rootroot00000000000000serverspec-runner-master/lib/extension/specinfra/command/base/000077500000000000000000000000001261704777000251365ustar00rootroot00000000000000serverspec-runner-master/lib/extension/specinfra/command/base/file.rb000066400000000000000000000002561261704777000264050ustar00rootroot00000000000000class Specinfra::Command::Base::File < Specinfra::Command::Base class << self def check_is_text(file) "file #{escape(file)} | egrep ' text$'" end end end serverspec-runner-master/lib/extension/specinfra/command/linux/000077500000000000000000000000001261704777000253635ustar00rootroot00000000000000serverspec-runner-master/lib/extension/specinfra/command/linux/base/000077500000000000000000000000001261704777000262755ustar00rootroot00000000000000serverspec-runner-master/lib/extension/specinfra/command/linux/base/mysql.rb000066400000000000000000000011101261704777000277600ustar00rootroot00000000000000class Specinfra::Command::Linux::Base::Mysql < Specinfra::Command::Base class << self def check_is_replicated(master=nil, user=nil, password=nil, port=nil) opt_user = "--user=#{user} " || '' opt_password = "--password=#{password} " || '' opt_port = "--port=#{port} " || '' cmd = '' cmd += "echo 'show slave status \\G;' | mysql #{opt_user} #{opt_password} #{opt_port} | " cmd += "grep -e 'Slave_IO_Running: Yes' -e 'Slave_SQL_Running: Yes' -e 'Master_Host: #{master}' | " cmd += "wc -l | grep -w 3" cmd end end end serverspec-runner-master/lib/serverspec-runner.rb000066400000000000000000000000441261704777000226330ustar00rootroot00000000000000require 'serverspec-runner/version' serverspec-runner-master/lib/serverspec-runner/000077500000000000000000000000001261704777000223105ustar00rootroot00000000000000serverspec-runner-master/lib/serverspec-runner/util/000077500000000000000000000000001261704777000232655ustar00rootroot00000000000000serverspec-runner-master/lib/serverspec-runner/util/hash.rb000066400000000000000000000005301261704777000245330ustar00rootroot00000000000000class Hash def depth 1 + (values.map{|v| Hash === v ? v.depth : 1}.max) end def deep_symbolize_keys self.each_with_object({}) do |(k, v), h| if v.is_a?(Array) v = v.map{|vv| vv.deep_symbolize_keys} elsif v.is_a?(Hash) v = v.deep_symbolize_keys end h[k.to_s.to_sym] = v end end end serverspec-runner-master/lib/serverspec-runner/version.rb000066400000000000000000000000601261704777000243160ustar00rootroot00000000000000module ServerspecRunner VERSION = "1.2.2" end serverspec-runner-master/scenario.yml000066400000000000000000000004311261704777000203760ustar00rootroot00000000000000# # test_dir_top: # test_dir_second_1: # - ssh-access-host-or-symbol # - : # role_dir_second_2: # - : # : # test_dir_hierarchies: # : # --- # ssh-access-host-or-symbol: # host: xxx.xxx.xxx.xxx # example: - anyhost-01 --- anyhost-01: host: 127.0.0.1 serverspec-runner-master/serverspec-runner.gemspec000066400000000000000000000017471261704777000231200ustar00rootroot00000000000000# 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-master/spec/000077500000000000000000000000001261704777000170045ustar00rootroot00000000000000serverspec-runner-master/spec/example/000077500000000000000000000000001261704777000204375ustar00rootroot00000000000000serverspec-runner-master/spec/example/default.rb000066400000000000000000000007771261704777000224230ustar00rootroot00000000000000require 'spec_helper' describe user('root') do it { should exist } it { should have_uid 0 } it { should have_home_directory '/root' } end describe group('root') do it { should have_gid 0 } end describe 'Filesystem' do describe file('/') do it { should be_mounted } end end describe host('www.google.com') do it { should be_resolvable } it { should be_reachable } end describe command('dmesg | grep "FAIL\|Fail\|fail\|ERROR\|Error\|error"') do its(:exit_status){ should_not eq 0 } end serverspec-runner-master/spec/spec_helper.rb000066400000000000000000000066451261704777000216350ustar00rootroot00000000000000require 'serverspec' require 'pathname' require 'net/ssh' require 'net/ssh/proxy/command' require 'yaml' require 'csv' require 'serverspec-runner/util/hash' # require extension libraries Dir.glob([ ENV['specroot'] + '/lib/extension/serverspec/**/*.rb', ENV['specroot'] + '/lib/extension/specinfra/**/*.rb']).each {|f| require f} 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] ssh_opts[:proxy] = Kernel.eval(ssh_opts[:proxy]) if ssh_opts[:proxy] user = options[:user] || ssh_opts[:user] || Etc.getlogin options.merge!(ssh_opts) set :ssh_options, options set :backend, :ssh set :request_pty, true 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] 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 + (self.example.metadata[: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-master/ssh_options_default.yml000066400000000000000000000001601261704777000226460ustar00rootroot00000000000000:port: 22 :paranoid: false #:user: "youre_name" #:keys: ["/path/to/private_key"] #:passphrase: "yourpassphrase"