cli: Refactor hook-specific logic into own functions
This commit is contained in:
parent
d5eca08944
commit
b10c1876b1
|
@ -19,11 +19,49 @@ func hookTypeInSlice(a hooks.HookType, list []hooks.HookType) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func preCreateCallback(event handler.HookEvent) (handler.HTTPResponse, error) {
|
func preCreateCallback(event handler.HookEvent) (handler.HTTPResponse, error) {
|
||||||
return invokeHookSync(hooks.HookPreCreate, event)
|
ok, hookRes, err := invokeHookSync(hooks.HookPreCreate, event)
|
||||||
|
if !ok || err != nil {
|
||||||
|
return handler.HTTPResponse{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
httpRes := hookRes.HTTPResponse
|
||||||
|
|
||||||
|
// If the hook response includes the instruction to reject the upload, reuse the error code
|
||||||
|
// and message from ErrUploadRejectedByServer, but also include custom HTTP response values.
|
||||||
|
if hookRes.RejectUpload {
|
||||||
|
err := handler.ErrUploadRejectedByServer
|
||||||
|
err.HTTPResponse = err.HTTPResponse.MergeWith(httpRes)
|
||||||
|
|
||||||
|
return handler.HTTPResponse{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return httpRes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func preFinishCallback(event handler.HookEvent) (handler.HTTPResponse, error) {
|
func preFinishCallback(event handler.HookEvent) (handler.HTTPResponse, error) {
|
||||||
return invokeHookSync(hooks.HookPreFinish, event)
|
ok, hookRes, err := invokeHookSync(hooks.HookPreFinish, event)
|
||||||
|
if !ok || err != nil {
|
||||||
|
return handler.HTTPResponse{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
httpRes := hookRes.HTTPResponse
|
||||||
|
return httpRes, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func postReceiveCallback(event handler.HookEvent) {
|
||||||
|
ok, hookRes, _ := invokeHookSync(hooks.HookPostReceive, event)
|
||||||
|
// invokeHookSync already logs the error, if any occurs. So by checking `ok`, we can ensure
|
||||||
|
// that the hook finished successfully
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if hookRes.StopUpload {
|
||||||
|
logEv(stdout, "HookStopUpload", "id", event.Upload.ID)
|
||||||
|
|
||||||
|
// TODO: Control response for PATCH request
|
||||||
|
event.Upload.StopUpload()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetupHookMetrics() {
|
func SetupHookMetrics() {
|
||||||
|
@ -100,10 +138,10 @@ func SetupPostHooks(handler *handler.Handler) {
|
||||||
invokeHookAsync(hooks.HookPostFinish, event)
|
invokeHookAsync(hooks.HookPostFinish, event)
|
||||||
case event := <-handler.TerminatedUploads:
|
case event := <-handler.TerminatedUploads:
|
||||||
invokeHookAsync(hooks.HookPostTerminate, event)
|
invokeHookAsync(hooks.HookPostTerminate, event)
|
||||||
case event := <-handler.UploadProgress:
|
|
||||||
invokeHookAsync(hooks.HookPostReceive, event)
|
|
||||||
case event := <-handler.CreatedUploads:
|
case event := <-handler.CreatedUploads:
|
||||||
invokeHookAsync(hooks.HookPostCreate, event)
|
invokeHookAsync(hooks.HookPostCreate, event)
|
||||||
|
case event := <-handler.UploadProgress:
|
||||||
|
go postReceiveCallback(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
@ -112,57 +150,45 @@ func SetupPostHooks(handler *handler.Handler) {
|
||||||
func invokeHookAsync(typ hooks.HookType, event handler.HookEvent) {
|
func invokeHookAsync(typ hooks.HookType, event handler.HookEvent) {
|
||||||
go func() {
|
go func() {
|
||||||
// Error handling is taken care by the function.
|
// Error handling is taken care by the function.
|
||||||
_, _ = invokeHookSync(typ, event)
|
_, _, _ = invokeHookSync(typ, event)
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func invokeHookSync(typ hooks.HookType, event handler.HookEvent) (httpRes handler.HTTPResponse, err error) {
|
// invokeHookSync executes a hook of the given type with the given event data. If
|
||||||
if !hookTypeInSlice(typ, Flags.EnabledHooks) {
|
// the hook was not executed properly (e.g. an error occurred or not handler is installed),
|
||||||
return httpRes, nil
|
// `ok` will be false and `res` is not filled. `err` can contain the underlying error.
|
||||||
|
// If `ok` is true, `res` contains the response as retrieved from the hook.
|
||||||
|
// Therefore, a caller should always check `ok` and `err` before assuming that the
|
||||||
|
// hook completed successfully.
|
||||||
|
func invokeHookSync(typ hooks.HookType, event handler.HookEvent) (ok bool, res hooks.HookResponse, err error) {
|
||||||
|
// Stop, if no hook handler is installed or this hook event is not enabled
|
||||||
|
if hookHandler == nil || !hookTypeInSlice(typ, Flags.EnabledHooks) {
|
||||||
|
return false, hooks.HookResponse{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
MetricsHookInvocationsTotal.WithLabelValues(string(typ)).Add(1)
|
MetricsHookInvocationsTotal.WithLabelValues(string(typ)).Add(1)
|
||||||
|
|
||||||
id := event.Upload.ID
|
id := event.Upload.ID
|
||||||
|
|
||||||
if hookHandler == nil {
|
|
||||||
return httpRes, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if Flags.VerboseOutput {
|
if Flags.VerboseOutput {
|
||||||
logEv(stdout, "HookInvocationStart", "type", string(typ), "id", id)
|
logEv(stdout, "HookInvocationStart", "type", string(typ), "id", id)
|
||||||
}
|
}
|
||||||
|
|
||||||
hookRes, err := hookHandler.InvokeHook(hooks.HookRequest{
|
res, err = hookHandler.InvokeHook(hooks.HookRequest{
|
||||||
Type: typ,
|
Type: typ,
|
||||||
Event: event,
|
Event: event,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
// If an error occurs during the hook execution, we log and track the error, but do not
|
||||||
|
// return a hook response.
|
||||||
logEv(stderr, "HookInvocationError", "type", string(typ), "id", id, "error", err.Error())
|
logEv(stderr, "HookInvocationError", "type", string(typ), "id", id, "error", err.Error())
|
||||||
MetricsHookErrorsTotal.WithLabelValues(string(typ)).Add(1)
|
MetricsHookErrorsTotal.WithLabelValues(string(typ)).Add(1)
|
||||||
return httpRes, err
|
return false, hooks.HookResponse{}, err
|
||||||
} else if Flags.VerboseOutput {
|
}
|
||||||
|
|
||||||
|
if Flags.VerboseOutput {
|
||||||
logEv(stdout, "HookInvocationFinish", "type", string(typ), "id", id)
|
logEv(stdout, "HookInvocationFinish", "type", string(typ), "id", id)
|
||||||
}
|
}
|
||||||
|
|
||||||
httpRes = hookRes.HTTPResponse
|
return true, res, nil
|
||||||
|
|
||||||
// If the hook response includes the instruction to reject the upload, reuse the error code
|
|
||||||
// and message from ErrUploadRejectedByServer, but also include custom HTTP response values
|
|
||||||
if typ == hooks.HookPreCreate && hookRes.RejectUpload {
|
|
||||||
err := handler.ErrUploadRejectedByServer
|
|
||||||
err.HTTPResponse = err.HTTPResponse.MergeWith(httpRes)
|
|
||||||
|
|
||||||
return httpRes, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if typ == hooks.HookPostReceive && hookRes.StopUpload {
|
|
||||||
logEv(stdout, "HookStopUpload", "id", id)
|
|
||||||
|
|
||||||
// TODO: Control response for PATCH request
|
|
||||||
event.Upload.StopUpload()
|
|
||||||
}
|
|
||||||
|
|
||||||
return httpRes, err
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue