From 655a108330ab057b670676cc2e15f74cc205d36e Mon Sep 17 00:00:00 2001 From: Matthieu Simonin <matthieu.simonin@inria.fr> Date: Wed, 12 Jun 2024 18:03:24 +0200 Subject: [PATCH] Refreshing tutorials --- g5k/00_setup_and_basics.ipynb | 475 ------------------ ...y.ipynb => 03_observability_service.ipynb} | 345 ++++++------- ...ation.ipynb => 04_network_emulation.ipynb} | 95 +++- ....ipynb => 05_using_several_networks.ipynb} | 34 +- ..._working_with_virtualized_resources.ipynb} | 20 +- ...estrators.ipynb => 07_orchestrators.ipynb} | 23 +- ...ervice.ipynb => 08_planning_service.ipynb} | 29 +- ...nb => 09_planning_service_revisited.ipynb} | 24 +- 8 files changed, 317 insertions(+), 728 deletions(-) delete mode 100644 g5k/00_setup_and_basics.ipynb rename g5k/{02_observability.ipynb => 03_observability_service.ipynb} (84%) rename g5k/{05_network_emulation.ipynb => 04_network_emulation.ipynb} (73%) rename g5k/{03_using_several_networks.ipynb => 05_using_several_networks.ipynb} (97%) rename g5k/{04_working_with_virtualized_resources.ipynb => 06_working_with_virtualized_resources.ipynb} (96%) rename g5k/{06_orchestrators.ipynb => 07_orchestrators.ipynb} (95%) rename g5k/{07_planning_service.ipynb => 08_planning_service.ipynb} (91%) rename g5k/{08_planning_service_revisited.ipynb => 09_planning_service_revisited.ipynb} (97%) diff --git a/g5k/00_setup_and_basics.ipynb b/g5k/00_setup_and_basics.ipynb deleted file mode 100644 index c1a8c38..0000000 --- a/g5k/00_setup_and_basics.ipynb +++ /dev/null @@ -1,475 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "direct-johnston", - "metadata": { - "tags": [] - }, - "source": [ - "# Setup and basic objects\n", - "\n", - "Get started with EnOSlib on Grid'5000.\n", - "\n", - "---\n", - "\n", - "- Website: https://discovery.gitlabpages.inria.fr/enoslib/index.html\n", - "- Instant chat: https://framateam.org/enoslib\n", - "- Source code: https://gitlab.inria.fr/discovery/enoslib\n", - "\n", - "---\n", - "\n", - "This is the first notebook in a serie that will let you discover the main features of EnOSlib on Grid'5000.\n", - "\n", - "If you want to actually execute them you'll need to setup your environment properly.\n", - "We sum up here the different steps to achieve this process.\n", - "\n", - "1. Get a Grid'5000 account\n", - " - Register using this [page](https://www.grid5000.fr/w/Grid5000:Get_an_account).\n", - " Pay attention to the fact that uploading a SSH key (public part) is mandatory to perform any EnOSlib action from your local machine.\n", - " - Make sure the SSH connection is ready. You can follow this [tutorial](https://www.grid5000.fr/w/Getting_Started).\n", - "2. Make sure EnOSlib is available in your notebook environment\n", - " - Follow the steps [here](https://discovery.gitlabpages.inria.fr/enoslib/tutorials/grid5000.html#installation).\n", - " Using a virtualenv is the way to go, make sure to use one.\n", - " Also adding the optional `jupyter` will improve your experience. (`pip install enoslib[jupyter]`)\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "ceramic-burst", - "metadata": {}, - "source": [ - "## Testing the import" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "thorough-maker", - "metadata": {}, - "outputs": [], - "source": [ - "import enoslib as en" - ] - }, - { - "cell_type": "markdown", - "id": "civilian-determination", - "metadata": { - "tags": [] - }, - "source": [ - "## Resources abstractions\n", - "\n", - "In this notebook, we won't execute anything remotely. Instead we'll just cover some basic abstractions provided by the library.\n", - "We start with the abstractions of resources (machines and networks that are usually given by an infrastructure)\n", - "\n", - "\n", - "### Host\n", - "\n", - "An host is anything we can connect to and act on. Most of the time it corresponds to a machine reachable through SSH.\n", - "The datastructure reflects this.\n", - "\n", - "Usually you don't instantiate hosts manually, instead they are brought to you by EnOSlib (because most likely they depend on a scheduler decision like OAR on Grid'5000).\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cleared-presence", - "metadata": {}, - "outputs": [], - "source": [ - "bare_host = en.Host(\"192.168.0.1\")\n", - "host_with_alias = en.Host(\"192.168.0.2\", alias=\"one_alias\")\n", - "host_with_alias_and_username = en.Host(\"192.168.0.3\", alias=\"one_alias\", user=\"foo\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "peripheral-campus", - "metadata": {}, - "outputs": [], - "source": [ - "bare_host" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "unlikely-credits", - "metadata": {}, - "outputs": [], - "source": [ - "host_with_alias" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "empty-privilege", - "metadata": {}, - "outputs": [], - "source": [ - "host_with_alias_and_username" - ] - }, - { - "cell_type": "markdown", - "id": "attractive-stationery", - "metadata": {}, - "source": [ - "The local machine can be represented by an instance of the `LocalHost` object. This is a specialization of an `Host`, the connection to this host will be made using sub-processes (instead of SSH). We can see it in the `extra` attribute of the `LocalHost` object. This `extra` attribute is actually interpreted when a \"remote\" action is triggered on our hosts." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "dental-population", - "metadata": {}, - "outputs": [], - "source": [ - "localhost = en.LocalHost()\n", - "localhost" - ] - }, - { - "cell_type": "markdown", - "id": "temporal-adaptation", - "metadata": {}, - "source": [ - "Other types of Hosts are possible. The library has a `DockerHost` which represents a docker container we want to reach using the docker TCP protocol. One needs to specify where this container is running by passing an host instance." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "educational-conviction", - "metadata": {}, - "outputs": [], - "source": [ - "docker_host = en.DockerHost(\"alias\", \"container_name\", host_with_alias_and_username)\n", - "docker_host" - ] - }, - { - "cell_type": "markdown", - "id": "executive-liberia", - "metadata": {}, - "source": [ - "The above `extra` field suggest that the connection to this docker container will be made through an ssh jump to the remote host hosting the container.\n", - "This will be done transparently by the library anyway.\n", - "\n", - "---" - ] - }, - { - "cell_type": "markdown", - "id": "exceptional-techno", - "metadata": {}, - "source": [ - "### Roles" - ] - }, - { - "cell_type": "markdown", - "id": "tight-request", - "metadata": {}, - "source": [ - "A common pratice when experimenting, especially with distributed applications, is to form logical group of machines.\n", - "Indeed, during an experiment your hosts will serve different purposes: some will host the system you are studying while other will install third party tools to inject some load, observe ...\n", - "\n", - "A natural way of configuring differently several sets of hosts is to tag them and group them according to their tags.\n", - "\n", - "The `Roles` datastructure serves this purpose: it lets you group your hosts based on tags. It follow a `dict-like` interface." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "spatial-probe", - "metadata": {}, - "outputs": [], - "source": [ - "h1 = en.Host(\"10.0.0.1\")\n", - "h2 = en.Host(\"10.0.0.2\")\n", - "h3 = en.Host(\"10.0.0.3\")\n", - "roles = en.Roles()\n", - "roles[\"tag1\"] = [h1, h2]\n", - "roles[\"tag2\"] = [h3]\n", - "roles[\"tag3\"] = [h2, h3]\n", - "\n", - "roles" - ] - }, - { - "cell_type": "markdown", - "id": "adapted-apparatus", - "metadata": {}, - "source": [ - "### Network and Networks\n", - "\n", - "`Network` and `Networks` are the same as `Host` and `Roles` but for networks:\n", - "\n", - "- `Network` represent a single Network\n", - "- `Networks` represent a \"Roles\" of Network: networks indexed by their tags\n", - ".\n", - "\n", - "Networks are usually given by an infrastructure and thus you won't really instantiate `Network` nor `Networks` by yourself.\n", - "More precisely there exists a specific subclass of `Network` per infrastructure which will be returned automatically by EnOSlib when needed.\n", - "\n", - "Moreover `Network` datastructure isn't exposed in EnOSlib at the top level, let's see however how a `DefaultNetwork` can look like. A `DefaultNetwork` is a very common abstraction of a network that allows to represent a basic network with optionnally a pool of free ips/macs address. For instance a subnet or a vlan on Grid5000 are represented by a specific `DefaultNetwork`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "distributed-ceramic", - "metadata": {}, - "outputs": [], - "source": [ - "from enoslib.objects import DefaultNetwork" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "empirical-somewhere", - "metadata": {}, - "outputs": [], - "source": [ - "one_network = DefaultNetwork(\"192.168.1.0/24\")\n", - "one_network_with_a_pool_of_ips = DefaultNetwork(\"192.168.1.0/24\", ip_start=\"192.168.1.10\", ip_end=\"192.168.1.100\") " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "stone-boxing", - "metadata": {}, - "outputs": [], - "source": [ - "one_network" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "aerial-coral", - "metadata": {}, - "outputs": [], - "source": [ - "one_network_with_a_pool_of_ips" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "appreciated-preservation", - "metadata": {}, - "outputs": [], - "source": [ - "# get one free ip\n", - "ip_gen = one_network_with_a_pool_of_ips.free_ips\n", - "next(ip_gen)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "determined-township", - "metadata": {}, - "outputs": [], - "source": [ - "# get another one\n", - "next(ip_gen)" - ] - }, - { - "cell_type": "markdown", - "id": "9ab4929f-1c39-46ca-b6ac-ae0b907cc3ed", - "metadata": {}, - "source": [ - "## Providers (and their configurations)\n", - "\n", - "EnOSlib uses `Provider`s to ... provide resources. \n", - "`Provider`s let the user get ownership of some resources (for the time of the experiment) in good shape (e.g access granted, network configured ...). \n", - "They transform an abstract `Configuration` to `Roles, Networks` : \n", - "\n", - "\n", - "$Configuration \\xrightarrow{provider} Roles, Networks$\n", - "\n", - "\n", - "There are different providers in EnOSlib: \n", - "\n", - "\n", - "- **Vbox/KVM** to work with locally hosted virtual machines\n", - "- **Openstack/Chameleon** to work with bare-metal resources hosted in the Chameleon platform\n", - "- **FiT/IOT lab** to work with sensors or low profile machines\n", - "- **Grid'5000** to get bare-metal resources from G5k.<br/>\n", - " There are also some composite providers that sit on top of the Grid'5000 provider\n", - " \n", - " - **VmonG5k** to work with virtual machines on Grid'5000**\n", - " - **Distem** to work with lxc containers on Grid'5000**\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "67a8c47b-5b0e-4e51-b17c-2ba3fd3d0d12", - "metadata": {}, - "source": [ - "### Configurations\n", - "\n", - "A `Provider` must be fed with a `Configuration`. `Configuration` objects are specific to each provider.\n", - "\n", - "You can build them from a dictionnary (e.g from a yaml/json file) or programmatically. For instance the schema for Grid'5000 is [here](https://discovery.gitlabpages.inria.fr/enoslib/apidoc/infra.html#g5k-schema).\n", - "\n", - "In this section, we'll only build some configurations (No resource will be reserved on Grid'5000)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fef3970b-5d7a-4e18-bc6f-59d944396e83", - "metadata": {}, - "outputs": [], - "source": [ - "import enoslib as en\n", - "\n", - "# An empty configuration isn't really useful but let you see\n", - "# some of the default parameters\n", - "# Note that by default (empty job_type) the nodes are provisioned\n", - "# with the standard Grid'5000 software environment.\n", - "conf = en.G5kConf()\n", - "conf" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ecdde599-41c3-420b-9ac9-88a1842cdfe4", - "metadata": {}, - "outputs": [], - "source": [ - "# changing the top level options is done by calling the classmethod `from_settings`\n", - "en.G5kConf.from_settings(walltime=\"10:00:00\", job_name=\"my awesome job\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "98ecf1f3-027f-4754-baed-7a7188990868", - "metadata": {}, - "outputs": [], - "source": [ - "# the canonical way of getting some machines" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4e95e4ef-442f-4364-bfdf-f0c7f8271027", - "metadata": {}, - "outputs": [], - "source": [ - "prod_network = en.G5kNetworkConf(roles=[\"mynetwork\"], site=\"rennes\", type=\"prod\")\n", - "conf = (\n", - " en.G5kConf()\n", - " .add_machine(cluster=\"paravance\", nodes=3, roles=[\"role1\", \"role2\"], primary_network=prod_network)\n", - " .add_machine(cluster=\"parasilo\", nodes=3, roles=[\"role2\", \"role3\"], primary_network=prod_network)\n", - " .add_network_conf(prod_network)\n", - " # optional, but do some sanity checks on the configuration \n", - " .finalize()\n", - " )\n", - "conf" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "08d69a20-a7f0-453c-a066-5b1304913d9e", - "metadata": {}, - "outputs": [], - "source": [ - "# Changing to a deploy job.\n", - "# The operating system to deploy needs to be selected (debian, ubuntu, centos...)\n", - "# See https://www.grid5000.fr/w/Advanced_Kadeploy#Search_an_environment\n", - "prod_network = en.G5kNetworkConf(roles=[\"mynetwork\"], site=\"rennes\", type=\"prod\")\n", - "conf = (\n", - " en.G5kConf.from_settings(job_type=[\"deploy\"], env_name=\"ubuntu2204-min\")\n", - " .add_machine(cluster=\"paravance\", nodes=3, roles=[\"role1\", \"role2\"], primary_network=prod_network)\n", - " .add_machine(cluster=\"parasilo\", nodes=3, roles=[\"role2\", \"role3\"], primary_network=prod_network)\n", - " .add_network_conf(prod_network)\n", - " # optional, but do some sanity checks on the configuration \n", - " .finalize()\n", - " )\n", - "conf" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a6eb4609-a873-4bd6-8cd4-06b56ff670a4", - "metadata": {}, - "outputs": [], - "source": [ - "# Using a secondary networks\n", - "prod_network = en.G5kNetworkConf(roles=[\"mynetwork\"], site=\"rennes\", type=\"prod\")\n", - "kavlan_network = en.G5kNetworkConf(roles=[\"myprivate\"], site=\"rennes\", type=\"kavlan\")\n", - "conf = (\n", - " en.G5kConf(job_type=[\"deploy\"], env_name=\"debian11-nfs\")\n", - " .add_machine(cluster=\"paravance\", nodes=3, roles=[\"role1\", \"role2\"], primary_network=prod_network, secondary_networks=[kavlan_network])\n", - " .add_machine(cluster=\"parasilo\", nodes=3, roles=[\"role2\", \"role3\"], primary_network=prod_network, secondary_networks=[kavlan_network])\n", - " .add_network_conf(prod_network)\n", - " .add_network_conf(kavlan_network)\n", - " # optional, but do some sanity checks on the configuration \n", - " .finalize()\n", - " )\n", - "conf" - ] - }, - { - "cell_type": "markdown", - "id": "ac4ab8b3-cdb2-46b8-be32-e709bc11fee0", - "metadata": {}, - "source": [ - "### Discussion and references\n", - "\n", - "- Many configurations options are possible. [The documentation](https://discovery.gitlabpages.inria.fr/enoslib/tutorials/grid5000.html) will show you some more.\n", - "- In EnOSlib `Roles` and `Networks` don't really depend on the provider that produced them. In other words you can substitute one provider's configuration to another one easily without changing the artifact code." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ce78182e-562a-46a1-b6f9-17ffade1d851", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.5" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/g5k/02_observability.ipynb b/g5k/03_observability_service.ipynb similarity index 84% rename from g5k/02_observability.ipynb rename to g5k/03_observability_service.ipynb index d852d88..014c697 100644 --- a/g5k/02_observability.ipynb +++ b/g5k/03_observability_service.ipynb @@ -2,12 +2,13 @@ "cells": [ { "cell_type": "markdown", - "id": "adjustable-crime", + "id": "33965d92-545e-4cc9-add1-261770b5a00e", "metadata": {}, "source": [ - "# Observability facilities\n", + "# Observability service\n", "\n", "Third party software stack to keep an eye on your experiment or gather some metrics.\n", + "Note that this tutorial is about instrumenting on your own the deployed nodes. Note that Grid'5000 also provides ways to get data from your job using [a REST API](https://www.grid5000.fr/w/Monitoring_Using_Kwollect).\n", "\n", "---\n", "\n", @@ -17,95 +18,27 @@ "\n", "---\n", "\n", - "\n", "## Prerequisites\n", "\n", "<div class=\"alert alert-block alert-warning\">\n", - " Make sure you've run the one time setup for your environment\n", - "</div>\n" - ] - }, - { - "cell_type": "markdown", - "id": "7b85cf55-938d-4758-9bd9-f6b4c7de2632", - "metadata": {}, - "source": [ - "## Grid'5000 monitoring facilities\n", - "\n", - "Grid'5000 collects automatically metrics of the nodes.\n", - "Those metrics can be queried using the REST API." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "177e81b3-ecc5-4412-b660-08dfd0a64bda", - "metadata": {}, - "outputs": [], - "source": [ - "from grid5000 import Grid5000\n", - "from pathlib import Path\n", - "\n", - "conf = Path.home() / \".python-grid5000.yaml\"\n", - "\n", - "gk = Grid5000.from_yaml(conf)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f5f2bc99-fb11-4fb1-b2af-857214a16721", - "metadata": {}, - "outputs": [], - "source": [ - "# get the list of the available metrics for a given cluster\n", - "import json\n", - "\n", - "metrics = gk.sites[\"lyon\"].clusters[\"nova\"].metrics\n", - "print(json.dumps(metrics, indent=4))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4c434dfa-4e9d-40f9-b69e-413f365c15b6", - "metadata": {}, - "outputs": [], - "source": [ - "[m[\"name\"] for m in metrics]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5f0aed1c-01ba-49b8-9571-ffbae2ec348d", - "metadata": {}, - "outputs": [], - "source": [ - "import time\n", - "metric = \"wattmetre_power_watt\"\n", - "now = time.time()\n", - "measurements = gk.sites[\"lyon\"].metrics.list(nodes=\"nova-1,nova-2,nova-3\", start_time=now - 1000, metrics=metric)\n", - "\n", - "# alternatively one can pass a job_id\n", - "# measurements = gk.sites[\"lyon\"].metrics.list(job_id=1307628, metrics=metric)\n", - "measurements[:10]" + " <ul>\n", + " <li>⚠️ Make sure you've run the one time setup for your environment</li>\n", + " <li>⚠️ Make sure you're running this notebook under the right kernel</li>\n", + " </ul>\n", + "</div>\n", + "\n" ] }, { "cell_type": "code", "execution_count": null, - "id": "e233fb27-d68d-4589-bbac-e5f564eecb30", + "id": "779ea70c-aacd-45eb-9472-b9d17a16fd3a", "metadata": {}, "outputs": [], "source": [ - "import pandas as pd\n", - "\n", - "df = pd.DataFrame([m.to_dict() for m in measurements])\n", - "df[\"timestamp\"] = pd.to_datetime(df[\"timestamp\"])\n", - "import seaborn as sns\n", + "import enoslib as en\n", "\n", - "sns.relplot(data=df, x=\"timestamp\", y=\"value\", hue=\"device_id\", alpha=0.7)" + "en.check()" ] }, { @@ -185,21 +118,17 @@ "metadata": {}, "outputs": [], "source": [ - "# claim the resources\n", - "network = en.G5kNetworkConf(type=\"prod\", roles=[\"my_network\"], site=\"rennes\")\n", - "\n", "conf = (\n", " en.G5kConf.from_settings(job_type=[], job_name=\"enoslib_observability\")\n", - " .add_network_conf(network)\n", " .add_machine(\n", - " roles=[\"control\", \"xp\"], cluster=\"parasilo\", nodes=1, primary_network=network\n", + " roles=[\"control\", \"xp\"], cluster=\"parasilo\", nodes=1\n", " )\n", " .add_machine(\n", - " roles=[\"agent\", \"xp\"], cluster=\"parasilo\", nodes=1, primary_network=network\n", + " roles=[\"agent\", \"xp\"], cluster=\"parasilo\", nodes=1\n", " )\n", " .finalize()\n", ")\n", - "conf" + "conf\n" ] }, { @@ -325,7 +254,139 @@ }, { "cell_type": "markdown", - "id": "cardiac-turkish", + "id": "fatal-center", + "metadata": {}, + "source": [ + "## Monitoring with Telegraf/[InfluxDB|prometheus]/grafana " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "finished-individual", + "metadata": {}, + "outputs": [], + "source": [ + "monitoring = en.TIGMonitoring(collector=roles[\"control\"][0], agent=roles[\"agent\"], ui=roles[\"control\"][0])\n", + "monitoring" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "982e398e-c0da-4451-b0e8-b074262295ad", + "metadata": {}, + "outputs": [], + "source": [ + "monitoring.deploy()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fossil-closer", + "metadata": {}, + "outputs": [], + "source": [ + "en.run_command(\"stress --cpu 24 --timeout 60\", roles=roles[\"agent\"], background=True)" + ] + }, + { + "cell_type": "markdown", + "id": "a6c0ea91-eb00-4be2-af27-d2b35a8e78fa", + "metadata": {}, + "source": [ + "<div class=\"alert alert-info\">\n", + "💡 Accessing a service inside Grid'5000 isn't straightforward.\n", + "The following depends on your environment.\n", + "</div>" + ] + }, + { + "cell_type": "markdown", + "id": "edcfb503-308e-4e40-82f9-73d1110af16f", + "metadata": {}, + "source": [ + "<div class=\"alert alert-info\">\n", + "💡 Run the following on a terminal in your local computer\n", + "</div>" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3e07f4ec-064f-4896-a4a9-7b7951470718", + "metadata": {}, + "outputs": [], + "source": [ + "print(f\"\"\"\n", + "Access the UI at {monitoring.ui.address}:3000 (admin/admin)\")\n", + "---\n", + "tip1: create a ssh port forwarding -> ssh -NL 3000:{monitoring.ui.address}:3000 access.grid5000.fr (and point your browser to http://localhost:3000)\n", + "tip2: use a proxy socks -> ssh -ND 2100 access.grid5000.fr (and point your browser to http://{monitoring.ui.address}:3000)\n", + "tip3: use the G5K vpn\n", + "\"\"\")" + ] + }, + { + "cell_type": "markdown", + "id": "4ea72b0d-854b-45f7-9f40-13bf00a5eed7", + "metadata": {}, + "source": [ + "<div class=\"alert alert-info\">\n", + "💡 EnOSlib provides a way to programmaticaly create the tunnel if this notebook runs on your laptop.\n", + "However this doesn't apply if the notebook is running on a frontend node or a compute node inside Grid'5000.\n", + "</div>" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "canadian-maryland", + "metadata": {}, + "outputs": [], + "source": [ + "# If you are running this notebook outside of Grid'5000 (e.g from your local machine), you can access the dashboard by creating a tunnel\n", + "\n", + "# This doesn't apply if you are running this notebook from the frontend or a node inside Grid5000\n", + "tunnel = en.G5kTunnel(address=monitoring.ui.address, port=3000)\n", + "local_address, local_port, _ = tunnel.start()\n", + "print(f\"The service is running at http://localhost:{local_port} (admin:admin)\")\n", + "\n", + "# wait some time\n", + "import time\n", + "time.sleep(60)\n", + "\n", + "\n", + "# don't forget to close it\n", + "tunnel.close()" + ] + }, + { + "cell_type": "markdown", + "id": "ethical-creation", + "metadata": {}, + "source": [ + "To not forget to close the tunnel you can use a context manager: the tunnel will be closed automatically when exiting the context manager." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "stunning-turkish", + "metadata": {}, + "outputs": [], + "source": [ + "import time\n", + "with en.G5kTunnel(address=monitoring.ui.address, port=3000) as (_, local_port, _):\n", + " print(f\"The service is running at http://localhost:{local_port}\")\n", + " time.sleep(60)\n", + " " + ] + }, + { + "cell_type": "markdown", + "id": "33b1fa5e-6303-4dfc-8d07-b7364939b1d7", "metadata": {}, "source": [ "## Packet sniffing with tcpdump\n", @@ -353,7 +414,7 @@ }, { "cell_type": "markdown", - "id": "nervous-joint", + "id": "4c60271e-a59d-4237-beba-979c8e38a67f", "metadata": {}, "source": [ "### Visualization" @@ -390,7 +451,7 @@ }, { "cell_type": "markdown", - "id": "5eae90d4-3f5f-4879-9791-5afab6278383", + "id": "993b61cd-c168-4d2a-b8ac-d451cddb7723", "metadata": {}, "source": [ "### Capture on a specific network\n", @@ -457,106 +518,6 @@ " packets[1].show()" ] }, - { - "cell_type": "markdown", - "id": "fatal-center", - "metadata": {}, - "source": [ - "## Monitoring with Telegraf/[InfluxDB|prometheus]/grafana " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "finished-individual", - "metadata": {}, - "outputs": [], - "source": [ - "monitoring = en.TIGMonitoring(collector=roles[\"control\"][0], agent=roles[\"agent\"], ui=roles[\"control\"][0])\n", - "monitoring" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "982e398e-c0da-4451-b0e8-b074262295ad", - "metadata": {}, - "outputs": [], - "source": [ - "monitoring.deploy()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fossil-closer", - "metadata": {}, - "outputs": [], - "source": [ - "en.run_command(\"stress --cpu 24 --timeout 60\", roles=roles[\"agent\"], background=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3e07f4ec-064f-4896-a4a9-7b7951470718", - "metadata": {}, - "outputs": [], - "source": [ - "print(f\"\"\"\n", - "Access the UI at {monitoring.ui.address}:3000 (admin/admin)\")\n", - "---\n", - "tip1: create a ssh port forwarding -> ssh -NL 3000:{monitoring.ui.address}:3000 access.grid5000.fr (and point your browser to http://localhost:3000)\n", - "tip2: use a proxy socks -> ssh -ND 2100 access.grid5000.fr (and point your browser to http://{monitoring.ui.address}:3000)\n", - "tip3: use the G5K vpn\n", - "\"\"\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "canadian-maryland", - "metadata": {}, - "outputs": [], - "source": [ - "# If you are running stuffs from outside g5k, you can access the dashboard by creating a tunnel\n", - "# create a tunnel to the service running inside g5k\n", - "\n", - "tunnel = en.G5kTunnel(address=monitoring.ui.address, port=3000)\n", - "local_address, local_port, _ = tunnel.start()\n", - "print(f\"The service is running at http://localhost:{local_port} (admin:admin)\")\n", - "\n", - "# wait some time\n", - "import time\n", - "time.sleep(60)\n", - "\n", - "\n", - "# don't forget to close it\n", - "tunnel.close()" - ] - }, - { - "cell_type": "markdown", - "id": "ethical-creation", - "metadata": {}, - "source": [ - "To not forget to close the tunnel you can use a context manager: the tunnel will be closed automatically when exiting the context manager." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "stunning-turkish", - "metadata": {}, - "outputs": [], - "source": [ - "import time\n", - "with en.G5kTunnel(address=monitoring.ui.address, port=3000) as (_, local_port, _):\n", - " print(f\"The service is running at http://localhost:{local_port}\")\n", - " time.sleep(60)\n", - " " - ] - }, { "cell_type": "markdown", "id": "separated-briefing", @@ -591,9 +552,9 @@ "hash": "c41aab4ca0eaec89556f08ac68d7d063aee1184b32505cfb99eab1b047dc078c" }, "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "my_venv", "language": "python", - "name": "python3" + "name": "my_venv" }, "language_info": { "codemirror_mode": { @@ -605,7 +566,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.5" + "version": "3.9.2" }, "toc-autonumbering": false, "toc-showcode": false, diff --git a/g5k/05_network_emulation.ipynb b/g5k/04_network_emulation.ipynb similarity index 73% rename from g5k/05_network_emulation.ipynb rename to g5k/04_network_emulation.ipynb index f4786cc..cdcbe85 100644 --- a/g5k/05_network_emulation.ipynb +++ b/g5k/04_network_emulation.ipynb @@ -1,11 +1,7 @@ { "cells": [ { - "attachments": { - "6b4d0f44-ecf5-4dd2-88d9-3e162bc0705c.png": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAhQAAAINCAYAAABmo+a2AAAgAElEQVR4XuydBbgVVffGF93SjaSAtHQ3SIdIpygC0oKUdDcqLSElKZ3SSIMg0iUgUtLd9fdd33f43w+Be865M+fMzHnX89znAndmx28Od7+z94pQL/4xoZEACZAACZAACZBACAiEoqAIAT3eSgIkQAIkQAIkoAQoKPhBIAESIAESIAESCDEBCooQI2QDJEACJEACJEACFBT8DJAACZAACZAACYSYAAVFiBGyARIgARIgARIgAQoKfgZIgARIgARIgARCTICCIsQI2QAJkAAJkAAJkAAFBT8DJEACJEACJEACISZAQRFihGyABEiABEiABEiAgoKfAVsTePLkiaxYsUIKFSokMWPG1LlcunRJTpw4IadOnZI///xTLl68KLdu3ZLbt29L7Nix5ezZsxIqVChJmTKl3LhxQ+9LlCiRxIoVS5InT65f77//vkSIEMHWbDh4EiABEvAlAQoKX9JmX4YSGDhwoPz888+SKlUq2bVrl0SLFk0OHz4skSNHlnv37knUqFHlzp07guzyz54905+HCRNGIkWKJFGiRJEYMWLotREjRtRr79+/r9dfuXJFjh49qoIja9askj9/fsmXL5988MEHho6fjZEACZCAkwhQUDjpaQbIXKZNmybNmzeXTJkyyenTp+XatWsqGjJnziyFCxeWbNmySYoUKSRZsmQqIMKFCyfhw4eX58+fy82bN3WnAl9Xr16VCxcu6A7G9evX5fjx43Ly5Elts0KFCnotxAfaxr9j5wN9Ykfj66+/lgIFCgQIcU6TBEiABIInQEERPCNeYREC27Ztk08++USFABZ77CDUr19fqlWrJv369ZNBgwZJ4sSJDRktRMWxY8f06ARCA0cn2P24e/eu9v348WMJHTq07nJgPDhCoZEACZBAIBOgoAjkp2+TuWMB/+ijj2T37t16VFGpUiUVEHHixPHLDOCDgbFs375dpkyZokckZcqUERzBYJeERgIkQAKBSICCIhCfuo3mjIUafhJly5aVXr16SY4cOSw3euxetG7dWlatWqVHIoMHD5aiRYtabpwcEAmQAAmYSYCCwky6bNtrAo0bN5YJEyZInjx5dKF+5513vG7LVzceOXJEatasqY6d8OH49ttvVWDQSIAESCAQCFBQBMJTttEccYTQ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" - } - }, + "attachments": {}, "cell_type": "markdown", "id": "loved-sandwich", "metadata": { @@ -25,15 +21,41 @@ "## Prerequisites\n", "\n", "<div class=\"alert alert-block alert-warning\">\n", - " Make sure you've run the one time setup for your environment\n", - "</div>\n", + " <ul>\n", + " <li>⚠️ Make sure you've run the one time setup for your environment</li>\n", + " <li>⚠️ Make sure you're running this notebook under the right kernel</li>\n", + " </ul>\n", + "</div>" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "957183a1-3602-4f73-93fd-d52c24842bc0", + "metadata": {}, + "outputs": [], + "source": [ + "import enoslib as en\n", "\n", + "en.check()" + ] + }, + { + "attachments": { + "92a38c23-c2e4-4033-ae10-f3371c95b91d.png": { + "image/png": "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fJE1a9YYHUNEREQKQbG5Zs/DwwMrKyvWrVunO3BN7Pz589SsWZOMjAxKly5tdBwRERExoWKxjHvq1ClycnJo0KCBil4hqFGjBo6OjixevNjoKCIiImJixaLsbdmyhXLlyvH2228bHcVs+fn56eHKIiIiZqhYlL2goCBSU1Np3ry50VHMVseOHTl06JDRMURERMTEikXZO3z4MMOGDTM6hll74YUXuHbtGtnZ2UZHERERERMq8mUvPj6e/Px8xo0bZ3QUs1a6dGkcHBxYunSp0VFERETEhIp82fv++++xsbHB0dHR6Chmr06dOmzbts3oGCIiImJCRb7s7dy5Ezc3N6NjlAiNGjXi2LFjRscQEREREyryZS8yMpJHH33U6BglwhNPPEF8fLzRMURERMSEinzZO3XqFN7e3kbHKBGeeOIJypQpQ0pKitFRRERExESKdNmLiIigfPny3Lx50+goJYK7uzuXL18mKirK6CgiIiJiIkW67J08eZIKFSpga2trdJQSw9HRkX379hkdQ0REREykSJe9ixcvUrFiRSpUqGB0lBKjQYMGREREGB1DRERETKRIl72srCxyc3NJSkoyOkqJYWFhQWRkpNExRERExESKfNkrXbo0GRkZRkcpMZydnbl8+bLRMURERMREinTZs7e3p3z58ty4ccPoKCVG9erVuXr1qtExRERExESKdNlzcHAgNTWVCxcuGB2lxKhYsaLKtYiIiBkp0mWvSpUqZGdnc/78eaOjlBj29vZkZ2cbHUNERERMpEiXPRcXF8qVK6ey9xA5ODiQm5trdAwRERExkSJd9urVq8e+fftwdnY2OkqJUbZsWcqXL290DBERETGRIl32SpUqhaurK+Hh4cTFxRkdp0S4fPky165dMzqGiIiImEiRLnsATZs2pWrVqpw8edLoKCVCRkYGNjY2RscQERERE7E2OsBfadu2LVevXuXMmTNGRykRcnNzqVKlitExRERExESK/Myej48PsbGxbN++3egoJUJ0dDR5eXlGxxARERETscjPz883OsRfKVeuHLa2tiQnJxsdxez5+vqSn5/P7t27jY4iIiIiJlDkZ/YAnn32WWxsbPTO1ofg2rVruLq6Gh1DRERETKRYlL02bdrg6OjIrl27jI5i9s6dO0ejRo2MjiEiIiImUiyWcW/cuEG5cuV48sknCQoKMjqOWbOy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" + } + }, + "cell_type": "markdown", + "id": "e0c0148f-a781-46ac-9541-bfadf261450e", + "metadata": {}, + "source": [ "\n", "## First example: a star topology\n", "\n", - "\n", + "\n", "\n", - "### Reservation" + "### Reservation\n" ] }, { @@ -48,28 +70,22 @@ "\n", "_ = en.init_logging()\n", "\n", - "\n", - "prod_network = en.G5kNetworkConf(type=\"prod\", roles=[\"my_network\"], site=\"rennes\")\n", "conf = (\n", " en.G5kConf.from_settings(job_type=[], walltime=\"01:00:00\", job_name=\"labs_netem\")\n", - " .add_network_conf(prod_network)\n", " .add_machine(\n", " roles=[\"city\", \"paris\"],\n", " cluster=\"paravance\",\n", " nodes=1,\n", - " primary_network=prod_network,\n", " )\n", " .add_machine(\n", " roles=[\"city\", \"berlin\"],\n", " cluster=\"paravance\",\n", " nodes=1,\n", - " primary_network=prod_network,\n", " )\n", " .add_machine(\n", " roles=[\"city\", \"londres\"],\n", " cluster=\"paravance\",\n", " nodes=1,\n", - " primary_network=prod_network,\n", " )\n", " .finalize()\n", ")\n", @@ -119,9 +135,9 @@ "\n", "(\n", " netem\n", - " .add_constraints(\"delay 5ms\", roles[\"paris\"], symetric=True)\n", - " .add_constraints(\"delay 10ms\", roles[\"londres\"], symetric=True)\n", - " .add_constraints(\"delay 15ms\", roles[\"berlin\"], symetric=True)\n", + " .add_constraints(\"delay 5ms\", roles[\"paris\"], symmetric=True)\n", + " .add_constraints(\"delay 10ms\", roles[\"londres\"], symmetric=True)\n", + " .add_constraints(\"delay 15ms\", roles[\"berlin\"], symmetric=True)\n", ")\n", "\n", "netem.deploy()\n", @@ -321,7 +337,7 @@ "metadata": {}, "outputs": [], "source": [ - "ipv6_network = networks[\"my_network\"][1]\n", + "ipv6_network = networks[\"prod\"][1]\n", "ipv6_network" ] }, @@ -340,7 +356,7 @@ " dest=roles[\"londres\"],\n", " delay=\"5ms\",\n", " rate=\"1gbit\",\n", - " symetric=True,\n", + " symmetric=True,\n", " networks=[ipv6_network]\n", " )\n", " .add_constraints(\n", @@ -348,7 +364,7 @@ " dest=roles[\"berlin\"],\n", " delay=\"10ms\",\n", " rate=\"1gbit\",\n", - " symetric=True,\n", + " symmetric=True,\n", " networks=[ipv6_network]\n", " )\n", "\n", @@ -357,7 +373,7 @@ " dest=roles[\"berlin\"],\n", " delay=\"15ms\",\n", " rate=\"1gbit\",\n", - " symetric=True,\n", + " symmetric=True,\n", " networks=[ipv6_network]\n", " )\n", ")" @@ -456,6 +472,24 @@ "conf" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "c0b067f8-a63d-4bd3-8599-a03a13b9d914", + "metadata": {}, + "outputs": [], + "source": [ + "vmon5k = en.VMonG5k(conf)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "45cc0b6e-2c30-45d9-8ff7-3abcd23d868c", + "metadata": {}, + "outputs": [], + "source": [] + }, { "cell_type": "code", "execution_count": null, @@ -463,7 +497,6 @@ "metadata": {}, "outputs": [], "source": [ - "vmon5k = en.VMonG5k(conf)\n", "vm_roles, vm_networks = vmon5k.init()" ] }, @@ -491,14 +524,14 @@ " dest=vm_roles[\"londres\"],\n", " delay=\"5ms\",\n", " rate=\"1gbit\",\n", - " symetric=True,\n", + " symmetric=True,\n", " )\n", " .add_constraints(\n", " src=vm_roles[\"paris\"],\n", " dest=vm_roles[\"berlin\"],\n", " delay=\"10ms\",\n", " rate=\"1gbit\",\n", - " symetric=True,\n", + " symmetric=True,\n", " )\n", "\n", " .add_constraints(\n", @@ -506,7 +539,7 @@ " dest=vm_roles[\"berlin\"],\n", " delay=\"15ms\",\n", " rate=\"1gbit\",\n", - " symetric=True,\n", + " symmetric=True,\n", " )\n", ")\n", "netem" @@ -564,6 +597,14 @@ "source": [ "provider.destroy()" ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7ef0788b-f14f-4931-a6c0-329e7c655a60", + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { @@ -582,7 +623,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.5" + "version": "3.9.2" }, "toc-showcode": false, "toc-showmarkdowntxt": false diff --git a/g5k/03_using_several_networks.ipynb b/g5k/05_using_several_networks.ipynb similarity index 97% rename from g5k/03_using_several_networks.ipynb rename to g5k/05_using_several_networks.ipynb index 3bba621..263a761 100644 --- a/g5k/03_using_several_networks.ipynb +++ b/g5k/05_using_several_networks.ipynb @@ -21,8 +21,23 @@ "## Prerequisites\n", "\n", "<div class=\"alert alert-block alert-warning\">\n", - " Make sure you've run the one time setup for your environment\n", - "</div>\n" + " <ul>\n", + " <li>⚠️ Make sure you've run the one time setup for your environment</li>\n", + " <li>⚠️ Make sure you're running this notebook under the right kernel</li>\n", + " </ul>\n", + "</div>" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "de8f598b-e6ee-4a58-a893-874164177da7", + "metadata": {}, + "outputs": [], + "source": [ + "import enoslib as en\n", + "\n", + "en.check()" ] }, { @@ -200,10 +215,7 @@ "outputs": [], "source": [ "with en.actions(roles=roles) as a:\n", - " a.apt_repository(\n", - " repo=\"deb http://deb.debian.org/debian $(lsb_release -c -s) main contrib non-free\",\n", - " state=\"present\",\n", - " )\n", + " # Note flent is on the non-free repo (activated by default nowadays on g5k)\n", " a.apt(\n", " name=[\"flent\", \"netperf\", \"python3-setuptools\", \"python3-matplotlib\"],\n", " state=\"present\",\n", @@ -547,14 +559,6 @@ "source": [ "provider.destroy()" ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "459d0b3f-82da-4869-8b5c-faaea8735ad4", - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { @@ -573,7 +577,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.5" + "version": "3.9.2" }, "toc-showcode": false, "toc-showmarkdowntxt": false diff --git a/g5k/04_working_with_virtualized_resources.ipynb b/g5k/06_working_with_virtualized_resources.ipynb similarity index 96% rename from g5k/04_working_with_virtualized_resources.ipynb rename to g5k/06_working_with_virtualized_resources.ipynb index 604b9e0..732e9da 100644 --- a/g5k/04_working_with_virtualized_resources.ipynb +++ b/g5k/06_working_with_virtualized_resources.ipynb @@ -36,9 +36,23 @@ "## Prerequisites\n", "\n", "<div class=\"alert alert-block alert-warning\">\n", - " Make sure you've run the one time setup for your environment\n", - "</div>\n", - "\n" + " <ul>\n", + " <li>⚠️ Make sure you've run the one time setup for your environment</li>\n", + " <li>⚠️ Make sure you're running this notebook under the right kernel</li>\n", + " </ul>\n", + "</div>\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "19071ee2-5021-4c7f-97f0-b14db25a94bb", + "metadata": {}, + "outputs": [], + "source": [ + "import enoslib as en\n", + "\n", + "en.check()" ] }, { diff --git a/g5k/06_orchestrators.ipynb b/g5k/07_orchestrators.ipynb similarity index 95% rename from g5k/06_orchestrators.ipynb rename to g5k/07_orchestrators.ipynb index a2e3e04..0b64b8f 100644 --- a/g5k/06_orchestrators.ipynb +++ b/g5k/07_orchestrators.ipynb @@ -20,12 +20,23 @@ "## Prerequisites\n", "\n", "<div class=\"alert alert-block alert-warning\">\n", - " Make sure you've run the one time setup for your environment\n", - "</div>\n", - "\n", - "An example of how a complex application can be bootstraped.\n", + " <ul>\n", + " <li>⚠️ Make sure you've run the one time setup for your environment</li>\n", + " <li>⚠️ Make sure you're running this notebook under the right kernel</li>\n", + " </ul>\n", + "</div>" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2349865a-8403-4181-a909-4ab39e884e00", + "metadata": {}, + "outputs": [], + "source": [ + "import enoslib as en\n", "\n", - "\n" + "en.check()" ] }, { @@ -349,7 +360,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.5" + "version": "3.9.2" }, "toc-showcode": false, "toc-showmarkdowntxt": false diff --git a/g5k/07_planning_service.ipynb b/g5k/08_planning_service.ipynb similarity index 91% rename from g5k/07_planning_service.ipynb rename to g5k/08_planning_service.ipynb index f643987..d45168d 100644 --- a/g5k/07_planning_service.ipynb +++ b/g5k/08_planning_service.ipynb @@ -17,11 +17,32 @@ "\n", "## Prerequisites\n", "\n", - "<div class=\"alert alert-block alert-warning\">\n", - " Make sure you've run the one time setup for your environment\n", - "</div>\n", "\n", + "<div class=\"alert alert-block alert-warning\">\n", + " <ul>\n", + " <li>⚠️ Make sure you've run the one time setup for your environment</li>\n", + " <li>⚠️ Make sure you're running this notebook under the right kernel</li>\n", + " </ul>\n", + "</div>\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f362272d-2384-469b-b70f-f86aef6c1b03", + "metadata": {}, + "outputs": [], + "source": [ + "import enoslib as en\n", "\n", + "en.check()" + ] + }, + { + "cell_type": "markdown", + "id": "c79e8cb2-01c0-4104-9d58-6b43e6edca1b", + "metadata": {}, + "source": [ "## Introduction\n", "\n", "In this notebook we show how processes can be started/killed/limited using EnOSlib following a given schedule.\n", @@ -235,7 +256,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.5" + "version": "3.9.2" } }, "nbformat": 4, diff --git a/g5k/08_planning_service_revisited.ipynb b/g5k/09_planning_service_revisited.ipynb similarity index 97% rename from g5k/08_planning_service_revisited.ipynb rename to g5k/09_planning_service_revisited.ipynb index 55c0ada..1fce29c 100644 --- a/g5k/08_planning_service_revisited.ipynb +++ b/g5k/09_planning_service_revisited.ipynb @@ -17,13 +17,25 @@ "\n", "## Prerequisites\n", "\n", - "<div class=\"alert alert-block alert-warning\">\n", - " Make sure you've run the one time setup for your environment\n", - "</div>\n", + "\n", "\n", "<div class=\"alert alert-block alert-warning\">\n", - " Make sure you've done the tutorial : 07_fault_injection_on_processes\n", - "</div>" + " <ul>\n", + " <li>⚠️ Make sure you've run the one time setup for your environment</li>\n", + " <li>⚠️ Make sure you're running this notebook under the right kernel</li>\n", + " </ul>\n", + "</div>\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import enoslib as en\n", + "\n", + "en.check()" ] }, { @@ -702,7 +714,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.5" + "version": "3.9.2" } }, "nbformat": 4, -- GitLab