VSCodeがWSL上で起動しなくなった

VSCodeをアップグレードしてWSL上で起動しようと思ったら

$ code .
/mnt/c/Program Files/Microsoft VS Code/bin/code: 61: /mnt/c/Program Files/Microsoft VS Code/Code.exe: Exec format error

といったエラーが表示されて起動しなくなりました。

ググったところでsystemdを有効にしていると問題が発生するようで、githubに以下の解決法が載ってました。

まずWSL上で以下のコマンドを実行します。

$ sudo sh -c 'echo :WSLInterop:M::MZ::/init:PF > /usr/lib/binfmt.d/WSLInterop.conf'

その後、WSLを終了させて再起動するとVSCodeが起動できるようになりました。

PS > wsl --shutdown

参考:[WSL2][systemd][interop] Unable to Execute Windows Binary when systemd enabled #8843

Hyper-V上のUbuntuにLIS(Linux Integration Services)をインストールする。

UbuntuをHyper-Vで実行していると遅いなと感じる場合はMicrosoftが提供するLinux Integration Services(LIS)をインストールすると改善する可能性があります。

最初に、/etc/initramfs-tools/modules に次の行を追加します。

$ sudo vi /etc/initramfs-tools/modules
hv_vmbus   # 追加
hv_storvsc # 追加
hv_blkvsc  # 追加
hv_netvsc  # 追加

次のコマンドを実行して modules ファイルを再初期化し、仮想ツールをインストールしてマシンを再起動します。

$ sudo apt install linux-virtual linux-cloud-tools-virtual linux-tools-virtual
$ sudo update-initramfs -u
$ sudo reboot

再起動されると、LISがシステムに登録されます。 インストールされているかを確認するには、ターミナルで lsmod を実行し、hid_hyperv、hv_netvsc、hv_utils、hv_storvc、hv_vmbus が存在する場合、LISのインストールは成功しています。

Docker for Windows を WSLで使う

Docker for Windowsをインストールする

まずは、Docker for Windowsをインストールします。
インストールが終わったら、画面右下のシステムトレイにあるDockerアイコンから設定画面を開きます。

下記項目にチェックを入れて、TLSなしでデーモンに接続できるようにします。
これにより、ローカルのWSLインスタンスが、Docker for Windows内で実行されているDockerデーモンに接続できるようになります。 デーモンはlocalhostにのみバインドされているため、ネットワーク上の他のマシンは接続できません。

## Dockerのインストール

Docker公式HPに記載のあるとおりDockerをインストールします。

$ sudo apt update
$ sudo apt install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo apt-key fingerprint 0EBFCD88
$ sudo add-apt-repository \
   deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable
$ sudo apt update
$ sudo apt install docker-ce docker-ce-cli containerd.io

docker-composeもインストールします。

$ sudo curl -L https://github.com/docker/compose/releases/download/1.25.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose

sudoしなくてもdockerコマンドを実行できるようにdockerグループにユーザーを追加します。

$ sudo usermod -aG docker $USER

Docker for Windowsに接続するために以下の設定を.bashrcに追加します。

$ echo export DOCKER_HOST=tcp://localhost:2375 >> ~/.bashrc && source ~/.bashrc 

dockerが動くようになっていることを確認します。

$ docker info
$ docker-compose --version

ボリュームマウントのための設定

WSL上ではドライブは /mnt/d にマウントされるのに対して、Docker for Windowsでは内部で /d にマウントされているため、そのままで空のボリュームをマウントしてしまいます。

この対策として、/etc/wsl.conf に root=/ の設定を追加することで /mnt ではなく / にマウントされるようになります。

$ vi /etc/wsl.conf
[automount]
root = /
options = metadata,umask=22,fmask=11

設定した後、一旦ログアウト/ログインするか、以下のコマンドをコマンドプロンプトで実行してWSLを再起動すると / に各ドライブがマウントされるようになります。

C:\> net stop LxssManager
LxssManager サービスを停止中です.
LxssManager サービスは正常に停止されました。
C:\> net start LxssManager
LxssManager サービスを開始します.
LxssManager サービスは正常に開始されました。 

また、別の方法として、/mnt/d を /d にマウントする方法があります。

$ sudo mkdir /d
$ sudo mount --bind /mnt/d /d

ただし、この方法だと.bashrcに以下のようにコマンドを追加しておく必要があります。

$ echo sudo mount --bind /mnt/c /c >> ~/.bashrc && source ~/.bashrc

$ # パスワードなしでマウント出来るようにしたい場合は以下の設定を追加する
$ sudo visudo
$ username ALL=(root) NOPASSWD: /bin/mount

Kubernetes 1.17にしたら起動しなくなった時

Kubernetesのパッケージを一部ホールド(apt-mark hold)し忘れて1.17にアップグレードしちゃいました。そしたら、Nodeが起動しなくなっちゃいました。

$ kubectl get node
NAME      STATUS     ROLES    AGE   VERSION
testvm1   NotReady   master   46d   v1.17.0

kubectl describeでノードの状態を調べると以下のようなログが出てました。

$ kubectl describe node testvm1
略
 Failed to initialize CSINodeInfo: error updating CSINode annotation:  timed out waiting for the condition; caused by: the server could not  find the requested resource 
“Kubernetes 1.17にしたら起動しなくなった時” の続きを読む

Windows10(WSL)にHomebrewを入れる

WSLには開発用ツールが入っていませんので、まずはbuild-essentialをインストールします(あとでもいいかも?)。

$ sudo apt install build-essential

Homebrewの公式HPにも記載のある次のコマンドを実行します。

$ sh -c "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install.sh)"

次の変数を~/.profileに追加します。

export HOMEBREW_PREFIX="/home/linuxbrew/.linuxbrew"
export HOMEBREW_CELLAR="/home/linuxbrew/.linuxbrew/Cellar"
export HOMEBREW_REPOSITORY="/home/linuxbrew/.linuxbrew/Homebrew"
export PATH="/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:$PATH"
export MANPATH="/home/linuxbrew/.linuxbrew/share/man:$MANPATH"
export INFOPATH="/home/linuxbrew/.linuxbrew/share/info:$INFOPATH"

Macのsedで改行を出力する

Macのsedで特定の文字を改行に変換したいと思ったことがあると思いますが、Macでは ‘\n’ が出力できません。

$ echo "pen#apple#pen#pineapple" | sed 's/#/\n/g'
pennapplenpennpineapple

こんな感じのことをすれば出力できるようなのですが面倒です。

ってことで、

$ echo "pen#apple#pen#pineapple" | sed 's/#/\
> /g'
pen
apple
pen
pineapple

てな感じで、一旦「\」を入力した後で実際に改行し、その後続けて入力すると改行が実際に出力されます。

[Mac] Finderに表示されないライブラリ(Library)フォルダ等を表示する

Macでは通常、アプリケーションが利用する設定情報など重要な情報は /Users/ユーザー名/Library に保存されてます。
しかし、このフォルダは重要なのでFinderからは通常見えなくなっています。

どこで可視/不可視を判別をしているかというと、各ファイル(フォルダ)にはchflagsというコマンドで設定できるフラグが設定されています。
これは以下のようにlsコマンドにOオプションをつけると確認できます。

$ ls -lO /Users/hoge/
total 0
drwx——+ 10 hoge staff – 340 5 13 01:08 Desktop
drwx——+ 33 hoge staff – 1122 2 27 02:19 Documents
drwx——+ 15 hoge staff – 510 5 16 16:12 Downloads
drwx——@ 61 hoge staff hidden 2074 5 17 09:57 Library
drwx——+ 3 hoge staff – 102 10 3 2015 Movies

グループ名の後ろにhiddenという表示が確認できると思います。このフラグをFinderが確認して非表示にしています。

これを取り除いてFinderに表示させるには次のコマンドを実行します。

$ chflags nohidden ~/Library

これで表示されているかと思います。

再度表示にするには次のように実行します。

$ chflags hidden ~/Library

[Mac] Finderで見えないファイルを表示する

Finderを使っていると「.(ドット)」で始まるUNIX特有の不可視ファイルやシステムが利用する重要なファイルなど、一部不可視設定になっているファイルがFinder上で表示されなくなっていると思います。

これらはターミナルからコマンドを使うとアクセスすることができますが、以下のコマンドを実行することでFinder上からも見えるようにすることができます。

$ defaults write com.apple.finder AppleShowAllFiles -bool true
$ killall Finder

元に戻すときは次のコマンドを実行します。

$ defaults delete com.apple.finder AppleShowAllFiles
$ killall Finder

まぁ、設定するのにターミナルが必要なので、だったらターミナルからアクセスすればいいじゃんって気がしなくもないですが、どうしてもFinderからアクセスする必要があれば設定してみてください。

SSHの環境変数を利用してiptablesのポートを解放する

安いVPSなどを借りて、普段はSSHだけ解放しといて、SSH以外のポートは自宅(社内)からのみアクセスできるようにしたいと思いました。

アクセス元のIPが固定であれば特に問題ないのですが、動的に割り当てられる環境だと毎回変わってしまうので、SSHの環境変数を利用して、SSHログイン後に実行するとフィルターが解除されるような次のスクリプトを作ってみました。

#!/bin/bash
IP=`env | grep SSH_CLIENT | sed ‘s/SSH_CLIENT=\([0-9\.]*\) .*/\1/’`
sudo sed -i’.old’ -e “/–dport 80/c\-A INPUT -m state –state NEW -m tcp -p tcp -s ${IP} –dport 80 -j ACCEPT” /etc/sysconfig/iptables
sudo service iptables restart

SSHでログインした後で実行すると、環境変数を参照して「–dport 80」の記述をログイン元のIPからのみHTTPを解放するように変更します。そのため、事前に「–dport 80」に関する何らかの記述がないとエラーになるかもしれません。

その他のポートも解放したければsedの行を増せば良いと思います。

[Ansible] さくらのVPSにCentOS6を再インストール

Ansibleを使って、さくらのVPSにCentOS6を最小パッケージで再インストールするroleです。

roles/sakura-install/tasks/main.yml

– include: kickstart.yml

roles/sakura-install/tasks/kickstart.yml

– name: Download vmlinuz
 get_url: url=”http://ftp.riken.jp/Linux/centos/6/os/x86_64/isolinux/vmlinuz” dest=/boot
 become: yes
 tags: install

– name: Download initrd.img
 get_url: url=”http://ftp.riken.jp/Linux/centos/6/os/x86_64/isolinux/initrd.img” dest=/boot
 tags: install

– name: Copy Kickstart file
 template: src={{ item.src }} dest={{ item.dst }}
 with_items:
 – src: ks.cfg.j2
 dst: /boot/ks.cfg
 tags: install

– name: Configure grub.conf
 lineinfile:
 dest: /etc/grub.conf
 line: “title CentOS 6 install
    root (hd0,0)
    kernel /vmlinuz ro root=LABEL=/ ks=hd:vda1:/ks.cfg
    initrd /initrd.img”
 tags: install

roles/sakura-install/templates/ks.cfg.j2

firewall –enabled –ssh –service=ssh
# Install OS instead of upgrade
install
# Use network installation
url –url=”http://ftp.riken.jp/Linux/centos/6/os/x86_64″
# Root password
rootpw {{ root_password }}
# System authorization information
auth –useshadow –passalgo=sha512
# Use text mode install
text
# System keyboard
keyboard jp106
# System language
lang en_US
# SELinux configuration
selinux –disabled
# Do not configure the X Window System
skipx
# Installation logging level
logging –level=info
# Reboot after installation
reboot
# System timezone
timezone Asia/Tokyo
# Network information
network –bootproto=static –device=eth0 –gateway={{ ansible_default_ipv4.gateway }} –ip={{ ansible_eth0.ipv4.address }} –nameserver={{ nameserver }} –netmask={{ ansible_eth0.ipv4.netmask }} –onboot=on –noipv6 –hostname {{ ansible_nodename }}
# System bootloader configuration
bootloader –append=”console=ttyS0,115200n8r crashkernel=auto” –location=mbr –driveorder=”vda”
# Partition clearing information
clearpart –all –drives=vda
# Disk partitioning information
part /boot –fstype=”ext4″ –size=500
part pv.00 –grow –size=1

volgroup vg_00 –pesize=4096 pv.00
logvol / –fstype=ext4 –name=lv_root –vgname=vg_00 –grow –size=1024 –maxsize=102400
logvol swap –name=lv_swap –vgname=vg_00 –grow –size=512 –maxsize=2048

%packages –nobase
@core

%end

ks.cfg.j2中にroot_passwordを変数で設定していますが、これはvars/main.ymlにべた書きするか、ansible-vaultコマンドで暗号化して保存しておいてください。

このroleを実行後に再起動すれば、自動的に再インストールが始まります。