以下の内容はhttps://tech.guitarrapc.com/entry/2020/06/11/040021より取得しました。


Windows開発環境をscoopで継続的に構築する

以前Windowsの開発環境をscoopで構築しているということを書きました。

https://tech.guitarrapc.com/entry/2019/12/01/233522

その際に、scoopを継続的に使っていくためのツールScoopPlaybookを書いたことに触れました。 今回はそのScoopPlaybookの紹介です。

概要

  • 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です。

https://github.com/guitarrapc/ScoopPlaybook

あんまり使い方とか書いていないので、どのような利用をするのか紹介します。

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/パスです。

https://github.com/guitarrapc/local-provisioner/tree/master/envs/windows

そのため、環境構築するときは次のコマンドを実行しています。

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では書かない気がする。




以上の内容はhttps://tech.guitarrapc.com/entry/2020/06/11/040021より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14