1use crate::buildah::{BuildahError, Builder, ContentOperations, Image};
6use rhai::{Array, Dynamic, Engine, EvalAltResult, Map};
7use sal_process::CommandResult;
8use std::collections::HashMap;
9
10pub fn register_bah_module(engine: &mut Engine) -> Result<(), Box<EvalAltResult>> {
20 register_bah_types(engine)?;
22
23 engine.register_fn("bah_new", bah_new);
25
26 engine.register_fn("run", builder_run);
28 engine.register_fn("run_with_isolation", builder_run_with_isolation);
29 engine.register_fn("copy", builder_copy);
30 engine.register_fn("add", builder_add);
31 engine.register_fn("commit", builder_commit);
32 engine.register_fn("remove", builder_remove);
33 engine.register_fn("reset", builder_reset);
34 engine.register_fn("config", builder_config);
35 engine.register_fn("set_entrypoint", builder_set_entrypoint);
37 engine.register_fn("set_cmd", builder_set_cmd);
38 engine.register_fn("write_content", builder_write_content);
39 engine.register_fn("read_content", builder_read_content);
40
41 engine.register_fn("images", builder_images);
43 engine.register_fn("image_remove", builder_image_remove);
44 engine.register_fn("image_pull", builder_image_pull);
45 engine.register_fn("image_push", builder_image_push);
46 engine.register_fn("image_tag", builder_image_tag);
47 engine.register_fn("build", builder_build);
48 engine.register_fn("read_content", builder_read_content);
49
50 Ok(())
51}
52
53fn register_bah_types(engine: &mut Engine) -> Result<(), Box<EvalAltResult>> {
55 engine.register_type_with_name::<Builder>("BuildahBuilder");
57
58 engine.register_get("container_id", get_builder_container_id);
60 engine.register_get("name", get_builder_name);
61 engine.register_get("image", get_builder_image);
62 engine.register_get("debug_mode", get_builder_debug);
63 engine.register_set("debug_mode", set_builder_debug);
64
65 engine.register_type_with_name::<Image>("BuildahImage");
67
68 engine.register_get("id", |img: &mut Image| img.id.clone());
70 engine.register_get("names", |img: &mut Image| {
71 let mut array = Array::new();
72 for name in &img.names {
73 array.push(Dynamic::from(name.clone()));
74 }
75 array
76 });
77 engine.register_get("name", |img: &mut Image| {
79 if img.names.is_empty() {
80 "<none>".to_string()
81 } else {
82 img.names[0].clone()
83 }
84 });
85 engine.register_get("size", |img: &mut Image| img.size.clone());
86 engine.register_get("created", |img: &mut Image| img.created.clone());
87
88 Ok(())
89}
90
91fn bah_error_to_rhai_error<T>(result: Result<T, BuildahError>) -> Result<T, Box<EvalAltResult>> {
93 result.map_err(|e| {
94 Box::new(EvalAltResult::ErrorRuntime(
95 format!("Buildah error: {}", e).into(),
96 rhai::Position::NONE,
97 ))
98 })
99}
100
101fn convert_map_to_hashmap(options: Map) -> Result<HashMap<String, String>, Box<EvalAltResult>> {
103 let mut config_options = HashMap::<String, String>::new();
104
105 for (key, value) in options.iter() {
106 if let Ok(value_str) = value.clone().into_string() {
107 config_options.insert(key.to_string(), value_str);
109 } else {
110 return Err(Box::new(EvalAltResult::ErrorRuntime(
111 format!("Option '{}' must be a string", key).into(),
112 rhai::Position::NONE,
113 )));
114 }
115 }
116
117 Ok(config_options)
118}
119
120pub fn bah_new(name: &str, image: &str) -> Result<Builder, Box<EvalAltResult>> {
122 bah_error_to_rhai_error(Builder::new(name, image))
123}
124
125pub fn builder_run(
127 builder: &mut Builder,
128 command: &str,
129) -> Result<CommandResult, Box<EvalAltResult>> {
130 bah_error_to_rhai_error(builder.run(command))
131}
132
133pub fn builder_run_with_isolation(
134 builder: &mut Builder,
135 command: &str,
136 isolation: &str,
137) -> Result<CommandResult, Box<EvalAltResult>> {
138 bah_error_to_rhai_error(builder.run_with_isolation(command, isolation))
139}
140
141pub fn builder_copy(
142 builder: &mut Builder,
143 source: &str,
144 dest: &str,
145) -> Result<CommandResult, Box<EvalAltResult>> {
146 bah_error_to_rhai_error(builder.copy(source, dest))
147}
148
149pub fn builder_add(
150 builder: &mut Builder,
151 source: &str,
152 dest: &str,
153) -> Result<CommandResult, Box<EvalAltResult>> {
154 bah_error_to_rhai_error(builder.add(source, dest))
155}
156
157pub fn builder_commit(
158 builder: &mut Builder,
159 image_name: &str,
160) -> Result<CommandResult, Box<EvalAltResult>> {
161 bah_error_to_rhai_error(builder.commit(image_name))
162}
163
164pub fn builder_remove(builder: &mut Builder) -> Result<CommandResult, Box<EvalAltResult>> {
165 bah_error_to_rhai_error(builder.remove())
166}
167
168pub fn builder_config(
169 builder: &mut Builder,
170 options: Map,
171) -> Result<CommandResult, Box<EvalAltResult>> {
172 let config_options = convert_map_to_hashmap(options)?;
174 bah_error_to_rhai_error(builder.config(config_options))
175}
176
177pub fn builder_set_entrypoint(
179 builder: &mut Builder,
180 entrypoint: &str,
181) -> Result<CommandResult, Box<EvalAltResult>> {
182 bah_error_to_rhai_error(builder.set_entrypoint(entrypoint))
183}
184
185pub fn builder_set_cmd(
187 builder: &mut Builder,
188 cmd: &str,
189) -> Result<CommandResult, Box<EvalAltResult>> {
190 bah_error_to_rhai_error(builder.set_cmd(cmd))
191}
192
193pub fn builder_write_content(
195 builder: &mut Builder,
196 content: &str,
197 dest_path: &str,
198) -> Result<CommandResult, Box<EvalAltResult>> {
199 if let Some(container_id) = builder.container_id() {
200 bah_error_to_rhai_error(ContentOperations::write_content(
201 container_id,
202 content,
203 dest_path,
204 ))
205 } else {
206 Err(Box::new(EvalAltResult::ErrorRuntime(
207 "No container ID available".into(),
208 rhai::Position::NONE,
209 )))
210 }
211}
212
213pub fn builder_read_content(
215 builder: &mut Builder,
216 source_path: &str,
217) -> Result<String, Box<EvalAltResult>> {
218 if let Some(container_id) = builder.container_id() {
219 bah_error_to_rhai_error(ContentOperations::read_content(container_id, source_path))
220 } else {
221 Err(Box::new(EvalAltResult::ErrorRuntime(
222 "No container ID available".into(),
223 rhai::Position::NONE,
224 )))
225 }
226}
227
228pub fn builder_images(_builder: &mut Builder) -> Result<Array, Box<EvalAltResult>> {
230 let images = bah_error_to_rhai_error(Builder::images())?;
231
232 let mut array = Array::new();
234 for image in images {
235 array.push(Dynamic::from(image));
236 }
237
238 Ok(array)
239}
240
241pub fn builder_image_remove(
242 _builder: &mut Builder,
243 image: &str,
244) -> Result<CommandResult, Box<EvalAltResult>> {
245 bah_error_to_rhai_error(Builder::image_remove(image))
246}
247
248pub fn builder_image_pull(
249 _builder: &mut Builder,
250 image: &str,
251 tls_verify: bool,
252) -> Result<CommandResult, Box<EvalAltResult>> {
253 bah_error_to_rhai_error(Builder::image_pull(image, tls_verify))
254}
255
256pub fn builder_image_push(
257 _builder: &mut Builder,
258 image: &str,
259 destination: &str,
260 tls_verify: bool,
261) -> Result<CommandResult, Box<EvalAltResult>> {
262 bah_error_to_rhai_error(Builder::image_push(image, destination, tls_verify))
263}
264
265pub fn builder_image_tag(
266 _builder: &mut Builder,
267 image: &str,
268 new_name: &str,
269) -> Result<CommandResult, Box<EvalAltResult>> {
270 bah_error_to_rhai_error(Builder::image_tag(image, new_name))
271}
272
273pub fn get_builder_container_id(builder: &mut Builder) -> String {
275 match builder.container_id() {
276 Some(id) => id.clone(),
277 None => "".to_string(),
278 }
279}
280
281pub fn get_builder_name(builder: &mut Builder) -> String {
282 builder.name().to_string()
283}
284
285pub fn get_builder_image(builder: &mut Builder) -> String {
286 builder.image().to_string()
287}
288
289pub fn get_builder_debug(builder: &mut Builder) -> bool {
291 builder.debug()
292}
293
294pub fn set_builder_debug(builder: &mut Builder, debug: bool) {
296 builder.set_debug(debug);
297}
298
299pub fn builder_reset(builder: &mut Builder) -> Result<(), Box<EvalAltResult>> {
301 bah_error_to_rhai_error(builder.reset())
302}
303
304pub fn builder_build(
306 _builder: &mut Builder,
307 tag: &str,
308 context_dir: &str,
309 file: &str,
310 isolation: &str,
311) -> Result<CommandResult, Box<EvalAltResult>> {
312 bah_error_to_rhai_error(Builder::build(
313 Some(tag),
314 context_dir,
315 file,
316 Some(isolation),
317 ))
318}