UbuntuでBitbucketからgit cloneできなくなったのはIPv6のせいらしい

一昨日の問題、解決した。どうも IPv6 で Bitbucket に接続しようとしていたかららしい。↓このページが役に立った。

 cf. 突然Bitbucketにgitで接続できなくなったらIPv6関連を疑ってみるとよいかも 2016/07/20 – Qiita

IPv4 で接続するようにするには、下のような ~/.ssh/config ファイルを作ってやればいい。

これで bitbucket.org には IPv4 で接続するようになる。

takatoh@apostrophe $ git clone git@bitbucket.org:takatoh/grp.git
Cloning into 'grp'...
remote: Counting objects: 638, done.
remote: Compressing objects: 100% (392/392), done.
remote: Total 638 (delta 382), reused 343 (delta 229)
Receiving objects: 100% (638/638), 509.65 KiB | 658.00 KiB/s, done.
Resolving deltas: 100% (382/382), done.
Checking connectivity... done.

できた。

UbuntuでBitbucketからgit cloneできなくなった

今朝試したら、SSH での git clonegit pull ができなくなっていた。HTTPS では clone できる。git push は試してない。
また、Windows マシンでは SSH で問題なく clone できる。

SSH の鍵を変えたわけでも、他の設定を変えたわけでもない。確か先週は普通にできたはずだ。
GitHub では問題ない。

SSH の鍵を登録しなおしてもダメ。どうすりゃいいんだ?

症状はこんな感じ。Bitbucket。

takatoh@apostrophe $ git clone git@bitbucket.org:takatoh/grp.git
Cloning into 'grp'...
Connection to bitbucket.org closed by remote host.
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

Github は大丈夫。

takatoh@apostrophe $ git clone git@github.com:takatoh/jscale.git
Cloning into 'jscale'...
remote: Enumerating objects: 39, done.
remote: Counting objects: 100% (39/39), done.
remote: Compressing objects: 100% (15/15), done.
remote: Total 274 (delta 19), reused 36 (delta 19), pack-reused 235
Receiving objects: 100% (274/274), 34.27 KiB | 0 bytes/s, done.
Resolving deltas: 100% (115/115), done.
Checking connectivity... done.

リスト(配列)の中で隣り合う同じ値をグループ化する(3)

しつこいようだけど、今度は Go でやってみた。

^o^ > go run adjacentGroup.go
[[1 1] [2 2] [3] [1 1]]
[]

リスト(配列)の中で隣り合う同じ値をグループ化する(2)

こないだのやつを Scheme と Haskell でやってみた。

まずは Scheme 版。

^o^ >gosh adjacent-group.scm
((1 1) (2 2) (3) (1 1))

基本的な考え方は、Ruby や Python のと同じ。ちょっと工夫したのは、先頭の要素を最初から結果のリストに入れたこと。これで分岐条件が1つ減った。
……のはいいんだけど、これって引数に空リストが来た時のことが考えられてないじゃないか。まあ、グループ化しようというんだから空リストは考えなくてもいいか……ホントか?

さて、Haskell 版。こっちはちゃんと空リストが来ても大丈夫(実行例は示さないけど)。

^o^ >runhaskell adjacentGroup.hs
[[1,1],[2,2],[3],[1,1]]

[追記](9/27)

Scheme 版を空リスト対応にした。分岐条件が1つ増えた。

^o^ >gosh adjacent-group2.scm
((1 1) (2 2) (3) (1 1))
()

[さらに追記](9/28)

分岐条件を工夫して2つに減らせた。cond じゃなく if になった。

^o^ > gosh adjacent-group3.scm
((1 1) (2 2) (3) (1 1))
()

サーバのOSをUbuntuからCentoOSに変えた

やっと書く気になってきた。
インターネット回線を乗り換えたので、一昨日、その工事があった。その関係で外部公開している WEB サーバを止めたくちゃいけなかったので、ついでにサーバの OS をクリーンインストールすることにした。というのも、どういうわけだかわからないけどずっとサーバの調子が悪くてたびたび WEB サーバが落ちる、ということが続いていて、それも最近は頻度が多くなっていたから。で、ちょうどいいので OS のインストールからやり直すことにしたってわけ。OS はタイトルのとおり、Ubuntu から CentOS に変更した。この記事はその顛末。
といっても、CentoOS のインストールと WEB サーバ、アプリの構築は去年の年末から今年にかけて一度やっているので、細かくは書かずにリンクを置くだけにする。

CentOS のインストール

最新の CentOS 7.5 1804 の ISO イメージをダウンロードして、DVD に焼いて使った。

 cf. CentOS 7のインストール
 cf. CentOSのアップデート

最低限のソフトウェアのインストール

Git、Ruby、ImageMagick をそれぞれ yum install でインストールした。今回、rbenv は使わなかった。yum でインストールした Ruby は 2.0.0 と古いけど、構築する予定の WEB アプリでは最近の新しい機能は使っていないのと、サービスとして rbenv の環境を使うのは煩わしいと感じたのでそうした。ImageMagick もアプリで使う。

一般ユーザーで sudo できるようにする

 cf. 一般ユーザーでsudoできるようにする

USB 外付け HDD

 cf. USBの外付けHDDを使ってみる
これはもとから使っていた HDD を繋いだ。OS が変わってうまく使えるか心配したけど、結果的には、ディレクトリとファイルの所有者を chown で変えてやればそのまま使えた。

Nginx

WEB サーバには前と同じ Nginx。
 cf. CentOS 7にNginxをインストールする

WEBアプリの構築

 cf. SinatraアプリをCentOSで動かす(2)

Nginxで仮想サーバー

 cf. Nginxを使って仮想サーバーをたてる

問題発生と解決(暫定的)

さて、ここまでは順調にきた。けど、Nginx で立てた仮想サーバーにアクセスしても 502 Bad Gateway が返ってきてしまう。Nginx も WEB アプリも正常に動いているように見える。ここで行き詰まった。
長々と書くつもりはないので、結果を書くと、SELinux のセキュリティに引っかかっているようだった。で、その SELinux というのがよくわからない。ググってみるとちゃんと解決する方法は見つからなくて、無効にする方法ばかり。仕方がないので暫定的に SELinux を無効にして当面の解決策とすることにした。

SELinux を無効にするには、/etc/selinux/config ファイルのつぎの箇所を変更する。

上のコメントアウトしてある行がデフォルトの設定。これを下の行のように disabled にした。
これで再起動すれば OK。

本当は SELinux をちゃんと理解して使わなきゃいけないところだけど、なにせ情報が少ない。今後の課題だな。

あ、あと書き忘れてたけど、ホスト名は nightschool にした。

というところで、今日はここまで。

リスト(配列)の中で隣り合う同じ値をグループ化する

リストでも配列でもいいけど、つまりこういうのを

[1, 1, 2, 2, 3, 1, 1]

こうしたい。

[[1, 1], [2, 2], [3], [1, 1]]

Ruby でやってみた。

^o^ >ruby adjacent_group.rb
[[1, 1], [2, 2], [3], [1, 1]]

おなじく Python で。

^o^ >python adjacent_group.py
[[1, 1], [2, 2], [3], [1, 1]]

ちょっとベタだな。もう少しスマートにいかないものか、と考えて Ruby の Array#inject が使えそうだと思いついた。

^o^ >ruby adjacent_group2.rb
[[1, 1], [2, 2], [3], [1, 1]]

うまくいった。

さて、じゃ、Python ではどうか。reduce を使えば同じことができると考えたけど、Python の reduce は初期値がとれない。まあ、それはリストの頭に初期値をつけてやれば済む話ではあるけど、もうひとつ問題がある。Ruby の Array#inject はブロックをとれるけど、Python の reduce には関数を渡してやらなきゃいけないので、関数定義がひとつ増えてしまう。一行では書けないので lambda 式は使えない。
というわけで、上のようにベタに書いたほうがまだマシそうだ。何かいい書き方があったら、誰か教えてください。

[追記](9/25)

Ruby の2つ目の実装では、引数に空の配列を渡したときに期待通りに動作しない([[]] が返ってきてしまう)。そこでちょっと直したのがこれ。

^o^ >ruby adjacent_group.rb
[[1, 1], [2, 2], [3], [1, 1]]
[]

これでいいだろう。

NginxでCGIを動かす

Nginx では CGI は動かない。サポートしてないんだそうだ。まあ、いまどき CGI ってのも……という気はするけど、ちょっと古い CGI プログラムが必要になったのでやってみた。
参考にしたページはここ。

 cf. NginxでCGIを動かそうと頑張った話 – Qiita

これによると、fcgiwrap というのを使えば、CGI を FCGI にラップしてくれて、CGI プログラムを動かせるようだ。ラップするといってもインターフェイスの話で、中身はあくまで CGI なので FCGI なみに早く動作するわけではない。

とにかくやってみよう。
まずは fcgiwrap のインストール。apt でインストールできる。

takatoh@wplj $ sudo apt install fcgiwrap
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています                
状態情報を読み取っています... 完了
以下のパッケージが自動でインストールされましたが、もう必要とされていません:
  libllvm3.8 libllvm4.0 libllvm5.0 libmircommon5 libpango1.0-0 libpangox-1.0-0
  libqmi-glib1 libqpdf17 linux-headers-4.4.0-101
  linux-headers-4.4.0-101-generic linux-headers-4.4.0-103
  linux-headers-4.4.0-103-generic linux-headers-4.4.0-104
  linux-headers-4.4.0-104-generic linux-headers-4.4.0-109
  linux-headers-4.4.0-109-generic linux-headers-4.4.0-112
  linux-headers-4.4.0-112-generic linux-headers-4.4.0-116
  linux-headers-4.4.0-116-generic linux-headers-4.4.0-119
  linux-headers-4.4.0-119-generic linux-headers-4.4.0-121
  linux-headers-4.4.0-121-generic linux-headers-4.4.0-122
  linux-headers-4.4.0-122-generic linux-headers-4.4.0-124
  linux-headers-4.4.0-124-generic linux-headers-4.4.0-127
  linux-headers-4.4.0-127-generic linux-headers-4.4.0-128
  linux-headers-4.4.0-128-generic linux-headers-4.4.0-130
  linux-headers-4.4.0-130-generic linux-headers-4.4.0-131
  linux-headers-4.4.0-131-generic linux-headers-4.4.0-21
  linux-headers-4.4.0-21-generic linux-headers-4.4.0-64
  linux-headers-4.4.0-64-generic linux-headers-4.4.0-66
  linux-headers-4.4.0-66-generic linux-headers-4.4.0-67
  linux-headers-4.4.0-67-generic linux-headers-4.4.0-70
  linux-headers-4.4.0-70-generic linux-headers-4.4.0-71
  linux-headers-4.4.0-71-generic linux-headers-4.4.0-72
  linux-headers-4.4.0-72-generic linux-headers-4.4.0-75
  linux-headers-4.4.0-75-generic linux-headers-4.4.0-77
  linux-headers-4.4.0-77-generic linux-headers-4.4.0-78
  linux-headers-4.4.0-78-generic linux-headers-4.4.0-79
  linux-headers-4.4.0-79-generic linux-headers-4.4.0-81
  linux-headers-4.4.0-81-generic linux-headers-4.4.0-83
  linux-headers-4.4.0-83-generic linux-headers-4.4.0-87
  linux-headers-4.4.0-87-generic linux-headers-4.4.0-89
  linux-headers-4.4.0-89-generic linux-headers-4.4.0-91
  linux-headers-4.4.0-91-generic linux-headers-4.4.0-92
  linux-headers-4.4.0-92-generic linux-headers-4.4.0-93
  linux-headers-4.4.0-93-generic linux-headers-4.4.0-96
  linux-headers-4.4.0-96-generic linux-headers-4.4.0-97
  linux-headers-4.4.0-97-generic linux-headers-4.4.0-98
  linux-headers-4.4.0-98-generic linux-image-4.4.0-101-generic
  linux-image-4.4.0-103-generic linux-image-4.4.0-104-generic
  linux-image-4.4.0-109-generic linux-image-4.4.0-112-generic
  linux-image-4.4.0-116-generic linux-image-4.4.0-119-generic
  linux-image-4.4.0-121-generic linux-image-4.4.0-122-generic
  linux-image-4.4.0-124-generic linux-image-4.4.0-127-generic
  linux-image-4.4.0-128-generic linux-image-4.4.0-130-generic
  linux-image-4.4.0-131-generic linux-image-4.4.0-21-generic
  linux-image-4.4.0-64-generic linux-image-4.4.0-66-generic
  linux-image-4.4.0-67-generic linux-image-4.4.0-70-generic
  linux-image-4.4.0-71-generic linux-image-4.4.0-72-generic
  linux-image-4.4.0-75-generic linux-image-4.4.0-77-generic
  linux-image-4.4.0-78-generic linux-image-4.4.0-79-generic
  linux-image-4.4.0-81-generic linux-image-4.4.0-83-generic
  linux-image-4.4.0-87-generic linux-image-4.4.0-89-generic
  linux-image-4.4.0-91-generic linux-image-4.4.0-92-generic
  linux-image-4.4.0-93-generic linux-image-4.4.0-96-generic
  linux-image-4.4.0-97-generic linux-image-4.4.0-98-generic
  linux-image-extra-4.4.0-101-generic linux-image-extra-4.4.0-103-generic
  linux-image-extra-4.4.0-104-generic linux-image-extra-4.4.0-109-generic
  linux-image-extra-4.4.0-112-generic linux-image-extra-4.4.0-116-generic
  linux-image-extra-4.4.0-119-generic linux-image-extra-4.4.0-121-generic
  linux-image-extra-4.4.0-122-generic linux-image-extra-4.4.0-124-generic
  linux-image-extra-4.4.0-127-generic linux-image-extra-4.4.0-128-generic
  linux-image-extra-4.4.0-130-generic linux-image-extra-4.4.0-131-generic
  linux-image-extra-4.4.0-21-generic linux-image-extra-4.4.0-64-generic
  linux-image-extra-4.4.0-66-generic linux-image-extra-4.4.0-67-generic
  linux-image-extra-4.4.0-70-generic linux-image-extra-4.4.0-71-generic
  linux-image-extra-4.4.0-72-generic linux-image-extra-4.4.0-75-generic
  linux-image-extra-4.4.0-77-generic linux-image-extra-4.4.0-78-generic
  linux-image-extra-4.4.0-79-generic linux-image-extra-4.4.0-81-generic
  linux-image-extra-4.4.0-83-generic linux-image-extra-4.4.0-87-generic
  linux-image-extra-4.4.0-89-generic linux-image-extra-4.4.0-91-generic
  linux-image-extra-4.4.0-92-generic linux-image-extra-4.4.0-93-generic
  linux-image-extra-4.4.0-96-generic linux-image-extra-4.4.0-97-generic
  linux-image-extra-4.4.0-98-generic linux-signed-image-4.4.0-101-generic
  linux-signed-image-4.4.0-103-generic linux-signed-image-4.4.0-104-generic
  linux-signed-image-4.4.0-109-generic linux-signed-image-4.4.0-112-generic
  linux-signed-image-4.4.0-116-generic linux-signed-image-4.4.0-119-generic
  linux-signed-image-4.4.0-121-generic linux-signed-image-4.4.0-122-generic
  linux-signed-image-4.4.0-124-generic linux-signed-image-4.4.0-127-generic
  linux-signed-image-4.4.0-128-generic linux-signed-image-4.4.0-130-generic
  linux-signed-image-4.4.0-131-generic linux-signed-image-4.4.0-64-generic
  linux-signed-image-4.4.0-66-generic linux-signed-image-4.4.0-67-generic
  linux-signed-image-4.4.0-70-generic linux-signed-image-4.4.0-71-generic
  linux-signed-image-4.4.0-72-generic linux-signed-image-4.4.0-75-generic
  linux-signed-image-4.4.0-77-generic linux-signed-image-4.4.0-78-generic
  linux-signed-image-4.4.0-79-generic linux-signed-image-4.4.0-81-generic
  linux-signed-image-4.4.0-83-generic linux-signed-image-4.4.0-87-generic
  linux-signed-image-4.4.0-89-generic linux-signed-image-4.4.0-91-generic
  linux-signed-image-4.4.0-92-generic linux-signed-image-4.4.0-93-generic
  linux-signed-image-4.4.0-96-generic linux-signed-image-4.4.0-97-generic
  linux-signed-image-4.4.0-98-generic snap-confine ubuntu-core-launcher
これを削除するには 'sudo apt autoremove' を利用してください。
以下の追加パッケージがインストールされます:
  libfcgi0ldbl spawn-fcgi
以下のパッケージが新たにインストールされます:
  fcgiwrap libfcgi0ldbl spawn-fcgi
アップグレード: 0 個、新規インストール: 3 個、削除: 0 個、保留: 28 個。
193 kB のアーカイブを取得する必要があります。
この操作後に追加で 665 kB のディスク容量が消費されます。
続行しますか? [Y/n] Y
取得:1 http://jp.archive.ubuntu.com/ubuntu xenial/main amd64 libfcgi0ldbl amd64 2.4.0-8.3 [161 kB]
取得:2 http://jp.archive.ubuntu.com/ubuntu xenial/universe amd64 spawn-fcgi amd64 1.6.4-1 [14.5 kB]
取得:3 http://jp.archive.ubuntu.com/ubuntu xenial/universe amd64 fcgiwrap amd64 1.1.0-6 [17.5 kB]
193 kB を 0秒 で取得しました (1,165 kB/s)
以前に未選択のパッケージ libfcgi0ldbl を選択しています。
(データベースを読み込んでいます ... 現在 1351986 個のファイルとディレクトリがインストールされています。)
.../libfcgi0ldbl_2.4.0-8.3_amd64.deb を展開する準備をしています ...
libfcgi0ldbl (2.4.0-8.3) を展開しています...
以前に未選択のパッケージ spawn-fcgi を選択しています。
.../spawn-fcgi_1.6.4-1_amd64.deb を展開する準備をしています ...
spawn-fcgi (1.6.4-1) を展開しています...
以前に未選択のパッケージ fcgiwrap を選択しています。
.../fcgiwrap_1.1.0-6_amd64.deb を展開する準備をしています ...
fcgiwrap (1.1.0-6) を展開しています...
man-db (2.7.5-1) のトリガを処理しています ...
systemd (229-4ubuntu21.2) のトリガを処理しています ...
ureadahead (0.100.0-19) のトリガを処理しています ...
ureadahead will be reprofiled on next reboot
libfcgi0ldbl (2.4.0-8.3) を設定しています ...
spawn-fcgi (1.6.4-1) を設定しています ...
fcgiwrap (1.1.0-6) を設定しています ...
insserv: warning: script 'K01tonzlr' missing LSB tags and overrides
insserv: warning: script 'K01bruschetta' missing LSB tags and overrides
insserv: warning: script 'K01ellie' missing LSB tags and overrides
insserv: warning: script 'tonzlr' missing LSB tags and overrides
insserv: warning: script 'ellie' missing LSB tags and overrides
insserv: warning: script 'bruschetta' missing LSB tags and overrides
libc-bin (2.23-0ubuntu10) のトリガを処理しています ...
systemd (229-4ubuntu21.2) のトリガを処理しています ...
ureadahead (0.100.0-19) のトリガを処理しています ...

Nginx の設定。/etc/nginx/sites-available/default ファイルに以下を追記。

これで .cgi 拡張子を持つファイルがすべて CGI プログラムとして認識されるはず。
/var/run/fcgiwrap.socket は fcgiwrap を apt でインストールすると自動的に作られている。

fcgiwrap の設定。/etc/init.d/fcgiwrap ファイルを編集する。

デフォルトで上のようになっているのを下のように変えた。

変えたのは FCGI_SOCKET_OWNER と FCGI_SOCKET_GROUP だ。

これで設定は終了のはず。fcgiwrap と Nginx を再起動しよう。

takatoh@wplj $ sudo systemctl restart fcgiwrap
takatoh@wplj $ sudo systemctl restart nginx

最後にテスト。/var/www/html ディレクトリにつぎのような hello.cgi ファイルを作って実行権限をつけた。

ブラウザでアクセスしてみると、ちゃんと Hello CGI world! と表示されたので OK。

要素の個数を数える

配列内の同じ要素それぞれの個数を数える。

 cf. 要素の個数を数える – 惰力飛行

Ruby でやってみる。Array#group_by が使えそう。

irb(main):001:0> lang = %w(perl python ruby perl python python ruby python ruby lisp)
=> ["perl", "python", "ruby", "perl", "python", "python", "ruby", "python", "ruby", "lisp"]
irb(main):002:0> lang.group_by{|x| x}.map{|k, v| [k, v.size]}.to_h
=> {"perl"=>2, "python"=>4, "ruby"=>3, "lisp"=>1}

いったん [[要素, 個数]] という配列の配列を作って、Array#to_h でハッシュにしている。うまく1行で書けた。

Windows PowerShellの実行ポリシーとプロンプトのカスタマイズ

PowerShell のデフォルトのプロンプトは、「PS カレントディレクトリのパス >」となっていて、ディレクトリが深くなるとすごく長くなる。これをもっとシンプルにしようと思った。具体的には、Ubuntu と同様に「ユーザー名@ホスト名 >」くらいでいい。
ググってみると、プロンプトは prompt 関数の返り値が使われるので、%USERPROFILE%\Documents\WindowsPowerShell\profile.ps1 ファイルに prompt 関数を書いておけばいいようだ。.ps1 てのは PowerShell のスクリプトの拡張子ね。
で、prompt 関数は次のようにした。

さて、これで新しいシェルを立ち上げれば、profile.ps1 が読み込まれてプロンプトの変更が反映されるはず。

Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

. : このシステムではスクリプトの実行が無効になっているため、ファイル C:\Users\takatoh\Documents\WindowsPowerShell\profile
.ps1 を読み込むことができません。詳細については、「about_Execution_Policies」(https://go.microsoft.com/fwlink/?LinkID=1
35170) を参照してください。
発生場所 行:1 文字:3
+ . 'C:\Users\takatoh\Documents\WindowsPowerShell\profile.ps1'
+   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : セキュリティ エラー: (: ) []、PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess

おっと、エラーになった。何やらスクリプトの実行が無効になっているらしい。ググってみると、PowerShell には実行ポリシーというのがあって、これの設定でスクリプトの実行を制御しているらしい。詳しくは上のメッセージにも書かれている、↓のページに説明がある。

 cf. about_Execution_Policies

このページに Windows10 については書かれていないけど、次のようにすると実行ポリシーが Restricted であることがわかる。

PS C:\Users\takatoh> Get-ExecutionPolicy
Restricted

Restricted というポリシーは、コマンドは実行できるがスクリプトは実行できない、というものらしい。なので、これを変更してやればいい。具体的には次のようにした。

PS C:\Users\takatoh> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -scope CurrentUser

実行ポリシーの変更
実行ポリシーは、信頼されていないスクリプトからの保護に役立ちます。実行ポリシーを変更すると、about_Execution_Policies
のヘルプ トピック (https://go.microsoft.com/fwlink/?LinkID=135170)
で説明されているセキュリティ上の危険にさらされる可能性があります。実行ポリシーを変更しますか?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "N"): Y

Y を入力してこれで実行ポリシーの変更はできたはず。RemoteSigned という実行ポリシーは、スクリプトの実行はできるがインターネットからダウンロードされたスクリプトは信頼された発行元によってデジタル署名されている必要がある、というもの。ローカルのスクリプトの実行には支障がないのでこれにした。

さて、改めて PowerShell を立ち上げてみよう。

Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

takatoh@FLAMBAY > Get-ExecutionPolicy -List

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser    RemoteSigned
 LocalMachine       Undefined


takatoh@FLAMBAY > Get-ExecutionPolicy
RemoteSigned

期待通り、プロンプトが変更されていて、カレントユーザーの実行ポリシーも RemoteSigned になっているのがわかる。
これでOK。