feat(docker): added StreamFormatReader

pull/183/head
Jef Roosens 2022-05-14 22:39:52 +02:00
parent 92cbea69d6
commit f22ed29631
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
3 changed files with 84 additions and 11 deletions

View File

@ -168,6 +168,21 @@ pub fn remove_container(id string) ?bool {
return res.status_code == 204 return res.status_code == 204
} }
pub fn (mut d DockerDaemon) get_container_logs(id string) ?&StreamFormatReader {
d.send_request('GET', urllib.parse('/v1.41/containers/$id/logs?stdout=true&stderr=true')?)?
head := d.read_response_head()?
if head.status_code != 200 {
content_length := head.header.get(http.CommonHeader.content_length)?.int()
body := d.read_response_body(content_length)?
data := json.decode(DockerError, body)?
return error(data.message)
}
return d.get_stream_format_reader()
}
// get_container_logs retrieves the logs for a Docker container, both stdout & // get_container_logs retrieves the logs for a Docker container, both stdout &
// stderr. // stderr.
pub fn get_container_logs(id string) ?string { pub fn get_container_logs(id string) ?string {

View File

@ -123,3 +123,10 @@ pub fn (mut d DockerDaemon) get_chunked_response_reader() &ChunkedResponseReader
return r return r
} }
pub fn (mut d DockerDaemon) get_stream_format_reader() &StreamFormatReader {
r := new_chunked_response_reader(d.reader)
r2 := new_stream_format_reader(r)
return r2
}

View File

@ -7,13 +7,10 @@ import encoding.hex
struct ChunkedResponseReader { struct ChunkedResponseReader {
mut: mut:
reader io.Reader reader io.Reader
// buf []u8
// offset int
// len int
bytes_left_in_chunk u64 bytes_left_in_chunk u64
end_of_stream bool end_of_stream bool
started bool started bool
} }
pub fn new_chunked_response_reader(reader io.Reader) &ChunkedResponseReader { pub fn new_chunked_response_reader(reader io.Reader) &ChunkedResponseReader {
@ -39,7 +36,7 @@ pub fn (mut r ChunkedResponseReader) read(mut buf []u8) ?int {
} }
mut c := 0 mut c := 0
if buf.len > r.bytes_left_in_chunk { if buf.len > r.bytes_left_in_chunk {
c = r.reader.read(mut buf[..r.bytes_left_in_chunk])? c = r.reader.read(mut buf[..r.bytes_left_in_chunk])?
} else { } else {
@ -56,8 +53,8 @@ fn (mut r ChunkedResponseReader) read_chunk_size() ?u64 {
mut res := []u8{} mut res := []u8{}
if r.started { if r.started {
// Each chunk ends with a `\r\n` which we want to skip first // Each chunk ends with a `\r\n` which we want to skip first
r.reader.read(mut buf) ? r.reader.read(mut buf)?
} }
r.started = true r.started = true
@ -85,9 +82,9 @@ fn (mut r ChunkedResponseReader) read_chunk_size() ?u64 {
mut num_data := hex.decode(res#[..-2].bytestr())? mut num_data := hex.decode(res#[..-2].bytestr())?
for num_data.len < 8 { for num_data.len < 8 {
num_data.insert(0, 0) num_data.insert(0, 0)
} }
num := binary.big_endian_u64(num_data) num := binary.big_endian_u64(num_data)
@ -97,3 +94,57 @@ fn (mut r ChunkedResponseReader) read_chunk_size() ?u64 {
return num return num
} }
struct StreamFormatReader {
stdout bool
stderr bool
stdin bool
mut:
reader io.Reader
bytes_left_in_chunk u32
end_of_stream bool
}
pub fn new_stream_format_reader(reader io.Reader) &StreamFormatReader {
r := &StreamFormatReader{
reader: reader
}
return r
}
pub fn (mut r StreamFormatReader) read(mut buf []u8) ?int {
if r.end_of_stream {
return none
}
if r.bytes_left_in_chunk == 0 {
r.bytes_left_in_chunk = r.read_chunk_size()?
if r.end_of_stream {
return none
}
}
mut c := 0
if buf.len > r.bytes_left_in_chunk {
c = r.reader.read(mut buf[..r.bytes_left_in_chunk])?
} else {
c = r.reader.read(mut buf)?
}
r.bytes_left_in_chunk -= u32(c)
return c
}
fn (mut r StreamFormatReader) read_chunk_size() ?u32 {
mut buf := []u8{len: 8}
r.reader.read(mut buf)?
num := binary.big_endian_u32(buf[4..])
return num
}