Skip to main content

nxd_core/domain/contract/
artifacts.rs

1use super::CanonicalConfig;
2use serde::{Deserialize, Serialize};
3
4pub const NXD_KEXEC_X86_64_ARTIFACT_SET_ID: &str = "artifact-set/nxd-kexec-x86_64";
5pub const NXD_KEXEC_AARCH64_ARTIFACT_SET_ID: &str = "artifact-set/nxd-kexec-aarch64";
6pub const NXD_KEXEC_ARTIFACT_SET_ID: &str = NXD_KEXEC_X86_64_ARTIFACT_SET_ID;
7
8pub fn nxd_kexec_artifact_set_id(system: &str) -> Option<&'static str> {
9	match system {
10		"x86_64-linux" => Some(NXD_KEXEC_X86_64_ARTIFACT_SET_ID),
11		"aarch64-linux" => Some(NXD_KEXEC_AARCH64_ARTIFACT_SET_ID),
12		_ => None,
13	}
14}
15
16#[cfg(test)]
17mod tests {
18	use super::*;
19
20	#[test]
21	fn takeover_artifact_is_selected_by_linux_architecture() {
22		assert_eq!(nxd_kexec_artifact_set_id("x86_64-linux"), Some(NXD_KEXEC_X86_64_ARTIFACT_SET_ID));
23		assert_eq!(nxd_kexec_artifact_set_id("aarch64-linux"), Some(NXD_KEXEC_AARCH64_ARTIFACT_SET_ID));
24		assert_eq!(nxd_kexec_artifact_set_id("x86_64-darwin"), None);
25	}
26}
27
28#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
29#[serde(rename_all = "camelCase", deny_unknown_fields)]
30pub struct SecretBinding {
31	pub id: String,
32	pub resolver: String,
33	pub reference: String,
34}
35
36#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
37#[serde(rename_all = "camelCase", deny_unknown_fields)]
38pub struct ArtifactSet {
39	pub id: String,
40	#[serde(default, skip_serializing_if = "Option::is_none")]
41	pub kexec: Option<ArtifactBinding>,
42	#[serde(default, skip_serializing_if = "Option::is_none")]
43	pub installer: Option<ArtifactBinding>,
44}
45
46#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
47#[serde(rename_all = "camelCase", deny_unknown_fields)]
48pub struct ArtifactBinding {
49	pub path: String,
50	#[serde(default, skip_serializing_if = "Option::is_none")]
51	pub sha256: Option<String>,
52}
53
54#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
55#[serde(rename_all = "camelCase", deny_unknown_fields)]
56pub struct ArtifactFile {
57	pub path: String,
58	pub sha256: String,
59	#[serde(default, skip_serializing_if = "Option::is_none")]
60	pub store_path: Option<String>,
61	#[serde(default, skip_serializing_if = "Option::is_none")]
62	pub nar_size: Option<u64>,
63}
64
65#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq)]
66pub enum ManifestKind {
67	ArtifactManifest,
68}
69
70#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
71pub struct ArtifactManifest {
72	pub api_version: String,
73	pub kind: ManifestKind,
74	pub metadata: ManifestMetadata,
75	pub spec: ManifestSpec,
76}
77
78#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
79#[serde(deny_unknown_fields)]
80pub struct ManifestMetadata {
81	pub name: String,
82}
83
84#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
85#[serde(rename_all = "camelCase", deny_unknown_fields)]
86pub struct ManifestSpec {
87	pub selector: String,
88	pub files: Vec<ArtifactFile>,
89	#[serde(default)]
90	pub sbom: Option<serde_json::Value>,
91	#[serde(default)]
92	pub provenance: Option<serde_json::Value>,
93}
94
95pub fn parse_canonical_config(input: &str) -> Result<CanonicalConfig, serde_json::Error> {
96	serde_json::from_str(input)
97}
98
99pub fn parse_artifact_manifest(input: &str) -> Result<ArtifactManifest, serde_json::Error> {
100	serde_json::from_str(input)
101}
102
103pub fn canonical_json<T>(value: &T) -> Result<String, serde_json::Error>
104where
105	T: Serialize,
106{
107	serde_json::to_string(value)
108}
109
110pub fn canonicalize_json_value(input: &str) -> Result<String, serde_json::Error> {
111	let value: serde_json::Value = serde_json::from_str(input)?;
112	serde_json::to_string(&value)
113}