zombienet_orchestrator/generators/
para_artifact.rs1use std::path::{Path, PathBuf};
2
3use configuration::types::CommandWithCustomArgs;
4use provider::{
5 constants::NODE_CONFIG_DIR,
6 types::{GenerateFileCommand, GenerateFilesOptions, TransferedFile},
7 DynNamespace,
8};
9use serde::{Deserialize, Serialize};
10use support::fs::FileSystem;
11use uuid::Uuid;
12
13use super::errors::GeneratorError;
14use crate::ScopedFilesystem;
15
16#[derive(Debug, Clone, Serialize, Deserialize)]
17pub(crate) enum ParaArtifactType {
18 Wasm,
19 State,
20}
21
22#[derive(Debug, Clone, Serialize, Deserialize)]
23pub(crate) enum ParaArtifactBuildOption {
24 Path(String),
25 Command(String),
26 CommandWithCustomArgs(CommandWithCustomArgs),
27}
28
29#[derive(Debug, Clone, Serialize, Deserialize)]
31pub struct ParaArtifact {
32 artifact_type: ParaArtifactType,
33 build_option: ParaArtifactBuildOption,
34 artifact_path: Option<PathBuf>,
35 image: Option<String>,
37}
38
39impl ParaArtifact {
40 pub(crate) fn new(
41 artifact_type: ParaArtifactType,
42 build_option: ParaArtifactBuildOption,
43 ) -> Self {
44 Self {
45 artifact_type,
46 build_option,
47 artifact_path: None,
48 image: None,
49 }
50 }
51
52 pub(crate) fn image(mut self, image: Option<String>) -> Self {
53 self.image = image;
54 self
55 }
56
57 pub(crate) fn artifact_path(&self) -> Option<&PathBuf> {
58 self.artifact_path.as_ref()
59 }
60
61 pub(crate) async fn build<'a, T>(
62 &mut self,
63 chain_spec_path: Option<impl AsRef<Path>>,
64 artifact_path: impl AsRef<Path>,
65 ns: &DynNamespace,
66 scoped_fs: &ScopedFilesystem<'a, T>,
67 maybe_output_path: Option<PathBuf>,
68 ) -> Result<(), GeneratorError>
69 where
70 T: FileSystem,
71 {
72 let (cmd, custom_args) = match &self.build_option {
73 ParaArtifactBuildOption::Path(path) => {
74 let t = TransferedFile::new(PathBuf::from(path), artifact_path.as_ref().into());
75 scoped_fs.copy_files(vec![&t]).await?;
76 self.artifact_path = Some(artifact_path.as_ref().into());
77 return Ok(()); },
79 ParaArtifactBuildOption::Command(cmd) => (cmd, &vec![]),
80 ParaArtifactBuildOption::CommandWithCustomArgs(cmd_with_custom_args) => {
81 (
82 &cmd_with_custom_args.cmd().as_str().to_string(),
83 cmd_with_custom_args.args(),
84 )
85 },
87 };
88
89 let generate_subcmd = match self.artifact_type {
90 ParaArtifactType::Wasm => "export-genesis-wasm",
91 ParaArtifactType::State => "export-genesis-state",
92 };
93 let temp_name = format!("temp-{}-{}", generate_subcmd, Uuid::new_v4());
95
96 let mut args: Vec<String> = vec![generate_subcmd.into()];
98
99 let files_to_inject = if let Some(chain_spec_path) = chain_spec_path {
100 let chain_spec_path_local = format!(
102 "{}/{}",
103 ns.base_dir().to_string_lossy(),
104 chain_spec_path.as_ref().to_string_lossy()
105 );
106 let chain_spec_path_in_pod = format!(
108 "{}/{}",
109 NODE_CONFIG_DIR,
110 chain_spec_path.as_ref().to_string_lossy()
111 );
112 let chain_spec_path_in_args = if ns.capabilities().prefix_with_full_path {
114 format!(
116 "{}/{}{}",
117 ns.base_dir().to_string_lossy(),
118 &temp_name,
119 &chain_spec_path_in_pod
120 )
121 } else {
122 chain_spec_path_in_pod.clone()
123 };
124
125 args.push("--chain".into());
126 args.push(chain_spec_path_in_args);
127
128 vec![TransferedFile::new(
129 chain_spec_path_local,
130 chain_spec_path_in_pod,
131 )]
132 } else {
133 vec![]
134 };
135
136 let custom_args_to_add = if !custom_args.is_empty() {
139 let skip_first = matches!(custom_args.first(), Some(configuration::types::Arg::Flag(flag)) if flag == generate_subcmd);
141 if skip_first {
142 &custom_args[1..]
143 } else {
144 custom_args
145 }
146 } else {
147 custom_args
148 };
149
150 for custom_arg in custom_args_to_add {
151 match custom_arg {
152 configuration::types::Arg::Flag(flag) => {
153 args.push(flag.into());
154 },
155 configuration::types::Arg::Option(flag, flag_value) => {
156 args.push(flag.into());
157 args.push(flag_value.into());
158 },
159 configuration::types::Arg::Array(flag, values) => {
160 args.push(flag.into());
161 values.iter().for_each(|v| args.push(v.into()));
162 },
163 }
164 }
165
166 let artifact_path_ref = artifact_path.as_ref();
167 let generate_command = GenerateFileCommand::new(cmd.as_str(), artifact_path_ref).args(args);
168 let options = GenerateFilesOptions::with_files(
169 vec![generate_command],
170 self.image.clone(),
171 &files_to_inject,
172 maybe_output_path,
173 )
174 .temp_name(temp_name);
175 ns.generate_files(options).await?;
176 self.artifact_path = Some(artifact_path_ref.into());
177
178 Ok(())
179 }
180}