swiftide_docker_executor/
docker_tool_executor.rs

1use std::{collections::HashMap, path::PathBuf};
2use uuid::Uuid;
3
4use crate::{DockerExecutorError, RunningDockerExecutor};
5
6/// Build a docker image with bollard and start it up
7#[derive(Clone, Debug)]
8pub struct DockerExecutor {
9    pub(crate) context_path: PathBuf,
10    pub(crate) image_name: String,
11    pub(crate) dockerfile: Option<PathBuf>,
12    pub(crate) container_uuid: Uuid,
13    pub(crate) user: Option<String>,
14    pub(crate) env_clear: bool,
15    pub(crate) remove_env: Vec<String>,
16    pub(crate) env: HashMap<String, String>,
17}
18
19impl Default for DockerExecutor {
20    fn default() -> Self {
21        Self {
22            container_uuid: Uuid::new_v4(),
23            context_path: ".".into(),
24            image_name: "docker-executor".into(),
25            dockerfile: Some("Dockerfile".into()),
26            user: None,
27            env: HashMap::new(),
28            env_clear: false,
29            remove_env: vec![],
30        }
31    }
32}
33
34impl DockerExecutor {
35    /// Set the path to build the context from (default ".")
36    pub fn with_context_path(&mut self, path: impl Into<PathBuf>) -> &mut Self {
37        self.context_path = path.into();
38
39        self
40    }
41
42    /// Clear the environment variables before starting the service in the container
43    pub fn clear_env(&mut self) -> &mut Self {
44        self.env_clear = true;
45
46        self
47    }
48
49    /// Remove an environment variable from the service in the container
50    pub fn remove_env(&mut self, env: impl Into<String>) -> &mut Self {
51        self.remove_env.push(env.into());
52
53        self
54    }
55
56    /// Set an environment variable for the service in the container
57    pub fn with_env(&mut self, key: impl Into<String>, value: impl Into<String>) -> &mut Self {
58        self.env.insert(key.into(), value.into());
59
60        self
61    }
62
63    /// Set multiple environment variables for the service in the container
64    pub fn with_envs(&mut self, envs: impl Into<HashMap<String, String>>) -> &mut Self {
65        self.env.extend(envs.into());
66
67        self
68    }
69
70    /// Set the user (or user_id:group_id) to run the container as (default None, which means root)
71    pub fn with_user(&mut self, user: impl Into<String>) -> &mut Self {
72        self.user = Some(user.into());
73
74        self
75    }
76
77    /// Start with an existing image (full tag). Will skip building the image, unless you set a new
78    /// Dockerfile. Note that this requires that the image has the service available as a binary.
79    pub fn with_existing_image(&mut self, path: impl Into<String>) -> &mut Self {
80        self.image_name = path.into();
81
82        // If an existing image is used, we don't need to build it
83        self.dockerfile = None;
84
85        self
86    }
87
88    /// Set the name of the image to build (default "docker-executor")
89    pub fn with_image_name(&mut self, name: impl Into<String>) -> &mut Self {
90        self.image_name = name.into();
91
92        self
93    }
94
95    /// Overwrite the uuid that is added as suffix to the running container
96    pub fn with_container_uuid(&mut self, uuid: impl Into<Uuid>) -> &mut Self {
97        self.container_uuid = uuid.into();
98
99        self
100    }
101
102    /// Overwrite the dockerfile to use (default "Dockerfile")
103    pub fn with_dockerfile(&mut self, path: impl Into<PathBuf>) -> &mut Self {
104        self.dockerfile = Some(path.into());
105        self
106    }
107
108    /// Starts the docker executor
109    ///
110    /// Note that on dropping the `RunningDockerExecutor`, the container will be stopped
111    pub async fn start(self) -> Result<RunningDockerExecutor, DockerExecutorError> {
112        RunningDockerExecutor::start(&self).await
113    }
114}