diff --git a/src/build/build.v b/src/build/build.v index 6f033e6..15a5eb8 100644 --- a/src/build/build.v +++ b/src/build/build.v @@ -3,9 +3,9 @@ module build import docker import encoding.base64 import time +import git import os import db -import client const container_build_dir = '/build' @@ -126,7 +126,7 @@ 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() ? + repos := git.get_repos(conf.address, conf.api_key) ? // We filter out any repos that aren't allowed to be built on this // architecture diff --git a/src/client/client.v b/src/client/client.v deleted file mode 100644 index 614b3db..0000000 --- a/src/client/client.v +++ /dev/null @@ -1,40 +0,0 @@ -module client - -import net.http -import response { Response } -import json - -pub struct Client { -pub: - address string - api_key string -} - -pub fn new(address string, api_key string) Client { - return Client{ - address: address - api_key: api_key - } -} - -// send_request is a convenience method for sending requests to the repos -// API. It mostly does string manipulation to create a query string containing -// the provided params. -fn (c &Client) send_request(method http.Method, url string, params map[string]string) ?Response { - mut full_url := '${c.address}$url' - - if params.len > 0 { - params_str := params.keys().map('$it=${params[it]}').join('&') - - full_url = '$full_url?$params_str' - } - - mut req := http.new_request(method, full_url, '') ? - req.add_custom_header('X-API-Key', c.api_key) ? - - res := req.do() ? - data := json.decode(Response, res.text) ? - - return data -} - diff --git a/src/client/git.v b/src/client/git.v deleted file mode 100644 index 5ed0620..0000000 --- a/src/client/git.v +++ /dev/null @@ -1,51 +0,0 @@ -module client - -import db -import net.http -import response { Response } - -// get_repos returns the current list of repos. -pub fn (c &Client) get_git_repos() ?[]db.GitRepo { - data := c.send_request<[]db.GitRepo>(http.Method.get, '/api/repos', {}) ? - - return data.data -} - -// get_repo returns the repo for a specific ID. -pub fn (c &Client) get_git_repo(id int) ?db.GitRepo { - data := c.send_request(http.Method.get, '/api/repos/$id', {}) ? - - return data.data -} - -// add_repo adds a new repo to the server. -pub fn (c &Client) add_git_repo(url string, branch string, repo string, arch []string) ?Response { - mut params := { - 'url': url - 'branch': branch - 'repo': repo - } - - if arch.len > 0 { - params['arch'] = arch.join(',') - } - - data := c.send_request(http.Method.post, '/api/repos', params) ? - - return data -} - -// remove_repo removes the repo with the given ID from the server. -pub fn (c &Client) remove_git_repo(id int) ?Response { - data := c.send_request(http.Method.delete, '/api/repos/$id', {}) ? - - return data -} - -// patch_repo sends a PATCH request to the given repo with the params as -// payload. -pub fn (c &Client) patch_git_repo(id int, params map[string]string) ?Response { - data := c.send_request(http.Method.patch, '/api/repos/$id', params) ? - - return data -} diff --git a/src/cron/daemon/build.v b/src/cron/daemon/build.v index d107fd3..e54a39e 100644 --- a/src/cron/daemon/build.v +++ b/src/cron/daemon/build.v @@ -77,7 +77,7 @@ fn (mut d Daemon) run_build(build_index int, sb ScheduledBuild) { // 0 means success, 1 means failure mut status := 0 - build.build_repo(d.client.address, d.client.api_key, d.builder_images.last(), &sb.repo) or { + build.build_repo(d.address, d.api_key, d.builder_images.last(), &sb.repo) or { d.ldebug('build_repo error: $err.msg()') status = 1 } diff --git a/src/cron/daemon/daemon.v b/src/cron/daemon/daemon.v index 71fc575..ffa2f6e 100644 --- a/src/cron/daemon/daemon.v +++ b/src/cron/daemon/daemon.v @@ -1,5 +1,6 @@ module daemon +import git import time import log import datatypes { MinHeap } @@ -9,7 +10,6 @@ import build import docker import db import os -import client const ( // How many seconds to wait before retrying to update API if failed @@ -31,7 +31,8 @@ fn (r1 ScheduledBuild) < (r2 ScheduledBuild) bool { pub struct Daemon { mut: - client client.Client + address string + api_key string base_image string builder_images []string global_schedule CronExpression @@ -55,7 +56,8 @@ mut: // populates the build queue for the first time. pub fn init_daemon(logger log.Log, address string, api_key string, base_image string, global_schedule CronExpression, max_concurrent_builds int, api_update_frequency int, image_rebuild_frequency int) ?Daemon { mut d := Daemon{ - client: client.new(address, api_key) + address: address + api_key: api_key base_image: base_image global_schedule: global_schedule api_update_frequency: api_update_frequency @@ -178,7 +180,7 @@ fn (mut d Daemon) schedule_build(repo db.GitRepo) { fn (mut d Daemon) renew_repos() { d.linfo('Renewing repos...') - mut new_repos := d.client.get_git_repos() or { + mut new_repos := git.get_repos(d.address, d.api_key) or { d.lerror('Failed to renew repos. Retrying in ${daemon.api_update_retry_timeout}s...') d.api_update_timestamp = time.now().add_seconds(daemon.api_update_retry_timeout) diff --git a/src/db/git.v b/src/db/git.v index 6eeecc8..b779140 100644 --- a/src/db/git.v +++ b/src/db/git.v @@ -152,11 +152,3 @@ pub fn (db &VieterDb) update_git_repo_archs(repo_id int, archs []GitRepoArch) { } } } - -pub fn (db &VieterDb) git_repo_exists(repo_id int) bool { - db.get_git_repo(repo_id) or { - return false - } - - return true -} diff --git a/src/db/logs.v b/src/db/logs.v index 589304e..3e5b600 100644 --- a/src/db/logs.v +++ b/src/db/logs.v @@ -3,12 +3,10 @@ module db import time pub struct BuildLog { -pub: id int [primary; sql: serial] - repo_id int [nonull] + repo GitRepo [nonull] start_time time.Time [nonull] end_time time.Time [nonull] - arch string [nonull] exit_code int [nonull] } @@ -21,16 +19,6 @@ pub fn (db &VieterDb) get_build_logs() []BuildLog { return res } -// get_build_logs_for_repo returns all BuildLog's in the database for a given -// repo. -pub fn (db &VieterDb) get_build_logs_for_repo(repo_id int) []BuildLog { - res := sql db.conn { - select from BuildLog where repo_id == repo_id order by id - } - - return res -} - // get_build_log tries to return a specific BuildLog. pub fn (db &VieterDb) get_build_log(id int) ?BuildLog { res := sql db.conn { diff --git a/src/git/cli.v b/src/git/cli.v index bdc0479..634b778 100644 --- a/src/git/cli.v +++ b/src/git/cli.v @@ -3,7 +3,6 @@ module git import cli import env import cron.expression { parse_expression } -import client struct Config { address string [required] @@ -120,8 +119,7 @@ pub fn cmd() cli.Command { // list prints out a list of all repositories. fn list(conf Config) ? { - c := client.new(conf.address, conf.api_key) - repos := c.get_git_repos() ? + repos := get_repos(conf.address, conf.api_key) ? for repo in repos { println('$repo.id\t$repo.url\t$repo.branch\t$repo.repo') @@ -130,8 +128,7 @@ fn list(conf Config) ? { // add adds a new repository to the server's list. fn add(conf Config, url string, branch string, repo string) ? { - c := client.new(conf.address, conf.api_key) - res := c.add_git_repo(url, branch, repo, []) ? + res := add_repo(conf.address, conf.api_key, url, branch, repo, []) ? println(res.message) } @@ -142,8 +139,7 @@ fn remove(conf Config, id string) ? { id_int := id.int() if id_int != 0 { - c := client.new(conf.address, conf.api_key) - res := c.remove_git_repo(id_int) ? + res := remove_repo(conf.address, conf.api_key, id_int) ? println(res.message) } } @@ -160,9 +156,7 @@ fn patch(conf Config, id string, params map[string]string) ? { id_int := id.int() if id_int != 0 { - - c := client.new(conf.address, conf.api_key) - res := c.patch_git_repo(id_int, params) ? + res := patch_repo(conf.address, conf.api_key, id_int, params) ? println(res.message) } @@ -176,7 +170,6 @@ fn info(conf Config, id string) ? { return } - c := client.new(conf.address, conf.api_key) - repo := c.get_git_repo(id_int) ? + repo := get_repo(conf.address, conf.api_key, id_int) ? println(repo) } diff --git a/src/git/client.v b/src/git/client.v new file mode 100644 index 0000000..b5f8e9f --- /dev/null +++ b/src/git/client.v @@ -0,0 +1,77 @@ +module git + +import json +import response { Response } +import net.http +import db + +// send_request is a convenience method for sending requests to the repos +// API. It mostly does string manipulation to create a query string containing +// the provided params. +fn send_request(method http.Method, address string, url string, api_key string, params map[string]string) ?Response { + mut full_url := '$address$url' + + if params.len > 0 { + params_str := params.keys().map('$it=${params[it]}').join('&') + + full_url = '$full_url?$params_str' + } + + mut req := http.new_request(method, full_url, '') ? + req.add_custom_header('X-API-Key', api_key) ? + + res := req.do() ? + data := json.decode(Response, res.text) ? + + return data +} + +// get_repos returns the current list of repos. +pub fn get_repos(address string, api_key string) ?[]db.GitRepo { + data := send_request<[]db.GitRepo>(http.Method.get, address, '/api/repos', api_key, + {}) ? + + return data.data +} + +// get_repo returns the repo for a specific ID. +pub fn get_repo(address string, api_key string, id int) ?db.GitRepo { + data := send_request(http.Method.get, address, '/api/repos/$id', api_key, + {}) ? + + return data.data +} + +// add_repo adds a new repo to the server. +pub fn add_repo(address string, api_key string, url string, branch string, repo string, arch []string) ?Response { + mut params := { + 'url': url + 'branch': branch + 'repo': repo + } + + if arch.len > 0 { + params['arch'] = arch.join(',') + } + + data := send_request(http.Method.post, address, '/api/repos', api_key, params) ? + + return data +} + +// remove_repo removes the repo with the given ID from the server. +pub fn remove_repo(address string, api_key string, id int) ?Response { + data := send_request(http.Method.delete, address, '/api/repos/$id', api_key, + {}) ? + + return data +} + +// patch_repo sends a PATCH request to the given repo with the params as +// payload. +pub fn patch_repo(address string, api_key string, id int, params map[string]string) ?Response { + data := send_request(http.Method.patch, address, '/api/repos/$id', api_key, + params) ? + + return data +} diff --git a/src/server/logs.v b/src/server/logs.v index 10b734d..01116b4 100644 --- a/src/server/logs.v +++ b/src/server/logs.v @@ -15,39 +15,11 @@ fn (mut app App) get_logs() web.Result { return app.json(http.Status.unauthorized, new_response('Unauthorized.')) } - logs := if 'repo' in app.query { - app.db.get_build_logs_for_repo(app.query['repo'].int()) - } else { - app.db.get_build_logs() - } + logs := app.db.get_build_logs() return app.json(http.Status.ok, new_data_response(logs)) } -['/api/logs/:id'; get] -fn (mut app App) get_single_log(id int) web.Result { - if !app.is_authorized() { - return app.json(http.Status.unauthorized, new_response('Unauthorized.')) - } - - log := app.db.get_build_log(id) or { return app.not_found() } - - return app.json(http.Status.ok, new_data_response(log)) -} - -['/api/logs/:id/content'; get] -fn (mut app App) get_log_contents(id int) web.Result { - if !app.is_authorized() { - return app.json(http.Status.unauthorized, new_response('Unauthorized.')) - } - - log := app.db.get_build_log(id) or { return app.not_found() } - file_name := log.start_time.custom_format('YYYY-MM-DD_HH-mm-ss') - full_path := os.join_path(app.conf.data_dir, server.logs_dir_name, log.repo_id.str(), log.arch, file_name) - - return app.file(full_path) -} - // parse_query_time unescapes an HTTP query parameter & tries to parse it as a // time.Time struct. fn parse_query_time(query string) ?time.Time { @@ -68,7 +40,7 @@ fn (mut app App) post_log() web.Result { return app.json(http.Status.bad_request, new_response('Invalid or missing start time.')) } - end_time := parse_query_time(app.query['endTime']) or { + end_time := time.parse(app.query['endTime'].replace('_', ' ')) or { return app.json(http.Status.bad_request, new_response('Invalid or missing end time.')) } @@ -84,24 +56,21 @@ fn (mut app App) post_log() web.Result { arch := app.query['arch'] - repo_id := app.query['repo'].int() - - if !app.db.git_repo_exists(repo_id) { - return app.json(http.Status.bad_request, new_response('Unknown Git repo.')) + repo := app.db.get_git_repo(app.query['repo'].int()) or { + return app.json(http.Status.bad_request, new_response('Unknown repo.')) } // Store log in db log := db.BuildLog{ - repo_id: repo_id + repo: repo start_time: start_time end_time: end_time - arch: arch exit_code: exit_code } app.db.add_build_log(log) - repo_logs_dir := os.join_path(app.conf.data_dir, logs_dir_name, repo_id.str(), arch) + repo_logs_dir := os.join_path(app.conf.data_dir, logs_dir_name, repo.id.str(), arch) // Create the logs directory of it doesn't exist if !os.exists(repo_logs_dir) {