以前 Windows の開発環境を scoop で構築しているということを書きました。
その際に、scoopを継続的に使っていくためのツール ScoopPlaybook を書いたことに触れました。 今回はその ScoopPlaybook の紹介です。
目次
TL;DR
- ScoopPlaybook という PowerShellモジュールを作った(2年近く使っている)
- scoop で何をインストールするかをYAML定義して使える
- Scoop-Playbook コマンドでYAML通りに実行される
- 使い心地は、Ansible Playbook のYAML定義とコマンドにインスパイアされている
scoop 使っていて、YAMLでインストールするツールを定義したい方は使ってみてください。
目指す姿
私は普段からOS環境を壊すことをアリと考えています。 ただし壊すからには再構築にコストをなるべくかけたくないため、対象のマシン上で再構築がコマンド1つでできるようにしています。 macOS は Homebrew や defaultsをAnsible Playbookで構築し、Ubuntu は Ansible Playbook で構築しています。
Ansible Playbook を使うことで、ほどよく緩くいい感じの目指す姿が可能になります。
- 利用する開発ツールをYAMLに定義して
- 何度実行しても同じ結果に収束させる
例えば Homebrew でインストールする場合は次のように定義できます。
# roles/homebrew/tasks/main.yaml - name: 'homebrew packages installation' homebrew: name: '{{ item.name }}' state: "{{ item.state|default('present') }}" with_items: "{{ homebrew_packages }}" # roles/homebrew/vars/main.yaml homebrew_packages: - name: autoconf - name: awscli - name: aws-iam-authenticator - name: azure-cli # and so on....
一度定義してしまえばツールを定義に追加したり、アンインストール ( state: "absent"
) を指定するだけとメンテナンスが非常に簡単です。
site.yml を置いたルートパスでいつも同じコマンドを実行するだけで、YAML定義通りに環境が構築されます、便利。
$ ansible-playbook -i hosts site.yml
sudo が必要な操作 (become) なら、実行時に入れるだけです。
ansible-playbook -i hosts site.yml --ask-become-pass
WSL との相性もよく、気軽に環境を壊してサクッと作り直すことがコストでなくなります。
自分の環境にどんなツールをいれているかを説明することがふとしたときにあるのですが、定義によって、いつでも確認したり継続的に変更をかけたり、場合によっては他人に共有できるのは個人的に好みです。
WindowsでAnsiblePlaybook のようなアプリケーションインストール基盤を作る
環境の再構築はWindowsでもたびたび行います。(OSいれなおしでなくてもリセットはやりますよね)
scoopを使っていくことに決めたときに、コマンドの羅列地獄になるのは嫌だと思いました。 しかしAnsible をWindows localhost に実行はサポートされていないので、Ansible Playbook のような定義とインストールを提供することにしました。(WSLからAnsible実行するというのはナシ派) その晩にザクっと書いたのが ScoopPlaybook という PowerShell Module です。
あんまり使い方とか書いていないので、どういう利用をするのか紹介します。
scoop の通常のインストール
例えば、scoop でgow、jq、time、unzipをインストールする場合、コマンドラインで次のように実行するでしょう。
scoop install gow jq time unzip
あるいは、次のようにコマンドを分けているかもしれません。
scoop install gow scoop install jq scoop install time scoop install unzip
アンインストールもコマンドラインで制御できます。
scoop uninstall gow
入っているツールは scoop list
で見えますが、ほかの環境や再構築、追加インストールをするときはいちいち考えるの嫌になります。
ScoopPlaybook で定義からインストールする
ScoopPlaybook はAnsible Playbook でやっていたのと同じ目指す姿を提供します。
- 利用する開発ツールをYAMLに定義して
- 何度実行しても同じ結果に収束させる
利用方法は Ansible Playbookに合わせています。
ルートパス/site.yml
に 利用する role のYAML定義し、ルートパス/roles/バケット/tasks/main.yml
にツールをYAML定義したら、- ルートパスで、
Scoop-Playbook
コマンドを実行すると、Scoopバケットやツールが定義通りにインストール/アンインストールされる
YAMLで定義して、コマンド1つで定義を実行。ただそれだけです。 実際にどうやるのかイメージしにくいので利用例を見てみましょう。
利用例
先ほどのmainバケットのツールをScoopPlaybookでYAML定義してインストールしてみましょう。 ScoopPlaybook モジュールとYAM解析モジュールをインストールします。PowerShell 5.1 以降で動作します。
PS> Install-Module ScoopPlaybook -Scope CurrentUser PS> Install-Module "PowerShell-Yaml" -Scope CurrentUser
適当にルートパスを切ります。
md ./begin cd ./begin
まずは、インストールしたいアプリの定義YAMLを ルートパス/roles/main/tasks/main.yml
に定義します。
PS> mkdir roles/main/tasks PS> New-Item roles/main/tasks/main.yml PS> vim roles/main/tasks/main.yml
- name: "Install main tools" scoop_install: state: present bucket: main name: - gow - jq - time - unzip
インストールするロールを指定したYAML定義 site.yml
をルートパスにおきます。
PS> New-Item site.yml PS> vim site.yml
今回のロールは main なのでこれを1つ指定します。
name: Windows Setup roles: - main
早速定義をドライランしてみましょう、次のコマンドを site.yml のパスで実行します。
PS> Scoop-Playbook -Mode check
scoop のバケットを更新して (scoop update
) 、ツールがインストールされるか実行計画を確認できます。
PRE [scoop : status] *************************************************************** [o] skip: [run with 'check' mode] [o] skip: [prerequisiting availability] [o] skip: [updating buckets] [o] check: [scoop-update: Updating Scoop...] [o] check: [scoop-update: Updating 'main' bucket...] [o] check: [scoop-update: Scoop was updated successfully!] [o] skip: [status checking] [o] skip: [scoop-status: Scoop is up to date.] [o] check: [scoop-status: Updates are available for:] .... 省略 PLAY [Windows Setup] *************************************************************** TASK [main : Install main tools] *************************************************** [!] check: [scoop_install: gow] => Installed: No [!] check: [scoop_install: jq] => Installed: No [!] check: [scoop_install: time] => Installed: No [!] check: [scoop_install: unzip] => Installed: No
問題なければインストールします。Mode パラメーターを省略するか、-Mode run
を明示的に付けると実行します。
PS> Scoop-Playbook
PRE [scoop : status] *************************************************************** .... 省略 PLAY [Windows Setup] *************************************************************** TASK [main : Install main tools] *************************************************** [!] changed: [scoop_install: gow] => Installed: No Installing 'gow' (0.8.0) [64bit] Loading Gow-0.8.0.exe from cache Checking hash of Gow-0.8.0.exe ... ok. Extracting dl.7z ... done. Running pre-install script... Linking ~\scoop\apps\gow\current => ~\scoop\apps\gow\0.8.0 .... 省略 'gow' (0.8.0) was installed successfully! [!] changed: [scoop_install: jq] => Installed: No Installing 'jq' (1.6) [64bit] .... 省略 'jq' (1.6) was installed successfully! [!] changed: [scoop_install: time] => Installed: No Installing 'time' (0.2018.07.25) [64bit] .... 省略 [!] changed: [scoop_install: time] => Installed: No Installing 'time' (0.2018.07.25) [64bit] .... 省略 'time' (0.2018.07.25) was installed successfully! Notes ----- Please use 'timecmd' instead of 'time' in cmd.exe. [!] changed: [scoop_install: unzip] => Installed: No Installing 'unzip' (6.00) [64bit] .... 省略 'unzip' (6.00) was installed successfully!
再度実行しても同じ結果に収束します。 もし更新があれば更新してくれます。
PS> Scoop-Playbook
Scoop-Playbook PRE [scoop : status] *************************************************************** .... 省略 PLAY [Windows Setup] *************************************************************** TASK [main : Install main tools] *************************************************** [o] skip: [scoop_install: gow] => gow 0.8.0 [o] skip: [scoop_install: jq] => jq 1.6 [o] skip: [scoop_install: time] => time 0.2018.07.25 [o] skip: [scoop_install: unzip] => unzip 6.00
何かの理由でscoop コマンドで直接インストールすることもあるでしょう、そんな時は定義に一行足せばいいだけです。
もし scoop コマンドで誤ってアンインストールしても、Scoop-Playbook
を実行すれば元通りです。
Scoop で管理したいツールを定義通りに実行する。それができます。
普段の利用例
私は ScoopPlaybook を使ってYAML定義をして GitHub においています。
参考に私が普段使っているリポジトリを置いておきます。ルートパスはこのリポジトリの ./envs/windows/
パスです。
local-provisioner/envs/windows at main · guitarrapc/local-provisioner · GitHub
そのため、環境構築するときは次のコマンドを実行しています。
git clone https://github.com/guitarrapc/local-provisioner.git cd local-provisioner/envs/windows . ./prerequisites.ps1 sudo Scoop-Playbook
ツールの追加や削除をしたいときは、定義のYAML を修正して git commit/push するだけです。 バッチファイルやスクリプトではないので、どのように動作するかは考えず、ツールをYAMLに並べるだけなのはメンテの面で作ってよかったと思っています。 実際これなしで scoop とかいやです。
できること
ScoopPlaybookは次の操作が可能です。これしかできないです。
scoop_bucket_install
: バケットの追加、削除scoop_install
: ツールのインストール、アンインストール
バケットの追加、削除
scoop は任意のGitHubリポジトリなどをバケットにできます。scoop bucket add xxxx
ScoopPlaybook も scoop_bucket_install
でバケットの追加、削除をサポートしています。
例えば extras バケットを追加する場合、次のように書けます。
- name: "Install extras bucket" scoop_bucket_install: state: present bucket: extras
extras バケットは特別扱いされていますが、自分の GitHub URL を指定したい場合は次のようになります。
- name: "Install guitarrapc bucket" scoop_bucket_install: state: present bucket: guitarrapc source: https://github.com/guitarrapc/scoop-bucket.git
もしも追加したバケットを消したいならstate に absent を指定します。 (source は省略できます)
- name: "Uninstall guitarrapc bucket" scoop_bucket_install: state: absent bucket: guitarrapc
それぞれのキーは、scoop bucket
コマンドに合わせてあります。
- state: present か absent を指定
- bucket: 対象のバケット名を指定
- source: GitHub などのバケットURLを指定
ツールのインストール、アンインストール
scoop はバケットからツールのインストール、アンインストールができます。scoop install xxxx
ScoopPlaybook も scoop_install
でツールのインストール、アンインストールをサポートしています。
- name: "Install main tools" scoop_install: state: present bucket: main name: - gow
先ほど追加した gow をアンインストールするなら次のように書けます。
- name: "Uninstall main tools" scoop_install: state: absent bucket: main name: - gow
それぞれのキーは、scoop install
コマンドに合わせてあります。
- state: present か absent を指定
- bucket: 対象のバケット名を指定
- name: ツールを配列で指定
すでにインストールされているツールに更新がある場合は、Scoop-Playbook
実行時に更新してくれます。便利。
管理者権限で実行したい
scoop はユーザー権限が基本でーとか言いますが、ツールによってはFiddler のように管理者権限がないとインストールできないものもあります。 そんなときは sudo コマンドです。
sudo コマンドをインストールしておいて(scoop install sudo
相当)
- name: "Install main tools" scoop_install: state: present bucket: main name: - sudo
Scoop-Playbook を sudo つきで実行すればok です。
sudo Scoop-Playbook
まとめ
一人で使ってて満足していたんですが、WinGet が出てきて未来はどうなるかと楽しみにしています。 ただ、WinGet はこのままいくとこういう YAML 定義に関しては手を出さず、誰かが何か作るのでしょう。
アンインストールやUAC考慮がない、今のWinGet 触る気はありませんが、WinGetを触る将来が来たらこういうツール書くかもしれません。 ただ、その時はたぶん PowerShell では書かない気がするかもしれない。