はじめに
タイトルの通り、シェルスクリプトを AIX でテストするために IBM Cloud に登録しました。説明するまでもないかもしれませんが、AIX は IBM が開発した System V 系の商用 Unix の一つで 1986 年からの非常に長い歴史がある OS です。そして最新の UNIX の標準規格である SUSv4 (Single UNIX Specification Version 4) と 最新の POSIX(POSIX.1-2008 の修正版である POSIX.1-2017)に準拠していると公表されている唯一の UNIX です(参照)。今回はその AIX 7.2 / 7.3 でシェルスクリプトをテストするために IBM Cloud に登録したという話です。
補足: Solaris 11.4 もSUSv4 に準拠していましたが Unix の認証の 2019 年に有効期限切れとなり更新していないため、事実上 SUSv4 準拠といえますが UNIX を名乗ることができません。ちなみに macOS が準拠しているのは一つ前の SUSv3(POSIX.1-2001 相当)です。
私は IBM Cloud に詳しくないので、この記事を参考にする人は書いてあることを鵜呑みにせず、自分で調べて自己責任で作業するようにお願いします。
なぜ IBM Cloud に登録したの?
IBM Cloud がおそらく個人で簡単に格安で AIX を使うための唯一の方法だからです(知る人ぞ知る「polarhome」はサービスを終了しました)。私はシェルスクリプト用の高機能なユニットテスト・フレームワークである ShellSpec を開発しています。少々長い期間開発を中断していたのですが最近開発を再開しました。ShellSpec はすべての POSIX シェルに対応することを目標(ほぼ実現)としており、bash だけでなく ksh や zsh、FreeBSD sh や Busybox ash などにも対応しています。ShellSpec 自身のテストも ShellSpec 自身で行われており、Linux に関しては CI と Docker を利用してかなり古いバージョンのシェルでテストを行っています。例えば bash は(実用は推奨しませんが)2.03 以上で動作することを確認しています。このテストを AIX でも行うために IBM Cloud に登録しました。
現在サポートが継続されている AIX 7.2 / 7.3 では ksh88 (/bin/sh
) を POSIX シェルとして使用しており ksh93 もインストールされています。本来の ksh88 は POSIX に準拠していませんが AIX が修正しているようです。AIX には bash もインストールされていましたが現在の最新版である 5.2 だったので、OS 組み込みではなくパッケージ(?)で追加インストールされているのでしょう。AIX 7.2 / 7.3 の ksh の具体的なバージョンは以下のとおりです。
# oslevel
7.2.0.0
# oslevel -s
7200-05-07-2346
# sh
# set -o vi
Version M-11/16/88f ← ESC, CTRL+V を押すと表示される
# ksh93 -c 'echo $KSH_VERSION'
Version M 93t+
# oslevel
7.3.0.0
# oslevel -s
7300-02-01-2346
# sh
# set -o vi
Version M-11/16/88f ← ESC, CTRL+V を押すと表示される
# ksh93 -c 'echo $KSH_VERSION'
Version AM 93u+ 2012-08-01
AIX 7.2 / 7.3 ともに ksh88 は 88f ですが、ksh93 は 93t+ と 93u+ と細かい違いがあります。ShellSpec は Solaris 10 の ksh88 (Version M-11/16/88i) と Debian 5.0 上の ksh93 (93s+)で動作確認ができており、88i よりも古い 88f はともかく、93s+ よりも新しい 93t+ なら動きそうなものですが、残念ながら AIX ユーザーからの報告で ksh88 でも ksh93 でも動作していないことが発覚してしまいました。
これまで古い環境のテストは Docker 上の Debian(debian/eol に 1999 年の 2.1 から用意されてある)で行っていたのですが、改めて見ると Debian は ksh 93t+ を標準で採用したことがないようでテストが抜けていました。ksh93 は 2005 年の ksh93q からオープンソースとなっており Red Hat Linux などでは 93t+ の採用例があるようですが、残念ながら Docker コンテナが用意されていないので少々面倒です。それにそもそも ksh93 はクローズドソース時代に各環境で個別のパッチが当てられたりしているため、Linux 上の ksh 93t+ で動作したからと言って AIX 上の ksh 93t+ で動作する保証はありません。確実に動作保証をするには AIX 上でテストする他に方法はありません。IBM Cloud 上で格安でテストできそうだなというのは以前から気づいていたのですが、慣れないクラウドだとクラウド破産が怖いので登録を躊躇しており、まあ動くやろで誤魔化していましたがはっきりと動かないという報告が来てしまったのでしょうがありません。
(´・ω・`)
仮想マシン(Power Virtual Server)の構築
今回私が欲しいのはクラウドサービスではなく、シェルスクリプトを動かすためのただ仮想マシンです。しかしそれがどれなのかさっぱりわかりませんでした。調べて Power Virtual Server (Power VS) だろうというのはわかったのですが一体それはどれなんだ?という状態です。IBM Cloud で AIX 環境を作る方法については以下のサイトに情報があります。
-
【てくさぽBLOG】IBM Power Virtual ServerでAIX環境を作ってみた
- 2021年05月の情報なので少し古い
-
【てくさぽBLOG】IBM Power Virtual ServerのAIX環境とIBM Cloud Object Storageを接続してみた(Part1)
- 2023年03月の情報でスクリーンショットなどはこちらを参照すると良い
自分で作業を終えて改めて上記を読むとちゃんと手順が書いてあることが分かるのですが、ハマりポイントは 「Power Virtual Server」が「Workspace for Power Virtual Server」に名前が変わっていることです。Power Virtual Server で仮想マシンが作れそうだとわかっても該当する項目が見つからず、似たような名前のサービスが複数あるため、名前が変わっただけなのかサービスが終了したのか、設定画面は IBM Cloud に登録してログインしないと見えないため、どれが正しいのかよくわかりませんでした。
アカウント作成
仮想マシンを作るための「Workspace for Power Virtual Server」へは以下のカタログ(「Power」の検索結果)からアクセスすることができます。
「Workspace for Power Virtual Server」をクリックすると(ログインしていなければ)ログイン画面が表示されます。アカウントを持っていなければアカウントを作成します。クレジットカードが必要ですがアカウントの作成自体はもちろん無料です。Power Virtual Server 自体に無料枠はないようですが(私が登録した時は)最初に 30 日間使用できる 200 ドル分のクレジットが貰えたので、それを使って有料のサービスを試すことができます。
ワークスペースの作成
ログインしたらまず最初に無料のワークスペースを作成する必要があります。以下(IBM Cloud より引用)に書いてあるとおり仮想マシンなどはすべて作成したワークスペースの中に作成するようです。
ワークスペースは、コンピュート・リソース、ネットワーキング・リソース、ストレージ・リソースなど、特定のリージョンにあるすべてのPower Virtual Serverリソースのフォルダーとして機能する無料の作業環境です。
私はワークスペースを「東京 04」リージョンで作成しました。リージョンによってコストが変わったりするのかはよくわかりません。
SSH鍵の登録
省略することも可能ですが、ssh ログインが楽になるので最初に登録しておいたほうが良いでしょう。
仮想サーバー・インスタンスの作成
仮想マシンは正確には「仮想サーバー・インスタンス」と呼ばれているようです。長いのでこの記事では仮想マシンと呼びます。ワークスペースを開いたら仮想マシンの管理画面になります。後はそう迷うことなく作成することができると思います。右側に作成する仮想マシンのコストが表示され、いくらかかるのかすぐに分かるので安心です。私は次のような設定で仮想マシンを作成しました。よくわからない用語の項目はデフォルトで進めています。
- 一般
- インスタンス名: 適当な名前
- インスタンスの数: 1
- サーバー配置グループに追加: なし
- 共用プロセッサー・プールに追加: なし
- 仮想サーバーのピン留め: なし
- SSH 鍵: 作成したSSH鍵の名前
- ブート・イメージ
- オペレーティング・システム: AIX
- (補足: Linux や IBM i も選択可能)
- Epic ワークロードの構成: なし
- イメージ: 7200-05-07 or 7300-02-01
- (補足: AIX のバージョン 7.2 or 7.3)
- 層: 層 3 (3 IOPs / GB)
- (補足: 一番安い項目)
- ストレージ・プール: プールの自動選択
- オペレーティング・システム: AIX
- プロファイル
- マシン・タイプ: s922
- (補足: e980 も選べるが s922 の方が安い)
- コア・タイプ: 上限なし共有
- (補足: 一番安い項目)
- コア: 0.25
- (補足: 設定可能な最小のコア数)
- メモリー(GiB): 2
- (補足: 設定可能な最小のメモリサイズ)
- マシン・タイプ: s922
- ストレージ・ボリューム
- 追加のボリュームなし
- ネットワーク・インターフェース
- パブリック・ネットワーク: 有効に変更
- (補足: 有効にしないと外部からアクセスできないよね?)
- パブリック・ネットワーク: 有効に変更
このような設定で 0.08ドル/時間(59.29ドル/月)でした。今日のレートでおよそ1時間12.5円ですね。1ヶ月連続で使えば月1万円ぐらいになりますが、テストとバグ修正で時々使うだけなので十分安いです。課金の単位はよくわかっていないのですが検索すると「分単位」という言葉が見つかるようです。もしかしたら Power Virtual Server も分単位なのでしょうか? テスト目的で使用する場合、起動して少し調べて停止することになるので、分単位の課金だと嬉しいですね。
仮想サーバー・インスタンスへの接続
仮想マシンを作成したらグローバル IP アドレスが割り当てられるので、SSH 鍵を登録していれば ssh で外部から簡単に接続することができます。接続した後は普通の Unix と同じです。AIX 環境はインターネットへのアクセスができますが、どのコマンドを使ってファイルをダウンロードすればいいのかとかわからないので、scp コマンドでローカルのファイルをアップロードしています。gunzip
コマンドや tar
コマンドは普通に使うことができます。パッケージの追加方法などはそのうち調べます。
仮想サーバー・インスタンスの削除
作業が終わったら仮想マシンを削除します。これはメニューから簡単に削除することができます。
課金金額と使用量の確認
いちばん重要な項目です。これは管理画面の上の方にある「管理」の中の「請求および使用量」から確認することができます。ここから何にいくら使ったかを調べることができます。金額は数分程度(?)で反映されるようですが、クラウド破産してしまわないように慣れないうちは定期的に確認して請求金額が増えていないか確認したほうが良いでしょう。「使用料の通知」の設定もしておくと安全です。
ちなみに私の今回の課金金額は 0.15ドルだったので 2 時間程度作業をしたようです。使用量の詳細を確認した所、以下のような感じで課金されていました。
メトリック | 単位 | 数量 | コスト |
---|---|---|---|
Scale Out Shared Virtual Processor Core-Hours |
Scale Out Shared Virtual Processor Core-Hour |
0.5 | $0.07 |
RAM Gigabyte-Hours | RAM Gigabyte-Hour | 4 | $0.05 |
AIX Scale Out License/Core-Hours | AIX Scale Out License/Core-Hour | 0.5 | $0.02 |
HDD Storage Gigabyte-Hours | HDD Storage Gigabyte-Hour | 40 | $0.01 |
「プロモーションとクレジット」を見ると、ちゃんと 200 ドルのクレジット残量から使用されていることがわかりました。残り 199.85 ドルですが、私がやることはそんなにないので 1ヶ月で使い切ることないんだろうなーと考えています。1 年ぐらい有効期限があればいいのに。
作業を終えて
ShellSpec の AIX 7.2 対応(ksh93t+ 対応)は 2 時間程度と短い時間で終わりましたが、実はからくりがあって古いバージョンの OpenIndiana が ksh93t+ を使用していたので、それを使って事前に修正は完了していたからです。ただしその修正が AIX でも通用するかはわからないため、実際の環境でテストしたという流れです。ちなみに ShellSpec が動作しなかった原因は ksh93t+ のバグです。ksh93 では特定の条件を満たしている場合にサブシェルも別プロセスを生成しない「仮想サブシェル」が使われるのですが、この機能にはいくつものバグ潜んでおり、それが原因でエラーになっていました。対応には特定の場合に仮想サブシェルが使われないように ulimit
を使用したワークアラウンドを追加しただけです。詳細は以下を参照してください。
NONFORKSUBSH: as a performance optimisation, subshells are implemented without forking a new process, so they share a PID with the main shell. (AT&T ksh93; it has many bugs related to this, but there's a nice workaround:
ulimit -t unlimited
forces a subshell to fork, making those bugs disappear! See also BUG_FNSUBSH.)
ShellSpec を AIX 7.2 / 7.3 の /bin/sh (Version M-11/16/88f) に対応するのは(今のところ?)断念しました。AIX は /bin/sh
(ksh88f) が POSIX に準拠していると主張していますが、簡単な検証を行った所、どうも errexit
周りのバグが有るようで、ShellSpec が本来終了しないはずの場所で終了してしまいます。回避方法は見つかりそうではあるのですが、影響範囲が広そうであちこちを修正せねばならず、今後の開発で毎回 IBM Cloud を使ってテストを行わなければいけなくなるので大変過ぎます。基本的にシステムの標準的な環境で ShellSpec が使えれば OK という考えなので、標準インストールされている ksh93 で使えれば問題ないでしょう。古いシェル(88f はおそらく 1995 年ぐらいに作られたシェル)はいい加減使用するのをやめるべきです。ちなみに Solaris 10 の ksh (ksh88i) であれば ShellSpec は動作します。ksh88 で修正されたバグ の中に原因があるのかもしれません。
もう一つ小さな問題点として AIX 7.3 の ksh93u+ では [ -e /dev/存在しないファイル名 ]
が常に真となるバグが有るようです。そのせいで ShellSpec 自身のテストが失敗していましたが、そもそもそのような名前のファイルを使ってテストするのがそもそも問題だったので修正しています。
さいごに
シェルスクリプトは環境依存の問題が大きく本当に大変だと思います。簡単なシェルスクリプトでは問題なく動くのでしょうが、バグがないソフトウェアはありません。POSIX に準拠していると主張していたとしてもシェルにもしっかりバグはあるので、実際の環境でテストしなければ動作保証はできません。もちろんこの話はシェルスクリプトに限らず他のプログラミング言語のプログラムっでも同じです。この記事はシェルスクリプトのテストの話ですが、単に AIX の仮想マシンを作ったと言うだけなので他の言語でも使えるはずです。以上 IBM Cloud を使えば AIX で開発したプログラムのテストができるという情報でした。
補足ですが、GitLab が AIX のサポートを検討しているっぽい情報を見つけました(参考)。4 年前からこの状況みたいなのですぐに対応されるとは思いませんが、AIX 環境でのテストが CI でできたら嬉しいですね。あとは HP-UX のテスト環境があれば良いのですが、標準サポートの終了が来年ですし、こっちはもういいかなーって思っています。HP-UX が POSIX に準拠してるのなら動くのでは? ちなみに ShellSpec は VM Actions を使用することで BSD系 Unix (FreeBSD、NetBSD、OpenBSD、DragonFlyBSD) と Solaris 11 の CI テストが完了しています。もちろん Windows や macOS でも CI テストを行っています。そして手動のテストですが今回 AIX にも公式に対応することができました。もう少し残っているバグを修正したら ShellSpec 0.29 をリリースする予定です。