use std::path::PathBuf;
mod bootstrap;
mod catalog;
mod client;
mod disk;
mod flow;
mod keys;
mod logs;
mod orphans;
mod provision;
mod record;
mod secret;
mod status;
mod target;
mod types;
pub use bootstrap::{
HOST_KEY_ENV, JOB_ENV, PodSettings, bootstrap_functions, pod_command, pod_env, watchdog_script,
};
pub use catalog::{
DataCenterStock, GpuFilter, GpuOffer, ResolveError, by_price, cheapest_in_stock,
data_center_stock, data_center_table, gpu_table, printable, resolve, resolve_with_floor,
select_gpus, stocked_data_centers, template_table, volume_table,
};
pub(crate) use catalog::{MAX_OUT_OF_STOCK, WalkOrder, walk_order};
pub use client::{ApiError, RunpodClient, SECRETS_FORBIDDEN_MESSAGE, USER_AGENT};
pub use disk::{
ACT_PERCENT, Assessment, Critical, DISK_PROBE_EVERY, DiskProbe, DiskWatch, GROW_WINDOW, Usage,
VOLUME_SIZE_FILE, VOLUME_USABLE_PERCENT, VolumeDisk, WARN_PERCENT, WARN_STEP,
WATCHDOG_ACT_PERCENT, assess, disk_probe_script, export_room_warning, grown_size,
parse_disk_probe,
};
pub use flow::{
COST_CAP_FILE, DEADLINE_MARGIN, Ending, LEASE_FILE, LEASE_TTL, MAX_COST_REACHED,
MAX_HOURS_REACHED, RETRIEVED_MARKER, SNAPSHOT_AT_FILE, WATCHDOG_LOG, Watched, arm_cost_cap,
connect_followed, end_pod, follow, forget_client_key, job_started, limit_reached,
past_deadline, reconnect, settle_watch, ssh_command, start_pod, watch_leased, watch_on_pod,
};
pub use keys::{
CLIENT_KEY, KNOWN_HOSTS, PodKeys, SSH_CONFIG, SSH_DIR, alias, base64, pod_endpoint, ssh_config,
write_config, write_known_hosts,
};
pub use logs::{
BOOTSTRAP_LOG, Capture, DRAIN_WAIT, LogError, LogQuery, LogSource, POD_LOG, POD_LOG_CAP,
POD_LOG_CURSOR, PodLogLine, TAIL_MAX, capture, drain, follow as follow_logs, keep_file,
kept_cursor, kept_lines, one_line, open_kept, parse_kept_line, read_kept, read_kept_from,
snapshot, with_pod_logs,
};
pub use orphans::{
PodRow, Removal, Removed, RowKind, listed_rows, orphan_warnings, pod_rows, remove_run_pods,
sweep_host_keys, table,
};
pub use provision::{
PodCtx, PodPlan, Provisioned, Timing, chain, provision, remove, resolve_target, sweep,
};
pub use record::{
Attempt, AttemptResult, CostCap, DeletedBy, MIN_CAP_TIME, POD_FILE, POD_RECORD_VERSION,
PodRecord, PodState, SNAPSHOT_LEAD, SNAPSHOT_SHARE, SshEndpoint, hours, short_cap_warning,
};
pub use secret::{
HOST_KEY_SECRET_PREFIX, drop_host_key, drop_host_key_or_warn, forget_keys,
host_key_placeholder, host_key_run, host_key_secret, store_host_key,
};
pub use status::{DeleteReason, PodStatus};
pub use target::{MIN_CUDA_VERSION, RunpodTarget, VOLUME_MOUNT, VOLUME_WORKDIR, WORKDIR};
pub use types::{
Availability, CreatePod, CudaVersion, DataCenter, DataCenterList, GpuMaxCount, GpuPrice,
GpuRequest, GpuType, GpuTypeList, InvalidPodId, Mounts, NetworkMount, NetworkVolume,
NetworkVolumeList, NewSecret, Pagination, Pod, PodEnv, PodGpu, PodId, PodPage, PodSsh,
RemoteStatus, Secret, SecretList, SshDirect, Stock, Template, TemplatePage,
};
#[cfg(feature = "builtin-ssh")]
const LOCAL_SSH_FIX: &str =
"; set ssh_client = \"builtin\" on the target (or OVERBRAINER_SSH_CLIENT=builtin)";
#[cfg(not(feature = "builtin-ssh"))]
const LOCAL_SSH_FIX: &str =
"; a build with the builtin-ssh feature (the release binaries have it) avoids the local ssh";
#[derive(Debug, thiserror::Error)]
pub enum PodError {
#[error(transparent)]
Api(#[from] ApiError),
#[error("cannot access {}", path.display())]
Io {
path: PathBuf,
#[source]
source: std::io::Error,
},
#[error("cannot generate the run's SSH keys: {0}")]
Keygen(String),
#[error("{0}")]
SshClient(String),
#[error("{0}")]
InvalidPath(String),
#[error("Runpod gave an unusable SSH endpoint: {0}")]
InvalidEndpoint(String),
#[error(transparent)]
Exec(#[from] crate::exec::ExecError),
#[error(transparent)]
Runs(#[from] crate::runs::RunsError),
#[error("{0}")]
NoCapacity(String),
#[error(transparent)]
NotInStock(#[from] ResolveError),
#[error(
"cannot read the size of network volume {id} ({reason}): no pod was created, since its watchdog could not watch the volume's disk space"
)]
VolumeSize {
id: String,
reason: String,
},
#[error(
"Runpod refused for lack of credits (402): deploying needs at least one hour of credits"
)]
NoCredits,
#[error("{0}")]
Rejected(String),
#[error("Runpod did not answer the create calls clearly; check `overbrainer pod ls`")]
Unanswered,
#[error(
"the pod's watchdog cannot remove its own pod ({reason}): pod {pod_id} was deleted and training refused"
)]
WatchdogRefused {
pod_id: PodId,
reason: String,
},
#[error("the pod's bootstrap failed ({reason}): pod {pod_id} was deleted and training refused")]
BootstrapFailed {
pod_id: PodId,
reason: String,
},
#[error(
"pod {pod_id} answers SSH, but the local ssh cannot keep its connection ({reason}); a wrapper around `ssh` on PATH, such as firejail, may kill its background process: put the real ssh first on PATH. The pod was deleted and no other GPU type tried{}",
LOCAL_SSH_FIX
)]
LocalSsh {
pod_id: PodId,
reason: String,
},
#[error("cannot store the pod's host key as a Runpod secret: {0}; no pod was created")]
HostKeySecret(String),
#[error("interrupted before the job started")]
Interrupted,
#[error("pod {0} could not be confirmed deleted: check `overbrainer pod ls`")]
NotDeleted(PodId),
#[error(transparent)]
Run(#[from] crate::runs::RunError),
#[error("max_hours reached: the pod was deleted before the job ended")]
DeadlineReached,
#[error("max_cost_usd reached: the pod was deleted before the job ended")]
CostCapReached,
#[error("max_cost_usd cannot be applied ({0}): the pod was deleted and training refused")]
CostCapUnset(String),
#[error("pod {0} no longer exists")]
PodGone(PodId),
#[error(
"run {run_id} is still running{kept}; stop it with `overbrainer train cancel {run_id}` first, or pass --force"
)]
RunStillRunning {
run_id: String,
kept: String,
},
#[error(
"run {0} is still starting its pod; wait for it, or use `overbrainer train cancel {0}` once it runs, or `pod rm {0} --force`"
)]
StillStarting(String),
#[error(
"run {0} is in progress but its pod is not recorded, so its pods are left alone; if the run is really dead, use `overbrainer pod rm {0} --force`"
)]
PodNotRecorded(String),
#[error(
"run {0} is not in this project's runs/: its pods may belong to another checkout; if none owns it, pass --force"
)]
NotInRuns(String),
#[error("pod {0} has no SSH endpoint (status {1}); try again once it runs")]
NoEndpoint(PodId, String),
#[error(
"pod {pod_id} is stopped and will not run again by itself; remove it with `overbrainer pod rm {run_id}`"
)]
PodStopped {
pod_id: PodId,
run_id: String,
},
}