読者です 読者をやめる 読者になる 読者になる

五条の比較的自由な日記

ツイッターだと短くて書けないようなことを書くためのブログ

chefでのサーバ設定確認に使えそうなメソッド

Chefでサーバの設定を行うのはいいとして、正常にファイルが配置されたかとか、ファイルの権限・所有者が正しいかとか確認するのもchefで行いたいよね。

というわけでChefで使える(かも知れない)メソッドを自分で書いてみました。いちいちクラスにする必要があるのか無いのかは置いておいて、これで最終確認用のChefレシピを使ってみましょう。

自分で動確していないものとかも幾つかあるのと、Ruby歴20時間くらいの私の書くコードなのであまり信用しないでください。あと、ブログに貼付け時にタブが落ちてしまいましたがそのままで行きます。引数を配列で返すところの変換周り、きっともっといい方法があると思いますが、私のRuby歴は20時かn(略)

require 'date'
require 'etc'
require 'fileutils'
require 'socket'

###########################
# クラス作成
class Std_class
def initialize()
end

######################################
# cpとchmod
def chprev(src,dest,user,group,prev)
if File.exist?(src)==false
return false
end
if File::ftype(src) == "directory" then
FileUtils.chmod_R(prev,src)
FileUtils.chown_R(Etc.getpwnam(user).uid , Etc.getgrnam(group).gid , src)
else
FileUtils.chmod(prev,src)
FileUtils.chown(Etc.getpwnam(user).uid , Etc.getgrnam(group).gid , src)
end
return true
end

######################################
# chmod
def chmod_r(src,prev)
FileUtils.chmod_R(prev,src)
end

######################################
# ファイルの存在確認
def file_exist (src)
return File.exist?(src)
end

######################################
# ファイルの存在確認
def dir_exist (src)
return Dir.exist?(src)
end

######################################
# ひとつ上のディレクトリがあるか確認し、なければ作成
def create_pdir (src)
src.gsub!(/\/$/,'')
data = src.split('/')
path = '/'
for i in 1..(data.length-2) do
path += data[i] + '/'
end
if File.exist?(path) == false
FileUtils.mkdir_p(path)
end
end

######################################
# preにバックアップ(存在していれば)
def back_pre (src)
if File.exist?(src)
create_pdir("#{$pre_root}#{src}")
FileUtils.cp("#{src}","#{$pre_root}#{src}")
end
end

######################################
# posにバックアップ
def back_pos (src)
# posにバックアップ
create_pdir("#{$pos_root}#{src}")
FileUtils.cp("#{src}","#{$pos_root}#{src}")
end


######################################
# 適用
def back_apply (src,user,group,prev)
FileUtils.cp("#{$chef_tmp}#{src}","#{src}")
# srcのオーナーとグループ変更
File.chown(Etc.getpwnam(user).uid , Etc.getgrnam(group).gid , src)
# srcの権限変更
FileUtils.chmod(prev,src)
end

######################################
# preにバックアップ。適用。posにバックアップ
def bak_apply (src,user,group,prev)
back_pre(src)
back_apply(src,user,group,prev)
back_pos(src)
end

######################################
# ポート番号チェック
# proはサーバ名
# 返り値は配列で返す
def port_check_net(pro)
com="sudo netstat -anp --tcp |grep #{pro}"
res=`#{com}`
headers, *scores = res.lines.map { |line| line.chomp.split(' ') }
j=0
port =Array.new()
for i in 1..(scores.length-1) do
@te1=scores[i][3].split(':')
if @te1.length >= 2
port[j] = @te1[@te1.length-1]
j += 1
end
end
port.sort!
port.uniq!
return port
end

######################################
# コマンド実行。
# 返り値は配列で、
# ['out'] 通常の返り値
# ['rtn'] 終了コード(boolでtrueが正常。falseが異常)
# ['arr'] 返り値を行で分割で返す。
def command(com)
com = com + ' ; echo $?'
res=`#{com}`
te1=res.split("\n")
kaeri={'out'=>'','err'=>'','arr'=>Array.new()}
if te1[te1.length-1] != '0' then
kaeri['err'] = te1[te1.length-1]
kaeri['out'] = false
return
end
for i in 0..(te1.length-2) do
kaeri['out'] += te1[i] + "\n"
kaeri['arr'][i] = te1[i]
kaeri['rtn'] = true
end
return kaeri
end

######################################
# ファイルが存在するか確認。
def exist (input)
return File.exist?(input)
end

######################################
# 日付を返す。
def date ()
day = Time.now
return day.strftime("%Y%m%d_%H%M%S")
end
# hostname
def hostname ()
return Socket.gethostname
end
end

 Rubyの所感として、

  • ループ周りがC言語臭くなくてやりにくいのと、i++が使えない(多分)で、やりにくかった。
  • 変数の$と@と@@があるとかかなりアレな言語だと思わざるを得ない。Perlのように「強引に拡張しましたァ」なら許せるが、普通にpublicとかstaticでいいのでは無いでしょうか。
  • bashpythonとかみたいにクセのある書き方の言語ですね。私はforがものすごく好きで、ほとんどループはforなんだけど、rubyのforは使いたくないと思った。なんでChefはrubyを採用したんだ、pythonでいいじゃないか。
  • やっぱりインタプリタ界最強の言語はphpだと確信できた。(書きやすさ的な意味で。javaは除く)

rubyがuid、gidでしか使用できないのを見てクラス化したのですが少しは役に立つと嬉しいです。