Category tech.

手元の NanoPi NEO2 が、証明書エラーでどうしても https 通信が不可能に。

Ubuntu 16.04 なのでそれほど古いOSというわけではない。証明書関係だろうと思いいろいろやってみたがうまくいかず、これは他の原因ではないか?と思って date したら 2016 年だった。知らないうちにリブートして、RTC を持たないため時刻設定がまきもどったようだ。

$ sudo apt-get install  ca-certificates
$ sudo update-ca-certificates  -v
$ curl https://google.com                                                                                                             
curl: (60) server certificate verification failed. CAfile: ./cacert.pem CRLfile: none
More details here: http://curl.haxx.se/docs/sslcerts.html

curl performs SSL certificate verification by default, using a "bundle"
 of Certificate Authority (CA) public keys (CA certs). If the default
 bundle file isn't adequate, you can specify an alternate file
 using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
 the bundle, the certificate verification probably failed due to a
 problem with the certificate (it might be expired, or the name might
 not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
 the -k (or --insecure) option.

今後こういうことが起きないよう ntpd を入れた

sudo apt-get install ntp
  1. トップ
  2. tech
  3. https 通信が不可能な原因が時刻ずれ

Google Photos が発狂してからと書いてから、いろいろ見積って画像をセルフホストすることに決めた。とにかくアップロード機能はあとで作るとして、現状の画像が表示されていない状態を是正しなければならない。つまり Google Photos に上がっている画像のうち、日記で使われている画像をこのホスト上にコピーして配信する必要がある。

事前知識

まず Google Picker API 経由で取得した media の id や URL と、Google Photos API は一切互換性がない。もともと念のために Picker 経由で取得した ID っぽいものは保存していたのだけれど、これはまったく使えない。よって、Google Photos 上の全写真のメタデータをすべて取得し、ファイル名マッチによって画像を特定 (つまりファイル名→Google Photos mediaId のマッピング) していくことにした。

手順

  • Google Photos 側のメタデータをすべて保存する
  • 日記内の画像のファイル名をすべて抜き出す
  • Google Photos 側のファイル名と日記内の画像のファイル名を一致させて対応づけ、Google Photos 側の mediaId を確定する
  • 利用している画像を、対応づけた mediaId に基いてダウンロードする
  • 日記内の画像パスをすべて書きかえる

Photos library API は 10000req/day が quota。0.1req/sec 程度でしかアクセスできない。そのうえ、item リスト API は 100items/req しか取得できない。つまり、1日で取得可能な item 数は100万件にすぎない。が、個人日記程度なら十分なので、一気に全メタデータを取得するスクリプトを書いて、1行に1つの mediaItem 形式のJSONとなるようなファイルをつくった。

実際にメディアを取得するリクエストは 75000req/day できるが、library API で取得できる、メディア実体を取得するための URL である baseUrl は60分で期限切れになる。全メタデータを取得したときの baseUrl は基本的に使えないため、ダウンロードするスクリプトではあらためて batchGet API を呼び、baseUrl を取得するようにした。

ハマったところ

日本語文字列のファイル名が Google Photos 上では分解されて正規化された状態だったり、API 経由ではそうでなかったりで困った。結局 NFC して常に正規化状態で扱うようにした。

ハマったということではないが、Google Photos の library API 類はレスポンスが結構遅く、オンデマンドにこれにアクセスして実体ファイルへリダイレクトするのは結構厳しいと思った。

今後

画像まわりを好きにできるようになったので、できれば webp メインにしたい。ただ、ファイル管理やバックアップまわりでやることが増えるので、面倒くさい。

それにしてもウェブサービスのAPIを組合せて Web 2.0 の時代はどこへやらで、かつてAPIを提供して好きにしてくれとしていたサービスもどんどん渋くなり、サービス存続が信用できないケースが多くなって全部自分でホストするみたいな原点回帰をしつつある。

ASP のブログサービスを使えばそのへんの面倒くさい実装は自分でやらなくてすむが、じゃあそのASPのサービスはいつまで続くのか?という話になるし、貧乏はとにかくつらい。

  1. トップ
  2. tech
  3. Google Photos 依存からの脱却

さくらのVPS ディスク拡張手順(標準OS Ubuntu18.04) を実行しようと思ってごにょごにょしていたら MBR を壊してしまった。具体的には

sudo sgdisk -s /dev/vda

が成功せず、GPT 形式に変換しろ、と言われたので何も考えず GPT に変換したら Booting from hard disk で止まるようになってしまった。まぁそりゃそうだろ考えろよという感じだが……

シングルユーザーモードの起動

さくらのVPSコンソールから「各種設定」→「OSインストール」とすすみ、「カスタムOS」→「Ubuntu 18.04 amd64」と選択して起動 (仮想 CD 経由でインストーラーが起動する)

ただVNCコンソールを開けるタイミングでは既にブートローダーを通過しているので、レスキューモードに入れなかった。

このため、インストーラー起動後のユーザー名を入力する画面で、何もせず「Back」を選択する。するとインストーラーメニューが出てくるので、一度 Detect disks を選んですぐに Back してから、シェルを起動するメニューを選ぶ (Detect disks することで /dev/vda が見えるようになる)。

この状態で、以下のように本来のディスクをマウントして chroot する。さくらの VPS の VNC コンソールは英語キーボードだと = が入力できないため、grub-install の引数を指定することができない。デフォルトでいけるようにするために chroot する。

mount /dev/vda1 /mnt
mount --rbind /dev /mnt/dev
mount -t proc none /mnt/proc
mount --rbind /sys /mnt/sys
chroot /mnt /bin/bash

これでほぼ本来の環境で作業できる。grub を再インストールする、念のため /boot をバックアップしてからやる。ここでは /dev/vda なので

cp -r /boot /boot.orig
grub-install --force /dev/vda

とした。GPT だからか何なのか --force しないと書けなかった。この手順は自信がない

grub 設定を作りなおす

update-grub

ここで reboot で起動するようになった

  1. トップ
  2. tech
  3. さくらのVPSが起動しなくなって grub 再インストール