private static List<String> getTaskNames(Collection<Protos.TaskInfo> taskInfos) { return taskInfos.stream() .map(taskInfo -> taskInfo.getName()) .collect(Collectors.toList()); }
private static void killUnneededTasks(StateStore stateStore, Set<String> taskToDeployNames) { Set<Protos.TaskInfo> unneededTaskInfos = stateStore.fetchTasks().stream() .filter(taskInfo -> !taskToDeployNames.contains(taskInfo.getName())) .collect(Collectors.toSet()); Set<Protos.TaskID> taskIdsToKill = unneededTaskInfos.stream() .map(taskInfo -> taskInfo.getTaskId()) .collect(Collectors.toSet()); taskIdsToKill.forEach(taskID -> TaskKiller.killTask(taskID)); }
private void logFailedPod(String failedPodName, List<Protos.TaskInfo> failedTasks) { List<String> permanentlyFailedTasks = failedTasks.stream() .filter(taskInfo -> isTaskPermanentlyFailed(taskInfo)) .map(taskInfo -> taskInfo.getName()) .collect(Collectors.toList()); List<String> transientlyFailedTasks = failedTasks.stream() .filter(taskInfo -> !isTaskPermanentlyFailed(taskInfo)) .map(taskInfo -> taskInfo.getName()) .collect(Collectors.toList()); if (!permanentlyFailedTasks.isEmpty() || !transientlyFailedTasks.isEmpty()) { logger.info("Failed tasks in pod: {}, permanent{}, transient{}", failedPodName, permanentlyFailedTasks, transientlyFailedTasks); } }
@Test public void testInitialPlanTaskError() throws Exception { // Specify TASK_ERROR status for TASK_B and TASK_C. Their exclusive resources should then be omitted from the plan: stateStore.storeTasks(Arrays.asList(TASK_B, TASK_C)); stateStore.storeStatus(TASK_B.getName(), TaskTestUtils.generateStatus(TASK_B.getTaskId(), Protos.TaskState.TASK_ERROR)); stateStore.storeStatus(TASK_C.getName(), TaskTestUtils.generateStatus(TASK_C.getTaskId(), Protos.TaskState.TASK_ERROR)); UninstallScheduler uninstallScheduler = getUninstallScheduler(); // Invoke getClientStatus so that plan status is correctly processed before offers are passed: Assert.assertEquals(ClientStatusResponse.launching(true), uninstallScheduler.getClientStatus()); Plan plan = getUninstallPlan(uninstallScheduler); List<Status> expected = Arrays.asList( Status.PENDING, Status.PENDING, Status.PENDING, // 3 task kills Status.PENDING, Status.PENDING, Status.PENDING, // 3 resources from task A. nothing from task B or C which are ERROR+permfail Status.PENDING); // deregister step Assert.assertEquals(plan.toString(), expected, getStepStatuses(plan)); }
private boolean taskHasReusableExecutor(Protos.TaskInfo taskInfo) { Optional<Protos.TaskStatus> taskStatus = stateStore.fetchStatus(taskInfo.getName()); if (!taskStatus.isPresent() || FailureUtils.isPermanentlyFailed(taskInfo)) { return false; } Protos.TaskState state = taskStatus.get().getState(); switch (state) { case TASK_STAGING: case TASK_STARTING: case TASK_RUNNING: return true; default: return false; } }
private Status getStatus(PodInstance podInstance, Protos.TaskInfo taskInfo, UUID targetConfigId) throws TaskException { GoalState goalState = TaskUtils.getGoalState(podInstance, taskInfo.getName()); boolean hasReachedGoal = hasReachedGoalState(taskInfo, goalState, targetConfigId); boolean hasPermanentlyFailed = FailureUtils.isPermanentlyFailed(taskInfo); // If the task is permanently failed ("pod replace"), its deployment is owned by the recovery plan, not the // deploy plan. The deploy plan can consider it complete until it is no longer marked as failed, at which point // the deploy plan will resume showing it as PENDING deployment. Status status = hasReachedGoal || hasPermanentlyFailed ? Status.COMPLETE : Status.PENDING; LOGGER.info("Deployment of {} task '{}' is {}: hasReachedGoal={} permanentlyFailed={}", goalState, taskInfo.getName(), status, hasReachedGoal, hasPermanentlyFailed); return status; }
private RecoveryType getTaskRecoveryType(Collection<Protos.TaskInfo> taskInfos) { if (taskInfos.stream().allMatch(taskInfo -> isTaskPermanentlyFailed(taskInfo))) { return RecoveryType.PERMANENT; } else if (taskInfos.stream().noneMatch(taskInfo -> isTaskPermanentlyFailed(taskInfo))) { return RecoveryType.TRANSIENT; } else { for (Protos.TaskInfo taskInfo : taskInfos) { RecoveryType recoveryType = isTaskPermanentlyFailed(taskInfo) ? RecoveryType.PERMANENT : RecoveryType.TRANSIENT; logger.info("Task: {} has recovery type: {}", taskInfo.getName(), recoveryType); } return RecoveryType.NONE; } }
@Override protected void processStatusUpdate(Protos.TaskStatus status) throws Exception { stateStore.storeStatus(StateStoreUtils.fetchTaskInfo(stateStore, status).getName(), status); }
/** * Gets the task name. * * @return The name of the task. */ public String getName() { return info.getName(); }
@Override protected void processStatusUpdate(Protos.TaskStatus status) throws Exception { String taskName = StateStoreUtils.fetchTaskInfo(stateStore, status).getName(); stateStore.storeStatus(taskName, status); }
@Override public String toString() { return String.format("%s(%s):%s", taskInfo.getName(), taskInfo.getTaskId().getValue(), status); } }
@Override public Collection<String> getKeys(TaskInfo taskInfo) { if (!taskFilter.matches(taskInfo.getName())) { return Collections.emptyList(); } return new TaskLabelReader(taskInfo).getOfferAttributeStrings().stream() .filter(attribute -> attributeMatcher.matches(attribute)) .collect(Collectors.toList()); }
/** * @see LabelReader#LabelReader(String, Labels) */ @SuppressWarnings("checkstyle:MultipleStringLiterals") public TaskLabelReader(TaskInfo taskInfo) { reader = new LabelReader(String.format("Task %s", taskInfo.getName()), taskInfo.getLabels()); }
/** * WARNING: This is a private method for a reason. Callers must validate that the taskID is already present in the * tasks map. */ private String getTaskName(Protos.TaskID taskID) { return tasks.get(taskID).getTaskInfo().getName(); }
public TriggerDecommissionStep( StateStore stateStore, Protos.TaskInfo taskInfo, Optional<String> namespace) { super("kill-" + taskInfo.getName(), namespace); this.stateStore = stateStore; this.taskInfo = taskInfo; }
private static Collection<Protos.TaskInfo> filterTasksByName(Collection<Protos.TaskInfo> tasks, String... names) { Set<String> namesSet = new HashSet<>(Arrays.asList(names)); return tasks.stream() .filter(t -> namesSet.contains(t.getName())) .collect(Collectors.toList()); } }
@Override public void start() { logger.info("Marking task for decommissioning: {}", taskInfo.getName()); setStatus(Status.IN_PROGRESS); stateStore.storeGoalOverrideStatus( taskInfo.getName(), DecommissionPlanFactory.DECOMMISSIONING_STATUS ); TaskKiller.killTask(taskInfo.getTaskId()); setStatus(Status.COMPLETE); } }
public static Optional<TaskSpec> getTaskSpec(ConfigStore<ServiceSpec> configStore, Protos.TaskInfo taskInfo) throws TaskException { return getTaskSpec(getPodInstance(configStore, taskInfo), taskInfo.getName()); }
private void validateDaemonTaskInfo(Protos.TaskInfo daemonTaskInfo) throws TaskException { Assert.assertEquals(testDaemonName, daemonTaskInfo.getName()); Assert.assertEquals(4, daemonTaskInfo.getResourcesCount()); Assert.assertEquals(testDaemonName, TaskUtils.toTaskName(daemonTaskInfo.getTaskId())); Assert.assertTrue(daemonTaskInfo.getSlaveId().getValue().isEmpty()); for (Protos.Resource resource : daemonTaskInfo.getResourcesList()) { Assert.assertTrue(ResourceUtils.getResourceId(resource).isEmpty()); } }
@Before public void beforeEach() { MockitoAnnotations.initMocks(this); for (TaskInfo taskInfo : TASK_INFOS) { when(mockStateStore.fetchStatus(taskInfo.getName())).thenReturn(Optional.empty()); } }