名もなき未知

エンジニアリングとか、日常とかそういうのをまとめる場所。

ansibleでasdfを適用するのに苦戦していたメモ

先週、こういうのを書いた。

zenn.dev

ansible の勉強もしているし、ついでに自動的にセットアップする、というのもやっていこうと思っていて現在、下記のリポジトリで作業中。

github.com

いろいろ勉強しながらやっているので、進みは悪いのだが、その中でも asdf を有効にするのに苦戦しているので、そのメモ。正攻法ではないと思うので、当ブログで一応書き残しておく程度にする。

いい感じにできたらリライトしてどこかにあげなおすかも。

ゴールとして

やりたいのはこんな感じ

  • asdf を入れる
  • asdf plugin の python を入れる(バージョンは最新の 3.9.1)
  • asdf で入れた python をデフォルトにする
  • yq を入れる

asdf を入れる

本来のインストール方法に従って作業していく。

asdf-vm.com

dependencies を見ると、 git, curl が必要であるため入れる。

これを表現すると下記のような task が書けるはず。ちなみに ansible-galaxy init --init-path="roles" yumechi みたいな形でセットアップしているので、 roles/yumechi/tasks/main.yaml かた include する形で実行している。

また playbook.yaml 側に become: yes とするように書いているので、実際には sudo apt install git curl と等価なものが実行されている認識。

- name: install tools
  apt:
    name:
      - git
      - curl
    update_cache: yes

で、ここからが問題なのですが asdf コマンドを有効にするためには ~/.asdf/asdf.sh をたたく必要があるのですが、これがなかなか有効にならず、苦戦した。

具体的には下記のコマンドが通りませんでした。

. $HOME/.asdf/asdf.sh

ファイルが存在しないと言われたり、ディレクトリを合わせに行っても、そもそもディレクトリが間違っているといわれることもあり(実行ユーザーが root だったり、作業ディレクトリが実質 root だからなのではという気もする)、解決ができませんでした。

うーん、難しい。

asdf を有効にしたい

ansible-galaxy あたりで調べると下記が見つかりました(ただ後述すると、これそのものだけではうまくいかなかったので、参考にだけしました)

github.com

これでやっていることとしては

  • ansible を git で pull する
  • asdf を有効にするスクリプト/etc/profile.d/ に置く、実行権限は 755 で与える

なので、下記のような形で書いて解決。ついでにすでにリポジトリが存在する場合は pull して最新にする、みたいにしたけど、正直最初の時点でディレクトリがあるかどうかチェックして、なければ clone あれば pull にしたほうが良い気がする。

---
# refer: https://github.com/cimon-io/ansible-role-asdf
- name: asdf git clone
  command: git clone https://github.com/asdf-vm/asdf.git ~/.asdf
  become_user: "{{ exec_ubuntu_user }}"
  ignore_errors: yes
  register: result

- name: asdf update
  command: "bash -lc 'cd ~/.asdf && git pull'"
  become_user: "{{ exec_ubuntu_user }}"
  ignore_errors: yes
  when: result is failed

- name: "source asdf script"
  template:
    src: "asdf.sh.j2"
    dest: "/etc/profile.d/asdf.sh"
    owner: "root"
    group: "root"
    mode: 0755
  become: True

templateは下記。なんかもう少しチェック固くするとかしたほうがいいような気がするが、それは要件次第かも。

# # refer: https://github.com/cimon-io/ansible-role-asdf

if [ -f "$HOME/.asdf/asdf.sh" ]; then
  source "$HOME/.asdf/asdf.sh"
fi

asdf plugin として python を入れる

参考にしているリポジトリでは python がサポートされていないこともあり、この部分は自分でなんとかする必要がある。

asdf-python は下記だが…

github.com

前も自分のPCに入れたときに引っかかったことだが、これは内部的に pyenv に依存している。

https://github.com/danhper/asdf-python/blob/8078f74efb47a3f7291c42c8373c9908baef2c01/bin/utils.sh

なので pyenv の python ビルドに使用するツール群が必要。

https://github.com/pyenv/pyenv/wiki#suggested-build-environment

よって python の build に必要なものを install する。

- name: install build tools
  apt:
    name:
      - make
      - build-essential
      - libssl-dev
      - zlib1g-dev
      - libbz2-dev
      - libreadline-dev
      - libsqlite3-dev
      - wget
      - curl
      - llvm
      - libncurses5-dev
      - xz-utils
      - tk-dev
      - libxml2-dev
      - libxmlsec1-dev
      - libffi-dev
      - liblzma-dev
    update_cache: yes

そのあと asdf python をインストールする。

Raspberry Piのメモリが足りていない + ネットワーク速度も微妙、なので、なんか無限の時間がかかっていた。

よって寝て起きてから確認した。1回目はssh 接続がタイムアウトしていた… もう一回やったら成功したので問題なし。

"bash -lc 'asdf plugin-add python'" で実行するのがポイントっぽい。

---
# tasks file for yumechi
# refer: https://github.com/cimon-io/ansible-role-asdf
- name: install plugins
  command: "bash -lc 'asdf plugin-add python'"
  args:
    creates: "{{ exec_ubuntu_user }}/.asdf/plugins/python"
    chdir: "~"
  become: True
  become_user: "{{ exec_ubuntu_user }}"
  ignore_errors: True

- name: install python
  command: "bash -lc 'asdf install python {{ python_version }}'"
  become_user: "{{ exec_ubuntu_user }}"


- name: setting python global version
  command: "bash -lc 'asdf global python {{ python_version }}'"
  become_user: "{{ exec_ubuntu_user }}"

yq をインストールする

ここまでこれば後は install するだけ。

---
# tasks file for yumechi
- name: pip install
  command: "bash -lc 'pip install yq'"
  become_user: "{{ exec_ubuntu_user }}"

pipでやったらうまくいかなかった気がするけど、詳しく覚えてないのでわからないです。

気づきとか

  • source するとか普段より頭使ったので疲れた
    • 実行コマンドを登録するのは意外と大変なんだなと
  • 参考にできるものが少なく苦戦
    • 仮想環境入れるとしても pyenv だけでいいような気がするので、わざわざ asdf を入れてがちゃがちゃやりたい、みたいなのが ansible 利用するユーザーの中にない?
    • ローカル開発環境も似たようなことをしてやろうとしているが、そこでもう一回くらい苦戦しそう
  • Raspberry Pi 2 Model B のスペック低すぎる問題
    • 無限に感じられる apt update, apt upgrade, apt install
    • 無限に感じられる Python build
    • このあたりメモリネックな気がする
    • pythonをbuildするのやめて、直 install にする形式をとるのが正解かも。ほかの言語環境についても同様。 apt install で事足りることを祈りたい
      • だが手元では Python 3.9 書くし、実行環境古いのはちょっと困るんだよなぁ
    • そろそろあきらめてこれを捨てるのもあり、あるいは比較的使わない画像などを保存しておくだけのサーバーにする
      • ansible 用のテストマシンとしての自分の中でのニーズはあるが、さすがに遅すぎる
      • Raspberry Pi 4 も空けてないので、そろそろ真面目に空けるか
      • Raspberry Pi 4 もう一個くらいほしい
  • ansible-galaxy よくわからん問題
    • コミュニティで使われているサードパーティーなパッケージみたいなイメージだが
    • ansible 自身の使い方も結構勘任せな感じはするので、次の isucon までにマスターしたい

感想

asdfを使いたいだけなのにめっちゃ苦戦しましたね、つらい。

まあ基本的に Raspberry Pi はデプロイしたものを動かすだけの環境として自分は活用を考えているので、この使い方は正しいのですが、流石に Raspberry Pi 2 は厳しいような気がしてきた。バイナリおいて実行するだけのマシンになってもらうくらいのほうがいいのかもしれない。

それと後段としてローカルの Ubuntu のツール群セットアップタスクもあるので、これに向けても頑張りたいかも(いろいろな開発環境の関係で、ユーザーレベル管理するよりもイメージ自体を分離したくなってきた、うっかり変な環境変数触ってしまうと微妙な気持ちになるし)。

このあとRaspberry Pi 側でやりたいこととしては、 deamon 化したプロセスとかでスケジュール実行する、ですかね。組み込みでも活用を考えるとそういうのを学んでおく必要があるなというお気持ちなので、頑張って勉強しようと思います。

(crontab はトラックが大変で極力使いたくないのでプロセスを常に立ち上げておいてそれをログ出力する形にしたいという気持ちもあります)

おまけ

後ろでこれ流しながら見てましたが、わいわい大会やるの楽しそうで、まあこういうの身内でやってみるのもの楽しいのかもしれないですね。


【#ホロお正月CUP】2021年もっとも勢いをつけるのは誰だ!熱い戦いが巻き起こる🔥🏎【全体視点有/常闇トワ】

笑いあり、涙ありで非常に面白かったです。あとアイテムの駆け引きとかもあって面白かったかも。