おは代々木ダイアリー

いろいろ試したメモを書きます。このブログはアフィリエイトを使用したプロモーションを含みます

PSVita用にアプリケーション開発をしたいので開発環境を構築してみる【VitaSDK】

PlayStation Vita」って個人的になかなか好きなハードなんですが、流行らずに終わってしまった不遇なハードですよね。

今回はそんなニッチなハード向けにアプリケーションを書いていくべく、開発環境を整えた、というメモになります。

はじめに

PlayStation Vitaは2011年の年末に発売されたハードですが、タッチパネル・SIMスロットがあるなど、かなり「未来のゲーム」を見越して作られたゲーム機だったなぁと当時を振り返ってみると思わずにいられませんね。

ソフト面も特徴的で、「PlayStation Mobile SDK」というSDKをユーザーに提供しており、アプリのエコシステムに個人を巻き込もうという思惑も見て取れました。当時の社会の動きとしても、OAuth2のRFCが登場するなど、各サービスがAPIを提供しやすくなっており、個人開発者にとっても胸躍る環境でしたね。自分もPlaystation Mobile

最近ではTwitter APIの有償化が囁かれていたり、無償で行うサービスの限界が見えてきて、ちょっとそういった時代とは逆行しているようにも見えなくもないですが。

そんな中登場したPlayStation Vitaですが、競合するスマートフォンに完全に市場を食われ、2019年には生産終了・ソフトの販売も完全に終わってしまいました。PlayStation Mobile SDKも正直、流行らずに終わってしまった印象があります(当時のゲームでよくある「外(Vita)でも家(PS4)でも同じソフトで遊べる!」ってそこまで流行らなかった気がする)。

界隈で人気のHENkaku

そんな不遇なPSVitaの救世主、「HENkaku(変革)」をご存じでしょうか。PSPの時代も「HEN」というのがありましたが、Vita用にも制作されているのですね。

HENkaku | What is HENkaku?

本ツールは公式サイトいわく「the first ever homebrew enabler for PS Vita and PSTV」らしいです。homebrewという「自作アプリケーションパッケージを動かすことを可能にするツール」ということです。

何それ胸アツ!!!!!!ということで、これからちょっと触ってみて、作れたらアプリなんかも作ってみたいなと思った次第です(何周遅れか・・・)

導入方法

詳しい導入方法については腐るほど解説しているサイトがあるのでそちらを参照してください。

基本的には、Vita内のブラウザが持つ脆弱性を突いてHENkakuを導入してくれるサイトにアクセス するという感じです。「HENlo vita」とかでググれば出てくると思います。

ブラウザのexploitが実行されて、謎のソフトウェアが起動してしまうの、普通に怖いですしなんかいい勉強になるなって気がしました。独自のOS開発の難しさですね。

記憶媒体の準備

これは必ずしも必須ではありません。Vita 2000(新型VITA)であれば1GBの内蔵メモリがあるのでそれを使えばよいです。

旧型Vitaを使いたい、もしくは1GBに収まらない大作自作アプリを導入するといった場合には以下のようにmicroSDをVITAカードのスロットに刺せるよう変換してくれるアダプタを購入するといいと思います。「sd2vita」で検索すると出てきます。(というかVITAのメモリーカードを置き換えるんじゃなくて、VITAのゲームのカードを置き換えるのね、とビックリしました)

自分は上記のめちゃくちゃ安いsd2vitaカードを購入したんですが、ちょっと注意が必要です。新型VITAだと蓋が閉まらなくなりますw

届いたsd2vitaのサイズ感(左:microSD 中央:sd2vita 右:vitaカード)

新型VITAだと蓋が閉まらないw

旧型ならバッチリ

なので、蓋と干渉している部分をガリガリカッターで削りました。やすりでもいいかと思ったんですが、粉末が入り込んだりしそうで嫌だなーと思いカリカリっとやりました。ケガには注意してください。

カッターで削りましたw

SDカードを挿入!

SDカードを入れて使います

SDカードは適当に最近のそこそこ速いものを使うのがいいんじゃないかなと思います。別にそんな差はないと思うし、sd2vitaがどんだけの性能出るか知らないけどw

開発環境準備

さてさて、ここからが本題。HENkakuというhomebrew enablerから起動可能なアプリを作っていくために、VitaSDKというのがあります。これも有志の方(すごすぎる!!)が作ってるSDKで、割となんでもできそうです。

Vita SDK

今回はそんなVita SDKを使って何か作れないか?ということでまずは開発環境を構築していきます・・・・が!!!!

aarch64で開発したい

VitaSDKのホームページ見ると導入方法がちゃんと書いてあるんで、その通りにやれば簡単に導入できます。

で、その手順に従って普通に開発するのもなんかアレなので、ちょうど持て余していたOracle Cloud」のARMインスタンスを使って開発してみるのはどうか、と思い立ちました。

正直、aarch64でarmv7のバイナリ吐くのと、x64でarmv7のバイナリ吐くのでどっちが有利とかそういうのわからないんですけど、なんかやってみたくなったので挑戦です。

できました

というわけで、紆余曲折ありましたが、基本的には以下のリポジトリの内容をビルドしてあげればよさそうです。

https://github.com/vitasdk/buildscripts

https://github.com/vitasdk/packages

vitasdkのsampleがビルドできて動作することを確認できました。

Dockerfile

そしてできたDockerfileがこれ。VSCodeのDevContainersで使う前提で書いていて、個人的な好みで開発に必要かなと思ったのは適宜足していきます。

github.com

(packagesのビルドを忘れていたので今頑張ってビルドしています。終わったら足します)

終わりに

もう10年近く前のハードですが、コードを書けるよう準備してみました。これからまた何か進展あったら書いていきたいと思います。

Switch版マイクラ統合版で自分で立てたサーバーで遊ぶためにセルフ中間者攻撃をする(unbound)

Nintendo Switch版マインクラフトは野良サーバーに参加することができないので、「誰かの立てたサーバーに遊びに行く」ためにはSwitchを騙す行為が必要になります。それを今回はDNSである「Unbound」を使って実施してみます。

(タイトルに中間者攻撃と書きましたが、ここではDNSで解決されるサーバーを自前のIPアドレスに変え、「Switch版マインクラフト統合版」に意図しないサーバーに繋ぎにいかせる行為をさします。)

JPRS用語辞典|中間者攻撃(man-in-the-middle attack)

背景

Switch版マインクラフト統合版は自分のワールドで遊ぶ以外は以下のゲームに限定されます

  • 「特集サーバー」と呼ばれる特定のサーバー
  • 有償で借りられるマイクラサーバー「Realms」
  • LAN内の他のマインクラフト統合版のゲーム(「クロスプラットフォームでフレンドを探す」)

つまり、マイクラの醍醐味である、「誰かが立てた自分たちだけのサーバーに参加しに行く」という行為ができないものとなっています。

一緒に遊ぶ人に「頼むからRealmsで立ててくれ!!」ってお願いするか、PC版やスマホ版を買いなおさざるを得ません。酷い。

解決法

しかし、良くも悪くもマイクラはサーバーの検証がザルなので、「特集サーバーはこっちだよ~~~」と言いながら他のサーバーに誘導すればホイホイそのサーバーに繋ぎに行ってしまいます 。今回はその習性を利用して特集サーバー以外のBedrock Serverに参加させる方法を記載します。

ここでの内容は、実施することを推奨するものではありません。最悪ネットワークが機能しなくなる可能性もなくはないので、何を実施しているのか理解したうえで、ご自身の責任と判断で実施してください。

手順

色々とやり方はあると思いますが、筆者は家庭内にIX2207とLAN内にマイクラサーバー(Minecraft Bedrock Server)を動かしているサーバーがあるのでそれにDNSサーバーをやらせることにします。

環境概要

いらないとは思うけど一応念のため環境について書きます。

サーバーとして使用しているのはMeLE Quieter2QというCeleron J4125に8GBメモリを積んでいるミニPCです。これにUbuntu20.04を入れて使ってるんですが、多分Bedrock Server動かすのにもDNSサーバー動かすのにも余剰なスペックだと思います。

ohayoyogi.hatenablog.com

ルーターはUNIVERGE IX2207を使用しています。一般家庭にはオーバースペックですが、省スペースかつ安くなっていたので導入しました。

ohayoyogi.hatenablog.com

unboundを導入する

unboundはDNSのキャッシュサーバーですが、固定レコードを設定に記載することができるので、NSDなどは導入せずにunboundを利用していきます。

sudo apt update
sudo apt install unbound

unbound -V してみると

Version 1.9.4

Configure line: --build=x86_64-linux-gnu --prefix=/usr --includedir=${prefix}/include --mandir=${prefix}/share/man --infodir=${prefix}/share/info --sysconfdir=/etc --localstatedir=/var --disable-silent-rules --libdir=${prefix}/lib/x86_64-linux-gnu --libexecdir=${prefix}/lib/x86_64-linux-gnu --disable-maintainer-mode --disable-dependency-tracking --disable-rpath --with-pidfile=/run/unbound.pid --with-rootkey-file=/var/lib/unbound/root.key --with-libevent --with-pythonmodule --enable-subnet --enable-dnstap --enable-systemd --with-chroot-dir= --with-dnstap-socket-path=/run/dnstap.sock --libdir=/usr/lib
Linked libs: libevent 2.1.11-stable (it uses epoll), OpenSSL 1.1.1f  31 Mar 2020
Linked modules: dns64 python subnetcache respip validator iterator

BSD licensed, see LICENSE in source package for details.
Report bugs to unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues

とのことで、 1.9.4が導入された模様。

次に、Ubuntuにはデフォルトで systemd-resolved というものが導入されていて、それが53番ポートを利用しているのでunboundと競合する、かつ、unboundが導入されていれば systemd-resolved は不要(多分)なので無効化します。

sudo systemctl disable systemd-resolved

これでOK。

unboundの設定

unboundの設定は /etc/unbound/unbound.conf に記載されているのですが、そこからさらに /etc/unbound/unbound.conf.d/ 内の conf ファイルを読んでいるようなので、そのフォルダ内に適当に設定ファイルを作ります。(/etc/unbound/unbound.conf.d/accept-from-home.conf としました)

内容は以下

server:
    interface: 0.0.0.0
    access-control: 192.168.1.0/24 allow
    do-ip4: yes
    do-ip6: no

    local-data: "geo.hivebedrock.network. IN A 192.168.1.100"

    forward-zone:
        name: "."
        forward-addr: <プロバイダ指定のDNS1>
        forward-addr: <プロバイダ指定のDNS2>

備考

  • access-control192.168.1.0/24 はスイッチのLANがいるサブネットで読み替えてください。
  • localdata192.168.1.100 はマイクラサーバーのIPアドレスで読み替えてください。
  • forward-addr の指定方法についてはこれであってるのかわかりません(配列で書くのか、forward-zone複数書くのか)。ご存じの方いらっしゃったら教えてください。

設定が終わったら、unboundを再起動します。

sudo systemctl restart unbound

(ここでsystemd-resolvedを殺しておかないとエラーが出ます。)

Switch側の設定

Switchのインターネットの設定からDNSを構築したDNSサーバーのIPアドレスにします。

今回は「The Hive」のドメインを自サーバーに誘導するようにしたので、以下のようにリストで見ると自サーバーの情報で置き換わっていることがわかります。PING値もローカルネットワークなのでべらぼうに低いですw

The Hiveが自分のサーバーになっていればOK

そして実際に選んでみて自サーバーに参加できればOKです。

(オプション)ルーターの設定

ルーターDNSプロキシ機能がある場合は、こちらに設定を記載することでSwitch側のDNS設定をいじらなくて済むようにすることができます。

ix2207# en
ix2207(config)# proxy-dns ip enable
ix2207(config)# proxy-dns server 192.168.1.100 priority 254

設定については上記コマンドで、proxy-dns ip enableDNSプロキシを有効化し、192.168.1.100 (今回のDNSサーバー)を優先度254(高い方が優先される)で追加する設定にしてみました。

これで、DNSサーバーがルーターを向いている状態にしておけば(というかDHCPで払い出す際のDNSルーターに向けておけばよい)、自動的に今回立てたDNSサーバーへ問い合わせるようになるので「たかがマインクラフトやるためだけにSwitchのDNSサーバーいじるの億劫だぜ」って人はこれするとよいかもしれないですね。

ほかのやりかた

不自由なマインクラフト統合版のために、自由にサーバーに繋ぎにいけるようにするツールはすでに色んな人が検討しています。

中でもOSSで開発されている「BedrockConnect」はすごくて、繋ぎに行くとマイクラ内でUIが立ち上がって好きなサーバーに移動することができます。

github.com

DNSでポチポチレコード書くのより数段楽なので、いろんなサーバーに行く人はこれを導入してみるのもいいかもしれません。

上記GitHubのREADME.mdには、上記サービスが使えるDNSサーバーの一覧も記載されていますが、他の人が運営するDNSサーバーに繋ぎに行くのはガチのマジで中間者攻撃を食らう可能性があるのでオススメしません。

ほかのやりかた②

ルーターの機能でやればいいじゃん?

はい、その通りですYAMAHAルーターとか、OpenWRTとかの機能で実現できると良いですね。UNIVERGEシリーズにはなかった・・・

【追記:20230201】

@n2naokun2 さんよりご指摘いただき、UNIVERGE IX2207でも dns host コマンドを使用すれば問い合わせに対して指定したIPアドレスを返せるようになるらしいので、今回はその設定のみで対応可能でした。ご指摘ありがとうございました。

具体的なコマンドは以下の通り。

ix2207# en
ix2207(config)# dns host geo.hivebedrock.network ip 192.168.1.100

コマンドリファレンスはちゃんと読みましょう。

製品マニュアル・詳細: 製品マニュアル・検索一覧 | NEC

というわけで、unboundももはや不要になったのでQuieter2からアンインストールして systemd-resolved を最有効化しました。

sudo apt purge unbound
sudo systemctl enable systemd-resolved
sudo systemctl start systemd-resolved

色々と遠回りしましたが、勉強になりました。IX2207便利!

【追記ここまで】

終わりに

というわけで、Switch版マインクラフト統合版を使って、自分で建てたサーバーに参加する方法でした。

この方法を応用すれば、ほかの人のサーバーにも遊びに行けますので、遊べる幅がぐんと広がると思います。

みなさんもよきマイクラライフを。

WSL --updateしてからSSH経由でWSLが起動しなくなって困った

久々に触ったパソコンでWSLでもしてみるかなーーーと思ったら wsl --list --online で表示されるディストリビューションが古く、あれ?!アップデートが必要??となって迂闊にも wsl --update したらSSH経由でログインしてwslコマンドを叩くことができなくなりました。

コンポーネント版とプリインストール版

WSLには、Windowsのオプション機能として導入できるWSLと、Microsoft Storeからダウンロードできるストア版のWSLが存在するらしいです。

参考: ASCII.jp:WSL(Windows Subsystem for Linux)がMicrosoftストア版に一本化される

今回触っているパソコンは、Windows 10 Homeで、低スペックにもかかわらず戯れで導入した「オプション機能として導入できるWSL」が入っていました。

それを上にも書きましたが、「久々に触るからアップデートするぞ~~~」wsl --update を叩いてしまったからあら大変。問題が起こってしまいました。

起こった問題: SSH経由でWSLコマンドが叩けなくなった

以前も書きましたが、ぼくはWSL2にSSHで乗り込んでWindows 10 Homeなパソコンを開発サーバーにするということをしています。

ohayoyogi.hatenablog.com

上記のような芸当をするためには、SSHで乗り込んで nc コマンドを叩くということが必要になるので、乗り込んだ先でWSLコマンドが叩けないといけません。

が、以下の画面。

wsl.exeで「ファイルにアクセスできません。」

「ファイルにアクセスできません」・・・ってなんじゃそりゃ~~~~

ちゃんとモニタ繋いでローカルにWSLコマンド叩くことはできるのにな~~~~~

解決策: ストア版をアンインストールする

どうやら、これって C:\ProgramData\Packages のアクセス権が特殊になっていて、SSHでログインしたユーザーからは触れなくなっていることが問題っぽい??

  • アクセス権限を修正すれば使えるようになる
  • Windows Update (KBいくつだったか忘れた)をアンインストールすれば解決

調べてみると、上記のような解決策がでてきましたが、アクセス権を修正したこと絶対後になって忘れるし、当該番号のWindows Updateは適用されていなかったしで最後の手段で update したものを元に戻してみることにしました。つまり、ストア版のアンインストールです。

Windows 10の設定の「アプリと機能」から、「LinuxWindows サブシステム」をアンインストールします。

ストア版をアンインストールしてみる

で、アンインストールが完了したら(ここで念のために再起動しました。)気を取り直して… ディストリビューション再インストール!!

wsl --install -d Ubuntu

Ubuntu再インストール

とまぁ、再インストールしてみましたが再インストールが必要かはわかりません。自分の場合、なぜかフォルダが圧縮されていたりしてちゃんと起動しなかったので気持ち悪くて再インストールしてみましたが、 wsl --update で単に起動しなくなったケースでは再インストールは不要かもしれません。

終わりに

というわけで、誤ってストア版に上げてしまったwsl.exeを戻して事なきを得ましたという記事でした。どなたかの参考になれば幸いです。

しかし、これからストア版に統一されるっていうのにこんな不具合抱えていて大丈夫なのか?と心配になりますね。このマシンも結構古くから使っているので最近のWindows10をクリーンインストールしたりすると良くなったりするんだろうか。

おまけ

なんでそもそも前回までで開発サーバー用意できたのにまたWSLいじってるの?と思われた方もいらっしゃると思いますが、ゲーミングPC付けっぱなしにしているのに罪悪感を覚え、低消費電力な録画サーバーに開発サーバーを兼務させられないか?と試してみているところでした。

もしよければ、Twitterもフォローお願いしいます~

WSL2 Bashを使うことですべての問題が解決したかと思われたWindowsリモート開発だったが結局WSL2にSSHした件

Windows10 HomeなゲーミングPCに乗り込んでリモート開発すべく、WindowsにOpenSSHサーバーを導入してVisual Studio Codeのリモート開発拡張機能を使ってきました。開発を進めていく上で遭遇した

  • SSH経由のgit pullがハングする
  • DevContainersが使えない

といった不具合を乗り越えるため、WSL2 Bashをデフォルトシェルに指定することで解決するという内容を前回記事で書きました。

ohayoyogi.hatenablog.com

まだ残っていた問題

デフォルトシェルをWSL2にすることで、当初の「SSH経由でのgit pull」や「DevContainersの利用」はできるようになったものの、新たな問題が発覚しました。

それは

  • ssh-agentのForwardingが効かない

ということです。「WSL Bash SSH Agent Forward」みたいなググり方をすると、使用するSSHクライアントによって癖があるようで、「Windowsssh-agent.exeに登録した鍵をWSL2 SSHで使用する」みたいな内容がよく出てきました。が、今回はそれとは違うような気がしています。

(そもそも、SSHのAgentForwardingってどうやって実現されているのかよくわかってないです。SSHサーバーが環境変数に参照すべきAgentの宛先を設定して、それをSSHクライアントが使用している…?詳しい人いたら教えてください…)

で、さんざん調査してわかったのはどうやらWindows向けのOpenSSHサーバーはAgentForwardingには未対応ということです。おお、マジか・・・

Agent Forwarding Windows client to Windows host not working? · Issue #1865 · PowerShell/Win32-OpenSSH · GitHub

というわけで、AgentForwardningが効かないのはちょっと(だいぶ)つらいので、頑張って解決してみようという内容になります。

解決方法

いままで開発してきて、Windows向けのOpenSSHクライアントからLinuxのOpenSSHサーバーに向けてつないだ時はAgentForwardingが機能することは確認できていたので、WSL2のLinuxに直接SSH接続すればいい ということになります。

が、ここで立ちはだかるのは2つの壁です。

  • WSL2でsshdを動かす
  • WSL2のsshdへ何とか繋がるようにする

一番目のsshdの動かし方は wsl sudo service sshd start とかやっちゃえばまぁ解決です。問題は二番目の「WSL2のsshdへの繋ぎ方」です。

これについては何が問題かというと、WSL2で使用されるIPアドレスは起動のたびに変わってしまうということが言われていて、現在固定する方法がない(Hyper-V使える人は固定できるみたい?まぁWindows Proエディションの話なので今回は対象外)ということです。

世の中の先人たちは、これに対して WSL2のIPアドレスを取得してnetshでポートフォワーディングの設定を書く という対処方法をよくとっているみたいです(著者調べ)。以下、参考にしたサイトです。

リモートマシンのWSLにOpenSSHサーバとDockerを入れてVSCodeからリモートアクセスできるようにする - てのひら

ただ、これ開発時以外もずっとポートフォワーディングしてるのが非常に気持ち悪いですし、そもそもタスクスケジューラとか普段使わないので設定したことを忘れて放置してたりしそうで怖いです。何よりファイアウォール開けるのが嫌ですね・・・

というわけで、別の方法をとりたいと思います。

Windowsホストを踏み台にしてWSL2にログインする

Windowsに開発時以外もポートフォワーディングさせるのちょっと怖いですし、昔ながらの「SSHのProxyCommandを使って接続する」という方法をとってみたいと思います。「踏み台」ってやつですね。

【ポートフォワーディングさせる場合】
クライアントマシン ==SSH==> WSL2(開発機)

【踏み台にする場合】
クライアントマシン ==SSH==> Windows(開発機) ==SSH==> WSL2(開発機)

そうだnetcatしよう

さて、踏み台にするにあたって「WSL2のIPアドレスはどう扱う?」という問題は依然としてあります。

が、ここで天啓。これ、フツーに「WSL2にnetcatさせればいいのでは????」となりました。

つまり、ProxyCommand で踏み台に wsl nc localhost 22 させればよいのです。

やりかた

というわけで早速 .ssh\config を書きました。WinHomeは開発機のホストで、DevWSLは開発機内のWSL2のホストです。

Host WinHome
  HostName 1.2.3.4
  # 以下略

Host DevWSL
  HostName localhost
  Port 22
  ProxyCommand ssh WinHome wsl nc %h %p
  # 以下略

接続時は ssh DevWSL とするだけでOK!。VSCode からもDevWSLを開くようにポチポチしているだけでWSL2に入って開発することができます。

結局、AgentForwardingならず

はい、ここまで引っ張っておいてアレなんですが、結局AgentForwardingできていません。なんかどうもWSL2に導入するOpenSSHのバージョンによってはForwardingできない問題が発生するそうです。なんじゃそりゃー!

WSL2のOpenSSH Agent Relayが動かなくなったので調査した

結局DevContainersでいく

結果としては失敗に終わりましたが、実はAgentForwardingできる方法がありました。

VSCodeのDevContainersのAgentForwarding機能を使用する という方法です。

これ、どうやらSSHとは異なった経路(?)でAgentForwardingしているようで(確かにDockerに入るのSSHじゃないもんな)、たぶんバケツリレー的に経由するホストの各地点でAgentForwardingできていなくてもSSHクライアントと連携できるんだと思います。(適当言ってます。間違ってたら指摘してください…)

devuser@0cf0909ae8ca:/workspaces/hogehoge $ ssh -T git@github.com
Hi ohayoyogi! You've successfully authenticated, but GitHub does not provide shell access.

え?じゃあこれWSL2 Bash経由で繋いでてもDevContainersだったらPortForwardingできたってこと~~~????っていう疑問もわくんですが、怖いので調べていません・・・(情報求む)

終わりに

というわけで、WSL2に対してnetshによるポートフォワーディングを使用せずにSSHで繋ぐ方法を考えてみました。

WSL2にAgentForwardingできたら最高だったんですが、それは時間が解決してくれるということで、今は頑張って何とかWSL2内でpullしてから鍵を使った作業はDevContainers内でどうにかするという方法をとりたいと思います。

それでは、みなさまもよきリモート開発ライフを。

nodeなどのコンテナイメージでdevcontainerを使うとuidが変わらなくて困る問題への対処

Visual Studio CodeのRemote Containers機能(Dev Containers)には、VSCodeの実行ユーザーのUIDでコンテナ内のユーザーのUIDを更新してくれる便利な機能があります。

例えば、UIDが1002のユーザーでVSCodeを立ち上げていて、コンテナ内で作成したユーザー devuser を使用したとき、コンテナ内の devuser のUIDは1002に上書きされるといった挙動になります。これは、手元のディレクトリをコンテナ内にマウントしていて、それをVSCodeでいじる場合に、UIDが異なってしまうという問題を回避することができるのでとても便利。

使い方

使い方は簡単で、devcontainer.json に以下のように remoteUserupdateRemoteUserUID を指定するだけ。remoteUser にコンテナイメージ内に存在するユーザー名を指定することでコンテナを開いたときに使用されるユーザーを指定でき、かつ updateRemoteUserUID を有効にすると 指定したユーザーのUIDが現在のログインユーザーのUIDになってくれます

{
  "remoteUser": "devuser",
  "updateRemoteUserUID": true,
}

説明のためupdateRemoteUserUID も念のため指定していますが、このオプションはデフォルトで有効になっているので明示的な設定は省略可能です。

DevContainersに使用するコンテナイメージには、以下のようなDockerfileを考えてみます。

FROM ubuntu:20.04

ARG USERNAME=devuser
ARG USER_UID=1234
ARG USER_GID=$USER_UID

# Create the user
RUN groupadd --gid $USER_GID $USERNAME \
    && useradd --uid $USER_UID --gid $USER_GID -m -s /bin/bash $USERNAME 

Dockerfile では UID 1234 で devuser というユーザーが作成されていますが、Dev Containersで開いてみると、見事IDなどが変わっていることがわかります。

devuser@cbb03f77d869:/workspaces/devcontainer_example$ id
uid=1000(devuser) gid=1000(devuser) groups=1000(devuser)

devuser@cbb03f77d869:/workspaces/devcontainer_example$ ls /home/devuser -la
total 28
drwxr-xr-x 1 devuser devuser 4096 Jan 12 04:17 .
drwxr-xr-x 1 root    root    4096 Jan 12 04:17 ..
-rw-r--r-- 1 devuser devuser  220 Feb 25  2020 .bash_logout
-rw-r--r-- 1 devuser devuser 3771 Feb 25  2020 .bashrc
-rw-r--r-- 1 devuser devuser  807 Feb 25  2020 .profile
drwxr-xr-x 6 devuser devuser 4096 Jan 12 04:17 .vscode-server

ちゃんと HOME のパーミッションも変わっていてとてもGOODですね。

問題点

「指定したユーザーのUIDが現在のログインユーザーのUIDになってくれます」と書きましたが、これが効かないケースもありました。

というのも、変更先のUID(つまりログインユーザーのUID)がコンテナイメージ内ですでに使われていた場合、このオプションは有効に働かず、コンテナイメージ内のUIDがそのまま使われてしまいます。

例えば、「node」のコンテナイメージはデフォルトで node というユーザーがUIDが1000で作成されているので、VSCodeを起動しているユーザーのUIDが1000だった時にバッティングしてしまい、devuser は作成した時点の UID 1234 の状態のままでDev Containersが立ち上がってしまいました。

解決方法

ここで、この問題を解決できる方法を考えてみました。

1. そのユーザーをそのまま開発にも使う

すでに使いたいUIDが使用されてしまっているのであれば、remoteUser にそのUIDが割り当てられているユーザーを指定してしまうのも手です。

ただ、これだとユーザー名が自由に選べませんし、意図した通りにセットアップされているかはDockerfileを読み解いていくしかありません。そもそも、Dev Contaienrsで乗り込むコンテナにユーザーがあったとしても、そのユーザーをそのまま活用するケースに出会ったことがありませんし、こういうユーザーは封印前提で次に示す解決策2を取るのがいいのかなと思います。

2. そのユーザーのUIDを変えてしまう

1でも書きましたが、これはこのユーザーがDockerfile作者の想定した通りに使えなくなる可能性があるので、「封印前提」で考えるべきでしょう。

RUN groupmod -g 12345 node && \
    usermod -u 12345 -g 12345 node

上記のように、node ユーザーがすでに使いたいUIDを使っていて邪魔なのであれば、そのユーザーのUIDを使わない値にしてしまえという発想です。(消しちゃってもいいのかもしれない)

このようにすることで、uid 1000がすでに使われていたとしてもログインユーザーのUIDに合わせてDevContainers内のUIDを上書きすることができるようになりました。

終わりに

以上、ゴリゴリっと書いてしまいましたが、DevContainersのremoteUser の問題と対処でした。

(読み返すとUID, VSCode, DevContainersと表現が揺れまくっているのが気になる…)

WindowsへのVSCode SSH Remoteに疲れたのでWSL bashを使ってLinuxっぽく使うことにした

リモート開発、便利ですよね。今回はWindows 10 HomeなPCに乗り込んで開発するという内容で記事を書いてみたいと思います。

想定読者

この記事はこんな方に向けて書いています。

  • Windows マシンに乗り込んでリモート開発をしたい!
  • Windows 10 ProのライセンスがないのでHomeでもできる方法を探している

ぼくはDellのG5 5000というゲーミングPCを開発環境として使っていて、先月も増設用のメモリなどを買ったところなんですが、これをリモート開発に使用したい!だけどOSがWindows 10のHomeエディションといういかんともしがたい状況なのです。

ohayoyogi.hatenablog.com

追記20230112:やっぱり駄目でした

どうもやはりssh-agent周りが厳しく、期待通りとはいきませんでした。ほかにやり方考えます。

背景

そもそもなぜリモート開発をしたいかというと、

  • どこからでも1つの環境に乗り込んで手慣れた環境で開発をしたい
  • かといって軽いノートパソコンではスペックが足りない
  • あんまりヘビー(物理)なマシンを持ち歩きたくない

などなど、皆様様々な理由があると思います。自分もインタプリタ系の言語でツールを書いているうちは試行錯誤に時間がかかるので問題にはならないんですが、TypeScriptなどトランスパイルを挟む言語だったり強力な補完を効かせたい言語で開発を行っているとなかなかにストレスが溜まってきます。

補完なんて使わずにメモ帳でも書けて、試行錯誤も1回で済むスーパーマンであればそういったストレスも少なくて済むのでしょうが、ぼくはゴリゴリにトライアルアンドエラーを繰り返して物を作っていく人間なのでそうはいきません・・・

リモート開発環境候補

ここに至るまでに考えた(試した)ものを記載します。

1. リモートデスクトップVNC, RDP, TeamViewer)

VNCやRDPを通して開発するという方法です。GUIを使う方法でネットワークの帯域は必要になりますが、ローカルネットワークであれば快適に開発できます。

「パワーで解決」という感じなので、ネットワークなどの環境に左右されがちなのが難点でしょうか。これがどんなところでも快適にできる未来が来るといいですね。

また、RDPを使うにはWindowsのProライセンスが必要になるので、使える人は限られるのではないかと思います。(自分が開発に使用しているゲーミングPCもHomeライセンスです)

2. Visual Studio Code のリモート開発機能(Linux

???「SSHでよくね?」

はい、昔ながらの方法、「SSH経由でVIM」。これが最強です

・・・ではなくて、最近はVisual Studio Codeのリモート拡張機能を使うとVSCodeの言語サーバー(補完などを提供するサーバー)をリモートで動かしつつ手元に表示して開発することができます。

おお、それなら無料で使えるOracleCloudのARMインスタンスを使ってみてはどうか?ということで、VSCodeのリモート機能で乗り込んで開発してみました。(ARMインスタンスは普段以下のような使い方をしています。)

ohayoyogi.hatenablog.com

が、やはりゲーミングPCのパワーは強く、見劣りするなぁというのが正直な感想です。まぁ使えなくはないんだけど…

3. Visual Studio Code のリモート開発機能(Windows

実はVisual Studio Codeのリモート機能にはSSHWindowsにも乗り込むことができます。

「エーWindowsSSH?」と思われる方もいるかもしれませんが、Windows 10には、とあるバージョンから「OpenSSHサーバー」をオプション機能としてインストールする機能が備わっていますので、簡単にSSHを導入できるのです。

実際に使ってみると、デスクトップPC内で作業しているような快適さでリモート開発できることがわかると思います。

Visual Studio Codeを使用したWindowsでのリモート開発の問題

というわけで、ここまで試してきた中でリモートのゲーミングPC(Windows 10 Home)にSSH経由でVSCodeで乗り込むという方法で快適なリモート開発環境が構築できました。これでしばらくは問題なく開発することができていたんですが・・・

しかし、これにも問題が…

  • SSH周りで問題がありそう?(SSHでgit pullできないとか)
  • devcontainerが使えない

一番目はターミナルでSSHしている場合は普通にgit pullできるのでVSCode拡張機能側の問題で、二番目はdevcontainerの拡張機能Windowsに対応していない(/etc/passwdとか参照しようとしてコケてる)というのが問題です。

Windowsでリモートはやはりマイナーなのか・・・

これについてはLinux互換の何かを動かせばよいので方法は複数考えられて、

  • VirtualBox など VMを立てる
  • WSL2 の LinuxSSHサーバーを立てる
  • デフォルトシェルをWSL2にしてみる

などがあります。が、1つ目はリソースをフルに活用できない問題、2つ目はWindowsとWSLでは内部で異なるIPアドレスになっているのでフォワーディングが別途必要になるなどから、今回取ってみるのは3つ目のWindowsのデフォルトシェルをWSL2のbashにしてみるという作戦です。

解決手順

解決は以下の3ステップです。

デフォルトシェルをWSL2のbashにする

まずはリモートで乗り込む先のWindowsマシンのデフォルトシェルをWSLのbashに変えてしまいます。サーバーにログインした後、レジストリエディタで HKEY_LOCAL_MACHINE\SOFTWARE\OpenSSHDefaultShell という名前で C:\Windows\system32\bash.exe という値の文字列を登録します。

HKEY_LOCAL_MACHINE\SOFTWARE\OpenSSH

PowerShellで行う場合は以下の通り。

New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Windows\system32\bash.exe" -PropertyType String -Force

参考: OpenSSH Server configuration for Windows | Microsoft Learn

VSCode Remote SSH の設定を「Linux」に

これでデフォルトシェルがWSLのbashになったので、VSCode側のリモート接続設定を Linux にしましょう。

設定の "remote.SSH.remotePlatform" の値を ホスト名: "linux" という形式で記載します。

{
  "remote.SSH.remotePlatform": {
    "hogemachine": "linux"
  }
}

このようにすることで、対象マシンがLinuxマシンと判断され、VSCodeもsh前提の動作をしてくれるようになるようです。

Windows設定のままだと以下のようなエラーが出てしまいます。PowerShellとかcmdとか探そうとしてしまうみたいですね。

[10:40:38.083] "install" terminal command done
[10:40:38.083] Install terminal quit with output: ]0;C:\Windows\System32\cmd.exebash: powershell: command not found
[10:40:38.083] Received install output: ]0;C:\Windows\System32\cmd.exebash: powershell: command not found
[10:40:38.084] Failed to parse remote port from server output

WSL2内でのdockerの設定を変える

何が原因なのかはわかっていませんが、devcontainerを使用しようとすると以下のようなエラーが出ました。

[2023-01-10T14:30:09.008Z]  => [internal] load build definition from Dockerfile.extended              0.0s
 => => transferring dockerfile: 3.30kB                                     0.0s
 => [internal] load .dockerignore                                          0.0s
 => => transferring context: 2B                                            0.0s
 => ERROR resolve image config for docker.io/docker/dockerfile:1.4         1.0s
------
 > resolve image config for docker.io/docker/dockerfile:1.4:
------
ERROR: failed to solve: rpc error: code = Unknown desc = failed to solve with frontend dockerfile.v0: failed to solve with frontend gateway.v0: rpc error: code = Unknown desc = error getting credentials - err: exit status 1, out: `error getting credentials - err: exit status 1, out: `A specified logon session does not exist. It may already have been terminated.``

どうもcredentialsを取得しようとしてるときにエラーが発生しているようなので、設定ファイルを見てみます。

{
  "credsStore": "desktop.exe"
}

desktop.exe とか怪しすぎるので、適当に無効な設定にしてしまいます。

{
}

これで再度devcontainerで開いてみて無事ビルドが通ればOKです。

終わりに

以上、開発環境構築記事でした。Windowsにリモートで乗り込んで開発したいとかいう珍しい方がいらっしゃったら参考になれば幸いです。

AmazonブラックフライデーでDell G5を増強しました

普段開発に使用してるゲーミングPC「Dell G5 5000」にパーツの増設を行ったのでそのメモ。

はじめに

今までもちょくちょくいじってきましたが、年末ということもあるので、PCパーツ買って整理するのもありかなと思い、購入に踏み切りました。

ohayoyogi.hatenablog.com

ohayoyogi.hatenablog.com

買ったもの

既存のゲーミングPCに増設するだけなので、正直そんなインパクトないですw

SSD: KIOXIA EXCERIA PLUS G2 1TB

まずはシステムディスクの増設用のSSDです。これは以前ノートパソコンのSSDを換装して出た余りを使っている状態だった(というかG5もここまで真剣に使うとは思っていなかった)ので、ちゃんと開発に不便しないように大きめのNVMeなSSDを買いました。

ディスクの大きさについては正直、開発のソースコードGitHubに上げますし、写真データもPrime Photoに上げるなどクラウド前提の立ち回りをするつもりなので、そんなに大きな容量は必要ないんじゃないかと思いますが、まぁ大は小を兼ねますので。

一応データ置き場として1TBの2.5インチSSDも積んであります。(以前購入したTranscendSSD

(これは余談ですが、ソースコードや依存モジュールなど、ビルド時に頻繁に読み書きするのを高速なNVMeに置いた方がいいんじゃないかーと思ったりもしますね。これ以上考えると進まなくなるのでとりあえずSATAにデータ、NVMeにシステムとしてしまいました)

写真をぺたー。これも余談ですが、販売はバッファローなんですね。

KIOXIA EXCERIA PLUS G2のパッケージ

さらに余談ですが、エクセリアといえば。(エクバシリーズ好きです)

メモリ: CORSAIR VENGEANCE LPX DDR4-3200MHz 2022限定モデル

続いてメモリです。今まではごちゃまぜのメモリ4×8GB構成でしたが、安かったのでこれを機に2×16GBで32GBとすることにしました。(増えてない)

換装した結果としては、G5で問題なく利用できているのですが、フルスペックは活かせていません。そもそも、このメモリを3200MHzで動作させるにはXMPに対応したマザーボードが必要ですが、Dell G5 5000はこれに対応していないため定格の2133MHzでの動作となる模様です。

Dellのマニュアルを読むと2666MHzでうごくっぽいぞとワクワクしていたんですが、

G5 5000 セットアップと仕様 | Dell 日本

Dell G5 5000のメモリ構成(「G5 5000 セットアップと仕様」より)

そんなことありませんでした。どうやら2666MHzで動作するのはDell純正のものを装着した場合のみ、らしい。

そこまで違いがわかるか、と言われると絶対そんなことないんですが、フルスペック出てないのは気持ちが悪いので、このメモリは自作PCするときにまた活躍してもらおうかなと思います。(とりあえずG5に付けてはおくけど)

CORSAIR VENGEANCE LPX

装着

というわけで、装着~~~~

Dell G5 5000にメモリとSSDを増設

(ほこりが汚い)

システムのセットアップ

と、今回はシステムディスクの換装を行ったので、Dell G5 5000をまっさらな状態にリカバリしてから開発環境を整えました。

OSの再インストール

Dell OS Recovery Tool」というものを使用することで、Dellのマシンに応じたUSBリカバリディスクを作成することができるので、これを使いました。(Optiplex 9020のリカバリでもお世話になりました)

www.dell.com

ポチポチとダイアログに従ってモデルやらOSの種類やらを選ぶとUSBに書き込まれるので、そこまで難しくないと思います。あとはいつも通りWindowsクリーンインストールされるのでWindows Updateで当たるドライバを片っ端から適用していけばOKです。

Windows Subsystem Linuxのインストール

もはや開発環境としてDockerは外せないですね。というわけで、まずは最初にWSL(WSL2)の導入。

最近のWindows10はすごいので、WSLコマンドが初めから入っています。管理者コマンドプロンプトから以下のコマンドをたたいてWSLを最新化したのち、

wsl --update

Microsoft StoreからUbuntuをインストールするだけ。

Microsoft StoreでUbuntuをインストールする

楽ちんですね。WSLのデフォルトバージョンを2にするのには以下のコマンド。

wsl --set-default-version 2

Docker Desktopのインストール

正直Docker DesktopのGUIは要らないんですが、インストールでごちゃごちゃするのも面倒なため、Docker Desktopを入れてしまいました。まぁ個人利用ならライセンス的にも問題ないのでいいかなと。

https://www.docker.com/products/docker-desktop/

その他もろもろ

必要に応じて必要なものを入れていきます。

などなど。まぁdockerを使えるようにしたらpythonだのnodeだのはコンテナで用意すればいいので、実質必要なのはGitとVisual Studio Codeぐらいかなという感じ。

終わりに

リカバリから始めましたが、作業環境を整えるのはそんなに時間がかかりませんでした。ドライバ回りもWindows Updateでほとんどあたりますし、Docker環境とVSCodeが整えば開発ツール系が一式揃ってしまうので、すごい時代になったなぁと感じずにはいられませんね。

と、ここまでをブラックフライデー直後の土日あたりに記事で公開する予定だったんですが、なんだかんだ年を越してしまいましたw今見たらAmazonで買ったパーツ類がブラックフライデー当時より安くなってて悲しくなっています。