func (h *DesiredLRPHandler) DesireDesiredLRP_r0(w http.ResponseWriter, req *http.Request) { logger := h.logger.Session("desire-lrp") request := &models.DesireLRPRequest{} response := &models.DesiredLRPLifecycleResponse{} defer func() { exitIfUnrecoverable(logger, h.exitChan, response.Error) }() defer writeResponse(w, response) err := parseRequestForDesireDesiredLRP_r0(logger, req, request) if err != nil { response.Error = models.ConvertError(err) return } err = h.desiredLRPDB.DesireLRP(logger, request.DesiredLrp) if err != nil { response.Error = models.ConvertError(err) return } desiredLRP, err := h.desiredLRPDB.DesiredLRPByProcessGuid(logger, request.DesiredLrp.ProcessGuid) if err != nil { response.Error = models.ConvertError(err) return } go h.desiredHub.Emit(models.NewDesiredLRPCreatedEvent(desiredLRP)) schedulingInfo := request.DesiredLrp.DesiredLRPSchedulingInfo() h.startInstanceRange(logger, 0, schedulingInfo.Instances, &schedulingInfo) }
func (h *TaskHandler) CompleteTask(w http.ResponseWriter, req *http.Request) { var err error logger := h.logger.Session("complete-task") request := &models.CompleteTaskRequest{} response := &models.TaskLifecycleResponse{} defer func() { exitIfUnrecoverable(logger, h.exitChan, response.Error) }() defer writeResponse(w, response) err = parseRequest(logger, req, request) if err != nil { response.Error = models.ConvertError(err) return } task, err := h.db.CompleteTask(logger, request.TaskGuid, request.CellId, request.Failed, request.FailureReason, request.Result) if err != nil { response.Error = models.ConvertError(err) return } if task.CompletionCallbackUrl != "" { logger.Info("task-client-completing-task") go h.taskCompletionClient.Submit(h.db, task) } }
func (db *serviceClient) Cells(logger lager.Logger) (models.CellSet, error) { kvPairs, _, err := db.consulClient.KV().List(CellSchemaRoot(), nil) if err != nil { bbsErr := models.ConvertError(convertConsulError(err)) if bbsErr.Type != models.Error_ResourceNotFound { return nil, bbsErr } } if kvPairs == nil { err = consuladapter.NewPrefixNotFoundError(CellSchemaRoot()) bbsErr := models.ConvertError(convertConsulError(err)) if bbsErr.Type != models.Error_ResourceNotFound { return nil, bbsErr } } cellPresences := models.NewCellSet() for _, kvPair := range kvPairs { if kvPair.Session == "" { continue } cell := kvPair.Value presence := new(models.CellPresence) err := models.FromJSON(cell, presence) if err != nil { logger.Error("failed-to-unmarshal-cells-json", err) continue } cellPresences.Add(presence) } return cellPresences, nil }
func (h *ActualLRPLifecycleHandler) StartActualLRP(w http.ResponseWriter, req *http.Request) { var err error logger := h.logger.Session("start-actual-lrp") request := &models.StartActualLRPRequest{} response := &models.ActualLRPLifecycleResponse{} defer func() { exitIfUnrecoverable(logger, h.exitChan, response.Error) }() defer writeResponse(w, response) err = parseRequest(logger, req, request) if err != nil { response.Error = models.ConvertError(err) return } before, after, err := h.db.StartActualLRP(logger, request.ActualLrpKey, request.ActualLrpInstanceKey, request.ActualLrpNetInfo) if err != nil { response.Error = models.ConvertError(err) return } if before == nil { go h.actualHub.Emit(models.NewActualLRPCreatedEvent(after)) } else if !before.Equal(after) { go h.actualHub.Emit(models.NewActualLRPChangedEvent(before, after)) } }
func (h *ActualLRPLifecycleHandler) ClaimActualLRP(w http.ResponseWriter, req *http.Request) { var err error logger := h.logger.Session("claim-actual-lrp") request := &models.ClaimActualLRPRequest{} response := &models.ActualLRPLifecycleResponse{} defer func() { exitIfUnrecoverable(logger, h.exitChan, response.Error) }() defer writeResponse(w, response) err = parseRequest(logger, req, request) if err != nil { response.Error = models.ConvertError(err) return } before, after, err := h.db.ClaimActualLRP(logger, request.ProcessGuid, request.Index, request.ActualLrpInstanceKey) if err != nil { response.Error = models.ConvertError(err) return } if !after.Equal(before) { go h.actualHub.Emit(models.NewActualLRPChangedEvent(before, after)) } }
func (h *TaskHandler) DesireTask(w http.ResponseWriter, req *http.Request) { var err error logger := h.logger.Session("desire-task") request := &models.DesireTaskRequest{} response := &models.TaskLifecycleResponse{} defer func() { exitIfUnrecoverable(logger, h.exitChan, response.Error) }() defer writeResponse(w, response) err = parseRequest(logger, req, request) if err != nil { response.Error = models.ConvertError(err) return } logger = logger.WithData(lager.Data{"task_guid": request.TaskGuid}) err = h.db.DesireTask(logger, request.TaskDefinition, request.TaskGuid, request.Domain) if err != nil { response.Error = models.ConvertError(err) return } logger.Debug("start-task-auction-request") taskStartRequest := auctioneer.NewTaskStartRequestFromModel(request.TaskGuid, request.Domain, request.TaskDefinition) err = h.auctioneerClient.RequestTaskAuctions([]*auctioneer.TaskStartRequest{&taskStartRequest}) if err != nil { logger.Error("failed-requesting-task-auction", err) // The creation succeeded, the auction request error can be dropped } else { logger.Debug("succeeded-requesting-task-auction") } }
func (h *ActualLRPLifecycleHandler) RemoveActualLRP(w http.ResponseWriter, req *http.Request) { var err error logger := h.logger.Session("remove-actual-lrp") request := &models.RemoveActualLRPRequest{} response := &models.ActualLRPLifecycleResponse{} defer func() { exitIfUnrecoverable(logger, h.exitChan, response.Error) }() defer writeResponse(w, response) err = parseRequest(logger, req, request) if err != nil { response.Error = models.ConvertError(err) return } beforeActualLRPGroup, err := h.db.ActualLRPGroupByProcessGuidAndIndex(logger, request.ProcessGuid, request.Index) if err != nil { response.Error = models.ConvertError(err) return } err = h.db.RemoveActualLRP(logger, request.ProcessGuid, request.Index, request.ActualLrpInstanceKey) if err != nil { response.Error = models.ConvertError(err) return } go h.actualHub.Emit(models.NewActualLRPRemovedEvent(beforeActualLRPGroup)) }
func (h *TaskHandler) ConvergeTasks(w http.ResponseWriter, req *http.Request) { var err error logger := h.logger.Session("converge-tasks") request := &models.ConvergeTasksRequest{} response := &models.ConvergeTasksResponse{} defer func() { exitIfUnrecoverable(logger, h.exitChan, response.Error) }() defer writeResponse(w, response) err = parseRequest(logger, req, request) if err != nil { response.Error = models.ConvertError(err) } logger.Debug("listing-cells") cellSet, err := h.serviceClient.Cells(logger) if err == models.ErrResourceNotFound { logger.Debug("no-cells-found") cellSet = models.CellSet{} } else if err != nil { logger.Debug("failed-listing-cells") response.Error = models.ConvertError(err) return } logger.Debug("succeeded-listing-cells") tasksToAuction, tasksToComplete := h.db.ConvergeTasks( logger, cellSet, time.Duration(request.KickTaskDuration), time.Duration(request.ExpirePendingTaskDuration), time.Duration(request.ExpireCompletedTaskDuration), ) if len(tasksToAuction) > 0 { logger.Debug("requesting-task-auctions", lager.Data{"num_tasks_to_auction": len(tasksToAuction)}) if err := h.auctioneerClient.RequestTaskAuctions(tasksToAuction); err != nil { taskGuids := make([]string, len(tasksToAuction)) for i, task := range tasksToAuction { taskGuids[i] = task.TaskGuid } logger.Error("failed-to-request-auctions-for-pending-tasks", err, lager.Data{"task_guids": taskGuids}) } logger.Debug("done-requesting-task-auctions", lager.Data{"num_tasks_to_auction": len(tasksToAuction)}) } logger.Debug("submitting-tasks-to-be-completed", lager.Data{"num_tasks_to_complete": len(tasksToComplete)}) for _, task := range tasksToComplete { h.taskCompletionClient.Submit(h.db, task) } logger.Debug("done-submitting-tasks-to-be-completed", lager.Data{"num_tasks_to_complete": len(tasksToComplete)}) }
func (db *ETCDDB) UnclaimActualLRP(logger lager.Logger, key *models.ActualLRPKey) (*models.ActualLRPGroup, *models.ActualLRPGroup, error) { actualLRP, modifiedIndex, err := db.rawActualLRPByProcessGuidAndIndex(logger, key.ProcessGuid, key.Index) bbsErr := models.ConvertError(err) if bbsErr != nil { return nil, nil, bbsErr } beforeActualLRP := *actualLRP if actualLRP.State == models.ActualLRPStateUnclaimed { logger.Debug("already-unclaimed") return nil, nil, models.ErrActualLRPCannotBeUnclaimed } actualLRP.State = models.ActualLRPStateUnclaimed actualLRP.ActualLRPKey = *key actualLRP.ActualLRPInstanceKey = models.ActualLRPInstanceKey{} actualLRP.ActualLRPNetInfo = models.EmptyActualLRPNetInfo() actualLRP.Since = db.clock.Now().UnixNano() actualLRP.ModificationTag.Increment() data, err := db.serializeModel(logger, actualLRP) if err != nil { return nil, nil, err } _, err = db.client.CompareAndSwap(ActualLRPSchemaPath(key.ProcessGuid, key.Index), data, 0, modifiedIndex) if err != nil { logger.Error("failed-compare-and-swap", err) return nil, nil, ErrorFromEtcdError(logger, err) } return &models.ActualLRPGroup{Instance: &beforeActualLRP}, &models.ActualLRPGroup{Instance: actualLRP}, nil }
func (h *StopAppHandler) StopApp(resp http.ResponseWriter, req *http.Request) { processGuid := req.FormValue(":process_guid") logger := h.logger.Session("stop-app", lager.Data{"process-guid": processGuid}) if processGuid == "" { logger.Error("missing-process-guid", missingParameterErr) resp.WriteHeader(http.StatusBadRequest) return } logger.Info("stop-request-from-cc", lager.Data{"processGuid": processGuid}) err := h.bbsClient.RemoveDesiredLRP(processGuid) if err != nil { logger.Error("failed-to-delete-desired-lrp", err) bbsError := models.ConvertError(err) if bbsError.Type == models.Error_ResourceNotFound { resp.WriteHeader(http.StatusNotFound) return } resp.WriteHeader(http.StatusServiceUnavailable) return } resp.WriteHeader(http.StatusAccepted) }
func (m Encryptor) Run(signals <-chan os.Signal, ready chan<- struct{}) error { logger := m.logger.Session("encryptor") currentEncryptionKey, err := m.db.EncryptionKeyLabel(logger) if err != nil { if models.ConvertError(err) != models.ErrResourceNotFound { return err } } else { if m.keyManager.DecryptionKey(currentEncryptionKey) == nil { return errors.New("Existing encryption key version (" + currentEncryptionKey + ") is not among the known keys") } } close(ready) if currentEncryptionKey != m.keyManager.EncryptionKey().Label() { encryptionStart := m.clock.Now() logger.Debug("encryption-started") m.performEncryption(logger) m.db.SetEncryptionKeyLabel(logger, m.keyManager.EncryptionKey().Label()) totalTime := m.clock.Since(encryptionStart) logger.Debug("encryption-finished", lager.Data{"total-time": totalTime}) encryptionDuration.Send(totalTime) } select { case <-signals: return nil } }
func (h *DesiredLRPHandler) DesiredLRPs_r1(w http.ResponseWriter, req *http.Request) { var err error logger := h.logger.Session("desired-lrps", lager.Data{"revision": 0}) request := &models.DesiredLRPsRequest{} response := &models.DesiredLRPsResponse{} err = parseRequest(logger, req, request) if err == nil { var lrps []*models.DesiredLRP filter := models.DesiredLRPFilter{Domain: request.Domain} lrps, err = h.desiredLRPDB.DesiredLRPs(logger, filter) if err == nil { for i := range lrps { transformedLRP := lrps[i].VersionDownTo(format.V1) response.DesiredLrps = append(response.DesiredLrps, transformedLRP) } } } response.Error = models.ConvertError(err) writeResponse(w, response) exitIfUnrecoverable(logger, h.exitChan, response.Error) }
func (p *taskProcessor) completeTask(logger lager.Logger, container executor.Container) { var result string var err error if !container.RunResult.Failed { result, err = p.containerDelegate.FetchContainerResultFile(logger, container.Guid, container.Tags[rep.ResultFileTag]) if err != nil { p.failTask(logger, container.Guid, TaskCompletionReasonFailedToFetchResult) return } } logger.Info("completing-task") err = p.bbsClient.CompleteTask(container.Guid, p.cellID, container.RunResult.Failed, container.RunResult.FailureReason, result) if err != nil { logger.Error("failed-completing-task", err) bbsErr := models.ConvertError(err) if bbsErr.Type == models.Error_InvalidStateTransition { p.failTask(logger, container.Guid, TaskCompletionReasonInvalidTransition) } return } logger.Info("succeeded-completing-task") }
func (h *ActualLRPLifecycleHandler) CrashActualLRP(w http.ResponseWriter, req *http.Request) { logger := h.logger.Session("crash-actual-lrp") request := &models.CrashActualLRPRequest{} response := &models.ActualLRPLifecycleResponse{} defer func() { exitIfUnrecoverable(logger, h.exitChan, response.Error) }() defer writeResponse(w, response) err := parseRequest(logger, req, request) if err != nil { response.Error = models.ConvertError(err) return } actualLRPKey := request.ActualLrpKey actualLRPInstanceKey := request.ActualLrpInstanceKey before, after, shouldRestart, err := h.db.CrashActualLRP(logger, actualLRPKey, actualLRPInstanceKey, request.ErrorMessage) if err != nil { response.Error = models.ConvertError(err) return } if shouldRestart { desiredLRP, err := h.desiredLRPDB.DesiredLRPByProcessGuid(logger, actualLRPKey.ProcessGuid) if err != nil { logger.Error("failed-fetching-desired-lrp", err) response.Error = models.ConvertError(err) return } schedInfo := desiredLRP.DesiredLRPSchedulingInfo() startRequest := auctioneer.NewLRPStartRequestFromSchedulingInfo(&schedInfo, int(actualLRPKey.Index)) logger.Info("start-lrp-auction-request", lager.Data{"app_guid": schedInfo.ProcessGuid, "index": int(actualLRPKey.Index)}) err = h.auctioneerClient.RequestLRPAuctions([]*auctioneer.LRPStartRequest{&startRequest}) logger.Info("finished-lrp-auction-request", lager.Data{"app_guid": schedInfo.ProcessGuid, "index": int(actualLRPKey.Index)}) if err != nil { logger.Error("failed-requesting-auction", err) response.Error = models.ConvertError(err) return } } actualLRP, _ := after.Resolve() go h.actualHub.Emit(models.NewActualLRPCrashedEvent(actualLRP)) go h.actualHub.Emit(models.NewActualLRPChangedEvent(before, after)) }
func (h *TaskHandler) CancelTask(w http.ResponseWriter, req *http.Request) { logger := h.logger.Session("cancel-task") request := &models.TaskGuidRequest{} response := &models.TaskLifecycleResponse{} defer func() { exitIfUnrecoverable(logger, h.exitChan, response.Error) }() defer writeResponse(w, response) err := parseRequest(logger, req, request) if err != nil { logger.Error("failed-parsing-request", err) response.Error = models.ConvertError(err) return } task, cellID, err := h.db.CancelTask(logger, request.TaskGuid) if err != nil { response.Error = models.ConvertError(err) return } if task.CompletionCallbackUrl != "" { logger.Info("task-client-completing-task") go h.taskCompletionClient.Submit(h.db, task) } if cellID == "" { return } logger.Info("start-check-cell-presence", lager.Data{"cell_id": cellID}) cellPresence, err := h.serviceClient.CellById(logger, cellID) if err != nil { logger.Error("failed-fetching-cell-presence", err) return } logger.Info("finished-check-cell-presence", lager.Data{"cell_id": cellID}) repClient := h.repClientFactory.CreateClient(cellPresence.RepAddress) logger.Info("start-rep-cancel-task", lager.Data{"task_guid": request.TaskGuid}) repClient.CancelTask(request.TaskGuid) if err != nil { logger.Error("failed-rep-cancel-task", err) return } logger.Info("finished-rep-cancel-task", lager.Data{"task_guid": request.TaskGuid}) }
func (h *DomainHandler) Domains(w http.ResponseWriter, req *http.Request) { var err error logger := h.logger.Session("domains") response := &models.DomainsResponse{} response.Domains, err = h.db.Domains(logger) response.Error = models.ConvertError(err) writeResponse(w, response) }
func (h *ActualLRPLifecycleHandler) RetireActualLRP(w http.ResponseWriter, req *http.Request) { logger := h.logger.Session("retire-actual-lrp") request := &models.RetireActualLRPRequest{} response := &models.ActualLRPLifecycleResponse{} var err error defer func() { exitIfUnrecoverable(logger, h.exitChan, response.Error) }() defer writeResponse(w, response) err = parseRequest(logger, req, request) if err != nil { response.Error = models.ConvertError(err) return } err = h.retirer.RetireActualLRP(logger, request.ActualLrpKey.ProcessGuid, request.ActualLrpKey.Index) response.Error = models.ConvertError(err) }
func (db *ETCDDB) StartActualLRP(logger lager.Logger, key *models.ActualLRPKey, instanceKey *models.ActualLRPInstanceKey, netInfo *models.ActualLRPNetInfo) (*models.ActualLRPGroup, *models.ActualLRPGroup, error) { logger = logger.WithData(lager.Data{ "actual_lrp_key": key, "actual_lrp_instance_key": instanceKey, "net_info": netInfo, }) logger.Info("starting") defer logger.Info("completed") lrp, prevIndex, err := db.rawActualLRPByProcessGuidAndIndex(logger, key.ProcessGuid, key.Index) bbsErr := models.ConvertError(err) if bbsErr != nil { if bbsErr.Type == models.Error_ResourceNotFound { lrp, err := db.createRunningActualLRP(logger, key, instanceKey, netInfo) return nil, &models.ActualLRPGroup{Instance: lrp}, err } logger.Error("failed-to-get-actual-lrp", err) return nil, nil, err } beforeActualLRP := *lrp if lrp.ActualLRPKey.Equal(key) && lrp.ActualLRPInstanceKey.Equal(instanceKey) && lrp.ActualLRPNetInfo.Equal(netInfo) && lrp.State == models.ActualLRPStateRunning { lrpGroup := &models.ActualLRPGroup{Instance: lrp} return lrpGroup, lrpGroup, nil } if !lrp.AllowsTransitionTo(key, instanceKey, models.ActualLRPStateRunning) { logger.Error("failed-to-transition-actual-lrp-to-started", nil) return nil, nil, models.ErrActualLRPCannotBeStarted } lrp.ModificationTag.Increment() lrp.State = models.ActualLRPStateRunning lrp.Since = db.clock.Now().UnixNano() lrp.ActualLRPInstanceKey = *instanceKey lrp.ActualLRPNetInfo = *netInfo lrp.PlacementError = "" lrpData, serializeErr := db.serializeModel(logger, lrp) if serializeErr != nil { return nil, nil, serializeErr } _, err = db.client.CompareAndSwap(ActualLRPSchemaPath(key.ProcessGuid, key.Index), lrpData, 0, prevIndex) if err != nil { logger.Error("failed", err) return nil, nil, models.ErrActualLRPCannotBeStarted } return &models.ActualLRPGroup{Instance: &beforeActualLRP}, &models.ActualLRPGroup{Instance: lrp}, nil }
func (p *ordinaryLRPProcessor) claimLRPContainer(logger lager.Logger, lrpContainer *lrpContainer) bool { err := p.bbsClient.ClaimActualLRP(lrpContainer.ProcessGuid, int(lrpContainer.Index), lrpContainer.ActualLRPInstanceKey) bbsErr := models.ConvertError(err) if err != nil { if bbsErr.Type == models.Error_ActualLRPCannotBeClaimed { p.containerDelegate.DeleteContainer(logger, lrpContainer.Guid) } return false } return true }
func (db *ETCDDB) RetireActualLRP(logger lager.Logger, key *models.ActualLRPKey) error { logger = logger.Session("retire-actual-lrp", lager.Data{"actual_lrp_key": key}) var err error var prevIndex uint64 var lrp *models.ActualLRP processGuid := key.ProcessGuid index := key.Index for i := 0; i < models.RetireActualLRPRetryAttempts; i++ { lrp, prevIndex, err = db.rawActuaLLRPByProcessGuidAndIndex(logger, processGuid, index) if err != nil { break } switch lrp.State { case models.ActualLRPStateUnclaimed, models.ActualLRPStateCrashed: err = db.removeActualLRP(logger, lrp, prevIndex) default: var cell *models.CellPresence key := lrp.ActualLRPKey instanceKey := lrp.ActualLRPInstanceKey cell, err = db.serviceClient.CellById(logger, instanceKey.CellId) if err != nil { bbsErr := models.ConvertError(err) if bbsErr.Type == models.Error_ResourceNotFound { err = db.removeActualLRP(logger, lrp, prevIndex) } err = err break } logger.Info("stopping-lrp-instance", lager.Data{ "actual-lrp-key": key, }) repClient := db.repClientFactory.CreateClient(cell.RepAddress) cellErr := repClient.StopLRPInstance(key, instanceKey) if cellErr != nil { err = models.ErrActualLRPCannotBeStopped } } if err == nil { break } if i+1 < models.RetireActualLRPRetryAttempts { logger.Error("retrying-failed-retire-of-actual-lrp", err, lager.Data{"attempt": i + 1}) } } return err }
func (db *ETCDDB) UpdateDesiredLRP(logger lager.Logger, processGuid string, update *models.DesiredLRPUpdate) error { logger = logger.Session("update-desired-lrp", lager.Data{"process-guid": processGuid}) logger.Info("starting") defer logger.Info("complete") var schedulingInfo *models.DesiredLRPSchedulingInfo var existingInstances int32 var err error for i := 0; i < 2; i++ { var index uint64 schedulingInfo, index, err = db.rawDesiredLRPSchedulingInfo(logger, processGuid) if err != nil { logger.Error("failed-to-fetch-scheduling-info", err) break } existingInstances = schedulingInfo.Instances schedulingInfo.ApplyUpdate(update) err = db.updateDesiredLRPSchedulingInfo(logger, schedulingInfo, index) if err != nil { logger.Error("update-scheduling-info-failed", err) modelErr := models.ConvertError(err) if modelErr != models.ErrResourceConflict { break } // Retry on CAS fail continue } break } if err != nil { return err } switch diff := schedulingInfo.Instances - existingInstances; { case diff > 0: db.startInstanceRange(logger, existingInstances, schedulingInfo.Instances, schedulingInfo) case diff < 0: db.stopInstanceRange(logger, schedulingInfo.Instances, existingInstances, schedulingInfo) case diff == 0: // this space intentionally left blank } return nil }
func (db *ETCDDB) EvacuateActualLRP( logger lager.Logger, lrpKey *models.ActualLRPKey, instanceKey *models.ActualLRPInstanceKey, netInfo *models.ActualLRPNetInfo, ttl uint64, ) (*models.ActualLRPGroup, error) { logger = logger.Session("evacuate-actual-lrp", lager.Data{"process_guid": lrpKey.ProcessGuid, "index": lrpKey.Index}) logger.Debug("starting") defer logger.Debug("complete") node, err := db.fetchRaw(logger, EvacuatingActualLRPSchemaPath(lrpKey.ProcessGuid, lrpKey.Index)) bbsErr := models.ConvertError(err) if bbsErr != nil { if bbsErr.Type == models.Error_ResourceNotFound { return db.createEvacuatingActualLRP(logger, lrpKey, instanceKey, netInfo, ttl) } return nil, bbsErr } lrp := models.ActualLRP{} err = db.deserializeModel(logger, node, &lrp) if err != nil { return nil, err } if lrp.ActualLRPKey.Equal(lrpKey) && lrp.ActualLRPInstanceKey.Equal(instanceKey) && reflect.DeepEqual(lrp.ActualLRPNetInfo, *netInfo) { return &models.ActualLRPGroup{Evacuating: &lrp}, nil } lrp.ActualLRPNetInfo = *netInfo lrp.ActualLRPKey = *lrpKey lrp.ActualLRPInstanceKey = *instanceKey lrp.Since = db.clock.Now().UnixNano() lrp.ModificationTag.Increment() data, err := db.serializeModel(logger, &lrp) if err != nil { logger.Error("failed-serializing", err) return nil, err } _, err = db.client.CompareAndSwap(EvacuatingActualLRPSchemaPath(lrp.ProcessGuid, lrp.Index), data, ttl, node.ModifiedIndex) if err != nil { return nil, ErrorFromEtcdError(logger, err) } return &models.ActualLRPGroup{Evacuating: &lrp}, nil }
func (db *ETCDDB) ActualLRPGroups(logger lager.Logger, filter models.ActualLRPFilter) ([]*models.ActualLRPGroup, error) { node, err := db.fetchRecursiveRaw(logger, ActualLRPSchemaRoot) bbsErr := models.ConvertError(err) if bbsErr != nil { if bbsErr.Type == models.Error_ResourceNotFound { return []*models.ActualLRPGroup{}, nil } return nil, err } if len(node.Nodes) == 0 { return []*models.ActualLRPGroup{}, nil } groups := []*models.ActualLRPGroup{} var workErr atomic.Value groupChan := make(chan []*models.ActualLRPGroup, len(node.Nodes)) wg := sync.WaitGroup{} logger.Debug("performing-deserialization-work") for _, node := range node.Nodes { node := node wg.Add(1) go func() { defer wg.Done() g, err := db.parseActualLRPGroups(logger, node, filter) if err != nil { workErr.Store(err) return } groupChan <- g }() } go func() { wg.Wait() close(groupChan) }() for g := range groupChan { groups = append(groups, g...) } if err, ok := workErr.Load().(error); ok { logger.Error("failed-performing-deserialization-work", err) return []*models.ActualLRPGroup{}, models.ErrUnknownError } logger.Debug("succeeded-performing-deserialization-work", lager.Data{"num_actual_lrp_groups": len(groups)}) return groups, nil }
func (h *DesireAppHandler) getDesiredLRP(processGuid string) (*models.DesiredLRP, error) { lrp, err := h.bbsClient.DesiredLRPByProcessGuid(processGuid) if err == nil { return lrp, nil } bbsError := models.ConvertError(err) if bbsError.Type == models.Error_ResourceNotFound { return nil, nil } return nil, err }
func (h *CellHandler) Cells(w http.ResponseWriter, req *http.Request) { var err error logger := h.logger.Session("cells") response := &models.CellsResponse{} cellSet, err := h.serviceClient.Cells(h.logger) cells := []*models.CellPresence{} for _, cp := range cellSet { cells = append(cells, cp) } response.Cells = cells response.Error = models.ConvertError(err) writeResponse(w, response) exitIfUnrecoverable(logger, h.exitChan, response.Error) }
func (h *EvacuationHandler) EvacuateStoppedActualLRP(w http.ResponseWriter, req *http.Request) { var err error logger := h.logger.Session("evacuate-stopped-actual-lrp") request := &models.EvacuateStoppedActualLRPRequest{} response := &models.EvacuationResponse{} err = parseRequest(logger, req, request) if err == nil { response.KeepContainer, err = h.db.EvacuateStoppedActualLRP(logger, request.ActualLrpKey, request.ActualLrpInstanceKey) } response.Error = models.ConvertError(err) writeResponse(w, response) }
func (db *ETCDDB) desiredLRPs(logger lager.Logger, filter models.DesiredLRPFilter) ([]*models.DesiredLRP, guidSet, error) { root, err := db.fetchRecursiveRaw(logger, DesiredLRPComponentsSchemaRoot) bbsErr := models.ConvertError(err) if bbsErr != nil { if bbsErr.Type == models.Error_ResourceNotFound { return []*models.DesiredLRP{}, newGuidSet(), nil } return nil, newGuidSet(), err } if root.Nodes.Len() == 0 { return []*models.DesiredLRP{}, newGuidSet(), nil } var schedules map[string]*models.DesiredLRPSchedulingInfo var runs map[string]*models.DesiredLRPRunInfo var malformedInfos guidSet var malformedRunInfos guidSet var wg sync.WaitGroup for i := range root.Nodes { node := root.Nodes[i] switch node.Key { case DesiredLRPSchedulingInfoSchemaRoot: wg.Add(1) go func() { defer wg.Done() schedules, malformedInfos = db.deserializeScheduleInfos(logger, node.Nodes, filter) }() case DesiredLRPRunInfoSchemaRoot: wg.Add(1) go func() { defer wg.Done() runs, malformedRunInfos = db.deserializeRunInfos(logger, node.Nodes, filter) }() default: logger.Error("unexpected-etcd-key", nil, lager.Data{"key": node.Key}) } } wg.Wait() desiredLRPs := []*models.DesiredLRP{} for processGuid, schedule := range schedules { desired := models.NewDesiredLRP(*schedule, *runs[processGuid]) desiredLRPs = append(desiredLRPs, &desired) } malformedInfos.Merge(malformedRunInfos) return desiredLRPs, malformedInfos, nil }
func (h *DesiredLRPHandler) DesiredLRPByProcessGuid(w http.ResponseWriter, req *http.Request) { var err error logger := h.logger.Session("desired-lrp-by-process-guid") request := &models.DesiredLRPByProcessGuidRequest{} response := &models.DesiredLRPResponse{} err = parseRequest(logger, req, request) if err == nil { response.DesiredLrp, err = h.db.DesiredLRPByProcessGuid(logger, request.ProcessGuid) } response.Error = models.ConvertError(err) writeResponse(w, response) }
func (db *ETCDDB) ActualLRPGroupsByProcessGuid(logger lager.Logger, processGuid string) ([]*models.ActualLRPGroup, error) { node, err := db.fetchRecursiveRaw(logger, ActualLRPProcessDir(processGuid)) bbsErr := models.ConvertError(err) if bbsErr != nil { if bbsErr.Type == models.Error_ResourceNotFound { return []*models.ActualLRPGroup{}, nil } return nil, err } if node.Nodes.Len() == 0 { return []*models.ActualLRPGroup{}, nil } return db.parseActualLRPGroups(logger, node, models.ActualLRPFilter{}) }
func (h *DesiredLRPHandler) UpdateDesiredLRP(w http.ResponseWriter, req *http.Request) { var err error logger := h.logger.Session("update-desired-lrp") request := &models.UpdateDesiredLRPRequest{} response := &models.DesiredLRPLifecycleResponse{} err = parseRequest(logger, req, request) if err == nil { err = h.db.UpdateDesiredLRP(logger, request.ProcessGuid, request.Update) } response.Error = models.ConvertError(err) writeResponse(w, response) }