Skip to content
This repository has been archived by the owner on Sep 4, 2024. It is now read-only.

Commit

Permalink
Refactor server index to use getJobs
Browse files Browse the repository at this point in the history
Fixes #50.
  • Loading branch information
apostergiou committed Apr 24, 2018
1 parent 3ec8a8c commit 0bdecf0
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 54 deletions.
118 changes: 64 additions & 54 deletions cmd/mistryd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"io/ioutil"
"log"
"net/http"
"os"
"path/filepath"
"sort"
"strings"
Expand Down Expand Up @@ -135,69 +136,17 @@ func (s *Server) HandleNewJob(w http.ResponseWriter, r *http.Request) {

// HandleIndex returns all available jobs.
func (s *Server) HandleIndex(w http.ResponseWriter, r *http.Request) {
var jobs []Job

if r.Method != "GET" {
http.Error(w, "Expected GET, got "+r.Method, http.StatusMethodNotAllowed)
return
}

projects, err := ioutil.ReadDir(s.cfg.BuildPath)
jobs, err := s.getJobs()
if err != nil {
s.Log.Print("cannot scan projects; ", err)
s.Log.Printf("cannot get jobs for path %s; %s", s.cfg.BuildPath, err)
w.WriteHeader(http.StatusInternalServerError)
return
}

for _, p := range projects {
pendingPath := filepath.Join(s.cfg.BuildPath, p.Name(), "pending")
readyPath := filepath.Join(s.cfg.BuildPath, p.Name(), "ready")
pendingJobs, err := ioutil.ReadDir(pendingPath)
if err != nil {
s.Log.Printf("cannot scan pending jobs of project %s; %s", p.Name(), err)
w.WriteHeader(http.StatusInternalServerError)
return
}
readyJobs, err := ioutil.ReadDir(readyPath)
if err != nil {
s.Log.Printf("cannot scan ready jobs of project %s; %s", p.Name(), err)
w.WriteHeader(http.StatusInternalServerError)
return
}

for _, j := range pendingJobs {
bi := types.BuildInfo{}
biBlob, err := ioutil.ReadFile(filepath.Join(pendingPath, j.Name(), BuildInfoFname))
if err != nil {
s.Log.Printf("cannot read build_info file of job %s; %s", j.Name(), err)
w.WriteHeader(http.StatusInternalServerError)
return
}
err = json.Unmarshal(biBlob, &bi)
jobs = append(jobs, Job{
ID: j.Name(),
Project: p.Name(),
StartedAt: bi.StartedAt,
State: "pending"})
}

for _, j := range readyJobs {
bi := types.BuildInfo{}
biBlob, err := ioutil.ReadFile(filepath.Join(readyPath, j.Name(), BuildInfoFname))
if err != nil {
s.Log.Printf("cannot read build_info file of job %s; %s", j.Name(), err)
w.WriteHeader(http.StatusInternalServerError)
return
}
err = json.Unmarshal(biBlob, &bi)
jobs = append(jobs, Job{
ID: j.Name(),
Project: p.Name(),
StartedAt: bi.StartedAt,
State: "ready"})
}
}

sort.Slice(jobs, func(i, j int) bool {
return jobs[j].StartedAt.Before(jobs[i].StartedAt)
})
Expand Down Expand Up @@ -435,3 +384,64 @@ func (s *Server) ListenAndServe() error {
go s.br.ListenForClients()
return s.srv.ListenAndServe()
}

// getJobs returns all pending and ready jobs.
func (s *Server) getJobs() ([]Job, error) {
var jobs []Job
var pendingJobs []os.FileInfo
var readyJobs []os.FileInfo

projects, err := ioutil.ReadDir(s.cfg.BuildPath)
if err != nil {
return nil, fmt.Errorf("cannot scan projects; %s", err)
}

for _, p := range projects {
pendingPath := filepath.Join(s.cfg.BuildPath, p.Name(), "pending")
_, err := os.Stat(pendingPath)
pendingExists := !os.IsNotExist(err)
readyPath := filepath.Join(s.cfg.BuildPath, p.Name(), "ready")
_, err = os.Stat(readyPath)
readyExists := !os.IsNotExist(err)

if pendingExists {
pendingJobs, err = ioutil.ReadDir(pendingPath)
if err != nil {
return nil, fmt.Errorf("cannot scan pending jobs of project %s; %s", p.Name(), err)
}
}
if readyExists {
readyJobs, err = ioutil.ReadDir(readyPath)
if err != nil {
return nil, fmt.Errorf("cannot scan ready jobs of project %s; %s", p.Name(), err)
}
}

getJob := func(path, jobID, project, state string) (Job, error) {
bi, err := types.GetBuildInfo(filepath.Join(path, jobID, BuildInfoFname))
if err != nil {
return Job{}, fmt.Errorf("cannot read build_info file of job %s; %s", jobID, err)
}

return Job{ID: jobID, Project: project, StartedAt: bi.StartedAt, State: state}, nil
}

for _, j := range pendingJobs {
job, err := getJob(pendingPath, j.Name(), p.Name(), "pending")
if err != nil {
return nil, fmt.Errorf("cannot find job %s; %s", j.Name(), err)
}
jobs = append(jobs, job)
}

for _, j := range readyJobs {
job, err := getJob(readyPath, j.Name(), p.Name(), "ready")
if err != nil {
return nil, fmt.Errorf("cannot find job %s; %s", j.Name(), err)
}
jobs = append(jobs, job)
}
}

return jobs, nil
}
15 changes: 15 additions & 0 deletions pkg/types/build_info.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package types

import (
"encoding/json"
"fmt"
"io/ioutil"
"time"
)

Expand Down Expand Up @@ -39,3 +41,16 @@ type ErrImageBuild struct {
func (e ErrImageBuild) Error() string {
return fmt.Sprintf("could not build docker image '%s': %s", e.Image, e.Err)
}

func GetBuildInfo(path string) (BuildInfo, error) {
bi := BuildInfo{}
biBlob, err := ioutil.ReadFile(path)
if err != nil {
return BuildInfo{}, fmt.Errorf("cannot read build_info file; %s", err)
}
err = json.Unmarshal(biBlob, &bi)
if err != nil {
return BuildInfo{}, fmt.Errorf("cannot unmarshal the build_info file; %s", err)
}
return bi, nil
}

0 comments on commit 0bdecf0

Please sign in to comment.