@@ -65,7 +65,10 @@ impl Api {
6565 } ;
6666
6767 let response = match Self :: process ( cmd, & mut stream, zinit) . await {
68- Ok ( body) => Response {
68+ // When process returns None means we can terminate without
69+ // writing any result to the socket.
70+ Ok ( None ) => return ,
71+ Ok ( Some ( body) ) => Response {
6972 body,
7073 state : State :: Ok ,
7174 } ,
@@ -94,7 +97,7 @@ impl Api {
9497 cmd : String ,
9598 stream : & mut BufStream < UnixStream > ,
9699 zinit : ZInit ,
97- ) -> Result < Value > {
100+ ) -> Result < Option < Value > > {
98101 let parts = match shlex:: split ( & cmd) {
99102 Some ( parts) => parts,
100103 None => bail ! ( "invalid command syntax" ) ,
@@ -104,23 +107,34 @@ impl Api {
104107 bail ! ( "unknown command" ) ;
105108 }
106109
107- match parts[ 0 ] . as_ref ( ) {
110+ if & parts[ 0 ] == "log" {
111+ match parts. len ( ) {
112+ 1 => Self :: log ( stream, zinit, true ) . await ,
113+ 2 if parts[ 1 ] == "snapshot" => Self :: log ( stream, zinit, false ) . await ,
114+ _ => bail ! ( "invalid log command arguments" ) ,
115+ } ?;
116+
117+ return Ok ( None ) ;
118+ }
119+
120+ let value = match parts[ 0 ] . as_ref ( ) {
108121 "list" => Self :: list ( zinit) . await ,
109122 "shutdown" => Self :: shutdown ( zinit) . await ,
110123 "reboot" => Self :: reboot ( zinit) . await ,
111- "log" => Self :: log ( stream, zinit) . await ,
112124 "start" if parts. len ( ) == 2 => Self :: start ( & parts[ 1 ] , zinit) . await ,
113125 "stop" if parts. len ( ) == 2 => Self :: stop ( & parts[ 1 ] , zinit) . await ,
114126 "kill" if parts. len ( ) == 3 => Self :: kill ( & parts[ 1 ] , & parts[ 2 ] , zinit) . await ,
115127 "status" if parts. len ( ) == 2 => Self :: status ( & parts[ 1 ] , zinit) . await ,
116128 "forget" if parts. len ( ) == 2 => Self :: forget ( & parts[ 1 ] , zinit) . await ,
117129 "monitor" if parts. len ( ) == 2 => Self :: monitor ( & parts[ 1 ] , zinit) . await ,
118130 _ => bail ! ( "unknown command '{}' or wrong arguments count" , parts[ 0 ] ) ,
119- }
131+ } ?;
132+
133+ Ok ( Some ( value) )
120134 }
121135
122- async fn log ( stream : & mut BufStream < UnixStream > , zinit : ZInit ) -> Result < Value > {
123- let mut logs = zinit. logs ( ) . await ? ;
136+ async fn log ( stream : & mut BufStream < UnixStream > , zinit : ZInit , follow : bool ) -> Result < Value > {
137+ let mut logs = zinit. logs ( follow ) . await ;
124138
125139 while let Some ( line) = logs. recv ( ) . await {
126140 stream. write_all ( line. as_bytes ( ) ) . await ?;
@@ -256,9 +270,18 @@ impl Client {
256270 & self ,
257271 mut out : O ,
258272 filter : Option < S > ,
273+ follow : bool ,
259274 ) -> Result < ( ) > {
260275 let mut con = self . connect ( ) . await ?;
261- con. write_all ( b"log\n " ) . await ?;
276+ if follow {
277+ // default behavior of log with no extra arguments
278+ // is to stream all logs
279+ con. write_all ( b"log\n " ) . await ?;
280+ } else {
281+ // adding a snapshot subcmd will make it auto terminate
282+ // immediate after
283+ con. write_all ( b"log snapshot\n " ) . await ?;
284+ }
262285 con. flush ( ) . await ?;
263286 match filter {
264287 None => tokio:: io:: copy ( & mut con, & mut out) . await ?,
0 commit comments