babie steps

作業療法記録

リモートの VPS から手元の Growl に autotest の通知を受けつけるようにした

※ 追記したから最後まで読んでから実行してね。


VPS から autotest の Growl の通知を受けたい。autotest-growl は Linux 対応してるのかしら?と思ってソースを見たら、どうも notify-send というコマンドに依存しているらしい。
Ubuntu では libnotify-bin というパッケージを入れれば notify-send が入るらしいのだが、こいつが Manpage を見る限りどうもリモートホストに対応してないっぽい。
調べると、ruby-growl というパッケージに growl ってコマンドが付いているらしい。んでこれは Pure Ruby 製で libなんたらとかインストールしないでいい上に -H オプションでリモートホストに対応してるらしい。いいぞ!こいつのラッパースクリプトを書こう!

$ gem install ruby-growl

zsh の人は rehash しておくこと。

Mac では、[システム環境設定]→[Growl]→[ネットワーク]の[受信される通知を開く]と[リモートアプリケーション登録を許可]にチェック。Windows Growl はわからん。

あと、CTU やルーターの設定で UDP 9887 に穴を空けること。growl コマンドは TCP 23052 じゃなくて UDP を使うっぽい。あと、Windows for Growl は UDP に対応して無くて、TCP 23053 らしい。なので、growl コマンドを使ったこの方法ではできないので注意。

growl コマンドをテスト。

$ growl -H xxx.xx.xx.xx -t title -m message

UDP で打ちっ放しなので、ちゃんと穴が開いてなくても普通終了します。頑張れ!

Growl 受け付け側というか今触っているコンピューターのグローバルIPを知るには、

$ echo $SSH_CLIENT
xxx.xx.xx.xx 61873 22

こうすれば、こっちの端末がVPS側からどう見えているのか分かる。


んで、ruby-growl の growl コマンドをラップした、オリジナルの notify-send コマンドを作る。

前準備:

$ mkdir -p ~/opt/bin
$ export PATH=~/opt/bin:$PATH

PATH の設定は .zshenv にも書いておく。俺はオリジナルコマンドは ~/opt/bin/ に入れることにしてるが、まぁお好きなように。

~/opt/bin/notifiy-send を作成:

#!/usr/bin/env ruby
# -*- coding: utf-8 -*-
require 'optparse'

if __FILE__ == $0
  OPTS = {
    :name => `hostname`,
    :hostname => ENV["SSH_CLIENT"].split.first,
  }
  OptionParser.new do |opt|
    # for notify-send compatible
    opt.on("-u LEVEL", "--urgency=LEVEL") {|v| }
    opt.on("-t TIME", "--expire-time=TIME") {|v| }
    opt.on("-i ICON", "--icon=ICON[,ICON,...]") {|v| OPTS[:icon] = v }
    opt.on("-c CATEGORY", "--category=TYPE[,TYPE,...]") {|v| }
    opt.on("-?", "--help") {|v| puts opt; exit}
    opt.on("-h", "--hint=TYPE:NAME:VALUE") {|v| }

    # for ruby-growl
    opt.on("-H HOSTNAME", "--host HOSTNAME") {|v| OPTS[:hostname] = v }
    opt.on("-n NAME", "--name NAME") {|v| OPTS[:name] = v }
    #opt.on("-P PASSWORD", "--password PASSWORD") {|v| OPTS[:password] = v }
    #opt.on("-s", "--sticky") {|v| OPTS[:sticky] = true }

    opt.parse!(ARGV)
  end
  title = ARGV[0]
  message = ARGV[1]

  `growl -H #{OPTS[:hostname]} -t "#{title}" -m "#{message}" -n "#{OPTS[:name]}"`
end

notify-send のオプションは受け入れるけどほとんど無視!autotest-growl を動かすための必要最低限しか書きません。

うまく動くかテスト:

$ chmod +x ~/opt/bin/notify-send
$ rehash
$ notify-send title message

動くっぽい。俺の環境では動いた。

これで安心して autotest-growl を入れられます。

$ gem install autotest-growl

~/.autotest に以下を追加:

require 'autotest/growl'

ラッパースクリプトで --password オプションを有効にした人は、Growl 側で設定した上で Autotest::Growl::custom_options = "--password PASSWORD" とかつけるといいんじゃないかなぁ。


できた!!色つかないけど、まぁよし!!


……とここまでやっておきながら、ラッパースクリプトは必要なくて、autotest-growlの中で、growl コマンドを呼び出せばもっとリッチになることに気づいた……ショック!!

autotest-growl-0.2.9/lib/autotest/growl.rb:96 辺り、

    when /linux|bsd/i
      #system %(notify-send "#{title}" "#{message}" -i #{image} -t 5000 #{@@custom_options})
      system %(growl -H #{ENV["SSH_CLIENT"].split.first} -n "#{`hostname`}" -t "#{title}" -m "#{message}" --priority=#{priority} #{'-s' if sticky} #{@@custom_options})

プライオリティが設定できるので赤くなったりしてこっちの方が嬉しい!