# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# # README
#
# ---
#
# VCP SDKを用いてクラウド上にCoursewareHub環境を構築します。

# ## 変更履歴
#
# ###  [20.04.0](https://github.com/nii-gakunin-cloud/ocs-templates/releases/tag/release%2F20.04.0)からの変更点
#
#
# 主に[NII-cloud-operation/CoursewareHub-LC_platform](https://github.com/NII-cloud-operation/CoursewareHub-LC_platform)の [#14](https://github.com/NII-cloud-operation/CoursewareHub-LC_platform/pull/14)から[#25](https://github.com/NII-cloud-operation/CoursewareHub-LC_platform/pull/25)までの変更内容を取り込んでいます。
#
# 追加された主要な機能を以下に記します。
#
# * 学認連携に基づく認証
# * LMS(Learning Management System)との認証連携
# * managerノードとNFSサーバを別ノードとして構成することを選択できるようになった
# * single-userコンテナに割り当てるリソース量をグループや認可タイプ毎に設定できるようになった

# ## はじめに
#
# このアプリケーションテンプレートではVCPで作成したノードに[CoursewareHub](https://github.com/NII-cloud-operation/CoursewareHub-LC_jupyterhub-deploy)環境を構築します。

# ### CoursewareHubのユーザ認証について
#
# CoursewareHubではユーザの認証機能として以下に示す三つの方式に対応しています。
#
# * ローカルユーザ認証
#     * CoursewareHubのローカルユーザデータベースを用いてユーザ管理を行う
# * 学認連携に基づく認証
#     * [学認](https://www.gakunin.jp/)のSPとして登録し、認証連携を行う
#     * CoursewareHubを直接SPとしては登録せずに、プロキシ(IdPプロキシ)を経由して連携することも可能
# * LMS(Learning Management System)との認証連携
#     * [LTI 1.3](http://www.imsglobal.org/spec/lti/v1p3/)による認証連携を行う
#     * このテンプレートでは連携するLMSとして[Moodle](https://moodle.org/)を想定している
#
# それぞれの認証機能は共存することが可能になっています。ただし、学認連携認証を用いる場合はコンテナの構成や設定手順が異なります。そのため、それに応じた異なる構築手順を用意しています。
#
# 一方 LMSとの認証連携を行う場合は、まずローカルユーザ認証、あるいは学認連携認証の手順でCoursewareHubを構築してください。その後にLMSとの認証連携の設定を追加する手順となっています。

# ### コンテナの構成について
#
# ローカルユーザ認証のみを用いる場合と、学認連携認証を利用する場合とではコンテナの構成が異なります。ここでは、それぞれのコンテナ構成について記します。
#
# CoursewareHubでは、学認連携の有無、あるいは連携方法の違いにより以下に示す方式を選択することができます。
# * ローカルユーザ認証のみを利用する
# * 学認フェデレーションに参加し、学認のIdPを利用して認証を行う
#     - IdP-proxyをSPとして学認に登録し、複数のCoursewareHubがIdP-proxyを通して学認のIdPを利用する
#     - CoursewareHubを直接SPとして学認に登録する
#     
# それぞれの方式に対応する構成図を以下に示します。
#     
# #### ローカルユーザ認証のみを利用する場合
#
# ![モジュール構成a](images/cw-000-a.png)
#
# #### IdP-proxyを利用する場合
#
# ![モジュール構成b](images/cw-000-b.png)
#
# #### CoursewareHubを直接SPとして登録する場合
#
# ![モジュール構成c](images/cw-000-c.png)

# ### ノード構成
#
# CoursewareHubのノードは役割に応じて以下のものに分類されます
#
# * manager
#     - JupyterHub, auth-proxy, PostgreSQLなどのSystemコンテナを実行するノード
#     - Docker Swarmのmanagerノードとなる
# * worker
#     - single-user Jupyter notebook serverを実行するノード
#     - Docker Swarm の workerノードとなる
#     
# CoursewareHubではデータやNotebookなどをノード間で共有するためにNFSを利用します。NFSサーバの配置により以下の３つパターン構成が可能となっています。
#
# 1. 構成1
#     - managerノードにNFSサーバを配置する
# 1. 構成2
#     - managerノードとNFSサーバを別のノードとして構成する
# 1. 構成3
#     - 構成2のNFSサーバに、新たなCoursewareHub環境を追加する構成

# #### 構成1
#
# managerノードでNFSサーバを実行します。
#
# ![構成1](notebooks/images/cw-011-01.png)

# #### 構成2
#
# managerノードとNFSサーバを分離し別々のノードとして構築します。
#
# ![構成2](notebooks/images/cw-021-01.png)

# #### 構成3
#
# 構成2のNFSサーバに、新たなCoursewareHub環境を追加します。NFSサーバは複数のCoursewareHub環境で共有されます。
#
# ![構成3](notebooks/images/cw-031-01.png)

# ### 収容設計について

# #### managerノード

# * システム用コンテナが実行される
#     - auth-proxyコンテナ
#     - JupyterHubコンテナ
#     - PostgreSQLコンテナ
# * ユーザが利用する single-userサーバコンテナは実行されない
# * NFSサーバをmanagerノードに共存させる場合（構成１）はディスク容量を適切な値に設定する

# #### workerノード

# * ユーザが利用するsingle-userコンテナが実行される
# * single-userコンテナのリソース量として以下の設定を行っている
#     - 最大CPU利用数
#     - 最大メモリ量(GB)
#     - 保証される最小割当てメモリ量(GB)
# * システム全体で必要となるリソース量を見積もるには
#     - (コンテナに割り当てるリソース量)×(最大同時使用人数)+(システムが利用するリソース量)×(ノード数)

# #### 運用例

# * 最大同時使用人数
#     - 400 人
# * コンテナに割り当てるリソース量
#     - メモリ最小値保証
#         - 1GB
#     - メモリ最大値制限
#         - 2GB(swap 4GB)
#     - CPU最大値制限
#         - 200% (2cores)
#         
# 上記の条件で運用を行った際の実績値を示します。

# * managerノード
#     - vCPU
#         - 10
#     - memory
#         - 16GB
#     - HDD
#         - 800GB
# * workerノード
#   - ノードA
#     - ノード数
#         - 4
#     - vCPU
#         - 30
#     - memory
#         - 100GB
#     - HDD
#         - 300GB
#   - ノードB
#     - ノード数
#         - 1
#     - vCPU
#         - 20
#     - memory
#         - 80GB
#     - HDD
#         - 300GB
#
# > workerノードはリソース量の異なるノードAとノードBで構成されていた。
#
# workerノードのメモリ総量は480GB(=100×4+80)となっていますが、これは以下のように見積もっています。
# ```
# (コンテナのメモリ最小値保証)×(最大同時使用人数)+(システム利用分)
# = 1GB × 400人 + 80GB
# ```

# ## 事前に準備が必要となるものについて
#
# このアプリケーションテンプレートを実行するにあたって事前に準備が必要となるものについて記します。

# ### VCノード
#
# ノードを作成するとき必要となるものについて記します。

# * VCCアクセストークン
#     - VCP SDKを利用してクラウド環境にノード作成などを行うために必要となります
#     - VCCアクセストークンがない場合はVC管理者に発行を依頼してください
# * SSH公開鍵ペア
#     - VCノードに登録するSSHの公開鍵
#     - このNotebook環境内で新たに作成するか、事前に作成したものをこの環境にアップロードしておいてください
# * VCノードに割り当てるアドレス
#     - ノードのネットワークインタフェースに以下に示す何れかのアドレスを指定することができます
#         - IPアドレス
#         - MACアドレス
# * NTPの設定
#     - 学認フェデレーションに参加し SAML 認証を利用する場合、正しい時刻設定が必要となります
#     - VCノードのNTPサービスを有効にするためには、事前にVCコントローラへの設定が必要となります
#     - VCコントローラへの設定にはOCS運用担当者への申請が必要となります

# ### CoursewareHub
#
# CoursewareHub環境を構築する際に必要となるものについて記します。

# * CoursewareHubのサーバ証明書
#     - CoursewareHubではHTTPSでサーバを公開するため、サーバ証明書とその秘密鍵が必要となります
#     - 必要に応じて、サーバ証明書の中間CA証明書を準備してください
#     - サーバ証明書に記載されているホスト名のDNS登録も必要となります
#
# また事前の段階では不要ですが、学認のIdPを認証に利用する場合は構築手順の過程で
# 学認フェデレーションに参加の申請を行う必要があります。

# ### IdP-proxy
#
# IdP-proxy を構築する際に必要となるものについて記します。

# * IdP-proxyのサーバ証明書
#     - IdP-proxyではHTTPSでサーバを公開するため、サーバ証明書とその秘密鍵が必要となります
#     - 必要に応じて、サーバ証明書の中間CA証明書を準備してください
#     - サーバ証明書に記載されているホスト名のDNS登録も必要となります
#
# また事前の段階では不要ですが、学認のIdPを認証に利用する場合は構築手順の過程で
# 学認フェデレーションに参加の申請を行う必要があります。

# ## Notebookの一覧
#
# テンプレートのNotebook一覧を示します。

# **注意**:
#
# この節ではテンプレートのNotebookへのリンクを示す箇所がありますが、リンク先のNotebookは参照用となっていて**そのままでは実行できません**。
#
# > Notebook自体は実行できてしまいますが、パスなどが想定しているものと異なるため正しく処理できずエラーとなります。
#
# 次のどちらかの手順で作業用Notebookを作成する必要があります。
#
# * 次節の「作業用Notebookの作成」で作業用のNotebookを作成する。
# * テンプレートのNotebookを配置してある `notebooks/` から、この`000-README.ipynb`と同じディレクトリにNotebookをコピーする。

# ### 各Notebookの関連について
#
# 各Notebookの実行順序などの関係性を示す図を表示します。

# 次のセルを実行すると、各Notebookの関連を示す図を表示します。
#
# > 図が表示されずに `<IPython.core.display.SVG object>` と表示されている場合は、次のセルを `unfreeze` した後に再実行してください。
#
# 図に表示される１つのブロックが１つのNotebookに対応しており、ブロックのタイトル部分にNotebookへのリンクが埋め込まれています。

# #### ローカルユーザ認証のみを利用する場合

from IPython.display import SVG
# %run scripts/nb_utils.py
setup_diag()
SVG(filename=generate_svg_diag(diag='images/notebooks-a.diag'))

# #### IdP-proxyを利用する場合

from IPython.display import SVG
# %run scripts/nb_utils.py
setup_diag()
SVG(filename=generate_svg_diag(diag='images/notebooks-b.diag'))

# #### CoursewareHubを直接SPとして登録する場合
#

from IPython.display import SVG
# %run scripts/nb_utils.py
setup_diag()
SVG(filename=generate_svg_diag(diag='images/notebooks-c.diag'))

# ### 各Notebookの目次

# 次のセルを実行すると、各Notebookの目次が表示されます。
#
# > 目次が表示されずに `<IPython.core.display.Markdown object>` と表示されている場合は、次のセルを `unfreeze` した後に再実行してください。
#
# リンクが表示されている項目が一つのNotebookに対応しており、そのサブ項目が各Notebook内の目次になっています。

from IPython.display import Markdown
# %run scripts/nb_utils.py
Markdown(notebooks_toc())

# ## 作業用Notebookの作成
#
# この節のセルを実行することで、テンプレートのNotebookから作業用Notebookを作成することができます。

# まず、作業用Notebookを配置するディレクトリを指定してください。

WORK_DIR = 'work'

# 以下のセルを実行すると、Notebook名のドロップダウンリストと「作業開始」ボタンが現れます。
# 「作業開始」ボタンを押すと、テンプレートのNotebookをコピーし、そのNotebookを自動的にブラウザで開きます。
# Notebookの説明を確認しながら実行、適宜修正しながら実行していってください。
#
# > このNotebookを Shutdown した後に再度開いた場合、次のセルに既に表示されている「作用開始」ボタンが正しく動作しません。この節のセルをいったん unfreeze した後、セルを再実行してから「作業開始」ボタンをクリックして下さい。
#
# 認証方式毎に実行するNotebookが異なるので、対応する節のセルを実行してください。

# ### ローカルユーザ認証のみを利用する場合

from IPython.core.display import HTML
# %run scripts/nb_utils.py
setup_nb_workdir(WORK_DIR)
HTML(generate_html_work_nbs(WORK_DIR, nb_group='group-a'))

# ### IdP-proxyを利用する場合

# #### IdP-proxyの構築

from IPython.core.display import HTML
# %run scripts/nb_utils.py
setup_nb_workdir(WORK_DIR)
HTML(generate_html_work_nbs(WORK_DIR, nb_group='group-b0'))

# #### CoursewareHubの構築

from IPython.core.display import HTML
# %run scripts/nb_utils.py
setup_nb_workdir(WORK_DIR)
HTML(generate_html_work_nbs(WORK_DIR, nb_group='group-b1'))

# ### CoursewareHubを直接SPとして登録する場合

from IPython.core.display import HTML
# %run scripts/nb_utils.py
setup_nb_workdir(WORK_DIR)
HTML(generate_html_work_nbs(WORK_DIR, nb_group='group-c'))

StarcoderdataJupyterScriptsDedupFiltered