├── .gitignore ├── deploy.yml ├── roles └── deploy-manage-tools │ ├── tasks │ └── main.yml │ └── files │ ├── tools │ ├── 12_UpdateMaterials.ipynb │ ├── 10_AcquireMaterials.ipynb │ ├── 00_GuidanceForStudent.ipynb │ └── 11_CheckUpdate.ipynb │ ├── admin-tools │ ├── 15_RestoreMaterialsFromGitHub.ipynb │ ├── 10_ReleaseMaterials.ipynb │ ├── 81_DelLocalUsers.ipynb │ ├── 82_ResetLocalUsersPassword.ipynb │ ├── 14_BackupMaterialsToGitHub.ipynb │ ├── 00_GuidanceForTeacher.ipynb │ ├── 85_ShowUserGroups.ipynb │ ├── 03_PrepareGitHub.ipynb │ ├── 13_RestoreMaterials.ipynb │ ├── 21_RestoreStudentMaterials.ipynb │ ├── 83_AddUsersToGroup.ipynb │ ├── 84_RemoveUsersFromGroup.ipynb │ └── 12_BackupMaterials.ipynb │ └── common │ ├── 01_JupyterOverview.ipynb │ ├── notebook-diff │ └── 02_JupyterOperationTips.ipynb ├── README.md └── LICENSE.txt /.gitignore: -------------------------------------------------------------------------------- 1 | .lc_wrapper_regex.txt 2 | .ipynb_checkpoints/ 3 | -------------------------------------------------------------------------------- /deploy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - become: true 3 | hosts: ch-master 4 | roles: 5 | - deploy-manage-tools 6 | -------------------------------------------------------------------------------- /roles/deploy-manage-tools/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - file: path=/jupyter/admin/admin_tools state=directory 3 | - file: path=/jupyter/admin/tools state=directory 4 | 5 | - copy: src=admin-tools/ dest=/jupyter/admin/admin_tools/ 6 | - copy: src=tools/ dest=/jupyter/admin/tools/ 7 | - copy: src=common/ dest=/jupyter/admin/admin_tools/ 8 | - copy: src=common/ dest=/jupyter/admin/tools/ 9 | 10 | - file: path=/jupyter/admin/tools/notebook-diff mode=a+x 11 | ignore_errors: "{{ ansible_check_mode }}" 12 | - file: path=/jupyter/admin/admin_tools/notebook-diff mode=a+x 13 | ignore_errors: "{{ ansible_check_mode }}" 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CoursewareHub-LC_manage-tools 2 | 3 | The management notebooks for CoursewareHub. 4 | 5 | # How to deploy the notebooks to your CoursewareHub 6 | 7 | Please log in to CoursewareHub as a teacher(an administrator) for the following operations. 8 | 9 | Clone this repository to local. 10 | 11 | $ git clone https://github.com/NII-cloud-operation/CoursewareHub-LC_manage-tools.git 12 | 13 | Run the ansible playbook named `deploy.yml`. 14 | 15 | $ cd CoursewareHub-LC_manage-tools 16 | $ ansible-playbook -i ~/ansible/inventory deploy.yml 17 | 18 | You can execute these operations in Jupyter Notebook or Jupyter terminal. 19 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2017-2018, National Institute of Informatics. 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /roles/deploy-manage-tools/files/tools/12_UpdateMaterials.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "lc_cell_meme": { 7 | "current": "aaa354ca-fe70-11ef-9b05-02420a640257", 8 | "next": "aaa35510-fe70-11ef-9b05-02420a640257", 9 | "previous": null 10 | } 11 | }, 12 | "source": [ 13 | "# 教材の更新\n", 14 | "---" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": { 20 | "lc_cell_meme": { 21 | "current": "aaa35510-fe70-11ef-9b05-02420a640257", 22 | "next": "aaa35542-fe70-11ef-9b05-02420a640257", 23 | "previous": "aaa354ca-fe70-11ef-9b05-02420a640257" 24 | } 25 | }, 26 | "source": [ 27 | "Homeディレクトリに配置されている教材を、 `textbook` フォルダの教材で更新します。\n", 28 | "\n", 29 | "はじめに、次のセルを実行して、更新されたファイルを確認して下さい。\n", 30 | "\n", 31 | "ファイル毎の更新内容を確認するには、[11_CheckUpdate.ipynb](11_CheckUpdate.ipynb)を利用して下さい。\n", 32 | "\n", 33 | "このセルで利用しているスクリプトはこちらを参照して下さい。\n", 34 | " + [notebook-diff](./notebook-diff)" 35 | ] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "execution_count": null, 40 | "metadata": { 41 | "deletable": false, 42 | "editable": false, 43 | "lc_cell_meme": { 44 | "current": "aaa35542-fe70-11ef-9b05-02420a640257", 45 | "next": "aaa35600-fe70-11ef-9b05-02420a640257", 46 | "previous": "aaa35510-fe70-11ef-9b05-02420a640257" 47 | }, 48 | "run_through_control": { 49 | "frozen": false 50 | } 51 | }, 52 | "outputs": [], 53 | "source": [ 54 | "%%bash\n", 55 | "\n", 56 | "./notebook-diff ~/${CWH_COURSE_NAME}/textbook/ ~/${CWH_COURSE_NAME}\n", 57 | "if [ $? -ne 0 ]; then\n", 58 | " echo 'There are updates available.' 1>&2\n", 59 | "else\n", 60 | " echo 'No updates are available' 1>&2\n", 61 | "fi" 62 | ] 63 | }, 64 | { 65 | "cell_type": "markdown", 66 | "metadata": { 67 | "lc_cell_meme": { 68 | "current": "aaa35600-fe70-11ef-9b05-02420a640257", 69 | "next": "aaa35628-fe70-11ef-9b05-02420a640257", 70 | "previous": "aaa35542-fe70-11ef-9b05-02420a640257" 71 | } 72 | }, 73 | "source": [ 74 | "更新する教材が特定できたら、次のセルで `cp` コマンドを実行して下さい。\n", 75 | "\n", 76 | "`textbook` フォルダの教材をHomeディレクトリにコピーします。\n", 77 | "\n", 78 | "```\n", 79 | "cp -r ~/textbook/notebook-1.ipynb ~/.\n", 80 | "```" 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "execution_count": null, 86 | "metadata": { 87 | "lc_cell_meme": { 88 | "current": "aaa35628-fe70-11ef-9b05-02420a640257", 89 | "next": null, 90 | "previous": "aaa35600-fe70-11ef-9b05-02420a640257" 91 | } 92 | }, 93 | "outputs": [], 94 | "source": [] 95 | } 96 | ], 97 | "metadata": { 98 | "kernelspec": { 99 | "display_name": "Python 3", 100 | "language": "python", 101 | "name": "python3" 102 | }, 103 | "language_info": { 104 | "file_extension": ".py", 105 | "mimetype": "text/x-python", 106 | "name": "python", 107 | "nbconvert_exporter": "python", 108 | "pygments_lexer": "ipython3", 109 | "version": "3.10.11" 110 | }, 111 | "lc_notebook_meme": { 112 | "current": "aaa353b2-fe70-11ef-9b05-02420a640257" 113 | }, 114 | "toc": { 115 | "base_numbering": 1, 116 | "nav_menu": {}, 117 | "number_sections": true, 118 | "sideBar": true, 119 | "skip_h1_title": false, 120 | "title_cell": "Table of Contents", 121 | "title_sidebar": "Contents", 122 | "toc_cell": false, 123 | "toc_position": {}, 124 | "toc_section_display": true, 125 | "toc_window_display": false 126 | } 127 | }, 128 | "nbformat": 4, 129 | "nbformat_minor": 2 130 | } 131 | -------------------------------------------------------------------------------- /roles/deploy-manage-tools/files/tools/10_AcquireMaterials.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "lc_cell_meme": { 7 | "current": "3addfb90-5773-11e9-9e9f-02420a0001bc-1-f352", 8 | "history": [ 9 | { 10 | "current": "3addfb90-5773-11e9-9e9f-02420a0001bc-1-f352", 11 | "next": "3addfbea-5773-11e9-9e9f-02420a0001bc", 12 | "previous": null 13 | } 14 | ], 15 | "next": "3addfbea-5773-11e9-9e9f-02420a0001bc-1-e4ff", 16 | "previous": null 17 | } 18 | }, 19 | "source": [ 20 | "# 教材の取得\n", 21 | "---" 22 | ] 23 | }, 24 | { 25 | "cell_type": "markdown", 26 | "metadata": { 27 | "lc_cell_meme": { 28 | "current": "3addfbea-5773-11e9-9e9f-02420a0001bc-1-e4ff", 29 | "history": [ 30 | { 31 | "current": "3addfbea-5773-11e9-9e9f-02420a0001bc-1-e4ff", 32 | "next": "3addfc1c-5773-11e9-9e9f-02420a0001bc", 33 | "previous": "3addfb90-5773-11e9-9e9f-02420a0001bc" 34 | } 35 | ], 36 | "next": "3addfc1c-5773-11e9-9e9f-02420a0001bc-1-8d50", 37 | "previous": "3addfb90-5773-11e9-9e9f-02420a0001bc-1-f352" 38 | } 39 | }, 40 | "source": [ 41 | "`textbook/` フォルダ内の演習Notebookなどの教材を取得します。\n", 42 | "\n", 43 | "この講座の教材を利用する場合は、このnoebookを実行して教材を取得します。
\n", 44 | "取得した教材は、Homeディレクトリに配置されます。演習はHomeに配置された演習Notebookで行なって下さい。\n", 45 | "\n", 46 | "次のセルを実行して、教材を取得して下さい。" 47 | ] 48 | }, 49 | { 50 | "cell_type": "code", 51 | "execution_count": null, 52 | "metadata": { 53 | "deletable": false, 54 | "editable": false, 55 | "lc_cell_meme": { 56 | "current": "3addfc1c-5773-11e9-9e9f-02420a0001bc-1-8d50", 57 | "history": [ 58 | { 59 | "current": "3addfc1c-5773-11e9-9e9f-02420a0001bc-1-8d50", 60 | "next": null, 61 | "previous": "3addfbea-5773-11e9-9e9f-02420a0001bc" 62 | } 63 | ], 64 | "next": null, 65 | "previous": "3addfbea-5773-11e9-9e9f-02420a0001bc-1-e4ff" 66 | }, 67 | "run_through_control": { 68 | "frozen": false 69 | } 70 | }, 71 | "outputs": [], 72 | "source": [ 73 | "%%bash\n", 74 | "\n", 75 | "cd\n", 76 | "umask 0022\n", 77 | "\n", 78 | "rsync -vhi -rLkKEtW ~/${CWH_COURSE_NAME}/textbook/ ~/${CWH_COURSE_NAME}\n", 79 | "if [ $? -ne 0 ]; then\n", 80 | " echo 'Failed to acquire materials.'\n", 81 | " exit 1\n", 82 | "fi\n", 83 | "\n", 84 | "find ~/ \\\n", 85 | " '(' -path ~/tools \\\n", 86 | " -o -path ~/textbook \\\n", 87 | " -o -path ~/info \\\n", 88 | " -o -path ~/private-info \\\n", 89 | " -o -name '.*' ')' -prune \\\n", 90 | " -o -type f -name '*.ipynb' \\\n", 91 | " -execdir jupyter-trust '{}' ';'" 92 | ] 93 | } 94 | ], 95 | "metadata": { 96 | "kernelspec": { 97 | "display_name": "Python 3", 98 | "language": "python", 99 | "name": "python3" 100 | }, 101 | "language_info": { 102 | "file_extension": ".py", 103 | "mimetype": "text/x-python", 104 | "name": "python", 105 | "nbconvert_exporter": "python", 106 | "pygments_lexer": "ipython3", 107 | "version": "3.10.11" 108 | }, 109 | "lc_notebook_meme": { 110 | "current": "34783468-fe6c-11ef-9b05-02420a640257" 111 | }, 112 | "toc": { 113 | "base_numbering": 1, 114 | "nav_menu": {}, 115 | "number_sections": true, 116 | "sideBar": true, 117 | "skip_h1_title": false, 118 | "title_cell": "Table of Contents", 119 | "title_sidebar": "Contents", 120 | "toc_cell": false, 121 | "toc_position": {}, 122 | "toc_section_display": true, 123 | "toc_window_display": false 124 | } 125 | }, 126 | "nbformat": 4, 127 | "nbformat_minor": 2 128 | } 129 | -------------------------------------------------------------------------------- /roles/deploy-manage-tools/files/tools/00_GuidanceForStudent.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "---\n", 8 | "# 受講者向けガイダンス\n", 9 | "---\n", 10 | "## はじめに\n", 11 | "---\n", 12 | "このガイダンスでは、Jupyterを利用した教材の利用方法について説明します。
\n", 13 | "Jupyterの概要については、[こちら](./01_JupyterOverview.ipynb)を参照して下さい。\n" 14 | ] 15 | }, 16 | { 17 | "cell_type": "markdown", 18 | "metadata": {}, 19 | "source": [ 20 | "## ホームの構成について\n", 21 | "---\n", 22 | "Jupyterにログインすると、Jupyterのダッシュボード画面のFilesタグが表示されます。FilesタグにはHomeディレクトリの内容が表示されています。
\n", 23 | "Homeディレクトリ配下は以下のフォルダがあります。\n", 24 | "\n", 25 | "* textbook\n", 26 | " + 演習に利用する教材(notebook、scriptその他)\n", 27 | "* info\n", 28 | " + 受講者全員に向けた資料などのファイル\n", 29 | "* private_info\n", 30 | " + 受講者個人毎に異なる情報を格納" 31 | ] 32 | }, 33 | { 34 | "cell_type": "markdown", 35 | "metadata": {}, 36 | "source": [ 37 | "## 1. この講座の教材を初めて利用する場合" 38 | ] 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "metadata": {}, 43 | "source": [ 44 | "### 1.1 演習実施の流れ\n", 45 | "---\n", 46 | "教材はHomeディレクトリにあるフォルダ「textbook」に格納されています。これを入手して演習を実施します。
\n", 47 | "課題が与えられた場合は、指示に従って回答ファイルを作成します。
\n", 48 | "演習実施は概ね下記の流れになります。\n", 49 | "\n", 50 | "1. 教材の入手\n", 51 | "2. 演習の実施\n", 52 | "3. 課題の回答作成" 53 | ] 54 | }, 55 | { 56 | "cell_type": "markdown", 57 | "metadata": {}, 58 | "source": [ 59 | "![documentflowstudent-1](https://cloud.githubusercontent.com/assets/1156894/26245034/3f31ff74-3ccd-11e7-9738-62f7d9a70178.png)" 60 | ] 61 | }, 62 | { 63 | "cell_type": "markdown", 64 | "metadata": {}, 65 | "source": [ 66 | "### 1.2 教材を入手する\n", 67 | "---\n", 68 | "教材の入手は、notebook [10_AcquireMaterials.ipynb](./10_AcquireMaterials.ipynb) で行って下さい。
\n", 69 | "入手した教材は、Homeディレクトリ直下に展開されます。" 70 | ] 71 | }, 72 | { 73 | "cell_type": "markdown", 74 | "metadata": {}, 75 | "source": [ 76 | "### 1.3 演習の実施\n", 77 | "---\n", 78 | "指示に従って演習を実施して下さい。
\n", 79 | "notebookの操作に関しては、[こちら](./02_JupyterOperationTips.ipynb)を参考にして下さい。" 80 | ] 81 | }, 82 | { 83 | "cell_type": "markdown", 84 | "metadata": {}, 85 | "source": [ 86 | "## 2. 教材が更新された場合\n", 87 | "特に講座が複数の日に跨る場合、教材が変更されるケースがあります。
\n", 88 | "教材に変更があった場合は、こちらの手順で教材を更新して演習を実施します。" 89 | ] 90 | }, 91 | { 92 | "cell_type": "markdown", 93 | "metadata": {}, 94 | "source": [ 95 | "### 2.1 教材が更新された場合の演習実施の流れ\n", 96 | "---\n", 97 | "教材の変更はHomeディレクトリにあるフォルダ「textbook」に格納されています。これを入手して演習を実施します。
\n", 98 | "演習実施は概ね下記の流れになります。「3. 演習の実施」以降は「1. この講座の教材を初めて利用する場合」と同じです。\n", 99 | "\n", 100 | "1. 教材の更新を確認\n", 101 | "2. 教材を更新\n", 102 | "3. 演習の実施\n", 103 | "4. 課題の回答作成" 104 | ] 105 | }, 106 | { 107 | "cell_type": "markdown", 108 | "metadata": {}, 109 | "source": [ 110 | "![documentflowstudent-2](https://cloud.githubusercontent.com/assets/1156894/26245041/45eb65c6-3ccd-11e7-9fbf-ce92a455e548.png)" 111 | ] 112 | }, 113 | { 114 | "cell_type": "markdown", 115 | "metadata": {}, 116 | "source": [ 117 | "### 2.2 教材の更新を確認する\n", 118 | "---\n", 119 | "教材が更新内容は、notebook [11_CheckUpdate.ipynb](./11_CheckUpdate.ipynb) で確認できます。このnotebookを利用して下さい。
" 120 | ] 121 | }, 122 | { 123 | "cell_type": "markdown", 124 | "metadata": {}, 125 | "source": [ 126 | "### 2.3 教材を更新する\n", 127 | "---\n", 128 | "textbookから更新された教材を取得して、Homeディレクトリ配下の教材を更新します。
\n", 129 | "#### 更新された教材を個別に更新する場合\n", 130 | "更新された教材の中から特定の教材のみを更新する場合は、notebook [12_UpdateMaterials.ipynb](./12_UpdateMaterials.ipynb) を利用して下さい。
\n", 131 | "#### 更新された教材を一括更新する場合\n", 132 | "更新された教材を一括更新する場合は、notebook [10_AcquireMaterials.ipynb](./10_AcquireMaterials.ipynb) を利用して下さい。
" 133 | ] 134 | } 135 | ], 136 | "metadata": { 137 | "kernelspec": { 138 | "display_name": "Python 3", 139 | "language": "python", 140 | "name": "python3" 141 | }, 142 | "language_info": { 143 | "codemirror_mode": { 144 | "name": "ipython", 145 | "version": 3 146 | }, 147 | "file_extension": ".py", 148 | "mimetype": "text/x-python", 149 | "name": "python", 150 | "nbconvert_exporter": "python", 151 | "pygments_lexer": "ipython3", 152 | "version": "3.7.1" 153 | }, 154 | "toc": { 155 | "colors": { 156 | "hover_highlight": "#DAA520", 157 | "navigate_num": "#000000", 158 | "navigate_text": "#333333", 159 | "running_highlight": "#FF0000", 160 | "selected_highlight": "#FFD700", 161 | "sidebar_border": "#EEEEEE", 162 | "wrapper_background": "#FFFFFF" 163 | }, 164 | "moveMenuLeft": true, 165 | "nav_menu": { 166 | "height": "225px", 167 | "width": "252px" 168 | }, 169 | "navigate_menu": true, 170 | "number_sections": true, 171 | "sideBar": true, 172 | "threshold": 4, 173 | "toc_cell": false, 174 | "toc_section_display": "block", 175 | "toc_window_display": false, 176 | "widenNotebook": false 177 | } 178 | }, 179 | "nbformat": 4, 180 | "nbformat_minor": 1 181 | } 182 | -------------------------------------------------------------------------------- /roles/deploy-manage-tools/files/admin-tools/15_RestoreMaterialsFromGitHub.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "lc_cell_meme": { 7 | "current": "935f6ee2-4bfd-11e9-b578-02420a0001bc", 8 | "history": [], 9 | "next": "935f6f64-4bfd-11e9-b578-02420a0001bc", 10 | "previous": null 11 | } 12 | }, 13 | "source": [ 14 | "# GitHubに保存した教材バックアップをリストアします\n", 15 | "---" 16 | ] 17 | }, 18 | { 19 | "cell_type": "markdown", 20 | "metadata": { 21 | "lc_cell_meme": { 22 | "current": "935f6f64-4bfd-11e9-b578-02420a0001bc", 23 | "history": [], 24 | "next": "935f6fc8-4bfd-11e9-b578-02420a0001bc", 25 | "previous": "935f6ee2-4bfd-11e9-b578-02420a0001bc" 26 | } 27 | }, 28 | "source": [ 29 | "GitHubリポジトリに保存してある教材バックアップをリストアします。" 30 | ] 31 | }, 32 | { 33 | "cell_type": "markdown", 34 | "metadata": { 35 | "lc_cell_meme": { 36 | "current": "935f6fc8-4bfd-11e9-b578-02420a0001bc", 37 | "history": [], 38 | "next": "935f7018-4bfd-11e9-b578-02420a0001bc", 39 | "previous": "935f6f64-4bfd-11e9-b578-02420a0001bc" 40 | } 41 | }, 42 | "source": [ 43 | "# リストアの準備" 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "metadata": { 49 | "lc_cell_meme": { 50 | "current": "935f7018-4bfd-11e9-b578-02420a0001bc", 51 | "history": [], 52 | "next": "935f7068-4bfd-11e9-b578-02420a0001bc", 53 | "previous": "935f6fc8-4bfd-11e9-b578-02420a0001bc" 54 | } 55 | }, 56 | "source": [ 57 | "このNotebookを実行すると、GitHubリポジトリの教材バックアップをホームディレクトリ直下に展開します。\n", 58 | "\n", 59 | "**リストアするには下記のフォルダ/ファイルは、全てバックアップの内容で上書きされます。**\n", 60 | "* `textbook`\n", 61 | "* `info`\n", 62 | "* `draft`\n", 63 | "* `test`\n", 64 | "* 任意でバックアップに追加したフォルダ/ファイル" 65 | ] 66 | }, 67 | { 68 | "cell_type": "markdown", 69 | "metadata": { 70 | "lc_cell_meme": { 71 | "current": "935f7068-4bfd-11e9-b578-02420a0001bc", 72 | "history": [], 73 | "next": "935f70b8-4bfd-11e9-b578-02420a0001bc", 74 | "previous": "935f7018-4bfd-11e9-b578-02420a0001bc" 75 | } 76 | }, 77 | "source": [ 78 | "# GitHubリポジトリへの接続情報を設定します" 79 | ] 80 | }, 81 | { 82 | "cell_type": "markdown", 83 | "metadata": { 84 | "lc_cell_meme": { 85 | "current": "935f70b8-4bfd-11e9-b578-02420a0001bc", 86 | "history": [], 87 | "next": "935f7108-4bfd-11e9-b578-02420a0001bc", 88 | "previous": "935f7068-4bfd-11e9-b578-02420a0001bc" 89 | } 90 | }, 91 | "source": [ 92 | "バックアップ先のGitHubリポジトリへの接続情報を設定します。\n", 93 | "\n", 94 | "1. GitHubに接続するSSHキーを新たに登録する場合は、 [GitHubリポジトリの準備/2. SSHキーの登録](03_PrepareGitHub.ipynb#create_ssh_key)を使って作成して下さい。\n", 95 | "2. [GitHubリポジトリの準備/3. GitHubリポジトリ接続情報の設定](03_PrepareGitHub.ipynb#connect_github_repo)を使って、バックアップ用のGitHubリポジトリの接続情報を設定して下さい。" 96 | ] 97 | }, 98 | { 99 | "cell_type": "markdown", 100 | "metadata": { 101 | "lc_cell_meme": { 102 | "current": "935f7108-4bfd-11e9-b578-02420a0001bc", 103 | "history": [], 104 | "next": "935f7158-4bfd-11e9-b578-02420a0001bc", 105 | "previous": "935f70b8-4bfd-11e9-b578-02420a0001bc" 106 | } 107 | }, 108 | "source": [ 109 | "# 次のセルを実行して、教材バックアップを展開して下さい" 110 | ] 111 | }, 112 | { 113 | "cell_type": "markdown", 114 | "metadata": { 115 | "lc_cell_meme": { 116 | "current": "935f7158-4bfd-11e9-b578-02420a0001bc", 117 | "history": [], 118 | "next": "935f71a8-4bfd-11e9-b578-02420a0001bc", 119 | "previous": "935f7108-4bfd-11e9-b578-02420a0001bc" 120 | } 121 | }, 122 | "source": [ 123 | "GitHubから教材バックアップを取得して、ホームディレクトリに展開します。" 124 | ] 125 | }, 126 | { 127 | "cell_type": "code", 128 | "execution_count": null, 129 | "metadata": { 130 | "lc_cell_meme": { 131 | "current": "935f71a8-4bfd-11e9-b578-02420a0001bc", 132 | "history": [], 133 | "next": null, 134 | "previous": "935f7158-4bfd-11e9-b578-02420a0001bc" 135 | } 136 | }, 137 | "outputs": [], 138 | "source": [ 139 | "%%bash\n", 140 | "\n", 141 | "cd\n", 142 | "comm -13 <(sort ~/.ssh/known_hosts) <(ssh-keyscan github.com 2>/dev/null | sort) >>~/.ssh/known_hosts\n", 143 | "\n", 144 | "IS_INSIDE_REPO=0\n", 145 | "S=\"$(git rev-parse --is-inside-work-tree 2>/dev/null)\"\n", 146 | "[ $? -eq 0 -a \"${S}\" = \"true\" ] && IS_INSIDE_REPO=1\n", 147 | "\n", 148 | "if [ ${IS_INSIDE_REPO} -ne 1 ]; then\n", 149 | " echo \"ERROR: git repository not initialized.\" 1>&2\n", 150 | " exit 1\n", 151 | "fi\n", 152 | "\n", 153 | "git fetch --force origin\n", 154 | "git reset --hard origin/master\n", 155 | "\n", 156 | "git ls-files -c | while read -r path; do\n", 157 | " if [ -f \"${path}\" -a \"${path: -6}\" = \".ipynb\" ]; then\n", 158 | " jupyter-trust \"${path}\"\n", 159 | " fi\n", 160 | "done" 161 | ] 162 | } 163 | ], 164 | "metadata": { 165 | "kernelspec": { 166 | "display_name": "Python 3", 167 | "language": "python", 168 | "name": "python3" 169 | }, 170 | "language_info": { 171 | "codemirror_mode": { 172 | "name": "ipython", 173 | "version": 3 174 | }, 175 | "file_extension": ".py", 176 | "mimetype": "text/x-python", 177 | "name": "python", 178 | "nbconvert_exporter": "python", 179 | "pygments_lexer": "ipython3", 180 | "version": "3.6.8" 181 | }, 182 | "lc_notebook_meme": { 183 | "current": "935f6d8e-4bfd-11e9-b578-02420a0001bc", 184 | "history": [], 185 | "root_cells": [ 186 | "935f6ee2-4bfd-11e9-b578-02420a0001bc", 187 | "935f6f64-4bfd-11e9-b578-02420a0001bc", 188 | "935f6fc8-4bfd-11e9-b578-02420a0001bc", 189 | "935f7018-4bfd-11e9-b578-02420a0001bc", 190 | "935f7068-4bfd-11e9-b578-02420a0001bc", 191 | "935f70b8-4bfd-11e9-b578-02420a0001bc", 192 | "935f7108-4bfd-11e9-b578-02420a0001bc", 193 | "935f7158-4bfd-11e9-b578-02420a0001bc", 194 | "935f71a8-4bfd-11e9-b578-02420a0001bc" 195 | ] 196 | }, 197 | "toc": { 198 | "base_numbering": 1, 199 | "nav_menu": {}, 200 | "number_sections": true, 201 | "sideBar": true, 202 | "skip_h1_title": false, 203 | "title_cell": "Table of Contents", 204 | "title_sidebar": "Contents", 205 | "toc_cell": false, 206 | "toc_position": {}, 207 | "toc_section_display": true, 208 | "toc_window_display": true 209 | } 210 | }, 211 | "nbformat": 4, 212 | "nbformat_minor": 2 213 | } 214 | -------------------------------------------------------------------------------- /roles/deploy-manage-tools/files/common/01_JupyterOverview.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "lc_cell_meme": { 7 | "current": "907db35a-4bfd-11e9-b98e-02420a0001bc", 8 | "history": [], 9 | "next": "907db3dc-4bfd-11e9-b98e-02420a0001bc", 10 | "previous": null 11 | } 12 | }, 13 | "source": [ 14 | "---\n", 15 | "# 演習ドキュメントの提供環境Jupyterの概要\n", 16 | "---" 17 | ] 18 | }, 19 | { 20 | "cell_type": "markdown", 21 | "metadata": { 22 | "lc_cell_meme": { 23 | "current": "907db3dc-4bfd-11e9-b98e-02420a0001bc", 24 | "history": [], 25 | "next": "907db440-4bfd-11e9-b98e-02420a0001bc", 26 | "previous": "907db35a-4bfd-11e9-b98e-02420a0001bc" 27 | } 28 | }, 29 | "source": [ 30 | "## Jupyterは…\n", 31 | "---\n", 32 | "\n", 33 | "* Webブラウザを用いてアクセスでき、\n", 34 | "* Markdown形式で記述されたドキュメントの表示と、\n", 35 | "* 部分的に任意の言語(コード)を埋め込み可能で、\u000b", 36 | "そのコードの表示、その場での実行、結果の表示が行える\n", 37 | "* インタラクティブなインターフェイスを提供するツール\n", 38 | "* PDFよりもインタラクティブ性が高く、Eラーニングシステムとして利用できる側面がある\n", 39 | "\n", 40 | "![jupyteroverview-1](https://cloud.githubusercontent.com/assets/1156894/20752911/230fa406-b747-11e6-94f1-83966a550c74.png)\n" 41 | ] 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "metadata": { 46 | "lc_cell_meme": { 47 | "current": "907db440-4bfd-11e9-b98e-02420a0001bc", 48 | "history": [], 49 | "next": "907db490-4bfd-11e9-b98e-02420a0001bc", 50 | "previous": "907db3dc-4bfd-11e9-b98e-02420a0001bc" 51 | } 52 | }, 53 | "source": [ 54 | "## Jupyterの構造\n", 55 | "---\n", 56 | "Jupyterは、ドキュメントを開くと同時に、対になるBashなどのプロセスを起動し、それと相互通信を行う。Jupyter ServerとブラウザはWebSocketで接続されている。
\n", 57 | "※ ipynb ... iPython Notebookの略。Jupyterの旧称\n", 58 | "\n", 59 | "![jupyteroverview-2](https://cloud.githubusercontent.com/assets/1156894/20753127/43192ef6-b748-11e6-9f57-417e06a687c2.png)\n" 60 | ] 61 | }, 62 | { 63 | "cell_type": "markdown", 64 | "metadata": { 65 | "lc_cell_meme": { 66 | "current": "907db490-4bfd-11e9-b98e-02420a0001bc", 67 | "history": [], 68 | "next": "907db4e0-4bfd-11e9-b98e-02420a0001bc", 69 | "previous": "907db440-4bfd-11e9-b98e-02420a0001bc" 70 | } 71 | }, 72 | "source": [ 73 | "## Bash Kernelを使う\n", 74 | "---\n", 75 | "![jupyteroverview-3](https://cloud.githubusercontent.com/assets/1156894/20754341/d8b6e6b0-b74d-11e6-85e7-fe5a1510ec63.png)" 76 | ] 77 | }, 78 | { 79 | "cell_type": "markdown", 80 | "metadata": { 81 | "lc_cell_meme": { 82 | "current": "907db4e0-4bfd-11e9-b98e-02420a0001bc", 83 | "history": [], 84 | "next": "907db530-4bfd-11e9-b98e-02420a0001bc", 85 | "previous": "907db490-4bfd-11e9-b98e-02420a0001bc" 86 | } 87 | }, 88 | "source": [ 89 | "## Bash Kernelでコマンドを実行する\n", 90 | "---\n", 91 | "![jupyteroverview-4](https://cloud.githubusercontent.com/assets/1156894/20754344/db2d362e-b74d-11e6-947f-500c06ca24a7.png)" 92 | ] 93 | }, 94 | { 95 | "cell_type": "markdown", 96 | "metadata": { 97 | "lc_cell_meme": { 98 | "current": "907db530-4bfd-11e9-b98e-02420a0001bc", 99 | "history": [], 100 | "next": "907db58a-4bfd-11e9-b98e-02420a0001bc", 101 | "previous": "907db4e0-4bfd-11e9-b98e-02420a0001bc" 102 | } 103 | }, 104 | "source": [ 105 | "## Kernelが起動している状態\n", 106 | "---\n", 107 | "![jupyteroverview-5](https://cloud.githubusercontent.com/assets/1156894/20754345/dd95ce44-b74d-11e6-9aaf-d3168d431690.png)" 108 | ] 109 | }, 110 | { 111 | "cell_type": "markdown", 112 | "metadata": { 113 | "lc_cell_meme": { 114 | "current": "907db58a-4bfd-11e9-b98e-02420a0001bc", 115 | "history": [], 116 | "next": "907db5da-4bfd-11e9-b98e-02420a0001bc", 117 | "previous": "907db530-4bfd-11e9-b98e-02420a0001bc" 118 | } 119 | }, 120 | "source": [ 121 | "## Kernelが起動している間は状態が維持される\n", 122 | "---\n", 123 | "![jupyteroverview-6](https://cloud.githubusercontent.com/assets/1156894/20754350/e02da442-b74d-11e6-9adb-8eb5d29b2fc9.png)\n", 124 | "Jupyterは、Kernelとして起動したプロセスがある限り、そのプロセスと通信を続ける。
\n", 125 | "プロセスの状態が変化すれば、それは次に実行されるCellの中から参照ができる。" 126 | ] 127 | }, 128 | { 129 | "cell_type": "markdown", 130 | "metadata": { 131 | "lc_cell_meme": { 132 | "current": "907db5da-4bfd-11e9-b98e-02420a0001bc", 133 | "history": [], 134 | "next": "907db62a-4bfd-11e9-b98e-02420a0001bc", 135 | "previous": "907db58a-4bfd-11e9-b98e-02420a0001bc" 136 | } 137 | }, 138 | "source": [ 139 | "## Kernel終了と再起動\n", 140 | "---\n", 141 | "![jupyteroverview-7](https://cloud.githubusercontent.com/assets/1156894/20754355/e49df18a-b74d-11e6-84f6-0de98fb144be.png)" 142 | ] 143 | }, 144 | { 145 | "cell_type": "markdown", 146 | "metadata": { 147 | "lc_cell_meme": { 148 | "current": "907db62a-4bfd-11e9-b98e-02420a0001bc", 149 | "history": [], 150 | "next": "907db67a-4bfd-11e9-b98e-02420a0001bc", 151 | "previous": "907db5da-4bfd-11e9-b98e-02420a0001bc" 152 | } 153 | }, 154 | "source": [ 155 | "## 便利なターミナル機能\n", 156 | "---\n", 157 | "従来通り、ターミナルから色々と試したい場合は、Jupyter上で新規にターミナルウインドウを開くことができます。\n", 158 | "Cellの中で確認しづらい事は、こちらを利用すると便利です。\n", 159 | "![jupyteroverview-8](https://cloud.githubusercontent.com/assets/1156894/20754362/e85383bc-b74d-11e6-93e5-8f5d7339d304.png)\n", 160 | "上記のように、Wakame-vdcで起動したインスタンスにもssh接続できます。" 161 | ] 162 | }, 163 | { 164 | "cell_type": "markdown", 165 | "metadata": { 166 | "lc_cell_meme": { 167 | "current": "907db67a-4bfd-11e9-b98e-02420a0001bc", 168 | "history": [], 169 | "next": null, 170 | "previous": "907db62a-4bfd-11e9-b98e-02420a0001bc" 171 | } 172 | }, 173 | "source": [ 174 | "## 【参考】Jupyterからpingのような処理が継続するコマンドを打つ\n", 175 | "---\n", 176 | "![jupyteroverview-9](https://cloud.githubusercontent.com/assets/1156894/20754371/ebc78980-b74d-11e6-9d0a-988755543aa1.png)\n" 177 | ] 178 | } 179 | ], 180 | "metadata": { 181 | "kernelspec": { 182 | "display_name": "Python 3", 183 | "language": "python", 184 | "name": "python3" 185 | }, 186 | "language_info": { 187 | "codemirror_mode": { 188 | "name": "ipython", 189 | "version": 3 190 | }, 191 | "file_extension": ".py", 192 | "mimetype": "text/x-python", 193 | "name": "python", 194 | "nbconvert_exporter": "python", 195 | "pygments_lexer": "ipython3", 196 | "version": "3.6.8" 197 | }, 198 | "lc_notebook_meme": { 199 | "current": "907db1f2-4bfd-11e9-b98e-02420a0001bc", 200 | "history": [], 201 | "root_cells": [ 202 | "907db35a-4bfd-11e9-b98e-02420a0001bc", 203 | "907db3dc-4bfd-11e9-b98e-02420a0001bc", 204 | "907db440-4bfd-11e9-b98e-02420a0001bc", 205 | "907db490-4bfd-11e9-b98e-02420a0001bc", 206 | "907db4e0-4bfd-11e9-b98e-02420a0001bc", 207 | "907db530-4bfd-11e9-b98e-02420a0001bc", 208 | "907db58a-4bfd-11e9-b98e-02420a0001bc", 209 | "907db5da-4bfd-11e9-b98e-02420a0001bc", 210 | "907db62a-4bfd-11e9-b98e-02420a0001bc", 211 | "907db67a-4bfd-11e9-b98e-02420a0001bc" 212 | ] 213 | }, 214 | "toc": { 215 | "base_numbering": 1, 216 | "nav_menu": {}, 217 | "number_sections": true, 218 | "sideBar": true, 219 | "skip_h1_title": false, 220 | "title_cell": "Table of Contents", 221 | "title_sidebar": "Contents", 222 | "toc_cell": false, 223 | "toc_position": {}, 224 | "toc_section_display": true, 225 | "toc_window_display": false 226 | } 227 | }, 228 | "nbformat": 4, 229 | "nbformat_minor": 1 230 | } 231 | -------------------------------------------------------------------------------- /roles/deploy-manage-tools/files/tools/11_CheckUpdate.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "lc_cell_meme": { 7 | "current": "9d9c7912-fe6d-11ef-9b05-02420a640257", 8 | "next": "9d9c794e-fe6d-11ef-9b05-02420a640257", 9 | "previous": null 10 | } 11 | }, 12 | "source": [ 13 | "# 教材の更新確認\n", 14 | "---" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": { 20 | "lc_cell_meme": { 21 | "current": "9d9c794e-fe6d-11ef-9b05-02420a640257", 22 | "next": "9d9c7976-fe6d-11ef-9b05-02420a640257", 23 | "previous": "9d9c7912-fe6d-11ef-9b05-02420a640257" 24 | } 25 | }, 26 | "source": [ 27 | "ホームディレクトリと `textbook` フォルダの教材を比較して、変更された教材ファイルの一覧を表示します。\n", 28 | "\n", 29 | "次のセルを実行して教材の更新の有無を確認してください。" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": null, 35 | "metadata": { 36 | "lc_cell_meme": { 37 | "current": "9d9c7976-fe6d-11ef-9b05-02420a640257", 38 | "next": "9d9c799e-fe6d-11ef-9b05-02420a640257", 39 | "previous": "9d9c794e-fe6d-11ef-9b05-02420a640257" 40 | } 41 | }, 42 | "outputs": [], 43 | "source": [ 44 | "import os, sys, urllib.parse, IPython.display, subprocess\n", 45 | "\n", 46 | "course_name = os.environ['CWH_COURSE_NAME']\n", 47 | "server_name = os.environ['JUPYTERHUB_SERVER_NAME']\n", 48 | "\n", 49 | "assert course_name != '', \"コース用のサーバー上で実行してください\"\n", 50 | "\n", 51 | "HOME_DIR = os.path.expanduser('~')\n", 52 | "TEXTBOOK_DIR = os.path.join(HOME_DIR, course_name, 'textbook')\n", 53 | "\n", 54 | "def get_released_files():\n", 55 | " for root, dirs, files in os.walk(TEXTBOOK_DIR):\n", 56 | " for file in files:\n", 57 | " yield os.path.relpath(os.path.join(root, file), start=TEXTBOOK_DIR)\n", 58 | "\n", 59 | "rows = []\n", 60 | "for file in sorted(get_released_files()):\n", 61 | " my_file = os.path.join(HOME_DIR, course_name, file)\n", 62 | " if os.path.isfile(my_file):\n", 63 | " try:\n", 64 | " cmd = './notebook-diff {} {}'.format(os.path.join(TEXTBOOK_DIR, file), my_file)\n", 65 | " diff = subprocess.run(cmd, shell=True)\n", 66 | " if diff.returncode == 0:\n", 67 | " rows.append((0, file, None))\n", 68 | " else:\n", 69 | " u = None\n", 70 | " if file.endswith('.ipynb'):\n", 71 | " p1 = urllib.parse.quote(file, safe='')\n", 72 | " p2 = urllib.parse.quote('/'.join(('textbook', file)), safe='')\n", 73 | " u = '/user-redirect/{}/tree?diffpath1={}&diffpath2={}#notebook_diff'.format(server_name, p2, p1)\n", 74 | " rows.append((1, file, u))\n", 75 | " except OSError as e:\n", 76 | " print('ERROR: notebook-diff failed: {}'.format(e), file=sys.stderr)\n", 77 | " else:\n", 78 | " rows.append((2, file, None))\n", 79 | "\n", 80 | "html = [\n", 81 | " '

',\n", 82 | " '更新があります' if [r for r in rows if r[0]] else '更新はありません',\n", 83 | " '

',\n", 84 | " ''\n", 85 | "]\n", 86 | "for row in rows:\n", 87 | " html.extend([\n", 88 | " ''.format(['#999', '#66c', '#c66'][row[0]]),\n", 89 | " '
',\n", 90 | " ['変更なし', '変更あり', '新規'][row[0]],\n", 91 | " '',\n", 92 | " '',\n", 93 | " row[1],\n", 94 | " '',\n", 95 | " ''\n", 96 | " ])\n", 97 | " if row[2] is not None:\n", 98 | " html.append('差分表示'.format(row[2]))\n", 99 | "html.append('
')\n", 100 | "\n", 101 | "IPython.display.display(IPython.display.HTML(''.join(html)))" 102 | ] 103 | }, 104 | { 105 | "cell_type": "markdown", 106 | "metadata": { 107 | "lc_cell_meme": { 108 | "current": "9d9c799e-fe6d-11ef-9b05-02420a640257", 109 | "next": "9d9c79c6-fe6d-11ef-9b05-02420a640257", 110 | "previous": "9d9c7976-fe6d-11ef-9b05-02420a640257" 111 | } 112 | }, 113 | "source": [ 114 | " " 115 | ] 116 | }, 117 | { 118 | "cell_type": "markdown", 119 | "metadata": { 120 | "lc_cell_meme": { 121 | "current": "9d9c79c6-fe6d-11ef-9b05-02420a640257", 122 | "next": "9d9c79ee-fe6d-11ef-9b05-02420a640257", 123 | "previous": "9d9c799e-fe6d-11ef-9b05-02420a640257" 124 | } 125 | }, 126 | "source": [ 127 | "---\n", 128 | "# 教材の更新" 129 | ] 130 | }, 131 | { 132 | "cell_type": "markdown", 133 | "metadata": { 134 | "lc_cell_meme": { 135 | "current": "9d9c79ee-fe6d-11ef-9b05-02420a640257", 136 | "next": "9d9c7a0c-fe6d-11ef-9b05-02420a640257", 137 | "previous": "9d9c79c6-fe6d-11ef-9b05-02420a640257" 138 | } 139 | }, 140 | "source": [ 141 | "上のセルを実行した結果、「変更あり」もしくは「新規」の教材を取得して更新します。\n", 142 | "対象となる Notebook に対して行なっている編集や、実行結果は、全て上書きされ破棄されますのでご注意ください。\n", 143 | "\n", 144 | "次のセルを実行すると、教材が更新されます。" 145 | ] 146 | }, 147 | { 148 | "cell_type": "code", 149 | "execution_count": null, 150 | "metadata": { 151 | "deletable": false, 152 | "editable": false, 153 | "lc_cell_meme": { 154 | "current": "9d9c7a0c-fe6d-11ef-9b05-02420a640257", 155 | "next": null, 156 | "previous": "9d9c79ee-fe6d-11ef-9b05-02420a640257" 157 | }, 158 | "run_through_control": { 159 | "frozen": false 160 | } 161 | }, 162 | "outputs": [], 163 | "source": [ 164 | "import os, sys, os.path, shutil\n", 165 | "\n", 166 | "if not 'rows' in globals():\n", 167 | " print('上のセルを実行してください。', file=sys.stderr)\n", 168 | "else:\n", 169 | " updated = False\n", 170 | " for row in [r for r in rows if r[0]]:\n", 171 | " src = os.path.join(TEXTBOOK_DIR, row[1])\n", 172 | " dst = os.path.join(HOME_DIR, course_name, row[1])\n", 173 | " dstdir = os.path.dirname(dst)\n", 174 | " if not os.path.isdir(dstdir):\n", 175 | " os.makedirs(dstdir, mode=0o755, exist_ok=True)\n", 176 | " shutil.copy2(src, dst)\n", 177 | " print('{} -> {}'.format(src,dst))\n", 178 | " if dst.endswith('.ipynb'):\n", 179 | " try:\n", 180 | " cmd = 'jupyter-trust {}'.format(dst)\n", 181 | " proc = subprocess.run(cmd, shell=True)\n", 182 | " if proc.returncode != 0:\n", 183 | " print('trust に失敗: {}'.format(dst), file=sys.stderr)\n", 184 | " updated = True\n", 185 | " except OSError as e:\n", 186 | " print('ERROR: jupyter-trust failed: {}'.format(e), file=sys.stderr)\n", 187 | " if updated:\n", 188 | " print('教材を更新しました。')\n", 189 | " else:\n", 190 | " print('更新はありません。', file=sys.stderr)" 191 | ] 192 | } 193 | ], 194 | "metadata": { 195 | "kernelspec": { 196 | "display_name": "Python 3", 197 | "language": "python", 198 | "name": "python3" 199 | }, 200 | "language_info": { 201 | "file_extension": ".py", 202 | "mimetype": "text/x-python", 203 | "name": "python", 204 | "nbconvert_exporter": "python", 205 | "pygments_lexer": "ipython3", 206 | "version": "3.10.11" 207 | }, 208 | "lc_notebook_meme": { 209 | "current": "9d9c7778-fe6d-11ef-9b05-02420a640257" 210 | }, 211 | "toc": { 212 | "base_numbering": 1, 213 | "nav_menu": {}, 214 | "number_sections": true, 215 | "sideBar": true, 216 | "skip_h1_title": false, 217 | "title_cell": "Table of Contents", 218 | "title_sidebar": "Contents", 219 | "toc_cell": false, 220 | "toc_position": {}, 221 | "toc_section_display": true, 222 | "toc_window_display": false 223 | } 224 | }, 225 | "nbformat": 4, 226 | "nbformat_minor": 2 227 | } 228 | -------------------------------------------------------------------------------- /roles/deploy-manage-tools/files/common/notebook-diff: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #set -x 3 | 4 | umask 0022 5 | shopt -s extglob 6 | 7 | ONE_DIRECTIONAL=1 8 | # one-directional mode 9 | 10 | BRIEF_OPT= 11 | IGNORE_D_REGEX='^(\.git|\.local|\.ipynb_checkpoints|\.ipython|\.jupyter)$' 12 | IGNORE_R_REGEX='^(\.bash_history)$' 13 | 14 | 15 | 16 | 17 | # 18 | # control functions 19 | # 20 | show_usage () { 21 | echo "Usage:" 1>&2 22 | if [ ${ONE_DIRECTIONAL} -eq 1 ]; then 23 | echo -e "\tnotebook-diff FILE-SRC FILE-DST" 1>&2 24 | echo -e "\tnotebook-diff DIRECTORY-SRC DIRECTORY-DST" 1>&2 25 | else 26 | echo -e "\tnotebook-diff FILE1 FILE2" 1>&2 27 | echo -e "\tnotebook-diff DIRECTORY1 DIRECTORY2" 1>&2 28 | fi 29 | exit 1 30 | } 31 | 32 | clean_up() { 33 | cd 34 | if [ ! -z "${TMP_WORK_DIR}" ]; then 35 | if [ -d "${TMP_WORK_DIR}" ]; then 36 | rm -rf "${TMP_WORK_DIR}" 37 | fi 38 | fi 39 | } 40 | 41 | error_exit() { 42 | local IFS=' ' 43 | cat <<<"notebook-diff: ${*}" 1>&2 44 | clean_up 45 | exit 1 46 | } 47 | 48 | ensure_work_dir() { 49 | if [ -z "${TMP_WORK_DIR}" ]; then 50 | TMP_WORK_DIR="$(mktemp --tmpdir --directory notebook-diff-XXXXXXXXXXXX)" 51 | if [ ! -d "${TMP_WORK_DIR}" ]; then 52 | error_exit "failed to create temporary directory ${TMP_WORK_DIR}." 53 | fi 54 | mkdir -p "${TMP_WORK_DIR}/text" 55 | fi 56 | } 57 | 58 | ensure_normalize_jq_filter() { 59 | if [ -z "${NORMALIZE_JQ_FILTER}" ]; then 60 | NORMALIZE_JQ_FILTER=$(cat <<'END_OF_JQ_FILTER' 61 | [ 62 | .cells 63 | | map( 64 | { 65 | "cell_type": .cell_type, 66 | "cell_text": [ 67 | ( 68 | .source[] 69 | | rtrimstr( "\n" ) 70 | | gsub( "^\\s+|\\s+$"; "" ) 71 | | select( test( "^\\s*$" ) | not ) 72 | ) 73 | ] 74 | } 75 | ) 76 | | .[] 77 | | select( 0 < ( .cell_text | length ) ) 78 | ] 79 | END_OF_JQ_FILTER 80 | ) 81 | fi 82 | } 83 | 84 | 85 | 86 | 87 | # 88 | # diff functions 89 | # 90 | normalize_jupyter_notebook () { 91 | local nb_file="${1}" 92 | local nb_name="${2}" 93 | local text_file="${TMP_WORK_DIR}/text/${nb_name}" 94 | 95 | ensure_normalize_jq_filter 96 | jq \ 97 | --sort-keys \ 98 | --monochrome-output \ 99 | --indent 1 \ 100 | "${NORMALIZE_JQ_FILTER}" \ 101 | <"${nb_file}" \ 102 | >"${text_file}" \ 103 | 2>/dev/null 104 | local es=$? 105 | 106 | return ${es} 107 | } 108 | 109 | diff_jupyter_notebooks () { 110 | local file_x="${1}" 111 | local file_y="${2}" 112 | 113 | ensure_work_dir 114 | 115 | local text_file_x="$(basename "${file_x}")" 116 | local text_file_y="$(basename "${file_y}")" 117 | if [ "${text_file_x}" = "${text_file_y}" ]; then 118 | text_file_x+="-1" 119 | text_file_y+="-2" 120 | fi 121 | 122 | local normalize_error=0 123 | normalize_jupyter_notebook "${file_x}" "${text_file_x}" 124 | if [ $? -ne 0 ]; then 125 | echo "WARNING: ${file_x}: failed to normalize notebook, treat as regular file." 126 | normalize_error=1 127 | fi 128 | normalize_jupyter_notebook "${file_y}" "${text_file_y}" 129 | if [ $? -ne 0 ]; then 130 | echo "WARNING: ${file_y}: failed to normalize notebook, treat as regular file." 131 | normalize_error=2 132 | fi 133 | if [ ${normalize_error} -ne 0 ]; then 134 | diff ${BRIEF_OPT} "${file_x}" "${file_y}" 135 | rm -f "${TMP_WORK_DIR}/text/${text_file_x}" "${TMP_WORK_DIR}/text/${text_file_y}" 136 | return $? 137 | fi 138 | 139 | command pushd "${TMP_WORK_DIR}/text/" >/dev/null 140 | diff ${BRIEF_OPT} "${text_file_x}" "${text_file_y}" 141 | local es=$? 142 | command popd >/dev/null 143 | 144 | rm -f "${TMP_WORK_DIR}/text/${text_file_x}" "${TMP_WORK_DIR}/text/${text_file_y}" 145 | 146 | return ${es} 147 | } 148 | 149 | diff_regular_files () { 150 | local file_x="${1}" 151 | local file_y="${2}" 152 | local es=0 153 | 154 | if [ ! -r "${file_x}" ]; then 155 | cat <<<"notebook-diff: ${file_x}: Permission denied" 1>&2 156 | es=2 157 | fi 158 | if [ ! -r "${file_y}" ]; then 159 | cat <<<"notebook-diff: ${file_y}: Permission denied" 1>&2 160 | es=2 161 | fi 162 | if [ ${es} -ne 0 ]; then 163 | return ${es} 164 | fi 165 | 166 | if [ "${file_x: -6}" = '.ipynb' -o "${file_y: -6}" = '.ipynb' ]; then 167 | diff_jupyter_notebooks "${file_x}" "${file_y}" 168 | es=$? 169 | else 170 | diff ${BRIEF_OPT} "${file_x}" "${file_y}" 171 | es=$? 172 | fi 173 | return ${es} 174 | } 175 | 176 | diff_directories () { 177 | local dir_x="${1%%+(/)}" 178 | local dir_y="${2%%+(/)}" 179 | local level="${3-0}" 180 | local differ=0 181 | 182 | if [ ! -x "${dir_x}" ]; then 183 | cat <<<"notebook-diff: ${dir_x}: Permission denied" 1>&2 184 | differ=2 185 | fi 186 | if [ ! -x "${dir_y}" ]; then 187 | cat <<<"notebook-diff: ${dir_y}: Permission denied" 1>&2 188 | differ=2 189 | fi 190 | if [ ${differ} -ne 0 ]; then 191 | return ${differ} 192 | fi 193 | 194 | ensure_work_dir 195 | local list_x="${TMP_WORK_DIR}/entries.${level}.x.list" 196 | local list_y="${TMP_WORK_DIR}/entries.${level}.y.list" 197 | 198 | find "${dir_x}" -mindepth 1 -maxdepth 1 -not -type d -print0 | xargs -0 -I PATH basename PATH | grep -Ev "${IGNORE_R_REGEX}" | sort >"${list_x}" 199 | if [ ${PIPESTATUS[0]} -ne 0 -o ${PIPESTATUS[1]} -ne 0 ]; then 200 | differ=2 201 | fi 202 | find "${dir_y}" -mindepth 1 -maxdepth 1 -not -type d -print0 | xargs -0 -I PATH basename PATH | grep -Ev "${IGNORE_R_REGEX}" | sort >"${list_y}" 203 | if [ ${PIPESTATUS[0]} -ne 0 -o ${PIPESTATUS[1]} -ne 0 ]; then 204 | differ=2 205 | fi 206 | if [ ${ONE_DIRECTIONAL} -eq 1 ]; then 207 | comm -23 "${list_x}" "${list_y}" | xargs -I PATH echo "Added: ${dir_x}/"PATH 208 | if [ $(comm -23 "${list_x}" "${list_y}" | wc -l) -gt 0 ]; then 209 | differ=1 210 | fi 211 | else 212 | comm -23 "${list_x}" "${list_y}" | xargs -I PATH echo "Only in ${dir_x}/:" PATH 213 | comm -13 "${list_x}" "${list_y}" | xargs -I PATH echo "Only in ${dir_y}/:" PATH 214 | if [ $(comm -3 "${list_x}" "${list_y}" | wc -l) -gt 0 ]; then 215 | differ=1 216 | fi 217 | fi 218 | while read line; do 219 | diff_regular_files "${dir_x}/${line}" "${dir_y}/${line}" 220 | if [ $? -ne 0 ]; then 221 | if [ ${ONE_DIRECTIONAL} -eq 1 ]; then 222 | echo "Changed: ${dir_x}/${line}" 223 | fi 224 | differ=1 225 | fi 226 | done < <(comm -12 "${list_x}" "${list_y}") 227 | 228 | find "${dir_x}" -mindepth 1 -maxdepth 1 -type d -print0 | xargs -0 -I PATH basename PATH | grep -Ev "${IGNORE_D_REGEX}" | sort >"${list_x}" 229 | if [ ${PIPESTATUS[0]} -ne 0 -o ${PIPESTATUS[1]} -ne 0 ]; then 230 | differ=2 231 | fi 232 | find "${dir_y}" -mindepth 1 -maxdepth 1 -type d -print0 | xargs -0 -I PATH basename PATH | grep -Ev "${IGNORE_D_REGEX}" | sort >"${list_y}" 233 | if [ ${PIPESTATUS[0]} -ne 0 -o ${PIPESTATUS[1]} -ne 0 ]; then 234 | differ=2 235 | fi 236 | if [ ${ONE_DIRECTIONAL} -eq 1 ]; then 237 | comm -23 "${list_x}" "${list_y}" | xargs -I PATH echo "Added: ${dir_x}/"PATH/ 238 | if [ $(comm -23 "${list_x}" "${list_y}" | wc -l) -gt 0 ]; then 239 | differ=1 240 | fi 241 | else 242 | comm -23 "${list_x}" "${list_y}" | xargs -I PATH echo "Only in ${dir_x}/:" PATH/ 243 | comm -13 "${list_x}" "${list_y}" | xargs -I PATH echo "Only in ${dir_y}/:" PATH/ 244 | if [ $(comm -3 "${list_x}" "${list_y}" | wc -l) -gt 0 ]; then 245 | differ=1 246 | fi 247 | fi 248 | while read line; do 249 | diff_directories "${dir_x}/${line}" "${dir_y}/${line}" $((${level} + 1)) 250 | if [ $? -ne 0 ]; then 251 | if [ ${ONE_DIRECTIONAL} -eq 1 ]; then 252 | echo "Changed: ${dir_x}/${line}/" 253 | fi 254 | differ=1 255 | fi 256 | done < <(comm -12 "${list_x}" "${list_y}") 257 | 258 | rm -f "${list_x}" "${list_y}" 259 | return ${differ} 260 | } 261 | 262 | 263 | 264 | 265 | # 266 | # main 267 | # 268 | if [ $# -ne 2 ]; then 269 | show_usage 270 | fi 271 | PATH_X="${1}" 272 | PATH_Y="${2}" 273 | 274 | diff_main () { 275 | local path_x="${1}" 276 | local path_y="${2}" 277 | if [ ! -e "${path_x}" ]; then 278 | error_exit "${path_x}: No such file or directory" 279 | elif [ ! -e "${path_y}" ]; then 280 | error_exit "${path_y}: No such file or directory" 281 | elif [ -d "${path_x}" -a -d "${path_y}" ]; then 282 | BRIEF_OPT=-q 283 | diff_directories "${path_x}" "${path_y}" 284 | return $? 285 | elif [ -d "${path_x}" ]; then 286 | diff_main "${path_x%%+(/)}/$(basename "${path_y}")" "${path_y}" 287 | return $? 288 | elif [ -d "${path_y}" ]; then 289 | diff_main "${path_x}" "${path_y%%+(/)}/$(basename "${path_x}")" 290 | return $? 291 | else 292 | diff_regular_files "${path_x}" "${path_y}" 293 | return $? 294 | fi 295 | } 296 | 297 | diff_main "${PATH_X}" "${PATH_Y}" 298 | ES=$? 299 | 300 | 301 | 302 | 303 | clean_up 304 | exit ${ES} 305 | -------------------------------------------------------------------------------- /roles/deploy-manage-tools/files/admin-tools/10_ReleaseMaterials.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "lc_cell_meme": { 7 | "current": "9193b640-4bfd-11e9-80f2-02420a0001bc-1-961e", 8 | "history": [ 9 | { 10 | "current": "9193b640-4bfd-11e9-80f2-02420a0001bc-1-961e", 11 | "next": "9193b6c2-4bfd-11e9-80f2-02420a0001bc", 12 | "previous": null 13 | } 14 | ], 15 | "next": "9193b6c2-4bfd-11e9-80f2-02420a0001bc-1-0ea3", 16 | "previous": null 17 | } 18 | }, 19 | "source": [ 20 | "# 教材をリリースします\n", 21 | "
" 22 | ] 23 | }, 24 | { 25 | "cell_type": "markdown", 26 | "metadata": { 27 | "collapsed": true, 28 | "lc_cell_meme": { 29 | "current": "9193b6c2-4bfd-11e9-80f2-02420a0001bc-1-0ea3", 30 | "history": [ 31 | { 32 | "current": "9193b6c2-4bfd-11e9-80f2-02420a0001bc-1-0ea3", 33 | "next": "9193b712-4bfd-11e9-80f2-02420a0001bc", 34 | "previous": "9193b640-4bfd-11e9-80f2-02420a0001bc" 35 | } 36 | ], 37 | "next": "9193b712-4bfd-11e9-80f2-02420a0001bc-1-017d", 38 | "previous": "9193b640-4bfd-11e9-80f2-02420a0001bc-1-961e" 39 | } 40 | }, 41 | "source": [ 42 | "作成した演習Notebook、講義資料などの教材をリリースします。
\n", 43 | "リリースすると、各受講者のHome画面で教材を操作できるようになります。" 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "metadata": { 49 | "lc_cell_meme": { 50 | "current": "9193b712-4bfd-11e9-80f2-02420a0001bc-1-017d", 51 | "history": [ 52 | { 53 | "current": "9193b712-4bfd-11e9-80f2-02420a0001bc-1-017d", 54 | "next": "9193b762-4bfd-11e9-80f2-02420a0001bc", 55 | "previous": "9193b6c2-4bfd-11e9-80f2-02420a0001bc" 56 | } 57 | ], 58 | "next": "9193b762-4bfd-11e9-80f2-02420a0001bc-1-06b2", 59 | "previous": "9193b6c2-4bfd-11e9-80f2-02420a0001bc-1-0ea3" 60 | } 61 | }, 62 | "source": [ 63 | "## 1. リリースの準備" 64 | ] 65 | }, 66 | { 67 | "cell_type": "markdown", 68 | "metadata": { 69 | "lc_cell_meme": { 70 | "current": "9193b762-4bfd-11e9-80f2-02420a0001bc-1-06b2", 71 | "history": [ 72 | { 73 | "current": "9193b762-4bfd-11e9-80f2-02420a0001bc-1-06b2", 74 | "next": "9193b7b2-4bfd-11e9-80f2-02420a0001bc", 75 | "previous": "9193b712-4bfd-11e9-80f2-02420a0001bc" 76 | } 77 | ], 78 | "next": "9193b7b2-4bfd-11e9-80f2-02420a0001bc-1-8dbd", 79 | "previous": "9193b712-4bfd-11e9-80f2-02420a0001bc-1-017d" 80 | } 81 | }, 82 | "source": [ 83 | "* リリースする教材をホームディレクトリ直下の下記のフォルダに格納してします。\n", 84 | " * textbook : 演習Notebookおよび演習Notebook実行に関わるスクリプト、設定ファイルなどを格納します。\n", 85 | " * info : 受講者全員が参照する資料などを格納します。" 86 | ] 87 | }, 88 | { 89 | "cell_type": "markdown", 90 | "metadata": { 91 | "lc_cell_meme": { 92 | "current": "9193b7b2-4bfd-11e9-80f2-02420a0001bc-1-8dbd", 93 | "history": [ 94 | { 95 | "current": "9193b7b2-4bfd-11e9-80f2-02420a0001bc-1-8dbd", 96 | "next": "9193b7f8-4bfd-11e9-80f2-02420a0001bc", 97 | "previous": "9193b762-4bfd-11e9-80f2-02420a0001bc" 98 | } 99 | ], 100 | "next": "9193b7f8-4bfd-11e9-80f2-02420a0001bc-1-0103", 101 | "previous": "9193b762-4bfd-11e9-80f2-02420a0001bc-1-06b2" 102 | } 103 | }, 104 | "source": [ 105 | "## 2. 次のセルを実行して、教材をリリースして下さい。" 106 | ] 107 | }, 108 | { 109 | "cell_type": "markdown", 110 | "metadata": { 111 | "lc_cell_meme": { 112 | "current": "9193b7f8-4bfd-11e9-80f2-02420a0001bc-1-0103", 113 | "history": [ 114 | { 115 | "current": "9193b7f8-4bfd-11e9-80f2-02420a0001bc-1-0103", 116 | "next": "9193b848-4bfd-11e9-80f2-02420a0001bc", 117 | "previous": "9193b7b2-4bfd-11e9-80f2-02420a0001bc" 118 | } 119 | ], 120 | "next": "9193b848-4bfd-11e9-80f2-02420a0001bc-1-0ae7", 121 | "previous": "9193b7b2-4bfd-11e9-80f2-02420a0001bc-1-8dbd" 122 | } 123 | }, 124 | "source": [ 125 | " リリースすると、各受講者のJupyterのHome画面でフォルダ「textbook」「info」として参照できるようになリます。" 126 | ] 127 | }, 128 | { 129 | "cell_type": "code", 130 | "execution_count": null, 131 | "metadata": { 132 | "deletable": false, 133 | "editable": false, 134 | "lc_cell_meme": { 135 | "current": "9193b848-4bfd-11e9-80f2-02420a0001bc-1-0ae7", 136 | "history": [ 137 | { 138 | "current": "9193b848-4bfd-11e9-80f2-02420a0001bc-1-0ae7", 139 | "next": "9193b88e-4bfd-11e9-80f2-02420a0001bc", 140 | "previous": "9193b7f8-4bfd-11e9-80f2-02420a0001bc" 141 | }, 142 | { 143 | "current": "9193b848-4bfd-11e9-80f2-02420a0001bc-1-0ae7", 144 | "next": "9193b88e-4bfd-11e9-80f2-02420a0001bc-1-3d06", 145 | "previous": "9193b7f8-4bfd-11e9-80f2-02420a0001bc-1-0103" 146 | } 147 | ], 148 | "next": "64cc969c-fd8e-11ef-ac33-02420a64024e", 149 | "previous": "9193b7f8-4bfd-11e9-80f2-02420a0001bc-1-0103" 150 | }, 151 | "run_through_control": { 152 | "frozen": false 153 | } 154 | }, 155 | "outputs": [], 156 | "source": [ 157 | "%%writefile /tmp/release.excludes\n", 158 | ".ipynb_checkpoints\n", 159 | ".ipython\n", 160 | ".jupyter\n", 161 | ".git\n", 162 | ".ssh\n", 163 | ".local\n", 164 | ".log" 165 | ] 166 | }, 167 | { 168 | "cell_type": "code", 169 | "execution_count": null, 170 | "metadata": { 171 | "deletable": false, 172 | "editable": false, 173 | "lc_cell_meme": { 174 | "current": "64cc969c-fd8e-11ef-ac33-02420a64024e", 175 | "next": "9193b88e-4bfd-11e9-80f2-02420a0001bc-1-3d06", 176 | "previous": "9193b848-4bfd-11e9-80f2-02420a0001bc-1-0ae7" 177 | }, 178 | "run_through_control": { 179 | "frozen": false 180 | } 181 | }, 182 | "outputs": [], 183 | "source": [ 184 | "import os\n", 185 | "\n", 186 | "# コース名の指定\n", 187 | "course_name = os.environ['CWH_COURSE_NAME']\n", 188 | "course_name" 189 | ] 190 | }, 191 | { 192 | "cell_type": "code", 193 | "execution_count": null, 194 | "metadata": { 195 | "deletable": false, 196 | "editable": false, 197 | "lc_cell_meme": { 198 | "current": "9193b88e-4bfd-11e9-80f2-02420a0001bc-1-3d06", 199 | "history": [ 200 | { 201 | "current": "9193b88e-4bfd-11e9-80f2-02420a0001bc-1-3d06", 202 | "next": null, 203 | "previous": "9193b848-4bfd-11e9-80f2-02420a0001bc" 204 | }, 205 | { 206 | "current": "9193b88e-4bfd-11e9-80f2-02420a0001bc-1-3d06", 207 | "next": null, 208 | "previous": "9193b848-4bfd-11e9-80f2-02420a0001bc-1-0ae7" 209 | } 210 | ], 211 | "next": null, 212 | "previous": "64cc969c-fd8e-11ef-ac33-02420a64024e" 213 | }, 214 | "run_through_control": { 215 | "frozen": false 216 | } 217 | }, 218 | "outputs": [], 219 | "source": [ 220 | "assert course_name != '', \"コース用のサーバー上で実行するか、コース名を指定してください\"\n", 221 | "\n", 222 | "# Adjust file permissions\n", 223 | "!find $(realpath ~/{course_name}/textbook/) $(realpath ~/{course_name}/info/) \\\n", 224 | " -type f -name '*.ipynb' -execdir chmod go+r '{{}}' ';' \\\n", 225 | " -o -type d -execdir chmod go+rx '{{}}' ';'\n", 226 | "\n", 227 | "# Release\n", 228 | "!rsync -v -ruLkpEtWhiO --delete --force --exclude-from=/tmp/release.excludes \\\n", 229 | " $(realpath ~/{course_name}/textbook)/ $(realpath /home/jupyter/textbook/{course_name})/\n", 230 | "!rsync -v -ruLkpEtWhiO --delete --force --exclude-from=/tmp/release.excludes \\\n", 231 | " $(realpath ~/{course_name}/info)/ $(realpath /home/jupyter/info/{course_name})/\n", 232 | "\n", 233 | "#\n", 234 | "!rm -f /tmp/release.excludes\n", 235 | "\n", 236 | "#\n", 237 | "print('Successfully released.')" 238 | ] 239 | } 240 | ], 241 | "metadata": { 242 | "kernelspec": { 243 | "display_name": "Python 3", 244 | "language": "python", 245 | "name": "python3" 246 | }, 247 | "language_info": { 248 | "file_extension": ".py", 249 | "mimetype": "text/x-python", 250 | "name": "python", 251 | "nbconvert_exporter": "python", 252 | "pygments_lexer": "ipython3", 253 | "version": "3.10.11" 254 | }, 255 | "lc_notebook_meme": { 256 | "current": "9193b4ec-4bfd-11e9-80f2-02420a0001bc", 257 | "history": [], 258 | "root_cells": [ 259 | "9193b640-4bfd-11e9-80f2-02420a0001bc", 260 | "9193b6c2-4bfd-11e9-80f2-02420a0001bc", 261 | "9193b712-4bfd-11e9-80f2-02420a0001bc", 262 | "9193b762-4bfd-11e9-80f2-02420a0001bc", 263 | "9193b7b2-4bfd-11e9-80f2-02420a0001bc", 264 | "9193b7f8-4bfd-11e9-80f2-02420a0001bc", 265 | "9193b848-4bfd-11e9-80f2-02420a0001bc", 266 | "9193b88e-4bfd-11e9-80f2-02420a0001bc" 267 | ] 268 | }, 269 | "toc": { 270 | "base_numbering": 1, 271 | "nav_menu": { 272 | "height": "30px", 273 | "width": "252px" 274 | }, 275 | "number_sections": true, 276 | "sideBar": true, 277 | "skip_h1_title": false, 278 | "title_cell": "Table of Contents", 279 | "title_sidebar": "Contents", 280 | "toc_cell": false, 281 | "toc_position": {}, 282 | "toc_section_display": "block", 283 | "toc_window_display": true 284 | } 285 | }, 286 | "nbformat": 4, 287 | "nbformat_minor": 1 288 | } 289 | -------------------------------------------------------------------------------- /roles/deploy-manage-tools/files/admin-tools/81_DelLocalUsers.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "lc_cell_meme": { 7 | "current": "95865046-4bfd-11e9-805e-02420a0001bc", 8 | "history": [], 9 | "next": "958650be-4bfd-11e9-805e-02420a0001bc", 10 | "previous": null 11 | } 12 | }, 13 | "source": [ 14 | "# ローカルユーザを削除します\n", 15 | "
" 16 | ] 17 | }, 18 | { 19 | "cell_type": "markdown", 20 | "metadata": { 21 | "lc_cell_meme": { 22 | "current": "958650be-4bfd-11e9-805e-02420a0001bc", 23 | "history": [], 24 | "next": "95865122-4bfd-11e9-805e-02420a0001bc", 25 | "previous": "95865046-4bfd-11e9-805e-02420a0001bc" 26 | } 27 | }, 28 | "source": [ 29 | "ローカルユーザとして登録済みのユーザを削除します。
\n", 30 | "\n", 31 | "次のセルで、下記のように削除するユーザのメールアドレスを配列`LOCAL_USERS_DELETE_LIST`に設定して、セルを実行して下さい。\n", 32 | "```\n", 33 | "LOCAL_USERS_DELETE_LIST = '''\n", 34 | "student-a01@example.com\n", 35 | "student-a02@example.com\n", 36 | "student-a03@example.com\n", 37 | "'''\n", 38 | "```" 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": null, 44 | "metadata": { 45 | "lc_cell_meme": { 46 | "current": "95865122-4bfd-11e9-805e-02420a0001bc", 47 | "history": [], 48 | "next": "95865172-4bfd-11e9-805e-02420a0001bc", 49 | "previous": "958650be-4bfd-11e9-805e-02420a0001bc" 50 | } 51 | }, 52 | "outputs": [], 53 | "source": [ 54 | "# 以下に、削除するローカルユーザのメールアドレスを列挙してください。\n", 55 | "LOCAL_USERS_DELETE_LIST = '''#ここから#\n", 56 | "# GROUP A\n", 57 | "student-a01@example.com\n", 58 | "student-a02@example.com\n", 59 | "student-a03@example.com\n", 60 | "'''#ここまで#" 61 | ] 62 | }, 63 | { 64 | "cell_type": "markdown", 65 | "metadata": { 66 | "lc_cell_meme": { 67 | "current": "95865172-4bfd-11e9-805e-02420a0001bc", 68 | "history": [], 69 | "next": "958651c2-4bfd-11e9-805e-02420a0001bc", 70 | "previous": "95865122-4bfd-11e9-805e-02420a0001bc" 71 | } 72 | }, 73 | "source": [ 74 | "# ローカルユーザーの削除" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": null, 80 | "metadata": { 81 | "lc_cell_meme": { 82 | "current": "958651c2-4bfd-11e9-805e-02420a0001bc", 83 | "history": [], 84 | "next": "95865212-4bfd-11e9-805e-02420a0001bc", 85 | "previous": "95865172-4bfd-11e9-805e-02420a0001bc" 86 | } 87 | }, 88 | "outputs": [], 89 | "source": [ 90 | "import os\n", 91 | "target_hub = ['-i', os.path.expanduser('~/ansible/inventory'), 'ch-master']\n", 92 | "\n", 93 | "!ansible -m ping {' '.join(target_hub)}" 94 | ] 95 | }, 96 | { 97 | "cell_type": "code", 98 | "execution_count": null, 99 | "metadata": { 100 | "lc_cell_meme": { 101 | "current": "95865212-4bfd-11e9-805e-02420a0001bc", 102 | "history": [], 103 | "next": "95865262-4bfd-11e9-805e-02420a0001bc", 104 | "previous": "958651c2-4bfd-11e9-805e-02420a0001bc" 105 | } 106 | }, 107 | "outputs": [], 108 | "source": [ 109 | "import subprocess\n", 110 | "\n", 111 | "default_user = !whoami\n", 112 | "default_user = default_user[0]\n", 113 | "\n", 114 | "result = subprocess.check_output(['ansible', '-m', 'ping'] + target_hub)\n", 115 | "print(result.decode('utf8'))" 116 | ] 117 | }, 118 | { 119 | "cell_type": "code", 120 | "execution_count": null, 121 | "metadata": { 122 | "lc_cell_meme": { 123 | "current": "95865262-4bfd-11e9-805e-02420a0001bc", 124 | "history": [], 125 | "next": "958652b2-4bfd-11e9-805e-02420a0001bc", 126 | "previous": "95865212-4bfd-11e9-805e-02420a0001bc" 127 | } 128 | }, 129 | "outputs": [], 130 | "source": [ 131 | "import re\n", 132 | "\n", 133 | "student_mails = []\n", 134 | "for line in LOCAL_USERS_DELETE_LIST.splitlines():\n", 135 | " s = re.sub(r'#.*$', '', line).strip()\n", 136 | " if 0 < len(s):\n", 137 | " student_mails.append(line)\n", 138 | "student_mails" 139 | ] 140 | }, 141 | { 142 | "cell_type": "markdown", 143 | "metadata": { 144 | "lc_cell_meme": { 145 | "current": "958652b2-4bfd-11e9-805e-02420a0001bc", 146 | "history": [], 147 | "next": "95865302-4bfd-11e9-805e-02420a0001bc", 148 | "previous": "95865262-4bfd-11e9-805e-02420a0001bc" 149 | } 150 | }, 151 | "source": [ 152 | "ユーザをDBから削除します。" 153 | ] 154 | }, 155 | { 156 | "cell_type": "code", 157 | "execution_count": null, 158 | "metadata": { 159 | "lc_cell_meme": { 160 | "current": "95865302-4bfd-11e9-805e-02420a0001bc", 161 | "history": [], 162 | "next": "95865352-4bfd-11e9-805e-02420a0001bc", 163 | "previous": "958652b2-4bfd-11e9-805e-02420a0001bc" 164 | } 165 | }, 166 | "outputs": [], 167 | "source": [ 168 | "def get_auth_proxy():\n", 169 | " import subprocess\n", 170 | " try:\n", 171 | " sid = subprocess.check_output(['ansible', '-b', '-a', 'docker service ps coursewarehub_auth-proxy -q'] + target_hub)\n", 172 | " sid = sid.decode('utf-8').split('\\n')[1].strip()\n", 173 | " cinfo = subprocess.check_output(\n", 174 | " ['ansible', '-b', '-a', \n", 175 | " 'docker inspect --format \"{% raw %} {{.NodeID}} {{.Status.ContainerStatus.ContainerID}} {% endraw %}\" ' + sid\n", 176 | " ] + target_hub)\n", 177 | " nodeid, cid = cinfo.decode('utf-8').split('\\n')[1].strip().split()\n", 178 | " nodeip = subprocess.check_output(\n", 179 | " ['ansible', '-b', '-a', \n", 180 | " 'docker node inspect --format \"{% raw %} {{.Status.Addr}} {% endraw %}\" ' + nodeid\n", 181 | " ] + target_hub)\n", 182 | " nodeip = nodeip.decode('utf-8').split('\\n')[1].split()[0]\n", 183 | " return (nodeip, cid)\n", 184 | " except subprocess.CalledProcessError as e:\n", 185 | " print(e.output.decode('utf-8'))\n", 186 | " raise\n", 187 | "\n", 188 | "auth_proxy = get_auth_proxy()\n", 189 | "auth_proxy" 190 | ] 191 | }, 192 | { 193 | "cell_type": "code", 194 | "execution_count": null, 195 | "metadata": { 196 | "lc_cell_meme": { 197 | "current": "95865352-4bfd-11e9-805e-02420a0001bc", 198 | "history": [], 199 | "next": "958653a2-4bfd-11e9-805e-02420a0001bc", 200 | "previous": "95865302-4bfd-11e9-805e-02420a0001bc" 201 | } 202 | }, 203 | "outputs": [], 204 | "source": [ 205 | "target_auth_proxy = ['-i', os.path.expanduser('~/ansible/inventory'), auth_proxy[0]]\n", 206 | "\n", 207 | "local_user_infos = []\n", 208 | "for student_mail in student_mails:\n", 209 | " local_user_info = subprocess.check_output(['ansible', '-b', '-a',\n", 210 | " 'docker exec -i {} php /var/www/bin/del-local-user.php \"{}\"'.format(auth_proxy[1], student_mail)] + target_auth_proxy)\n", 211 | " local_user_infos.append(local_user_info.decode('utf8'))\n", 212 | "local_user_infos[0]" 213 | ] 214 | }, 215 | { 216 | "cell_type": "markdown", 217 | "metadata": { 218 | "lc_cell_meme": { 219 | "current": "958653a2-4bfd-11e9-805e-02420a0001bc", 220 | "history": [], 221 | "next": "958653f2-4bfd-11e9-805e-02420a0001bc", 222 | "previous": "95865352-4bfd-11e9-805e-02420a0001bc" 223 | } 224 | }, 225 | "source": [ 226 | "講師環境の `admin_tools/data/students.tsv` に控えてあるユーザー情報を削除します。" 227 | ] 228 | }, 229 | { 230 | "cell_type": "code", 231 | "execution_count": null, 232 | "metadata": { 233 | "lc_cell_meme": { 234 | "current": "958653f2-4bfd-11e9-805e-02420a0001bc", 235 | "history": [], 236 | "next": null, 237 | "previous": "958653a2-4bfd-11e9-805e-02420a0001bc" 238 | } 239 | }, 240 | "outputs": [], 241 | "source": [ 242 | "import re\n", 243 | "\n", 244 | "for local_user_info in local_user_infos:\n", 245 | " local_user_info = local_user_info.split('\\n')[1]\n", 246 | " email = local_user_info\n", 247 | " print(email)\n", 248 | " print(subprocess.check_output(['ansible', '-m', 'lineinfile', '-b', '-a',\n", 249 | " 'path=/jupyter/admin/admin_tools/data/students.tsv regexp=\"^{}.+\" state=absent'.format(\n", 250 | " re.escape(email)\n", 251 | " )] + target_hub).decode('utf-8'))\n" 252 | ] 253 | } 254 | ], 255 | "metadata": { 256 | "kernelspec": { 257 | "display_name": "Python 3", 258 | "language": "python", 259 | "name": "python3" 260 | }, 261 | "language_info": { 262 | "codemirror_mode": { 263 | "name": "ipython", 264 | "version": 3 265 | }, 266 | "file_extension": ".py", 267 | "mimetype": "text/x-python", 268 | "name": "python", 269 | "nbconvert_exporter": "python", 270 | "pygments_lexer": "ipython3", 271 | "version": "3.6.8" 272 | }, 273 | "lc_notebook_meme": { 274 | "current": "95864f06-4bfd-11e9-805e-02420a0001bc", 275 | "history": [], 276 | "root_cells": [ 277 | "95865046-4bfd-11e9-805e-02420a0001bc", 278 | "958650be-4bfd-11e9-805e-02420a0001bc", 279 | "95865122-4bfd-11e9-805e-02420a0001bc", 280 | "95865172-4bfd-11e9-805e-02420a0001bc", 281 | "958651c2-4bfd-11e9-805e-02420a0001bc", 282 | "95865212-4bfd-11e9-805e-02420a0001bc", 283 | "95865262-4bfd-11e9-805e-02420a0001bc", 284 | "958652b2-4bfd-11e9-805e-02420a0001bc", 285 | "95865302-4bfd-11e9-805e-02420a0001bc", 286 | "95865352-4bfd-11e9-805e-02420a0001bc", 287 | "958653a2-4bfd-11e9-805e-02420a0001bc", 288 | "958653f2-4bfd-11e9-805e-02420a0001bc" 289 | ] 290 | }, 291 | "toc": { 292 | "base_numbering": 1, 293 | "nav_menu": {}, 294 | "number_sections": true, 295 | "sideBar": true, 296 | "skip_h1_title": false, 297 | "title_cell": "Table of Contents", 298 | "title_sidebar": "Contents", 299 | "toc_cell": false, 300 | "toc_position": {}, 301 | "toc_section_display": true, 302 | "toc_window_display": true 303 | } 304 | }, 305 | "nbformat": 4, 306 | "nbformat_minor": 2 307 | } 308 | -------------------------------------------------------------------------------- /roles/deploy-manage-tools/files/admin-tools/82_ResetLocalUsersPassword.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "lc_cell_meme": { 7 | "current": "95e19c30-4bfd-11e9-91d1-02420a0001bc", 8 | "history": [], 9 | "next": "95e19ca8-4bfd-11e9-91d1-02420a0001bc", 10 | "previous": null 11 | } 12 | }, 13 | "source": [ 14 | "# ローカルユーザのパスワードをリセットします\n", 15 | "
" 16 | ] 17 | }, 18 | { 19 | "cell_type": "markdown", 20 | "metadata": { 21 | "lc_cell_meme": { 22 | "current": "95e19ca8-4bfd-11e9-91d1-02420a0001bc", 23 | "history": [], 24 | "next": "95e19d02-4bfd-11e9-91d1-02420a0001bc", 25 | "previous": "95e19c30-4bfd-11e9-91d1-02420a0001bc" 26 | } 27 | }, 28 | "source": [ 29 | "ローカルユーザがパスワードを忘れてしまったなどの場合、利用します。
\n", 30 | "\n", 31 | "次のセルで、下記のようにパスワードをリセットするユーザのメールアドレスを`LOCAL_USERS_RESET_PASSWORD_LIST`に設定して、セルを実行して下さい。\n", 32 | "\n", 33 | "```\n", 34 | "LOCAL_USERS_RESET_PASSWORD_LIST = '''\n", 35 | "student-a01@example.com\n", 36 | "student-a02@example.com\n", 37 | "student-a03@example.com\n", 38 | "'''\n", 39 | "```\n", 40 | "\n", 41 | "**ユーザのメールアドレスと新しいパスワードが講師環境の `admin_tools/data/students.tsv` に登録されますので、必ず、記録して下さい。**" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": null, 47 | "metadata": { 48 | "lc_cell_meme": { 49 | "current": "95e19d02-4bfd-11e9-91d1-02420a0001bc", 50 | "history": [], 51 | "next": "95e19de8-4bfd-11e9-91d1-02420a0001bc", 52 | "previous": "95e19ca8-4bfd-11e9-91d1-02420a0001bc" 53 | } 54 | }, 55 | "outputs": [], 56 | "source": [ 57 | "# 以下に、削除するローカルユーザのメールアドレスを列挙してください。\n", 58 | "LOCAL_USERS_RESET_PASSWORD_LIST = '''#ここから#\n", 59 | "# GROUP A\n", 60 | "student-a01@example.com\n", 61 | "student-a02@example.com\n", 62 | "student-a03@example.com\n", 63 | "'''#ここまで#" 64 | ] 65 | }, 66 | { 67 | "cell_type": "markdown", 68 | "metadata": { 69 | "lc_cell_meme": { 70 | "current": "95e19de8-4bfd-11e9-91d1-02420a0001bc", 71 | "history": [], 72 | "next": "95e19e6a-4bfd-11e9-91d1-02420a0001bc", 73 | "previous": "95e19d02-4bfd-11e9-91d1-02420a0001bc" 74 | } 75 | }, 76 | "source": [ 77 | "# ローカルユーザーのパスワードリセット" 78 | ] 79 | }, 80 | { 81 | "cell_type": "code", 82 | "execution_count": null, 83 | "metadata": { 84 | "lc_cell_meme": { 85 | "current": "95e19e6a-4bfd-11e9-91d1-02420a0001bc", 86 | "history": [], 87 | "next": "95e19ec4-4bfd-11e9-91d1-02420a0001bc", 88 | "previous": "95e19de8-4bfd-11e9-91d1-02420a0001bc" 89 | } 90 | }, 91 | "outputs": [], 92 | "source": [ 93 | "import os\n", 94 | "target_hub = ['-i', os.path.expanduser('~/ansible/inventory'), 'ch-master']\n", 95 | "\n", 96 | "!ansible -m ping {' '.join(target_hub)}" 97 | ] 98 | }, 99 | { 100 | "cell_type": "code", 101 | "execution_count": null, 102 | "metadata": { 103 | "lc_cell_meme": { 104 | "current": "95e19ec4-4bfd-11e9-91d1-02420a0001bc", 105 | "history": [], 106 | "next": "95e19f14-4bfd-11e9-91d1-02420a0001bc", 107 | "previous": "95e19e6a-4bfd-11e9-91d1-02420a0001bc" 108 | } 109 | }, 110 | "outputs": [], 111 | "source": [ 112 | "import subprocess\n", 113 | "\n", 114 | "default_user = !whoami\n", 115 | "default_user = default_user[0]\n", 116 | "\n", 117 | "result = subprocess.check_output(['ansible', '-m', 'ping'] + target_hub)\n", 118 | "print(result.decode('utf8'))" 119 | ] 120 | }, 121 | { 122 | "cell_type": "code", 123 | "execution_count": null, 124 | "metadata": { 125 | "lc_cell_meme": { 126 | "current": "95e19f14-4bfd-11e9-91d1-02420a0001bc", 127 | "history": [], 128 | "next": "95e19f64-4bfd-11e9-91d1-02420a0001bc", 129 | "previous": "95e19ec4-4bfd-11e9-91d1-02420a0001bc" 130 | } 131 | }, 132 | "outputs": [], 133 | "source": [ 134 | "import re\n", 135 | "\n", 136 | "student_mails = []\n", 137 | "for line in LOCAL_USERS_RESET_PASSWORD_LIST.splitlines():\n", 138 | " s = re.sub(r'#.*$', '', line).strip()\n", 139 | " if 0 < len(s):\n", 140 | " student_mails.append(line)\n", 141 | "student_mails" 142 | ] 143 | }, 144 | { 145 | "cell_type": "markdown", 146 | "metadata": { 147 | "lc_cell_meme": { 148 | "current": "95e19f64-4bfd-11e9-91d1-02420a0001bc", 149 | "history": [], 150 | "next": "95e19fb4-4bfd-11e9-91d1-02420a0001bc", 151 | "previous": "95e19f14-4bfd-11e9-91d1-02420a0001bc" 152 | } 153 | }, 154 | "source": [ 155 | "ユーザをDB上のパスワードをリセットします。" 156 | ] 157 | }, 158 | { 159 | "cell_type": "code", 160 | "execution_count": null, 161 | "metadata": { 162 | "lc_cell_meme": { 163 | "current": "95e19fb4-4bfd-11e9-91d1-02420a0001bc", 164 | "history": [], 165 | "next": "95e19ffa-4bfd-11e9-91d1-02420a0001bc", 166 | "previous": "95e19f64-4bfd-11e9-91d1-02420a0001bc" 167 | } 168 | }, 169 | "outputs": [], 170 | "source": [ 171 | "def get_auth_proxy():\n", 172 | " import subprocess\n", 173 | " try:\n", 174 | " sid = subprocess.check_output(['ansible', '-b', '-a', 'docker service ps coursewarehub_auth-proxy -q'] + target_hub)\n", 175 | " sid = sid.decode('utf-8').split('\\n')[1].strip()\n", 176 | " cinfo = subprocess.check_output(\n", 177 | " ['ansible', '-b', '-a', \n", 178 | " 'docker inspect --format \"{% raw %} {{.NodeID}} {{.Status.ContainerStatus.ContainerID}} {% endraw %}\" ' + sid\n", 179 | " ] + target_hub)\n", 180 | " nodeid, cid = cinfo.decode('utf-8').split('\\n')[1].strip().split()\n", 181 | " nodeip = subprocess.check_output(\n", 182 | " ['ansible', '-b', '-a', \n", 183 | " 'docker node inspect --format \"{% raw %} {{.Status.Addr}} {% endraw %}\" ' + nodeid\n", 184 | " ] + target_hub)\n", 185 | " nodeip = nodeip.decode('utf-8').split('\\n')[1].split()[0]\n", 186 | " return (nodeip, cid)\n", 187 | " except subprocess.CalledProcessError as e:\n", 188 | " print(e.output.decode('utf-8'))\n", 189 | " raise\n", 190 | "\n", 191 | "auth_proxy = get_auth_proxy()\n", 192 | "auth_proxy" 193 | ] 194 | }, 195 | { 196 | "cell_type": "code", 197 | "execution_count": null, 198 | "metadata": { 199 | "lc_cell_meme": { 200 | "current": "95e19ffa-4bfd-11e9-91d1-02420a0001bc", 201 | "history": [], 202 | "next": "95e1a04a-4bfd-11e9-91d1-02420a0001bc", 203 | "previous": "95e19fb4-4bfd-11e9-91d1-02420a0001bc" 204 | } 205 | }, 206 | "outputs": [], 207 | "source": [ 208 | "target_auth_proxy = ['-i', os.path.expanduser('~/ansible/inventory'), auth_proxy[0]]\n", 209 | "\n", 210 | "local_user_infos = []\n", 211 | "for student_mail in student_mails:\n", 212 | " local_user_info = subprocess.check_output(['ansible', '-b', '-a',\n", 213 | " 'docker exec -i {} php /var/www/bin/reset-local-user-password.php \"{}\"'.format(auth_proxy[1], student_mail)] + target_auth_proxy)\n", 214 | " local_user_infos.append(local_user_info.decode('utf8'))\n", 215 | "local_user_infos[0]" 216 | ] 217 | }, 218 | { 219 | "cell_type": "markdown", 220 | "metadata": { 221 | "lc_cell_meme": { 222 | "current": "95e1a04a-4bfd-11e9-91d1-02420a0001bc", 223 | "history": [], 224 | "next": "95e1a09a-4bfd-11e9-91d1-02420a0001bc", 225 | "previous": "95e19ffa-4bfd-11e9-91d1-02420a0001bc" 226 | } 227 | }, 228 | "source": [ 229 | "講師環境の `admin_tools/data/students.tsv` に控えてあるユーザー情報を更新します。" 230 | ] 231 | }, 232 | { 233 | "cell_type": "code", 234 | "execution_count": null, 235 | "metadata": { 236 | "lc_cell_meme": { 237 | "current": "95e1a09a-4bfd-11e9-91d1-02420a0001bc", 238 | "history": [], 239 | "next": null, 240 | "previous": "95e1a04a-4bfd-11e9-91d1-02420a0001bc" 241 | } 242 | }, 243 | "outputs": [], 244 | "source": [ 245 | "import re\n", 246 | "\n", 247 | "for local_user_info in local_user_infos:\n", 248 | " local_user_info = local_user_info.split('\\n')[1]\n", 249 | " email = local_user_info.split('\\t')[0]\n", 250 | " print(email)\n", 251 | " print(subprocess.check_output(['ansible', '-m', 'lineinfile', '-b', '-a',\n", 252 | " 'path=/jupyter/admin/admin_tools/data/students.tsv line=\"{}\" regexp=\"^{}.+\"'.format(\n", 253 | " local_user_info,\n", 254 | " re.escape(email)\n", 255 | " )] + target_hub).decode('utf-8'))\n" 256 | ] 257 | } 258 | ], 259 | "metadata": { 260 | "kernelspec": { 261 | "display_name": "Python 3", 262 | "language": "python", 263 | "name": "python3" 264 | }, 265 | "language_info": { 266 | "codemirror_mode": { 267 | "name": "ipython", 268 | "version": 3 269 | }, 270 | "file_extension": ".py", 271 | "mimetype": "text/x-python", 272 | "name": "python", 273 | "nbconvert_exporter": "python", 274 | "pygments_lexer": "ipython3", 275 | "version": "3.6.8" 276 | }, 277 | "lc_notebook_meme": { 278 | "current": "95e19ae6-4bfd-11e9-91d1-02420a0001bc", 279 | "history": [], 280 | "root_cells": [ 281 | "95e19c30-4bfd-11e9-91d1-02420a0001bc", 282 | "95e19ca8-4bfd-11e9-91d1-02420a0001bc", 283 | "95e19d02-4bfd-11e9-91d1-02420a0001bc", 284 | "95e19de8-4bfd-11e9-91d1-02420a0001bc", 285 | "95e19e6a-4bfd-11e9-91d1-02420a0001bc", 286 | "95e19ec4-4bfd-11e9-91d1-02420a0001bc", 287 | "95e19f14-4bfd-11e9-91d1-02420a0001bc", 288 | "95e19f64-4bfd-11e9-91d1-02420a0001bc", 289 | "95e19fb4-4bfd-11e9-91d1-02420a0001bc", 290 | "95e19ffa-4bfd-11e9-91d1-02420a0001bc", 291 | "95e1a04a-4bfd-11e9-91d1-02420a0001bc", 292 | "95e1a09a-4bfd-11e9-91d1-02420a0001bc" 293 | ] 294 | }, 295 | "toc": { 296 | "base_numbering": 1, 297 | "nav_menu": {}, 298 | "number_sections": true, 299 | "sideBar": true, 300 | "skip_h1_title": false, 301 | "title_cell": "Table of Contents", 302 | "title_sidebar": "Contents", 303 | "toc_cell": false, 304 | "toc_position": {}, 305 | "toc_section_display": true, 306 | "toc_window_display": true 307 | } 308 | }, 309 | "nbformat": 4, 310 | "nbformat_minor": 2 311 | } 312 | -------------------------------------------------------------------------------- /roles/deploy-manage-tools/files/admin-tools/14_BackupMaterialsToGitHub.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "lc_cell_meme": { 7 | "current": "930494a4-4bfd-11e9-9f74-02420a0001bc", 8 | "history": [], 9 | "next": "9304954e-4bfd-11e9-9f74-02420a0001bc", 10 | "previous": null 11 | } 12 | }, 13 | "source": [ 14 | "# 作成した教材をGitHubへバックアップします\n", 15 | "---" 16 | ] 17 | }, 18 | { 19 | "cell_type": "markdown", 20 | "metadata": { 21 | "lc_cell_meme": { 22 | "current": "9304954e-4bfd-11e9-9f74-02420a0001bc", 23 | "history": [], 24 | "next": "930495b2-4bfd-11e9-9f74-02420a0001bc", 25 | "previous": "930494a4-4bfd-11e9-9f74-02420a0001bc" 26 | } 27 | }, 28 | "source": [ 29 | "ホームディレクトリで作成した教材をGitHubリポジトリへバックアップします。" 30 | ] 31 | }, 32 | { 33 | "cell_type": "markdown", 34 | "metadata": { 35 | "lc_cell_meme": { 36 | "current": "930495b2-4bfd-11e9-9f74-02420a0001bc", 37 | "history": [], 38 | "next": "93049602-4bfd-11e9-9f74-02420a0001bc", 39 | "previous": "9304954e-4bfd-11e9-9f74-02420a0001bc" 40 | } 41 | }, 42 | "source": [ 43 | "# バックアップ用GitHubリポジトリの準備" 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "metadata": { 49 | "lc_cell_meme": { 50 | "current": "93049602-4bfd-11e9-9f74-02420a0001bc", 51 | "history": [], 52 | "next": "93049652-4bfd-11e9-9f74-02420a0001bc", 53 | "previous": "930495b2-4bfd-11e9-9f74-02420a0001bc" 54 | } 55 | }, 56 | "source": [ 57 | "* 既にバックアップ用GitHubリポジトリが作成済みの場合は、この項を読み飛ばして結構です。\n", 58 | "* 初めて教材をGitHubリポジトリへバックアップする場合は、[GitHubリポジトリの準備/1. GitHubで新しいリポジトリを作成](03_PrepareGitHub.ipynb#create_github_repo) にしたがって、バックアップ用のGitHubリポジトリを作成して下さい。" 59 | ] 60 | }, 61 | { 62 | "cell_type": "markdown", 63 | "metadata": { 64 | "lc_cell_meme": { 65 | "current": "93049652-4bfd-11e9-9f74-02420a0001bc", 66 | "history": [], 67 | "next": "930496a2-4bfd-11e9-9f74-02420a0001bc", 68 | "previous": "93049602-4bfd-11e9-9f74-02420a0001bc" 69 | } 70 | }, 71 | "source": [ 72 | "# GitHubリポジトリへの接続情報を設定します" 73 | ] 74 | }, 75 | { 76 | "cell_type": "markdown", 77 | "metadata": { 78 | "lc_cell_meme": { 79 | "current": "930496a2-4bfd-11e9-9f74-02420a0001bc", 80 | "history": [], 81 | "next": "930496f2-4bfd-11e9-9f74-02420a0001bc", 82 | "previous": "93049652-4bfd-11e9-9f74-02420a0001bc" 83 | } 84 | }, 85 | "source": [ 86 | "バックアップ先のGitHubリポジトリへの接続情報を設定します。\n", 87 | "1. GitHubに接続するSSHキーを新たに登録する場合は、 [GitHubリポジトリの準備/2. SSHキーの登録](03_PrepareGitHub.ipynb#create_ssh_key)を使って作成して下さい。\n", 88 | "2. [GitHubリポジトリの準備/3. GitHubリポジトリ接続情報の設定](03_PrepareGitHub.ipynb#connect_github_repo)を使って、バックアップ用のGitHubリポジトリの接続情報を設定して下さい。" 89 | ] 90 | }, 91 | { 92 | "cell_type": "markdown", 93 | "metadata": { 94 | "lc_cell_meme": { 95 | "current": "930496f2-4bfd-11e9-9f74-02420a0001bc", 96 | "history": [], 97 | "next": "93049738-4bfd-11e9-9f74-02420a0001bc", 98 | "previous": "930496a2-4bfd-11e9-9f74-02420a0001bc" 99 | } 100 | }, 101 | "source": [ 102 | "# バックアップの準備" 103 | ] 104 | }, 105 | { 106 | "cell_type": "markdown", 107 | "metadata": { 108 | "lc_cell_meme": { 109 | "current": "93049738-4bfd-11e9-9f74-02420a0001bc", 110 | "history": [], 111 | "next": "93049788-4bfd-11e9-9f74-02420a0001bc", 112 | "previous": "930496f2-4bfd-11e9-9f74-02420a0001bc" 113 | } 114 | }, 115 | "source": [ 116 | "このNotebookを実行すると、ホームディレクトリ直下の下記のフォルダをGitHubリポジトリに保存します。
\n", 117 | "**バックアップしたいファイル/フォルダは、下記のフォルダに移動してください。**\n", 118 | "* `textbook`\n", 119 | " + 教材Notebookおよび教材Notebookから呼び出すスクリプトなど\n", 120 | "* `info`\n", 121 | " + 受講者が参照する参考資料など\n", 122 | "* `draft`\n", 123 | " + 教材以外で保存して置きたいNotebook、その他ファイル\n", 124 | "\n", 125 | "注) GitHubには `test` フォルダも保存されます。\n", 126 | "* `test` フォルダは、この教材の自動テストに必要なファイルを保存するフォルダです。\n", 127 | "* **`test` フォルダにはその他のファイルを格納しないで下さい。**" 128 | ] 129 | }, 130 | { 131 | "cell_type": "markdown", 132 | "metadata": { 133 | "lc_cell_meme": { 134 | "current": "93049788-4bfd-11e9-9f74-02420a0001bc", 135 | "history": [], 136 | "next": "930497ce-4bfd-11e9-9f74-02420a0001bc", 137 | "previous": "93049738-4bfd-11e9-9f74-02420a0001bc" 138 | } 139 | }, 140 | "source": [ 141 | "# その他にバックアップしたいファイル/フォルダがある場合" 142 | ] 143 | }, 144 | { 145 | "cell_type": "markdown", 146 | "metadata": { 147 | "lc_cell_meme": { 148 | "current": "930497ce-4bfd-11e9-9f74-02420a0001bc", 149 | "history": [], 150 | "next": "9304981e-4bfd-11e9-9f74-02420a0001bc", 151 | "previous": "93049788-4bfd-11e9-9f74-02420a0001bc" 152 | } 153 | }, 154 | "source": [ 155 | "もし、`textbook`、`info`、`draft` 以外に保存したいファイルまたはフォルダがある場合は、`INCLUDES` にスペース区切りで列挙して下さい。\n", 156 | "* `textbook`、`info`、`draft`、`test` フォルダは必ずバックアップに保存されます。\n", 157 | "* 管理用Notebookフォルダ `tools` はバックアップに保存されません\n", 158 | "```\n", 159 | "%env INCLUDES=ext-textbook ext-data Sample.ipynb\n", 160 | "```\n", 161 | "\n", 162 | "**次のセルでバックアップに含めたいファイル/フォルダを指定して、セルを実行して下さい。**" 163 | ] 164 | }, 165 | { 166 | "cell_type": "code", 167 | "execution_count": null, 168 | "metadata": { 169 | "lc_cell_meme": { 170 | "current": "9304981e-4bfd-11e9-9f74-02420a0001bc", 171 | "history": [], 172 | "next": "9304986e-4bfd-11e9-9f74-02420a0001bc", 173 | "previous": "930497ce-4bfd-11e9-9f74-02420a0001bc" 174 | } 175 | }, 176 | "outputs": [], 177 | "source": [ 178 | "%env INCLUDES=" 179 | ] 180 | }, 181 | { 182 | "cell_type": "markdown", 183 | "metadata": { 184 | "lc_cell_meme": { 185 | "current": "9304986e-4bfd-11e9-9f74-02420a0001bc", 186 | "history": [], 187 | "next": "930498b4-4bfd-11e9-9f74-02420a0001bc", 188 | "previous": "9304981e-4bfd-11e9-9f74-02420a0001bc" 189 | } 190 | }, 191 | "source": [ 192 | "# GitHubにpushします" 193 | ] 194 | }, 195 | { 196 | "cell_type": "markdown", 197 | "metadata": { 198 | "lc_cell_meme": { 199 | "current": "930498b4-4bfd-11e9-9f74-02420a0001bc", 200 | "history": [], 201 | "next": "93049904-4bfd-11e9-9f74-02420a0001bc", 202 | "previous": "9304986e-4bfd-11e9-9f74-02420a0001bc" 203 | } 204 | }, 205 | "source": [ 206 | "指定したGitHub repositoryに保存します。\n", 207 | "\n", 208 | "```\n", 209 | "%env COMMIT_MESSAGE=Add special notebook.\n", 210 | "```\n", 211 | "\n", 212 | "**次のセルで、commitメッセージを設定して下さい。**" 213 | ] 214 | }, 215 | { 216 | "cell_type": "code", 217 | "execution_count": null, 218 | "metadata": { 219 | "lc_cell_meme": { 220 | "current": "93049904-4bfd-11e9-9f74-02420a0001bc", 221 | "history": [], 222 | "next": "9304994a-4bfd-11e9-9f74-02420a0001bc", 223 | "previous": "930498b4-4bfd-11e9-9f74-02420a0001bc" 224 | } 225 | }, 226 | "outputs": [], 227 | "source": [ 228 | "%env COMMIT_MESSAGE=" 229 | ] 230 | }, 231 | { 232 | "cell_type": "markdown", 233 | "metadata": { 234 | "lc_cell_meme": { 235 | "current": "9304994a-4bfd-11e9-9f74-02420a0001bc", 236 | "history": [], 237 | "next": "9304999a-4bfd-11e9-9f74-02420a0001bc", 238 | "previous": "93049904-4bfd-11e9-9f74-02420a0001bc" 239 | } 240 | }, 241 | "source": [ 242 | "**次のセルを実行して、GitHubに保存して下さい。**" 243 | ] 244 | }, 245 | { 246 | "cell_type": "code", 247 | "execution_count": null, 248 | "metadata": { 249 | "lc_cell_meme": { 250 | "current": "9304999a-4bfd-11e9-9f74-02420a0001bc", 251 | "history": [], 252 | "next": null, 253 | "previous": "9304994a-4bfd-11e9-9f74-02420a0001bc" 254 | } 255 | }, 256 | "outputs": [], 257 | "source": [ 258 | "%%bash\n", 259 | "\n", 260 | "cd\n", 261 | "comm -13 <(sort ~/.ssh/known_hosts) <(ssh-keyscan github.com 2>/dev/null | sort) >>~/.ssh/known_hosts \n", 262 | "\n", 263 | "IS_INSIDE_REPO=0\n", 264 | "S=\"$(git rev-parse --is-inside-work-tree 2>/dev/null)\"\n", 265 | "[ $? -eq 0 -a \"${S}\" = \"true\" ] && IS_INSIDE_REPO=1\n", 266 | "\n", 267 | "if [ ${IS_INSIDE_REPO} -ne 1 ]; then\n", 268 | " echo \"ERROR: git repository not initialized.\" 1>&2\n", 269 | " exit 1\n", 270 | "fi\n", 271 | "\n", 272 | "if [ ! -z \"${INCLUDES}\" ]; then\n", 273 | " for item in ${INCLUDES}; do\n", 274 | " git add -A \"${item}\"\n", 275 | " done\n", 276 | "fi\n", 277 | "\n", 278 | "if [ -z \"${COMMIT_MESSAGE}\" ]; then\n", 279 | " COMMIT_MESSAGE=\"Backup of $(< /etc/courseware.configmap/fqdn).\"\n", 280 | "fi\n", 281 | "\n", 282 | "git add -A ./textbook/ ./info/ ./draft/\n", 283 | "git fetch --force origin\n", 284 | "git merge -s recursive -X ours origin/master\n", 285 | "git commit -m \"${COMMIT_MESSAGE}\"\n", 286 | "git push --set-upstream origin master" 287 | ] 288 | } 289 | ], 290 | "metadata": { 291 | "kernelspec": { 292 | "display_name": "Python 3", 293 | "language": "python", 294 | "name": "python3" 295 | }, 296 | "language_info": { 297 | "codemirror_mode": { 298 | "name": "ipython", 299 | "version": 3 300 | }, 301 | "file_extension": ".py", 302 | "mimetype": "text/x-python", 303 | "name": "python", 304 | "nbconvert_exporter": "python", 305 | "pygments_lexer": "ipython3", 306 | "version": "3.6.8" 307 | }, 308 | "lc_notebook_meme": { 309 | "current": "930492c4-4bfd-11e9-9f74-02420a0001bc", 310 | "history": [], 311 | "root_cells": [ 312 | "930494a4-4bfd-11e9-9f74-02420a0001bc", 313 | "9304954e-4bfd-11e9-9f74-02420a0001bc", 314 | "930495b2-4bfd-11e9-9f74-02420a0001bc", 315 | "93049602-4bfd-11e9-9f74-02420a0001bc", 316 | "93049652-4bfd-11e9-9f74-02420a0001bc", 317 | "930496a2-4bfd-11e9-9f74-02420a0001bc", 318 | "930496f2-4bfd-11e9-9f74-02420a0001bc", 319 | "93049738-4bfd-11e9-9f74-02420a0001bc", 320 | "93049788-4bfd-11e9-9f74-02420a0001bc", 321 | "930497ce-4bfd-11e9-9f74-02420a0001bc", 322 | "9304981e-4bfd-11e9-9f74-02420a0001bc", 323 | "9304986e-4bfd-11e9-9f74-02420a0001bc", 324 | "930498b4-4bfd-11e9-9f74-02420a0001bc", 325 | "93049904-4bfd-11e9-9f74-02420a0001bc", 326 | "9304994a-4bfd-11e9-9f74-02420a0001bc", 327 | "9304999a-4bfd-11e9-9f74-02420a0001bc" 328 | ] 329 | }, 330 | "toc": { 331 | "base_numbering": 1, 332 | "nav_menu": {}, 333 | "number_sections": true, 334 | "sideBar": true, 335 | "skip_h1_title": false, 336 | "title_cell": "Table of Contents", 337 | "title_sidebar": "Contents", 338 | "toc_cell": false, 339 | "toc_position": {}, 340 | "toc_section_display": true, 341 | "toc_window_display": true 342 | } 343 | }, 344 | "nbformat": 4, 345 | "nbformat_minor": 2 346 | } 347 | -------------------------------------------------------------------------------- /roles/deploy-manage-tools/files/admin-tools/00_GuidanceForTeacher.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "lc_cell_meme": { 7 | "current": "901afed6-4bfd-11e9-a5b6-02420a0001bc", 8 | "history": [], 9 | "next": "901aff58-4bfd-11e9-a5b6-02420a0001bc", 10 | "previous": null 11 | } 12 | }, 13 | "source": [ 14 | "---\n", 15 | "# 先生向けガイダンス\n", 16 | "---\n", 17 | "## はじめに\n", 18 | "---\n", 19 | "このガイダンスでは、Jupyterを利用した講義・演習のための教材作りについて説明します。\n", 20 | "\n", 21 | "Jupyterは、 Webブラウザからアクセスできる「notebook」と呼ばれるインタラクティブなインターフェイスを提供するツールです。
\n", 22 | "notebookは、Markdown形式のドキュメントの表示と任意の言語(コード)を埋め込みが可能で、埋め込んだコードの表示、実行、結果の表示が行えます。\n", 23 | "\n", 24 | "なお、Jupyterの概要については、[こちら](./01_JupyterOverview.ipynb)を参考にして下さい。\n" 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "metadata": { 30 | "lc_cell_meme": { 31 | "current": "901aff58-4bfd-11e9-a5b6-02420a0001bc", 32 | "history": [], 33 | "next": "901affbc-4bfd-11e9-a5b6-02420a0001bc", 34 | "previous": "901afed6-4bfd-11e9-a5b6-02420a0001bc" 35 | } 36 | }, 37 | "source": [ 38 | "## 教材の作成から講義・演習の実施までの流れ\n", 39 | "---\n", 40 | "講義・演習用の教材の作成から演習の実施までは以下のように進めます。さらに、講義で課題を設けた場合、受講者が作成した回答ファイルを一括回収することができます。\n", 41 | "\n", 42 | "1. 教材の作成\n", 43 | "2. 教材のリリース\n", 44 | "3. 教材の動作を確認する\n", 45 | "4. 講義・演習の実施\n", 46 | "5. 回答ファイルの回収" 47 | ] 48 | }, 49 | { 50 | "cell_type": "markdown", 51 | "metadata": { 52 | "lc_cell_meme": { 53 | "current": "901affbc-4bfd-11e9-a5b6-02420a0001bc", 54 | "history": [], 55 | "next": "901b0016-4bfd-11e9-a5b6-02420a0001bc", 56 | "previous": "901aff58-4bfd-11e9-a5b6-02420a0001bc" 57 | } 58 | }, 59 | "source": [ 60 | "![documentflowteacher](https://cloud.githubusercontent.com/assets/1156894/20779650/1ff53ade-b7b9-11e6-9d39-057555b81d61.png)" 61 | ] 62 | }, 63 | { 64 | "cell_type": "markdown", 65 | "metadata": { 66 | "lc_cell_meme": { 67 | "current": "901b0016-4bfd-11e9-a5b6-02420a0001bc", 68 | "history": [], 69 | "next": "901b0070-4bfd-11e9-a5b6-02420a0001bc", 70 | "previous": "901affbc-4bfd-11e9-a5b6-02420a0001bc" 71 | } 72 | }, 73 | "source": [ 74 | " ## 1. 教材を作成する" 75 | ] 76 | }, 77 | { 78 | "cell_type": "markdown", 79 | "metadata": { 80 | "lc_cell_meme": { 81 | "current": "901b0070-4bfd-11e9-a5b6-02420a0001bc", 82 | "history": [], 83 | "next": "901b00ca-4bfd-11e9-a5b6-02420a0001bc", 84 | "previous": "901b0016-4bfd-11e9-a5b6-02420a0001bc" 85 | } 86 | }, 87 | "source": [ 88 | "### 教材の作成場所について\n", 89 | "---\n", 90 | "Jupyterにログインすると、ダッシュボード画面が表示されます。
\n", 91 | "Filesタブを選択するとHomeディレクトリが表示されます。教材は、このHomeディレクトリ直下で作成して下さい。Homeディレクトリにフォルダを作成して、その下に配置しても構いません。\n", 92 | "\n", 93 | "[フォルダを作成する](02_JupyterOperationTips.ipynb#folder)" 94 | ] 95 | }, 96 | { 97 | "cell_type": "markdown", 98 | "metadata": { 99 | "lc_cell_meme": { 100 | "current": "901b00ca-4bfd-11e9-a5b6-02420a0001bc", 101 | "history": [], 102 | "next": "901b011a-4bfd-11e9-a5b6-02420a0001bc", 103 | "previous": "901b0070-4bfd-11e9-a5b6-02420a0001bc" 104 | } 105 | }, 106 | "source": [ 107 | "### 教材ファイルの作成\n", 108 | "---\n", 109 | "notebookやテキストファイルは、WebブラウザからJupyterの画面で作成、編集します。
\n", 110 | "\n", 111 | "[notebookを作成する](02_JupyterOperationTips.ipynb#create_note) / [テキストファイルを作成する](02_JupyterOperationTips.ipynb#create_textfile) / [ファイルを保存する](02_JupyterOperationTips.ipynb#save_notebook) / [notebookの名前を変更する](02_JupyterOperationTips.ipynb#rename_notebook) / [notebook以外のファイル/フォルダの名前を変更する](02_JupyterOperationTips.ipynb#rename_file) / [ファイルをコピーする](02_JupyterOperationTips.ipynb#copy_file)" 112 | ] 113 | }, 114 | { 115 | "cell_type": "markdown", 116 | "metadata": { 117 | "lc_cell_meme": { 118 | "current": "901b011a-4bfd-11e9-a5b6-02420a0001bc", 119 | "history": [], 120 | "next": "901b0174-4bfd-11e9-a5b6-02420a0001bc", 121 | "previous": "901b00ca-4bfd-11e9-a5b6-02420a0001bc" 122 | } 123 | }, 124 | "source": [ 125 | "### ファイル/フォルダの移動\n", 126 | "---\n", 127 | "教材ファイルや教材ファイルを格納するフォルダは、Jupyterの画面上で移動が可能です。
\n", 128 | "\n", 129 | "[notebookを移動する](02_JupyterOperationTips.ipynb#move_note) / [notebook以外のファイル/フォルダを移動する](02_JupyterOperationTips.ipynb#move_file)" 130 | ] 131 | }, 132 | { 133 | "cell_type": "markdown", 134 | "metadata": { 135 | "lc_cell_meme": { 136 | "current": "901b0174-4bfd-11e9-a5b6-02420a0001bc", 137 | "history": [], 138 | "next": "901b01ce-4bfd-11e9-a5b6-02420a0001bc", 139 | "previous": "901b011a-4bfd-11e9-a5b6-02420a0001bc" 140 | } 141 | }, 142 | "source": [ 143 | "### ファイルのアップロード/ダウンロード\n", 144 | "---\n", 145 | "PDFや画像ファイルなどのファイルをアップロードして教材に含めることができます。アップロードした教材は手元にダウンロードすることもできます。\n", 146 | "\n", 147 | "[ファイルをアップロードする](02_JupyterOperationTips.ipynb#upload_file) / [notebookをダウンロードする](02_JupyterOperationTips.ipynb#download_note) / [notebook以外のファイルをダウンロードする](02_JupyterOperationTips.ipynb#download_file)" 148 | ] 149 | }, 150 | { 151 | "cell_type": "markdown", 152 | "metadata": { 153 | "lc_cell_meme": { 154 | "current": "901b01ce-4bfd-11e9-a5b6-02420a0001bc", 155 | "history": [], 156 | "next": "901b021e-4bfd-11e9-a5b6-02420a0001bc", 157 | "previous": "901b0174-4bfd-11e9-a5b6-02420a0001bc" 158 | } 159 | }, 160 | "source": [ 161 | "### 参考 : ターミナルの利用\n", 162 | "---\n", 163 | "Jupyterは、Webブラウザにターミナル画面を表示できます。
\n", 164 | "通常のターミナルと同様、このターミナルからLinuxコマンドを実行できます。\n", 165 | "\n", 166 | "[ターミナルを開く](02_JupyterOperationTips.ipynb#terminal_open) / [ターミナルを閉じる](02_JupyterOperationTips.ipynb#terminal_close)" 167 | ] 168 | }, 169 | { 170 | "cell_type": "markdown", 171 | "metadata": { 172 | "lc_cell_meme": { 173 | "current": "901b021e-4bfd-11e9-a5b6-02420a0001bc", 174 | "history": [], 175 | "next": "901b0278-4bfd-11e9-a5b6-02420a0001bc", 176 | "previous": "901b01ce-4bfd-11e9-a5b6-02420a0001bc" 177 | } 178 | }, 179 | "source": [ 180 | "## 2. 教材をリリースする\n", 181 | "教材の準備が整ったら、リリースします。\n", 182 | "リリースする教材は、HOME直下にある下記の\n", 183 | " * textbook : 演習Notebookおよび演習Notebook実行に関わるスクリプト、設定ファイルなどを格納します\n", 184 | " * info : 受講者全員が参照する資料などを格納します\n", 185 | " \n", 186 | "リリースすると、受講者のJupyter Homeから参照できる「textbook」「info」に格納され、以後、受講者がこれをコピーして利用できるようになります。
\n", 187 | "教材のリリース作業はnotebook [10_ReleaseMaterials.ipynb](10_ReleaseMaterials.ipynb) で行って下さい。" 188 | ] 189 | }, 190 | { 191 | "cell_type": "markdown", 192 | "metadata": { 193 | "lc_cell_meme": { 194 | "current": "901b0278-4bfd-11e9-a5b6-02420a0001bc", 195 | "history": [], 196 | "next": "901b02d2-4bfd-11e9-a5b6-02420a0001bc", 197 | "previous": "901b021e-4bfd-11e9-a5b6-02420a0001bc" 198 | } 199 | }, 200 | "source": [ 201 | "## 3. 教材の動作を確認する\n", 202 | "リリースした教材が問題なく動作するかを確認します。
\n", 203 | "動作確認は、動作確認用ユーザを追加して実施します。" 204 | ] 205 | }, 206 | { 207 | "cell_type": "markdown", 208 | "metadata": { 209 | "lc_cell_meme": { 210 | "current": "901b02d2-4bfd-11e9-a5b6-02420a0001bc", 211 | "history": [], 212 | "next": "901b0322-4bfd-11e9-a5b6-02420a0001bc", 213 | "previous": "901b0278-4bfd-11e9-a5b6-02420a0001bc" 214 | } 215 | }, 216 | "source": [ 217 | "### 動作確認用ユーザを追加する\n", 218 | "---\n", 219 | "1. ダッシュボード画面右上の [Control Panel] ボタンをクリックします。Jupyterの管理画面が表示されます。\n", 220 | "2. Jupyter管理画面左上の [Add User] ボタンをクリックします。「Add User」ダイアログが表示されます。\n", 221 | "3. 動作確認用ユーザ名を入力して、[Add User] ボタンをクリックします。この時、[Admin] チェックボックスは「OFF」にして下さい。\n", 222 | "4. Jupyter管理画面に追加した動作確認用ユーザが表示されます。" 223 | ] 224 | }, 225 | { 226 | "cell_type": "markdown", 227 | "metadata": { 228 | "lc_cell_meme": { 229 | "current": "901b0322-4bfd-11e9-a5b6-02420a0001bc", 230 | "history": [], 231 | "next": "901b037c-4bfd-11e9-a5b6-02420a0001bc", 232 | "previous": "901b02d2-4bfd-11e9-a5b6-02420a0001bc" 233 | } 234 | }, 235 | "source": [ 236 | "### 動作確認用ユーザのJupyterへアクセスする\n", 237 | "---\n", 238 | "1. Jupyter管理画面で、動作確認用ユーザの [start server] ボタンをクリックします。\n", 239 | "2. 動作確認用ユーザのサーバが起動すると、[access server] ボタンが表示されます。\n", 240 | "3. [access server] ボタンをクリックします。動作確認用ユーザのダッシュボード画面が表示されます。" 241 | ] 242 | }, 243 | { 244 | "cell_type": "markdown", 245 | "metadata": { 246 | "lc_cell_meme": { 247 | "current": "901b037c-4bfd-11e9-a5b6-02420a0001bc", 248 | "history": [], 249 | "next": "901b03d6-4bfd-11e9-a5b6-02420a0001bc", 250 | "previous": "901b0322-4bfd-11e9-a5b6-02420a0001bc" 251 | } 252 | }, 253 | "source": [ 254 | "### 動作確認\n", 255 | "---\n", 256 | "1. 動作確認用ユーザのダッシュボード画面で、Filesタブ画面を開きます。\n", 257 | "2. 教材を取得して動作を確認します。教材の取得方法は、受講者向けガイダンス(tools/00_GuidanceForStudent.ipynb)を参照して下さい。" 258 | ] 259 | }, 260 | { 261 | "cell_type": "markdown", 262 | "metadata": { 263 | "lc_cell_meme": { 264 | "current": "901b03d6-4bfd-11e9-a5b6-02420a0001bc", 265 | "history": [], 266 | "next": null, 267 | "previous": "901b037c-4bfd-11e9-a5b6-02420a0001bc" 268 | } 269 | }, 270 | "source": [ 271 | "## 4. 課題の回答を回収する\n", 272 | "---\n", 273 | "講義で課題を設けた場合、受講者が作成した回答ファイル(notebook、その他ファイル)を一括回収できます。
\n", 274 | "回答の回収作業はnotebook [11_CollectAnswer.ipynb](11_CollectAnswer.ipynb) で行って下さい。" 275 | ] 276 | } 277 | ], 278 | "metadata": { 279 | "kernelspec": { 280 | "display_name": "Python 3", 281 | "language": "python", 282 | "name": "python3" 283 | }, 284 | "language_info": { 285 | "codemirror_mode": { 286 | "name": "ipython", 287 | "version": 3 288 | }, 289 | "file_extension": ".py", 290 | "mimetype": "text/x-python", 291 | "name": "python", 292 | "nbconvert_exporter": "python", 293 | "pygments_lexer": "ipython3", 294 | "version": "3.6.8" 295 | }, 296 | "lc_notebook_meme": { 297 | "current": "901afd64-4bfd-11e9-a5b6-02420a0001bc", 298 | "history": [], 299 | "root_cells": [ 300 | "901afed6-4bfd-11e9-a5b6-02420a0001bc", 301 | "901aff58-4bfd-11e9-a5b6-02420a0001bc", 302 | "901affbc-4bfd-11e9-a5b6-02420a0001bc", 303 | "901b0016-4bfd-11e9-a5b6-02420a0001bc", 304 | "901b0070-4bfd-11e9-a5b6-02420a0001bc", 305 | "901b00ca-4bfd-11e9-a5b6-02420a0001bc", 306 | "901b011a-4bfd-11e9-a5b6-02420a0001bc", 307 | "901b0174-4bfd-11e9-a5b6-02420a0001bc", 308 | "901b01ce-4bfd-11e9-a5b6-02420a0001bc", 309 | "901b021e-4bfd-11e9-a5b6-02420a0001bc", 310 | "901b0278-4bfd-11e9-a5b6-02420a0001bc", 311 | "901b02d2-4bfd-11e9-a5b6-02420a0001bc", 312 | "901b0322-4bfd-11e9-a5b6-02420a0001bc", 313 | "901b037c-4bfd-11e9-a5b6-02420a0001bc", 314 | "901b03d6-4bfd-11e9-a5b6-02420a0001bc" 315 | ] 316 | }, 317 | "toc": { 318 | "base_numbering": 1, 319 | "nav_menu": { 320 | "height": "264px", 321 | "width": "252px" 322 | }, 323 | "number_sections": true, 324 | "sideBar": true, 325 | "skip_h1_title": false, 326 | "title_cell": "Table of Contents", 327 | "title_sidebar": "Contents", 328 | "toc_cell": false, 329 | "toc_position": {}, 330 | "toc_section_display": "block", 331 | "toc_window_display": false 332 | } 333 | }, 334 | "nbformat": 4, 335 | "nbformat_minor": 1 336 | } 337 | -------------------------------------------------------------------------------- /roles/deploy-manage-tools/files/admin-tools/85_ShowUserGroups.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "lc_cell_meme": { 7 | "current": "f67f71fa-7d8a-11eb-b28e-02420a01004f-1-fb8b", 8 | "history": [ 9 | { 10 | "current": "f67f71fa-7d8a-11eb-b28e-02420a01004f-1-fb8b", 11 | "next": "f67f73d0-7d8a-11eb-b28e-02420a01004f", 12 | "previous": null 13 | } 14 | ], 15 | "next": "f67f73d0-7d8a-11eb-b28e-02420a01004f-1-3c08", 16 | "previous": null 17 | } 18 | }, 19 | "source": [ 20 | "# ユーザーの属するグループの確認\n", 21 | "\n", 22 | "ユーザーが属するグループを確認します。JupyterHub上にユーザーが作成済みである必要があります。\n", 23 | "\n", 24 | "グループは、所属グループに応じたリソース制限設定に使用します。" 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "metadata": { 30 | "lc_cell_meme": { 31 | "current": "f67f73d0-7d8a-11eb-b28e-02420a01004f-1-3c08", 32 | "history": [ 33 | { 34 | "current": "f67f73d0-7d8a-11eb-b28e-02420a01004f-1-3c08", 35 | "next": "f67f7538-7d8a-11eb-b28e-02420a01004f", 36 | "previous": "f67f71fa-7d8a-11eb-b28e-02420a01004f" 37 | } 38 | ], 39 | "next": "f67f7538-7d8a-11eb-b28e-02420a01004f-1-0f83", 40 | "previous": "f67f71fa-7d8a-11eb-b28e-02420a01004f-1-fb8b" 41 | } 42 | }, 43 | "source": [ 44 | "# グループの定義" 45 | ] 46 | }, 47 | { 48 | "cell_type": "markdown", 49 | "metadata": { 50 | "lc_cell_meme": { 51 | "current": "f67f7538-7d8a-11eb-b28e-02420a01004f-1-0f83", 52 | "history": [ 53 | { 54 | "current": "f67f7538-7d8a-11eb-b28e-02420a01004f-1-0f83", 55 | "next": "f67f77b8-7d8a-11eb-b28e-02420a01004f", 56 | "previous": "f67f73d0-7d8a-11eb-b28e-02420a01004f" 57 | }, 58 | { 59 | "current": "f67f7538-7d8a-11eb-b28e-02420a01004f-1-0f83", 60 | "next": "f67f77b8-7d8a-11eb-b28e-02420a01004f-1-486d", 61 | "previous": "f67f73d0-7d8a-11eb-b28e-02420a01004f-1-3c08" 62 | } 63 | ], 64 | "next": "f64746ea-7d8a-11eb-bdf7-02420a01004f-2-1444-bff4", 65 | "previous": "f67f73d0-7d8a-11eb-b28e-02420a01004f-1-3c08" 66 | } 67 | }, 68 | "source": [ 69 | "グループを調べるユーザーのメールアドレス" 70 | ] 71 | }, 72 | { 73 | "cell_type": "code", 74 | "execution_count": null, 75 | "metadata": { 76 | "lc_cell_meme": { 77 | "current": "f64746ea-7d8a-11eb-bdf7-02420a01004f-2-1444-bff4", 78 | "history": [ 79 | { 80 | "current": "f64746ea-7d8a-11eb-bdf7-02420a01004f-1-1444", 81 | "next": "f6474816-7d8a-11eb-bdf7-02420a01004f", 82 | "previous": "f64745b4-7d8a-11eb-bdf7-02420a01004f" 83 | }, 84 | { 85 | "current": "f64746ea-7d8a-11eb-bdf7-02420a01004f-2-1444-bff4", 86 | "next": "f6474816-7d8a-11eb-bdf7-02420a01004f-1-c575", 87 | "previous": "f64745b4-7d8a-11eb-bdf7-02420a01004f-1-eedb" 88 | } 89 | ], 90 | "next": "f67f77b8-7d8a-11eb-b28e-02420a01004f-1-486d", 91 | "previous": "f67f7538-7d8a-11eb-b28e-02420a01004f-1-0f83" 92 | } 93 | }, 94 | "outputs": [], 95 | "source": [ 96 | "user_email_list = '''\n", 97 | "student-a01@example.com\n", 98 | "student-a02@example.com\n", 99 | "student-a03@example.com\n", 100 | "'''" 101 | ] 102 | }, 103 | { 104 | "cell_type": "code", 105 | "execution_count": null, 106 | "metadata": { 107 | "lc_cell_meme": { 108 | "current": "f67f77b8-7d8a-11eb-b28e-02420a01004f-1-486d", 109 | "history": [ 110 | { 111 | "current": "f67f77b8-7d8a-11eb-b28e-02420a01004f-1-486d", 112 | "next": "f67f7934-7d8a-11eb-b28e-02420a01004f", 113 | "previous": "f67f7538-7d8a-11eb-b28e-02420a01004f" 114 | }, 115 | { 116 | "current": "f67f77b8-7d8a-11eb-b28e-02420a01004f-1-486d", 117 | "next": "f67f7a74-7d8a-11eb-b28e-02420a01004f-1-0af3", 118 | "previous": "f67f7538-7d8a-11eb-b28e-02420a01004f-1-0f83" 119 | } 120 | ], 121 | "next": "f67f7a74-7d8a-11eb-b28e-02420a01004f-1-0af3", 122 | "previous": "f64746ea-7d8a-11eb-bdf7-02420a01004f-2-1444-bff4" 123 | } 124 | }, 125 | "outputs": [], 126 | "source": [ 127 | "import re\n", 128 | "user_emails = user_email_list.splitlines()\n", 129 | "user_emails = [x.strip() for x in user_emails \n", 130 | " if re.sub(r'#.*$', '', x).strip()]\n", 131 | "user_emails" 132 | ] 133 | }, 134 | { 135 | "cell_type": "code", 136 | "execution_count": null, 137 | "metadata": { 138 | "lc_cell_meme": { 139 | "current": "f67f7a74-7d8a-11eb-b28e-02420a01004f-1-0af3", 140 | "history": [ 141 | { 142 | "current": "f67f7a74-7d8a-11eb-b28e-02420a01004f-1-0af3", 143 | "next": "f67f7bb4-7d8a-11eb-b28e-02420a01004f", 144 | "previous": "f67f7934-7d8a-11eb-b28e-02420a01004f" 145 | } 146 | ], 147 | "next": "f67f7bb4-7d8a-11eb-b28e-02420a01004f-1-ba17", 148 | "previous": "f67f77b8-7d8a-11eb-b28e-02420a01004f-1-486d" 149 | } 150 | }, 151 | "outputs": [], 152 | "source": [ 153 | "import hashlib\n", 154 | "\n", 155 | "def get_username_from_mail_address(mail_address):\n", 156 | " # Convert to lower and remove characters except for alphabets and digits\n", 157 | " wk = mail_address.split('@')\n", 158 | " local_part = wk[0].lower()\n", 159 | " result = re.sub(r'[^a-zA-Z0-9]', '', local_part)\n", 160 | " # Add top 6bytes of hash string\n", 161 | " md5 = hashlib.md5()\n", 162 | " md5.update(mail_address.encode('us-ascii'))\n", 163 | " h = md5.hexdigest()[0:6]\n", 164 | " result += 'x'\n", 165 | " result += h;\n", 166 | " return result;\n", 167 | "\n", 168 | "user_names = [get_username_from_mail_address(x) for x in user_emails]\n", 169 | "user_names" 170 | ] 171 | }, 172 | { 173 | "cell_type": "markdown", 174 | "metadata": { 175 | "lc_cell_meme": { 176 | "current": "f67f7bb4-7d8a-11eb-b28e-02420a01004f-1-ba17", 177 | "history": [ 178 | { 179 | "current": "f67f7bb4-7d8a-11eb-b28e-02420a01004f-1-ba17", 180 | "next": "f67f7cf4-7d8a-11eb-b28e-02420a01004f", 181 | "previous": "f67f7a74-7d8a-11eb-b28e-02420a01004f" 182 | } 183 | ], 184 | "next": "feba8ca8-d0a0-11ee-a40c-02420a640143-4-b18e-b902-eb3e-0b05", 185 | "previous": "f67f7a74-7d8a-11eb-b28e-02420a01004f-1-0af3" 186 | } 187 | }, 188 | "source": [ 189 | "# グループの確認" 190 | ] 191 | }, 192 | { 193 | "cell_type": "markdown", 194 | "metadata": { 195 | "lc_cell_meme": { 196 | "current": "feba8ca8-d0a0-11ee-a40c-02420a640143-4-b18e-b902-eb3e-0b05", 197 | "history": [ 198 | { 199 | "current": "feba8ca8-d0a0-11ee-a40c-02420a640143-2-b18e-b902", 200 | "next": "feba9248-d0a0-11ee-a40c-02420a640143", 201 | "previous": "952ac744-4bfd-11e9-845a-02420a0001bc-1-4ad7" 202 | }, 203 | { 204 | "current": "feba8ca8-d0a0-11ee-a40c-02420a640143-4-b18e-b902-eb3e-0b05", 205 | "next": "feba9248-d0a0-11ee-a40c-02420a640143-2-36f9-b12d", 206 | "previous": "952ac744-4bfd-11e9-845a-02420a0001bc-1-65df" 207 | } 208 | ], 209 | "next": "feba9248-d0a0-11ee-a40c-02420a640143-4-36f9-b12d-d25b-6b47", 210 | "previous": "f67f7bb4-7d8a-11eb-b28e-02420a01004f-1-ba17" 211 | } 212 | }, 213 | "source": [ 214 | "[API Tokens](/hub/token)のページで、tokenを作成して以下に入力してください。" 215 | ] 216 | }, 217 | { 218 | "cell_type": "code", 219 | "execution_count": null, 220 | "metadata": { 221 | "lc_cell_meme": { 222 | "current": "feba9248-d0a0-11ee-a40c-02420a640143-4-36f9-b12d-d25b-6b47", 223 | "history": [ 224 | { 225 | "current": "feba9248-d0a0-11ee-a40c-02420a640143-2-36f9-b12d", 226 | "next": "952ac794-4bfd-11e9-845a-02420a0001bc-1-21a4", 227 | "previous": "feba8ca8-d0a0-11ee-a40c-02420a640143" 228 | }, 229 | { 230 | "current": "feba9248-d0a0-11ee-a40c-02420a640143-4-36f9-b12d-d25b-6b47", 231 | "next": "952ac794-4bfd-11e9-845a-02420a0001bc-1-2b6f", 232 | "previous": "feba8ca8-d0a0-11ee-a40c-02420a640143-2-b18e-b902" 233 | } 234 | ], 235 | "next": "f67f7cf4-7d8a-11eb-b28e-02420a01004f-1-0941", 236 | "previous": "feba8ca8-d0a0-11ee-a40c-02420a640143-4-b18e-b902-eb3e-0b05" 237 | } 238 | }, 239 | "outputs": [], 240 | "source": [ 241 | "import getpass\n", 242 | "apitoken = getpass.getpass('JupyterHub API token')" 243 | ] 244 | }, 245 | { 246 | "cell_type": "code", 247 | "execution_count": null, 248 | "metadata": { 249 | "lc_cell_meme": { 250 | "current": "f67f7cf4-7d8a-11eb-b28e-02420a01004f-1-0941", 251 | "history": [ 252 | { 253 | "current": "f67f7cf4-7d8a-11eb-b28e-02420a01004f-1-0941", 254 | "next": "f67f7e2a-7d8a-11eb-b28e-02420a01004f", 255 | "previous": "f67f7bb4-7d8a-11eb-b28e-02420a01004f" 256 | } 257 | ], 258 | "next": "f67f7e2a-7d8a-11eb-b28e-02420a01004f-1-1663", 259 | "previous": "feba9248-d0a0-11ee-a40c-02420a640143-4-36f9-b12d-d25b-6b47" 260 | } 261 | }, 262 | "outputs": [], 263 | "source": [ 264 | "import os\n", 265 | "api_url = os.environ['JUPYTERHUB_API_URL']" 266 | ] 267 | }, 268 | { 269 | "cell_type": "markdown", 270 | "metadata": { 271 | "lc_cell_meme": { 272 | "current": "f67f7e2a-7d8a-11eb-b28e-02420a01004f-1-1663", 273 | "history": [ 274 | { 275 | "current": "f67f7e2a-7d8a-11eb-b28e-02420a01004f-1-1663", 276 | "next": "f67f7f6a-7d8a-11eb-b28e-02420a01004f", 277 | "previous": "f67f7cf4-7d8a-11eb-b28e-02420a01004f" 278 | } 279 | ], 280 | "next": "f67f7f6a-7d8a-11eb-b28e-02420a01004f-1-2c1f", 281 | "previous": "f67f7cf4-7d8a-11eb-b28e-02420a01004f-1-0941" 282 | } 283 | }, 284 | "source": [ 285 | "グループの表示" 286 | ] 287 | }, 288 | { 289 | "cell_type": "code", 290 | "execution_count": null, 291 | "metadata": { 292 | "lc_cell_meme": { 293 | "current": "f67f7f6a-7d8a-11eb-b28e-02420a01004f-1-2c1f", 294 | "history": [ 295 | { 296 | "current": "f67f7f6a-7d8a-11eb-b28e-02420a01004f-1-2c1f", 297 | "next": "f67f80a0-7d8a-11eb-b28e-02420a01004f", 298 | "previous": "f67f7e2a-7d8a-11eb-b28e-02420a01004f" 299 | } 300 | ], 301 | "next": "f67f80a0-7d8a-11eb-b28e-02420a01004f-1-a78c", 302 | "previous": "f67f7e2a-7d8a-11eb-b28e-02420a01004f-1-1663" 303 | } 304 | }, 305 | "outputs": [], 306 | "source": [ 307 | "headers = {\n", 308 | " 'Authorization': 'token %s' % apitoken,\n", 309 | "}" 310 | ] 311 | }, 312 | { 313 | "cell_type": "code", 314 | "execution_count": null, 315 | "metadata": { 316 | "lc_cell_meme": { 317 | "current": "f67f80a0-7d8a-11eb-b28e-02420a01004f-1-a78c", 318 | "history": [ 319 | { 320 | "current": "f67f80a0-7d8a-11eb-b28e-02420a01004f-1-a78c", 321 | "next": null, 322 | "previous": "f67f7f6a-7d8a-11eb-b28e-02420a01004f" 323 | } 324 | ], 325 | "next": null, 326 | "previous": "f67f7f6a-7d8a-11eb-b28e-02420a01004f-1-2c1f" 327 | } 328 | }, 329 | "outputs": [], 330 | "source": [ 331 | "import requests\n", 332 | "import json\n", 333 | "\n", 334 | "user2mail = dict(zip(user_names, user_emails))\n", 335 | "\n", 336 | "for username in user_names:\n", 337 | " r = requests.get(api_url + '/users/{}'.format(username),\n", 338 | " headers=headers)\n", 339 | " assert r.status_code == 200\n", 340 | " user = r.json()\n", 341 | " print('{}({}){}: {}'.format(user2mail[username], username, \n", 342 | " ' [admin]' if user['admin'] else '',\n", 343 | " ', '.join(user['groups'])))" 344 | ] 345 | } 346 | ], 347 | "metadata": { 348 | "kernelspec": { 349 | "display_name": "Python 3", 350 | "language": "python", 351 | "name": "python3" 352 | }, 353 | "language_info": { 354 | "file_extension": ".py", 355 | "mimetype": "text/x-python", 356 | "name": "python", 357 | "nbconvert_exporter": "python", 358 | "pygments_lexer": "ipython3", 359 | "version": "3.10.11" 360 | }, 361 | "lc_notebook_meme": { 362 | "current": "f67f6db8-7d8a-11eb-b28e-02420a01004f", 363 | "history": [], 364 | "root_cells": [ 365 | "f67f71fa-7d8a-11eb-b28e-02420a01004f", 366 | "f67f73d0-7d8a-11eb-b28e-02420a01004f", 367 | "f67f7538-7d8a-11eb-b28e-02420a01004f", 368 | "f67f77b8-7d8a-11eb-b28e-02420a01004f", 369 | "f67f7934-7d8a-11eb-b28e-02420a01004f", 370 | "f67f7a74-7d8a-11eb-b28e-02420a01004f", 371 | "f67f7bb4-7d8a-11eb-b28e-02420a01004f", 372 | "f67f7cf4-7d8a-11eb-b28e-02420a01004f", 373 | "f67f7e2a-7d8a-11eb-b28e-02420a01004f", 374 | "f67f7f6a-7d8a-11eb-b28e-02420a01004f", 375 | "f67f80a0-7d8a-11eb-b28e-02420a01004f" 376 | ] 377 | }, 378 | "toc": { 379 | "base_numbering": 1, 380 | "nav_menu": {}, 381 | "number_sections": true, 382 | "sideBar": true, 383 | "skip_h1_title": false, 384 | "title_cell": "Table of Contents", 385 | "title_sidebar": "Contents", 386 | "toc_cell": false, 387 | "toc_position": {}, 388 | "toc_section_display": true, 389 | "toc_window_display": true 390 | } 391 | }, 392 | "nbformat": 4, 393 | "nbformat_minor": 4 394 | } 395 | -------------------------------------------------------------------------------- /roles/deploy-manage-tools/files/admin-tools/03_PrepareGitHub.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "lc_cell_meme": { 7 | "current": "9138c690-4bfd-11e9-916e-02420a0001bc", 8 | "history": [], 9 | "next": "9138c708-4bfd-11e9-916e-02420a0001bc", 10 | "previous": null 11 | } 12 | }, 13 | "source": [ 14 | "# GitHubリポジトリの準備\n", 15 | "---" 16 | ] 17 | }, 18 | { 19 | "cell_type": "markdown", 20 | "metadata": { 21 | "lc_cell_meme": { 22 | "current": "9138c708-4bfd-11e9-916e-02420a0001bc", 23 | "history": [], 24 | "next": "9138c762-4bfd-11e9-916e-02420a0001bc", 25 | "previous": "9138c690-4bfd-11e9-916e-02420a0001bc" 26 | } 27 | }, 28 | "source": [ 29 | "教材のバックアップにGitHubを利用する場合の、GitHubリポジトリ作成・操作に関わる手順です。" 30 | ] 31 | }, 32 | { 33 | "cell_type": "markdown", 34 | "metadata": { 35 | "lc_cell_meme": { 36 | "current": "9138c762-4bfd-11e9-916e-02420a0001bc", 37 | "history": [], 38 | "next": "9138c7b2-4bfd-11e9-916e-02420a0001bc", 39 | "previous": "9138c708-4bfd-11e9-916e-02420a0001bc" 40 | } 41 | }, 42 | "source": [ 43 | "\n" 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "metadata": { 49 | "lc_cell_meme": { 50 | "current": "9138c7b2-4bfd-11e9-916e-02420a0001bc", 51 | "history": [], 52 | "next": "9138c802-4bfd-11e9-916e-02420a0001bc", 53 | "previous": "9138c762-4bfd-11e9-916e-02420a0001bc" 54 | } 55 | }, 56 | "source": [ 57 | "## GitHubで新しいリポジトリを作成" 58 | ] 59 | }, 60 | { 61 | "cell_type": "markdown", 62 | "metadata": { 63 | "lc_cell_meme": { 64 | "current": "9138c802-4bfd-11e9-916e-02420a0001bc", 65 | "history": [], 66 | "next": "9138c852-4bfd-11e9-916e-02420a0001bc", 67 | "previous": "9138c7b2-4bfd-11e9-916e-02420a0001bc" 68 | } 69 | }, 70 | "source": [ 71 | "### リポジトリの作成\n", 72 | "次の手順にしたがって、バックアップ用のリポジトリを作成して下さい。" 73 | ] 74 | }, 75 | { 76 | "cell_type": "markdown", 77 | "metadata": { 78 | "lc_cell_meme": { 79 | "current": "9138c852-4bfd-11e9-916e-02420a0001bc", 80 | "history": [], 81 | "next": "9138c898-4bfd-11e9-916e-02420a0001bc", 82 | "previous": "9138c802-4bfd-11e9-916e-02420a0001bc" 83 | } 84 | }, 85 | "source": [ 86 | "1. GitHubにログインします。\n", 87 | " * GitHubアカウントをお持ちでない場合は作成して下さい。\n", 88 | "2. 画面上のメニューから[Repositories]を選択します。\n", 89 | "3. 画面右上の[New]ボタンをクリックします。下記の要領で入力します。\n", 90 | " * Repository name: 作成するリポジトリの名前を入力します。(必須)\n", 91 | " * Description: リポジトリ関する説明を入力します。(任意)\n", 92 | " * Public/Private: 作成したリポジトリを公開する場合は「Public」、非公開とする場合は「Private」を選択します。「Private」は有償契約の場合のみ利用できます。\n", 93 | " * Initialize this repository with a README: `README` を作成する場合はチェックします。`README` は後から作成できます。\n", 94 | " * Add .gitignore: [None]を選択。\n", 95 | " * Add a license: [None]を選択。\n", 96 | "4. [Create repository]ボタンをクリックします。" 97 | ] 98 | }, 99 | { 100 | "cell_type": "markdown", 101 | "metadata": { 102 | "lc_cell_meme": { 103 | "current": "9138c898-4bfd-11e9-916e-02420a0001bc", 104 | "history": [], 105 | "next": "9138c8e8-4bfd-11e9-916e-02420a0001bc", 106 | "previous": "9138c852-4bfd-11e9-916e-02420a0001bc" 107 | } 108 | }, 109 | "source": [ 110 | "## SSHキーの登録" 111 | ] 112 | }, 113 | { 114 | "cell_type": "markdown", 115 | "metadata": { 116 | "lc_cell_meme": { 117 | "current": "9138c8e8-4bfd-11e9-916e-02420a0001bc", 118 | "history": [], 119 | "next": "9138c938-4bfd-11e9-916e-02420a0001bc", 120 | "previous": "9138c898-4bfd-11e9-916e-02420a0001bc" 121 | } 122 | }, 123 | "source": [ 124 | "次の手順にしたがって、リポジトリにアクセスするためのSSHキーを登録して下さい。既に登録済みのキーをお持ちに場合は、そちらをお使い頂いても構いません。\n", 125 | "\n", 126 | "登録済みのキーを使用する場合には、`$HOME/.ssh/id_rsa` に `mode=0600` で秘密鍵を格納してください。" 127 | ] 128 | }, 129 | { 130 | "cell_type": "markdown", 131 | "metadata": { 132 | "lc_cell_meme": { 133 | "current": "9138c938-4bfd-11e9-916e-02420a0001bc", 134 | "history": [], 135 | "next": "9138c97e-4bfd-11e9-916e-02420a0001bc", 136 | "previous": "9138c8e8-4bfd-11e9-916e-02420a0001bc" 137 | } 138 | }, 139 | "source": [ 140 | "### SSHキーの生成\n", 141 | "\n", 142 | "**次のセルを実行して、SSHキーペアを作成して下さい。キーペアは `$HOME/.ssh/` 以下に作成されます**\n", 143 | "- 秘密鍵: `$HOME/.ssh/id_rsa`\n", 144 | "- 公開鍵: `$HOME/.ssh/id_rsa.pub`" 145 | ] 146 | }, 147 | { 148 | "cell_type": "code", 149 | "execution_count": null, 150 | "metadata": { 151 | "lc_cell_meme": { 152 | "current": "9138c97e-4bfd-11e9-916e-02420a0001bc", 153 | "history": [], 154 | "next": "9138c9ce-4bfd-11e9-916e-02420a0001bc", 155 | "previous": "9138c938-4bfd-11e9-916e-02420a0001bc" 156 | } 157 | }, 158 | "outputs": [], 159 | "source": [ 160 | "%%bash\n", 161 | "export LANG=\n", 162 | "EMAIL=\"your-email@example.com\"\n", 163 | "# rm ~/.ssh/id_rsa{,.pub}\n", 164 | "if [ -f ~/.ssh/id_rsa ]; then\n", 165 | " echo 'Private key already exists.' 1>&2\n", 166 | "else\n", 167 | " ssh-keygen -t rsa -b 4096 -P \"\" -C \"${EMAIL}\" -f ~/.ssh/id_rsa\n", 168 | " echo 'Key pair generated.'\n", 169 | "fi" 170 | ] 171 | }, 172 | { 173 | "cell_type": "markdown", 174 | "metadata": { 175 | "lc_cell_meme": { 176 | "current": "9138c9ce-4bfd-11e9-916e-02420a0001bc", 177 | "history": [], 178 | "next": "9138ca1e-4bfd-11e9-916e-02420a0001bc", 179 | "previous": "9138c97e-4bfd-11e9-916e-02420a0001bc" 180 | } 181 | }, 182 | "source": [ 183 | "**次のセルを実行して、作成した公開鍵を表示してください。コピーして GitHub に登録します。**" 184 | ] 185 | }, 186 | { 187 | "cell_type": "code", 188 | "execution_count": null, 189 | "metadata": { 190 | "lc_cell_meme": { 191 | "current": "9138ca1e-4bfd-11e9-916e-02420a0001bc", 192 | "history": [], 193 | "next": "9138ca64-4bfd-11e9-916e-02420a0001bc", 194 | "previous": "9138c9ce-4bfd-11e9-916e-02420a0001bc" 195 | } 196 | }, 197 | "outputs": [], 198 | "source": [ 199 | "%pycat ~/.ssh/id_rsa.pub" 200 | ] 201 | }, 202 | { 203 | "cell_type": "markdown", 204 | "metadata": { 205 | "lc_cell_meme": { 206 | "current": "9138ca64-4bfd-11e9-916e-02420a0001bc", 207 | "history": [], 208 | "next": "9138cab4-4bfd-11e9-916e-02420a0001bc", 209 | "previous": "9138ca1e-4bfd-11e9-916e-02420a0001bc" 210 | } 211 | }, 212 | "source": [ 213 | "### GitHubに生成したキーを登録" 214 | ] 215 | }, 216 | { 217 | "cell_type": "markdown", 218 | "metadata": { 219 | "lc_cell_meme": { 220 | "current": "9138cab4-4bfd-11e9-916e-02420a0001bc", 221 | "history": [], 222 | "next": "9138cafa-4bfd-11e9-916e-02420a0001bc", 223 | "previous": "9138ca64-4bfd-11e9-916e-02420a0001bc" 224 | } 225 | }, 226 | "source": [ 227 | "1. GitHubにログインします。\n", 228 | "2. 画面右上の[View profile and more]プルダウンから、[Settings]を選択します。\n", 229 | "3. 画面左のメニューから[SSH and GPG keys]を選択します。「SSH Keys」画面が表示されます。\n", 230 | "4. 画面右上の[New SSH key]ボタンをクリックします。\n", 231 | "5. キー登録フォームが表示されますので、下記の要領で入力して下さい。\n", 232 | " * Title: キーの名前を入力します。\n", 233 | " * Key: 「2.1 SSHキーの生成」作成したキーペアの「公開鍵」をコピー&ペーストします。\n", 234 | "3. [Add SSH key]ボタンをクリックします。" 235 | ] 236 | }, 237 | { 238 | "cell_type": "markdown", 239 | "metadata": { 240 | "lc_cell_meme": { 241 | "current": "9138cafa-4bfd-11e9-916e-02420a0001bc", 242 | "history": [], 243 | "next": "9138cb4a-4bfd-11e9-916e-02420a0001bc", 244 | "previous": "9138cab4-4bfd-11e9-916e-02420a0001bc" 245 | } 246 | }, 247 | "source": [ 248 | " " 249 | ] 250 | }, 251 | { 252 | "cell_type": "markdown", 253 | "metadata": { 254 | "lc_cell_meme": { 255 | "current": "9138cb4a-4bfd-11e9-916e-02420a0001bc", 256 | "history": [], 257 | "next": "9138cb90-4bfd-11e9-916e-02420a0001bc", 258 | "previous": "9138cafa-4bfd-11e9-916e-02420a0001bc" 259 | } 260 | }, 261 | "source": [ 262 | "# GitHubリポジトリ接続情報の設定" 263 | ] 264 | }, 265 | { 266 | "cell_type": "markdown", 267 | "metadata": { 268 | "lc_cell_meme": { 269 | "current": "9138cb90-4bfd-11e9-916e-02420a0001bc", 270 | "history": [], 271 | "next": "9138cbe0-4bfd-11e9-916e-02420a0001bc", 272 | "previous": "9138cb4a-4bfd-11e9-916e-02420a0001bc" 273 | } 274 | }, 275 | "source": [ 276 | "## 接続情報の入力" 277 | ] 278 | }, 279 | { 280 | "cell_type": "markdown", 281 | "metadata": { 282 | "lc_cell_meme": { 283 | "current": "9138cbe0-4bfd-11e9-916e-02420a0001bc", 284 | "history": [], 285 | "next": "9138cc26-4bfd-11e9-916e-02420a0001bc", 286 | "previous": "9138cb90-4bfd-11e9-916e-02420a0001bc" 287 | } 288 | }, 289 | "source": [ 290 | "* バックアップ先のGitHubリポジトリへの接続情報を設定します。\n", 291 | "\n", 292 | " + GIT_REPO: GitHubリポジトリのcloneパス。\n", 293 | " ```\n", 294 | " GIT_REPO=git@github.com:****/course-a.git\n", 295 | " ```\n", 296 | " + GIT_USER_NAME: GitHubのユーザ名\n", 297 | " ```\n", 298 | " GIT_USER_NAME=user\n", 299 | " ```\n", 300 | " + GIT_USER_EMAIL: コミットログに記載されるe-mailアドレス\n", 301 | " ```\n", 302 | " GIT_USER_EMAIL=user@example.com\n", 303 | " ```\n", 304 | " \n", 305 | "**次のセルで接続情報パラメータを設定して、セルを実行して下さい。**" 306 | ] 307 | }, 308 | { 309 | "cell_type": "code", 310 | "execution_count": null, 311 | "metadata": { 312 | "lc_cell_meme": { 313 | "current": "9138cc26-4bfd-11e9-916e-02420a0001bc", 314 | "history": [], 315 | "next": "9138cc76-4bfd-11e9-916e-02420a0001bc", 316 | "previous": "9138cbe0-4bfd-11e9-916e-02420a0001bc" 317 | } 318 | }, 319 | "outputs": [], 320 | "source": [ 321 | "%env GIT_REPO=git@github.com:****/course-a.git\n", 322 | "%env GIT_USER_NAME=UserName\n", 323 | "%env GIT_USER_EMAIL=user@example.com" 324 | ] 325 | }, 326 | { 327 | "cell_type": "markdown", 328 | "metadata": { 329 | "lc_cell_meme": { 330 | "current": "9138cc76-4bfd-11e9-916e-02420a0001bc", 331 | "history": [], 332 | "next": "9138ccbc-4bfd-11e9-916e-02420a0001bc", 333 | "previous": "9138cc26-4bfd-11e9-916e-02420a0001bc" 334 | } 335 | }, 336 | "source": [ 337 | "## 接続情報の設定" 338 | ] 339 | }, 340 | { 341 | "cell_type": "markdown", 342 | "metadata": { 343 | "lc_cell_meme": { 344 | "current": "9138ccbc-4bfd-11e9-916e-02420a0001bc", 345 | "history": [], 346 | "next": "9138cd0c-4bfd-11e9-916e-02420a0001bc", 347 | "previous": "9138cc76-4bfd-11e9-916e-02420a0001bc" 348 | } 349 | }, 350 | "source": [ 351 | "**次のセルを実行して、GitHubリポジトリの接続情報を設定して下さい。**" 352 | ] 353 | }, 354 | { 355 | "cell_type": "code", 356 | "execution_count": null, 357 | "metadata": { 358 | "lc_cell_meme": { 359 | "current": "9138cd0c-4bfd-11e9-916e-02420a0001bc", 360 | "history": [], 361 | "next": null, 362 | "previous": "9138ccbc-4bfd-11e9-916e-02420a0001bc" 363 | } 364 | }, 365 | "outputs": [], 366 | "source": [ 367 | "%%bash\n", 368 | "\n", 369 | "cd\n", 370 | "\n", 371 | "comm -13 <(sort ~/.ssh/known_hosts) <(ssh-keyscan github.com 2>/dev/null | sort) >>~/.ssh/known_hosts \n", 372 | "\n", 373 | "IS_INSIDE_REPO=0\n", 374 | "S=\"$(git rev-parse --is-inside-work-tree 2>/dev/null)\"\n", 375 | "[ $? -eq 0 -a \"${S}\" = \"true\" ] && IS_INSIDE_REPO=1\n", 376 | "\n", 377 | "if [ ${IS_INSIDE_REPO} -ne 1 ]; then\n", 378 | " git init\n", 379 | "fi\n", 380 | "\n", 381 | "git remote get-url origin >/dev/null 2>&1\n", 382 | "if [ $? -eq 0 ]; then\n", 383 | " git remote rm origin\n", 384 | "\n", 385 | "fi\n", 386 | "git remote add origin \"${GIT_REPO}\"\n", 387 | "\n", 388 | "git config user.name \"${GIT_USER_NAME}\"\n", 389 | "git config user.email \"${GIT_USER_EMAIL}\"\n", 390 | "git config push.default simple\n", 391 | "\n", 392 | "git fetch --force origin\n", 393 | "\n", 394 | "git status" 395 | ] 396 | } 397 | ], 398 | "metadata": { 399 | "kernelspec": { 400 | "display_name": "Python 3", 401 | "language": "python", 402 | "name": "python3" 403 | }, 404 | "language_info": { 405 | "codemirror_mode": { 406 | "name": "ipython", 407 | "version": 3 408 | }, 409 | "file_extension": ".py", 410 | "mimetype": "text/x-python", 411 | "name": "python", 412 | "nbconvert_exporter": "python", 413 | "pygments_lexer": "ipython3", 414 | "version": "3.6.8" 415 | }, 416 | "lc_notebook_meme": { 417 | "current": "9138c546-4bfd-11e9-916e-02420a0001bc", 418 | "history": [], 419 | "root_cells": [ 420 | "9138c690-4bfd-11e9-916e-02420a0001bc", 421 | "9138c708-4bfd-11e9-916e-02420a0001bc", 422 | "9138c762-4bfd-11e9-916e-02420a0001bc", 423 | "9138c7b2-4bfd-11e9-916e-02420a0001bc", 424 | "9138c802-4bfd-11e9-916e-02420a0001bc", 425 | "9138c852-4bfd-11e9-916e-02420a0001bc", 426 | "9138c898-4bfd-11e9-916e-02420a0001bc", 427 | "9138c8e8-4bfd-11e9-916e-02420a0001bc", 428 | "9138c938-4bfd-11e9-916e-02420a0001bc", 429 | "9138c97e-4bfd-11e9-916e-02420a0001bc", 430 | "9138c9ce-4bfd-11e9-916e-02420a0001bc", 431 | "9138ca1e-4bfd-11e9-916e-02420a0001bc", 432 | "9138ca64-4bfd-11e9-916e-02420a0001bc", 433 | "9138cab4-4bfd-11e9-916e-02420a0001bc", 434 | "9138cafa-4bfd-11e9-916e-02420a0001bc", 435 | "9138cb4a-4bfd-11e9-916e-02420a0001bc", 436 | "9138cb90-4bfd-11e9-916e-02420a0001bc", 437 | "9138cbe0-4bfd-11e9-916e-02420a0001bc", 438 | "9138cc26-4bfd-11e9-916e-02420a0001bc", 439 | "9138cc76-4bfd-11e9-916e-02420a0001bc", 440 | "9138ccbc-4bfd-11e9-916e-02420a0001bc", 441 | "9138cd0c-4bfd-11e9-916e-02420a0001bc" 442 | ] 443 | }, 444 | "toc": { 445 | "base_numbering": 1, 446 | "nav_menu": {}, 447 | "number_sections": true, 448 | "sideBar": true, 449 | "skip_h1_title": false, 450 | "title_cell": "Table of Contents", 451 | "title_sidebar": "Contents", 452 | "toc_cell": false, 453 | "toc_position": {}, 454 | "toc_section_display": true, 455 | "toc_window_display": true 456 | } 457 | }, 458 | "nbformat": 4, 459 | "nbformat_minor": 2 460 | } 461 | -------------------------------------------------------------------------------- /roles/deploy-manage-tools/files/admin-tools/13_RestoreMaterials.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "lc_cell_meme": { 7 | "current": "92aa200a-4bfd-11e9-a41e-02420a0001bc-1-8362", 8 | "history": [ 9 | { 10 | "current": "92aa200a-4bfd-11e9-a41e-02420a0001bc-1-8362", 11 | "next": "92aa2082-4bfd-11e9-a41e-02420a0001bc", 12 | "previous": null 13 | } 14 | ], 15 | "next": "92aa2082-4bfd-11e9-a41e-02420a0001bc-1-c20b", 16 | "previous": null 17 | } 18 | }, 19 | "source": [ 20 | "# 保存した教材バックアップをリストアします\n", 21 | "
" 22 | ] 23 | }, 24 | { 25 | "cell_type": "markdown", 26 | "metadata": { 27 | "lc_cell_meme": { 28 | "current": "92aa2082-4bfd-11e9-a41e-02420a0001bc-1-c20b", 29 | "history": [ 30 | { 31 | "current": "92aa2082-4bfd-11e9-a41e-02420a0001bc-1-c20b", 32 | "next": "92aa20dc-4bfd-11e9-a41e-02420a0001bc", 33 | "previous": "92aa200a-4bfd-11e9-a41e-02420a0001bc" 34 | } 35 | ], 36 | "next": "92aa20dc-4bfd-11e9-a41e-02420a0001bc-1-5a81", 37 | "previous": "92aa200a-4bfd-11e9-a41e-02420a0001bc-1-8362" 38 | } 39 | }, 40 | "source": [ 41 | "保存してある教材のバックアップファイルを展開して、指定された位置に配置します。" 42 | ] 43 | }, 44 | { 45 | "cell_type": "markdown", 46 | "metadata": { 47 | "lc_cell_meme": { 48 | "current": "92aa20dc-4bfd-11e9-a41e-02420a0001bc-1-5a81", 49 | "history": [ 50 | { 51 | "current": "92aa20dc-4bfd-11e9-a41e-02420a0001bc-1-5a81", 52 | "next": "92aa212c-4bfd-11e9-a41e-02420a0001bc", 53 | "previous": "92aa2082-4bfd-11e9-a41e-02420a0001bc" 54 | } 55 | ], 56 | "next": "92aa212c-4bfd-11e9-a41e-02420a0001bc-1-2d40", 57 | "previous": "92aa2082-4bfd-11e9-a41e-02420a0001bc-1-c20b" 58 | } 59 | }, 60 | "source": [ 61 | "# リストアの準備" 62 | ] 63 | }, 64 | { 65 | "cell_type": "markdown", 66 | "metadata": { 67 | "lc_cell_meme": { 68 | "current": "92aa212c-4bfd-11e9-a41e-02420a0001bc-1-2d40", 69 | "history": [ 70 | { 71 | "current": "92aa212c-4bfd-11e9-a41e-02420a0001bc-1-2d40", 72 | "next": "92aa2172-4bfd-11e9-a41e-02420a0001bc", 73 | "previous": "92aa20dc-4bfd-11e9-a41e-02420a0001bc" 74 | } 75 | ], 76 | "next": "92aa2172-4bfd-11e9-a41e-02420a0001bc-1-649d", 77 | "previous": "92aa20dc-4bfd-11e9-a41e-02420a0001bc-1-5a81" 78 | } 79 | }, 80 | "source": [ 81 | "このNotebookを実行すると、ホームディレクトリ直下の下記のフォルダを、バックアップファイルの内容で上書きコピーします。\n", 82 | "\n", 83 | "**上書きしたくないファイル/フォルダは、下記のフォルダから退避しておいて下さい。**\n", 84 | "\n", 85 | "* `textbook/`\n", 86 | " + 教材Notebookおよび教材Notebookから呼び出すスクリプトなど\n", 87 | "* `info/`\n", 88 | " + 受講者が参照する参考資料など\n", 89 | "* `draft/`\n", 90 | " + 教材以外で保存して置きたいNotebook、その他ファイル\n", 91 | " \n", 92 | "バックアップを作成する際に、上記以外のファイル/フォルダを `INCLUDES` で追加した場合、それらのファイル/フォルダも上書きコピーされます。" 93 | ] 94 | }, 95 | { 96 | "cell_type": "markdown", 97 | "metadata": { 98 | "lc_cell_meme": { 99 | "current": "92aa2172-4bfd-11e9-a41e-02420a0001bc-1-649d", 100 | "history": [ 101 | { 102 | "current": "92aa2172-4bfd-11e9-a41e-02420a0001bc-1-649d", 103 | "next": "92aa21c2-4bfd-11e9-a41e-02420a0001bc", 104 | "previous": "92aa212c-4bfd-11e9-a41e-02420a0001bc" 105 | } 106 | ], 107 | "next": "92aa21c2-4bfd-11e9-a41e-02420a0001bc-1-37ad", 108 | "previous": "92aa212c-4bfd-11e9-a41e-02420a0001bc-1-2d40" 109 | } 110 | }, 111 | "source": [ 112 | "# バックアップファイルを転送します" 113 | ] 114 | }, 115 | { 116 | "cell_type": "markdown", 117 | "metadata": { 118 | "lc_cell_meme": { 119 | "current": "92aa21c2-4bfd-11e9-a41e-02420a0001bc-1-37ad", 120 | "history": [ 121 | { 122 | "current": "92aa21c2-4bfd-11e9-a41e-02420a0001bc-1-37ad", 123 | "next": "92aa2208-4bfd-11e9-a41e-02420a0001bc", 124 | "previous": "92aa2172-4bfd-11e9-a41e-02420a0001bc" 125 | } 126 | ], 127 | "next": "92aa2208-4bfd-11e9-a41e-02420a0001bc-1-ffef", 128 | "previous": "92aa2172-4bfd-11e9-a41e-02420a0001bc-1-649d" 129 | } 130 | }, 131 | "source": [ 132 | "リストアする バックアップファイル(`*.tgz` または `*.tar.gz` 形式)を、Jupyter に転送して下さい。\n", 133 | "\n", 134 | "バックアップファイルがローカルマシンにある場合は、下記の手順でアップロードできます。\n", 135 | " 1. ブラウザのHome画面で、フォルダを開きます。\n", 136 | " 2. 画面右上の[Upload]ボタンを押します。ファイル選択ダイアログが開きます。\n", 137 | " 3. ファイルを選択して[開く]ボタンを押します。ファイル一覧最上部にアップロードファイル名が表示されます。\n", 138 | " 4. ファイル名を変更する場合にはファイル名を選択して編集します。\n", 139 | " 5. バックアップファイル名の行の右端の[Upload]ボタンを押すとアップロードされます。" 140 | ] 141 | }, 142 | { 143 | "cell_type": "markdown", 144 | "metadata": { 145 | "lc_cell_meme": { 146 | "current": "92aa2208-4bfd-11e9-a41e-02420a0001bc-1-ffef", 147 | "history": [ 148 | { 149 | "current": "92aa2208-4bfd-11e9-a41e-02420a0001bc-1-ffef", 150 | "next": "92aa224e-4bfd-11e9-a41e-02420a0001bc", 151 | "previous": "92aa21c2-4bfd-11e9-a41e-02420a0001bc" 152 | } 153 | ], 154 | "next": "92aa224e-4bfd-11e9-a41e-02420a0001bc-1-2b05", 155 | "previous": "92aa21c2-4bfd-11e9-a41e-02420a0001bc-1-37ad" 156 | } 157 | }, 158 | "source": [ 159 | "# バックアップファイル名を指定します" 160 | ] 161 | }, 162 | { 163 | "cell_type": "markdown", 164 | "metadata": { 165 | "lc_cell_meme": { 166 | "current": "92aa224e-4bfd-11e9-a41e-02420a0001bc-1-2b05", 167 | "history": [ 168 | { 169 | "current": "92aa224e-4bfd-11e9-a41e-02420a0001bc-1-2b05", 170 | "next": "92aa229e-4bfd-11e9-a41e-02420a0001bc", 171 | "previous": "92aa2208-4bfd-11e9-a41e-02420a0001bc" 172 | } 173 | ], 174 | "next": "92aa229e-4bfd-11e9-a41e-02420a0001bc-1-a131", 175 | "previous": "92aa2208-4bfd-11e9-a41e-02420a0001bc-1-ffef" 176 | } 177 | }, 178 | "source": [ 179 | "* ARCHIVE_FILE_NAME にリストアするバックアップファイル名を指定して下さい。\n", 180 | "```\n", 181 | "%env ARCHIVE_FILE_NAME=backup-course-01.tgz\n", 182 | "```\n", 183 | "* バックアップファイルは、ホームディレクトリからの相対パスで指定します。\n", 184 | "\n", 185 | "**次のセルでバックアップファイル名を指定して、セルを実行して下さい。**" 186 | ] 187 | }, 188 | { 189 | "cell_type": "code", 190 | "execution_count": null, 191 | "metadata": { 192 | "deletable": false, 193 | "editable": false, 194 | "lc_cell_meme": { 195 | "current": "92aa229e-4bfd-11e9-a41e-02420a0001bc-1-a131", 196 | "history": [ 197 | { 198 | "current": "92aa229e-4bfd-11e9-a41e-02420a0001bc-1-a131", 199 | "next": "92aa22e4-4bfd-11e9-a41e-02420a0001bc", 200 | "previous": "92aa224e-4bfd-11e9-a41e-02420a0001bc" 201 | } 202 | ], 203 | "next": "a09cf1c8-fe54-11ef-96fa-02420a640255-6-c795-8dcc-a674-acfd-7211-a7dc", 204 | "previous": "92aa224e-4bfd-11e9-a41e-02420a0001bc-1-2b05" 205 | }, 206 | "run_through_control": { 207 | "frozen": false 208 | } 209 | }, 210 | "outputs": [], 211 | "source": [ 212 | "%env ARCHIVE_FILE_NAME=backup-course-01.tgz" 213 | ] 214 | }, 215 | { 216 | "cell_type": "markdown", 217 | "metadata": { 218 | "lc_cell_meme": { 219 | "current": "a09cf1c8-fe54-11ef-96fa-02420a640255-6-c795-8dcc-a674-acfd-7211-a7dc", 220 | "history": [ 221 | { 222 | "current": "a09cf1c8-fe54-11ef-96fa-02420a640255-2-c795-8dcc", 223 | "next": "64cc969c-fd8e-11ef-ac33-02420a64024e-1-3a7b", 224 | "previous": "91ef93c0-4bfd-11e9-ad24-02420a0001bc-1-1627" 225 | }, 226 | { 227 | "current": "a09cf1c8-fe54-11ef-96fa-02420a640255-4-c795-8dcc-a674-acfd", 228 | "next": "64cc969c-fd8e-11ef-ac33-02420a64024e-3-3a7b-e4d3-8e14", 229 | "previous": "947105ac-4bfd-11e9-8c4f-02420a0001bc-1-da56" 230 | }, 231 | { 232 | "current": "a09cf1c8-fe54-11ef-96fa-02420a640255-6-c795-8dcc-a674-acfd-7211-a7dc", 233 | "next": "64cc969c-fd8e-11ef-ac33-02420a64024e-5-3a7b-e4d3-8e14-9084-80c1", 234 | "previous": "924bfdc2-4bfd-11e9-bee0-02420a0001bc-1-1b9b" 235 | } 236 | ], 237 | "next": "64cc969c-fd8e-11ef-ac33-02420a64024e-7-3a7b-e4d3-8e14-9084-80c1-c439-34df", 238 | "previous": "92aa229e-4bfd-11e9-a41e-02420a0001bc-1-a131" 239 | } 240 | }, 241 | "source": [ 242 | "# コースの指定" 243 | ] 244 | }, 245 | { 246 | "cell_type": "code", 247 | "execution_count": null, 248 | "metadata": { 249 | "deletable": false, 250 | "editable": false, 251 | "lc_cell_meme": { 252 | "current": "64cc969c-fd8e-11ef-ac33-02420a64024e-7-3a7b-e4d3-8e14-9084-80c1-c439-34df", 253 | "history": [ 254 | { 255 | "current": "64cc969c-fd8e-11ef-ac33-02420a64024e-1-3a7b", 256 | "next": "9193b88e-4bfd-11e9-80f2-02420a0001bc-1-3d06", 257 | "previous": "9193b848-4bfd-11e9-80f2-02420a0001bc-1-0ae7" 258 | }, 259 | { 260 | "current": "64cc969c-fd8e-11ef-ac33-02420a64024e-3-3a7b-e4d3-8e14", 261 | "next": "91ef9410-4bfd-11e9-ad24-02420a0001bc-1-9cb9", 262 | "previous": "a09cf1c8-fe54-11ef-96fa-02420a640255" 263 | }, 264 | { 265 | "current": "64cc969c-fd8e-11ef-ac33-02420a64024e-5-3a7b-e4d3-8e14-9084-80c1", 266 | "next": "94710606-4bfd-11e9-8c4f-02420a0001bc-1-9c59", 267 | "previous": "a09cf1c8-fe54-11ef-96fa-02420a640255-2-c795-8dcc" 268 | }, 269 | { 270 | "current": "64cc969c-fd8e-11ef-ac33-02420a64024e-7-3a7b-e4d3-8e14-9084-80c1-c439-34df", 271 | "next": "924bfe08-4bfd-11e9-bee0-02420a0001bc-1-ccc6", 272 | "previous": "a09cf1c8-fe54-11ef-96fa-02420a640255-4-c795-8dcc-a674-acfd" 273 | } 274 | ], 275 | "next": "92aa22e4-4bfd-11e9-a41e-02420a0001bc-1-d4e5", 276 | "previous": "a09cf1c8-fe54-11ef-96fa-02420a640255-6-c795-8dcc-a674-acfd-7211-a7dc" 277 | }, 278 | "run_through_control": { 279 | "frozen": false 280 | } 281 | }, 282 | "outputs": [], 283 | "source": [ 284 | "import os\n", 285 | "\n", 286 | "# コース名の指定\n", 287 | "course_name = os.environ['CWH_COURSE_NAME']\n", 288 | "course_name" 289 | ] 290 | }, 291 | { 292 | "cell_type": "markdown", 293 | "metadata": { 294 | "lc_cell_meme": { 295 | "current": "92aa22e4-4bfd-11e9-a41e-02420a0001bc-1-d4e5", 296 | "history": [ 297 | { 298 | "current": "92aa22e4-4bfd-11e9-a41e-02420a0001bc-1-d4e5", 299 | "next": "92aa232a-4bfd-11e9-a41e-02420a0001bc", 300 | "previous": "92aa229e-4bfd-11e9-a41e-02420a0001bc" 301 | } 302 | ], 303 | "next": "92aa232a-4bfd-11e9-a41e-02420a0001bc-1-94e7", 304 | "previous": "64cc969c-fd8e-11ef-ac33-02420a64024e-7-3a7b-e4d3-8e14-9084-80c1-c439-34df" 305 | } 306 | }, 307 | "source": [ 308 | "# 次のセルを実行して、バックアップファイルを展開して下さい\n" 309 | ] 310 | }, 311 | { 312 | "cell_type": "markdown", 313 | "metadata": { 314 | "lc_cell_meme": { 315 | "current": "92aa232a-4bfd-11e9-a41e-02420a0001bc-1-94e7", 316 | "history": [ 317 | { 318 | "current": "92aa232a-4bfd-11e9-a41e-02420a0001bc-1-94e7", 319 | "next": "92aa237a-4bfd-11e9-a41e-02420a0001bc", 320 | "previous": "92aa22e4-4bfd-11e9-a41e-02420a0001bc" 321 | } 322 | ], 323 | "next": "92aa237a-4bfd-11e9-a41e-02420a0001bc-1-a58f", 324 | "previous": "92aa22e4-4bfd-11e9-a41e-02420a0001bc-1-d4e5" 325 | } 326 | }, 327 | "source": [ 328 | "バックアップファイルを展開して、ホームディレクトリに配置します。" 329 | ] 330 | }, 331 | { 332 | "cell_type": "code", 333 | "execution_count": null, 334 | "metadata": { 335 | "deletable": false, 336 | "editable": false, 337 | "lc_cell_meme": { 338 | "current": "92aa237a-4bfd-11e9-a41e-02420a0001bc-1-a58f", 339 | "history": [ 340 | { 341 | "current": "92aa237a-4bfd-11e9-a41e-02420a0001bc-1-a58f", 342 | "next": null, 343 | "previous": "92aa232a-4bfd-11e9-a41e-02420a0001bc" 344 | } 345 | ], 346 | "next": null, 347 | "previous": "92aa232a-4bfd-11e9-a41e-02420a0001bc-1-94e7" 348 | }, 349 | "run_through_control": { 350 | "frozen": false 351 | } 352 | }, 353 | "outputs": [], 354 | "source": [ 355 | "%%bash\n", 356 | "set -e\n", 357 | "\n", 358 | "umask 0022\n", 359 | "cd ~/${CWH_COURSE_NAME}\n", 360 | "\n", 361 | "if [ ! -e \"${ARCHIVE_FILE_NAME}\" ]; then\n", 362 | " echo \"${ARCHIVE_FILE_NAME}: No such file or directory\" 1>&2\n", 363 | " exit 1\n", 364 | "fi\n", 365 | "\n", 366 | "# Test Archive\n", 367 | "tar -tz -f \"${ARCHIVE_FILE_NAME}\" >/dev/null\n", 368 | "if [ $? -ne 0 ]; then\n", 369 | " echo \"${ARCHIVE_FILE_NAME}: Unexpected backup file format\" 1>&2\n", 370 | " exit 1\n", 371 | "fi \n", 372 | "\n", 373 | "# Extract files\n", 374 | "tar -xz --overwrite -f \"${ARCHIVE_FILE_NAME}\"\n", 375 | "if [ $? -ne 0 ]; then\n", 376 | " echo \"Error while extracting backup file\"\n", 377 | " exit 1\n", 378 | "fi\n", 379 | "\n", 380 | "# Trust notebooks\n", 381 | "tar -tz -f \"${ARCHIVE_FILE_NAME}\" | while read -r path; do\n", 382 | " if [ -f \"${path}\" -a \"${path: -6}\" = \".ipynb\" ]; then\n", 383 | " jupyter-trust \"${path}\"\n", 384 | " fi\n", 385 | "done\n", 386 | "\n", 387 | "echo\n", 388 | "echo \"Successfully restored.\"" 389 | ] 390 | } 391 | ], 392 | "metadata": { 393 | "kernelspec": { 394 | "display_name": "Python 3", 395 | "language": "python", 396 | "name": "python3" 397 | }, 398 | "language_info": { 399 | "file_extension": ".py", 400 | "mimetype": "text/x-python", 401 | "name": "python", 402 | "nbconvert_exporter": "python", 403 | "pygments_lexer": "ipython3", 404 | "version": "3.10.11" 405 | }, 406 | "lc_notebook_meme": { 407 | "current": "92aa1ec0-4bfd-11e9-a41e-02420a0001bc", 408 | "history": [], 409 | "root_cells": [ 410 | "92aa200a-4bfd-11e9-a41e-02420a0001bc", 411 | "92aa2082-4bfd-11e9-a41e-02420a0001bc", 412 | "92aa20dc-4bfd-11e9-a41e-02420a0001bc", 413 | "92aa212c-4bfd-11e9-a41e-02420a0001bc", 414 | "92aa2172-4bfd-11e9-a41e-02420a0001bc", 415 | "92aa21c2-4bfd-11e9-a41e-02420a0001bc", 416 | "92aa2208-4bfd-11e9-a41e-02420a0001bc", 417 | "92aa224e-4bfd-11e9-a41e-02420a0001bc", 418 | "92aa229e-4bfd-11e9-a41e-02420a0001bc", 419 | "92aa22e4-4bfd-11e9-a41e-02420a0001bc", 420 | "92aa232a-4bfd-11e9-a41e-02420a0001bc", 421 | "92aa237a-4bfd-11e9-a41e-02420a0001bc" 422 | ] 423 | }, 424 | "toc": { 425 | "base_numbering": 1, 426 | "nav_menu": {}, 427 | "number_sections": true, 428 | "sideBar": true, 429 | "skip_h1_title": false, 430 | "title_cell": "Table of Contents", 431 | "title_sidebar": "Contents", 432 | "toc_cell": false, 433 | "toc_position": {}, 434 | "toc_section_display": true, 435 | "toc_window_display": true 436 | } 437 | }, 438 | "nbformat": 4, 439 | "nbformat_minor": 2 440 | } 441 | -------------------------------------------------------------------------------- /roles/deploy-manage-tools/files/common/02_JupyterOperationTips.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "lc_cell_meme": { 7 | "current": "90d94f30-4bfd-11e9-b582-02420a0001bc", 8 | "history": [], 9 | "next": "90d95084-4bfd-11e9-b582-02420a0001bc", 10 | "previous": null 11 | } 12 | }, 13 | "source": [ 14 | "# Jupyterの画面操作Tips\n", 15 | "
" 16 | ] 17 | }, 18 | { 19 | "cell_type": "markdown", 20 | "metadata": { 21 | "lc_cell_meme": { 22 | "current": "90d95084-4bfd-11e9-b582-02420a0001bc", 23 | "history": [], 24 | "next": "90d950fc-4bfd-11e9-b582-02420a0001bc", 25 | "previous": "90d94f30-4bfd-11e9-b582-02420a0001bc" 26 | } 27 | }, 28 | "source": [ 29 | "ここでは、Jupyterの主な画面操作を簡単に説明します。
\n", 30 | "Jupyterの概要については、[こちら](./01_JupyterOverview.ipynb)をご覧下さい。" 31 | ] 32 | }, 33 | { 34 | "cell_type": "markdown", 35 | "metadata": { 36 | "lc_cell_meme": { 37 | "current": "90d950fc-4bfd-11e9-b582-02420a0001bc", 38 | "history": [], 39 | "next": "90d95156-4bfd-11e9-b582-02420a0001bc", 40 | "previous": "90d95084-4bfd-11e9-b582-02420a0001bc" 41 | } 42 | }, 43 | "source": [ 44 | "## 1. ファイル/フォルダの操作" 45 | ] 46 | }, 47 | { 48 | "cell_type": "markdown", 49 | "metadata": { 50 | "lc_cell_meme": { 51 | "current": "90d95156-4bfd-11e9-b582-02420a0001bc", 52 | "history": [], 53 | "next": "90d951a6-4bfd-11e9-b582-02420a0001bc", 54 | "previous": "90d950fc-4bfd-11e9-b582-02420a0001bc" 55 | } 56 | }, 57 | "source": [ 58 | "### notebookを作成する\n", 59 | "---\n", 60 | "1. 利用する Kernel を決めます。Bash、Python2、Python3から選択します。\n", 61 | "2. ダッシュボード画面右上のプルダウンメニュー [New] から選択したKernelをクリックします。「Untitled.ipynb」が表示されます。" 62 | ] 63 | }, 64 | { 65 | "cell_type": "markdown", 66 | "metadata": { 67 | "lc_cell_meme": { 68 | "current": "90d951a6-4bfd-11e9-b582-02420a0001bc", 69 | "history": [], 70 | "next": "90d95200-4bfd-11e9-b582-02420a0001bc", 71 | "previous": "90d95156-4bfd-11e9-b582-02420a0001bc" 72 | } 73 | }, 74 | "source": [ 75 | "### テキストファイルを作成する\n", 76 | "---\n", 77 | "1. Jupyterのダッシュボード画面でFilesタブを表示します。\n", 78 | "2. 画面右上のプルダウンメニュー [New] から [Text File] を選択します。編集画面が表示されます。\n", 79 | "3. ファイルを保存するには、画面上の [Files] メニューから [Save] を選択します。" 80 | ] 81 | }, 82 | { 83 | "cell_type": "markdown", 84 | "metadata": { 85 | "lc_cell_meme": { 86 | "current": "90d95200-4bfd-11e9-b582-02420a0001bc", 87 | "history": [], 88 | "next": "90d9525a-4bfd-11e9-b582-02420a0001bc", 89 | "previous": "90d951a6-4bfd-11e9-b582-02420a0001bc" 90 | } 91 | }, 92 | "source": [ 93 | "### ファイルを保存する\n", 94 | "---\n", 95 | "notebookやその他のファイルを保存します。2つの方法があります。\n", 96 | "* notebook画面上部の [ディスク] アイコン をクリックします。\n", 97 | "* notebook画面上部のメニューから [File][Save and Checkpoint] をクリックします。" 98 | ] 99 | }, 100 | { 101 | "cell_type": "markdown", 102 | "metadata": { 103 | "lc_cell_meme": { 104 | "current": "90d9525a-4bfd-11e9-b582-02420a0001bc", 105 | "history": [], 106 | "next": "90d952aa-4bfd-11e9-b582-02420a0001bc", 107 | "previous": "90d95200-4bfd-11e9-b582-02420a0001bc" 108 | } 109 | }, 110 | "source": [ 111 | "### ファイルをコピーする\n", 112 | "---\n", 113 | "1. Jupyterのダッシュボード画面でFilesタブへ移動します。\n", 114 | "2. コピーするするファイル先頭のチェックボックスをクリックします。\n", 115 | "4. 画面上部の [Duplicate] ボタンをクリックします。確認ダイアログが表示されます。\n", 116 | "5. 確認ダイアログで[Duplicate] ボタンをクリックします。「選択したファイル名-Copy」という名称のファイルが作成されます。\n", 117 | "6. 必要があればnotebookの名前を変更する及びファイル/フォルダの名前を変更するにしたがって、ファイル名を変更して下さい。" 118 | ] 119 | }, 120 | { 121 | "cell_type": "markdown", 122 | "metadata": { 123 | "lc_cell_meme": { 124 | "current": "90d952aa-4bfd-11e9-b582-02420a0001bc", 125 | "history": [], 126 | "next": "90d95304-4bfd-11e9-b582-02420a0001bc", 127 | "previous": "90d9525a-4bfd-11e9-b582-02420a0001bc" 128 | } 129 | }, 130 | "source": [ 131 | "### フォルダを作成する\n", 132 | "---\n", 133 | "1. Jupyterのダッシュボード画面でFilesタブを表示します。\n", 134 | "2. 画面右上のプルダウンメニュー [New] から [Folder] をクリックします。「Untitled Folder」が作成されます。\n", 135 | "3. 「Untitled Folder」先頭のチェックボックスをクリックします。\n", 136 | "4. 画面上部の [Rename] ボタンをクリックします。「Rename directory」ダイアログが表示されます。\n", 137 | "5. 名前に変更して、[Rename] ボタンをクリックします。" 138 | ] 139 | }, 140 | { 141 | "cell_type": "markdown", 142 | "metadata": { 143 | "lc_cell_meme": { 144 | "current": "90d95304-4bfd-11e9-b582-02420a0001bc", 145 | "history": [], 146 | "next": "90d95354-4bfd-11e9-b582-02420a0001bc", 147 | "previous": "90d952aa-4bfd-11e9-b582-02420a0001bc" 148 | } 149 | }, 150 | "source": [ 151 | "### notebookの名前を変更する \n", 152 | "---\n", 153 | "1. 名前を変更するnotebookが表示されている場合は、notebookを保存してブラウザのタブを閉じます。\n", 154 | "2. Jupyterのダッシュボード画面でFilesタブへ移動します。\n", 155 | "3. 名前を変更するnotebooke先頭のチェックボックスをクリックします。\n", 156 | "4. 画面上部の [Shutdown] ボタンをクリックします。Kernelが終了します。\n", 157 | "5. 再度、名前を変更するnotebooke先頭のチェックボックスをクリックします。\n", 158 | "6. 画面上部の [Rename] ボタンをクリックします。「Rename directory」ダイアログが表示されます。\n", 159 | "7. 名前を変更して、[Rename] ボタンをクリックします。" 160 | ] 161 | }, 162 | { 163 | "cell_type": "markdown", 164 | "metadata": { 165 | "lc_cell_meme": { 166 | "current": "90d95354-4bfd-11e9-b582-02420a0001bc", 167 | "history": [], 168 | "next": "90d953ae-4bfd-11e9-b582-02420a0001bc", 169 | "previous": "90d95304-4bfd-11e9-b582-02420a0001bc" 170 | } 171 | }, 172 | "source": [ 173 | "### notebook以外のファイル/フォルダの名前を変更する\n", 174 | "---\n", 175 | "1. Jupyterのダッシュボード画面でFilesタブへ移動します。\n", 176 | "2. 名前を変更するファイル/フォルダ先頭のチェックボックスをクリックします。\n", 177 | "3. 画面上部の[Rename] ボタンをクリックします。「Rename directory」ダイアログが表示されます。\n", 178 | "4. 名前を変更して、[Rename] ボタンをクリックします。" 179 | ] 180 | }, 181 | { 182 | "cell_type": "markdown", 183 | "metadata": { 184 | "lc_cell_meme": { 185 | "current": "90d953ae-4bfd-11e9-b582-02420a0001bc", 186 | "history": [], 187 | "next": "90d953fe-4bfd-11e9-b582-02420a0001bc", 188 | "previous": "90d95354-4bfd-11e9-b582-02420a0001bc" 189 | } 190 | }, 191 | "source": [ 192 | "### notebookを移動する \n", 193 | "---\n", 194 | "notebookを他のフォルダへ移動します。\n", 195 | "1. 名前を変更するnotebookが表示されている場合は、notebookを保存してブラウザのタブを閉じます。\n", 196 | "2. Jupyterのダッシュボード画面でFilesタブへ移動します。\n", 197 | "3. 移動するnotebooke先頭のチェックボックスをクリックします。\n", 198 | "4. 画面上部の [Shutdown] ボタンをクリックします。Kernelが終了します。\n", 199 | "5. 再度、移動するnotebooke先頭のチェックボックスをクリックします。\n", 200 | "6. 画面上部の [Move] をクリックします。「Move」ダイアログが表示されます。\n", 201 | "7. 移動先フォルダを指定して、[Move] ボタンをクリックします。\n", 202 | " + 移動先フォルダを指定しない場合は、ホームディレクトリ直下が移動先になります。" 203 | ] 204 | }, 205 | { 206 | "cell_type": "markdown", 207 | "metadata": { 208 | "lc_cell_meme": { 209 | "current": "90d953fe-4bfd-11e9-b582-02420a0001bc", 210 | "history": [], 211 | "next": "90d95458-4bfd-11e9-b582-02420a0001bc", 212 | "previous": "90d953ae-4bfd-11e9-b582-02420a0001bc" 213 | } 214 | }, 215 | "source": [ 216 | "### notebook以外のファイル/フォルダを移動する \n", 217 | "---\n", 218 | "notebook以外のファイル/フォルダを他のフォルダへ移動します。\n", 219 | "1. Jupyterのダッシュボード画面でFilesタブへ移動します。\n", 220 | "2. 移動するファイル/フォルダ先頭のチェックボックスをクリックします。\n", 221 | "3. 画面上部の[Move] ボタンをクリックします。「Move」ダイアログが表示されます。\n", 222 | "4. 移動先フォルダを指定して、[Move] ボタンをクリックします。\n", 223 | " + 移動先フォルダを指定しない場合は、ホームディレクトリ直下が移動先になります。" 224 | ] 225 | }, 226 | { 227 | "cell_type": "markdown", 228 | "metadata": { 229 | "lc_cell_meme": { 230 | "current": "90d95458-4bfd-11e9-b582-02420a0001bc", 231 | "history": [], 232 | "next": "90d954a8-4bfd-11e9-b582-02420a0001bc", 233 | "previous": "90d953fe-4bfd-11e9-b582-02420a0001bc" 234 | } 235 | }, 236 | "source": [ 237 | "## 2. ファイルのアップロードとダウンロード" 238 | ] 239 | }, 240 | { 241 | "cell_type": "markdown", 242 | "metadata": { 243 | "lc_cell_meme": { 244 | "current": "90d954a8-4bfd-11e9-b582-02420a0001bc", 245 | "history": [], 246 | "next": "90d954f8-4bfd-11e9-b582-02420a0001bc", 247 | "previous": "90d95458-4bfd-11e9-b582-02420a0001bc" 248 | } 249 | }, 250 | "source": [ 251 | "### ファイルをアップロードする\n", 252 | "---\n", 253 | "1. Jupyterのダッシュボード画面でFilesタブを表示します。\n", 254 | "2. 画面右上の[Upload]ボタンをクリックします。ファイル選択ダイアログが表示されます。\n", 255 | "3. ファイル選択ダイアログでアップロードしたいファイルを選択します。(複数選択できます)\n", 256 | "4. [開く]ボタンをクリックします。選択したファイルが一覧に表示されます。\n", 257 | "5. 表示されたファイルの右にある[Upload]ボタンをクリックします。" 258 | ] 259 | }, 260 | { 261 | "cell_type": "markdown", 262 | "metadata": { 263 | "lc_cell_meme": { 264 | "current": "90d954f8-4bfd-11e9-b582-02420a0001bc", 265 | "history": [], 266 | "next": "90d95548-4bfd-11e9-b582-02420a0001bc", 267 | "previous": "90d954a8-4bfd-11e9-b582-02420a0001bc" 268 | } 269 | }, 270 | "source": [ 271 | "### notebookをダウンロードする \n", 272 | "---\n", 273 | "notebookをローカルマシンへダウンロードします。\n", 274 | "1. 名前を変更するnotebookが表示されている場合は、notebookを保存してブラウザのタブを閉じます。\n", 275 | "2. Jupyterのダッシュボード画面でFilesタブへ移動します。\n", 276 | "3. ダウンロードするnotebooke先頭のチェックボックスをクリックします。\n", 277 | "4. 画面上部の [Shutdown] ボタンをクリックします。Kernelが終了します。\n", 278 | "5. 再度、ダウンロードするnotebooke先頭のチェックボックスをクリックします。\n", 279 | "6. 画面上部の [Download] をクリックします。" 280 | ] 281 | }, 282 | { 283 | "cell_type": "markdown", 284 | "metadata": { 285 | "lc_cell_meme": { 286 | "current": "90d95548-4bfd-11e9-b582-02420a0001bc", 287 | "history": [], 288 | "next": "90d95598-4bfd-11e9-b582-02420a0001bc", 289 | "previous": "90d954f8-4bfd-11e9-b582-02420a0001bc" 290 | } 291 | }, 292 | "source": [ 293 | "### notebook以外のファイルをダウンロードする \n", 294 | "---\n", 295 | "notebook以外のファイルを、ローカルマシンへダウンロードします。\n", 296 | "1. Jupyterのダッシュボード画面でFilesタブへ移動します。\n", 297 | "3. ダウンロードするnotebooke先頭のチェックボックスをクリックします。\n", 298 | "2. 画面上部の [Download] をクリックします。" 299 | ] 300 | }, 301 | { 302 | "cell_type": "markdown", 303 | "metadata": { 304 | "lc_cell_meme": { 305 | "current": "90d95598-4bfd-11e9-b582-02420a0001bc", 306 | "history": [], 307 | "next": "90d955f2-4bfd-11e9-b582-02420a0001bc", 308 | "previous": "90d95548-4bfd-11e9-b582-02420a0001bc" 309 | } 310 | }, 311 | "source": [ 312 | "## 3. Notebookの操作" 313 | ] 314 | }, 315 | { 316 | "cell_type": "markdown", 317 | "metadata": { 318 | "lc_cell_meme": { 319 | "current": "90d955f2-4bfd-11e9-b582-02420a0001bc", 320 | "history": [], 321 | "next": "90d95642-4bfd-11e9-b582-02420a0001bc", 322 | "previous": "90d95598-4bfd-11e9-b582-02420a0001bc" 323 | } 324 | }, 325 | "source": [ 326 | "### セルを実行する\n", 327 | "---\n", 328 | "notebookでコードを記述したセルは、その場で実行でき、実行結果はセルの直下に出力されます。
\n", 329 | "セルは次の方法で実行します。\n", 330 | "* ショートカットキーで実行する\n", 331 | " + セルを選択して、キーボードから shift+Enter を入力する。セルを実行して、次のセルが選択されます。\n", 332 | " + セルを選択して、キーボードから ctrl+Enter を入力する。セルを実行して、実行したセルの選択を保持します。\n", 333 | "* notebook画面上のメニュー [Cell] から [Run Cells] を選択する。\n", 334 | " + [Cell] メニューには、全セルを実行する、選択しているセルの後を全部実行する、などの機能が用意されています。" 335 | ] 336 | }, 337 | { 338 | "cell_type": "markdown", 339 | "metadata": { 340 | "lc_cell_meme": { 341 | "current": "90d95642-4bfd-11e9-b582-02420a0001bc", 342 | "history": [], 343 | "next": "90d95692-4bfd-11e9-b582-02420a0001bc", 344 | "previous": "90d955f2-4bfd-11e9-b582-02420a0001bc" 345 | } 346 | }, 347 | "source": [ 348 | "## 4. ターミナルを利用する
\n" 349 | ] 350 | }, 351 | { 352 | "cell_type": "markdown", 353 | "metadata": { 354 | "lc_cell_meme": { 355 | "current": "90d95692-4bfd-11e9-b582-02420a0001bc", 356 | "history": [], 357 | "next": "90d956e2-4bfd-11e9-b582-02420a0001bc", 358 | "previous": "90d95642-4bfd-11e9-b582-02420a0001bc" 359 | } 360 | }, 361 | "source": [ 362 | "### ターミナルを開く\n", 363 | "---\n", 364 | "1. Jupyterのダッシュボード画面でFilesタブを表示します。\n", 365 | "2. 画面右上のプルダウンメニュー [New] から [Terminal] を選択します。ターミナル画面が表示されます。" 366 | ] 367 | }, 368 | { 369 | "cell_type": "markdown", 370 | "metadata": { 371 | "lc_cell_meme": { 372 | "current": "90d956e2-4bfd-11e9-b582-02420a0001bc", 373 | "history": [], 374 | "next": null, 375 | "previous": "90d95692-4bfd-11e9-b582-02420a0001bc" 376 | } 377 | }, 378 | "source": [ 379 | "### ターミナルを閉じる\n", 380 | "---\n", 381 | "1. 閉じるターミナルのURLの最後尾にある番号を記録しておきます。\n", 382 | "2. ターミナルを表示しているWebブラウザ画面(またはタブ)を閉じます。\n", 383 | "2. Jupyterのダッシュボード画面でRunningタブを表示します。\n", 384 | "3. Terminals欄で、記録しておいた番号のターミナルの [Shutdown] ボタンをクリックします。" 385 | ] 386 | } 387 | ], 388 | "metadata": { 389 | "kernelspec": { 390 | "display_name": "Python 3", 391 | "language": "python", 392 | "name": "python3" 393 | }, 394 | "language_info": { 395 | "codemirror_mode": { 396 | "name": "ipython", 397 | "version": 3 398 | }, 399 | "file_extension": ".py", 400 | "mimetype": "text/x-python", 401 | "name": "python", 402 | "nbconvert_exporter": "python", 403 | "pygments_lexer": "ipython3", 404 | "version": "3.6.8" 405 | }, 406 | "lc_notebook_meme": { 407 | "current": "90d94de6-4bfd-11e9-b582-02420a0001bc", 408 | "history": [], 409 | "root_cells": [ 410 | "90d94f30-4bfd-11e9-b582-02420a0001bc", 411 | "90d95084-4bfd-11e9-b582-02420a0001bc", 412 | "90d950fc-4bfd-11e9-b582-02420a0001bc", 413 | "90d95156-4bfd-11e9-b582-02420a0001bc", 414 | "90d951a6-4bfd-11e9-b582-02420a0001bc", 415 | "90d95200-4bfd-11e9-b582-02420a0001bc", 416 | "90d9525a-4bfd-11e9-b582-02420a0001bc", 417 | "90d952aa-4bfd-11e9-b582-02420a0001bc", 418 | "90d95304-4bfd-11e9-b582-02420a0001bc", 419 | "90d95354-4bfd-11e9-b582-02420a0001bc", 420 | "90d953ae-4bfd-11e9-b582-02420a0001bc", 421 | "90d953fe-4bfd-11e9-b582-02420a0001bc", 422 | "90d95458-4bfd-11e9-b582-02420a0001bc", 423 | "90d954a8-4bfd-11e9-b582-02420a0001bc", 424 | "90d954f8-4bfd-11e9-b582-02420a0001bc", 425 | "90d95548-4bfd-11e9-b582-02420a0001bc", 426 | "90d95598-4bfd-11e9-b582-02420a0001bc", 427 | "90d955f2-4bfd-11e9-b582-02420a0001bc", 428 | "90d95642-4bfd-11e9-b582-02420a0001bc", 429 | "90d95692-4bfd-11e9-b582-02420a0001bc", 430 | "90d956e2-4bfd-11e9-b582-02420a0001bc" 431 | ] 432 | }, 433 | "toc": { 434 | "base_numbering": 1, 435 | "nav_menu": {}, 436 | "number_sections": true, 437 | "sideBar": true, 438 | "skip_h1_title": false, 439 | "title_cell": "Table of Contents", 440 | "title_sidebar": "Contents", 441 | "toc_cell": false, 442 | "toc_position": {}, 443 | "toc_section_display": true, 444 | "toc_window_display": false 445 | } 446 | }, 447 | "nbformat": 4, 448 | "nbformat_minor": 1 449 | } 450 | -------------------------------------------------------------------------------- /roles/deploy-manage-tools/files/admin-tools/21_RestoreStudentMaterials.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "lc_cell_meme": { 7 | "current": "94ce7d18-4bfd-11e9-8208-02420a0001bc-2-1a0b-f83e", 8 | "history": [ 9 | { 10 | "current": "94ce7d18-4bfd-11e9-8208-02420a0001bc-1-1a0b", 11 | "next": "94ce7da4-4bfd-11e9-8208-02420a0001bc", 12 | "previous": null 13 | }, 14 | { 15 | "current": "94ce7d18-4bfd-11e9-8208-02420a0001bc-2-1a0b-f83e", 16 | "next": "94ce7da4-4bfd-11e9-8208-02420a0001bc-1-95a8", 17 | "previous": null 18 | } 19 | ], 20 | "next": "94ce7da4-4bfd-11e9-8208-02420a0001bc-2-95a8-155f", 21 | "previous": null 22 | } 23 | }, 24 | "source": [ 25 | "# 受講者の演習環境バックアップをリストアします\n", 26 | "---" 27 | ] 28 | }, 29 | { 30 | "cell_type": "markdown", 31 | "metadata": { 32 | "lc_cell_meme": { 33 | "current": "94ce7da4-4bfd-11e9-8208-02420a0001bc-2-95a8-155f", 34 | "history": [ 35 | { 36 | "current": "94ce7da4-4bfd-11e9-8208-02420a0001bc-1-95a8", 37 | "next": "94ce7dfe-4bfd-11e9-8208-02420a0001bc", 38 | "previous": "94ce7d18-4bfd-11e9-8208-02420a0001bc" 39 | }, 40 | { 41 | "current": "94ce7da4-4bfd-11e9-8208-02420a0001bc-2-95a8-155f", 42 | "next": "94ce7dfe-4bfd-11e9-8208-02420a0001bc-1-3032", 43 | "previous": "94ce7d18-4bfd-11e9-8208-02420a0001bc-1-1a0b" 44 | } 45 | ], 46 | "next": "94ce7dfe-4bfd-11e9-8208-02420a0001bc-2-3032-27e0", 47 | "previous": "94ce7d18-4bfd-11e9-8208-02420a0001bc-2-1a0b-f83e" 48 | } 49 | }, 50 | "source": [ 51 | "バックアップした受講者の演習環境を展開します。" 52 | ] 53 | }, 54 | { 55 | "cell_type": "markdown", 56 | "metadata": { 57 | "lc_cell_meme": { 58 | "current": "94ce7dfe-4bfd-11e9-8208-02420a0001bc-2-3032-27e0", 59 | "history": [ 60 | { 61 | "current": "94ce7dfe-4bfd-11e9-8208-02420a0001bc-1-3032", 62 | "next": "94ce7e58-4bfd-11e9-8208-02420a0001bc", 63 | "previous": "94ce7da4-4bfd-11e9-8208-02420a0001bc" 64 | }, 65 | { 66 | "current": "94ce7dfe-4bfd-11e9-8208-02420a0001bc-2-3032-27e0", 67 | "next": "94ce7e58-4bfd-11e9-8208-02420a0001bc-1-3e0e", 68 | "previous": "94ce7da4-4bfd-11e9-8208-02420a0001bc-1-95a8" 69 | } 70 | ], 71 | "next": "94ce7e58-4bfd-11e9-8208-02420a0001bc-2-3e0e-446b", 72 | "previous": "94ce7da4-4bfd-11e9-8208-02420a0001bc-2-95a8-155f" 73 | } 74 | }, 75 | "source": [ 76 | "# バックアップファイルを指定します" 77 | ] 78 | }, 79 | { 80 | "cell_type": "markdown", 81 | "metadata": { 82 | "lc_cell_meme": { 83 | "current": "94ce7e58-4bfd-11e9-8208-02420a0001bc-2-3e0e-446b", 84 | "history": [ 85 | { 86 | "current": "94ce7e58-4bfd-11e9-8208-02420a0001bc-1-3e0e", 87 | "next": "94ce7ea8-4bfd-11e9-8208-02420a0001bc", 88 | "previous": "94ce7dfe-4bfd-11e9-8208-02420a0001bc" 89 | }, 90 | { 91 | "current": "94ce7e58-4bfd-11e9-8208-02420a0001bc-2-3e0e-446b", 92 | "next": "94ce7ea8-4bfd-11e9-8208-02420a0001bc-1-de4e", 93 | "previous": "94ce7dfe-4bfd-11e9-8208-02420a0001bc-1-3032" 94 | } 95 | ], 96 | "next": "94ce7ea8-4bfd-11e9-8208-02420a0001bc-2-de4e-0a79", 97 | "previous": "94ce7dfe-4bfd-11e9-8208-02420a0001bc-2-3032-27e0" 98 | } 99 | }, 100 | "source": [ 101 | "リストアするバックアップファルを指定します。\n", 102 | "- ホームディレクトリからの相対パスで指定します。\n", 103 | "- フォルダを指定した場合、フォルダ内の全ての `*.tgz` ファイルが対象となります。\n", 104 | "- バックアップファイルがローカルマシンにある場合は、下記の手順でアップロードできます。\n", 105 | " 1. ブラウザのHome画面で、リストア作業用フォルダを開きます。\n", 106 | " 2. 画面右上の[Upload]ボタンをクリックします。ファイル選択ダイアログが開きます。\n", 107 | " 3. ファイルを選択して[開く]ボタンをクリックします。 バックアップファイル名がリストされます。\n", 108 | " 4. バックアップファイル名の行の右端に表示される[Upload]ボタンをクリックします。\n", 109 | "\n", 110 | "**次のセルを実行して、バックアップファイルを設定してください。**" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": null, 116 | "metadata": { 117 | "lc_cell_meme": { 118 | "current": "94ce7ea8-4bfd-11e9-8208-02420a0001bc-2-de4e-0a79", 119 | "history": [ 120 | { 121 | "current": "94ce7ea8-4bfd-11e9-8208-02420a0001bc-1-de4e", 122 | "next": "94ce802e-4bfd-11e9-8208-02420a0001bc", 123 | "previous": "94ce7e58-4bfd-11e9-8208-02420a0001bc" 124 | }, 125 | { 126 | "current": "94ce7ea8-4bfd-11e9-8208-02420a0001bc-2-de4e-0a79", 127 | "next": "a09cf1c8-fe54-11ef-96fa-02420a640255-4-c795-8dcc-7cec-38b8", 128 | "previous": "94ce7e58-4bfd-11e9-8208-02420a0001bc-1-3e0e" 129 | } 130 | ], 131 | "next": "a09cf1c8-fe54-11ef-96fa-02420a640255-5-c795-8dcc-7cec-38b8-1612", 132 | "previous": "94ce7e58-4bfd-11e9-8208-02420a0001bc-2-3e0e-446b" 133 | } 134 | }, 135 | "outputs": [], 136 | "source": [ 137 | "BACKUP_FILE='backup/0123/student-a01@example.com-backup.tgz'" 138 | ] 139 | }, 140 | { 141 | "cell_type": "markdown", 142 | "metadata": { 143 | "lc_cell_meme": { 144 | "current": "a09cf1c8-fe54-11ef-96fa-02420a640255-5-c795-8dcc-7cec-38b8-1612", 145 | "history": [ 146 | { 147 | "current": "a09cf1c8-fe54-11ef-96fa-02420a640255-2-c795-8dcc", 148 | "next": "64cc969c-fd8e-11ef-ac33-02420a64024e-1-3a7b", 149 | "previous": "91ef93c0-4bfd-11e9-ad24-02420a0001bc-1-1627" 150 | }, 151 | { 152 | "current": "a09cf1c8-fe54-11ef-96fa-02420a640255-4-c795-8dcc-7cec-38b8", 153 | "next": "64cc969c-fd8e-11ef-ac33-02420a64024e-3-3a7b-e4d3-8e14", 154 | "previous": "947105ac-4bfd-11e9-8c4f-02420a0001bc-1-da56" 155 | }, 156 | { 157 | "current": "a09cf1c8-fe54-11ef-96fa-02420a640255-5-c795-8dcc-7cec-38b8-1612", 158 | "next": "64cc969c-fd8e-11ef-ac33-02420a64024e-5-3a7b-e4d3-8e14-72a2-4e79", 159 | "previous": "94ce7ea8-4bfd-11e9-8208-02420a0001bc-1-de4e" 160 | } 161 | ], 162 | "next": "64cc969c-fd8e-11ef-ac33-02420a64024e-6-3a7b-e4d3-8e14-72a2-4e79-748d", 163 | "previous": "94ce7ea8-4bfd-11e9-8208-02420a0001bc-2-de4e-0a79" 164 | } 165 | }, 166 | "source": [ 167 | "# コースの指定" 168 | ] 169 | }, 170 | { 171 | "cell_type": "code", 172 | "execution_count": null, 173 | "metadata": { 174 | "lc_cell_meme": { 175 | "current": "64cc969c-fd8e-11ef-ac33-02420a64024e-6-3a7b-e4d3-8e14-72a2-4e79-748d", 176 | "history": [ 177 | { 178 | "current": "64cc969c-fd8e-11ef-ac33-02420a64024e-1-3a7b", 179 | "next": "9193b88e-4bfd-11e9-80f2-02420a0001bc-1-3d06", 180 | "previous": "9193b848-4bfd-11e9-80f2-02420a0001bc-1-0ae7" 181 | }, 182 | { 183 | "current": "64cc969c-fd8e-11ef-ac33-02420a64024e-3-3a7b-e4d3-8e14", 184 | "next": "91ef9410-4bfd-11e9-ad24-02420a0001bc-1-9cb9", 185 | "previous": "a09cf1c8-fe54-11ef-96fa-02420a640255" 186 | }, 187 | { 188 | "current": "64cc969c-fd8e-11ef-ac33-02420a64024e-5-3a7b-e4d3-8e14-72a2-4e79", 189 | "next": "94710606-4bfd-11e9-8c4f-02420a0001bc-1-9c59", 190 | "previous": "a09cf1c8-fe54-11ef-96fa-02420a640255-2-c795-8dcc" 191 | }, 192 | { 193 | "current": "64cc969c-fd8e-11ef-ac33-02420a64024e-6-3a7b-e4d3-8e14-72a2-4e79-748d", 194 | "next": "94ce818c-4bfd-11e9-8208-02420a0001bc-1-6bab", 195 | "previous": "a09cf1c8-fe54-11ef-96fa-02420a640255-4-c795-8dcc-7cec-38b8" 196 | } 197 | ], 198 | "next": "94ce818c-4bfd-11e9-8208-02420a0001bc-2-6bab-907b", 199 | "previous": "a09cf1c8-fe54-11ef-96fa-02420a640255-5-c795-8dcc-7cec-38b8-1612" 200 | } 201 | }, 202 | "outputs": [], 203 | "source": [ 204 | "import os\n", 205 | "\n", 206 | "# コース名の指定\n", 207 | "course_name = os.environ['CWH_COURSE_NAME']\n", 208 | "course_name" 209 | ] 210 | }, 211 | { 212 | "cell_type": "markdown", 213 | "metadata": { 214 | "lc_cell_meme": { 215 | "current": "94ce818c-4bfd-11e9-8208-02420a0001bc-2-6bab-907b", 216 | "history": [ 217 | { 218 | "current": "94ce818c-4bfd-11e9-8208-02420a0001bc-1-6bab", 219 | "next": "94ce81f0-4bfd-11e9-8208-02420a0001bc", 220 | "previous": "94ce802e-4bfd-11e9-8208-02420a0001bc" 221 | }, 222 | { 223 | "current": "94ce818c-4bfd-11e9-8208-02420a0001bc-2-6bab-907b", 224 | "next": "94ce81f0-4bfd-11e9-8208-02420a0001bc-1-5f0e", 225 | "previous": "64cc969c-fd8e-11ef-ac33-02420a64024e-5-3a7b-e4d3-8e14-72a2-4e79" 226 | } 227 | ], 228 | "next": "94ce81f0-4bfd-11e9-8208-02420a0001bc-2-5f0e-0197", 229 | "previous": "64cc969c-fd8e-11ef-ac33-02420a64024e-6-3a7b-e4d3-8e14-72a2-4e79-748d" 230 | } 231 | }, 232 | "source": [ 233 | "# バックアップを展開します" 234 | ] 235 | }, 236 | { 237 | "cell_type": "markdown", 238 | "metadata": { 239 | "lc_cell_meme": { 240 | "current": "94ce81f0-4bfd-11e9-8208-02420a0001bc-2-5f0e-0197", 241 | "history": [ 242 | { 243 | "current": "94ce81f0-4bfd-11e9-8208-02420a0001bc-1-5f0e", 244 | "next": "94ce82e0-4bfd-11e9-8208-02420a0001bc", 245 | "previous": "94ce818c-4bfd-11e9-8208-02420a0001bc" 246 | }, 247 | { 248 | "current": "94ce81f0-4bfd-11e9-8208-02420a0001bc-2-5f0e-0197", 249 | "next": "94ce82e0-4bfd-11e9-8208-02420a0001bc-1-21c2", 250 | "previous": "94ce818c-4bfd-11e9-8208-02420a0001bc-1-6bab" 251 | } 252 | ], 253 | "next": "94ce82e0-4bfd-11e9-8208-02420a0001bc-2-21c2-d609", 254 | "previous": "94ce818c-4bfd-11e9-8208-02420a0001bc-2-6bab-907b" 255 | } 256 | }, 257 | "source": [ 258 | "- バックアップはファイル名に含まれる名前の受講者のフォルダに展開されます。\n", 259 | "- 同一のファイルは上書きされます。" 260 | ] 261 | }, 262 | { 263 | "cell_type": "code", 264 | "execution_count": null, 265 | "metadata": { 266 | "lc_cell_meme": { 267 | "current": "94ce82e0-4bfd-11e9-8208-02420a0001bc-2-21c2-d609", 268 | "history": [ 269 | { 270 | "current": "94ce82e0-4bfd-11e9-8208-02420a0001bc-1-21c2", 271 | "next": null, 272 | "previous": "94ce81f0-4bfd-11e9-8208-02420a0001bc" 273 | }, 274 | { 275 | "current": "94ce82e0-4bfd-11e9-8208-02420a0001bc-2-21c2-d609", 276 | "next": null, 277 | "previous": "94ce81f0-4bfd-11e9-8208-02420a0001bc-1-5f0e" 278 | } 279 | ], 280 | "next": null, 281 | "previous": "94ce81f0-4bfd-11e9-8208-02420a0001bc-2-5f0e-0197" 282 | } 283 | }, 284 | "outputs": [], 285 | "source": [ 286 | "import os, sys, re, hashlib, string, tempfile, shutil, subprocess\n", 287 | "\n", 288 | "assert course_name != '', \"コース用のサーバー上で実行するか、コース名を指定してください\"\n", 289 | "\n", 290 | "def get_username_from_mail_address(mail_address):\n", 291 | " # Convert to lower and remove characters except for alphabets and digits\n", 292 | " wk = mail_address.split('@')\n", 293 | " local_part = wk[0].lower()\n", 294 | " result = re.sub(r'[^a-zA-Z0-9]', '', local_part)\n", 295 | " # Add top 6bytes of hash string\n", 296 | " md5 = hashlib.md5()\n", 297 | " md5.update(mail_address.encode('us-ascii'))\n", 298 | " h = md5.hexdigest()[0:6]\n", 299 | " result += 'x'\n", 300 | " result += h;\n", 301 | " return result;\n", 302 | "\n", 303 | "try:\n", 304 | " BACKUP_FILE\n", 305 | "except NameError:\n", 306 | " BACKUP_FILE=None\n", 307 | "\n", 308 | "if BACKUP_FILE is None:\n", 309 | " print('BACKUP_FILE にバックアップファイルを指定してください', file=sys.stderr)\n", 310 | " SRC_PATH=None\n", 311 | "elif os.path.isabs(BACKUP_FILE):\n", 312 | " SRC_PATH=os.path.realpath(BACKUP_FILE)\n", 313 | "else:\n", 314 | " SRC_PATH=os.path.realpath(os.path.join(os.getenv('HOME'), course_name, BACKUP_FILE))\n", 315 | "\n", 316 | "backup_files=set()\n", 317 | "if SRC_PATH is None:\n", 318 | " print('バックアップファイルがありません', file=sys.stderr)\n", 319 | "elif os.path.isdir(SRC_PATH):\n", 320 | " for (root, dirs, files) in os.walk(SRC_PATH):\n", 321 | " for file in files:\n", 322 | " path = os.path.join(root, file)\n", 323 | " if path.endswith('.tgz') or path.endswith('.tar.gz'):\n", 324 | " backup_files.add(os.path.realpath(path))\n", 325 | "elif os.path.exists(SRC_PATH):\n", 326 | " print('mode SINGLE FILE')\n", 327 | " backup_files.add(os.path.realpath(SRC_PATH))\n", 328 | "else:\n", 329 | " print('{}: バックアップファイルが見つかりません'.format(BACKUP_FILE), file=sys.stderr)\n", 330 | "\n", 331 | "#\n", 332 | "with tempfile.TemporaryDirectory() as tmp_dir:\n", 333 | " for tgzfile in backup_files:\n", 334 | " basename = os.path.basename(tgzfile)\n", 335 | " m = re.compile(r'^(.+)-backup\\.(tgz|tar\\.gz)$').match(basename)\n", 336 | " user_mail = m.group(1) if (m is not None) else None\n", 337 | " if (user_mail is None) or (len(user_mail) < 1):\n", 338 | " print('WARNING: 受講者名が不明のファイル: {}'.format(tgzfile))\n", 339 | " continue\n", 340 | " print('受講者[{}]のバックアップを展開します'.format(user_mail))\n", 341 | " user_name = get_username_from_mail_address(user_mail)\n", 342 | " user_dir = os.path.join('/home/jupyter/workspace', user_name, course_name)\n", 343 | " user_dir_info = os.stat(user_dir)\n", 344 | " user_uid = user_dir_info.st_uid\n", 345 | " user_gid = user_dir_info.st_gid\n", 346 | " user_tmp_dir = '{}/{}'.format(tmp_dir, user_name)\n", 347 | " os.makedirs(user_tmp_dir, exist_ok=True)\n", 348 | " try:\n", 349 | " tarcmd = 'tar -xz -C \"{}\" -f \"{}\"'.format(user_tmp_dir, tgzfile)\n", 350 | " cp = subprocess.run(tarcmd, shell=True, cwd=user_tmp_dir, stderr=subprocess.PIPE)\n", 351 | " for line in cp.stderr.splitlines():\n", 352 | " print('tar> {}'.format(line.strip().decode('utf-8')), file=sys.stderr)\n", 353 | " if cp.returncode != 0:\n", 354 | " print('ERROR: tar コマンドが失敗しました', file=sys.stderr)\n", 355 | " continue\n", 356 | " except OSError as e:\n", 357 | " print('ERROR: tar コマンドが実行できません:{}'.format(e), file=sys.stderr)\n", 358 | " continue\n", 359 | " try:\n", 360 | " cmd = 'cd {}'.format(tmp_dir) \\\n", 361 | " + ' && sudo -n -s mkdir -p \"{}\"'.format(user_dir) \\\n", 362 | " + ' && sudo -n -s rsync -vhi -rLkKEtW \"{}/\" \"{}/\"'.format(user_tmp_dir, user_dir) \\\n", 363 | " + ' && sudo -n -s chown -R {}:{} \"{}/\"'.format(user_uid, user_gid, user_dir) \\\n", 364 | " + ' && sudo -n -s find \"{}/\" -name \".*\" -prune'.format(user_dir) \\\n", 365 | " + ' -o -type d -execdir chmod 0755 \"{}\" \"+\"' \\\n", 366 | " + ' && sudo -n -s find \"{}/\" -name \".*\" -prune'.format(user_dir) \\\n", 367 | " + ' -o -type f -execdir chmod 0644 \"{}\" \"+\"' \\\n", 368 | " + ' && true'\n", 369 | " cp = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n", 370 | " for line in cp.stdout.splitlines():\n", 371 | " print('rsync> {}'.format(line.strip().decode('utf-8')))\n", 372 | " for line in cp.stderr.splitlines():\n", 373 | " print('rsync> {}'.format(line.strip().decode('utf-8')), file=sys.stderr)\n", 374 | " if cp.returncode == 0:\n", 375 | " print('-> 完了')\n", 376 | " else:\n", 377 | " print('ERROR: rsync コマンドが失敗しました', file=sys.stderr)\n", 378 | " continue\n", 379 | " except OSError as e:\n", 380 | " print(type(e))\n", 381 | " print('ERROR: rsync コマンドが実行できません:{}'.format(e), file=sys.stderr)\n", 382 | " continue" 383 | ] 384 | } 385 | ], 386 | "metadata": { 387 | "kernelspec": { 388 | "display_name": "Python 3", 389 | "language": "python", 390 | "name": "python3" 391 | }, 392 | "language_info": { 393 | "file_extension": ".py", 394 | "mimetype": "text/x-python", 395 | "name": "python", 396 | "nbconvert_exporter": "python", 397 | "pygments_lexer": "ipython3", 398 | "version": "3.10.11" 399 | }, 400 | "lc_notebook_meme": { 401 | "current": "94ce7bb0-4bfd-11e9-8208-02420a0001bc", 402 | "history": [], 403 | "root_cells": [ 404 | "94ce7d18-4bfd-11e9-8208-02420a0001bc", 405 | "94ce7da4-4bfd-11e9-8208-02420a0001bc", 406 | "94ce7dfe-4bfd-11e9-8208-02420a0001bc", 407 | "94ce7e58-4bfd-11e9-8208-02420a0001bc", 408 | "94ce7ea8-4bfd-11e9-8208-02420a0001bc", 409 | "94ce802e-4bfd-11e9-8208-02420a0001bc", 410 | "94ce818c-4bfd-11e9-8208-02420a0001bc", 411 | "94ce81f0-4bfd-11e9-8208-02420a0001bc", 412 | "94ce82e0-4bfd-11e9-8208-02420a0001bc" 413 | ] 414 | }, 415 | "toc": { 416 | "base_numbering": 1, 417 | "nav_menu": {}, 418 | "number_sections": true, 419 | "sideBar": true, 420 | "skip_h1_title": false, 421 | "title_cell": "Table of Contents", 422 | "title_sidebar": "Contents", 423 | "toc_cell": false, 424 | "toc_position": {}, 425 | "toc_section_display": true, 426 | "toc_window_display": false 427 | } 428 | }, 429 | "nbformat": 4, 430 | "nbformat_minor": 2 431 | } 432 | -------------------------------------------------------------------------------- /roles/deploy-manage-tools/files/admin-tools/83_AddUsersToGroup.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "lc_cell_meme": { 7 | "current": "f60d962a-7d8a-11eb-aa43-02420a01004f-1-e5e0", 8 | "history": [ 9 | { 10 | "current": "f60d962a-7d8a-11eb-aa43-02420a01004f-1-e5e0", 11 | "next": "f60d981e-7d8a-11eb-aa43-02420a01004f", 12 | "previous": null 13 | } 14 | ], 15 | "next": "f60d981e-7d8a-11eb-aa43-02420a01004f-1-33e1", 16 | "previous": null 17 | } 18 | }, 19 | "source": [ 20 | "# ユーザーをグループに追加します\n", 21 | "\n", 22 | "ユーザーをグループに追加します。JupyterHub上にユーザーが作成済みである必要があります。\n", 23 | "\n", 24 | "所属グループに応じたリソース制限設定に使用します。" 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "metadata": { 30 | "lc_cell_meme": { 31 | "current": "f60d981e-7d8a-11eb-aa43-02420a01004f-1-33e1", 32 | "history": [ 33 | { 34 | "current": "f60d981e-7d8a-11eb-aa43-02420a01004f-1-33e1", 35 | "next": "f60d999a-7d8a-11eb-aa43-02420a01004f", 36 | "previous": "f60d962a-7d8a-11eb-aa43-02420a01004f" 37 | } 38 | ], 39 | "next": "f60d999a-7d8a-11eb-aa43-02420a01004f-1-0379", 40 | "previous": "f60d962a-7d8a-11eb-aa43-02420a01004f-1-e5e0" 41 | } 42 | }, 43 | "source": [ 44 | "# グループの定義" 45 | ] 46 | }, 47 | { 48 | "cell_type": "markdown", 49 | "metadata": { 50 | "lc_cell_meme": { 51 | "current": "f60d999a-7d8a-11eb-aa43-02420a01004f-1-0379", 52 | "history": [ 53 | { 54 | "current": "f60d999a-7d8a-11eb-aa43-02420a01004f-1-0379", 55 | "next": "f60d9b20-7d8a-11eb-aa43-02420a01004f", 56 | "previous": "f60d981e-7d8a-11eb-aa43-02420a01004f" 57 | } 58 | ], 59 | "next": "f60d9b20-7d8a-11eb-aa43-02420a01004f-1-6321", 60 | "previous": "f60d981e-7d8a-11eb-aa43-02420a01004f-1-33e1" 61 | } 62 | }, 63 | "source": [ 64 | "グループ名" 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": null, 70 | "metadata": { 71 | "lc_cell_meme": { 72 | "current": "f60d9b20-7d8a-11eb-aa43-02420a01004f-1-6321", 73 | "history": [ 74 | { 75 | "current": "f60d9b20-7d8a-11eb-aa43-02420a01004f-1-6321", 76 | "next": "f60d9c7e-7d8a-11eb-aa43-02420a01004f", 77 | "previous": "f60d999a-7d8a-11eb-aa43-02420a01004f" 78 | } 79 | ], 80 | "next": "f60d9c7e-7d8a-11eb-aa43-02420a01004f-1-03ad", 81 | "previous": "f60d999a-7d8a-11eb-aa43-02420a01004f-1-0379" 82 | } 83 | }, 84 | "outputs": [], 85 | "source": [ 86 | "group_name = 'group1'\n", 87 | "group_name" 88 | ] 89 | }, 90 | { 91 | "cell_type": "markdown", 92 | "metadata": { 93 | "lc_cell_meme": { 94 | "current": "f60d9c7e-7d8a-11eb-aa43-02420a01004f-1-03ad", 95 | "history": [ 96 | { 97 | "current": "f60d9c7e-7d8a-11eb-aa43-02420a01004f-1-03ad", 98 | "next": "f60d9dd2-7d8a-11eb-aa43-02420a01004f", 99 | "previous": "f60d9b20-7d8a-11eb-aa43-02420a01004f" 100 | } 101 | ], 102 | "next": "f60d9dd2-7d8a-11eb-aa43-02420a01004f-1-8e9a", 103 | "previous": "f60d9b20-7d8a-11eb-aa43-02420a01004f-1-6321" 104 | } 105 | }, 106 | "source": [ 107 | "このグループに所属させるユーザーのメールアドレス" 108 | ] 109 | }, 110 | { 111 | "cell_type": "code", 112 | "execution_count": null, 113 | "metadata": { 114 | "lc_cell_meme": { 115 | "current": "f60d9dd2-7d8a-11eb-aa43-02420a01004f-1-8e9a", 116 | "history": [ 117 | { 118 | "current": "f60d9dd2-7d8a-11eb-aa43-02420a01004f-1-8e9a", 119 | "next": "f60d9f26-7d8a-11eb-aa43-02420a01004f", 120 | "previous": "f60d9c7e-7d8a-11eb-aa43-02420a01004f" 121 | } 122 | ], 123 | "next": "f60d9f26-7d8a-11eb-aa43-02420a01004f-1-8bce", 124 | "previous": "f60d9c7e-7d8a-11eb-aa43-02420a01004f-1-03ad" 125 | } 126 | }, 127 | "outputs": [], 128 | "source": [ 129 | "user_email_list = '''\n", 130 | "student-a01@example.com\n", 131 | "student-a02@example.com\n", 132 | "student-a03@example.com\n", 133 | "'''" 134 | ] 135 | }, 136 | { 137 | "cell_type": "code", 138 | "execution_count": null, 139 | "metadata": { 140 | "lc_cell_meme": { 141 | "current": "f60d9f26-7d8a-11eb-aa43-02420a01004f-1-8bce", 142 | "history": [ 143 | { 144 | "current": "f60d9f26-7d8a-11eb-aa43-02420a01004f-1-8bce", 145 | "next": "f60da08e-7d8a-11eb-aa43-02420a01004f", 146 | "previous": "f60d9dd2-7d8a-11eb-aa43-02420a01004f" 147 | } 148 | ], 149 | "next": "f60da08e-7d8a-11eb-aa43-02420a01004f-1-14b8", 150 | "previous": "f60d9dd2-7d8a-11eb-aa43-02420a01004f-1-8e9a" 151 | } 152 | }, 153 | "outputs": [], 154 | "source": [ 155 | "import re\n", 156 | "user_emails = user_email_list.splitlines()\n", 157 | "user_emails = [x.strip() for x in user_emails \n", 158 | " if re.sub(r'#.*$', '', x).strip()]\n", 159 | "user_emails" 160 | ] 161 | }, 162 | { 163 | "cell_type": "code", 164 | "execution_count": null, 165 | "metadata": { 166 | "lc_cell_meme": { 167 | "current": "f60da08e-7d8a-11eb-aa43-02420a01004f-1-14b8", 168 | "history": [ 169 | { 170 | "current": "f60da08e-7d8a-11eb-aa43-02420a01004f-1-14b8", 171 | "next": "f60da304-7d8a-11eb-aa43-02420a01004f", 172 | "previous": "f60d9f26-7d8a-11eb-aa43-02420a01004f" 173 | } 174 | ], 175 | "next": "f60da304-7d8a-11eb-aa43-02420a01004f-1-15d3", 176 | "previous": "f60d9f26-7d8a-11eb-aa43-02420a01004f-1-8bce" 177 | } 178 | }, 179 | "outputs": [], 180 | "source": [ 181 | "import hashlib\n", 182 | "\n", 183 | "def get_username_from_mail_address(mail_address):\n", 184 | " # Convert to lower and remove characters except for alphabets and digits\n", 185 | " wk = mail_address.split('@')\n", 186 | " local_part = wk[0].lower()\n", 187 | " result = re.sub(r'[^a-zA-Z0-9]', '', local_part)\n", 188 | " # Add top 6bytes of hash string\n", 189 | " md5 = hashlib.md5()\n", 190 | " md5.update(mail_address.encode('us-ascii'))\n", 191 | " h = md5.hexdigest()[0:6]\n", 192 | " result += 'x'\n", 193 | " result += h;\n", 194 | " return result;\n", 195 | "\n", 196 | "user_names = [get_username_from_mail_address(x) for x in user_emails]\n", 197 | "user_names" 198 | ] 199 | }, 200 | { 201 | "cell_type": "markdown", 202 | "metadata": { 203 | "lc_cell_meme": { 204 | "current": "f60da304-7d8a-11eb-aa43-02420a01004f-1-15d3", 205 | "history": [ 206 | { 207 | "current": "f60da304-7d8a-11eb-aa43-02420a01004f-1-15d3", 208 | "next": "f60da48a-7d8a-11eb-aa43-02420a01004f", 209 | "previous": "f60da08e-7d8a-11eb-aa43-02420a01004f" 210 | } 211 | ], 212 | "next": "feba8ca8-d0a0-11ee-a40c-02420a640143-4-b18e-b902-b7fc-4c94", 213 | "previous": "f60da08e-7d8a-11eb-aa43-02420a01004f-1-14b8" 214 | } 215 | }, 216 | "source": [ 217 | "# グループの設定" 218 | ] 219 | }, 220 | { 221 | "cell_type": "markdown", 222 | "metadata": { 223 | "lc_cell_meme": { 224 | "current": "feba8ca8-d0a0-11ee-a40c-02420a640143-4-b18e-b902-b7fc-4c94", 225 | "history": [ 226 | { 227 | "current": "feba8ca8-d0a0-11ee-a40c-02420a640143-2-b18e-b902", 228 | "next": "feba9248-d0a0-11ee-a40c-02420a640143", 229 | "previous": "952ac744-4bfd-11e9-845a-02420a0001bc-1-4ad7" 230 | }, 231 | { 232 | "current": "feba8ca8-d0a0-11ee-a40c-02420a640143-4-b18e-b902-b7fc-4c94", 233 | "next": "feba9248-d0a0-11ee-a40c-02420a640143-2-36f9-b12d", 234 | "previous": "952ac744-4bfd-11e9-845a-02420a0001bc-1-65df" 235 | } 236 | ], 237 | "next": "feba9248-d0a0-11ee-a40c-02420a640143-4-36f9-b12d-d36c-9a8a", 238 | "previous": "f60da304-7d8a-11eb-aa43-02420a01004f-1-15d3" 239 | } 240 | }, 241 | "source": [ 242 | "[API Tokens](/hub/token)のページで、tokenを作成して以下に入力してください。" 243 | ] 244 | }, 245 | { 246 | "cell_type": "code", 247 | "execution_count": null, 248 | "metadata": { 249 | "lc_cell_meme": { 250 | "current": "feba9248-d0a0-11ee-a40c-02420a640143-4-36f9-b12d-d36c-9a8a", 251 | "history": [ 252 | { 253 | "current": "feba9248-d0a0-11ee-a40c-02420a640143-2-36f9-b12d", 254 | "next": "952ac794-4bfd-11e9-845a-02420a0001bc-1-21a4", 255 | "previous": "feba8ca8-d0a0-11ee-a40c-02420a640143" 256 | }, 257 | { 258 | "current": "feba9248-d0a0-11ee-a40c-02420a640143-4-36f9-b12d-d36c-9a8a", 259 | "next": "952ac794-4bfd-11e9-845a-02420a0001bc-1-2b6f", 260 | "previous": "feba8ca8-d0a0-11ee-a40c-02420a640143-2-b18e-b902" 261 | } 262 | ], 263 | "next": "f60da48a-7d8a-11eb-aa43-02420a01004f-1-5b4c", 264 | "previous": "feba8ca8-d0a0-11ee-a40c-02420a640143-4-b18e-b902-b7fc-4c94" 265 | } 266 | }, 267 | "outputs": [], 268 | "source": [ 269 | "import getpass\n", 270 | "apitoken = getpass.getpass('JupyterHub API token')" 271 | ] 272 | }, 273 | { 274 | "cell_type": "code", 275 | "execution_count": null, 276 | "metadata": { 277 | "lc_cell_meme": { 278 | "current": "f60da48a-7d8a-11eb-aa43-02420a01004f-1-5b4c", 279 | "history": [ 280 | { 281 | "current": "f60da48a-7d8a-11eb-aa43-02420a01004f-1-5b4c", 282 | "next": "f60da5de-7d8a-11eb-aa43-02420a01004f", 283 | "previous": "f60da304-7d8a-11eb-aa43-02420a01004f" 284 | } 285 | ], 286 | "next": "f60da5de-7d8a-11eb-aa43-02420a01004f-1-b5b9", 287 | "previous": "feba9248-d0a0-11ee-a40c-02420a640143-4-36f9-b12d-d36c-9a8a" 288 | } 289 | }, 290 | "outputs": [], 291 | "source": [ 292 | "import os\n", 293 | "api_url = os.environ['JUPYTERHUB_API_URL']" 294 | ] 295 | }, 296 | { 297 | "cell_type": "markdown", 298 | "metadata": { 299 | "lc_cell_meme": { 300 | "current": "f60da5de-7d8a-11eb-aa43-02420a01004f-1-b5b9", 301 | "history": [ 302 | { 303 | "current": "f60da5de-7d8a-11eb-aa43-02420a01004f-1-b5b9", 304 | "next": "f60da732-7d8a-11eb-aa43-02420a01004f", 305 | "previous": "f60da48a-7d8a-11eb-aa43-02420a01004f" 306 | } 307 | ], 308 | "next": "f60da732-7d8a-11eb-aa43-02420a01004f-1-2c82", 309 | "previous": "f60da48a-7d8a-11eb-aa43-02420a01004f-1-5b4c" 310 | } 311 | }, 312 | "source": [ 313 | "グループの作成(必要な場合)" 314 | ] 315 | }, 316 | { 317 | "cell_type": "code", 318 | "execution_count": null, 319 | "metadata": { 320 | "lc_cell_meme": { 321 | "current": "f60da732-7d8a-11eb-aa43-02420a01004f-1-2c82", 322 | "history": [ 323 | { 324 | "current": "f60da732-7d8a-11eb-aa43-02420a01004f-1-2c82", 325 | "next": "f60da87c-7d8a-11eb-aa43-02420a01004f", 326 | "previous": "f60da5de-7d8a-11eb-aa43-02420a01004f" 327 | } 328 | ], 329 | "next": "f60da87c-7d8a-11eb-aa43-02420a01004f-1-055c", 330 | "previous": "f60da5de-7d8a-11eb-aa43-02420a01004f-1-b5b9" 331 | } 332 | }, 333 | "outputs": [], 334 | "source": [ 335 | "headers = {\n", 336 | " 'Authorization': 'token %s' % apitoken,\n", 337 | "}" 338 | ] 339 | }, 340 | { 341 | "cell_type": "code", 342 | "execution_count": null, 343 | "metadata": { 344 | "lc_cell_meme": { 345 | "current": "f60da87c-7d8a-11eb-aa43-02420a01004f-1-055c", 346 | "history": [ 347 | { 348 | "current": "f60da87c-7d8a-11eb-aa43-02420a01004f-1-055c", 349 | "next": "f60daa02-7d8a-11eb-aa43-02420a01004f", 350 | "previous": "f60da732-7d8a-11eb-aa43-02420a01004f" 351 | } 352 | ], 353 | "next": "f60daa02-7d8a-11eb-aa43-02420a01004f-1-f8f8", 354 | "previous": "f60da732-7d8a-11eb-aa43-02420a01004f-1-2c82" 355 | } 356 | }, 357 | "outputs": [], 358 | "source": [ 359 | "import requests\n", 360 | "import json\n", 361 | "\n", 362 | "r = requests.get(api_url + '/groups/{}'.format(group_name),\n", 363 | " headers=headers)\n", 364 | "if r.status_code == 404:\n", 365 | " r = requests.post(api_url + '/groups/{}'.format(group_name),\n", 366 | " headers=headers)\n", 367 | " group = json.loads(r.text)\n", 368 | "else:\n", 369 | " group = json.loads(r.text)\n", 370 | "\n", 371 | "group" 372 | ] 373 | }, 374 | { 375 | "cell_type": "code", 376 | "execution_count": null, 377 | "metadata": { 378 | "lc_cell_meme": { 379 | "current": "f60daa02-7d8a-11eb-aa43-02420a01004f-1-f8f8", 380 | "history": [ 381 | { 382 | "current": "f60daa02-7d8a-11eb-aa43-02420a01004f-1-f8f8", 383 | "next": "f60dab60-7d8a-11eb-aa43-02420a01004f", 384 | "previous": "f60da87c-7d8a-11eb-aa43-02420a01004f" 385 | } 386 | ], 387 | "next": "f60dab60-7d8a-11eb-aa43-02420a01004f-1-e4ae", 388 | "previous": "f60da87c-7d8a-11eb-aa43-02420a01004f-1-055c" 389 | } 390 | }, 391 | "outputs": [], 392 | "source": [ 393 | "import json\n", 394 | "\n", 395 | "r = requests.get(api_url + '/groups/{}'.format(group_name),\n", 396 | " headers=headers)\n", 397 | "group = json.loads(r.text)\n", 398 | "current_users = group['users']\n", 399 | "\n", 400 | "user2mail = dict(zip(user_names, user_emails))\n", 401 | "\n", 402 | "new_users = set(user_names) - set(current_users)\n", 403 | "\n", 404 | "if new_users:\n", 405 | " print(\"Add the following users to group '{}'\".format(group_name))\n", 406 | " for username in new_users:\n", 407 | " print('{}({})'.format(user2mail[username], username))\n", 408 | " h = headers.copy()\n", 409 | " h['Content-Type'] : 'application/json'\n", 410 | " r = requests.post(api_url + '/groups/{}/users'.format(group_name),\n", 411 | " data = json.dumps({\n", 412 | " \"users\" : list(new_users)\n", 413 | " }),\n", 414 | " headers=h)\n", 415 | " assert r.status_code == 200\n", 416 | "member_users = set(user_names) - set(new_users)\n", 417 | "if member_users:\n", 418 | " print(\"The fowllowing users are already member of group '{}'\".format(group_name))\n", 419 | " for username in member_users:\n", 420 | " print('{}({})'.format(user2mail[username], username))\n" 421 | ] 422 | }, 423 | { 424 | "cell_type": "markdown", 425 | "metadata": { 426 | "lc_cell_meme": { 427 | "current": "f60dab60-7d8a-11eb-aa43-02420a01004f-1-e4ae", 428 | "history": [ 429 | { 430 | "current": "f60dab60-7d8a-11eb-aa43-02420a01004f-1-e4ae", 431 | "next": "f60dacd2-7d8a-11eb-aa43-02420a01004f", 432 | "previous": "f60daa02-7d8a-11eb-aa43-02420a01004f" 433 | } 434 | ], 435 | "next": "f60dacd2-7d8a-11eb-aa43-02420a01004f-1-d169", 436 | "previous": "f60daa02-7d8a-11eb-aa43-02420a01004f-1-f8f8" 437 | } 438 | }, 439 | "source": [ 440 | "確認" 441 | ] 442 | }, 443 | { 444 | "cell_type": "code", 445 | "execution_count": null, 446 | "metadata": { 447 | "lc_cell_meme": { 448 | "current": "f60dacd2-7d8a-11eb-aa43-02420a01004f-1-d169", 449 | "history": [ 450 | { 451 | "current": "f60dacd2-7d8a-11eb-aa43-02420a01004f-1-d169", 452 | "next": null, 453 | "previous": "f60dab60-7d8a-11eb-aa43-02420a01004f" 454 | } 455 | ], 456 | "next": null, 457 | "previous": "f60dab60-7d8a-11eb-aa43-02420a01004f-1-e4ae" 458 | } 459 | }, 460 | "outputs": [], 461 | "source": [ 462 | "r = requests.get(api_url + '/groups/{}'.format(group_name),\n", 463 | " headers=headers)\n", 464 | "group = json.loads(r.text)\n", 465 | "group" 466 | ] 467 | } 468 | ], 469 | "metadata": { 470 | "kernelspec": { 471 | "display_name": "Python 3", 472 | "language": "python", 473 | "name": "python3" 474 | }, 475 | "language_info": { 476 | "file_extension": ".py", 477 | "mimetype": "text/x-python", 478 | "name": "python", 479 | "nbconvert_exporter": "python", 480 | "pygments_lexer": "ipython3", 481 | "version": "3.10.11" 482 | }, 483 | "lc_notebook_meme": { 484 | "current": "f60d9116-7d8a-11eb-aa43-02420a01004f", 485 | "history": [], 486 | "root_cells": [ 487 | "f60d962a-7d8a-11eb-aa43-02420a01004f", 488 | "f60d981e-7d8a-11eb-aa43-02420a01004f", 489 | "f60d999a-7d8a-11eb-aa43-02420a01004f", 490 | "f60d9b20-7d8a-11eb-aa43-02420a01004f", 491 | "f60d9c7e-7d8a-11eb-aa43-02420a01004f", 492 | "f60d9dd2-7d8a-11eb-aa43-02420a01004f", 493 | "f60d9f26-7d8a-11eb-aa43-02420a01004f", 494 | "f60da08e-7d8a-11eb-aa43-02420a01004f", 495 | "f60da304-7d8a-11eb-aa43-02420a01004f", 496 | "f60da48a-7d8a-11eb-aa43-02420a01004f", 497 | "f60da5de-7d8a-11eb-aa43-02420a01004f", 498 | "f60da732-7d8a-11eb-aa43-02420a01004f", 499 | "f60da87c-7d8a-11eb-aa43-02420a01004f", 500 | "f60daa02-7d8a-11eb-aa43-02420a01004f", 501 | "f60dab60-7d8a-11eb-aa43-02420a01004f", 502 | "f60dacd2-7d8a-11eb-aa43-02420a01004f" 503 | ] 504 | }, 505 | "toc": { 506 | "base_numbering": 1, 507 | "nav_menu": {}, 508 | "number_sections": true, 509 | "sideBar": true, 510 | "skip_h1_title": false, 511 | "title_cell": "Table of Contents", 512 | "title_sidebar": "Contents", 513 | "toc_cell": false, 514 | "toc_position": {}, 515 | "toc_section_display": true, 516 | "toc_window_display": true 517 | } 518 | }, 519 | "nbformat": 4, 520 | "nbformat_minor": 4 521 | } 522 | -------------------------------------------------------------------------------- /roles/deploy-manage-tools/files/admin-tools/84_RemoveUsersFromGroup.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "lc_cell_meme": { 7 | "current": "f6474014-7d8a-11eb-bdf7-02420a01004f-1-1b82", 8 | "history": [ 9 | { 10 | "current": "f6474014-7d8a-11eb-bdf7-02420a01004f-1-1b82", 11 | "next": "f64741ea-7d8a-11eb-bdf7-02420a01004f", 12 | "previous": null 13 | } 14 | ], 15 | "next": "f64741ea-7d8a-11eb-bdf7-02420a01004f-1-17f9", 16 | "previous": null 17 | } 18 | }, 19 | "source": [ 20 | "# ユーザーグループを設定します\n", 21 | "\n", 22 | "ユーザーのグループを設定します。\n", 23 | "\n", 24 | "所属グループに応じたリソース制限設定に使用します。" 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "metadata": { 30 | "lc_cell_meme": { 31 | "current": "f64741ea-7d8a-11eb-bdf7-02420a01004f-1-17f9", 32 | "history": [ 33 | { 34 | "current": "f64741ea-7d8a-11eb-bdf7-02420a01004f-1-17f9", 35 | "next": "f6474348-7d8a-11eb-bdf7-02420a01004f", 36 | "previous": "f6474014-7d8a-11eb-bdf7-02420a01004f" 37 | } 38 | ], 39 | "next": "f6474348-7d8a-11eb-bdf7-02420a01004f-1-96ac", 40 | "previous": "f6474014-7d8a-11eb-bdf7-02420a01004f-1-1b82" 41 | } 42 | }, 43 | "source": [ 44 | "# グループの定義" 45 | ] 46 | }, 47 | { 48 | "cell_type": "markdown", 49 | "metadata": { 50 | "lc_cell_meme": { 51 | "current": "f6474348-7d8a-11eb-bdf7-02420a01004f-1-96ac", 52 | "history": [ 53 | { 54 | "current": "f6474348-7d8a-11eb-bdf7-02420a01004f-1-96ac", 55 | "next": "f6474488-7d8a-11eb-bdf7-02420a01004f", 56 | "previous": "f64741ea-7d8a-11eb-bdf7-02420a01004f" 57 | } 58 | ], 59 | "next": "f6474488-7d8a-11eb-bdf7-02420a01004f-1-cd5a", 60 | "previous": "f64741ea-7d8a-11eb-bdf7-02420a01004f-1-17f9" 61 | } 62 | }, 63 | "source": [ 64 | "グループ名" 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": null, 70 | "metadata": { 71 | "lc_cell_meme": { 72 | "current": "f6474488-7d8a-11eb-bdf7-02420a01004f-1-cd5a", 73 | "history": [ 74 | { 75 | "current": "f6474488-7d8a-11eb-bdf7-02420a01004f-1-cd5a", 76 | "next": "f64745b4-7d8a-11eb-bdf7-02420a01004f", 77 | "previous": "f6474348-7d8a-11eb-bdf7-02420a01004f" 78 | } 79 | ], 80 | "next": "f64745b4-7d8a-11eb-bdf7-02420a01004f-1-eedb", 81 | "previous": "f6474348-7d8a-11eb-bdf7-02420a01004f-1-96ac" 82 | } 83 | }, 84 | "outputs": [], 85 | "source": [ 86 | "group_name = 'group1'\n", 87 | "group_name" 88 | ] 89 | }, 90 | { 91 | "cell_type": "markdown", 92 | "metadata": { 93 | "lc_cell_meme": { 94 | "current": "f64745b4-7d8a-11eb-bdf7-02420a01004f-1-eedb", 95 | "history": [ 96 | { 97 | "current": "f64745b4-7d8a-11eb-bdf7-02420a01004f-1-eedb", 98 | "next": "f64746ea-7d8a-11eb-bdf7-02420a01004f", 99 | "previous": "f6474488-7d8a-11eb-bdf7-02420a01004f" 100 | } 101 | ], 102 | "next": "f64746ea-7d8a-11eb-bdf7-02420a01004f-1-1444", 103 | "previous": "f6474488-7d8a-11eb-bdf7-02420a01004f-1-cd5a" 104 | } 105 | }, 106 | "source": [ 107 | "このグループから削除するユーザーのメールアドレス" 108 | ] 109 | }, 110 | { 111 | "cell_type": "code", 112 | "execution_count": null, 113 | "metadata": { 114 | "lc_cell_meme": { 115 | "current": "f64746ea-7d8a-11eb-bdf7-02420a01004f-1-1444", 116 | "history": [ 117 | { 118 | "current": "f64746ea-7d8a-11eb-bdf7-02420a01004f-1-1444", 119 | "next": "f6474816-7d8a-11eb-bdf7-02420a01004f", 120 | "previous": "f64745b4-7d8a-11eb-bdf7-02420a01004f" 121 | } 122 | ], 123 | "next": "f6474816-7d8a-11eb-bdf7-02420a01004f-1-c575", 124 | "previous": "f64745b4-7d8a-11eb-bdf7-02420a01004f-1-eedb" 125 | } 126 | }, 127 | "outputs": [], 128 | "source": [ 129 | "user_email_list = '''\n", 130 | "student-a01@example.com\n", 131 | "student-a02@example.com\n", 132 | "student-a03@example.com\n", 133 | "'''" 134 | ] 135 | }, 136 | { 137 | "cell_type": "code", 138 | "execution_count": null, 139 | "metadata": { 140 | "lc_cell_meme": { 141 | "current": "f6474816-7d8a-11eb-bdf7-02420a01004f-1-c575", 142 | "history": [ 143 | { 144 | "current": "f6474816-7d8a-11eb-bdf7-02420a01004f-1-c575", 145 | "next": "f6474942-7d8a-11eb-bdf7-02420a01004f", 146 | "previous": "f64746ea-7d8a-11eb-bdf7-02420a01004f" 147 | } 148 | ], 149 | "next": "f6474942-7d8a-11eb-bdf7-02420a01004f-1-ea7f", 150 | "previous": "f64746ea-7d8a-11eb-bdf7-02420a01004f-1-1444" 151 | } 152 | }, 153 | "outputs": [], 154 | "source": [ 155 | "import re\n", 156 | "user_emails = user_email_list.splitlines()\n", 157 | "user_emails = [x.strip() for x in user_emails \n", 158 | " if re.sub(r'#.*$', '', x).strip()]\n", 159 | "user_emails" 160 | ] 161 | }, 162 | { 163 | "cell_type": "code", 164 | "execution_count": null, 165 | "metadata": { 166 | "lc_cell_meme": { 167 | "current": "f6474942-7d8a-11eb-bdf7-02420a01004f-1-ea7f", 168 | "history": [ 169 | { 170 | "current": "f6474942-7d8a-11eb-bdf7-02420a01004f-1-ea7f", 171 | "next": "f6474a64-7d8a-11eb-bdf7-02420a01004f", 172 | "previous": "f6474816-7d8a-11eb-bdf7-02420a01004f" 173 | } 174 | ], 175 | "next": "f6474a64-7d8a-11eb-bdf7-02420a01004f-1-cf49", 176 | "previous": "f6474816-7d8a-11eb-bdf7-02420a01004f-1-c575" 177 | } 178 | }, 179 | "outputs": [], 180 | "source": [ 181 | "import hashlib\n", 182 | "\n", 183 | "def get_username_from_mail_address(mail_address):\n", 184 | " # Convert to lower and remove characters except for alphabets and digits\n", 185 | " wk = mail_address.split('@')\n", 186 | " local_part = wk[0].lower()\n", 187 | " result = re.sub(r'[^a-zA-Z0-9]', '', local_part)\n", 188 | " # Add top 6bytes of hash string\n", 189 | " md5 = hashlib.md5()\n", 190 | " md5.update(mail_address.encode('us-ascii'))\n", 191 | " h = md5.hexdigest()[0:6]\n", 192 | " result += 'x'\n", 193 | " result += h;\n", 194 | " return result;\n", 195 | "\n", 196 | "user_names = [get_username_from_mail_address(x) for x in user_emails]\n", 197 | "user_names" 198 | ] 199 | }, 200 | { 201 | "cell_type": "markdown", 202 | "metadata": { 203 | "lc_cell_meme": { 204 | "current": "f6474a64-7d8a-11eb-bdf7-02420a01004f-1-cf49", 205 | "history": [ 206 | { 207 | "current": "f6474a64-7d8a-11eb-bdf7-02420a01004f-1-cf49", 208 | "next": "f6474b90-7d8a-11eb-bdf7-02420a01004f", 209 | "previous": "f6474942-7d8a-11eb-bdf7-02420a01004f" 210 | } 211 | ], 212 | "next": "feba8ca8-d0a0-11ee-a40c-02420a640143-4-b18e-b902-dd0f-135b", 213 | "previous": "f6474942-7d8a-11eb-bdf7-02420a01004f-1-ea7f" 214 | } 215 | }, 216 | "source": [ 217 | "# グループの設定" 218 | ] 219 | }, 220 | { 221 | "cell_type": "markdown", 222 | "metadata": { 223 | "lc_cell_meme": { 224 | "current": "feba8ca8-d0a0-11ee-a40c-02420a640143-4-b18e-b902-dd0f-135b", 225 | "history": [ 226 | { 227 | "current": "feba8ca8-d0a0-11ee-a40c-02420a640143-2-b18e-b902", 228 | "next": "feba9248-d0a0-11ee-a40c-02420a640143", 229 | "previous": "952ac744-4bfd-11e9-845a-02420a0001bc-1-4ad7" 230 | }, 231 | { 232 | "current": "feba8ca8-d0a0-11ee-a40c-02420a640143-4-b18e-b902-dd0f-135b", 233 | "next": "feba9248-d0a0-11ee-a40c-02420a640143-2-36f9-b12d", 234 | "previous": "952ac744-4bfd-11e9-845a-02420a0001bc-1-65df" 235 | } 236 | ], 237 | "next": "feba9248-d0a0-11ee-a40c-02420a640143-4-36f9-b12d-7522-edfa", 238 | "previous": "f6474a64-7d8a-11eb-bdf7-02420a01004f-1-cf49" 239 | } 240 | }, 241 | "source": [ 242 | "[API Tokens](/hub/token)のページで、tokenを作成して以下に入力してください。" 243 | ] 244 | }, 245 | { 246 | "cell_type": "code", 247 | "execution_count": null, 248 | "metadata": { 249 | "lc_cell_meme": { 250 | "current": "feba9248-d0a0-11ee-a40c-02420a640143-4-36f9-b12d-7522-edfa", 251 | "history": [ 252 | { 253 | "current": "feba9248-d0a0-11ee-a40c-02420a640143-2-36f9-b12d", 254 | "next": "952ac794-4bfd-11e9-845a-02420a0001bc-1-21a4", 255 | "previous": "feba8ca8-d0a0-11ee-a40c-02420a640143" 256 | }, 257 | { 258 | "current": "feba9248-d0a0-11ee-a40c-02420a640143-4-36f9-b12d-7522-edfa", 259 | "next": "952ac794-4bfd-11e9-845a-02420a0001bc-1-2b6f", 260 | "previous": "feba8ca8-d0a0-11ee-a40c-02420a640143-2-b18e-b902" 261 | } 262 | ], 263 | "next": "f6474b90-7d8a-11eb-bdf7-02420a01004f-1-1e52", 264 | "previous": "feba8ca8-d0a0-11ee-a40c-02420a640143-4-b18e-b902-dd0f-135b" 265 | } 266 | }, 267 | "outputs": [], 268 | "source": [ 269 | "import getpass\n", 270 | "apitoken = getpass.getpass('JupyterHub API token')" 271 | ] 272 | }, 273 | { 274 | "cell_type": "code", 275 | "execution_count": null, 276 | "metadata": { 277 | "lc_cell_meme": { 278 | "current": "f6474b90-7d8a-11eb-bdf7-02420a01004f-1-1e52", 279 | "history": [ 280 | { 281 | "current": "f6474b90-7d8a-11eb-bdf7-02420a01004f-1-1e52", 282 | "next": "f6474cb2-7d8a-11eb-bdf7-02420a01004f", 283 | "previous": "f6474a64-7d8a-11eb-bdf7-02420a01004f" 284 | } 285 | ], 286 | "next": "f6474cb2-7d8a-11eb-bdf7-02420a01004f-1-6757", 287 | "previous": "feba9248-d0a0-11ee-a40c-02420a640143-4-36f9-b12d-7522-edfa" 288 | } 289 | }, 290 | "outputs": [], 291 | "source": [ 292 | "import os\n", 293 | "api_url = os.environ['JUPYTERHUB_API_URL']" 294 | ] 295 | }, 296 | { 297 | "cell_type": "markdown", 298 | "metadata": { 299 | "lc_cell_meme": { 300 | "current": "f6474cb2-7d8a-11eb-bdf7-02420a01004f-1-6757", 301 | "history": [ 302 | { 303 | "current": "f6474cb2-7d8a-11eb-bdf7-02420a01004f-1-6757", 304 | "next": "f6474dde-7d8a-11eb-bdf7-02420a01004f", 305 | "previous": "f6474b90-7d8a-11eb-bdf7-02420a01004f" 306 | } 307 | ], 308 | "next": "f6474dde-7d8a-11eb-bdf7-02420a01004f-1-6e90", 309 | "previous": "f6474b90-7d8a-11eb-bdf7-02420a01004f-1-1e52" 310 | } 311 | }, 312 | "source": [ 313 | "グループの存在確認" 314 | ] 315 | }, 316 | { 317 | "cell_type": "code", 318 | "execution_count": null, 319 | "metadata": { 320 | "lc_cell_meme": { 321 | "current": "f6474dde-7d8a-11eb-bdf7-02420a01004f-1-6e90", 322 | "history": [ 323 | { 324 | "current": "f6474dde-7d8a-11eb-bdf7-02420a01004f-1-6e90", 325 | "next": "f6474ffa-7d8a-11eb-bdf7-02420a01004f", 326 | "previous": "f6474cb2-7d8a-11eb-bdf7-02420a01004f" 327 | } 328 | ], 329 | "next": "f6474ffa-7d8a-11eb-bdf7-02420a01004f-1-25f7", 330 | "previous": "f6474cb2-7d8a-11eb-bdf7-02420a01004f-1-6757" 331 | } 332 | }, 333 | "outputs": [], 334 | "source": [ 335 | "headers = {\n", 336 | " 'Authorization': 'token %s' % apitoken,\n", 337 | "}" 338 | ] 339 | }, 340 | { 341 | "cell_type": "code", 342 | "execution_count": null, 343 | "metadata": { 344 | "lc_cell_meme": { 345 | "current": "f6474ffa-7d8a-11eb-bdf7-02420a01004f-1-25f7", 346 | "history": [ 347 | { 348 | "current": "f6474ffa-7d8a-11eb-bdf7-02420a01004f-1-25f7", 349 | "next": "f647516c-7d8a-11eb-bdf7-02420a01004f", 350 | "previous": "f6474dde-7d8a-11eb-bdf7-02420a01004f" 351 | } 352 | ], 353 | "next": "f647516c-7d8a-11eb-bdf7-02420a01004f-1-03f5", 354 | "previous": "f6474dde-7d8a-11eb-bdf7-02420a01004f-1-6e90" 355 | } 356 | }, 357 | "outputs": [], 358 | "source": [ 359 | "import requests\n", 360 | "import json\n", 361 | "\n", 362 | "r = requests.get(api_url + '/groups/{}'.format(group_name),\n", 363 | " headers=headers)\n", 364 | "assert r.status_code == 200\n", 365 | "\n", 366 | "group = json.loads(r.text)\n", 367 | "group" 368 | ] 369 | }, 370 | { 371 | "cell_type": "code", 372 | "execution_count": null, 373 | "metadata": { 374 | "lc_cell_meme": { 375 | "current": "f647516c-7d8a-11eb-bdf7-02420a01004f-1-03f5", 376 | "history": [ 377 | { 378 | "current": "f647516c-7d8a-11eb-bdf7-02420a01004f-1-03f5", 379 | "next": "f64752a2-7d8a-11eb-bdf7-02420a01004f", 380 | "previous": "f6474ffa-7d8a-11eb-bdf7-02420a01004f" 381 | } 382 | ], 383 | "next": "f64752a2-7d8a-11eb-bdf7-02420a01004f-1-2c2e", 384 | "previous": "f6474ffa-7d8a-11eb-bdf7-02420a01004f-1-25f7" 385 | } 386 | }, 387 | "outputs": [], 388 | "source": [ 389 | "import json\n", 390 | "\n", 391 | "r = requests.get(api_url + '/groups/{}'.format(group_name),\n", 392 | " headers=headers)\n", 393 | "group = json.loads(r.text)\n", 394 | "current_users = group['users']\n", 395 | "\n", 396 | "user2mail = dict(zip(user_names, user_emails))\n", 397 | "\n", 398 | "nonmember_users = set(user_names) - set(current_users)\n", 399 | "remove_users = set(user_names) - set(nonmember_users)\n", 400 | "\n", 401 | "if remove_users:\n", 402 | " print(\"Remove the following users from group '{}'\".format(group_name))\n", 403 | " for username in remove_users:\n", 404 | " print('{}({})'.format(user2mail[username], username))\n", 405 | " h = headers.copy()\n", 406 | " h['Content-Type'] : 'application/json'\n", 407 | " r = requests.delete(api_url + '/groups/{}/users'.format(group_name),\n", 408 | " data = json.dumps({\n", 409 | " \"users\" : list(remove_users)\n", 410 | " }),\n", 411 | " headers=h)\n", 412 | " assert r.status_code == 200\n", 413 | "\n", 414 | "nonmember_users = set(user_names) - set(remove_users)\n", 415 | "if nonmember_users:\n", 416 | " print(\"The fowllowing users are not member of group '{}'\".format(group_name))\n", 417 | " for username in nonmember_users:\n", 418 | " print('{}({})'.format(user2mail[username], username))\n" 419 | ] 420 | }, 421 | { 422 | "cell_type": "markdown", 423 | "metadata": { 424 | "lc_cell_meme": { 425 | "current": "f64752a2-7d8a-11eb-bdf7-02420a01004f-1-2c2e", 426 | "history": [ 427 | { 428 | "current": "f64752a2-7d8a-11eb-bdf7-02420a01004f-1-2c2e", 429 | "next": "f64753ce-7d8a-11eb-bdf7-02420a01004f", 430 | "previous": "f647516c-7d8a-11eb-bdf7-02420a01004f" 431 | } 432 | ], 433 | "next": "f64753ce-7d8a-11eb-bdf7-02420a01004f-1-6d7b", 434 | "previous": "f647516c-7d8a-11eb-bdf7-02420a01004f-1-03f5" 435 | } 436 | }, 437 | "source": [ 438 | "確認" 439 | ] 440 | }, 441 | { 442 | "cell_type": "code", 443 | "execution_count": null, 444 | "metadata": { 445 | "lc_cell_meme": { 446 | "current": "f64753ce-7d8a-11eb-bdf7-02420a01004f-1-6d7b", 447 | "history": [ 448 | { 449 | "current": "f64753ce-7d8a-11eb-bdf7-02420a01004f-1-6d7b", 450 | "next": null, 451 | "previous": "f64752a2-7d8a-11eb-bdf7-02420a01004f" 452 | } 453 | ], 454 | "next": null, 455 | "previous": "f64752a2-7d8a-11eb-bdf7-02420a01004f-1-2c2e" 456 | } 457 | }, 458 | "outputs": [], 459 | "source": [ 460 | "r = requests.get(api_url + '/groups/{}'.format(group_name),\n", 461 | " headers=headers)\n", 462 | "group = json.loads(r.text)\n", 463 | "group" 464 | ] 465 | } 466 | ], 467 | "metadata": { 468 | "kernelspec": { 469 | "display_name": "Python 3", 470 | "language": "python", 471 | "name": "python3" 472 | }, 473 | "language_info": { 474 | "file_extension": ".py", 475 | "mimetype": "text/x-python", 476 | "name": "python", 477 | "nbconvert_exporter": "python", 478 | "pygments_lexer": "ipython3", 479 | "version": "3.10.11" 480 | }, 481 | "lc_notebook_meme": { 482 | "current": "f6473b46-7d8a-11eb-bdf7-02420a01004f", 483 | "history": [], 484 | "root_cells": [ 485 | "f6474014-7d8a-11eb-bdf7-02420a01004f", 486 | "f64741ea-7d8a-11eb-bdf7-02420a01004f", 487 | "f6474348-7d8a-11eb-bdf7-02420a01004f", 488 | "f6474488-7d8a-11eb-bdf7-02420a01004f", 489 | "f64745b4-7d8a-11eb-bdf7-02420a01004f", 490 | "f64746ea-7d8a-11eb-bdf7-02420a01004f", 491 | "f6474816-7d8a-11eb-bdf7-02420a01004f", 492 | "f6474942-7d8a-11eb-bdf7-02420a01004f", 493 | "f6474a64-7d8a-11eb-bdf7-02420a01004f", 494 | "f6474b90-7d8a-11eb-bdf7-02420a01004f", 495 | "f6474cb2-7d8a-11eb-bdf7-02420a01004f", 496 | "f6474dde-7d8a-11eb-bdf7-02420a01004f", 497 | "f6474ffa-7d8a-11eb-bdf7-02420a01004f", 498 | "f647516c-7d8a-11eb-bdf7-02420a01004f", 499 | "f64752a2-7d8a-11eb-bdf7-02420a01004f", 500 | "f64753ce-7d8a-11eb-bdf7-02420a01004f" 501 | ] 502 | }, 503 | "toc": { 504 | "base_numbering": 1, 505 | "nav_menu": {}, 506 | "number_sections": true, 507 | "sideBar": true, 508 | "skip_h1_title": false, 509 | "title_cell": "Table of Contents", 510 | "title_sidebar": "Contents", 511 | "toc_cell": false, 512 | "toc_position": { 513 | "height": "calc(100% - 180px)", 514 | "left": "10px", 515 | "top": "150px", 516 | "width": "350.391px" 517 | }, 518 | "toc_section_display": true, 519 | "toc_window_display": true 520 | } 521 | }, 522 | "nbformat": 4, 523 | "nbformat_minor": 4 524 | } 525 | -------------------------------------------------------------------------------- /roles/deploy-manage-tools/files/admin-tools/12_BackupMaterials.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "lc_cell_meme": { 7 | "current": "924bfaac-4bfd-11e9-bee0-02420a0001bc-1-c008", 8 | "history": [ 9 | { 10 | "current": "924bfaac-4bfd-11e9-bee0-02420a0001bc-1-c008", 11 | "next": "924bfb2e-4bfd-11e9-bee0-02420a0001bc", 12 | "previous": null 13 | } 14 | ], 15 | "next": "924bfb2e-4bfd-11e9-bee0-02420a0001bc-1-2261", 16 | "previous": null 17 | } 18 | }, 19 | "source": [ 20 | "# 作成した教材をバックアップします\n", 21 | "
" 22 | ] 23 | }, 24 | { 25 | "cell_type": "markdown", 26 | "metadata": { 27 | "lc_cell_meme": { 28 | "current": "924bfb2e-4bfd-11e9-bee0-02420a0001bc-1-2261", 29 | "history": [ 30 | { 31 | "current": "924bfb2e-4bfd-11e9-bee0-02420a0001bc-1-2261", 32 | "next": "924bfb92-4bfd-11e9-bee0-02420a0001bc", 33 | "previous": "924bfaac-4bfd-11e9-bee0-02420a0001bc" 34 | } 35 | ], 36 | "next": "924bfb92-4bfd-11e9-bee0-02420a0001bc-1-e4d9", 37 | "previous": "924bfaac-4bfd-11e9-bee0-02420a0001bc-1-c008" 38 | } 39 | }, 40 | "source": [ 41 | "ホームディレクトリで作成した教材をバックアップします。" 42 | ] 43 | }, 44 | { 45 | "cell_type": "markdown", 46 | "metadata": { 47 | "lc_cell_meme": { 48 | "current": "924bfb92-4bfd-11e9-bee0-02420a0001bc-1-e4d9", 49 | "history": [ 50 | { 51 | "current": "924bfb92-4bfd-11e9-bee0-02420a0001bc-1-e4d9", 52 | "next": "924bfbe2-4bfd-11e9-bee0-02420a0001bc", 53 | "previous": "924bfb2e-4bfd-11e9-bee0-02420a0001bc" 54 | } 55 | ], 56 | "next": "924bfbe2-4bfd-11e9-bee0-02420a0001bc-1-c7c6", 57 | "previous": "924bfb2e-4bfd-11e9-bee0-02420a0001bc-1-2261" 58 | } 59 | }, 60 | "source": [ 61 | "# バックアップの準備" 62 | ] 63 | }, 64 | { 65 | "cell_type": "markdown", 66 | "metadata": { 67 | "lc_cell_meme": { 68 | "current": "924bfbe2-4bfd-11e9-bee0-02420a0001bc-1-c7c6", 69 | "history": [ 70 | { 71 | "current": "924bfbe2-4bfd-11e9-bee0-02420a0001bc-1-c7c6", 72 | "next": "924bfc3c-4bfd-11e9-bee0-02420a0001bc", 73 | "previous": "924bfb92-4bfd-11e9-bee0-02420a0001bc" 74 | } 75 | ], 76 | "next": "924bfc3c-4bfd-11e9-bee0-02420a0001bc-1-c0b2", 77 | "previous": "924bfb92-4bfd-11e9-bee0-02420a0001bc-1-e4d9" 78 | } 79 | }, 80 | "source": [ 81 | "このNotebookを実行すると、ホームディレクトリ直下の下記のフォルダをバックアップファイルに保存します。\n", 82 | "\n", 83 | "**バックアップしたいファイル/フォルダは、下記のフォルダに移動してください。**\n", 84 | "\n", 85 | "* `textbook`\n", 86 | " + 教材Notebookおよび教材Notebookから呼び出すスクリプトなど\n", 87 | "* `info`\n", 88 | " + 受講者が参照する参考資料など\n", 89 | "* `draft`\n", 90 | " + 教材以外で保存して置きたいNotebook、その他ファイル\n", 91 | "\n", 92 | "注) バックアップファイルには `test` フォルダも保存されます。\n", 93 | "* `test` フォルダは、この教材の自動テストに必要なファイルを保存するフォルダです。
(初期状態で、テスト手順Notebookのテンプレートが配置されています)\n", 94 | "* **`test` フォルダにはその他のファイルを格納しないで下さい。**" 95 | ] 96 | }, 97 | { 98 | "cell_type": "markdown", 99 | "metadata": { 100 | "lc_cell_meme": { 101 | "current": "924bfc3c-4bfd-11e9-bee0-02420a0001bc-1-c0b2", 102 | "history": [ 103 | { 104 | "current": "924bfc3c-4bfd-11e9-bee0-02420a0001bc-1-c0b2", 105 | "next": "924bfc8c-4bfd-11e9-bee0-02420a0001bc", 106 | "previous": "924bfbe2-4bfd-11e9-bee0-02420a0001bc" 107 | } 108 | ], 109 | "next": "924bfc8c-4bfd-11e9-bee0-02420a0001bc-1-a411", 110 | "previous": "924bfbe2-4bfd-11e9-bee0-02420a0001bc-1-c7c6" 111 | } 112 | }, 113 | "source": [ 114 | "# その他にバックアップしたいファイル/フォルダがある場合" 115 | ] 116 | }, 117 | { 118 | "cell_type": "markdown", 119 | "metadata": { 120 | "lc_cell_meme": { 121 | "current": "924bfc8c-4bfd-11e9-bee0-02420a0001bc-1-a411", 122 | "history": [ 123 | { 124 | "current": "924bfc8c-4bfd-11e9-bee0-02420a0001bc-1-a411", 125 | "next": "924bfcd2-4bfd-11e9-bee0-02420a0001bc", 126 | "previous": "924bfc3c-4bfd-11e9-bee0-02420a0001bc" 127 | } 128 | ], 129 | "next": "924bfcd2-4bfd-11e9-bee0-02420a0001bc-1-b50d", 130 | "previous": "924bfc3c-4bfd-11e9-bee0-02420a0001bc-1-c0b2" 131 | } 132 | }, 133 | "source": [ 134 | "もし、`textbook`、`info`、`draft` 以外に保存したいファイルまたはフォルダがある場合は、`INCLUDES` にスペース区切りで列挙して下さい。\n", 135 | "* `textbook`、`info`、`draft`、`test` フォルダは必ずバックアップに保存されます。\n", 136 | "* 管理用Notebookフォルダ `tools` はバックアップに保存されません。\n", 137 | "* ホームディレクトリからの相対パスで指定します。\n", 138 | "```\n", 139 | "%env INCLUDES=ext-textbook ext-data Sample.ipynb\n", 140 | "```\n", 141 | "\n", 142 | "**次のセルでバックアップに含めたいファイル/フォルダを指定して、セルを実行して下さい。**" 143 | ] 144 | }, 145 | { 146 | "cell_type": "code", 147 | "execution_count": null, 148 | "metadata": { 149 | "deletable": false, 150 | "editable": false, 151 | "lc_cell_meme": { 152 | "current": "924bfcd2-4bfd-11e9-bee0-02420a0001bc-1-b50d", 153 | "history": [ 154 | { 155 | "current": "924bfcd2-4bfd-11e9-bee0-02420a0001bc-1-b50d", 156 | "next": "924bfd22-4bfd-11e9-bee0-02420a0001bc", 157 | "previous": "924bfc8c-4bfd-11e9-bee0-02420a0001bc" 158 | } 159 | ], 160 | "next": "924bfd22-4bfd-11e9-bee0-02420a0001bc-1-7c53", 161 | "previous": "924bfc8c-4bfd-11e9-bee0-02420a0001bc-1-a411" 162 | }, 163 | "run_through_control": { 164 | "frozen": false 165 | } 166 | }, 167 | "outputs": [], 168 | "source": [ 169 | "%env INCLUDES=" 170 | ] 171 | }, 172 | { 173 | "cell_type": "markdown", 174 | "metadata": { 175 | "lc_cell_meme": { 176 | "current": "924bfd22-4bfd-11e9-bee0-02420a0001bc-1-7c53", 177 | "history": [ 178 | { 179 | "current": "924bfd22-4bfd-11e9-bee0-02420a0001bc-1-7c53", 180 | "next": "924bfd72-4bfd-11e9-bee0-02420a0001bc", 181 | "previous": "924bfcd2-4bfd-11e9-bee0-02420a0001bc" 182 | } 183 | ], 184 | "next": "924bfd72-4bfd-11e9-bee0-02420a0001bc-1-c324", 185 | "previous": "924bfcd2-4bfd-11e9-bee0-02420a0001bc-1-b50d" 186 | } 187 | }, 188 | "source": [ 189 | "# バックアップに含めないファイル/フォルダを指定します" 190 | ] 191 | }, 192 | { 193 | "cell_type": "markdown", 194 | "metadata": { 195 | "lc_cell_meme": { 196 | "current": "924bfd72-4bfd-11e9-bee0-02420a0001bc-1-c324", 197 | "history": [ 198 | { 199 | "current": "924bfd72-4bfd-11e9-bee0-02420a0001bc-1-c324", 200 | "next": "924bfdc2-4bfd-11e9-bee0-02420a0001bc", 201 | "previous": "924bfd22-4bfd-11e9-bee0-02420a0001bc" 202 | } 203 | ], 204 | "next": "924bfdc2-4bfd-11e9-bee0-02420a0001bc-1-1b9b", 205 | "previous": "924bfd22-4bfd-11e9-bee0-02420a0001bc-1-7c53" 206 | } 207 | }, 208 | "source": [ 209 | "バックアップファイルに保存しないファイルまたはフォルダがある場合は、EXCLUDES にスペース区切りで列挙して下さい。\n", 210 | "* 管理用Notebookフォルダ「admin_tools」はバックアップファイルに保存されません\n", 211 | "```\n", 212 | "EXCLUDES=\".ipynb_checkpoints\"\n", 213 | "```\n", 214 | "\n", 215 | "**次のセルで除外するファイル/フォルダを指定して、セルを実行して下さい。**" 216 | ] 217 | }, 218 | { 219 | "cell_type": "code", 220 | "execution_count": null, 221 | "metadata": { 222 | "deletable": false, 223 | "editable": false, 224 | "lc_cell_meme": { 225 | "current": "924bfdc2-4bfd-11e9-bee0-02420a0001bc-1-1b9b", 226 | "history": [ 227 | { 228 | "current": "924bfdc2-4bfd-11e9-bee0-02420a0001bc-1-1b9b", 229 | "next": "924bfe08-4bfd-11e9-bee0-02420a0001bc", 230 | "previous": "924bfd72-4bfd-11e9-bee0-02420a0001bc" 231 | } 232 | ], 233 | "next": "a09cf1c8-fe54-11ef-96fa-02420a640255-4-c795-8dcc-a674-acfd", 234 | "previous": "924bfd72-4bfd-11e9-bee0-02420a0001bc-1-c324" 235 | }, 236 | "run_through_control": { 237 | "frozen": false 238 | } 239 | }, 240 | "outputs": [], 241 | "source": [ 242 | "%env EXCLUDES=.ipynb_checkpoints .log" 243 | ] 244 | }, 245 | { 246 | "cell_type": "markdown", 247 | "metadata": { 248 | "lc_cell_meme": { 249 | "current": "a09cf1c8-fe54-11ef-96fa-02420a640255-4-c795-8dcc-a674-acfd", 250 | "history": [ 251 | { 252 | "current": "a09cf1c8-fe54-11ef-96fa-02420a640255-2-c795-8dcc", 253 | "next": "64cc969c-fd8e-11ef-ac33-02420a64024e-1-3a7b", 254 | "previous": "91ef93c0-4bfd-11e9-ad24-02420a0001bc-1-1627" 255 | }, 256 | { 257 | "current": "a09cf1c8-fe54-11ef-96fa-02420a640255-4-c795-8dcc-a674-acfd", 258 | "next": "64cc969c-fd8e-11ef-ac33-02420a64024e-3-3a7b-e4d3-8e14", 259 | "previous": "947105ac-4bfd-11e9-8c4f-02420a0001bc-1-da56" 260 | } 261 | ], 262 | "next": "64cc969c-fd8e-11ef-ac33-02420a64024e-5-3a7b-e4d3-8e14-9084-80c1", 263 | "previous": "924bfdc2-4bfd-11e9-bee0-02420a0001bc-1-1b9b" 264 | } 265 | }, 266 | "source": [ 267 | "# コースの指定" 268 | ] 269 | }, 270 | { 271 | "cell_type": "code", 272 | "execution_count": null, 273 | "metadata": { 274 | "deletable": false, 275 | "editable": false, 276 | "lc_cell_meme": { 277 | "current": "64cc969c-fd8e-11ef-ac33-02420a64024e-5-3a7b-e4d3-8e14-9084-80c1", 278 | "history": [ 279 | { 280 | "current": "64cc969c-fd8e-11ef-ac33-02420a64024e-1-3a7b", 281 | "next": "9193b88e-4bfd-11e9-80f2-02420a0001bc-1-3d06", 282 | "previous": "9193b848-4bfd-11e9-80f2-02420a0001bc-1-0ae7" 283 | }, 284 | { 285 | "current": "64cc969c-fd8e-11ef-ac33-02420a64024e-3-3a7b-e4d3-8e14", 286 | "next": "91ef9410-4bfd-11e9-ad24-02420a0001bc-1-9cb9", 287 | "previous": "a09cf1c8-fe54-11ef-96fa-02420a640255" 288 | }, 289 | { 290 | "current": "64cc969c-fd8e-11ef-ac33-02420a64024e-5-3a7b-e4d3-8e14-9084-80c1", 291 | "next": "94710606-4bfd-11e9-8c4f-02420a0001bc-1-9c59", 292 | "previous": "a09cf1c8-fe54-11ef-96fa-02420a640255-2-c795-8dcc" 293 | } 294 | ], 295 | "next": "924bfe08-4bfd-11e9-bee0-02420a0001bc-1-ccc6", 296 | "previous": "a09cf1c8-fe54-11ef-96fa-02420a640255-4-c795-8dcc-a674-acfd" 297 | }, 298 | "run_through_control": { 299 | "frozen": false 300 | } 301 | }, 302 | "outputs": [], 303 | "source": [ 304 | "import os\n", 305 | "\n", 306 | "# コース名の指定\n", 307 | "course_name = os.environ['CWH_COURSE_NAME']\n", 308 | "course_name" 309 | ] 310 | }, 311 | { 312 | "cell_type": "markdown", 313 | "metadata": { 314 | "lc_cell_meme": { 315 | "current": "924bfe08-4bfd-11e9-bee0-02420a0001bc-1-ccc6", 316 | "history": [ 317 | { 318 | "current": "924bfe08-4bfd-11e9-bee0-02420a0001bc-1-ccc6", 319 | "next": "924bfe58-4bfd-11e9-bee0-02420a0001bc", 320 | "previous": "924bfdc2-4bfd-11e9-bee0-02420a0001bc" 321 | } 322 | ], 323 | "next": "924bfe58-4bfd-11e9-bee0-02420a0001bc-1-54e6", 324 | "previous": "64cc969c-fd8e-11ef-ac33-02420a64024e-5-3a7b-e4d3-8e14-9084-80c1" 325 | } 326 | }, 327 | "source": [ 328 | "# バックアップの作業用フォルダを作成します" 329 | ] 330 | }, 331 | { 332 | "cell_type": "markdown", 333 | "metadata": { 334 | "lc_cell_meme": { 335 | "current": "924bfe58-4bfd-11e9-bee0-02420a0001bc-1-54e6", 336 | "history": [ 337 | { 338 | "current": "924bfe58-4bfd-11e9-bee0-02420a0001bc-1-54e6", 339 | "next": "924bfea8-4bfd-11e9-bee0-02420a0001bc", 340 | "previous": "924bfe08-4bfd-11e9-bee0-02420a0001bc" 341 | } 342 | ], 343 | "next": "924bfea8-4bfd-11e9-bee0-02420a0001bc-1-ce8b", 344 | "previous": "924bfe08-4bfd-11e9-bee0-02420a0001bc-1-ccc6" 345 | } 346 | }, 347 | "source": [ 348 | "* バックアップファイルを格納するフォルダを作成します。\n", 349 | "* フォルダを変更する場合は、BACKUP_WORK_DIR を変更して下さい。\n", 350 | "* フォルダが既存の場合、フォルダ配下のファイルは削除されます。必要があれば事前に退避して下さい。\n", 351 | "\n", 352 | "**次のセルを実行して、作業用フォルダを作成して下さい。**" 353 | ] 354 | }, 355 | { 356 | "cell_type": "code", 357 | "execution_count": null, 358 | "metadata": { 359 | "deletable": false, 360 | "editable": false, 361 | "lc_cell_meme": { 362 | "current": "924bfea8-4bfd-11e9-bee0-02420a0001bc-1-ce8b", 363 | "history": [ 364 | { 365 | "current": "924bfea8-4bfd-11e9-bee0-02420a0001bc-1-ce8b", 366 | "next": "924bfef8-4bfd-11e9-bee0-02420a0001bc", 367 | "previous": "924bfe58-4bfd-11e9-bee0-02420a0001bc" 368 | } 369 | ], 370 | "next": "924bfef8-4bfd-11e9-bee0-02420a0001bc-1-52c6", 371 | "previous": "924bfe58-4bfd-11e9-bee0-02420a0001bc-1-54e6" 372 | }, 373 | "run_through_control": { 374 | "frozen": false 375 | } 376 | }, 377 | "outputs": [], 378 | "source": [ 379 | "%env BACKUP_WORK_DIR=~/{course_name}/backup\n", 380 | "\n", 381 | "import os.path\n", 382 | "\n", 383 | "backupdir = os.path.expanduser(os.environ['BACKUP_WORK_DIR'])\n", 384 | "print(backupdir)\n", 385 | "%env BACKUP_WORK_DIR={backupdir}\n", 386 | "\n", 387 | "# create backup work directory\n", 388 | "if not os.path.exists(backupdir):\n", 389 | " os.makedirs(backupdir)\n", 390 | "\n", 391 | "# cleanup backup work directory\n", 392 | "!rm -rf {backupdir}/*" 393 | ] 394 | }, 395 | { 396 | "cell_type": "markdown", 397 | "metadata": { 398 | "lc_cell_meme": { 399 | "current": "924bfef8-4bfd-11e9-bee0-02420a0001bc-1-52c6", 400 | "history": [ 401 | { 402 | "current": "924bfef8-4bfd-11e9-bee0-02420a0001bc-1-52c6", 403 | "next": "924bff48-4bfd-11e9-bee0-02420a0001bc", 404 | "previous": "924bfea8-4bfd-11e9-bee0-02420a0001bc" 405 | } 406 | ], 407 | "next": "924bff48-4bfd-11e9-bee0-02420a0001bc-1-9a6e", 408 | "previous": "924bfea8-4bfd-11e9-bee0-02420a0001bc-1-ce8b" 409 | } 410 | }, 411 | "source": [ 412 | "# バックアップ名を指定します" 413 | ] 414 | }, 415 | { 416 | "cell_type": "markdown", 417 | "metadata": { 418 | "lc_cell_meme": { 419 | "current": "924bff48-4bfd-11e9-bee0-02420a0001bc-1-9a6e", 420 | "history": [ 421 | { 422 | "current": "924bff48-4bfd-11e9-bee0-02420a0001bc-1-9a6e", 423 | "next": "924bff8e-4bfd-11e9-bee0-02420a0001bc", 424 | "previous": "924bfef8-4bfd-11e9-bee0-02420a0001bc" 425 | } 426 | ], 427 | "next": "924bff8e-4bfd-11e9-bee0-02420a0001bc-1-e5f3", 428 | "previous": "924bfef8-4bfd-11e9-bee0-02420a0001bc-1-52c6" 429 | } 430 | }, 431 | "source": [ 432 | "* バックパップの名前を BACKUP_NAME に設定して下さい。\n", 433 | "```\n", 434 | "BACKUP_NAME=\"course\"\n", 435 | "```\n", 436 | "* バックアップファイルは、「バックアップ名_backup.tar.gz」として保存します。\n", 437 | "\n", 438 | "**次のセルでバックアップ名を指定して、セルを実行して下さい。**" 439 | ] 440 | }, 441 | { 442 | "cell_type": "code", 443 | "execution_count": null, 444 | "metadata": { 445 | "deletable": false, 446 | "editable": false, 447 | "lc_cell_meme": { 448 | "current": "924bff8e-4bfd-11e9-bee0-02420a0001bc-1-e5f3", 449 | "history": [ 450 | { 451 | "current": "924bff8e-4bfd-11e9-bee0-02420a0001bc-1-e5f3", 452 | "next": "924bffde-4bfd-11e9-bee0-02420a0001bc", 453 | "previous": "924bff48-4bfd-11e9-bee0-02420a0001bc" 454 | } 455 | ], 456 | "next": "924bffde-4bfd-11e9-bee0-02420a0001bc-1-4001", 457 | "previous": "924bff48-4bfd-11e9-bee0-02420a0001bc-1-9a6e" 458 | }, 459 | "run_through_control": { 460 | "frozen": false 461 | } 462 | }, 463 | "outputs": [], 464 | "source": [ 465 | "%env BACKUP_NAME=course-01" 466 | ] 467 | }, 468 | { 469 | "cell_type": "markdown", 470 | "metadata": { 471 | "lc_cell_meme": { 472 | "current": "924bffde-4bfd-11e9-bee0-02420a0001bc-1-4001", 473 | "history": [ 474 | { 475 | "current": "924bffde-4bfd-11e9-bee0-02420a0001bc-1-4001", 476 | "next": "924c002e-4bfd-11e9-bee0-02420a0001bc", 477 | "previous": "924bff8e-4bfd-11e9-bee0-02420a0001bc" 478 | } 479 | ], 480 | "next": "924c002e-4bfd-11e9-bee0-02420a0001bc-1-f02f", 481 | "previous": "924bff8e-4bfd-11e9-bee0-02420a0001bc-1-e5f3" 482 | } 483 | }, 484 | "source": [ 485 | "# 次のセルを実行して、バックアップファイルを作成して下さい" 486 | ] 487 | }, 488 | { 489 | "cell_type": "markdown", 490 | "metadata": { 491 | "lc_cell_meme": { 492 | "current": "924c002e-4bfd-11e9-bee0-02420a0001bc-1-f02f", 493 | "history": [ 494 | { 495 | "current": "924c002e-4bfd-11e9-bee0-02420a0001bc-1-f02f", 496 | "next": "924c0100-4bfd-11e9-bee0-02420a0001bc", 497 | "previous": "924bffde-4bfd-11e9-bee0-02420a0001bc" 498 | } 499 | ], 500 | "next": "924c0100-4bfd-11e9-bee0-02420a0001bc-1-d2b3", 501 | "previous": "924bffde-4bfd-11e9-bee0-02420a0001bc-1-4001" 502 | } 503 | }, 504 | "source": [ 505 | "* バックアップファイルを生成します。\n", 506 | "* バックアップファイルは、上記で作成したバックアップフォルダに格納されます。" 507 | ] 508 | }, 509 | { 510 | "cell_type": "code", 511 | "execution_count": null, 512 | "metadata": { 513 | "deletable": false, 514 | "editable": false, 515 | "lc_cell_meme": { 516 | "current": "924c0100-4bfd-11e9-bee0-02420a0001bc-1-d2b3", 517 | "history": [ 518 | { 519 | "current": "924c0100-4bfd-11e9-bee0-02420a0001bc-1-d2b3", 520 | "next": "924c015a-4bfd-11e9-bee0-02420a0001bc", 521 | "previous": "924c002e-4bfd-11e9-bee0-02420a0001bc" 522 | } 523 | ], 524 | "next": "924c015a-4bfd-11e9-bee0-02420a0001bc-1-af4b", 525 | "previous": "924c002e-4bfd-11e9-bee0-02420a0001bc-1-f02f" 526 | }, 527 | "run_through_control": { 528 | "frozen": false 529 | } 530 | }, 531 | "outputs": [], 532 | "source": [ 533 | "%%bash\n", 534 | "set -e\n", 535 | "\n", 536 | "TARGET_FILES=('textbook' 'info' 'draft' 'test' ${INCLUDES})\n", 537 | "EXCLUDE_PATTERNS=('backup-*.tgz' '.ipynb_checkpoints' ${EXCLUDES})\n", 538 | "BACKUP_NAME=\"${BACKUP_NAME,,}\"\n", 539 | "[ -z \"${BACKUP_NAME}\" ] && BACKUP_NAME=\"$(< /etc/courseware.configmap/fqdn)\"\n", 540 | "[ -z \"${BACKUP_NAME}\" ] && BACKUP_NAME=\"untitled\"\n", 541 | "TMP_WORK_DIR=\"$(mktemp -d --tmpdir courseware-bk.tmp.XXXXXXXX)\"\n", 542 | "TGZ_FILE=\"${TMP_WORK_DIR}/backup-${BACKUP_NAME}.tgz\"\n", 543 | "TARGET_LIST=\"${TMP_WORK_DIR}/target.list\"\n", 544 | "EXCLUDE_LIST=\"${TMP_WORK_DIR}/exclude.list\"\n", 545 | "\n", 546 | "cd ~/${CWH_COURSE_NAME}\n", 547 | "for entry in \"${TARGET_FILES[@]}\"; do\n", 548 | " if [ -e \"${entry}\" ]; then\n", 549 | " echo \"$(realpath --relative-base=. \"${entry}\")\" >>\"${TARGET_LIST}\"\n", 550 | " fi\n", 551 | "done\n", 552 | "for entry in \"${EXCLUDE_PATTERNS[@]}\"; do\n", 553 | " echo ${entry} >>\"${EXCLUDE_LIST}\"\n", 554 | "done\n", 555 | "\n", 556 | "tar -cz -X <(sort -u \"${EXCLUDE_LIST}\") -T <(sort -u \"${TARGET_LIST}\") -f \"${TGZ_FILE}\"\n", 557 | "mv \"${TGZ_FILE}\" ~/${CWH_COURSE_NAME}/\n", 558 | "rm -rf \"${TMP_WORK_DIR}\"\n", 559 | "\n", 560 | "TGZ_NAME=$(basename \"${TGZ_FILE}\")\n", 561 | "TGZ_DST_PATH=$(realpath ~/\"${CWH_COURSE_NAME}\"/\"${TGZ_NAME}\")\n", 562 | "\n", 563 | "echo 'Backup completed successfully:' \"${TGZ_DST_PATH}\"" 564 | ] 565 | }, 566 | { 567 | "cell_type": "markdown", 568 | "metadata": { 569 | "lc_cell_meme": { 570 | "current": "924c015a-4bfd-11e9-bee0-02420a0001bc-1-af4b", 571 | "history": [ 572 | { 573 | "current": "924c015a-4bfd-11e9-bee0-02420a0001bc-1-af4b", 574 | "next": "924c01aa-4bfd-11e9-bee0-02420a0001bc", 575 | "previous": "924c0100-4bfd-11e9-bee0-02420a0001bc" 576 | } 577 | ], 578 | "next": "924c01aa-4bfd-11e9-bee0-02420a0001bc-1-8442", 579 | "previous": "924c0100-4bfd-11e9-bee0-02420a0001bc-1-d2b3" 580 | } 581 | }, 582 | "source": [ 583 | "# バックアップファイルを保存します" 584 | ] 585 | }, 586 | { 587 | "cell_type": "markdown", 588 | "metadata": { 589 | "lc_cell_meme": { 590 | "current": "924c01aa-4bfd-11e9-bee0-02420a0001bc-1-8442", 591 | "history": [ 592 | { 593 | "current": "924c01aa-4bfd-11e9-bee0-02420a0001bc-1-8442", 594 | "next": null, 595 | "previous": "924c015a-4bfd-11e9-bee0-02420a0001bc" 596 | } 597 | ], 598 | "next": null, 599 | "previous": "924c015a-4bfd-11e9-bee0-02420a0001bc-1-af4b" 600 | } 601 | }, 602 | "source": [ 603 | "* バックアップファイルを適切な保管場所へ転送して保存して下さい。\n", 604 | "* ローカルマシンに保存する場合は、下記の手順でダウンロードできます。\n", 605 | " 1. ブラウザのHome画面で、バックアップファイルを格納したフォルダを開きます。バックアップファイルが表示されます。\n", 606 | " 2. バックアップファイル名先頭のチェックボックスをクリックします。画面左上に操作ボタンが表示されます。\n", 607 | " 3. [Download]ボタンをクリックします。" 608 | ] 609 | } 610 | ], 611 | "metadata": { 612 | "kernelspec": { 613 | "display_name": "Python 3", 614 | "language": "python", 615 | "name": "python3" 616 | }, 617 | "language_info": { 618 | "file_extension": ".py", 619 | "mimetype": "text/x-python", 620 | "name": "python", 621 | "nbconvert_exporter": "python", 622 | "pygments_lexer": "ipython3", 623 | "version": "3.10.11" 624 | }, 625 | "lc_notebook_meme": { 626 | "current": "924bf958-4bfd-11e9-bee0-02420a0001bc", 627 | "history": [], 628 | "root_cells": [ 629 | "924bfaac-4bfd-11e9-bee0-02420a0001bc", 630 | "924bfb2e-4bfd-11e9-bee0-02420a0001bc", 631 | "924bfb92-4bfd-11e9-bee0-02420a0001bc", 632 | "924bfbe2-4bfd-11e9-bee0-02420a0001bc", 633 | "924bfc3c-4bfd-11e9-bee0-02420a0001bc", 634 | "924bfc8c-4bfd-11e9-bee0-02420a0001bc", 635 | "924bfcd2-4bfd-11e9-bee0-02420a0001bc", 636 | "924bfd22-4bfd-11e9-bee0-02420a0001bc", 637 | "924bfd72-4bfd-11e9-bee0-02420a0001bc", 638 | "924bfdc2-4bfd-11e9-bee0-02420a0001bc", 639 | "924bfe08-4bfd-11e9-bee0-02420a0001bc", 640 | "924bfe58-4bfd-11e9-bee0-02420a0001bc", 641 | "924bfea8-4bfd-11e9-bee0-02420a0001bc", 642 | "924bfef8-4bfd-11e9-bee0-02420a0001bc", 643 | "924bff48-4bfd-11e9-bee0-02420a0001bc", 644 | "924bff8e-4bfd-11e9-bee0-02420a0001bc", 645 | "924bffde-4bfd-11e9-bee0-02420a0001bc", 646 | "924c002e-4bfd-11e9-bee0-02420a0001bc", 647 | "924c0100-4bfd-11e9-bee0-02420a0001bc", 648 | "924c015a-4bfd-11e9-bee0-02420a0001bc", 649 | "924c01aa-4bfd-11e9-bee0-02420a0001bc" 650 | ] 651 | }, 652 | "toc": { 653 | "base_numbering": 1, 654 | "nav_menu": {}, 655 | "number_sections": true, 656 | "sideBar": true, 657 | "skip_h1_title": false, 658 | "title_cell": "Table of Contents", 659 | "title_sidebar": "Contents", 660 | "toc_cell": false, 661 | "toc_position": {}, 662 | "toc_section_display": true, 663 | "toc_window_display": true 664 | } 665 | }, 666 | "nbformat": 4, 667 | "nbformat_minor": 2 668 | } 669 | --------------------------------------------------------------------------------