Pythonで簡単なコマンドラインツールを作ってみた その1 Vagrant編

2016年12月17日土曜日

CentOS Python Vagrant VirtualBox

vagrant

Pythonを使って簡単なコマンドラインツールを作りました。

定期運用で出す作業依頼メールの本文を出力してくれるものです。毎回ちょっとだけ違う文面を作るのが面倒だったので、自動化してみました。

作成するにあたり開発環境の作り方など、色々調べたので残しておきます。

前提

表題の通り、pythonで簡単なコマンドラインツール(100Linesないくらい)を作成した時に調べたことのまとめです。大規模な開発やWebアプリ、GUIアプリなどでは、また違う環境が必要だと思います。

ただ、どんなに小さなツールでも運用で使い続けるつもりがあるなら、testコードがあった方が良いですし、pipでインストールできた方が管理も簡単なので、その辺りはミニマム中でもそれなりのものを、と考えました。

環境

  • Winsows 10
  • VirtualBox + Vagrant + centos/7
  • git
  • pyenv + virtualenv

その他、おまけ

  • zsh、tmux、vim

Vagrantfile

開発環境は仮想で作ることにしました。色々インストールして、ホストの環境を汚したくなかったからです。

仮想マシンの構築はVirtualBox + Vagrantで、ゲストはCentOS 7にしました。ホストはWindowsです。今だとDockerがいいのかな。調査不足です。ゲストは慣れと好みで選びました。

作ったVagrantfileはこんな感じ。

Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
  config.vm.synced_folder ".", "/vagrant", type: "virtualbox"
  config.vm.provision "shell", 
    path: 'provision/scripts/provision_root.sh'
  config.vm.provision "shell", 
    path: 'provision/scripts/provision.sh', privileged: false
end

大変シンプルでよろしい。

centos/7のboxはContOSのページから リンク されているものです。公式っぽい?

Windowsにrsyncをインストールするつもりはないので、synced_folderのtype:に”virtualbox”を指定しています。

あとは、root権が必要なprovisionとvagrantユーザで行うprovisionをシェルスクリプトで用意しています。

config.vm.provision

provision_root.shの内容は以下の通り。開発向けに趣味でzshとかをインストールしています。その他、pyenvを使ってpythonの環境を作るので、必要なものをインストールしています。

下のスクリプトではtmuxをインストールしていますが、今のところ便利さを享受できていません。

私が感じるtmuxなどのターミナルマルチプレクサの利点は、デタッチ・アタッチによる作業復帰と画面分割の2点が主です。

今回のような仮想のローカル開発環境は、サーバのように常時起動していないので、デタッチ・アタッチで作業に復帰するシーンは少なかったです。

画面分割に関しては、ホストのターミナル(iTerm2RLogin など)で行う方が、余計なことを考えずに制御コードを送受信できるので良いかもと思いました。

#! /bin/sh
# provision/scripts/provision_root.sh


yum update -y


# development environment
yum install zsh -y
chsh -s `cat /etc/shells | grep zsh` vagrant
yum install tmux -y
yum install vim -y
yum install git -y
yum groupinstall "Development Tools" -y


# pyenv
yum install readline-devel zlib-devel bzip2-devel sqlite-devel openssl-devel -y

provision.shではvagrantユーザで開発の下準備をしています。ただ、これはdotfilesを準備して、initialize処理としてやらせるのが良いかもと今は思っています。provision.shではdotfilesのダウンロード、deployとinitializeを実行する感じです。

pipsiのインストールのため、pyenvでいったんglobalを変更しています。pipsiはpip-initを使いたくてインストールしたのですが、pip-initで最初にテンプレートを作らなくても、pypaのサンプルプロジェクト を使えば良いので、この辺りはごっそり必要ないかなと今は思っています。

#! /bin/sh
# provision/scripts/provision.sh


# oh-my-zsh
if [ ! -d ~/.oh-my-zsh ]; then
  sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
  cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc
fi


# pyenv
PYENV_PATH=`cat << 'EOS'

# Load pyenv automatically by adding
export PATH="$HOME/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
EOS
`
SYSTEM_PYTHON_VERSION=`python -V 2>&1 | cut -d' ' -f2`
if [ ! -d ~/.pyenv ]; then
  curl -L https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/pyenv-installer | bash
  echo "$PYENV_PATH" >> ~/.zshrc
fi
export PATH="$HOME/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
pyenv install $SYSTEM_PYTHON_VERSION
pyenv global $SYSTEM_PYTHON_VERSION
pip install -U pip
pip install virtualenv



# pipsi
PIPSI_PATH=`cat << 'EOS'

# Load pipsi automatically by adding
export PATH="$HOME/.local/bin:$PATH"
EOS
`
if [ ! -d ~/.local/venvs ]; then
  curl https://raw.githubusercontent.com/mitsuhiko/pipsi/master/get-pipsi.py | python
  echo "$PIPSI_PATH" >> ~/.zshrc
fi
export PATH="$HOME/.local/bin:$PATH"
pipsi install pip-init

Plugin

pluginは1つだけインストールしています。VirtualBox Guest Additionを自分の環境のものに自動で合わせてくれます。box作成した環境のVirtualBoxと自分の環境のVirtualBoxにバージョン差異があると、共有ディレクトリがマウント出来なかったりするので、インストールしておくと便利です。

$ vagrant plugin install vagrant-vbguest

まとめ

仮想環境の準備はこんな感じです。provisionは再考の余地ありですね。ネットワーク関連は必要ないので全体的にまだシンプルな感じですね。次はdotfilesについて書こうと思います。