From 4c97489f8a7f868e2ea58afbe9fe3fd47477ed02 Mon Sep 17 00:00:00 2001 From: Jef Roosens Date: Fri, 13 May 2022 22:03:06 +0200 Subject: [PATCH] feat(docker): partially migrate to new code --- src/build/build.v | 11 ++++++---- src/docker/containers.v | 47 ++++++++++++++++++++++++++++++++++++++--- src/docker/socket.v | 12 +++++++++-- src/main.v | 1 + 4 files changed, 62 insertions(+), 9 deletions(-) diff --git a/src/build/build.v b/src/build/build.v index 41f68e2..b470853 100644 --- a/src/build/build.v +++ b/src/build/build.v @@ -17,6 +17,8 @@ const build_image_repo = 'vieter-build' // makepkg with. The base image should be some Linux distribution that uses // Pacman as its package manager. pub fn create_build_image(base_image string) ?string { + mut dd := docker.new_conn() ? + commands := [ // Update repos & install required packages 'pacman -Syu --needed --noconfirm base-devel git' @@ -48,12 +50,13 @@ pub fn create_build_image(base_image string) ?string { // We pull the provided image docker.pull_image(image_name, image_tag)? - id := docker.create_container(c)? - docker.start_container(id)? + id := dd.create_container(c)?.id + /* id := docker.create_container(c)? */ + dd.start_container(id)? // This loop waits until the container has stopped, so we can remove it after for { - data := docker.inspect_container(id)? + data := dd.inspect_container(id)? if !data.state.running { break @@ -68,7 +71,7 @@ pub fn create_build_image(base_image string) ?string { // conflicts. tag := time.sys_mono_now().str() image := docker.create_image_from_container(id, 'vieter-build', tag)? - docker.remove_container(id)? + dd.remove_container(id)? return image.id } diff --git a/src/docker/containers.v b/src/docker/containers.v index 3b674e6..98116cc 100644 --- a/src/docker/containers.v +++ b/src/docker/containers.v @@ -12,15 +12,14 @@ struct Container { pub fn (mut d DockerDaemon) containers() ?[]Container { d.send_request('GET', urllib.parse('/v1.41/containers/json')?)? - res_header := d.read_response_head()? - content_length := res_header.header.get(http.CommonHeader.content_length)?.int() - res := d.read_response_body(content_length)? + _, res := d.read_response()? data := json.decode([]Container, res)? return data } +[params] pub struct NewContainer { image string [json: Image] entrypoint []string [json: Entrypoint] @@ -31,7 +30,25 @@ pub struct NewContainer { } struct CreatedContainer { +pub: id string [json: Id] + warnings []string [json: Warnings] +} + +pub fn (mut d DockerDaemon) create_container(c NewContainer) ?CreatedContainer { + d.send_request_with_json('POST', urllib.parse('/v1.41/containers/create')?, c)? + _, res := d.read_response()? + + data := json.decode(CreatedContainer, res)? + + return data +} + +pub fn (mut d DockerDaemon) start_container(id string) ?bool { + d.send_request('POST', urllib.parse('/v1.41/containers/$id/start')?)? + head := d.read_response_head() ? + + return head.status_code == 204 } // create_container creates a container defined by the given configuration. If @@ -72,6 +89,25 @@ pub mut: end_time time.Time [skip] } +pub fn (mut d DockerDaemon) inspect_container(id string) ?ContainerInspect { + d.send_request('GET', urllib.parse('/v1.41/containers/$id/json')?)? + head, body := d.read_response()? + + if head.status_code != 200 { + return error('Failed to inspect container.') + } + + mut data := json.decode(ContainerInspect, body)? + + data.state.start_time = time.parse_rfc3339(data.state.start_time_str)? + + if data.state.status == 'exited' { + data.state.end_time = time.parse_rfc3339(data.state.end_time_str)? + } + + return data +} + // inspect_container returns the result of inspecting a container with a given // ID. pub fn inspect_container(id string) ?ContainerInspect { @@ -92,6 +128,11 @@ pub fn inspect_container(id string) ?ContainerInspect { return data } +pub fn (mut d DockerDaemon) remove_container(id string) ? { + d.send_request('DELETE', urllib.parse('/v1.41/containers/$id')?)? + head := d.read_response_head() ? +} + // remove_container removes a container with a given ID. pub fn remove_container(id string) ?bool { res := request('DELETE', urllib.parse('/v1.41/containers/$id')?)? diff --git a/src/docker/socket.v b/src/docker/socket.v index 7815435..41f9f6d 100644 --- a/src/docker/socket.v +++ b/src/docker/socket.v @@ -42,10 +42,10 @@ pub fn (mut d DockerDaemon) send_request_with_body(method string, url urllib.URL d.socket.write_string(req)? } -pub fn (mut d DockerDaemon) request_with_json(method string, url urllib.URL, data &T) ? { +pub fn (mut d DockerDaemon) send_request_with_json(method string, url urllib.URL, data &T) ? { body := json.encode(data) - return request_with_body(method, url, 'application/json', body) + return d.send_request_with_body(method, url, 'application/json', body) } // read_response_head consumes the socket's contents until it encounters @@ -100,3 +100,11 @@ pub fn (mut d DockerDaemon) read_response_body(length int) ?string { return builder.str() } + +pub fn (mut d DockerDaemon) read_response() ?(http.Response, string) { + head := d.read_response_head()? + content_length := head.header.get(http.CommonHeader.content_length)?.int() + res := d.read_response_body(content_length)? + + return head, res +} diff --git a/src/main.v b/src/main.v index db6d5ef..6b1e7bc 100644 --- a/src/main.v +++ b/src/main.v @@ -7,6 +7,7 @@ import build import console.git import console.logs import cron +import docker fn main() { mut app := cli.Command{