- curlは古い環境でも継続してビルド・テストできるように変更を制限しており、最近のプルリクエストでも 32ビット
time_t とレガシープラットフォームとの互換性を壊さない条件を求めていた
- 重要なのは多数のプラットフォーム一覧を維持することではなく、ユーザーがアップグレードしても動作が維持されるという ABI/API安定性 の約束を守ることにある
- 特定のオペレーティングシステムのユーザー数よりも、実際に面倒を見て修正する人がいるかどうかのほうが重要であり、保守担当者が残っていれば ユーザーが少ないプラットフォーム も引き続きサポートできる
- curlとlibcurlは、オペレーティングシステム、CPUアーキテクチャ、特殊な構成全般で「ビルドされて実行できる」状態を保つ 移植性重視の原則 によって広がってきた
- 古いcurlコマンドが失敗する主な理由は、curl自体の変化よりも ホスト名やURLの消滅、そしてHTTPからHTTPSへの移行といったインターネット環境の変化に近い
レガシープラットフォームを壊さない変更基準
- 最近のcurlのプルリクエストでは、変更内容がレガシープラットフォームでのビルドやテストを壊さない形でなければgitコードリポジトリにマージできなかった
- 該当の変更は
time_t 関連の領域で、curlはすでに 32ビット time_t 型をサポートしているため、その動作を維持する必要があった
- 32ビット
time_t はすでに用途が限られており、2038年 が近づくにつれてさらに制約が強まる可能性はあるが、多くのレガシープラットフォームは依然として32ビット版のままである
- このような要求はコントリビューターの作業をより難しくするが、curlでは変更を完成度の高いものにするプロセスとして扱っている
互換性はプラットフォーム数より大きな約束
- curlプロジェクトは ABIとAPIの安定性 および互換性を維持するために継続的に努力している
- 2000年代半ばのlibcurl利用アプリケーションは、アプリケーションを再コンパイルしなくても最新のlibcurlにアップグレードして同じように動作できる
- 2000年代初頭に書かれたcurlスクリプトも、最新のcurlリリースでほぼ同じように動作すると期待できる
- この互換性は単なる宣伝文句ではなく、curlとlibcurlが提供する中核原則である
- ユーザーはcurlに依存できる
- バグを含むリリースがあったとしても、一般的なソフトウェアアップグレードの苦痛なしに新バージョンへ移行できる更新を提供しようとしている
- すでによく動いているものをわざわざ壊さない姿勢が保守基準に含まれている
サポートの可否を分けるのは保守担当者
- 特定のプラットフォームのユーザー数は、curlがそのプラットフォームを継続サポートするかを決める主な動機ではない
- より重要な基準は、誰が作業を引き受け、実際に必要な保守が行われているかである
- あるプラットフォームでcurlが引き続き動作することを確認するコントリビューターがいれば、ユーザー数が少ないことで知られるプラットフォームでもcurlは動き続けられる
- プラットフォームがcurlから事実上消えるのは、そのプラットフォームに必要なコードがもはや保守されなくなったときである
- 保守されないコードでも何年も動作状態のまま残ることがある
- 特定のプラットフォームでcurlがもう動かないと判明するまでにも長い時間がかかることがある
- 逆にユーザーの多いプラットフォームでも、そのプラットフォーム固有の問題に取り組む意思と知識を持つ保守担当者が不足すれば維持は難しい
多様な環境に広がった理由
- curlとlibcurlは、できるだけ多くの環境で ビルドされて実行されること に強く注力している
- 独特または変わった構成でも動作するよう維持しようとする姿勢が、多くのオペレーティングシステムやCPUアーキテクチャへ広がった理由の一つである
- 多くのユーザーや企業は、古かったりニッチだったりレガシーだったりするプラットフォームを使い続けている
- そうした人々にとって、curlの転送機能を維持するほうが自前の代替実装よりセキュリティ面で優れている場合が多い
- 機能を壊す必要がないのであれば、既存ユーザーがcurlに依存し続けられるようにしておくほうがよいという判断がある
サポート削除は遅く、公開的に進められる
- curlも時には一部のサポートを削除する
- 主な削除対象は、利用が減って消えつつある サードパーティライブラリ のサポートだが、他の領域でもサポート削除は起こりうる
- サポート終了は、ゆっくり、慎重に、公開の場で伝えながら進められる
- 知りたいユーザーが変更を事前に把握できるようにする必要がある
- ユーザーは準備したり、提案が不当だと思えば反対したりできるべきである
- ユーザーが動作の変化を検知できないなら、それは変更されたとは見なさない
- curlはユーザーのために作られており、ユーザーがある動作を引き続き望むなら、その動作は維持されるべきだとしている
古いコマンドが失敗する本当の理由
- インターネットプロトコルやそのバージョンは、時間の経過とともに現れては消えていく
- 2002年に書かれたcurlコマンドラインの多くは、今日そのままでは動作しない可能性がある
- 失敗の理由はcurl自体ではなく、当時使っていた ホスト名やURL がもう機能しないためかもしれない
- 2002年のcurlコマンドが今日そのまま動かない大きな理由の一つは、HTTPからHTTPSへの移行である
- 2002年にTLSまたはSSLを使うサイトがあったとしても、当時は一般的ではなく、そのとき使われていたTLSプロトコルのバージョンは今日では安全でないと見なされる可能性がある
- 最新のTLSライブラリとcurlは、更新されていない古いTLS設定への接続を拒否することがある
- 2002年のcurl実行ファイルを保管していて今日実行したとしても、現代のHTTPSサイトには接続できない可能性がある
- これはcurlの変化ではなく、転送プロトコル層 の変化によるものである
1件のコメント
Hacker Newsのコメント
すごい成果だ。curlは本当にありがたいツールだ。
Danielが32ビットの
time_tを互換性の重要ポイントとして強調していたのが興味深い。多くのOSで動き続けることが目標なら、完全に筋が通っている。ただ、2038年まではもう14年しかなく、curlが最初に登場した時点より今のほうがずっと近い。いつごろになれば32ビット時間をサポートする労力はもう見合わないと判断されるのか気になる。予想ではY2K38の日付を過ぎて3か月後くらい、あるいはもっと長いかもしれない開発者は運用担当に近づくにつれて学ぶことがある。依存する側が増えるほど負担は大きくなる。インフラや中央システムは、十分に多くのものが依存するようになると俊敏さを失い、ちょっとした変更でさえ本当に難しくなる。
バックエンドとフロントエンドを持つ自分のサービスで、その間のAPIを作り直したいなら、誰が気にするだろうか。そのままやればいい。
だが「見た目が悪い」という理由で、基本テンプレートの妙な境界ケースをなくしたいなら、古いサービス20個、人が触りたがらない半分だけ近代化されたサービス20個、さらにそれを使うサービス50個を見る必要がある。その変更がどれだけ大仕事かを把握するために必要な作業だけでそれくらいだ。この段階では、実際の変更実施や難解な秘密のリバースエンジニアリングの話ですらない。
華やかな仕事とは言わないが、誰にも気づかれないように土台を全部入れ替えながら、輝く主役を支え続けることには、ローディーや管理者にとっての誇りがある
一覧には25年以上リリースがないものもかなり含まれている。SCO、Xenix、OS/2、NextStepで、今でも現行ビルドを作っているのだろうか。
こういうものを動かしたことはあるし、そこにcurlがあることも知っているが、私の経験ではそのcurlはいつも少なくとも15年は前のバージョンだった。
あるサポートマトリクスを壊したくないと言いながら、そのマトリクスのかなりの部分が最後のビルドから10年以上たっているなら、本当に壊れていないとどうやって分かるのだろうか。
Xenix向けにビルドできるかは分からない。対象にできる最新のGCCが2.7で、それ自体すでに太古の代物だ。ネットワークコードまで考えるとなおさらだ。たぶん「ある時点ではそれらのシステムで動いていた」くらいの話だろう
「非常に多くのユーザーや企業が古く、ニッチで、レガシーなプラットフォームに固執しており、私たちにできることはない」という話について言えば、たいていの人は独占的クローズドソースの開発者も含め、ライセンスの冒頭に「このプログラムは役に立つことを期待して配布されるが、いかなる保証もなく、商品性や特定目的適合性についての黙示の保証もない」といった文言が入ったソフトウェアを作っている。
それは低コストだ。
一方で私を含む一部の人は、目的適合性が保証され、保証内容が明示的かつ絶対的なソフトウェアを開発している。
それは非常に高価で遅い。
何かが壊れたときに人が死ぬかもしれず、環境が破壊されるかもしれず、何百万ドルもの損害が出るかもしれないなら、30〜40年にわたり非常に遅く慎重な開発者たちが徹底的に検証してきた古くてニッチなプラットフォームを使い続けるのは理にかなっている。
少なくともPowerPC上のINTEGRITYでAdaを見ているときには、自分にそう言い聞かせている
1人の死が数百万ドルの損害につながりうるなら、開発者プールが「ウィルソン病を患うフランス人ジャグラーの数」くらいしかいないソフトウェアやプラットフォームは使わないほうがいい
この人気の理由の一つは寛容なライセンスにある気がする。MITライセンスだろうと思っていたが、少し違うようだ [1]。MITとの主な違いを平易に説明できる人はいるだろうか。著作権ページには詳しい説明がない。
[1] https://curl.se/docs/copyright.html
「この通知に含まれる場合を除き、著作権者の事前の書面による許可なく、著作権者の名前をこのソフトウェアの販売、使用、その他の取引の広告または宣伝に使用してはならない」
[1] https://spdx.org/licenses/curl.html
Linuxのバージョンだけでほぼ100あるのかと思ったが、すべてのLinuxバージョンを1つのOSとして数えてなお100あるのは驚きだ
複数のレガシーシステムを考慮してコードを書くと、個人的な経験ではコードはだいたい良くなる。
命名、型、モジュール化といったよく知られたコーディング慣行により忠実になり、明示された部分を除けば標準準拠も良くなる。抽象化はより堅牢になり、特に現代のプラットフォームでバグが減り、ビルドシステムもより強くなる。将来のプラットフォームとも自動的に互換になるか、少なくとも互換にするのが非常に容易になる。
ただし、少数のレガシーシステムだけを対象にするなら、奇妙な継ぎはぎとハックの組み合わせで何とかなるので、この話は当てはまらないかもしれない
FreeDOS、DR-DOS、MS-DOSを別々のOSとして並べているのは変だ。これらは互いに非常によく似ていて、異なるUnix系とは違い、実質的にABI互換だ
それなのに人々はこれをRustで書き直したがる。RustはあれだけのアーキテクチャやOSを実際に対象にできるのだろうか。
関連する読み物: curlがどのように生まれ、どんな歴史をたどったかについての記事 (1)
(1) https://daniel.haxx.se/blog/2023/03/20/twenty-five-years-of-...