func ListCases(w http.ResponseWriter, r *http.Request) { //Need better explaination of 'status', currently, only hasReport/isUpdated db := liboct.GetDefaultDB() var query liboct.DBQuery page_string := r.URL.Query().Get("Page") page, err := strconv.Atoi(page_string) if err == nil { query.Page = page } pageSizeString := r.URL.Query().Get("PageSize") pageSize, err := strconv.Atoi(pageSizeString) if err != nil { query.PageSize = pageSize } status := r.URL.Query().Get("Status") if len(status) > 0 { query.Params = make(map[string]string) query.Params["Status"] = status } ids := db.Lookup(liboct.DBCase, query) var caseList []liboct.TestCase for index := 0; index < len(ids); index++ { if val, err := db.Get(liboct.DBCase, ids[index]); err == nil { tc, _ := liboct.CaseFromString(val.String()) caseList = append(caseList, tc) } } liboct.RenderOK(w, fmt.Sprintf("%d cases founded", len(caseList)), caseList) }
func ReceiveTask(w http.ResponseWriter, r *http.Request) { db := liboct.GetDefaultDB() realURL, params := liboct.ReceiveFile(w, r, OCTDCacheDir) logrus.Debugf("ReceiveTask %v", realURL) if id, ok := params["id"]; ok { if strings.HasSuffix(realURL, ".tar.gz") { liboct.UntarFile(realURL, strings.TrimSuffix(realURL, ".tar.gz")) } var task liboct.TestTask task.ID = id task.BundleURL = realURL if name, ok := params["name"]; ok { task.Name = name } else { task.Name = id logrus.Warnf("Cannot find the name of the task.") } db.Update(liboct.DBTask, id, task) liboct.RenderOK(w, "", nil) } else { liboct.RenderErrorf(w, fmt.Sprintf("Cannot find the task id: %d", id)) } }
func init() { cmf, err := os.Open("casemanager.conf") if err != nil { logrus.Fatal(err) return } defer cmf.Close() if err = json.NewDecoder(cmf).Decode(&pubConfig); err != nil { logrus.Fatal(err) return } if pubConfig.Debug { logrus.SetLevel(logrus.DebugLevel) } else { logrus.SetLevel(logrus.WarnLevel) } db := liboct.GetDefaultDB() db.RegistCollect(liboct.DBCase) db.RegistCollect(liboct.DBRepo) db.RegistCollect(liboct.DBTask) repos := pubConfig.Repos for index := 0; index < len(repos); index++ { if err := repos[index].IsValid(); err != nil { logrus.Warnf("The repo ", repos[index], " is invalid. ", err.Error()) continue } if id, err := db.Add(liboct.DBRepo, repos[index]); err == nil { RefreshRepo(id) } } }
func ReceiveTask(w http.ResponseWriter, r *http.Request) { logrus.Debugf("ReceiveTask begin") var tc liboct.TestCase db := liboct.GetDefaultDB() realURL, _ := liboct.ReceiveFile(w, r, liboct.SchedulerCacheDir) tc, err := liboct.CaseFromTar(realURL, "") if err != nil { liboct.RenderError(w, err) return } s, _ := liboct.SchedulerNew(tc) err = s.Command(liboct.TestActionApply) if err == nil { if id, e := db.Add(liboct.DBScheduler, s); e == nil { updateSchedulerBundle(id, realURL) liboct.RenderOK(w, id, nil) } else { liboct.RenderError(w, e) } } else { liboct.RenderError(w, err) } }
// redirect to local to test func GetTaskReport(w http.ResponseWriter, r *http.Request) { db := liboct.GetDefaultDB() id := r.URL.Query().Get(":TaskID") taskInterface, err := db.Get(liboct.DBTask, id) if err != nil { liboct.RenderError(w, err) return } task, _ := liboct.TaskFromString(taskInterface.String()) // Here the task.PostURL is: http://ip:port/task/id getURL := fmt.Sprintf("%s/report", task.PostURL) logrus.Debugf("Get url ", getURL) resp, err := http.Get(getURL) if err != nil { liboct.RenderError(w, err) return } defer resp.Body.Close() resp_body, err := ioutil.ReadAll(resp.Body) if err != nil { liboct.RenderError(w, err) return } w.Write([]byte(resp_body)) }
func init() { of, err := os.Open("octd.conf") if err != nil { logrus.Fatal(err) return } defer of.Close() if err = json.NewDecoder(of).Decode(&pubConfig); err != nil { logrus.Fatal(err) return } if pubConfig.Class == "container" { cmd := exec.Command("/bin/sh", "-c", pubConfig.ContainerDaemon) cmd.Stdin = os.Stdin if _, err := cmd.CombinedOutput(); err != nil { logrus.Fatal(err) return } } if pubConfig.Debug { logrus.SetLevel(logrus.DebugLevel) } else { logrus.SetLevel(logrus.InfoLevel) } db := liboct.GetDefaultDB() db.RegistCollect(liboct.DBTask) RegisterToTestServer() }
func GetTaskReport(w http.ResponseWriter, r *http.Request) { filename := r.URL.Query().Get("File") id := r.URL.Query().Get(":ID") db := liboct.GetDefaultDB() taskInterface, err := db.Get(liboct.DBTask, id) if err != nil { logrus.Warnf("Cannot find the test job %v", id) w.WriteHeader(http.StatusNotFound) w.Write([]byte("Cannot find the test job " + id)) return } task, _ := liboct.TaskFromString(taskInterface.String()) workingDir := strings.TrimSuffix(task.BundleURL, ".tar.gz") //The real working dir is under 'source' realURL := path.Join(workingDir, "source", filename) file, err := os.Open(realURL) defer file.Close() if err != nil { logrus.Warnf("Cannot open the file %v", filename) w.WriteHeader(http.StatusNotFound) w.Write([]byte("Cannot open the file: " + realURL)) return } buf := bytes.NewBufferString("") buf.ReadFrom(file) w.Write([]byte(buf.String())) }
func ReceiveTaskCommand(w http.ResponseWriter, r *http.Request) { db := liboct.GetDefaultDB() id := r.URL.Query().Get(":ID") sInterface, err := db.Get(liboct.DBScheduler, id) if err != nil { liboct.RenderError(w, err) return } s, _ := liboct.SchedulerFromString(sInterface.String()) result, _ := ioutil.ReadAll(r.Body) logrus.Debugf("Receive task Command %s", string(result)) r.Body.Close() /* Donnot use this now FIXME var cmd liboct.TestActionCommand json.Unmarshal([]byte(result), &cmd) */ action, err := liboct.TestActionFromString(string(result)) if err != nil { liboct.RenderError(w, err) return } err = s.Command(action) db.Update(liboct.DBScheduler, id, s) if err != nil { liboct.RenderError(w, err) } else { liboct.RenderOK(w, "", nil) } }
func AddRepo(w http.ResponseWriter, r *http.Request) { action := r.URL.Query().Get("Action") db := liboct.GetDefaultDB() //Add and refresh if action == "Add" { var repo liboct.TestCaseRepo result, _ := ioutil.ReadAll(r.Body) r.Body.Close() err := json.Unmarshal([]byte(result), &repo) if err != nil { liboct.RenderError(w, err) } else { if err := repo.IsValid(); err == nil { if id, e := db.Add(liboct.DBRepo, repo); e != nil { liboct.RenderError(w, err) } else { RefreshRepo(id) liboct.RenderOK(w, "", nil) } } else { liboct.RenderError(w, err) } } } else if action == "Refresh" { ids := db.Lookup(liboct.DBRepo, liboct.DBQuery{}) for index := 0; index < len(ids); index++ { RefreshRepo(ids[index]) } liboct.RenderOK(w, "", nil) } else { liboct.RenderErrorf(w, "The action in AddRepo is limited to Add/Refresh") } }
func ModifyRepo(w http.ResponseWriter, r *http.Request) { repoID := r.URL.Query().Get(":ID") action := r.URL.Query().Get("Action") db := liboct.GetDefaultDB() val, err := db.Get(liboct.DBRepo, repoID) if err != nil { liboct.RenderError(w, err) return } if action == "Modify" { var newRepo liboct.TestCaseRepo result, _ := ioutil.ReadAll(r.Body) r.Body.Close() err := json.Unmarshal([]byte(result), &newRepo) if err != nil { liboct.RenderError(w, err) } else { oldRepo, _ := liboct.RepoFromString(val.String()) oldRepo.Modify(newRepo) db.Update(liboct.DBRepo, repoID, oldRepo) RefreshRepo(repoID) liboct.RenderOK(w, "", nil) } } else if action == "Refresh" { RefreshRepo(repoID) liboct.RenderOK(w, "", nil) } else { liboct.RenderErrorf(w, "The action in ModifyRepo is limited to Add/Refresh") } }
func RefreshRepos(w http.ResponseWriter, r *http.Request) { db := liboct.GetDefaultDB() ids := db.Lookup(liboct.DBRepo, liboct.DBQuery{}) for index := 0; index < len(ids); index++ { RefreshRepo(ids[index]) } liboct.RenderOK(w, "", nil) }
func GetRepo(w http.ResponseWriter, r *http.Request) { id := r.URL.Query().Get(":ID") db := liboct.GetDefaultDB() if repo, err := db.Get(liboct.DBRepo, id); err != nil { liboct.RenderError(w, err) } else { liboct.RenderOK(w, "", repo) } }
func GetTaskStatus(w http.ResponseWriter, r *http.Request) { db := liboct.GetDefaultDB() id := r.URL.Query().Get(":TaskID") if taskInterface, err := db.Get(liboct.DBTask, id); err != nil { liboct.RenderError(w, err) } else { liboct.RenderOK(w, "", taskInterface) } }
func CleanRepo(repo liboct.TestCaseRepo) { var query liboct.DBQuery db := liboct.GetDefaultDB() query.Params = make(map[string]string) query.Params["RepoID"] = repo.GetID() ids := db.Lookup(liboct.DBRepo, query) for index := 0; index < len(ids); index++ { db.Remove(liboct.DBCase, ids[index]) } }
func GetTaskReport(w http.ResponseWriter, r *http.Request) { db := liboct.GetDefaultDB() id := r.URL.Query().Get(":ID") sInterface, err := db.Get(liboct.DBScheduler, id) if err != nil { liboct.RenderError(w, err) return } s, _ := liboct.SchedulerFromString(sInterface.String()) //Send the collect command to the octd if err := s.Command(liboct.TestActionCollect); err != nil { db.Update(liboct.DBScheduler, id, s) liboct.RenderError(w, err) return } else { db.Update(liboct.DBScheduler, id, s) } //Tar the reports in the cacheDir reportURL := path.Join(strings.TrimSuffix(s.Case.GetBundleURL(), ".tar.gz"), "source", "reports.tar.gz") found := false logrus.Debugf("Get reportURL %s", reportURL) _, err = os.Stat(reportURL) if err != nil { logrus.Debugf("Regenerate the report") var reports []string for index := 0; index < len(s.Case.Units); index++ { if len(s.Case.Units[index].ReportURL) > 0 { reports = append(reports, s.Case.Units[index].ReportURL) } //Add log reports = append(reports, fmt.Sprintf("%s.log", s.Case.Units[index].Name)) } tarDir := path.Join(strings.TrimSuffix(s.Case.GetBundleURL(), ".tar.gz"), "source") reportURL, found = liboct.TarFileList(reports, tarDir, "reports") } if !found { liboct.RenderError(w, err) return } file, err := os.Open(reportURL) defer file.Close() if err != nil { liboct.RenderError(w, err) } else { buf := bytes.NewBufferString("") buf.ReadFrom(file) //Different write back, not json w.Write([]byte(buf.String())) } }
func DeleteResource(w http.ResponseWriter, r *http.Request) { db := liboct.GetDefaultDB() id := r.URL.Query().Get("ID") lock.Lock() if err := db.Remove(liboct.DBResource, id); err != nil { liboct.RenderError(w, err) } else { liboct.RenderOK(w, "Success in remove the resource", nil) } lock.Unlock() }
func GetCaseReport(w http.ResponseWriter, r *http.Request) { db := liboct.GetDefaultDB() id := r.URL.Query().Get(":ID") if val, err := db.Get(liboct.DBCase, id); err != nil { liboct.RenderError(w, err) } else { tc, _ := liboct.CaseFromString(val.String()) content := tc.GetReportContent() if len(content) > 0 { liboct.RenderOK(w, "", content) } else { liboct.RenderErrorf(w, "Case report is empty.") } } }
//This refresh the 'cache' maintained in casemanager func RefreshRepo(id string) { db := liboct.GetDefaultDB() val, err := db.Get(liboct.DBRepo, id) if err != nil { return } repo, _ := liboct.RepoFromString(val.String()) if repo.Refresh() { CleanRepo(repo) cases := repo.GetCases() for index := 0; index < len(cases); index++ { fmt.Println("case loaded ", cases[index]) db.Add(liboct.DBCase, cases[index]) } } }
func GetResource(w http.ResponseWriter, r *http.Request) { query := GetResourceQuery(r) db := liboct.GetDefaultDB() ids := db.Lookup(liboct.DBResource, query) if len(ids) == 0 { liboct.RenderErrorf(w, "Cannot find the avaliable resource") } else { var rss []liboct.DBInterface for index := 0; index < len(ids); index++ { res, _ := db.Get(liboct.DBResource, ids[index]) rss = append(rss, res) } liboct.RenderOK(w, "Find the avaliable resource", rss) } }
// Since the sheduler ID is got after receiving the test files // we need to move it to a better place // /tmp/.../A.tar.gz --> /tmp/.../id/A.tar.gz func updateSchedulerBundle(id string, oldURL string) { db := liboct.GetDefaultDB() sInterface, _ := db.Get(liboct.DBScheduler, id) s, _ := liboct.SchedulerFromString(sInterface.String()) dir := path.Dir(path.Dir(oldURL)) newURL := fmt.Sprintf("%s/%s", path.Join(dir, id), path.Base(oldURL)) liboct.PreparePath(path.Join(dir, id), "") logrus.Debugf("Old URL %s, New URL %s", oldURL, newURL) os.Rename(strings.TrimSuffix(oldURL, ".tar.gz"), strings.TrimSuffix(newURL, ".tar.gz")) os.Rename(oldURL, newURL) //bundleURL is the directory of the bundle s.Case.SetBundleURL(strings.TrimSuffix(newURL, ".tar.gz")) db.Update(liboct.DBScheduler, id, s) os.RemoveAll(path.Dir(oldURL)) }
func GetCase(w http.ResponseWriter, r *http.Request) { //TODO: support another query method : repo/group/name db := liboct.GetDefaultDB() id := r.URL.Query().Get(":ID") if val, err := db.Get(liboct.DBCase, id); err != nil { liboct.RenderError(w, err) } else { tc, _ := liboct.CaseFromString(val.String()) value := tc.GetBundleContent() if len(value) > 0 { w.Write([]byte(value)) } else { liboct.RenderErrorf(w, "Case is empty.") } } }
func PostTaskAction(w http.ResponseWriter, r *http.Request) { result, _ := ioutil.ReadAll(r.Body) logrus.Debugf("Post task action %v", string(result)) r.Body.Close() action, err := liboct.ActionCommandFromString(string(result)) if err != nil { liboct.RenderError(w, err) return } id := r.URL.Query().Get(":ID") db := liboct.GetDefaultDB() taskInterface, err := db.Get(liboct.DBTask, id) if err != nil { liboct.RenderError(w, err) return } task, _ := liboct.TaskFromString(taskInterface.String()) workingDir := path.Join(strings.TrimSuffix(task.BundleURL, ".tar.gz"), "source") if _, err := os.Stat(workingDir); err != nil { //Create in the case which has no 'source' files os.MkdirAll(workingDir, 0777) } switch action.Action { case liboct.TestActionDeploy: fallthrough case liboct.TestActionRun: val, err := RunCommand(action, workingDir) //Save the logs logFile := fmt.Sprintf("%s/%s.log", workingDir, task.Name) ioutil.WriteFile(logFile, val, 0644) if err != nil { liboct.RenderErrorf(w, fmt.Sprintf("Failed in run command: %s", string(result))) } else { liboct.RenderOK(w, "", string(val)) } return } liboct.RenderErrorf(w, fmt.Sprintf("Action %s is not support yet", action.Action)) }
func PostResource(w http.ResponseWriter, r *http.Request) { var res liboct.Resource db := liboct.GetDefaultDB() result, _ := ioutil.ReadAll(r.Body) r.Body.Close() logrus.Debugf(string(result)) json.Unmarshal([]byte(result), &res) if err := res.IsValid(); err != nil { liboct.RenderError(w, err) } else { lock.Lock() if id, err := db.Add(liboct.DBResource, res); err != nil { liboct.RenderError(w, err) } else { liboct.RenderOK(w, fmt.Sprintf("Success in adding the resource: %s ", id), nil) } lock.Unlock() } }
// Will use DB in the future, (mongodb for example) func init() { sf, err := os.Open("scheduler.conf") if err != nil { logrus.Fatal(err) return } defer sf.Close() if err = json.NewDecoder(sf).Decode(&pubConfig); err != nil { logrus.Fatal(err) return } if pubConfig.Debug { logrus.SetLevel(logrus.DebugLevel) } else { logrus.SetLevel(logrus.InfoLevel) } db := liboct.GetDefaultDB() db.RegistCollect(liboct.DBResource) db.RegistCollect(liboct.DBScheduler) if len(pubConfig.ServerListFile) == 0 { return } slf, err := os.Open(pubConfig.ServerListFile) if err != nil { return } defer slf.Close() var rl []liboct.Resource if err = json.NewDecoder(slf).Decode(&rl); err != nil { return } for index := 0; index < len(rl); index++ { if _, e := db.Add(liboct.DBResource, rl[index]); e != nil { logrus.Warn(e) } } }
func AddTask(w http.ResponseWriter, r *http.Request) { result, _ := ioutil.ReadAll(r.Body) r.Body.Close() db := liboct.GetDefaultDB() caseID := string(result) caseInterface, err := db.Get(liboct.DBCase, caseID) if err != nil { liboct.RenderError(w, err) return } tc, _ := liboct.CaseFromString(caseInterface.String()) bundleURL := tc.GetBundleTarURL() postURL := pubConfig.SchedulerURL if task, err := liboct.TestTaskNew(postURL, bundleURL, liboct.SchedulerDefaultPrio); err != nil { liboct.RenderError(w, err) } else { id, _ := db.Add(liboct.DBTask, task) liboct.RenderOK(w, id, nil) } }
func PostTaskAction(w http.ResponseWriter, r *http.Request) { db := liboct.GetDefaultDB() result, _ := ioutil.ReadAll(r.Body) r.Body.Close() action, err := liboct.TestActionFromString(string(result)) if err != nil { liboct.RenderError(w, err) return } id := r.URL.Query().Get(":TaskID") taskInterface, err := db.Get(liboct.DBTask, id) if err != nil { liboct.RenderError(w, err) return } task, _ := liboct.TaskFromString(taskInterface.String()) if e := task.Command(action); e != nil { liboct.RenderError(w, err) } else { liboct.RenderOK(w, "", nil) } }
func ListRepos(w http.ResponseWriter, r *http.Request) { var query liboct.DBQuery page_string := r.URL.Query().Get("Page") page, err := strconv.Atoi(page_string) if err == nil { query.Page = page } pageSizeString := r.URL.Query().Get("PageSize") pageSize, err := strconv.Atoi(pageSizeString) if err == nil { query.PageSize = pageSize } var rl []liboct.DBInterface db := liboct.GetDefaultDB() ids := db.Lookup(liboct.DBRepo, query) for index := 0; index < len(ids); index++ { repo, _ := db.Get(liboct.DBRepo, ids[index]) rl = append(rl, repo) } liboct.RenderOK(w, fmt.Sprintf("%d repos founded", len(rl)), rl) }
func ListTasks(w http.ResponseWriter, r *http.Request) { //TODO status var query liboct.DBQuery db := liboct.GetDefaultDB() pageStr := r.URL.Query().Get("Page") page, err := strconv.Atoi(pageStr) if err == nil { query.Page = page } pageSizeStr := r.URL.Query().Get("PageSize") pageSize, err := strconv.Atoi(pageSizeStr) if err == nil { query.PageSize = pageSize } ids := db.Lookup(liboct.DBTask, query) var tl []liboct.DBInterface for index := 0; index < len(ids); index++ { task, _ := db.Get(liboct.DBTask, ids[index]) tl = append(tl, task) } liboct.RenderOK(w, fmt.Sprintf("%d tasks founded", len(tl)), tl) }