From 820c6f21058c2d3ea31a99772ddbb24055e15b3f Mon Sep 17 00:00:00 2001 From: Prabhakar Kumar Date: Mon, 24 Jun 2024 10:16:00 +0530 Subject: [PATCH] Introducing install_guide/the-littlest-jupyterhub and a TLJH Plugin for MATLAB called tljh-matlab --- .github/workflows/publish-tljh-matlab.yml | 35 ++++ .github/workflows/test-tljh-matlab.yml | 48 ++++++ .../the-littlest-jupyterhub/README.md | 87 ++++++++++ .../tljh-matlab/.gitignore | 162 ++++++++++++++++++ .../tljh-matlab/LICENSE | 16 ++ .../tljh-matlab/README.md | 40 +++++ .../tljh-matlab/SECURITY.md | 4 + .../tljh-matlab/setup.py | 23 +++ .../tljh-matlab/src/__init__.py | 0 .../tljh-matlab/src/tests/__init__.py | 0 .../test_get_extra_apt_packages_for_matlab.py | 85 +++++++++ .../tljh-matlab/src/tljh_matlab/__init__.py | 0 .../bash_scripts/get-matlab-deps.sh | 19 ++ .../bash_scripts/install-matlab.sh | 36 ++++ .../get_extra_apt_packages_for_matlab.py | 118 +++++++++++++ .../src/tljh_matlab/install_matlab.py | 41 +++++ .../src/tljh_matlab/tljh_matlab.py | 54 ++++++ 17 files changed, 768 insertions(+) create mode 100644 .github/workflows/publish-tljh-matlab.yml create mode 100644 .github/workflows/test-tljh-matlab.yml create mode 100644 install_guides/the-littlest-jupyterhub/README.md create mode 100644 install_guides/the-littlest-jupyterhub/tljh-matlab/.gitignore create mode 100644 install_guides/the-littlest-jupyterhub/tljh-matlab/LICENSE create mode 100644 install_guides/the-littlest-jupyterhub/tljh-matlab/README.md create mode 100644 install_guides/the-littlest-jupyterhub/tljh-matlab/SECURITY.md create mode 100755 install_guides/the-littlest-jupyterhub/tljh-matlab/setup.py create mode 100644 install_guides/the-littlest-jupyterhub/tljh-matlab/src/__init__.py create mode 100644 install_guides/the-littlest-jupyterhub/tljh-matlab/src/tests/__init__.py create mode 100644 install_guides/the-littlest-jupyterhub/tljh-matlab/src/tests/test_get_extra_apt_packages_for_matlab.py create mode 100755 install_guides/the-littlest-jupyterhub/tljh-matlab/src/tljh_matlab/__init__.py create mode 100755 install_guides/the-littlest-jupyterhub/tljh-matlab/src/tljh_matlab/bash_scripts/get-matlab-deps.sh create mode 100755 install_guides/the-littlest-jupyterhub/tljh-matlab/src/tljh_matlab/bash_scripts/install-matlab.sh create mode 100644 install_guides/the-littlest-jupyterhub/tljh-matlab/src/tljh_matlab/get_extra_apt_packages_for_matlab.py create mode 100644 install_guides/the-littlest-jupyterhub/tljh-matlab/src/tljh_matlab/install_matlab.py create mode 100755 install_guides/the-littlest-jupyterhub/tljh-matlab/src/tljh_matlab/tljh_matlab.py diff --git a/.github/workflows/publish-tljh-matlab.yml b/.github/workflows/publish-tljh-matlab.yml new file mode 100644 index 000000000..234e29242 --- /dev/null +++ b/.github/workflows/publish-tljh-matlab.yml @@ -0,0 +1,35 @@ +# Copyright 2024 The MathWorks, Inc. +name: Upload Python Package for tljh-matlab + +on: + release: + types: [published] + +permissions: + contents: read + id-token: write + +jobs: + deploy: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v3 + with: + python-version: '3.x' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + cd ./install_guides/the-littlest-jupyterhub/tljh-matlab + pip install build + + - name: Build package + run: python -m build + + - name: Publish to PyPI. + uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/.github/workflows/test-tljh-matlab.yml b/.github/workflows/test-tljh-matlab.yml new file mode 100644 index 000000000..026f320f3 --- /dev/null +++ b/.github/workflows/test-tljh-matlab.yml @@ -0,0 +1,48 @@ +# Copyright 2024 The MathWorks, Inc. +name: Test TLJH-MATLAB package + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +permissions: + contents: read + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Set up Python 3.10 + uses: actions/setup-python@v3 + with: + python-version: "3.10" + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install flake8 black + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + + - name: Install Package + run: | + cd ./install_guides/the-littlest-jupyterhub/tljh-matlab + python -m pip install . + + - name: Lint with flake8 + run: | + # stop the build if there are Python syntax errors or undefined names + flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics + # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide + flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + + - name: Lint with black + run: black --check . + + - name: Test with unittest + run: | + python -m unittest discover --verbose diff --git a/install_guides/the-littlest-jupyterhub/README.md b/install_guides/the-littlest-jupyterhub/README.md new file mode 100644 index 000000000..424fef480 --- /dev/null +++ b/install_guides/the-littlest-jupyterhub/README.md @@ -0,0 +1,87 @@ +# Running MATLAB Integration for Jupyter on The Littlest JupyterHub in a Docker Container + +This guide customizes a **"The Littlest JupyterHub"** aka **TLJH** stack to include MATLAB, its dependencies and the MATLAB Integration for Jupyter. + +**TLJH** can run on several modern linux environments. For a full listing for the supported environements, See [Installing (TLJH)](https://tljh.jupyter.org/en/stable/install/index.html). + +The rest of this document will use the [Setting up Development Environment (TLJH)](https://tljh.jupyter.org/en/stable/contributing/dev-setup.html) to install TLJH in a Docker Container and customize it to include MATLAB and the MATLAB Integration for Jupyter. + +When completed, you will have access to a JupyterHub server running from within your Docker container, capable of serving Jupyter Notebook Servers for multiple users at `http://Your-FQDN:12000` + +Customize it to include MATLAB and the MATLAB Integration for Jupyter with the plugin `tljh-matlab` using the following command: + +```bash +python3 /srv/src/bootstrap/bootstrap.py --admin admin:password --plugin tljh-matlab +``` + +### Table of Contents +1. [Set up TLJH with Docker](#set-up-tljh-with-docker) +2. [Customize Installation to include MATLAB](#customize-installation-to-include-matlab) + + +## Set up TLJH with Docker + +The following lines are taken directly from [Setting up Development Environment (TLJH)](https://tljh.jupyter.org/en/stable/contributing/dev-setup.html) for your convenience. We **highly** recommend following the instruction directly from the link above. + +> The easiest & safest way to develop & test TLJH is with [Docker](https://www.docker.com/). +> +> 1. Install Docker Community Edition by following the instructions on [their website](https://www.docker.com/community-edition). +> 1. Clone the [git repo](https://github.com/jupyterhub/the-littlest-jupyterhub) (or your fork of it). +> +> 1. Build a docker image that has a functional systemd in it. +> ```bash +> git clone https://github.com/jupyterhub/the-littlest-jupyterhub && cd the-littlest-jupyterhub +> docker build -t tljh-systemd . -f integration-tests/Dockerfile +> ``` +> 1. Run a docker container with the image in the background, while bind mounting your TLJH repository under `/srv/src`. +> ```bash +> docker run \ +> --privileged \ +> --detach \ +> --name=tljh-dev \ +> --publish 12000:80 \ +> --mount type=bind,source="$(pwd)",target=/srv/src \ +> tljh-systemd +> ``` +> 1. Get a shell inside the running docker container. +> ```bash +> docker exec -it tljh-dev /bin/bash +> ``` +> 1. Run the bootstrapper from inside the container (see step above): The container image is already set up to default to a `dev` install, so it’ll install from your local repo rather than from github. +> ```bash +> python3 /srv/src/bootstrap/bootstrap.py --admin admin +> ``` +> 1. Or, if you would like to setup the admin’s password during install, you can use this command (replace “admin” with the desired admin username and “password” with the desired admin password): +> ```bash +> python3 /srv/src/bootstrap/bootstrap.py --admin admin:password +> ``` +> +> The primary hub environment will also be in your PATH already for convenience. +> +> You should be able to access the JupyterHub from your browser now at http://localhost:12000. +> +> **Congratulations**, you are set up to develop TLJH! +> + +## Customize Installation to include MATLAB +TLJH can install additional *plugins* to customize the installation. +See [Installing TLJH plugins](https://tljh.jupyter.org/en/stable/topic/customizing-installer.html) for more information. + +This repository publishes a python package `tljh-matlab` which installs MATLAB, its dependencies and the MATLAB integration for Jupyter into TLJH. + +To install the plugin, run the `bootstrap.py` script in `step 6.` from the previous section, as shown below: +```bash +python3 /srv/src/bootstrap/bootstrap.py --admin admin:password --plugin tljh-matlab +``` + + +Customize it using `tljh-matlab` ([TLJH Plugin](https://tljh.jupyter.org/en/stable/contributing/plugins.html) for MATLAB) + + +## Background Reading +### TLJH +A simple JupyterHub distribution for a small (0-100) number of users on a single server. + +Refer to the official documentation of [The Littlest JupyterHub](https://tljh.jupyter.org/en/stable/index.html) for more information on capabilities and installation guides. + +We recommend reading [When to use The Littlest JupyterHub](https://tljh.jupyter.org/en/stable/topic/whentouse.html) to determine if TLJH right tool for you. \ No newline at end of file diff --git a/install_guides/the-littlest-jupyterhub/tljh-matlab/.gitignore b/install_guides/the-littlest-jupyterhub/tljh-matlab/.gitignore new file mode 100644 index 000000000..efa407c35 --- /dev/null +++ b/install_guides/the-littlest-jupyterhub/tljh-matlab/.gitignore @@ -0,0 +1,162 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/latest/usage/project/#working-with-version-control +.pdm.toml +.pdm-python +.pdm-build/ + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ \ No newline at end of file diff --git a/install_guides/the-littlest-jupyterhub/tljh-matlab/LICENSE b/install_guides/the-littlest-jupyterhub/tljh-matlab/LICENSE new file mode 100644 index 000000000..5cdec65bc --- /dev/null +++ b/install_guides/the-littlest-jupyterhub/tljh-matlab/LICENSE @@ -0,0 +1,16 @@ +MATHWORKS CLOUD REFERENCE ARCHITECTURE LICENSE + +The files in this GitHub repository refer to commercial software products and services, virtual machine images, and related materials of The MathWorks, Inc. (“MathWorks Programs”). MathWorks Programs are separately licensed under the MathWorks Software License Agreement, available in the desktop installation of the MathWorks Programs or in the virtual machine image. The files in this GitHub repository may also refer to third-party software licensed under separate terms provided by such third parties. + +The following license terms apply only to the files in this GitHub repository, including files in this folder and its subfolders, and do not apply to MathWorks Programs. References to “software” and “code” in the following license terms refer to the files in this GitHub repository. + +Copyright (c) 2024, The MathWorks, Inc. + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +In all cases, the software is, and all modifications and derivatives of the software shall be, licensed to you solely for use in conjunction with MathWorks products and service offerings. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/install_guides/the-littlest-jupyterhub/tljh-matlab/README.md b/install_guides/the-littlest-jupyterhub/tljh-matlab/README.md new file mode 100644 index 000000000..951d22f63 --- /dev/null +++ b/install_guides/the-littlest-jupyterhub/tljh-matlab/README.md @@ -0,0 +1,40 @@ +# tljh-matlab + +TLJH plugin for [The Littlest JupyterHub](https://tljh.jupyter.org/) that installs MATLAB, and the MATLAB Integration for Jupyter. + +The [Littlest JupyterHub installation](https://tljh.jupyter.org/en/latest/topic/customizing-installer.html#installing-tljh-plugins) can install **plugins** that provide additional features, in the JupyterHub stack being provisioned. + +The `tljh-matlab` plugin installs: +* A specified version of MATLAB +* The system libraries required by MATLAB +* The MATLAB Integration for Jupyter, to enable the usage of MATLAB via Notebooks, and to access the MATLAB desktop from Jupyter. See [jupyter-matlab-proxy](github.com/mathworks/jupyter-matlab-proxy) for more information. + + +Command to install plugin: +```bash +docker run --privileged --detach --name=tljh-dev --publish 12000:80 --mount type=bind,source="$(pwd)",target=/srv/src tljh-systemd +docker exec -it tljh-dev /bin/bash +python3 /srv/src/bootstrap/bootstrap.py --admin admin:password --plugin tljh-matlab +``` + +To customize the default values used by the plugin , set the appropriate environment variable before the `bootstrap` command + +| Environment Variable Name | Default Values | Notes| +|--|--|--| +| MATLAB_RELEASE | R2024a | Specify the MATLAB release you would like to install | +| MATLAB_PRODUCT_LIST | "MATLAB Symbolic_Math_Toolbox" | See `--products` section of [MPM.md](https://github.com/mathworks-ref-arch/matlab-dockerfile/blob/main/MPM.md) for information on the supported products and their name specification. For example to install Simulink along with MATLAB use `"MATLAB Simulink"` | +|MATLAB_INSTALL_DESTINATION| /opt/matlab/R2024a | Specify the path to the location you would like to install MATLAB | +| OS | ubuntu22.04 | See [matlab-deps](https://github.com/mathworks-ref-arch/container-images/tree/main/matlab-deps/r2024a) for the list of supported OS values by Release.| + +Example: +```bash +env MATLAB_RELEASE=R2023b MATLAB_PRODUCT_LIST="MATLAB Simulink" python3 /srv/src/bootstrap/bootstrap.py --admin admin:password --plugin tljh-matlab +``` + + + +---- + +Copyright 2024 The MathWorks, Inc. + +---- \ No newline at end of file diff --git a/install_guides/the-littlest-jupyterhub/tljh-matlab/SECURITY.md b/install_guides/the-littlest-jupyterhub/tljh-matlab/SECURITY.md new file mode 100644 index 000000000..986ee9e98 --- /dev/null +++ b/install_guides/the-littlest-jupyterhub/tljh-matlab/SECURITY.md @@ -0,0 +1,4 @@ +# Reporting Security Vulnerabilities + +If you believe you have discovered a security vulnerability, please report it to +[security@mathworks.com](mailto:security@mathworks.com). For more information, see [MathWorks Vulnerability Disclosure Policy for Security Researchers](https://www.mathworks.com/company/aboutus/policies_statements/vulnerability-disclosure-policy.html). \ No newline at end of file diff --git a/install_guides/the-littlest-jupyterhub/tljh-matlab/setup.py b/install_guides/the-littlest-jupyterhub/tljh-matlab/setup.py new file mode 100755 index 000000000..1e2e0f3b5 --- /dev/null +++ b/install_guides/the-littlest-jupyterhub/tljh-matlab/setup.py @@ -0,0 +1,23 @@ +# Copyright 2024 The MathWorks, Inc. +from setuptools import setup, find_namespace_packages +from pathlib import Path + +HERE = Path(__file__).parent.resolve() +long_description = (HERE / "README.md").read_text() + +setup( + name="tljh-matlab", + entry_points={"tljh": ["matlab = tljh_matlab.tljh_matlab"]}, + version="0.0.5", + packages=find_namespace_packages(where="src"), + package_dir={"": "src"}, + package_data={"tljh_matlab.bash_scripts": ["*.sh"]}, + include_package_data=True, + long_description=long_description, + long_description_content_type="text/markdown", + url="https://github.com/prabhakk-mw/tljh-matlab", + author="The MathWorks, Inc.", + author_email="cloud@mathworks.com", + license="MATHWORKS CLOUD REFERENCE ARCHITECTURE LICENSE", + description="TLJH plugin for MATLAB", +) diff --git a/install_guides/the-littlest-jupyterhub/tljh-matlab/src/__init__.py b/install_guides/the-littlest-jupyterhub/tljh-matlab/src/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/install_guides/the-littlest-jupyterhub/tljh-matlab/src/tests/__init__.py b/install_guides/the-littlest-jupyterhub/tljh-matlab/src/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/install_guides/the-littlest-jupyterhub/tljh-matlab/src/tests/test_get_extra_apt_packages_for_matlab.py b/install_guides/the-littlest-jupyterhub/tljh-matlab/src/tests/test_get_extra_apt_packages_for_matlab.py new file mode 100644 index 000000000..452cebcfb --- /dev/null +++ b/install_guides/the-littlest-jupyterhub/tljh-matlab/src/tests/test_get_extra_apt_packages_for_matlab.py @@ -0,0 +1,85 @@ +# Copyright 2024 The MathWorks, Inc. + +from tljh_matlab import get_extra_apt_packages_for_matlab as testmodule +import unittest +from unittest import mock +import os + + +class TestGetExtraAptPackagesForMATLAB(unittest.TestCase): + extra_apt_packages = [ + "wget", + "unzip", + "ca-certificates", + "xvfb", + "git", + ] + + # List of dependencies specifically required for MATLAB R2024a. + # This list includes both the basic packages and those specifically needed for MATLAB R2024a on a Ubuntu 22.04 system. + matlab_deps_for_r2024a = extra_apt_packages + [ + "ca-certificates", + "libasound2", + "libc6", + "libcairo-gobject2", + "libcairo2", + "libcap2", + "libcups2", + "libdrm2", + "libfontconfig1", + "libgbm1", + "libgdk-pixbuf-2.0-0", + "libgl1", + "libglib2.0-0", + "libgstreamer-plugins-base1.0-0", + "libgstreamer1.0-0", + "libgtk-3-0", + "libice6", + "libltdl7", + "libnspr4", + "libnss3", + "libpam0g", + "libpango-1.0-0", + "libpangocairo-1.0-0", + "libpangoft2-1.0-0", + "libsndfile1", + "libudev1", + "libuuid1", + "libwayland-client0", + "libxcomposite1", + "libxcursor1", + "libxdamage1", + "libxfixes3", + "libxft2", + "libxinerama1", + "libxrandr2", + "libxt6", + "libxtst6", + "libxxf86vm1", + "locales", + "locales-all", + "make", + "net-tools", + "procps", + "sudo", + "unzip", + "zlib1g", + ] + + def test_get_extra_apt_packages_for_matlab(self): + extra_packages = testmodule.get_extra_apt_packages_for_matlab_impl() + assert extra_packages == self.matlab_deps_for_r2024a + + def test_get_packages_for_invalid_release(self): + with mock.patch.dict(os.environ, {"MATLAB_RELEASE": "R2030a"}): + with self.assertRaises(Exception) as context: + testmodule.get_extra_apt_packages_for_matlab_impl() + + self.assertTrue( + "Invalid Release or OS Specified to fetch matlab-deps" + in context.exception + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/install_guides/the-littlest-jupyterhub/tljh-matlab/src/tljh_matlab/__init__.py b/install_guides/the-littlest-jupyterhub/tljh-matlab/src/tljh_matlab/__init__.py new file mode 100755 index 000000000..e69de29bb diff --git a/install_guides/the-littlest-jupyterhub/tljh-matlab/src/tljh_matlab/bash_scripts/get-matlab-deps.sh b/install_guides/the-littlest-jupyterhub/tljh-matlab/src/tljh_matlab/bash_scripts/get-matlab-deps.sh new file mode 100755 index 000000000..dbd87aaaa --- /dev/null +++ b/install_guides/the-littlest-jupyterhub/tljh-matlab/src/tljh_matlab/bash_scripts/get-matlab-deps.sh @@ -0,0 +1,19 @@ +#!/bin/bash +# Copyright 2024 The MathWorks, Inc. + +# Example invocation: +# subprocess.call(["bash", "/mathworks/devel/sandbox/prabhakk/cit/jupyter/tljh/the-littlest-jupyterhub/tljh_matlab/get-matlab-deps"], +# env={"MATLAB_RELEASE":"R2024a", "OUTPUT_FILE":"myfile.txt", "OS":"ubuntu20.04"}) + +# Set the default release to R2024a. +MATLAB_RELEASE="${MATLAB_RELEASE:-"r2024a"}" +# Lowercase first letter, to form correct URL +MATLAB_RELEASE="${MATLAB_RELEASE,}" + +# Set the default OS to ubuntu22.04 +OS="${OS:-"ubuntu22.04"}" + +MATLAB_DEPS_REQUIREMENTS_FILE="https://raw.githubusercontent.com/mathworks-ref-arch/container-images/main/matlab-deps/${MATLAB_RELEASE}/${OS}/base-dependencies.txt" + +echo "Fetching dependencies for ${MATLAB_RELEASE}" +curl -O -s ${MATLAB_DEPS_REQUIREMENTS_FILE} diff --git a/install_guides/the-littlest-jupyterhub/tljh-matlab/src/tljh_matlab/bash_scripts/install-matlab.sh b/install_guides/the-littlest-jupyterhub/tljh-matlab/src/tljh_matlab/bash_scripts/install-matlab.sh new file mode 100755 index 000000000..34af5dbbe --- /dev/null +++ b/install_guides/the-littlest-jupyterhub/tljh-matlab/src/tljh_matlab/bash_scripts/install-matlab.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# Copyright 2024 The MathWorks, Inc. + +# Example invocation: +# subprocess.call(["bash", "/mathworks/devel/sandbox/prabhakk/cit/jupyter/tljh/the-littlest-jupyterhub/tljh_matlab/install-matlab.sh"], +# env={"MATLAB_RELEASE":"R2024a", "MATLAB_PRODUCT_LIST":"MATLAB Simulink"}) + +# Set the default release to R2024a. +MATLAB_RELEASE="${MATLAB_RELEASE:-"R2024a"}" +# Uppercase first letter +MATLAB_RELEASE=${MATLAB_RELEASE^} + +# Set the default product list to only install MATLAB. +MATLAB_PRODUCT_LIST="${MATLAB_PRODUCT_LIST:-"MATLAB"}" + +MATLAB_INSTALL_DESTINATION="${MATLAB_INSTALL_DESTINATION:-"/opt/matlab/${MATLAB_RELEASE}"}" + +echo "Installing..." +echo "MATLAB_RELEASE: $MATLAB_RELEASE" +echo "MATLAB_PRODUCT_LIST: $MATLAB_PRODUCT_LIST" +echo "MATLAB_INSTALL_DESTINATION: $MATLAB_INSTALL_DESTINATION" + +echo "Installing MPM dependencies..." + +apt-get update && apt-get install curl ca-certificates unzip + +# Run mpm to install MATLAB in the target location and move mpm into /opt/matlab +curl -L -O https://www.mathworks.com/mpm/glnxa64/mpm && + chmod +x mpm && + ./mpm install \ + --release=${MATLAB_RELEASE} \ + --destination=${MATLAB_INSTALL_DESTINATION} \ + --products ${MATLAB_PRODUCT_LIST} && + rm -f /tmp/mathworks_root.log && + mv mpm $(dirname $MATLAB_INSTALL_DESTINATION) && + ln -s ${MATLAB_INSTALL_DESTINATION}/bin/matlab /usr/local/bin/matlab diff --git a/install_guides/the-littlest-jupyterhub/tljh-matlab/src/tljh_matlab/get_extra_apt_packages_for_matlab.py b/install_guides/the-littlest-jupyterhub/tljh-matlab/src/tljh_matlab/get_extra_apt_packages_for_matlab.py new file mode 100644 index 000000000..2163ea7ba --- /dev/null +++ b/install_guides/the-littlest-jupyterhub/tljh-matlab/src/tljh_matlab/get_extra_apt_packages_for_matlab.py @@ -0,0 +1,118 @@ +# Copyright 2024 The MathWorks, Inc. + +# @package get_extra_apt_packages_for_matlab +# This module is designed to manage the dependencies required for setting +# up a MATLAB environment for the R2024a release. It includes functionalities to dynamically +# fetch and list additional apt packages necessary for the installation on a Ubuntu 22.04 system. + +import subprocess +import os + +# List of basic extra apt packages required for MATLAB setup. +# These are the fundamental packages needed across different MATLAB releases and setups. +extra_apt_packages = [ + "wget", + "unzip", + "ca-certificates", + "xvfb", + "git", +] + +# List of dependencies specifically required for MATLAB R2024a. +# This list includes both the basic packages and those specifically needed for MATLAB R2024a on a Ubuntu 22.04 system. +matlab_deps_for_r2024a = extra_apt_packages + [ + "ca-certificates", + "libasound2", + "libc6", + "libcairo-gobject2", + "libcairo2", + "libcap2", + "libcups2", + "libdrm2", + "libfontconfig1", + "libgbm1", + "libgdk-pixbuf-2.0-0", + "libgl1", + "libglib2.0-0", + "libgstreamer-plugins-base1.0-0", + "libgstreamer1.0-0", + "libgtk-3-0", + "libice6", + "libltdl7", + "libnspr4", + "libnss3", + "libpam0g", + "libpango-1.0-0", + "libpangocairo-1.0-0", + "libpangoft2-1.0-0", + "libsndfile1", + "libudev1", + "libuuid1", + "libwayland-client0", + "libxcomposite1", + "libxcursor1", + "libxdamage1", + "libxfixes3", + "libxft2", + "libxinerama1", + "libxrandr2", + "libxt6", + "libxtst6", + "libxxf86vm1", + "locales", + "locales-all", + "make", + "net-tools", + "procps", + "sudo", + "unzip", + "zlib1g", +] + + +# Retrieves the list of extra apt packages required for The Littlest JupyterHub (TLJH) setup with MATLAB dependencies. +# This function dynamically fetches the dependencies by executing a bash script and reading its output. +# In case of any failure, it defaults to returning a static list of dependencies for MATLAB R2024a. +# @return Returns a list of apt package dependencies. +def get_extra_apt_packages_for_matlab_impl(): + + try: + script = os.path.join( + os.path.dirname(__file__), "bash_scripts/get-matlab-deps.sh" + ) + result = subprocess.call( + [ + "bash", + script, + ], + env={ + "MATLAB_RELEASE": os.environ.get("MATLAB_RELEASE", "R2024a"), + "OS": "ubuntu22.04", + }, + ) + + if result == 0: + # No error, read file + deps_file = "base-dependencies.txt" + + with open(deps_file) as f: + matlab_deps = f.read().splitlines() + + if "404: Not Found" in matlab_deps: + raise Exception("Invalid Release or OS Specified to fetch matlab-deps") + print(f"extra libs: ${matlab_deps}") + + # Drool clean + os.remove(deps_file) + + return extra_apt_packages + matlab_deps + else: + # In case the bash script above fails, return a list for R2024a + return matlab_deps_for_r2024a + except Exception as err: + print(f"Unexpected {err=}, {type(err)=}") + print("Returning dependencies for ubuntu22.04 and MATLAB R2024a") + raise err + + +get_extra_apt_packages_for_matlab_impl() diff --git a/install_guides/the-littlest-jupyterhub/tljh-matlab/src/tljh_matlab/install_matlab.py b/install_guides/the-littlest-jupyterhub/tljh-matlab/src/tljh_matlab/install_matlab.py new file mode 100644 index 000000000..af8457e36 --- /dev/null +++ b/install_guides/the-littlest-jupyterhub/tljh-matlab/src/tljh_matlab/install_matlab.py @@ -0,0 +1,41 @@ +# Copyright 2024 The MathWorks, Inc. + +import subprocess +import os + +# @package install_matlab +# This module provides functionalities to install MATLAB using a bash script. + + +def install_matlab_impl(): + """ + @brief Installs MATLAB using a predefined bash script. + + This function constructs the path to a bash script responsible for installing MATLAB and executes it. + The MATLAB release and product list are specified through environment variables. If not present, defaults are used. + + @param None + @return None + """ + # Construct the path to the install script + script = os.path.join(os.path.dirname(__file__), "bash_scripts/install-matlab.sh") + + # Call the bash script with environment variables + subprocess.call( + [ + "bash", + script, + ], + env={ + # Default to R2024a if not specified + "MATLAB_RELEASE": os.environ.get("MATLAB_RELEASE", "R2024a"), + # Default products if not specified + "MATLAB_PRODUCT_LIST": os.environ.get( + "MATLAB_PRODUCT_LIST", "MATLAB Symbolic_Math_Toolbox" + ), + }, + ) + + +# Execute the install function +install_matlab_impl() diff --git a/install_guides/the-littlest-jupyterhub/tljh-matlab/src/tljh_matlab/tljh_matlab.py b/install_guides/the-littlest-jupyterhub/tljh-matlab/src/tljh_matlab/tljh_matlab.py new file mode 100755 index 000000000..3abda3dbb --- /dev/null +++ b/install_guides/the-littlest-jupyterhub/tljh-matlab/src/tljh_matlab/tljh_matlab.py @@ -0,0 +1,54 @@ +# Copyright 2024 The MathWorks, Inc. + +""" +MATLAB plugin that installs MATLAB, its dependencies and the MATLAB Integration for Jupyter +""" + +from tljh.hooks import hookimpl + +from . import get_extra_apt_packages_for_matlab +from . import install_matlab + + +@hookimpl +def tljh_extra_user_pip_packages(): + return ["jupyter-matlab-proxy"] + + +@hookimpl +def tljh_extra_apt_packages(): + return get_extra_apt_packages_for_matlab.get_extra_apt_packages_for_matlab_impl() + + +@hookimpl +def tljh_post_install(): + """ + Post install script to be executed after installation + and after all the other hooks. + + This can be arbitrary Python code. + """ + install_matlab.install_matlab_impl() + + +# @hookimpl +# def tljh_custom_jupyterhub_config(c): +# # c.Test.jupyterhub_config_set_by_matlab_plugin = True +# # c.JupyterHub.services.cull.every = 60 +# # c.JupyterHub.services.cull.timeout = 180 +# # # Dont set a max age, and dont cull users (these are default anyways) +# # c.JupyterHub.services.cull.max_age = 0 +# # c.JupyterHub.services.cull.users = False +# # c.JupyterHub.services.cull.users = False + + +# @hookimpl +# def tljh_config_post_install(config): +# config["Test"] = {"tljh_config_set_by_matlab_plugin": True} + + +# @hookimpl +# def tljh_new_user_create(username): +# with open("test_new_user_create", "w") as f: +# f.write("tljh_config_set_by_matlab_plugin") +# f.write(username)