Skip to content

Commit cac172b

Browse files
committed
[drbd-build-svr]: fix linter and add new method
1 parent 51cc84f commit cac172b

File tree

2 files changed

+87
-3
lines changed

2 files changed

+87
-3
lines changed

images/drbd-build-server/pkg/control/control.go

Lines changed: 87 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919

2020
const (
2121
buildPath = "/api/v1/build"
22+
getBuildPath = "/api/v1/builds/{job_id}" // SYNC analog of download API with timeout
2223
jobStatusPath = "/api/v1/status/{job_id}"
2324
downloadPath = "/api/v1/download/{job_id}"
2425
helloPath = "/api/v1/hello"
@@ -134,6 +135,7 @@ func (s *BuildServer) registerRoutes() {
134135
s.router.HandleFunc(buildPath, s.buildModuleHandler()).Methods("POST")
135136
s.router.HandleFunc(jobStatusPath, s.getStatusHandler()).Methods("GET")
136137
s.router.HandleFunc(downloadPath, s.downloadModule()).Methods("GET")
138+
s.router.HandleFunc(getBuildPath, s.helloHandler()).Methods("GET")
137139
s.router.HandleFunc(helloPath, s.helloHandler()).Methods("GET")
138140
}
139141

@@ -144,9 +146,9 @@ func (s *BuildServer) replyErrorFormated(code int, remoteAddr string, w http.Res
144146
s.logger.Error("HTTP error", "remote_addr", remoteAddr, "code", code, "error", msg)
145147
}
146148

147-
func (s *BuildServer) replyError(code int, remoteAddr string, w http.ResponseWriter, error error) {
149+
func (s *BuildServer) replyError(code int, remoteAddr string, w http.ResponseWriter, errorOccurred error) {
148150
w.WriteHeader(code)
149-
s.logger.Error("HTTP error", "remote_addr", remoteAddr, "code", code, "error", error)
151+
s.logger.Error("HTTP error", "remote_addr", remoteAddr, "code", code, "error", errorOccurred)
150152
}
151153

152154
func (s *BuildServer) helloHandler() http.HandlerFunc {
@@ -354,3 +356,86 @@ func (s *BuildServer) downloadModule() http.HandlerFunc {
354356
s.logger.Debug("Module file sent successfully", "remote_addr", remoteAddr)
355357
}
356358
}
359+
360+
func (s *BuildServer) getBuiLdModule() http.HandlerFunc {
361+
return func(w http.ResponseWriter, r *http.Request) {
362+
remoteAddr := r.RemoteAddr
363+
vars := mux.Vars(r)
364+
jobID := vars["job_id"]
365+
s.logger.Debug("Download request for job", "remote_addr", remoteAddr, "job_id", jobID)
366+
367+
job := s.buildService.GetJob(jobID)
368+
369+
switch job.Status {
370+
case model.StatusNotExist:
371+
s.logger.Debug("Job not found", "remote_addr", remoteAddr, "job_id", jobID)
372+
s.replyErrorFormated(http.StatusNotFound, remoteAddr, w, "Job not found: %s", jobID)
373+
return
374+
case model.StatusFailed:
375+
s.logger.Debug("Job is failed ", "remote_addr", remoteAddr, "job_id", jobID)
376+
s.replyErrorFormated(http.StatusInternalServerError, remoteAddr, w, "Job is failed: %s", jobID)
377+
return
378+
case model.StatusPending:
379+
s.logger.Debug("Job is pending ", "remote_addr", remoteAddr, "job_id", jobID)
380+
s.replyErrorFormated(http.StatusAccepted, remoteAddr, w, "Job is pending: %s", jobID)
381+
return
382+
}
383+
384+
// from this line wait until s.buildService.GetJob(jobID).Status == model.StatusCompleted with check step 5 sec and timeout 5 min
385+
const (
386+
pollInterval = 5 * time.Second
387+
waitTimeout = 5 * time.Minute
388+
)
389+
390+
deadline := time.Now().Add(waitTimeout)
391+
for job.Status != model.StatusCompleted {
392+
// Check for client cancellation
393+
select {
394+
case <-r.Context().Done():
395+
s.logger.Debug("Client cancelled download request while waiting for job completion", "remote_addr", remoteAddr, "job_id", jobID)
396+
return
397+
case <-time.After(pollInterval):
398+
}
399+
400+
if time.Now().After(deadline) {
401+
s.logger.Debug("Timed out waiting for job completion", "remote_addr", remoteAddr, "job_id", jobID)
402+
s.replyErrorFormated(http.StatusGatewayTimeout, remoteAddr, w, "Timed out waiting for job completion: %s", jobID)
403+
return
404+
}
405+
406+
job = s.buildService.GetJob(jobID)
407+
408+
if job.Status == model.StatusFailed {
409+
s.logger.Debug("Job failed while waiting", "remote_addr", remoteAddr, "job_id", jobID)
410+
s.replyErrorFormated(http.StatusInternalServerError, remoteAddr, w, "Job failed: %s", jobID)
411+
return
412+
}
413+
}
414+
415+
s.logger.Debug("Job status", "remote_addr", remoteAddr, "status", job.Status, "cache_path", job.CachePath)
416+
if job.Status != model.StatusCompleted {
417+
s.logger.Debug("Job not completed", "remote_addr", remoteAddr, "status", job.Status)
418+
s.replyErrorFormated(http.StatusBadRequest, remoteAddr, w, "Job is not completed yet. Status: %s", job.Status)
419+
return
420+
}
421+
422+
if job.CachePath == "" {
423+
s.logger.Debug("Cache path not set for completed job", "remote_addr", remoteAddr)
424+
s.replyErrorFormated(http.StatusInternalServerError, remoteAddr, w, "Cache path not set for completed job")
425+
return
426+
}
427+
428+
cacheInfo, err := os.Stat(job.CachePath)
429+
if os.IsNotExist(err) {
430+
s.logger.Debug("Cache file not found", "remote_addr", remoteAddr, "cache_path", job.CachePath)
431+
s.replyErrorFormated(http.StatusNotFound, remoteAddr, w, "Cache file not found: %s", job.CachePath)
432+
return
433+
}
434+
435+
s.logger.Info("Serving module file", "remote_addr", remoteAddr, "cache_path", job.CachePath, "size_bytes", cacheInfo.Size())
436+
w.Header().Set("Content-Type", "application/gzip")
437+
w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"drbd-modules-%s.tar.gz\"", job.KernelVersion))
438+
http.ServeFile(w, r, job.CachePath)
439+
s.logger.Debug("Module file sent successfully", "remote_addr", remoteAddr)
440+
}
441+
}

images/drbd-build-server/pkg/service/service.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ type BuildService struct {
4949
}
5050

5151
func NewTestBuildService(cacheDir *string, logger *slog.Logger) *BuildService {
52-
5352
return &BuildService{
5453
cacheDir: *cacheDir,
5554
logger: logger,

0 commit comments

Comments
 (0)