わすれっぽいきみえ

みらいのじぶんにやさしくしてやる

CentOS6系から7系にバージョンアップして変わったtimezoneの設定についてchefのレシピを編集した

昔書いたchefのレシピを適応しようと思って、自分の書いたコード読み直してたら、default.rbの一番最初の内容がtimezoneの設定だった。

そういえばCentOS6.5とCentOS7でどう変わったのかなんも調べずにvagrantのbox立ち上げたなーと思ったので、ちょっと調べた。

CentOS6とCentOS7でのtimezone設定に関するファイルの違い

以下古いdefault.rbのtimezone設定のところだけ抜粋した。

##################################################################
### clock settings
##################################################################
template "clock" do
  path "/etc/sysconfig/clock"
  source "clock.erb"
  owner "root"
  group "root"
  mode 0644
  notifies :run, 'bash[clock_settings]'
  only_if {File.exists?("/usr/share/zoneinfo/Asia/Tokyo")}
end

bash "clock_settings" do
  user "root"
  code <<-EOH
    source /etc/sysconfig/clock
    cp -p /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
  EOH
  only_if {File.exists?("/usr/share/zoneinfo/Asia/Tokyo")}
end

/etc/sysconfig/clock/usr/share/zoneinfo/etc/localtimeの3つを見てtimezoneの設定をしている。
CentOS6.5では

centos-6.5 ~ $ ls /etc/sysconfig/ | grep clock
clock
centos-6.5 ~ $ ls /etc/ | grep local
localtime
rc.local
centos-6.5 ~ $ ls /usr/share/ | grep zone
zoneinfo

こんな風にファイルがちゃんと存在している。だがCentOS7だと

centos-7.0 ~ $ ls /etc/sysconfig/ | grep clock
centos-7.0 ~ $ ls /etc/ | grep local
locale.conf
localtime
rc.local
centos-7.0 ~ $ ls /usr/share/ | grep zone
zoneinfo

/etc/sysconfig/clockはなくなっている。だからこのファイルを編集するように書いた古いdefault.rbではtimezoneの変更ができない。

CentOS7とCentOS6のどっちもtimezoneを適切に変えるには

ググったところ

がヒットした。timedatectlというコマンドを使うという。ちなみにCentOS6では存在しないコマンドである(それぞれのOSにログインしてtype timedatectlとコマンドを叩いてみるといい)。だから7と6の時とでdefault.rbを書き換えるのがいいかと思ったが、いやサードパーティ製cookbookではCentOS以外にも使えるより汎用的な書き方をしているはずだと思い、timezone関係をいじるレシピを調べてみた。

からtimezoneをキーワードに検索をすると以下のレシピが当たる。

timezoneは2010年12月8日、timezone-iiは2013年2月18日を最後に更新が途絶えているが、systemはなんと2015年2月6日*1とめっちゃホカホカだったので、このレシピでtimezoneを設定する箇所を読んでみた。

https://github.com/xhost-cookbooks/system/blob/master/providers/timezone.rb
のtimezone設定のところだけを読むとdebianubuntu以外は以下のコードでtimezoneを設定している。

  link '/etc/localtime' do
    to "/usr/share/zoneinfo/#{new_resource.name}"
    notifies :restart, "service[#{node['system']['cron_service_name']}]", :immediately
  end

  ruby_block 'verify linked timezone' do
    block do
      tz_info = ::Time.now.strftime('%z %Z')
      tz_info << "#{::File.readlink('/etc/localtime').gsub(/^/, ' (').gsub(/$/, ')')})"
      Chef::Log.info("tz-info: #{tz_info}")
    end
  end

service[#{node['system']['cron_service_name']}]のところに代入するべき値は
https://github.com/xhost-cookbooks/system/blob/master/attributes/default.rb
を読めばよくてcrondを入れればいい。
つまりlocaltimeにzoneinfoへのリンクを貼ってcronを再起動してるだけだった。
ただし単にservice[crond]と記載しても動かないので、cronレシピの読み込みと何もしない service 'crond'の行を追加しておく。

というわけで以下のように変更した。前よりコンパクトになった。

##################################################################
### clock settings
##################################################################
log("tz-info(before): #{Time.now.strftime("%z %Z")}")

service 'crond'

link '/etc/localtime' do
  to '/usr/share/zoneinfo/Asia/Tokyo'
  notifies :restart, 'service[crond]', :immediately
  only_if {File.exists?('/usr/share/zoneinfo/Asia/Tokyo')}
end

log("tz-info(after): #{Time.now.strftime("%z %Z")}")

ちなみになんでCentOS6.5ではなく、CentOS7のboxを使うようにしたかというと新しいバージョンを使ってみたかったというのもあるけども、

というバグを踏んで嫌になったから。CentOS7だと上記のようなことにはならんのですよ。別にvagrant sshでログインしてからsudo yum install kernel-develを実行したらいいだけの話だけど、vagrant up一発で出来て欲しいなって思うしね。

あとCentOS6と7の違いをまとめた記事として次のものが個人的にわかりやすかった。

*1:実はこの記事自体は去年の12月23日には書き始めていて、あとは細かいところを詰めて実際に実行して見るだけだった。その時点でもsystemレシピは12月23日当日にアップデートされていたから、コミッターの人がすごい頑張ってるんだなと思った。