forked from vieter-v/vieter
feat(docker): added StreamFormatReader
parent
92cbea69d6
commit
f22ed29631
|
@ -168,6 +168,21 @@ pub fn remove_container(id string) ?bool {
|
|||
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 &
|
||||
// stderr.
|
||||
pub fn get_container_logs(id string) ?string {
|
||||
|
|
|
@ -123,3 +123,10 @@ pub fn (mut d DockerDaemon) get_chunked_response_reader() &ChunkedResponseReader
|
|||
|
||||
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
|
||||
}
|
||||
|
|
|
@ -7,13 +7,10 @@ import encoding.hex
|
|||
|
||||
struct ChunkedResponseReader {
|
||||
mut:
|
||||
reader io.Reader
|
||||
// buf []u8
|
||||
// offset int
|
||||
// len int
|
||||
reader io.Reader
|
||||
bytes_left_in_chunk u64
|
||||
end_of_stream bool
|
||||
started bool
|
||||
started bool
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
|
||||
if buf.len > r.bytes_left_in_chunk {
|
||||
c = r.reader.read(mut buf[..r.bytes_left_in_chunk])?
|
||||
} else {
|
||||
|
@ -56,8 +53,8 @@ fn (mut r ChunkedResponseReader) read_chunk_size() ?u64 {
|
|||
mut res := []u8{}
|
||||
|
||||
if r.started {
|
||||
// Each chunk ends with a `\r\n` which we want to skip first
|
||||
r.reader.read(mut buf) ?
|
||||
// Each chunk ends with a `\r\n` which we want to skip first
|
||||
r.reader.read(mut buf)?
|
||||
}
|
||||
|
||||
r.started = true
|
||||
|
@ -85,9 +82,9 @@ fn (mut r ChunkedResponseReader) read_chunk_size() ?u64 {
|
|||
|
||||
mut num_data := hex.decode(res#[..-2].bytestr())?
|
||||
|
||||
for num_data.len < 8 {
|
||||
num_data.insert(0, 0)
|
||||
}
|
||||
for num_data.len < 8 {
|
||||
num_data.insert(0, 0)
|
||||
}
|
||||
|
||||
num := binary.big_endian_u64(num_data)
|
||||
|
||||
|
@ -97,3 +94,57 @@ fn (mut r ChunkedResponseReader) read_chunk_size() ?u64 {
|
|||
|
||||
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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue