Skip to content
This repository has been archived by the owner on Jun 22, 2018. It is now read-only.

Commit

Permalink
#506 Support for Marathon groups.
Browse files Browse the repository at this point in the history
  • Loading branch information
frankscholten committed Mar 8, 2017
1 parent 117c434 commit e5689ad
Show file tree
Hide file tree
Showing 28 changed files with 513 additions and 166 deletions.
Empty file modified bin/minimesos
100644 → 100755
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
import com.containersol.minimesos.cluster.MesosCluster;
import com.containersol.minimesos.cluster.MesosClusterFactory;
import com.containersol.minimesos.mesos.MesosMasterContainer;
import com.containersol.minimesos.state.Discovery;
import com.containersol.minimesos.state.Framework;
import com.containersol.minimesos.state.Port;
import com.containersol.minimesos.state.Ports;
import com.containersol.minimesos.state.State;
import com.containersol.minimesos.state.Task;
import org.apache.commons.io.output.ByteArrayOutputStream;
Expand All @@ -15,16 +18,17 @@
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;

import static java.util.Collections.singletonList;
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class CommandPsTest {

private static final String FORMAT = "%-20s %-20s %s\n";
private static final Object[] COLUMNS = { "FRAMEWORK", "TASK", "STATE" };
private static final Object[] VALUES = {"marathon", "weave-scope", "TASK_RUNNING" };
private static final String FORMAT = "%-20s %-20s %-20s %-20s\n";
private static final Object[] COLUMNS = { "FRAMEWORK", "TASK", "STATE", "PORT"};
private static final Object[] VALUES = {"marathon", "weave-scope", "TASK_RUNNING", "4040" };

private ByteArrayOutputStream outputStream;

Expand All @@ -46,6 +50,17 @@ public void execute() throws UnsupportedEncodingException {
task.setName("weave-scope");
task.setState("TASK_RUNNING");

Port port = new Port();
port.setNumber(4040);

Ports ports = new Ports();
ports.setPorts(singletonList(port));

Discovery discovery = new Discovery();
discovery.setPorts(ports);

task.setDiscovery(discovery);

ArrayList<Task> tasks = new ArrayList<>();
tasks.add(task);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ public void testInstall() {
commandUp.execute();

CommandInstall install = new CommandInstall();
install.setMarathonFile("src/integration-test/resources/app.json");
install.app = "src/integration-test/resources/app.json";

install.execute();

Expand All @@ -163,7 +163,7 @@ public void testInstall_alreadyRunning() {
commandUp.execute();

CommandInstall install = new CommandInstall();
install.setMarathonFile("src/integration-test/resources/app.json");
install.app = "src/integration-test/resources/app.json";

install.execute();
install.execute();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
import com.containersol.minimesos.cluster.Marathon;
import com.containersol.minimesos.cluster.MesosCluster;
import com.containersol.minimesos.cluster.MesosClusterFactory;
import mesosphere.marathon.client.model.v2.Result;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Matchers;
Expand All @@ -15,6 +15,9 @@
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;

public class CommandUninstallTest {

private ByteArrayOutputStream outputStream;
Expand All @@ -33,24 +36,55 @@ public void initTest() {
marathon = Mockito.mock(Marathon.class);

mesosCluster = Mockito.mock(MesosCluster.class);
Mockito.when(mesosCluster.getMarathon()).thenReturn(marathon);
when(mesosCluster.getMarathon()).thenReturn(marathon);

repository = Mockito.mock(ClusterRepository.class);
Mockito.when(repository.loadCluster(Matchers.any(MesosClusterFactory.class))).thenReturn(mesosCluster);
when(repository.loadCluster(Matchers.any(MesosClusterFactory.class))).thenReturn(mesosCluster);

commandUninstall = new CommandUninstall(ps);
commandUninstall.setRepository(repository);
commandUninstall.setApp("app");
}

@Test
public void execute() throws UnsupportedEncodingException {
Mockito.doNothing().when(marathon).deleteApp("app");
public void execute_app() throws UnsupportedEncodingException {
// Given
commandUninstall.setApp("/app");
when(marathon.deleteApp("/app")).thenReturn(new Result());

// When
commandUninstall.execute();

String result = outputStream.toString("UTF-8");
Assert.assertEquals("Deleted app 'app'\n", result);
// Then
String string = outputStream.toString("UTF-8");
assertEquals("Deleted app '/app'\n", string);
}

@Test
public void execute_group() throws UnsupportedEncodingException {
// Given
commandUninstall.setGroup("/group");
when(marathon.deleteGroup("/group")).thenReturn(new Result());

// When
commandUninstall.execute();

// Then
String string = outputStream.toString("UTF-8");
assertEquals("Deleted group '/group'\n", string);
}

@Test
public void execute_appAndGroup() throws UnsupportedEncodingException {
// Given
commandUninstall.setGroup("/group1");
commandUninstall.setApp("/app2");

// When
commandUninstall.execute();

// Then
String string = outputStream.toString("UTF-8");
assertEquals("Please specify --app or --group to uninstall an app or group\n", string);
}

@Test
Expand All @@ -60,6 +94,6 @@ public void execute_appDoesNotExist() throws UnsupportedEncodingException {
commandUninstall.execute();

String result = outputStream.toString("UTF-8");
Assert.assertEquals("", result);
assertEquals("Please specify --app or --group to uninstall an app or group\n", result);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public void execute() {

MesosDns mesosDns = cluster.getMesosDns();
if (mesosDns != null) {
output.println("Running dnsmasq? Add 'server=/mm/" + mesosDns.getIpAddress() + "#5353' to /etc/dnsmasq.d/10-minimesos to resolve master.mm, zookeeper.mm and Marathon apps on app.marathon.mm.");
output.println("Running dnsmasq? Add 'server=/mm/" + mesosDns.getIpAddress() + "#53' to /etc/dnsmasq.d/10-minimesos to resolve master.mm, zookeeper.mm and Marathon apps on app.marathon.mm.");
}
} else {
output.println(String.format("Minimesos cluster %s is not running. %s is removed", clusterId, repository.getMinimesosFile().getAbsolutePath()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,65 +7,37 @@
import com.containersol.minimesos.cluster.Marathon;
import com.containersol.minimesos.cluster.MesosCluster;
import com.containersol.minimesos.mesos.MesosClusterContainersFactory;
import org.apache.commons.io.IOUtils;

import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;

import static org.apache.commons.lang.StringUtils.*;

/**
* Installs a framework with Marathon
* Installs an Marathon application or application group.
*/
@Parameters(commandDescription = "Install a framework with Marathon")
@Parameters(commandDescription = "Install a Marathon application or application group")
public class CommandInstall implements Command {

public static final String CLINAME = "install";
private static final String CLINAME = "install";

@Deprecated
@Parameter(names = "--marathonFile", description = "[Deprecated - Please use --marathonApp] Relative path or URL to a JSON file with a Marathon app definition.")
String marathonFile = null;

@Parameter(names = "--app", description = "Relative path or URL to a JSON file with a Marathon app definition. See https://mesosphere.github.io/marathon/docs/application-basics.html.")
String app = null;

@Parameter(names = "--marathonFile", description = "Marathon JSON app install file path or URL. Either this or --stdin parameter must be used")
private String marathonFile = null;
@Parameter(names = "--group", description = "Relative path or URL to a JSON file with a group of Marathon apps. See https://mesosphere.github.io/marathon/docs/application-groups.html.")
String group = null;

@Parameter(names = "--stdin", description = "Use JSON from standard import. Allow piping JSON from other processes. Either this or --marathonFile parameter must be used")
@Parameter(names = "--stdin", description = "Read JSON file with Marathon app or group definition from stdin.")
private boolean stdin = false;

@Parameter(names = "--update", description = "Update a running application instead of attempting to deploy a new application")
private boolean update = false;

private ClusterRepository repository = new ClusterRepository();

/**
* Getting content of <code>marathonFile</code>, if provided, or standard input
*
* @return content of the file or standard input
*/
public String getMarathonJson() throws IOException {

String fileContents = "";
Scanner scanner;

if (marathonFile != null && !marathonFile.isEmpty()) {

InputStream json = MesosCluster.getInputStream(marathonFile);
if (json == null) {
throw new MinimesosException("Failed to find content of " + marathonFile);
}

scanner = new Scanner(json);

} else if (stdin) {
scanner = new Scanner(System.in);
} else {
throw new MinimesosException("Neither --marathonFile nor --stdin parameters are provided");
}

try {
while (scanner.hasNextLine()) {
fileContents = fileContents.concat(scanner.nextLine());
}
} finally {
scanner.close();
}

return fileContents;
}
ClusterRepository repository = new ClusterRepository();

@Override
public void execute() {
Expand All @@ -80,30 +52,51 @@ public void execute() {
try {
marathonJson = getMarathonJson();
} catch (IOException e) {
throw new MinimesosException("Failed to read JSON", e);
throw new MinimesosException("Failed to read JSON file from path, URL or stdin", e);
}

if (update) {
marathon.updateApp(marathonJson);
} else {
} else if (isNotBlank(app) || isNotBlank(marathonFile)) {
marathon.deployApp(marathonJson);
} else if (isNotBlank(group)) {
marathon.deployGroup(marathonJson);
} else {
throw new MinimesosException("Neither app, group, --stdinApp or --stdinGroup is provided");
}
} else {
throw new MinimesosException("Running cluster is not found");
}
}

/**
* Getting content of the Marathon JSON file if specified or via standard input
*
* @return content of the file or standard input
*/
private String getMarathonJson() throws IOException {
if (stdin) {
return IOUtils.toString(System.in, "UTF-8");
} else {
if (isNotBlank(marathonFile)) {
return IOUtils.toString(MesosCluster.getInputStream(marathonFile), "UTF-8");
} else if (isNotBlank(app)) {
return IOUtils.toString(MesosCluster.getInputStream(app), "UTF-8");
} else if (isNotBlank(group)) {
return IOUtils.toString(MesosCluster.getInputStream(group), "UTF-8");
}
}
throw new IOException("Please specify a URL or path to Marathon JSON file or use --stdin");
}

@Override
public boolean validateParameters() {
return stdin || (marathonFile != null && !marathonFile.isEmpty());
return isNotBlank(app) || isNotBlank(group) || isNotBlank(marathonFile);
}

@Override
public String getName() {
return CLINAME;
}

public void setMarathonFile(String marathonFile) {
this.marathonFile = marathonFile;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@
@Parameters(separators = "=", commandDescription = "List running tasks")
public class CommandPs implements Command {

private static final String FORMAT = "%-20s %-20s %s\n";
private static final Object[] COLUMNS = { "FRAMEWORK", "TASK", "STATE" };
private static final String FORMAT = "%-20s %-20s %-20s %-20s\n";

private static final Object[] COLUMNS = { "FRAMEWORK", "TASK", "STATE", "PORT" };

private ClusterRepository repository = new ClusterRepository();

Expand Down Expand Up @@ -54,7 +55,7 @@ public void execute() {
State state = cluster.getMaster().getState();
for (Framework framework : state.getFrameworks()) {
for (Task task : framework.getTasks()) {
output.printf(FORMAT, framework.getName(), task.getName(), task.getState());
output.printf(FORMAT, framework.getName(), task.getName(), task.getState(), task.getDiscovery().getPorts().getPorts().get(0).getNumber());
}
}
}
Expand Down
Loading

0 comments on commit e5689ad

Please sign in to comment.