use of com.spotify.helios.common.descriptors.HostStatus in project helios by spotify.
the class DeploymentGroupResource method getDeploymentGroupStatus.
@GET
@Path("/{name}/status")
@Produces(APPLICATION_JSON)
@Timed
@ExceptionMetered
public Response getDeploymentGroupStatus(@PathParam("name") @Valid final String name) {
try {
final DeploymentGroup deploymentGroup = model.getDeploymentGroup(name);
final DeploymentGroupStatus deploymentGroupStatus = model.getDeploymentGroupStatus(name);
final List<String> hosts = model.getDeploymentGroupHosts(name);
final List<DeploymentGroupStatusResponse.HostStatus> result = Lists.newArrayList();
for (final String host : hosts) {
final HostStatus hostStatus = model.getHostStatus(host);
JobId deployedJobId = null;
TaskStatus.State state = null;
if (hostStatus != null && hostStatus.getStatus().equals(HostStatus.Status.UP)) {
for (final Map.Entry<JobId, Deployment> entry : hostStatus.getJobs().entrySet()) {
if (name.equals(entry.getValue().getDeploymentGroupName())) {
deployedJobId = entry.getKey();
final TaskStatus taskStatus = hostStatus.getStatuses().get(deployedJobId);
if (taskStatus != null) {
state = taskStatus.getState();
}
break;
}
}
result.add(new DeploymentGroupStatusResponse.HostStatus(host, deployedJobId, state));
}
}
final DeploymentGroupStatusResponse.Status status;
if (deploymentGroupStatus == null) {
status = DeploymentGroupStatusResponse.Status.IDLE;
} else if (deploymentGroupStatus.getState() == DeploymentGroupStatus.State.FAILED) {
status = DeploymentGroupStatusResponse.Status.FAILED;
} else if (deploymentGroupStatus.getState() == DeploymentGroupStatus.State.ROLLING_OUT) {
status = DeploymentGroupStatusResponse.Status.ROLLING_OUT;
} else {
status = DeploymentGroupStatusResponse.Status.ACTIVE;
}
final String error = deploymentGroupStatus == null ? "" : deploymentGroupStatus.getError();
return Response.ok(new DeploymentGroupStatusResponse(deploymentGroup, status, error, result, deploymentGroupStatus)).build();
} catch (final DeploymentGroupDoesNotExistException e) {
return Response.status(Response.Status.NOT_FOUND).build();
}
}
use of com.spotify.helios.common.descriptors.HostStatus in project helios by spotify.
the class HostListCommand method run.
@Override
int run(final Namespace options, final HeliosClient client, final PrintStream out, final boolean json, final BufferedReader stdin) throws ExecutionException, InterruptedException {
final String pattern = options.getString(patternArg.getDest());
final List<String> selectorArgValue = options.getList(hostSelectorsArg.getDest());
final Set<String> selectors = ImmutableSet.copyOf(selectorArgValue);
final List<String> hosts;
if (pattern.isEmpty() && selectors.isEmpty()) {
hosts = client.listHosts().get();
} else if (!pattern.isEmpty() && selectors.isEmpty()) {
hosts = client.listHosts(pattern).get();
} else if (pattern.isEmpty() && !selectors.isEmpty()) {
hosts = client.listHosts(selectors).get();
} else {
hosts = client.listHosts(pattern, selectors).get();
}
final Map<String, String> queryParams = Maps.newHashMap();
final String statusFilter = options.getString(statusArg.getDest());
if (!isNullOrEmpty(statusFilter)) {
try {
HostStatus.Status.valueOf(statusFilter);
queryParams.put("status", statusFilter);
} catch (IllegalArgumentException ignored) {
throw new IllegalArgumentException("Invalid status. Valid statuses are: " + statusChoicesString);
}
}
final boolean full = options.getBoolean(fullArg.getDest());
final boolean quiet = options.getBoolean(quietArg.getDest());
if (hosts.isEmpty()) {
if (json) {
out.println("{ }");
} else if (!quiet && !isNullOrEmpty(pattern)) {
out.printf("host pattern %s matched no hosts%n", pattern);
}
return 1;
}
if (quiet) {
final List<String> sortedHosts = natural().sortedCopy(hosts);
if (json) {
out.println(Json.asPrettyStringUnchecked(sortedHosts));
} else {
for (final String host : sortedHosts) {
out.println(formatHostname(full, host));
}
}
} else {
final Map<String, HostStatus> statuses = new TreeMap<>(client.hostStatuses(hosts, queryParams).get());
if (json) {
out.println(Json.asPrettyStringUnchecked(statuses));
} else {
final Table table = table(out);
table.row("HOST", "STATUS", "DEPLOYED", "RUNNING", "CPUS", "MEM", "LOAD AVG", "MEM USAGE", "OS", "HELIOS", "DOCKER", "LABELS");
for (final Map.Entry<String, HostStatus> e : statuses.entrySet()) {
final String host = e.getKey();
final HostStatus s = e.getValue();
if (s == null) {
continue;
}
final Set<TaskStatus> runningDeployedJobs = Sets.newHashSet();
for (final JobId jobId : s.getJobs().keySet()) {
final TaskStatus taskStatus = s.getStatuses().get(jobId);
if (taskStatus == null) {
continue;
}
if (taskStatus.getState() == TaskStatus.State.RUNNING) {
runningDeployedJobs.add(taskStatus);
}
}
final HostInfo hi = s.getHostInfo();
final String memUsage;
final String cpus;
final String mem;
final String loadAvg;
final String os;
final String docker;
if (hi != null) {
final long free = hi.getMemoryFreeBytes();
final long total = hi.getMemoryTotalBytes();
memUsage = format("%.2f", (float) (total - free) / total);
cpus = String.valueOf(hi.getCpus());
mem = hi.getMemoryTotalBytes() / (1024 * 1024 * 1024) + " gb";
loadAvg = format("%.2f", hi.getLoadAvg());
os = hi.getOsName() + " " + hi.getOsVersion();
final DockerVersion dv = hi.getDockerVersion();
docker = (dv != null) ? format("%s (%s)", dv.getVersion(), dv.getApiVersion()) : "";
} else {
memUsage = cpus = mem = loadAvg = os = docker = "";
}
final String version;
if (s.getAgentInfo() != null) {
version = Optional.fromNullable(s.getAgentInfo().getVersion()).or("");
} else {
version = "";
}
String status = s.getStatus() == UP ? "Up" : "Down";
if (s.getAgentInfo() != null) {
final long startTime = s.getAgentInfo().getStartTime();
final long upTime = s.getAgentInfo().getUptime();
if (s.getStatus() == UP) {
status += " " + humanDuration(currentTimeMillis() - startTime);
} else {
status += " " + humanDuration(currentTimeMillis() - startTime - upTime);
}
}
final String hostLabels = Joiner.on(", ").withKeyValueSeparator("=").join(s.getLabels());
table.row(formatHostname(full, host), status, s.getJobs().size(), runningDeployedJobs.size(), cpus, mem, loadAvg, memUsage, os, version, docker, hostLabels);
}
table.print();
}
}
return 0;
}
use of com.spotify.helios.common.descriptors.HostStatus in project helios by spotify.
the class HostListCommandTest method testSelectorFilter.
@Test
public void testSelectorFilter() throws Exception {
final String hostname = "foo1.example.com";
final List<String> hosts = ImmutableList.of(hostname);
when(client.listHosts(ImmutableSet.of("foo=bar"))).thenReturn(Futures.immediateFuture(hosts));
final Map<String, HostStatus> statusResponse = ImmutableMap.of(hostname, upStatus);
when(client.hostStatuses(eq(hosts), anyMapOf(String.class, String.class))).thenReturn(Futures.immediateFuture(statusResponse));
final int ret = runCommand("--selector", "foo=bar");
assertEquals(0, ret);
assertEquals(ImmutableList.of("HOST", hostname + "."), TestUtils.readFirstColumnFromOutput(baos.toString(), false));
}
use of com.spotify.helios.common.descriptors.HostStatus in project helios by spotify.
the class MultiplePortJobTest method test.
@Test
public void test() throws Exception {
startDefaultMaster();
// 'Reserve' a 2 port wide range of ports.
final Range<Integer> portRange = temporaryPorts.localPortRange("agent1", 2);
// Start an agent using the aforementioned 2 port wide range.
final AgentMain agent1 = startDefaultAgent(testHost(), "--port-range=" + portRange.lowerEndpoint() + ":" + portRange.upperEndpoint());
try (final DockerClient dockerClient = getNewDockerClient()) {
final HeliosClient client = defaultClient();
awaitHostStatus(client, testHost(), UP, LONG_WAIT_SECONDS, SECONDS);
// foo is a mapping of 4711 -> A port dynamically allocated by the agent's PortAllocator
// bar is a mapping of 4712 -> A static port randomly selected by temporaryPorts
final Map<String, PortMapping> ports1 = ImmutableMap.of("foo", PortMapping.of(4711), "bar", staticMapping1);
// foo is a mapping of 4711 -> A port dynamically allocated by the agent's PortAllocator
// bar is a mapping of 4712 -> A static port randomly selected by temporaryPorts
final Map<String, PortMapping> ports2 = ImmutableMap.of("foo", PortMapping.of(4711), "bar", staticMapping2);
final JobId jobId1 = createJob(testJobName + 1, testJobVersion, BUSYBOX, IDLE_COMMAND, EMPTY_ENV, ports1);
assertNotNull(jobId1);
deployJob(jobId1, testHost());
final TaskStatus firstTaskStatus1 = awaitJobState(client, testHost(), jobId1, RUNNING, LONG_WAIT_SECONDS, SECONDS);
final JobId jobId2 = createJob(testJobName + 2, testJobVersion, BUSYBOX, IDLE_COMMAND, EMPTY_ENV, ports2);
assertNotNull(jobId2);
deployJob(jobId2, testHost());
final TaskStatus firstTaskStatus2 = awaitJobState(client, testHost(), jobId2, RUNNING, LONG_WAIT_SECONDS, SECONDS);
// Verify we allocated dynamic ports from within the specified range.
assertTrue(portRange.contains(firstTaskStatus1.getPorts().get("foo").getExternalPort()));
assertTrue(portRange.contains(firstTaskStatus2.getPorts().get("foo").getExternalPort()));
// Verify we allocated the static ports we asked for.
assertEquals(staticMapping1, firstTaskStatus1.getPorts().get("bar"));
assertEquals(staticMapping2, firstTaskStatus2.getPorts().get("bar"));
// Verify we didn't allocate the same dynamic port to both jobs.
assertNotEquals(firstTaskStatus1.getPorts().get("foo"), firstTaskStatus2.getPorts().get("foo"));
// TODO (dano): the supervisor should report the allocated ports at all times
// Verify that port allocation is kept across container restarts
dockerClient.killContainer(firstTaskStatus1.getContainerId());
final TaskStatus restartedTaskStatus1 = Polling.await(LONG_WAIT_SECONDS, SECONDS, new Callable<TaskStatus>() {
@Override
public TaskStatus call() throws Exception {
final HostStatus hostStatus = client.hostStatus(testHost()).get();
final TaskStatus taskStatus = hostStatus.getStatuses().get(jobId1);
return (taskStatus != null && taskStatus.getState() == RUNNING && !Objects.equals(taskStatus.getContainerId(), firstTaskStatus1.getContainerId())) ? taskStatus : null;
}
});
assertEquals(firstTaskStatus1.getPorts(), restartedTaskStatus1.getPorts());
// Verify that port allocation is kept across agent restarts
agent1.stopAsync().awaitTerminated();
dockerClient.killContainer(firstTaskStatus2.getContainerId());
startDefaultAgent(testHost());
final TaskStatus restartedTaskStatus2 = Polling.await(LONG_WAIT_SECONDS, SECONDS, new Callable<TaskStatus>() {
@Override
public TaskStatus call() throws Exception {
final HostStatus hostStatus = client.hostStatus(testHost()).get();
final TaskStatus taskStatus = hostStatus.getStatuses().get(jobId2);
return (taskStatus != null && taskStatus.getState() == RUNNING && !Objects.equals(taskStatus.getContainerId(), firstTaskStatus2.getContainerId())) ? taskStatus : null;
}
});
assertEquals(firstTaskStatus2.getPorts(), restartedTaskStatus2.getPorts());
}
}
use of com.spotify.helios.common.descriptors.HostStatus in project helios by spotify.
the class EnvironmentVariableTest method test.
@Test
public void test() throws Exception {
startDefaultMaster();
startDefaultAgent(testHost(), "--env", "SPOTIFY_POD=PODNAME", "SPOTIFY_ROLE=ROLENAME", "BAR=badfood");
awaitHostStatus(testHost(), UP, LONG_WAIT_SECONDS, SECONDS);
// Wait for the agent to report environment vars
Polling.await(LONG_WAIT_SECONDS, SECONDS, new Callable<Object>() {
@Override
public Object call() throws Exception {
final Map<String, HostStatus> status = Json.read(cli("hosts", testHost(), "--json"), new TypeReference<Map<String, HostStatus>>() {
});
return status.get(testHost()).getEnvironment();
}
});
try (final DockerClient dockerClient = getNewDockerClient()) {
final List<String> command = asList("sh", "-c", "echo pod: $SPOTIFY_POD; " + "echo role: $SPOTIFY_ROLE; " + "echo foo: $FOO; " + "echo bar: $BAR");
// Create job
final JobId jobId = createJob(testJobName, testJobVersion, BUSYBOX, command, ImmutableMap.of("FOO", "4711", "BAR", "deadbeef"));
// deploy
deployJob(jobId, testHost());
final TaskStatus taskStatus = awaitTaskState(jobId, testHost(), EXITED);
final LogStream logs = dockerClient.logs(taskStatus.getContainerId(), stdout(), stderr());
final String log = logs.readFully();
assertThat(log, containsString("pod: PODNAME"));
assertThat(log, containsString("role: ROLENAME"));
assertThat(log, containsString("foo: 4711"));
// Verify that the the BAR environment variable in the job overrode the agent config
assertThat(log, containsString("bar: deadbeef"));
final Map<String, HostStatus> status = Json.read(cli("hosts", testHost(), "--json"), new TypeReference<Map<String, HostStatus>>() {
});
assertEquals(ImmutableMap.of("SPOTIFY_POD", "PODNAME", "SPOTIFY_ROLE", "ROLENAME", "BAR", "badfood"), status.get(testHost()).getEnvironment());
assertEquals(ImmutableMap.of("SPOTIFY_POD", "PODNAME", "SPOTIFY_ROLE", "ROLENAME", "BAR", "deadbeef", "FOO", "4711"), status.get(testHost()).getStatuses().get(jobId).getEnv());
}
}
Aggregations