diff --git a/src/build/build.v b/src/build/build.v index 9505171..6f033e6 100644 --- a/src/build/build.v +++ b/src/build/build.v @@ -73,17 +73,10 @@ pub fn create_build_image(base_image string) ?string { return image.id } -struct BuildResult { - start_time time.Time - end_time time.Time - exit_code int - logs string -} - // build_repo builds, packages & publishes a given Arch package based on the // provided GitRepo. The base image ID should be of an image previously created -// by create_build_image. It returns the logs of the container. -pub fn build_repo(address string, api_key string, base_image_id string, repo &db.GitRepo) ?BuildResult { +// by create_build_image. +pub fn build_repo(address string, api_key string, base_image_id string, repo &db.GitRepo) ? { build_arch := os.uname().machine // TODO what to do with PKGBUILDs that build multiple packages? @@ -114,50 +107,43 @@ pub fn build_repo(address string, api_key string, base_image_id string, repo &db id := docker.create_container(c) ? docker.start_container(id) ? - mut data := docker.inspect_container(id) ? - // This loop waits until the container has stopped, so we can remove it after for { + data := docker.inspect_container(id) ? + if !data.state.running { break } time.sleep(1 * time.second) - - data = docker.inspect_container(id) ? } - logs := docker.get_container_logs(id) ? - docker.remove_container(id) ? - - return BuildResult{ - start_time: data.state.start_time - end_time: data.state.end_time - exit_code: data.state.exit_code - logs: logs - } } // build builds every Git repo in the server's list. -fn build(conf Config, repo_id int) ? { - c := client.new(conf.address, conf.api_key) - repo := c.get_git_repo(repo_id) ? - +fn build(conf Config) ? { build_arch := os.uname().machine + // We get the repos map from the Vieter instance + repos := client.new(conf.address, conf.api_key).get_git_repos() ? + + // We filter out any repos that aren't allowed to be built on this + // architecture + filtered_repos := repos.filter(it.arch.map(it.value).contains(build_arch)) + + // No point in doing work if there's no repos present + if filtered_repos.len == 0 { + return + } + // First, we create a base image which has updated repos n stuff - println('Creating base image...') image_id := create_build_image(conf.base_image) ? - println('Running build...') - res := build_repo(conf.address, conf.api_key, image_id, repo) ? + for repo in filtered_repos { + build_repo(conf.address, conf.api_key, image_id, repo) ? + } - // Remove the builder image - println('Removing build image...') + // Finally, we remove the builder image docker.remove_image(image_id) ? - - // Upload the build log to the Vieter instance - println('Uploading logs to Vieter...') - c.add_build_log(repo.id, res.start_time, res.end_time, build_arch, res.exit_code, res.logs) ? } diff --git a/src/build/cli.v b/src/build/cli.v index 5247e87..0131396 100644 --- a/src/build/cli.v +++ b/src/build/cli.v @@ -14,16 +14,12 @@ pub: pub fn cmd() cli.Command { return cli.Command{ name: 'build' - required_args: 1 - usage: 'id' - description: 'Build the repository with the given ID.' + description: 'Run the build process.' execute: fn (cmd cli.Command) ? { config_file := cmd.flags.get_string('config-file') ? conf := env.load(config_file) ? - id := cmd.args[0].int() - - build(conf, id) ? + build(conf) ? } } } diff --git a/src/docker/containers.v b/src/docker/containers.v index 63095a6..d0f5a4d 100644 --- a/src/docker/containers.v +++ b/src/docker/containers.v @@ -2,8 +2,6 @@ module docker import json import net.urllib -import regex -import time struct Container { id string [json: Id] @@ -51,28 +49,13 @@ pub fn start_container(id string) ?bool { } struct ContainerInspect { -pub mut: +pub: state ContainerState [json: State] } struct ContainerState { pub: running bool [json: Running] - status string [json: Status] - exit_code int [json: ExitCode] - // These use a rather specific format so they have to be parsed later - start_time_str string [json: StartedAt] - end_time_str string [json: FinishedAt] -pub mut: - start_time time.Time [skip] - end_time time.Time [skip] -} - -fn docker_timestamp_to_time(s string) ?time.Time { - parts := s.split('.') - clipped := parts[0] + '.' + parts[1][..3] - - return time.parse_rfc3339(clipped) } // inspect_container returns the result of inspecting a container with a given @@ -84,15 +67,7 @@ pub fn inspect_container(id string) ?ContainerInspect { return error('Failed to inspect container.') } - mut data := json.decode(ContainerInspect, res.text) ? - - data.state.start_time = docker_timestamp_to_time(data.state.start_time_str) ? - - if data.state.status == "exited" { - data.state.end_time = docker_timestamp_to_time(data.state.end_time_str) ? - } - - return data + return json.decode(ContainerInspect, res.text) or {} } // remove_container removes a container with a given ID. @@ -101,23 +76,3 @@ pub fn remove_container(id string) ?bool { return res.status_code == 204 } - -pub fn get_container_logs(id string) ?string { - res := request('GET', urllib.parse('/v1.41/containers/$id/logs?stdout=true&stderr=true') ?) ? - mut res_bytes := res.text.bytes() - - // Docker uses a special "stream" format for their logs, so we have to - // clean up the data. - mut index := 0 - - for index < res_bytes.len { - // The reverse is required because V reads in the bytes differently - t := res_bytes[index + 4..index + 8].reverse() - len_length := unsafe { *(&u32(&t[0])) } - - res_bytes.delete_many(index, 8) - index += int(len_length) - } - - return res_bytes.bytestr() -}