2021-10-01 に Let's Encrypt の SSLでエラーが出る模様
systemd-nspawn ゲストの一般ユーザーでネットが繋がらない。
何もしてないのに壊れた。
$ git remote show origin fatal: unable to access 'https://example.com/app/app.git/': server certificate verification failed. CAfile: none CRLfile: none
$ ping localhost ping: socket: 許可されていない操作です $ LANG=C ping localhost ping: socket: Operation not permitted
検索するとSSL系の設定やsuidの記事が出てくるが、違う感じがする。pingは元々 /usr/ping は u+s ではない。
libcap2-bin 系も違う。別の環境ではgetcapの結果は同じなのに使えたりするので。
ログにも異常は見つけられず。
pingはrootだと問題なさそうなので、権限系っぽいが…。
ホストごと再起動してみるも直らず。
opensslは自動アップグレードがかかっているけど、それだとpingは関係ないよねえ…。
systemdのセキュリティ更新は二ヶ月以上前で、その後は問題なかった。
pingが問題ないマシンもあるので、違いを見てみる。
grep Cap /proc/$$/status の結果や getcap /bin/ping の結果は同じ。
$ grep Cap /proc/$$/status CapInh: 0000000000000000 CapPrm: 0000000000000000 CapEff: 0000000000000000 CapBnd: 00000000fdecbfff CapAmb: 0000000000000000 # getcap /bin/ping /bin/ping = cap_net_raw+ep
他にも試す。
export GIT_SSL_NO_VERIFY=1
あれ?これでいけた。
もしかして最初からpingは使えなかった?
うーん…。でもopensslの更新も二ヶ月前だった。なんで?
9/27は問題なし、今月になってから問題になったということは…
もしかしてこれ?
wgetはダメだった。curlはいける。
git は rootでもダメだった。
openssl が 1.1 なので完全にスルーしてた。ホストもゲストも同じバージョンなのにゲストだけエラーが出る。何かパッケージが足りないのだろうか?
/usr/share/ca-certificates/ にも違いが無い。
update-ca-certificates をやっても変わらない。
/etc/ssl/certs/ca-certificates.crt もエラーが無いゲストとエラーがあるゲストで同じだった。…うーん。
www.mail-archive.com
stackoverflow.com
最悪ローカルのcrtを何とかすればいいっぽいけど…。普通にパッケージ更新していれば大丈夫だとか、update-ca-certificatesでうまくいくって書いてあるよね。
openssl s_client -CApath /etc/ssl/certs -showcerts -connect lists.debian.org:443 < /dev/null
openssl のコマンドでは成功するけど、wgetが成功しない。分からん…。
新しい環境でダメな人も居るみたい。
マジで困った。
/etc/ca-certificates.conf の
mozilla/DST_Root_CA_X3.crt
この行の先頭に ! を入れて、update-ca-certificates をすれば取りあえずはしのげる。
でも、この手作業の対応をそれぞれのサーバーでやる…?まったく同じバージョンで問題ないサーバーもあるのに…?
うーん…すっきりしない。
update-ca-certificates --fresh --verbose
でも変わらず、wgetでエラーが出るサーバーとエラーが出ないサーバーがある。
muttを設定する
ちょっとミーハーな心持ちで、以前挫折したCLIのメーラーをインストールしてみる。
一応
GnuPG を使えるメーラーを探す - ログ日記
の続き。
大量のメールを処理できるNeomutt - Solist Work Blog
ここを読んでNeomuttが気になったけど
NeomuttでGmailにOAuth2.0する - Qiita
Debian(buster) の場合はMuttよりNeomuttの方が古いっぽいので。
bullseye なら大丈夫っぽい。
muttをインストールすると
/usr/share/doc/mutt/examples/mutt_oauth2.py
があるので、どこかのbinにコピーしてくる。
python のファイルの上の方に registrations 変数があって接続情報が書かれているので、直接編集。
ENCRYPTION_PIPE にもGPGで使っているメールアドレスを書く。
/usr/share/doc/mutt/examples/mutt_oauth2.py.README を読みつつ
Mutt - ArchWiki
ここも読みながら muttrc を設定する。
先にGoogleのAPIでoauthのIDを発行しておく。テスト用でいけた。
とりあえず接続テストは
./bin/mutt_oauth2.py user@example.com.tokens --verbose --authorize
のようにして質問に答えていってから
./bin/mutt_oauth2.py user@example.com.tokens --verbose --test
で確認。
muttrcでのGmailの設定は
set from="user@example.com" set realname="User Name" set imap_user="user@example.com" set folder="imaps://imap.gmail.com/" set smtp_url="smtps://${imap_user}@smtp.gmail.com:587/" set imap_authenticators="oauthbearer:xoauth2" set imap_oauth_refresh_command="/home/user/bin/mutt_oauth2.py /home/user/.mutt/${imap_user}.tokens" set smtp_authenticators=${imap_authenticators} set smtp_oauth_refresh_command=${imap_oauth_refresh_command}
このように書いた。
あとは設定を適当なサンプルから持ってきた。
set spoolfile = "+INBOX" set imap_check_subscribed set hostname = gmail.com set mail_check = 120 set timeout = 300 set imap_keepalive = 300 set postponed = "+[GMail]/Drafts" set record = "+[GMail]/Sent Mail" set trash = "+[GMail]/Trash" set header_cache=~/.mutt/cache/headers set message_cachedir=~/.mutt/cache/bodies set certificate_file=~/.mutt/certificates set signature =~/.mutt/signature
Gmailを見れるようにはなった。
でも、使えるかと言われると…うーん。
初めてvimを起動して終了方法すら分からなかったときような感じ。
Claws MailじゃなくてSylpheedを試してみようか。
DebianでVMwareが遅い問題は解決してなかった
https://n314.hatenablog.com/entry/2021/01/28/104312
こっちの設定をやってしばらく使ってるけど、やっぱりVMwareの起動直後はkcompactd0がフルにCPUを使って3分ぐらいほとんど操作できない。
/sys/kernel/mm/transparent_hugepage/defrag の設定は madvise にしていた。これってアプリケーションが必要だからデフラグを要求してるってことだよねえ…。
VMware用にメモリを12GB設定しているから、その分のデフラグは必要だってことなんだろうか。
固まるのは起動時だけで、最初にちょっと待てば後は大丈夫なんだけど。
PHPStanとPsalmを混ぜた機能が欲しい
PHPStanはテンプレート+callableのネストに対応していた。
<?php /** * @template A * @template B * @template X * @param callable(A,B):X $f * @return callable(A):(callable(B):X) */ function f2(callable $f) { return function($a) use ($f){ return function ($b) use ($f, $a){ return $f($a, $b); }; }; } /** * @template A * @template B * @template C * @template X * @param callable(A,B,C):X $f * @return callable(A):(callable(B):(callable(C):X)) */ function f3(callable $f) { return function($a) use ($f){ return function($b) use ($f, $a){ return function($c) use ($f, $a, $b){ return $f($a, $b, $c); }; }; }; } function str_repeat_split(string $s, int $time, string $separator):string { $arr = []; for ($i = 0; $i < $time; $i++){ $arr[] = $s; } return implode($separator, $arr); } function test(): string { $f = f3('str_repeat_split'); $g = $f('abc'); $h = $g(1); // $h(1); $h("\n"); $i = f2('str_repeat'); //$j = $i('abc')('def'); $j = $i('abc')(2); $k = f2('str_repeat')('abc'); //$l = $k('def'); $l = $k(2); // $m = f2('str_repeat')('abc')('foo'); $n = f2('str_repeat')('abc')(2); return nl2br($n); }
コメントを外すと正しいエラーが報告される。
ここで、括弧がちょっとめんどいので
<?php $n = f2('str_repeat')('abc')(2); $n = f2('str_repeat', 'abc', 2);
引数と関数呼び出しの区別を無くして、並べて呼び出せるようにしたい。
機能だけなら
github.com
昔作ったんだけど、型チェックが効かない。
PsalmのConditional return typesの機能を使ってfunc_num_argsで戻り値の型を条件分岐させたい。
でもPsalmは
* @return callable(A):(callable(B):(callable(C):X))
みたいな複雑な型に対応してないっぽい。
github.com
PHPStanにもconditional return typesの機能を付ける話は出ているみたい。
That's what this open feature request asks for, it's on my roadmap to implement this.
issue登録者が間違ってクローズしたものを作者が再オープンしていたので、しばらく待てば実装されるんだろうか。
もうすぐ1年経ってしまうけれども。
haskell-language-server の設定2
https://n314.hatenablog.com/entry/2021/07/24/173834 の続き。
「emacs lsp-mode "disconnected"」で検索した https://github.com/emacs-lsp/lsp-mode/issues/905 ここのコメントに M-x lsp してログを見ろと書いていたので、そのようにする。
lsp-haskell stack "Cradle requires ghc but couldn't find it"
という警告が出ていた。
というかそもそもEmacs起動時に
Server lsp-haskell:27768/starting exited with status exit(check corresponding stderr buffer for details). Do you want to restart it? (y or n)
というエラーも出ていた。
検索して出てきた
haskell-language-server+emacsでのハマりどころ2020年夏
このページを見てもよく分からなかったけど、そういえば hie.yaml が必要だったとどこかに書いていた記憶がある。
手動で作ってうまくいかなくて消したんだった。
hie.yamlでもう一度調べる。
(廃止) VS Code と haskell-ide-engine で Haskell 開発環境を構築する
Haskell環境構築2020簡易版 (macOS, Linux向け) - LugendrePublic
stack install implicit-hie gen-hie > hie.yaml
そして stackプロジェクトのMain.hsを起動。
emacs app/Main.hs &
おおお、いけたじゃん!
あとは修正と設定。
Error running timer ‘lsp--on-idle’: (wrong-type-argument integerp 9.223372036854776e+18)
というエラーが出るのを回避する。
https://github.com/emacs-lsp/lsp-mode/issues/2435
(setq lsp-headerline-breadcrumb-enable nil)
Error while checking syntax automatically: (error "Keyword argument :end-line not one of (:buffer :checker :filename :line :column :message :level :id :group)")
というエラーが出るのでflycheckをバージョンアップ。
型を自動で挿入したいので
(defun lsp-haskell-execute-code-action-add-signature () "Execute code action of add signature. Add the type signature that GHC infers to the function located below the point." (interactive) (let ((action (seq-find (lambda (e) (string-prefix-p "add signature" (lsp:code-action-title e))) (lsp-code-actions-at-point)))) (if action (lsp-execute-code-action action) (message "I can't find add signature action for this point"))))https://www.ncaq.net/2021/06/25/18/20/30/
これを何かのキーに割り当てる。
オプションで
{-# OPTIONS_GHC -Wmissing-signatures #-}
を設定してwarningが出るようにしておく必要があるっぽい。
あとは定義ジャンプ。
Emacs で Language Server Protocol を使ってみる :: プログラマになりたい人生 — プログラマになりたいおじさんの日記
右に色々出たりコードに線が出るけど、まだあまり意味が分かっていない。
Fold とか Unfold は何なんだろう…?IDEで関数を閉じたりする?haskell-modeでは使わない?
Use pointとかreduceとかは押したら文字が削られる…。
How do you use (un)folding? · Issue #418 · haskell/haskell-language-server · GitHub
よく分からん…。
他にも、haskellではなくてlsp-modeのreadmeを見た方がいいかも。
7/31 追記:
Main.hs is not part of any project. Select action: i==>Import project root path/to/project/ I==>Import project by selecting root directory interactively. d==>Do not ask again for the current project by adding /path/to/project to lsp-session-folders-blacklist D==>Do not ask again for the current project by selecting ignore path interactively. n==>Do nothing: ask again when opening other files from the current project.
というメッセージがミニバッファに出る場合は i を押す。
一瞬で消えたりするので、他のキーを触らずに i を押す。M-x lsp でもう一度見れる。
もしかして以前やったときはこのメッセージを見逃していたのかもしれない。
あと、他のファイルに飛べない?
xref-find-definitions で Main.hs から Lib.hs に飛べない。
と思ったけど、Lib.hs と同じ階層にFoo.hsを作ったらそこには飛べる。
stack new したプロジェクトの構成が分かってないのが問題か…。
Haskellのstackによるプロジェクトについて - Qiita
コメントも参考になる。
Stackでやる最速Haskell Hello world! (GHCのインストール付き!) - Qiita
チュートリアル。
Emacsのplantuml-modeのpreviewで日本語が文字化け
別のPCで設定したらPlantUMLのプレビューで日本語が出なくなっていて、放置していた。
コマンドなら問題なかったので、Emacsがどういうコマンドオプションで呼び出しているのかをシェルスクリプトでprint debugして調べて、手動で実行してみる。
cat foo.plantuml | /path/to/bin/plantuml -headless -tsvg -p > foo.svg
svgに問題はなかった。
でもこのsvgをEmacsで開くと文字化けする。
Emacsのimage-modeの設定?
昔の環境だとsvgではなくpngでプレビューしてたのかな。
どこかに設定があるはずだと思って設定方法を探す。
GitHub - skuro/plantuml-mode: A major mode for editing PlantUML sources in Emacs
よく分からんかったのでplantuml-mode.el のソースを見て調べた。
(setq plantuml-output-type "png")
これでプレビューの日本語が出るようになった。
関数型プログラミングの考え方を理解するための昔の記事
この前
関数型プログラミングはまずは純粋関数型言語を用いて、考え方から理解しよう
関数型プログラミングはまず考え方から理解しよう - Qiita
ここを読んだ。
関数型プログラミングの考えを学ぶには、純粋関数型言語で学ぶべきである
これは同意なんだけど、サンプルコードがしっくり来ない。
こんなに複雑になる?というかオブジェクト指向のコードを関数型っぽく変換ということに無理があるような。
仕様を満たすコードをゼロから考えたら、全然変わってくるような。
ということでちょっとHaskellで書いてみた。
data Dish = Karaage deriving Eq data Bento = Bento Dish Int deriving Eq
単純な数値のリストかタプルでもいいんだけど、オブジェクト指向に寄せてデータ構造を書く。
eat :: Bento -> Bento eat (Bento s a) = Bento s (a - 1) replaceList :: Bento -> [Bento] -> [Bento] replaceList m a = replace a where replace [] = [] replace (x:xs) | m == x = eat x:xs | otherwise = x:replace xs
「データを1減らす」という処理と「リストを一つ入れ替える」という処理を書く。
「リストから最大のものを1件探す」という処理は maximumが使えるので、そのまま使う。
それからユーティリティ的な関数、「xに関数fをn回適用した結果を返す」を作る。
nest :: (a -> a) -> a -> Int -> a nest f x n = (iterate f x) !! n
最後に
bentoList :: [Bento] bentoList = [Bento Karaage 10, Bento Karaage 8, Bento Karaage 6] main :: IO () main = putStrLn $ show $ nest (maximum >>= replaceList) bentoList 5
一気に関数を接続して、計算。
※ n回繰り返したときの処理ログが欲しいわけではなく、最後の結果が欲しいということだと読み取ったので、途中経過は出力しない。
関数型プログラミングっていうかHaskell独自のことかもしれないけど、とりあえず細かい関数のパーツを作っておいて、繋ぎ合わせて大きな機能を作るのが関数型プログラミングの考え方っぽいと思える。
昔見たブログのやり取りはとても良かった。
Haskell でグローバル変数が欲しい理由 - あどけない話
グローバル変数が欲しい理由? (http://web.archive.org/web/20100702191552/http://www.sampou.org/cgi-bin/haskell.cgi?%A5%B0%A5%ED%A1%BC%A5%D0%A5%EB%CA%D1%BF%F4%A4%AC%CD%DF%A4%B7%A4%A4%CD%FD%CD%B3%A1%A9 )
「グローバル変数が欲しい理由?」の考察 - あどけない話
URLが変わっちゃったので再度メモ。
以下全体のコード。
module Main where data Dish = Karaage deriving Eq data Bento = Bento Dish Int deriving Eq instance Show Dish where show Karaage = "唐揚げ" instance Show Bento where show (Bento a b) = show a ++ show b ++ "個" instance Ord Bento where compare (Bento Karaage a) (Bento Karaage a') = compare a a' nest :: (a -> a) -> a -> Int -> a nest f x n = (iterate f x) !! n eat :: Bento -> Bento eat (Bento s a) = Bento s (a - 1) replaceList :: Bento -> [Bento] -> [Bento] replaceList m a = replace a where replace [] = [] replace (x:xs) | m == x = eat x:xs | otherwise = x:replace xs bentoList :: [Bento] bentoList = [Bento Karaage 10, Bento Karaage 8, Bento Karaage 6] main :: IO () main = putStrLn $ show $ nest (maximum >>= replaceList) bentoList 5