{ "cells": [ { "cell_type": "markdown", "id": "3647b70c-d999-4b29-bb46-99fb3acca648", "metadata": {}, "source": [ "# Schedule events using a Planning\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", "## Prerequisites\n", "\n", "
\n", " Make sure you've run the one time setup for your environment\n", "
\n", "\n", "\n", "## Introduction\n", "\n", "In this notebook we show how processes can be started/killed/limited using EnOSlib following a given schedule.\n", "You first start by declaring all the wanted events and let EnOSlib schedule them by using the PlanningService.\n", "\n", "Behind the scene events are scheduled using cronjobs. Crons aren't known to be very accurate on their execution dates. However we observe that the gap between the actual event date and the wanted date don't exceed few seconds in most of the situations we tested. If a better accuracy is required by your experiment, be in touch :).\n", "\n", "EnOSlib also uses cgroup (v2) to identify processes started by the events (they are given a name). Also you can define events to limit the cpu/mem/ios ... according to waht cgroup (v2) offers." ] }, { "cell_type": "markdown", "id": "420ab62c-2c71-4005-9f78-1860eb33bdfe", "metadata": {}, "source": [ "## Setup" ] }, { "cell_type": "code", "execution_count": null, "id": "c47e663e-4591-418f-9522-f384571aa3c0", "metadata": {}, "outputs": [], "source": [ "import logging\n", "\n", "import enoslib as en\n", "import time\n", "\n", "en.init_logging(level=logging.INFO)\n", "en.check()\n", "\n", "job_name = \"stress-planning\"\n", "\n", "conf = (\n", " en.G5kConf.from_settings(job_name=job_name, walltime=\"3:00:00\", job_type=\"deploy\", env_name=\"debian11-nfs\")\n", " .add_machine(roles=[\"groupA\", \"xp\"], cluster=\"paravance\", nodes=1)\n", ")\n", "\n", "# This will validate the configuration, but not reserve resources yet\n", "provider = en.G5k(conf)\n", "\n", "# Get actual resources\n", "roles, networks = provider.init()\n", "\n", "\n", "from datetime import datetime, timedelta\n", "\n", "with en.actions(roles=roles) as p:\n", " p.apt(name=\"stress\", state=\"present\")" ] }, { "cell_type": "markdown", "id": "1497e51a-b684-4132-be9d-dc5ed4c7d4ca", "metadata": {}, "source": [ "## Build the planning" ] }, { "cell_type": "code", "execution_count": null, "id": "349f36a5-988e-40c1-b020-afedfa172c13", "metadata": {}, "outputs": [], "source": [ "ps = en.PlanningService()\n", "\n", "N = 2\n", "delay = 70\n", "\n", "(\n", " ps.add_event(\n", " en.StartEvent(\n", " date=datetime.now() + timedelta(seconds=delay), \n", " cmd=\"stress -c 30\",\n", " host=roles[\"groupA\"][0],\n", " name=f\"mysleep\"\n", " )\n", " )\n", " .add_event(\n", " en.CGroupEvent(\n", " date=datetime.now() + timedelta(seconds=delay + 30),\n", " cpath=\"cpuset.cpus\",\n", " value=\"1-10\",\n", " host=roles[\"groupA\"][0],\n", " name=f\"mysleep\"\n", " )\n", " )\n", " .add_event(\n", " en.CGroupEvent(\n", " date=datetime.now() + timedelta(seconds=delay + 60),\n", " cpath=\"cpuset.cpus\",\n", " value=\"0-31\",\n", " host=roles[\"groupA\"][0],\n", " name=f\"mysleep\"\n", " )\n", " )\n", " .add_event(\n", " en.KillEvent(\n", " date=datetime.now() + timedelta(seconds=delay + 90), \n", " host=roles[\"groupA\"][0],\n", " name=f\"mysleep\"\n", " )\n", " )\n", ")\n", " \n", "\n", "ps" ] }, { "cell_type": "markdown", "id": "09c4dba8-8a0c-4f4d-83b1-b0ea29983034", "metadata": {}, "source": [ "## Execute the planning" ] }, { "cell_type": "code", "execution_count": null, "id": "dcb50003-46b5-4cb9-a92b-734d43e81bf3", "metadata": {}, "outputs": [], "source": [ "ps.until_end.total_seconds()" ] }, { "cell_type": "code", "execution_count": null, "id": "129479b8-3d5d-4280-a6ef-43c517ee6a27", "metadata": {}, "outputs": [], "source": [ "# start monitoring\n", "dstat = en.Dstat(nodes=roles[\"xp\"])\n", "dstat.destroy()\n", "dstat.deploy()\n", "\n", "# deploy the planning\n", "ps.deploy()\n", "# waiting a bit\n", "time.sleep(ps.until_end.total_seconds() + 60)\n", "\n", "# backup the data\n", "dstat.destroy()\n", "dstat.backup()" ] }, { "cell_type": "code", "execution_count": null, "id": "df7e173e-058d-4ceb-a15d-f0b9c02482f5", "metadata": {}, "outputs": [], "source": [ "from pathlib import Path" ] }, { "cell_type": "code", "execution_count": null, "id": "ba577023-7738-4b1e-84e1-0676184519ff", "metadata": {}, "outputs": [], "source": [ "import seaborn as sns\n", "df = en.Dstat.to_pandas(Path(\"./__enoslib_dstat__/\"))\n", "\n", "sns.lineplot(df, x=\"epoch\", y=\"usr\", hue=\"csv\", legend=\"full\")" ] }, { "cell_type": "code", "execution_count": null, "id": "30a06fb9-2ea2-412d-87b5-e6be4b4386ff", "metadata": {}, "outputs": [], "source": [ "ps.destroy()" ] }, { "cell_type": "code", "execution_count": null, "id": "bf8e2da1-f5b0-40c3-bae2-64ab6b4d6e44", "metadata": {}, "outputs": [], "source": [ "ps.status()" ] } ], "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 }