@@ -3,6 +3,8 @@ use std::process::{Child, Command, Output, Stdio};
3
3
use std:: thread:: sleep;
4
4
use std:: time:: { Duration , Instant } ;
5
5
6
+ use log:: debug;
7
+
6
8
pub struct Docker { }
7
9
8
10
impl Docker {
@@ -19,24 +21,51 @@ impl Docker {
19
21
if status. success ( ) {
20
22
Ok ( ( ) )
21
23
} else {
22
- Err ( io:: Error :: new ( io:: ErrorKind :: Other , "Failed to build Docker image" ) )
24
+ Err ( io:: Error :: new (
25
+ io:: ErrorKind :: Other ,
26
+ format ! ( "Failed to build Docker image from dockerfile {dockerfile}" ) ,
27
+ ) )
23
28
}
24
29
}
25
30
26
- /// Runs a Docker container from a given image.
31
+ /// Runs a Docker container from a given image with multiple environment variables.
32
+ ///
33
+ /// # Arguments
34
+ ///
35
+ /// * `image` - The Docker image to run.
36
+ /// * `container` - The name for the Docker container.
37
+ /// * `env_vars` - A slice of tuples, each representing an environment variable as ("KEY", "value").
27
38
///
28
39
/// # Errors
29
40
///
30
41
/// Will fail if the docker run command fails.
31
- pub fn run ( image : & str , name : & str ) -> io:: Result < Output > {
32
- let output = Command :: new ( "docker" )
33
- . args ( [ "run" , "--detach" , "--name" , name, image] )
34
- . output ( ) ?;
42
+ pub fn run ( image : & str , container : & str , env_vars : & [ ( String , String ) ] ) -> io:: Result < Output > {
43
+ let initial_args = vec ! [
44
+ "run" . to_string( ) ,
45
+ "--detach" . to_string( ) ,
46
+ "--name" . to_string( ) ,
47
+ container. to_string( ) ,
48
+ ] ;
49
+
50
+ let mut env_var_args: Vec < String > = vec ! [ ] ;
51
+ for ( key, value) in env_vars {
52
+ env_var_args. push ( "--env" . to_string ( ) ) ;
53
+ env_var_args. push ( format ! ( "{key}={value}" ) ) ;
54
+ }
55
+
56
+ let args = [ initial_args, env_var_args, [ image. to_string ( ) ] . to_vec ( ) ] . concat ( ) ;
57
+
58
+ debug ! ( "Docker run args: {:?}" , args) ;
59
+
60
+ let output = Command :: new ( "docker" ) . args ( args) . output ( ) ?;
35
61
36
62
if output. status . success ( ) {
37
63
Ok ( output)
38
64
} else {
39
- Err ( io:: Error :: new ( io:: ErrorKind :: Other , "Failed to run Docker container" ) )
65
+ Err ( io:: Error :: new (
66
+ io:: ErrorKind :: Other ,
67
+ format ! ( "Failed to run Docker image {image}" ) ,
68
+ ) )
40
69
}
41
70
}
42
71
@@ -45,9 +74,9 @@ impl Docker {
45
74
/// # Errors
46
75
///
47
76
/// Will fail if the docker run command fails to start.
48
- pub fn run_spawned ( image : & str , name : & str ) -> io:: Result < Child > {
77
+ pub fn run_spawned ( image : & str , container : & str ) -> io:: Result < Child > {
49
78
let child = Command :: new ( "docker" )
50
- . args ( [ "run" , "--name" , name , image] )
79
+ . args ( [ "run" , "--name" , container , image] )
51
80
. stdin ( Stdio :: null ( ) ) // Ignore stdin
52
81
. stdout ( Stdio :: null ( ) ) // Ignore stdout
53
82
. stderr ( Stdio :: null ( ) ) // Ignore stderr
@@ -61,13 +90,16 @@ impl Docker {
61
90
/// # Errors
62
91
///
63
92
/// Will fail if the docker stop command fails.
64
- pub fn stop ( name : & str ) -> io:: Result < ( ) > {
65
- let status = Command :: new ( "docker" ) . args ( [ "stop" , name ] ) . status ( ) ?;
93
+ pub fn stop ( container : & str ) -> io:: Result < ( ) > {
94
+ let status = Command :: new ( "docker" ) . args ( [ "stop" , container ] ) . status ( ) ?;
66
95
67
96
if status. success ( ) {
68
97
Ok ( ( ) )
69
98
} else {
70
- Err ( io:: Error :: new ( io:: ErrorKind :: Other , "Failed to stop Docker container" ) )
99
+ Err ( io:: Error :: new (
100
+ io:: ErrorKind :: Other ,
101
+ format ! ( "Failed to stop Docker container {container}" ) ,
102
+ ) )
71
103
}
72
104
}
73
105
@@ -76,13 +108,16 @@ impl Docker {
76
108
/// # Errors
77
109
///
78
110
/// Will fail if the docker rm command fails.
79
- pub fn remove ( name : & str ) -> io:: Result < ( ) > {
80
- let status = Command :: new ( "docker" ) . args ( [ "rm" , "-f" , name ] ) . status ( ) ?;
111
+ pub fn remove ( container : & str ) -> io:: Result < ( ) > {
112
+ let status = Command :: new ( "docker" ) . args ( [ "rm" , "-f" , container ] ) . status ( ) ?;
81
113
82
114
if status. success ( ) {
83
115
Ok ( ( ) )
84
116
} else {
85
- Err ( io:: Error :: new ( io:: ErrorKind :: Other , "Failed to remove Docker container" ) )
117
+ Err ( io:: Error :: new (
118
+ io:: ErrorKind :: Other ,
119
+ format ! ( "Failed to remove Docker container {container}" ) ,
120
+ ) )
86
121
}
87
122
}
88
123
@@ -91,15 +126,15 @@ impl Docker {
91
126
/// # Errors
92
127
///
93
128
/// Will fail if the docker logs command fails.
94
- pub fn logs ( container_name : & str ) -> io:: Result < String > {
95
- let output = Command :: new ( "docker" ) . args ( [ "logs" , container_name ] ) . output ( ) ?;
129
+ pub fn logs ( container : & str ) -> io:: Result < String > {
130
+ let output = Command :: new ( "docker" ) . args ( [ "logs" , container ] ) . output ( ) ?;
96
131
97
132
if output. status . success ( ) {
98
133
Ok ( String :: from_utf8_lossy ( & output. stdout ) . to_string ( ) )
99
134
} else {
100
135
Err ( io:: Error :: new (
101
136
io:: ErrorKind :: Other ,
102
- "Failed to fetch logs from Docker container" ,
137
+ format ! ( "Failed to fetch logs from Docker container {container}" ) ,
103
138
) )
104
139
}
105
140
}
0 commit comments