ログ日記

作業ログと日記とメモ

G Suite 無償版がサービス終了するのでさくらのメールボックスに乗り換えると同時にさくらにドメイン転入

ついに無料版が終了することになってしまった。
3ドメインほどのアカウントがあって、二つはメールサーバーが他にあるところからの転送なので、無くなっても最悪問題なし。
実質、無くなったら困るものは一つ。

過去のメールを移行すると同時にドメイン管理もさくらに移管する。
バリュードメインドメインを取得してずっとそのままだった。別に悪くないというか安くて必要十分な機能があるんだけど、あちこちログインするのが面倒なので。

バリュードメインでAuthCodeを取得してさくらで転入の手続きをしながら、メールをThunderbirdimapでローカルに保存。
さくらのメールボックスも契約する。

バリュードメインDNSを使っていたので、これはメモで保存しておいて、これも後でさくらにする。


さくらの転入手続きが完了したら、数分とか数十分とか(数日とか?)時間がかかりそうな認証メールを待つ。
バリュードメインDNSがオフになるタイミングからさくらのDNSとメールを設定するまでの時間がダウンタイムになると思う。

DNSはeNomだからそのまま使えそうなイメージがあるけど、バリュードメインの方に移転したらDNSサービスは無くなるって書いてあった。


バリュードメインはeNomを使っていてさくらはJPRSらしいから、全然違うのかな?というかJPRSでgTLDが管理できたのか。この辺の知識があやふやというか、.jp を個人が簡単に登録できるようになった頃の知識のままかもしれない。






・・・一週間後。


ドメイン移管の手続きするよ!キャンセルする場合はこのURLにアクセスしてね!

という罠メールをスルーして一週間待つと、無事にさくらにドメインが移管された。
DNSはまだeNom(dns*.name-services.com)を指している。名前解決もできるみたい。
whoisdnsも旧情報のまま。管理者情報はさくらに書き換わっていた。


ひとまずメモっておいた以前のDNS設定をさくらのドメインのゾーンに設定していく。


レンタルサーバー側では、メールアドレスを追加しておく。



そしてwhoisのns情報変更。



whoisコマンドでnsが書き換わったかチェック。digでもチェック。
適当なサーバーからメールを送信して受信チェック。


その後にThunderbirdでアカウントを追加(変更ではなく追加!)
そして旧Gmailアカウントのメールフォルダの中でメッセージを全て選択して、新しい方のアカウントにコピー。
サイト移転に伴うメールの移行(IMAPの場合) | Web Design Leaves

古い方はまだ見れるので一応置いておく。G Suite完全終了まで繋がるのかな?



で、普段使っているGmailでもインポートしておく。
「メッセージと連絡先のインポート」から。
サーバーにメッセージを残すにチェック。(全てチェックした)

そして転送とGmailの「他のメールアドレスを追加」設定。エイリアスはオフ。(エイリアスオンだと相手が返信時にgmailになるらしい)
Gmailで受け取った独自ドメインメールの送信サーバーもskauraに設定する。(こんなのできたんだ?)
メーラーGmailの両方で使ったら送信済みトレイがややこしいことになりそうだけど。




これで、さくらのメールボックスでPCのメールソフトで受信できるようにしつつ、(独自ドメインではない)Gmailにも転送して使えるようになった。旧メールも見れる。

頻繁に使っているGmailをコピーしたら一瞬でさくらの上限を超えてしまうと思うけど、今回の場合は0.1GBしか使ってなかったから全部「すべてのメール」と追加で「重要」「スター付き」を全部コピーした。新アカウントの「[Gmail]」以下にサブフォルダとして入れた。


GmailのPOPでインポートは、裏側で動いているらしい。まだ見れない。



そういえばGmailの+(プラス)でエイリアスを使って登録したサービスとかがあって、それは全部無しに変更した。
これは見落としがあるかもしれない。


# 2/9 追記
インポートが失敗していた。
他のアカウントのメールを確認する - パソコン - Gmail ヘルプ
すぐに別のアカウントを追加したらダメだったのかも。
ここの説明を見ると、内部的にそういう動きになっている気がする。

仕方がないのでThunderbirdimapでコピーした。こっちは動きが把握できるから失敗しない。


# 2/17 追記
別のアカウントを消してからもう一度インポートをしたら成功した。
どうやら、転送よりインポートの方がスパム判定にならなくて使いやすいらしい。
転送だと宛先と受け取りのメールアドレスが異なっているのでスパムになりやすいのだとか。

インポートを実行してもIMAPで手動でコピーしたメールが二重になったりはしていない。

Chrome の拡張機能で Uncaught TypeError: Cannot read properties of null (reading 'removeEventListener') のエラーが出る

Youtube の埋め込みでJavaScriptのエラーが出る。

Uncaught TypeError: Cannot read properties of null (reading 'removeEventListener')
    at YouTubeDelegate.self.unregister_element (<anonymous>:194:37)
    at remove_element (<anonymous>:406:43)
    at MutationObserver.<anonymous> (<anonymous>:428:21)
YouTubeDelegate.self.unregister_element @ 
remove_element @ 
(anonymous) @ 
childList (async)
mp @ www.youtube.com/s/player/0c96dfd3/www-embed-player.vflset/www-embed-player.js:1186
(anonymous) @ www.youtube.com/s/player/0c96dfd3/www-embed-player.vflset/www-embed-player.js:1343
(anonymous) @ www.youtube.com/s/player/0c96dfd3/www-embed-player.vflset/www-embed-player.js:575

Chrome のシークレットモードでは出ないので、何かの拡張が影響している模様。


stackoverflow.com

Ok, for future reference, it was a bug caused by "Disable HTML5 Autoplay" addon in chrome, I've created issue on their github.

なるほど。
Disable HTML5 Autoplay の拡張機能を停止したらエラーが無くなった。

今見ると、大きく

NOTICE
This extension is currently unmaintained.
The former developer will no longer be providing support.
If you would like to know the circumstances or develop this extension, consuit the sidebar.

と書かれていた。
もう必要ないのかな?

github.com
ここを読むと、まだまだ必要っぽい。

HTML5 Autoplay Blocker という拡張もあるけど、利用者数が一桁違うんだよなあ。
ひとまず放置で。

Google Closure Library を使ったJavaScriptをブラウザ無しでテストする

試行錯誤して長くかかったのでメモ。


まず、Closure Library は最初の頃はJSのファイルを羅列したhtmlを読み込んでテストする方式だったと思う。
JsUnit がその形だったかな?
CIとかが手軽に出来なかった頃はそれでも問題なかった。今ではテストのハードルがぐっと上がるので、ブラウザを自分で開いて確認するのはよろしくない。

jsunit test report not showing tests · Issue #869 · google/closure-library · GitHub

昔から使っていた人も他のツールに移っていっている模様。



今では(というか数年前?)ブラウザをコマンドで立ち上げてブラウザ機能を使いつつ、コンソールに結果を表示するという方法が取られるようだ。
blockly/run_mocha_tests_in_browser.js at master · google/blockly · GitHub
Googleのプロジェクトでサンプルを見れる。
このプロジェクトだとES5で書かれているから問題ないようだけど、ES6のmoduleを使うと、file:// で読み込めない問題がある。別途Webサーバーを立ち上げないといけない。
E2Eテストが遅いからJavaScriptだけでテストしたいのに、こんなに色々な準備が必要なら本末転倒である。見た目は綺麗で良い感じなんだけど。


かと言ってシンプルにmocha だけ使っても、documentが無いのでクライアントのテストができない。
Mocha - the fun, simple, flexible JavaScript test framework



MVC的にうまく切り分けられているならModelだけテストできそうだけれども、Closure LibraryはControl系コンポーネント以外はViewもゴチャ混ぜになっている。
そういうわけで色々試した結果、mocha と jsdom を使うことにした。
mochaはテストフレームワーク、jsdomはdomを提供してくれる。
(mocha-jsdomというパッケージもあるが、更新されていないようだった)

npm install --save-dev mocha
npm install --save-dev jsdom


mochaディレクトリを作り、初期化用ファイルを置く。

mkdir mocha
vi mocha/init.js
vi mocha/accordion_test.js


init.js

require('../lib/closure-library/closure/goog/bootstrap/nodejs.js');

// Polyfill for encoding which isn't present globally in jsdom
var util = require('util');
global.TextEncoder = util.TextEncoder;
global.TextDecoder = util.TextDecoder;

goog.nodeGlobalRequire('build/mocha_deps.js');

jsdomに無い関数を割り当てたりしながら、deps.jsも読み込む。
nodeを使いつつモジュール以外のファイルを読み込む場合は goog.nodeGlobalRequire を使うようだ。


mocha_deps.js は依存関係が書かれたファイル。
pathの扱いがややこしく、普段Closure Libraryで使っているものをそのまま使えなかった。base.jsとnodejs.jsはpathが一段深くなるので、deps.jsを生成するときのroot_with_prefixの指定を一段深くする必要があった。
これは別のファイルを生成することに。


mocha_js.sh

#!/bin/bash

set -eux

cd `dirname $0`/../

./lib/closure-library/closure/bin/build/depswriter.py \
    --root_with_prefix="js ../../../../js" \
    > ./build/mocha_deps.js


実際のテストのファイルはこんな感じ。


accordion_test.js

var JSDOM = require('jsdom').JSDOM;
var assert = require('assert');
var FakeTimers = require("@sinonjs/fake-timers");

goog.require('app.anim.Accordion');
var Accordion = goog.module.get('app.anim.Accordion');

goog.require('goog.style');
var clock;

describe('app.anim.Accordion', function() {
  before(function(){
    var dom = new JSDOM(
      '<html><body><form name="form">'
        + '<input type="checkbox" name="check">'
        + '<div id="area" style="display:none">test</div>'
        + '</form></body></html>');
    global.window = dom.window;
    global.document = window.document;

    this.check_ = document.forms.form.elements.check;
    this.area_ = document.getElementById('area');

    clock = FakeTimers.install();

    this.nowOrig_ = goog.now;
    goog.now = (function() {
      return +new Date();
    });
  });
  after(function(){
    this.check_ = null;
    this.area_ = null;

    clock.uninstall();
    goog.now = this.nowOrig_;
  });
  describe('#decorate()', function() {

    it('can decorate Accordion', function() {
      var target = new Accordion(this.check_, 100);
      target.decorate(this.area_);
      assert.equal(target.isInDocument(), true);
    });

    it('should change shown and running animation', function() {
      var target = new Accordion(this.check_, 100);
      target.decorate(this.area_);

      assert.equal(goog.style.isElementShown(this.area_), false, 'element is not shown before starred');
      this.check_.dispatchEvent(new window.Event('change'));

      assert(target.anim_, "exists anim object");
      assert.equal(target.anim_.isPlaying(), true, 'anim is started');
      assert.equal(goog.style.isElementShown(this.area_), true, "element is shown just after clicked");

      clock.tick(20); // start delay

      assert.equal(target.anim_.isPlaying(), true, 'anim is still started');
      assert.equal(goog.style.isElementShown(this.area_), true, "element is shown");

      clock.tick(80);

      assert.equal(target.anim_.isPlaying(), false, 'anim is stopped');
      assert.equal(goog.style.isElementShown(this.area_), true, "element is shown");
    });
  });
});

チェックボックスがオンされるとアコーディオンがアニメーションで開く、というコンポーネントのテスト。
ハマりポイントが結構あった。


最初は init.js でjsdomを読み込んでいたけれど、テストごとに別のhtmlを使うと思ってtest.jsに移動した。逆に言うと、htmlが同じなら*test.jsを同じファイルにまとめられる。


ES6を読み込む場合は goog.require と goog.module.get の両方が必要なことに注意する。


Closure Libraryの時刻系処理は全てgoog.nowを使っていて、それは読み込み時に既にnew Date()が割り当てられているので、goog.nowも置き換える必要がある。めっちゃライブラリのソース読んだ。
domの幅は取れなかった。画面が無いもんね。なのでstyleを確認。


イベントはjsdomで作ったwindowのEventをnewすればOK。




最後に、GitLab用のCIファイルを書く。
.gitlab-ci.yml

mocha_test:
  image: registry.gitlab.example.com/app/nodejs-python:12.0
  stage: test
  before_script:
    - npm install
  script:
    - ./bin/mocha_js.sh
    - ./node_modules/mocha/bin/mocha --file mocha/init.js "mocha/**/*test.js"
  except:
    - schedules

nodejs-python は自分でビルドしてGitLabのレジストリに登録した。


Dockerfile

FROM node:12-buster-slim

RUN apt-get -y update && apt-get -y upgrade && apt-get -y install python

バージョンが古いのは、今使っているdebianに合わせるため。普通にbuster-slimからapt install nodejs でも良かったかも。



キャッシュが無い状態で1分半、キャッシュがあれば53秒だった。
なかなか良い感じではないかな。


これでやっとJavaScriptのテストが書けるという最低限の状態にできた。

Debian の /bin と /usr/bin と debootstrap

https://n314.hatenablog.com/entry/2021/10/07/200305 の続き。



/bin/ping と /usr/bin/ping のバイナリが異なることに気付いた。

/bin/ping ならゲストからでもエラーが出ない。
でもPATHの設定で/usr/bin/ping が優先されるのでエラーが出るようだ。
/usr/bin/ping は getcap で /bin/ping = cap_net_raw+ep が付いていない。更新日も2018年で/bin/pingは2021年だった。


エラーが出ない方のゲストは /usr/bin/ping と /bin/ping が同一で、ホストは /usr/bin/ping が存在していなかった。


UsrMerge - Debian Wiki
debootstrap を実行したタイミングによって異なっている?


iputils-ping を削除すると /bin/ping は削除されるが /usr/bin/ping はそのままのようだ。
これと同じように、openssl系のライブラリもどこかに優先されるPATHで古いバージョンが残っている…?

2021-03-28 のiputils-ping の更新で、 /bin/ping, /usr/bin/ping の両方が更新されているパターンと /bin/ping だけ更新されているパターンがあるっぽい。


これは、もうこの状態になったらどうしようもないのかな。エラーが出るサーバーだけ手動で /etc/ca-certificates.conf を変更していくしかない?

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は問題なし、今月になってから問題になったということは…

www.walbrix.co.jp

もしかしてこれ?
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が成功しない。分からん…。


community.letsencrypt.org

新しい環境でダメな人も居るみたい。


マジで困った。



/etc/ca-certificates.conf の

mozilla/DST_Root_CA_X3.crt

この行の先頭に ! を入れて、update-ca-certificates をすれば取りあえずはしのげる。
でも、この手作業の対応をそれぞれのサーバーでやる…?まったく同じバージョンで問題ないサーバーもあるのに…?
うーん…すっきりしない。

update-ca-certificates --fresh --verbose

でも変わらず、wgetでエラーが出るサーバーとエラーが出ないサーバーがある。