示例#1
0
文件: scans.go 项目: iwarsong/bearded
func (m *ScanManager) UpdateSession(sc *scan.Scan, obj *scan.Session) error {
	var index *int
	isRootSession := !obj.HasParent()
	if isRootSession {
		// find session indx for updating, but only for root session
		for i, s := range sc.Sessions {
			if s.Id == obj.Id {
				index = &i
				break
			}
		}
	}
	if isRootSession && index == nil {
		return mgo.ErrNotFound
	}
	now := time.Now().UTC()
	switch st := obj.Status; true {
	case st == scan.StatusQueued:
		if obj.Queued == nil {
			obj.Queued = &now
		}
	case st == scan.StatusFinished || st == scan.StatusFailed:
		if obj.Finished == nil {
			obj.Finished = &now
		}
	case st == scan.StatusWorking:
		if obj.Started == nil {
			obj.Started = &now
		}
	}

	scanModified := false

	// only root sessions have influence on scan
	if isRootSession {
		// if session is queued then scan should also be queued
		if obj.Status == scan.StatusQueued && (sc.Status == scan.StatusCreated || sc.Status == scan.StatusWorking) {
			sc.Status = scan.StatusQueued
			scanModified = true
		}

		// if session is working then scan should also be working
		if obj.Status == scan.StatusWorking && (sc.Status != scan.StatusWorking) {
			sc.Status = scan.StatusWorking
			scanModified = true
		}

		// if session failed then scan should be failed too
		if obj.Status == scan.StatusFailed {
			sc.Status = scan.StatusFailed
			scanModified = true
		}
		// if session was the last one
		if obj.Status == scan.StatusFinished && (*index+1) == len(sc.Sessions) {
			sc.Status = scan.StatusFinished
			scanModified = true
		}
	}

	// if scan modified then update the whole scan object
	if scanModified || !isRootSession {
		return m.Update(sc)
	}

	// TODO (m0sth8): update non root session with set
	key := fmt.Sprintf("sessions.%d", *index)
	update := bson.M{"$set": bson.M{key: obj, "updated": now}}
	m.col.UpdateId(sc.Id, update)
	return m.Update(sc)
}