ssh + su環境でServerspec/Specinfraを利用するためのバックエンドを書いた

こんにちは。業務都合上、サーバー運用ではsudoが使えずsuでrootになって作業を行わなければならないhayajoです。

Specinfraのsshバックエンドはsudoでのコマンド実行を前提としているため、suでrootになって運用しているサーバーに対してSpecinfra/Serverspecを実行するには少々手間がかかります。(Specinfra.configuration.disable_sudo + run_commandでexpect実行とか)

そこでSSH + suでのコマンド実行を行うSpecinfraバックエンドを書きました。

Specinfraでの使用例はこんな感じです。

require 'specinfra'
require 'specinfra/helper/set'
require 'specinfra/backend/extension/ssh_su'
require 'highline/import'

include Specinfra::Helper::Set
include Specinfra::Helper::Os

host = ARGV[0]

set :host, host
set :backend, :ssh_su

options = Net::SSH::Config.for(host)
options[:user] = ask("Enter ssh user: ")
options[:password] = ask("Enter ssh password: ") { |q| q.echo = false }
set :ssh_options, options

set :su_password, ask("Enter su password: ") { |q| q.echo = false }

puts Specinfra::Runner::run_command('whoami').stdout
puts Specinfra::Runner::run_command('cat /etc/passwd | grep `whoami`').stdout

set :os, os
if Specinfra.configuration.os[:family] == 'redhat'
  puts Specinfra::Runner::install_package('epel-release').stdout
end

puts Specinfra::Runner::install_package('nginx').stdout

モジュールをrequireし、バックエンドにssh_suを指定して使います。Serverspecで使用する場合も同様です。

configurationはsshバックエンドとほぼ同様で、sudo*のものをsu*に置き換えてください。

suのパスワードプロンプトはデフォルトで"Password: "を想定していますが、ロケールを変更した場合など、対象サーバーのプロンプトと異なる場合はsu_promptを設定して調整してください。

suで運用する環境は減ってきていると思うので需要はあまりないとは思いますが、そのようなホストに対してSpecinfra/Serverspecを実行したい場合は使ってみてはいかがでしょうか。

不具合がありましたらGihubのIssuやプルリクエストをお願いします。