Schedule events using a Planning#



Prerequisites#

Make sure you’ve run the one time setup for your environment

Introduction#

In this notebook we show how processes can be started/killed/limited using EnOSlib following a given schedule. You first start by declaring all the wanted events and let EnOSlib schedule them by using the PlanningService.

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 :).

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.

Setup#

[ ]:
import logging

import enoslib as en
import time

en.init_logging(level=logging.INFO)
en.check()

job_name = "stress-planning"

conf = (
    en.G5kConf.from_settings(job_name=job_name, walltime="3:00:00", job_type="deploy", env_name="debian11-nfs")
    .add_machine(roles=["groupA", "xp"], cluster="paravance", nodes=1)
)

# This will validate the configuration, but not reserve resources yet
provider = en.G5k(conf)

# Get actual resources
roles, networks = provider.init()


from datetime import datetime, timedelta

with en.actions(roles=roles) as p:
    p.apt(name="stress", state="present")

Build the planning#

[ ]:
ps = en.PlanningService()

N = 2
delay = 70

(
    ps.add_event(
        en.StartEvent(
            date=datetime.now() + timedelta(seconds=delay),
            cmd="stress -c 30",
            host=roles["groupA"][0],
            name=f"mysleep"
        )
    )
    .add_event(
        en.CGroupEvent(
            date=datetime.now() + timedelta(seconds=delay  + 30),
            cpath="cpuset.cpus",
            value="1-10",
            host=roles["groupA"][0],
            name=f"mysleep"
        )
    )
    .add_event(
        en.CGroupEvent(
            date=datetime.now() + timedelta(seconds=delay  + 60),
            cpath="cpuset.cpus",
            value="0-31",
            host=roles["groupA"][0],
            name=f"mysleep"
        )
    )
    .add_event(
        en.KillEvent(
            date=datetime.now() + timedelta(seconds=delay  + 90),
            host=roles["groupA"][0],
            name=f"mysleep"
        )
    )
)


ps

Execute the planning#

[ ]:
ps.until_end.total_seconds()
[ ]:
# start monitoring
dstat = en.Dstat(nodes=roles["xp"])
dstat.destroy()
dstat.deploy()

# deploy the planning
ps.deploy()
# waiting a bit
time.sleep(ps.until_end.total_seconds() + 60)

# backup the data
dstat.destroy()
dstat.backup()
[ ]:
from pathlib import Path
[ ]:
import seaborn as sns
df = en.Dstat.to_pandas(Path("./__enoslib_dstat__/"))

sns.lineplot(df, x="epoch", y="usr", hue="csv", legend="full")
[ ]:
ps.destroy()
[ ]:
ps.status()