private void deploy(final Job job, final String host) throws Exception { Futures.addCallback(client.deploy(Deployment.of(job.getId(), START), host), new FutureCallback<JobDeployResponse>() { @Override public void onSuccess(final JobDeployResponse result) { assertEquals(JobDeployResponse.Status.OK, result.getStatus()); } @Override public void onFailure(@NotNull final Throwable th) { fail("deploy failed"); } }, MoreExecutors.directExecutor()); }
/** * Used to update the existing deployment of a job. */ @Override public void updateDeployment(final String host, final Deployment deployment, final String token) throws HostNotFoundException, JobNotDeployedException, TokenVerificationException { log.info("updating deployment {}: {}", deployment, host); final ZooKeeperClient client = provider.get("updateDeployment"); final JobId jobId = deployment.getJobId(); final Job job = getJob(client, jobId); final Deployment existingDeployment = getDeployment(host, jobId); if (job == null) { throw new JobNotDeployedException(host, jobId); } verifyToken(token, job); assertHostExists(client, host); assertTaskExists(client, host, deployment.getJobId()); final String path = Paths.configHostJob(host, jobId); final Task task = new Task(job, deployment.getGoal(), existingDeployment.getDeployerUser(), existingDeployment.getDeployerMaster(), existingDeployment.getDeploymentGroupName()); try { client.setData(path, task.toJsonBytes()); } catch (Exception e) { throw new HeliosRuntimeException("updating deployment " + deployment + " on host " + host + " failed", e); } }
public Deployment build() { return new Deployment(jobId, goal, deployerUser, deployerMaster, deploymentGroupName); } }
final DeploymentGroup deploymentGroup) { if (!Objects.equals(deployment.getDeploymentGroupName(), deploymentGroup.getName())) { return false; if (!deployment.getJobId().equals(deploymentGroup.getJobId())) { return false; if (!Goal.START.equals(deployment.getGoal())) { return false;
public void task(final JobId jobId, final String host, final TaskStatus ts, final Deployment deployment) { final String goal = (deployment == null) ? "" : deployment.getGoal().toString(); final int maxContainerId = full ? Integer.MAX_VALUE : 7; final String jobIdString = full ? jobId.toString() : jobId.toShortString(); if (ts == null) { table.row(jobIdString, host, goal, "", "", ""); } else { final List<String> portMappings = new ArrayList<>(); for (final Map.Entry<String, PortMapping> entry : ts.getPorts().entrySet()) { final PortMapping portMapping = entry.getValue(); portMappings.add(String.format("%s=%d:%d", entry.getKey(), portMapping.getInternalPort(), portMapping.getExternalPort())); } String state = ts.getState().toString(); if (ts.getThrottled() != ThrottleState.NO) { state += " (" + ts.getThrottled() + ")"; } final String ports = Joiner.on(" ").join(portMappings); final String cid = truncate(fromNullable(ts.getContainerId()).or(""), maxContainerId, ""); table.row(jobIdString, host, goal, state, cid, ports); } }
private boolean ownedByDeploymentGroup(final Deployment deployment, final DeploymentGroup deploymentGroup) { return Objects.equals(deployment.getDeploymentGroupName(), deploymentGroup.getName()); }
public ListenableFuture<JobDeployResponse> deploy(final Deployment job, final String host, final String token) { final Set<Integer> deserializeReturnCodes = ImmutableSet.of(HTTP_OK, HTTP_NOT_FOUND, HTTP_BAD_METHOD, HTTP_BAD_REQUEST, HTTP_FORBIDDEN); return transformAsync(request(uri(path("/hosts/%s/jobs/%s", host, job.getJobId()), ImmutableMap.of("token", token)), "PUT", job), ConvertResponseToPojo.create(JobDeployResponse.class, deserializeReturnCodes), MoreExecutors.directExecutor()); }
@Test public void testRollingUpdateCoordination() throws Exception { // stop the default master master.stopAsync().awaitTerminated(); // start a bunch of masters and agents final Map<String, MasterMain> masters = startDefaultMasters(3); final Map<String, AgentMain> agents = Maps.newLinkedHashMap(); for (int i = 0; i < 20; i++) { final String name = TEST_HOST + i; agents.put(name, startDefaultAgent(name, "--labels", TEST_LABEL)); } // create a deployment group and start rolling out cli("create-deployment-group", "--json", TEST_GROUP, TEST_LABEL); final JobId jobId = createJob(testJobName, testJobVersion, BUSYBOX, IDLE_COMMAND); cli("rolling-update", "--async", "--par", String.valueOf(agents.size()), testJobNameAndVersion, TEST_GROUP); // wait until the task is running on the final agent awaitTaskState(jobId, getLast(agents.keySet()), TaskStatus.State.RUNNING); // ensure that all masters were involved final Set<String> deployingMasters = Sets.newHashSet(); final Map<String, HostStatus> hostStatuses = defaultClient().hostStatuses( Lists.newArrayList(agents.keySet())).get(); for (final HostStatus status : hostStatuses.values()) { for (final Deployment deployment : status.getJobs().values()) { deployingMasters.add(deployment.getDeployerMaster()); } } assertEquals(masters.size(), deployingMasters.size()); }
final Deployment actualDeployment = deployment.toBuilder().setDeployerUser(username).build(); model.deployJob(host, actualDeployment, token); return new JobDeployResponse(JobDeployResponse.Status.OK, host, jobId);
private RollingUpdateTaskResult rollingUpdateUndeploy(final DeploymentGroup deploymentGroup, final String host) { final ZooKeeperClient client = provider.get("rollingUpdateUndeploy"); final List<ZooKeeperOperation> operations = Lists.newArrayList(); for (final Deployment deployment : getTasks(client, host).values()) { final boolean isOwnedByDeploymentGroup = Objects.equals( deployment.getDeploymentGroupName(), deploymentGroup.getName()); final boolean isSameJob = deployment.getJobId().equals(deploymentGroup.getJobId()); if (isOwnedByDeploymentGroup || ( isSameJob && deploymentGroup.getRolloutOptions().getMigrate())) { if (isSameJob && isOwnedByDeploymentGroup && deployment.getGoal().equals(Goal.START)) { // The job we want deployed is already deployed and set to run, so just leave it. continue; } try { operations.addAll(getUndeployOperations(client, host, deployment.getJobId(), Job.EMPTY_TOKEN)); } catch (TokenVerificationException | HostNotFoundException e) { return RollingUpdateTaskResult.error(e, host); } catch (JobNotDeployedException e) { // probably somebody beat us to the punch of undeploying. that's fine. } } } return RollingUpdateTaskResult.of(operations); }
@Test public void testMaster() throws Exception { final JobId jobId = createAndAwaitJobRunning(); // shut down the agent so it cannot remove the tombstone we make agent.stopAsync().awaitTerminated(); // make sure things look correct before assertFalse(zkMasterModel.getJobs().isEmpty()); assertEquals(START, zkMasterModel.getDeployment(TEST_HOST, jobId).getGoal()); // undeploy job client.undeploy(jobId, TEST_HOST).get(); // These used to be filtered away assertNull(zkMasterModel.getDeployment(TEST_HOST, jobId)); assertTrue(zkMasterModel.getHostStatus(TEST_HOST).getJobs().isEmpty()); }
@Override public String call() throws Exception { final Deployment deployment = defaultClient().hostStatus(host).get().getJobs().get(jobId); if (deployment != null && !isNullOrEmpty(deployment.getDeploymentGroupName())) { return deployment.getDeploymentGroupName(); } else { return null; } } });
public ListenableFuture<SetGoalResponse> setGoal(final Deployment job, final String host, final String token) { return transformAsync(request(uri(path("/hosts/%s/jobs/%s", host, job.getJobId()), ImmutableMap.of("token", token)), "PATCH", job), ConvertResponseToPojo.create(SetGoalResponse.class, ImmutableSet.of(HTTP_OK, HTTP_NOT_FOUND, HTTP_FORBIDDEN)), MoreExecutors.directExecutor()); }
final Deployment actualDeployment = deployment.toBuilder().setDeployerUser(username).build(); model.deployJob(host, actualDeployment, token); return new JobDeployResponse(JobDeployResponse.Status.OK, host, jobId);
HostNotFoundException, JobPortAllocationConflictException { assertHostExists(client, host); final JobId id = deployment.getJobId(); final Job job = getJob(id); final Task task = new Task(job, deployment.getGoal(), deployment.getDeployerUser(), deployment.getDeployerMaster(), deployment.getDeploymentGroupName()); final List<ZooKeeperOperation> operations = Lists.newArrayList( check(jobPath),
private JobId createAndAwaitJobRunning() throws Exception { final CreateJobResponse jobby = client.createJob(job).get(); assertEquals(CreateJobResponse.Status.OK, jobby.getStatus()); final JobId jobId = job.getId(); final JobDeployResponse deployResponse = client.deploy( Deployment.of(jobId, START), TEST_HOST).get(); assertEquals(JobDeployResponse.Status.OK, deployResponse.getStatus()); awaitJobState(client, TEST_HOST, jobId, State.RUNNING, 30, TimeUnit.SECONDS); return jobId; }
defaultClient().hostStatus(host).get().getJobs().get(manualJobId); assertNotNull(manualDeployment); assertEquals(Goal.START, manualDeployment.getGoal());
@Override public String call() throws Exception { final Deployment deployment = defaultClient().hostStatus(host).get().getJobs().get(jobId); if (deployment != null && !isNullOrEmpty(deployment.getDeploymentGroupName())) { return deployment.getDeploymentGroupName(); } else { return null; } } });
private boolean isMigration(final Deployment deployment, final DeploymentGroup deploymentGroup) { return (deploymentGroup.getRolloutOptions() != null && TRUE.equals(deploymentGroup.getRolloutOptions().getMigrate()) && deployment.getJobId().equals(deploymentGroup.getJobId())); }
@Test public void testNoIntOnExit() throws Exception { startDefaultMaster(); final String host = testHost(); startDefaultAgent(host); final HeliosClient client = defaultClient(); awaitHostStatus(client, host, UP, LONG_WAIT_SECONDS, SECONDS); // Note: signal 2 is SIGINT final Job jobToInterrupt = Job.newBuilder() .setName(testJobName) .setVersion(testJobVersion) .setImage(BUSYBOX) .setCommand(asList("/bin/sh", "-c", "trap handle 2; handle() { echo int; exit 0; }; " + "while true; do sleep 1; done")) .build(); final JobId jobId = createJob(jobToInterrupt); deployJob(jobId, host); awaitTaskState(jobId, host, RUNNING); client.setGoal(new Deployment(jobId, Goal.STOP, Deployment.EMTPY_DEPLOYER_USER, Deployment.EMPTY_DEPLOYER_MASTER, Deployment.EMPTY_DEPLOYMENT_GROUP_NAME), host); final TaskStatus taskStatus = awaitTaskState(jobId, host, STOPPED); final String log; try (final DockerClient dockerClient = getNewDockerClient(); LogStream logs = dockerClient.logs(taskStatus.getContainerId(), stdout())) { log = logs.readFully(); } // No message expected, since SIGINT should not be sent assertEquals("", log); }