オフライン環境にPythonのパッケージをpipで持ち込みたい


- ◎本番環境はCentOS 6.7
- ○本番環境へのファイルの持ち込みは可能 (一応やろうと思えば何でもできる。)
- △本番環境へ用意されたリポジトリのパッケージは利用可能 (Ansibleを入れるなら少なくとも以下が無いと辛い)
    - 開発者ツール(gccやmake等)
    - opensslとgmpのライブラリとdevelパッケージ(ヘッダファイル)
    - setuptools (pythonでpipより前からあるパッケージ管理システム )
- ×本番環境はインターネットに繋げない(操作も別端末で行う)
- ×本番環境はシステム環境を汚してはならない

今回はこんな環境にpipを使ってAnsibleを入れました。
pipを使う理由は、依存関係の解決とそのソースコード一式のダウンロードが出来るので汎用性がありそうだと思ったからです。

長々書いちゃってますが、コマンドを流すだけなら3分ぐらいで出来ます。

必要なものを揃える
-----
以下が必要です。無いと逆に怖いです。

- インターネットが繋がる環境
- OS(Windows 7 or CentOS 6)
- python(2.6)
- setuptools

本番環境がLinuxですが、揃えるだけであればWindowsでもOKです。
(今後バージョンが上がるとできなくなるかもしれません。)

Pythonは公式からWindowsのバイナリが出ているので入れましょう。 CentOSはminimal構成でもPython2.xは入ってます。

setuptoolsはネットワークが繋がる環境であれば、https://pypi.python.org/pypi/setuptools にある [ez_setup.py](https://bootstrap.pypa.io/ez_setup.py) をpythonで実行することで簡単に導入できます。

```
python ez_setup.py
```

### get-pip.py をダウンロードする
pipを導入するわけですが、まず、http://pip.readthedocs.org/en/stable/installing/ にある get-pip.pyをダウンロードします。

https://bootstrap.pypa.io/get-pip.py

pythonでのパッケージ管理システムの`pip`のインストールスクリプト
・・・なんですが、これ、`pip install`で出来ることなら大抵出来るようになっています。
これを使ってAnsibleに必要なものを全て揃えます。

ディレクトリを作り、そこで作業します。

```
mkdir pip-ansible-installer
cd pip-ansible-installer
```

`get-pip.py`を上記のリンク先のコピペなりcurlなりでダウンロードします。

```
curl -O https://bootstrap.pypa.io/get-pip.py
```

### 必要なパッケージ名を書く

次に`requirements.txt`というファイルをコマンドを打って作ります。
これは他の言語のパッケージ管理システムでいう`Gemfile`や`cpanfile`のようなものです。

今回はansibleの最新を入れたいのでansibleとだけ書いておきます。

```
echo ansible > requirements.txt
```

もしpythonのあんなパッケージこんなパッケージも入れたい！ってときはここに書いておくといいかもしれません。(ただ、`pip`もこのタイミングで入るので、別口で入れてもいいと思います。)

なお、setuptoolsとpipは暗黙的に宣言されているので記載は不要です(書くと2重定義で怒られる)


### 必要なパッケージをget-pip.pyでダウンロード
これよりダウンロードの儀に入ります。

もし、プロキシを経由しないと外に出れない場合は、環境変数`HTTPS_PROXY`の設定をしておきましょう。(https通信をします。)

```
HTTPS_PROXY=http://proxy:8080/
```

パッケージのソースを格納するディレクトリを作ったら、いよいよダウンロード開始です。

```
mkdir .src
python get-pip.py --download .src --requirement requirements.txt --no-binary :all:
```

- `--download`: インストールではなく指定したディレクトリにパッケージ(orソースコード)をダウンロード
- `--requirement`: 利用するアプリが依存しているパッケージ名を記載したファイルを指定すると、引数指定の代わりになる
- `--no-binary`: `:all:`でバイナリパッケージではなくソースコードパッケージをダウンロードします。(環境に合わせたバイナリをダウンロードさせないため)

詳細は http://pip.readthedocs.org/en/stable/reference/pip_install/ をお読みください


ここまではLinuxでもWindowsでも同じ手順で出来ます。
(うちの仕事場では基本的にWindowsしかインターネットがつながらないので重要...)

### 出来上がったものを圧縮
Windowsなら右クリックからzipに、Linuxなら以下のコマンドでtar.gzなどに圧縮しておきます。

```
cd ../
tar czf pip-ansible-installer.tar.gz pip-ansible-installer
```


インターネットが繋がらない環境へのインストール
---------
少し長くなりましたが、以降はAnsibleを入れたい環境の作業です。ansibleを実行するユーザで実行してください。

### 事前準備
Ansibleは一般的なビルドツールのほかに、以下が必要です。

- Pythonのライブラリのソースコード
- setuptools (リポジトリにあることを祈るしかない)
- OpenSSLライブラリとソースコード
- GMPのライブラリとソースコード(mpfrでも良かった気がする)

これらは`yum`などで入れておきましょう。

```
sudo yum install -y python-setuptools python-devel openssl-devel gmp gmp-devel
```

### インストールする
先に上記で作り上げた圧縮ファイルを入れたい環境に持ち込みます。
`unzip`なり、`tar xzf`なりで解凍してビルドしていきます。

```
cd pip-ansible-installer
python get-pip.py --no-index --find-links=.src --requirement requirements.txt --user
```

- `--no-index`: PyPIにアクセスしません(パッケージの一覧を得るためにネットワーク通信が発生するのを抑制する)
- `--find-links`: パッケージをこの直下から探します
- `--user`: `~/.local` にインストールします(システム環境を汚さない。)

以下のような出力が出たら終了です。

> Successfully installed ansible jinja2 paramiko pip setuptools-0.9.8 wheel


### PATHを通す
ansibleのコマンドを実行するのはユーザであると思うので、とりあえず`.bash_profile`に追記しておきます。自分のシェルに合わせて追加してください。

```
echo "export PATH=\$HOME/.local/bin:\$PATH" >> "$HOME/.bash_profile"
source "$HOME/.bash_profile"
```

あとは`ansible-playbook`するなりして世界を変えていきましょう。

おしまい
------
なんでこんなしょうもない苦労しないとならないんだ。