🐹

golangをansibleでインストールする

2023/05/06に公開

Overview

intro

ansible擦り第二弾、今回はgolangです。
aptで管理すればええやんと思うかもしれませんが、どうやらaptのgolangは古いらしい。

使い方

vars/main.ymlに入れたいバージョンを指定して、playbookからroleで呼び出して下さい。
旧 → 新, 新 → 旧 の切り替えもvarのバージョン書き換え → playbook実行でできます。

file tree

今回もrole形式です。

boomkun ~/.ansible (main *=) $ tree roles/golang
roles/golang
├── tasks
│   └── main.yml
├── templates
│   └── golang.sh
└── vars
    └── main.yml

処理の概要

tarをダウンロードして解凍。/usr/local/goに解凍するのが公式のようですが
バージョンの切り戻しを便利にするため、あえて解凍先をずらしてsymlinkしてます。

boomkun ~/.ansible (main *=) $ ls -ld /usr/local/go*
lrwxrwxrwx 1 root root   27 May  6 17:07 /usr/local/go -> /usr/local/golang-1.20.4/go
drwxr-xr-x 3 root root 4096 May  6 16:35 /usr/local/golang-1.19.9
drwxr-xr-x 3 root root 4096 May  6 17:07 /usr/local/golang-1.20.4

あとは

  • ダウンロード済みならダウンロードをスキップ
  • GOのPATHを/etc/profile.d/に追加する

という処理があります。
https://go.dev/doc/install

タスク

ソース(クリックで展開)
roles/golang/tasks/main.yml
---
- name: Create dest directory if not exists
  become: yes
  file:
    path: "/usr/local/golang-{{ version }}"
    state: directory

- name: Check if file exists
  become: yes
  stat:
    path: "{{ item }}"
  register: file_stats
  with_items:
    - /tmp/go{{ version }}.{{ arch }}.tar.gz
    - /usr/local/golang-{{ version }}/go

- name: get specified version archive
  become: yes
  get_url:
    url: "{{ golang.src }}"
    dest: /tmp
  when:
    - file_stats.results[0].stat.exists == False
    - file_stats.results[1].stat.exists == False

- name: unarchive specified version package  
  become: yes
  unarchive:
    src: /tmp/go{{ version }}.{{ arch }}.tar.gz
    dest: /usr/local/golang-{{ version }}
  when: file_stats.results[1].stat.exists == False

- name: symlink to specified version directory
  become: yes
  file:
    src: "/usr/local/golang-{{ version }}/go"
    dest: "/usr/local/go"
    state: link
    force: yes

- name: add golang path
  become: yes
  template:
    src: golang.sh
    dest: /etc/profile.d/golang.sh

変数

指定したバージョンで取りにいきます。
最新バージョンはコメントアウトしたURLから参照できます。

ソース(クリックで展開)
roles/golang/vars/main.yml
---
version: 1.20.4
arch : linux-amd64
golang:
  src: https://go.dev/dl/go{{ version }}.{{ arch }}.tar.gz

# check latest version below
# https://go.dev/dl/

https://go.dev/dl/

テンプレート

/usr/local/go/bin配下と、GOPATH配下をPATHに追加してます。
一般的に$GOPATH$HOME/goが推奨されているようですが、ホームにディレクトリを置きたくない性分なので$HOME/.goにしてます。
あと、最近はvgo modeの登場によりGOPATHを気にしなくて済むんだとか。

ソース(クリックで展開)
roles/golang/templates/golang.sh
#!/bin/sh
export GOPATH=~/.go
export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin

動作確認

ansible-playbook実行。適当なplaybookを作ってroleを呼び出して下さい。
go が入っていることの確認

boomkun ~/.ansible (main *=) $ which go && go version
/usr/local/go/bin/go
go version go1.20.4 linux/amd64

go のモジュールを入れてみて、コマンドが叩けるか。
今回はgatを入れてみます。

boomkun ~ $ go install github.com/koki-develop/gat@latest
go: downloading github.com/koki-develop/gat v0.8.2
go: downloading golang.org/x/term v0.7.0
~(略)~
boomkun ~ $ which gat
/home/boomkun/.go/bin/gat

outro

最新版をCLIで確認できそうであれば
playbook実行時に差分を出したいんですが、なかなかいいアイデアが出ず...
ここどうにかしたいですねー。

Discussion