Mastodon on Clear Linux(3)

前回の枕に書いた、国旗。きっと分類してるだろうと思って、暇つぶししてみた。

学術系

国旗の計量的文字論素案

コルモゴロフ複雑性に基づく画像圧縮と分類に関する実験と考察

お楽しみ系

世界の国旗の色彩による分類

「国旗に興奮する」「壁や天井になりたい」 深すぎる女性オタクの世界

国旗のデザインがほぼ同じ国・よく似ている国

うんちく系

世界中の国旗でよく使われている色・レイアウト・デザイン要素がよくわかる「Flag Stories」

こんなのもヒット。 最新図解知的財産権の法律と手続きがわかる事典 そして、 特許・実用新案、意匠、商標の簡易検索に誘導された。

これ面白い、酒の商標を検索したら、64件ヒット。商標とイメージ(ラベル?)が出て来る んだけど、これっぽちしか登録されてないの?

マストドンの中(脳味噌部分)

プラモデルを組み立てるだけじゃ面白くない。やっぱり中がどうなってるか見たいな。 Gemで部品を世界中から調達して、それをRails工場で組み立てているんで、どれかの アッセンブリーを抜き出して、そこに分け入っていけばよいだろう。

で、眼を付けたのが、脳味噌に相当する記憶部分。短期記憶のredisじゃなくて、エピソード記憶と言うか長期記憶を担う、PosgresDBね。

脳味噌とやり取りするには、シナプスじゃなかった、脳幹経由になるのかな。 host側からは、下記コマンドで、ちゃんねるが分かるそうな。

[clr mastodon]$ docker inspect -f "{{ .NetworkSettings.Networks.mastodon_default.IPAddress }}" mastodon_db_1
172.18.0.2

じゃ、中に踏み入ってみます。

[clr mastodon]$ docker exec -it mastodon_db_1 /bin/ash
/ # ps -a
PID   USER     TIME   COMMAND
    1 postgres   0:00 postgres
   18 postgres   0:00 postgres: checkpointer process
   19 postgres   0:00 postgres: writer process
   20 postgres   0:00 postgres: wal writer process
   21 postgres   0:00 postgres: autovacuum launcher process
   22 postgres   0:00 postgres: stats collector process
   23 postgres   0:00 postgres: postgres postgres 172.18.0.4(55646) idle
   24 postgres   0:00 postgres: postgres postgres 172.18.0.6(39826) idle
   25 postgres   0:00 postgres: postgres postgres 172.18.0.6(39842) idle
   26 postgres   0:00 postgres: postgres postgres 172.18.0.6(39840) idle
 2321 postgres   0:00 postgres: postgres postgres 172.18.0.4(55672) idle
 2322 postgres   0:00 postgres: postgres postgres 172.18.0.4(55678) idle
 2325 postgres   0:00 postgres: postgres postgres 172.18.0.4(55684) idle
 2327 postgres   0:00 postgres: postgres postgres 172.18.0.6(39866) idle
 2333 postgres   0:00 postgres: postgres postgres 172.18.0.4(55692) idle
 2363 root       0:00 /bin/ash
 2367 root       0:00 ps -a

並列にデータの出し入れが出来るように、多数のプロセスが動いているんだな。そして、potgresの特徴であるバキュームも動いている。

なんでも、アルツハイマー病になるのは、脳内にゴミが溜まって、活動が低下する事が原因らしい。 posgresもそんな事が怒らないように、定期的にゴミ掃除してるんだな。

昔々、Web掲示板を作ろうとした時、MySQLを使うかPostgesを使うか真剣に悩んだ事がある。 オイラーがチョイスしたのは、MySQLだったんだけど、選択理由の一つに、ゴミ掃除で停止する 必要無しってのがあったな。そんな事で、posgresは全く知らないのさ。(MySQLも今となっては、すっかり忘却の彼方ですけどね)

次は、神経系のオープン状況

/ # ip address
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
321: eth0@if322: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
    link/ether 02:42:ac:12:00:03 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.2/16 scope global eth0
       valid_lft forever preferred_lft forever
/ # netstat -an
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 127.0.0.11:40341        0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:5432            0.0.0.0:*               LISTEN
tcp        0      0 172.18.0.2:5432         172.18.0.4:58514        ESTABLISHED
tcp        0      0 172.18.0.2:5432         172.18.0.5:51036        ESTABLISHED
tcp        0      0 172.18.0.2:5432         172.18.0.5:51032        ESTABLISHED
tcp        0      0 172.18.0.2:5432         172.18.0.4:58498        ESTABLISHED
tcp        0      0 172.18.0.2:5432         172.18.0.5:51000        ESTABLISHED
tcp        0      0 172.18.0.2:5432         172.18.0.4:58472        ESTABLISHED
tcp        0      0 172.18.0.2:5432         172.18.0.5:51034        ESTABLISHED
tcp        0      0 172.18.0.2:5432         172.18.0.4:58492        ESTABLISHED
tcp        0      0 :::5432                 :::*                    LISTEN
udp        0      0 127.0.0.1:46253         127.0.0.1:46253         ESTABLISHED
udp        0      0 127.0.0.11:40540        0.0.0.0:*
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags       Type       State         I-Node Path
unix  2      [ ACC ]     STREAM     LISTENING     180021 /var/run/postgresql/.s.PGSQL.5432

PostgreSQLのお勉強

普通に検索するとWindows用の記事も多数混じってくるんで、CentOSとかで絞り込むと よいかも。

PostgreSQLの使い方

PostgreSQLの使い方メモ

CentOSにPostgreSQL9.5をインストールおよびテスト

PostgreSQL 9.6.1をCentOS 7.2へインストールして初期設定

以上はつまみ食いっぽいんで、きちんとした資料に眼を通す。

PostgreSQL 9.4.5文書

元祖のやつ。生まれがFreeBSDとかの故郷と同じ、バークレーって、初めて知ったよ。 ノルウェー産のMySQLと覇権を競ってきるんだな。富士通あたりも、PostgreSQLの資格試験を 実施してるみたいだから、企業にも認知されるんだ。まあ、ノルウェー産はぼらくるが胴元に なっちゃいましたからねぇ。

ちょいと触りをつかんで、DBの管理者ってのは、通常postgresって名前にするそうだ。 そんなユーザーが居るか確認。変な所が、homeになってて、そこにDBのファイル類とか、 管理情報が置いてあるそうだ。

DBにアクセスするには、DBの管理者に変身してから、psqlって言う対話プログラムを 起動するとな。

/ # grep postg /etc/passwd
postgres:x:70:70::/var/lib/postgresql:/bin/sh
/ # su postgres
~ $ psql
psql (9.6.3)
Type "help" for help.

postgres=# help
You are using psql, the command-line interface to PostgreSQL.
Type:  \copyright for distribution terms
       \h for help with SQL commands
       \? for help with psql commands
       \g or terminate with semicolon to execute query
       \q to quit

データベース名一覧。アカウントとDB名が同じなのは、無用な混乱を避けるため。まあ、データベース名ってのは、そのユーザー専用のdirって事。そしてその中に入れるテーブル各種。 テーブルって平たく言うとエクセルファイルだな。

postgres=# \l
                                 List of databases
   Name    |  Owner   | Encoding |  Collate   |   Ctype    |   Access privileges
-----------+----------+----------+------------+------------+-----------------------
 postgres  | postgres | UTF8     | en_US.utf8 | en_US.utf8 |
 template0 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
           |          |          |            |            | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
           |          |          |            |            | postgres=CTc/postgres
(3 rows)

テーブル一覧

postgres=# \d
                      List of relations
 Schema |             Name             |   Type   |  Owner
--------+------------------------------+----------+----------
 public | account_domain_blocks        | table    | postgres
 public | account_domain_blocks_id_seq | sequence | postgres
 public | accounts                     | table    | postgres
 public | accounts_id_seq              | sequence | postgres
  :
 public | web_settings                 | table    | postgres
 public | web_settings_id_seq          | sequence | postgres
(55 rows)

後は、それぞれのテーブルを見て行けとな。えと、select hoge from table とかが基本系 だったような。データを引っ張り出す時に、filterをかませて絞り込みも出来たな。 その場合は、whereとかで修飾するんだったな。深入りしそうなんで、止めておこう。

それより、 23.1.1. バキューム作業の基本の方が面白そう。

お掃除は、普段のお掃除と年末にやる大掃除が有るとな。ガベコレなんで、マイナーとフルが あるのは頷ける。で、フルはDBを止めてやる。STOP the World ですな。

ノルウェー産とかのDBシステムは、このガベコレをどうやっているんだろう?ゴミが出ない ような設計って出来ないと思うんだけど。レフィレンスカウンター方式で、ごみが出たら その場で回収みたいな事をして、ユーザーには見せない方針なのかな。

表 48-1. システムカタログなんていう資料が有るな。頭にpgが付くテーブルは、ユーザーが変更しちゃ いかんというやつだな。勿論、プロテクトがかかっているだろうけど。

管理者画面のPgHeroを見ていたら、ちょいと設定するだけど、実行したSQLを確認出来るよって 案内が出てた。面白そうなので、野次馬してみる。設定は、

/var/lib/postgresql/data # tail -2 postgresql.conf
shared_preload_libraries = 'pg_stat_statements'
pg_stat_statements.track = all

を追加して、posgresを再起動するだけ。Queriesにと言わせSQLと実行時間が出てくる。 ローカルタイムラインをクリックした時、一番時間がかかったSQLは23ms、内容は

SELECT schemaname AS schema, t.relname AS table, ix.relname AS name, regexp_replace(pg_get_indexdef(i.indexrelid), ?, ?) AS columns, regexp_replace(pg_get_indexdef(i.indexrelid), ?, ?) AS using, indisunique AS unique, indisprimary AS primary, indisvalid AS valid, indexprs::text, indpred::text, pg_get_indexdef(i.indexrelid) AS definition FROM pg_index i INNER JOIN pg_class t ON t.oid = i.indrelid INNER JOIN pg_class ix ON ix.oid = i.indexrelid LEFT JOIN pg_stat_user_indexes ui ON ui.indexrelid = i.indexrelid ORDER BY 1, 2

なんだか、チチンプイプイな呪文だなあ。オイラーがかろうじて分かるのは、下記ぐらいか。

SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2
UPDATE "users" SET "current_sign_in_at" = $1, "last_sign_in_at" = $2, "sign_in_count" = $3, "updated_at" = $4 WHERE "users"."id" = $5

レールの力は偉大なり。SQLを知らなくても、DBを叩けるし、一度SQLした結果はキャッシュして 無駄な問い合わせをしないようにしてるぞ。

puma, Bundler

マストドンで使ってるWebサーバーは、ピューマって言うものらしい。カテゴリーがWebと 分かれば、FreeBSDのports/wwwの部を見るに限る。

rubygemと言う接頭語が付くものが250個を超えてた。Webと一口に言っても、色々な切口が あるだろうけど、激戦地だな。

[fb11: rubygem-puma]$ cat pkg-descr
Puma is a simple, fast, threaded, and highly concurrent HTTP 1.1 server for
Ruby/Rack applications. Puma is intended for use in both development and
production environments. In order to get the best throughput, it is highly
recommended that you use a Ruby implementation with real threads like Rubinius
or JRuby.

WWW: http://puma.io/

で、これが売り言葉。買い言葉で、pypyと喧嘩するんですかねぇ。いや、そうじゃないよ。 これはセールストークよ。眉毛につばをつけて、話半分と思っていれば間違いない。

PUMAへ行ってみた。メモリー使用量少な目、高速に動くって証拠の グラフが掲載されてた。棒グラフのスケールが怪しいなあ。詳細な測定条件が掲載されて いないため、追試が出来ません。これじゃ、言った者勝ちのプレゼン用グラフです。 (と、某教授の突っ込みが有りそうですよ。)

gemを使って直接インストールしてもいいし、bundleって言うアプリを経由して使っても よいとな。

で、ここで出てきたbundleって、rubyに特化したドッカーのように思えるんだけど、どうよ?

Bundlerの使い方

そんな感じで、Rubygemsたちの更新は速いのでGemfileをちゃんと書かないとすぐに
プログラムは動かなくなります。Bundlerを使いましょう

この言葉ってレールに送るものだな。オイラーがレールに触れた時も、参考書通りに 動かず、悩んだものだ。この傾向がgem全体に広がっているんで、その対策なんだな。

まあ、こういう話はrubyに限らず、有名どころの言語では必ず発生する。(例、Haskell) 逆にこういう返礼が無いものは、過疎ってるやつだ。いや、枯れてるって言え。これ仙人 みたいな誉め言葉なんで、そこん所を間違えなき様。

Rubyリファレンス に、レールとかバンドル、 rb環境の説明が公開されてた。

シークレット

マストドンを動かすのにシークレットキーを3個必要としてる。下記のコマンドを3回叩けと 指示されてる。そして、出てきた鍵を順番に、設定ファイルに書く事になってる。 最初、順番通りに書くものと思っていたけど、順番なんてどうでもいいのね。

サイコロを振って、鍵を決め、適当に設定してっていうのが正解。

# PAPERCLIP_SECRET用の鍵を作成(鍵生成1回目)
$ docker-compose run --rm web rake secret

で、その鍵はどうやって作られているのか? そりゃruby特製のMakeを実行してるんだから、 secretってのが、メークのターゲットに相当する。他にどんなターゲットがあるか、簡単に 確認出来るようなんで、やってみた。

[clr mastodon]$ bin/rake -T
/usr/lib64/ruby/2.4.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- bundler/setup (LoadError)
        from /usr/lib64/ruby/2.4.0/rubygems/core_ext/kernel_require.rb:55:in `require'
        from /home/sakae/mastodon/config/boot.rb:3:in `<top (required)>'
        from bin/rake:2:in `require_relative'
        from bin/rake:2:in `<main>'

そして、怒られた。ホスト側は仮の姿なんで、だめなのね。ならば、敵地に乗り込んで行って、 そこで確認したるわい。潜入捜査だな。

[clr mastodon]$ docker exec -it mastodon_web_1 /bin/ash
/mastodon # bin/rake -T
rake about                                       # List versions of all Rai...
rake app:template                                # Applies the template sup...
 :
rake secret                                      # Generate a cryptographic...
rake stats                                       # Report code statistics (...
 :

色々なターゲットが山盛りになってたよ。そのまとめコマンドが有ったので、叩いてびっくら こいてます。

/mastodon # rake stats
+----------------------+--------+--------+---------+---------+-----+-------+
| Name                 |  Lines |    LOC | Classes | Methods | M/C | LOC/M |
+----------------------+--------+--------+---------+---------+-----+-------+
| Controllers          |   2676 |   1977 |      74 |     319 |   4 |     4 |
| Helpers              |    268 |    211 |       0 |      35 |   0 |     4 |
| Models               |   2132 |   1343 |      30 |     181 |   6 |     5 |
| Mailers              |    120 |     92 |       3 |      10 |   3 |     7 |
| Libraries            |    347 |    280 |       2 |       8 |   4 |    33 |
| Tasks                |    260 |    218 |       0 |       0 |   0 |     0 |
| App Libraries        |   1208 |    909 |      17 |      98 |   5 |     7 |
| Presenters           |     32 |     25 |       1 |       5 |   5 |     3 |
| Services             |   2083 |   1510 |      43 |     217 |   5 |     4 |
| Validators           |     55 |     38 |       3 |       7 |   2 |     3 |
| Workers              |    700 |    505 |      30 |      79 |   2 |     4 |
+----------------------+--------+--------+---------+---------+-----+-------+
| Total                |   9881 |   7108 |     203 |     959 |   4 |     5 |
+----------------------+--------+--------+---------+---------+-----+-------+
  Code LOC: 7108     Test LOC: 0     Code to Test Ratio: 1:0.0

大雑把に1万行か。ああ、これはrubyの部ね。この他にnodeの部だとかJavascriptの 部が有るぞ。

トレースと言う期待を持たせるやつが有ったので付けてみた。

/mastodon # bin/rake --trace secret
** Invoke secret (first_time)
** Execute secret
b5f66e261f7c3142af384d91abbb6746f3849c67eae6e17cff5d4a84b3032dfcb8f7f39fafe1e0f40de872eb958d7dd71275510162d69ef06a4a6d915a1eb643

だめじゃん。欲しい情報(どのスクリプトが実行されるか)が出てこない。 苦し紛れにプロファイル取って、どうすると?

/mastodon # ruby -rprofile bin/rake  secret
169e689826f0e62b2178a707a1cae6f2baefa5a3c08fb219f0aeb113087e86842f7d6a245bf5b865
921e50bab5e31312741ad48c0beae024290587f23b963e6e
  %   cumulative   self              self     total
 time   seconds   seconds    calls  ms/call  ms/call  name
 15.71     1.40      1.40     3393     0.41     7.98  Kernel#require
 11.34     2.41      1.01    13476     0.07     0.98  Array#each
  :
  0.00     8.84      0.00        2     0.00     0.00  OpenSSL::Random.random_add
  0.00     8.84      0.00        1     0.00     0.00  Random.raw_seed
  0.00     8.84      0.00        1     0.00     0.00  OpenSSL::Random.random_byt
es

そして、伝家の宝刀が登場します。

/mastodon # ruby -rtracer bin/rake  secret
#0:/mastodon/vendor/bundle/ruby/2.4.0/gems/bootsnap-0.3.0/lib/bootsnap/load_path
_cache/cache.rb:55:Bootsnap::LoadPathCache::Cache:-:           return x if x    #0:/mastodon/vendor/bundle/ruby/2.4.0/gems/bootsnap-0.3.0/lib/bootsnap/load_path
_cache/cache.rb:53:Bootsnap::LoadPathCache::Cache:<:         @mutex.synchronize
do
c63d0accb0411b3bce44f8d96e9e08f95f9e78fcd1dfc1cf6f1e8a0b32c467d1d463c404b62a8ab7
776d68d74d2ac14bf74bae998dfc46fd2027c2035bc6c728
#0:/usr/local/lib/ruby/2.4.0/monitor.rb:216:MonitorMixin:-:       mon_exit

詳しすぎて、追う気ゼロ。その言い訳に、何行実行されてるかチェック。

/mastodon # ruby -rtracer bin/rake  secret | wc
   896392   3824924 104482697

こうして、追う気ZEROの言い訳になります。

たかがサイコロを一回振るだけに、90万ステップも費やすとは、何という富豪なんでしょ。 そりゃ、バニーなおねーちゃんが、プリプリお尻をくねくねしながら、酒を配っているような 所じゃないと採用出来んわ。金に糸目を付けぬじゃなくて、CPUリソースに糸目をつけぬ 人達御用達。

本当に追うなら、OpenSSLとrandomの文字列を組み合わせて、調べてみて下さい。 と、さじを投げておきます。

もう少し言い訳。 敵地じゃ、まともな道具(例えば、emacs)も無いしね。下手にそんな道具を取り入れようもの なら、敵に気付かれてしまいますよ。そう思うと、敵地に乗り込んで、ウィルスをばら撒いたり、情報を盗んで来るクラッカーは、よくやってると思うぞ。オイラーみたいにへたれじゃない からな。奴らは訓練された兵士ですから。

まてよ、敵地に乗り込む時、特権のrootで入っているな。堂々とガサ入れと称して、証拠 物件を押収しちゃったらどうだろう。上で実行したトレースログがあれば、いいだけですから。 でも、そのログをどうやって、搬出する?

そりゃ、sshを入れればscpを使えますが...だから、現状を壊す事はなるべく避けたい。現代人はこの時点で 固まってしまうかも? 原始人は、ftpなんてのが有ったなあと思い出したぞ。調べてみたら、 ftpの片割れが居た。

/ # ftpput
BusyBox v1.25.1 (2016-10-26 16:15:20 GMT) multi-call binary.

Usage: ftpput [OPTIONS] HOST [REMOTE_FILE] LOCAL_FILE

Upload a file to a FTP server

        -v      Verbose
        -u USER Username
        -p PASS Password
        -P NUM  Port number

本社に連絡して、受け口を用意して貰おう。

ftpd

現場から依頼を受けた本社では、ftpサーバーなんて誰も知らないと言ってる。現に今使ってる Clear Linuxでも、そんな商品は扱っていない。(時代の遺物、昭和の遺産ですからねぇ)

困った時には、Pythonに聞け、、、ですな。世界遺産が保存されてました。pip3とかで すっと入りましたよ。何もしなくても、使えそうですよ。

[clr ~]$ python3 -m pyftpdlib
[I 2017-06-18 16:44:17] >>> starting FTP server on 0.0.0.0:2121, pid=11712 <<<
[I 2017-06-18 16:44:17] concurrency model: async
[I 2017-06-18 16:44:17] masquerade (NAT) address: None
[I 2017-06-18 16:44:17] passive ports: None
^C[I 2017-06-18 16:44:46] received interrupt signal
[I 2017-06-18 16:44:46] >>> shutting down FTP server (1 active socket fds) <<<

ちゃんとしたいなら、カスタマイズしてくださいってか。時代の流れに沿ってSSLにも対応 してるようですしね。

すぐ作ってすぐ壊せるFTPサーバーを立てる (Pythonで)

どーしてもFTPサーバを立てなければいけない時に使う、使い捨てFTPサーバ

etc

Docker入門からしてきたことを棚卸しする