1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

fossil-scmの th1で httpアクセス

Last updated at Posted at 2021-05-05

個人的に文章書いたりソースコード書いたりといった時に fossil-scm を長年使っています。

特徴としてはこんな感じ。

  • Distributed / Centralized どっちも行ける感
  • wiki / Bug Tracking等を内蔵
  • 1ファイル/コマンドで全部入り(コピーすればすぐ使える)
  • repositoryも1ファイルでバックアップ楽ちん

コマンド一発で 各種 Server としても動かせてとても便利なのですが、内蔵している th1スクリプトからの httpアクセス方法については、ドキュメントや実装上の問題等も多いので Webで検索しても成功例がなかなか見つからないと思います。

色々制約はあるのですが、通知目的ぐらいであれば全然出来ないってわけでも無いのでそのやり方について。

なお、CommitやPush時等で Chatbotを実装したいといった場合は Hookを使う方が楽ちんなはず。

th1スクリプトについて

th1は Tclを元にしたミニマルな言語です。

th1のスクリプトはコマンドの羅列。ifも 一つのコマンドです。

コマンドは 改行か ; で終端。

{ } で括られたのはブロックではなく複数行文字列。

言語としての文法らしい文法があまりないのでシンプルですが、Cっぽく見えちゃうあたりが逆に罠な感じに思います。
「なんとなく見ればわかる」気もしますが、一度公式のドキュメント等を参照していただくと良いと思います。

ベースにある tclについては tcl.tkのサイト にあるドキュメント
日本語の解説だと株式会社フリーソフトネットのサイトにある解説が、とても役に立つかと思います。

th1 でサポートしている tclのコマンド及び、th1 独自コマンドは fossil-th1 公式ドキュメント を参照してください。

th1: httpコマンド

httpコマンドは以下の2パターンだけになります。

  • GETなら http -asynchronous -- URL
  • POSTなら http -asynchronous -- URL POSTDATA

公式ドキュメントを見ると POST 時の Content-Typeは text/plain だと書かれているのですが、
正しくは application/x-www-form-urlencoded かと思います(2.15.1時点1) 。

この呼び出しの結果を受け取る方法は現在のところ無い。はず。

th1-uri-regexp 設定

th1 からhttpアクセス可能な URLはなんでもOKというわけではなく、
各レポジトリ/グローバル設定の th1-uri-regexp に 正規表現で許可するURLを設定する必要があります2

この設定は repository毎の local設定で良いと思うので repository を checkoutした フォルダに行ってから、以下のようなコマンドを実行します3

例では DiscordのWebHooks APIに限定して許可するような設定です。

fossil status && fossil set th1-uri-regexp "https://discord.com/api/webhooks/.*"

個人的に使ってるだけなら globalで全部許しちゃうというのもありかと思います。

fossil set th1-uri-regexp "http.*" --global

認証局証明書の設定

fossilは ssl通信に opensslを使っています。
信頼出来るルート証明書について OSが持っている証明書ストアを使わないため、なんとかする必要があります。

Debianや Ubuntu等では sudo apt-get install ca-certificates で行けると思います。
macではやったことないですが(作業不要かな?)、Windowsの場合は以下の二通りのうちどちらかで対応します。

Windows対応その1 ルートCA証明書をインストール

ここは色々問題がある4のですが、公式が配布している x64版 fossil.exe の場合、
C:\Program Files\Common Files\SSL\cert.pemに証明書を置くという方法が取れます。

設定する証明書は、PublicなCAでれば curlが配布している ルートCA一覧を使うと良いでしょう。
ダウンロードした cacert.pemC:\Program Files\Common Files\SSL\cert.pem として保存します。

curlが使える環境であれば 管理者権限で以下のバッチで設定できます。

mkdir "C:\Program Files\Common Files\SSL"
curl -LRs https://curl.se/ca/cacert.pem -o "C:\Program Files\Common Files\SSL\cert.pem"

管理者権限が無く、上記のパスにファイルを置けないという場合、
以下の「その2」の設定を試してみてください。

Windows対応その2 ルートCA証明書のパスを指定する

ssl-ca-location にフルパスで設定を入れれば そのファイルが使われます。

サンプルの設定バッチファイルとしては以下です。

SET "CERTPATH=%LOCALAPPDATA%\fossil_cacert.pem"
curl -LRs https://curl.se/ca/cacert.pem -o "%CERTPATH%"
fossil settings ssl-ca-location "%CERTPATH%" --global

ここでは global設定としていますが、Private CAを利用している等で、CAの証明書を設定したい場合は Repository Localの設定を入れる等すれば良いかと。

設定確認

テストとして以下のコマンドを実行します。

fossil test-th-eval --open-config "http -asynchronous -- https://discord.com/api/webhooks"

何も出なければ 設定はうまくいってると思います。

th1-uri-regexpの設定にしくってる場合は以下のように url not allowed エラーが表示されます。

C:\work\fossil\project>fossil test-th-eval --open-config "http -asynchronous -- https://discord.com/api/webhooks"
TH_ERROR: url not allowed

CA証明書の設定が出来ていないと以下の様に Verify出来ないのでサーバ証明書を受け入れるかどうかを聞いてきます。

C:\work\fossil\project>fossil test-th-eval --open-config "http -asynchronous -- https://discord.com/api/webhooks"
Unable to verify SSL cert from discord.com
  subject: C = US, ST = CA, L = San Francisco, O = "Cloudflare, Inc.", CN = sni.cloudflaressl.com
  issuer:  C = US, O = "Cloudflare, Inc.", CN = Cloudflare Inc ECC CA-3
  sha256:  8a50f2ecf6273f9416179361a05abe5fe2c6b9acb227efee8eebc511f902972a
accept this cert and continue (y/N)? N
TH_ERROR: SSL cert declined

なお、ここで受け入れをして y を答えるとSSL証明書確認の例外として保存する事も出来ます。

accept this cert and continue (y/N)? y
remember this exception (y/N)? y

この受け入れ情報が保存されるのは repository localではなく、global設定("%LOCALAPPDATA%\_fossil") のDBなので、ここらへん理解した上で実行する必要があるかと思います。

また、fossil uiで開くWeb UIでも th1スクリプトを入力する事が出来る(http://localhost:8080/admin_th1 等)のですが、設定をしくじっていた場合、Webページが戻ってこない事がある5のでコマンドラインでやりましょう。

Discordへの Chat送信

試しに Discordの Webhooksに Postしてみます。

まずth1スクリプトファイルを作ります。WEBHOOK.ID と WEBHOOK.TOKEN は自分で取得して設定してください。

discord-post.th
http -asynchronous -- {https://discord.com/api/webhooks/WEBHOOK.ID/WEBHOOK.TOKEN} {content=Hello%20from%20Fossil-SCM}

コマンドで投入

fossil test-th-source --open-config discord-post.th

こんな感じで postできれば 確認完了です。

image.png

まとめ

  • 認証局の証明書の設定を忘れずに。特にWindows
  • デフォルトではhttpアクセスはすべてのURLについて禁止されているので、許可するURLを設定
  • POSTする Content-Typeは application/x-www-form-urlencoded
  1. it will be interpreted as text/plain and the POST method will be used

  2. これくらいはhttpコマンドのドキュメントに書いておいても良いと思うのですが……。設定値のドキュメントには記載があります。

  3. Fossilの管理下にないFolderで実行すると Global設定になってしまいます。fossil statusを仕込んでいるのはfoolproofです。

  4. X509_STORE_set_default_pathsで設定しているので、hardcoded default paths で設定されます。opensslが dllリンクだと環境依存のため不定としか言えない気がしますが、公式のfossil.exeは static linkのため、2.15.1 でのデフォルトは この記事に書いたパスです。C:\Program Files\Common Files\SSL\certs\* のディレクトリ指定もあるはずです。ただ、私が試す限りこちらは効いてないようでした。原因までは探っていません。

  5. 多分SSL証明書のConfirmationで止まってるような気がしています……。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?