意外と読めない人には読めないらしい

最近はもっぱらアプリはDockerコンテナで展開してしまい、さくっとECSに任せてしまうのがあまりに楽すぎて、真面目にアプリを入れろとか言われると如実に嫌な顔をするようになってしまいました。

アレは楽でいいものです。沙耶です。

ただし、やっぱりどうやってもそのアプリを最低一回は環境構築含め、自力インストールしておくべきだ、というのが沙耶の考えではあります。

そのうえで、dockerfileもentrypointも何をしているのかきちんと読んだうえでやるべきだ。

Vagrantfileもそうだけど、こういう箱もの全部セットアップ処理は、必ずすべて読んだうえで実行すべきだと沙耶は思います。
もう少しすれば、読まなくてもよい、といえるとは思うのですが、まだプロプライエタリ的に仕様がこうである、と言ってしまえるほどは成熟していないので。

 

結果として、これらをがりごり読むために必要になるのが、
・JSON/YAMLくらい見て分かれ
・ShellScriptくらい読めるだろ
・Ansibleくらいは楽なんだからわかるだろ
・sed/awk/正規表現はマスターしてるよね?
とかのこの辺のテクニックになってくるわけです。

ところが、意外とこれができない。いや、できない理由ははっきりしています。別にスキルが足りない、とかそういうことじゃない。いや、スキルが足りないから読めないのは間違いないんだけど、要求スキルが低いかっていうと実はそうじゃない。

特にShellScript。Dockerfile記述は別に大したことをやらせないことが多いのでまあ良い。
たまにEntrypointじゃなくてDockerfileで曲芸やってるコンテナに出会うけど、レアケースで、基本的にはここにガリゴリ書いていることは少ない。

ガリゴリ書かれるのはEntrypointの方である。Entrtypointのシェルが単独ならまだしも、沙耶の作るコンテナとかはあっちこっちにsourceで読みに行って取り込んだり取り込まなかったり判断分岐してたりする。

別にDockerfileに書いたっていいんだけど、RUNの下に何十行と&& \でつなぐことになりかねない。なので結局手早くできるEntrypointに逃げるのだ。まあどっちにしろビルドしなきゃいけないめんどくささはあるんだけど。

可読性? 知るかボケ。

こんなアホが基本作ってると思っていい。そのシェルだって、シェルスクリプトは基本コマンドラインの集まりだ。結果として、自分がよく使うオプションやテクニックの濫用になるに決まっているのだ。アレにコーディング規約なんて求めるだけ無駄である。

結果。

 

スパゲッティどころではない難読コードが出来上がる(ことがある)。

特にシェルは自由度が高い。そして、シェルによってはさまざまな記法が入り乱れる。perl由来っぽい省略記法や、testのオプションとその出力、[と[[の違いとか、tcsh風の書き方とbash風ってだけでまた違う。そもそも#!/bin/shでsh準拠で書いたらそこまで難読には本来ならないはずなんだけど、それでもアホみたいな書き方をすることはある。

そして書くやつはそれを把握したうえで書いてるんだが、正直所詮シェルだし。とか思ってるのでろくなコメントも書かないし、パイプが5段くらいつながっててもああ普通だね。とか思ってる。

ああ、だって沙耶だって思うもん。

パイプが3段4段くらいならまあ普通だよ。普通じゃない理由にもなんないよ。だってインフラの連中はそのパイプ接続、障害真っ最中とか攻撃真っ最中とかにホスト上でリアルタイムに組んで実行するんだもの。そんなの当たり前だし、シェル上で普通にループと条件分岐を書いたコードをそのままプロンプト上にいきなり書き始める人種だもの。

なにもおかしくない。何も間違ってない。

そのノリがそのまま持ち込まれるのが、インフラ屋の書くコードになる。つまりそれは複雑怪奇で難解でそもそも可読性って何ですか知らない子ですね。とかいう人たちのコードである。それはもう読みにくくて、随所にいらん要素のエッセンスが詰まっている。しかも、その多くは普段使わないようなコマンドをふんだんに盛り込んでいる。

シェルスクリプトは単純なものならば、シェル上の実行コードを並べるだけでよい。

が、彼らはそれを”スクリプト”というコードに落とし込むときに余計なエッセンスを加える。沙耶だって加える。それは、全体を一発コピペすれば済むようにしたいとか、条件分岐とループまとめとくか、なんてのをいかに短くコンパクトでタイプ数少なく実現するかとか、そういういらん要素のエッセンスを加える。

それはある種の習性なのかもしれない。別にもう4KB以内でコードをまとめないといけません、とかのメモリ制約なんかないんだが、コードは短ければ短い方が美しい。とか思ってる。いや、思うwwww

とんでもなく短いシェルワンライナーなんて見て感動する。たぶん共感するのはインフラ屋だけなのだが。

つまり、アレを積極的に読みたいと思うのはたぶんインフラ屋気質なのだ。アプリ屋ではない。アプリ屋的に美しいコードではないのだ、あれは。アプリ屋にDockerイイヨ。って言っても反応が微妙なのはそういうことなのだ。
※単にデプロイサイクルがめんどくさくなる、とかその他の要因も大きいです。

Dockerを使う場合、おそらく正しいのは

・アプリのデプロイはインフラ屋が行う

なんじゃないかと最近思う。あそこのキチガイ領域をお気軽にアプリの人にやっといて。とか言いたくないし言えない。そんな無駄テクニックを身に着けるのも時間の無駄である。
だってアプリの人の書くシェルスクリプトって、無駄にキレイなんですよ。まあ引数がサニタイズされてなかったりなんやかんやあったりするけど、それでもコード自体はとてもすっきりしてて読みやすい。

対して自分はといえば、サブシェルは濫用する、sedとawkがダンスして、正規表現はメタ文字やエスケープ文字が連打され、無駄にあちこちのコマンドには各種オプションが動的にぶち込まれるような仕掛けになっているうえ、あちこちで変数と環境変数が入り混じり、最終的にどーせ全部exportしてねぇのは消えるだろ的ノリでごっちゃごちゃにしている。

汚い。

とても汚いし読みにくい。

だが自分的にはそれほど違和感はないのだ。

だって普段からそれをコンソールでリアルタイムに叩いているのだ。
ヘタすればコンソールからそのままfunctionから書き始めることさえあるのだから。

アプリ屋とインフラ屋、使うツールは似ているし、完全な隣接領域なんだけど、やっぱりいろいろ違うんだよなぁとしみじみ思う。

なので、割とアプリ屋さんの作ったDockerコンテナと、インフラ屋の作ったDockerコンテナは、一見してわかりやすい。
読んでてわかりやすいのはアプリ屋のモノだ。Redmineとかとてもすっきりしてる。hadoopのコンテナも、ブツが巨大なわりにすっきりだ。まあもちろんDockerにどこまで可変性を持たせるのか、とかそのへんも絡むんだけど。

基本公式のDockerコンテナはそこまでひどくはないんだが、Automatic Buildを銘打ってるアプリとドッキングしたコンテナの中には、たまにそういうのが混ざる。公式にもごくまれに居たりはするけど。

Readme.md見て、すごく大量の環境変数があったら少し警戒する方がいいんじゃないかしらwwwwww
※モノによってはそもそもdockerfileをjinja2で書いてるとかそんなものもある

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です