use of com.spotify.helios.servicescommon.coordination.ZooKeeperClient in project helios by spotify.
the class ZooKeeperMasterModel method updateDeployment.
/**
* 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);
}
}
use of com.spotify.helios.servicescommon.coordination.ZooKeeperClient in project helios by spotify.
the class ZooKeeperMasterModel method stopDeploymentGroup.
@Override
public void stopDeploymentGroup(final String deploymentGroupName) throws DeploymentGroupDoesNotExistException {
checkNotNull(deploymentGroupName, "name");
log.info("stop deployment-group: name={}", deploymentGroupName);
final ZooKeeperClient client = provider.get("stopDeploymentGroup");
// Delete deployment group tasks (if any) and set DG state to FAILED
final DeploymentGroupStatus status = DeploymentGroupStatus.newBuilder().setState(FAILED).setError("Stopped by user").build();
final String statusPath = Paths.statusDeploymentGroup(deploymentGroupName);
final String tasksPath = Paths.statusDeploymentGroupTasks(deploymentGroupName);
try {
client.ensurePath(Paths.statusDeploymentGroupTasks());
final List<ZooKeeperOperation> operations = Lists.newArrayList();
// NOTE: This remove operation is racey. If tasks exist and the rollout finishes before the
// delete() is executed then this will fail. Conversely, if it doesn't exist but is created
// before the transaction is executed it will also fail. This is annoying for users, but at
// least means we won't have inconsistent state.
//
// That the set() is first in the list of operations is important because of the
// kludgy error checking we do below to disambiguate "doesn't exist" failures from the race
// condition mentioned below.
operations.add(set(statusPath, status));
final Stat tasksStat = client.exists(tasksPath);
if (tasksStat != null) {
operations.add(delete(tasksPath));
} else {
// There doesn't seem to be a "check that node doesn't exist" operation so we
// do a create and a delete on the same path to emulate it.
operations.add(create(tasksPath));
operations.add(delete(tasksPath));
}
client.transaction(operations);
} catch (final NoNodeException e) {
// Yes, the way you figure out which operation in a transaction failed is retarded.
if (((OpResult.ErrorResult) e.getResults().get(0)).getErr() == KeeperException.Code.NONODE.intValue()) {
throw new DeploymentGroupDoesNotExistException(deploymentGroupName);
} else {
throw new HeliosRuntimeException("stop deployment-group " + deploymentGroupName + " failed due to a race condition, please retry", e);
}
} catch (final KeeperException e) {
throw new HeliosRuntimeException("stop deployment-group " + deploymentGroupName + " failed", e);
}
}
use of com.spotify.helios.servicescommon.coordination.ZooKeeperClient in project helios by spotify.
the class ZooKeeperMasterModel method getJobs.
/**
* Returns a {@link Map} of {@link JobId} to {@link Job} objects for all of the jobs known.
*/
@Override
public Map<JobId, Job> getJobs() {
log.debug("getting jobs");
final String folder = Paths.configJobs();
final ZooKeeperClient client = provider.get("getJobs");
try {
final List<String> ids;
try {
ids = client.getChildren(folder);
} catch (NoNodeException e) {
return Maps.newHashMap();
}
final Map<JobId, Job> descriptors = Maps.newHashMap();
for (final String id : ids) {
final JobId jobId = JobId.fromString(id);
final String path = Paths.configJob(jobId);
try {
final byte[] data = client.getData(path);
final Job descriptor = parse(data, Job.class);
descriptors.put(descriptor.getId(), descriptor);
} catch (NoNodeException e) {
// Ignore, the job was deleted before we had a chance to read it.
log.debug("Ignoring deleted job {}", jobId);
}
}
return descriptors;
} catch (KeeperException | IOException e) {
throw new HeliosRuntimeException("getting jobs failed", e);
}
}
use of com.spotify.helios.servicescommon.coordination.ZooKeeperClient in project helios by spotify.
the class ZooKeeperMasterModel method addDeploymentGroup.
/**
* Create a deployment group.
*
* <p>If successful, the following ZK nodes will be created:
* <ul>
* <li>/config/deployment-groups/[group-name]</li>
* <li>/status/deployment-groups/[group-name]</li>
* <li>/status/deployment-groups/[group-name]/hosts</li>
* </ul>
* These nodes are guaranteed to exist until the DG is removed.
*
* <p>If the operation fails no ZK nodes will be created. If any of the nodes above already exist
* the operation will fail.
*
* @throws DeploymentGroupExistsException If a DG with the same name already exists.
*/
@Override
public void addDeploymentGroup(final DeploymentGroup deploymentGroup) throws DeploymentGroupExistsException {
log.info("adding deployment-group: {}", deploymentGroup);
final ZooKeeperClient client = provider.get("addDeploymentGroup");
try {
try {
client.ensurePath(Paths.configDeploymentGroups());
client.ensurePath(Paths.statusDeploymentGroups());
client.transaction(create(Paths.configDeploymentGroup(deploymentGroup.getName()), deploymentGroup), create(Paths.statusDeploymentGroup(deploymentGroup.getName())), create(Paths.statusDeploymentGroupHosts(deploymentGroup.getName()), Json.asBytesUnchecked(emptyList())), create(Paths.statusDeploymentGroupRemovedHosts(deploymentGroup.getName()), Json.asBytesUnchecked(emptyList())));
} catch (final NodeExistsException e) {
throw new DeploymentGroupExistsException(deploymentGroup.getName());
}
} catch (final KeeperException e) {
throw new HeliosRuntimeException("adding deployment-group " + deploymentGroup + " failed", e);
}
}
use of com.spotify.helios.servicescommon.coordination.ZooKeeperClient in project helios by spotify.
the class ZooKeeperMasterModel method getDeploymentGroupHosts.
@Override
public List<String> getDeploymentGroupHosts(final String name) throws DeploymentGroupDoesNotExistException {
log.debug("getting deployment group hosts: {}", name);
final ZooKeeperClient client = provider.get("getDeploymentGroupHosts");
final DeploymentGroup deploymentGroup = getDeploymentGroup(client, name);
if (deploymentGroup == null) {
throw new DeploymentGroupDoesNotExistException(name);
}
return getHosts(client, Paths.statusDeploymentGroupHosts(name));
}
Aggregations