SVX日記
2021-08-06(Fri) 生誕50周年記念のパックマン🍒🍓🍊🍊🍎🍎🍈🍈🔰🔰🔔🔔🔑🔑🔑🔑🔑🔑…
しかしな、最後に「橙色のプ(以下略)」が揃わないことには台無し……と言いかけた瞬間に「橙色のプ(以下略)」が発掘された。パーフェクト。パーフェクトだウォルター。どのモンスターも、キャラに見合った、正しい表情、正しい両手の付き方をしている。ちゃんとシルクや金型を作り分けていることに感謝すら覚えるわ。
んが、ここはシークレットとして「紫色のスー」が用意されていたりしないのか、と思ったが、それは最初からないようであった。まぁ、それはパックランド規格だからな。初代規格には入れないのが正しいことに違いない。
2021-08-12(Thu) dockerでcronを使わずに周期実行
諸君、私はdockerが好きだ。諸君、私はdockerが好きだ。諸君、私はdockerが大好きだ。KubernetesやOpenShiftも便利には違いないが、個人で使うにはアレは重すぎるものだ。では、どんなコンテナ管理を望むか? よろしい、ならばdocker-composeだ。
自分は長らく自宅サーバを運用しているが、過去記事によれば立ち上げたのは2002年の4月頃らしいから、もうすぐ20年というところ。当然、何度もサーバの移行を繰り返してきたが、この作業が面倒で仕方なかった。
昔はPCのアプリの導入も「実行ファイルをコピーするだけ」だったが、いつのまにか「インストーラ」なるものを使うのが普通になった。まぁ、構成ファイルが一定数以上になれば仕方ないのだが、それは「システムに永続的な変更をもたらすにも関わらず、何をしでかすかを知りえないプログラム」であるから、いまだ実行するには抵抗がある。
Linuxの場合、RPMを使う限り安心して導入できるが、データや設定の引き継ぎや、バージョンで仕様に差異があるなど、どうしても細々とした作業が必要となってしまう。長らくどうにかならないものかと思っていたが、ある日、そんな解決方法があったのかと目からウロコが落ちた。それがdockerだ。
データや設定を分離し、OS環境とアプリと構築手順をまとめてカートリッジ化してしまう。一度、そうしてしまえば、docker/docker-composeが使える環境でありさえすれば、どのカートリッジだろうが、ほぼ共通の僅かなコマンドだけでサービスが起動できてしまう。想像もできなかった解決方法だ。しかし、欲しかったのはまさにこれなのだ。
そして、意外と楽しいのが、Dockerfileとdocker-compose.ymlを書く作業だ。できるだけ無駄なく、美しく、構築手順を詰めていく。つまり、最低限のコマンド以外の全てを削ぎ落として箱詰めしてカートリッジ化する……おやおや、おやおやおやおや、なんと……なんと素晴らしい……。
# Dockerfile 中の設定スクリプトを抽出するスクリプトを出力、実行
COPY Dockerfile .
RUN echo $'\
cat Dockerfile | sed -n \'/^##__BEGIN0/,/^##__END0/p\' | sed \'s/^#//\' > startup.sh\n\
' > extract.sh && bash extract.sh
# docker-compose up の最後に実行される設定スクリプト
##__BEGIN0__startup.sh__
#
# # easy cron
# now=`date +%s`
# target0=$((now - now % ${CYCLE0:=86400} + ${SCHED0:=$(( 5 * 60 + 4 * 3600 - 32400))})) # day
# while [ $target0 -lt $now ]; do
# ((target0 += CYCLE0))
# done
# target1=$((now - now % ${CYCLE1:=604800} + ${SCHED1:=$(( 5 * 60 + 2 * 3600 + 0 * 86400 - 378000))})) # week
# while [ $target1 -lt $now ]; do
# ((target1 += CYCLE1))
# done
# target2=$((now - now % ${CYCLE2:=2419200} + ${SCHED2:=$(( 5 * 60 + 3 * 3600 + 0 * 86400 - 378000))})) # 4weeks
# while [ $target2 -lt $now ]; do
# ((target2 += CYCLE2))
# done
#
# s=S
# while true; do
# pgrep -f httpd > /dev/null
# if [ $? -ne 0 ]; then
# echo "`date`: ${s}tart httpd."
# /usr/sbin/httpd
# fi
# s=Res
#
# # easy cron
# if [ `date +%s` -ge $target0 ]; then
# ((target0 += CYCLE0))
# echo "`date`: Job easy cron 0 started."
# (cd /var/lib/pv/hyperestraier; find documents/ -type f -name "*.$FILE_TYPE" | estcmd gather -cl $GATHER_OPTS -cm casket - | grep -v ' passed ')
# fi
# if [ `date +%s` -ge $target1 ]; then
# ((target1 += CYCLE1))
# echo "`date`: Job easy cron 1 started."
# (cd /var/lib/pv/hyperestraier; estcmd purge -cl casket | grep -v ' passed')
# fi
# if [ `date +%s` -ge $target2 ]; then
# ((target2 += CYCLE2))
# echo "`date`: Job easy cron 2 started."
# (cd /var/lib/pv/hyperestraier; estcmd optimize casket)
# fi
# sleep 5
# done
#
## target0=$((now - now % ${CYCLE0:=3600} + ${SCHED0:=$(( 0 * 60))})) # hour
## target0=$((now - now % ${CYCLE0:=86400} + ${SCHED0:=$(( 0 * 60 + 0 * 3600 - 32400))})) # day
## target0=$((now - now % ${CYCLE0:=604800} + ${SCHED0:=$(( 0 * 60 + 0 * 3600 + 0 * 86400 - 378000))})) # week
## target0=$((now - now % ${CYCLE0:=2419200} + ${SCHED0:=$(( 0 * 60 + 0 * 3600 + 0 * 86400 - 378000))})) # 4weeks
#
##__END0__startup.sh__
ENTRYPOINT ["bash", "startup.sh"]
2021-08-14(Sat) イヤホン「EARNiNE EN120」半殺し
思い返せば、衝撃的だった2019年7月の購入から2年と1ヶ月。よく持った方ではないかと思う。なにせ稼働時間がモノスゴイ。それなりに大事に扱っていたとはいえ、通勤、ランニング、寝ホンと、ほぼ毎日のように使い続けていたのだから。
2021-08-16(Mon) anacronの挙動の細かすぎるところを伝えたい
これまで「かなり奇妙な挙動をするらしい」というだけの認識だったが、いざ知ってみれば、やっぱりかなり奇妙だった。詳細は「細かすぎて伝わらないanacronの挙動」という文書にあって、ものすごく参考になったのだが、やっぱり細かすぎて伝わりにくい……ので、ちょっと図化してみた。
まず、前提はこの「/etc/anacrontab」内の設定。着目点は「RANDOM_DELAY」の「45」と「START_HOURS_RANGE」の「3-22」と「delay in minutes」の「25」だ。
# the maximal random delay added to the base delay of the jobs
RANDOM_DELAY=45
# the jobs will be started during the following hours only
START_HOURS_RANGE=3-22
#period in days delay in minutes job-identifier command
7 25 cron.weekly nice run-parts /etc/cron.weekly
2:00 2:30 3:00 3:30 4:00
|---------+---------+---------+---------+---------+---------|---------+---------+---------+---------+---------+---------+---------+----
2:01 anacron 起動
0 + 25 = 25 ----------> 2:26 (開始せず, RANGE 外)
:
33 + 25 = 58 -------------------------------------------> 2:59 (開始せず, RANGE 外)
34 + 25 = 59 --------------------------------------------> 3:00 (開始)
:
45 + 25 = 70--------------------------------------------------------> 3:11 (開始)
^^ ^^ 3:01 anacron 起動
| +-- delay in minutes 0 + 25 = 25 ----------> 3:26 (開始)
+-- RANDOM_DELAY :
45 + 25 = 70 -------------------------------------------------------> 4:11 (開始)
|---------+---------+---------+---------+---------+---------|---------+---------+---------+---------+---------+---------+---------+----
2:00 2:30 3:00 3:30 4:00
開始する可能性のある範囲....................................oooooooooooo..............oooooooooooooooooooooooooooooooooooooooooooooo...
3:00〜3:11 (2:01の回の anacron で起動された場合)、または
3:32〜4:11 (3:01の回の anacron で起動された場合)
3:00〜3:11 (2:01の回の anacron で起動された場合)、または
3:26〜4:11 (3:01の回の anacron で起動された場合)
xxx nn 02:01:01 xxxxxxx anacron[nnnnn]: Will run job `cron.weekly' in 59 min.
xxx nn 03:00:01 xxxxxxx anacron[nnnnn]: Job `cron.weekly' started
xxx nn 02:01:01 xxxxxxx anacron[nnnnn]: Will run job `cron.weekly' in 70 min.
xxx nn 03:11:01 xxxxxxx anacron[nnnnn]: Job `cron.weekly' started
xxx nn 03:01:01 xxxxxxx anacron[nnnnn]: Will run job `cron.weekly' in 25 min.
xxx nn 03:26:01 xxxxxxx anacron[nnnnn]: Job `cron.weekly' started
xxx nn 03:01:01 xxxxxxx anacron[nnnnn]: Will run job `cron.weekly' in 70 min.
xxx nn 04:11:01 xxxxxxx anacron[nnnnn]: Job `cron.weekly' started
2021-08-19(Thu) アクセラワイパー交換
車検の直前ではあるが、車検の直前にワイパーの拭きが悪くなり、車検の直前に雨模様の中をやや遠出する予定があるので、車検の直前にワイパーのゴムだけを交換した。まぁ、車検時に交換されるより、自分で交換作業をしたかったし、そっちのが安く済むというのもあるのだが。