class Configspec::Setup

Public Class Methods

ask_os_type() click to toggle source
# File lib/configspec/setup.rb, line 45
    def self.ask_os_type
      prompt = <<-EOF
Select OS type:

  1) UN*X
  2) Windows

Select number: 
EOF

      print prompt.chop
      num = $stdin.gets.to_i - 1
      puts

      @os_type = [ 'UN*X', 'Windows' ][num] || 'UN*X'
    end
ask_unix_backend() click to toggle source
# File lib/configspec/setup.rb, line 62
    def self.ask_unix_backend
      prompt = <<-EOF
Select a backend type:

  1) SSH
  2) Exec (local)
  3) Dockerfile

Select number: 
EOF
      print prompt.chop
      num = $stdin.gets.to_i - 1
      puts

      @backend_type = [ 'Ssh', 'Exec', 'Dockerfile' ][num] || 'Exec'
    end
ask_windows_backend() click to toggle source
# File lib/configspec/setup.rb, line 79
    def self.ask_windows_backend
      prompt = <<-EOF
Select a backend type:

  1) WinRM
  2) Cmd (local)

Select number: 
EOF
      print prompt.chop
      num = $stdin.gets.to_i - 1
      puts

      @backend_type = [ 'WinRM', 'Cmd' ][num] || 'Exec'
    end
auto_vagrant_configuration() click to toggle source
# File lib/configspec/setup.rb, line 174
def self.auto_vagrant_configuration
  if find_vagrantfile
    vagrant_list = `vagrant status`
    list_of_vms = []
    if vagrant_list != ''
      vagrant_list.each_line do |line|
        if match = /([a-z_-]+[\s]+)(created|not created|poweroff|running|saved)[\s](\(virtualbox\)|\(vmware\))/.match(line)
          list_of_vms << match[1].strip!
        end
      end
      if list_of_vms.length == 1
        @hostname = list_of_vms[0]
      else
        list_of_vms.each_with_index { |vm, index | puts "#{index}) #{vm}\n" }
        print "Choose a VM from the Vagrantfile: "
        chosen_vm = $stdin.gets.chomp
        @hostname = list_of_vms[chosen_vm.to_i]
      end
    else
      $stderr.puts "Vagrant status error - Check your Vagrantfile or .vagrant"
      exit 1
    end
  else
    $stderr.puts "Vagrantfile not found in directory!"
    exit 1
  end
end
find_vagrantfile() click to toggle source
# File lib/configspec/setup.rb, line 166
def self.find_vagrantfile
  Pathname.new(Dir.pwd).ascend do |dir|
    path = File.expand_path("Vagrantfile", dir)
    return path if File.exists?(path)
  end
  nil
end
run() click to toggle source
# File lib/configspec/setup.rb, line 6
def self.run

  # ask_os_type
  @os_type = 'UN*X'

  if @os_type == 'UN*X'
    ask_unix_backend
  else
    ask_windows_backend
  end

  if @backend_type == 'Ssh'
    print "Vagrant instance y/n: "
    @vagrant = $stdin.gets.chomp
    if @vagrant =~ (/(true|t|yes|y|1)$/i)
      @vagrant = true
      print "Auto-configure Vagrant from Vagrantfile? y/n: "
      auto_config = $stdin.gets.chomp
      if auto_config =~ (/(true|t|yes|y|1)$/i)
        auto_vagrant_configuration
      else
        print("Input vagrant instance name: ")
        @hostname = $stdin.gets.chomp
      end
    else
      @vagrant = false
      print("Input target host name: ")
      @hostname = $stdin.gets.chomp
    end
  elsif @backend_type == 'Exec'
    @hostname = 'localhost'
  end

  [ 'spec', "spec/#{@hostname}" ].each { |dir| safe_mkdir(dir) }
  safe_create_spec
  safe_create_spec_helper
  safe_create_rakefile
end
safe_create_rakefile() click to toggle source
# File lib/configspec/setup.rb, line 144
    def self.safe_create_rakefile
      content = <<-'EOF'
require 'rake'
require 'rspec/core/rake_task'

RSpec::Core::RakeTask.new(:spec) do |t|
  t.pattern = 'spec/*/*_spec.rb'
end
EOF
      if File.exists? 'Rakefile'
        old_content = File.read('Rakefile')
        if old_content != content
          $stderr.puts "!! Rakefile already exists and differs from template"
        end
      else
        File.open('Rakefile', 'w') do |f|
          f.puts content
        end
        puts ' + Rakefile'
      end
    end
safe_create_spec() click to toggle source
# File lib/configspec/setup.rb, line 95
    def self.safe_create_spec
      content = <<-EOF
require 'spec_helper'

describe package('httpd') do
  it { should be_installed }
end
EOF

      if File.exists? "spec/#{@hostname}/001_httpd_spec.rb"
        old_content = File.read("spec/#{@hostname}/001_httpd_spec.rb")
        if old_content != content
          $stderr.puts "!! spec/#{@hostname}/httpd_spec.rb already exists and differs from template"
        end
      else
        File.open("spec/#{@hostname}/001_httpd_spec.rb", 'w') do |f|
          f.puts content
        end
        puts " + spec/#{@hostname}/001_httpd_spec.rb"
      end
    end
safe_create_spec_helper() click to toggle source
# File lib/configspec/setup.rb, line 128
def self.safe_create_spec_helper
  requirements = []
  content = ERB.new(spec_helper_template, nil, '-').result(binding)
  if File.exists? 'spec/spec_helper.rb'
    old_content = File.read('spec/spec_helper.rb')
    if old_content != content
      $stderr.puts "!! spec/spec_helper.rb already exists and differs from template"
    end
  else
    File.open('spec/spec_helper.rb', 'w') do |f|
      f.puts content
    end
    puts ' + spec/spec_helper.rb'
  end
end
safe_mkdir(dir) click to toggle source
# File lib/configspec/setup.rb, line 117
def self.safe_mkdir(dir)
  if File.exists? dir
    unless File.directory? dir
      $stderr.puts "!! #{dir} already exists and is not a directory"
    end
  else
    FileUtils.mkdir dir
    puts " + #{dir}/"
  end
end
spec_helper_template() click to toggle source
# File lib/configspec/setup.rb, line 202
    def self.spec_helper_template
      template = <<-EOF
require 'configspec'
<% if @os_type == 'UN*X' and @backend_type != 'Dockerfile' -%>
require 'pathname'
<% end -%>
<% if @backend_type == 'Ssh' -%>
require 'net/ssh'
require 'net/scp'
<% end -%>
<% if @backend_type == 'WinRM' -%>
require 'winrm'
<% end -%>

<% if @backend_type == 'Dockerfile' -%>
include SpecInfra::Helper::<%= @backend_type %>
<% else -%>
include SpecInfra::Helper::<%= @backend_type %>
<% end -%>
<% if @os_type == 'UN*X' && @backend_type != 'Dockerfile' -%>
include SpecInfra::Helper::DetectOS
<% else  -%>
include SpecInfra::Helper::RedHat
<% end -%>

<% if @os_type == 'UN*X' && @backend_type != 'Dockerfile' -%>
RSpec.configure do |c|
  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
  <%- if @backend_type == 'Ssh' -%>
  c.before :all do
    block = self.class.metadata[:example_group_block]
    if RUBY_VERSION.start_with?('1.8')
      file = block.to_s.match(/.*@(.*):[0-9]+>/)[1]
    else
      file = block.source_location.first
    end
    host  = File.basename(Pathname.new(file).dirname)
    if c.host != host
      c.ssh.close if c.ssh
      c.scp.close if c.scp
      c.host  = host
      options = Net::SSH::Config.for(c.host)
      user    = options[:user] || Etc.getlogin
    <%- if @vagrant -%>
      vagrant_up = `vagrant up #{@hostname}`
      config = `vagrant ssh-config #{@hostname}`
      if config != ''
        config.each_line do |line|
          if match = /HostName (.*)/.match(line)
            host = match[1]
          elsif  match = /User (.*)/.match(line)
            user = match[1]
          elsif match = /IdentityFile (.*)/.match(line)
            options[:keys] =  [match[1].gsub(/\"/,'')]
          elsif match = /Port (.*)/.match(line)
            options[:port] = match[1]
          end
        end
      end
    <%- end -%>
      c.ssh   = Net::SSH.start(host, user, options)
      c.scp   = Net::SCP.start(host, user, options)
    end
  end
  <%- end -%>
end
<% end -%>
<% if @backend_type == 'WinRM'-%>
RSpec.configure do |c|
  user = <username>
  pass = <password>
  endpoint = "http://<hostname>:5985/wsman"

  c.winrm = ::WinRM::WinRMWebService.new(endpoint, :ssl, :user => user, :pass => pass, :basic_auth_only => true)
  c.winrm.set_timeout 300 # 5 minutes max timeout for any operation
end
<% end -%>
EOF
      template
    end