2012年12月20日

NetSpear - ネットワーク・スクリプトの自動実行アプリケーションを作ってみた

今身の回りにある家電製品、モバイル・ガジェットを見ると、その中身であるOSにはLinuxを採用しているというケースが増えて来ていますよね。

僕もブログを通じて家電製品やLinuxサーバーのカスタマイズ・設定方法を説明することがあるんですが、その手順の大部分はSSH/SFTPプロトコルとCLIと呼ばれるコマンド形式を組み合わせた操作で、知らない・慣れない人には途端に難しくなってしまうことに不満を感じていたんです。

かと言って機器・オペレーションが変わる度に専用デスクトップ・アプリケーションを作るのも大変・・・。 

機能を絞り込み・その分操作がシンプルで、操作内容を外部設定(スクリプト)化でき、色々な手順の自動化に使えるツールがあれば良いな、という事で NetSpear というネットワーク・スクリプトの実行アプリケーションを作って見ました。

netspear-logo

NetSpearのダウンロード


ダウンロードはこちらのリンクからどうぞ。


Software Requirements: Oracle JRE(Not OpenJDK) 1.6 or Later



NetSpearのインストール・起動


ダウンロードしたzipファイルを解凍すると、3つのファイル(netspear-x.x.jar、netspear-x.x.exe、netspear.sh)があるはずです。

spear17

exeファイルはWindows用、jar、shはLinux、Mac OS向け。

このアプリケーションにはJava実行環境(JRE)が必要です。もし、うまく動かない場合には本家(Oracle)サイトから1.6 or 1.7系のJREをダウンロード、インストールしてから試してみて下さいね。
 
全オペレーティング・システムのJavaのダウンロード一覧

Javaのインストールが終わったらWindowsであればexeファイルをダブルクリック、Linux、Mac OSであれば端末(ターミナル)からnetspear.shを実行してみて下さい(OpenJDKの場合は起動しませんよ!)。

すると、NetSpearが起動するはずです。

spear0

ボタンは3つ。左から注射はスクリプト(ロジックの定義されたXMLファイル)の読み込み、ロケットはスクリプトの実行、Testボタンは指定したユーザー名、パスワード、ホストを使って外部デバイスへの接続確認に使います。

ロケット、TestボタンはXMLファイルを読み込むと使えるようになります。


NetSpear用スクリプト構成とサンプル・スクリプト


NetSpear自体はスクリプトを実行するだけのデスクトップ・アプリケーションで、肝心のロジックはXMLファイルとして用意する必要があります。

こちらがそのサンプル。

<spearConfig>
  
  <conection>
    <host>localhost</host><!-- mandatory -->
    <userId>hoge</userId><!-- mandatory -->
    <password>hoge's-password</password><!-- mandatory -->
    <type>ssh</type><!-- mandatory -->
    <encoding>UTF8</encoding><!-- mandatory -->
  </conection>
  
  <welcomMessage>Welcom!</welcomMessage><!-- optional -->
  
  <successMessage>Completed!</successMessage><!-- optional -->
  
  <commands class="java.util.ArrayList"><!-- mandatory -->
    <runCommamd>
      <descr>ssh command1 description</descr><!-- optional -->
      <command>command1</command><!-- mandatory -->
      <rollbackId>Rollback command id</rollbackId><!-- optional -->
      <type>ssh | sftp</type><!-- mandatory -->
      <checkEndStatus>true | false</checkEndStatus><!-- mandatory -->
      <failedMessage>Failed: command1</failedMessage><!-- optional -->
    </runCommamd>
    
    <runCommamd>
      <descr>ssh command2 description</descr>
      <command>command2</command>
      <type>ssh</type>
      <checkEndStatus>false</checkEndStatus>
    </runCommamd>
    
    <runCommamd>
      <descr>sftp command1 description</descr>
      <command>put | get file1 [file2]</command>
      <type>sftp</type>
      <checkEndStatus>false</checkEndStatus>
    </runCommamd>
  </commands>
   
  <rollbacks class="java.util.ArrayList">
  </rollbacks>
   
</spearConfig>


まずは、<conection>タグ内ででSSH/SFTP接続先ホスト、認証情報を定義します。

<welcomMessage>、<successMessage>タグでは、それぞれ最初に画面に表示されるメッセージと全ての処理が正常終了した際に表示するメッセージを定義します。

さあ、ここからがロジック。<commands>タグ内に<runCommamd>タグで実行するコマンドを順番に定義します。
<descr>はアプリケーション上で表示するコマンドの説明、<command>は実行するコマンド、<type>は接続種類でsshかsftpの何れかを定義、<checkEndStatus>では実行したコマンドの終了ステータス($?)をチェックするか否かをtrue/falseの何れかを定義します。

もし、<checkEndStatus>でfalseを指定すると、アプリケーション(NetSpear)はそのコマンドの正常・異常終了を問わずに全てのコマンドを実行します。逆にtrueを指定すると、もし終了ステータスが正常終了(0)でない場合にはそのコマンドをもってスクリプトの実行を停止します(その際、アプリケーションは<failedMessage>の内容をダイアログで表示します)。

最後に<rollbackId>。これは<checkEndStatus>がtrueである<runCommamd>の実行に失敗した場合に<rollbacks>タグ内で、同じ<rollbackId>を持つ<runCommamd>を実行・以前の状態に回復する場合に使います。

実例を見るのが早いかもしれませんね。次に示す定義ファイルはlocalhostにsshでログインしてapt-get update、apt-get upgradeを実行するスクリプトです。

<spearConfig>
  
  <conection>
    <host>localhost</host>
    <userId>netbuffalo</userId>
    <password>mypassword</password>
    <type>ssh</type>
    <encoding>UTF8</encoding>
  </conection>
  
  <welcomMessage>
    このスクリプトはapt-get update及びupgradeを実行し、システムを最新の状態に保ちます。
    バージョン1.0
  </welcomMessage>
  
  <successMessage>
    システムのアップデート処理が完了しました。
  </successMessage>
  
  <commands class="java.util.ArrayList">
    <runCommamd>
      <descr>アップデート情報の更新</descr>
      <command>sudo apt-get update</command>
      <type>ssh</type>
      <checkEndStatus>false</checkEndStatus>
      <failedMessage>アップデート情報の取得に失敗しました(1)</failedMessage>
    </runCommamd>

    <runCommamd>
      <descr>パスワードの入力</descr>
      <command>mypassword</command>
      <type>ssh</type>
      <checkEndStatus>true</checkEndStatus>
      <failedMessage>アップデート情報の取得に失敗しました(2)</failedMessage>
    </runCommamd>
    
    <runCommamd>
      <descr>ソフトウェアのアップグレード</descr>
      <command>sudo apt-get upgrade</command>
      <type>ssh</type>
      <checkEndStatus>false</checkEndStatus>
      <failedMessage>アップデートの実行に失敗しました(1)</failedMessage>
    </runCommamd>
    
    <runCommamd>
      <descr>アップグレードの実行(y入力)</descr>
      <command>y</command>
      <type>ssh</type>
      <checkEndStatus>true</checkEndStatus>
      <failedMessage>
        アップデートの実行に失敗しました(2)
        アップデートが存在しない可能性が可能性があります。
        </failedMessage>
    </runCommamd>
  </commands>
   
  <rollbacks class="java.util.ArrayList">
  </rollbacks>
   
</spearConfig>


たった2つのコマンド(apt-get update、apt-get upgrade)を実行するだけですが、<runCommamd>タグは4つあります。
 
よく考えてみると理由は簡単。 sudo apt-get updateを入力すると、

$ sudo apt-get update
[sudo] password for netbuffalo:

と入力を求められるからです。

NetSpearではコマンド実行中に入力を求められるような対話的なコマンドは基本使えませんがsudo時のパスワード入力、yes/no入力プロンプトには対応しているので、続けて入力しているんです。

sudo apt-get upgradeの場合も同じ。[Y/n]?プロンプトが出力されることがわかっているのでyを入力しているんです。

$ sudo apt-get upgrade
- snip -
続行しますか [Y/n]? 

このXMLファイルを読み込んで、

spear5

ロケット・ボタンをクリックすると全てのコマンドが自動実行されるという訳です。

spear8

全てのコマンドが正常終了すると<successMessage>タグで定義した完了メッセージが表示されておしまいです。

spear9


SFTP、Rollbackの使いどころ


こちらもサンプルを使って説明しましょうか。次に示すスクリプトはMySQLサーバーにログインし、

  1. MySQLサービス停止
  2. /var/lib/mysqlディレクトリのアーカイブ(zipファイル)を/tmpディレクトリに作成
  3. SFTPで/tmp/mysql.zipをローカルに転送(ローカル側のパスを指定することも可能。ここでは無指定)
  4. MySQLサービス再開
  5. /tmpディレクトリをクリーンアップ

を順次実行しています。

<spearConfig>
  
  <conection>
    <host>mysql-host</host>
    <userId>mysql-user</userId>
    <password>mysql-password</password>
    <type>ssh</type>
  </conection>
  
  <welcomMessage>
    MySQLのバックアップを作成し、ローカルに転送するスクリプトです。
    バージョン1.0
  </welcomMessage>
  <successMessage>全ての処理が正常終了しました。</successMessage>
  
  <commands class="java.util.ArrayList">
    <runCommamd>
      <descr>MySQLのサービス停止</descr>
      <command>/etc/init.d/mysqld stop</command>
      <failedMessage>MySQLのサービス停止に失敗しました。</failedMessage>
      <type>ssh</type>
      <checkEndStatus>true</checkEndStatus>
    </runCommamd>
 
    <runCommamd>
      <descr>MySQLのバックアップ</descr>
      <command>zip -r /tmp/mysql.zip /var/lib/mysql</command>
      <rollbackId>ROLLBACK-1</rollbackId>
      <failedMessage>zipファイルの作成に失敗しました。</failedMessage>
      <type>ssh</type>
      <checkEndStatus>true</checkEndStatus>
    </runCommamd>
 
    <runCommamd>
      <descr>バックアップ・ファイルの転送</descr>
      <command>get /tmp/mysql.zip</command>
      <type>sftp</type>
      <checkEndStatus>true</checkEndStatus>
    </runCommamd>
 
    <runCommamd>
      <descr>MySQLのサービス開始</descr>
      <command>/etc/init.d/mysqld start</command>
      <failedMessage>サービス再開に失敗しました。</failedMessage>
      <type>ssh</type>
      <checkEndStatus>true</checkEndStatus>
    </runCommamd>
 
    <runCommamd>
      <descr>クリーンアップ</descr>
      <command>rm -rf /tmp/mysql.zip</command>
      <failedMessage>クリーンアップ(/tmp/mysql.zipの削除)に失敗しました。</failedMessage>
      <type>ssh</type>
      <checkEndStatus>true</checkEndStatus>
    </runCommamd>
  </commands>
   
  <rollbacks class="java.util.ArrayList">
    <runCommamd>
      <descr>MySQLのサービスの開始</descr>
      <command>/etc/init.d/mysqld start</command>
      <type>ssh</type>
      <rollbackId>ROLLBACK-1</rollbackId>
      <checkEndStatus>true</checkEndStatus>
      <failedMessage>システムの復元(MySQLのサービス再開)に失敗しました。管理者に連絡して下さい。</failedMessage>
    </runCommamd>
  </rollbacks>
   
</spearConfig>


これをNetSpearに読み込み、実行してみます。

全てのコマンドが正常終了すると、各コマンドのステータス(status)が笑顔アイコンになり、最後に”全ての処理が正常終了しました。”と表示されます。

spear18

逆に、全てが正常終了しなかった場合、例えば”zip -r /tmp/mysql.zip /var/lib/mysql”が失敗した場合を考えると、このコマンドの<checkEndStatus>属性はtrueなので、エラーメッセージを表示しつつ、この段階で処理は終了します。

spear12

しかし、このままではmysqldサービスが停止したままになってしまうので困りますよね? 

ということで、このコマンドでは<rollbackId>タグでROLLBACK-1を指定しています。

こうしておくと、異常終了した場合に<rollbacks>タグ内でROLLBACK-1というIDで定義されているコマンド(<RunCommand>)が呼び出されるようになります。

もし、本当にrollbackが呼び出されると画面上ではこんな表示になります。

spear19

zipファイルの作成に失敗したので、以降のコマンドはキャンセルし、ロールバック系のコマンドを実行しています。

今後ブログでSSH/SFTPを使った Geek な手順を紹介するときには、よくわからない・心配な人向けにNetSpearを使った自動実行方法も用意しようかと思っております。


それでは! 



地獄のコマンド+地獄のヒーロー(初回生産限定) [DVD]
20世紀フォックス・ホーム・エンターテイメント・ジャパン (2010-12-17)
売り上げランキング: 43,594

入門bash 第3版
入門bash 第3版
posted with amazlet at 12.12.20
Cameron Newham Bill Rosenblatt 
オライリージャパン 
売り上げランキング: 53,892

Posted by netbuffalo at 23:00│Comments(0)TrackBack(0) プログラミング | Java


この記事へのトラックバックURL

コメントする

名前
 
  絵文字