ライブラリを追加・削除する
==========================

.. Contents:: 目次
    :local:
    :depth: 2

.. highlight:: console

はじめに
--------
AAClusterにライブラリを追加・削除する手順を説明します。

| 以下の手順では、Jupyter Notebookへ接続済みで、Terminalが起動済みであるとします。
| Jupyter Notebookへの接続方法は、 :ref:`access_jupyter_notebook` を参照してください。
| Terminalの起動は、Jupyter Notebookで [New] ボタンを押下し、 [Terminal] を選択してください。


ライブラリを追加する
--------------------
追加するライブラリは、:ref:`追加可能なPythonパッケージの要件<requirements-of-python-packages>`
に記載の要件を満たしている必要があります。

.. note:: 追加したライブラリは、追加作業を行ったAAClusterでのみ有効です。
          他のAAClusterや新たに作成したAAClusterには反映されません。

.. note:: この手順では、 `Jupyter Extension <https://jupyter-notebook.readthedocs.io/en/5.4.1/examples/Notebook/Distributing%20Jupyter%20Extensions%20as%20Python%20Packages.html>`_
          を新たに追加することはできません（インストールしたJupyter Extensionを有効化できません）。

PyPIで公開されているライブラリを追加する
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PyPIで公開されているライブラリを追加する場合の手順を例を通して説明します。

この例では、代数計算ライブラリである 'sympy' をインストールします。

1. 追加したいライブラリのPythonパッケージがPyPIに公開されていることの確認

  `PyPI - The Python Package Index <https://pypi.org/pypi>`_ にアクセスして、Pythonパッケージを検索し公開されていることを確認します。

2. Pythonパッケージの依存関係の確認

  | `pip-compile` コマンドを利用してライブラリのインストール後もAAClusterにプリインストールされている
    Pythonパッケージの依存関係が満たされることを確認します。
  | 依存関係が満たされない場合、Jupyter Notebookが動かなくなる等の
    何らかの不具合が発生する可能性があります。

  .. parsed-literal::

    $ mkdir ~/package_req
    $ echo sympy > ~/package_req/requirements_user.in
    $ PIP_NO_INDEX=1 pip-compile -r -o ~/package_req/requirements_all.txt \\
        /opt/aapf/1.5.4/python_env/py3/python_system_packages.txt
    #
    # This file is autogenerated by pip-compile
    # To update, run:
    #
    #    pip-compile -r -o /home/aa_svc/package_req/requirements_all.txt /opt/aapf/1.5.4/python_env/py3/python_system_packages.txt
    #
    attrs==19.1.0
    backcall==0.1.0
    bleach==3.1.0
    ...
    ...

    $ pip-compile -o ~/package_req/requirements_all.txt \\
        ~/package_req/requirements_user.in \\
        /opt/aapf/1.5.4/python_env/py3/python_system_packages.txt
    #
    # This file is autogenerated by pip-compile
    # To update, run:
    #
    #    pip-compile -o /home/aa_svc/package_req/requirements_all.txt /home/aa_svc/package_req/requirements_user.in /opt/aapf/1.5.4/python_env/py3/python_system_packages.txt
    #
    attrs==19.1.0
    backcall==0.1.0
    bleach==3.1.0
    ...
    ...

  上のようなコマンド実行結果が出力され、`~/package_req/requirements_all.txt` が生成されていれば、依存関係が満たされることの確認は完了です。

  `pip-compile` コマンドが失敗する場合は、トラブルシューティングの :ref:`failed-pip-compile` を参照してください。

3. ライブラリのインストール

  `pip-compile` コマンドの実行で生成された `requirements_all.txt` を利用して、ライブラリをインストールします。

  .. parsed-literal::

    $ pip install -r ~/package_req/requirements_all.txt
    Requirement already satisfied: attrs==19.1.0 in /opt/aapf/1.5.4/python_env/py3/lib/python3.6/site-packages (from -r /home/aa_svc/package_req/requirements_all.txt (line 7))
    Requirement already satisfied: backcall==0.1.0 in /opt/aapf/1.5.4/python_env/py3/lib/python3.6/site-packages (from -r /home/aa_svc/package_req/requirements_all.txt (line 8))
    ...
    ...
    Successfully installed xxx xxx xxx sympy-1.4

  `pip install` コマンドが失敗する場合は、トラブルシューティングの :ref:`failed-pip-install` を参照してください。

AACluster上に配置したPythonパッケージファイルからライブラリを追加する
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
AACluster上に配置したPythonパッケージファイルを直接指定してライブラリを
追加する場合の手順を例を通して説明します。

この例では、作成済みの自作 Python パッケージファイル('my-analytics')をインストールします

1. 追加したいライブラリのPythonパッケージファイルをAAClusterへアップロード

   AAClusterへのファイルのアップロード方法は、 :doc:`operate_files` を参照してください。

2. Pythonパッケージの依存関係の確認

  アップロードしたPythonパッケージファイルを適当なディレクトリに配置します。

  .. code-block:: bash

    $ mkdir -p ~/package_req/wheels
    $ cp /path/to/my-analytics.whl ~/package_req/wheels

  | ライブラリのインストール後もAAClusterにプリインストールされているPythonパッケージの
    依存関係が満たされることを確認します。
  | 依存関係が満たされない場合、Jupyter Notebookが動かなくなる等の
    何らかの不具合が発生する可能性があります。

  .. parsed-literal::

    $ echo my-analytics > ~/package_req/requirements_user.in
    $ PIP_NO_INDEX=1 pip-compile -r -o ~/package_req/requirements_all.txt \\
        /opt/aapf/1.5.4/python_env/py3/python_system_packages.txt
    #
    # This file is autogenerated by pip-compile
    # To update, run:
    #
    #    pip-compile --output-file /home/aa_svc/package_req/requirements_all.txt /opt/aapf/1.5.4/python_env/py3/python_system_packages.txt
    #

    avro-mapper==0.4.5
    avro-python3==1.8.2       # via avro-mapper
    backports-abc==0.5        # via tornado
    ...
    ...
    $ pip-compile -f ~/package_req/wheels -o ~/package_req/requirements_all.txt \\
        ~/package_req/requirements_user.in \\
        /opt/aapf/1.5.4/python_env/py3/python_system_packages.txt
    #
    # This file is autogenerated by pip-compile
    # To update, run:
    #
    #    pip-compile --output-file /home/aa_svc/package_req/requirements_all.txt /home/aa_svc/package_req/requirements_user.in /opt/aapf/1.5.4/python_env/py3/python_system_packages.txt
    #

    avro-mapper==0.4.5
    avro-python3==1.8.2       # via avro-mapper
    backports-abc==0.5        # via tornado
    ...
    ...

  上のようなコマンド実行結果が出力され、`~/package_req/requirements_all.txt` が生成されていれば、依存関係が満たされることの確認は完了です。

  `pip-compile` コマンドが失敗する場合は、トラブルシューティングの :ref:`failed-pip-compile` を参照してください。

3. ライブラリのインストール

  `pip-compile` コマンドの実行で生成された `requirements_all.txt` を利用して、ライブラリをインストールします。

  .. parsed-literal::

    $ pip install -f ~/package_req/wheels -r ~/package_req/requirements_all.txt
    Requirement already satisfied (use --upgrade to upgrade): avro-mapper==0.4.5 in /opt/aapf/1.5.4/python_env/py3/lib/python3.6/site-packages (from -r /home/aa_svc/package_req/requirements_all.txt (line 10))
    Requirement already satisfied (use --upgrade to upgrade): avro-python3==1.8.2 in /opt/aapf/1.5.4/python_env/py3/lib/python3.6/site-packages (from -r /home/aa_svc/package_req/requirements_all.txt (line 11))
    ...
    ...
    Successfully installed xxx xxx xxx my-analytics-1.0.0

  `pip install` コマンドが失敗する場合は、トラブルシューティングの :ref:`failed-pip-install` を参照してください。

追加したライブラリの動作確認を行う
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
追加したライブラリが正常に利用できるか、NotebookもしくはTerminal上で動作確認を行ってください。

正常に動作しない場合は、トラブルシューティングの :ref:`failed-operation-check` を参照してください。


ライブラリを削除する
--------------------
追加したライブラリを `pip uninstall` コマンドを実行してアンインストールします。

.. parsed-literal::

  $ pip uninstall sympy
  Unistalling sympy-1.4:
    /opt/aapf/1.5.4/python_env/py3/bin/isympy
    /opt/aapf/1.5.4/python_env/py3/lib/python3.6/site-packages/__pycache__/isympy.cpython-36.pyc
    ...
    ...
  Proceed (y/n)? y
    Successfully uninstalled sympy-1.4

| この方法は指定したライブラリのみをアンインストールします。
| 指定したライブラリが依存するその他のPythonパッケージはアンインストールされません。
| ライブラリの追加時にインストールされたすべてのPythonパッケージもアンインストールしたい場合は、AAClusterを初期状態にしてください。
| AAClusterを初期状態にする場合は、付録の :ref:`init_aacluster` を参照してください。


トラブルシューティング
----------------------
ライブラリの追加・削除作業中に何らかの問題が発生した場合は、
以下を参考に問題の解決を図ってください。

問題が解決せず、AAClusterを正常に利用できない場合は、AAClusterを初期状態にして下さい。
AAClusterを初期状態にする場合は、付録の :ref:`init_aacluster` を参照してください。

.. _failed-pip-compile:

pip-compileコマンドが失敗する
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pip-compileコマンドが失敗する場合、以下の対処方法があります。

* Pythonパッケージの依存関係を満すようにライブラリをバージョンダウンする
* Pythonパッケージの依存関係を無視してライブラリをインストールする

.. _resolve_version_conflict:

Pythonパッケージの依存関係を満すようにライブラリをバージョンダウンする
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AAClusterにプリインストールされているPythonパッケージの依存関係が満たされない場合、
以下のように `pip-compile` コマンドの実行に失敗します。

.. parsed-literal::

  $ pip-compile -o ~/package_req/requirements_all.txt \\
     ~/package_req/requirements_user.in \\
     /opt/aapf/1.5.4/python_env/py3/python_system_packages.txt
  Could not find a version that matches numpy==1.10.4,>=1.12.1,>=1.6,>=1.7.0,>=1.8.2
  Tried: 1.3.0, 1.4.1, 1.5.0, 1.5.1, 1.6.0, 1.6.0, 1.6.1, 1.6.1, 1.6.2, 1.6.2, 1.7.0,
  1.7.0, 1.7.0, 1.7.1, 1.7.1, 1.7.1, 1.7.2, 1.7.2, 1.7.2, 1.8.0, 1.8.0, 1.8.0, 1.8.1,
  1.8.1, 1.8.1, 1.8.2, 1.8.2, 1.8.2, 1.9.0, 1.9.0, 1.9.0, 1.9.1, 1.9.1, 1.9.1, 1.9.2,
  1.9.2, 1.9.2, 1.9.3, 1.9.3, 1.9.3, 1.10.0, 1.10.0.post2, 1.10.0.post2, 1.10.1,
  1.10.1, 1.10.1, 1.10.2, 1.10.2, 1.10.2, 1.10.3, 1.10.4, 1.10.4, 1.10.4, 1.11.0b3,
  ...
  ...

| この実行例では、numpyのバージョンが競合していることが確認できます。
| まず、AAClusterが要求するnumpyのバージョンを確認してください。
| バージョンは、/opt/aapf/1.5.4/python_env/py3/python_system_packages.txt に記載されています。
| 以下のコマンドを実行してください。

.. parsed-literal::

  $ cat /opt/aapf/1.5.4/python_env/py3/python_system_packages.txt
  avro-mapper>=0.4.3
  cliff>=2.11.0,<2.12
  ...
  ...
  numpy==1.10.4
  ...

| コマンド実行結果から、AAClusterはnumpyのバージョンを '1.10.4' で要求していることがわかります。
| 従って、上述の `pip-compile` コマンドの実行例は、追加するライブラリおよびその依存Pythonパッケージの
| いずれかがnumpyのバージョンを '>=1.12.1' で要求しており、Pythonパッケージの依存関係を満たせないため
| 失敗していることがわかります。

| Pythonパッケージの依存関係が満たされない場合は、追加しようとしているライブラリが要求する
| 依存Pythonパッケージを調べ、最新版よりも古いバージョンであれば追加できるかどうか確認してください。
| 以下は、最新版ではないバージョン番号を指定してPythonパッケージの依存関係の確認を行う場合の例です。

.. parsed-literal::

  $ echo "<インストールするライブラリのPythonパッケージ名>==<バージョン番号>" > ~/package_req/requirements_user.in
  $ pip-compile -o ~/package_req/requirements_all.txt \\
      ~/package_req/requirements_user.in \\
      /opt/aapf/1.5.4/python_env/py3/python_system_packages.txt

Pythonパッケージの依存関係を無視してライブラリをインストールする
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| :ref:`resolve_version_conflict` にあるようなバージョン競合が発生したとしても、
| Pythonパッケージの依存関係を無視して、ライブラリをインストールすることができます。

| その場合、Jupyter Notebookが動かなくなる等の何らかの不具合が発生する可能性があります。
| これらの不具合を許容して、ライブラリを利用したい場合は、以下のコマンドを実行してください。

.. code-block:: bash

  $ pip install <インストールするライブラリのPythonパッケージ名>

.. _failed-pip-install:

pip installコマンドが失敗する
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
`pip install` コマンドの実行時に表示されたエラーメッセージから
インストールが失敗した原因を特定し、対処を行ってください。

失敗した原因の例として以下が考えられます。

* インストール時に拡張モジュールのビルドが必要なPythonパッケージである
   * あらかじめ拡張モジュールをビルドした上で、Wheelファイルを作成してからインストールしてください
* AAClusterにインストールされていないRPMパッケージが必要である
   * 分析PF管理者に必要なRPMパッケージのインストールを依頼してください

.. _failed-operation-check:

追加したライブラリの動作確認で失敗する
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
動作確認時に発生したエラーメッセージなどから不具合の原因を調査し、対処を行ってください。

動作に不具合がある原因の例として以下が考えられます。

* 動作に必要なPythonパッケージが足りていない
   * 追加のPythonパッケージが必要な場合は、そのPythonパッケージをさらにインストールしてください
* AAClusterにインストールされていないRPMパッケージが必要である
   * 分析PF管理者に必要なRPMパッケージのインストールを依頼してください

付録
----

.. _init_aacluster:

AAClusterを初期状態にする
~~~~~~~~~~~~~~~~~~~~~~~~~
AAClusterを初期状態にしたい場合は、AAClusterを作成し直す必要があります。

| AAPF WebUIのTopページから、対象のAAClusterを[Delete]ボタンを押下して削除し、
  [Create AACluster] ボタンを押下して新しくAAClusterを作成します。
| 詳しくは、 :doc:`manage_aacluster` を参照してください。

.. note:: AAClusterを削除すると、永続化領域( :ref:`about_working_storage` 参照)以外に
          配置されているファイルは削除され復元することはできません。

.. note:: 初期状態にする前のPythonパッケージ構成に戻したい場合は、ライブラリの追加作業中に
          生成した `requirements_all.txt` （本手順では、`~/package_req/requirements_all.txt`）を利用して
          `pip install` コマンドを実行することで、簡単に復元することができます。

問い合わせに必要な情報
~~~~~~~~~~~~~~~~~~~~~~
| ライブラリのインストール後もAAClusterにプリインストールされているPythonパッケージの依存関係が満たされることを
| 確認したにもかかわらず、ライブラリの動作に不具合が生じる場合に、問い合わせを行う際は以下の情報が必要になります。

* インストールしたライブラリのPythonパッケージの名前
* 不具合の生じているAAClusterにインストールされているPythonパッケージの一覧
  （取得方法は :ref:`こちら <confirm-available-packages>`）
