arc.job.ssh
A module for SSHing into servers. Used for giving commands, uploading, and downloading files.
- exception arc.job.ssh.HostKeyMismatchError[source]
Raised when the host key a server presents contradicts the one stored in
known_hosts.Told apart from
UnknownHostKeyError, which is the absence of a stored key, because the two mean different things: an absent key is a host never connected to before, while a contradicted key is either a re-keyed server or an interception, and only the second of those is a security event. Being an ARCServerErrorkeeps it inside ARC’s server error handling, and being aparamiko.SSHExceptionkeeps it catchable alongside the exception it is raised from.
- class arc.job.ssh.LogAndAcceptHostKeyPolicy[source]
A missing host key policy that reports the unknown key through ARC’s logger, then accepts it.
paramiko’s
WarningPolicyemits throughwarnings.warn(), which ARC’sarc.common.initialize_log()filters out for theparamikomodule, so nothing of it reaches the log file or the terminal. This policy logs the host and the key’s fingerprint at the warning level, and connects.
- class arc.job.ssh.RejectUnknownHostKeyPolicy[source]
A missing host key policy that refuses the connection, raising
UnknownHostKeyError.- missing_host_key(client, hostname, key)[source]
Refuse the unknown host key.
- Parameters:
client (paramiko.SSHClient) – The client the key was presented to.
hostname (str) – The address of the server that presented the key.
key (paramiko.PKey) – The host key that is not in
known_hosts.
- Raises:
UnknownHostKeyError – Always.
- class arc.job.ssh.SSHClient(server='', connection_attempts=1440)[source]
This is a class for communicating with remote servers via SSH.
- Parameters:
server (str) – The server name as specified in ARCs’s settings file under
serversas a key.connection_attempts (int, optional) – The number of times to try connecting to the server, waiting a minute between attempts. The default keeps trying for 24 hours, which is appropriate while jobs are running. Pass a low number where blocking is worse than giving up. A permanent failure raises on the first attempt whatever this is set to, see
connect().
- server
The server name as specified in ARCs’s settings file under
serversas a key.- Type:
str
- address
The server’s address.
- Type:
str
- un
The username to use on the server.
- Type:
str
- key
A path to a file containing the SSH private key to the server. Optional: when it is not set (or set to an empty string), no explicit identity is offered and paramiko falls back to a running ssh-agent and then to the default key paths (
~/.ssh/id_rsa,~/.ssh/id_ecdsa,~/.ssh/id_ed25519), which is how agent-based setups authenticate.- Type:
str | None
- connection_attempts
The number of times to try connecting to the server.
- Type:
int
- _ssh
A high-level representation of a session with an SSH server.
- Type:
paramiko.SSHClient
- _sftp
SFTP client used to perform remote file operations.
- Type:
paramiko.sftp_client.SFTPClient
- _keepalive_interval
The keepalive interval this client was asked for, which
connect()re-applies to every transport it opens.Noneuntilarc.job.ssh_pool.set_keepalive()sets it, since a client that is not pooled is not held open long enough to be dropped while idle.- Type:
int | None
- change_mode(mode, file_name, recursive=False, remote_path='')[source]
Change the mode of a file or a directory.
- Parameters:
mode (str) – The mode change to be applied, can be either octal or symbolic.
file_name (str) – The path to the file or the directory to be changed.
recursive (bool, optional) – Whether to recursively change the mode to all files under a directory.``True`` for recursively change.
remote_path (str, optional) – The directory path at which the command will be executed.
- check_job_status(job_id)[source]
Check job’s status.
- Parameters:
job_id (int) – The job’s ID.
- Returns: str
Possible statuses: before_submission, running, errored on node xx, done, and errored: …
- check_running_jobs_ids()[source]
Check all jobs submitted by the user on a server.
- Returns: list
A list of job IDs.
- connect()[source]
A modulator function for _connect(). Connect to the server.
Failures that retrying cannot resolve – a rejected authentication, a host key that does not match
known_hosts, and an unknown host key on a server that setsstrict_host_key_checking(PERMANENT_CONNECTION_ERRORS) – raise aServerErroron the first attempt, carrying the paramiko exception as its cause – this holds whateverconnection_attemptsis set to, since no number of retries can resolve them. A configuredkeyfile that does not exist is permanent for the same reason, and is told apart from the transport-levelOSError``s by :meth:`_is_a_missing_key_file`. Every other failure is transport-level, and is retried once a minute until ``connection_attemptsattempts have been made (24 hours by default). No interval is waited out after the last attempt, so a client asked for a single attempt fails at once.A contradicted host key raises the
HostKeyMismatchErrorsubclass ofServerErrorrather than a plain one, and is reported at the error level naming both fingerprints, so it is told apart from a wrong password in the log rather than reading as one more failed connection.- Raises:
HostKeyMismatchError – The server’s host key contradicts the one in
known_hosts.ServerError – Cannot connect to the server with maximum times to try, or the failure is permanent.
- delete_jobs(jobs=None)[source]
Delete all of the jobs on a specific server.
- Parameters:
jobs (list[str | int], optional) – Specific ARC job IDs to delete.
- delete_remote_check_files(remote_path)[source]
Delete ESS checkfiles under a remote directory (recursively). They usually take up lots of space and are not needed after ARC terminates. Pass
Trueto thekeep_checksflag in ARC to avoid deleting check files. The local counterpart of this method isarc.common.delete_check_files().Unlike
remove_dir(), this keeps the remote directory and everything in it that is not a checkfile, so a project’s outputs remain on the server after the cleanup. A failure is logged rather than raised, seedelete_check_files_on_servers().- Parameters:
remote_path (str) – The remote directory path under which checkfiles will be deleted.
- find_package(package_name)[source]
Find the path to the package.
- Parameters:
package_name (str) – The name of the package to search for.
- list_available_nodes()[source]
List available nodes on the server.
- Returns:
lines of the node hostnames.
- Return type:
list
- list_dir(remote_path='')[source]
List directory contents.
- Parameters:
remote_path (str, optional) – The directory path at which the command will be executed.
- remove_dir(remote_path)[source]
Remove a directory, and everything under it, on the server.
This is the remote-cleanup primitive. ARC’s own job flow does not call it: no job removes its remote work directory today, and the caller that will is added separately. It is reached through
arc.job.adapter.JobAdapter.remove_remote_files(), which supplies the job’s remote path.- Parameters:
remote_path (str) – The path to the directory to remove on the remote server.
- Raises:
ServerError – If the directory could not be removed.
- submit_job(remote_path, recursion=False)[source]
Submit a job to the server.
- Parameters:
remote_path (str) – The remote path contains the input file and the submission script.
recursion (bool, optional) – Whether this call is within a recursion.
- Returns: tuple[str, int]
A string indicate the status of job submission. Either errored or submitted.
The job ID of the submitted job.
- exception arc.job.ssh.UnknownHostKeyError[source]
Raised when a server’s host key is absent from
known_hostsand the server setsstrict_host_key_checking.An ARC
ServerError, so ARC’s server error handling covers it, and aparamiko.SSHException, which is what a missing host key policy is expected to raise. Being a distinct type, a refused host key is told apart from a transport failure without matching on paramiko’s message text.
- arc.job.ssh.check_connections(function)[source]
A decorator designned for
SSHClient``to check SSH connections before calling a method. It first checks if ``self._sshis available in a SSHClient instance and then checks if you can sendlsand get response to make sure your connection still alive. If connection is bad, this decorator will reconnect the SSH channel, to avoid connection related error when executing the method.connect()assignsself._sftpandself._sshitself and returns nothing, so its result is not unpacked into them. Unpacking it raisedTypeError: cannot unpack non-iterable NoneType objectfor any client that had not connected yet, which is the one case this branch exists to serve.
- arc.job.ssh.check_job_status_in_stdout(job_id, stdout, server)[source]
A helper function for checking job status.
- Parameters:
job_id (int) – the job ID recognized by the server.
stdout (list | str) – The output of a queue status check.
server (str) – The server name.
- Returns:
The job status on the server (‘running’, ‘done’, or ‘errored’).
- Return type:
str
- arc.job.ssh.check_servers_known_hosts(server_dict=None, known_hosts_path=None)[source]
Report configured servers whose host keys need attention before any job is submitted.
Two offline conditions are reported, at two levels. A server with no host key at all is a warning: ARC connects to an unknown host anyway (see
SSHClient._connect()), so without this the first sign of an unseededknown_hostsis a per-connection warning buried in a running job’s log, or – for a server withstrict_host_key_checking– a run that appears to hang while every connection is refused. A server with contradictory entries (get_servers_with_conflicting_host_keys()) is an error: the file records two different keys as that server’s, only one of them is consulted, and which one is trusted is decided by line order rather than by anything the reader chose.A stored key that no longer matches the key the server presents is not reported here and cannot be, since the comparison needs the server. paramiko makes it while connecting, and it surfaces as
HostKeyMismatchError.- Parameters:
server_dict (dict, optional) – The servers to check. Defaults to the configured servers.
known_hosts_path (str, optional) – The
known_hostsfile to read. Defaults toKNOWN_HOSTS_PATH.
- Returns: dict[str, str]
The address of each server that has no host key, keyed by server name.
- arc.job.ssh.delete_all_arc_jobs(server_list, jobs=None)[source]
Delete all ARC-spawned jobs (with job name starting with a and a digit) from :list:servers (servers could also be a string of one server name) Make sure you know what you’re doing, so unrelated jobs won’t be deleted… Useful when terminating ARC while some (ghost) jobs are still running.
- Parameters:
server_list (list) – List of servers to delete ARC jobs from.
jobs (list[str] | None) – Specific ARC job IDs to delete.
- arc.job.ssh.delete_check_files_on_servers(remote_project_paths)[source]
Delete ESS checkfiles from an ARC project’s directory on all servers it ran jobs on. The local counterpart of this function is
arc.common.delete_check_files(). Errors are only logged and never raised: this runs once ARC is done with the science, an unreachable server at that point is an inconvenience, not a reason to lose a run.Each server is reached through its own single-attempt client rather than through the connection pool (
arc.job.ssh_pool), for the same reason: both the pool’s factory and the fallback inborrow_ssh_client()build a client with the default 24-hour retry, so borrowing here would let a server that has gone away hold up the end of a run indefinitely. A cleanup that cannot reach a server must give up, not wait.- Parameters:
remote_project_paths (dict) – Keys are server names, values are the respective remote paths of the project’s directory on that server.
- arc.job.ssh.get_host_key_fingerprint(key)[source]
Return the OpenSSH-style SHA256 fingerprint of a host key.
- Parameters:
key (paramiko.PKey) – The host key to fingerprint.
- Returns: str
The fingerprint, formatted as
SHA256:<unpadded base64>, as reported byssh-keygen -lfand by OpenSSH when it prompts about an unknown host.
- arc.job.ssh.get_servers_missing_host_keys(server_dict=None, known_hosts_path=None)[source]
Determine which of the configured servers have no host key on this machine.
The lookup is local and offline: the
known_hostsfile is read, nothing is resolved and no connection is opened. paramiko’sHostKeysperforms the lookup, so hashed entries (ssh-keyscan -H) and[host]:portentries are matched as OpenSSH matches them.This reports an absent key only. Whether a stored key still matches the one a server presents is not knowable from this machine, since only the server can present it; that comparison is made by paramiko while connecting, and raises
HostKeyMismatchError. What can be checked offline alongside an absent key is aknown_hostsfile that contradicts itself, which isget_servers_with_conflicting_host_keys().- Parameters:
server_dict (dict, optional) – The servers to check. Defaults to the configured servers.
known_hosts_path (str, optional) – The
known_hostsfile to read. Defaults toKNOWN_HOSTS_PATH.
- Returns: dict[str, str]
The address of each server that has no host key, keyed by server name.
- arc.job.ssh.get_servers_with_conflicting_host_keys(server_dict=None, known_hosts_path=None)[source]
Determine which of the configured servers have contradictory host keys on this machine.
A server legitimately has one host key per key type, and
ssh-keyscanwrites one line per type. More than one entry of the same type for one address means the file disagrees with itself about what that server’s key is, which is what a stale entry left behind by a rebuilt server looks like, and equally what an entry prepended to shadow the real key looks like. Only the first matching entry is ever consulted – by OpenSSH, and by theHostKeys.lookupparamiko authenticates with – so a shadowed key is trusted silently while the server’s real key is reported as a mismatch.The check is local and offline: the
known_hostsfile is read, nothing is resolved and no connection is opened. It therefore cannot say which of the recorded keys is the server’s; answering that requires the key the server presents, which is compared while connecting and raisesHostKeyMismatchError.- Parameters:
server_dict (dict, optional) – The servers to check. Defaults to the configured servers.
known_hosts_path (str, optional) – The
known_hostsfile to read. Defaults toKNOWN_HOSTS_PATH.
- Returns: dict[str, list[str]]
The key types recorded more than once, sorted, keyed by server name. Servers whose entries do not contradict each other are absent.