Add /hash/:hash endpoint
It looks up the given hash and finds the latest build producing an artifact with this hash.
This commit is contained in:
parent
3a106342f5
commit
6b96cae318
5 changed files with 50 additions and 0 deletions
|
@ -388,6 +388,23 @@ module Build = struct
|
||||||
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
|}
|
|}
|
||||||
|
|
||||||
|
let get_by_hash =
|
||||||
|
Caqti_request.find_opt
|
||||||
|
Rep.cstruct
|
||||||
|
(Caqti_type.tup2
|
||||||
|
Caqti_type.string
|
||||||
|
t)
|
||||||
|
{| SELECT job.name,
|
||||||
|
b.uuid, b.start_d, b.start_ps, b.finish_d, b.finish_ps,
|
||||||
|
b.result_kind, b.result_code, b.result_msg,
|
||||||
|
b.console, b.script, b.main_binary, b.job
|
||||||
|
FROM build_artifact a
|
||||||
|
INNER JOIN build b ON b.id = a.build
|
||||||
|
INNER JOIN job ON job.id = b.job
|
||||||
|
WHERE a.sha256 = ?
|
||||||
|
ORDER BY b.start_d DESC, b.start_ps DESC
|
||||||
|
LIMIT 1
|
||||||
|
|}
|
||||||
end
|
end
|
||||||
|
|
||||||
module User = struct
|
module User = struct
|
||||||
|
|
|
@ -128,6 +128,8 @@ sig
|
||||||
(id, id * Meta.t * file option, [< `Many | `One | `Zero > `One `Zero ])
|
(id, id * Meta.t * file option, [< `Many | `One | `Zero > `One `Zero ])
|
||||||
Caqti_request.t
|
Caqti_request.t
|
||||||
val add : (t, unit, [< `Many | `One | `Zero > `Zero ]) Caqti_request.t
|
val add : (t, unit, [< `Many | `One | `Zero > `Zero ]) Caqti_request.t
|
||||||
|
val get_by_hash :
|
||||||
|
(Cstruct.t, string * t, [< `Many | `One | `Zero > `One `Zero]) Caqti_request.t
|
||||||
end
|
end
|
||||||
|
|
||||||
module User : sig
|
module User : sig
|
||||||
|
|
|
@ -199,12 +199,37 @@ let routes t =
|
||||||
Lwt.return (Response.of_plain_text "Internal server error\n" ~status:`Internal_server_error)
|
Lwt.return (Response.of_plain_text "Internal server error\n" ~status:`Internal_server_error)
|
||||||
in
|
in
|
||||||
|
|
||||||
|
let hash req =
|
||||||
|
let hash_s = Router.param req "hash" in
|
||||||
|
let hash = try Some (Hex.to_cstruct (`Hex hash_s))
|
||||||
|
with Invalid_argument _ -> None
|
||||||
|
in
|
||||||
|
match hash with
|
||||||
|
| None ->
|
||||||
|
Log.debug (fun m -> m "Invalid hash hex %S" hash_s);
|
||||||
|
Response.of_plain_text "Bad request\n" ~status:`Bad_request
|
||||||
|
|> Lwt.return
|
||||||
|
| Some hash ->
|
||||||
|
let+ build = Caqti_lwt.Pool.use (Model.build_hash hash) t.pool in
|
||||||
|
match build with
|
||||||
|
| Error e ->
|
||||||
|
Log.warn (fun m -> m "Database error: %a" pp_error e);
|
||||||
|
Response.of_plain_text "Internal server error\n" ~status:`Internal_server_error
|
||||||
|
| Ok None ->
|
||||||
|
Log.debug (fun m -> m "Hash not found: %S" hash_s);
|
||||||
|
Response.of_plain_text "Artifact not found\n" ~status:`Not_found
|
||||||
|
| Ok (Some (job_name, build)) ->
|
||||||
|
Response.redirect_to (Fmt.strf "/job/%s/build/%a/" job_name
|
||||||
|
Uuidm.pp build.Builder_db.Build.uuid)
|
||||||
|
in
|
||||||
|
|
||||||
[
|
[
|
||||||
App.get "/" builder;
|
App.get "/" builder;
|
||||||
App.get "/job/:job/" job;
|
App.get "/job/:job/" job;
|
||||||
App.get "/job/:job/build/:build/" job_build;
|
App.get "/job/:job/build/:build/" job_build;
|
||||||
App.get "/job/:job/build/:build/f/**" job_build_file;
|
App.get "/job/:job/build/:build/f/**" job_build_file;
|
||||||
App.post "/upload" (authorized t upload);
|
App.post "/upload" (authorized t upload);
|
||||||
|
App.get "/hash/:hash" hash;
|
||||||
]
|
]
|
||||||
|
|
||||||
let add_routes t (app : App.t) =
|
let add_routes t (app : App.t) =
|
||||||
|
|
|
@ -49,6 +49,9 @@ let build_meta job (module Db : CONN) =
|
||||||
Db.find_opt Builder_db.Build.get_latest job >|=
|
Db.find_opt Builder_db.Build.get_latest job >|=
|
||||||
Option.map (fun (_id, meta, file) -> (meta, file))
|
Option.map (fun (_id, meta, file) -> (meta, file))
|
||||||
|
|
||||||
|
let build_hash hash (module Db : CONN) =
|
||||||
|
Db.find_opt Builder_db.Build.get_by_hash hash
|
||||||
|
|
||||||
let build_exists uuid (module Db : CONN) =
|
let build_exists uuid (module Db : CONN) =
|
||||||
Db.find_opt Builder_db.Build.get_by_uuid uuid >|=
|
Db.find_opt Builder_db.Build.get_by_uuid uuid >|=
|
||||||
Option.is_some
|
Option.is_some
|
||||||
|
|
|
@ -14,6 +14,9 @@ val build : Uuidm.t -> Caqti_lwt.connection ->
|
||||||
val build_meta : Builder_db.id -> Caqti_lwt.connection ->
|
val build_meta : Builder_db.id -> Caqti_lwt.connection ->
|
||||||
((Builder_db.Build.Meta.t * Builder_db.file option) option, [> error ]) result Lwt.t
|
((Builder_db.Build.Meta.t * Builder_db.file option) option, [> error ]) result Lwt.t
|
||||||
|
|
||||||
|
val build_hash : Cstruct.t -> Caqti_lwt.connection ->
|
||||||
|
((string * Builder_db.Build.t) option, [> error ]) result Lwt.t
|
||||||
|
|
||||||
val build_exists : Uuidm.t -> Caqti_lwt.connection ->
|
val build_exists : Uuidm.t -> Caqti_lwt.connection ->
|
||||||
(bool, [> error ]) result Lwt.t
|
(bool, [> error ]) result Lwt.t
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue