diff --git a/src/docker/containers.v b/src/docker/containers.v index 0bc59bb..a790243 100644 --- a/src/docker/containers.v +++ b/src/docker/containers.v @@ -9,6 +9,27 @@ struct DockerError { message string } +struct Container { + id string [json: Id] + names []string [json: Names] +} + +// containers returns a list of all containers. +pub fn (mut d DockerConn) containers() ?[]Container { + d.send_request(Method.get, urllib.parse('/v1.41/containers/json')?)? + head, res := d.read_response()? + + if head.status_code != 200 { + data := json.decode(DockerError, res)? + + return error(data.message) + } + + data := json.decode([]Container, res)? + + return data +} + pub struct NewContainer { image string [json: Image] entrypoint []string [json: Entrypoint] diff --git a/src/docker/stream.v b/src/docker/stream.v index 001f4b3..02fb972 100644 --- a/src/docker/stream.v +++ b/src/docker/stream.v @@ -9,14 +9,15 @@ import encoding.hex // it as if it was a continuous stream of data. struct ChunkedResponseReader { mut: - reader io.BufferedReader + reader io.Reader bytes_left_in_chunk u64 + end_of_stream bool started bool } // new_chunked_response_reader creates a new ChunkedResponseReader on the heap // with the provided reader. -pub fn new_chunked_response_reader(reader io.BufferedReader) &ChunkedResponseReader { +pub fn new_chunked_response_reader(reader io.Reader) &ChunkedResponseReader { r := &ChunkedResponseReader{ reader: reader } @@ -26,10 +27,16 @@ pub fn new_chunked_response_reader(reader io.BufferedReader) &ChunkedResponseRea // read satisfies the io.Reader interface. pub fn (mut r ChunkedResponseReader) read(mut buf []u8) ?int { + if r.end_of_stream { + return none + } + if r.bytes_left_in_chunk == 0 { - // An io.BufferedReader always returns none if its stream has - // ended. r.bytes_left_in_chunk = r.read_chunk_size()? + + if r.end_of_stream { + return none + } } mut c := 0 @@ -75,7 +82,7 @@ fn (mut r ChunkedResponseReader) read_chunk_size() ?u64 { // This only occurs for the very last chunk, which always reports a size of // 0. if num == 0 { - return none + r.end_of_stream = true } return num @@ -85,13 +92,14 @@ fn (mut r ChunkedResponseReader) read_chunk_size() ?u64 { // header bytes. struct StreamFormatReader { mut: - reader ChunkedResponseReader + reader io.Reader bytes_left_in_chunk u32 + end_of_stream bool } // new_stream_format_reader creates a new StreamFormatReader using the given // reader. -pub fn new_stream_format_reader(reader ChunkedResponseReader) &StreamFormatReader { +pub fn new_stream_format_reader(reader io.Reader) &StreamFormatReader { r := &StreamFormatReader{ reader: reader } @@ -101,8 +109,16 @@ pub fn new_stream_format_reader(reader ChunkedResponseReader) &StreamFormatReade // read satisfies the io.Reader interface. 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 @@ -127,9 +143,5 @@ fn (mut r StreamFormatReader) read_chunk_size() ?u32 { num := binary.big_endian_u32(buf[4..]) - if num == 0 { - return none - } - return num }