feat(docker): error when HTTP requests fail

pull/183/head
Jef Roosens 2022-05-13 22:15:30 +02:00
parent 4c97489f8a
commit da46b8b4ae
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
4 changed files with 51 additions and 7 deletions

View File

@ -56,6 +56,7 @@ pub fn create_build_image(base_image string) ?string {
// This loop waits until the container has stopped, so we can remove it after // This loop waits until the container has stopped, so we can remove it after
for { for {
println('wot')
data := dd.inspect_container(id)? data := dd.inspect_container(id)?
if !data.state.running { if !data.state.running {

View File

@ -5,6 +5,10 @@ import net.urllib
import time import time
import net.http import net.http
struct DockerError {
message string
}
struct Container { struct Container {
id string [json: Id] id string [json: Id]
names []string [json: Names] names []string [json: Names]
@ -12,7 +16,13 @@ struct Container {
pub fn (mut d DockerDaemon) containers() ?[]Container { pub fn (mut d DockerDaemon) containers() ?[]Container {
d.send_request('GET', urllib.parse('/v1.41/containers/json')?)? d.send_request('GET', urllib.parse('/v1.41/containers/json')?)?
_, res := d.read_response()? head, res := d.read_response()?
if head.status_code != 200 {
data := json.decode(DockerError, res)?
return error(data.message)
}
data := json.decode([]Container, res)? data := json.decode([]Container, res)?
@ -37,18 +47,28 @@ pub:
pub fn (mut d DockerDaemon) create_container(c NewContainer) ?CreatedContainer { pub fn (mut d DockerDaemon) create_container(c NewContainer) ?CreatedContainer {
d.send_request_with_json('POST', urllib.parse('/v1.41/containers/create')?, c)? d.send_request_with_json('POST', urllib.parse('/v1.41/containers/create')?, c)?
_, res := d.read_response()? head, res := d.read_response()?
if head.status_code != 201 {
data := json.decode(DockerError, res)?
return error(data.message)
}
data := json.decode(CreatedContainer, res)? data := json.decode(CreatedContainer, res)?
return data return data
} }
pub fn (mut d DockerDaemon) start_container(id string) ?bool { pub fn (mut d DockerDaemon) start_container(id string) ? {
d.send_request('POST', urllib.parse('/v1.41/containers/$id/start')?)? d.send_request('POST', urllib.parse('/v1.41/containers/$id/start')?)?
head := d.read_response_head() ? head, body := d.read_response() ?
return head.status_code == 204 if head.status_code != 204 {
data := json.decode(DockerError, body)?
return error(data.message)
}
} }
// create_container creates a container defined by the given configuration. If // create_container creates a container defined by the given configuration. If
@ -94,7 +114,9 @@ pub fn (mut d DockerDaemon) inspect_container(id string) ?ContainerInspect {
head, body := d.read_response()? head, body := d.read_response()?
if head.status_code != 200 { if head.status_code != 200 {
return error('Failed to inspect container.') data := json.decode(DockerError, body)?
return error(data.message)
} }
mut data := json.decode(ContainerInspect, body)? mut data := json.decode(ContainerInspect, body)?
@ -130,7 +152,13 @@ pub fn inspect_container(id string) ?ContainerInspect {
pub fn (mut d DockerDaemon) remove_container(id string) ? { pub fn (mut d DockerDaemon) remove_container(id string) ? {
d.send_request('DELETE', urllib.parse('/v1.41/containers/$id')?)? d.send_request('DELETE', urllib.parse('/v1.41/containers/$id')?)?
head := d.read_response_head() ? head, body := d.read_response() ?
if head.status_code != 204 {
data := json.decode(DockerError, body)?
return error(data.message)
}
} }
// remove_container removes a container with a given ID. // remove_container removes a container with a given ID.

View File

@ -50,6 +50,8 @@ pub fn (mut d DockerDaemon) send_request_with_json<T>(method string, url urllib.
// read_response_head consumes the socket's contents until it encounters // read_response_head consumes the socket's contents until it encounters
// '\r\n\r\n', after which it parses the response as an HTTP response. // '\r\n\r\n', after which it parses the response as an HTTP response.
// Importantly, this function never consumes past the HTTP separator, so the
// body can be read fully later on.
pub fn (mut d DockerDaemon) read_response_head() ?http.Response { pub fn (mut d DockerDaemon) read_response_head() ?http.Response {
mut c := 0 mut c := 0
mut buf := []u8{len: 4} mut buf := []u8{len: 4}
@ -88,6 +90,10 @@ pub fn (mut d DockerDaemon) read_response_head() ?http.Response {
} }
pub fn (mut d DockerDaemon) read_response_body(length int) ?string { pub fn (mut d DockerDaemon) read_response_body(length int) ?string {
if length == 0 {
return ''
}
mut buf := []u8{len: docker.buf_len} mut buf := []u8{len: docker.buf_len}
mut c := 0 mut c := 0
mut builder := strings.new_builder(docker.buf_len) mut builder := strings.new_builder(docker.buf_len)

View File

@ -0,0 +1,9 @@
module docker
import io
struct ChunkedResponseStream {
reader io.Reader
}