// Start kicks off the statemachine to transit from current state to s, and moves on // It will search the transit map if the next state is "_continue", and // will enter error state if there's more than one possible path when next state is "_continue" func (sm *SM) Start(s string) { n, err := sm.EnterState(s) log.Debugf("Job id: %d, next state from handler: %s", sm.JobID, n) for len(n) > 0 && err == nil { if d := sm.getDesiredState(); len(d) > 0 { log.Debugf("Job id: %d. Desired state: %s, will ignore the next state from handler", sm.JobID, d) n = d sm.setDesiredState("") continue } if n == models.JobContinue && len(sm.Transitions[sm.CurrentState]) == 1 { for n = range sm.Transitions[sm.CurrentState] { break } log.Debugf("Job id: %d, Continue to state: %s", sm.JobID, n) continue } if n == models.JobContinue && len(sm.Transitions[sm.CurrentState]) != 1 { log.Errorf("Job id: %d, next state is continue but there are %d possible next states in transition table", sm.JobID, len(sm.Transitions[sm.CurrentState])) err = fmt.Errorf("Unable to continue") break } n, err = sm.EnterState(n) log.Debugf("Job id: %d, next state from handler: %s", sm.JobID, n) } if err != nil { log.Warningf("Job id: %d, the statemachin will enter error state due to error: %v", sm.JobID, err) sm.EnterState(models.JobError) } }
func resumeJobs() { log.Debugf("Trying to resume halted jobs...") err := dao.ResetRunningJobs() if err != nil { log.Warningf("Failed to reset all running jobs to pending, error: %v", err) } jobs, err := dao.GetRepJobByStatus(models.JobPending, models.JobRetrying) if err == nil { for _, j := range jobs { log.Debugf("Resuming job: %d", j.ID) job.Schedule(j.ID) } } else { log.Warningf("Failed to jobs to resume, error: %v", err) } }
func init() { maxWorkersEnv := os.Getenv("MAX_JOB_WORKERS") maxWorkers64, err := strconv.ParseInt(maxWorkersEnv, 10, 32) maxJobWorkers = int(maxWorkers64) if err != nil { log.Warningf("Failed to parse max works setting, error: %v, the default value: %d will be used", err, defaultMaxWorkers) maxJobWorkers = defaultMaxWorkers } localRegURL = os.Getenv("REGISTRY_URL") if len(localRegURL) == 0 { localRegURL = "http://registry:5000" } localUIURL = os.Getenv("UI_URL") if len(localUIURL) == 0 { localUIURL = "http://ui" } logDir = os.Getenv("LOG_DIR") if len(logDir) == 0 { logDir = "/var/log" } f, err := os.Open(logDir) defer f.Close() if err != nil { panic(err) } finfo, err := f.Stat() if err != nil { panic(err) } if !finfo.IsDir() { panic(fmt.Sprintf("%s is not a direcotry", logDir)) } uiSecret = os.Getenv("UI_SECRET") if len(uiSecret) == 0 { panic("UI Secret is not set") } verifyRemoteCert = os.Getenv("VERIFY_REMOTE_CERT") if len(verifyRemoteCert) == 0 { verifyRemoteCert = "on" } configPath := os.Getenv("CONFIG_PATH") if len(configPath) != 0 { log.Infof("Config path: %s", configPath) beego.LoadAppConfig("ini", configPath) } log.Debugf("config: maxJobWorkers: %d", maxJobWorkers) log.Debugf("config: localUIURL: %s", localUIURL) log.Debugf("config: localRegURL: %s", localRegURL) log.Debugf("config: verifyRemoteCert: %s", verifyRemoteCert) log.Debugf("config: logDir: %s", logDir) log.Debugf("config: uiSecret: ******") }
// Prepare validates the URL and parms func (pma *ProjectMemberAPI) Prepare() { pid, err := strconv.ParseInt(pma.Ctx.Input.Param(":pid"), 10, 64) if err != nil { log.Errorf("Error parsing project id: %d, error: %v", pid, err) pma.CustomAbort(http.StatusBadRequest, "invalid project Id") return } p, err := dao.GetProjectByID(pid) if err != nil { log.Errorf("Error occurred in GetProjectById, error: %v", err) pma.CustomAbort(http.StatusInternalServerError, "Internal error.") } if p == nil { log.Warningf("Project with id: %d does not exist.", pid) pma.CustomAbort(http.StatusNotFound, "Project does not exist") } pma.project = p pma.currentUserID = pma.ValidateUser() mid := pma.Ctx.Input.Param(":mid") if mid == "current" { pma.memberID = pma.currentUserID } else if len(mid) == 0 { pma.memberID = 0 } else if len(mid) > 0 { memberID, err := strconv.Atoi(mid) if err != nil { log.Errorf("Invalid member Id, error: %v", err) pma.CustomAbort(http.StatusBadRequest, "Invalid member id") } pma.memberID = memberID } }
// ToggleProjectPublic ... func (p *ProjectAPI) ToggleProjectPublic() { p.userID = p.ValidateUser() var req projectReq var public int projectID, err := strconv.ParseInt(p.Ctx.Input.Param(":id"), 10, 64) if err != nil { log.Errorf("Error parsing project id: %d, error: %v", projectID, err) p.RenderError(http.StatusBadRequest, "invalid project id") return } p.DecodeJSONReq(&req) if req.Public { public = 1 } if !isProjectAdmin(p.userID, projectID) { log.Warningf("Current user, id: %d does not have project admin role for project, id: %d", p.userID, projectID) p.RenderError(http.StatusForbidden, "") return } err = dao.ToggleProjectPublicity(p.projectID, public) if err != nil { log.Errorf("Error while updating project, project id: %d, error: %v", projectID, err) p.RenderError(http.StatusInternalServerError, "Failed to update project") } }
// ValidateUser checks if the request triggered by a valid user func (b *BaseAPI) ValidateUser() int { username, password, ok := b.Ctx.Request.BasicAuth() if ok { log.Infof("Requst with Basic Authentication header, username: %s", username) user, err := auth.Login(models.AuthModel{ Principal: username, Password: password, }) if err != nil { log.Errorf("Error while trying to login, username: %s, error: %v", username, err) user = nil } if user != nil { return user.UserID } } sessionUserID := b.GetSession("userId") if sessionUserID == nil { log.Warning("No user id in session, canceling request") b.CustomAbort(http.StatusUnauthorized, "") } userID := sessionUserID.(int) u, err := dao.GetUser(models.User{UserID: userID}) if err != nil { log.Errorf("Error occurred in GetUser, error: %v", err) b.CustomAbort(http.StatusInternalServerError, "Internal error.") } if u == nil { log.Warningf("User was deleted already, user id: %d, canceling request.", userID) b.CustomAbort(http.StatusUnauthorized, "") } return userID }
// Enter updates the status of a job and returns "_continue" status to tell state machine to move on. // If the status is a final status it returns empty string and the state machine will be stopped. func (su StatusUpdater) Enter() (string, error) { err := dao.UpdateRepJobStatus(su.JobID, su.State) if err != nil { log.Warningf("Failed to update state of job: %d, state: %s, error: %v", su.JobID, su.State, err) } var next = models.JobContinue if su.State == models.JobStopped || su.State == models.JobError || su.State == models.JobFinished { next = "" } return next, err }
// ToggleUserAdminRole handles PUT api/users/{}/sysadmin func (ua *UserAPI) ToggleUserAdminRole() { if !ua.IsAdmin { log.Warningf("current user, id: %d does not have admin role, can not update other user's role", ua.currentUserID) ua.RenderError(http.StatusForbidden, "User does not have admin role") return } userQuery := models.User{UserID: ua.userID} ua.DecodeJSONReq(&userQuery) if err := dao.ToggleUserAdminRole(userQuery.UserID, userQuery.HasAdminRole); err != nil { log.Errorf("Error occurred in ToggleUserAdminRole: %v", err) ua.CustomAbort(http.StatusInternalServerError, "Internal error.") } }
// Post ... func (pma *ProjectMemberAPI) Post() { currentUserID := pma.currentUserID projectID := pma.project.ProjectID if !hasProjectAdminRole(currentUserID, projectID) { log.Warningf("Current user, id: %d does not have project admin role for project, id:", currentUserID, projectID) pma.RenderError(http.StatusForbidden, "") return } var req memberReq pma.DecodeJSONReq(&req) username := req.Username userID := checkUserExists(username) if userID <= 0 { log.Warningf("User does not exist, user name: %s", username) pma.RenderError(http.StatusNotFound, "User does not exist") return } rolelist, err := dao.GetUserProjectRoles(userID, projectID) if err != nil { log.Errorf("Error occurred in GetUserProjectRoles, error: %v", err) pma.CustomAbort(http.StatusInternalServerError, "Internal error.") } if len(rolelist) > 0 { log.Warningf("user is already added to project, user id: %d, project id: %d", userID, projectID) pma.RenderError(http.StatusConflict, "user is ready in project") return } for _, rid := range req.Roles { err = dao.AddProjectMember(projectID, userID, int(rid)) if err != nil { log.Errorf("Failed to update DB to add project user role, project id: %d, user id: %d, role id: %d", projectID, userID, rid) pma.RenderError(http.StatusInternalServerError, "Failed to update data in database") return } } }
// Delete ... func (ua *UserAPI) Delete() { if !ua.IsAdmin { log.Warningf("current user, id: %d does not have admin role, can not remove user", ua.currentUserID) ua.RenderError(http.StatusForbidden, "User does not have admin role") return } var err error err = dao.DeleteUser(ua.userID) if err != nil { log.Errorf("Failed to delete data from database, error: %v", err) ua.RenderError(http.StatusInternalServerError, "Failed to delete User") return } }
// Put ... func (pma *ProjectMemberAPI) Put() { currentUserID := pma.currentUserID pid := pma.project.ProjectID if !hasProjectAdminRole(currentUserID, pid) { log.Warningf("Current user, id: %d does not have project admin role for project, id:", currentUserID, pid) pma.RenderError(http.StatusForbidden, "") return } mid := pma.memberID var req memberReq pma.DecodeJSONReq(&req) roleList, err := dao.GetUserProjectRoles(mid, pid) if len(roleList) == 0 { log.Warningf("User is not in project, user id: %d, project id: %d", mid, pid) pma.RenderError(http.StatusNotFound, "user not exist in project") return } //TODO: delete and insert should in one transaction //delete user project role record for the given user err = dao.DeleteProjectMember(pid, mid) if err != nil { log.Errorf("Failed to delete project roles for user, user id: %d, project id: %d, error: %v", mid, pid, err) pma.RenderError(http.StatusInternalServerError, "Failed to update data in DB") return } //insert roles in request for _, rid := range req.Roles { err = dao.AddProjectMember(pid, mid, int(rid)) if err != nil { log.Errorf("Failed to update DB to add project user role, project id: %d, user id: %d, role id: %d", pid, mid, rid) pma.RenderError(http.StatusInternalServerError, "Failed to update data in database") return } } }
// Delete ... func (pma *ProjectMemberAPI) Delete() { currentUserID := pma.currentUserID pid := pma.project.ProjectID if !hasProjectAdminRole(currentUserID, pid) { log.Warningf("Current user, id: %d does not have project admin role for project, id:", currentUserID, pid) pma.RenderError(http.StatusForbidden, "") return } mid := pma.memberID err := dao.DeleteProjectMember(pid, mid) if err != nil { log.Errorf("Failed to delete project roles for user, user id: %d, project id: %d, error: %v", mid, pid, err) pma.RenderError(http.StatusInternalServerError, "Failed to update data in DB") return } }
// Get renders user's navigation details header func (ndc *NavigationDetailController) Get() { sessionUserID := ndc.GetSession("userId") var isAdmin int if sessionUserID != nil { userID := sessionUserID.(int) u, err := dao.GetUser(models.User{UserID: userID}) if err != nil { log.Errorf("Error occurred in GetUser, error: %v", err) ndc.CustomAbort(http.StatusInternalServerError, "Internal error.") } if u == nil { log.Warningf("User was deleted already, user id: %d, canceling request.", userID) ndc.CustomAbort(http.StatusUnauthorized, "") } isAdmin = u.HasAdminRole } ndc.Data["IsAdmin"] = isAdmin ndc.TplName = "navigation-detail.htm" ndc.Render() }
// Get ... func (pma *ProjectMemberAPI) Get() { pid := pma.project.ProjectID if !checkProjectPermission(pma.currentUserID, pid) { log.Warningf("Current user, user id: %d does not have permission for project, id: %d", pma.currentUserID, pid) pma.RenderError(http.StatusForbidden, "") return } if pma.memberID == 0 { //member id not set return list of the members username := pma.GetString("username") queryUser := models.User{Username: "******" + username + "%"} userList, err := dao.GetUserByProject(pid, queryUser) if err != nil { log.Errorf("Failed to query database for member list, error: %v", err) pma.RenderError(http.StatusInternalServerError, "Internal Server Error") return } pma.Data["json"] = userList } else { //return detail of a member roleList, err := listRoles(pma.memberID, pid) if err != nil { log.Errorf("Error occurred in GetUserProjectRoles, error: %v", err) pma.CustomAbort(http.StatusInternalServerError, "Internal error.") } //return empty role list to indicate if a user is not a member result := make(map[string]interface{}) user, err := dao.GetUser(models.User{UserID: pma.memberID}) if err != nil { log.Errorf("Error occurred in GetUser, error: %v", err) pma.CustomAbort(http.StatusInternalServerError, "Internal error.") } result["username"] = user.Username result["user_id"] = pma.memberID result["roles"] = roleList pma.Data["json"] = result } pma.ServeJSON() }
//Get renders sign_in page func (sic *SignInController) Get() { sessionUserID := sic.GetSession("userId") var hasLoggedIn bool var username string if sessionUserID != nil { hasLoggedIn = true userID := sessionUserID.(int) u, err := dao.GetUser(models.User{UserID: userID}) if err != nil { log.Errorf("Error occurred in GetUser, error: %v", err) sic.CustomAbort(http.StatusInternalServerError, "Internal error.") } if u == nil { log.Warningf("User was deleted already, user id: %d, canceling request.", userID) sic.CustomAbort(http.StatusUnauthorized, "") } username = u.Username } sic.Data["AuthMode"] = sic.AuthMode sic.Data["Username"] = username sic.Data["HasLoggedIn"] = hasLoggedIn sic.TplName = "sign-in.htm" sic.Render() }
// Get renders optional menu, Admin user has "Add User" menu func (omc *OptionalMenuController) Get() { sessionUserID := omc.GetSession("userId") var hasLoggedIn bool var allowAddNew bool if sessionUserID != nil { hasLoggedIn = true userID := sessionUserID.(int) u, err := dao.GetUser(models.User{UserID: userID}) if err != nil { log.Errorf("Error occurred in GetUser, error: %v", err) omc.CustomAbort(http.StatusInternalServerError, "Internal error.") } if u == nil { log.Warningf("User was deleted already, user id: %d, canceling request.", userID) omc.CustomAbort(http.StatusUnauthorized, "") } omc.Data["Username"] = u.Username isAdmin, err := dao.IsAdminRole(sessionUserID.(int)) if err != nil { log.Errorf("Error occurred in IsAdminRole: %v", err) omc.CustomAbort(http.StatusInternalServerError, "") } if isAdmin && omc.AuthMode == "db_auth" { allowAddNew = true } } omc.Data["AddNew"] = allowAddNew omc.Data["HasLoggedIn"] = hasLoggedIn omc.TplName = "optional-menu.htm" omc.Render() }
// Get ... func (ra *RepositoryAPI) Get() { projectID, err := ra.GetInt64("project_id") if err != nil { log.Errorf("Failed to get project id, error: %v", err) ra.RenderError(http.StatusBadRequest, "Invalid project id") return } p, err := dao.GetProjectByID(projectID) if err != nil { log.Errorf("Error occurred in GetProjectById, error: %v", err) ra.CustomAbort(http.StatusInternalServerError, "Internal error.") } if p == nil { log.Warningf("Project with Id: %d does not exist", projectID) ra.RenderError(http.StatusNotFound, "") return } if p.Public == 0 { var userID int if svc_utils.VerifySecret(ra.Ctx.Request) { userID = 1 } else { userID = ra.ValidateUser() } if !checkProjectPermission(userID, projectID) { ra.RenderError(http.StatusForbidden, "") return } } repoList, err := cache.GetRepoFromCache() if err != nil { log.Errorf("Failed to get repo from cache, error: %v", err) ra.RenderError(http.StatusInternalServerError, "internal sever error") } projectName := p.Name q := ra.GetString("q") var resp []string if len(q) > 0 { for _, r := range repoList { if strings.Contains(r, "/") && strings.Contains(r[strings.LastIndex(r, "/")+1:], q) && r[0:strings.LastIndex(r, "/")] == projectName { resp = append(resp, r) } } ra.Data["json"] = resp } else if len(projectName) > 0 { for _, r := range repoList { if strings.Contains(r, "/") && r[0:strings.LastIndex(r, "/")] == projectName { resp = append(resp, r) } } ra.Data["json"] = resp } else { ra.Data["json"] = repoList } ra.ServeJSON() }