multipass を windows にインストール
windows で ubuntu の実行環境を手軽に使いたかった。
choco install multipass
UAC のPSから使う。
multipass は UAC 昇格後のPSから使うように設計されている。
基本的な使い方は以下の通り。
新しくインスタンスを起動する
multipass launch --name sample01
メモリ・ディスク容量・CPU数を指定して、新しいインスタンスを作る。
multipass launch --name sample01 --disk 20G --cpus 8 -m 8G
シェルに入る。
multipass shell sample01
シェルに入る(別の方法)
## docker exec / lxc exec 的な方法 multipass exec sample01 bash
インスタンスを削除する(データは残る。)
multipass delete sample01
削除済みのインスタンスを完全に消去する。
multipass purge
wsl から使う。
私は WSL1 を使っているので直接EXEを叩けば使える。
alias を設定しておくと便利。
alias multipass=/mnt/c/ProgramData/chocolatey/bin/multipass.exe
標準はHyper-Vが使われる。
multipassはデフォルト設定では、Hyper-V を使うので、Hyper-Vの管理画面から、インスタンスを制御できる。
もしトラブったらそこを見ればいい。
UACなしだと、delete && purge ができない。
Admin権限のユーザーであればUAC昇格 なしでも launch や shell は動くのですが、delete purge がうまく動かずHyper-Vのインスタンスが消されずに残ってしまう。
もし、Hyper-Vを使っているのであれば、次のフォルダのアクセス権限を取得しておけば、削除される。(はず)
C:\Windows\System32\config\systemprofile\AppData\Roaming\multipassd
virtualbox をバックエンドに使用する。
purge がHyper-Vでうまく行かないのであれば、 Virtualboxを利用する。
hyper-Vの代わりにVirtualBoxを使うように設定する。
choco install virtualbox multipass set local.driver=virtualbox
わたしの場合、フォルダのアクセス権限を取得しておいて、virtualbox で起動することにした。
virtualbox を使うと、ファイルは次にの場所に設置される。
仮想ハードディスクなどは次の場所に設置された。
C:\Windows\System32\config\systemprofile\AppData\Roaming\multipassd\virtualbox
万が一の場合は、ここのフォルダを全消ししたら良さそう。
multipass の Virtualbox を表示する。
https://multipass.run/docs/using-virtualbox-in-multipass-windows
hyper-v みたいに、仮想マシンの管理画面でMultipassのゲストを確認するには、次のようなコマンドで pstoolsを使って起動する。
choco install pstools PsExec.exe -s -i $env:VBOX_MSI_INSTALL_PATH\VirtualBox.exe
hyper-v に戻すには
multipass set local.driver=hyperv
multipass 便利ですね。
カーネルビルドとかやってると完全仮想化のマシンが欲しくなる。削除・作成・起動ができる環境が手に入るのはとても嬉しい。
multipass の bash-completion とかも
wsl で multipass 使うなら bash-completion もあれば便利 ubuntu から持ってきた bash-completion を bashrc に追記しておく
#export PATH="${PATH}:/mnt/c/ProgramData/chocolatey/bin/multipass.exe" alias multipass=/mnt/c/ProgramData/chocolatey/bin/multipass.exe # Copyright © 2017-2019 Canonical Ltd. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License version 3 as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. _multipass_complete() { _multipass_instances() { local state=$1 local cmd="multipass list --format=csv" [ -n "$state" ] && cmd="$cmd | \grep -E '$state'" local instances=$( \eval $cmd | \grep -Ev '(\+--|Name)' | \cut -d',' -f 1 ) local found _get_comp_words_by_ref -n := -w WORDS -i CWORD cur prev for instance in $instances; do found=0 for ((i=2; i<CWORD; i++)); do if [[ "${WORDS[i]}" == ${instance} ]]; then found=1 break fi done if [ ${found} == 0 ]; then opts="${opts} ${instance}" fi done } local cur cmd opts prev prev_opts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" cmd="${COMP_WORDS[1]}" prev_opts=false multipass_cmds="transfer delete exec find help info launch list mount purge \ recover shell start stop suspend restart umount version get set" opts="--help --verbose" case "${cmd}" in "info") opts="${opts} --all --format" ;; "list"|"ls") opts="${opts} --format" ;; "delete") opts="${opts} --all --purge" ;; "launch") opts="${opts} --cpus --disk --mem --name --cloud-init" ;; "mount") opts="${opts} --gid-map --uid-map" ;; "recover"|"start"|"suspend"|"restart") opts="${opts} --all" ;; "stop") opts="${opts} --all --cancel --time" ;; "find") opts="${opts} --show-unsupported --format" ;; esac if [[ ${prev} == -* ]]; then case "${prev}" in "--format"|"-f") opts="table json csv yaml" prev_opts=true ;; "--cloud-init") _filedir return ;; esac fi if [[ "$prev_opts" = false ]]; then case "${cmd}" in "exec"|"stop"|"suspend"|"restart") _multipass_instances "Running" ;; "connect"|"sh"|"shell") _multipass_instances "Running" _multipass_instances "Stopped" _multipass_instances "Suspended" ;; "start") _multipass_instances "Stopped" _multipass_instances "Suspended" ;; "delete"|"info"|"umount"|"unmount") _multipass_instances ;; "recover") _multipass_instances "Deleted" ;; "mount") local source_set=0 local prev _get_comp_words_by_ref -n := -w WORDS -i CWORD cur prev # Scan through the current command line to detect if the source # positional arg has been set. for ((i=2; i<CWORD; i++)); do if [[ "${WORDS[i]}" != -* ]] && \ ([[ "${WORDS[i-1]}" != -* ]] || [[ "${WORDS[i-1]}" == *=* ]]); then source_set=1 break fi done if [ ${source_set} == 0 ] ; then if [[ ${prev} != -* ]] || ([[ ${prev} == -* ]] && [[ ${prev} == *=* ]]); then _filedir -d return fi elif [ ${source_set} == 1 ] && [[ ${prev} != -* ]]; then _multipass_instances "Running" _multipass_instances "Stopped" _multipass_instances "Suspended" fi ;; "transfer"|"copy-files") _multipass_instances "Running" COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) if [[ "${#COMPREPLY[@]}" == "0" ]]; then _filedir return fi ;; "help") opts=$multipass_cmds ;; esac fi if [[ ${COMP_CWORD} -eq 1 ]]; then opts="${opts} ${multipass_cmds}" fi if [[ -n "${opts}" ]]; then COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) fi return 0 } complete -F _multipass_complete multipass