2015-08-30 00:13:07 +00:00
|
|
|
# encoding: utf-8
|
2015-09-01 09:48:50 +00:00
|
|
|
require 'shellwords'
|
2015-08-30 00:13:07 +00:00
|
|
|
|
|
|
|
module Vulcano::Backends
|
|
|
|
|
|
|
|
class SpecinfraHelper < Vulcano.backend(1)
|
|
|
|
name 'specinfra'
|
|
|
|
|
|
|
|
def initialize(conf)
|
|
|
|
@conf = conf
|
|
|
|
@files = {}
|
|
|
|
type = @conf[:backend]
|
2015-08-30 02:46:46 +00:00
|
|
|
|
2015-08-30 00:13:07 +00:00
|
|
|
configure_shared_options
|
2015-08-30 02:46:46 +00:00
|
|
|
|
|
|
|
# configure the given backend, if we can handle it
|
|
|
|
# e.g. backend = exec ==> try to call configure_exec
|
|
|
|
# if we don't support it, error out
|
2015-08-30 00:13:07 +00:00
|
|
|
m = "configure_#{type}"
|
|
|
|
if self.respond_to?(m.to_sym)
|
|
|
|
self.send(m)
|
|
|
|
else
|
|
|
|
raise "Cannot configure Specinfra backend #{type}: it isn't supported yet."
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def file(path)
|
|
|
|
@files[path] ||= File.new(path)
|
|
|
|
end
|
|
|
|
|
|
|
|
def run_command(cmd)
|
|
|
|
Specinfra::Runner.run_command(cmd)
|
|
|
|
end
|
|
|
|
|
|
|
|
def to_s
|
|
|
|
'SpecInfra Backend Runner'
|
|
|
|
end
|
|
|
|
|
|
|
|
def configure_shared_options
|
|
|
|
Specinfra::Backend::Cmd.send(:include, Specinfra::Helper::Set)
|
|
|
|
si = Specinfra.configuration
|
|
|
|
si.os = nil
|
|
|
|
if @conf['disable_sudo']
|
|
|
|
si.disable_sudo = true
|
|
|
|
else
|
|
|
|
si.sudo_password = @conf['sudo_password']
|
|
|
|
si.sudo_options = @conf['sudo_options']
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def configure_docker
|
2015-09-01 08:55:28 +00:00
|
|
|
host = @conf['host'].to_s
|
2015-08-30 00:13:07 +00:00
|
|
|
Specinfra.configuration.backend = :docker
|
|
|
|
Specinfra.configuration.docker_container = host
|
|
|
|
end
|
|
|
|
|
|
|
|
def configure_exec
|
|
|
|
Specinfra.configuration.backend = :exec
|
|
|
|
end
|
|
|
|
|
|
|
|
def configure_ssh
|
|
|
|
si = Specinfra.configuration
|
|
|
|
si.backend = :ssh
|
|
|
|
si.request_pty = true
|
|
|
|
|
|
|
|
host = @conf['host'].to_s
|
|
|
|
RSpec.configuration.host = host
|
|
|
|
|
|
|
|
ssh_opts = {
|
|
|
|
port: @conf['port'] || 22,
|
|
|
|
auth_methods: ['none'],
|
|
|
|
user_known_hosts_file: "/dev/null",
|
|
|
|
global_known_hosts_file: "/dev/null",
|
|
|
|
number_of_password_prompts: 0,
|
|
|
|
user: @conf['user'],
|
|
|
|
password: @conf['password'],
|
|
|
|
keys: [@conf['key_file']].compact,
|
|
|
|
}
|
|
|
|
|
|
|
|
if host.empty?
|
|
|
|
raise "You must configure a target host."
|
|
|
|
end
|
|
|
|
unless ssh_opts[:port] > 0
|
|
|
|
raise "Port must be > 0 (not #{ssh_opts[:port]})"
|
|
|
|
end
|
|
|
|
if ssh_opts[:user].to_s.empty?
|
|
|
|
raise "User must not be empty."
|
|
|
|
end
|
|
|
|
unless ssh_opts[:keys].empty?
|
|
|
|
ssh_opts[:auth_methods].push('publickey')
|
|
|
|
ssh_opts[:keys_only] = true if ssh_opts[:password].nil?
|
|
|
|
end
|
|
|
|
unless ssh_opts[:password].nil?
|
|
|
|
ssh_opts[:auth_methods].push('password')
|
|
|
|
end
|
|
|
|
if ssh_opts[:keys].empty? and ssh_opts[:password].nil?
|
|
|
|
raise "You must configure at least one authentication method" +
|
|
|
|
": Password or key."
|
|
|
|
end
|
|
|
|
|
|
|
|
si.ssh_options = ssh_opts
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
def configure_winrm
|
|
|
|
si = Specinfra.configuration
|
|
|
|
si.backend = :winrm
|
|
|
|
si.os = { family: 'windows'}
|
|
|
|
|
|
|
|
# common options
|
|
|
|
host = conf['host'].to_s
|
|
|
|
port = conf['port']
|
|
|
|
user = conf['user'].to_s
|
|
|
|
pass = conf['password'].to_s
|
|
|
|
|
|
|
|
# SSL configuration
|
|
|
|
if conf['winrm_ssl']
|
|
|
|
scheme = 'https'
|
|
|
|
port = port || 5986
|
|
|
|
else
|
|
|
|
scheme = 'http'
|
|
|
|
port = port || 5985
|
|
|
|
end
|
|
|
|
|
|
|
|
# validation
|
|
|
|
if host.empty?
|
|
|
|
raise "You must configure a target host."
|
|
|
|
end
|
|
|
|
unless port > 0
|
|
|
|
raise "Port must be > 0 (not #{port})"
|
|
|
|
end
|
|
|
|
if user.empty?
|
|
|
|
raise "You must configure a WinRM user for login."
|
|
|
|
end
|
|
|
|
if pass.empty?
|
|
|
|
raise "You must configure a WinRM password."
|
|
|
|
end
|
|
|
|
|
|
|
|
# create the connection
|
|
|
|
endpoint = "#{scheme}://#{host}:#{port}/wsman"
|
|
|
|
winrm = ::WinRM::WinRMWebService.new(
|
|
|
|
endpoint,
|
|
|
|
:ssl,
|
|
|
|
user: user,
|
|
|
|
pass: pass,
|
|
|
|
basic_auth_only: true,
|
|
|
|
no_ssl_peer_verification: conf['winrm_self_signed'],
|
|
|
|
)
|
|
|
|
si.winrm = winrm
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
class SpecinfraHelper
|
|
|
|
|
|
|
|
class File
|
|
|
|
def initialize(path)
|
|
|
|
@path = path
|
|
|
|
end
|
|
|
|
|
2015-09-01 09:48:50 +00:00
|
|
|
def type
|
|
|
|
path = Shellwords.escape(@path)
|
|
|
|
Specinfra::Runner.run_command("stat -c %f #{path}").stdout
|
|
|
|
end
|
|
|
|
|
|
|
|
def exists?
|
|
|
|
Specinfra::Runner.check_file_exists(@path)
|
|
|
|
end
|
|
|
|
|
2015-08-30 00:13:07 +00:00
|
|
|
def file?
|
|
|
|
Specinfra::Runner.check_file_is_file(@path)
|
|
|
|
end
|
|
|
|
|
2015-09-01 09:48:50 +00:00
|
|
|
def block_device?
|
|
|
|
Specinfra::Runner.check_file_is_block_device(@path)
|
|
|
|
end
|
|
|
|
|
|
|
|
def character_device?
|
|
|
|
Specinfra::Runner.check_file_is_character_device(@path)
|
|
|
|
end
|
|
|
|
|
|
|
|
def socket?
|
|
|
|
Specinfra::Runner.check_file_is_socket(@path)
|
|
|
|
end
|
|
|
|
|
|
|
|
def directory?
|
|
|
|
Specinfra::Runner.check_file_is_directory(@path)
|
|
|
|
end
|
|
|
|
|
|
|
|
def symlink?
|
|
|
|
Specinfra::Runner.check_file_is_symlink(@path)
|
|
|
|
end
|
|
|
|
|
|
|
|
def pipe?
|
|
|
|
Specinfra::Runner.check_file_is_pipe(@path)
|
|
|
|
end
|
|
|
|
|
|
|
|
def mode
|
|
|
|
Specinfra::Runner.get_file_mode(@path).stdout
|
|
|
|
end
|
|
|
|
|
|
|
|
def owner
|
|
|
|
Specinfra::Runner.get_file_owner(@path).stdout
|
|
|
|
end
|
|
|
|
|
|
|
|
def group
|
|
|
|
Specinfra::Runner.get_file_group(@path).stdout
|
|
|
|
end
|
|
|
|
|
|
|
|
def link_target
|
|
|
|
path = Shellwords.escape(@path)
|
|
|
|
Specinfra::Runner.run_command("readlink #{path}").stdout
|
|
|
|
end
|
|
|
|
|
2015-08-30 00:13:07 +00:00
|
|
|
def content
|
|
|
|
Specinfra::Runner.get_file_content(@path).stdout
|
|
|
|
end
|
|
|
|
|
2015-09-01 09:48:50 +00:00
|
|
|
def mtime
|
|
|
|
Specinfra::Runner.get_file_mtime(@path).stdout.strip
|
|
|
|
end
|
|
|
|
|
|
|
|
def ctime
|
|
|
|
Specinfra::Runner.get_file_ctime(@path).stdout.strip
|
|
|
|
end
|
|
|
|
|
2015-08-30 00:13:07 +00:00
|
|
|
def size
|
|
|
|
Specinfra::Runner.get_file_size(@path).stdout.strip.to_i
|
|
|
|
end
|
2015-09-01 09:48:50 +00:00
|
|
|
|
|
|
|
def selinux_label
|
|
|
|
Specinfra::Runner.get_file_selinuxlabel(@path).stdout.strip
|
|
|
|
end
|
|
|
|
|
|
|
|
def readable?(by_type, by_user)
|
|
|
|
if by_user.nil?
|
|
|
|
Specinfra::Runner.check_file_is_readable(@path, by_type)
|
|
|
|
else
|
|
|
|
Specinfra::Runner.check_file_is_accessible_by_user(@path, by_user, 'r')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def writable?(by_type, by_user)
|
|
|
|
if by_user.nil?
|
|
|
|
Specinfra::Runner.check_file_is_writable(@path, by_type)
|
|
|
|
else
|
|
|
|
Specinfra::Runner.check_file_is_accessible_by_user(@path, by_user, 'w')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def executable?(by_type, by_user)
|
|
|
|
if by_user.nil?
|
|
|
|
Specinfra::Runner.check_file_is_executable(@path, by_type)
|
|
|
|
else
|
|
|
|
Specinfra::Runner.check_file_is_accessible_by_user(@path, by_user, 'x')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def mounted?(opts, only_with)
|
|
|
|
Specinfra::Runner.check_file_is_mounted(@name, opts, only_with)
|
|
|
|
end
|
|
|
|
|
|
|
|
def immutable?
|
|
|
|
Specinfra::Runner.get_file_immutable(@path)
|
|
|
|
end
|
|
|
|
|
2015-08-30 00:13:07 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|