scrun
部分:Slurm 命令 (1)更新:Slurm 命令
索引
名称
scrun - Slurm 的 OCI 运行时代理。概要
创建操作
-
在当前工作目录中准备一个新的容器,容器 ID 为 container-id。
启动操作
-
请求启动并运行容器。
查询状态操作
-
输出 OCI 定义的容器 JSON 状态。
杀死操作
-
向容器发送信号(默认:SIGTERM)。
删除操作
-
释放容器在本地和远程持有的任何资源。
根据以下内容对container-id执行 OCI 运行时操作:
https://github.com/opencontainers/runtime-spec/blob/main/runtime.mdscrun 尝试尽可能模仿crun 和runc 的命令行行为,以保持与DOCKER 和podman 的就地替换兼容性。所有crun 和runc 的命令行参数都将被接受以保持兼容性,但可能会根据其适用性被忽略。
描述
scrun 是 Slurm 的 OCI 运行时代理。它充当与DOCKER 或podman 的公共接口,以允许在 Slurm 下作为作业执行容器操作。scrun 将接受所有作为 OCI 兼容运行时的命令,但会将容器及其所有 STDIO 代理到 Slurm 进行调度和执行。容器将根据oci.conf(5) 中的设置在 Slurm 计算节点上远程执行。
scrun 要求所有容器符合 OCI 镜像标准:
https://github.com/opencontainers/image-spec/blob/main/spec.md
返回值
在操作成功时,scrun 将返回 0。对于任何其他情况,scrun 将返回任何非零数字以表示错误。全局选项
- --cgroup-manager
- 被忽略。
-
- --debug
- 激活调试级别日志记录。
-
- -f <slurm_conf_path>
- 使用指定的 slurm.conf 进行配置。
默认:在编译期间从configure获取的 sysconfdir -
- --usage
- 显示关于如何调用scrun的快速帮助
-
- --log-format=<json|text>
- 可选选择日志记录格式。可以是“json”或“text”。
默认:文本 -
- --root=<root_path>
- 用于通信套接字和临时目录及文件的存储目录路径。此路径应为 tmpfs,并应在重启时清除。
默认:/run/user/{user_id}/scrun/ -
- --rootless
- 被忽略。所有scrun命令始终是无根的。
-
- --systemd-cgroup
- 被忽略。
-
- -v
- 增加日志记录详细程度。多个 -v 会增加详细程度。
-
- -V, --version
- 打印版本信息并退出。
-
创建选项
- -b <bundle_path>, --bundle=<bundle_path>
- 指向捆绑目录的根路径。
默认:调用者的工作目录 -
- --console-socket=<console_socket_path>
- 可选路径,指向一个 AF_UNIX 套接字,该套接字将接收一个引用控制台伪终端主端的文件描述符。
默认:被忽略 -
- --no-pivot
- 被忽略。
-
- --no-new-keyring
- 被忽略。
-
- --pid-file=<pid_file_path>
- 指定要锁定并填充进程 ID 的文件。
默认:被忽略 -
- --preserve-fds
- 被忽略。
-
删除选项
输入环境变量
- SCRUN_DEBUG=<quiet|fatal|error|info|verbose|debug|debug2|debug3|debug4|debug5>
- 设置日志记录级别。
-
- SCRUN_STDERR_DEBUG=<quiet|fatal|error|info|verbose|debug|debug2|debug3|debug4|debug5>
- 仅为标准错误输出设置日志记录级别。
-
- SCRUN_SYSLOG_DEBUG=<quiet|fatal|error|info|verbose|debug|debug2|debug3|debug4|debug5>
- 仅为系统日志记录设置日志记录级别。
-
- SCRUN_FILE_DEBUG=<quiet|fatal|error|info|verbose|debug|debug2|debug3|debug4|debug5>
- 仅为日志文件设置日志记录级别。
-
作业输入环境变量
- SCRUN_ACCOUNT
- 参见SLURM_ACCOUNT,来自srun(1)。
-
- SCRUN_ACCTG_FREQ
- 参见SLURM_ACCTG_FREQ,来自srun(1)。
-
- SCRUN_BURST_BUFFER
- 参见SLURM_BURST_BUFFER,来自srun(1)。
-
- SCRUN_CLUSTER_CONSTRAINT
- 参见SLURM_CLUSTER_CONSTRAINT,来自srun(1)。
-
- SCRUN_CLUSTERS
- 参见SLURM_CLUSTERS,来自srun(1)。
-
- SCRUN_CONSTRAINT
- 参见SLURM_CONSTRAINT,来自srun(1)。
-
- SLURM_CORE_SPEC
- 参见SLURM_ACCOUNT,来自srun(1)。
-
- SCRUN_CPU_BIND
- 参见SLURM_CPU_BIND,来自srun(1)。
-
- SCRUN_CPU_FREQ_REQ
- 参见SLURM_CPU_FREQ_REQ,来自srun(1)。
-
- SCRUN_CPUS_PER_GPU
- 参见SLURM_CPUS_PER_GPU,来自srun(1)。
-
- SCRUN_CPUS_PER_TASK
- 参见SRUN_CPUS_PER_TASK,来自srun(1)。
-
- SCRUN_DELAY_BOOT
- 参见SLURM_DELAY_BOOT,来自srun(1)。
-
- SCRUN_DEPENDENCY
- 参见SLURM_DEPENDENCY,来自srun(1)。
-
- SCRUN_DISTRIBUTION
- 参见SLURM_DISTRIBUTION,来自srun(1)。
-
- SCRUN_EPILOG
- 参见SLURM_EPILOG,来自srun(1)。
-
- SCRUN_EXACT
- 参见SLURM_EXACT,来自srun(1)。
-
- SCRUN_EXCLUSIVE
- 参见SLURM_EXCLUSIVE,来自srun(1)。
-
- SCRUN_GPU_BIND
- 参见SLURM_GPU_BIND,来自srun(1)。
-
- SCRUN_GPU_FREQ
- 参见SLURM_GPU_FREQ,来自srun(1)。
-
- SCRUN_GPUS
- 参见SLURM_GPUS,来自srun(1)。
-
- SCRUN_GPUS_PER_NODE
- 参见SLURM_GPUS_PER_NODE,来自srun(1)。
-
- SCRUN_GPUS_PER_SOCKET
- 参见SLURM_GPUS_PER_SOCKET,来自salloc(1)。
-
- SCRUN_GPUS_PER_TASK
- 参见SLURM_GPUS_PER_TASK,来自srun(1)。
-
- SCRUN_GRES_FLAGS
- 参见SLURM_GRES_FLAGS,来自srun(1)。
-
- SCRUN_GRES
- 参见SLURM_GRES,来自srun(1)。
-
- SCRUN_HINT
- 参见SLURM_HIST,来自srun(1)。
-
- SCRUN_JOB_NAME
- 参见SLURM_JOB_NAME,来自srun(1)。
-
- SCRUN_JOB_NODELIST
- 参见SLURM_JOB_NODELIST,来自srun(1)。
-
- SCRUN_JOB_NUM_NODES
- 参见SLURM_JOB_NUM_NODES,来自srun(1)。
-
- SCRUN_LABELIO
- 参见SLURM_LABELIO,来自srun(1)。
-
- SCRUN_MEM_BIND
- 参见SLURM_MEM_BIND,来自srun(1)。
-
- SCRUN_MEM_PER_CPU
- 参见SLURM_MEM_PER_CPU,来自srun(1)。
-
- SCRUN_MEM_PER_GPU
- 参见SLURM_MEM_PER_GPU,来自srun(1)。
-
- SCRUN_MEM_PER_NODE
- 参见SLURM_MEM_PER_NODE,来自srun(1)。
-
- SCRUN_MPI_TYPE
- 参见SLURM_MPI_TYPE,来自srun(1)。
-
- SCRUN_NCORES_PER_SOCKET
- 参见SLURM_NCORES_PER_SOCKET,来自srun(1)。
-
- SCRUN_NETWORK
- 参见SLURM_NETWORK,来自srun(1)。
-
- SCRUN_NSOCKETS_PER_NODE
- 参见SLURM_NSOCKETS_PER_NODE,来自srun(1)。
-
- SCRUN_NTASKS
- 参见SLURM_NTASKS,来自srun(1)。
-
- SCRUN_NTASKS_PER_CORE
- 参见SLURM_NTASKS_PER_CORE,来自srun(1)。
-
- SCRUN_NTASKS_PER_GPU
- 参见SLURM_NTASKS_PER_GPU,来自srun(1)。
-
- SCRUN_NTASKS_PER_NODE
- 参见SLURM_NTASKS_PER_NODE,来自srun(1)。
-
- SCRUN_NTASKS_PER_TRES
- 参见SLURM_NTASKS_PER_TRES,来自srun(1)。
-
- SCRUN_OPEN_MODE
- 参见SLURM_MODE,来自srun(1)。
-
- SCRUN_OVERCOMMIT
- 参见SLURM_OVERCOMMIT,来自srun(1)。
-
- SCRUN_OVERLAP
- 参见SLURM_OVERLAP,来自srun(1)。
-
- SCRUN_PARTITION
- 参见SLURM_PARTITION,来自srun(1)。
-
- SCRUN_POWER
- 参见SLURM_POWER,来自srun(1)。
-
- SCRUN_PROFILE
- 参见SLURM_PROFILE,来自srun(1)。
-
- SCRUN_PROLOG
- 参见SLURM_PROLOG,来自srun(1)。
-
- SCRUN_QOS
- 参见SLURM_QOS,来自srun(1)。
-
- SCRUN_REMOTE_CWD
- 参见SLURM_REMOTE_CWD,来自srun(1)。
-
- SCRUN_REQ_SWITCH
- 参见SLURM_REQ_SWITCH,来自srun(1)。
-
- SCRUN_RESERVATION
- 参见SLURM_RESERVATION,来自srun(1)。
-
- SCRUN_SIGNAL
- 参见SLURM_SIGNAL,来自srun(1)。
-
- SCRUN_SLURMD_DEBUG
- 参见SLURMD_DEBUG,来自srun(1)。
-
- SCRUN_SPREAD_JOB
- 参见SLURM_SPREAD_JOB,来自srun(1)。
-
- SCRUN_TASK_EPILOG
- 参见SLURM_TASK_EPILOG,来自srun(1)。
-
- SCRUN_TASK_PROLOG
- 参见SLURM_TASK_PROLOG,来自srun(1)。
-
- SCRUN_THREAD_SPEC
- 参见SLURM_THREAD_SPEC,来自srun(1)。
-
- SCRUN_THREADS_PER_CORE
- 参见SLURM_THREADS_PER_CORE,来自srun(1)。
-
- SCRUN_THREADS
- 参见SLURM_THREADS,来自srun(1)。
-
- SCRUN_TIMELIMIT
- 参见SLURM_TIMELIMIT,来自srun(1)。
-
- SCRUN_TRES_BIND
- 与--tres-bind相同
-
- SCRUN_TRES_PER_TASK
- 参见SLURM_TRES_PER_TASK,来自srun(1)。
-
- SCRUN_UNBUFFEREDIO
- 参见SLURM_UNBUFFEREDIO,来自srun(1)。
-
- SCRUN_USE_MIN_NODES
- 参见SLURM_USE_MIN_NODES,来自srun(1)。
-
- SCRUN_WAIT4SWITCH
- 参见SLURM_WAIT4SWITCH,来自srun(1)。
-
- SCRUN_WCKEY
- 参见SLURM_WCKEY,来自srun(1)。
-
- SCRUN_WORKING_DIR
- 参见SLURM_WORKING_DIR,来自srun(1)。
-
输出环境变量
- SCRUN_OCI_VERSION
- 容器的 OCI 合规性广告版本。
-
- SCRUN_CONTAINER_ID
- 在创建操作期间基于container_id的值。
-
- SCRUN_PID
- 用于监控和控制分配节点上容器的进程 PID。
-
- SCRUN_BUNDLE
- 指向容器捆绑目录的路径。
-
- SCRUN_SUBMISSION_BUNDLE
- 在 Lua 脚本修改之前指向容器捆绑目录的路径。
-
- SCRUN_ANNOTATION_*
- 来自容器的 config.json 的注释列表。
-
- SCRUN_PID_FILE
- 指向 PID 文件的路径,该文件被锁定并填充 scrun 的 PID。
-
- SCRUN_SOCKET
- 指向 scrun 控制套接字的路径。
" href="#OPT_SCRUN_SUBMISSION_CONFIG_FILE"> - 提交时容器的 config.json 文件路径。
-
- SCRUN_USER
- 调用创建操作的用户名称。
-
- SCRUN_USER_ID
- 调用创建操作的用户的数字 ID。
-
- SCRUN_GROUP
- 调用创建操作的用户的主要组名称。
-
- SCRUN_GROUP_ID
- 调用创建操作的用户主要组的数字 ID。
-
- SCRUN_ROOT
- 请参见 --root。
-
- SCRUN_ROOTFS_PATH
- 容器根目录的路径。
-
- SCRUN_SUBMISSION_ROOTFS_PATH
- 提交时容器根目录的路径。
-
- SCRUN_LOG_FILE
- 创建操作期间 scrun 的日志文件路径。
-
- SCRUN_LOG_FORMAT
- 创建操作期间的日志格式类型。
-
作业输出环境变量
- SLURM_*_HET_GROUP_#
- 对于异构作业分配,环境变量会为每个组件单独设置。
-
- SLURM_CLUSTER_NAME
- 作业正在执行的集群名称。
-
- SLURM_CONTAINER
- 作业的 OCI 包。
-
- SLURM_CONTAINER_ID
- 作业的 OCI ID。
-
- SLURM_CPUS_PER_GPU
- 每个分配的 GPU 请求的 CPU 数量。
-
- SLURM_CPUS_PER_TASK
- 每个任务请求的 CPU 数量。
-
- SLURM_DIST_PLANESIZE
- 平面分布大小。仅为平面分布设置。
-
- SLURM_DISTRIBUTION
- 分配作业的分布类型。
-
- SLURM_GPU_BIND
- 请求将任务绑定到 GPU。
-
- SLURM_GPU_FREQ
- 请求的 GPU 频率。
-
- SLURM_GPUS
- 请求的 GPU 数量。
-
- SLURM_GPUS_PER_NODE
- 每个分配节点请求的 GPU 数量。
-
- SLURM_GPUS_PER_SOCKET
- 每个分配插槽请求的 GPU 数量。
-
- SLURM_GPUS_PER_TASK
- 每个分配任务请求的 GPU 数量。
-
- SLURM_HET_SIZE
- 设置为异构作业中的组件数量。
-
- SLURM_JOB_ACCOUNT
- 与作业分配相关联的账户名称。
-
- SLURM_JOB_CPUS_PER_NODE
- 分配节点上可用于作业的 CPU 数量,使用格式 CPU_count[(xnumber_of_nodes)][,CPU_count[(xnumber_of_nodes)] ...]。 例如:SLURM_JOB_CPUS_PER_NODE='72(x2),36' 表示在第一个和第二个节点(如 SLURM_JOB_NODELIST 列出)上分配了 72 个 CPU,而第三个节点上有 36 个 CPU。 注意:select/linear 插件将整个节点分配给作业,因此该值表示分配节点上 CPU 的总数。select/cons_tres 插件将单个 CPU 分配给作业,因此该数字表示分配给作业的 CPU 数量。
-
- SLURM_JOB_END_TIME
- 作业预计结束时间的 UNIX 时间戳。
-
- SLURM_JOB_GPUS
- 分配给该作业的 GPU 的全局 GPU ID。GPU ID 不相对于任何设备 cgroup,即使设备受到任务/cgroup 的约束。 仅在批处理和交互式作业中设置。
-
- SLURM_JOB_ID
- 作业分配的 ID。
-
- SLURM_JOB_NODELIST
- 分配给作业的节点列表。
-
- SLURM_JOB_NUM_NODES
- 作业分配中的节点总数。
-
- SLURM_JOB_PARTITION
- 作业正在运行的分区名称。
-
- SLURM_JOB_QOS
- 作业分配的服务质量 (QOS)。
-
- SLURM_JOB_RESERVATION
- 包含作业分配的高级预留(如果有)。
-
- SLURM_JOB_START_TIME
- 作业开始时间的 UNIX 时间戳。
-
- SLURM_MEM_BIND
- 将任务绑定到内存。
-
- SLURM_MEM_BIND_LIST
- 设置为用于内存绑定的位掩码。
-
- SLURM_MEM_BIND_PREFER
- 如果 SLURM_MEM_BIND 选项包括 prefer 选项,则设置为“prefer”。
-
- SLURM_MEM_BIND_SORT
- 对空闲缓存页面进行排序(在 Intel KNL 节点上运行 zonesort)
-
- SLURM_MEM_BIND_TYPE
- 设置为使用 SLURM_MEM_BIND 选项指定的内存绑定类型。 可能的值为“none”、“rank”、“map_map”、“mask_mem”和“local”。
-
- SLURM_MEM_BIND_VERBOSE
- 如果 SLURM_MEM_BIND 选项包括详细选项,则设置为“verbose”。 否则设置为“quiet”。
-
- SLURM_MEM_PER_CPU
- 每个可用分配 CPU 所需的最小内存。
-
- SLURM_MEM_PER_GPU
- 每个分配 GPU 请求的内存。
-
- SLURM_MEM_PER_NODE
- 指定每个节点所需的实际内存。
-
- SLURM_NTASKS
- 指定要运行的任务数量。
-
- SLURM_NTASKS_PER_CORE
- 请求在每个核心上调用最大 ntasks。
-
- SLURM_NTASKS_PER_GPU
- 请求为每个 GPU 调用 ntasks 任务。
-
- SLURM_NTASKS_PER_NODE
- 请求在每个节点上调用 ntasks。
-
- SLURM_NTASKS_PER_SOCKET
- 请求在每个插槽上调用最大 ntasks。
-
- SLURM_OVERCOMMIT
- 超额分配资源。
-
- SLURM_PROFILE
- 通过 acct_gather_profile 插件启用详细数据收集。
-
- SLURM_SHARDS_ON_NODE
- 此节点上可用于步骤的 GPU 分片数量。
-
- SLURM_SUBMIT_HOST
- 从中调用 scrun 的计算机的主机名。
-
- SLURM_TASKS_PER_NODE
- 每个节点上要启动的任务数量。值用逗号分隔,并与 SLURM_JOB_NODELIST 中的顺序相同。 如果两个或更多连续节点要具有相同的任务计数,则该计数后跟“(x#)”,其中“#”是重复计数。例如,“SLURM_TASKS_PER_NODE=2(x3),1”表示前 3 个节点将各自执行两个任务,而第四个节点将执行一个任务。
-
- SLURM_THREADS_PER_CORE
- 仅在指定了 --threads-per-core 或 SCRUN_THREADS_PER_CORE 时设置。该值将设置为 --threads-per-core 或 SCRUN_THREADS_PER_CORE 指定的值。此值在作业分配中的后续 srun 调用中使用。
-
- SLURM_TRES_PER_TASK
- 设置为 --tres-per-task 的值。如果指定了 --cpus-per-task 或 --gpus-per-task,则它也会在 SLURM_TRES_PER_TASK 中设置,就像在 --tres-per-task 中指定的一样。
-
SCRUN.LUA
/etc/slurm/scrun.lua 必须存在于任何将调用 scrun 的节点上。scrun.lua 必须是合规的 lua 脚本。
必需的函数
以下函数必须被定义。
- • function slurm_scrun_stage_in(id, bundle, spool_dir, config_file, job_id, user_id, group_id, job_env)
- 在作业分配后立即调用以将容器阶段放入作业节点。必须返回 SLURM.success,否则作业将被取消。要求该函数准备容器以便在作业节点上执行,按照 oci.conf(1) 中配置的要求。该函数可以阻塞,直到容器完全准备好(最长可达作业的最大墙时间)。
-
- id
- 容器 ID
- bundle
- OCI 包路径
- orig_bundle
- 在被 set_bundle_path() 修改之前提交的原始 OCI 包路径。
- root_path
- 容器内容的目录根路径。
- orig_root_path
- 在被 set_root_path() 修改之前的容器内容的目录根路径。
- spool_dir
- 容器的临时工作目录
- config_file
- 容器的 config.json 路径
- job_id
- jobid 的作业分配
- user_id
- 作业分配的解析数字用户 ID。通常期望 lua 脚本将在以 root(0) 用户身份运行的用户命名空间内执行。
- group_id
- 作业分配的解析数字组 ID。通常期望 lua 脚本将在以 root(0) 组身份运行的用户命名空间内执行。
提供的函数
以下函数可供任何 Lua 函数根据需要调用。
- • slurm.set_bundle_path(PATH)
-
调用以通知 scrun 使用 PATH 作为新的 OCI 容器包路径。根据文件系统布局,可能需要克隆容器包以允许在作业节点上执行。
- • slurm.set_root_path(PATH)
-
调用以通知 scrun 使用 PATH 作为新的容器根文件系统路径。根据文件系统布局,可能需要克隆容器包以允许在作业节点上执行。脚本在更改根路径时还必须更新 config.json 中的 #/root/path。
- • STATUS,OUTPUT = slurm.remote_command(SCRIPT)
-
在所有作业节点的新作业步骤中运行 SCRIPT。返回数字作业状态作为 STATUS 和作业标准输入输出作为 OUTPUT。阻塞直到 SCRIPT 退出。
- • STATUS,OUTPUT = slurm.allocator_command(SCRIPT)
-
作为 scrun 的分叉子进程运行 SCRIPT。返回数字作业状态作为 STATUS 和作业标准输入输出作为 OUTPUT。阻塞直到 SCRIPT 退出。
- • slurm.log(MSG, LEVEL)
-
在日志 LEVEL 记录 MSG。LEVEL 的有效值范围为 [0, 4]。
- • slurm.error(MSG)
-
记录错误 MSG。
- • slurm.log_error(MSG)
-
记录错误 MSG。
- • slurm.log_info(MSG)
-
在日志级别 INFO 记录 MSG。
- • slurm.log_verbose(MSG)
-
在日志级别 VERBOSE 记录 MSG。
- • slurm.log_verbose(MSG)
-
在日志级别 VERBOSE 记录 MSG。
- • slurm.log_debug(MSG)
-
在日志级别 DEBUG 记录 MSG。
- • slurm.log_debug2(MSG)
-
在日志级别 DEBUG2 记录 MSG。
- • slurm.log_debug3(MSG)
-
在日志级别 DEBUG3 记录 MSG。
- • slurm.log_debug4(MSG)
-
在日志级别 DEBUG4 记录 MSG。
- • MINUTES = slurm.time_str2mins(TIME_STRING)
-
将 TIME_STRING 解析为分钟数 MINUTES。有效格式:
-
- • days-[hours[:minutes[:seconds]]]
- • hours:minutes:seconds
- • minutes[:seconds]
- • -1
- • INFINITE
- • UNLIMITED
-
示例 scrun.lua 脚本
- 使用 rsync 的完整容器阶段示例:
-
此完整示例将根据 docker 或 podman 阶段一个容器。容器的 config.json 被修改以删除可能导致容器在 crun 或 runc 下运行的无用功能。
该脚本使用 rsync 将容器移动到 scratch_path 变量下的共享文件系统。
注意:在编译 Slurm 之前,必须通常安装 liblua 中对 JSON 的支持。通过直接使用 lua 调用脚本来测试 scrun.lua 的语法和加载 JSON 支持的能力。
local json = require 'json' 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 = json.decode(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 -- 始终使用绝对路径 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 可能由于权限问题而失败,但这可能无关紧要 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 -- 始终强制容器中的用户命名空间支持,否则 runc 将拒绝 local process_user_id = 0 local process_group_id = 0 if ((config["process"] ~= nil) and (config["process"]["user"] ~= nil)) then -- 在容器中解析用户 if (config["process"]["user"]["uid"] ~= nil) then process_user_id=config["process"]["user"]["uid"] else process_user_id=0 end -- 在容器中解析组 if (config["process"]["user"]["gid"] ~= nil) then process_group_id=config["process"]["user"]["gid"] else process_group_id=0 end -- 清除 additionalGids,因为它们在无根模式下不受支持 if (config["process"]["user"]["additionalGids"] ~= nil) then config["process"]["user"]["additionalGids"] = nil end end if (config["linux"] ~= nil) then -- 强制用户命名空间始终在无根模式下定义 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 -- 如果未提供,则提供默认用户映射为 root if (true or config["linux"]["uidMappings"] == nil) then config["linux"]["uidMappings"] = {{containerID=process_user_id, hostID=math.floor(user_id), size=1}} end -- 如果未提供,则提供默认组映射为 root -- 映射在构建时失败??? if (true or config["linux"]["gidMappings"] == nil) then config["linux"]["gidMappings"] = {{containerID=process_group_id, hostID=math.floor(group_id), size=1}} end -- 禁用尝试使用特定 cgroup config["linux"]["cgroupsPath"] = nil end if (config["mounts"] ~= nil) then -- 查找并删除挂载中的任何用户/组设置 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 -- 通过将文件复制到 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 可能由于权限问题而失败,但这可能无关紧要 slurm.log_info("rsync failed") end else table.insert(mounts, mount) end end config["mounts"] = mounts end -- 强制版本与旧版 runc/crun 兼容,以防新功能静默失败 config["ociVersion"] = "1.0.0" -- 将作业环境合并到容器中 -- 这是可选的! if (config["process"]["env"] == nil) then config["process"]["env"] = {} end for _, env in ipairs(job_env) do table.insert(config["process"]["env"], env) end -- 删除所有预启动钩子以压制任何网络尝试 if ((config["hooks"] ~= nil) and (config["hooks"]["prestart"] ~= nil)) then config["hooks"]["prestart"] = nil end -- 删除所有 rlimits if ((config["process"] ~= nil) and (config["process"]["rlimits"] ~= nil)) then config["process"]["rlimits"] = nil end write_file(dst_config, json.encode(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 可能由于权限问题而失败,但这可能无关紧要 slurm.log_info("rsync failed") else -- 在同步回源后清理临时文件 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
信号
版权
版权所有 (C) 2023 SchedMD LLC。此文件是 Slurm 的一部分,资源管理程序。 有关详细信息,请参见 <https://slurm.schedmd.com/>。
Slurm 是自由软件;您可以根据自由软件基金会发布的 GNU 通用公共许可证的条款重新分发和/或修改它;许可证的第 2 版,或(根据您的选择)任何更高版本。
Slurm 的分发希望它能有用,但不提供任何担保;甚至没有适销性或适合特定目的的隐含担保。有关详细信息,请参阅 GNU 通用公共许可证。
另见
slurm(1), oci.conf(5), srun(1), crun, runc, DOCKER 和 podman
索引
此文档由 man2html 使用手册页创建。
时间:2025年7月2日 13:21:56 GMT