diff --git a/exasol/ds/sandbox/runtime/ansible/roles/jupyter/files/notebook/script_languages_container/configure_slc_flavor.ipynb b/exasol/ds/sandbox/runtime/ansible/roles/jupyter/files/notebook/script_languages_container/configure_slc_flavor.ipynb index b20a9eca..9c756fa7 100644 --- a/exasol/ds/sandbox/runtime/ansible/roles/jupyter/files/notebook/script_languages_container/configure_slc_flavor.ipynb +++ b/exasol/ds/sandbox/runtime/ansible/roles/jupyter/files/notebook/script_languages_container/configure_slc_flavor.ipynb @@ -23,14 +23,14 @@ }, { "cell_type": "code", - "execution_count": 87, + "execution_count": 2, "id": "e70ad0a9-7042-4fe8-814b-5c586b9bee6d", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "e6b503a366de4fbfaa27133cd764cf89", + "model_id": "a4095da05fc44fa68654b7f5d13712cc", "version_major": 2, "version_minor": 0 }, @@ -44,7 +44,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "350dc0e4b76d4f83ba1c31818b4e4688", + "model_id": "435bd583cc9941b7afca1535080febb4", "version_major": 2, "version_minor": 0 }, @@ -72,14 +72,14 @@ }, { "cell_type": "code", - "execution_count": 242, + "execution_count": 10, "id": "224345da-f14e-4a45-bf8a-07e3ba0870dc", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "34d26190895748799ba240ff5496ae6c", + "model_id": "d4dfaf571f824949bb3ecb49f0de15d4", "version_major": 2, "version_minor": 0 }, @@ -106,14 +106,14 @@ }, { "cell_type": "code", - "execution_count": 243, + "execution_count": 20, "id": "0f8caa77-35a0-403d-af96-e5f8056ba489", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "13649f5f9c334d1499382b6df9af8cbb", + "model_id": "68853b81424749c8a5a8c3d5796598ea", "version_major": 2, "version_minor": 0 }, @@ -140,19 +140,14 @@ }, { "cell_type": "code", - "execution_count": 244, + "execution_count": 21, "id": "56e16540-5f4b-4d5c-8c83-d34c1217eb00", "metadata": {}, "outputs": [ { "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "dc590fa666f64d24bb267f1d77592468", - "version_major": 2, - "version_minor": 0 - }, "text/plain": [ - "Box(children=(Box(children=(Label(value='Existing script-languages directory', layout=Layout(border_bottom='so…" + "None" ] }, "metadata": {}, @@ -174,14 +169,19 @@ }, { "cell_type": "code", - "execution_count": 245, + "execution_count": 22, "id": "7d84889f-7c3a-4f69-9bf1-c193481867af", "metadata": {}, "outputs": [ { "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "381ca9801c2e4c3da7eae780bb7103fc", + "version_major": 2, + "version_minor": 0 + }, "text/plain": [ - "None" + "Box(children=(Box(children=(Label(value='Target Directory', layout=Layout(border_bottom='solid 1px', border_le…" ] }, "metadata": {}, @@ -202,7 +202,7 @@ }, { "cell_type": "code", - "execution_count": 246, + "execution_count": 23, "id": "31132726-9827-4c9b-8fb8-0884d2f36e67", "metadata": {}, "outputs": [ @@ -210,16 +210,17 @@ "name": "stdout", "output_type": "stream", "text": [ + "Directory '/home/jupyter/script_languages_release' already exists. Skipping cloning....\n", "Ready\n" ] } ], "source": [ "from pathlib import Path\n", - "if use_slc_repo(ai_lab_config):\n", + "if clone_slc_repo(ai_lab_config):\n", " from git import Repo\n", " \n", - " slc_dir = Path(ai_lab_config.get(\"Script-Languages-Release-Dir\"))\n", + " slc_dir = Path(ai_lab_config.get(slc_target_dir_store_key))\n", " if not slc_dir.is_dir():\n", " print (f\"Cloning into {slc_dir}...\")\n", " repo = Repo.clone_from(\"https://github.com/exasol/script-languages-release\", slc_dir)\n", @@ -240,7 +241,7 @@ }, { "cell_type": "code", - "execution_count": 247, + "execution_count": 18, "id": "bb6b26b9-cb24-4b66-85c9-e15a0c92ff2c", "metadata": { "scrolled": true @@ -249,7 +250,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "a151ede22ef447c1988bb2d92f7fea09", + "model_id": "bb267088d6514e33bd1ea2b2ca4f4491", "version_major": 2, "version_minor": 0 }, diff --git a/exasol/ds/sandbox/runtime/ansible/roles/jupyter/files/notebook/script_languages_container/using_a_script_languages_container.ipynb b/exasol/ds/sandbox/runtime/ansible/roles/jupyter/files/notebook/script_languages_container/using_a_script_languages_container.ipynb index 951ab611..53c48678 100644 --- a/exasol/ds/sandbox/runtime/ansible/roles/jupyter/files/notebook/script_languages_container/using_a_script_languages_container.ipynb +++ b/exasol/ds/sandbox/runtime/ansible/roles/jupyter/files/notebook/script_languages_container/using_a_script_languages_container.ipynb @@ -14,7 +14,7 @@ "id": "39333102-7652-4699-ba0e-d184aeec1753", "metadata": {}, "source": [ - "Before we start we need to configure the script-languages directory and flavor. See [Configure SLC Flavor](http://localhost:49494/lab/tree/script_languages_container/configure_slc_flavor.ipynb)" + "Before we start we need to configure the script-languages directory and flavor. See [Configure SLC Flavor](./configure_slc_flavor.ipynb)" ] }, { @@ -28,14 +28,14 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 131, "id": "da57e77a-b41f-45e3-9a17-4b474bba898b", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "55496235b82f434cb9c8b66503078815", + "model_id": "da078af7f81049b08d649318e6935b81", "version_major": 2, "version_minor": 0 }, @@ -49,7 +49,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "2a16af727a574dbe89c2d702f5513ebc", + "model_id": "14ae65ffd50441ef99a1d239cee68f04", "version_major": 2, "version_minor": 0 }, @@ -79,7 +79,7 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 132, "id": "27352b75-823d-40a1-b8df-d33218fd7de6", "metadata": {}, "outputs": [], @@ -99,26 +99,6 @@ " os.chdir(prev_cwd)" ] }, - { - "cell_type": "markdown", - "id": "c6d50944-6065-463c-be74-0e2b88c18346", - "metadata": {}, - "source": [ - "#### Show directory content" - ] - }, - { - "cell_type": "code", - "execution_count": 56, - "id": "9543044f-0f8d-426d-a7b3-a13dac6a921d", - "metadata": {}, - "outputs": [], - "source": [ - "def show_directory_content(directory: Path):\n", - " for p in directory.iterdir():\n", - " print(p)" - ] - }, { "cell_type": "markdown", "id": "9fba4c9e-4a1b-4f84-a9a6-f05810aa8922", @@ -129,14 +109,14 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 134, "id": "c554d698-d5a2-4f9b-846a-f606a3f183b7", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "9f901d9d3d364ae6b9a4943ddcdf5abb", + "model_id": "0482436b4166407fb592a265a83ed2d2", "version_major": 2, "version_minor": 0 }, @@ -155,7 +135,9 @@ "# Need to search for the styles NB from the current directory upwards.\n", "\n", "%run {upward_file_search('utils/ui_styles.ipynb')}\n", - "%run {upward_file_search('utils/popup_message_ui.ipynb')}" + "%run {upward_file_search('utils/popup_message_ui.ipynb')}\n", + "%run ./utils/file_system_ui.ipynb\n", + "\n" ] }, { @@ -169,7 +151,7 @@ }, { "cell_type": "code", - "execution_count": 50, + "execution_count": 135, "id": "f03723b8-2229-4e10-b801-ac074c7388cb", "metadata": {}, "outputs": [ @@ -177,7 +159,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Script-languages repository path is '/tmp/script_languages_release'\n", + "Script-languages repository path is '/home/jupyter/script_languages_release'\n", "Selected flavor is 'template-Exasol-all-python-3.10'\n" ] } @@ -212,7 +194,7 @@ }, { "cell_type": "code", - "execution_count": 52, + "execution_count": 13, "id": "20665390-4f31-48db-ab78-249a1ef629e9", "metadata": { "scrolled": true @@ -224,6 +206,17 @@ "text": [ "Ready\n" ] + }, + { + "ename": "NameError", + "evalue": "name 'prunt' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[13], line 9\u001b[0m\n\u001b[1;32m 7\u001b[0m export_result \u001b[38;5;241m=\u001b[39m exaslct_api\u001b[38;5;241m.\u001b[39mexport(flavor_path\u001b[38;5;241m=\u001b[39m(\u001b[38;5;28mstr\u001b[39m(flavor_path),), export_path\u001b[38;5;241m=\u001b[39mexport_path)\n\u001b[1;32m 8\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mReady\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m----> 9\u001b[0m \u001b[43mprunt\u001b[49m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mResult: \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;132;01m{export_result}\u001b[39;00m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n", + "\u001b[0;31mNameError\u001b[0m: name 'prunt' is not defined" + ] } ], "source": [ @@ -233,7 +226,7 @@ "output_path = \"/tmp/output\"\n", "\n", "with working_directory(slc_dir):\n", - " exaslct_api.export(flavor_path=(str(flavor_path),), export_path=export_path)\n", + " export_result = exaslct_api.export(flavor_path=(str(flavor_path),), export_path=export_path)\n", "print(\"Ready\")" ] }, @@ -247,7 +240,7 @@ }, { "cell_type": "code", - "execution_count": 57, + "execution_count": 117, "id": "fc142500-d855-4112-bba2-ed3395889b9b", "metadata": {}, "outputs": [ @@ -255,19 +248,1102 @@ "name": "stdout", "output_type": "stream", "text": [ + "Result file: /tmp/slc/template-Exasol-all-python-3.10_release.tar.gz\n", + "Directory content:\n", "/tmp/slc/template-Exasol-all-python-3.10_release.tar.gz\n", "/tmp/slc/template-Exasol-all-python-3.10_release.tar.gz.sha512sum\n" ] } ], "source": [ + "print(f\"Result file: {export_result.export_infos[str(flavor_path)]['release'].output_file}\")\n", + "print(\"Directory content:\")\n", "show_directory_content(Path(export_path))" ] }, + { + "cell_type": "markdown", + "id": "33d76239-60fd-430f-b7e2-fca74c2e0871", + "metadata": {}, + "source": [ + "### What to do if something doesn't work?\n", + "\n", + "During the build it can happen that external package repositories might not be available or something is wrong on your machine where you run the build. For these cases, exaslct stores many logs to identify the problem.\n", + "\n", + "#### Exaslsct Log\n", + "The main log for exaslct is stored directly as main.log in the build output of the job. With the following command you can find the main logs for all previous executions." + ] + }, + { + "cell_type": "code", + "execution_count": 136, + "id": "423b261a-3d99-4893-95dc-224a5794c588", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/home/jupyter/script_languages_release/.build_output/jobs/2024_06_19_10_58_26_2_ExportContainers/logs/main.log\n", + "/home/jupyter/script_languages_release/.build_output/jobs/2024_06_19_10_38_46_1_ExportContainers/logs/main.log\n" + ] + } + ], + "source": [ + "build_output = Path(slc_dir) / \".build_output\"\n", + "show_files(list(build_output.glob('**/main.log')))" + ] + }, + { + "cell_type": "markdown", + "id": "47e38bb4-6a56-478a-9719-40caf3f8b488", + "metadata": {}, + "source": [ + "With the following command you can show the log file from the last execution. " + ] + }, + { + "cell_type": "code", + "execution_count": 137, + "id": "b5a816ae-1276-4649-997c-d50f0a3be991", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2024-06-19 10:58:33,527 - luigi.scheduler - DEBUG - Done pruning task graph\n", + "2024-06-19 10:58:33,527 - luigi-interface - DEBUG - Done\n", + "2024-06-19 10:58:33,527 - luigi-interface - DEBUG - There are no more tasks to run at this time\n", + "2024-06-19 10:58:33,533 - luigi-interface - INFO - Worker Worker(salt=4698573545, workers=5, host=c402bff327cd, username=root, pid=370, sudo_user=ubuntu) was stopped. Shutting down Keep-Alive thread\n", + "2024-06-19 10:58:33,538 - luigi-interface - INFO - \n", + "===== Luigi Execution Summary =====\n", + "\n", + "Scheduled 12 tasks of which:\n", + "* 12 ran successfully:\n", + " - 1 AnalyzeBuildDeps_9fb2953fff(job_id=2024_06_19_10_58_26_2_ExportContainers, no_cache=False, flavor_path=flavors/template-Exasol-all-python-3.10)\n", + " - 1 AnalyzeBuildRun_9fb2953fff(job_id=2024_06_19_10_58_26_2_ExportContainers, no_cache=False, flavor_path=flavors/template-Exasol-all-python-3.10)\n", + " - 1 AnalyzeFlavorBaseDeps_9fb2953fff(job_id=2024_06_19_10_58_26_2_ExportContainers, no_cache=False, flavor_path=flavors/template-Exasol-all-python-3.10)\n", + " - 1 AnalyzeFlavorCustomization_9fb2953fff(job_id=2024_06_19_10_58_26_2_ExportContainers, no_cache=False, flavor_path=flavors/template-Exasol-all-python-3.10)\n", + " - 1 AnalyzeLanguageDeps_9fb2953fff(job_id=2024_06_19_10_58_26_2_ExportContainers, no_cache=False, flavor_path=flavors/template-Exasol-all-python-3.10)\n", + " ...\n", + "\n", + "This progress looks :) because there were no failed tasks or missing dependencies\n", + "\n", + "===== Luigi Execution Summary =====\n", + "\n", + "\n" + ] + } + ], + "source": [ + "tail_file(main_logs[0], 20)" + ] + }, + { + "cell_type": "markdown", + "id": "c067c03e-f5c4-430e-90f0-b213b255c0d4", + "metadata": {}, + "source": [ + "#### Build Output Directory\n", + "\n", + "More detailed information about the build or other operations can be found in the `.build_output/jobs/*/outputs` directory. Here each run of `exaslct` creates its own directory under `.build_output/jobs`. The outputs directory stores the outputs and log files (if any) that each executed task of `exaslct` produces. Especially, the Docker tasks such as build, pull and push store the logs returned by the Docker API. This can be helpful for finding problems during the build." + ] + }, + { + "cell_type": "code", + "execution_count": 138, + "id": "1aa24f25-789c-49b3-bb5e-81d49f4afa69", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/home/jupyter/script_languages_release/.build_output/jobs/2024_06_19_10_58_26_2_ExportContainers/logs/main.log\n", + "/home/jupyter/script_languages_release/.build_output/jobs/2024_06_19_10_38_46_1_ExportContainers/logs/main.log\n", + "/home/jupyter/script_languages_release/.build_output/jobs/2024_06_19_10_38_46_1_ExportContainers/outputs/ExportContainers_d23d451ed9/ExportFlavorContainer_5ca839d186/ExportContainerTask_aca305cb5f/logs/pack_release_file.log\n", + "/home/jupyter/script_languages_release/.build_output/jobs/2024_06_19_10_38_46_1_ExportContainers/outputs/ExportContainers_d23d451ed9/ExportFlavorContainer_5ca839d186/ExportContainerTask_aca305cb5f/logs/extract_release_file.log\n" + ] + } + ], + "source": [ + "all_logs = list(build_output.glob('**/*.log'))\n", + "show_files(all_logs)" + ] + }, + { + "attachments": { + "47f643bc-704e-4b00-8405-917b5fdae990.png": { + "image/png": "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" + } + }, + "cell_type": "markdown", + "id": "ac19449e-f9a1-4b35-b73b-e35771031f20", + "metadata": {}, + "source": [ + "## Customizing Script-Language Containers\n", + "Sometimes you need very specific dependencies or versions of dependencies in the Exasol UDFs. In such case you can customize a Script-Language Container.\n", + "### Flavor Definition\n", + "![image.png](attachment:47f643bc-704e-4b00-8405-917b5fdae990.png)\n" + ] + }, + { + "cell_type": "markdown", + "id": "58895979-99f7-4fad-ab0f-9cfa020b3750", + "metadata": {}, + "source": [ + "For customizing a flavor usually the flavor_customization build step is most important. It contains everything you need to add dependencies. The remaining build steps should be only changed with care, but sometimes some dependencies are defined in other build steps because the script client depends on them. \n", + "Let's check the directory structure of the selected flavor." + ] + }, + { + "cell_type": "code", + "execution_count": 139, + "id": "11f3d8ae-d23b-4968-a5c3-a18de8f434d8", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/home/jupyter/script_languages_release/flavors/template-Exasol-all-python-3.10/flavor_customization\n", + "/home/jupyter/script_languages_release/flavors/template-Exasol-all-python-3.10/flavor_customization/packages\n", + "/home/jupyter/script_languages_release/flavors/template-Exasol-all-python-3.10/flavor_customization/Dockerfile\n", + "/home/jupyter/script_languages_release/flavors/template-Exasol-all-python-3.10/FLAVOR_DESCRIPTION.md\n", + "/home/jupyter/script_languages_release/flavors/template-Exasol-all-python-3.10/flavor_base\n", + "/home/jupyter/script_languages_release/flavors/template-Exasol-all-python-3.10/flavor_base/testconfig\n", + "/home/jupyter/script_languages_release/flavors/template-Exasol-all-python-3.10/flavor_base/base_test_build_run\n", + "/home/jupyter/script_languages_release/flavors/template-Exasol-all-python-3.10/flavor_base/security_scan\n", + "/home/jupyter/script_languages_release/flavors/template-Exasol-all-python-3.10/flavor_base/release\n", + "/home/jupyter/script_languages_release/flavors/template-Exasol-all-python-3.10/flavor_base/build_run\n", + "/home/jupyter/script_languages_release/flavors/template-Exasol-all-python-3.10/flavor_base/base_test_deps\n", + "/home/jupyter/script_languages_release/flavors/template-Exasol-all-python-3.10/flavor_base/language_deps\n", + "/home/jupyter/script_languages_release/flavors/template-Exasol-all-python-3.10/flavor_base/udfclient_deps\n", + "/home/jupyter/script_languages_release/flavors/template-Exasol-all-python-3.10/flavor_base/build_steps.py\n", + "/home/jupyter/script_languages_release/flavors/template-Exasol-all-python-3.10/flavor_base/language_definition\n", + "/home/jupyter/script_languages_release/flavors/template-Exasol-all-python-3.10/flavor_base/build_deps\n", + "/home/jupyter/script_languages_release/flavors/template-Exasol-all-python-3.10/flavor_base/derived_from\n", + "/home/jupyter/script_languages_release/flavors/template-Exasol-all-python-3.10/flavor_base/flavor_test_build_run\n", + "/home/jupyter/script_languages_release/flavors/template-Exasol-all-python-3.10/flavor_base/flavor_base_deps\n", + "/home/jupyter/script_languages_release/flavors/template-Exasol-all-python-3.10/flavor_base/__pycache__\n" + ] + } + ], + "source": [ + "show_directory_content(slc_dir / flavor_path, 2)" + ] + }, + { + "cell_type": "markdown", + "id": "67752053-c6a6-476f-892f-613113c1668b", + "metadata": {}, + "source": [ + "### Flavor Customization Build Step" + ] + }, + { + "cell_type": "markdown", + "id": "fbfdb5b8-4c9f-4174-9752-8652013630e4", + "metadata": {}, + "source": [ + "The **flavor_customization** build step consists of a Dockerfile and several package lists which can be modified. We recommend to use the package lists to add new packages to the flavor and only modify the Dockerfile if you need very specific changes, like adding additional resources." + ] + }, + { + "cell_type": "code", + "execution_count": 140, + "id": "de268b34-99e3-4af6-a9b3-02a44e803c9f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/home/jupyter/script_languages_release/flavors/template-Exasol-all-python-3.10/flavor_customization/packages\n", + "/home/jupyter/script_languages_release/flavors/template-Exasol-all-python-3.10/flavor_customization/Dockerfile\n" + ] + } + ], + "source": [ + "show_directory_content(slc_dir / flavor_path / \"flavor_customization\")" + ] + }, + { + "cell_type": "markdown", + "id": "5803c74e-2f7f-4d77-b363-f5968d1937bc", + "metadata": {}, + "source": [ + "#### Dockerfile\n", + "The Dockerfile consists of two parts. The first part installs the packages from the package list and should only be change with care. The second part is free for your changes. Read the description in the Dockerfile carefully to find out what you can and shouldn't do." + ] + }, + { + "cell_type": "code", + "execution_count": 141, + "id": "28ee0a8b-dc06-41ed-b96a-f270ae4bb862", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
############################################################################################\n",
+       "############################################################################################\n",
+       "# This Dockerfile allows you to extend this flavor by installing packages or adding files. \n",
+       "# IF you didn't change the lines below, you can add packages and their version to the  \n",
+       "# files in ./packages and they get automatically installed.                                \n",
+       "############################################################################################\n",
+       "############################################################################################\n",
+       "\n",
+       "#######################################################################\n",
+       "#######################################################################\n",
+       "# Do not change the following lines unless you know what you are doing \n",
+       "#######################################################################\n",
+       "#######################################################################\n",
+       "\n",
+       "FROM {{flavor_base_deps}}\n",
+       "\n",
+       "RUN mkdir -p /build_info/packages/flavor_customization\n",
+       "\n",
+       "COPY flavor_customization/packages/apt_get_packages /build_info/packages/flavor_customization\n",
+       "RUN /scripts/install_scripts/install_via_apt.pl --file /build_info/packages/flavor_customization/apt_get_packages --with-versions\n",
+       "\n",
+       "COPY flavor_customization/packages/python3_pip_packages /build_info/packages/flavor_customization\n",
+       "RUN /scripts/install_scripts/install_via_pip.pl --file /build_info/packages/flavor_customization/python3_pip_packages --python-binary python3 --with-versions --allow-no-version\n",
+       "\n",
+       "\n",
+       "##########################################################################\n",
+       "##########################################################################\n",
+       "# Below this text you can add any Dockerfile commands except of FROM.            \n",
+       "# However only commands which change the filesystem will be              \n",
+       "# reflected to the final script-language container.                      \n",
+       "# We recommend to use only RUN, COPY and ADD. For example, WORKDIR, USER \n",
+       "# and ENV will be not carried over into the final container. For more \n",
+       "# information about Dockerfile commands, please check the reference \n",
+       "# https://docs.docker.com/engine/reference/builder/#dockerfile-reference \n",
+       "##########################################################################\n",
+       "##########################################################################\n",
+       "\n",
+       "\n",
+       "###########\n",
+       "###########\n",
+       "# Examples:\n",
+       "###########\n",
+       "###########\n",
+       "\n",
+       "#################################################\n",
+       "# Execute a command during the build of the image\n",
+       "#################################################\n",
+       "\n",
+       "# With RUN you can excute any command you usally would run in a bash shell.\n",
+       "# It usually is a good idea to cleanup downloaded files or packages \n",
+       "# caches in the same in the same RUN statement to keep the image size\n",
+       "# small. You can execute multiple shell commands in one RUN statement\n",
+       "# by combine them with \n",
+       "# - `&&` (only execute if the previous command was successfull), \n",
+       "# - `||` (only execute if the previous command was unsuccesfull)\n",
+       "# - `;` (execute regardless of the success of the previous command)\n",
+       "# To format multiple command per RUN statement you can add a line break with `\\`.\n",
+       "# If you need to execute complex sequences of commands you should execute\n",
+       "# scripts which you can copy into the image.\n",
+       "# -------------------------------------------------------------------------------\n",
+       "\n",
+       "# RUN git clone https://github.com/exasol/data-science-examples\n",
+       "# RUN curl -o data-science-examples.zip https://codeload.github.com/exasol/data-science-examples/zip/master && \\\n",
+       "#     unzip data-science-examples.zip && \\\n",
+       "#     rm data-science-examples.zip\n",
+       "\n",
+       "#####################################\n",
+       "# Copy a file from ./ into the image. \n",
+       "#####################################\n",
+       "\n",
+       "# In case of exaslct it is important to prefix source files or directories with `flavor_customization`\n",
+       "# if you want to copy files or directories located in the same directory as this Dockerfile\n",
+       "# -----------------------------------------------------------------------------------------------------\n",
+       "\n",
+       "# COPY flavor_customization/packages/python3_pip_packages /build_info/packages/flavor_customization\n",
+       "# ADD flavor_customization/code.tar.gz /code\n",
+       "
\n" + ], + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\\PY{c}{\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}}\n", + "\\PY{c}{\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}}\n", + "\\PY{c}{\\PYZsh{} This Dockerfile allows you to extend this flavor by installing packages or adding files. }\n", + "\\PY{c}{\\PYZsh{} IF you didn\\PYZsq{}t change the lines below, you can add packages and their version to the }\n", + "\\PY{c}{\\PYZsh{} files in ./packages and they get automatically installed. }\n", + "\\PY{c}{\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}}\n", + "\\PY{c}{\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}}\n", + "\n", + "\\PY{c}{\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}}\n", + "\\PY{c}{\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}}\n", + "\\PY{c}{\\PYZsh{} Do not change the following lines unless you know what you are doing }\n", + "\\PY{c}{\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}}\n", + "\\PY{c}{\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}}\n", + "\n", + "\\PY{k}{FROM}\\PY{+w}{ }\\PY{l+s}{\\PYZob{}\\PYZob{}flavor\\PYZus{}base\\PYZus{}deps\\PYZcb{}\\PYZcb{}}\n", + "\n", + "\\PY{k}{RUN}\\PY{+w}{ }mkdir\\PY{+w}{ }\\PYZhy{}p\\PY{+w}{ }/build\\PYZus{}info/packages/flavor\\PYZus{}customization\n", + "\n", + "\\PY{k}{COPY}\\PY{+w}{ }flavor\\PYZus{}customization/packages/apt\\PYZus{}get\\PYZus{}packages\\PY{+w}{ }/build\\PYZus{}info/packages/flavor\\PYZus{}customization\n", + "\\PY{k}{RUN}\\PY{+w}{ }/scripts/install\\PYZus{}scripts/install\\PYZus{}via\\PYZus{}apt.pl\\PY{+w}{ }\\PYZhy{}\\PYZhy{}file\\PY{+w}{ }/build\\PYZus{}info/packages/flavor\\PYZus{}customization/apt\\PYZus{}get\\PYZus{}packages\\PY{+w}{ }\\PYZhy{}\\PYZhy{}with\\PYZhy{}versions\n", + "\n", + "\\PY{k}{COPY}\\PY{+w}{ }flavor\\PYZus{}customization/packages/python3\\PYZus{}pip\\PYZus{}packages\\PY{+w}{ }/build\\PYZus{}info/packages/flavor\\PYZus{}customization\n", + "\\PY{k}{RUN}\\PY{+w}{ }/scripts/install\\PYZus{}scripts/install\\PYZus{}via\\PYZus{}pip.pl\\PY{+w}{ }\\PYZhy{}\\PYZhy{}file\\PY{+w}{ }/build\\PYZus{}info/packages/flavor\\PYZus{}customization/python3\\PYZus{}pip\\PYZus{}packages\\PY{+w}{ }\\PYZhy{}\\PYZhy{}python\\PYZhy{}binary\\PY{+w}{ }python3\\PY{+w}{ }\\PYZhy{}\\PYZhy{}with\\PYZhy{}versions\\PY{+w}{ }\\PYZhy{}\\PYZhy{}allow\\PYZhy{}no\\PYZhy{}version\n", + "\n", + "\n", + "\\PY{c}{\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}}\n", + "\\PY{c}{\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}}\n", + "\\PY{c}{\\PYZsh{} Below this text you can add any Dockerfile commands except of FROM. }\n", + "\\PY{c}{\\PYZsh{} However only commands which change the filesystem will be }\n", + "\\PY{c}{\\PYZsh{} reflected to the final script\\PYZhy{}language container. }\n", + "\\PY{c}{\\PYZsh{} We recommend to use only RUN, COPY and ADD. For example, WORKDIR, USER }\n", + "\\PY{c}{\\PYZsh{} and ENV will be not carried over into the final container. For more }\n", + "\\PY{c}{\\PYZsh{} information about Dockerfile commands, please check the reference }\n", + "\\PY{c}{\\PYZsh{} https://docs.docker.com/engine/reference/builder/\\PYZsh{}dockerfile\\PYZhy{}reference }\n", + "\\PY{c}{\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}}\n", + "\\PY{c}{\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}}\n", + "\n", + "\n", + "\\PY{c}{\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}}\n", + "\\PY{c}{\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}}\n", + "\\PY{c}{\\PYZsh{} Examples:}\n", + "\\PY{c}{\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}}\n", + "\\PY{c}{\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}}\n", + "\n", + "\\PY{c}{\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}}\n", + "\\PY{c}{\\PYZsh{} Execute a command during the build of the image}\n", + "\\PY{c}{\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}}\n", + "\n", + "\\PY{c}{\\PYZsh{} With RUN you can excute any command you usally would run in a bash shell.}\n", + "\\PY{c}{\\PYZsh{} It usually is a good idea to cleanup downloaded files or packages }\n", + "\\PY{c}{\\PYZsh{} caches in the same in the same RUN statement to keep the image size}\n", + "\\PY{c}{\\PYZsh{} small. You can execute multiple shell commands in one RUN statement}\n", + "\\PY{c}{\\PYZsh{} by combine them with }\n", + "\\PY{c}{\\PYZsh{} \\PYZhy{} `\\PYZam{}\\PYZam{}` (only execute if the previous command was successfull), }\n", + "\\PY{c}{\\PYZsh{} \\PYZhy{} `||` (only execute if the previous command was unsuccesfull)}\n", + "\\PY{c}{\\PYZsh{} \\PYZhy{} `;` (execute regardless of the success of the previous command)}\n", + "\\PY{c}{\\PYZsh{} To format multiple command per RUN statement you can add a line break with `\\PYZbs{}`.}\n", + "\\PY{c}{\\PYZsh{} If you need to execute complex sequences of commands you should execute}\n", + "\\PY{c}{\\PYZsh{} scripts which you can copy into the image.}\n", + "\\PY{c}{\\PYZsh{} \\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}}\n", + "\n", + "\\PY{c}{\\PYZsh{} RUN git clone https://github.com/exasol/data\\PYZhy{}science\\PYZhy{}examples}\n", + "\\PY{c}{\\PYZsh{} RUN curl \\PYZhy{}o data\\PYZhy{}science\\PYZhy{}examples.zip https://codeload.github.com/exasol/data\\PYZhy{}science\\PYZhy{}examples/zip/master \\PYZam{}\\PYZam{} \\PYZbs{}}\n", + "\\PY{c}{\\PYZsh{} unzip data\\PYZhy{}science\\PYZhy{}examples.zip \\PYZam{}\\PYZam{} \\PYZbs{}}\n", + "\\PY{c}{\\PYZsh{} rm data\\PYZhy{}science\\PYZhy{}examples.zip}\n", + "\n", + "\\PY{c}{\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}}\n", + "\\PY{c}{\\PYZsh{} Copy a file from ./ into the image. }\n", + "\\PY{c}{\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}\\PYZsh{}}\n", + "\n", + "\\PY{c}{\\PYZsh{} In case of exaslct it is important to prefix source files or directories with `flavor\\PYZus{}customization`}\n", + "\\PY{c}{\\PYZsh{} if you want to copy files or directories located in the same directory as this Dockerfile}\n", + "\\PY{c}{\\PYZsh{} \\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}}\n", + "\n", + "\\PY{c}{\\PYZsh{} COPY flavor\\PYZus{}customization/packages/python3\\PYZus{}pip\\PYZus{}packages /build\\PYZus{}info/packages/flavor\\PYZus{}customization}\n", + "\\PY{c}{\\PYZsh{} ADD flavor\\PYZus{}customization/code.tar.gz /code}\n", + "\\end{Verbatim}\n" + ], + "text/plain": [ + "############################################################################################\n", + "############################################################################################\n", + "# This Dockerfile allows you to extend this flavor by installing packages or adding files. \n", + "# IF you didn't change the lines below, you can add packages and their version to the \n", + "# files in ./packages and they get automatically installed. \n", + "############################################################################################\n", + "############################################################################################\n", + "\n", + "#######################################################################\n", + "#######################################################################\n", + "# Do not change the following lines unless you know what you are doing \n", + "#######################################################################\n", + "#######################################################################\n", + "\n", + "FROM {{flavor_base_deps}}\n", + "\n", + "RUN mkdir -p /build_info/packages/flavor_customization\n", + "\n", + "COPY flavor_customization/packages/apt_get_packages /build_info/packages/flavor_customization\n", + "RUN /scripts/install_scripts/install_via_apt.pl --file /build_info/packages/flavor_customization/apt_get_packages --with-versions\n", + "\n", + "COPY flavor_customization/packages/python3_pip_packages /build_info/packages/flavor_customization\n", + "RUN /scripts/install_scripts/install_via_pip.pl --file /build_info/packages/flavor_customization/python3_pip_packages --python-binary python3 --with-versions --allow-no-version\n", + "\n", + "\n", + "##########################################################################\n", + "##########################################################################\n", + "# Below this text you can add any Dockerfile commands except of FROM. \n", + "# However only commands which change the filesystem will be \n", + "# reflected to the final script-language container. \n", + "# We recommend to use only RUN, COPY and ADD. For example, WORKDIR, USER \n", + "# and ENV will be not carried over into the final container. For more \n", + "# information about Dockerfile commands, please check the reference \n", + "# https://docs.docker.com/engine/reference/builder/#dockerfile-reference \n", + "##########################################################################\n", + "##########################################################################\n", + "\n", + "\n", + "###########\n", + "###########\n", + "# Examples:\n", + "###########\n", + "###########\n", + "\n", + "#################################################\n", + "# Execute a command during the build of the image\n", + "#################################################\n", + "\n", + "# With RUN you can excute any command you usally would run in a bash shell.\n", + "# It usually is a good idea to cleanup downloaded files or packages \n", + "# caches in the same in the same RUN statement to keep the image size\n", + "# small. You can execute multiple shell commands in one RUN statement\n", + "# by combine them with \n", + "# - `&&` (only execute if the previous command was successfull), \n", + "# - `||` (only execute if the previous command was unsuccesfull)\n", + "# - `;` (execute regardless of the success of the previous command)\n", + "# To format multiple command per RUN statement you can add a line break with `\\`.\n", + "# If you need to execute complex sequences of commands you should execute\n", + "# scripts which you can copy into the image.\n", + "# -------------------------------------------------------------------------------\n", + "\n", + "# RUN git clone https://github.com/exasol/data-science-examples\n", + "# RUN curl -o data-science-examples.zip https://codeload.github.com/exasol/data-science-examples/zip/master && \\\n", + "# unzip data-science-examples.zip && \\\n", + "# rm data-science-examples.zip\n", + "\n", + "#####################################\n", + "# Copy a file from ./ into the image. \n", + "#####################################\n", + "\n", + "# In case of exaslct it is important to prefix source files or directories with `flavor_customization`\n", + "# if you want to copy files or directories located in the same directory as this Dockerfile\n", + "# -----------------------------------------------------------------------------------------------------\n", + "\n", + "# COPY flavor_customization/packages/python3_pip_packages /build_info/packages/flavor_customization\n", + "# ADD flavor_customization/code.tar.gz /code\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show_docker_file(slc_dir / flavor_path / \"flavor_customization\" / \"Dockerfile\")" + ] + }, + { + "cell_type": "markdown", + "id": "562eac65-b205-49d4-971e-9ed0090796b4", + "metadata": {}, + "source": [ + "#### Package Lists\n", + "The package lists have a unified format. Each line consists of the package name and the package version separated by \"|\", e.g `xgboost|1.3.3`. You can comment out a whole line by adding\"#\" at the beginning. You can also add a trailing comment to a package definition by adding a \"#\" after the package definition. We usually recommend to pin the version, such that there are no surprises for which version gets installed." + ] + }, + { + "cell_type": "code", + "execution_count": 142, + "id": "ce88261d-efc4-470e-a875-447a28c0125c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
# This file specifies the package list which gets installed via pip for python3.\n",
+       "# You must specify the the package and its version separated by a |.\n",
+       "# We recommend here the usage of package versions, to ensure that the container \n",
+       "# builds are reproducible. However, we allow also packages without version.\n",
+       "# As you can see, this file can contain comments which start with #.\n",
+       "# If a line starts with # the whole line is a comment, however you can\n",
+       "# also start a comment after the package definition.\n",
+       "\n",
+       "#tensorflow-probability|0.9.0\n",
+       "xgboost|2.0.3\n",
+       "scikit-learn|1.5.0\n",
+       "
\n" + ], + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\\PY{c+c1}{\\PYZsh{} This file specifies the package list which gets installed via pip for python3.}\n", + "\\PY{c+c1}{\\PYZsh{} You must specify the the package and its version separated by a |.}\n", + "\\PY{c+c1}{\\PYZsh{} We recommend here the usage of package versions, to ensure that the container }\n", + "\\PY{c+c1}{\\PYZsh{} builds are reproducible. However, we allow also packages without version.}\n", + "\\PY{c+c1}{\\PYZsh{} As you can see, this file can contain comments which start with \\PYZsh{}.}\n", + "\\PY{c+c1}{\\PYZsh{} If a line starts with \\PYZsh{} the whole line is a comment, however you can}\n", + "\\PY{c+c1}{\\PYZsh{} also start a comment after the package definition.}\n", + "\n", + "\\PY{c+c1}{\\PYZsh{}tensorflow\\PYZhy{}probability|0.9.0}\n", + "\\PY{n}{xgboost}\\PY{err}{|}\\PY{n}{2}\\PY{p}{.}\\PY{n}{0}\\PY{p}{.}\\PY{n}{3}\n", + "\\PY{n}{scikit\\PYZhy{}learn}\\PY{err}{|}\\PY{n}{1}\\PY{p}{.}\\PY{n}{5}\\PY{p}{.}\\PY{n}{0}\n", + "\\end{Verbatim}\n" + ], + "text/plain": [ + "# This file specifies the package list which gets installed via pip for python3.\n", + "# You must specify the the package and its version separated by a |.\n", + "# We recommend here the usage of package versions, to ensure that the container \n", + "# builds are reproducible. However, we allow also packages without version.\n", + "# As you can see, this file can contain comments which start with #.\n", + "# If a line starts with # the whole line is a comment, however you can\n", + "# also start a comment after the package definition.\n", + "\n", + "#tensorflow-probability|0.9.0\n", + "xgboost|2.0.3\n", + "scikit-learn|1.5.0" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "custom_pip_file = slc_dir / flavor_path / \"flavor_customization\" / \"packages\" / \"python3_pip_packages\"\n", + "show_pip_file(custom_pip_file)" + ] + }, + { + "cell_type": "markdown", + "id": "5857a6fb-f0b7-413f-8ce5-88ced8645abb", + "metadata": {}, + "source": [ + "We are now going to append the \"xgboost\" Python package to one of the package lists by adding `xgboost|2.0.3` and `scikit-learn|1.5.0` to the `flavor_customization/packages/python3_pip_packages` file. (Note that running the following the command multiple times will iteratively append the packages)" + ] + }, + { + "cell_type": "code", + "execution_count": 146, + "id": "fe3db39f-5588-44a9-9e64-d4ec495423ee", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
# This file specifies the package list which gets installed via pip for python3.\n",
+       "# You must specify the the package and its version separated by a |.\n",
+       "# We recommend here the usage of package versions, to ensure that the container \n",
+       "# builds are reproducible. However, we allow also packages without version.\n",
+       "# As you can see, this file can contain comments which start with #.\n",
+       "# If a line starts with # the whole line is a comment, however you can\n",
+       "# also start a comment after the package definition.\n",
+       "\n",
+       "#tensorflow-probability|0.9.0\n",
+       "xgboost|2.0.3\n",
+       "scikit-learn|1.5.0\n",
+       "xgboost|2.0.3\n",
+       "scikit-learn|1.5.0\n",
+       "
\n" + ], + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\\PY{c+c1}{\\PYZsh{} This file specifies the package list which gets installed via pip for python3.}\n", + "\\PY{c+c1}{\\PYZsh{} You must specify the the package and its version separated by a |.}\n", + "\\PY{c+c1}{\\PYZsh{} We recommend here the usage of package versions, to ensure that the container }\n", + "\\PY{c+c1}{\\PYZsh{} builds are reproducible. However, we allow also packages without version.}\n", + "\\PY{c+c1}{\\PYZsh{} As you can see, this file can contain comments which start with \\PYZsh{}.}\n", + "\\PY{c+c1}{\\PYZsh{} If a line starts with \\PYZsh{} the whole line is a comment, however you can}\n", + "\\PY{c+c1}{\\PYZsh{} also start a comment after the package definition.}\n", + "\n", + "\\PY{c+c1}{\\PYZsh{}tensorflow\\PYZhy{}probability|0.9.0}\n", + "\\PY{n}{xgboost}\\PY{err}{|}\\PY{n}{2}\\PY{p}{.}\\PY{n}{0}\\PY{p}{.}\\PY{n}{3}\n", + "\\PY{n}{scikit\\PYZhy{}learn}\\PY{err}{|}\\PY{n}{1}\\PY{p}{.}\\PY{n}{5}\\PY{p}{.}\\PY{n}{0}\n", + "\\PY{n}{xgboost}\\PY{err}{|}\\PY{n}{2}\\PY{p}{.}\\PY{n}{0}\\PY{p}{.}\\PY{n}{3}\n", + "\\PY{n}{scikit\\PYZhy{}learn}\\PY{err}{|}\\PY{n}{1}\\PY{p}{.}\\PY{n}{5}\\PY{p}{.}\\PY{n}{0}\n", + "\\end{Verbatim}\n" + ], + "text/plain": [ + "# This file specifies the package list which gets installed via pip for python3.\n", + "# You must specify the the package and its version separated by a |.\n", + "# We recommend here the usage of package versions, to ensure that the container \n", + "# builds are reproducible. However, we allow also packages without version.\n", + "# As you can see, this file can contain comments which start with #.\n", + "# If a line starts with # the whole line is a comment, however you can\n", + "# also start a comment after the package definition.\n", + "\n", + "#tensorflow-probability|0.9.0\n", + "xgboost|2.0.3\n", + "scikit-learn|1.5.0\n", + "xgboost|2.0.3\n", + "scikit-learn|1.5.0" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "with open(custom_pip_file, \"a\") as f:\n", + " print(\"xgboost|2.0.3\", file=f)\n", + " print(\"scikit-learn|1.5.0\", file=f)\n", + "show_pip_file(custom_pip_file)" + ] + }, + { + "cell_type": "markdown", + "id": "834a2314-13ab-4ae8-bca5-9d1861376419", + "metadata": {}, + "source": [ + "#### Rebuilding the customized Flavor\n", + "After changing the flavor you need to rebuild it. You can do it by running `export` again. Exaslct automatically recognizes that the flavor has changed and builds a new version of the container." + ] + }, + { + "cell_type": "code", + "execution_count": 144, + "id": "2e7e9bbb-bf77-474f-949f-9521e9e3fd86", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ready\n" + ] + } + ], + "source": [ + "with working_directory(slc_dir):\n", + " export_result = exaslct_api.export(flavor_path=(str(flavor_path),), export_path=export_path)\n", + "print(\"Ready\")" + ] + }, + { + "cell_type": "markdown", + "id": "d0cec469-33de-4b1a-b481-735e69722c9f", + "metadata": {}, + "source": [ + "Note: Your old container doesn't get lost, because when you change a flavor your container gets a new hash code. If you revert your changes the system automatically uses the existing cached container. Below you can see the content of the cache directory for the containers." + ] + }, + { + "cell_type": "code", + "execution_count": 145, + "id": "f683dec3-101d-451d-b590-0518a8fdfdc9", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/home/jupyter/script_languages_release/.build_output/cache/exports/template-Exasol-all-python-3.10-release-BFRSH344TDRPT7LK2FBOJK4KBIDW6A253FFPYEUYT4O2ERFMTCNA.tar.gz\n", + "/home/jupyter/script_languages_release/.build_output/cache/exports/template-Exasol-all-python-3.10-release-LSTTMRG6XRKQIR2ABGJEPE564HLPUM7EGMG6LQPHCTGLTUZQIYZQ.tar.gz.sha512sum\n", + "/home/jupyter/script_languages_release/.build_output/cache/exports/template-Exasol-all-python-3.10-release-BFRSH344TDRPT7LK2FBOJK4KBIDW6A253FFPYEUYT4O2ERFMTCNA.tar.gz.sha512sum\n", + "/home/jupyter/script_languages_release/.build_output/cache/exports/template-Exasol-all-python-3.10-release-LSTTMRG6XRKQIR2ABGJEPE564HLPUM7EGMG6LQPHCTGLTUZQIYZQ.tar.gz\n" + ] + } + ], + "source": [ + "show_directory_content(build_output / \"cache\" / \"exports\")" + ] + }, + { + "cell_type": "markdown", + "id": "67f605e5-0fc6-4e9c-bf6a-1932d04ebdcc", + "metadata": {}, + "source": [ + "### Testing the new Script-Language Container\n", + "\n", + "Now, that we have an updated container, we need to check if our changes were successful. For that we are going to upload the container to an Exasol Database and have a look into it.\n", + "First we get the necessary information from the Secret Store." + ] + }, + { + "cell_type": "code", + "execution_count": 159, + "id": "edbe432c-5440-40f5-b9be-fd4aef89d5c3", + "metadata": {}, + "outputs": [], + "source": [ + "from exasol.nb_connector.ai_lab_config import AILabConfig as CKey, StorageBackend\n", + "bucketfs_name = ai_lab_config.get(CKey.bfs_service)\n", + "bucket_name = ai_lab_config.get(CKey.bfs_bucket)\n", + "database_host = ai_lab_config.get(CKey.bfs_host_name)\n", + "bucketfs_port = ai_lab_config.get(CKey.bfs_port)\n", + "bucketfs_username = ai_lab_config.get(CKey.bfs_user)\n", + "bucketfs_password = ai_lab_config.get(CKey.bfs_password)\n", + "\n", + "PATH_IN_BUCKET = \"container\"\n", + "RELEASE_NAME = \"current\"" + ] + }, + { + "cell_type": "markdown", + "id": "a44b4189-4842-41ce-85e7-f47d4c6ddcec", + "metadata": {}, + "source": [ + "#### Upload the Container to the Database\n", + "To use our container we need to upload it to the BucketFS . If the build machine has access to the BucketFS we can do it with the exaslct upload command, otherwise you need to export the container and transfer it to a machine that has access to the BucketFS and upload it via curl, as described in our documentation.\n", + "\n", + "With the following command we upload the new script language container.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 160, + "id": "28f7f45c-8d38-49c0-860a-132b4e8f12c4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Uploaded .build_output/cache/exports/template-Exasol-all-python-3.10-release-FGDQ7PIAQXFUH2MSD6JYBD2QBENYM7LXKGF5GXH6H4RWTXA7LZDA.tar.gz to\n", + "http://172.17.0.3:2580/default/container/template-Exasol-all-python-3.10-release-current.tar.gz\n", + "\n", + "\n", + "In SQL, you can activate the languages supported by the template-Exasol-all-python-3.10\n", + "flavor by using the following statements:\n", + "\n", + "\n", + "To activate the flavor only for the current session:\n", + "\n", + "ALTER SESSION SET SCRIPT_LANGUAGES='PYTHON3=localzmq+protobuf:///bfsdefault/default/container/template-Exasol-all-python-3.10-release-current?lang=python#buckets/bfsdefault/default/container/template-Exasol-all-python-3.10-release-current/exaudf/exaudfclient_py3';\n", + "\n", + "\n", + "To activate the flavor on the system:\n", + "\n", + "ALTER SYSTEM SET SCRIPT_LANGUAGES='PYTHON3=localzmq+protobuf:///bfsdefault/default/container/template-Exasol-all-python-3.10-release-current?lang=python#buckets/bfsdefault/default/container/template-Exasol-all-python-3.10-release-current/exaudf/exaudfclient_py3';\n", + "\n", + "=================================================\n", + "\n" + ] + } + ], + "source": [ + "with working_directory(slc_dir):\n", + " upload_result = exaslct_api.upload(flavor_path=(str(flavor_path),), database_host=database_host, bucketfs_name=bucketfs_name, \n", + " bucket_name=bucket_name, bucketfs_port=bucketfs_port, bucketfs_username=bucketfs_username, \n", + " bucketfs_password=bucketfs_password, path_in_bucket=PATH_IN_BUCKET, release_name=RELEASE_NAME)\n", + " \n", + " # The returned string contains the reference to output file containing information about how to use the uploaded container\n", + " tail_file(slc_dir / str(upload_result), 100)\n" + ] + }, + { + "cell_type": "markdown", + "id": "30014673-f03f-4f38-bd3f-5f9f27ad10b0", + "metadata": {}, + "source": [ + "#### Getting the language container activation statement without upload\n", + "Sometimes you can't use the upload command to upload your container to the BucketFS. To get the language activation statement regardless of that, you can use the generate-language-activation command. The API returns a tuple with 3 items:\n", + "- The ALTER SESSION SQL command to activate the container\n", + "- The ALTER SYSTEM SQL command to activate the container" + ] + }, + { + "cell_type": "code", + "execution_count": 180, + "id": "d2f3130b-70f5-44ce-8d27-aa1efe6aa545", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "In SQL, you can activate the languages supported by the template-Exasol-all-python-3.10\n", + "flavor by using the following statements:\n", + "\n", + "\n", + "To activate the flavor only for the current session:\n", + "\n", + "ALTER SESSION SET SCRIPT_LANGUAGES='PYTHON3=localzmq+protobuf:///bfsdefault/default/container/template-Exasol-all-python-3.10-release-current?lang=python#buckets/bfsdefault/default/container/template-Exasol-all-python-3.10-release-current/exaudf/exaudfclient_py3';\n", + "\n", + "\n", + "To activate the flavor on the system:\n", + "\n", + "ALTER SYSTEM SET SCRIPT_LANGUAGES='PYTHON3=localzmq+protobuf:///bfsdefault/default/container/template-Exasol-all-python-3.10-release-current?lang=python#buckets/bfsdefault/default/container/template-Exasol-all-python-3.10-release-current/exaudf/exaudfclient_py3';\n", + "\n" + ] + } + ], + "source": [ + "from IPython.display import JSON\n", + "import json\n", + "PATH_IN_BUCKET = \"container\"\n", + "with working_directory(slc_dir):\n", + " container_name = f\"{selected_flavor}-release-{RELEASE_NAME}\"\n", + " result = exaslct_api.generate_language_activation(flavor_path=flavor_path, bucketfs_name=bucketfs_name, \n", + " bucket_name=bucket_name, container_name=container_name,\n", + " path_in_bucket=PATH_IN_BUCKET)\n", + " alter_session_cmd = result[0]\n", + " alter_system_cmd = result[1]\n", + " explanation = result[2]\n", + " print(explanation)" + ] + }, + { + "cell_type": "markdown", + "id": "60ec9ae4-7b88-4840-8c07-f75a15b833c5", + "metadata": {}, + "source": [ + "#### Connecting to the database and activate the container\n", + "Once we have a connection to the database we run the ALTER SESSION statement or ALTER SYSTEM statement (if you want to activate the container permanently and globally) we got from the upload." + ] + }, + { + "cell_type": "code", + "execution_count": 177, + "id": "357caa4f-74ca-4d41-9157-04608a1a3c8c", + "metadata": {}, + "outputs": [ + { + "ename": "ExaQueryError", + "evalue": "\n(\n message => syntax error, unexpected '<', expecting FOR_ or LOOP_ or WHILE_ or REPEAT_ [line 1, column 1] (Session: 1802313923611066368)\n dsn => 172.17.0.3:8563\n user => sys\n schema => \n session_id => 1802313923611066368\n code => 42000\n query => <_io.TextIOWrapper name='/home/jupyter/script_languages_release/flavors/template-Exasol-all-python-3.10/flavor_customization/packages/python3_pip_packages' mode='a' encoding='UTF-8'>\n)\n", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mExaQueryError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[177], line 9\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m open_pyexasol_connection(ai_lab_config, compression\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m) \u001b[38;5;28;01mas\u001b[39;00m conn:\n\u001b[1;32m 6\u001b[0m \n\u001b[1;32m 7\u001b[0m \u001b[38;5;66;03m# Create tables\u001b[39;00m\n\u001b[1;32m 8\u001b[0m sql \u001b[38;5;241m=\u001b[39m f\n\u001b[0;32m----> 9\u001b[0m \u001b[43mconn\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mexecute\u001b[49m\u001b[43m(\u001b[49m\u001b[43mquery\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43msql\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/jupyterenv/lib/python3.10/site-packages/pyexasol/connection.py:194\u001b[0m, in \u001b[0;36mExaConnection.execute\u001b[0;34m(self, query, query_params)\u001b[0m\n\u001b[1;32m 189\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mexecute\u001b[39m(\u001b[38;5;28mself\u001b[39m, query, query_params\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m ExaStatement:\n\u001b[1;32m 190\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 191\u001b[0m \u001b[38;5;124;03m Execute SQL query with optional query formatting parameters\u001b[39;00m\n\u001b[1;32m 192\u001b[0m \u001b[38;5;124;03m Return ExaStatement object\u001b[39;00m\n\u001b[1;32m 193\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[0;32m--> 194\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcls_statement\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mquery\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mquery_params\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/jupyterenv/lib/python3.10/site-packages/pyexasol/statement.py:55\u001b[0m, in \u001b[0;36mExaStatement.__init__\u001b[0;34m(self, connection, query, query_params, prepare, meta_nosql, **options)\u001b[0m\n\u001b[1;32m 53\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_execute_meta_nosql()\n\u001b[1;32m 54\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m---> 55\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_execute\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/jupyterenv/lib/python3.10/site-packages/pyexasol/statement.py:157\u001b[0m, in \u001b[0;36mExaStatement._execute\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 156\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_execute\u001b[39m(\u001b[38;5;28mself\u001b[39m):\n\u001b[0;32m--> 157\u001b[0m ret \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mconnection\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mreq\u001b[49m\u001b[43m(\u001b[49m\u001b[43m{\u001b[49m\n\u001b[1;32m 158\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mcommand\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mexecute\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 159\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43msqlText\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mquery\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 160\u001b[0m \u001b[43m \u001b[49m\u001b[43m}\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 162\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mexecution_time \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mconnection\u001b[38;5;241m.\u001b[39mws_req_time\n\u001b[1;32m 163\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_init_result_set(ret)\n", + "File \u001b[0;32m~/jupyterenv/lib/python3.10/site-packages/pyexasol/connection.py:558\u001b[0m, in \u001b[0;36mExaConnection.req\u001b[0;34m(self, req)\u001b[0m\n\u001b[1;32m 555\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 556\u001b[0m cls_err \u001b[38;5;241m=\u001b[39m ExaQueryError\n\u001b[0;32m--> 558\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m cls_err(\u001b[38;5;28mself\u001b[39m, req[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124msqlText\u001b[39m\u001b[38;5;124m'\u001b[39m], ret[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mexception\u001b[39m\u001b[38;5;124m'\u001b[39m][\u001b[38;5;124m'\u001b[39m\u001b[38;5;124msqlCode\u001b[39m\u001b[38;5;124m'\u001b[39m], ret[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mexception\u001b[39m\u001b[38;5;124m'\u001b[39m][\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtext\u001b[39m\u001b[38;5;124m'\u001b[39m])\n\u001b[1;32m 559\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m req\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124musername\u001b[39m\u001b[38;5;124m'\u001b[39m) \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m 560\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m ExaAuthError(\u001b[38;5;28mself\u001b[39m, ret[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mexception\u001b[39m\u001b[38;5;124m'\u001b[39m][\u001b[38;5;124m'\u001b[39m\u001b[38;5;124msqlCode\u001b[39m\u001b[38;5;124m'\u001b[39m], ret[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mexception\u001b[39m\u001b[38;5;124m'\u001b[39m][\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtext\u001b[39m\u001b[38;5;124m'\u001b[39m])\n", + "\u001b[0;31mExaQueryError\u001b[0m: \n(\n message => syntax error, unexpected '<', expecting FOR_ or LOOP_ or WHILE_ or REPEAT_ [line 1, column 1] (Session: 1802313923611066368)\n dsn => 172.17.0.3:8563\n user => sys\n schema => \n session_id => 1802313923611066368\n code => 42000\n query => <_io.TextIOWrapper name='/home/jupyter/script_languages_release/flavors/template-Exasol-all-python-3.10/flavor_customization/packages/python3_pip_packages' mode='a' encoding='UTF-8'>\n)\n" + ] + } + ], + "source": [ + "from exasol.nb_connector.connections import open_pyexasol_connection\n", + "\n", + "\n", + "# Create an Exasol connection\n", + "with open_pyexasol_connection(ai_lab_config, compression=True) as conn:\n", + " \n", + " # Create tables\n", + " con.execut\n", + " con.execute(\"OPEN SCHEMA TEST\")\n", + " return con\n", + " conn.execute(query=sql)" + ] + }, { "cell_type": "code", "execution_count": null, - "id": "79be765f-7849-4bee-9397-18911c0c6735", + "id": "3cf9e4bb-97f6-4fef-8bed-f5bfa0a3c6b9", "metadata": {}, "outputs": [], "source": [] diff --git a/exasol/ds/sandbox/runtime/ansible/roles/jupyter/files/notebook/script_languages_container/utils/slc_ui.ipynb b/exasol/ds/sandbox/runtime/ansible/roles/jupyter/files/notebook/script_languages_container/utils/slc_ui.ipynb index 700c1d43..109e815a 100644 --- a/exasol/ds/sandbox/runtime/ansible/roles/jupyter/files/notebook/script_languages_container/utils/slc_ui.ipynb +++ b/exasol/ds/sandbox/runtime/ansible/roles/jupyter/files/notebook/script_languages_container/utils/slc_ui.ipynb @@ -106,7 +106,7 @@ " \"\"\"\n", " Creates a UI form for editing the Script-Languages-Container repository configuration.\n", " \"\"\"\n", - " default_target_dir = conf.get(slc_target_dir_store_key, '/home/jupyter')\n", + " default_target_dir = '/home/jupyter'\n", " target_dir_chooser_widget = FileChooser(path=default_target_dir, select_default=True)\n", " target_dir_chooser_widget.show_only_dirs = True\n", " \n",