Skip to content

Commit

Permalink
[cms] Adapt to changes in crab.
Browse files Browse the repository at this point in the history
  • Loading branch information
riga committed Jan 11, 2025
1 parent 3403ef8 commit 5e43d64
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 19 deletions.
2 changes: 1 addition & 1 deletion law.cfg.example
Original file line number Diff line number Diff line change
Expand Up @@ -960,7 +960,7 @@
; installation, ``"dir"``, a custom install directory, ``"arch"``, a custom scram architecture, and
; ``"cores"``, the number of CPU cores to use for installation.
; Type: ``str``
; Default: ``"CMSSW_10_6_30"``
; Default: ``"CMSSW_14_2_1::arch=el9_amd64_gcc12"``

; crab_password_file
; Description: A file containing the X509 certificate password for automatic proxy delegations by
Expand Down
2 changes: 1 addition & 1 deletion law/contrib/cms/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def config_defaults(default_config: dict) -> dict[str, dict[str, Any]]:
"job": {
"crab_job_file_dir": None,
"crab_job_file_dir_cleanup": False,
"crab_sandbox_name": "CMSSW_10_6_30",
"crab_sandbox_name": "CMSSW_14_2_1::arch=el9_amd64_gcc12",
"crab_password_file": None,
},
"cmssw_sandbox": {
Expand Down
3 changes: 2 additions & 1 deletion law/contrib/cms/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ def query( # type: ignore[override]
shell=True,
executable="/bin/bash",
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
env=self.cmssw_env,
)

Expand Down Expand Up @@ -453,6 +454,7 @@ def extra(
"HOLDING on command SUBMIT",
"NEW on command SUBMIT",
"QUEUED on command SUBMIT",
"WAITING on command SUBMIT",
"SUBMITTED",
]
if server_status not in accepted_server_states:
Expand Down Expand Up @@ -711,7 +713,6 @@ def __init__(
("scriptExe", no_value),
("maxMemoryMB", 2048),
("allowUndistributedCMSSW", True),
("sendPythonFolder", False),
("disableAutomaticOutputCollection", True),
("inputFiles", no_value),
("outputFiles", no_value),
Expand Down
15 changes: 10 additions & 5 deletions law/contrib/cms/sandbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@

class CMSSWSandboxVariables(SandboxVariables):

fields = ("version", "setup", "args", "dir", "arch", "cores")
eq_fields = ("name", "version", "setup", "args", "dir", "arch")
fields = ("version", "setup", "args", "dir", "arch", "cores", "source")
eq_fields = ("name", "version", "setup", "args", "dir", "arch", "source")

@classmethod
def parse_name(cls, name: str) -> dict[str, Any]:
Expand All @@ -50,26 +50,31 @@ def parse_name(cls, name: str) -> dict[str, Any]:
if "cores" in values:
values["cores"] = int(values["cores"])

if "source" in values:
values["source"] = expand(values["source"])

return values

def __init__(
self,
name: str,
version: str,
setup: str | None = None,
setup: str | pathlib.Path | None = None,
args: str | None = None,
dir: str | None = None,
arch: str | None = None,
cores: int | None = None,
source: str | pathlib.Path | None = None,
) -> None:
super().__init__(name)

self.version = version
self.setup = setup
self.setup = str(setup) if setup else None
self.args = args
self.dir = dir
self.arch = arch
self.cores = cores
self.source = str(source) if source else None


class CMSSWSandbox(BashSandbox):
Expand Down Expand Up @@ -115,7 +120,7 @@ def env_cache_key(self) -> tuple[str, str, str]: # type: ignore[override]
# use version, setup, args, dir and arch as cache key
return tuple(
getattr(self.variables, attr)
for attr in ("version", "setup", "args", "dir", "arch")
for attr in CMSSWSandboxVariables.eq_fields[1:]
)

@property
Expand Down
7 changes: 6 additions & 1 deletion law/contrib/cms/scripts/delegate_myproxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,9 @@ def main():

# entry hook
if __name__ == "__main__":
main()
import sys

exit_code = main()

if isinstance(exit_code, int):
sys.exit(exit_code)
17 changes: 17 additions & 0 deletions law/contrib/cms/scripts/setup_cmssw.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
# The directory in which CMSSW is installed. Defaults to $LAW_HOME/cms/cmssw.
# - LAW_CMSSW_CORES:
# The number of cores to use for compilation. Defaults to 1.
# - LAW_CMSSW_SOURCE:
# A path to a script that is source'd after successful installation. Optional.

setup_cmssw() {
local shell_is_zsh="$( [ -z "${ZSH_VERSION}" ] && echo "false" || echo "true" )"
Expand Down Expand Up @@ -82,6 +84,7 @@ setup_cmssw() {
local custom_setup_args="${LAW_CMSSW_ARGS}"
local custom_install_dir="${LAW_CMSSW_DIR}"
local custom_install_cores="${LAW_CMSSW_CORES:-1}"
local custom_source_script="${LAW_CMSSW_SOURCE}"

# checks
if [ -z "${custom_cmssw_version}" ]; then
Expand Down Expand Up @@ -190,6 +193,20 @@ setup_cmssw() {
return "9"
fi

# additional source script
if [ ! -z "${custom_source_script}" ] && [ -f "${custom_source_script}" ]; then
source "${custom_source_script}" ""
local source_ret="$?"
if [ "${source_ret}" != "0" ]; then
>&2 echo "custom source script '${custom_source_script}' failed"
return "10"
fi
fi

# patch for crab: pythonpath is incomplete so add missing fragments
local cmssw_py_past_path="$( python3 -c "import os, past; print(os.path.normpath(os.path.join(past.__file__, '../..')))" )"
[ "$?" = "0" ] && export PYTHONPATH="${PYTHONPATH}:${cmssw_py_past_path}"

# setup done
return "0"
}
Expand Down
18 changes: 10 additions & 8 deletions law/contrib/cms/workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from law.logger import get_logger
from law._types import Any, Type, Generator

from law.contrib.wlcg import check_vomsproxy_validity, get_myproxy_info
from law.contrib.wlcg import get_vomsproxy_file, check_vomsproxy_validity, get_myproxy_info
from law.contrib.cms.job import CrabJobManager, CrabJobFileFactory
from law.contrib.cms.util import renew_vomsproxy, delegate_myproxy

Expand All @@ -46,13 +46,15 @@ def setup_job_manager(self) -> dict[str, Any]:
cfg = Config.instance()
password_file = cfg.get_expanded("job", "crab_password_file")

# determine the proxy file first
proxy_file = get_vomsproxy_file()

# ensure a VOMS proxy exists
if not check_vomsproxy_validity():
print("renew voms-proxy")
renew_vomsproxy(password_file=password_file)
renew_vomsproxy(proxy_file=proxy_file, password_file=password_file)

# ensure that it has been delegated to the myproxy server
info = get_myproxy_info(silent=True)
info = get_myproxy_info(proxy_file=proxy_file, silent=True)
delegate = False
if not info:
delegate = True
Expand All @@ -69,12 +71,11 @@ def setup_job_manager(self) -> dict[str, Any]:

# actual delegation
if delegate:
print("delegate to myproxy server")
myproxy_username = delegate_myproxy(password_file=password_file)
myproxy_username = delegate_myproxy(proxy_file=proxy_file, password_file=password_file)
else:
myproxy_username = info["username"] # type: ignore[index, assignment]

return {"myproxy_username": myproxy_username}
return {"proxy": proxy_file, "myproxy_username": myproxy_username}

def create_job_file_factory(self, **kwargs) -> CrabJobFileFactory:
return self.task.crab_create_job_file_factory(**kwargs) # type: ignore[attr-defined]
Expand Down Expand Up @@ -367,7 +368,8 @@ def crab_create_job_file_factory(self, **kwargs) -> CrabJobFileFactory:
def crab_job_config(
self,
config: CrabJobFileFactory.Config,
submit_jobs: dict[int, list[int]],
job_num: list[int],
branches: list[list[int]],
) -> CrabJobFileFactory.Config:
"""
Hook to inject custom settings into the job *config*, which is an instance of the
Expand Down
12 changes: 10 additions & 2 deletions law/contrib/wlcg/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ def delegate_myproxy(
userkey: str | pathlib.Path | None = None,
usercert: str | pathlib.Path | None = None,
username: str | None = None,
proxy_file: str | pathlib.Path | None = None,
encode_username: bool = True,
cred_lifetime: int = 720,
proxy_lifetime: int = 168,
Expand Down Expand Up @@ -399,7 +400,10 @@ def delegate_myproxy(
usercert = get_usercert()
usercert = str(usercert)
if not username:
username = get_vomsproxy_identity(silent=True) or get_usercert_subject()
username = (
get_vomsproxy_identity(proxy_file=proxy_file, silent=True) or
get_usercert_subject()
)
if encode_username:
username = hashlib.sha1(username.encode("utf-8")).hexdigest()

Expand Down Expand Up @@ -462,6 +466,7 @@ def delegate_myproxy(
def get_myproxy_info(
endpoint: str = "myproxy.cern.ch",
username: str | None = None,
proxy_file: str | pathlib.Path | None = None,
encode_username: bool = True,
silent: bool = False,
) -> dict[str, str | int] | None:
Expand All @@ -477,7 +482,10 @@ def get_myproxy_info(
"""
# prepare arguments
if not username:
username = get_vomsproxy_identity(silent=True) or get_usercert_subject()
username = (
get_vomsproxy_identity(proxy_file=proxy_file, silent=True) or
get_usercert_subject()
)
if encode_username:
username = hashlib.sha1(username.encode("utf-8")).hexdigest()

Expand Down

0 comments on commit 5e43d64

Please sign in to comment.