1use std::path::PathBuf;
2
3#[derive(Debug, thiserror::Error)]
4pub enum NucleusError {
5 #[error("Failed to create namespace: {0}")]
6 NamespaceError(String),
7
8 #[error("Failed to configure cgroup: {0}")]
9 CgroupError(String),
10
11 #[error("Failed to mount filesystem: {0}")]
12 FilesystemError(String),
13
14 #[error("Failed to pivot root: {0}")]
15 PivotRootError(String),
16
17 #[error("Failed to populate context: {0}")]
18 ContextError(String),
19
20 #[error("Failed to drop capabilities: {0}")]
21 CapabilityError(String),
22
23 #[error("Failed to apply seccomp filter: {0}")]
24 SeccompError(String),
25
26 #[error("Failed to apply Landlock policy: {0}")]
27 LandlockError(String),
28
29 #[error("Invalid resource limit: {0}")]
30 InvalidResourceLimit(String),
31
32 #[error("Resource error: {0}")]
33 ResourceError(String),
34
35 #[error("Configuration error: {0}")]
36 ConfigError(String),
37
38 #[error("Invalid path: {path:?}")]
39 InvalidPath { path: PathBuf },
40
41 #[error("Process execution failed: {0}")]
42 ExecError(String),
43
44 #[error("gVisor runtime error: {0}")]
45 GVisorError(String),
46
47 #[error("Container not found: {0}")]
48 ContainerNotFound(String),
49
50 #[error("Ambiguous container reference: {0}")]
51 AmbiguousContainer(String),
52
53 #[error("Checkpoint error: {0}")]
54 CheckpointError(String),
55
56 #[error("Network error: {0}")]
57 NetworkError(String),
58
59 #[error("Attach error: {0}")]
60 AttachError(String),
61
62 #[error("Permission denied: {0}")]
63 PermissionDenied(String),
64
65 #[error("Container not running: {0}")]
66 ContainerNotRunning(String),
67
68 #[error("Syscall error: {0}")]
69 SyscallError(#[from] nix::Error),
70
71 #[error("IO error: {0}")]
72 IoError(#[from] std::io::Error),
73
74 #[error("Invalid state transition: from {from} to {to}")]
75 InvalidStateTransition { from: String, to: String },
76
77 #[error("OCI hook failed: {0}")]
78 HookError(String),
79
80 #[error("JSON serialization error: {0}")]
81 SerdeJsonError(#[from] serde_json::Error),
82}
83
84pub type Result<T> = std::result::Result<T, NucleusError>;
85
86pub trait StateTransition: std::fmt::Debug + Sized {
93 fn can_transition_to(&self, next: &Self) -> bool;
95
96 fn is_terminal(&self) -> bool;
98
99 fn transition(self, next: Self) -> Result<Self> {
101 if self.can_transition_to(&next) {
102 Ok(next)
103 } else {
104 Err(NucleusError::InvalidStateTransition {
105 from: format!("{:?}", self),
106 to: format!("{:?}", next),
107 })
108 }
109 }
110}