飴屋

開発日記/2015年の日記

2015/12/19

年の瀬も近づき、10月の後半からお仕事のご依頼をたくさんいただき、複数の締め切りが並行してやってきているところです。肉体がボロボロになってきました。

さて、先日納品した成果物についてお問い合わせをいただいたのですが、WEBサイトのフォームの一部が正常に動作しないというものでした。スマホ用のページで発生とのことなので、Android端末とiPhone端末で再度動作確認を行ったところ、お問い合わせいただいたような現象が確認できませんでした。原因を特定すべくお客さんに詳細をうかがうと・・・

  • どうもiPhoneでしかおきない
  • 納品時に確認したときには起きなかった

との情報をいただきました。これはお客さんの端末側に何かが起こっている予感がしました。

最終的にたどり着いた答えはiPhoneのSafariがプライベートブラウズ状態にあるときは、window.sessionStorage.setItemを呼び出すと例外が発生するというのが原因でした。そこでスクリプトが停止していたので、とりあえず例外をcatchするように書き換えて、プライベートブラウズ状態でも動作するようにしました。

自分であまりプライベートブラウズ機能を使わないので、ブラウジングに要したデータが他人にみられないように消えてくれるぐらいの認識でいたのですが、setItemの利用が禁止されるとは盲点でした。webStorageは便利なので積極的に使っていこうと思っていましたが、利用時には気を付けないといけないこともあるのでした。

2015/8/25

いろいろ悩んだ末、解決したお客さんのご依頼のメモ。

お客さんの契約するレンタルサーバー会社からサーバーの移管を申し入れられて、移管したらブログが更新できなくなったのでなんとかしてほしいというご依頼をいただきました。最近、サーバー上の累積したセキュリティ問題への対処が難しくなってきたのかサーバーの移管のお手伝いをすることが多いのですが、これもその延長線上にある作業といえます。

詳しく聞いてみるとMovableTypeでログインができなくなったとのこと。これまで使っていたIDとパスワードを入力してもログインできないということです。salt付きハッシュ化のアルゴリズムがサーバーによって変化することでもあるんだっけか?と適当に考えながら、ログインできるように修正する旨、お返事したところ作業のGoサインをいただきました。

まず、レンタルサーバーのコントロールパネルにアクセスしてデータベースの状態を確認すると、データベースサーバーは使われていないということだったので、SQLiteで運用しているのかなと思い、MovableTypeの設定を確認すると、ObjectDriverの設定はコメントアウトされていて、SQLiteでもないようです。そういう場合、MovableTypeはBerkeley DBを使っているらしいです。DataSource設定のパスの中を調べるとそれっぽいファイルがいっぱい入っていたので、おそらくログインに関連する情報のあるauthor.dbの中身を覗いてみるとなんとなくパスワードがハッシュ化されたような文字列があります。この文字列を適切なものにバイナリエディタで変えてしまえばいいような気がしましたが、試しにお客さんの元々使っていたパスワードをハッシュ化してみると、データベースの中の文字列と一致しました。

となると別の問題をはらんでいそうなので、あんまりよく知らなかったBerkeley DBのことを調べてみました。今はOracleの管理下でオープンソースなんですね。それで、Berkeley DBのファイルのフォーマットがバージョンによって異なるので、サーバー移管によってBerkeley DBのバージョンが上がってしまうと、元のサーバーで作られたファイルが読み込めなくなるとの情報を得ました。対策としてはdb_upgradeコマンド一発でデータベースを新しいバージョンに合わせることができるとのことでした。

なお、このレンタルサーバーはtelnetやsshといったプロトコルを開放していないとのことなので、CGI越しにコマンドを実行しました。結果、「db_upgradeというコマンドはありませんよw」という無慈悲なエラー出力が返ってきました。

ここからこういった問題を先人がいかに解決したのかを検索するが始まります。まず、こちらのCGIを使って、Berkley DBのデータをMySQL、PostgreSQL、SQLiteに移行できるというというので試してみましたが、データベースのテーブルファイルが作成されるものの、やはりBerkeley DBの読み込みができないという点では同じようで中身がテーブルの中身は0件でした。

次にこちらの情報がとても参考になりました。2004年の記事のようですね。10年以上前か・・・お客さんのMovableTypeのバージョンも3.15だしな・・・。要するにdb_upgradeがダメならdb_dumpかdb_dump185という手もあるよというお話なのですが、これがのちにとても役に立ちました。

これらのdbコマンドはパスが通っていないのか、インストールされていないのか判断がつかなかったので、Oracleのサイトから移管先のサーバーに入っているBerkeley DB(ver4.5.2)と同じバージョンのWindows版をダウンロードしてdbのアップグレードだけでもできないかとインストールしてみました。結果、変なエラーメッセージ(Windows2000ならreg.exeがあるか確認しろ的な)が出て動きませんでした。Windows10には対応していないのかも。

Windowsがダメならということで、自分が契約しているVPSにデータベースのファイルだけ持って行って、db_upgradeを実行してみました。すると「扱えない形式のファイルです」的なエラーメッセージが出ます。続いてデータベースを一度ダンプしてからダンプしたファイルを再読み込みして新しいデータベースとして保存しなおすという手を試してみます。db_dumpを実行するとやはり「扱えない形式のファイルです」的なエラーメッセージが出たので、嫌な汗をかきつつ「db_dump185」の方を試してみると、なんだか手ごたえがありました!

どうやら新しいフォーマットに変換できたようなのでこのデータベースをお客さんのサーバーに戻して、直ったかどうかログインしてみた結果・・・「不正なパスワードでログインできません」的なメッセージがやはり表示されます・・・。もうだめかと思いつつ、先ほど一度失敗している「mt-db-convert.cgi」を使って再度、Berkeley DBのデータをSQLiteのファイルに書き出すようにしてみると、なんだか画面に進捗を表す「・・・・・」が大量に表れ、うまいこと処理が進んでいるようです。

おそるおそるデータベースを新しく作成されたSQLiteの方につなぎ直してみると、ついにお客さんが元々使っていたIDとパスワードでログインすることができました。2015年も三分の二が終わろうとしていますが、古いMovableTypeの問題を解決する仕事をしたことにもびっくりですが、この問題を解決する方法を検索していて、参考サイトのリンク切れが多発していて調査がうまく進まなかったことにも驚きました。昔の技術系ブログの情報は日々失われているのでしょう。自動アップデートが普通になってしまった昨今、古い情報は必要性が薄れているのかもしれませんが、こんなときのために残っていてくれると助かりますね。

2015/8/1

悲しいことに夏の暑さに我が家のNASがやられてしまいました。

壊れたのはIO DATAのHDL2-Aシリーズという個人向けのNASでHDDが2台内蔵されているという商品でした。ファイルを操作している途中、突然アクセスが不能となりました。ネットワーク->コンピューターからは共有フォルダのトップディレクトリ(トップフォルダ?)までは覗けるようですが、その下の階層につなごうとするとエラーが出るという状況。なお、ブラウザ越しに管理画面にはつながるので、完全に壊れたというわけではなさそうでした。管理画面を見る限りHDD1もHDD2も生きてはいる様子。ただ、NASの残り容量は表示できない状態で、RAIDという欄に「崩壊」の二文字が。

こういった事態に備えてバックアップを定期的にとってはいるのですが、最後に取ったバックアップは一月以上前なので、その間のデータはもしかしたら消えてしまうかもしれないというピンチです。Google先生に「RAIDの崩壊」について尋ねまくる苦行が始まりました。

このNASは出荷状態ではRAID 0(ストライピング)の設定になっているとのことですが、RAID 1(ミラーリング)にもできるとのことです。データの保全を考えればRAID 1にするはずですが、購入時の私は「バックアップとるし大丈夫だろ」ぐらいな気持ちでRAID 0のまま利用を開始したみたいです。過去の自分のバカ!容量2倍で不安も2倍です。

RAID 0はHDDをWindows機に1台ずつ普通につなげただけでは正しく認識されないらしいのでなんとかする必要があります。それ以前にNASから取り出したHDDをマウントする機械がありません。というわけで、まず、AmazonさんでHDDを2台USB接続できるとかいう機械を購入します。なお、NASからHDDを取り外すのはとても簡単でした。ドライバー要らずです。さすがによく考えて作られていますね。そして、Windows機にHDDを二台接続するとPCのドライブが一気に10個増えました。パーティションが切られているのと同じような状況ですね。もちろん、それらのドライブの中身はよくわからないことになっていました。というか、「余計な操作はするな」というのがRAIDのHDDからデータを復旧するときの鉄則だとどこかで読んだので、興味はありましたが、あんまい深入りしませんでした。知らずに勝手な操作をすると、大事なデータを破壊してしまい、業者に頼んでもお手上げになってしまうとか書いてありましたのでね。なお、業者に復旧を頼むと10万円以上確実にかかりそうで、さらに詐欺まがいの業者がデータを人質にふっかけてくるという記事をいくつもみてしまったので、見積もりを取ってもらうことすらしませんでした。突然のNASの崩壊に何も信じられない疑心暗鬼状態でした。

続きまして、RAIDの中身を取り出す復元ソフトとして「復旧天使」というのがよくレビューに上がっているようですので、こちらを試してみました。お試し版で事前に中身にアクセスできるかどうかわかるので、無駄にお金を払う必要もありませんでした。なお、ファイルシステムに応じて機能を分割して販売している廉価版があるのでそちらのRAID対応バージョンを購入しました。ファイルシステムはXFSでした。

結果、無事データのサルベージが済みました。たまたま2TBのHDDが余っていたのでそちらにデータを移しました。2TBほぼ使い切るぐらいのデータの移動はとても時間がかかりました。それで、100個くらいのファイルが最終的に読みだせないとのことでした。これはバックアップデータから復元できそうなので、ほぼ損失はゼロです。

データをさらったので、HDDを再びNASの筐体に戻して、HDDを初期化して再び使えるようにしようとしたところ・・・結果は「フォーマットに失敗しました」とのこと。意味が分からないので今後はRAIDの再構築みたいなコマンドを実行しました。・・・NASが赤いランプを点滅させながら死に絶えました。どうも、このNASは基幹となるプログラムもHDDに一緒に保存するものらしく、そのプログラムごと昇天してしまったという印象です。

再度Amazonさんを呼び出して、後継機を購入し、現在、またサルベージしたデータを戻しているというところです、今現在。一週間くらい何やかんやと気を揉んでいたのでドッと疲れました。あと同じころに自転車がパンクしまして、「なんて日だっ!」ってなりました。そして、パンクしないタイヤと、壊れないHDDを人類は早期に開発しないとならないと思うのでした。

2015/5/21

Twitter APIを叩いて取得したJSONを使ってWEBサイト上にツイートを表示しようとした際に、Display Requirements(表示規則)に従おうとしたら、絵文字や一部の漢字が含まれたツイートの各エンティティにリンクを張ろうとするとリンク位置がずれたので対策したときのメモ。

絵文字や一部の漢字(異体字)ではサロゲートペアという表現を使って表示を制御しているそうなのですが、この場合、一文字が4バイトになってしまい、utf-8のサイト上では二文字として扱われるようです。JavaScriptのString(文字列)クラスのメソッドやプロパティでは意図した文字数で扱えないことになります。

"●野家".length; // >> 4
//●は「吉」の異体字のつもり

Twitter APIでは各エンティティの開始位置と終了位置を文字列内のインデックスの数で指定してくるのですが、このインデックスに従ってリンクを張ると文字数のカウントがずれているので、リンクの位置もずれてしまうのでした。

function strSplit(str,p1,p2) {
var i=0,len=str.length,ret=[],pos=0,sp=0;
if (p1==0) ret.push('');
while (i < len) {
var x = str.charCodeAt(i);
i++;
if (0xD800 <= x && x < 0xDC00) sp++;
if (i-sp==p1 || i-sp==p2) {
ret.push(str.substring(pos,i));
pos = i;
if (i-sp==p2) break;
}
}
ret.push(str.substring(pos));
if (ret.length==2) ret.push('');
return ret;
}

そこで文字列と二つのインデックスを引数に渡すと、インデックス番号の位置で文字列を三つに区切って返す関数を用意してみました。サロゲートペアの数(sp)を数えて正しいインデックス番号の位置を探しています。とりあえず、今のところうまく動いているので様子見中。

2015/5/18

何かに使うかもしれないのでメモ。

chcp 65001

Windowsのcmd.exe(DOSプロンプト)のコードページをutf-8に変更するコマンド。
WEB制作にあたってShift_JISを使用することがほぼなくなってきたので、Windowsはいつかutf-8化するのだろうかと思って調べているうちに見つけたコマンド。

2015/2/17

お客さんから更新作業をcapistranoで自動化したいと相談され、こちらの環境でも対応しようとしたときにつまづいたのでメモ。ネットで資料を集めてインストールしてみたものの、エラーメッセージが出て処理が途中で止まってしまうはめに。なんでも新しいバージョンを入れればいいというものではないらしいです。

まずcapistranoの最新版はバージョン3系ですが、お客さんは2系の運用らしく「Capfile」の書式が違う模様。2系を入れなおすと処理が進みました。

次にgitコマンドでssh先のリモートリポジトリにアクセスする段になってアクセスできないとのアラートが表示されました。接続先のポート番号が標準の22ではないことと、認証に鍵のファイルが必要だったのげ原因でした。config/deploy.rbの中でssh_optionsに指定した値よりも優先して使われる設定があるらしく、ここで設定を変更しても何も変わりませんでした。こちらの環境はWindowsでお客さんの環境がMacだったので、お客さんもはっきりとしたことはわからないとのこと。

C:\Users\(ユーザ名)\.ssh/config

結局↑ここにファイルを作って、ホスト、ユーザー、ポート、鍵の設定を書き加えたらうまくいきました。

gitコマンドはうまく動くようになりましたが、また別のアラートが出るようになりました。(Net::SSH::Exception: Creation of fil
e mapping failed with error: 998)とありましたのでこれを手がかりに調べてみるとrubyのバージョンとcapistranoのバージョンと(gem)net-sshのバージョンがいろいろ複雑に絡み合っているとのことでした。いろいろ試してやっと動いたのが次の組み合わせでした。

  • ruby 2.1.5(x64ではダメだったので、x86)
  • capistrano 2.15.5
  • net-ssh 2.7.0(capistranoと一緒に入った2.9.2ではダメだった)

とりあえず動くようになったのでよかったよかった。

開発日記