scrun(1) Slurm Commands scrun(1)

scrun - یک پراکسی زمان‌اجرای OCI برای Slurm.

scrun [GLOBAL OPTIONS...] create [CREATE OPTIONS] <container-id>

یک کانتینر جدید با container-id در دایرکتوری کاری فعلی آماده می‌کند.

scrun [GLOBAL OPTIONS...] start <container-id>

درخواست برای شروع و اجرای کانتینر در job.

scrun [GLOBAL OPTIONS...] state <container-id>

وضعیت کانتینر را در قالب JSON تعریف‌شده توسط OCI خروجی می‌دهد.

scrun [GLOBAL OPTIONS...] kill <container-id> [signal]

ارسال سیگنال (پیش‌فرض: SIGTERM) به کانتینر.

scrun [GLOBAL OPTIONS...] delete [DELETE OPTIONS] <container-id>

آزادسازی تمام منابع اشغال‌شده توسط کانتینر به‌صورت محلی و از راه دور.

انجام عملیات‌های زمان‌اجرای OCI روی container-id بر اساس:
https://github.com/opencontainers/runtime-spec/blob/main/runtime.md

scrun تلاش می‌کند تا حد امکان رفتار خط فرمانی crun و runc را شبیه‌سازی کند تا سازگاری به عنوان جایگزین مستقیم برای DOCKER و podman حفظ شود. تمامی آرگومان‌های خط فرمان برای crun و runc به منظور سازگاری پذیرفته می‌شوند، اما بسته به کاربردپذیری‌شان ممکن است نادیده گرفته شوند.

scrun یک پراکسی زمان‌اجرای OCI برای Slurm است. این ابزار به عنوان یک واسط مشترک برای DOCKER یا podman عمل می‌کند تا امکان اجرای عملیات‌های کانتینری تحت Slurm در قالب jobها فراهم شود. scrun تمامی دستورها را به عنوان یک زمان‌اجرای منطبق با OCI می‌پذیرد، اما کانتینر و تمام STDIO را برای زمان‌بندی و اجرا به Slurm پروکسی می‌کند. کانتینرها از راه دور بر روی گره‌های محاسباتی Slurm با توجه به تنظیمات موجود در oci.conf(5) اجرا خواهند شد.

scrun نیازمند آن است که همه کانتینرها مطابق با مشخصات OCI image باشند بر اساس:
https://github.com/opencontainers/image-spec/blob/main/spec.md

در صورت موفقیت‌آمیز بودن عملیات، scrun مقدار 0 را برمی‌گرداند. در هر شرایط دیگری، scrun یک عدد غیر صفر را برای نشان دادن خطا برمی‌گرداند.

نادیده گرفته می‌شود.
فعال‌سازی ثبت وقایع در سطح اشکال‌زدایی (debug).
استفاده از slurm.conf مشخص‌شده برای پیکربندی.
پیش‌فرض: sysconfdir از configure در هنگام کامپایل
نمایش راهنمای سریع درباره نحوه فراخوانی scrun
انتخاب اختیاری قالب برای ثبت وقایع. می‌تواند "json" یا "text" باشد.
پیش‌فرض: text
مسیر دایرکتوری spool برای سوکت‌های ارتباطی و دایرکتوری‌ها و فایل‌های موقت. این مسیر باید یک tmpfs باشد و هنگام راه‌اندازی مجدد سیستم پاک شود.
پیش‌فرض: /run/user/{user_id}/scrun/
نادیده گرفته می‌شود. تمامی دستورهای scrun همیشه بدون ریشه (rootless) هستند.
نادیده گرفته می‌شود.
افزایش میزان جزئیات ثبت وقایع. تکرار -v میزان جزئیات را بیشتر افزایش می‌دهد.
چاپ اطلاعات نسخه و خروج.
مسیر به ریشهٔ دایرکتوری bundle.
پیش‌فرض: دایرکتوری کاری فراخواننده
مسیر اختیاری به یک سوکت AF_UNIX که توصیف‌گر فایلی را دریافت می‌کند که به سمت اصلی (master) شبه‌پایانهٔ کنسول اشاره دارد.
پیش‌فرض: نادیده گرفته می‌شود
نادیده گرفته می‌شود.
نادیده گرفته می‌شود.
مشخص کردن فایلی برای قفل‌گذاری و ثبت شناسه فرایند (PID).
پیش‌فرض: نادیده گرفته می‌شود
نادیده گرفته می‌شود.

نادیده گرفته می‌شود. تمامی درخواست‌های حذف اجباری هستند و هر کار در حال اجرایی را خاتمه می‌دهند.

تعیین سطح ثبت گزارش (logging).
تعیین سطح ثبت گزارش فقط برای خروجی خطای استاندارد.
تعیین سطح ثبت گزارش فقط برای syslog.
تعیین سطح ثبت گزارش فقط برای فایل لاگ.

به SLURM_ACCOUNT در srun(1) مراجعه کنید.
به SLURM_ACCTG_FREQ در srun(1) مراجعه کنید.
به SLURM_BURST_BUFFER در srun(1) مراجعه کنید.
به SLURM_CLUSTER_CONSTRAINT در srun(1) مراجعه کنید.
به SLURM_CLUSTERS در srun(1) مراجعه کنید.
به SLURM_CONSTRAINT در srun(1) مراجعه کنید.
به SLURM_ACCOUNT در srun(1) مراجعه کنید.
به SLURM_CPU_BIND در srun(1) مراجعه کنید.
به SLURM_CPU_FREQ_REQ در srun(1) مراجعه کنید.
به SLURM_CPUS_PER_GPU در srun(1) مراجعه کنید.
به SRUN_CPUS_PER_TASK در srun(1) مراجعه کنید.
به SLURM_DELAY_BOOT در srun(1) مراجعه کنید.
به SLURM_DEPENDENCY در srun(1) مراجعه کنید.
به SLURM_DISTRIBUTION در srun(1) مراجعه کنید.
به SLURM_EPILOG در srun(1) مراجعه کنید.
به SLURM_EXACT در srun(1) مراجعه کنید.
به SLURM_EXCLUSIVE در srun(1) مراجعه کنید.
به SLURM_GPU_BIND در srun(1) مراجعه کنید.
به SLURM_GPU_FREQ در srun(1) مراجعه کنید.
به SLURM_GPUS در srun(1) مراجعه کنید.
به SLURM_GPUS_PER_NODE در srun(1) مراجعه کنید.
به SLURM_GPUS_PER_SOCKET در salloc(1) مراجعه کنید. SCRUN_GPUS_PER_TASK به SLURM_GPUS_PER_TASK از srun(1) مراجعه کنید.
به SLURM_GRES_FLAGS از srun(1) مراجعه کنید.
به SLURM_GRES از srun(1) مراجعه کنید.
به SLURM_HIST از srun(1) مراجعه کنید.
به SLURM_JOB_NAME از srun(1) مراجعه کنید.
به SLURM_JOB_NODELIST از srun(1) مراجعه کنید.
به SLURM_JOB_NUM_NODES از srun(1) مراجعه کنید.
به SLURM_LABELIO از srun(1) مراجعه کنید.
به SLURM_MEM_BIND از srun(1) مراجعه کنید.
به SLURM_MEM_PER_CPU از srun(1) مراجعه کنید.
به SLURM_MEM_PER_GPU از srun(1) مراجعه کنید.
به SLURM_MEM_PER_NODE از srun(1) مراجعه کنید.
به SLURM_MPI_TYPE از srun(1) مراجعه کنید.
به SLURM_NCORES_PER_SOCKET از srun(1) مراجعه کنید.
به SLURM_NETWORK از srun(1) مراجعه کنید.
به SLURM_NSOCKETS_PER_NODE از srun(1) مراجعه کنید.
به SLURM_NTASKS از srun(1) مراجعه کنید.
به SLURM_NTASKS_PER_CORE از srun(1) مراجعه کنید.
به SLURM_NTASKS_PER_GPU از srun(1) مراجعه کنید.
به SLURM_NTASKS_PER_NODE از srun(1) مراجعه کنید.
به SLURM_NTASKS_PER_TRES از srun(1) مراجعه کنید.
به SLURM_MODE از srun(1) مراجعه کنید.
به SLURM_OVERCOMMIT از srun(1) مراجعه کنید.
به SLURM_OVERLAP از srun(1) مراجعه کنید.
به SLURM_PARTITION از srun(1) مراجعه کنید.
به SLURM_POWER از srun(1) مراجعه کنید.
به SLURM_PROFILE از srun(1) مراجعه کنید.
به SLURM_PROLOG از srun(1) مراجعه کنید.
به SLURM_QOS از srun(1) مراجعه کنید.
به SLURM_REMOTE_CWD از srun(1) مراجعه کنید.
به SLURM_REQ_SWITCH از srun(1) مراجعه کنید.
به SLURM_RESERVATION از srun(1) مراجعه کنید.
به SLURM_SIGNAL از srun(1) مراجعه کنید.
به SLURMD_DEBUG از srun(1) مراجعه کنید.
به SLURM_SPREAD_JOB از srun(1) مراجعه کنید.
به SLURM_TASK_EPILOG از srun(1) مراجعه کنید. SCRUN_TASK_PROLOG نگاه کنید به SLURM_TASK_PROLOG از srun(1).
نگاه کنید به SLURM_THREAD_SPEC از srun(1).
نگاه کنید به SLURM_THREADS_PER_CORE از srun(1).
نگاه کنید به SLURM_THREADS از srun(1).
نگاه کنید به SLURM_TIMELIMIT از srun(1).
همانند --tres-bind
نگاه کنید به SLURM_TRES_PER_TASK از srun(1).
نگاه کنید به SLURM_UNBUFFEREDIO از srun(1).
نگاه کنید به SLURM_USE_MIN_NODES از srun(1).
نگاه کنید به SLURM_WAIT4SWITCH از srun(1).
نگاه کنید به SLURM_WCKEY از srun(1).
نگاه کنید به SLURM_WORKING_DIR از srun(1).

نسخه اعلام‌شده سازگاری OCI کانتینر.
مقداری که به عنوان container_id در طول عملیات create ارسال شده است.
شناسه فرایند (PID) فرایندی که برای نظارت و کنترل کانتینر روی گره تخصیص استفاده می‌شود.
مسیر دایرکتوری باندل کانتینر.
مسیر دایرکتوری باندل کانتینر پیش از اعمال تغییرات توسط اسکریپت Lua.
فهرستی از حاشیه‌نویسی‌ها برگرفته از config.json کانتینر.
مسیر فایل pid که قفل شده و با PID دستور scrun پر می‌شود.
مسیر سوکت کنترلی برای scrun.
مسیر فضای کاری برای تمام فایل‌های موقت کانتینر جاری. با عملیات deletion پاک‌سازی می‌شود.
مسیر فایل config.json کانتینر در زمان ارسال (submission).
نام کاربری که عملیات create را فراخوانی کرده است.
شناسه عددی (ID) کاربری که عملیات create را فراخوانی کرده است.
نام گروه اصلی کاربری که عملیات create را فراخوانی کرده است.
شناسه عددی (ID) گروه اصلی کاربری که عملیات create را فراخوانی کرده است.
نگاه کنید به --root.
مسیر دایرکتوری ریشه کانتینر.
مسیر دایرکتوری ریشه کانتینر در زمان ارسال (submission).
مسیر فایل گزارش (log) مربوط به scrun در طول عملیات create.
نوع قالب گزارش (log) در طول عملیات create.
برای یک تخصیص کار ناهمگن (heterogeneous)، متغیرهای محیطی برای هر مؤلفه به‌صورت جداگانه تنظیم می‌شوند.
نام کلاستری که کار روی آن در حال اجرا است.
بسته OCI (OCI Bundle) برای کار.
شناسه OCI (OCI id) برای کار.
تعداد CPUهای درخواستی به ازای هر GPU تخصیص‌یافته.
تعداد CPUهای درخواستی به ازای هر وظیفه (task).
اندازه توزیع سطحی (plane distribution size). فقط برای توزیع‌های سطحی تنظیم می‌شود.
نوع توزیع برای کارهای تخصیص‌یافته.
اتصال (binding) درخواستی وظایف به GPU.
بسامد (فرکانس) درخواستی GPU.
تعداد GPUهای درخواستی.
تعداد GPU درخواستی به ازای هر گره تخصیص‌یافته.
تعداد GPU درخواستی به ازای هر سوکت تخصیص‌یافته.
تعداد GPU درخواستی به ازای هر وظیفه تخصیص‌یافته.
برابر با تعداد مؤلفه‌ها در کار ناهمگن تنظیم می‌شود.
نام حساب مرتبط با تخصیص کار.
تعداد CPUهای دردسترس کار روی گره‌های موجود در تخصیص، با استفاده از قالب CPU_count[(xnumber_of_nodes)][,CPU_count [(xnumber_of_nodes)] ...]. برای مثال: SLURM_JOB_CPUS_PER_NODE='72(x2),36' نشان می‌دهد که روی گره‌های اول و دوم (همان‌طور که در SLURM_JOB_NODELIST فهرست شده) تخصیص دارای ۷۲ پردازنده است، در حالی که گره سوم ۳۶ پردازنده دارد. نکته: افزونه select/linear گره‌های کامل را به کارها تخصیص می‌دهد، بنابراین این مقدار نشان‌دهنده تعداد کل CPUها در گره‌های تخصیص‌یافته است. افزونه select/cons_tres پردازنده‌های منفرد را به کارها تخصیص می‌دهد، بنابراین این عدد نشان‌دهنده تعداد CPUهای تخصیص‌یافته به کار است.
برچسب زمان یونیکس (UNIX timestamp) برای زمان تخمینی پایان کار.
شناسه‌های سراسری GPU (global GPU IDs) برای GPUهای تخصیص‌یافته به این کار. شناسه‌های GPU نسبت به هیچ cgroup دستگاهی سنجیده نمی‌شوند، حتی اگر دستگاه‌ها با task/cgroup محدود شده باشند. فقط در کارهای دسته‌ای (batch) و تعاملی (interactive) تنظیم می‌شود.
شناسه تخصیص کار.
فهرست گره‌های تخصیص‌یافته به کار.
تعداد کل گره‌ها در تخصیص کار.
نام پارتیشنی که کار در آن در حال اجرا است.
کیفیت سرویس (QOS) برای تخصیص کار.
رزرو پیشرفته (advanced reservation) شامل تخصیص کار، در صورت وجود.
برچسب زمان یونیکس (UNIX timestamp) برای زمان شروع کار.
اتصال وظایف به حافظه (Memory binding).
برابر با ماسک بیتی (bit mask) استفاده‌شده برای اتصال حافظه تنظیم می‌شود.
اگر گزینه SLURM_MEM_BIND شامل گزینه prefer باشد، روی “prefer” تنظیم می‌شود.
برابر با نوع اتصال حافظه مشخص‌شده با گزینه SLURM_MEM_BIND تنظیم می‌شود. مقادیر ممکن عبارتند از “none”، “rank”، “map_mem:”، “mask_mem:” و “local”.
اگر گزینه SLURM_MEM_BIND شامل گزینه verbose باشد، روی “verbose” تنظیم می‌شود. در غیر این صورت روی “quiet” تنظیم می‌شود.
حداقل حافظه مورد نیاز به ازای هر CPU قابل استفاده تخصیص‌یافته.
حافظه درخواستی به ازای هر GPU تخصیص‌یافته. SLURM_MEM_PER_NODE حافظه واقعی مورد نیاز به ازای هر گره را مشخص می‌کند.
تعداد تسک‌هایی که باید اجرا شوند را مشخص می‌کند.
درخواست اجرای حداکثر ntasks روی هر هسته.
درخواست اجرای ntasks تسک به ازای هر GPU.
درخواست اجرای ntasks روی هر گره.
درخواست اجرای حداکثر ntasks روی هر سوکت.
تخصیص بیش از ظرفیت منابع (Overcommit).
جمع‌آوری تفصیلی داده‌ها توسط افزونه acct_gather_profile را فعال می‌کند.
تعداد GPU Shardهای در دسترس برای این گام روی این گره.
نام میزبان رایانه‌ای که scrun از آن فراخوانی شده است.
تعداد تسک‌هایی که باید روی هر گره آغاز شوند. مقادیر با کاما از هم جدا شده و به همان ترتیب SLURM_JOB_NODELIST هستند. اگر دو یا چند گره متوالی دارای تعداد تسک یکسانی باشند، آن تعداد با «(x#)» دنبال می‌شود که در آن «#» تعداد تکرار است. برای مثال، «SLURM_TASKS_PER_NODE=2(x3),1» مشخص می‌کند که سه گره اول هر کدام دو تسک و گره چهارم یک تسک را اجرا خواهند کرد.
این متغیر تنها زمانی تنظیم می‌شود که --threads-per-core یا SCRUN_THREADS_PER_CORE مشخص شده باشند. مقدار آن برابر با مقدار تعیین‌شده توسط --threads-per-core یا SCRUN_THREADS_PER_CORE خواهد بود. این متغیر توسط فراخوانی‌های بعدی srun در تخصیص کار استفاده می‌شود.
روی مقدار --tres-per-task تنظیم می‌شود. اگر --cpus-per-task یا --gpus-per-task مشخص شده باشد، در SLURM_TRES_PER_TASK نیز تنظیم می‌گردد، درست مانند اینکه در --tres-per-task تعیین شده باشد.

فایل /etc/slurm/scrun.lua باید روی هر گره‌ای که scrun در آن فراخوانی خواهد شد، وجود داشته باشد. scrun.lua باید یک اسکریپت معتبر و سازگار با lua باشد..SS "توابع مورد نیاز (Required functions)" توابع زیر باید تعریف شوند.

• function slurm_scrun_stage_in(id, bundle, spool_dir, config_file, job_id, user_id, group_id, job_env)
درست پس از تخصیص کار (job allocation) برای آماده‌سازی و انتقال به درون (stage in) کانتینر به گره(های) کار فراخوانی می‌شود. باید مقدار SLURM.success را برگرداند، در غیر این صورت کار لغو خواهد شد. ضروری است که تابع، کانتینر را جهت اجرا روی گره(های) کار بر اساس آنچه در oci.conf(1) پیکربندی شده، آماده سازد. این تابع می‌تواند تا زمانی که کانتینر کاملاً آماده شود معلق (block) بماند (حداکثر تا سقف زمان مجاز اجرای کار یا wall time).
شناسه کانتینر (Container ID)
مسیر OCI bundle
دایرکتوری کاری موقت برای کانتینر
مسیر فایل config.json برای کانتینر
مقدار jobid مربوط به تخصیص کار
شناسه کاربری عددی حل‌شده برای تخصیص کار. به‌طور کلی انتظار می‌رود که اسکریپت lua درون یک user namespace تحت کاربر root(0) اجرا شود.
شناسه گروهی عددی حل‌شده برای تخصیص کار. به‌طور کلی انتظار می‌رود که اسکریپت lua درون یک user namespace تحت گروه root(0) اجرا شود.
جدولی که هر ورودی آن کلید=مقدار (Key=Value) یا مقدارِ هر متغیر محیطیِ کار است.
• function slurm_scrun_stage_out(id, bundle, orig_bundle, root_path, orig_root_path, spool_dir, config_file, jobid, user_id, group_id)
درست پس از اتمام گام کانتینر (container step) جهت انتقال فایل‌ها به بیرون (stage out) از گره‌های کار فراخوانی می‌شود. باید مقدار SLURM.success را برگرداند، در غیر این صورت کار لغو خواهد شد. ضروری است که این تابع هرگونه تغییرات را بازگردانی کرده و کانتینر را در گره(های) کار پاک‌سازی کند. این تابع می‌تواند تا زمانی که آماده‌سازی کانتینر کامل شود معلق (block) بماند (حداکثر تا سقف زمان مجاز اجرای کار یا wall time).
شناسه کانتینر (Container ID)
مسیر OCI bundle
مسیر اولیه OCI bundle ثبت‌شده، پیش از اعمال تغییرات توسط set_bundle_path().
مسیر دایرکتوری ریشهٔ محتویات کانتینر.
مسیر اولیه به دایرکتوری ریشهٔ محتویات کانتینر، پیش از اعمال تغییرات توسط set_root_path().
دایرکتوری کاری موقت برای کانتینر
مسیر فایل config.json برای کانتینر
مقدار jobid مربوط به تخصیص کار
شناسه کاربری عددی حل‌شده برای تخصیص کار. به‌طور کلی انتظار می‌رود که اسکریپت lua درون یک user namespace تحت کاربر root(0) اجرا شود.
شناسه گروهی عددی حل‌شده برای تخصیص کار. به‌طور کلی انتظار می‌رود که اسکریپت lua درون یک user namespace تحت گروه root(0) اجرا شود. توابع زیر برای فراخوانی توسط هر تابع Lua در صورت نیاز ارائه شده‌اند.
• slurm.set_bundle_path(PATH)
برای آگاه‌سازی scrun جهت استفاده از PATH به‌‌عنوان مسیر جدید بسته کانتینر OCI فراخوانی می‌شود. بسته به چیدمان سیستم‌فایل، ممکن است برای امکان‌پذیر ساختن اجرا روی گره‌های کاری (job nodes)، کلون کردن بسته کانتینر لازم باشد.
• slurm.set_root_path(PATH)
برای آگاه‌سازی scrun جهت استفاده از PATH به‌‌عنوان مسیر جدید سیستم‌فایل ریشه کانتینر فراخوانی می‌شود. بسته به چیدمان سیستم‌فایل، ممکن است برای امکان‌پذیر ساختن اجرا روی گره‌های کاری، کلون کردن بسته کانتینر لازم باشد. اسکریپت همچنین باید هنگام تغییر مسیر ریشه، #/root/path را در config.json به‌روزرسانی کند.
• STATUS,OUTPUT = slurm.remote_command(SCRIPT)
اجرای SCRIPT در یک گام کاری (job step) جدید روی تمام گره‌های کاری. وضعیت عددی کار را به‌صورت STATUS و stdio کار را به‌صورت OUTPUT بازمی‌گرداند. تا زمان خروج SCRIPT مسدود می‌شود.
• STATUS,OUTPUT = slurm.allocator_command(SCRIPT)
اجرای SCRIPT به‌صورت فرایند فرزند منشعب‌شده (forked) از scrun. وضعیت عددی کار را به‌صورت STATUS و stdio کار را به‌صورت OUTPUT بازمی‌گرداند. تا زمان خروج SCRIPT مسدود می‌شود.
• slurm.log(MSG, LEVEL)
ثبت MSG در سطح لاگ LEVEL. بازه معتبر مقادیر برای LEVEL برابر [0, 4] است.
• slurm.error(MSG)
ثبت پیام خطای MSG.
• slurm.log_error(MSG)
ثبت پیام خطای MSG.
• slurm.log_info(MSG)
ثبت MSG در سطح لاگ INFO.
• slurm.log_verbose(MSG)
ثبت MSG در سطح لاگ VERBOSE.
• slurm.log_verbose(MSG)
ثبت MSG در سطح لاگ VERBOSE.
• slurm.log_debug(MSG)
ثبت MSG در سطح لاگ DEBUG.
• slurm.log_debug2(MSG)
ثبت MSG در سطح لاگ DEBUG2.
• slurm.log_debug3(MSG)
ثبت MSG در سطح لاگ DEBUG3.
• slurm.log_debug4(MSG)
ثبت MSG در سطح لاگ DEBUG4.
• MINUTES = slurm.time_str2mins(TIME_STRING)
تجزیه TIME_STRING به تعداد دقایق در قالب MINUTES. قالب‌های معتبر:
• days-[hours[:minutes[:seconds]]]
• hours:minutes:seconds
• minutes[:seconds]
• -1
• INFINITE
• UNLIMITED
نمونهٔ کامل استیجینگ کانتینر با استفاده از rsync:
این نمونه کامل، کانتینر ارائه‌شده توسط docker یا podman را آماده‌سازی (stage) می‌کند. فایل config.json کانتینر برای حذف عملکردهای نامطلوبی که ممکن است اجرای کانتینر را تحت crun یا runc دچار مشکل کنند، ویرایش می‌شود. این اسکریپت از rsync برای انتقال کانتینر به یک سیستم‌فایل اشتراکی تحت متغیر scratch_path استفاده می‌کند.

نکته: پشتیبانی از JSON در liblua عموماً باید پیش از کامپایل شدن Slurm نصب شده باشد. نحو scrun.lua و توانایی آن در بارگذاری پشتیبانی از JSON باید با فراخوانی مستقیم اسکریپت با استفاده از lua در خارج از Slurm آزمایش شود.

local open = io.open
local scratch_path = "/run/user"
local function read_file(path)
	local file = open(path, "rb")
	if not file then return nil end
	local content = file:read "*all"
	file:close()
	return content
end
local function write_file(path, contents)
	local file = open(path, "wb")
	if not file then return nil end
	file:write(contents)
	file:close()
	return
end
function slurm_scrun_stage_in(id, bundle, spool_dir, config_file, job_id, user_id, group_id, job_env)
	slurm.log_debug(string.format("stage_in(%s, %s, %s, %s, %d, %d, %d)",
		       id, bundle, spool_dir, config_file, job_id, user_id, group_id))
	local status, output, user, rc
	local config = slurm.from_json(read_file(config_file))
	local src_rootfs = config["root"]["path"]
	rc, user = slurm.allocator_command(string.format("id -un %d", user_id))
	user = string.gsub(user, "%s+", "")
	local root = scratch_path.."/"..math.floor(user_id).."/slurm/scrun/"
	local dst_bundle = root.."/"..id.."/"
	local dst_config = root.."/"..id.."/config.json"
	local dst_rootfs = root.."/"..id.."/rootfs/"
	if string.sub(src_rootfs, 1, 1) ~= "/"
	then
		-- always use absolute path
		src_rootfs = string.format("%s/%s", bundle, src_rootfs)
	end
	status, output = slurm.allocator_command("mkdir -p "..dst_rootfs)
	if (status ~= 0)
	then
		slurm.log_info(string.format("mkdir(%s) failed %u: %s",
			       dst_rootfs, status, output))
		return slurm.ERROR
	end
	status, output = slurm.allocator_command(string.format("/usr/bin/env rsync --exclude sys --exclude proc --numeric-ids --delete-after --ignore-errors --stats -a -- %s/ %s/", src_rootfs, dst_rootfs))
	if (status ~= 0)
	then
		-- rsync can fail due to permissions which may not matter
		slurm.log_info(string.format("WARNING: rsync failed: %s", output))
	end
	slurm.set_bundle_path(dst_bundle)
	slurm.set_root_path(dst_rootfs)
	config["root"]["path"] = dst_rootfs
	-- Always force user namespace support in container or runc will reject
	local process_user_id = 0
	local process_group_id = 0
	if ((config["process"] ~= nil) and (config["process"]["user"] ~= nil))
	then
		-- resolve out user in the container
		if (config["process"]["user"]["uid"] ~= nil)
		then
			process_user_id=config["process"]["user"]["uid"]
		else
			process_user_id=0
		end
		-- resolve out group in the container
		if (config["process"]["user"]["gid"] ~= nil)
		then
			process_group_id=config["process"]["user"]["gid"]
		else
			process_group_id=0
		end
		-- purge additionalGids as they are not supported in rootless
		if (config["process"]["user"]["additionalGids"] ~= nil)
		then
			config["process"]["user"]["additionalGids"] = nil
		end
	end
	if (config["linux"] ~= nil)
	then
		-- force user namespace to always be defined for rootless mode
		local found = false
		if (config["linux"]["namespaces"] == nil)
		then
			config["linux"]["namespaces"] = {}
		else
			for _, namespace in ipairs(config["linux"]["namespaces"]) do
				if (namespace["type"] == "user")
				then
					found=true
					break
				end
			end
		end
		if (found == false)
		then
			table.insert(config["linux"]["namespaces"], {type= "user"})
		end
		-- Provide default user map as root if one not provided
		if (true or config["linux"]["uidMappings"] == nil)
		then
			config["linux"]["uidMappings"] =
				{{containerID=process_user_id, hostID=math.floor(user_id), size=1}}
		end
		-- Provide default group map as root if one not provided
		-- mappings fail with build???
		if (true or config["linux"]["gidMappings"] == nil)
		then
			config["linux"]["gidMappings"] =
				{{containerID=process_group_id, hostID=math.floor(group_id), size=1}}
		end
		-- disable trying to use a specific cgroup
		config["linux"]["cgroupsPath"] = nil
	end
	if (config["mounts"] ~= nil)
	then
		-- Find and remove any user/group settings in mounts
		for _, mount in ipairs(config["mounts"]) do
			local opts = {}
			if (mount["options"] ~= nil)
			then
				for _, opt in ipairs(mount["options"]) do
					if ((string.sub(opt, 1, 4) ~= "gid=") and (string.sub(opt, 1, 4) ~= "uid="))
					then
						table.insert(opts, opt)
					end
				end
			end
			if (opts ~= nil and #opts > 0)
			then
				mount["options"] = opts
			else
				mount["options"] = nil
			end
		end
		-- Remove all bind mounts by copying files into rootfs
		local mounts = {}
		for i, mount in ipairs(config["mounts"]) do
			if ((mount["type"] ~= nil) and (mount["type"] == "bind") and (string.sub(mount["source"], 1, 4) ~= "/sys") and (string.sub(mount["source"], 1, 5) ~= "/proc"))
			then
				status, output = slurm.allocator_command(string.format("/usr/bin/env rsync --numeric-ids --ignore-errors --stats -a -- %s %s", mount["source"], dst_rootfs..mount["destination"]))
				if (status ~= 0)
				then
					-- rsync can fail due to permissions which may not matter
					slurm.log_info("rsync failed")
				end
			else
				table.insert(mounts, mount)
			end
		end
		config["mounts"] = mounts
	end
	-- Force version to one compatible with older runc/crun at risk of new features silently failing
	config["ociVersion"] = "1.0.0"
	-- Merge in Job environment into container -- this is optional!
	if (config["process"]["env"] == nil)
	then
		config["process"]["env"] = {}
	end
	for _, env in ipairs(job_env) do
		table.insert(config["process"]["env"], env)
	end
	-- Remove all prestart hooks to squash any networking attempts
	if ((config["hooks"] ~= nil) and (config["hooks"]["prestart"] ~= nil))
	then
		config["hooks"]["prestart"] = nil
	end
	-- Remove all rlimits
	if ((config["process"] ~= nil) and (config["process"]["rlimits"] ~= nil))
	then
		config["process"]["rlimits"] = nil
	end
	write_file(dst_config, slurm.to_json(config))
	slurm.log_info("created: "..dst_config)
	return slurm.SUCCESS
end
function slurm_scrun_stage_out(id, bundle, orig_bundle, root_path, orig_root_path, spool_dir, config_file, jobid, user_id, group_id)
	if (root_path == nil)
	then
		root_path = ""
	end
	slurm.log_debug(string.format("stage_out(%s, %s, %s, %s, %s, %s, %s, %d, %d, %d)",
		       id, bundle, orig_bundle, root_path, orig_root_path, spool_dir, config_file, jobid, user_id, group_id))
	if (bundle == orig_bundle)
	then
		slurm.log_info(string.format("skipping stage_out as bundle=orig_bundle=%s", bundle))
		return slurm.SUCCESS
	end
	status, output = slurm.allocator_command(string.format("/usr/bin/env rsync --numeric-ids --delete-after --ignore-errors --stats -a -- %s/ %s/", root_path, orig_root_path))
	if (status ~= 0)
	then
		-- rsync can fail due to permissions which may not matter
		slurm.log_info("rsync failed")
	else
		-- cleanup temporary after they have been synced backed to source
		slurm.allocator_command(string.format("/usr/bin/rm --preserve-root=all --one-file-system -dr -- %s", bundle))
	end
	return slurm.SUCCESS
end
slurm.log_info("initialized scrun.lua")
return slurm.SUCCESS
تلاش برای لغو منظم کارهای مرتبط (در صورت وجود) و پاک‌سازی.
انتظار برای تمام فرزندان، پاک‌سازی anchor و خاموش‌سازی منظم.

حق نشر (C) 2023 SchedMD LLC.

این فایل بخشی از Slurm، یک برنامه‌ی مدیریت منابع است. برای جزئیات، https://slurm.schedmd.com را ببینید.

نرم‌افزار Slurm نرم‌افزار آزاد است؛ شما می‌توانید آن را تحت شرایط «پروانه عمومی همگانی گنو» همان‌طور که توسط بنیاد نرم‌افزارهای آزاد منتشر شده است، چه نسخه ۲ پروانه و چه (به انتخاب خودتان) هر نسخهٔ بعدی دیگری، بازتوزیع کرده یا تغییر دهید.

نرم‌افزار Slurm با این امید توزیع شده است که مفید واقع شود، اما بدون هرگونه ضمانتی؛ حتی بدون ضمانت ضمنی قابل فروش بودن یا مناسب بودن برای یک هدف خاص. برای جزئیات بیشتر به «پروانه عمومی همگانی گنو» مراجعه کنید.

slurm(1)، oci.conf(5)، srun(1)، crun، runc، DOCKER و podman

Slurm Commands Slurm 26.05