C# REPL GUI Shell, Mono gsharp を Ubuntu に入れようとすると発生するエラーを回避する

.NET Core の登場で大分影が薄くなったものの、 まだまだ Xamarin でガンガン使われている Mono。
この Mono には, gsharp という C# GUI Shell が存在する。

CUI 版の Shell と比べると、 グラフがプロットできるとか、 画像が手軽に表示できるといったメリットしかないが、タブ補完も効くし、まぁ便利っちゃ便利なツールだ。

しかし Windows で gsharp を動かしたくても、 Windwos 用の Mono インストーラには gsharp が入っていないため、そのままでは gsharp を使えない。
このため、 WSL の Ubuntu に gsharp をインストールして、 VcXsrv などの X Server を使って動かすのが手っ取り早い。

以下の記事が詳しい。

ところが、 この gsharp などを含む、 Mono 拡張 GUI ツールを、 WSL を含む Ubuntu ベースのディストリビューションにインストールしようとすると、エラーになってしまう。

今回は、 その暫定的な回避策について。

TL;DR

早く mono/mono#16322 の不具合直した Mono パッケージを出してくれ。

Ubuntu に mono-tools-gui をインストールしようとすると、依存関係エラー

基本的に、 WSL だろうと ピュアな Ubuntu だろうと、インストール手順は変わらない。

前述の Mono Project の記事では、 GUI ツールは mono-tools というパッケージでインストールすると記載されているが、 Ubuntu では mono-tools-gui というパッケージ名で登録されている。

Download – Stable | Mono / Ubuntu の案内に従ってインストールしようとすると、以下のような依存関係エラーが発生する。

$ sudo apt install gnupg ca-certificates
$ sudo apt-key adv –keyserver hkp://keyserver.ubuntu.com:80 –recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
$ echo "deb https://download.mono-project.com/repo/ubuntu stable-bionic main" | sudo tee /etc/apt/sources.list.d/mono-official-stable.list
$ sudo apt update
$ sudo apt install mono-devel mono-tools-gui

Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
mono-tools-gui : Depends: libmono-cecil-private-cil (< 6.4.0.171) but 6.4.0.198-0xamarin3+ubuntu1804b1 is to be installed
E: Unable to correct problems, you have held broken packages.

2019-10-25 時点の mono-tools-gui のパッケージの依存関係を見てみると、

$ apt depends mono-tools-gui
mono-tools-gui
[…]
Depends: libmono-cecil-private-cil (>= 6.4.0.170)
Depends: libmono-cecil-private-cil (<< 6.4.0.171)

6.4.0.170 のピンポイントの依存関係が書かれているのだが、 そんなバージョン存在しないため、 エラーになっているようだ。
依存関係の “>=” とか “<<” の意味は Debian Policy Manual / 7. Declaring relationships between packages に書いてある。

何故 =6.4.0.170 と書かないのか。 << 6.4.0 としてバグフィックスバージョンが上がるのを許容しようとしていた?
うーん、 依存関係定義のバグっぽい。

調べてみると、 Mono 6.0 系 も同じバグ (>= 6.0.0.313, << 6.0.0.314 の依存関係が定義されているのに、 存在するのは 6.0.0.319 以降のバージョン) がある。

過去のバージョンのスナップショット を確認してみたところ、 Mono 5.18 系 まで遡れば不具合なくインストールできるようなので、 mono-tools-gui は 5.18系で、 Mono 自体は最新版でインストールしてみよう。

バージョンを指定してパッケージをインストールしたい

Ubuntu や Debian 用の Mono のリポジトリでは、 各パッケージの最新 のみ が載っているリストがリリース毎に用意され、 その最新のリストのシンボリックリンクを参照する構造になっている。
(何故そのような仕組みなのかはよく知らないが…)

例えば、 Ubuntu 18.04 向けに登録している Mono のパッケージソースは
deb https://download.mono-project.com/repo/ubuntu stable-bionic main
となっているが、 これは 2019年10月 現在、
deb https://download.mono-project.com/repo/ubuntu stable-bionic/snapshots/6.4.0.198 main
への参照となっている。

このため、 インストール手順に書かれたリポジトリ設定では、 mono-tools-gui の 5.18系 のバージョンを探そうにも、そのようなバージョンはみつからない。

これを解消するためは、以下のように 5.18系 のリストを書き足してやればよい。

$ echo -e "deb https://download.mono-project.com/repo/ubuntu stable-bionic/snapshots/5.18 main\ndeb https://download.mono-project.com/repo/ubuntu stable-bionic main" | sudo tee /etc/apt/sources.list.d/mono-official-stable.list
$ sudo apt update

上記は Ubuntu 18.04 の場合だが、 例えば 16.04 であれば bionic の部分をを xenial に読み替えるなど、 他の Ubuntu / Debian / Raspbian ディストリビューションの場合は適度に読み替えてくれ。

次に、 apt list -a で 5.18 のスナップショットに登録されている mono-tools-gui のバージョンを確認する。

$ apt list -a mono-tools-gui
Listing… Done
mono-tools-gui/stable-bionic 4.2-3xamarin3+ubuntu1804b1 all
mono-tools-gui/bionic 4.2-2.2 all
mono-tools-gui/bionic/snapshots/5.18.1.3 4.2-2xamarin12+ubuntu1804b1 all

4.2-2xamarin12+ubuntu1804b1 というバージョンだということがわかった。
(これも、ディストリビューションが異ればバージョンの名前も異なるので、適宜読み替えてくれ)

最後に apt install で バージョン指定した mono-tools-gui と、 最新の mono-devel をインストールすれば、無事 gsharp がインストールされる。

sudo apt install mono-tools-gui=4.2-2xamarin12+ubuntu1804b1 mono-devel

原因

この問題に関する Issue は、すでに mono/mono#16322 に立っている。
Ubuntu のパッケージの依存バージョンを Debian のものにしてしまうと言う、 Mono Project 内のビルドツールによるものらしい。

Issue はクローズされているが、 その後にリリースされた 6.4.0.198 でも不具合が残っている。

さっさと直して欲しい。。。

ルータを経由すると仮想ブリッジ接続の VM にアクセスできない?

今回は、ネットワークの話。

解決してみれば割としょうも無いトラブルで、時間を浪費してしまったので、自戒の意味を込めて記事にしておく。

サブネット外から ping が通らない

ある日、 ホストPC の NIC とブリッジ接続されている VM に、 サブネット外からアクセスできなくなってしまった。

構成を図にすると、以下のような感じ。
(あまり UML図 に明るくないので、書き方がヘタクソだったり本来の意味と違う記号の使い方をしている点は大目に見て欲しい。)

data:application/gzip;base64,H4sIAAAAAAAEAIVTPU/DMBDdI+U/nLIihziUAhVC5UOCDmWgqAtlMM61jZTYleOIAbW/Hcdy6qQtwkt8757f3dkv40ozpeuyCIMw4IWsM4gmQqMSqCNgFeQuMFkptJIFRG+yNpjNKrsNA4VcM7EqECJ6lcZ0GA/SODlPBxH8hAGYxWW5kQKFhuhFVhqmjK9zgVZlwy3kmM2yVZeMo2O/Th4tE/W6iT2xU3g+raKuxoHO6/27lRBM9zm+s4PDBwKmNm2boMfMzoDzKTzXWGk3nN3/J5200kmfue2H7gKAfKzzLEPxSY4HMoDPn5BsENjtCa7BEZSoVc6BLgS9ad7wOr4cxmn/rCPDzt7CCPxr0+HpTnct9UHl2Qo9yU22PfKHswZIsRAzViLM6q/WjhtuGtqeNNzFn4brCj7lyyWqBu6pUqvamh1uCdl72ySB3Hmr2y+QTH4LcuYdaTpzYOLBMBijyMzv9QsMZU+SaAMAAA

同一サブネット内 (図の “Machine on Same Subnet”) から 172.16.42.16 を叩くと VM ゲストに到達するのだが、 サブネット外 (図の “Machine on Different Subnet”) からだと ping すら通らない。

以前は同じ構成で、サブネット外から繋がっていたはずだ。

ちょうど直前に、ネットワーク機器のメンテナンスがあったため、 そちらで IPフィルタの動作がおかしくなったのではないかと疑ってしまった。
しかし、繋がらなくなった直接的な原因は、 VM Gurest 側にあった。
このため、答えにたどり着くのに時間がかかってしまった。

アクセスできなかった原因

続きを読む

Python pipenv で pywin32 をインストールするとエラー

11/10 頃から、 Python でpypiwin32 や pywin32 パッケージや、それらに依存しているパッケージを pipenv にてインストールしようとすると、

AttributeError: module &#039;site&#039; has no attribute &#039;getsitepackages&#039;

とエラーが出て失敗するようになった。

10/22 追記: pywin32 v227 で問題は修正された。
“there’s nothing wrong with PyWin32, it’s just a fix applied on PyWin32’s side to work around a VirtualEnv bug.” と、修正コメントで強調されている。 わかるよ、その気持ち。
追記ここまで

原因

直接的な原因は、 pipenv ではなく virtualenv にある。

続きを読む

AWX をインストールした後の Server Error を解決したかった話

この記事は、 Ansible AWX をインストールしたときに、 Server Error に なったりならなかったりする 問題に対処したときのポエムだ。

はじめに断っておくが、最終的に AWX 8.0.0 で解消しているっぽいものの、 原因や正確な条件などは不明なままである。
また後述するが、 (タイトルに反して)おそらく Ansible AWX の問題ではなく、 postgres:9.6 の docker イメージの問題ではないかと思われる。

発生した問題の状況

続きを読む

プロキシ環境下で Ansible AWX をインストールする Playbook を作る

構成管理ツール (いわゆる Infrastructure as Code(IaC)) の中でも比較的易しいと言われる Ansible。
その Ansible の運用を省力化してくれるツールとして Ansible Tower というものがあり、そのコミュニティ管理版 (OSS版) が AWX だ。

その AWX がインストールされたサーバを作成する Playbook を作ろうとしたら意外と手間取ったので、そのメモ。

なお、インストール先は CentOS 7 である。
AWX のインストールは、 公式ビルド済み docker イメージを Docker Compose を使ってコンテナ化する方法 を使った。

11/21: 追記

docker-compose の PyPI (pip) パッケージが 1.25.0 に更新後、 CentOS 7 (正確には、 Python 2 系を使っている環境) で docker-compose のインストールや実行がうまくいかなくなった。
(commit:719a1b0 で) subprocess32 に依存するようになり、 gcc 等のビルド環境のインストールが別途必要になったためだ。

それに加え、たとえ gcc をインストールしても、依存パッケージの python2 対応が不十分なようで、 docker-compose 実行時にエラーになってしまう。

docker/compose#7030 の Issue には挙がっているが、修正されるかどうか不明なため、一つ前の 1.24.1 を使うことで回避するように、コードを修正した。

python2 ツラい。。。
しかし、 2020年にサポート切れになった後も、 CentOS 7 が生きているしばらくの間はこの辛みと付き合わなければならないようだ。
ツラい。。。

追記ここまで

最終的な Playbook

続きを読む

Proxy 下で vscode の WSL 上の他の拡張機能のインストールに失敗する

プロキシ環境下の vscode で、 WSL 上で拡張機能を動かしたいのに、 インストールインストールに失敗する問題を解決するメモ。

前回の↓の記事は、 『Remote – WSL 拡張が有効にできない』問題だったが、今回は『Remote – WSL 拡張 を有効にした後、その環境上で他の拡張機能がインストールできない』問題なのでちょっと違う点に注意。ややこしいね。

遭遇した問題

Visual Sutdio Code (以下、 vscode) へ 無事に Remote – WSL 拡張機能 の “VS Code Server for WSL” のインストールが完了し、 Windows 上から 快適に WSL の環境にアクセスできるようになった。
しかし、 いくつかの vscode の拡張機能は、 Windows 上の環境とは別に WSL 上の環境で改めてインストールしなくてはならない。

そこで、 UI 上の案内に従って各拡張機能で “Install in WSL” を行ったところ、 プロキシ環境下だと以下のエラーが発生してインストールに失敗する問題に遭遇した。

Failed to install extension

パネル上の OUTPUT タブで “Log (Remote Server)” の情報を見ると、以下のようなエラーが発生しているのがわかる。

[remoteagent] [error] Failed to install extension: {拡張機能ID} connect ECONNREFUSED 13.107.6.175:443

settings.json ではプロキシの設定しているし、更には WSL 上の環境変数 (http_proxy, https_proxy) にだってプロキシを入れている。
更には(前述の)前回の記事に倣って、 WSL のコンソール上から code . の立ち上げまで行ってみた。

それでも解消しない。何故だ。

なお、試した vscode のバージョンは、 August 2019 (version 1.38.1) だ。

“Remote [WSL]” 用の設定ファイルを書き換える

続きを読む

Proxy 下で vscode の WSL 拡張へ接続できない

Windows 上の Visual Studio Code (以下、 vscode) で、WSL 上のファイルやシェルを使えるようになる、 Remote – WSL 拡張機能。

これを、プロキシ環境下でインストールしたり更新したりすると、 vscode から WSL 環境ににアクセスするときに、

VS Code Server for WSL closed unexpectedly.
Check WSL terminal for mor details.

とエラーになってしまう。

WSL ターミナルのログを見てみると、だいたい以下のようになっていて、どうやら update.code.visualstudio.com から VS Code Server の更新版のファイルをダウンロードするのに失敗しているように見える。

Starting VS Code Server inside WSL (default distro)
Extension version: 0.39.5, Windows build: 17763. Multi distro support: disabled. WSL path support: enabled
Probing if server is already installed: C:\WINDOWS\System32\wsl.exe  -e sh -c "[ -d ~/.vscode-server/bin/3db7e09f3b61f915d03bbfa58e258d6eee843f35 ] && echo found || echo missing"
No server install found on WSL, downloading server on client side: C:\Users\user\AppData\Local\Temp\vscode-remote-wsl\3db7e09f3b61f915d03bbfa58e258d6eee843f35\vscode-server-linux-x64.tar.gz
Unable to detect if server is already installed: Error: connect ECONNREFUSED 104.42.78.153:443
Launching C:\WINDOWS\System32\wsl.exe sh -c '"$VSCODE_WSL_EXT_LOCATION/scripts/wslServer.sh" 3db7e09f3b61f915d03bbfa58e258d6eee843f35 stable .vscode-server 0  --disable-telemetry' in c:\Users\user\.vscode\extensions\ms-vscode-remote.remote-wsl-0.39.5
WSL version: 4.4.0-17763-Microsoft 
Updating server...
Updating VS Code Server to version 3db7e09f3b61f915d03bbfa58e258d6eee843f35
Removing previous installation...
Downloading:     
Failed
--2019-09-11 20:50:12--  https://update.code.visualstudio.com/commit:3db7e09f3b61f915d03bbfa58e258d6eee843f35/server-linux-x64/stable
Resolving update.code.visualstudio.com (update.code.visualstudio.com)... 104.42.78.153
Connecting to update.code.visualstudio.com (update.code.visualstudio.com)|104.42.78.153|:443... 
failed: Connection refused.
ERROR: Failed to download https://update.code.visualstudio.com/commit:3db7e09f3b61f915d03bbfa58e258d6eee843f35/server-linux-x64/stable to ~/.vscode-server/bin/3db7e09f3b61f915d03bbfa58e258d6eee843f35-xxxxxxxxxx.tar.gz
VS Code Server for WSL closed unexpectedly.
For help with startup problems, go to
https://code.visualstudio.com/docs/remote/troubleshooting#_wsl-tips

どう解決したものか。


そもそも wget でダウンロードができる状態なのか

続きを読む

同一ファイルに対して、 複数種類のファイルハッシュを高速に計算する

ネットワークドライブ上の GB オーダーのファイルに対して、複数のハッシュアルゴリズムでファイルハッシュを計算する必要に駆られていた。
「そんなシチュエーションが本当にあるのか?」と思うかも知れないが、あったのだから仕方ない。

最初は、 PowerShell を使って 愚直に Get-FileHash を 2回 計算していた。
しかし当たり前だが、 2回ファイルをダウンロードすることになるこの方法は遅くて仕方ない。

ということで、 C# でコンパイルしたコード上で、 一度メモリに読み込ませてから複数のハッシュアルゴリズムで計算できるようなコードを作成した。

バッファーサイズを 80KiB 程度とすると、 .NET の仕様で 85KB を境にメモリの扱いが変わる (LOH と呼ばれる特別なヒープに移動する) ことから、 このサイズを超えると一般的に動作速度が下がると言われている。
しかし、今回のコードの場合バッファーが小さいと、 Task 周りの処理がボトルネックになってしまうので、 8MiB くらいのサイズとしている。

80KiB としているのは、 .NET mscorlib の System.IO.Stream.CopyTo メソッドなどでもおなじみなのだが、これが必ずしも正解とは限らないわけだな。


パフォーマンス

800Mbps 位でシーケンシャルリードできるリモート上の 4GB のファイルを、 4回 ずつ計測した平均を計測した。
Get-FileHash の 2種類目 以外はクライアントキャッシュが効かないように注意し、 計測の各回でハッシュを計算するファイルはそれぞれ別のファイルで、中身はランダムバイナリとした。
Get-FileHash については、 計測の各回では同じファイルに対して -Algorithm パラメータを変えて複数回連続で呼び出した。

計算したハッシュの種類 Get-FileHash 上記の改良スクリプト
1種類 (SHA1) 48.8s 43.3s
2種類 (MD5, SHA1) 60.4s 44.2s
3種類 (MD5, SHA1, SHA256) 83.3s 48.2s

ん? 計算したハッシュが 1種類 の場合でも、改良スクリプトの方が早いぞ?


うわっ… HashAlgorithm.ComputeHash の実行速度、低すぎ…?

PowerShell v5 相当

PowerShell v6 相当

上記のように、 Get-FileHash は、内部的に HashAlgorithm.ComputeHash でハッシュ計算を実行している。

で、その HashAlgorithm.ComputeHash がどうなっているかというと、 4KiB 毎に ファイルの読み込みと、 ハッシュストリームへの書き込みを 同期的に 行っている。

ファイルの読み込みも、 (使うアルゴリズムにもよるけど) ハッシュの計算も、 どちらもコストがかかるので、同期的にやってたらそりゃ遅いわ。

LINEマイカード をワンタップで起動するショートカットを作る裏技 【非公式】

LINE のサービスのひとつに、「LINEマイカード」というものがある。
いくつかの種類のポイントカードをスマホにまとめる機能だ。

ポイントカードで財布がパンパンになりがちな私には、なかなかもってこいなサービスだ。
# 正直、2018年10月にロンチしてからこの数ヶ月間、カードの種類が大して増えないので、今後も使える将来性のあるサービスなのか正直怪しいのだが…

しかし、この LINEマイカード、実際使い始めてみると、ある致命的な問題に遭遇する。
LINEマイカード の起動するまでが遠い のだ。

例えば、適当な画面から LINEマイカード を開こうとすると、

  1. ホーム画面に移動する
  2. LINE を起動する(おそらくトーク画面だろう)
  3. トップページに移動する
  4. ウォレットタブに移動する
  5. マイカードアイコンを選ぶ
  6. 使いたいポイントカードを

という、 6動作も必要となる。 ((1)はいらんやろという異論はあるだろうが)

レジでの会計時にパッと使いたいのに、こんなにももたつく操作では大変使いづらい。

LINE Pay や LINE Out などであれば、 LINE アプリ内からホーム画面にショートカットを作ることができる。
しかし、 LINEマイカードについてはそのような機能はない。 (2019年3月現在)

ということで、別の方法で Android のホーム画面からワンタップで LINEマイカードに起動する方法を考えてみよう。

詳細な手順は異なるが、 考え方自体は同じなので iPhone でも実現できるはずだ。

続きを読む

Twenty Eleven Theme Extensions が SSL化 でエラー

当ブログでは、 WordPress の Twenty Eleven テーマを使っている。

このテーマでば、なぜかシングルページの表示や個別記事のページでサイドバーが表示されない。

当ブログのアクセスのほとんどは、 検索からの個別記事のページへの流入なので、個別記事へのサイドバーの表示は行っておきたいところだ。

それを実現するのが、 Twenty Eleven Theme Extensions プラグインだ。

とても古いプラグインだが、 Twenty Eleven テーマの最新版でも問題なく動いている。

ところが、 このプラグインを有効にしたところ、 Google の Search Console で怒られるようになってしまった。

調べてみたところ、 [cci]/plugins/twenty-eleven-theme-extensions/moztheme2011.css[/cci] の配信が [cci]This request has been blocked; the content must be served over HTTPS.[/cci] でエラーになってしまっているようだ。
このブログは SSL化 され https:// で配信されているのに、プラグインの CSS が http:// で配信されているためだ。

これを修正してみよう。

続きを読む