Python3 と venv と Ansible

# はじめに
Python2 系のサポートが終了してそろそろ1年ですね。
常日頃使っているサーバでは、まだ2系で問題なくスクリプトが動いているわけですが・・・
そろそろ3系も使えるようにならねばと、一念発起し今回調べた内容を簡単にまとめてみました。
タイトルの通り複数環境用に ```venv``` と 、インフラ環境構築用で使う ```Ansible``` を例にとって説明します。

# 環境構成
VirtualBox 上に CentOS 7 を起動して試行します。

**ホストマシン**

- Windows 10 Pro (20H2)
- VirtualBox：6.1.16
- Vagrant：2.2.14

**ゲストマシン**

- CentOS：7.8.2003

# VM 起動
以下 ```Vagrantfile``` で起動します。
```vagrant up``` ！
※CPU や Memory の設定はお好みで

```ruby:Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.define "centos" do |server|
    server.vm.box = "centos/7"
    server.vm.box_version = "2004.01"
    server.vm.hostname = "centos"
    
    server.vm.provider "virtualbox" do |vb|
      vb.customize [
        "modifyvm", :id,
        "--memory", "4096",
        "--cpus", "2"
      ]
    end
  end
end
```

# Python3 インストール
```vagrant ssh``` で早速ログインし、Python3 をインストールしていきます。
その前に、既存 python 環境を確認します。

```shell-session
$ python -V
Python 2.7.5
```

だいぶ古いですね・・・
それでは Python3 をインストールしていきます。

```shell-session
$ sudo yum install python3

# パスは変更されないので、python コマンドは 2 系のまま
$ python -V
Python 2.7.5

# python3 コマンド 3 系に
$ python3 -V
Python 3.6.8
```

# venv を使う
```python3``` コマンドだと打っていて違和感があるのと、開発環境として複数の異なるパッケージの環境が欲しかったので ```venv``` を利用します。
```venv``` はパッケージの異なる環境を複数用意することが出来ます。
```pip``` コマンドでインストールするパッケージやパッケージのバージョンが異なる環境を用意できますが、python のバージョンが環境内で固定となることが制約となります。

python 3.3 から標準機能として利用できるため、早速実行してみます。

```
# テスト用にディレクトリ作成
$ mkdir ansible-2.9
$ cd ansible-2.9

# 環境作成
# venv モジュールを使って、新しい環境（.venv）を作成
$ python3 -m venv .venv

# 環境情報用のディレクトリが環境名で作成される
# 今回は . 付きのフォルダのため隠しフォルダになっている
$ ls
$ ls -a
.  ..  .venv

# venv を実行して仮想環境をオンに。
$ source .venv/bin/activate
(.venv) $

または以下でも。
$ . .venv/bin/activate

# python の実行で 3系になっていることを確認
(.venv) $ python -V
Python 3.6.8

# 仮想環境をオフに。
(.venv) $ deactivate
$ python -V
Python 2.7.5
```

# Ansible（2.9）のインストールと起動
```venv``` が利用できたところで、パッケージを入れてみます。
今回は インフラの環境構成で利用する Ansible です。
2.9 / 2.10 のバージョンを導入してみます。

```
# venv で仮想環境をオン
$ pwd
/home/vagrant/ansible-2.9

$ . .venv/bin/activate
(.venv) $ pip install ansible==2.9.16
・・・
(.venv) $ ansible --version
ansible 2.9.16
  config file = None
  configured module search path = ['/home/vagrant/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/vagrant/ansible-2.9/.venv/lib64/python3.6/site-packages/ansible
  executable location = /home/vagrant/ansible-2.9/.venv/bin/ansible
  python version = 3.6.8 (default, Nov 16 2020, 16:55:22) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]
```

# Ansible（2.10） のインストールと起動
Ansible 2.9 の環境ができたので今度は別の環境を作って、Ansible 2.10 の環境を用意します。

```
# 仮想環境をオフに
(.venv) $ deactivate

# Ansible 2.10 用の環境を作ります
$ cd ../
$ mkdir ansible-2.10
$ cd ansible-2.10
$ python3 -m venv .venv
$ . .venv/bin/activate

# ansible がインストールされていないことを確認
(.venv) $ ansible --version
-bash: ansible: command not found

# ansible 2.10 のインストール
(.venv) $ pip install ansible==2.10.4
(.venv) $ ansible --version
ansible 2.10.4
  config file = None
  configured module search path = ['/home/vagrant/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/vagrant/ansible-2.10/.venv/lib64/python3.6/site-packages/ansible
  executable location = /home/vagrant/ansible-2.10/.venv/bin/ansible
  python version = 3.6.8 (default, Nov 16 2020, 16:55:22) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]
```

ディレクトリ毎にパッケージが異なる環境を準備することが出来ました。

# まとめ
今回は python 周りの開発環境を準備をしてみました。
今まで python2 との共存で億劫になっていた方の参考になれば幸いです。

以下、参考にさせて頂いた記事です（感謝）。

> venv: Python 仮想環境管理
> https://qiita.com/fiftystorm36/items/b2fd47cf32c7694adc2e
> 
> Pythonによるパッケージ開発
> https://future-architect.github.io/articles/20200820/

# 補足１
Python3 のサポート期限は以下みたいです。
期限が切れているバージョンや、そろそろ切れそうなバージョンもあるんですね・・・知らなかった。
3.6 も来年には・・・
※wikipedia 引用（https://ja.wikipedia.org/wiki/Python）

|バージョン|リリース日|サポート期限|
|:---|:---|:---|
|3.5|2015/09/13|2020/09|
|3.6|2016/12/23|2021/12|
|3.7|2018/06/27|2023/06|
|3.8|2019/10/14|2024/10|

# 補足２
```venv``` をご紹介したのですが、それぞれの環境でパッケージを保持するため、ディスクの使用量にはお気をつけください。
ちなみに今回の場合は以下のとおりです。
※Collection については金魚先生のスライドを。
https://www.slideshare.net/akira6592/ansible210andcollection

```
# 単位はMB
$ du -ms *
356     ansible-2.10
144     ansible-2.9

$ du -ms ansible-2.10/.venv/lib/python3.6/site-packages/ansible*
10      ansible-2.10/.venv/lib/python3.6/site-packages/ansible
6       ansible-2.10/.venv/lib/python3.6/site-packages/ansible-2.10.4-py3.6.egg-info
1       ansible-2.10/.venv/lib/python3.6/site-packages/ansible_base-2.10.4-py3.6.egg-info
314     ansible-2.10/.venv/lib/python3.6/site-packages/ansible_collections
3       ansible-2.10/.venv/lib/python3.6/site-packages/ansible_test
```

# 補足３
Vagrant で利用している ```ubuntu 18.04``` の Box で ```venv``` を実行しようとしましたが、実行出来ませんでした。
ディストリビューションによっては入ってないのかもしれないですね。
※実行結果の通り、python3-venv をインストールしたら動きました。

```
$ python3 -V
Python 3.6.9

$ python3 -m venv .venv
The virtual environment was not created successfully because ensurepip is not
available.  On Debian/Ubuntu systems, you need to install the python3-venv
package using the following command.

    apt-get install python3-venv

You may need to use sudo with that command.  After installing the python3-venv
package, recreate your virtual environment.

Failing command: ['/home/vagrant/test/.venv/bin/python3', '-Im', 'ensurepip', '--upgrade', '--default-pip']
```


# 補足４
現在(2020/12/26)、```pip search``` が使えないみたいです。
いきなりエラーを吐いて環境がおかしくなったと思ったのですが、世の中色々あるんですね・・・
https://github.com/pypa/pip/issues/5216